update
This commit is contained in:
@@ -435,7 +435,7 @@ const handlePaste = () => {
|
|||||||
const triggerFileUpload = () => { fileInputRef.value?.click(); };
|
const triggerFileUpload = () => { fileInputRef.value?.click(); };
|
||||||
|
|
||||||
// --- 下载触发器 (定义在此处,供 Composable 使用) ---
|
// --- 下载触发器 (定义在此处,供 Composable 使用) ---
|
||||||
const triggerDownload = (item: FileListItem) => { // item 已有类型
|
const triggerDownload = (items: FileListItem[]) => { // 修改:接受 FileListItem 数组
|
||||||
// 恢复使用 props.wsDeps.isConnected
|
// 恢复使用 props.wsDeps.isConnected
|
||||||
if (!props.wsDeps.isConnected.value) {
|
if (!props.wsDeps.isConnected.value) {
|
||||||
alert(t('fileManager.errors.notConnected'));
|
alert(t('fileManager.errors.notConnected'));
|
||||||
@@ -455,15 +455,30 @@ const triggerDownload = (item: FileListItem) => { // item 已有类型
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadPath = currentSftpManager.value.joinPath(currentSftpManager.value.currentPath.value, item.filename);
|
// 遍历数组中的每个文件项
|
||||||
const downloadUrl = `/api/v1/sftp/download?connectionId=${currentConnectionId}&remotePath=${encodeURIComponent(downloadPath)}`;
|
items.forEach(item => {
|
||||||
console.log(`[FileManager ${props.sessionId}-${props.instanceId}] Triggering download: ${downloadUrl}`);
|
// 确保只下载文件
|
||||||
const link = document.createElement('a');
|
if (!item.attrs.isFile) {
|
||||||
link.href = downloadUrl;
|
console.warn(`[FileManager ${props.sessionId}-${props.instanceId}] Skipping download for non-file item: ${item.filename}`);
|
||||||
link.setAttribute('download', item.filename);
|
return;
|
||||||
document.body.appendChild(link);
|
}
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
const downloadPath = currentSftpManager.value!.joinPath(currentSftpManager.value!.currentPath.value, item.filename);
|
||||||
|
const downloadUrl = `/api/v1/sftp/download?connectionId=${currentConnectionId}&remotePath=${encodeURIComponent(downloadPath)}`;
|
||||||
|
console.log(`[FileManager ${props.sessionId}-${props.instanceId}] Triggering download for ${item.filename}: ${downloadUrl}`);
|
||||||
|
|
||||||
|
// 为每个文件创建一个链接并点击
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = downloadUrl;
|
||||||
|
link.setAttribute('download', item.filename); // 使用原始文件名
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
// 稍微延迟移除链接,以确保下载开始
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export interface UseFileManagerContextMenuOptions {
|
|||||||
// --- 回调函数 ---
|
// --- 回调函数 ---
|
||||||
onRefresh: () => void;
|
onRefresh: () => void;
|
||||||
onUpload: () => void;
|
onUpload: () => void;
|
||||||
onDownload: (item: FileListItem) => void;
|
onDownload: (items: FileListItem[]) => void; // 修改:接受 FileListItem 数组
|
||||||
onDelete: () => void; // 删除操作现在由外部处理
|
onDelete: () => void; // 删除操作现在由外部处理
|
||||||
onRename: (item: FileListItem) => void;
|
onRename: (item: FileListItem) => void;
|
||||||
onChangePermissions: (item: FileListItem) => void;
|
onChangePermissions: (item: FileListItem) => void;
|
||||||
@@ -97,22 +97,37 @@ export function useFileManagerContextMenu(options: UseFileManagerContextMenuOpti
|
|||||||
// Build context menu items (使用传入的回调)
|
// Build context menu items (使用传入的回调)
|
||||||
if (selectionSize > 1 && clickedItemIsSelected) {
|
if (selectionSize > 1 && clickedItemIsSelected) {
|
||||||
// Multi-selection menu
|
// Multi-selection menu
|
||||||
|
const selectedFileItems = Array.from(selectedItems.value)
|
||||||
|
.map(filename => fileList.value.find(f => f.filename === filename))
|
||||||
|
.filter((item): item is FileListItem => !!item); // 过滤掉未找到的项并确保类型
|
||||||
|
|
||||||
|
const allFilesSelected = selectedFileItems.length === selectionSize && selectedFileItems.every(item => item.attrs.isFile);
|
||||||
|
|
||||||
menu = [
|
menu = [
|
||||||
// 调整顺序:剪切、复制优先
|
// 调整顺序:剪切、复制优先
|
||||||
{ label: t('fileManager.actions.cut'), action: onCut, disabled: !canPerformActions },
|
{ label: t('fileManager.actions.cut'), action: onCut, disabled: !canPerformActions },
|
||||||
{ label: t('fileManager.actions.copy'), action: onCopy, disabled: !canPerformActions },
|
{ label: t('fileManager.actions.copy'), action: onCopy, disabled: !canPerformActions },
|
||||||
// --- 分隔符 (视觉) ---
|
];
|
||||||
|
|
||||||
|
// --- 新增:多选下载 ---
|
||||||
|
if (allFilesSelected) {
|
||||||
|
menu.push({ label: t('fileManager.actions.downloadMultiple', { count: selectionSize }), action: () => onDownload(selectedFileItems), disabled: !canPerformActions });
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.push(
|
||||||
|
// --- 分隔符 (视觉) ---
|
||||||
{ label: t('fileManager.actions.deleteMultiple', { count: selectionSize }), action: onDelete, disabled: !canPerformActions },
|
{ label: t('fileManager.actions.deleteMultiple', { count: selectionSize }), action: onDelete, disabled: !canPerformActions },
|
||||||
// --- 分隔符 (视觉) ---
|
// --- 分隔符 (视觉) ---
|
||||||
{ label: t('fileManager.actions.refresh'), action: onRefresh, disabled: !canPerformActions },
|
{ label: t('fileManager.actions.refresh'), action: onRefresh, disabled: !canPerformActions }
|
||||||
];
|
);
|
||||||
} else if (targetItem && targetItem.filename !== '..') {
|
} else if (targetItem && targetItem.filename !== '..') {
|
||||||
// Single item (not '..') menu
|
// Single item (not '..') menu
|
||||||
|
// --- 修改:单选下载也调用接收数组的回调 ---
|
||||||
menu = [];
|
menu = [];
|
||||||
|
|
||||||
// 1. 主要操作 (下载 - 如果是文件)
|
// 1. 主要操作 (下载 - 如果是文件)
|
||||||
if (targetItem.attrs.isFile) {
|
if (targetItem.attrs.isFile) {
|
||||||
menu.push({ label: t('fileManager.actions.download', { name: targetItem.filename }), action: () => onDownload(targetItem), disabled: !canPerformActions });
|
menu.push({ label: t('fileManager.actions.download', { name: targetItem.filename }), action: () => onDownload([targetItem]), disabled: !canPerformActions }); // 传递包含单个项的数组
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 剪切、复制、粘贴 (粘贴 - 如果是文件夹)
|
// 2. 剪切、复制、粘贴 (粘贴 - 如果是文件夹)
|
||||||
|
|||||||
@@ -250,6 +250,7 @@
|
|||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"deleteMultiple": "Delete {count} items",
|
"deleteMultiple": "Delete {count} items",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
|
"downloadMultiple": "Download {count} items",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"closeTab": "Close Tab",
|
"closeTab": "Close Tab",
|
||||||
|
|||||||
@@ -250,6 +250,7 @@
|
|||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
"deleteMultiple": "删除 {count} 个项目",
|
"deleteMultiple": "删除 {count} 个项目",
|
||||||
"download": "下载",
|
"download": "下载",
|
||||||
|
"downloadMultiple": "下载 {count} 个项目",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
"closeTab": "关闭标签页",
|
"closeTab": "关闭标签页",
|
||||||
|
|||||||
Reference in New Issue
Block a user