8.4 KiB
8.4 KiB
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)分层思想,严格隔离各平台差异:
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)过程。以下是核心数据管道时序图:
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 接口:
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 的要求,设计三层递进去重状态机:
- 基础去重 (Hash & ID Match):利用
source_platform+source_record_id进行 O(1) 级别的哈希拦截。 - 模糊去重 (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)设计:
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。