# 项目上传文件列表删除功能设计 ## 背景 当前项目详情页“上传数据”中的“上传文件列表”仅展示文件信息和状态,不支持针对单条文件记录执行业务操作。 现有系统已经具备以下基础能力: - `ccdi_file_upload_record` 已保存每条上传记录的 `id`、`lsfxProjectId`、`logId`、`fileStatus`、`errorMessage` - `ccdi_bank_statement` 已按 `projectId + batchId(logId)` 关联每次上传入库的流水数据 - 流水分析平台客户端 `LsfxAnalysisClient` 已封装删除文件接口 `deleteFiles` 当前缺失的是: - 解析失败文件缺少“查看错误原因”入口 - 解析成功文件缺少“删除”入口 - 删除后缺少保留历史记录并展示“已删除”状态的机制 ## 目标 - 在项目详情-上传数据-上传文件列表中新增“操作”列 - 当文件状态为 `parsed_failed` 时,支持查看错误原因 - 当文件状态为 `parsed_success` 时,支持删除文件 - 删除时增加二次确认,明确会同步删除平台文件与本地流水 - 删除成功后调用流水分析平台删除接口 - 删除成功后删除本地银行流水表中对应文件的全部流水 - 删除成功后保留上传记录,并将状态更新为 `deleted` - 删除后的列表状态显示为“已删除” ## 非目标 - 不删除 `ccdi_file_upload_record` 历史记录 - 不新增独立删除标记字段,如 `deleted_flag`、`deleted_time` - 不调整现有批量上传、轮询解析、本行信息拉取等主流程 - 不改造流水明细查询页面的筛选交互 ## 现状分析 ### 前端现状 上传文件列表页面位于: - `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue` 当前列表字段包括: - 文件名 - 文件大小 - 状态 - 主体名称 - 主体账号 - 上传时间 - 上传人 当前前端已经具备: - 查询列表:`getFileUploadList` - 查询统计:`getFileUploadStatistics` - 查看列表中的 `fileStatus` - 弹窗提示能力 `this.$alert` - 二次确认能力 `this.$confirm` 当前前端未具备: - 操作列渲染 - 按记录 ID 删除文件的 API - `deleted` 状态映射 ### 后端现状 后端上传记录相关接口位于: - `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiFileUploadController.java` 当前已提供: - `GET /ccdi/file-upload/list` - `GET /ccdi/file-upload/statistics/{projectId}` - `GET /ccdi/file-upload/detail/{id}` 服务层位于: - `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiFileUploadServiceImpl.java` 当前已具备: - 按状态统计上传记录 - 根据 `logId` 拉取并入库银行流水 - 失败时记录 `errorMessage` - 通过 `CcdiBankStatementMapper.deleteByProjectIdAndBatchId(projectId, logId)` 清理本地流水 流水分析平台客户端位于: - `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/client/LsfxAnalysisClient.java` 当前已具备: - `deleteFiles(DeleteFilesRequest)` 删除平台文件 ### 状态现状 当前 `file_status` 已存在以下状态: - `uploading` - `parsing` - `parsed_success` - `parsed_failed` 当前缺少删除后的业务状态,因此无法在保留记录的前提下表达“已删除”。 ## 方案对比 ### 方案一:基于现有状态字段增加 `deleted` - 在 `file_status` 中新增 `deleted` - 删除成功后仅更新记录状态,不删除记录 - 前后端统一基于状态判断操作按钮与文案 优点: - 最符合“保留并显示为已删除”的需求 - 复用现有查询、展示、统计结构 - 改动范围集中,数据库结构无需新增字段 缺点: - 需要同步扩展状态映射和统计逻辑 ### 方案二:新增独立删除标记字段 - 保留原有 `file_status` - 额外增加 `deletedFlag` 或 `deletedTime` 优点: - 删除状态与解析状态语义分离 缺点: - 查询、展示、统计逻辑更复杂 - 需要新增数据库字段和 Mapper 映射 - 当前需求下属于过度设计 ### 方案三:物理删除上传记录 优点: - 实现最直接 缺点: - 与“继续保留并显示为已删除”冲突 - 无法追溯文件历史和删除操作结果 ## 最终方案 采用方案一:在 `ccdi_file_upload_record.file_status` 中新增 `deleted` 状态,基于现有上传记录做软删除保留。 ## 详细设计 ### 状态模型 上传记录状态统一定义为: - `uploading`:上传中 - `parsing`:解析中 - `parsed_success`:解析成功 - `parsed_failed`:解析失败 - `deleted`:已删除 状态驱动前端操作规则: - `parsed_failed`:显示“查看错误原因” - `parsed_success`:显示“删除” - `deleted`:不显示按钮 - `uploading`、`parsing`:不显示按钮 ### 删除链路 删除流程按以下顺序执行: 1. 前端点击“删除” 2. 前端展示二次确认弹窗 3. 用户确认后调用“按上传记录 ID 删除文件”接口 4. 后端校验记录存在、归属当前项目、状态为 `parsed_success`、且包含 `lsfxProjectId` 与 `logId` 5. 后端调用流水分析平台 `deleteFiles` 6. 平台删除成功后,后端删除本地 `ccdi_bank_statement` 中 `projectId + batchId(logId)` 的全部流水 7. 本地流水删除成功后,后端将 `ccdi_file_upload_record.file_status` 更新为 `deleted` 8. 前端收到成功响应后刷新列表与统计 ### 一致性原则 删除必须遵守“先平台、后本地、再改状态”: - 平台删除失败:不删本地流水,不更新记录状态 - 本地流水删除失败:不更新记录状态为 `deleted` - 状态更新失败:整体按失败返回,避免界面和数据不一致 ### 后端接口设计 新增接口建议: - `DELETE /ccdi/file-upload/{id}` 接口语义: - 按上传记录 ID 删除对应文件 - 仅允许删除 `parsed_success` 状态记录 返回规则: - 成功:`AjaxResult.success("删除成功")` - 失败:`AjaxResult.error("具体失败原因")` ### 后端服务设计 服务层新增删除方法,职责包括: - 查询上传记录 - 校验项目归属与状态 - 组装 `DeleteFilesRequest` - 调用 `LsfxAnalysisClient.deleteFiles` - 删除本地银行流水 - 更新上传记录状态为 `deleted` 建议保持数据库层面不新增表结构,仅扩展状态值和相关逻辑。 ### 前端交互设计 上传文件列表新增“操作”列。 操作规则: - `parsed_failed`:点击“查看错误原因”,弹出错误信息弹窗 - `parsed_success`:点击“删除”,弹出确认框 - `deleted`:显示状态“已删除”,无操作按钮 删除确认文案建议: `删除后将同步删除流水分析平台中的文件,并清除本系统中该文件对应的所有银行流水数据,是否继续?` 删除成功后: - 提示“删除成功” - 刷新列表 - 刷新统计 ### 统计设计 当前统计 VO 仅统计: - `uploading` - `parsing` - `parsedSuccess` - `parsedFailed` - `total` 本次建议扩展: - `deleted` 这样前端统计口径可以完整覆盖全部状态,也便于后续展示已删除数量。 如果短期内页面不展示该数字,也建议后端先统一支持,避免状态被统计遗漏。 ## 影响范围 ### 后端 - `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiFileUploadController.java` - `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiFileUploadService.java` - `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiFileUploadServiceImpl.java` - `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiFileUploadStatisticsVO.java` - `ccdi-project/src/main/resources/mapper/ccdi/project/CcdiFileUploadRecordMapper.xml` ### 前端 - `ruoyi-ui/src/api/ccdiProjectUpload.js` - `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue` ## 风险与边界 需要重点拦截以下删除场景: - 记录不存在 - 记录不属于当前项目 - 记录状态不是 `parsed_success` - 记录已经是 `deleted` - 记录缺少 `lsfxProjectId` - 记录缺少 `logId` 需要注意以下业务影响: - 软删除后,流水明细查询将不再能查到该文件对应流水 - 上传记录会继续保留,便于审计和追溯 - 如果平台删除成功但本地状态更新失败,需要明确作为失败返回并记录日志 ## 测试方案 ### 后端单元测试 - 删除成功时:平台删除成功、本地流水删除成功、记录状态更新为 `deleted` - 平台删除失败时:本地流水不删除、记录状态不变 - 本地流水删除失败时:记录状态不变 - 非 `parsed_success` 状态删除时返回失败 - `deleted` 状态重复删除时返回失败 - 缺少 `logId` 或 `lsfxProjectId` 时返回失败 ### 控制器测试 - 删除接口成功返回正确消息 - Service 抛出异常时返回错误消息 ### 前端测试 - `parsed_failed` 状态显示“查看错误原因” - `parsed_success` 状态显示“删除” - `deleted` 状态显示“已删除”且不显示操作按钮 - 删除前弹出二次确认 - 删除成功后刷新列表和统计 - 错误原因弹窗能正确显示 `errorMessage` ## 验收标准 - 上传文件列表新增“操作”列 - 解析失败文件可以查看错误原因 - 解析成功文件可以二次确认后删除 - 删除成功后已调用流水分析平台删除接口 - 删除成功后本地银行流水数据被清理 - 删除成功后上传记录仍保留,状态显示为“已删除” - 已删除记录不再出现删除按钮 --- **设计日期:** 2026-03-16 **设计人员:** Codex **审核状态:** 已确认