feat(components): 新建网盘页面布局
11
src/assets/svg-icon/file-image.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg t="1642407370336" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6354"
|
||||
width="200" height="200">
|
||||
<path
|
||||
d="M952.888889 281.6V910.222222c0 62.862222-50.915556 113.777778-113.777778 113.777778H156.444444c-62.862222 0-113.777778-50.915556-113.777777-113.777778V113.777778c0-62.862222 50.915556-113.777778 113.777777-113.777778h514.844445L952.888889 281.6z"
|
||||
fill="#85BCFF" p-id="6355"></path>
|
||||
<path d="M676.664889 167.822222V0l281.6 281.6h-167.822222c-62.862222 0-113.777778-50.915556-113.777778-113.777778"
|
||||
fill="#529EE0" p-id="6356"></path>
|
||||
<path
|
||||
d="M685.824 363.804444a53.76 53.76 0 0 1 53.731556 53.731556v307.029333a53.76 53.76 0 0 1-53.731556 53.731556H309.76a53.731556 53.731556 0 0 1-53.731556-53.76V417.564444c0-29.667556 24.035556-53.731556 53.731556-53.731555H685.795556z m-72.903111 149.674667l-138.183111 146.545778-80.583111-62.805333-92.131556 94.208v31.402666c0 11.548444 10.325333 20.906667 23.04 20.906667h345.400889c12.714667 0 23.04-9.386667 23.04-20.906667v-125.610666l-80.583111-83.740445z m-227.896889-85.532444a32.085333 32.085333 0 1 0 0 64.142222 32.085333 32.085333 0 0 0 0-64.142222z"
|
||||
fill="#FFFFFF" p-id="6357"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
11
src/assets/svg-icon/file-music.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg t="1642407502942" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7293"
|
||||
width="200" height="200">
|
||||
<path
|
||||
d="M967.111111 281.6V910.222222c0 62.862222-50.915556 113.777778-113.777778 113.777778H170.666667c-62.862222 0-113.777778-50.915556-113.777778-113.777778V113.777778c0-62.862222 50.915556-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
|
||||
fill="#A15FDE" p-id="7294"></path>
|
||||
<path d="M685.511111 196.266667V0L967.111111 281.6H770.844444a85.333333 85.333333 0 0 1-85.333333-85.333333"
|
||||
fill="#C386F0" p-id="7295"></path>
|
||||
<path
|
||||
d="M669.980444 426.268444v236.999112c0 26.254222-31.857778 47.587556-71.082666 47.587555-39.253333 0-70.741333-21.333333-70.741334-47.587555 0-26.282667 31.516444-47.587556 70.741334-47.587556 14.848 0 28.728889 3.100444 40.163555 8.334222v-165.916444l-205.767111 48.497778v211.057777c0 26.254222-32.142222 47.559111-71.992889 47.559111-39.850667 0-72.305778-21.333333-72.305777-47.559111 0-26.282667 32.426667-47.587556 72.305777-47.587555a96.711111 96.711111 0 0 1 41.102223 8.647111V474.168889c0-14.222222 9.870222-26.88 23.779555-29.980445l205.795556-47.900444a30.862222 30.862222 0 0 1 38.001777 29.980444"
|
||||
fill="#FFFFFF" p-id="7296"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
11
src/assets/svg-icon/file-other.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg t="1642408119178" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="53519" width="200" height="200">
|
||||
<path
|
||||
d="M967.111111 281.6V910.222222c0 62.862222-50.915556 113.777778-113.777778 113.777778H170.666667c-62.862222 0-113.777778-50.915556-113.777778-113.777778V113.777778c0-62.862222 50.915556-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
|
||||
fill="#BABABA" p-id="53520"></path>
|
||||
<path d="M685.511111 167.822222V0L967.111111 281.6H799.288889c-62.862222 0-113.777778-50.915556-113.777778-113.777778"
|
||||
fill="#979797" p-id="53521"></path>
|
||||
<path
|
||||
d="M733.667556 632.689778a111.104 111.104 0 0 1-110.819556 110.819555h-221.667556a111.132444 111.132444 0 0 1-110.848-110.819555 111.047111 111.047111 0 0 1 99.754667-110.279111A122.197333 122.197333 0 0 1 512 407.694222a122.197333 122.197333 0 0 1 121.912889 114.716445 111.160889 111.160889 0 0 1 99.754667 110.279111"
|
||||
fill="#FFFFFF" p-id="53522"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1002 B |
11
src/assets/svg-icon/file-txt.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg t="1642407315436" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5906"
|
||||
width="200" height="200">
|
||||
<path
|
||||
d="M967.111111 281.6V910.222222c0 62.862222-50.915556 113.777778-113.777778 113.777778H170.666667c-62.862222 0-113.777778-50.915556-113.777778-113.777778V113.777778c0-62.862222 50.915556-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
|
||||
fill="#6D9FE5" p-id="5907"></path>
|
||||
<path d="M685.511111 167.822222V0L967.111111 281.6H799.288889c-62.862222 0-113.777778-50.915556-113.777778-113.777778"
|
||||
fill="#4B80CB" p-id="5908"></path>
|
||||
<path
|
||||
d="M344.177778 485.575111h312.888889V426.666667h-312.888889zM471.153778 770.019556h58.908444v-284.444445h-58.908444z"
|
||||
fill="#FFFFFF" p-id="5909"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 795 B |
14
src/assets/svg-icon/file-video.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<svg t="1642407389455" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6501"
|
||||
width="200" height="200">
|
||||
<path
|
||||
d="M967.111111 281.6V910.222222c0 62.862222-50.915556 113.777778-113.777778 113.777778H170.666667c-62.862222 0-113.777778-50.915556-113.777778-113.777778V113.777778c0-62.862222 50.915556-113.777778 113.777778-113.777778h514.844444L967.111111 281.6z"
|
||||
fill="#C386F0" p-id="6502"></path>
|
||||
<path
|
||||
d="M284.444444 398.222222m42.666667 0l298.666667 0q42.666667 0 42.666666 42.666667l0 234.666667q0 42.666667-42.666666 42.666666l-298.666667 0q-42.666667 0-42.666667-42.666666l0-234.666667q0-42.666667 42.666667-42.666667Z"
|
||||
fill="#FFFFFF" p-id="6503"></path>
|
||||
<path
|
||||
d="M738.417778 457.841778a31.971556 31.971556 0 0 1 48.014222 27.676444v154.538667c0 24.632889-26.652444 40.021333-47.985778 27.704889L684.430222 636.586667V488.96z"
|
||||
fill="#FFFFFF" p-id="6504"></path>
|
||||
<path d="M685.511111 167.822222V0L967.111111 281.6H799.288889c-62.862222 0-113.777778-50.915556-113.777778-113.777778"
|
||||
fill="#A15FDE" p-id="6505"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/svg-icon/menu-file.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg t="1684652847211" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2238" width="200" height="200"><path d="M0 0m372.363636 0l279.272728 0q372.363636 0 372.363636 372.363636l0 279.272728q0 372.363636-372.363636 372.363636l-279.272728 0q-372.363636 0-372.363636-372.363636l0-279.272728q0-372.363636 372.363636-372.363636Z" fill="#F7A647" p-id="2239"></path><path d="M232.727273 303.872C232.727273 290.327273 243.781818 279.272727 257.326545 279.272727h148.631273c5.620364 0 10.984727 2.292364 14.848 6.283637l50.897455 52.805818c1.186909 1.233455 2.210909 2.594909 3.037091 4.049454h259.874909c31.138909 0 56.657455 25.460364 56.657454 56.610909V688.058182c0 31.150545-25.518545 56.669091-56.657454 56.669091H289.396364C258.245818 744.727273 232.727273 719.208727 232.727273 688.058182V303.872zM726.702545 556.218182h-239.825454a10.216727 10.216727 0 0 0-10.205091 10.205091v25.390545c0 5.620364 4.584727 10.205091 10.205091 10.205091h239.825454a10.216727 10.216727 0 0 0 10.205091-10.205091v-25.390545a10.216727 10.216727 0 0 0-10.205091-10.205091z m-0.058181-87.691637h-239.825455a10.216727 10.216727 0 0 0-10.205091 10.205091h-0.069818v25.390546c0 5.632 4.573091 10.216727 10.205091 10.216727h239.895273a10.216727 10.216727 0 0 0 10.205091-10.216727V478.72a10.216727 10.216727 0 0 0-10.205091-10.205091z" fill="#FFFFFF" p-id="2240"></path></svg>
|
After Width: | Height: | Size: 1.4 KiB |
1
src/assets/svg-icon/return.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1740719602812" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3072" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M462.266 167.466L134.168 451.847l328.098 284.359V544.827s454.799-147.683 362.705 311.707c0 0 293.586-557.828-368.422-519.544l5.719-169.527z" fill="#2C2C2C" p-id="3073"></path></svg>
|
After Width: | Height: | Size: 514 B |
@ -3,5 +3,6 @@ export enum SetupStoreId {
|
||||
Theme = 'theme-store',
|
||||
Auth = 'auth-store',
|
||||
Route = 'route-store',
|
||||
Tab = 'tab-store'
|
||||
Tab = 'tab-store',
|
||||
Pan = 'pan-store'
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ withDefaults(defineProps<Props>(), {
|
||||
<RouterLink to="/" class="w-full flex-center nowrap-hidden">
|
||||
<SystemLogo class="text-32px text-primary" />
|
||||
<h2 v-show="showTitle" class="pl-8px text-16px text-primary font-bold transition duration-300 ease-in-out">
|
||||
{{ $t(title) }}
|
||||
{{ title }}
|
||||
</h2>
|
||||
</RouterLink>
|
||||
</template>
|
||||
|
@ -10,6 +10,7 @@ import { getRouteName } from '@/router/elegant/transform';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { localStg } from '@/utils/storage';
|
||||
import { usePanStore } from '@/store/modules/pan';
|
||||
|
||||
/**
|
||||
* create route guard
|
||||
@ -19,10 +20,17 @@ import { localStg } from '@/utils/storage';
|
||||
export function createRouteGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const routeStore = useRouteStore();
|
||||
const panStore = usePanStore();
|
||||
// 每次路由变化时更新页面类型
|
||||
routeStore.setPageType(to);
|
||||
const location = await initRoute(to);
|
||||
|
||||
if (to.name === 'pan') {
|
||||
// 从路由参数中初始化路径
|
||||
const pathParams = to.query.path as string;
|
||||
panStore.initPathFromRoute(pathParams);
|
||||
}
|
||||
|
||||
if (location) {
|
||||
next(location);
|
||||
return;
|
||||
|
58
src/store/modules/pan/index.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
import { localStg } from '@/utils/storage';
|
||||
|
||||
export const usePanStore = defineStore(SetupStoreId.Pan, () => {
|
||||
const fileShowMode = ref<UnionKey.FileListMode>(localStg.get('fileShowMode') || 'grid');
|
||||
const currentPath = ref<string[]>([]);
|
||||
|
||||
// 切换文件列表视图的方法
|
||||
const toggleFileShowMode = (mode: UnionKey.FileListMode) => {
|
||||
fileShowMode.value = mode;
|
||||
localStg.set('fileShowMode', mode);
|
||||
};
|
||||
|
||||
// 初始化路径
|
||||
const initPathFromRoute = (pathStr?: string) => {
|
||||
if (!pathStr) {
|
||||
currentPath.value = [];
|
||||
return;
|
||||
}
|
||||
const pathArr = pathStr.split('/');
|
||||
pathArr.shift();
|
||||
currentPath.value = pathArr;
|
||||
};
|
||||
|
||||
// 带路由更新的导航方法
|
||||
const navigateTo = async (path: string[]) => {
|
||||
const router = useRouter();
|
||||
currentPath.value = path;
|
||||
|
||||
// 更新路由(使用 replace 避免产生多余历史记录)
|
||||
await router.replace({ query: { path: path.length ? `/${path.join('/')}` : undefined } });
|
||||
};
|
||||
|
||||
// 进入文件夹方法
|
||||
const enterFolder = async (folderName: string) => {
|
||||
await navigateTo([...currentPath.value, folderName]);
|
||||
};
|
||||
|
||||
// 返回上级方法
|
||||
const backToParent = async () => {
|
||||
if (currentPath.value.length > 0) {
|
||||
await navigateTo(currentPath.value.slice(0, -1));
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
currentPath,
|
||||
initPathFromRoute,
|
||||
navigateTo,
|
||||
enterFolder,
|
||||
backToParent,
|
||||
fileShowMode,
|
||||
toggleFileShowMode
|
||||
};
|
||||
});
|
11
src/typings/components.d.ts
vendored
@ -17,8 +17,11 @@ declare module 'vue' {
|
||||
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
|
||||
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
|
||||
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
|
||||
'IconCuida:swapVerticalArrowsOutline': typeof import('~icons/cuida/swap-vertical-arrows-outline')['default']
|
||||
'IconFluent:multiselect20Filled': typeof import('~icons/fluent/multiselect20-filled')['default']
|
||||
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
|
||||
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
|
||||
'IconIc:outlineFileUpload': typeof import('~icons/ic/outline-file-upload')['default']
|
||||
'IconIc:roundPlus': typeof import('~icons/ic/round-plus')['default']
|
||||
IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
|
||||
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
|
||||
@ -30,12 +33,16 @@ declare module 'vue' {
|
||||
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
||||
IconLocalWechat: typeof import('~icons/local/wechat')['default']
|
||||
IconLocalWecom: typeof import('~icons/local/wecom')['default']
|
||||
'IconMaterialSymbols:apps': typeof import('~icons/material-symbols/apps')['default']
|
||||
'IconMdi:formatListBulleted': typeof import('~icons/mdi/format-list-bulleted')['default']
|
||||
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
||||
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
||||
IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
||||
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
||||
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
||||
'IconMeteorIcons:trashCan': typeof import('~icons/meteor-icons/trash-can')['default']
|
||||
'IconTabler:filter': typeof import('~icons/tabler/filter')['default']
|
||||
IconUilSearch: typeof import('~icons/uil/search')['default']
|
||||
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
||||
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
||||
@ -44,6 +51,7 @@ declare module 'vue' {
|
||||
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
|
||||
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
|
||||
NButton: typeof import('naive-ui')['NButton']
|
||||
NButtonGroup: typeof import('naive-ui')['NButtonGroup']
|
||||
NCard: typeof import('naive-ui')['NCard']
|
||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
||||
@ -62,6 +70,7 @@ declare module 'vue' {
|
||||
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
|
||||
NGi: typeof import('naive-ui')['NGi']
|
||||
NGrid: typeof import('naive-ui')['NGrid']
|
||||
NGridItem: typeof import('naive-ui')['NGridItem']
|
||||
NInput: typeof import('naive-ui')['NInput']
|
||||
NInputGroup: typeof import('naive-ui')['NInputGroup']
|
||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||
@ -74,11 +83,13 @@ declare module 'vue' {
|
||||
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
||||
NPopover: typeof import('naive-ui')['NPopover']
|
||||
NProgress: typeof import('naive-ui')['NProgress']
|
||||
NRadio: typeof import('naive-ui')['NRadio']
|
||||
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSelect: typeof import('naive-ui')['NSelect']
|
||||
NSpace: typeof import('naive-ui')['NSpace']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NStatistic: typeof import('naive-ui')['NStatistic']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTab: typeof import('naive-ui')['NTab']
|
||||
|
1
src/typings/storage.d.ts
vendored
@ -37,5 +37,6 @@ declare namespace StorageType {
|
||||
layout: UnionKey.ThemeLayoutMode;
|
||||
siderCollapse: boolean;
|
||||
};
|
||||
fileShowMode: UnionKey.FileListMode;
|
||||
}
|
||||
}
|
||||
|
2
src/typings/union-key.d.ts
vendored
@ -53,6 +53,8 @@ declare namespace UnionKey {
|
||||
|
||||
type SystemPageType = 'pan' | 'admin' | null;
|
||||
|
||||
type FileListMode = 'grid' | 'list';
|
||||
|
||||
/** Unocss animate key */
|
||||
type UnoCssAnimateKey =
|
||||
| 'pulse'
|
||||
|
18
src/views/pan/components/file-path.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({ name: 'FilePath' });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-y-center gap-8px">
|
||||
<SvgIcon local-icon="return" class="text-size-icon-large" />
|
||||
<NBreadcrumb>
|
||||
<NBreadcrumbItem separator=">">
|
||||
根目录
|
||||
<template #separator></template>
|
||||
</NBreadcrumbItem>
|
||||
<NBreadcrumbItem separator=">">新建文件夹</NBreadcrumbItem>
|
||||
</NBreadcrumb>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -1,7 +1,27 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import FileAside from './modules/file-aside.vue';
|
||||
import FileMain from './modules/file-main.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const gap = computed(() => (appStore.isMobile ? 0 : 16));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>网盘页面</div>
|
||||
<div class="h-full flex-col">
|
||||
<div class="h-full flex pb[-28px]">
|
||||
<NGrid :x-gap="gap" responsive="screen" item-responsive>
|
||||
<NGridItem span="0 s:8 m:6 l:5 xl:4">
|
||||
<FileAside></FileAside>
|
||||
</NGridItem>
|
||||
<NGridItem span="24 s:16 m:18 l:19 xl:20">
|
||||
<FileMain />
|
||||
</NGridItem>
|
||||
</NGrid>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
86
src/views/pan/modules/file-aside.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useSvgIcon } from '@/hooks/common/icon';
|
||||
|
||||
defineOptions({
|
||||
name: 'FileAside'
|
||||
});
|
||||
|
||||
const { SvgIconVNode } = useSvgIcon();
|
||||
|
||||
const selectedKey = ref('2');
|
||||
|
||||
const showPersent = ref(false);
|
||||
|
||||
const fileMenuOptions = [
|
||||
{
|
||||
key: '1',
|
||||
label: '文件类型',
|
||||
icon: SvgIconVNode({ icon: 'uim:apps' }),
|
||||
children: [
|
||||
{
|
||||
key: '2',
|
||||
label: '全部',
|
||||
icon: SvgIconVNode({ localIcon: 'menu-file', fontSize: 28 })
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: '图片',
|
||||
icon: SvgIconVNode({ localIcon: 'file-image', fontSize: 28 })
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
label: '文档',
|
||||
icon: SvgIconVNode({ localIcon: 'file-txt', fontSize: 28 })
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
label: '视频',
|
||||
icon: SvgIconVNode({ localIcon: 'file-video', fontSize: 28 })
|
||||
},
|
||||
{
|
||||
key: '6',
|
||||
label: '音频',
|
||||
icon: SvgIconVNode({ localIcon: 'file-music', fontSize: 28 })
|
||||
},
|
||||
{
|
||||
key: '7',
|
||||
label: '其他',
|
||||
icon: SvgIconVNode({ localIcon: 'file-other', fontSize: 28 })
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full flex-col">
|
||||
<NCard
|
||||
title="文件列表"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
:content-style="{ padding: 0, display: 'flex', flexDirection: 'column' }"
|
||||
class="h-full flex-1"
|
||||
>
|
||||
<template #header-extra>
|
||||
<NTooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<NSwitch v-model:value="showPersent" :round="false" size="small" />
|
||||
</template>
|
||||
显示容量
|
||||
</NTooltip>
|
||||
</template>
|
||||
<NMenu v-model:value="selectedKey" :options="fileMenuOptions"></NMenu>
|
||||
</NCard>
|
||||
<div v-show="showPersent" class="mt-10px box-border">
|
||||
<NCard :bordered="false">
|
||||
<NSpace justify="center">
|
||||
<NProgress type="circle" :percentage="30" :stroke-width="5" />
|
||||
<NStatistic label="剩余容量 / 总容量" value="512GB / 1T"></NStatistic>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
137
src/views/pan/modules/file-main.vue
Normal file
@ -0,0 +1,137 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { useSvgIcon } from '@/hooks/common/icon';
|
||||
import { usePanStore } from '@/store/modules/pan';
|
||||
import FilePath from '../components/file-path.vue';
|
||||
defineOptions({
|
||||
name: 'FileMain'
|
||||
});
|
||||
const { SvgIconVNode } = useSvgIcon();
|
||||
const panStore = usePanStore();
|
||||
|
||||
// 是否是批量操作
|
||||
const isBatchMode = ref<boolean>(false);
|
||||
// 是否是加载的状态
|
||||
const show = ref(false);
|
||||
|
||||
// 获取当前文件列表的展示模式
|
||||
const currentMode = computed(() => panStore.fileShowMode);
|
||||
|
||||
// 切换展示模式
|
||||
const toggleMode = () => {
|
||||
const newMode = currentMode.value === 'grid' ? 'list' : 'grid';
|
||||
panStore.toggleFileShowMode(newMode);
|
||||
};
|
||||
|
||||
const uploadOptions = [
|
||||
{
|
||||
key: 'file',
|
||||
label: '上传文件',
|
||||
icon: SvgIconVNode({ localIcon: 'upload-file', fontSize: 20 }),
|
||||
props: {
|
||||
onClick: () => {
|
||||
// handleFileUpload();
|
||||
window.$message?.info('上传文件功能');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'folder',
|
||||
label: '上传文件夹',
|
||||
icon: SvgIconVNode({ localIcon: 'upload-folder', fontSize: 20 }),
|
||||
props: {
|
||||
onClick: () => {
|
||||
// handleFolderUpload();
|
||||
window.$message?.info('上传文件夹功能');
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full flex-col overflow-hidden">
|
||||
<NCard class="h-full">
|
||||
<FilePath />
|
||||
<NSpace justify="space-between" class="mt-10px">
|
||||
<NSpace>
|
||||
<!--上传操作按钮-->
|
||||
<NDropdown trigger="click" :options="uploadOptions">
|
||||
<NButton type="primary" round>
|
||||
<template #icon>
|
||||
<icon-ic:outline-file-upload />
|
||||
</template>
|
||||
上传
|
||||
</NButton>
|
||||
</NDropdown>
|
||||
|
||||
<!--搜索框-->
|
||||
<NInputGroup>
|
||||
<NSelect class="w-150px"></NSelect>
|
||||
<NInput placeholder="请输入关键词..."></NInput>
|
||||
<NButton type="primary">
|
||||
<template #icon>
|
||||
<icon-uil-search />
|
||||
</template>
|
||||
搜索
|
||||
</NButton>
|
||||
</NInputGroup>
|
||||
</NSpace>
|
||||
<!--右侧按钮及功能-->
|
||||
<NSpace>
|
||||
<NButton v-if="isBatchMode" type="error">
|
||||
<template #icon>
|
||||
<icon-meteor-icons:trash-can />
|
||||
</template>
|
||||
</NButton>
|
||||
<NButton type="primary" @click="isBatchMode = !isBatchMode">
|
||||
<template #icon>
|
||||
<icon-fluent:multiselect-20-filled />
|
||||
</template>
|
||||
<template #default>{{ isBatchMode ? '取消批量' : '批量操作' }}</template>
|
||||
</NButton>
|
||||
<NButtonGroup>
|
||||
<NTooltip placement="bottom" trigger="hover">
|
||||
<template #trigger>
|
||||
<NButton>
|
||||
<template #icon>
|
||||
<icon-cuida:swap-vertical-arrows-outline />
|
||||
</template>
|
||||
</NButton>
|
||||
</template>
|
||||
<span>传输列表</span>
|
||||
</NTooltip>
|
||||
<NTooltip placement="bottom" trigger="hover">
|
||||
<template #trigger>
|
||||
<NButton>
|
||||
<template #icon>
|
||||
<icon-tabler:filter />
|
||||
</template>
|
||||
</NButton>
|
||||
</template>
|
||||
<span>排序</span>
|
||||
</NTooltip>
|
||||
<NTooltip placement="bottom" trigger="hover">
|
||||
<template #trigger>
|
||||
<NButton @click="toggleMode">
|
||||
<template #icon>
|
||||
<icon-material-symbols:apps v-if="currentMode === 'grid'" />
|
||||
<icon-mdi:format-list-bulleted v-else />
|
||||
</template>
|
||||
</NButton>
|
||||
</template>
|
||||
<span>视图</span>
|
||||
</NTooltip>
|
||||
</NButtonGroup>
|
||||
</NSpace>
|
||||
</NSpace>
|
||||
|
||||
<!--文件列表--宫格模式-->
|
||||
<NSpin :show="show" class="box-border flex-col px-0 py-16px">
|
||||
<FileGrid />
|
||||
</NSpin>
|
||||
</NCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|