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',
|
Theme = 'theme-store',
|
||||||
Auth = 'auth-store',
|
Auth = 'auth-store',
|
||||||
Route = 'route-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">
|
<RouterLink to="/" class="w-full flex-center nowrap-hidden">
|
||||||
<SystemLogo class="text-32px text-primary" />
|
<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">
|
<h2 v-show="showTitle" class="pl-8px text-16px text-primary font-bold transition duration-300 ease-in-out">
|
||||||
{{ $t(title) }}
|
{{ title }}
|
||||||
</h2>
|
</h2>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</template>
|
</template>
|
||||||
|
@ -10,6 +10,7 @@ import { getRouteName } from '@/router/elegant/transform';
|
|||||||
import { useAuthStore } from '@/store/modules/auth';
|
import { useAuthStore } from '@/store/modules/auth';
|
||||||
import { useRouteStore } from '@/store/modules/route';
|
import { useRouteStore } from '@/store/modules/route';
|
||||||
import { localStg } from '@/utils/storage';
|
import { localStg } from '@/utils/storage';
|
||||||
|
import { usePanStore } from '@/store/modules/pan';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create route guard
|
* create route guard
|
||||||
@ -19,10 +20,17 @@ import { localStg } from '@/utils/storage';
|
|||||||
export function createRouteGuard(router: Router) {
|
export function createRouteGuard(router: Router) {
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
const routeStore = useRouteStore();
|
const routeStore = useRouteStore();
|
||||||
|
const panStore = usePanStore();
|
||||||
// 每次路由变化时更新页面类型
|
// 每次路由变化时更新页面类型
|
||||||
routeStore.setPageType(to);
|
routeStore.setPageType(to);
|
||||||
const location = await initRoute(to);
|
const location = await initRoute(to);
|
||||||
|
|
||||||
|
if (to.name === 'pan') {
|
||||||
|
// 从路由参数中初始化路径
|
||||||
|
const pathParams = to.query.path as string;
|
||||||
|
panStore.initPathFromRoute(pathParams);
|
||||||
|
}
|
||||||
|
|
||||||
if (location) {
|
if (location) {
|
||||||
next(location);
|
next(location);
|
||||||
return;
|
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']
|
IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
|
||||||
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
|
IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
|
||||||
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-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']
|
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
|
||||||
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['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']
|
'IconIc:roundPlus': typeof import('~icons/ic/round-plus')['default']
|
||||||
IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
|
IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
|
||||||
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
|
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
|
||||||
@ -30,12 +33,16 @@ declare module 'vue' {
|
|||||||
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
IconLocalLogo: typeof import('~icons/local/logo')['default']
|
||||||
IconLocalWechat: typeof import('~icons/local/wechat')['default']
|
IconLocalWechat: typeof import('~icons/local/wechat')['default']
|
||||||
IconLocalWecom: typeof import('~icons/local/wecom')['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']
|
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
||||||
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
||||||
IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
||||||
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
||||||
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
||||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['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']
|
IconUilSearch: typeof import('~icons/uil/search')['default']
|
||||||
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
|
||||||
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
LookForward: typeof import('./../components/custom/look-forward.vue')['default']
|
||||||
@ -44,6 +51,7 @@ declare module 'vue' {
|
|||||||
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
|
NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
|
||||||
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
|
NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
|
||||||
NButton: typeof import('naive-ui')['NButton']
|
NButton: typeof import('naive-ui')['NButton']
|
||||||
|
NButtonGroup: typeof import('naive-ui')['NButtonGroup']
|
||||||
NCard: typeof import('naive-ui')['NCard']
|
NCard: typeof import('naive-ui')['NCard']
|
||||||
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
NColorPicker: typeof import('naive-ui')['NColorPicker']
|
||||||
@ -62,6 +70,7 @@ declare module 'vue' {
|
|||||||
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
|
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
|
||||||
NGi: typeof import('naive-ui')['NGi']
|
NGi: typeof import('naive-ui')['NGi']
|
||||||
NGrid: typeof import('naive-ui')['NGrid']
|
NGrid: typeof import('naive-ui')['NGrid']
|
||||||
|
NGridItem: typeof import('naive-ui')['NGridItem']
|
||||||
NInput: typeof import('naive-ui')['NInput']
|
NInput: typeof import('naive-ui')['NInput']
|
||||||
NInputGroup: typeof import('naive-ui')['NInputGroup']
|
NInputGroup: typeof import('naive-ui')['NInputGroup']
|
||||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||||
@ -74,11 +83,13 @@ declare module 'vue' {
|
|||||||
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||||
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
NPopconfirm: typeof import('naive-ui')['NPopconfirm']
|
||||||
NPopover: typeof import('naive-ui')['NPopover']
|
NPopover: typeof import('naive-ui')['NPopover']
|
||||||
|
NProgress: typeof import('naive-ui')['NProgress']
|
||||||
NRadio: typeof import('naive-ui')['NRadio']
|
NRadio: typeof import('naive-ui')['NRadio']
|
||||||
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
NSelect: typeof import('naive-ui')['NSelect']
|
NSelect: typeof import('naive-ui')['NSelect']
|
||||||
NSpace: typeof import('naive-ui')['NSpace']
|
NSpace: typeof import('naive-ui')['NSpace']
|
||||||
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
NStatistic: typeof import('naive-ui')['NStatistic']
|
NStatistic: typeof import('naive-ui')['NStatistic']
|
||||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||||
NTab: typeof import('naive-ui')['NTab']
|
NTab: typeof import('naive-ui')['NTab']
|
||||||
|
1
src/typings/storage.d.ts
vendored
@ -37,5 +37,6 @@ declare namespace StorageType {
|
|||||||
layout: UnionKey.ThemeLayoutMode;
|
layout: UnionKey.ThemeLayoutMode;
|
||||||
siderCollapse: boolean;
|
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 SystemPageType = 'pan' | 'admin' | null;
|
||||||
|
|
||||||
|
type FileListMode = 'grid' | 'list';
|
||||||
|
|
||||||
/** Unocss animate key */
|
/** Unocss animate key */
|
||||||
type UnoCssAnimateKey =
|
type UnoCssAnimateKey =
|
||||||
| 'pulse'
|
| '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>
|
<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>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<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>
|