Files
X-Financial/document/development/receipt-folder/CONCEPT.md
caoxiaozhu 34457f9c3e feat: 本体字段治理与风险规则模板执行器重构
- 新增本体字段注册表与字段治理审计脚本
- 重构风险规则模板执行器、DSL 验证与清单分类器
- 完善票据夹服务与差旅请求详情页交互
- 优化趋势图表与总览页数据展示
- 增强报销平台风险分级与模拟公司筛选
- 补充本体字段、风险规则生成与票据夹服务测试覆盖
2026-06-03 15:46:56 +08:00

9.9 KiB
Raw Blame History

票据夹功能概念文档

更新时间2026-05-29

功能一句话

票据夹用于归集用户已上传并经过 OCR 识别的原始票据文件,避免票据已识别但忘记关联报销单后无法找回。

背景与问题

当前系统有两条票据路径:

  • 报销明细附件路径:票据上传到某个草稿费用明细后,会存入 expense_claims 附件目录,并写入附件元数据。
  • 独立 OCR 识别路径:报销对话里先上传票据识别时,/ocr/recognize 只返回识别结果,源文件使用临时目录,识别结束后会清理。

这会导致一个业务缺口:用户可能已经上传票据并完成 OCR但还没有把票据关联到报销草稿。只要用户关闭会话、切走页面或忘记继续操作原始票据就没有一个稳定入口可追溯。

票据夹要补齐这个缺口:凡是系统对用户上传文件做过 OCR 并持久化源文件,就应进入票据夹列表;后续用户可以查看、修正票据信息、删除无效票据,或一键把未关联票据带入报销对话。

目标与非目标

目标:

  • 在左侧侧边栏的“单据中心”下面新增“票据夹”入口。
  • 建立票据源文件持久化能力OCR 后保留原始文件、预览文件和识别元数据。
  • 提供票据夹列表,复用单据中心的紧凑列表视觉语言。
  • 支持“未关联票据 / 已关联票据”两个状态切换。
  • 支持票据详情:基本票据信息可编辑、原始文件可预览、底部返回列表和删除票据。
  • 支持“一键关联票据”:选择未关联票据,选择未提交草稿或新建报销单,再跳转到报销对话继续填写和关联。

非目标:

  • 本轮不引入 document_assets 等数据库结构变更;先用文件资产和元数据 JSON 完成产品闭环。
  • 本轮不替换现有报销明细附件接口。
  • 本轮不把票据夹做成财务共享的全公司档案库;默认只展示当前登录用户自己的票据。
  • 本轮不在列表页直接完成报销单提交,提交仍回到现有对话核对流程。

用户与场景

涉及角色:

  • 普通员工:上传票据后稍后再归集到草稿。
  • 经理或财务用户:在自己名下上传票据时同样需要留存和追溯。

典型场景:

  1. 用户在个人工作台上传 3 张票据OCR 成功后暂时没有保存草稿。
  2. 用户第二天打开票据夹,看到这 3 张票据仍在“未关联票据”。
  3. 用户进入详情,修正票据类型、金额或日期。
  4. 用户点击“一键关联票据”,多选未关联票据。
  5. 用户选择已有草稿,或选择新建报销单。
  6. 系统打开报销对话,把票据源文件和 OCR 信息带入现有核对流程。

功能能力

票据持久化

  • OCR 入口接收文件后,在识别完成阶段保存源文件。
  • 保存位置建议为 storage/receipt_folder/<owner_key>/<receipt_id>/
  • 每个票据目录包含:
    • 原始文件:source.<ext>
    • 预览文件:preview.<ext>,可为空
    • 元数据:meta.json
  • 元数据记录:
    • id
    • owner_key
    • file_name
    • media_type
    • size_bytes
    • uploaded_at
    • status: unlinked / linked
    • linked_claim_id
    • linked_claim_no
    • linked_item_id
    • linked_at
    • OCR 引擎、模型、文本、摘要、置信度、票据类型、场景、结构化字段、提示信息

列表

  • 页签:
    • 未关联票据
    • 已关联票据
  • 表格字段建议:
    • 票据文件
    • 识别类型
    • 费用场景
    • 金额
    • 票据日期
    • OCR 置信度
    • 关联状态
    • 上传时间
  • 交互:
    • 搜索文件名、摘要、字段值、关联单号
    • 按状态切换
    • 点击行进入详情
    • 未关联页显示“一键关联票据”

详情

  • 基本票据信息:
    • 文件名只读
    • 票据类型可编辑
    • 费用场景可编辑
    • 票据日期可编辑
    • 金额可编辑
    • 商户 / 出发地 / 到达地 / 票据号码等 OCR 字段可编辑
  • 原始文件展示:
    • 图片直接预览
    • PDF 用浏览器内嵌预览
    • 不可预览类型提供下载入口
  • 底部动作:
    • 返回列表
    • 删除票据

一键关联票据

流程:

  1. 打开关联弹窗,展示未关联票据多选列表。
  2. 下一步展示当前用户未提交草稿报销单,也提供“新建报销单”选项。
  3. 确认后打开现有报销对话。
  4. 如果选择已有草稿:
    • 对话以 link_to_existing_draft 语义继续。
    • 携带 draft_claim_id 和票据文件。
  5. 如果选择新建报销单:
    • 对话以 create_new_claim_from_documents 语义继续。
    • 携带票据文件和 OCR 元数据。

方案设计

后端

新增模块:

  • schemas/receipt_folder.py
  • services/receipt_folder.py
  • api/v1/endpoints/receipt_folder.py

接口建议:

  • GET /api/v1/receipt-folder?status=unlinked|linked|all
  • GET /api/v1/receipt-folder/{receipt_id}
  • PATCH /api/v1/receipt-folder/{receipt_id}
  • DELETE /api/v1/receipt-folder/{receipt_id}
  • GET /api/v1/receipt-folder/{receipt_id}/preview
  • GET /api/v1/receipt-folder/{receipt_id}/source

OCR 改造:

  • /api/v1/ocr/recognize 保持现有响应结构兼容。
  • 在识别后调用票据夹服务保存源文件和识别结果。
  • 给每个返回的 OCR 文档补充可选 receipt_idreceipt_preview_urlreceipt_source_url 字段。

前端

新增模块:

  • services/receiptFolder.js
  • views/ReceiptFolderView.vue
  • assets/styles/views/receipt-folder-view.css

导航改造:

  • useNavigation.js 新增 receiptFolder,放在 documents 后面。
  • accessControl.jsreceiptFolder 作为默认可见视图。
  • router/index.js 自动生成 /app/receiptFolder 路由。
  • AppShellRouteView.vue 渲染新页面,并允许页面触发 openSmartEntry

对话衔接:

  • 票据夹确认关联时,前端从 source 接口取回 Blob构造 File 对象传给 openSmartEntry
  • 同时把已编辑 OCR 元数据转为 initialReceiptDocuments 或直接通过 prompt / extraContext 进入对话。
  • 本轮优先用现有 initial-filesinitial-prompt 打开对话,确保用户可以继续核对和保存。

算法与公式

当前功能不涉及显式数学公式。

列表排序使用上传时间倒序:


sortKey(receipt) = uploadedAt(receipt)

状态归类:


status(receipt) =
\begin{cases}
linked, & linkedClaimId \neq \emptyset \\
unlinked, & linkedClaimId = \emptyset
\end{cases}

测试方案

后端:

  • OCR 识别后会保存源文件和 meta.json
  • 列表只返回当前用户票据。
  • status=unlinked 只返回未关联票据。
  • 详情可读取 OCR 字段。
  • PATCH 后字段持久化。
  • 预览接口能返回图片或 PDF。
  • DELETE 只删除票据夹根目录下的目标票据。

前端:

  • 导航中“票据夹”位于“单据中心”下面。
  • 列表空态、加载态、错误态可用。
  • 未关联和已关联两个页签计数正确。
  • 点击行进入详情。
  • 详情可保存字段、返回列表、删除票据。
  • 一键关联弹窗能完成票据选择和草稿选择。

集成:

  • 上传票据触发 OCR 后,票据出现在票据夹。
  • 从票据夹选择未关联票据,可打开报销对话。
  • 选择已有草稿时,对话带入草稿单号。
  • 选择新建报销单时,对话提示基于票据新建。

指标与验收

  • OCR 成功返回后,票据夹列表能查到对应源文件。
  • 票据源文件和预览文件在重启后仍可访问。
  • 未关联票据和已关联票据状态切换正确。
  • 票据详情字段修改后刷新仍保留。
  • 删除票据后列表不再显示,预览接口返回 404。
  • 侧边栏位置符合要求:票据夹在单据中心下面。
  • 单个新增核心前端和后端模块不超过 800 行。

风险与开放问题

  • 当前报销草稿流主要持久化 OCR 文本和文件名,真实文件复制到报销明细附件目录仍需要进一步打通。
  • 本轮采用文件元数据而非数据库,适合先完成闭环;后续若需要审计、权限、跨用户协作和全文检索,应升级到资产表。
  • 已关联状态如何自动回写,需要在后续把票据夹 ID 与报销明细 invoice_id 建立更强绑定。
  • 多票据关联时,如果用户中途取消对话,本轮仍保留为未关联,避免误标。

2026-06-03 详情页与上传治理补充

本轮根据新的验收要求收敛为三块核心内容:

  • 左侧为票据预览,使用共享详情页主区域承载,图片和 PDF 都以完整票据可见为优先目标,不再提供“打开源文件”按钮。
  • 右侧为识别票据详情,展示当前票据所有 OCR 字段和基础字段;用户点击“编辑”后可直接修改识别内容,保存后写回票据夹元数据。
  • 底部为关联信息;左侧预览卡底部同时展示用户编辑操作记录,用于后续财务判断人工修改痕迹。

编辑记录治理:

  • PATCH /receipt-folder/{receipt_id} 在保存前后对可编辑票据信息做字段级 diff。
  • 每条编辑日志记录操作者、操作时间、字段名称、修改前值、修改后值。
  • 前端详情页只展示真实 edit_logs,不再用模拟操作日志替代。

重复上传治理:

  • OCR 持久化票据时计算源文件 sha256
  • 同一用户再次上传相同源文件时,不新建票据目录,返回已有 receipt_id,并在 OCR 文档 warnings 中提示“已上传过同样的单据,请不要重复上传。”

报销助手联动:

  • 用户在报销助手上传新附件前,如果票据夹中存在未关联票据,先提示用户是否进入票据夹关联。
  • 用户可以选择“去票据夹关联”,也可以选择“继续上传新附件”;继续上传时只跳过本次未关联提醒,不影响后续重复附件校验。

删除级联:

  • 已关联票据对应的报销单被删除时,票据夹中关联该报销单的票据源文件、预览文件和元数据一并删除。