Files
ccdi/docs/plans/2026-03-10-project-detail-transaction-query-design.md

9.3 KiB
Raw Blame History

项目详情流水明细查询设计

概述

本次设计面向项目详情页中的“流水明细查询”菜单,按原型图实现“查询 + 筛选 + 导出”能力,不包含旧需求中的“加入分析”“二次分析”等扩展功能。

页面默认查询当前项目下全部已入库流水,数据源仅使用本地表 ccdi_bank_statement,不再依赖上传记录的“查看流水”跳转。上传数据页同步移除上传记录表的操作列,后续不再从上传记录进入流水明细页。

已确认范围

  • 页面入口保留在项目详情页的 detail 菜单
  • 默认查询范围为当前 projectId 下全部流水
  • 上传页移除“查看流水”入口
  • “导出流水”需要实现真实功能
  • 导出范围为当前页面筛选后的全部结果
  • 本次只做“查询 + 筛选 + 导出”
  • 摘要筛选仅使用 userMemo
  • 筛选栏中的多选项需要基于整个项目维度单独查询
  • 进入页面时即并行加载列表数据和项目级多选项

方案对比

方案一:本地库专用查询模块

  • ccdi-project 模块新增银行流水查询 Controller、Service、Mapper 查询方法
  • 页面直接查询本地 ccdi_bank_statement
  • 导出使用本地查询条件复用

优点:

  • 与现有“上传后落本地库”架构一致
  • 查询与导出结果稳定,可复现
  • 后续可继续扩展更多项目级分析能力

缺点:

  • 需要补充 DTO、VO、Mapper SQL、导出模型

方案二:大而全聚合接口

  • 用一个接口同时返回列表、多选项、统计信息

优点:

  • 前端调用少

缺点:

  • 接口职责混杂
  • 后续增加筛选维度时维护成本高
  • 导出仍需要单独处理

方案三:直接回源 LSFX 接口

  • 页面查询与导出实时调用流水分析平台接口

优点:

  • 本地查询层改动少

缺点:

  • 与现有本地入库方案冲突
  • 项目级全量查询稳定性差
  • 页面与导出口径难统一

选型

采用方案一:本地库专用查询模块。

该方案与当前 ccdi_bank_statementCcdiFileUploadServiceImpl 的入库逻辑一致,最符合“项目维度统一查询 + 当前筛选导出”的实现要求。

页面结构

页面仍由 ruoyi-ui/src/views/ccdiProject/detail.vue 动态加载 DetailQuery.vue

DetailQuery.vue 从占位组件升级为正式页面,整体布局分为左右两栏:

  • 左侧:固定筛选栏
  • 右侧:结果区域

右侧结果区域包含:

  • 标题“流水明细查询”
  • 顶部页签:全部 / 流入 / 流出
  • 导出按钮:导出流水
  • 列表表格
  • 分页器

列表中的操作位保留只读详情能力,用于打开详情抽屉或弹窗查看单条流水完整字段。

筛选项设计

左侧筛选栏按原型提供以下条件:

  1. 交易时间
  • 对应字段:trxDate
  • 支持起止范围查询
  • 后端兼容 yyyy-MM-dd HH:mm:ssyyyy-MM-dd
  1. 对方名称 + 空值
  • 对应字段:customerAccountName
  • 输入框为模糊匹配
  • 勾选空值时匹配 null、空串、全空白字符串
  1. 摘要 + 空值
  • 对应字段:userMemo
  • 输入框为模糊匹配
  • 勾选空值时匹配 null、空串、全空白字符串
  1. 本方主体
  • 对应字段:leAccountName
  • 多选
  1. 本方银行
  • 对应字段:bank
  • 多选
  1. 本方账户
  • 对应字段:leAccountNo
  • 多选
  1. 交易金额
  • 使用绝对值范围筛选
  • 统一适配 全部 / 流入 / 流出 三个页签
  1. 对方账户 + 空值
  • 对应字段:customerAccountNo
  • 输入框为模糊匹配
  1. 交易类型 + 空值
  • 对应字段:cashType
  • 输入框为模糊匹配

多选项加载规则

本方主体、本方银行、本方账户三类多选项不从当前列表结果派生,而是通过单独接口按整个项目维度去重查询。

进入页面时前端并行加载:

  • 列表接口:默认查询当前项目全部流水
  • 多选项接口:返回整个项目维度的全部主体、银行、账户选项

多选项接口返回值:

  • ourSubjectOptions
  • ourBankOptions
  • ourAccountOptions

前端多选框内部搜索仅在已加载的项目级选项上做本地过滤,不再触发额外远程请求。

列表列设计

表格列与原型语义对齐:

  1. 交易时间
  • 字段:trxDate
  1. 本行账户/主体
  • 主行:leAccountNo
  • 副行:leAccountName
  1. 对方名称/账户
  • 主行:customerAccountName
  • 副行:customerAccountNo
  1. 摘要/交易类型
  • 主行:userMemo
  • 副行:cashType
  1. 交易金额
  • 流入显示 +amountCr
  • 流出显示 -amountDr
  • 页面展示统一输出计算后的 displayAmount
  1. 操作
  • 只读详情

页签与排序规则

页签规则

  • 全部:不过滤金额方向
  • 流入:仅查询 amount_cr > 0
  • 流出:仅查询 amount_dr > 0

排序规则

支持两个排序字段:

  • 交易时间
  • 交易金额

排序方向支持:

  • 升序
  • 降序

交易金额排序按绝对值排序,和金额范围筛选保持一致。

排序字段必须由后端白名单控制,禁止前端任意传值直接拼接 SQL。

后端接口设计

建议新增专用 ControllerCcdiBankStatementController

1. 列表分页查询

  • 路径:GET /ccdi/project/bank-statement/list
  • 入参:CcdiBankStatementQueryDTO
  • 返回:TableDataInfo

入参字段包括:

  • projectId
  • tabType
  • transactionStartTime
  • transactionEndTime
  • counterpartyName
  • counterpartyNameEmpty
  • userMemo
  • userMemoEmpty
  • ourSubjects
  • ourBanks
  • ourAccounts
  • amountMin
  • amountMax
  • counterpartyAccount
  • counterpartyAccountEmpty
  • transactionType
  • transactionTypeEmpty
  • orderBy
  • orderDirection

2. 多选项查询

  • 路径:GET /ccdi/project/bank-statement/options
  • 入参:projectId
  • 返回:CcdiBankStatementFilterOptionsVO

3. 单条详情

  • 路径:GET /ccdi/project/bank-statement/detail/{bankStatementId}
  • 返回:CcdiBankStatementDetailVO

4. 导出

  • 路径:POST /ccdi/project/bank-statement/export
  • 入参:复用 CcdiBankStatementQueryDTO
  • 返回Excel 文件流

服务层设计

建议新增:

  • ICcdiBankStatementService
  • CcdiBankStatementServiceImpl

职责拆分:

  • 列表查询参数校验与标准化
  • 排序字段白名单处理
  • 时间范围解析与兼容
  • 多选项去重查询
  • 单条详情查询
  • 导出列表查询与导出模型组装

Mapper 设计

保留现有 CcdiBankStatementMapper,在接口和 XML 中新增查询方法,不新增独立 Mapper。

建议补充的方法:

  • selectStatementPage
  • selectStatementListForExport
  • selectFilterOptions
  • selectStatementDetailById

SQL 规则:

  • 基于 project_id 做主过滤
  • 使用动态 SQL 处理输入框、空值、多选数组
  • 用统一表达式计算排序时间字段
  • 用统一表达式计算展示金额与金额排序值

前端设计

建议新增 API 文件:

  • ruoyi-ui/src/api/ccdiProjectBankStatement.js

建议改造文件:

  • ruoyi-ui/src/views/ccdiProject/components/detail/DetailQuery.vue
  • ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue

页面初始化流程:

  1. 读取 projectId
  2. 并行调用:
    • list
    • options
  3. 渲染左侧筛选和右侧列表

交互规则:

  • 查询、页签切换、排序切换、分页切换时重置到第一页并刷新列表
  • 重置时恢复默认筛选并回到 全部
  • 导出时使用当前筛选条件导出全部结果

导出规则

  • 导出范围:当前页面筛选后的全部结果
  • 不受当前分页限制
  • 导出文件名:项目名称_流水明细_时间戳.xlsx
  • 导出列与页面列表保持一致:
    • 交易时间
    • 本方账户
    • 本方主体
    • 对方名称
    • 对方账户
    • 摘要
    • 交易类型
    • 交易金额
  • 当前筛选结果为空时,不生成空文件,直接提示“当前条件下无可导出数据”

异常处理

  • 多选项接口失败:列表仍可查询,筛选项置空并提示可刷新重试
  • 列表接口失败:显示错误态并保留当前筛选值
  • 详情接口失败:仅阻断详情展示,不影响主页面
  • 导出失败:保留筛选条件并提示失败原因
  • 项目下无流水数据:显示空态,导出按钮禁用

验收标准

功能验收

  • 进入页面时并行加载列表与项目级多选项
  • 默认展示当前项目下全部流水
  • 三个页签切换结果正确
  • 所有筛选项单独与组合查询均正确
  • 空值筛选逻辑正确
  • 交易时间兼容两种时间格式
  • 金额范围按绝对值筛选正确
  • 排序仅支持交易时间与交易金额
  • 导出结果与页面筛选口径一致
  • 上传页操作列已移除,不再支持查看流水跳转

技术验收

  • 后端遵循项目 DTO / VO 分层规范
  • Controller 使用 Swagger 注释
  • 简单查询由 MyBatis Plus + XML 动态 SQL 实现
  • 前端 API 独立封装到 src/api
  • 页面在桌面端和移动端均可正常展示

风险与约束

  1. TRX_DATE 为字符串字段
  • 需要在 SQL 或服务层统一解析,保证筛选与排序稳定
  1. 历史数据可能存在空字符串与空白字符串混用
  • 空值筛选必须统一兼容
  1. 项目维度多选项可能数量较大
  • 首版先按项目维度一次性加载
  • 若实际数据量过大,再考虑远程搜索优化
  1. 当前页面不引入旧需求中的二次分析能力
  • 后续若扩展,需要新增业务表与关联逻辑