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

编辑任务时附件显示问题修复说明

问题现象

用户反馈:上传文件显示成功,但是编辑任务时没有附件显示。

问题分析

1. 原始代码问题

在原始的 editTask 函数中:

const editTask = (task: any) => {
  editingTask.value = task
  Object.assign(taskForm, task)  // 只复制了基本任务信息
  showCreateDialog.value = true
}

问题:

  • 没有加载任务的附件列表
  • 没有将附件数据转换为前端显示格式
  • 编辑时会重复添加已有附件

2. 数据流分析

编辑任务时需要的数据流:

  1. 获取任务基本信息
  2. 调用 getTaskAttachments API 获取附件列表
  3. 将附件数据转换为 taskForm.attachments 格式
  4. 将附件数据转换为 fileList 格式用于UI显示
  5. 区分已有附件和新上传附件

修复方案

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. 编辑任务显示附件

  1. 创建一个带附件的任务
  2. 编辑该任务
  3. 确认附件正确显示在上传组件中

2. 编辑时添加新附件

  1. 编辑已有任务
  2. 添加新附件
  3. 保存确认只添加新附件,不重复添加已有附件

3. 编辑时删除附件

  1. 编辑有附件的任务
  2. 删除已有附件
  3. 确认附件从服务器删除
  4. 删除新添加的附件
  5. 确认只从UI中移除,不调用删除API

预期结果

修复后,编辑任务时: 正确显示已有附件 可以添加新附件 可以删除已有附件 保存时只处理变更的附件 不会重复添加已有附件