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.
cz-hjjc-budget/docs/attachment-file-rendering-l...

5.4 KiB

attachment/file 类型字段渲染逻辑说明

概述

本文档说明 PlannedExpenditureTemplateReadonly.vue 组件中 attachment/file 类型字段的完整渲染逻辑和数据流向。

数据流向

后端返回数据 (elementValues)
    ↓
getFieldValue(field) - 获取原始字段值
    ↓
getFileItems(field) - 处理并转换为文件项数组
    ↓
模板渲染 - 显示文件列表
    ↓
handleFileClick(file) - 处理文件点击事件

详细步骤

1. 字段值获取 (getFieldValue)

位置: PlannedExpenditureTemplateReadonly.vue:310

查找顺序:

  1. 通过 field_key 查找 (field.keyfield.field_key)

    • elementValues 中直接查找该 key
    • 如果找到的是对象且包含 value 属性,返回 direct.value
    • 否则直接返回找到的值
  2. 通过 element_id 查找 (field.element_id)

    • elementValues 中使用 element_id 作为 key 查找
    • 如果找到的是对象且包含 value 属性,返回 ev.value
    • 否则直接返回找到的值
  3. 兜底查找 (element_{elementId})

    • 尝试使用 element_${elementId} 作为 key 查找
    • 处理方式同上
  4. 遍历查找 (兼容"值对象"模式)

    • 遍历 elementValues 的所有值
    • 查找 field_key 匹配的对象
    • 返回其 value 属性

调试信息:

  • 开发环境下,会在控制台输出详细的查找过程
  • 包括:使用的 key、找到的值、值的类型等
  • 如果未找到值,会输出警告和所有可用的 keys

2. 文件项处理 (getFileItems)

位置: PlannedExpenditureTemplateReadonly.vue:620

输入: getFieldValue(field) 返回的原始值

处理逻辑:

2.1 字符串类型

// 如果值是字符串,例如: "/uploads/file.pdf"
{
  name: "file.pdf",  // 从路径提取文件名
  url: "/uploads/file.pdf"  // 原始字符串作为 URL
}

2.2 对象类型

从对象中提取以下字段(按优先级):

  • URL 字段: url, path, file_url, download_url, href, preview_url
  • 名称字段: original_name, file_name, name, filename, originalName
  • 如果 URL 存在但名称不存在,从 URL 路径提取文件名

2.3 数组类型

  • 如果值是数组,遍历每个元素
  • 每个元素按上述规则处理(字符串或对象)
  • 返回处理后的文件项数组

调试信息:

  • 输出原始值的类型、长度等信息
  • 输出每个文件项的处理结果
  • 如果处理失败,输出警告和可用的字段

3. 模板渲染

位置: PlannedExpenditureTemplateReadonly.vue:150

渲染逻辑:

  • 如果 getFileItems(field).length > 0,显示文件列表
  • 每个文件项:
    • 有 URL: 显示为可点击链接,点击在新窗口打开
    • 无 URL: 显示为可点击链接,点击提示"文件链接不可用"
  • 如果文件列表为空,显示 "-"

调试信息 (开发环境):

  • 在页面上显示字段的调试信息框
  • 包括字段ID、字段Key、字段类型、原始值、处理后的文件项数
  • 每个文件项显示其 name 和 url

4. 文件点击处理 (handleFileClick)

位置: PlannedExpenditureTemplateReadonly.vue:651

处理逻辑:

  • 如果文件有 url,使用 window.open(url, '_blank') 打开
  • 如果文件没有 url,显示提示:"文件链接不可用"

调试信息:

  • 输出点击的文件对象
  • 输出是否有 URL
  • 如果打开失败,输出错误信息

调试方法

1. 查看控制台日志

在浏览器开发者工具的控制台中,查找以下前缀的日志:

  • [getFieldValue] - 字段值获取过程
  • [getFileItems] - 文件项处理过程
  • [handleFileClick] - 文件点击事件

2. 查看页面调试信息

在开发环境下,页面上的 attachment/file 字段会显示一个调试信息框,包含:

  • 字段ID和Key
  • 原始值
  • 处理后的文件项数

3. 常见问题排查

问题1: 文件列表为空

  • 检查 [getFieldValue] 日志,确认是否找到了字段值
  • 检查 elementValues 中是否包含该字段的数据
  • 检查字段的 field_keyelement_id 是否正确

问题2: 文件有名称但没有URL

  • 检查 [getFileItems.toItem] 日志,查看对象中有哪些字段
  • 确认对象中是否包含 URL 相关字段url, path, file_url 等)
  • 检查后端返回的数据结构

问题3: 点击文件无反应

  • 检查 [handleFileClick] 日志,确认文件对象的内容
  • 检查浏览器是否阻止了弹窗
  • 检查 URL 是否有效

数据结构示例

elementValues 结构示例

模式1: 字段键值模式

{
  "element_123": [
    {
      "name": "文件1.pdf",
      "url": "/uploads/file1.pdf"
    }
  ]
}

模式2: 值对象模式

{
  "123": {
    "element_id": 123,
    "field_key": "element_123",
    "value": [
      {
        "name": "文件1.pdf",
        "url": "/uploads/file1.pdf"
      }
    ]
  }
}

模式3: 字符串模式

{
  "element_123": "/uploads/file1.pdf"
}

注意事项

  1. 开发环境: 调试信息只在开发环境(config.isDevelopment === true)下显示
  2. 性能: 调试信息可能影响性能,生产环境会自动禁用
  3. 数据格式: 组件兼容多种数据格式,但建议使用统一格式
  4. 错误处理: 所有错误都会在控制台输出,便于排查问题