You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.9 KiB
5.9 KiB
编辑任务时附件显示问题修复说明
问题现象
用户反馈:上传文件显示成功,但是编辑任务时没有附件显示。
问题分析
1. 原始代码问题
在原始的 editTask 函数中:
const editTask = (task: any) => {
editingTask.value = task
Object.assign(taskForm, task) // 只复制了基本任务信息
showCreateDialog.value = true
}
问题:
- 没有加载任务的附件列表
- 没有将附件数据转换为前端显示格式
- 编辑时会重复添加已有附件
2. 数据流分析
编辑任务时需要的数据流:
- 获取任务基本信息
- 调用
getTaskAttachmentsAPI 获取附件列表 - 将附件数据转换为
taskForm.attachments格式 - 将附件数据转换为
fileList格式用于UI显示 - 区分已有附件和新上传附件
修复方案
1. 修复 editTask 函数
const editTask = async (task: any) => {
editingTask.value = task
Object.assign(taskForm, task)
// 清空之前的附件数据
taskForm.attachments = []
fileList.value = []
// 如果任务有附件,加载附件列表
if (task.id) {
try {
const response: any = await taskApi.getTaskAttachments(task.id)
if (response.code === 200 && response.data && response.data.length > 0) {
// 将附件数据转换为taskForm.attachments格式(保留ID)
taskForm.attachments = response.data.map((attachment: any) => ({
id: attachment.id, // ✓ 保留ID用于区分已有附件
file_name: attachment.file_name,
file_path: attachment.file_path,
file_size: attachment.file_size,
file_type: attachment.file_type
}))
// 将附件数据转换为fileList格式,用于前端显示
fileList.value = response.data.map((attachment: any) => ({
name: attachment.file_name,
url: attachment.file_path,
size: attachment.file_size,
status: 'success',
uid: attachment.id, // ✓ 使用附件ID作为uid
response: {
data: {
filename: attachment.file_name,
filepath: attachment.file_path,
size: attachment.file_size,
mime_type: attachment.file_type
}
}
}))
}
} catch (error) {
console.error('Failed to load task attachments:', error)
ElMessage.warning('加载任务附件失败')
}
}
showCreateDialog.value = true
}
2. 修复保存逻辑,区分新附件和已有附件
// 处理附件关联
if (editingTask.value) {
// 编辑模式:只添加新上传的附件
const newAttachments = taskForm.attachments.filter((attachment: any) => !attachment.id)
if (newAttachments.length > 0) {
// 只处理新上传的附件
for (const attachment of newAttachments) {
await taskApi.addTaskAttachment(taskId, attachment)
}
}
} else {
// 创建模式:添加所有附件
for (const attachment of taskForm.attachments) {
await taskApi.addTaskAttachment(taskId, attachment)
}
}
3. 修复新上传文件处理
const handleUploadSuccess = (response: any, file: any, fileList: any[]) => {
// 新上传的文件不设置id,用于区分已有附件
const attachmentData = {
file_name: response.data.filename || file.name,
file_path: response.data.filepath || response.data.path || '',
file_size: response.data.size || file.size || 0,
file_type: response.data.mime_type || file.type || '',
// 注意:不设置id,表示这是新上传的文件
}
taskForm.attachments.push(attachmentData)
}
4. 增强文件删除处理
const handleFileRemove = async (file: any, fileList: any[]) => {
const index = taskForm.attachments.findIndex((attachment: any) => {
// 对于新上传的文件,匹配文件名
if (!attachment.id) {
const uploadedFileName = file.response?.data?.filename || file.name
return attachment.file_name === uploadedFileName
}
// 对于已有的附件,匹配uid(实际上是attachment.id)
return attachment.id === file.uid
})
if (index > -1) {
const attachment = taskForm.attachments[index]
// 如果是已有的附件(有id),需要调用删除API
if (attachment.id) {
try {
await taskApi.deleteAttachment(attachment.id)
ElMessage.success(`附件 "${attachment.file_name}" 删除成功`)
} catch (error) {
ElMessage.error(`删除附件 "${attachment.file_name}" 失败`)
return // 删除失败,不从列表中移除
}
}
taskForm.attachments.splice(index, 1)
}
}
关键改进点
1. 数据结构设计
- 已有附件:包含
id属性,从服务器加载 - 新上传附件:不包含
id属性,通过上传获得
2. UI显示
fileList.value用于 el-upload 组件显示taskForm.attachments用于业务逻辑处理- 两者保持同步更新
3. API调用优化
- 编辑时只对新附件调用
addTaskAttachment - 删除已有附件时调用
deleteAttachment - 避免重复添加已有附件
4. 错误处理
- 附件加载失败时给出提示但不阻止编辑
- 附件删除失败时不从UI中移除
- 详细的调试日志便于问题排查
测试验证
1. 编辑任务显示附件
- 创建一个带附件的任务
- 编辑该任务
- 确认附件正确显示在上传组件中
2. 编辑时添加新附件
- 编辑已有任务
- 添加新附件
- 保存确认只添加新附件,不重复添加已有附件
3. 编辑时删除附件
- 编辑有附件的任务
- 删除已有附件
- 确认附件从服务器删除
- 删除新添加的附件
- 确认只从UI中移除,不调用删除API
预期结果
修复后,编辑任务时: ✅ 正确显示已有附件 ✅ 可以添加新附件 ✅ 可以删除已有附件 ✅ 保存时只处理变更的附件 ✅ 不会重复添加已有附件