6.0 KiB
上传流水文件原始文件名保持设计
背景
项目详情的“上传数据”页支持批量上传流水文件。当前前端提交文件时保留了浏览器选择文件的原始文件名,但后端为了异步处理,会先把文件保存为带有批次号、序号和时间戳的临时文件名。异步任务再把这个临时文件对象转传给流水分析平台,导致流水分析平台上传接口收到的 multipart 文件名不是用户初始上传的文件名。
同时,后端在查询流水分析平台文件状态后,会用平台返回的 uploadFileName 或 downloadFileName 覆盖本系统上传记录 ccdi_file_upload_record.file_name,页面列表读取该字段展示文件名,因此页面展示名也可能与初始上传文件名不一致。
目标
- 新上传流水文件时,页面展示的文件名必须保持用户初始上传文件名。
- 调用流水分析平台上传文件接口时,multipart 文件 part 的 filename 必须保持用户初始上传文件名。
- 临时文件仍需保持唯一命名,避免批量上传、同名文件或并发上传互相覆盖。
- 本次只处理“上传本地流水文件”链路,不改变“拉取本行信息”链路的现有文件名展示与状态处理行为。
- 历史已上传记录不做批量回改。
非目标
- 不修改历史上传记录的文件名。
- 不调整上传入口、文件格式限制、文件大小限制、异步任务调度和解析轮询规则。
- 不新增数据库字段。
- 不改变流水分析平台接口地址、请求参数名和响应解析口径。
- 不改变“拉取本行信息”生成的上传记录文件名规则。
现状链路
- 前端
UploadData.vue将selectedFiles.map((f) => f.raw)传给batchUploadFiles。 ccdiProjectUpload.js使用FormData.append("files", file)上传,浏览器侧仍保留原始文件名。CcdiFileUploadController.batchUpload通过MultipartFile.getOriginalFilename()校验格式。CcdiFileUploadServiceImpl.batchUploadFiles保存记录时写入原始文件名,但临时文件路径使用batchId_index_timestamp_originalFilename。processFileAsync读取临时文件并调用lsfxClient.uploadFile(lsfxProjectId, file)。LsfxAnalysisClient.uploadFile和HttpUtil.uploadFile只接收File,最终用FileSystemResource发送文件,multipart filename 来自临时文件名。- 查询文件上传状态后,
processRecordAfterLogIdReady使用平台返回文件名覆盖record.fileName。
设计方案
后端上传转发
保留当前临时文件唯一命名方式,避免同名文件覆盖。异步处理时以 CcdiFileUploadRecord.fileName 作为原始文件名来源,将“临时文件内容”和“原始文件名”一起传给流水分析客户端。
LsfxAnalysisClient.uploadFile 增加可指定上传文件名的能力。对项目上传流水链路,调用新签名并传入原始文件名;测试 Controller 或其他调用方如果不传原始文件名,可继续使用现有文件名语义。
HttpUtil.uploadFile 增加对“文件内容 + 指定 filename”的 multipart 资源包装。发送时仍使用参数名 files,但文件 part 的 filename 使用原始文件名,而不是临时文件名。
上传记录文件名
“上传本地流水文件”链路中的 ccdi_file_upload_record.file_name 只记录本系统初始上传文件名。查询流水分析平台状态后,该链路不再用 uploadFileName 或 downloadFileName 覆盖该字段。
平台返回的文件大小仍可继续更新到 file_size,解析状态、主体名称、账号、错误信息等字段保持现有处理方式。
当前状态后处理逻辑会被本地上传和“拉取本行信息”复用。实现时需要在调用或方法参数上区分来源:本地上传链路保留初始文件名;拉取本行信息链路保持现有行为,继续按当前规则处理平台返回文件名。
前端展示
前端无需改造。上传记录列表继续展示后端返回的 fileName。由于本地上传链路后端不再覆盖该字段,新上传记录从创建、处理中、成功或失败状态都会展示初始上传文件名。
数据流
用户选择文件: 银行流水A.xlsx
-> 前端 FormData files: filename=银行流水A.xlsx
-> 后端 MultipartFile originalFilename=银行流水A.xlsx
-> 本地临时文件: batchId_0_timestamp_银行流水A.xlsx
-> 上传记录 file_name=银行流水A.xlsx
-> 流水分析平台 multipart files: filename=银行流水A.xlsx
-> 页面上传记录 fileName=银行流水A.xlsx
错误处理
- 原始文件名为空时,沿用 Controller 现有“文件名不能为空”校验。
- 临时文件不存在、上传失败、解析失败时,沿用现有失败状态和错误信息记录方式。
- 指定原始文件名只影响 multipart filename,不影响临时文件读取和异常处理。
测试计划
- 后端单测或轻量验证覆盖 multipart 资源 filename:传入临时文件和原始文件名后,上传请求中的文件名应为原始文件名。
- 后端链路测试覆盖
CcdiFileUploadServiceImpl:创建上传记录后,异步上传调用使用record.fileName作为原始文件名。 - 状态处理测试覆盖平台返回
uploadFileName/downloadFileName与初始文件名不一致时,本系统记录仍保持初始文件名。 - 拉取本行信息链路回归:本次改动不改变其现有文件名展示与状态处理行为。
- 真实页面测试:在项目详情“上传数据”页上传一个文件名带中文的流水文件,核对页面上传记录展示初始文件名,并通过日志或 mock 接收端确认流水分析平台上传接口收到的 filename 为初始文件名。
影响范围
ccdi-project:上传流水异步处理链路。ccdi-lsfx:流水分析平台上传客户端和 multipart 工具。ruoyi-ui:无需源码改动,仅做真实页面验证。- 数据库:无需结构变更,历史数据不回改。