chore: 初始化文档站仓库
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# 数据模型
|
||||
|
||||
系统共 **18 张表**,覆盖用户、记账、标签、规则、AI、通知、邮箱账单与日志审计。所有表主键为自增 `id`,表间关系均为**逻辑外键**(通过 `user_id`、`category_id` 等字段在应用层维护,未声明物理外键)。
|
||||
|
||||
## 表清单
|
||||
|
||||
| 业务域 | 表名 | 说明 |
|
||||
|---|---|---|
|
||||
| 用户 | `t_user` | 用户表(用户名、BCrypt 密码、昵称) |
|
||||
| 用户 | `t_user_preference` | 每用户多条的用户偏好(键值) |
|
||||
| 记账 | `t_category` | 收支分类(收入/支出,含图标与排序) |
|
||||
| 记账 | `t_transaction` | 收支记录(核心表) |
|
||||
| 标签 | `t_tag` | 标签 |
|
||||
| 标签 | `t_transaction_tag` | 交易-标签关联(多对多) |
|
||||
| 规则 | `t_rule` | 自定义归类规则 |
|
||||
| 规则 | `t_rule_tag` | 规则-标签关联(多对多) |
|
||||
| AI | `t_ai_config` | 每用户一条的 AI 配置 |
|
||||
| AI | `t_ai_usage` | AI 调用用量记录 |
|
||||
| 通知 | `t_notification_config` | 每用户一条的提醒配置 |
|
||||
| 通知 | `t_notification_channel` | 通知渠道 |
|
||||
| 通知 | `t_notification_log` | 通知发送日志 |
|
||||
| 邮箱账单 | `t_email_bill_config` | IMAP 邮箱配置 |
|
||||
| 邮箱账单 | `t_email_bill_sender_rule` | 发件人规则 |
|
||||
| 邮箱账单 | `t_email_bill_message` | 拉取到的账单消息 |
|
||||
| 日志 | `t_http_log` | 接口访问日志 |
|
||||
| 日志 | `t_login_log` | 登录日志 |
|
||||
|
||||
## 关系概览
|
||||
|
||||
### 以用户为中心(一对多)
|
||||
|
||||
| 主体 | 关系 | 对象 | 关联字段 |
|
||||
|---|---|---|---|
|
||||
| t_user | 1 : N | t_category | user_id |
|
||||
| t_user | 1 : N | t_transaction | user_id |
|
||||
| t_user | 1 : N | t_tag | user_id |
|
||||
| t_user | 1 : N | t_rule | user_id |
|
||||
| t_user | 1 : N | t_notification_channel | user_id |
|
||||
| t_user | 1 : N | t_email_bill_config | user_id |
|
||||
| t_user | 1 : N | t_email_bill_sender_rule | user_id |
|
||||
| t_user | 1 : N | t_email_bill_message | user_id |
|
||||
| t_user | 1 : N | t_user_preference | user_id |
|
||||
| t_user | 1 : N | t_ai_usage / t_http_log / t_login_log / t_notification_log | user_id |
|
||||
|
||||
### 一对一(每用户一条)
|
||||
|
||||
| 主体 | 关系 | 对象 | 关联字段 |
|
||||
|---|---|---|---|
|
||||
| t_user | 1 : 1 | t_ai_config | user_id(唯一) |
|
||||
| t_user | 1 : 1 | t_notification_config | user_id(唯一) |
|
||||
|
||||
### 记账与标签
|
||||
|
||||
| 主体 | 关系 | 对象 | 关联字段 / 中间表 |
|
||||
|---|---|---|---|
|
||||
| t_category | 1 : N | t_transaction | transaction.category_id(可空=未分类) |
|
||||
| t_transaction | N : M | t_tag | 中间表 t_transaction_tag(联合唯一) |
|
||||
| t_category | 1 : N | t_rule | rule.category_id(命中目标分类) |
|
||||
| t_rule | N : M | t_tag | 中间表 t_rule_tag(联合唯一) |
|
||||
|
||||
### 通知与邮箱账单
|
||||
|
||||
| 主体 | 关系 | 对象 | 关联字段 |
|
||||
|---|---|---|---|
|
||||
| t_notification_channel | 1 : N | t_notification_log | channel_id(可空) |
|
||||
| t_email_bill_config | 1 : N | t_email_bill_message | config_id |
|
||||
| t_email_bill_sender_rule | 1 : N | t_email_bill_message | sender_rule_id(可空) |
|
||||
|
||||
> 邮箱配置与发件人规则的默认分类通过 `expense_category_id` / `income_category_id` 逻辑引用 `t_category`;默认标签以 JSON 数组字符串保存(未用关联表)。
|
||||
|
||||
## 核心表字段
|
||||
|
||||
### t_transaction(收支记录)
|
||||
|
||||
| 字段 | 说明 |
|
||||
|---|---|
|
||||
| user_id | 所属用户 |
|
||||
| category_id | 分类(可空,未分类) |
|
||||
| type | `INCOME` / `EXPENSE` |
|
||||
| amount | 金额(DECIMAL(12,2)) |
|
||||
| channel | 交易渠道(如 `ALIPAY` / `WECHAT` / `CASH` / `BANK`) |
|
||||
| remark | 备注 |
|
||||
| remark_hidden | 备注是否隐藏 |
|
||||
| external_no | 外部账单交易号,导入去重 |
|
||||
| transaction_time | 交易发生时间 |
|
||||
| include_in_stats | 是否计入统计(默认 1) |
|
||||
| raw_data | 账单导入原始 JSON(手动记录为空) |
|
||||
|
||||
关键索引:唯一索引 `uk_user_external (user_id, external_no)` 实现导入去重;`idx_user_time (user_id, transaction_time)` 支撑按时间查询与统计。
|
||||
|
||||
### t_category / t_tag
|
||||
|
||||
- 分类:`name`、`type`、`icon`(Emoji)、`sort_order`。
|
||||
- 标签:`name`、`color`、`sort_order`,唯一索引 `uk_user_name (user_id, name)` 保证用户内标签名唯一。
|
||||
|
||||
### t_rule
|
||||
|
||||
`name`、`enabled`、`sort_order`(优先级)、`type`、`keyword`、`min_amount`、`max_amount`、`category_id`。
|
||||
|
||||
### t_user_preference
|
||||
|
||||
按用户存储的键值偏好:`pref_key` 为偏好键(如 `billSourceIncludeInStats`、`excludedDisplayStyle`),`pref_value` 为标量字符串或 JSON。唯一索引 `uk_user_pref (user_id, pref_key)` 保证每个用户每个偏好仅一条。未配置时由应用回退系统默认值。
|
||||
|
||||
### t_email_bill_config
|
||||
|
||||
IMAP 连接信息(`host`/`port`/`use_ssl`/`username`/`password`/`folder`)、状态(`status`/`last_error`/`last_connected_at`/`last_uid`)、默认归类(`expense_category_id`/`income_category_id`/`tag_ids`)与拉取范围(`fetch_scope`/`fetch_limit`)。
|
||||
|
||||
### t_email_bill_message
|
||||
|
||||
`config_id`、`uid`、`message_id`、`subject`、`from_address`、`received_at`、附件信息、命中的 `sender_rule_id` 与 `bill_type`、状态(`PULLED`/`CONFIRMED`/`IGNORED`)、`error`。唯一索引 `uk_email_bill_message (config_id, uid, attachment_index)` 防止重复拉取。
|
||||
|
||||
## MySQL 与 SQLite 双脚本
|
||||
|
||||
系统同时维护 `sql/init.sql`(MySQL)与 `sql/schema-sqlite.sql`(SQLite),表结构与语义保持一致,主要差异:
|
||||
|
||||
| 维度 | MySQL | SQLite |
|
||||
|---|---|---|
|
||||
| 主键自增 | `BIGINT AUTO_INCREMENT` | `INTEGER PRIMARY KEY AUTOINCREMENT` |
|
||||
| 布尔 | `TINYINT(1)` | `INTEGER` |
|
||||
| 金额 | `DECIMAL(12,2)` | `NUMERIC(12,2)` |
|
||||
| JSON | `JSON` | `TEXT` |
|
||||
| 时间默认值 | `DEFAULT CURRENT_TIMESTAMP` | `strftime(...,'localtime')` |
|
||||
| `updated_at` 自动更新 | `ON UPDATE CURRENT_TIMESTAMP` | `AFTER UPDATE` 触发器 |
|
||||
| 语句分隔符 | `;` | `;;`(兼容触发器内部的分号) |
|
||||
| 列注释 | 支持 | 不支持 |
|
||||
|
||||
统计模块会依据当前数据源类型,切换 MySQL 与 SQLite 的时间分组函数(`DATE_FORMAT/QUARTER` 与 `strftime`)。
|
||||
|
||||
## 初始化与迁移
|
||||
|
||||
- 应用启动时由 `SchemaInitializer` 执行对应建表脚本(幂等)。
|
||||
- 建表脚本只做 `CREATE TABLE IF NOT EXISTS`,无法修改已有库的列;需要就地变更列名时由 `SchemaMigrator` 在启动/切换数据源时**幂等迁移**(如 `t_transaction.payment_method` → `channel`,MySQL 用 `information_schema`、SQLite 用 `PRAGMA table_info` 检测)。
|
||||
- 新用户注册时由 `DefaultDataInitializer` 初始化默认分类、标签与邮箱发件人规则。
|
||||
Reference in New Issue
Block a user