大量更新

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,21 @@
你现在是一名策略产品经理,你擅长进行市场研究和竞品分析,以制定产品策略。你能把握行业趋势,了解用户需求,并在此基础上优化产品功能和用户体验。请在这个角色下为我解答以下问题。
----
你是一名出色的产品经理,能够根据用户的初始需求,理解用户需求的真实需求意图,改善客户不够完善的需求,形成专业、简练的需求文档。并且能够在基础需求上优化产品的额设计和功能
请根据要求,进行深度的思考,优化[1-初始需求稿.md]直接给出优化后的PRD
注意及要求如下
1. 括号内的内容需要关注,需要根据括号内的内容进行修改,是你需要给出建议的内容,正式文档中应该去掉括号及内容
2. 必要时候应该联网搜索,查询开源的项目实现等
----
你是一名出色的产品经理,请你根据[1-初始需求稿.md]客户的原始需求,审查[2-优化产品需求文档PRD.md],检查PRD文档是否完全满足原始需求;如果有更加优秀的设计方案,请给出修改建议
----
你是一名出色的产品经理,能够根据用户的初始需求,理解用户需求的真实需求意图,改善客户不够完善的需求,形成专业、简练的需求文档。并且能够在基础需求上优化产品的额设计和功能
你之前根据[1-初始需求稿.md]输出了[2-优化产品需求文档PRD.md], 目前初始需求有一些更新,见[1.1-初始需求稿.md],请你详细对比[1.1-初始需求稿.md]和[1-初始需求稿.md]之间的差异, 修改[2-优化产品需求文档PRD.md],得到新的需求文档

View File

@@ -0,0 +1,83 @@
# 个人财务分析系统
``` 项目名称: ProjectMoneyM ```
``` 项目版本: v1.0 ```
``` 项目编制日期: 2026-02-26 ```
## 数据来源
1. 数据来源
| 数据来源 | 最长周期 | 文件格式 | 说明 | 数据维度 |
| --- | --- | --- | --- | --- |
| 支付宝账单 | 1年 | csv | 第一来源 | 最全 |
| 微信账单 | 3个月 | csv | 第二来源 | 第二全 |
| 招商银行 | 1年 | pdf | 第三来源 | 第三全 |
| 京东商城 | 1年 | pdf | 第四来源 | 第四全 |
2. 数据解析工具
1. 能够读取不同格式的账单来源
2. 能够通过OCR的方式解析特定的收入数据
## 数据清洗及标准化
1. 时间维度清洗
1. 需要统一时间维度,统一为东八区时间,格式为yyyy-MM-dd HH:mm:ss
2. 数据展示环节 需要能够通过时间段进行筛选查询收支数据
2. 支付项目清洗
1. 需要过滤重复的支付项
2. 需要明确支付途径和支付卡
3. 例如,一笔支出,银行账单会记录支出,支付宝或者微信会记录支出,需要将这些重复的支付项合并
4. 支付途径为: 支付宝,微信,云闪付,京东,美团,拼多多
5. 实际支付卡为: 信用卡,借记卡,余额宝,微信钱包,支付宝钱包
6. 支出项目的账本归类
1. 一笔支出可以归于一个或者多个账本
2. 一笔支出需要在日常开支中进行分析,也需要在过年支出这种特殊的账本中进行分析
3. 支付金额清洗
1. 需要统一为标准的数据格式
4. 支出去向清洗
1. 需要将支出进行分类
2. 请参考支付宝的支出分类
## 收支情况 展示内容
```此部分重要使用前端图表工具进行绘图展示```
### 收支分析(请给出能够展示的图形类型)
1. 需要直观的看出结余情况, 收入大于支出,支出大于收入的对比
2. 时间维度为,月度,季度,年度,重点展示月度收支情况
3. 收支的最小维度为月度
### 收入分析(请给出能够展示的图形类型)
#### 收入趋势
1. 能够根据不同的时间维度进行收入的对比
2. 能够直观的展示收入的趋势
#### 收入总览
1. 收入来源占比分析
2. 时间维度,重点展示年度收入,季度收入
3. 收入的最小维度为月度
#### 收入
### 支出分析(请给出能够展示的图形类型)
#### 支出趋势
1. 能够根据不同的时间维度进行支出的对比
2. 能够直观的展示支出的趋势
#### 支出总览
1. 支出去向占比分析
2. 时间维度,重点展示年度支出,季度支出
3. 支出的最小维度为月度
### 展示内容导出
1. 支持将展示内容导出为图片
2. 支持将展示内容导出为PDF文件
## 技术栈
1. Golang
2. Vue
3. TypeScript
4. SQLite
5. ECharts(寻找适合的图表工具,不限于ECharts)

View File

@@ -0,0 +1,106 @@
# 产品需求文档 (PRD): ProjectMoneyX 个人全景财务分析系统
| 文档属性 | 详情 |
| --- | --- |
| **项目名称** | ProjectMoneyX |
| **版本号** | v1.2 (基于开源 ETL 架构优化版) |
| **编制日期** | 2026-02-26 |
| **文档状态** | 进行中 |
## 1. 项目背景与目标
### 1.1 项目背景
随着移动支付的普及,个人财务数据分散在支付宝、微信、各家银行及电商平台中。用户面临“账单碎片化”、“流水重复记录”等痛点。传统的记账软件通常依赖手动记录或单一的账单导入,缺乏灵活的规则引擎来处理复杂的跨账户对账。
### 1.2 项目目标
构建一套自动化、高精度的个人财务分析系统。借鉴开源社区成熟的双轨制记账流转架构,通过引入 `Provider` 解析器与 `Translate` 规则引擎实现多源数据的标准化转换IR并利用算法解决跨账户流水重复问题提供多维度的收支分析与预算管理功能。
---
## 2. 核心系统架构ETL 数据工作流
参考业内成熟方案,系统底层采用高度解耦的管道架构,确保后续极强的可扩展性:
**数据流转路径:** `原始账单 (Raw Files) -> 提供方解析 (Provider) -> 中间表示 (IR) -> 规则转换 (Translate) -> 数据库标准账单`
* **Provider 层:** 专注于“读”。屏蔽不同账单格式CSV, PDF, Excel的差异。
* **IR 层 (Intermediate Representation)** 统一的数据结构协议,作为 Provider 和 Translate 的桥梁。
* **Translate 层:** 专注于“洗”。基于 YAML/JSON 规则配置,执行分类映射、时间标准化与账户归属。
---
## 3. 数据采集与 Provider 模块 (Data Ingestion)
针对不同来源的账单,建立独立的 Provider 适配器。当某银行账单格式更新时,仅需修改或新增对应的 Provider不影响系统核心逻辑。
| 提供方 (Provider) | 原始格式 | 核心提取字段 | 数据权重 | 提取说明 |
| --- | --- | --- | --- | --- |
| **Alipay (支付宝)** | CSV | 订单号、商户、商品明细、金额 | **L1 (最高)** | 标准 CSV 解析,作为消费类主数据。 |
| **WeChat (微信支付)** | CSV | 交易单号、交易对方、交易类型 | **L2** | 预处理跳过表头,提取转账与红包标记。 |
| **Banks (招商/工行等)** | PDF/XLS | 交易日、交易摘要、收支金额 | **L3** | 作为资金实际扣款核对依据 (Reconciliation)。 |
| **JD/Meituan (电商)** | PDF/CSV | 订单明细、支付通道 | **L3** | 重点关注白条/月付等信用支付记录。 |
---
## 4. 数据转换与清洗逻辑 (Translate & Cleaning)
Translate 层是数据质量的核心把控者,负责将 IR 数据转换为最终的财务记录,并解决数据冲突。
### 4.1 Translate 规则引擎
建立基于配置文件的映射规则,实现自动化数据归位:
* **时间与时区标准化:** 统一转换为 ISO 8601 格式,所有国内交易归一化为东八区时间。
* **账户路由 (Account Routing)** * *规则示例:* 当 Provider 为 `Alipay`且原始数据中的支付方式为“招商银行信用卡”时资金来源Funding Source自动映射至用户的“招行信用卡”实体账户。
* **智能分类映射 (Category Mapping)**
* 根据交易对方 (Peer) 或 商品说明 (Item) 进行正则匹配。
* *规则示例:* `Peer` 包含“星巴克”或“瑞幸” -> 映射分类为 [餐饮-咖啡]。
### 4.2 交易链路合并与去重算法 (De-duplication)
同一笔交易会在支付平台(如微信)和资金源(如银行卡)各产生一条流水。系统通过**时间窗与金额双重校验**进行链路合并,而非粗暴删除。
**核心算法逻辑:**
设高权重账单记录为 $T_{primary}$(如支付宝),低权重账单记录为 $T_{secondary}$(如银行卡)。
当同时满足以下条件时,判定为同一条交易链路:
$$| Time(T_{primary}) - Time(T_{secondary}) | \le \Delta t \quad (\text{建议 } \Delta t = 120s)$$
$$Amount(T_{primary}) = Amount(T_{secondary})$$
**处理策略:**
1. 将两条记录在底层数据库建立关联Parent-Child 或 LinkID
2. 前端展示时,**合并为一笔记录**。保留 $T_{primary}$ 的丰富消费明细(如分类、商户名),将 $T_{secondary}$ 的账户信息作为该笔消费的资金出处。
---
## 5. 核心功能模块详述
### 5.1 全景仪表盘 (Dashboard)
* **资产负债表:** 实时聚合各账户总资产、总负债(信用卡/白条),计算净资产。
* **现金流概览:** 本月总收入 vs 总支出,环比上月 (MoM) 增减百分比。
### 5.2 账单查询与多维分析
* **组合漏斗筛选:** 支持时间范围、金额区间、支付渠道、资金账户、交易分类的多条件交叉查询。
* **可视化图表:**
* **消费结构:** 饼图展示各大类的支出占比。
* **资金流向 (Sankey Diagram)** 桑基图直观展示“收入源 -> 资金池 (账户) -> 支出分类”的完整链路。
### 5.3 预算管理
* **精细化限额:** 支持全局预算和分类预算(例如:设定“交通”每月额度 1000 元)。
* **阈值预警:** 当分类支出进度达到 80% 和 100% 时,系统触发视觉高亮预警。
---
## 6. 非功能需求 (NFR)
* **数据隐私 (Local-First)** 财务数据极其敏感,系统解析 (Provider) 和转换 (Translate) 过程应优先在客户端(本地环境)执行,拒绝未经加密的云端明文传输。

View File

@@ -0,0 +1,139 @@
# 产品需求文档 (PRD): ProjectMoneyX 个人全景财务分析系统
| 文档属性 | 详情 |
| --- | --- |
| **项目名称** | ProjectMoneyX |
| **版本号** | v1.1 (优化版) |
| **编制日期** | 2026-02-26 |
## 1. 项目背景与目标
### 1.1 项目背景
随着移动支付的普及个人财务数据分散在支付宝、微信、各家银行APP及电商平台中。用户难以通过单一平台获取全景财务状况面临“账单碎片化”、“流水重复记录”、“统计维度单一”等痛点。
### 1.2 项目目标
构建一套自动化、高精度的个人财务分析系统。通过ETL抽取、转换、加载技术整合多源数据利用算法解决跨账户流水重复问题提供多维度的收支分析、资产趋势及预算管理功能帮助用户实现“上帝视角”的财务管控。
---
## 2. 数据源与采集规范 (Data Ingestion)
系统需支持多格式、多来源的账单导入,并建立可扩展的解析适配器模式。
| 数据来源 | 原始格式 | 数据周期 | 解析策略 | 数据权重 | 备注 |
| --- | --- | --- | --- | --- | --- |
| **支付宝** | CSV | 1年 | Pandas直接读取 | **L1 (最高)** | 包含商品明细,作为消费类主数据 |
| **微信支付** | CSV | 3个月 | Pandas预处理 (表头清洗) | **L2** | 包含转账与社交红包,需特殊标记 |
| **招商银行** | PDF | 1年 | 文本流解析 (pdfplumber) | **L3** | 作为资金来源核对依据 (Reconciliation) |
| **京东金融** | PDF/XLS | 1年 | 文本流解析 / OCR辅助 | **L3** | 重点关注“白条”类信贷数据 |
| **云闪付** | PDF/CSV | 1年 | 适配器解析 | **L3** | 银联通道补充数据 |
**功能要求:**
* **适配器模式Adapter Pattern** 针对不同来源开发独立的解析类Parser Class当银行账单格式变更时仅需更新对应解析器。
* **OCR 增强解析:** 针对图片格式的账单或非标准的扫描版PDF集成 OCR 引擎(如 PaddleOCR进行关键字段日期、金额、商户提取。
---
## 3. 数据清洗与核心逻辑 (Data Cleaning & Logic)
这是本系统的核心壁垒,重点解决多渠道数据冲突与标准化问题。
### 3.1 时间维度标准化
* **存储标准:** 所有交易时间戳统一转换为 **ISO 8601** 格式存储。
* **时区处理:** 统一归一化为 `UTC+8`。若涉及跨国交易(如外币信用卡),需保留原始交易币种和时间,并记录当期汇率。
* **查询支持:** 数据库层需支持基于时间窗口Time Window的聚合查询`BETWEEN '2026-02-01' AND '2026-02-28'`)。
### 3.2 交易去重与链路合并 (De-duplication & Linkage)
初始需求中提到的“重复项”实际上是“同一笔交易在不同账户的映射”。系统不应简单删除,而应建立**交易链路Transaction Linkage**。
**核心算法逻辑:**
设支付宝账单记录为 $T_{ali}$,银行账单记录为 $T_{bank}$。
当满足以下条件时,判定为同一笔交易:
$$| Time(T_{ali}) - Time(T_{bank}) | \le \Delta t \quad (\text{建议 } \Delta t = 120s)$$
$$Amount(T_{ali}) = Amount(T_{bank})$$
**处理策略:**
1. **合并展示:** 将两条记录关联。
* **主记录(保留):** 支付宝/微信记录(因其包含具体的商户名、商品名、消费分类)。
* **辅记录(隐藏/标记):** 银行卡记录标记为“资金划转Transfer”或“支付源扣款”。
2. **账户归属明确:**
* **支付渠道Payment Channel** 支付宝、微信、云闪付、美团。
* **资金账户Funding Source** 招商银行信用卡、工商银行储蓄卡、京东白条、余额宝。
* *示例:* 用户在淘宝买衣服,用支付宝绑定的招行卡支付。系统记录为:**支出 200元 (分类:服饰)**,支付渠道:**支付宝**,资金来源:**招行信用卡**。
### 3.3 智能分类 (Smart Categorization)
* **多级分类体系:**
* 一级分类:餐饮、交通、购物、居住、娱乐、医疗、金融。
* 二级分类:早餐/正餐、地铁/打车、数码/服饰、房租/水电。
* **关键词映射:** 建立 `Merchant_Keyword_Map` 表。
* 例:包含“星巴克”、“瑞幸” -> 自动归类为 [餐饮-咖啡]。
* 例:包含“中国石油” -> 自动归类为 [交通-加油]。
* **人工修正与学习:** 用户手动修改某一笔交易分类后,系统询问“是否将该商户后续交易默认应用此分类”。
---
## 4. 功能模块详述
### 4.1 仪表盘 (Dashboard)
* **全景资产卡片:** 显示总资产、总负债(信用卡+白条+花呗)、净资产。
* **本月收支概览:** * 当月支出 vs 上月同期环比 (MoM)。
* 预算执行进度条(如:本月预算剩余 30%)。
* **收支趋势图:** 折线图展示近12个月的收支波动。
### 4.2 账单查询与分析
* **高级筛选器:** 支持组合条件筛选:
* 时间范围(自定义/本周/本月/本年)。
* 金额区间(如:> 1000元的大额支出
* 支付渠道 & 资金账户。
* 交易分类。
* 关键词搜索(如:“京东”)。
* **多维图表:**
* [饼图] 消费结构分析(哪类钱花得最多)。
* [堆叠柱状图] 支付渠道依赖度分析。
* [桑基图 (Sankey Diagram)] 资金流向可视化(从收入 -> 账户 -> 支出类别)。
### 4.3 预算与预警
* **预算设置:** 支持总预算及分分类预算(如:“餐饮”每月限额 3000元
* **超支预警:** 当某一类别支出达到预算的 80% 时,界面高亮提示。
---
## 5. 非功能需求 (NFR)
### 5.1 数据隐私与安全
* **本地优先Local-First** 鉴于财务数据极度敏感,建议所有数据解析、清洗、存储默认在用户本地电脑中完成。
---
## 技术栈
1. Golang
2. Vue
3. TypeScript
4. SQLite
5. ECharts(寻找适合的图表工具,不限于ECharts)

View File

@@ -0,0 +1,33 @@
你是一名资深的软件系统架构师具备以下核心职责与能力绘图请使用mermaid语言
## 需求分析与理解
- 深度解读产品需求文档PRD识别业务目标、功能需求与非功能性需求
- 分析需求间的依赖关系与优先级,识别潜在的技术风险与挑战
## 架构设计与规划
- 设计高可用、可扩展、高性能的系统架构,确保系统健壮性与安全性
- 制定技术选型方案,包括开发语言、框架、中间件、数据库等关键技术栈
- 绘制多层次架构图(系统架构图、数据流图、组件交互图)
- 定义模块划分、接口规范、数据模型与核心算法策略
- 规划系统分层结构(展现层、业务层、数据层),明确各层职责边界
## 方案设计与输出
- 针对核心需求点提供详细的技术解决方案,包含实现路径与备选方案
- 设计关键业务流程的时序图与状态机,确保逻辑清晰完整
- 输出规范化的《系统详细设计说明书》,包含架构设计、接口定义、数据库设计等完整文档
## 技术栈说明
- 后端开发技术栈 Golang GROM GIN
- 前端开发技术栈 Vue3 TypeScript Vuetify
## 参考项目
- 项目有非常完善的数据清洗工具基本满足了数据读取部分可以摘取此项目的数据translate provider部分代码 [double-entry-generator](https://github.com/deb-sig/double-entry-generator)
请根据[2-优化产品需求文档PRD.md],按照上述的要求,输出系统详细设计说明书
你之前根据[2-优化产品需求文档PRD.md]输出了[3-详细设计说明书.md], 目前PRD需求有一些更新,见[2.1-优化产品需求文档PRD.md],请你详细对比[2.1-优化产品需求文档PRD.md]和[2-优化产品需求文档PRD.md]之间的差异, 修改[3-详细设计说明书.md],得到新的需求文档.要求尽量不改动[3-详细设计说明书.md]的初始设计,只改动差异化部分的设计

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
# 产品需求文档 (PRD): ProjectMoneyX 个人全景财务分析系统
| 文档属性 | 详情 |
| --- | --- |
| **项目名称** | ProjectMoneyX |
| **版本号** | v1.2 (基于开源 ETL 架构优化版) |
| **编制日期** | 2026-02-26 |
| **文档状态** | 进行中 |
## 1. 项目背景与目标
### 1.1 项目背景
随着移动支付的普及,个人财务数据分散在支付宝、微信、各家银行及电商平台中。用户面临“账单碎片化”、“流水重复记录”等痛点。传统的记账软件通常依赖手动记录或单一的账单导入,缺乏灵活的规则引擎来处理复杂的跨账户对账。
### 1.2 项目目标
构建一套自动化、高精度的个人财务分析系统。借鉴开源社区成熟的双轨制记账流转架构,通过引入 `Provider` 解析器与 `Translate` 规则引擎实现多源数据的标准化转换IR并利用算法解决跨账户流水重复问题提供多维度的收支分析与预算管理功能。
---
## 2. 核心系统架构ETL 数据工作流
参考业内成熟方案,系统底层采用高度解耦的管道架构,确保后续极强的可扩展性:
**数据流转路径:** `原始账单 (Raw Files) -> 提供方解析 (Provider) -> 中间表示 (IR) -> 规则转换 (Translate) -> 数据库标准账单`
* **Provider 层:** 专注于“读”。屏蔽不同账单格式CSV, PDF, Excel的差异。
* **IR 层 (Intermediate Representation)** 统一的数据结构协议,作为 Provider 和 Translate 的桥梁。
* **Translate 层:** 专注于“洗”。基于 YAML/JSON 规则配置,执行分类映射、时间标准化与账户归属。
---
## 3. 数据采集与 Provider 模块 (Data Ingestion)
针对不同来源的账单,建立独立的 Provider 适配器。当某银行账单格式更新时,仅需修改或新增对应的 Provider不影响系统核心逻辑。
| 提供方 (Provider) | 原始格式 | 核心提取字段 | 数据权重 | 提取说明 |
| --- | --- | --- | --- | --- |
| **Alipay (支付宝)** | CSV | 订单号、商户、商品明细、金额 | **L1 (最高)** | 标准 CSV 解析,作为消费类主数据。 |
| **WeChat (微信支付)** | CSV | 交易单号、交易对方、交易类型 | **L2** | 预处理跳过表头,提取转账与红包标记。 |
| **Banks (招商/工行等)** | PDF/XLS | 交易日、交易摘要、收支金额 | **L3** | 作为资金实际扣款核对依据 (Reconciliation)。 |
| **JD/Meituan (电商)** | PDF/CSV | 订单明细、支付通道 | **L3** | 重点关注白条/月付等信用支付记录。 |
---
## 4. 数据转换与清洗逻辑 (Translate & Cleaning)
Translate 层是数据质量的核心把控者,负责将 IR 数据转换为最终的财务记录,并解决数据冲突。
### 4.1 Translate 规则引擎
建立基于配置文件的映射规则,实现自动化数据归位:
* **时间与时区标准化:** 统一转换为 ISO 8601 格式,所有国内交易归一化为东八区时间。
* **账户路由 (Account Routing)** * *规则示例:* 当 Provider 为 `Alipay`且原始数据中的支付方式为“招商银行信用卡”时资金来源Funding Source自动映射至用户的“招行信用卡”实体账户。
* **智能分类映射 (Category Mapping)**
* 根据交易对方 (Peer) 或 商品说明 (Item) 进行正则匹配。
* *规则示例:* `Peer` 包含“星巴克”或“瑞幸” -> 映射分类为 [餐饮-咖啡]。
### 4.2 交易链路合并与去重算法 (De-duplication)
同一笔交易会在支付平台(如微信)和资金源(如银行卡)各产生一条流水。系统通过**时间窗与金额双重校验**进行链路合并,而非粗暴删除。
**核心算法逻辑:**
设高权重账单记录为 $T_{primary}$(如支付宝),低权重账单记录为 $T_{secondary}$(如银行卡)。
当同时满足以下条件时,判定为同一条交易链路:
$$| Time(T_{primary}) - Time(T_{secondary}) | \le \Delta t \quad (\text{建议 } \Delta t = 120s)$$
$$Amount(T_{primary}) = Amount(T_{secondary})$$
**处理策略:**
1. 将两条记录在底层数据库建立关联Parent-Child 或 LinkID
2. 前端展示时,**合并为一笔记录**。保留 $T_{primary}$ 的丰富消费明细(如分类、商户名),将 $T_{secondary}$ 的账户信息作为该笔消费的资金出处。
---
## 5. 核心功能模块详述
### 5.1 全景仪表盘 (Dashboard)
* **资产负债表:** 实时聚合各账户总资产、总负债(信用卡/白条),计算净资产。
* **现金流概览:** 本月总收入 vs 总支出,环比上月 (MoM) 增减百分比。
### 5.2 账单查询与多维分析
* **组合漏斗筛选:** 支持时间范围、金额区间、支付渠道、资金账户、交易分类的多条件交叉查询。
* **可视化图表:**
* **消费结构:** 饼图展示各大类的支出占比。
* **资金流向 (Sankey Diagram)** 桑基图直观展示“收入源 -> 资金池 (账户) -> 支出分类”的完整链路。
### 5.3 预算管理
* **精细化限额:** 支持全局预算和分类预算(例如:设定“交通”每月额度 1000 元)。
* **阈值预警:** 当分类支出进度达到 80% 和 100% 时,系统触发视觉高亮预警。
---
## 6. 非功能需求 (NFR)
* **数据隐私 (Local-First)** 财务数据极其敏感,系统解析 (Provider) 和转换 (Translate) 过程应优先在客户端(本地环境)执行,拒绝未经加密的云端明文传输。

View File

@@ -0,0 +1,951 @@
# 系统详细设计说明书 (DDS): ProjectMoneyX 个人全景财务分析系统
| 文档属性 | 详情 |
| --- | --- |
| **项目名称** | ProjectMoneyX |
| **版本号** | v1.0 |
| **编制日期** | 2026-02-26 |
| **文档状态** | 初稿 |
| **技术栈** | Golang (Gin + GORM) / Vue3 + TypeScript + Vuetify / ECharts |
| **参考项目** | [double-entry-generator](https://github.com/deb-sig/double-entry-generator) |
---
## 1. 系统总体架构
### 1.1 架构概览
系统采用前后端分离的 B/S 架构,后端以 Golang Gin 框架提供 RESTful API前端以 Vue3 + Vuetify 构建 SPA 应用。核心数据处理流程借鉴 `double-entry-generator`**Provider → IR → Translate** 管道模式,将其从命令行工具改造为 Web 服务。
```mermaid
graph TB
subgraph Frontend["前端 (Vue3 + Vuetify + ECharts)"]
UI_Upload["账单上传"]
UI_Dashboard["全景仪表盘"]
UI_Query["账单查询与分析"]
UI_Budget["预算管理"]
UI_Account["账户管理"]
UI_Rule["规则配置"]
end
subgraph Backend["后端 (Golang Gin)"]
API["RESTful API Layer (Gin Router)"]
SVC["Service Layer"]
ETL["ETL Pipeline"]
subgraph ETL_Detail["ETL 管道"]
Provider["Provider 解析层"]
IR["IR 中间表示层"]
Translate["Translate 规则引擎"]
Dedup["去重引擎"]
end
REPO["Repository Layer (GORM)"]
end
subgraph Storage["数据存储"]
DB["SQLite / MySQL"]
FileStore["本地文件存储"]
end
Frontend -->|HTTP/JSON| API
API --> SVC
SVC --> ETL
ETL_Detail --> REPO
SVC --> REPO
REPO --> DB
Provider --> FileStore
```
### 1.2 分层架构说明
| 层级 | 职责 | 技术选择 |
| --- | --- | --- |
| **展现层 (Presentation)** | UI 渲染、用户交互、数据可视化 | Vue3 + Vuetify + ECharts |
| **API 层 (API Gateway)** | 路由分发、参数校验、认证鉴权、响应封装 | Gin Framework |
| **业务层 (Service)** | 核心业务逻辑编排、ETL 流程调度 | Go Service |
| **数据处理层 (ETL Pipeline)** | Provider 解析、IR 转换、Translate 规则、去重合并 | Go (参考 double-entry-generator) |
| **数据访问层 (Repository)** | ORM 映射、数据库 CRUD | GORM |
| **数据存储层 (Storage)** | 持久化存储 | SQLite (默认, Local-First) / MySQL (可选) |
---
## 2. 后端详细设计
### 2.1 项目目录结构
```
projectmoneyx-server/
├── main.go # 程序入口
├── config/
│ └── config.go # 配置加载 (YAML)
├── internal/
│ ├── api/ # API 层 (Gin Handler)
│ │ ├── router.go # 路由注册
│ │ ├── middleware/ # 中间件 (CORS, Logger, Auth)
│ │ ├── handler/
│ │ │ ├── bill_handler.go
│ │ │ ├── account_handler.go
│ │ │ ├── budget_handler.go
│ │ │ ├── dashboard_handler.go
│ │ │ ├── category_handler.go
│ │ │ └── rule_handler.go
│ │ └── dto/ # 请求/响应 DTO
│ │ ├── request.go
│ │ └── response.go
│ ├── service/ # 业务层
│ │ ├── bill_service.go
│ │ ├── account_service.go
│ │ ├── budget_service.go
│ │ ├── dashboard_service.go
│ │ └── import_service.go # ETL 编排
│ ├── etl/ # ETL 管道 (核心)
│ │ ├── pipeline.go # 管道编排器
│ │ ├── provider/ # Provider 层 (参考 double-entry-generator)
│ │ │ ├── interface.go # Provider 接口定义
│ │ │ ├── alipay/
│ │ │ │ ├── alipay.go
│ │ │ │ └── parse.go
│ │ │ ├── wechat/
│ │ │ │ ├── wechat.go
│ │ │ │ └── parse.go
│ │ │ └── bank/
│ │ │ ├── cmb.go # 招商银行
│ │ │ └── icbc.go # 工商银行
│ │ ├── ir/ # IR 中间表示
│ │ │ └── ir.go
│ │ ├── translate/ # Translate 规则引擎
│ │ │ ├── engine.go
│ │ │ ├── category.go
│ │ │ └── account.go
│ │ └── dedup/ # 去重引擎
│ │ └── dedup.go
│ ├── model/ # GORM 数据模型
│ │ ├── bill.go
│ │ ├── account.go
│ │ ├── category.go
│ │ ├── budget.go
│ │ └── rule.go
│ └── repository/ # 数据访问层
│ ├── bill_repo.go
│ ├── account_repo.go
│ └── budget_repo.go
├── configs/
│ ├── app.yaml # 应用配置
│ └── rules/ # Translate 规则配置
│ ├── category_rules.yaml
│ └── account_rules.yaml
└── uploads/ # 上传文件临时存储
```
### 2.2 ETL 管道核心设计
#### 2.2.1 Provider 接口定义
借鉴 `double-entry-generator` 的 Provider 模式,定义统一接口:
```go
// internal/etl/provider/interface.go
package provider
import "projectmoneyx/internal/etl/ir"
// Provider 定义账单解析器的通用接口
type Provider interface {
// Translate 将原始账单文件解析为 IR 中间表示
Translate(filename string) (*ir.IR, error)
// Name 返回 Provider 名称
Name() string
// SupportedFormats 返回支持的文件格式
SupportedFormats() []string
}
// ProviderFactory Provider 工厂,根据类型创建对应 Provider
func NewProvider(providerType string) (Provider, error) {
switch providerType {
case "alipay":
return alipay.New(), nil
case "wechat":
return wechat.New(), nil
case "cmb":
return bank.NewCMB(), nil
default:
return nil, fmt.Errorf("unsupported provider: %s", providerType)
}
}
```
#### 2.2.2 IR 中间表示结构
参考 `double-entry-generator``ir.Order` 结构,针对个人财务场景扩展:
```go
// internal/etl/ir/ir.go
package ir
import "time"
// IR 中间表示,作为 Provider 与 Translate 的桥梁
type IR struct {
Orders []Order `json:"orders"`
}
// Order 统一的订单中间表示
type Order struct {
// --- 基础字段 (对齐 double-entry-generator) ---
Peer string `json:"peer"` // 交易对方
Item string `json:"item"` // 商品说明
Category string `json:"category"` // 原始分类
Money float64 `json:"money"` // 交易金额
PayTime time.Time `json:"pay_time"` // 支付时间 (ISO 8601)
Type TxType `json:"type"` // 收/支/其他
TypeOriginal string `json:"type_original"` // 原始交易类型文本
Method string `json:"method"` // 支付方式
MerchantOrderID string `json:"merchant_order_id"` // 商户订单号
OrderID string `json:"order_id"` // 交易单号
Status string `json:"status"` // 交易状态
Note string `json:"note"` // 备注
// --- ProjectMoneyX 扩展字段 ---
ProviderName string `json:"provider_name"` // 来源 Provider
DataWeight int `json:"data_weight"` // 数据权重 (L1=1, L2=2, L3=3)
Currency string `json:"currency"` // 币种,默认 CNY
Metadata map[string]string `json:"metadata"` // 扩展元数据
}
// TxType 交易方向
type TxType string
const (
TxTypeSend TxType = "Send" // 支出
TxTypeRecv TxType = "Recv" // 收入
TxTypeUnknown TxType = "Unknown" // 未知
)
```
#### 2.2.3 Translate 规则引擎
```go
// internal/etl/translate/engine.go
package translate
// TranslateEngine 规则引擎核心
type TranslateEngine struct {
CategoryRules []CategoryRule `yaml:"category_rules"`
AccountRules []AccountRule `yaml:"account_rules"`
}
// CategoryRule 分类映射规则
type CategoryRule struct {
Match MatchCondition `yaml:"match"`
Category string `yaml:"category"` // 目标分类 (如 "餐饮-咖啡")
Priority int `yaml:"priority"` // 规则优先级
}
// AccountRule 账户路由规则
type AccountRule struct {
Provider string `yaml:"provider"` // Provider 名称 (如 "alipay")
MethodMatch string `yaml:"method_match"` // 支付方式正则
AccountID uint `yaml:"account_id"` // 目标账户 ID
}
// MatchCondition 匹配条件
type MatchCondition struct {
Field string `yaml:"field"` // 匹配字段: peer / item / category
Pattern string `yaml:"pattern"` // 正则表达式
}
// Apply 对 IR 应用规则转换
func (e *TranslateEngine) Apply(irData *ir.IR) ([]model.Bill, error) {
// 1. 时间标准化 (ISO 8601, UTC+8)
// 2. 遍历每条 Order匹配 CategoryRules 进行分类
// 3. 遍历每条 Order匹配 AccountRules 进行账户路由
// 4. 转换为 model.Bill 结构
}
```
#### 2.2.4 去重引擎
```go
// internal/etl/dedup/dedup.go
package dedup
import "time"
const DefaultTimeDelta = 120 * time.Second // 默认时间窗口 120 秒
// DedupEngine 交易链路去重引擎
type DedupEngine struct {
TimeDelta time.Duration
}
// Process 执行去重合并
// 算法: 按 DataWeight 升序排列,低权重记录尝试匹配高权重记录
// 匹配条件: |Time(Tp) - Time(Ts)| <= Δt AND Amount(Tp) == Amount(Ts)
func (d *DedupEngine) Process(bills []model.Bill) []model.Bill {
// 1. 按 DataWeight 分组: primary (L1) vs secondary (L2, L3)
// 2. 双层循环匹配: 时间窗 + 金额精确匹配
// 3. 匹配成功: 建立 LinkID 关联, 标记 secondary 为 linked
// 4. 返回合并后的结果集
}
```
#### 2.2.5 Pipeline 编排
```go
// internal/etl/pipeline.go
package etl
// Pipeline ETL 管道编排器
type Pipeline struct {
providerRegistry map[string]provider.Provider
translateEngine *translate.TranslateEngine
dedupEngine *dedup.DedupEngine
}
// Run 执行完整 ETL 流程
func (p *Pipeline) Run(providerType, filePath string) (*ImportResult, error) {
// Step 1: Provider 解析 -> IR
prov, err := provider.NewProvider(providerType)
irData, err := prov.Translate(filePath)
// Step 2: Translate 规则转换 -> []Bill
bills, err := p.translateEngine.Apply(irData)
// Step 3: Dedup 去重合并
mergedBills := p.dedupEngine.Process(bills)
// Step 4: 持久化入库
return p.save(mergedBills)
}
```
```mermaid
sequenceDiagram
participant U as 用户
participant FE as 前端
participant API as Gin API
participant SVC as ImportService
participant P as Provider
participant T as Translate
participant D as DedupEngine
participant DB as Database
U->>FE: 上传账单文件 + 选择来源类型
FE->>API: POST /api/v1/bills/import (multipart)
API->>SVC: ImportBill(providerType, file)
SVC->>P: Translate(filePath)
P-->>SVC: IR (中间表示)
SVC->>T: Apply(IR)
T-->>SVC: []Bill (标准账单)
SVC->>D: Process([]Bill)
D->>DB: 查询已有账单 (时间窗)
DB-->>D: 存量数据
D-->>SVC: 去重后 []Bill
SVC->>DB: 批量写入
DB-->>SVC: 写入结果
SVC-->>API: ImportResult(成功/跳过/失败数)
API-->>FE: JSON Response
FE-->>U: 导入结果报告
```
### 2.3 数据模型设计 (GORM)
#### 2.3.1 ER 关系图
```mermaid
erDiagram
USER ||--o{ ACCOUNT : owns
USER ||--o{ BUDGET : sets
ACCOUNT ||--o{ BILL : "fund_source"
CATEGORY ||--o{ BILL : classifies
CATEGORY ||--o{ BUDGET : limits
BILL ||--o| BILL_LINK : linked
CATEGORY ||--o{ CATEGORY : "parent-child"
USER ||--o{ TRANSLATE_RULE : configures
USER {
uint id PK
string username
string password_hash
timestamp created_at
}
ACCOUNT {
uint id PK
uint user_id FK
string name
string type "debit/credit/ewallet"
float64 balance
string currency
bool is_active
}
BILL {
uint id PK
uint user_id FK
uint account_id FK
uint category_id FK
string provider_name
string order_id UK
string merchant_order_id
string peer
string item
float64 amount
string tx_type "income/expense/transfer"
string method
string status
string note
string link_id
int data_weight
timestamp pay_time
timestamp created_at
}
CATEGORY {
uint id PK
uint parent_id FK
string name
string icon
int sort_order
string type "income/expense"
}
BUDGET {
uint id PK
uint user_id FK
uint category_id FK "nullable, null=全局"
float64 amount
string period "monthly/yearly"
string month "2026-02"
}
BILL_LINK {
uint id PK
string link_id UK
uint primary_bill_id FK
uint secondary_bill_id FK
}
TRANSLATE_RULE {
uint id PK
uint user_id FK
string rule_type "category/account"
string match_field
string match_pattern
string target_value
int priority
bool is_active
}
```
#### 2.3.2 核心 Model 定义
```go
// internal/model/bill.go
package model
import (
"time"
"gorm.io/gorm"
)
type Bill struct {
gorm.Model
UserID uint `gorm:"index;not null" json:"user_id"`
AccountID uint `gorm:"index" json:"account_id"`
CategoryID uint `gorm:"index" json:"category_id"`
ProviderName string `gorm:"size:32" json:"provider_name"`
OrderID string `gorm:"size:128;uniqueIndex" json:"order_id"`
MerchantOrderID string `gorm:"size:128" json:"merchant_order_id"`
Peer string `gorm:"size:256" json:"peer"`
Item string `gorm:"size:512" json:"item"`
Amount float64 `gorm:"type:decimal(12,2);not null" json:"amount"`
TxType string `gorm:"size:16;not null" json:"tx_type"`
Method string `gorm:"size:64" json:"method"`
Status string `gorm:"size:32" json:"status"`
Note string `gorm:"size:512" json:"note"`
LinkID string `gorm:"size:64;index" json:"link_id"`
DataWeight int `gorm:"default:1" json:"data_weight"`
PayTime time.Time `gorm:"index;not null" json:"pay_time"`
// 关联
Account Account `gorm:"foreignKey:AccountID" json:"account,omitempty"`
Category Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
}
// internal/model/account.go
type Account struct {
gorm.Model
UserID uint `gorm:"index;not null" json:"user_id"`
Name string `gorm:"size:128;not null" json:"name"`
Type string `gorm:"size:32;not null" json:"type"` // debit/credit/ewallet
Balance float64 `gorm:"type:decimal(14,2);default:0" json:"balance"`
Currency string `gorm:"size:8;default:CNY" json:"currency"`
IsActive bool `gorm:"default:true" json:"is_active"`
}
// internal/model/category.go
type Category struct {
gorm.Model
ParentID *uint `gorm:"index" json:"parent_id"`
Name string `gorm:"size:64;not null" json:"name"`
Icon string `gorm:"size:64" json:"icon"`
SortOrder int `gorm:"default:0" json:"sort_order"`
Type string `gorm:"size:16" json:"type"` // income/expense
Children []Category `gorm:"foreignKey:ParentID" json:"children,omitempty"`
}
// internal/model/budget.go
type Budget struct {
gorm.Model
UserID uint `gorm:"index;not null" json:"user_id"`
CategoryID *uint `gorm:"index" json:"category_id"` // nil = 全局预算
Amount float64 `gorm:"type:decimal(12,2);not null" json:"amount"`
Period string `gorm:"size:16;default:monthly" json:"period"`
Month string `gorm:"size:8;not null" json:"month"` // "2026-02"
}
```
### 2.4 API 接口设计
#### 2.4.1 接口总表
| 模块 | Method | Path | 描述 |
| --- | --- | --- | --- |
| **账单导入** | POST | `/api/v1/bills/import` | 上传并导入账单文件 |
| | GET | `/api/v1/bills/import-history` | 导入历史记录 (导入质量图数据) |
| **账单管理** | GET | `/api/v1/bills` | 多条件查询账单列表 |
| | GET | `/api/v1/bills/:id` | 查询账单详情 |
| | PUT | `/api/v1/bills/:id` | 修改账单 (手动调整分类等) |
| | DELETE | `/api/v1/bills/:id` | 删除账单 |
| **仪表盘** | GET | `/api/v1/dashboard/summary` | 资产负债 + 现金流概览 |
| | GET | `/api/v1/dashboard/trend` | 收支趋势 + 净资产趋势 (按月) |
| | GET | `/api/v1/dashboard/asset-composition` | 各账户资产构成 (堆叠图数据) |
| **分析** | GET | `/api/v1/analysis/category` | 分类占比 (饼图, 支持 type=income/expense) |
| | GET | `/api/v1/analysis/sankey` | 资金流向 (桑基图数据) |
| | GET | `/api/v1/analysis/heatmap` | 日消费热力图数据 |
| | GET | `/api/v1/analysis/category-trend` | 分类支出趋势 (多折线图数据) |
| **账户** | GET | `/api/v1/accounts` | 账户列表 |
| | POST | `/api/v1/accounts` | 创建账户 |
| | PUT | `/api/v1/accounts/:id` | 修改账户 |
| | DELETE | `/api/v1/accounts/:id` | 删除账户 |
| | GET | `/api/v1/accounts/:id/waterfall` | 账户收支瀑布图数据 |
| **预算** | GET | `/api/v1/budgets` | 预算列表 (含执行进度) |
| | POST | `/api/v1/budgets` | 创建/更新预算 |
| | DELETE | `/api/v1/budgets/:id` | 删除预算 |
| **分类** | GET | `/api/v1/categories` | 分类树 |
| | POST | `/api/v1/categories` | 新增分类 |
| **规则** | GET | `/api/v1/rules` | 规则列表 |
| | POST | `/api/v1/rules` | 新增规则 |
| | PUT | `/api/v1/rules/:id` | 修改规则 |
| | DELETE | `/api/v1/rules/:id` | 删除规则 |
#### 2.4.2 核心接口详细定义
**POST /api/v1/bills/import — 账单导入**
```
Request: multipart/form-data
- file: 账单文件 (CSV/XLS/PDF)
- provider: string ("alipay" | "wechat" | "cmb" | "icbc" | "jd" | "meituan")
Response 200:
{
"code": 0,
"data": {
"total": 150, // 解析总条数
"imported": 132, // 新导入条数
"duplicated": 15, // 去重跳过条数
"linked": 3, // 链路合并条数
"failed": 0 // 失败条数
}
}
```
**GET /api/v1/bills — 账单查询**
```
Query Params:
- start_date: string (2026-01-01)
- end_date: string (2026-01-31)
- min_amount: float64
- max_amount: float64
- tx_type: string (income/expense)
- category_id: uint
- account_id: uint
- provider: string
- keyword: string (模糊搜索 peer/item)
- page: int (default 1)
- page_size: int (default 20)
Response 200:
{
"code": 0,
"data": {
"total": 500,
"items": [ { ...Bill } ]
}
}
```
**GET /api/v1/dashboard/summary — 仪表盘概览**
```
Query Params:
- month: string (2026-02, 默认当月)
Response 200:
{
"code": 0,
"data": {
"total_assets": 125000.00,
"total_liabilities": 8500.00,
"net_worth": 116500.00,
"month_income": 15000.00,
"month_expense": 8200.00,
"income_mom_pct": 5.2,
"expense_mom_pct": -3.1,
"accounts": [ { "name": "招行储蓄卡", "balance": 80000.00, "type": "debit" } ]
}
}
```
**GET /api/v1/analysis/sankey — 桑基图数据**
```
Query Params:
- start_date / end_date
Response 200:
{
"code": 0,
"data": {
"nodes": [
{ "name": "工资" }, { "name": "招行储蓄卡" }, { "name": "餐饮" }
],
"links": [
{ "source": "工资", "target": "招行储蓄卡", "value": 15000 },
{ "source": "招行储蓄卡", "target": "餐饮", "value": 3200 }
]
}
}
```
---
## 3. 前端详细设计
### 3.1 页面结构与路由
```mermaid
graph LR
subgraph Layout["AppLayout"]
Sidebar["侧边导航栏"]
Header["顶部栏"]
Main["主内容区"]
end
Main --> Dashboard["/dashboard 仪表盘"]
Main --> Bills["/bills 账单管理"]
Main --> Import["/import 账单导入"]
Main --> Accounts["/accounts 账户管理"]
Main --> Budgets["/budgets 预算管理"]
Main --> Analysis["/analysis 多维分析"]
Main --> Rules["/rules 规则配置"]
```
### 3.2 前端项目结构
```
projectmoneyx-web/
├── src/
│ ├── main.ts
│ ├── App.vue
│ ├── router/
│ │ └── index.ts
│ ├── api/ # Axios 接口封装
│ │ ├── request.ts # Axios 实例 + 拦截器
│ │ ├── bill.ts
│ │ ├── account.ts
│ │ ├── dashboard.ts
│ │ ├── analysis.ts
│ │ ├── budget.ts
│ │ └── rule.ts
│ ├── views/
│ │ ├── DashboardView.vue # 全景仪表盘
│ │ ├── BillListView.vue # 账单查询
│ │ ├── ImportView.vue # 账单导入
│ │ ├── AccountView.vue # 账户管理
│ │ ├── BudgetView.vue # 预算管理
│ │ ├── AnalysisView.vue # 多维分析 (桑基图/饼图)
│ │ └── RuleView.vue # 规则配置
│ ├── components/
│ │ ├── charts/
│ │ │ ├── NetWorthTrendChart.vue # 图表1: 净资产趋势折线图
│ │ │ ├── CashFlowBarChart.vue # 图表2: 现金流对比柱状图
│ │ │ ├── AssetCompositionChart.vue # 图表3: 资产构成堆叠图
│ │ │ ├── ExpensePieChart.vue # 图表4: 支出结构环形图
│ │ │ ├── CalendarHeatmap.vue # 图表5: 收支日历热力图
│ │ │ ├── CategoryTrendChart.vue # 图表6: 分类支出趋势折线图
│ │ │ ├── SankeyChart.vue # 图表7: 资金流向桑基图
│ │ │ ├── IncomePieChart.vue # 图表8: 收入来源环形图
│ │ │ ├── BudgetGauge.vue # 图表9: 预算进度仪表盘
│ │ │ ├── BudgetCompareChart.vue # 图表10: 预算vs实际对比图
│ │ │ ├── AccountWaterfallChart.vue # 图表11: 账户收支瀑布图
│ │ │ └── ImportQualityChart.vue # 图表12: 导入质量统计图
│ │ ├── BillFilterPanel.vue # 账单筛选面板
│ │ ├── ImportUploader.vue # 文件上传组件
│ │ └── AccountCard.vue # 账户卡片
│ ├── stores/ # Pinia 状态管理
│ │ ├── bill.ts
│ │ ├── account.ts
│ │ └── dashboard.ts
│ └── types/ # TypeScript 类型定义
│ ├── bill.d.ts
│ ├── account.d.ts
│ └── api.d.ts
```
### 3.3 核心页面设计
#### 3.3.1 全景仪表盘 (DashboardView)
* **资产负债表:** 实时聚合各账户总资产、总负债(信用卡/白条),计算净资产。
* **现金流概览:** 本月总收入 vs 总支出,环比上月 (MoM) 增减百分比。
```
┌─────────────────────────────────────────────────────────┐
│ [净资产卡片] [本月收入卡片] [本月支出卡片] │
│ ¥116,500 ¥15,000 ↑5.2% ¥8,200 ↓3.1% │
├──────────────────────────┬──────────────────────────────┤
│ 收支趋势折线图 (ECharts) │ 消费结构饼图 (ECharts) │
│ (近12个月) │ (本月各分类占比) │
├──────────────────────────┴──────────────────────────────┤
│ 各账户余额一栏表 (v-data-table) │
│ 招行储蓄卡 ¥80,000 | 支付宝余额 ¥5,000 | ... │
└─────────────────────────────────────────────────────────┘
```
#### 3.3.2 账单导入页 (ImportView)
```
┌─────────────────────────────────────────────────────────┐
│ Step 1: 选择来源 ○ 支付宝 ○ 微信 ○ 招商银行 ... │
├─────────────────────────────────────────────────────────┤
│ Step 2: 上传文件 [拖拽区域 / 点击选择文件] │
├─────────────────────────────────────────────────────────┤
│ Step 3: 导入结果 │
│ ✅ 解析 150 条 | 导入 132 条 | 去重 15 条 | 合并 3 条 │
└─────────────────────────────────────────────────────────┘
```
#### 3.3.3 多维分析页 (AnalysisView)
* **组合漏斗筛选:** 支持时间范围、金额区间、支付渠道、资金账户、交易分类的多条件交叉查询。
* **可视化图表:**
* **消费结构:** 饼图展示各大类的支出占比。
* **资金流向 (Sankey Diagram)** 桑基图直观展示“收入源 -> 资金池 (账户) -> 支出分类”的完整链路。
桑基图核心配置:
```typescript
// components/charts/SankeyChart.vue
const option: EChartsOption = {
series: [{
type: 'sankey',
data: nodes, // [{ name: '工资' }, { name: '招行卡' }, { name: '餐饮' }]
links: links, // [{ source: '工资', target: '招行卡', value: 15000 }]
emphasis: { focus: 'adjacency' },
lineStyle: { color: 'gradient', curveness: 0.5 },
label: { position: 'right' }
}]
}
```
---
## 4. 关键业务流程
### 4.1 账单导入全流程状态机
```mermaid
stateDiagram-v2
[*] --> FileUploaded: 用户上传文件
FileUploaded --> Parsing: 开始解析
Parsing --> ParseSuccess: Provider 解析成功
Parsing --> ParseFailed: 格式错误/文件损坏
ParseSuccess --> Translating: 规则引擎转换
Translating --> TranslateSuccess: 转换完成
TranslateSuccess --> Deduplicating: 去重处理
Deduplicating --> ImportComplete: 写入数据库
ImportComplete --> [*]: 返回导入报告
ParseFailed --> [*]: 返回错误信息
```
### 4.2 预算预警触发流程
```mermaid
sequenceDiagram
participant SVC as BudgetService
participant DB as Database
participant FE as 前端
Note over SVC: 每次账单写入后触发
SVC->>DB: 查询本月已用 (SUM by category)
DB-->>SVC: 已用金额
SVC->>DB: 查询预算限额
DB-->>SVC: 预算配置
alt 已用 >= 100% 限额
SVC-->>FE: 超支预警 (红色标记)
else 已用 >= 80% 限额
SVC-->>FE: 临近预警 (橙色标记)
else 正常
SVC-->>FE: 正常状态 (绿色)
end
```
---
## 5. Translate 规则配置规范
### 5.1 分类规则配置示例 (YAML)
```yaml
# configs/rules/category_rules.yaml
category_rules:
# --- 餐饮 ---
- match: { field: "peer", pattern: "星巴克|瑞幸|Luckin" }
category: "餐饮-咖啡"
priority: 10
- match: { field: "peer", pattern: "美团|饿了么|美团外卖" }
category: "餐饮-外卖"
priority: 10
- match: { field: "item", pattern: "早餐|午餐|晚餐|堂食" }
category: "餐饮-正餐"
priority: 5
# --- 交通 ---
- match: { field: "peer", pattern: "滴滴|高德打车|T3出行" }
category: "交通-打车"
priority: 10
- match: { field: "peer", pattern: "12306|铁路" }
category: "交通-火车"
priority: 10
# --- 购物 ---
- match: { field: "peer", pattern: "淘宝|天猫|拼多多" }
category: "购物-电商"
priority: 3
# --- 兜底规则 ---
- match: { field: "peer", pattern: ".*" }
category: "其他-未分类"
priority: 0
```
### 5.2 账户路由配置示例 (YAML)
```yaml
# configs/rules/account_rules.yaml
account_rules:
- provider: "alipay"
method_match: "招商银行信用卡"
account_name: "招行信用卡"
- provider: "alipay"
method_match: "花呗"
account_name: "花呗"
- provider: "alipay"
method_match: "余额宝|账户余额"
account_name: "支付宝余额"
- provider: "wechat"
method_match: "零钱"
account_name: "微信零钱"
- provider: "wechat"
method_match: "招商银行"
account_name: "招行储蓄卡"
```
---
## 6. 非功能性设计
### 6.1 数据隐私 (Local-First)
| 设计要点 | 实现方式 |
| --- | --- |
| 本地部署 | 默认使用 SQLite单一二进制文件部署无需外部数据库 |
| 文件处理 | 上传的原始账单文件仅在本地解析后即删除,不持久存储原始文件 |
| 无远程调用 | ETL 管道全过程本地执行,不依赖任何云端 API |
| 可选 MySQL | 如需多端访问,可配置切换到 MySQL但建议内网部署 |
### 6.2 性能设计
| 场景 | 指标 | 措施 |
| --- | --- | --- |
| 账单导入 | 1000 条/秒 | GORM 批量插入 (CreateInBatches) |
| 账单列表查询 | < 200ms | 复合索引 (user_id, pay_time, category_id) |
| 仪表盘聚合 | < 500ms | 数据库聚合查询 + 前端缓存 (Pinia) |
| 去重匹配 | O(n·m) | 按时间窗口分桶预排序减少比较次数 |
### 6.3 可扩展性设计
- **新增 Provider**实现 `provider.Provider` 接口注册到工厂即可
- **新增规则**YAML 配置热加载无需重启
- **新增图表**ECharts 组件化封装新图表只需新建 Vue 组件
---
## 7. 参考项目代码复用说明
### 7.1 从 double-entry-generator 复用的部分
| 模块 | 源路径 | 复用说明 |
| --- | --- | --- |
| IR 结构 | `pkg/ir/ir.go` | 复用 `Order` 结构体核心字段扩展 `ProviderName``DataWeight` 等字段 |
| Alipay Provider | `pkg/provider/alipay/` | 复用 CSV 解析GBK 编码处理字段映射逻辑 |
| WeChat Provider | `pkg/provider/wechat/` | 复用 CSV/XLSX 解析跳过表头逻辑 |
| 退款后处理 | `alipay.postProcess()` | 复用退款订单匹配和交易关闭处理逻辑 |
### 7.2 需要新增/改造的部分
| 模块 | 改造说明 |
| --- | --- |
| Provider 接口 | 从直接函数调用改为 Web API 触发增加文件上传处理 |
| Translate | 原项目的 Compiler 输出 Beancount 文本改为输出数据库 Model |
| 去重引擎 | 原项目不涉及需完全新写 |
| 规则配置 | 原项目配置固定改为数据库存储 + YAML 双模式支持用户自定义 |
---
## 8. 部署架构
```mermaid
graph LR
subgraph Local["本地部署 (推荐)"]
Binary["Go 单体二进制"]
SQLite["SQLite 数据库文件"]
StaticFiles["Vue 前端静态文件 (embed)"]
Binary --> SQLite
Binary --> StaticFiles
end
subgraph Docker["Docker 部署 (可选)"]
Container["Docker Container"]
Volume["Data Volume"]
Container --> Volume
end
User["浏览器"] -->|http://localhost:8080| Binary
User -->|http://host:8080| Container
```
> **推荐部署方式**:使用 Go 的 `embed` 包将编译后的 Vue 前端静态资源嵌入后端二进制文件,实现**单文件部署**,配合 SQLite 达到真正的 Local-First 体验。

View File

@@ -0,0 +1,637 @@
# ProjectMoneyX 数据可视化详细设计说明书
| 文档属性 | 详情 |
| --- | --- |
| **所属系统** | ProjectMoneyX 个人全景财务分析系统 |
| **关联文档** | [2-ProjectMoneyX-DDS.md](./2-ProjectMoneyX-DDS.md) §3 前端详细设计 |
| **技术框架** | ECharts 5.x + Vue3 Composition API + TypeScript |
| **编制日期** | 2026-02-26 |
---
## 0. 图表总览与需求覆盖矩阵
下表将 PRD 中的核心分析需求映射到具体图表实现,确保**多维度全覆盖**
| PRD 需求 | 分析维度 | 实现图表 | 所在页面 |
|---|---|---|---|
| 资产负债表 | 总资产/负债/净资产趋势 | 图表1: 净资产趋势折线图 | Dashboard |
| 现金流概览 (MoM) | 月度收入 vs 支出对比 | 图表2: 现金流对比柱状图 | Dashboard |
| 各账户资产构成 | 账户维度的资金分布 | 图表3: 资产构成堆叠图 | Dashboard |
| 消费结构 (饼图) | 分类维度的支出占比 | 图表4: 支出结构环形图 | Analysis |
| 消费规律识别 | 时间维度的消费强度 | 图表5: 收支日历热力图 | Analysis |
| 分类趋势对比 | 分类×时间交叉分析 | 图表6: 分类支出趋势折线图 | Analysis |
| 资金流向 (Sankey) | 收入→账户→支出全链路 | 图表7: 资金流向桑基图 ⭐ | Analysis |
| 收入结构分析 | 收入来源维度的占比 | 图表8: 收入来源环形图 | Analysis |
| 预算管理 (阈值预警) | 预算执行进度 | 图表9: 预算进度仪表盘 | Budget |
| 预算执行趋势 | 预算 vs 实际的偏差跟踪 | 图表10: 预算 vs 实际对比图 | Budget |
| 账户交易分析 | 单账户维度的流水趋势 | 图表11: 账户收支瀑布图 | Account |
| 去重链路可视化 | ETL 导入质量监控 | 图表12: 导入质量统计图 | Import |
### 图表与页面分布
```mermaid
graph TB
subgraph Dashboard["仪表盘 (DashboardView)"]
C1["图表1: 净资产趋势折线图"]
C2["图表2: 现金流对比柱状图"]
C3["图表3: 资产构成堆叠图"]
end
subgraph Analysis["多维分析 (AnalysisView)"]
C4["图表4: 支出结构环形图"]
C5["图表5: 收支日历热力图"]
C6["图表6: 分类支出趋势折线图"]
C7["图表7: 资金流向桑基图 ⭐"]
C8["图表8: 收入来源环形图"]
end
subgraph Budget["预算管理 (BudgetView)"]
C9["图表9: 预算进度仪表盘"]
C10["图表10: 预算 vs 实际对比图"]
end
subgraph Account["账户管理 (AccountView)"]
C11["图表11: 账户收支瀑布图"]
end
subgraph Import["账单导入 (ImportView)"]
C12["图表12: 导入质量统计图"]
end
```
---
## 1. 仪表盘总览区 (DashboardView)
### 图表1净资产趋势折线图
**图表类型:** `ECharts Line Chart`面积折线图Area Line
**用途:** 展示净资产随时间的增长趋势,是资产健康度的核心指标。
| 配置项 | 说明 |
|---|---|
| `xAxis.type` | `'category'`,数据为月份标签 `['2024-06', ..., '2026-02']` |
| `yAxis.type` | `'value'`,单位 CNY开启 `scale: true` 避免从0开始压缩曲线 |
| `series.type` | `'line'`,开启 `areaStyle` 填充半透明渐变区域 |
| `series.smooth` | `true`,平滑曲线更符合财务趋势感 |
| 关键数据字段 | `{ month: string, netWorth: number, totalAssets: number, totalLiabilities: number }[]` |
| 多线配置 | 叠加三条线:净资产(主线蓝 `#4F6EF7`)、总资产(绿虚线 `#10B981`)、总负债(红虚线 `#EF4444`),用 `markLine` 标注最高/最低点 |
**ECharts 高级能力:** 使用 `visualMap` 组件,当净资产低于某阈值时自动将线段变红预警。
**后端接口:** `GET /api/v1/dashboard/trend?range=12m`
```json
// Response
{
"code": 0,
"data": {
"months": ["2025-03", "2025-04", "..."],
"net_worth": [98000, 101000, "..."],
"total_assets": [120000, 125000, "..."],
"total_liabilities": [22000, 24000, "..."]
}
}
```
---
### 图表2月度现金流对比柱状图
**图表类型:** `ECharts Bar Chart`(分组柱 + 折线混合)
**用途:** 直观对比每月收入/支出,突出结余(净现金流)。
| 配置项 | 说明 |
|---|---|
| `xAxis` | 近12个月`type: 'category'` |
| `series[0]` | 收入柱,`barMaxWidth: 20`,颜色 `#10B981`(绿) |
| `series[1]` | 支出柱,同组排列,颜色 `#EF4444`(红) |
| `series[2]` | 结余折线(叠加 `type: 'line'`),颜色 `#4F6EF7`(蓝),`z: 10` 置于顶层 |
| `tooltip.formatter` | 自定义同时显示收入、支出、结余、环比变化MoM% |
| `markArea` | 标记亏损月(收入 < 支出的柱背景为浅红色区域 |
**后端接口:** 复用 `GET /api/v1/dashboard/trend?range=12m`数据中应增加 `month_income[]` `month_expense[]` 数组
---
### 图表3资产构成堆叠柱 / 堆叠面积图
**图表类型:** `ECharts Bar Chart (stack)` `Line Chart (stack + areaStyle)`
**用途:** 展示各账户资产随时间的构成变化如活期基金信用卡负债各占比的演变
| 配置项 | 说明 |
|---|---|
| `series[n].stack` | 统一设为 `'total'`触发堆叠模式 |
| 账户数据字段 | `{ month, accounts: { name: string, balance: number }[] }[]` |
| `series` 中负债处理 | 负债账户信用卡/白条使用负值自动向下延伸形成正负对称的资产负债视图 |
| `legend` | 开启可点击切换方便单独聚焦某账户 |
**后端接口:** `GET /api/v1/dashboard/asset-composition?range=12m`
```json
// Response
{
"code": 0,
"data": {
"months": ["2025-03", "2025-04"],
"series": [
{ "name": "招行储蓄卡", "type": "debit", "data": [80000, 82000] },
{ "name": "支付宝余额", "type": "ewallet", "data": [5000, 4500] },
{ "name": "招行信用卡", "type": "credit", "data": [-8000, -7500] }
]
}
}
```
---
## 2. 支出分析区 (AnalysisView - Tab1: 支出)
### 图表4支出结构环形图Donut
**图表类型:** `ECharts Pie Chart``radius: ['40%', '70%']` 环形
**用途:** 展示选定时间段内各消费分类占比支持二级下钻
| 配置项 | 说明 |
|---|---|
| `series.radius` | `['40%', '70%']` 形成环形中心显示总支出金额 |
| `series.label` | 外侧显示分类名 + 百分比`labelLine` 引导线 |
| `graphic`中心文字 | 使用 ECharts `graphic` 组件在环心渲染总支出 / ¥9,820 |
| `series.emphasis` | 鼠标悬停时扇区放大 `scaleSize: 10`联动下方账单表格筛选 |
| 数据字段 | `{ name: string, value: number, percentage: number }[]` |
| 二级下钻 | 点击一级分类餐饮)→ 触发 `series.data` 替换为二级分类外卖/堂食/咖啡配合 Vue3 `ref` 响应式切换面包屑导航返回上级 |
**后端接口:** `GET /api/v1/analysis/category?type=expense&start_date=&end_date=&parent_id=`
```json
// Response
{
"code": 0,
"data": {
"total": 9820.50,
"items": [
{ "category_id": 1, "name": "餐饮", "value": 3200, "percentage": 32.6, "has_children": true },
{ "category_id": 2, "name": "购物", "value": 2500, "percentage": 25.5, "has_children": true },
{ "category_id": 3, "name": "交通", "value": 1200, "percentage": 12.2, "has_children": false }
]
}
}
```
---
### 图表5收支日历热力图
**图表类型:** `ECharts HeatMap`日历坐标系
**用途:** 以日历形式展示每日消费强度快速识别高消费日/周期性支出规律如固定还款日周末消费高峰)。
| 配置项 | 说明 |
|---|---|
| `calendar.range` | 设置为当前选中月份或全年 `'2026'` `'2026-02'` |
| `series.coordinateSystem` | `'calendar'` `calendar` 组件绑定 |
| `series.data` | `[['2026-02-15', 420], ['2026-02-16', 85], ...]`日期 + 消费金额 |
| `visualMap` | 连续型从浅绿低消费 `#E8F5E9`到深红高消费 `#C62828`渐变阈值按数据自适应 |
| `tooltip` | 显示该日消费总额和前3笔最大账单 |
**后端接口:** `GET /api/v1/analysis/heatmap?year=2026&type=expense`
```json
// Response
{
"code": 0,
"data": [
["2026-02-01", 156.50],
["2026-02-02", 320.00],
["2026-02-14", 899.00]
]
}
```
---
### 图表6分类支出趋势多折线图
**图表类型:** `ECharts Line Chart`多系列
**用途:** 对比各支出分类餐饮购物交通 N 个月的趋势找出异常增长的分类
| 配置项 | 说明 |
|---|---|
| `legend` | 开启可交互默认只显示前5大分类其余折叠于 `legend.selector` |
| `xAxis` | 月份近12个月 |
| 每条 `series` | 对应一个支出分类最多显示 6 条线其余归入"其他" |
| `dataZoom` | 开启 X 轴缩放 (`type: 'slider'`)支持拖拽查看任意时间段 |
| 颜色规范 | 自定义 10 palette**与环形图(图表4)保持颜色一致**保证跨图表认知一致性 |
| `markPoint` | 自动标注各分类的月度最大值 (`type: 'max'`) |
**后端接口:** `GET /api/v1/analysis/category-trend?type=expense&range=12m&top=6`
```json
// Response
{
"code": 0,
"data": {
"months": ["2025-03", "2025-04", "..."],
"series": [
{ "name": "餐饮", "data": [3200, 2800, "..."] },
{ "name": "购物", "data": [2500, 3100, "..."] },
{ "name": "交通", "data": [1200, 1100, "..."] }
]
}
}
```
---
## 3. 资金流向区 (AnalysisView - Tab2: 流向)
### 图表7资金流向桑基图Sankey⭐ 核心图
**图表类型:** `ECharts Sankey Diagram`
**用途:** 唯一能完整展示收入源 资金池(账户) 支出分类全链路的图表是个人收支系统最有价值的可视化
```typescript
// 核心数据结构TypeScript
interface SankeyNode {
name: string // 节点名称
itemStyle?: { color: string }
depth?: number // 强制分层: 0=收入源, 1=账户, 2=支出分类
}
interface SankeyLink {
source: string // 来源节点 name
target: string // 目标节点 name
value: number // 流量金额CNY
}
// 三列节点分组示例
const nodes: SankeyNode[] = [
// 收入源(左列, depth=0
{ name: '工资薪酬', itemStyle: { color: '#10B981' }, depth: 0 },
{ name: '兼职收入', itemStyle: { color: '#34D399' }, depth: 0 },
{ name: '投资收益', itemStyle: { color: '#6EE7B7' }, depth: 0 },
// 账户池(中列, depth=1
{ name: '招行储蓄', itemStyle: { color: '#4F6EF7' }, depth: 1 },
{ name: '支付宝', itemStyle: { color: '#818CF8' }, depth: 1 },
{ name: '微信钱包', itemStyle: { color: '#A5B4FC' }, depth: 1 },
// 支出分类(右列, depth=2
{ name: '餐饮', itemStyle: { color: '#EF4444' }, depth: 2 },
{ name: '购物', itemStyle: { color: '#F97316' }, depth: 2 },
{ name: '居住', itemStyle: { color: '#F59E0B' }, depth: 2 },
{ name: '储蓄/投资',itemStyle: { color: '#10B981' }, depth: 2 },
]
```
| 关键配置项 | 说明 |
|---|---|
| `series.type` | `'sankey'` |
| `series.layout` | `'none'`禁用自动布局通过 `depth` 属性手动控制三列分层 |
| `series.nodeGap` | `12`节点间距 |
| `series.nodeWidth` | `20`节点宽度 |
| `series.lineStyle.color` | `'gradient'`从源到目标渐变色ECharts 内置支持 |
| `series.lineStyle.opacity` | `0.4`悬停时 `emphasis.lineStyle.opacity: 0.8` |
| `series.emphasis.focus` | `'adjacency'`高亮相邻节点和链接淡化其他 |
| `series.label.position` | 左列 `'left'`右列 `'right'`中列 `'inside'` |
| `tooltip.formatter` | 自定义显示节点`账户名: 总额 ¥X,XXX`链接`源 → 目标: ¥X,XXX占XX%` |
**后端接口:** `GET /api/v1/analysis/sankey?start_date=&end_date=`已在 DDS 中定义
---
## 4. 收入分析区 (AnalysisView - Tab3: 收入)
### 图表8收入来源环形图
**图表类型:** `ECharts Pie Chart``radius: ['40%', '70%']` 环形
**用途:** 展示选定时间段内各收入来源占比工资兼职理财收益转账收款等与支出环形图(图表4)形成对称分析
| 配置项 | 说明 |
|---|---|
| `series.radius` | `['40%', '70%']` 形成环形中心显示总收入金额 |
| `series.color` | 使用绿色系 palette与支出红色系区分 `['#10B981', '#34D399', '#6EE7B7', '#A7F3D0']` |
| `graphic`中心文字 | 在环心渲染总收入 / ¥15,000 |
| `series.emphasis` | 悬停扇区放大tooltip 显示收入来源明细 |
| 数据字段 | `{ name: string, value: number, percentage: number }[]` |
**后端接口:** 复用 `GET /api/v1/analysis/category?type=income&start_date=&end_date=`
> **设计说明:** PRD 原文重点描述了支出维度的分析,但收入来源的结构分析是完整财务画像不可缺少的一环。用户需要了解"钱从哪来"的占比分布,才能做出更好的财务规划决策。
---
## 5. 预算管理区 (BudgetView)
### 图表9预算进度仪表盘多量规阵列
**图表类型:** `ECharts Gauge Chart`多个仪表盘组成阵列
**用途:** 直观展示每个预算分类的执行进度百分比配合 DDS 中定义的 80%/100% 阈值预警逻辑
| 配置项 | 说明 |
|---|---|
| `series.type` | `'gauge'` |
| `series.progress.show` | `true`显示进度弧 |
| `series.axisLine.lineStyle.color` | 三段式渐变`[[0.8, '#10B981'], [1.0, '#F59E0B'], [1.0+, '#EF4444']]`绿 |
| `series.detail.formatter` | `'{value}%'`中心显示百分比 |
| `series.title.text` | 分类名称"餐饮"、"交通" |
| `series.data` | `[{ value: 75, name: '餐饮' }]`表示已用 75% |
| 布局 | 使用 `v-row` + `v-col` 阵列每个分类一个小仪表盘全局预算用大号仪表盘 |
**阈值预警联动(对齐 DDS §4.2**
- `0% ~ 79%` 绿色弧 `#10B981` + 正常文字
- `80% ~ 99%` 橙色弧 `#F59E0B` + 橙色警告徽章
- `≥ 100%` 红色弧 `#EF4444` + 红色超支提示 + 弧度超出刻度线
```typescript
// BudgetGauge.vue 核心 option
const getGaugeOption = (budget: BudgetItem): EChartsOption => ({
series: [{
type: 'gauge',
startAngle: 200,
endAngle: -20,
min: 0,
max: 100,
progress: { show: true, width: 12 },
pointer: { show: false },
axisLine: {
lineStyle: {
width: 12,
color: [[0.8, '#10B981'], [1, '#F59E0B'], [1.2, '#EF4444']] // 允许超出100%
}
},
axisTick: { show: false },
splitLine: { show: false },
axisLabel: { show: false },
detail: {
valueAnimation: true,
formatter: `{value}%\${budget.used} / ¥${budget.limit}`,
fontSize: 14
},
title: { text: budget.categoryName, offsetCenter: [0, '80%'] },
data: [{ value: Math.round((budget.used / budget.limit) * 100) }]
}]
})
```
**后端接口:** `GET /api/v1/budgets?month=2026-02`已在 DDS 中定义响应需扩展
```json
// Response
{
"code": 0,
"data": [
{
"id": 1, "category_name": "全局", "category_id": null,
"limit": 10000, "used": 8200, "percentage": 82,
"status": "warning"
},
{
"id": 2, "category_name": "餐饮", "category_id": 1,
"limit": 3000, "used": 2400, "percentage": 80,
"status": "warning"
},
{
"id": 3, "category_name": "交通", "category_id": 3,
"limit": 1000, "used": 650, "percentage": 65,
"status": "normal"
}
]
}
```
---
### 图表10预算 vs 实际对比柱状图
**图表类型:** `ECharts Bar Chart`分组柱状图
**用途:** 对比各分类的预算限额与实际支出直观发现超支和节省的分类辅助下月预算调整
| 配置项 | 说明 |
|---|---|
| `xAxis` | 各预算分类名称 `type: 'category'` |
| `series[0]` | 预算限额柱颜色 `#93C5FD`浅蓝`barMaxWidth: 24` |
| `series[1]` | 实际支出柱颜色动态未超支 `#10B981`绿超支 `#EF4444` |
| `series[1].itemStyle.color` | 使用 `function(params)` 回调根据是否超支动态着色 |
| `markLine` | 100% 预算位置画水平参考线 |
| `tooltip` | 显示`分类名 | 预算: ¥X | 实际: ¥Y | 差额: ±¥Z (XX%)` |
**后端接口:** 复用 `GET /api/v1/budgets?month=2026-02`
---
## 6. 账户管理区 (AccountView)
### 图表11账户收支瀑布图
**图表类型:** `ECharts Bar Chart`瀑布图使用透明柱实现
**用途:** 展示选定账户在某月内余额的逐日/逐笔变化过程帮助用户理解"钱是怎么花没的"。
| 配置项 | 说明 |
|---|---|
| 实现方式 | 使用 ECharts 堆叠柱模拟瀑布底部透明柱 (`itemStyle.color: 'transparent'`) + 上方有色柱 |
| `xAxis` | 日期或交易序号 |
| 颜色逻辑 | 收入笔绿色柱向上增长支出笔红色柱向下减少最终柱蓝色(期末余额) |
| `tooltip` | 显示`日期 | 交易对方 | ±金额 | 余额` |
| `series.label` | 在柱体上方/下方显示金额增减 |
**后端接口:** `GET /api/v1/accounts/:id/waterfall?month=2026-02`
```json
// Response
{
"code": 0,
"data": {
"account_name": "招行储蓄卡",
"opening_balance": 80000,
"closing_balance": 82500,
"transactions": [
{ "date": "2026-02-01", "peer": "工资", "amount": 15000, "type": "income", "balance": 95000 },
{ "date": "2026-02-03", "peer": "房租", "amount": -5500, "type": "expense", "balance": 89500 },
{ "date": "2026-02-05", "peer": "美团外卖", "amount": -35, "type": "expense", "balance": 89465 }
]
}
}
```
---
## 7. 导入质量区 (ImportView)
### 图表12导入质量统计图
**图表类型:** `ECharts Bar Chart`堆叠柱状图
**用途:** 每次导入后展示本次及历史导入的数据质量分布新增/去重/链路合并/失败帮助用户监控 ETL 管道健康度
| 配置项 | 说明 |
|---|---|
| `xAxis` | 导入批次按时间倒序最近 10 |
| `series[0]` | 新导入数颜色 `#10B981`绿`stack: 'total'` |
| `series[1]` | 去重跳过数颜色 `#F59E0B``stack: 'total'` |
| `series[2]` | 链路合并数颜色 `#4F6EF7``stack: 'total'` |
| `series[3]` | 失败数颜色 `#EF4444``stack: 'total'` |
| `tooltip` | 显示各类明细和总解析条数 |
**后端接口:** `GET /api/v1/bills/import-history?limit=10`
```json
// Response
{
"code": 0,
"data": [
{
"batch_id": "20260226-001",
"provider": "alipay",
"imported_at": "2026-02-26T19:30:00+08:00",
"total": 150, "imported": 132, "duplicated": 15, "linked": 3, "failed": 0
}
]
}
```
---
## 8. 全局设计规范
### 8.1 统一色彩系统
为保证跨图表的**视觉一致性****认知连贯性**所有图表使用统一的语义化色板
| 语义 | 色值 | 用途场景 |
|---|---|---|
| **收入/正向/安全** | `#10B981` (Emerald-500) | 收入柱正常进度储蓄类 |
| **支出/负向/危险** | `#EF4444` (Red-500) | 支出柱超支预警失败 |
| **警告/临近阈值** | `#F59E0B` (Amber-500) | 80% 预算警告去重跳过 |
| **中性/信息** | `#4F6EF7` (Indigo-500) | 结余线链路合并账户主色 |
| **辅助蓝** | `#818CF8` (Violet-400) | 辅助信息次要指标 |
| **背景辅助** | `#F8FAFC` (Slate-50) | 图表背景空白区域 |
**分类色板**饼图/折线图/桑基图多分类通用 10 色循环
```typescript
const CATEGORY_PALETTE = [
'#4F6EF7', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6',
'#EC4899', '#06B6D4', '#F97316', '#84CC16', '#6366F1'
]
```
### 8.2 ECharts 公共配置封装
```typescript
// composables/useECharts.ts
import * as echarts from 'echarts/core'
import { ref, onMounted, onUnmounted, watch } from 'vue'
export function useECharts(containerRef: Ref<HTMLElement | null>) {
const chartInstance = ref<echarts.ECharts | null>(null)
let resizeObserver: ResizeObserver | null = null
onMounted(() => {
if (containerRef.value) {
chartInstance.value = echarts.init(containerRef.value)
// 响应式 resize
resizeObserver = new ResizeObserver(() => {
chartInstance.value?.resize()
})
resizeObserver.observe(containerRef.value)
}
})
onUnmounted(() => {
resizeObserver?.disconnect()
chartInstance.value?.dispose()
})
const setOption = (option: echarts.EChartsOption) => {
chartInstance.value?.setOption(option, { notMerge: true })
}
return { chartInstance, setOption }
}
```
### 8.3 图表联动设计
12 张图在 Vue3 中的协作方式
```mermaid
graph LR
Store["Pinia: dateRangeStore"] -->|watch dateRange| C1["图表1~3 (Dashboard)"]
Store -->|watch dateRange| C4["图表4~8 (Analysis)"]
Store -->|watch month| C9["图表9~10 (Budget)"]
C4 -->|"emit('category-filter')"| BillTable["账单列表表格"]
C4 -->|"emit('category-filter')"| C7["图表7: 桑基图高亮"]
C9 -->|"点击分类仪表盘"| C10["图表10: 对应分类高亮"]
```
| 联动机制 | 实现方式 |
|---|---|
| **全局时间筛选器** | Pinia store 存储 `dateRange`所有图表 `watch` 该变量触发 API 重新请求并刷新 |
| **分类联动** | 点击环形图扇区 `emits('category-filter', categoryId)` 账单表格过滤 + 桑基图高亮对应节点 |
| **图表 resize** | 统一在 `useECharts` composable 中使用 `ResizeObserver` 处理配合 Vuetify 响应式断点 |
| **数据懒加载** | 桑基图和热力图数据量较大使用 `defineAsyncComponent` 延迟渲染进入视口后加载 |
| **颜色同步** | 跨图表的相同分类使用 `CATEGORY_PALETTE` 通过 `categoryId % 10` 索引取色保证颜色映射一致 |
### 8.4 ECharts 组件注册清单
采用 ECharts 按需引入减少打包体积
```typescript
// plugins/echarts.ts
import * as echarts from 'echarts/core'
import {
LineChart, // 图表1, 6
BarChart, // 图表2, 3, 10, 11, 12
PieChart, // 图表4, 8
HeatmapChart, // 图表5
SankeyChart, // 图表7
GaugeChart, // 图表9
} from 'echarts/charts'
import {
TitleComponent, TooltipComponent, LegendComponent,
GridComponent, DataZoomComponent, VisualMapComponent,
CalendarComponent, MarkLineComponent, MarkPointComponent,
MarkAreaComponent, GraphicComponent, ToolboxComponent
} from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
echarts.use([
LineChart, BarChart, PieChart, HeatmapChart, SankeyChart, GaugeChart,
TitleComponent, TooltipComponent, LegendComponent,
GridComponent, DataZoomComponent, VisualMapComponent,
CalendarComponent, MarkLineComponent, MarkPointComponent,
MarkAreaComponent, GraphicComponent, ToolboxComponent,
CanvasRenderer
])
export default echarts
```
### 8.5 前端组件与后端 API 完整映射
| Vue 组件 | ECharts 图表类型 | 后端 API |
|---|---|---|
| `NetWorthTrendChart.vue` | Line (Area) | `GET /api/v1/dashboard/trend` |
| `CashFlowBarChart.vue` | Bar + Line (混合) | `GET /api/v1/dashboard/trend` |
| `AssetCompositionChart.vue` | Bar (Stack) | `GET /api/v1/dashboard/asset-composition` |
| `ExpensePieChart.vue` | Pie (Donut) | `GET /api/v1/analysis/category?type=expense` |
| `CalendarHeatmap.vue` | Heatmap (Calendar) | `GET /api/v1/analysis/heatmap` |
| `CategoryTrendChart.vue` | Line (Multi) | `GET /api/v1/analysis/category-trend` |
| `SankeyChart.vue` | Sankey | `GET /api/v1/analysis/sankey` |
| `IncomePieChart.vue` | Pie (Donut) | `GET /api/v1/analysis/category?type=income` |
| `BudgetGauge.vue` | Gauge | `GET /api/v1/budgets` |
| `BudgetCompareChart.vue` | Bar (Grouped) | `GET /api/v1/budgets` |
| `AccountWaterfallChart.vue` | Bar (Waterfall) | `GET /api/v1/accounts/:id/waterfall` |
| `ImportQualityChart.vue` | Bar (Stack) | `GET /api/v1/bills/import-history` |

View File

@@ -0,0 +1,566 @@
# DDS 文档 → Google Stitch UI 设计 Prompt 转换指南
> 本文档提供一套系统化的方法论,用于将软件系统的 **DDS详细设计说明书** 转换为 **Google Stitch** 能够理解并生成高质量 UI 设计的 prompt。
---
## 一、转换方法论总览
### 核心思路Zoom-Out → Zoom-In 分层提取
```
DDS 文档
├── 第1层系统全局上下文Zoom-Out → Stitch 全局系统 prompt
├── 第2层页面级结构提取 → Stitch 逐页设计 prompt
├── 第3层组件级细节提取 → Stitch 组件精修 prompt
└── 第4层交互与联动提取 → Stitch 交互追加 prompt
```
> [!IMPORTANT]
> Google Stitch 的最佳实践是**分步生成、逐步精修**,不要试图一次性生成整个系统的 UI。建议按页面逐一生成每个页面先生成骨架再通过迭代精修细节。
### DDS 信息提取清单
从 DDS 文档中需要提取的 UI 相关信息:
| 提取维度 | DDS 中的对应章节 | 提取要点 |
|---|---|---|
| **系统定位与目标用户** | §1 项目背景 / PRD | 产品类型、面向人群、核心价值主张 |
| **页面结构与路由** | §3.1 页面结构与路由 | 有哪些页面、层级关系、导航结构 |
| **页面布局** | §3.3 核心页面设计 | ASCII 布局图、区域划分、信息层级 |
| **图表与数据可视化** | 数据可视化 DDS | 图表类型、数据维度、色彩规范 |
| **色彩系统** | §8.1 统一色彩系统 | 语义化色板、分类色板、品牌色 |
| **组件清单** | §3.2 项目结构 | Vue 组件列表、功能定义 |
| **数据模型** | §2.3 数据模型 | 实体关系、字段定义(用于理解界面数据) |
| **API 接口** | §2.4 API 接口 | 数据结构(用于理解界面需要展示什么数据) |
---
## 二、Prompt 模板体系
### 🔹 Step 0全局 Design Token Prompt系统级仅需执行一次
> 目的:为 Stitch 建立设计系统的基础约束,后续每个页面 prompt 可引用此上下文。
```
【系统设计基调 Prompt】
我正在设计一个名为「ProjectMoneyX」的个人全景财务分析系统的 Web 端 UI。
### 产品定位
- 这是一款面向个人用户的财务数据分析工具
- 核心功能:多源账单导入(支付宝/微信/银行)→ 智能去重 → 多维可视化分析 → 预算管理
- 用户画像25-40岁的白领/自由职业者,关注个人财务健康,有一定数据分析意识
- 使用场景主要在桌面端浏览器使用每周查看1-2次财务报告
### 设计风格要求
- 整体风格现代金融科技FinTech风格专业但不冰冷
- 设计语言:类似 Material Design 3 的圆角卡片式布局
- 色彩基调:
- 主色/中性蓝:#4F6EF7Indigo-500用于品牌调性和信息展示
- 正向/收入色:#10B981Emerald-500用于收入、正常状态
- 负向/支出色:#EF4444Red-500用于支出、超支预警
- 警告色:#F59E0BAmber-500用于临近阈值提醒
- 背景色:#F8FAFC浅灰白卡片背景白色
- 字体:使用系统字体 + Noto Sans SC中文
- 布局:左侧固定导航栏 + 右侧主内容区的经典 Dashboard 布局
- 深色模式支持:需要考虑暗色主题的兼容性
### 导航结构(侧边栏菜单)
1. 📊 仪表盘Dashboard— 默认首页
2. 📋 账单管理Bills
3. 📤 账单导入Import
4. 🏦 账户管理Accounts
5. 💰 预算管理Budget
6. 📈 多维分析Analysis
7. ⚙️ 规则配置Rules
请为这个系统设计一致的视觉风格。所有页面文字使用中文。
```
---
### 🔹 Step 1仪表盘页面DashboardView
> 从 DDS §3.3.1 + 数据可视化 DDS §1 提取
```
【仪表盘页面设计 Prompt】
为「ProjectMoneyX 个人全景财务分析系统」设计仪表盘Dashboard页面。
### 页面目标
用户打开系统后的第一个页面,需要在一屏内快速获取个人财务健康全貌。
### 页面布局(从上到下)
**第一行核心指标卡片区3个等宽卡片**
- 卡片1「净资产」显示 ¥116,500下方小字"较上月 ↑3.2%",背景带有淡蓝色渐变
- 卡片2「本月收入」显示 ¥15,000下方 ↑5.2%(绿色箭头),图标用收入符号
- 卡片3「本月支出」显示 ¥8,200下方 ↓3.1%(绿色箭头表示支出减少是好事),图标用支出符号
- 每个卡片都有圆角、微弱阴影、悬停时轻微上浮动画
**第二行图表区2列布局左宽右窄比例约 6:4**
- 左侧「净资产趋势图」面积折线图展示近12个月的净资产、总资产、总负债三条线
- 净资产线为实线蓝色(#4F6EF7)带半透明渐变填充
- 总资产为绿色虚线(#10B981)
- 总负债为红色虚线(#EF4444)
- 图表上方有标题"净资产趋势"和时间范围选择器近6月/近12月/全部)
- 右侧「月度现金流对比」:柱状图+折线图混合
- 绿色柱=收入,红色柱=支出,蓝色折线=结余
- 亏损月份的柱状图背景有淡红色标记
**第三行:资产构成区(全宽)**
- 「各账户资产构成」:堆叠面积图,展示各账户余额随时间的构成变化
- 包含:招行储蓄卡、支付宝余额、微信零钱等正向资产(向上堆叠)
- 以及:招行信用卡、花呗等负债(负值向下延伸)
- 图表外框是白色卡片容器,有圆角和阴影
### 视觉要求
- 卡片之间有 16px 间距
- 图表容器统一使用白色圆角卡片border-radius: 12px
- 页面顶部有"仪表盘"标题和全局时间筛选器
- 所有数字使用等宽字体,金额显示千分位分隔符
- 页面内容使用中文
请生成一个专业的、现代化的仪表盘页面设计。
```
---
### 🔹 Step 2账单导入页ImportView
> 从 DDS §3.3.2 + 数据可视化 DDS §7 提取
```
【账单导入页设计 Prompt】
为「ProjectMoneyX」设计账单导入页面。
### 页面目标
引导用户完成账单文件的上传和导入,展示导入结果和历史导入质量。
### 页面布局
**上半部分导入操作区卡片式步骤引导Step 1-2-3 横向流程)**
- Step 1「选择来源」
- 展示 4-6 个可选来源的图标卡片(横向排列)
- 每个卡片包含图标和名称:支付宝(蓝色)、微信支付(绿色)、招商银行(红色)、工商银行(红色)、京东(红色)、美团(黄色)
- 选中状态:卡片边框高亮 + 勾选标记
- 卡片之间 12px 间距,悬停有缩放效果
- Step 2「上传文件」
- 大尺寸拖拽上传区域(虚线边框,中间云上传图标 + 文字"拖拽文件到此处,或点击选择"
- 支持的格式提示文字CSV / XLS / PDF
- 上传中显示进度条
- Step 3「导入结果」
- 导入成功后显示统计卡片行:
- ✅ 解析 150 条(蓝色)
- ✅ 新导入 132 条(绿色)
- ⚠️ 去重跳过 15 条(橙色)
- 🔗 链路合并 3 条(蓝色)
- ❌ 失败 0 条(灰色)
**下半部分:导入历史质量图表(全宽卡片)**
- 标题:「导入质量趋势」
- 堆叠柱状图X轴为最近10次导入批次Y轴为条数
- 绿色段=新导入数,橙色段=去重数,蓝色段=合并数,红色段=失败数
- 图表下方有最近导入记录表格,显示时间、来源、各项统计
### 视觉要求
- 步骤之间用连接线或箭头串联,当前步骤高亮
- 未到达的步骤灰化处理
- 整体卡片式布局,白色圆角卡片 + 淡灰背景
- 页面所有文字使用中文
```
---
### 🔹 Step 3多维分析页AnalysisView
> 从 DDS §3.3.3 + 数据可视化 DDS §2-4 提取
```
【多维分析页设计 Prompt】
为「ProjectMoneyX」设计多维分析页面这是系统中数据可视化最丰富的页面。
### 页面目标
提供深度的收支分析能力,帮助用户理解"钱花在哪了"和"钱从哪来"。
### 页面结构
**顶部:全局筛选栏**
- 时间范围选择器(日期区间 picker
- 快捷选项按钮组:本月 / 近3月 / 近6月 / 近1年 / 自定义
- 页面标题左侧显示"多维分析"
**Tab 标签页切换3个 Tab**
---
**Tab 1支出分析**
- 左右两列布局5:5
- 左侧「支出结构环形图」:
- 大尺寸环形图Donut中心显示"总支出 ¥9,820"
- 外侧标签:餐饮 32.6%、购物 25.5%、交通 12.2% 等
- 支持点击某分类后下钻到二级分类(如 餐饮→外卖/堂食/咖啡)
- 下钻后顶部出现面包屑导航 "全部 > 餐饮"
- 颜色使用分类色板:#4F6EF7、#10B981、#F59E0B、#EF4444、#8B5CF6...
- 右侧「分类支出趋势折线图」:
- 多条折线,每条代表一个支出分类
- 默认展示前5大分类其余折叠
- 底部有缩放滑块,支持拖拽查看任意时间段
- 颜色与左侧环形图一致(跨图表颜色同步)
- 下方全宽「收支日历热力图」:
- 日历格子视图,展示每日消费强度
- 颜色从浅绿(低消费)渐变到深红(高消费)
- 悬停显示该日总额和前3笔最大账单
- 支持月份/年份切换
---
**Tab 2资金流向**
- 全宽展示「资金流向桑基图」Sankey Diagram⭐ 核心图表
- 三列布局:左列=收入来源(工资、兼职、投资收益),中列=资金池/账户(招行储蓄、支付宝、微信),右列=支出分类(餐饮、购物、居住、储蓄)
- 流线颜色使用源到目标的渐变色
- 悬停高亮相邻节点和链接,淡化其他
- 节点标签:左列左对齐,中列居中,右列右对齐
- 整体图表高度 500px 以上,确保信息清晰
---
**Tab 3收入分析**
- 「收入来源环形图」:与支出环形图对称设计
- 中心显示"总收入 ¥15,000"
- 使用绿色系配色:#10B981、#34D399、#6EE7B7、#A7F3D0
- 分类:工资、兼职收入、理财收益、转账收款等
### 视觉要求
- Tab 切换使用底部指示线动画
- 所有图表统一白色卡片容器,带标题栏
- 图表标题栏右侧可放置图表操作图标(下载、全屏等)
- 页面所有文字使用中文
```
---
### 🔹 Step 4预算管理页BudgetView
> 从 DDS §4.2 + 数据可视化 DDS §5 提取
```
【预算管理页设计 Prompt】
为「ProjectMoneyX」设计预算管理页面。
### 页面目标
直观展示各分类预算执行进度,快速识别超支和节省项。
### 页面布局
**顶部:月份选择器 + 操作按钮**
- 左侧:月份选择器(< 2026年2月 >),可左右切换
- 右侧:「设置预算」按钮(主色调),点击弹出预算编辑弹窗
**第一行:全局预算仪表盘(居中,大号)**
- 单个大尺寸仪表盘Gauge展示全局预算使用率
- 弧形进度条0-79% 绿色 → 80-99% 橙色 → ≥100% 红色
- 中心显示百分比数字 + "¥8,200 / ¥10,000"
- 标题"全局预算"在仪表盘下方
**第二行分类预算仪表盘阵列网格布局3-4列**
- 每个分类一个小号仪表盘卡片,包含:
- 分类图标 + 分类名称
- 环形进度条(同样三段变色逻辑)
- 中心数字82% + "¥2,400/¥3,000"
- 超支的卡片有红色边框闪烁效果
- 示例分类:餐饮(80%⚠️)、交通(65%✅)、购物(110%🔴)、居住(45%✅)、娱乐(30%✅)
**第三行:预算 vs 实际对比柱状图(全宽卡片)**
- 分组柱状图:每个分类两根柱子
- 浅蓝柱=预算限额
- 动态色柱=实际支出(未超支绿色,超支红色)
- 100% 预算位置有水平参考虚线
- tooltip 显示差额和百分比
### 视觉要求
- 仪表盘弧度动画页面加载时从0动画填充到目标值
- 超支项有强烈的红色视觉提示(不仅是颜色,还有图标/徽章)
- 分类卡片支持悬停展开详情
- 页面所有文字使用中文
```
---
### 🔹 Step 5账户管理页AccountView
> 从 DDS §3.1 + 数据可视化 DDS §6 提取
```
【账户管理页设计 Prompt】
为「ProjectMoneyX」设计账户管理页面。
### 页面目标
管理用户的所有资金账户,查看各账户余额和交易流水。
### 页面布局
**顶部:账户总览卡片行**
- 横向卡片滚动/网格,每个账户一个卡片:
- 卡片上半部分:账户图标 + 账户名称 + 账户类型标签(储蓄卡/信用卡/电子钱包)
- 卡片下半部分:当前余额(大字加粗)
- 储蓄卡类:蓝色系渐变背景
- 信用卡类:红色系渐变背景,额外显示"已用额度/总额度"
- 电子钱包类:紫色系渐变背景
- 右上角有编辑和删除小图标
- 最右侧有一个虚线框的「+ 添加账户」卡片
**下半部分:选中账户的详情区**
- 选中某个账户卡片后,下方展示该账户的详情:
- 左侧6/10宽度「账户收支瀑布图」
- 瀑布柱状图,展示月内余额逐笔变化
- 起始柱(月初余额)→ 绿色向上柱(收入)→ 红色向下柱(支出)→ 蓝色终止柱(月末余额)
- 每根柱子上方/下方标注金额变化
- 月份选择器在图表标题栏
- 右侧4/10宽度账户信息卡片
- 账户名称、类型、币种
- 本月收入合计 / 支出合计 / 净变化
- 最近 5 笔交易列表
### 视觉要求
- 账户卡片类似银行卡片造型,有微光泽/渐变效果
- 选中账户卡片有高亮边框 + 下方指示箭头
- 页面所有文字使用中文
```
---
### 🔹 Step 6账单管理页BillListView
```
【账单管理页设计 Prompt】
为「ProjectMoneyX」设计账单管理页面。
### 页面目标
支持多维条件筛选和查看所有账单记录。
### 页面布局
**顶部:高级筛选面板(可展开/收起的卡片)**
- 第一行筛选项:时间范围(日期区间)、交易类型(收入/支出/全部 按钮组)
- 第二行筛选项:金额区间(最小~最大)、账户(下拉选择)、分类(级联选择器)、来源(支付宝/微信等 多选)
- 第三行:关键词搜索框(搜索交易对方/商品说明)+ 「查询」按钮 + 「重置」按钮
- 展开/收起按钮,默认只显示第一行
**主体:账单数据表格**
- 表头列:日期、交易对方、商品说明、金额、交易类型、分类、账户、来源
- 金额列:收入行显示绿色正数,支出行显示红色负数
- 交易类型列使用小标签tag收入=绿tag支出=红tag
- 来源列:显示对应图标(支付宝/微信等小logo
- 每行末尾有操作列:查看详情、编辑、删除
- 表格支持列排序(点击表头)
- 底部分页器显示总条数每页20/50/100条切换
**表格上方工具栏**
- 左侧:显示匹配结果数"共 500 条记录"
- 右侧:导出按钮、列设置按钮
### 视觉要求
- 表格偶数行有浅灰背景(斑马纹)
- 悬停行高亮
- 支出和收入行的金额颜色区分明显
- 页面所有文字使用中文
```
---
### 🔹 Step 7规则配置页RuleView
```
【规则配置页设计 Prompt】
为「ProjectMoneyX」设计规则配置页面。
### 页面目标
让用户管理自动分类映射规则和账户路由规则,控制 ETL 数据清洗行为。
### 页面布局
**Tab 切换:分类规则 / 账户路由规则**
---
**Tab 1分类映射规则**
- 顶部:「+ 新增规则」按钮
- 规则列表(卡片式,非表格):
- 每条规则一个卡片,显示:
- 匹配条件:标识标签 "交易对方" 或 "商品说明",后面显示正则表达式(代码样式)
- 箭头 →
- 目标分类:"餐饮-咖啡" (带分类颜色标签)
- 优先级数字徽章
- 启用/禁用切换开关
- 编辑/删除操作图标
- 规则按优先级降序排列,高优先级规则排在前面
- 支持拖拽排序调整优先级
---
**Tab 2账户路由规则**
- 类似的卡片式列表:
- 来源标签:"支付宝"(蓝色标签)
- 匹配方式:支付方式包含 "招商银行信用卡"
- 箭头 →
- 目标账户:"招行信用卡" (带账户类型图标)
**新增/编辑弹窗**
- 表单弹窗:选择匹配字段、输入正则表达式、选择目标分类/账户、设置优先级
- 有"测试规则"按钮,可输入样例文本测试匹配结果
### 视觉要求
- 规则卡片之间有清晰的分隔
- 正则表达式用等宽字体 + 代码背景色展示
- 箭头使用 → 图标表达映射关系
- 页面所有文字使用中文
```
---
## 三、迭代精修 Prompt 模板
在 Stitch 生成初版设计后,使用以下追加 prompt 进行精修:
### 3.1 交互动效精修
```
请为当前设计添加以下交互效果:
1. 卡片悬停时轻微上浮translateY: -2px+ 阴影加深
2. 数字指标在页面加载时有从0到目标值的计数动画
3. Tab 切换时有滑动过渡效果
4. 图表区域在进入视口时有淡入+上滑的入场动画
5. 按钮点击有涟漪扩散效果Material Design ripple
```
### 3.2 响应式适配
```
请调整当前设计的响应式布局:
- 桌面端≥1280px侧边栏固定展开 + 主内容区自适应
- 平板端768-1279px侧边栏收起为图标模式主内容区全宽
- 移动端(<768px侧边栏变为底部 Tab 导航,卡片竖向堆叠
- 仪表盘的三列卡片在移动端变为单列
- 图表在小屏下高度等比缩小,保持可读性
```
### 3.3 暗色模式
```
请为当前设计创建暗色模式版本:
- 背景色从 #F8FAFC 变为 #0F172A深蓝灰
- 卡片背景从白色变为 #1E293B
- 文字颜色从深灰变为 #E2E8F0
- 图表背景透明,网格线使用 rgba(255,255,255,0.1)
- 色彩系统中的语义色(绿/红/橙/蓝)保持不变但亮度微调
- 阴影从灰色阴影变为更深的投影
- 侧边栏背景 #1E293B选中项高亮使用主色半透明
```
### 3.4 空状态设计
```
请为以下场景设计空状态界面:
1. 首次使用 - 仪表盘无数据:显示插画 + "开始导入您的第一份账单" + 引导按钮
2. 账单列表搜索无结果:显示搜索插画 + "未找到匹配的账单记录"
3. 预算页面未设置预算:显示图标 + "您还未设置任何预算" + "立即设置"按钮
4. 分析页面数据不足:显示图表插画 + "数据量不足,建议导入更多账单后查看分析"
```
---
## 四、高级技巧
### 4.1 使用 DDS 中的 ASCII 布局图
> DDS 中常包含 ASCII 格式的页面布局草图,可以直接转化为 Stitch 的结构描述。
**DDS 原文示例:**
```
┌─────────────────────────────────────────────────────────┐
│ [净资产卡片] [本月收入卡片] [本月支出卡片] │
│ ¥116,500 ¥15,000 ↑5.2% ¥8,200 ↓3.1% │
├──────────────────────────┬──────────────────────────────┤
│ 收支趋势折线图 (ECharts) │ 消费结构饼图 (ECharts) │
│ (近12个月) │ (本月各分类占比) │
├──────────────────────────┴──────────────────────────────┤
│ 各账户余额一栏表 (v-data-table) │
└─────────────────────────────────────────────────────────┘
```
**转化手法:** 将 ASCII 图的区块关系、比例、信息层级直接翻译为自然语言的空间描述(上/下、左/右、占比等),如上述各页面 prompt 所示。
### 4.2 从 API Response 推导界面数据
> DDS 中的 API 响应结构直接告诉我们界面需要展示哪些字段。
```json
// 从 DDS 的 API 响应结构
{
"total_assets": 125000.00, UI: "总资产 ¥125,000"
"total_liabilities": 8500.00, UI: "总负债 ¥8,500"
"net_worth": 116500.00, UI: "净资产 ¥116,500"(核心指标卡片)
"income_mom_pct": 5.2, UI: "↑5.2%"(环比增长标签)
}
```
### 4.3 从色彩系统构建 Stitch Prompt
> DDS §8.1 的色彩系统应该完整传递给 Stitch确保生成的设计色彩一致。
**关键做法:** 在每个页面 prompt 中引用完整的语义化色彩映射(收入=绿、支出=红、警告=橙、中性=蓝),而不是仅给出色值。
### 4.4 Stitch 的 Experimental Mode 高级用法
如果你有系统的线框图或草图,可以使用 Stitch 的 **Experimental Mode**
1. 将 DDS 中的 Mermaid 图表导出为图片
2. 将 ASCII 布局图在画图工具中绘制为简单线框
3. 配合文字 prompt 一起上传到 Stitch Experimental Mode
4. 这种图文并茂的方式能获得更精准的布局结果
---
## 五、完整工作流程
```mermaid
graph TD
A["1. 阅读 DDS 文档"] --> B["2. 提取 UI 相关信息"]
B --> C["3. 编写全局设计 Token Prompt"]
C --> D["4. 按页面逐一生成设计"]
D --> E["5. 使用迭代 Prompt 精修"]
E --> F{"6. 满意?"}
F -->|否| E
F -->|是| G["7. 导出为 Figma/HTML"]
G --> H["8. 结合 DDS 技术选型进行开发"]
```
### 推荐执行顺序
| 步骤 | Prompt | 预期产出 |
|---|---|---|
| 1 | Step 0: 设计基调 | 确定整体风格,不需要实际页面 |
| 2 | Step 1: 仪表盘 | 最重要的页面,奠定视觉基调 |
| 3 | Step 3: 多维分析 | 最复杂的页面,包含最多图表 |
| 4 | Step 4: 预算管理 | 仪表盘风格的延伸 |
| 5 | Step 2: 账单导入 | 流程导向页面 |
| 6 | Step 5: 账户管理 | 卡片+图表混合 |
| 7 | Step 6: 账单管理 | 表格导向页面 |
| 8 | Step 7: 规则配置 | 配置类页面 |
> [!TIP]
> **先攻克最重要+最复杂的页面**(仪表盘和多维分析),这两个页面的设计语言确立后,其他页面可以快速复用。