mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 11:27:17 +08:00
feat: 文件操作支持覆盖
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { AxiosResponse } from 'axios'
|
||||
|
||||
import { request } from '@/utils'
|
||||
import type { RequestConfig } from '~/types/axios'
|
||||
|
||||
export default {
|
||||
// 创建文件/文件夹
|
||||
@@ -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 }),
|
||||
|
||||
@@ -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'
|
||||
@@ -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> = [
|
||||
@@ -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 = () => {
|
||||
@@ -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
|
||||
|
||||
@@ -83,6 +83,10 @@ const handleMove = () => {
|
||||
window.$message.success('标记成功,请前往目标路径粘贴')
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
marked.value = []
|
||||
}
|
||||
|
||||
const handlePaste = async () => {
|
||||
if (!marked.value.length) {
|
||||
window.$message.error('请先标记需要复制或移动的文件/文件夹')
|
||||
@@ -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('请选择要删除的文件/文件夹')
|
||||
|
||||
Reference in New Issue
Block a user