From 822711a530d4cc8566acbdc706fedb93a9cf5d86 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Fri, 17 Jan 2025 13:28:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor=EF=BC=9A=E9=87=8D=E6=9E=84=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E8=BE=93=E5=85=A5=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/cards/DirectoryCard.vue | 39 ++++-------- src/components/field/PathField.vue | 49 +++++++++++++++ src/components/input/PathInput.vue | 87 +++++++++++++++++++++++++- src/main.ts | 2 + 4 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 src/components/field/PathField.vue diff --git a/src/components/cards/DirectoryCard.vue b/src/components/cards/DirectoryCard.vue index b7b5fb22..8e451540 100644 --- a/src/components/cards/DirectoryCard.vue +++ b/src/components/cards/DirectoryCard.vue @@ -1,6 +1,5 @@ + + diff --git a/src/components/input/PathInput.vue b/src/components/input/PathInput.vue index bf53a5f5..8fb77258 100644 --- a/src/components/input/PathInput.vue +++ b/src/components/input/PathInput.vue @@ -3,6 +3,10 @@ import api from '@/api' import { FileItem } from '@/api/types' const props = defineProps({ + modelValue: { + type: String, + default: '/', + }, root: { type: String, default: '/', @@ -16,7 +20,7 @@ const props = defineProps({ const emit = defineEmits(['update:modelValue']) -const activedDirs = ref[]>([]) +const menuVisible = ref(false) const treeItems = ref([ { @@ -29,16 +33,70 @@ const treeItems = ref([ }, ]) +const activedDirs = ref([]) + +const openedDirs = ref([]) + +// 调用API查询子目录 async function fetchDirs(item: any) { return api .post('/storage/list', item) .then((data: any) => { data = data.filter((i: any) => i.type === 'dir') - item.children.push(...data) + item.children?.push(...data) }) .catch(err => console.warn(err)) } +// 递归查询路径 +function findPath(item: FileItem, path: string): FileItem | null { + if (item.path === path) { + return item + } + if (item.children) { + for (const child of item.children) { + const res: FileItem | null = findPath(child, path) + if (res) { + return res + } + } + } + return null +} + +// 根据路径展开所有子目录 +async function expandDirs(path: string) { + // 分割路径 + const paths = path.split('/').filter(i => i) + // 展开根目录 + const root_item = treeItems.value[0] + await fetchDirs(root_item) + openedDirs.value.push(root_item) + // 逐级展开 + let currentPath = '/' + for (const p of paths) { + currentPath += `${p}/` + // 查询当前目录 + const item = findPath(root_item, currentPath) + if (!item) { + break + } + // 加载子目录 + if (item.children?.length === 0) { + await fetchDirs(item) + } + // 打开当前目录 + if (!openedDirs.value.includes(item) && path != currentPath) { + openedDirs.value.push(item) + } + // 选中当前目录 + if (path == currentPath) { + activedDirs.value = [item] + } + } +} + +// 当前选中项 const selectedPath = computed(() => { if (activedDirs.value.length > 0) { return activedDirs.value[0].path @@ -51,6 +109,27 @@ watch(activedDirs, newVal => { emit('update:modelValue', selectedPath.value) }) +watch( + () => menuVisible.value, + async visible => { + if (visible) { + treeItems.value = [ + { + name: '/', + path: props.root, + children: [], + type: 'dir', + basename: props.root, + storage: props.storage, + }, + ] + openedDirs.value = [] + activedDirs.value = [] + await expandDirs(props.modelValue) + } + }, +) + watch( () => props.storage, async newVal => { @@ -65,18 +144,20 @@ watch( }, ] activedDirs.value = [] + openedDirs.value = [] }, )