完善商务模块重命名功能,修复文件上传bug
This commit is contained in:
parent
e9d68d7ae3
commit
53a81f0b01
|
@ -58,7 +58,8 @@ export function getFilesApi(params?: FileListParams) {
|
|||
params: {
|
||||
page: params?.page || 1,
|
||||
pageSize: params?.pageSize || 10,
|
||||
folderId: params?.folderId || '0'
|
||||
folderId: params?.folderId || '0',
|
||||
fileName: params?.fileName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -167,8 +168,19 @@ export function previewFileApi(fileId: string) {
|
|||
})
|
||||
}
|
||||
|
||||
// 重命名文件(后端没有提供重命名接口,需要先删除再上传)
|
||||
// 重命名文件
|
||||
export function renameFileApi(fileId: string, newFileName: string) {
|
||||
return request({
|
||||
url: '/businessData/file/rename',
|
||||
method: 'put',
|
||||
params: {
|
||||
fileId: fileId,
|
||||
newFileName: newFileName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 重命名文件(兼容旧接口)
|
||||
export function updateFileNameApi(fileId: string, data: RenameFileParams) {
|
||||
// 注意:后端没有提供文件重命名接口,这里返回一个Promise.reject
|
||||
return Promise.reject(new Error('后端暂不支持文件重命名功能'))
|
||||
return renameFileApi(fileId, data.newFileName)
|
||||
}
|
|
@ -30,6 +30,7 @@ export interface FileListParams {
|
|||
page?: number
|
||||
pageSize?: number
|
||||
folderId?: string
|
||||
fileName?: string
|
||||
}
|
||||
|
||||
/** 文件夹列表响应 */
|
||||
|
@ -91,5 +92,5 @@ export interface PreviewFileParams {
|
|||
/** 重命名文件请求参数 */
|
||||
export interface RenameFileParams {
|
||||
fileId: string
|
||||
newName: string
|
||||
newFileName: string
|
||||
}
|
|
@ -158,6 +158,20 @@
|
|||
<a-layout-content class="file-content">
|
||||
<a-card :bordered="false" class="file-card">
|
||||
<a-descriptions :title="`文件列表 (${fileList.length})`" v-if="currentFolderId" />
|
||||
|
||||
<!-- 文件搜索功能 -->
|
||||
<div v-if="currentFolderId" class="file-search-container">
|
||||
<a-input-search
|
||||
v-model="fileSearchKeyword"
|
||||
placeholder="搜索文件名..."
|
||||
class="file-search-input"
|
||||
@search="handleFileSearch"
|
||||
@input="handleFileSearchInput"
|
||||
@clear="handleFileSearchClear"
|
||||
allow-clear
|
||||
/>
|
||||
</div>
|
||||
|
||||
<a-divider size="small" v-if="currentFolderId" />
|
||||
|
||||
<template v-if="!currentFolderId">
|
||||
|
@ -303,6 +317,21 @@
|
|||
</a-row>
|
||||
</div>
|
||||
|
||||
<!-- 文件分页 -->
|
||||
<div v-if="currentFolderId && !loading && totalFiles > 0" class="file-pagination">
|
||||
<a-pagination
|
||||
:total="totalFiles"
|
||||
:current="fileCurrentPage"
|
||||
:page-size="filePageSize"
|
||||
:show-total="true"
|
||||
:show-page-size="true"
|
||||
:page-size-options="[10, 20, 50, 100]"
|
||||
:show-jumper="true"
|
||||
@change="handleFilePageChange"
|
||||
@page-size-change="handleFilePageSizeChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<a-empty
|
||||
v-if="!loading && currentFolderId && fileList.length === 0"
|
||||
|
@ -384,7 +413,6 @@
|
|||
:show-file-list="false"
|
||||
@change="handleFileChange"
|
||||
:accept="allowedFileTypes"
|
||||
multiple
|
||||
>
|
||||
<a-button type="primary" class="upload-btn">
|
||||
<icon-upload />
|
||||
|
@ -499,6 +527,26 @@
|
|||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<!-- 重命名文件对话框 -->
|
||||
<a-modal
|
||||
v-model:visible="renameFileModalVisible"
|
||||
title="重命名文件"
|
||||
width="520px"
|
||||
@ok="confirmRenameFile"
|
||||
@cancel="renameFileModalVisible = false"
|
||||
>
|
||||
<a-form layout="vertical">
|
||||
<a-form-item label="新文件名">
|
||||
<a-input
|
||||
v-model="renameFileForm.newName"
|
||||
placeholder="请输入新的文件名称(不含扩展名)"
|
||||
max-length="100"
|
||||
@keyup.enter="confirmRenameFile"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-layout>
|
||||
</template>
|
||||
|
||||
|
@ -534,6 +582,7 @@ import {
|
|||
downloadFileApi,
|
||||
uploadFileApi,
|
||||
updateFileNameApi,
|
||||
renameFileApi,
|
||||
previewFileApi
|
||||
} from '@/apis/bussiness'
|
||||
|
||||
|
@ -614,7 +663,8 @@ const canUpload = computed(() => {
|
|||
});
|
||||
|
||||
// 搜索相关
|
||||
const searchKeyword = ref('');
|
||||
const searchKeyword = ref(''); // 文件夹搜索关键词
|
||||
const fileSearchKeyword = ref(''); // 文件搜索关键词
|
||||
const searchTimeout = ref(null);
|
||||
|
||||
// 初始化文件夹数据
|
||||
|
@ -735,13 +785,61 @@ const handleSearchClear = () => {
|
|||
initData();
|
||||
};
|
||||
|
||||
// 文件搜索相关函数
|
||||
const handleFileSearch = () => {
|
||||
console.log('=== 执行文件搜索 ===');
|
||||
console.log('文件搜索关键词:', fileSearchKeyword.value);
|
||||
// 重置到第一页并搜索
|
||||
fileCurrentPage.value = 1;
|
||||
console.log('重置文件页码为:', fileCurrentPage.value);
|
||||
if (currentFolderId.value) {
|
||||
loadFiles(currentFolderId.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileSearchInput = (value) => {
|
||||
console.log('=== 文件搜索输入 ===');
|
||||
console.log('输入值:', value);
|
||||
fileSearchKeyword.value = value;
|
||||
console.log('设置文件搜索关键词为:', fileSearchKeyword.value);
|
||||
// 防抖搜索:300ms后自动搜索
|
||||
if (searchTimeout.value) {
|
||||
clearTimeout(searchTimeout.value);
|
||||
console.log('清除之前的文件搜索定时器');
|
||||
}
|
||||
searchTimeout.value = setTimeout(() => {
|
||||
console.log('=== 防抖文件搜索执行 ===');
|
||||
fileCurrentPage.value = 1;
|
||||
console.log('重置文件页码为:', fileCurrentPage.value);
|
||||
if (currentFolderId.value) {
|
||||
loadFiles(currentFolderId.value);
|
||||
}
|
||||
}, 300);
|
||||
};
|
||||
|
||||
const handleFileSearchClear = () => {
|
||||
console.log('=== 清除文件搜索 ===');
|
||||
fileSearchKeyword.value = '';
|
||||
console.log('清空文件搜索关键词');
|
||||
if (searchTimeout.value) {
|
||||
clearTimeout(searchTimeout.value);
|
||||
console.log('清除文件搜索定时器');
|
||||
}
|
||||
fileCurrentPage.value = 1;
|
||||
console.log('重置文件页码为:', fileCurrentPage.value);
|
||||
if (currentFolderId.value) {
|
||||
loadFiles(currentFolderId.value);
|
||||
}
|
||||
};
|
||||
|
||||
const loadFiles = async (folderId) => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await getFilesApi({
|
||||
folderId: folderId,
|
||||
page: fileCurrentPage.value,
|
||||
pageSize: filePageSize.value
|
||||
pageSize: filePageSize.value,
|
||||
fileName: fileSearchKeyword.value || undefined
|
||||
});
|
||||
|
||||
// 根据后端返回的数据结构处理
|
||||
|
@ -777,6 +875,8 @@ const handleFolderClick = (folderId) => {
|
|||
const id = String(folderId);
|
||||
if (currentFolderId.value !== id) {
|
||||
fileCurrentPage.value = 1;
|
||||
// 切换文件夹时清空文件搜索关键词
|
||||
fileSearchKeyword.value = '';
|
||||
}
|
||||
currentFolderId.value = id;
|
||||
};
|
||||
|
@ -790,6 +890,14 @@ const renameForm = reactive({
|
|||
isRoot: false
|
||||
});
|
||||
|
||||
// 重命名文件对话框状态
|
||||
const renameFileModalVisible = ref(false);
|
||||
const renameFileForm = reactive({
|
||||
fileId: '',
|
||||
newName: '',
|
||||
fileExtension: ''
|
||||
});
|
||||
|
||||
// 文件夹重命名处理函数
|
||||
const handleRenameFolder = (folder, folderId, currentName) => {
|
||||
console.log('handleRenameFolder 被调用:', { folder, folderId, currentName });
|
||||
|
@ -971,7 +1079,21 @@ const handleFileChange = (info) => {
|
|||
console.log('文件列表:', fileList);
|
||||
console.log('文件列表长度:', fileList.length);
|
||||
|
||||
// 处理新选择的文件
|
||||
// 每次选择文件时,强制清空所有状态
|
||||
fileListTemp.value = [];
|
||||
console.log('已清空之前的文件列表');
|
||||
|
||||
// 强制重置上传组件状态
|
||||
if (uploadRef.value) {
|
||||
try {
|
||||
uploadRef.value.reset();
|
||||
console.log('已强制重置上传组件');
|
||||
} catch (error) {
|
||||
console.log('重置上传组件时出错:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理新选择的文件 - 只处理当前选择的文件
|
||||
fileList.forEach((file, index) => {
|
||||
console.log(`处理第${index + 1}个文件:`, file);
|
||||
console.log('文件名称:', file.name);
|
||||
|
@ -990,35 +1112,22 @@ const handleFileChange = (info) => {
|
|||
originFileObj: file.file || file // 保存原始File对象
|
||||
};
|
||||
|
||||
// 只处理新选择的文件,避免重复添加
|
||||
if (!fileListTemp.value.find(f => f.uid === fileObj.uid)) {
|
||||
console.log('这是新文件,开始验证...');
|
||||
|
||||
// 验证文件
|
||||
const isValid = validateFile(fileObj);
|
||||
console.log('文件验证结果:', isValid);
|
||||
|
||||
if (isValid) {
|
||||
fileListTemp.value.push(fileObj);
|
||||
console.log('✅ 成功添加文件到列表:', fileObj.name);
|
||||
} else {
|
||||
console.log('❌ 文件验证失败:', fileObj.name, '错误:', fileObj.error);
|
||||
}
|
||||
console.log('开始验证新文件...');
|
||||
|
||||
// 验证文件
|
||||
const isValid = validateFile(fileObj);
|
||||
console.log('文件验证结果:', isValid);
|
||||
|
||||
if (isValid) {
|
||||
// 确保只添加当前选择的文件
|
||||
fileListTemp.value = [fileObj]; // 只保留当前文件
|
||||
console.log('✅ 成功设置文件到列表:', fileObj.name);
|
||||
} else {
|
||||
console.log('文件已存在,跳过:', fileObj.name);
|
||||
console.log('❌ 文件验证失败:', fileObj.name, '错误:', fileObj.error);
|
||||
}
|
||||
});
|
||||
|
||||
// 清理已移除的文件
|
||||
const beforeCleanCount = fileListTemp.value.length;
|
||||
fileListTemp.value = fileListTemp.value.filter(file =>
|
||||
fileList.some(f => f.uid === file.uid)
|
||||
);
|
||||
const afterCleanCount = fileListTemp.value.length;
|
||||
|
||||
if (beforeCleanCount !== afterCleanCount) {
|
||||
console.log(`清理了 ${beforeCleanCount - afterCleanCount} 个已移除的文件`);
|
||||
}
|
||||
// 文件列表已在上方清空并重新填充,无需额外清理
|
||||
|
||||
console.log('=== 当前文件列表状态 ===');
|
||||
console.log('fileListTemp长度:', fileListTemp.value.length);
|
||||
|
@ -1171,42 +1280,47 @@ const handleUploadSubmit = async () => {
|
|||
fileItem.error = result.msg || '上传失败';
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据结果显示相应的消息
|
||||
if (hasFileExists && !hasError) {
|
||||
Message.warning('文件已存在');
|
||||
} else if (hasError) {
|
||||
Message.error('上传失败');
|
||||
} else {
|
||||
Message.success('上传成功');
|
||||
// 刷新当前文件夹文件列表
|
||||
if (currentFolderId.value === uploadForm.folderId) {
|
||||
loadFiles(currentFolderId.value);
|
||||
}
|
||||
}
|
||||
|
||||
resetUpload();
|
||||
}
|
||||
|
||||
uploading.value = false;
|
||||
// 根据结果显示相应的消息
|
||||
if (hasFileExists && !hasError) {
|
||||
Message.warning('文件已存在');
|
||||
} else if (hasError) {
|
||||
Message.error('上传失败');
|
||||
} else {
|
||||
Message.success('上传成功');
|
||||
// 刷新当前文件夹文件列表
|
||||
if (currentFolderId.value === uploadForm.folderId) {
|
||||
loadFiles(currentFolderId.value);
|
||||
}
|
||||
}
|
||||
|
||||
resetUpload();
|
||||
};
|
||||
|
||||
// 重置上传表单
|
||||
const resetUpload = () => {
|
||||
console.log('=== 重置上传表单 ===');
|
||||
|
||||
// 取消所有正在进行的上传
|
||||
Object.values(cancelTokens.value).forEach(source => {
|
||||
source.cancel('上传已取消');
|
||||
});
|
||||
|
||||
// 重置所有状态
|
||||
uploadDialogVisible.value = false;
|
||||
uploadForm.folderId = currentFolderId.value || '';
|
||||
fileListTemp.value = [];
|
||||
cancelTokens.value = {};
|
||||
uploading.value = false;
|
||||
|
||||
// 清空上传组件
|
||||
if (uploadRef.value) {
|
||||
uploadRef.value.reset();
|
||||
console.log('已重置上传组件');
|
||||
}
|
||||
|
||||
console.log('上传表单重置完成');
|
||||
};
|
||||
|
||||
// 预览文件
|
||||
|
@ -1261,11 +1375,87 @@ const handleDownload = async (file) => {
|
|||
|
||||
// 重命名文件
|
||||
const handleEditFile = (file) => {
|
||||
Modal.warning({
|
||||
title: '功能提示',
|
||||
content: '后端暂不支持文件重命名功能,如需重命名请先删除文件再重新上传。',
|
||||
okText: '知道了'
|
||||
console.log('=== 重命名文件函数被调用 ===');
|
||||
console.log('重命名文件 - 文件对象:', file);
|
||||
console.log('文件对象的所有属性:', Object.keys(file));
|
||||
console.log('文件属性详情:', {
|
||||
fileId: file.fileId,
|
||||
fileName: file.fileName,
|
||||
name: file.name,
|
||||
originalName: file.originalName,
|
||||
displayName: file.displayName,
|
||||
title: file.title
|
||||
});
|
||||
|
||||
// 尝试多种可能的文件名字段
|
||||
let fileName = '';
|
||||
if (file.fileName) {
|
||||
fileName = file.fileName;
|
||||
console.log('使用 fileName 字段:', fileName);
|
||||
} else if (file.name) {
|
||||
fileName = file.name;
|
||||
console.log('使用 name 字段:', fileName);
|
||||
} else if (file.originalName) {
|
||||
fileName = file.originalName;
|
||||
console.log('使用 originalName 字段:', fileName);
|
||||
} else if (file.displayName) {
|
||||
fileName = file.displayName;
|
||||
console.log('使用 displayName 字段:', fileName);
|
||||
} else if (file.title) {
|
||||
fileName = file.title;
|
||||
console.log('使用 title 字段:', fileName);
|
||||
}
|
||||
|
||||
console.log('最终获取到的文件名:', fileName);
|
||||
|
||||
if (!fileName) {
|
||||
console.error('无法获取文件名,文件对象:', file);
|
||||
Message.error('无法获取文件名,请检查文件数据');
|
||||
return;
|
||||
}
|
||||
|
||||
const fileExtension = getFileExtension(fileName);
|
||||
const fileNameWithoutExtension = fileExtension ? fileName.substring(0, fileName.lastIndexOf('.')) : fileName;
|
||||
|
||||
console.log('处理后的文件名信息:', {
|
||||
originalName: fileName,
|
||||
extension: fileExtension,
|
||||
nameWithoutExtension: fileNameWithoutExtension
|
||||
});
|
||||
|
||||
// 设置重命名表单数据
|
||||
renameFileForm.fileId = file.fileId;
|
||||
renameFileForm.newName = fileNameWithoutExtension;
|
||||
renameFileForm.fileExtension = fileExtension;
|
||||
|
||||
console.log('设置的重命名表单数据:', renameFileForm);
|
||||
|
||||
// 显示重命名弹窗
|
||||
renameFileModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 确认重命名文件
|
||||
const confirmRenameFile = async () => {
|
||||
if (!renameFileForm.newName.trim()) {
|
||||
Message.warning('请输入文件名称');
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用用户输入的文件名,不添加任何扩展名
|
||||
const newFileName = renameFileForm.newName.trim();
|
||||
|
||||
try {
|
||||
await renameFileApi(renameFileForm.fileId, newFileName);
|
||||
Message.success('文件重命名成功');
|
||||
renameFileModalVisible.value = false;
|
||||
// 刷新当前文件夹的文件列表
|
||||
if (currentFolderId.value) {
|
||||
loadFiles(currentFolderId.value);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('重命名文件失败:', error);
|
||||
Message.error('重命名失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 删除文件夹
|
||||
|
@ -2330,5 +2520,64 @@ onMounted(() => {
|
|||
100% { transform: translateX(100%); }
|
||||
}
|
||||
|
||||
/* 文件搜索样式 */
|
||||
.file-search-container {
|
||||
margin: 16px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.file-search-input {
|
||||
max-width: 300px;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:focus-within {
|
||||
box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 文件分页样式 */
|
||||
.file-pagination {
|
||||
margin-top: 24px;
|
||||
padding: 16px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-top: 1px solid var(--color-border);
|
||||
background: var(--color-bg-1);
|
||||
|
||||
.arco-pagination {
|
||||
.arco-pagination-total {
|
||||
color: var(--color-text-2);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.arco-pagination-item {
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
&.arco-pagination-item-active {
|
||||
background: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.arco-pagination-prev,
|
||||
.arco-pagination-next {
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue