From f331b33b0afde712e83a7d47c9b49af9b103aff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E7=A3=8A?= <17600116464@163.com> Date: Fri, 28 Feb 2025 03:32:18 -0500 Subject: [PATCH] =?UTF-8?q?feat(components):=20=E6=96=B0=E5=BB=BA=E7=BD=91?= =?UTF-8?q?=E7=9B=98=E9=A1=B5=E9=9D=A2=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/svg-icon/file-image.svg | 11 ++ src/assets/svg-icon/file-music.svg | 11 ++ src/assets/svg-icon/file-other.svg | 11 ++ src/assets/svg-icon/file-txt.svg | 11 ++ src/assets/svg-icon/file-video.svg | 14 +++ src/assets/svg-icon/menu-file.svg | 1 + src/assets/svg-icon/return.svg | 1 + src/enum/index.ts | 3 +- src/layouts/modules/global-logo/index.vue | 2 +- src/router/guard/route.ts | 8 ++ src/store/modules/pan/index.ts | 58 +++++++++ src/typings/components.d.ts | 11 ++ src/typings/storage.d.ts | 1 + src/typings/union-key.d.ts | 2 + src/views/pan/components/file-path.vue | 18 +++ src/views/pan/index.vue | 24 +++- src/views/pan/modules/file-aside.vue | 86 ++++++++++++++ src/views/pan/modules/file-main.vue | 137 ++++++++++++++++++++++ 18 files changed, 406 insertions(+), 4 deletions(-) create mode 100644 src/assets/svg-icon/file-image.svg create mode 100644 src/assets/svg-icon/file-music.svg create mode 100644 src/assets/svg-icon/file-other.svg create mode 100644 src/assets/svg-icon/file-txt.svg create mode 100644 src/assets/svg-icon/file-video.svg create mode 100644 src/assets/svg-icon/menu-file.svg create mode 100644 src/assets/svg-icon/return.svg create mode 100644 src/store/modules/pan/index.ts create mode 100644 src/views/pan/components/file-path.vue create mode 100644 src/views/pan/modules/file-aside.vue create mode 100644 src/views/pan/modules/file-main.vue diff --git a/src/assets/svg-icon/file-image.svg b/src/assets/svg-icon/file-image.svg new file mode 100644 index 00000000..4d1bd688 --- /dev/null +++ b/src/assets/svg-icon/file-image.svg @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/src/assets/svg-icon/file-music.svg b/src/assets/svg-icon/file-music.svg new file mode 100644 index 00000000..4f44a86a --- /dev/null +++ b/src/assets/svg-icon/file-music.svg @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/src/assets/svg-icon/file-other.svg b/src/assets/svg-icon/file-other.svg new file mode 100644 index 00000000..91570bbc --- /dev/null +++ b/src/assets/svg-icon/file-other.svg @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/src/assets/svg-icon/file-txt.svg b/src/assets/svg-icon/file-txt.svg new file mode 100644 index 00000000..f65ead70 --- /dev/null +++ b/src/assets/svg-icon/file-txt.svg @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/src/assets/svg-icon/file-video.svg b/src/assets/svg-icon/file-video.svg new file mode 100644 index 00000000..f7e5750f --- /dev/null +++ b/src/assets/svg-icon/file-video.svg @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/src/assets/svg-icon/menu-file.svg b/src/assets/svg-icon/menu-file.svg new file mode 100644 index 00000000..d2a1c8a0 --- /dev/null +++ b/src/assets/svg-icon/menu-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svg-icon/return.svg b/src/assets/svg-icon/return.svg new file mode 100644 index 00000000..82a61776 --- /dev/null +++ b/src/assets/svg-icon/return.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/enum/index.ts b/src/enum/index.ts index 2739b3a4..315ec788 100644 --- a/src/enum/index.ts +++ b/src/enum/index.ts @@ -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' } diff --git a/src/layouts/modules/global-logo/index.vue b/src/layouts/modules/global-logo/index.vue index bca7530c..d8e5d94d 100644 --- a/src/layouts/modules/global-logo/index.vue +++ b/src/layouts/modules/global-logo/index.vue @@ -26,7 +26,7 @@ withDefaults(defineProps(), { - {{ $t(title) }} + {{ title }} diff --git a/src/router/guard/route.ts b/src/router/guard/route.ts index fc3cfa46..9e7966c4 100644 --- a/src/router/guard/route.ts +++ b/src/router/guard/route.ts @@ -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; diff --git a/src/store/modules/pan/index.ts b/src/store/modules/pan/index.ts new file mode 100644 index 00000000..343c42cc --- /dev/null +++ b/src/store/modules/pan/index.ts @@ -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(localStg.get('fileShowMode') || 'grid'); + const currentPath = ref([]); + + // 切换文件列表视图的方法 + 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 + }; +}); diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts index e43c8f33..c3c7bfd6 100644 --- a/src/typings/components.d.ts +++ b/src/typings/components.d.ts @@ -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'] diff --git a/src/typings/storage.d.ts b/src/typings/storage.d.ts index 02668fcc..f7134d4b 100644 --- a/src/typings/storage.d.ts +++ b/src/typings/storage.d.ts @@ -37,5 +37,6 @@ declare namespace StorageType { layout: UnionKey.ThemeLayoutMode; siderCollapse: boolean; }; + fileShowMode: UnionKey.FileListMode; } } diff --git a/src/typings/union-key.d.ts b/src/typings/union-key.d.ts index 99c3111a..935eb474 100644 --- a/src/typings/union-key.d.ts +++ b/src/typings/union-key.d.ts @@ -53,6 +53,8 @@ declare namespace UnionKey { type SystemPageType = 'pan' | 'admin' | null; + type FileListMode = 'grid' | 'list'; + /** Unocss animate key */ type UnoCssAnimateKey = | 'pulse' diff --git a/src/views/pan/components/file-path.vue b/src/views/pan/components/file-path.vue new file mode 100644 index 00000000..be065d59 --- /dev/null +++ b/src/views/pan/components/file-path.vue @@ -0,0 +1,18 @@ + + + + + + + + 根目录 + + + 新建文件夹 + + + + + diff --git a/src/views/pan/index.vue b/src/views/pan/index.vue index 68fba895..5302c894 100644 --- a/src/views/pan/index.vue +++ b/src/views/pan/index.vue @@ -1,7 +1,27 @@ - + - 网盘页面 + + + + + + + + + + + + diff --git a/src/views/pan/modules/file-aside.vue b/src/views/pan/modules/file-aside.vue new file mode 100644 index 00000000..1d0b19d8 --- /dev/null +++ b/src/views/pan/modules/file-aside.vue @@ -0,0 +1,86 @@ + + + + + + + + + + + 显示容量 + + + + + + + + + + + + + + + + diff --git a/src/views/pan/modules/file-main.vue b/src/views/pan/modules/file-main.vue new file mode 100644 index 00000000..82fdced5 --- /dev/null +++ b/src/views/pan/modules/file-main.vue @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + 上传 + + + + + + + + + + + + 搜索 + + + + + + + + + + + + + + + {{ isBatchMode ? '取消批量' : '批量操作' }} + + + + + + + + + + + 传输列表 + + + + + + + + + + 排序 + + + + + + + + + + + 视图 + + + + + + + + + + + + + +