feat(files): 移除文件管理下载入口
去掉行内与右键下载;大文件提示改为使用终端。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
# 文件管理移除下载入口
|
||||||
|
|
||||||
|
**日期**: 2026-06-12
|
||||||
|
|
||||||
|
## 变更摘要
|
||||||
|
|
||||||
|
移除文件管理页行内「下载」按钮与右键菜单项;大文件提示改为仅建议使用终端。
|
||||||
|
|
||||||
|
## 动机
|
||||||
|
|
||||||
|
产品决策:文件管理不提供浏览器下载,避免大文件与 SFTP 流式链路问题。
|
||||||
|
|
||||||
|
## 涉及文件
|
||||||
|
|
||||||
|
- `frontend/src/components/files/FilesList.vue`
|
||||||
|
- `frontend/src/composables/files/useFilesActions.ts`
|
||||||
|
- `frontend/src/composables/files/useFilesPage.ts`
|
||||||
|
- `frontend/src/composables/files/useFilesEditor.ts`
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
`npm run type-check`;文件页无下载按钮;右键菜单无下载项。
|
||||||
@@ -113,16 +113,6 @@ const p = useFilesPageContext()
|
|||||||
>
|
>
|
||||||
查看
|
查看
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
|
||||||
v-if="p.isRegularFile(item)"
|
|
||||||
variant="text"
|
|
||||||
size="x-small"
|
|
||||||
density="compact"
|
|
||||||
:loading="p.actionLoading"
|
|
||||||
@click.stop="p.downloadFile(item)"
|
|
||||||
>
|
|
||||||
下载
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
<v-btn
|
||||||
variant="text"
|
variant="text"
|
||||||
size="x-small"
|
size="x-small"
|
||||||
@@ -173,13 +163,6 @@ const p = useFilesPageContext()
|
|||||||
>
|
>
|
||||||
<v-list-item-title>查看</v-list-item-title>
|
<v-list-item-title>查看</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item
|
|
||||||
v-if="p.contextFile && p.isRegularFile(p.contextFile)"
|
|
||||||
prepend-icon="mdi-download"
|
|
||||||
@click="p.contextAction('download')"
|
|
||||||
>
|
|
||||||
<v-list-item-title>下载</v-list-item-title>
|
|
||||||
</v-list-item>
|
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-if="p.contextFile"
|
v-if="p.contextFile"
|
||||||
prepend-icon="mdi-content-copy"
|
prepend-icon="mdi-content-copy"
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { useSnackbar } from '@/composables/useSnackbar'
|
|||||||
import { useFilesStore } from '@/stores/files'
|
import { useFilesStore } from '@/stores/files'
|
||||||
import type { FileEntry } from '@/types/api'
|
import type { FileEntry } from '@/types/api'
|
||||||
import { isArchiveFile } from '@/utils/fileSort'
|
import { isArchiveFile } from '@/utils/fileSort'
|
||||||
import { saveBlobAsFile } from '@/utils/fileDownload'
|
|
||||||
import { invalidateCachedFile } from '@/utils/filePreload'
|
import { invalidateCachedFile } from '@/utils/filePreload'
|
||||||
import {
|
import {
|
||||||
joinRemotePath,
|
joinRemotePath,
|
||||||
@@ -172,9 +171,6 @@ export function useFilesActions(options: {
|
|||||||
case 'preview':
|
case 'preview':
|
||||||
void options.previewFile(item)
|
void options.previewFile(item)
|
||||||
break
|
break
|
||||||
case 'download':
|
|
||||||
void downloadFile(item)
|
|
||||||
break
|
|
||||||
case 'copyPath':
|
case 'copyPath':
|
||||||
void copyRemotePath(item)
|
void copyRemotePath(item)
|
||||||
break
|
break
|
||||||
@@ -414,25 +410,6 @@ export function useFilesActions(options: {
|
|||||||
else snackbar(`删除完成:成功 ${ok},失败 ${fail}`, fail > 0 ? 'warning' : 'success')
|
else snackbar(`删除完成:成功 ${ok},失败 ${fail}`, fail > 0 ? 'warning' : 'success')
|
||||||
}
|
}
|
||||||
|
|
||||||
async function downloadFile(item: FileEntry) {
|
|
||||||
if (!selectedServer.value) return
|
|
||||||
actionLoading.value = true
|
|
||||||
try {
|
|
||||||
const remotePath = joinRemotePath(currentPath.value, item.name)
|
|
||||||
const { blob, filename } = await http.download('/sync/download', {
|
|
||||||
server_id: selectedServer.value,
|
|
||||||
path: remotePath,
|
|
||||||
})
|
|
||||||
saveBlobAsFile(blob, filename)
|
|
||||||
snackbar(`已下载 ${filename}`)
|
|
||||||
} catch (e: unknown) {
|
|
||||||
const msg = e instanceof Error ? e.message : '下载失败'
|
|
||||||
snackbar(msg, 'error')
|
|
||||||
} finally {
|
|
||||||
actionLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function confirmDeleteFile(item: FileEntry) {
|
async function confirmDeleteFile(item: FileEntry) {
|
||||||
deletingFile.value = item
|
deletingFile.value = item
|
||||||
showFileDelete.value = true
|
showFileDelete.value = true
|
||||||
@@ -608,7 +585,6 @@ export function useFilesActions(options: {
|
|||||||
startChmod,
|
startChmod,
|
||||||
doChmod,
|
doChmod,
|
||||||
batchDelete,
|
batchDelete,
|
||||||
downloadFile,
|
|
||||||
confirmDeleteFile,
|
confirmDeleteFile,
|
||||||
doDeleteFile,
|
doDeleteFile,
|
||||||
doMkdir,
|
doMkdir,
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export function useFilesEditor(options: {
|
|||||||
function rejectOversizedFile(item: FileEntry, action: '编辑' | '查看'): boolean {
|
function rejectOversizedFile(item: FileEntry, action: '编辑' | '查看'): boolean {
|
||||||
if (exceedsEditorMaxSize(item.size)) {
|
if (exceedsEditorMaxSize(item.size)) {
|
||||||
snackbar(
|
snackbar(
|
||||||
`文件超过 2MB(${formatSize(item.size)}),无法${action},请下载或使用终端`,
|
`文件超过 2MB(${formatSize(item.size)}),无法${action},请使用终端`,
|
||||||
'warning',
|
'warning',
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ export function useFilesPage() {
|
|||||||
{ title: '归属', key: 'owner', width: 110, sortable: false },
|
{ title: '归属', key: 'owner', width: 110, sortable: false },
|
||||||
{ title: '大小', key: 'size', width: 120 },
|
{ title: '大小', key: 'size', width: 120 },
|
||||||
{ title: '修改时间', key: 'modified', width: 180 },
|
{ title: '修改时间', key: 'modified', width: 180 },
|
||||||
{ title: '操作', key: 'actions', width: 200, sortable: false, align: 'end' as const },
|
{ title: '操作', key: 'actions', width: 160, sortable: false, align: 'end' as const },
|
||||||
]
|
]
|
||||||
|
|
||||||
useFilesHotkeys(
|
useFilesHotkeys(
|
||||||
@@ -268,7 +268,6 @@ export function useFilesPage() {
|
|||||||
pasteClipboard: actions.pasteClipboard,
|
pasteClipboard: actions.pasteClipboard,
|
||||||
editFile: editor.editFile,
|
editFile: editor.editFile,
|
||||||
previewFile: editor.previewFile,
|
previewFile: editor.previewFile,
|
||||||
downloadFile: actions.downloadFile,
|
|
||||||
confirmDeleteFile: actions.confirmDeleteFile,
|
confirmDeleteFile: actions.confirmDeleteFile,
|
||||||
openInTerminal: nav.openInTerminal,
|
openInTerminal: nav.openInTerminal,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user