fix FileManager

This commit is contained in:
jxxghp
2023-08-26 14:30:51 +08:00
parent f4aef8f9dd
commit e3df4000bb
6 changed files with 58 additions and 59 deletions
+1
View File
@@ -903,6 +903,7 @@ export interface EndPoints {
list: any list: any
mkdir: any mkdir: any
delete: any delete: any
download: any
} }
// 文件浏览项目 // 文件浏览项目
+4 -11
View File
@@ -12,17 +12,12 @@ const props = defineProps({
storages: String, storages: String,
storage: String, storage: String,
path: String, path: String,
tree: String, tree: Boolean,
endpoints: Object as PropType<EndPoints>, endpoints: Object as PropType<EndPoints>,
axios: Object as PropType<Axios>, axios: Object as PropType<Axios>,
axiosconfig: Object, axiosconfig: Object,
}) })
// 事件f
const emit = defineEmits(['change'])
console.log('FileBrowser Init Path', props.path)
const availableStorages = [ const availableStorages = [
{ {
name: '本地', name: '本地',
@@ -53,14 +48,14 @@ const fileIcons = {
other: 'mdi-file-outline', other: 'mdi-file-outline',
} }
// 加载次数
const loading = ref(0)
// 当前路径 // 当前路径
const path = ref(props.path) const path = ref(props.path)
// 加载次数
const loading = ref(0)
// 当前存储 // 当前存储
const activeStorage = ref('local') const activeStorage = ref('local')
// 刷新 // 刷新
const refreshPending = ref(true) const refreshPending = ref(false)
// axios实例 // axios实例
const axiosInstance = ref<Axios>() const axiosInstance = ref<Axios>()
@@ -84,8 +79,6 @@ function storageChanged(storage: string) {
function pathChanged(_path: string) { function pathChanged(_path: string) {
path.value = _path path.value = _path
console.log('Browser changePath', path.value)
emit('change', path)
} }
// 初始化 // 初始化
+35 -23
View File
@@ -19,8 +19,6 @@ const props = defineProps({
// 对外事件 // 对外事件
const emit = defineEmits(['loading', 'pathchanged', 'refreshed', 'filedeleted']) const emit = defineEmits(['loading', 'pathchanged', 'refreshed', 'filedeleted'])
console.log('List Init Path', props.path)
// 确认框 // 确认框
const createConfirm = useConfirm() const createConfirm = useConfirm()
@@ -30,18 +28,12 @@ const axiosInstance = ref<Axios>(props.axios ?? axios)
// 内容列表 // 内容列表
const items = ref<FileItem[]>([]) const items = ref<FileItem[]>([])
// 当前路径
const path = ref(props.path)
// 过滤条件 // 过滤条件
const filter = ref('') const filter = ref('')
// 存储空间类型 // 存储空间类型
const storage = ref(props.storage ?? '') const storage = ref(props.storage ?? '')
// 是否正在加载
const refreshPending = ref(props.refreshpending || false)
// 目录过滤 // 目录过滤
const dirs = computed(() => const dirs = computed(() =>
items.value.filter(item => item.type === 'dir' && item.basename.includes(filter.value)), items.value.filter(item => item.type === 'dir' && item.basename.includes(filter.value)),
@@ -53,27 +45,27 @@ const files = computed(() =>
) )
// 是否目录 // 是否目录
const isDir = computed(() => path.value?.endsWith('/')) const isDir = computed(() => props.path?.endsWith('/'))
// 是否文件 // 是否文件
const isFile = computed(() => !isDir.value) const isFile = computed(() => !isDir.value)
// 调API加载内容 // 调API加载内容
async function load() { async function load() {
console.log('List load', path.value, isDir.value) emit('loading', true)
if (isDir.value) { if (isDir.value) {
const url = props.endpoints?.list.url const url = props.endpoints?.list.url
.replace(/{storage}/g, storage.value) .replace(/{storage}/g, storage.value)
.replace(/{path}/g, path.value) .replace(/{path}/g, props.path)
const config = { const config = {
url, url,
method: props.endpoints?.list.method || 'get', method: props.endpoints?.list.method || 'get',
} }
console.log('List load', url, config)
// 加载数据 // 加载数据
items.value = await axiosInstance.value.request(config) ?? [] items.value = await axiosInstance.value.request(config) ?? []
} }
emit('loading', false)
} }
// 删除项目 // 删除项目
@@ -104,23 +96,41 @@ async function deleteItem(item: FileItem) {
await axiosInstance.value.request(config) await axiosInstance.value.request(config)
emit('filedeleted') emit('filedeleted')
emit('loading', false) emit('loading', false)
// 重新加载
load()
} }
} }
// 切换路径 // 切换路径
function changePath(_path: string) { function changePath(_path: string) {
path.value = _path emit('pathchanged', _path)
console.log('List changePath', path.value) }
emit('pathchanged', path)
// 新窗口中下载文件
function download(path: string) {
if (!path)
return
const url = props.endpoints?.download.url
.replace(/{storage}/g, storage.value)
.replace(/{path}/g, path)
// FIXME 下载文件
window.open(url, '_blank')
} }
// 监听path变化 // 监听path变化
watch( watch(
path, () => props.path,
async () => { async () => {
console.log('List pathChanged', path.value)
items.value = [] items.value = []
if (refreshPending.value) { await load()
},
)
// 监听refreshPending变化
watch(
() => props.refreshpending,
async () => {
if (props.refreshpending) {
await load() await load()
emit('refreshed') emit('refreshed')
} }
@@ -147,7 +157,7 @@ onMounted(() => {
文件: {{ path }} 文件: {{ path }}
</VCardText> </VCardText>
<VCardText v-else-if="dirs.length || files.length" class="grow"> <VCardText v-else-if="dirs.length || files.length" class="grow">
<VList v-if="dirs.length" subheader> <VList v-if="dirs.length" subheader max-height="300">
<VListSubheader>目录</VListSubheader> <VListSubheader>目录</VListSubheader>
<VListItem <VListItem
v-for="(item, index) in dirs" v-for="(item, index) in dirs"
@@ -167,7 +177,7 @@ onMounted(() => {
</VListItem> </VListItem>
</VList> </VList>
<VDivider v-if="dirs.length && files.length" /> <VDivider v-if="dirs.length && files.length" />
<VList v-if="files.length" subheader> <VList v-if="files.length" subheader max-height="300">
<VListSubheader>文件</VListSubheader> <VListSubheader>文件</VListSubheader>
<VListItem <VListItem
v-for="(item, index) in files" v-for="(item, index) in files"
@@ -203,8 +213,9 @@ onMounted(() => {
空目录 空目录
</VCardText> </VCardText>
<VDivider v-if="path" /> <VDivider v-if="path" />
<VToolbar v-if="path && isFile" density="compact" flat color="gray"> <VToolbar density="compact" flat color="gray">
<VTextField <VTextField
v-if="!isFile"
v-model="filter" v-model="filter"
hide-details hide-details
flat flat
@@ -214,10 +225,11 @@ onMounted(() => {
prepend-inner-icon="mdi-filter-outline" prepend-inner-icon="mdi-filter-outline"
class="me-2" class="me-2"
/> />
<VBtn icon> <VSpacer v-if="isFile" />
<VBtn v-if="isFile" @click="download(props.path || '')">
<VIcon>mdi-download</VIcon> <VIcon>mdi-download</VIcon>
</VBtn> </VBtn>
<VBtn icon @click="load"> <VBtn v-if="!isFile" @click="load">
<VIcon>mdi-refresh</VIcon> <VIcon>mdi-refresh</VIcon>
</VBtn> </VBtn>
</VToolbar> </VToolbar>
+12 -13
View File
@@ -14,9 +14,6 @@ const inProps = defineProps({
// 对外事件 // 对外事件
const emit = defineEmits(['storagechanged', 'pathchanged', 'loading', 'foldercreated']) const emit = defineEmits(['storagechanged', 'pathchanged', 'loading', 'foldercreated'])
// 当前路径
const path = ref(inProps.path ?? '')
// 新建文件夹名称 // 新建文件夹名称
const newFolderPopper = ref(false) const newFolderPopper = ref(false)
@@ -26,16 +23,16 @@ const newFolderName = ref('')
// 计算PATH面包屑 // 计算PATH面包屑
const pathSegments = computed(() => { const pathSegments = computed(() => {
let path_str = '/' let path_str = '/'
const isFolder = path.value.endsWith('/') const isFolder = inProps.path?.endsWith('/')
const segments = path.value.split('/').filter(item => item) const segments = inProps.path?.split('/').filter(item => item)
return segments.map((item, index) => { return segments?.map((item, index) => {
path_str += item + ((index < segments.length - 1 || isFolder) ? '/' : '') path_str += item + ((index < segments.length - 1 || isFolder) ? '/' : '')
return { return {
name: item, name: item,
path: path_str, path: path_str,
} }
}) }) ?? []
}) })
const storageObject = computed(() => { const storageObject = computed(() => {
@@ -52,15 +49,13 @@ function changeStorage(code: string) {
// 路径变化 // 路径变化
function changePath(_path: string) { function changePath(_path: string) {
path.value = _path emit('pathchanged', _path)
console.log('Toolbar changePath', path.value)
emit('pathchanged', path)
} }
// 返回上一级 // 返回上一级
function goUp() { function goUp() {
const segments = pathSegments.value const segments = pathSegments.value ?? []
const path = segments.length === 1 ? '/' : segments[segments.length - 2].path const path = segments?.length === 1 ? '/' : segments[segments.length - 2].path
changePath(path) changePath(path)
} }
@@ -76,11 +71,15 @@ async function mkdir() {
method: inProps.endpoints?.mkdir.method || 'post', method: inProps.endpoints?.mkdir.method || 'post',
} }
// 调API
await inProps.axios?.request(config) await inProps.axios?.request(config)
emit('foldercreated', newFolderName.value)
newFolderPopper.value = false newFolderPopper.value = false
newFolderName.value = '' newFolderName.value = ''
emit('loading', false) emit('loading', false)
// 通知重新加载
emit('foldercreated')
} }
</script> </script>
+3 -10
View File
@@ -15,9 +15,6 @@ const props = defineProps({
// 对外事件 // 对外事件
const emit = defineEmits(['pathchanged', 'loading', 'refreshed']) const emit = defineEmits(['pathchanged', 'loading', 'refreshed'])
// 当前路径
const path = ref(props.path)
// 变量 // 变量
const open = ref<string[]>([]) const open = ref<string[]>([])
// 活跃的文件夹 // 活跃的文件夹
@@ -26,8 +23,6 @@ const active = ref<string[]>([])
const items = ref<FileItem[]>([]) const items = ref<FileItem[]>([])
// 过滤 // 过滤
const filter = ref('') const filter = ref('')
// 刷新状态
const refreshPending = ref(props.refreshpending || false)
// 方法 // 方法
function init() { function init() {
@@ -69,8 +64,6 @@ async function readFolder(item: FileItem) {
// 选中变化 // 选中变化
function activeChanged(_active: string[]) { function activeChanged(_active: string[]) {
console.log('Tree changePath', _active)
active.value = _active
let path = '' let path = ''
if (active.value.length) if (active.value.length)
path = active.value[0] path = active.value[0]
@@ -103,7 +96,7 @@ watch(() => props.storage, () => {
// 监听路径变化 // 监听路径变化
watch( watch(
path, () => props.path,
() => { () => {
if (props.path) { if (props.path) {
active.value = [props.path] active.value = [props.path]
@@ -114,9 +107,9 @@ watch(
// 监听 refreshPending // 监听 refreshPending
watch( watch(
refreshPending, () => props.refreshpending,
async () => { async () => {
if (refreshPending.value && props.path) { if (props.refreshpending && props.path) {
const item = findItem(props.path) const item = findItem(props.path)
if (item) { if (item) {
await readFolder(item) await readFolder(item)
+3 -2
View File
@@ -2,17 +2,18 @@
import api from '@/api' import api from '@/api'
import FileBrowser from '@/components/FileBrowser.vue' import FileBrowser from '@/components/FileBrowser.vue'
const initPath = ref('/Users/jxxghp/Downloads/爱情生活 (2020)/') const initPath = '/Users/jxxghp/Downloads/爱情生活 (2020)/'
const endpoints = { const endpoints = {
list: { url: '/filebrowser/list?path={path}', method: 'get' }, list: { url: '/filebrowser/list?path={path}', method: 'get' },
mkdir: { url: '/filebrowser/mkdir?path={path}', method: 'get' }, mkdir: { url: '/filebrowser/mkdir?path={path}', method: 'get' },
delete: { url: '/filebrowser/delete?path={path}', method: 'get' }, delete: { url: '/filebrowser/delete?path={path}', method: 'get' },
download: { url: '/filebrowser/download?path={path}', method: 'get' },
} }
</script> </script>
<template> <template>
<div> <div>
<FileBrowser storages="local" tree="true" :path="initPath" :endpoints="endpoints" :axios="api" /> <FileBrowser storages="local" :tree="false" :path="initPath" :endpoints="endpoints" :axios="api" />
</div> </div>
</template> </template>