Skip to content

Commit

Permalink
feat: 文件操作支持覆盖
Browse files Browse the repository at this point in the history
  • Loading branch information
devhaozi committed Oct 26, 2024
1 parent 42dd00c commit 658b6a7
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 24 deletions.
4 changes: 2 additions & 2 deletions internal/service/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func (s *FileService) Move(w http.ResponseWriter, r *http.Request) {
}

if io.Exists(req.Target) && !req.Force {
Error(w, http.StatusForbidden, "target path %s already exists", req.Target)
Error(w, http.StatusForbidden, "target path already exists") // no translate, frontend will use it to determine whether to continue
return
}

Expand All @@ -200,7 +200,7 @@ func (s *FileService) Copy(w http.ResponseWriter, r *http.Request) {
}

if io.Exists(req.Target) && !req.Force {
Error(w, http.StatusForbidden, "target path %s already exists", req.Target)
Error(w, http.StatusForbidden, "target path already exists") // no translate, frontend will use it to determine whether to continue
return
}

Expand Down
9 changes: 5 additions & 4 deletions web/src/api/panel/file/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { AxiosResponse } from 'axios'

import { request } from '@/utils'
import type { RequestConfig } from '~/types/axios'

export default {
// 创建文件/文件夹
Expand All @@ -25,11 +26,11 @@ export default {
})
},
// 移动文件
move: (source: string, target: string): Promise<AxiosResponse<any>> =>
request.post('/file/move', { source, target }),
move: (source: string, target: string, force: boolean): Promise<AxiosResponse<any>> =>
request.post('/file/move', { source, target, force }, { noNeedTip: true } as RequestConfig),
// 复制文件
copy: (source: string, target: string): Promise<AxiosResponse<any>> =>
request.post('/file/copy', { source, target }),
copy: (source: string, target: string, force: boolean): Promise<AxiosResponse<any>> =>
request.post('/file/copy', { source, target, force }, { noNeedTip: true } as RequestConfig),
// 远程下载
remoteDownload: (path: string, url: string): Promise<AxiosResponse<any>> =>
request.post('/file/remoteDownload', { path, url }),
Expand Down
133 changes: 127 additions & 6 deletions web/src/views/file/ListTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const unCompressModel = ref({
const options = computed<DropdownOption[]>(() => {
if (selectedRow.value == null) return []
return [
let options = [
{
label: selectedRow.value.dir ? '打开' : '编辑',
key: selectedRow.value.dir ? 'open' : 'edit'
Expand All @@ -59,6 +59,14 @@ const options = computed<DropdownOption[]>(() => {
{ label: '重命名', key: 'rename' },
{ label: () => h('span', { style: { color: 'red' } }, '删除'), key: 'delete' }
]
if (marked.value.length) {
options.unshift({
label: '粘贴',
key: 'paste'
})
}
return options
})
const columns: DataTableColumns<RowData> = [
Expand Down Expand Up @@ -385,11 +393,43 @@ const handleRename = () => {
return
}
file.move(source, target).then(() => {
window.$message.success('重命名成功')
renameModal.value = false
window.$bus.emit('file:refresh')
})
file
.move(source, target, false)
.then(() => {
window.$message.success(
`重命名 ${renameModel.value.source} 为 ${renameModel.value.target} 成功`
)
renameModal.value = false
window.$bus.emit('file:refresh')
})
.catch((err) => {
if (err.message == 'target path already exists') {
window.$dialog.warning({
title: '警告',
content: `存在同名项,是否强制覆盖?`,
positiveText: '覆盖',
negativeText: '取消',
onPositiveClick: () => {
file
.move(source, target, true)
.then(() => {
window.$message.success(
`重命名 ${renameModel.value.source} 为 ${renameModel.value.target} 成功`
)
renameModal.value = false
window.$bus.emit('file:refresh')
})
.catch((err) => {
window.$message.error(err.message)
})
},
onNegativeClick: () => {
renameModal.value = false
window.$bus.emit('file:refresh')
}
})
}
})
}
const handleUnCompress = () => {
Expand Down Expand Up @@ -422,8 +462,89 @@ const onChecked = (rowKeys: any) => {
selected.value = rowKeys
}
const handlePaste = async () => {
if (!marked.value.length) {
window.$message.error('请先标记需要复制或移动的文件/文件夹')
return
}
for (const { name, source, type } of marked.value) {
const target = path.value + '/' + name
if (type === 'copy') {
file
.copy(source, target, false)
.then(() => {
window.$message.success(`复制 ${source} 到 ${target} 成功`)
})
.catch((err) => {
if (err.message == 'target path already exists') {
window.$dialog.warning({
title: '警告',
content: `目标 ${target} 已存在,是否覆盖?`,
positiveText: '覆盖',
negativeText: '取消',
onPositiveClick: () => {
file
.copy(source, target, true)
.then(() => {
window.$message.success(`复制 ${source} 到 ${target} 成功`)
})
.catch((err) => {
window.$message.error(err.message)
})
},
onNegativeClick: () => {
marked.value = []
}
})
}
})
.finally(() => {
window.$bus.emit('file:refresh')
})
} else {
file
.move(source, target, false)
.then(() => {
window.$message.success(`移动 ${source} 到 ${target} 成功`)
})
.catch((err) => {
if (err.message == 'target path already exists') {
window.$dialog.warning({
title: '警告',
content: `目标 ${target} 已存在,是否覆盖?`,
positiveText: '覆盖',
negativeText: '取消',
onPositiveClick: () => {
file
.move(source, target, true)
.then(() => {
window.$message.success(`移动 ${source} 到 ${target} 成功`)
})
.catch((err) => {
window.$message.error(err.message)
})
},
onNegativeClick: () => {
marked.value = []
}
})
}
})
.finally(() => {
window.$bus.emit('file:refresh')
})
}
}
marked.value = []
}
const handleSelect = (key: string) => {
switch (key) {
case 'paste':
handlePaste()
break
case 'open':
path.value = selectedRow.value.full
break
Expand Down
78 changes: 66 additions & 12 deletions web/src/views/file/ToolBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ const handleMove = () => {
window.$message.success('标记成功,请前往目标路径粘贴')
}
const handleCancel = () => {
marked.value = []
}
const handlePaste = async () => {
if (!marked.value.length) {
window.$message.error('请先标记需要复制或移动的文件/文件夹')
Expand All @@ -92,25 +96,75 @@ const handlePaste = async () => {
for (const { name, source, type } of marked.value) {
const target = path.value + '/' + name
if (type === 'copy') {
await file.copy(source, target).then(() => {
window.$message.success(`复制 ${source} 到 ${target} 成功`)
window.$bus.emit('file:refresh')
})
file
.copy(source, target, false)
.then(() => {
window.$message.success(`复制 ${source} 到 ${target} 成功`)
})
.catch((err) => {
if (err.message == 'target path already exists') {
window.$dialog.warning({
title: '警告',
content: `目标 ${target} 已存在,是否覆盖?`,
positiveText: '覆盖',
negativeText: '取消',
onPositiveClick: () => {
file
.copy(source, target, true)
.then(() => {
window.$message.success(`复制 ${source} 到 ${target} 成功`)
})
.catch((err) => {
window.$message.error(err.message)
})
},
onNegativeClick: () => {
handleCancel()
}
})
}
})
.finally(() => {
window.$bus.emit('file:refresh')
})
} else {
await file.move(source, target).then(() => {
window.$message.success(`移动 ${source} 到 ${target} 成功`)
window.$bus.emit('file:refresh')
})
file
.move(source, target, false)
.then(() => {
window.$message.success(`移动 ${source} 到 ${target} 成功`)
})
.catch((err) => {
if (err.message == 'target path already exists') {
window.$dialog.warning({
title: '警告',
content: `目标 ${target} 已存在,是否覆盖?`,
positiveText: '覆盖',
negativeText: '取消',
onPositiveClick: () => {
file
.move(source, target, true)
.then(() => {
window.$message.success(`移动 ${source} 到 ${target} 成功`)
})
.catch((err) => {
window.$message.error(err.message)
})
},
onNegativeClick: () => {
handleCancel()
}
})
}
})
.finally(() => {
window.$bus.emit('file:refresh')
})
}
}
marked.value = []
}
const handleCancel = () => {
marked.value = []
}
const bulkDelete = () => {
if (!selected.value.length) {
window.$message.error('请选择要删除的文件/文件夹')
Expand Down

0 comments on commit 658b6a7

Please sign in to comment.