Files
ledgerly-docs/dev/architecture.md
T
rosercode 8bfdde24f2 docs: 定时通知补充飞书自定义机器人渠道说明
定时通知新增飞书渠道后同步文档:使用文档补充飞书渠道的配置方式与示例截图,开发文档补充 FEISHU 渠道类型与发送器实现,并在功能概览、技术栈等处同步“飞书”。

变更内容:
- guide/notifications.md 增加飞书渠道配置项与获取路径,新增飞书渠道配置示例图
- dev/notifications.md 渠道表新增 FEISHU(post 富文本、可选加签),补充 webhookUrl/secret 与 hasSecret 脱敏说明
- guide/introduction.md、guide/settings.md、index.md、dev/architecture.md 同步“飞书”
- scripts/ts/capture-elements.ts 新增 captureChannelFeishu 并纳入 main 全量调用
2026-10-13 12:52:43 +08:00

106 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 整体架构
本章介绍系统的分层结构与关键技术设计。
## 技术栈
| 层级 | 技术 |
|---|---|
| 后端 | Spring Boot 3.3.6 + Java 21 + MyBatis-Plus 3.5.12 |
| 数据库 | SQLite(本地单文件)/ MySQL |
| 前端 | Vue 3 + TypeScript + Vite + Naive UI + ECharts + Pinia + vue-i18n |
| 认证 | JWT(HMAC) |
| 对象映射 | MapStruct 1.6.3 |
| 账单解析 | EasyExcel(xlsx)/ Apache POI(xls)+ commons-csv + PDFBox + Zip4j |
| AI | DeepSeek(OpenAI 兼容接口,Spring RestClient) |
| 通知 | Jakarta Mail(SMTP / IMAP)+ Server 酱 + 飞书自定义机器人 |
| API 文档 | Knife4j(OpenAPI 3) |
## 后端分层
```text
controller 接口层,统一返回 Result<T>,经 UserContext 取当前用户
│
service 业务层(接口 + impl),事务、跨表校验、聚合
│
mapper MyBatis-Plus BaseMapper,少量自定义 SQL
│
entity 数据库表映射实体
```
辅助包:
| 包 | 职责 |
|---|---|
| `dto` / `vo` | 入参请求对象 / 出参视图对象 |
| `converter` | MapStruct 实体↔VO 转换(`VoConverter`) |
| `importer` | 账单解析器(`BillParser` 及实现、`BillArchiveExtractor`) |
| `exporter` | Excel 导出样式处理 |
| `notification` | 通知渠道发送器(工厂 + 各渠道实现) |
| `scheduler` | 定时任务(通知、日志清理、邮箱账单) |
| `interceptor` | JWT 鉴权、访问日志 |
| `config` | Web、JWT、Knife4j、MyBatis-Plus、动态数据源、SPA 路由回退 |
| `client` | DeepSeek 客户端 |
| `email` | IMAP 邮箱账单抓取(监听、拉取、解析、存储) |
| `common` | `Result`、`PageResult`、业务异常、全局异常处理 |
| `util` | `JwtUtil`、`UserContext`、`AppLogUtils` 等 |
| `enums` | `BillType`、`AiCallType`、`StatisticsDimension` 等 |
## 请求处理流程
```text
浏览器
│ /api/**
▼
AccessLogInterceptor 记录访问日志(方法/路径/耗时/状态/IP/用户)
│
JwtInterceptor 校验 Bearer Token(兼容 ?token= 供 SSE),写入 userId
│
Controller UserContext.getUserId()
│
Service → Mapper → 数据库(动态数据源)
│
GlobalExceptionHandler 统一异常 → Result{code,message,data}
```
- 登录、注册、注册状态、数据库状态等接口无需鉴权。
- 数据库未配置时,`UnconfiguredDataSource` 抛出的异常会转为业务码 `5031`,前端据此跳转初始化引导页。
## 认证与鉴权
- `JwtUtil` 使用 HMAC 密钥签发 JWT,`subject` 为用户 ID,附带用户名 claim,默认有效期 24 小时。
- `JwtInterceptor` 从 `Authorization: Bearer <token>` 解析;由于 `EventSource` 无法自定义请求头,同时兼容 `?token=` 查询参数(用于日志实时推送等 SSE 场景)。
- `UserContext` 基于 `RequestContextHolder` 读取拦截器写入的 `userId`,使控制器无需声明 `HttpServletRequest`。
## 前端结构
```text
src/
├── api/ 各模块 REST 接口封装(axios,统一携带 Token、处理 401/业务码)
├── views/ 页面组件(Dashboard、TransactionList、BillImport 等)
├── components/ 复用组件(账单预览、导入结果、AI 配置、通知配置等)
├── router/ 路由与导航守卫(数据库配置校验、登录校验)
├── store/ Pinia 状态(user / database / registration)
├── locales/ 中/英/日三语文案
├── composables/ 组合式函数(关键词历史)
└── utils/ 工具(交易渠道标签、SSE 封装等)
```
## 关键设计亮点
1. **运行时动态数据源**:启动无需数据库,配置后热切换,见[动态数据源](/dev/database)。
2. **账单两阶段导入**:解析预览 → 确认导入,按交易号去重,见[账单解析](/dev/bill-parsing)。
3. **规则引擎**:分类取最高优先级、标签取并集,见[规则引擎](/dev/rule-engine)。
4. **体系化 AI 调用**:13 类调用类型并记录 token 用量,见 [AI 集成](/dev/ai)。
5. **SSE 实时能力**:运行日志、邮箱检查进度、图片记账识别进度与数据库配置执行进度实时推送。
6. **用户偏好缓存**:`t_user_preference` 的读取走 Spring Cache 进程内缓存(`ConcurrentMapCacheManager`),写入时按用户失效,切换数据源时整体清空。
## 相关文档
- [数据模型](/dev/data-model)
- [账单解析](/dev/bill-parsing)
- [规则引擎](/dev/rule-engine)
- [AI 集成](/dev/ai)
- [定时通知](/dev/notifications)
- [动态数据源](/dev/database)