大量更新
This commit is contained in:
565
17-ProjectMoneyX/3-实现详细稿/1-ProjectMoneyX-PRD.md
Normal file
565
17-ProjectMoneyX/3-实现详细稿/1-ProjectMoneyX-PRD.md
Normal file
@@ -0,0 +1,565 @@
|
||||
# ProjectMoneyX — 产品需求文档(PRD)
|
||||
|
||||
> **版本**:v1.0 | **日期**:2026-03-03 | **状态**:综合定稿
|
||||
|
||||
---
|
||||
|
||||
## 1. 产品概述
|
||||
|
||||
### 1.1 产品名称
|
||||
|
||||
**ProjectMoneyX**
|
||||
|
||||
### 1.2 产品定位
|
||||
|
||||
ProjectMoneyX 是一款面向 Firefly III 生态的**本地化多源账单数据治理中间件**。
|
||||
它并非简单的"导入工具",而是 Firefly III 的前置**数据治理层**——负责将分散在支付平台、银行、生活服务及加密货币交易所的零散账单,经过标准化清洗、智能去重与链路合并后,无缝推送至 Firefly III / Data Importer,实现全资产的自动化流转与管理。
|
||||
|
||||
### 1.3 产品愿景
|
||||
|
||||
让用户可以将来自多源账单**一键汇总**为统一结构,经过规则映射与去重合并后,稳定导入 Firefly III,形成**可持续、可审计、可复用**的个人财务数据资产。
|
||||
|
||||
---
|
||||
|
||||
## 2. 背景与核心痛点
|
||||
|
||||
### 2.1 当前问题
|
||||
|
||||
| # | 痛点 | 说明 |
|
||||
|---|------|------|
|
||||
| 1 | **数据源分散** | 账单来源覆盖支付宝、微信、银行、生活服务平台、交易所,导出格式各异 |
|
||||
| 2 | **字段不统一** | 不同平台对时间、金额、收支方向、交易类型、对手方、备注等字段定义不同 |
|
||||
| 3 | **重复与链路拆分** | 同一笔真实交易可能在多个来源中出现(如银行卡转支付宝同时出现在两方账单),或在单一来源中拆成多条流水(下单、支付、退款、手续费) |
|
||||
| 4 | **导入链路复杂** | Data Importer 偏重"导入",并不擅长承担复杂的本地多源清洗编排 |
|
||||
| 5 | **规则分散** | 若完全依赖 Data Importer 进行规则映射,会导致多来源规则难以统一沉淀和复用 |
|
||||
|
||||
### 2.2 真实需求意图
|
||||
|
||||
从原始需求分析,用户真正需要的是一个完整的:
|
||||
|
||||
- **多源账单标准化中台** — 屏蔽平台差异
|
||||
- **本地清洗去重引擎** — 消除重复与链路碎片
|
||||
- **可配置规则映射系统** — 沉淀长期积累的分类知识
|
||||
- **面向 Firefly III 的导入适配层** — 无缝对接现有生态
|
||||
|
||||
---
|
||||
|
||||
## 3. 产品目标
|
||||
|
||||
### 3.1 核心目标
|
||||
|
||||
1. 支持多源账单文件导入并解析为**统一交易模型**
|
||||
2. 支持在本地完成清洗、标准化、规则映射、去重与链路合并
|
||||
3. 支持通过 API 或中间文件方式将数据导入 Data Importer / Firefly III
|
||||
4. 支持将清洗后的标准交易持久化到本地 SQLite,便于追溯、重跑和校验
|
||||
|
||||
### 3.2 MVP 成功标准
|
||||
|
||||
| # | 标准 |
|
||||
|---|------|
|
||||
| 1 | 用户可导入至少 3 类主流账单(支付平台、银行、生活消费平台) |
|
||||
| 2 | 同一批数据可在本地完成去重并输出统一交易记录 |
|
||||
| 3 | 用户可完成从「上传文件 → 预览清洗结果 → 应用规则 → 导入 Firefly III」的完整闭环 |
|
||||
| 4 | 导入失败可追溯到原始文件、解析结果和转换结果 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 目标用户
|
||||
|
||||
### 4.1 核心用户画像
|
||||
|
||||
- 拥有多平台消费/收支记录的个人用户
|
||||
- 使用 Firefly III 进行个人财务管理的进阶用户
|
||||
- 有一定技术能力,希望本地掌控账单数据的用户
|
||||
|
||||
### 4.2 用户特征
|
||||
|
||||
- 注重隐私,倾向于本地部署
|
||||
- 可接受文件导入而非完全自动爬取
|
||||
- 关注财务统计的一致性与长期可维护性
|
||||
|
||||
---
|
||||
|
||||
## 5. 产品范围
|
||||
|
||||
### 5.1 本期范围(In Scope)
|
||||
|
||||
1. 本地账单文件导入(CSV / Excel / 常见文本格式)
|
||||
2. 多来源适配器解析(插件化架构)
|
||||
3. 统一交易模型转换
|
||||
4. 本地规则映射(分类/账户/标签)
|
||||
5. 去重与链路合并
|
||||
6. SQLite 本地持久化
|
||||
7. 导入结果预览与确认
|
||||
8. 对接 Firefly III / Data Importer 的导入能力
|
||||
9. 导入任务日志与失败重试
|
||||
|
||||
### 5.2 非本期范围(Out of Scope)
|
||||
|
||||
1. 直接登录第三方平台自动抓取账单
|
||||
2. 银行/平台开放 API 的在线拉取(后续可扩展)
|
||||
3. 完整 BI 分析平台
|
||||
4. 替代 Firefly III 的账本能力
|
||||
5. 高频实时同步(本期以"批量导入"为主)
|
||||
|
||||
---
|
||||
|
||||
## 6. 产品架构与数据流转
|
||||
|
||||
### 6.1 数据流转拓扑
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ 多源账单导入 │ -> │ 解析器(Parser) │ -> │ 标准化入库 │ -> │ 去重与链路合并 │ -> │ 规则映射 │ -> │ 导出/推送 │
|
||||
│ (文件上传) │ │ (Adapter层) │ │ (SQLite) │ │ (Dedup+Link) │ │ (Rule Engine) │ │ (API/CSV) │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
### 6.2 规则映射策略:两段式分离
|
||||
|
||||
> **关键产品决策**:规则映射采用"本地为主,Data Importer 为辅"的两段式策略。
|
||||
|
||||
**第一阶段 — ProjectMoneyX 负责(数据对齐 + 业务分类)**:
|
||||
|
||||
- **字段级映射**:将各平台异构字段(如支付宝"交易对方"、银行"附言")统一映射为标准数据字段
|
||||
- **业务分类映射**:将交易对手、描述等信息映射到分类(餐饮、交通、工资等)、账户、标签
|
||||
- **商户名归一化**:统一商户别名(如"美团外卖-xxx店"→ 统一商户名)
|
||||
|
||||
**第二阶段 — Firefly III / Data Importer 负责(兜底与补充)**:
|
||||
|
||||
- 最后一层字段兼容适配
|
||||
- 临时补充规则
|
||||
- 与 Firefly III 导入格式保持兼容
|
||||
|
||||
**选择本地规则映射为主的核心理由:**
|
||||
|
||||
1. **多源统一能力更强**:本地能先统一语义,再输出稳定格式
|
||||
2. **规则可沉淀**:用户长期积累的分类规则、商户别名、账户映射,不应绑定在某个导入器实例里
|
||||
3. **可解释性更高**:用户能在导入前看到"这条为何被分到餐饮/交通"
|
||||
4. **迁移性更好**:即使未来不使用 Data Importer,也能复用规则引擎
|
||||
|
||||
### 6.3 分层架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Web UI / CLI │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Adapter 层 │ 各平台账单解析器(插件化) │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Normalize 层 │ 字段标准化、统一交易模型转换 │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Match 层 │ 去重与链路合并 │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Rule 层 │ 分类/账户/标签/对手方映射 │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Export 层 │ 导出至 Data Importer / Firefly III │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Storage 层 │ SQLite 持久化 + 审计日志 │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**设计原则:**
|
||||
- 平台差异尽量收敛在 Adapter 层
|
||||
- 统一模型要稳定,避免被单个平台格式污染
|
||||
- 导入层与规则层解耦,便于未来替换下游系统
|
||||
|
||||
---
|
||||
|
||||
## 7. 核心功能模块
|
||||
|
||||
### 7.1 模块 A:数据源接入模块
|
||||
|
||||
负责接收和管理多来源账单文件。
|
||||
|
||||
**功能点:**
|
||||
|
||||
- 支持文件上传(CSV / Excel / 常见文本格式)
|
||||
- 支持来源类型自动识别或用户手动指定
|
||||
- 支持批量文件导入
|
||||
- 支持记录原始文件元信息(文件名、来源、导入时间、文件哈希值)
|
||||
|
||||
**首批支持来源:**
|
||||
|
||||
| 类型 | 平台 | 备注 |
|
||||
|------|------|------|
|
||||
| 支付平台 | 支付宝、微信支付 | 核心优先级 |
|
||||
| 传统银行 | 建设银行、工商银行、中信银行、汇丰银行 | 需考虑不同语言/地区的格式兼容 |
|
||||
| 生活服务 | 美团、京东 | 用于细化支付平台的笼统账单 |
|
||||
| 加密货币 | 币安(Binance)、ByBit | 优先支持现货/资金流水,衍生品后续扩展 |
|
||||
|
||||
> **产品建议**:电商/生活平台的账单主要用于**细化**支付平台的笼统记录。例如,将微信支付的"美团订单"替换为具体的"外卖-商家名"。
|
||||
|
||||
### 7.2 模块 B:解析与标准化模块
|
||||
|
||||
负责将不同来源账单解析为**统一交易模型**,屏蔽不同平台字段差异。
|
||||
|
||||
**统一交易模型核心字段:**
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| `transaction_id` | String | 系统内唯一 ID(自动生成) |
|
||||
| `source_platform` | Enum | 来源平台(alipay/wechat/ccb/icbc/...) |
|
||||
| `source_record_id` | String | 原始记录 ID / 交易流水号 |
|
||||
| `trade_time` | DateTime | 交易时间(统一为本地标准时区) |
|
||||
| `amount` | Decimal | 交易金额(高精度,正数) |
|
||||
| `currency` | String | 币种(CNY/USD/USDT/...) |
|
||||
| `direction` | Enum | 收入 / 支出 / 转账 / 退款 / 手续费 |
|
||||
| `counterparty` | String | 交易对手 |
|
||||
| `merchant_name` | String | 商户名 |
|
||||
| `category_raw` | String | 原始分类(平台提供) |
|
||||
| `category_mapped` | String | 映射后分类(规则引擎输出) |
|
||||
| `order_id` | String | 订单号 |
|
||||
| `parent_order_id` | String | 父链路号(用于链路合并) |
|
||||
| `note` | String | 备注 |
|
||||
| `raw_payload` | JSON | 原始记录快照(完整保留) |
|
||||
| `import_batch_id` | String | 导入批次 |
|
||||
| `status` | Enum | 待清洗 / 待导入 / 已导入 / 失败 |
|
||||
|
||||
**标准化规则:**
|
||||
|
||||
- 时间统一为本地标准时区(UTC+8)
|
||||
- 金额统一为 Decimal 高精度保存
|
||||
- 正负号规则统一:独立 `direction` 字段 + 正金额值
|
||||
- 交易类型统一到平台无关的业务枚举
|
||||
|
||||
### 7.3 模块 C:去重与链路合并模块
|
||||
|
||||
这是本系统的**核心亮点**,负责识别重复流水与还原真实交易链路。
|
||||
|
||||
#### 7.3.1 去重目标
|
||||
|
||||
解决以下典型问题:
|
||||
|
||||
- 同一账单文件被重复导入
|
||||
- 同一交易在多个来源重复出现(如银行卡转支付宝同时出现在两方账单)
|
||||
- 同一文件中存在重复记录
|
||||
|
||||
#### 7.3.2 链路合并目标
|
||||
|
||||
解决以下典型问题:
|
||||
|
||||
- 一笔真实消费对应多条流水(支付、优惠、退款、手续费)
|
||||
- 同一订单在不同平台产生镜像记录(如京东订单 + 微信支付流水)
|
||||
- 跨账户资金流动产生的两笔独立记录
|
||||
|
||||
#### 7.3.3 三层去重策略
|
||||
|
||||
采用"**基础去重 → 模糊去重 → 链路合并**"三层递进模型:
|
||||
|
||||
**A. 基础去重(严格去重 — 精确匹配)**
|
||||
|
||||
基于以下唯一性组合进行绝对去重,确保同一份账单多次上传不会重复落库:
|
||||
|
||||
- 来源平台 + 原始记录 ID(`source_platform` + `source_record_id`)
|
||||
- 文件哈希 + 行指纹
|
||||
- 订单号 / 交易单号(若可信)
|
||||
|
||||
**B. 模糊去重(相似去重 — 多因子评分)**
|
||||
|
||||
当缺少唯一 ID 时,使用以下组合进行评分匹配:
|
||||
|
||||
- 时间窗(如 ±5 分钟,可配置)
|
||||
- 金额精准一致(考虑手续费设置极小金额容差)
|
||||
- 交易方向一致
|
||||
- 对手方相似
|
||||
- 订单号相同或相近
|
||||
- 来源平台关联规则命中
|
||||
|
||||
> **多因子判定升级**:原始需求中提出"时间窗+金额双重校验"作为起点,实际应升级为**"时间窗 + 金额 + 方向 + 订单号 + 对手方 + 来源规则"的多因子判定机制**,以覆盖真实复杂场景。
|
||||
|
||||
**C. 链路合并(转账闭环)**
|
||||
|
||||
对跨账户资金流动与同一业务链路的记录进行聚合:
|
||||
|
||||
- **典型场景**:银行卡支出 1000 元(流向支付宝),支付宝收入 1000 元 → 合并为一笔**内部转账(Transfer)**,源账户=银行卡,目标账户=支付宝
|
||||
- **主交易 + 附属事件**:消费/收入主体 + 手续费、退款、优惠抵扣、汇率损耗
|
||||
|
||||
#### 7.3.4 置信度与人工干预
|
||||
|
||||
- 高置信度记录:自动合并
|
||||
- 低置信度记录:标记为"疑似重复/疑似链路",进入人工确认队列
|
||||
- 所有合并操作可回溯、可撤销
|
||||
|
||||
### 7.4 模块 D:规则映射模块
|
||||
|
||||
负责将标准化交易映射到最终记账语义。
|
||||
|
||||
**规则映射内容:**
|
||||
|
||||
| 映射类型 | 说明 | 示例 |
|
||||
|----------|------|------|
|
||||
| 分类映射 | 交易 → 预设分类 | "美团外卖" → 餐饮 |
|
||||
| 账户映射 | 来源 → 账户名 | 微信支付 → 微信零钱 |
|
||||
| 对手方映射 | 商户名标准化 | "饿了么-xxx店" → "饿了么" |
|
||||
| 标签映射 | 交易 → 标签 | 可标记为:报销、家庭、订阅、投资 |
|
||||
| Firefly III 字段映射 | 内部字段 → FF3 字段 | direction → type (withdrawal/deposit/transfer) |
|
||||
|
||||
**规则配置能力:**
|
||||
|
||||
- 支持基于正则、关键词、金额范围等条件的规则定义
|
||||
- 支持规则优先级排序
|
||||
- 规则命中结果可精确解释(每条交易展示命中的具体规则)
|
||||
- 支持规则模板库,预置常见映射
|
||||
|
||||
### 7.5 模块 E:导入编排模块
|
||||
|
||||
负责将清洗后的数据导入 Firefly III 生态。
|
||||
|
||||
**模式 A:API 推送模式(优先)**
|
||||
|
||||
- 通过 Webhook 或直接调用 Data Importer / Firefly III API
|
||||
- 自动发起导入任务
|
||||
- "本地清洗完毕 → 自动触发 DataImporter 导入任务"的丝滑体验
|
||||
- 可追踪返回结果
|
||||
|
||||
**模式 B:中间文件导出模式**
|
||||
|
||||
- 生成完全符合 Data Importer 规范的标准 CSV / JSON
|
||||
- 用户手动导入
|
||||
- 适合 API 不稳定或权限受限场景
|
||||
|
||||
**导入前校验:**
|
||||
|
||||
- 必填字段完整性校验
|
||||
- 金额/时间格式校验
|
||||
- 账户映射完整性校验
|
||||
- 重复导入拦截
|
||||
|
||||
**导入后反馈:**
|
||||
|
||||
- 导入成功/失败数量统计
|
||||
- 失败原因分类展示
|
||||
- 失败记录可单独重试(无需整批重做)
|
||||
|
||||
### 7.6 模块 F:本地存储与审计模块
|
||||
|
||||
负责数据持久化与全链路可追溯性。
|
||||
|
||||
**SQLite 核心数据表:**
|
||||
|
||||
| 表名 | 说明 |
|
||||
|------|------|
|
||||
| `source_files` | 原始文件表(文件名、哈希、来源、导入时间) |
|
||||
| `raw_records` | 原始解析记录表(原始数据快照) |
|
||||
| `transactions` | 标准交易表(统一模型) |
|
||||
| `dedup_relations` | 去重关系表(记录合并依据) |
|
||||
| `rules` | 规则配置表 |
|
||||
| `import_tasks` | 导入任务表 |
|
||||
| `import_results` | 导入结果表 |
|
||||
| `audit_logs` | 操作日志表 |
|
||||
|
||||
**设计目标:**
|
||||
|
||||
- 支持重跑:任意阶段可重新执行
|
||||
- 支持审计:完整记录每条交易的处理全过程
|
||||
- 支持回溯:任一交易可追溯到来源文件、来源平台、经过的规则处理链
|
||||
|
||||
---
|
||||
|
||||
## 8. 核心用户场景
|
||||
|
||||
### 场景 1:月度账单统一入账
|
||||
|
||||
用户每月从支付宝、微信、银行导出账单,批量上传后,系统自动清洗并去重,用户预览确认后一键导入 Firefly III。
|
||||
|
||||
### 场景 2:跨平台订单去重
|
||||
|
||||
用户在京东下单,通过微信支付。京东账单与微信账单均包含该笔信息。系统识别为同一订单链路,仅保留主交易并记录来源关联。
|
||||
|
||||
### 场景 3:跨账户转账闭环
|
||||
|
||||
用户从建行卡转入 1000 元到支付宝。银行账单显示"支出 1000",支付宝账单显示"收入 1000"。系统匹配时间窗 + 金额,将两笔记录合并为一笔内部转账。
|
||||
|
||||
### 场景 4:交易所流水整理
|
||||
|
||||
用户导入币安和 ByBit 资金流水,系统将充提币、手续费、现货买卖拆分为统一的账务事件,并映射到投资类账户与标签。支持将 Crypto 交易折算为基础法币或保留原始币种。
|
||||
|
||||
### 场景 5:导入失败快速修复
|
||||
|
||||
某次批量导入中 5 条记录因账户映射缺失而失败。用户在失败列表中查看原因,补充规则后仅重试这 5 条,无需重做整批。
|
||||
|
||||
---
|
||||
|
||||
## 9. 功能优先级
|
||||
|
||||
### P0 — 必须有(MVP 核心)
|
||||
|
||||
| # | 功能 |
|
||||
|---|------|
|
||||
| 1 | 文件上传与批量导入 |
|
||||
| 2 | 来源类型识别/选择 |
|
||||
| 3 | 多来源解析器框架(插件化) |
|
||||
| 4 | 统一交易模型 |
|
||||
| 5 | 本地 SQLite 持久化 |
|
||||
| 6 | 基础去重(严格去重) |
|
||||
| 7 | 链路合并(转账闭环) |
|
||||
| 8 | 基础规则映射(分类/账户) |
|
||||
| 9 | 导入预览与确认 |
|
||||
| 10 | API / 文件两种导入方式 |
|
||||
| 11 | 导入日志与失败重试 |
|
||||
|
||||
### P1 — 应该有
|
||||
|
||||
| # | 功能 |
|
||||
|---|------|
|
||||
| 1 | 模糊去重(多因子评分) |
|
||||
| 2 | 规则模板库 |
|
||||
| 3 | 商户别名归一化 |
|
||||
| 4 | 用户可配置时间窗与去重阈值 |
|
||||
| 5 | 导入批次管理 |
|
||||
| 6 | 手动合并/手动拆分疑似交易链路 |
|
||||
| 7 | 标签映射 |
|
||||
|
||||
### P2 — 可以有
|
||||
|
||||
| # | 功能 |
|
||||
|---|------|
|
||||
| 1 | 自动来源识别增强(智能推断文件类型) |
|
||||
| 2 | 可视化规则调试 |
|
||||
| 3 | 简易统计报表(导入概览、分类占比) |
|
||||
| 4 | 多账本导入支持 |
|
||||
| 5 | 对账可视化(展示未匹配的"孤儿"转账记录) |
|
||||
| 6 | 加密货币多币种与法币折算 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 产品信息架构
|
||||
|
||||
### 10.1 一级模块
|
||||
|
||||
```
|
||||
ProjectMoneyX
|
||||
├── 导入中心 # 文件上传、批次管理
|
||||
├── 数据清洗 # 解析结果、标准化预览
|
||||
├── 去重处理 # 重复记录、链路合并、人工确认
|
||||
├── 规则管理 # 分类/账户/标签/对手方规则配置
|
||||
├── 导入任务 # 导入执行、结果查看、失败重试
|
||||
├── 数据审计 # 全链路追溯、操作日志
|
||||
└── 系统设置 # Firefly III 连接配置、时间窗参数等
|
||||
```
|
||||
|
||||
### 10.2 关键页面
|
||||
|
||||
| 页面 | 说明 |
|
||||
|------|------|
|
||||
| 文件上传页 | 拖拽/选择文件,选择或自动识别来源类型 |
|
||||
| 导入批次详情页 | 展示批次内所有记录和处理状态 |
|
||||
| 清洗结果预览页 | 展示标准化后的交易列表,支持逐条查看映射详情 |
|
||||
| 重复记录处理页 | 展示疑似重复/链路合并记录,支持人工确认或拒绝 |
|
||||
| 规则配置页 | 可视化配置分类、账户、标签映射规则 |
|
||||
| 导入结果页 | 展示导入成功/失败统计,失败可重试 |
|
||||
| 审计追溯页 | 查看任一交易的完整处理链路 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 关键交互原则
|
||||
|
||||
1. **先预览,后导入**:任何清洗结果必须允许用户确认后再执行导入
|
||||
2. **规则可解释**:每条交易应展示命中的具体规则和分类依据
|
||||
3. **重复可回溯**:被判定重复/合并的记录必须可查看判定依据与原始数据
|
||||
4. **失败可重试**:导入失败不应要求整批重做,支持单条/选择性重试
|
||||
5. **操作可逆**:合并、分类等操作均可撤销回滚
|
||||
|
||||
---
|
||||
|
||||
## 12. 非功能需求
|
||||
|
||||
### 12.1 安全与隐私
|
||||
|
||||
- **本地优先原则**:鉴于财务数据的极度敏感性,完全采用本地化部署(Docker / 本地命令行 / 本地 Web UI)
|
||||
- SQLite 数据库仅存在于本地,敏感账单数据默认不上传云端
|
||||
- API Token 加密存储
|
||||
- 操作日志不泄露敏感字段
|
||||
|
||||
### 12.2 性能
|
||||
|
||||
- 单次导入 1 万条记录应可完成解析与清洗
|
||||
- 去重计算应在合理时间内完成(建议 30 秒内完成主流程)
|
||||
|
||||
### 12.3 可维护性
|
||||
|
||||
- **插件化架构**:解析器(Parser)设计为独立模块,银行/平台格式变更时只需更新对应 Parser,无需重构主程序
|
||||
- **规则引擎可扩展**:支持新增规则类型和匹配条件
|
||||
- **去重策略可配置**:时间窗、金额容差、置信度阈值均可配置
|
||||
|
||||
### 12.4 可追溯性
|
||||
|
||||
- 任一导入结果必须可追溯至原始文件与原始记录
|
||||
- 任一规则命中必须可解释
|
||||
- 任一合并操作必须记录判定依据
|
||||
|
||||
---
|
||||
|
||||
## 13. 版本规划
|
||||
|
||||
### V1.0(MVP)
|
||||
|
||||
- 支付宝 / 微信 / 2 家银行账单支持
|
||||
- 文件导入、解析、标准化
|
||||
- SQLite 持久化
|
||||
- 基础去重(严格去重)
|
||||
- 基础规则映射(分类/账户)
|
||||
- Data Importer API 导入 + CSV 导出
|
||||
- 导入预览与确认
|
||||
|
||||
### V1.5
|
||||
|
||||
- 美团 / 京东账单支持
|
||||
- 链路合并增强(转账闭环 + 订单链路聚合)
|
||||
- 模糊去重(多因子评分)
|
||||
- 批次管理与失败重试
|
||||
- 手动修正与确认流程
|
||||
- 商户别名归一化
|
||||
|
||||
### V2.0
|
||||
|
||||
- 币安 / ByBit 交易所流水适配
|
||||
- 高级规则系统(模板库 + 可视化调试)
|
||||
- 对账可视化(孤儿记录展示 + 手动干预)
|
||||
- 简易统计报表(导入概览、分类占比)
|
||||
- 多账本 / 多环境支持
|
||||
- 加密货币多币种管理(法币折算 / 多货币对接)
|
||||
|
||||
---
|
||||
|
||||
## 14. 风险与应对策略
|
||||
|
||||
| # | 风险 | 影响 | 应对策略 |
|
||||
|---|------|------|----------|
|
||||
| 1 | 不同平台账单格式频繁变化 | 解析器失效 | 采用插件化解析器 + 版本化适配,格式变更只需更新对应 Parser |
|
||||
| 2 | 去重误判(误合并/漏合并) | 数据准确性受损 | 采用"严格+模糊"分层策略;低置信度记录进人工确认队列 |
|
||||
| 3 | 交易所流水语义复杂 | 解析困难 | V1 仅支持资金流水和基础现货,衍生品/复杂划转后续扩展 |
|
||||
| 4 | 过度依赖 Data Importer | 耦合风险 | 核心规则与标准化能力沉淀在本地,导入器仅作为输出目标之一 |
|
||||
| 5 | 加密货币汇率波动 | 金额折算不稳定 | 支持保留原始币种,汇率折算为可选项,对接 Firefly III 多货币系统 |
|
||||
|
||||
---
|
||||
|
||||
## 15. 参考项目
|
||||
|
||||
| 项目 | 说明 |
|
||||
|------|------|
|
||||
| [double-entry-generator](https://github.com/deb-sig/double-entry-generator) | 复式记账生成工具,核心参考项目 |
|
||||
| [Firefly III](https://github.com/firefly-iii/firefly-iii) | 目标对接的个人财务管理系统 |
|
||||
| [Data Importer](https://github.com/firefly-iii/data-importer) | Firefly III 的数据导入器 |
|
||||
| [Firefly III Docs](https://docs.firefly-iii.org/) | Firefly III 官方文档 |
|
||||
|
||||
---
|
||||
|
||||
## 16. 总结
|
||||
|
||||
ProjectMoneyX 不是一个"简单导入工具",而是一个面向 Firefly III 的**本地账单数据治理中台**。
|
||||
|
||||
其核心价值可以浓缩为:
|
||||
|
||||
> 1. **汇聚多源账单** — 一站式接入支付平台、银行、生活服务、交易所
|
||||
> 2. **统一交易语义** — 屏蔽平台差异,建立标准化交易模型
|
||||
> 3. **智能去重合并** — 消除重复,还原真实交易链路与转账闭环
|
||||
> 4. **本地规则沉淀** — 分类/账户/标签映射可长期积累、可解释、可迁移
|
||||
> 5. **无缝对接导入** — 丝滑推送至 Firefly III / Data Importer
|
||||
|
||||
**核心产品决策:**
|
||||
|
||||
> - **规则映射以本地为主,Data Importer 为辅**
|
||||
> - **去重策略从"时间窗+金额"升级为多因子判定**
|
||||
> - **SQLite 不仅是缓存,更是清洗结果与审计链路的核心数据底座**
|
||||
> - **插件化架构确保可持续维护**
|
||||
1959
17-ProjectMoneyX/3-实现详细稿/2-ProjectMoneyX-DDS.md
Normal file
1959
17-ProjectMoneyX/3-实现详细稿/2-ProjectMoneyX-DDS.md
Normal file
File diff suppressed because it is too large
Load Diff
951
17-ProjectMoneyX/3-实现详细稿/dds-chatgpt.md
Normal file
951
17-ProjectMoneyX/3-实现详细稿/dds-chatgpt.md
Normal file
@@ -0,0 +1,951 @@
|
||||
# ProjectMoneyX 系统详细设计说明书(DDS)
|
||||
|
||||
**项目名称**:ProjectMoneyX
|
||||
**文档类型**:系统详细设计说明书
|
||||
**版本**:v1.0
|
||||
**设计目标**:构建面向 Firefly III 生态的本地化多源账单数据治理中间件,实现账单导入、解析、标准化、去重、链路合并、规则映射与导入编排闭环。
|
||||
|
||||
---
|
||||
|
||||
## 1. 设计目标与范围
|
||||
|
||||
### 1.1 设计目标
|
||||
|
||||
本系统负责将多源账单文件(优先支付宝、微信)导入后,完成以下处理链路:
|
||||
|
||||
1. 原始文件接入与批次化管理
|
||||
2. 多平台账单解析与字段标准化
|
||||
3. 统一交易模型入库
|
||||
4. 严格去重、模糊去重、链路合并
|
||||
5. 分类/账户/标签/商户归一化规则映射
|
||||
6. 导出为 Firefly III / Data Importer 可消费的数据格式
|
||||
7. 提供预览、审计、失败重试与可回溯能力。
|
||||
|
||||
### 1.2 本期范围(V1 / MVP)
|
||||
|
||||
* 支持支付宝、微信账单导入
|
||||
* 支持 CSV / Excel / 常见文本格式
|
||||
* 支持本地 SQLite 持久化
|
||||
* 支持基础规则映射(分类/账户)
|
||||
* 支持严格去重 + 转账闭环链路合并
|
||||
* 支持导入预览与确认
|
||||
* 支持 API 推送或中间文件导出至 Firefly III / Data Importer。
|
||||
|
||||
### 1.3 非目标
|
||||
|
||||
* 不直接登录第三方平台抓取账单
|
||||
* 不实现完整 BI 平台
|
||||
* 不替代 Firefly III 本体记账能力
|
||||
* 不做高频实时同步。
|
||||
|
||||
---
|
||||
|
||||
## 2. 需求分析与架构判断
|
||||
|
||||
### 2.1 核心业务意图
|
||||
|
||||
PRD 的真实意图不是“导入工具”,而是一个 **本地账单数据治理层**,核心是先统一语义与规则,再输出给 Firefly III。换言之,系统的重点不在“上传文件”,而在:
|
||||
|
||||
* 多源异构字段收敛
|
||||
* 多因子去重与链路恢复
|
||||
* 可沉淀、可解释、可迁移的本地规则体系。
|
||||
|
||||
### 2.2 关键设计约束
|
||||
|
||||
1. **本地优先**:财务数据敏感,必须本地部署,默认不上传云端。
|
||||
2. **插件化解析器**:平台格式变化频繁,适配逻辑必须隔离。
|
||||
3. **统一交易模型稳定**:避免下游 Firefly III 或上游平台格式污染核心域模型。
|
||||
4. **支付宝分类为主标准**:账单说明明确支付宝交易类型最丰富,其他平台应映射到支付宝分类体系。
|
||||
5. **微信分类需推断**:微信“交易类型”较粗,需要结合“商品”字段推断细分分类。
|
||||
|
||||
### 2.3 技术风险
|
||||
|
||||
* 平台格式变更导致解析失败
|
||||
* 模糊去重误判造成误合并
|
||||
* 内部转账闭环识别不准确
|
||||
* Firefly III 字段映射不完整导致导入失败
|
||||
* 用户规则不断增加后性能退化。
|
||||
|
||||
---
|
||||
|
||||
## 3. 总体架构设计
|
||||
|
||||
## 3.1 分层架构
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
UI[Web UI / CLI]
|
||||
API[GIN API Layer]
|
||||
APP[Application Service Layer]
|
||||
ADAPTER[Adapter Layer\n账单解析器插件]
|
||||
NORMALIZE[Normalize Layer\n字段标准化]
|
||||
MATCH[Match Layer\n去重/链路合并]
|
||||
RULE[Rule Engine Layer\n分类/账户/标签映射]
|
||||
EXPORT[Export Layer\nFirefly III / Data Importer 适配]
|
||||
REPO[Repository Layer\nGORM]
|
||||
DB[(SQLite)]
|
||||
FF[Firefly III / Data Importer]
|
||||
|
||||
UI --> API
|
||||
API --> APP
|
||||
APP --> ADAPTER
|
||||
APP --> NORMALIZE
|
||||
APP --> MATCH
|
||||
APP --> RULE
|
||||
APP --> EXPORT
|
||||
APP --> REPO
|
||||
REPO --> DB
|
||||
EXPORT --> FF
|
||||
```
|
||||
|
||||
### 3.2 分层职责
|
||||
|
||||
* **UI 层**:上传文件、批次管理、预览确认、规则配置、人工确认、导入结果展示
|
||||
* **API 层**:RESTful 接口,统一鉴权、参数校验、响应封装
|
||||
* **应用服务层**:编排完整业务流程,不承载具体解析规则
|
||||
* **Adapter 层**:按平台解析原始文件,输出平台原始记录 DTO
|
||||
* **Normalize 层**:统一字段、金额、方向、时间、分类原始值
|
||||
* **Match 层**:严格去重、模糊去重、链路聚合、转账闭环
|
||||
* **Rule 层**:分类、账户、对手方、标签映射
|
||||
* **Export 层**:适配 Firefly III / Data Importer API 或 CSV/JSON
|
||||
* **Repository 层**:隔离数据库访问,面向领域对象持久化。
|
||||
|
||||
---
|
||||
|
||||
## 4. 系统模块划分
|
||||
|
||||
## 4.1 模块清单
|
||||
|
||||
| 模块 | 职责 | 优先级 |
|
||||
| ------------------- | --------------- | ----- |
|
||||
| import-center | 文件上传、批次管理、来源识别 | P0 |
|
||||
| parser-engine | 平台解析器装载与执行 | P0 |
|
||||
| normalize-engine | 统一模型转换 | P0 |
|
||||
| dedup-engine | 严格去重与模糊去重 | P0/P1 |
|
||||
| link-engine | 转账闭环与订单链路合并 | P0 |
|
||||
| rule-engine | 分类/账户/标签/商户归一 | P0/P1 |
|
||||
| import-orchestrator | 导入预览、执行、重试 | P0 |
|
||||
| audit-center | 审计日志、处理链追溯 | P0 |
|
||||
| settings-center | Firefly 配置、阈值参数 | P1 |
|
||||
|
||||
### 4.2 后端包结构建议(Go)
|
||||
|
||||
```text
|
||||
projectmoneyx/
|
||||
├── cmd/server
|
||||
├── internal/
|
||||
│ ├── handler/
|
||||
│ ├── service/
|
||||
│ ├── domain/
|
||||
│ │ ├── entity/
|
||||
│ │ ├── valueobject/
|
||||
│ │ ├── enum/
|
||||
│ │ └── repository/
|
||||
│ ├── parser/
|
||||
│ │ ├── alipay/
|
||||
│ │ ├── wechat/
|
||||
│ │ └── registry/
|
||||
│ ├── normalize/
|
||||
│ ├── matcher/
|
||||
│ ├── linker/
|
||||
│ ├── rule/
|
||||
│ ├── exporter/
|
||||
│ ├── dao/
|
||||
│ ├── dto/
|
||||
│ ├── middleware/
|
||||
│ └── config/
|
||||
├── migrations/
|
||||
└── web/
|
||||
```
|
||||
|
||||
### 4.3 前端结构建议(Vue3)
|
||||
|
||||
```text
|
||||
src/
|
||||
├── api/
|
||||
├── views/
|
||||
│ ├── ImportCenterView.vue
|
||||
│ ├── BatchDetailView.vue
|
||||
│ ├── PreviewView.vue
|
||||
│ ├── DedupReviewView.vue
|
||||
│ ├── RuleConfigView.vue
|
||||
│ ├── ImportTaskView.vue
|
||||
│ └── AuditTraceView.vue
|
||||
├── components/
|
||||
├── stores/
|
||||
├── types/
|
||||
└── router/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 核心业务流程设计
|
||||
|
||||
## 5.1 主流程时序图
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as User
|
||||
participant FE as Web UI
|
||||
participant API as Gin API
|
||||
participant IMP as Import Service
|
||||
participant PARSER as Parser Engine
|
||||
participant NORM as Normalize Engine
|
||||
participant MATCH as Match/Link Engine
|
||||
participant RULE as Rule Engine
|
||||
participant EXP as Export Engine
|
||||
participant DB as SQLite
|
||||
participant FF as Firefly/Data Importer
|
||||
|
||||
U->>FE: 上传账单文件
|
||||
FE->>API: 创建导入批次
|
||||
API->>IMP: startImport(batchId)
|
||||
IMP->>DB: 保存 source_files / import_batch
|
||||
IMP->>PARSER: 解析文件
|
||||
PARSER->>DB: 保存 raw_records
|
||||
IMP->>NORM: 标准化转换
|
||||
NORM->>DB: 保存 transactions(待清洗)
|
||||
IMP->>MATCH: 严格去重/模糊去重/链路合并
|
||||
MATCH->>DB: 保存 dedup_relations / link_relations
|
||||
IMP->>RULE: 应用映射规则
|
||||
RULE->>DB: 更新 category/account/tag
|
||||
API-->>FE: 返回预览结果
|
||||
U->>FE: 确认导入
|
||||
FE->>API: 执行导入
|
||||
API->>EXP: export(batchId)
|
||||
EXP->>FF: 调用 API / 导出 CSV
|
||||
FF-->>EXP: 返回结果
|
||||
EXP->>DB: 保存 import_results
|
||||
API-->>FE: 展示导入结果
|
||||
```
|
||||
|
||||
## 5.2 批次状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> CREATED
|
||||
CREATED --> UPLOADED: 文件已上传
|
||||
UPLOADED --> PARSED: 解析完成
|
||||
PARSED --> NORMALIZED: 标准化完成
|
||||
NORMALIZED --> MATCHED: 去重/链路完成
|
||||
MATCHED --> RULE_APPLIED: 规则映射完成
|
||||
RULE_APPLIED --> PREVIEW_READY: 可预览
|
||||
PREVIEW_READY --> IMPORTING: 用户确认导入
|
||||
IMPORTING --> IMPORT_SUCCESS: 全部成功
|
||||
IMPORTING --> PARTIAL_FAILED: 部分失败
|
||||
IMPORTING --> IMPORT_FAILED: 全部失败
|
||||
PARTIAL_FAILED --> RETRYING: 用户重试失败项
|
||||
RETRYING --> IMPORT_SUCCESS
|
||||
RETRYING --> PARTIAL_FAILED
|
||||
IMPORT_FAILED --> RETRYING
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 账单解析与标准化设计
|
||||
|
||||
## 6.1 解析器接口设计
|
||||
|
||||
```go
|
||||
type BillParser interface {
|
||||
Platform() string
|
||||
Detect(fileMeta FileMeta, header []string) bool
|
||||
Parse(ctx context.Context, filePath string) ([]RawBillRecord, error)
|
||||
}
|
||||
```
|
||||
|
||||
### 解析器注册中心
|
||||
|
||||
* 启动时注册所有 Parser
|
||||
* 上传后根据文件头、列名、用户指定来源进行匹配
|
||||
* 匹配失败时进入“未知来源待人工选择”状态
|
||||
|
||||
## 6.2 支付宝解析规则
|
||||
|
||||
支付宝字段包括:
|
||||
|
||||
* 交易时间
|
||||
* 交易分类
|
||||
* 交易对方
|
||||
* 对方账号
|
||||
* 商品说明
|
||||
* 收/支
|
||||
* 金额
|
||||
* 收/付款方式
|
||||
* 交易状态
|
||||
* 交易订单号
|
||||
* 商家订单号
|
||||
* 备注。
|
||||
|
||||
### 支付宝映射策略
|
||||
|
||||
| 原字段 | 目标字段 |
|
||||
| ------ | ----------------------------------- |
|
||||
| 交易时间 | trade_time |
|
||||
| 交易分类 | category_raw |
|
||||
| 交易对方 | counterparty |
|
||||
| 对方账号 | counterparty_account |
|
||||
| 商品说明 | merchant_name / note |
|
||||
| 收/支 | direction |
|
||||
| 金额 | amount |
|
||||
| 收/付款方式 | payment_method_raw |
|
||||
| 交易状态 | trade_status |
|
||||
| 交易订单号 | source_record_id / order_id |
|
||||
| 商家订单号 | merchant_order_id / parent_order_id |
|
||||
| 备注 | note |
|
||||
|
||||
### 特别说明
|
||||
|
||||
支付宝交易类型最丰富,系统将其作为 **一级业务分类基准字典**。其他平台最终都应落到这套分类枚举上。
|
||||
|
||||
## 6.3 微信解析规则
|
||||
|
||||
微信字段包括:
|
||||
|
||||
* 交易时间
|
||||
* 交易类型
|
||||
* 交易对方
|
||||
* 商品
|
||||
* 收/支
|
||||
* 金额(元)
|
||||
* 支付方式
|
||||
* 当前状态
|
||||
* 交易单号
|
||||
* 商户单号
|
||||
* 备注。
|
||||
|
||||
### 微信映射策略
|
||||
|
||||
| 原字段 | 目标字段 |
|
||||
| ----- | ----------------------------------- |
|
||||
| 交易时间 | trade_time |
|
||||
| 交易类型 | category_raw / wechat_trade_type |
|
||||
| 交易对方 | counterparty |
|
||||
| 商品 | merchant_name / product_desc |
|
||||
| 收/支 | direction |
|
||||
| 金额(元) | amount |
|
||||
| 支付方式 | payment_method_raw |
|
||||
| 当前状态 | trade_status |
|
||||
| 交易单号 | source_record_id / order_id |
|
||||
| 商户单号 | merchant_order_id / parent_order_id |
|
||||
| 备注 | note |
|
||||
|
||||
### 微信分类推断规则
|
||||
|
||||
由于微信“交易类型”较粗(如商户消费、扫二维码付款、转账、红包等),系统必须结合“商品”字段推断更细分类。
|
||||
|
||||
#### 示例推断逻辑
|
||||
|
||||
| 微信交易类型 | 商品关键词 | 推断分类 |
|
||||
| ------ | ----------- | --------- |
|
||||
| 商户消费 | 美团/外卖/餐厅/咖啡 | 餐饮美食 |
|
||||
| 商户消费 | 滴滴/打车/地铁/高铁 | 交通出行 |
|
||||
| 商户消费 | 京东/超市/便利店 | 日用百货 |
|
||||
| 商户消费 | 电费/水费/话费 | 充值缴费 |
|
||||
| 转账 | 无 | 转账红包 / 其他 |
|
||||
| 微信红包 | 无 | 转账红包 |
|
||||
| xxx-退款 | 无 | 退款 |
|
||||
|
||||
> 若商品内容无法识别,先落入“其他”,并允许用户通过规则管理补充映射。
|
||||
|
||||
## 6.4 统一交易模型
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Transaction {
|
||||
+string transaction_id
|
||||
+string source_platform
|
||||
+string source_record_id
|
||||
+datetime trade_time
|
||||
+decimal amount
|
||||
+string currency
|
||||
+string direction
|
||||
+string counterparty
|
||||
+string merchant_name
|
||||
+string category_raw
|
||||
+string category_mapped
|
||||
+string order_id
|
||||
+string parent_order_id
|
||||
+string note
|
||||
+json raw_payload
|
||||
+string import_batch_id
|
||||
+string status
|
||||
}
|
||||
```
|
||||
|
||||
该模型与 PRD 保持一致,作为系统核心领域对象。
|
||||
|
||||
### 标准化规则
|
||||
|
||||
1. 时间统一存储为 **Asia/Shanghai (UTC+8)**
|
||||
2. 金额统一使用正数,方向独立用 `direction` 表达
|
||||
3. 币种默认 CNY,后续可扩展多币种
|
||||
4. 状态初始为 `PENDING_CLEAN`
|
||||
5. 原始记录完整写入 `raw_payload` 以便审计。
|
||||
|
||||
---
|
||||
|
||||
## 7. 去重与链路合并设计
|
||||
|
||||
## 7.1 三层处理模型
|
||||
|
||||
PRD 明确采用:
|
||||
|
||||
* 基础去重(严格)
|
||||
* 模糊去重(多因子)
|
||||
* 链路合并(转账/订单闭环)。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[新标准化交易] --> B{严格去重}
|
||||
B -- 命中 --> X[标记重复并建立关系]
|
||||
B -- 未命中 --> C{模糊去重}
|
||||
C -- 高置信 --> X
|
||||
C -- 低置信 --> D[进入人工确认队列]
|
||||
C -- 未命中 --> E{链路合并}
|
||||
E -- 命中 --> F[生成合并链路]
|
||||
E -- 未命中 --> G[保留独立交易]
|
||||
```
|
||||
|
||||
## 7.2 严格去重
|
||||
|
||||
### 唯一判定键
|
||||
|
||||
1. `source_platform + source_record_id`
|
||||
2. `source_file_hash + row_fingerprint`
|
||||
3. `可信订单号(order_id)`
|
||||
|
||||
### 行指纹算法建议
|
||||
|
||||
对以下字段标准化后做 SHA256:
|
||||
|
||||
* trade_time(分钟粒度)
|
||||
* amount
|
||||
* direction
|
||||
* counterparty
|
||||
* merchant_name
|
||||
* order_id
|
||||
|
||||
这样可防止同一文件重复导入。
|
||||
|
||||
## 7.3 模糊去重
|
||||
|
||||
### 多因子评分模型
|
||||
|
||||
| 因子 | 分值 |
|
||||
| ---------- | -- |
|
||||
| 时间在 ±5 分钟内 | 30 |
|
||||
| 金额一致 | 30 |
|
||||
| 方向一致 | 10 |
|
||||
| 订单号相同/相近 | 15 |
|
||||
| 对手方相似 | 10 |
|
||||
| 来源关联规则命中 | 5 |
|
||||
|
||||
### 判定阈值
|
||||
|
||||
* `>= 85`:自动判定重复
|
||||
* `60 ~ 84`:疑似重复,进入人工确认
|
||||
* `< 60`:不判定重复
|
||||
|
||||
### 对手方相似算法
|
||||
|
||||
* 统一大小写/空格/符号
|
||||
* 去除平台前缀后再比较
|
||||
* 使用 `contains + Levenshtein` 混合评分
|
||||
|
||||
## 7.4 链路合并(转账闭环)
|
||||
|
||||
### 典型场景
|
||||
|
||||
* 银行卡支出 1000
|
||||
* 支付宝收入 1000
|
||||
* 时间接近、金额相同、方向互补
|
||||
|
||||
则合并为一笔内部转账:
|
||||
|
||||
* from_account = 银行卡
|
||||
* to_account = 支付宝
|
||||
* type = transfer。
|
||||
|
||||
### 转账识别规则
|
||||
|
||||
1. 金额一致
|
||||
2. 一条为支出,一条为收入
|
||||
3. 时间在可配置窗口内
|
||||
4. 来源平台不同但账户映射可闭环
|
||||
5. 非退款、非手续费
|
||||
|
||||
### 订单链路合并
|
||||
|
||||
对于“京东订单 + 微信支付”类场景:
|
||||
|
||||
* 保留更完整的业务记录为主交易
|
||||
* 其他记录挂为关联来源
|
||||
* 形成 `parent_order_id` 聚合链路。
|
||||
|
||||
---
|
||||
|
||||
## 8. 规则引擎设计
|
||||
|
||||
## 8.1 规则模型
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Rule {
|
||||
+string id
|
||||
+string rule_type
|
||||
+int priority
|
||||
+string platform_scope
|
||||
+json conditions
|
||||
+json actions
|
||||
+bool enabled
|
||||
}
|
||||
```
|
||||
|
||||
### 规则类型
|
||||
|
||||
* CATEGORY_MAPPING
|
||||
* ACCOUNT_MAPPING
|
||||
* COUNTERPARTY_NORMALIZE
|
||||
* TAG_MAPPING
|
||||
* FIREFLY_FIELD_MAPPING
|
||||
|
||||
## 8.2 规则匹配条件
|
||||
|
||||
支持:
|
||||
|
||||
* 平台
|
||||
* 原始分类
|
||||
* 交易类型
|
||||
* 商品/商户关键词
|
||||
* 金额范围
|
||||
* 方向
|
||||
* 对手方关键字
|
||||
* 正则匹配
|
||||
|
||||
### 示例
|
||||
|
||||
```json
|
||||
{
|
||||
"platform": "wechat",
|
||||
"conditions": {
|
||||
"trade_type": "商户消费",
|
||||
"product_keywords": ["美团", "外卖"]
|
||||
},
|
||||
"actions": {
|
||||
"category_mapped": "餐饮美食",
|
||||
"merchant_name_normalized": "美团"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8.3 执行顺序
|
||||
|
||||
1. 对手方归一化
|
||||
2. 商户归一化
|
||||
3. 分类映射
|
||||
4. 账户映射
|
||||
5. 标签映射
|
||||
6. Firefly 字段映射
|
||||
|
||||
### 原因
|
||||
|
||||
先做归一化,再做分类,可提升规则命中率与稳定性。
|
||||
|
||||
## 8.4 可解释性设计
|
||||
|
||||
每条交易保留:
|
||||
|
||||
* 命中的规则 ID
|
||||
* 命中条件摘要
|
||||
* 规则执行前后字段对比
|
||||
|
||||
用于前端“为何被分到餐饮/交通”的解释展示。
|
||||
|
||||
---
|
||||
|
||||
## 9. Firefly III / Data Importer 适配设计
|
||||
|
||||
## 9.1 导出模式
|
||||
|
||||
### 模式 A:API 推送
|
||||
|
||||
* 系统生成 Firefly 兼容 DTO
|
||||
* 调用 Data Importer / Firefly API
|
||||
* 接收导入结果并更新任务状态。
|
||||
|
||||
### 模式 B:文件导出
|
||||
|
||||
* 生成标准 CSV / JSON
|
||||
* 用户手动导入
|
||||
* 适用于 API 不可用或权限受限场景。
|
||||
|
||||
## 9.2 Firefly 交易类型映射
|
||||
|
||||
| 内部 direction | Firefly type |
|
||||
| ------------ | ----------------------- |
|
||||
| expense | withdrawal |
|
||||
| income | deposit |
|
||||
| transfer | transfer |
|
||||
| refund | deposit / reversal(按配置) |
|
||||
| fee | withdrawal |
|
||||
|
||||
## 9.3 导入前校验
|
||||
|
||||
* 必填字段完整
|
||||
* 金额与时间合法
|
||||
* 账户映射完整
|
||||
* 是否已导入过
|
||||
* 是否存在未确认疑似重复记录。
|
||||
|
||||
---
|
||||
|
||||
## 10. 数据库详细设计(SQLite)
|
||||
|
||||
## 10.1 ER 图
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
SOURCE_FILES ||--o{ RAW_RECORDS : contains
|
||||
SOURCE_FILES ||--o{ IMPORT_BATCHES : belongs_to
|
||||
IMPORT_BATCHES ||--o{ TRANSACTIONS : generates
|
||||
TRANSACTIONS ||--o{ DEDUP_RELATIONS : source
|
||||
TRANSACTIONS ||--o{ LINK_RELATIONS : linked
|
||||
TRANSACTIONS ||--o{ RULE_HITS : matched
|
||||
IMPORT_BATCHES ||--o{ IMPORT_TASKS : owns
|
||||
IMPORT_TASKS ||--o{ IMPORT_RESULTS : produces
|
||||
RULES ||--o{ RULE_HITS : referenced
|
||||
TRANSACTIONS ||--o{ AUDIT_LOGS : traced
|
||||
```
|
||||
|
||||
## 10.2 表结构
|
||||
|
||||
### 10.2.1 source_files
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --------------- | ------------ | ------------ |
|
||||
| id | varchar(36) | 主键 |
|
||||
| file_name | varchar(255) | 文件名 |
|
||||
| file_hash | varchar(64) | 文件哈希 |
|
||||
| source_platform | varchar(32) | 来源平台 |
|
||||
| file_type | varchar(32) | csv/xlsx/txt |
|
||||
| uploaded_at | datetime | 上传时间 |
|
||||
| batch_id | varchar(36) | 批次 ID |
|
||||
|
||||
### 10.2.2 raw_records
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| ---------------- | ------------ | ------- |
|
||||
| id | varchar(36) | 主键 |
|
||||
| source_file_id | varchar(36) | 来源文件 |
|
||||
| row_no | int | 行号 |
|
||||
| source_platform | varchar(32) | 平台 |
|
||||
| source_record_id | varchar(128) | 原始流水号 |
|
||||
| row_fingerprint | varchar(64) | 行指纹 |
|
||||
| raw_payload | text | 原始 JSON |
|
||||
| parse_status | varchar(32) | 解析状态 |
|
||||
| parse_error | text | 错误信息 |
|
||||
|
||||
### 10.2.3 transactions
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| ---------------- | ------------- | ----- |
|
||||
| id | varchar(36) | 主键 |
|
||||
| transaction_id | varchar(64) | 业务 ID |
|
||||
| batch_id | varchar(36) | 导入批次 |
|
||||
| source_platform | varchar(32) | 来源平台 |
|
||||
| source_record_id | varchar(128) | 原始记录号 |
|
||||
| trade_time | datetime | 交易时间 |
|
||||
| amount | decimal(18,6) | 金额 |
|
||||
| currency | varchar(16) | 币种 |
|
||||
| direction | varchar(16) | 方向 |
|
||||
| counterparty | varchar(255) | 对手方 |
|
||||
| merchant_name | varchar(255) | 商户名 |
|
||||
| category_raw | varchar(128) | 原始分类 |
|
||||
| category_mapped | varchar(128) | 映射分类 |
|
||||
| order_id | varchar(128) | 订单号 |
|
||||
| parent_order_id | varchar(128) | 父链路号 |
|
||||
| note | text | 备注 |
|
||||
| status | varchar(32) | 状态 |
|
||||
| imported_at | datetime | 导入时间 |
|
||||
|
||||
### 10.2.4 dedup_relations
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --------------------- | ----------- | ------------ |
|
||||
| id | varchar(36) | 主键 |
|
||||
| src_transaction_id | varchar(64) | 原交易 |
|
||||
| target_transaction_id | varchar(64) | 目标交易 |
|
||||
| relation_type | varchar(32) | strict/fuzzy |
|
||||
| confidence | int | 置信度 |
|
||||
| reason_json | text | 判定依据 |
|
||||
|
||||
### 10.2.5 link_relations
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --------------------- | ----------- | ------------------------- |
|
||||
| id | varchar(36) | 主键 |
|
||||
| parent_transaction_id | varchar(64) | 主交易 |
|
||||
| child_transaction_id | varchar(64) | 子交易 |
|
||||
| link_type | varchar(32) | transfer/order/refund/fee |
|
||||
| reason_json | text | 关联依据 |
|
||||
|
||||
### 10.2.6 rules
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --------------- | ----------- | ---- |
|
||||
| id | varchar(36) | 主键 |
|
||||
| rule_type | varchar(64) | 规则类型 |
|
||||
| priority | int | 优先级 |
|
||||
| platform_scope | varchar(32) | 平台范围 |
|
||||
| conditions_json | text | 条件 |
|
||||
| actions_json | text | 动作 |
|
||||
| enabled | bool | 是否启用 |
|
||||
|
||||
### 10.2.7 import_tasks / import_results / audit_logs
|
||||
|
||||
按 PRD 设计分别记录导入任务、结果与操作日志。
|
||||
|
||||
---
|
||||
|
||||
## 11. API 接口设计(Gin)
|
||||
|
||||
## 11.1 导入中心
|
||||
|
||||
### 上传账单文件
|
||||
|
||||
`POST /api/v1/import/batches`
|
||||
|
||||
* form-data:
|
||||
|
||||
* files[]
|
||||
* sourcePlatform(可选)
|
||||
* autoDetect(bool)
|
||||
|
||||
返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"batchId": "xxx",
|
||||
"status": "UPLOADED"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 获取批次详情
|
||||
|
||||
`GET /api/v1/import/batches/{batchId}`
|
||||
|
||||
### 触发解析与清洗
|
||||
|
||||
`POST /api/v1/import/batches/{batchId}/process`
|
||||
|
||||
### 获取预览结果
|
||||
|
||||
`GET /api/v1/import/batches/{batchId}/preview`
|
||||
|
||||
## 11.2 去重确认
|
||||
|
||||
### 获取疑似重复列表
|
||||
|
||||
`GET /api/v1/dedup/reviews?batchId=xxx`
|
||||
|
||||
### 确认合并
|
||||
|
||||
`POST /api/v1/dedup/reviews/{reviewId}/confirm`
|
||||
|
||||
### 拒绝合并
|
||||
|
||||
`POST /api/v1/dedup/reviews/{reviewId}/reject`
|
||||
|
||||
## 11.3 规则管理
|
||||
|
||||
* `GET /api/v1/rules`
|
||||
* `POST /api/v1/rules`
|
||||
* `PUT /api/v1/rules/{id}`
|
||||
* `DELETE /api/v1/rules/{id}`
|
||||
|
||||
## 11.4 导入执行
|
||||
|
||||
### 确认导入到 Firefly
|
||||
|
||||
`POST /api/v1/import/tasks`
|
||||
|
||||
### 获取导入结果
|
||||
|
||||
`GET /api/v1/import/tasks/{taskId}`
|
||||
|
||||
### 重试失败项
|
||||
|
||||
`POST /api/v1/import/tasks/{taskId}/retry`
|
||||
|
||||
---
|
||||
|
||||
## 12. 前端页面设计
|
||||
|
||||
## 12.1 信息架构
|
||||
|
||||
PRD 已定义一级模块:
|
||||
|
||||
* 导入中心
|
||||
* 数据清洗
|
||||
* 去重处理
|
||||
* 规则管理
|
||||
* 导入任务
|
||||
* 数据审计
|
||||
* 系统设置。
|
||||
|
||||
## 12.2 页面职责
|
||||
|
||||
### 导入中心
|
||||
|
||||
* 拖拽上传
|
||||
* 批量文件列表
|
||||
* 来源自动识别结果
|
||||
* 批次创建与处理按钮
|
||||
|
||||
### 清洗结果预览
|
||||
|
||||
* 交易列表
|
||||
* 原始字段 vs 标准字段对比
|
||||
* 规则命中说明
|
||||
* 待人工处理标记
|
||||
|
||||
### 去重处理页
|
||||
|
||||
* 疑似重复列表
|
||||
* 评分与命中因子展开
|
||||
* 合并/拒绝操作
|
||||
|
||||
### 规则配置页
|
||||
|
||||
* 规则列表
|
||||
* 优先级排序
|
||||
* 条件编辑器
|
||||
* 测试命中预览
|
||||
|
||||
### 导入结果页
|
||||
|
||||
* 成功/失败统计
|
||||
* 失败原因
|
||||
* 单条重试
|
||||
|
||||
### 审计追溯页
|
||||
|
||||
* 交易全处理链
|
||||
* 原始文件 → 原始记录 → 标准化 → 规则 → 导入结果
|
||||
|
||||
---
|
||||
|
||||
## 13. 非功能设计
|
||||
|
||||
## 13.1 性能
|
||||
|
||||
目标:单次 1 万条记录在主流程内完成解析与清洗,建议 30 秒内完成主要去重流程。
|
||||
|
||||
### 优化策略
|
||||
|
||||
* 批量插入 raw_records / transactions
|
||||
* 构建关键索引:
|
||||
|
||||
* `source_platform + source_record_id`
|
||||
* `batch_id`
|
||||
* `trade_time`
|
||||
* `order_id`
|
||||
* 模糊去重按时间分桶,降低全表扫描
|
||||
* 规则按平台和启用状态预筛选
|
||||
|
||||
## 13.2 安全
|
||||
|
||||
* API Token 加密存储
|
||||
* 审计日志默认脱敏(账号、订单号局部遮罩)
|
||||
* 本地部署,不上传云端。
|
||||
|
||||
## 13.3 可维护性
|
||||
|
||||
* 解析器插件化
|
||||
* 规则条件 JSON 化
|
||||
* 导入器解耦,可替换下游目标
|
||||
* 统一 DTO / VO / Entity 分层。
|
||||
|
||||
---
|
||||
|
||||
## 14. 关键实现建议(面向 Go + GIN + GORM)
|
||||
|
||||
## 14.1 分层规范
|
||||
|
||||
* `handler`:仅做参数绑定、返回
|
||||
* `service`:负责编排
|
||||
* `domain`:承载核心规则
|
||||
* `dao/repository`:数据访问
|
||||
* `parser/matcher/rule/exporter`:独立可测试组件
|
||||
|
||||
## 14.2 推荐关键对象
|
||||
|
||||
* `ImportBatchService`
|
||||
* `ParserRegistry`
|
||||
* `TransactionNormalizeService`
|
||||
* `DedupMatchService`
|
||||
* `TransferLinkService`
|
||||
* `RuleApplyService`
|
||||
* `FireflyExportService`
|
||||
* `AuditTraceService`
|
||||
|
||||
## 14.3 事务边界
|
||||
|
||||
建议以下阶段分别事务化:
|
||||
|
||||
1. 文件入库 + 原始记录入库
|
||||
2. 标准化结果落库
|
||||
3. 去重/链路关系落库
|
||||
4. 规则命中落库
|
||||
5. 导入结果落库
|
||||
|
||||
避免一个超长事务覆盖整个批次。
|
||||
|
||||
---
|
||||
|
||||
## 15. MVP 与后续版本演进建议
|
||||
|
||||
## 15.1 MVP(优先上线)
|
||||
|
||||
* 支付宝 / 微信 Parser
|
||||
* 严格去重
|
||||
* 转账闭环
|
||||
* 基础规则映射
|
||||
* 导入预览
|
||||
* CSV / API 两种导出
|
||||
|
||||
## 15.2 V1.5
|
||||
|
||||
* 模糊去重评分
|
||||
* 手动合并/拆分
|
||||
* 商户别名库
|
||||
* 批次管理增强
|
||||
|
||||
## 15.3 V2.0
|
||||
|
||||
* 京东 / 美团链路增强
|
||||
* 多币种
|
||||
* 可视化规则调试
|
||||
* 统计报表。
|
||||
|
||||
---
|
||||
|
||||
## 16. 结论
|
||||
|
||||
ProjectMoneyX 的最佳实现方式,不是把逻辑堆到 Firefly III 导入器里,而是建设一个本地、分层、插件化的 **账单治理中台**:
|
||||
|
||||
* **Adapter** 收敛平台差异
|
||||
* **Normalize** 建立统一交易语义
|
||||
* **Match/Link** 解决重复与交易链碎片
|
||||
* **Rule Engine** 沉淀可解释、可复用的分类知识
|
||||
* **Export** 以最小耦合接入 Firefly 生态。
|
||||
|
||||
同时,基于账单格式说明,V1 必须把下面两点做成产品级能力:
|
||||
|
||||
1. **支付宝分类字典作为统一分类基准**
|
||||
2. **微信“交易类型 + 商品”联合推断分类**。
|
||||
230
17-ProjectMoneyX/3-实现详细稿/dds-gemini.md
Normal file
230
17-ProjectMoneyX/3-实现详细稿/dds-gemini.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# ProjectMoneyX 系统详细设计说明书
|
||||
|
||||
## 1. 架构概览与技术选型
|
||||
|
||||
ProjectMoneyX 定位为 Firefly III 的前置数据治理层。系统核心目标是屏蔽多源账单(如支付宝、微信)的底层差异,通过清洗、去重、映射,最终生成规范化的账单数据。
|
||||
|
||||
### 1.1 技术栈基准
|
||||
|
||||
* **前端 (Frontend)**: Vue3 + TypeScript + Vuetify (提供规范的 Material Design 风格,适合本地管理后台界面)。
|
||||
* **后端 (Backend)**: Golang + GIN (高性能、轻量级的 Web 框架,适合提供 API 与静态服务)。
|
||||
* **数据层 (Database)**: SQLite + GORM (满足本地优先、保护隐私的需求,GORM 提供便捷的结构体映射能力)。
|
||||
* **部署架构**: Docker 容器化部署 / 跨平台二进制单体可执行文件(整合静态前端资源与后端服务)。
|
||||
|
||||
### 1.2 系统分层架构图
|
||||
|
||||
系统采用经典的领域驱动设计(DDD)分层思想,严格隔离各平台差异:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "展现层 (Vue3 + TS + Vuetify)"
|
||||
UI_Upload[导入中心/文件上传]
|
||||
UI_Preview[数据清洗预览]
|
||||
UI_Match[去重与链路确认]
|
||||
UI_Rule[规则与映射管理]
|
||||
UI_Task[导入任务与审计]
|
||||
end
|
||||
|
||||
subgraph "接入层 (GIN Framework)"
|
||||
API_File[文件上传 API]
|
||||
API_Data[数据流转 API]
|
||||
API_Config[系统配置 API]
|
||||
end
|
||||
|
||||
subgraph "业务逻辑层 (Core Domain)"
|
||||
subgraph "Adapter 解析层 (插件化)"
|
||||
Parser_Alipay[支付宝解析器]
|
||||
Parser_WeChat[微信解析器]
|
||||
Parser_Bank[银行解析器]
|
||||
end
|
||||
|
||||
Norm_Engine[Normalize 标准化引擎]
|
||||
Match_Engine[Match 去重与链路合并引擎]
|
||||
Rule_Engine[Rule 规则映射引擎]
|
||||
Export_Engine[Export 导出推送引擎]
|
||||
end
|
||||
|
||||
subgraph "数据持久层 (GORM + SQLite)"
|
||||
DB_Source[(SourceFiles)]
|
||||
DB_Raw[(RawRecords)]
|
||||
DB_Trans[(Transactions)]
|
||||
DB_Rule[(Rules & Dedup)]
|
||||
end
|
||||
|
||||
subgraph "外部系统 (External)"
|
||||
Firefly[Firefly III API]
|
||||
DataImporter[Data Importer]
|
||||
end
|
||||
|
||||
%% 关联关系
|
||||
UI_Upload --> API_File
|
||||
UI_Preview & UI_Match & UI_Rule & UI_Task --> API_Data
|
||||
|
||||
API_File --> Parser_Alipay
|
||||
API_File --> Parser_WeChat
|
||||
API_File --> Parser_Bank
|
||||
|
||||
Parser_Alipay & Parser_WeChat & Parser_Bank --> Norm_Engine
|
||||
Norm_Engine --> Match_Engine
|
||||
Match_Engine --> Rule_Engine
|
||||
Rule_Engine --> Export_Engine
|
||||
|
||||
Export_Engine --> Firefly
|
||||
Export_Engine --> DataImporter
|
||||
|
||||
Norm_Engine -.-> DB_Raw
|
||||
Match_Engine -.-> DB_Trans
|
||||
Rule_Engine -.-> DB_Rule
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心业务与数据流转设计
|
||||
|
||||
数据从原始文件到导入 Firefly III,经历了标准的 ETL(Extract, Transform, Load)过程。以下是核心数据管道时序图:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as 用户
|
||||
participant Web as 前端 (Vue3)
|
||||
participant API as 后端接口 (GIN)
|
||||
participant Adapter as Adapter层
|
||||
participant Norm as 标准化引擎
|
||||
participant Match as 去重引擎
|
||||
participant Rule as 规则引擎
|
||||
participant DB as SQLite (GORM)
|
||||
participant Export as 导出引擎
|
||||
|
||||
User->>Web: 上传账单文件 (如微信CSV)
|
||||
Web->>API: POST /api/v1/import/file
|
||||
API->>Adapter: 路由至对应平台 Parser
|
||||
Adapter->>DB: 存储原始文件元信息 (source_files)
|
||||
Adapter->>Norm: 解析每一行记录
|
||||
Norm->>Norm: 提取公共字段、规范化处理
|
||||
Norm->>DB: 批量入库 (raw_records & transactions 待清洗态)
|
||||
|
||||
API->>Match: 触发基础与模糊去重
|
||||
Match->>Match: 1. 严格唯一性检查<br/>2. 多因子相似评分<br/>3. 跨源转账合并
|
||||
Match->>DB: 更新交易状态与合并关系 (dedup_relations)
|
||||
|
||||
API->>Rule: 触发规则映射引擎
|
||||
Rule->>Rule: 执行分类/商户/账户映射
|
||||
Rule->>DB: 落盘映射结果 (category_mapped 等)
|
||||
|
||||
API-->>Web: 返回清洗与映射预览结果
|
||||
User->>Web: 确认无误,发起导入
|
||||
Web->>API: POST /api/v1/export/task
|
||||
API->>Export: 执行推送流程
|
||||
Export->>External System: 调用 Data Importer / FF3 API
|
||||
Export->>DB: 记录导入结果 (import_tasks/results)
|
||||
API-->>Web: 返回导入状态
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 关键模块详细设计
|
||||
|
||||
### 3.1 适配器层 (Adapter) 插件化设计
|
||||
|
||||
由于各平台格式多变,后端在 Golang 中必须抽象出统一的 `BillParser` 接口:
|
||||
|
||||
```go
|
||||
type BillParser interface {
|
||||
GetPlatform() string // 返回平台标识,如 "alipay", "wechat"
|
||||
Parse(file io.Reader) ([]*RawRecord, error)
|
||||
Normalize(raw *RawRecord) (*Transaction, error)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### 针对支付宝与微信的差异化适配策略
|
||||
|
||||
根据账单数据特征指南:
|
||||
|
||||
* **支付宝对齐策略**:支付宝拥有最为丰富的 22 种交易分类(餐饮美食、交通出行等)。将其定义为**系统全局基础分类基准 (`Category_Raw` 基准)**。
|
||||
* **微信推断策略**:微信的“交易类型”多为支付动作(如扫二维码付款、微信红包),无实际消费语义。在微信的 Adapter `Normalize` 实现中,需引入**基于“商品”字段的关键词推断机制**,提取词根后强行映射回支付宝的 22 种分类中,再流转至后续处理链路。
|
||||
|
||||
### 3.2 去重与链路合并模块 (Match Engine)
|
||||
|
||||
基于 PRD 的要求,设计三层递进去重状态机:
|
||||
|
||||
1. **基础去重 (Hash & ID Match)**:利用 `source_platform` + `source_record_id` 进行 O(1) 级别的哈希拦截。
|
||||
2. **模糊去重 (Multi-Factor Scoring)**:
|
||||
针对缺失唯一 ID 的跨表记录,采用多因子评分算法:
|
||||
|
||||
$$Score = W_{time} \cdot f(\Delta t) + W_{amount} \cdot f(\Delta amt) + W_{merchant} \cdot Sim(M_1, M_2)$$
|
||||
|
||||
|
||||
|
||||
*(时间容差设为默认 $\pm5$ 分钟,金额容差限额针对手续费特定配置)。*
|
||||
3. **链路合并 (Transfer Linkage)**:
|
||||
识别 `direction` 为出金和入金的两笔高分记录,若来源为 `CCB(建行)`,对手方为 `Alipay`,且时间金额一致,则自动将 `direction` 改写为 `Transfer`,关联 `parent_order_id`。
|
||||
|
||||
### 3.3 规则引擎层 (Rule Engine)
|
||||
|
||||
采用两段式规则映射,ProjectMoneyX 负责对齐语义与业务分类。
|
||||
|
||||
* **执行顺序**:对手方归一化 -> 账户映射 -> 标签打标 -> 最终分类映射。
|
||||
* **存储结构**:采用 JSON 序列化存储条件表达式,在 Go 中使用类似 `govaluate` 或自定义简单的 AST 引擎解析。
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据库结构设计 (GORM)
|
||||
|
||||
基于核心交易模型的要求,以下为关系实体(ER)设计:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
SOURCE_FILES ||--o{ RAW_RECORDS : contains
|
||||
RAW_RECORDS ||--|| TRANSACTIONS : normalizes_to
|
||||
TRANSACTIONS ||--o{ DEDUP_RELATIONS : has
|
||||
IMPORT_TASKS ||--o{ TRANSACTIONS : processes
|
||||
|
||||
SOURCE_FILES {
|
||||
string id PK
|
||||
string file_name
|
||||
string file_hash "文件指纹防重复上传"
|
||||
string source_platform
|
||||
datetime import_time
|
||||
}
|
||||
|
||||
TRANSACTIONS {
|
||||
string transaction_id PK "系统唯一ID"
|
||||
string source_platform "alipay/wechat/ccb等"
|
||||
string source_record_id "原始流水号"
|
||||
datetime trade_time "统一UTC+8时区时间"
|
||||
decimal amount "高精度金额,绝对值"
|
||||
string currency "CNY/USD等"
|
||||
string direction "收入/支出/转账/退款"
|
||||
string counterparty "交易对手"
|
||||
string merchant_name "商户名"
|
||||
string category_raw "原始分类"
|
||||
string category_mapped "映射后分类"
|
||||
string order_id "订单号"
|
||||
string parent_order_id "父链路号"
|
||||
string status "待清洗/待导入/已导入/失败"
|
||||
}
|
||||
|
||||
RULES {
|
||||
int id PK
|
||||
string rule_type "分类/账户/商户别名"
|
||||
string match_condition "JSON格式匹配规则"
|
||||
string target_value "映射目标值"
|
||||
int priority "优先级排序"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 核心接口设计规范 (GIN API)
|
||||
|
||||
系统遵循 RESTful 风格,采用 JSON 通信规范:
|
||||
|
||||
* `POST /api/v1/files/upload`:账单文件上传,采用 `multipart/form-data`,返回解析批次 `batch_id`。
|
||||
* `GET /api/v1/transactions`:分页获取当前批次的标准化交易记录,支持按状态(如:疑似重复、待确认)过滤。
|
||||
* `POST /api/v1/rules/evaluate`:触发重新评估本地规则(当用户修改分类映射规则后调用)。
|
||||
* `POST /api/v1/export/run`:一键触发推送逻辑,下发 `batch_id` 至 Data Importer 或 Firefly III。
|
||||
Reference in New Issue
Block a user