大量更新

This commit is contained in:
zeaslity
2026-03-18 16:16:47 +08:00
parent 8efefcc230
commit ed945abdf1
136 changed files with 28252 additions and 16 deletions

View 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 生态。
**模式 AAPI 推送模式(优先)**
- 通过 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.0MVP
- 支付宝 / 微信 / 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 不仅是缓存,更是清洗结果与审计链路的核心数据底座**
> - **插件化架构确保可持续维护**

File diff suppressed because it is too large Load Diff

View 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 导出模式
### 模式 AAPI 推送
* 系统生成 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可选
* autoDetectbool
返回:
```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. **微信“交易类型 + 商品”联合推断分类**

View 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经历了标准的 ETLExtract, 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。