Files
cmbone/docs/04-architecture.md
T

237 lines
9.3 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.
# 架构设计
## 总览
```text
main.go
├─ Wails application
├─ embedded frontend/dist
├─ embedded frontend/src/locales/*.json
└─ services
├─ AppService
├─ AppConfigService
├─ HotkeyService
├─ SystemInfo
├─ OCRService # 当前存量示例
├─ AuthService # 已实现 provider 边界
├─ AuditLogService # 已实现审计日志边界
├─ AppLogService # 已实现运行日志边界
├─ ImageOptimizationService # 已实现本地模拟任务模型
└─ MetricsService # 已实现 P0 统计聚合
frontend/src
├─ router
├─ layouts
├─ pages
├─ components
├─ modules
├─ utils
└─ locales
```
前端通过 `frontend/bindings` 调用 Wails 暴露的 Go 服务。后端服务访问本地 SQLite、平台热键、文件系统、真实后端或 AI provider。
## 后端边界
- `main.go`:只负责应用组装、资源嵌入、服务注册和启动。
- `internal/models/`:定义数据库和服务返回的结构体。
- `internal/services/store.go`:负责 SQLite 连接、迁移和基础读写。
- `internal/services/appservice.go`:负责窗口、托盘、语言资源和应用生命周期。
- `internal/services/appconfig_service.go`:负责配置读写的 Wails 服务边界。
- `internal/services/settings_schema.go`:集中定义设置模块 schema、默认值、选项和初始化 SQL。
- `internal/services/hotkey_service.go`:负责热键读取、更新和重新注册。
- `internal/services/ocr_service.go`:当前 OCR 存量示例,后续可演进为图片 AI 能力的一部分。
- `internal/services/image_optimization_service.go`:负责商品图片 AI 优化任务、结果和本地模拟 provider。
- `internal/services/log_service.go`:负责审计日志和运行日志的记录、查询和共享写入 helper。
- `internal/services/metrics_service.go`:负责 P0 统计指标和趋势聚合。
- `platform/`:隔离 Windows / macOS 热键和系统能力差异。
已实现边界:
- `AuthService`:登录、退出、会话读取;内部通过 `AuthProvider` 接入本地固定账号或真实后端。当前 `LocalAuthProvider` 可用,`RemoteAuthProvider` 保留边界并返回未配置错误。
- `AppConfigService`:通过统一设置 schema 初始化和校验主题、语言、窗口行为、快捷键展示、数据目录、日志策略和登录配置。
- `ImageOptimizationService`:商品图片 AI 优化任务模型和本地模拟任务创建已可用,页面已接入任务创建、列表和结果预览。
- `AuditLogService`:审计日志记录和查询已可用,登录、设置变更和图片任务创建会写审计日志。
- `AppLogService`:运行日志记录和查询已可用,图片任务创建失败和服务错误会写运行日志。
- `MetricsService`:P0 统计指标和最近 N 天趋势已可查询,当前直接聚合 `image_tasks` 和 `audit_logs`。
服务之间不要互相绕过边界直接操作平台实现。新增平台能力时,优先放在 `platform/`,再由 `internal/services/` 暴露稳定方法。
## 前端边界
- `frontend/src/router/index.ts`:维护页面路由。
- `frontend/src/layouts/`:目标目录,放登录布局和主应用布局。
- `frontend/src/modules/auth/`:目标目录,放登录页面、会话状态和 provider 调用。
- `frontend/src/modules/settings/`:目标目录,放设置页和设置项。
- `frontend/src/modules/image-optimizer/`:放已接入的商品图片 AI 优化样例页面。
- `frontend/src/modules/logs/`:目标目录,放审计日志和运行日志页面。
- `frontend/src/modules/statistics/`:放统计卡片和趋势图。
- `frontend/src/modules/components-demo/`:目标目录,放常用组件示例。
- `frontend/src/components/template/`:放当前模块占位页共享壳。
- `frontend/src/components/`:通用展示组件和组合控件。
- `frontend/src/utils/`:国际化、主题、OS、热键等工具函数。
- `frontend/bindings/`:由 Wails 生成或按 Wails 合约维护,不写业务逻辑。
## 登录架构
登录已经通过 provider 边界实现:
```text
AuthService
└─ AuthProvider
├─ LocalAuthProvider
└─ RemoteAuthProvider
```
- `LocalAuthProvider`:用于模板演示和离线模式,固定账号密码由后端配置或安全哈希保存,不写死在前端。
- `RemoteAuthProvider`:用于真实后端,负责请求登录接口并保存 token / session;当前只保留接口边界并返回未配置错误。
- 前端只关心登录、退出和当前会话,不关心 provider 细节。
- 默认本地账号由 `appconfig` 初始化,用户名为 `admin`,默认密码为 `admin123`,密码以 salt + SHA-256 hash 形式保存。
- 登录成功、失败和退出会写入 `audit_logs`。
## 日志架构
审计日志和运行日志分开:
- 审计日志:记录用户可解释动作,支持查询、筛选和导出。
- 运行日志:记录系统错误和排错信息,支持按时间、级别、模块查看。
审计日志用于“责任链”,运行日志用于“故障定位”。不要用一张表混合两种语义。
## 数据模型
SQLite 数据库位于用户配置目录下的 `cmbone/cmbone.db`,不进入 git。
当前核心表:
```sql
hotkeys(
id INTEGER PRIMARY KEY,
keycode INTEGER,
modifiers INTEGER,
description TEXT,
target TEXT
)
```
```sql
appconfig(
id INTEGER PRIMARY KEY,
key TEXT,
type TEXT,
value TEXT,
description TEXT,
state INTEGER
)
```
当前 `appconfig` 默认配置由统一设置 schema 生成:
- `theme.mode`、`language`
- `window.start_state`、`window.width`、`window.height`、`window.remember_state`
- `shortcut.open_second_window`、`shortcut.open_main_window`
- `data.root_mode`、`data.custom_directory`
- `logs.level`、`logs.audit_retention_days`、`logs.app_retention_days`
- `auth.provider`、`auth.local.username`、`auth.local.password_salt`、`auth.local.password_hash`
```sql
auth_sessions(
id INTEGER PRIMARY KEY,
user_id TEXT,
username TEXT,
provider TEXT,
token TEXT,
created_at TEXT,
expires_at TEXT,
active INTEGER
)
```
```sql
audit_logs(
id INTEGER PRIMARY KEY,
actor TEXT,
action TEXT,
target_type TEXT,
target_id TEXT,
detail TEXT,
created_at TEXT
)
```
```sql
image_tasks(
id INTEGER PRIMARY KEY,
source_path TEXT,
status TEXT,
operation TEXT,
duration_ms INTEGER,
error_message TEXT,
created_at DATETIME,
updated_at DATETIME
)
```
```sql
image_task_results(
id INTEGER PRIMARY KEY,
task_id INTEGER,
output_path TEXT,
before_size INTEGER,
after_size INTEGER,
created_at DATETIME
)
```
当前 `image_tasks` 和 `image_task_results` 已由 `T-020` 落地,用于本地模拟图片优化任务和后续统计聚合。
```sql
app_logs(
id INTEGER PRIMARY KEY,
level TEXT,
module TEXT,
message TEXT,
detail TEXT,
created_at DATETIME
)
```
当前 `audit_logs` 和 `app_logs` 分别用于用户动作审计和运行排错。`MetricsService` 已直接用 SQL 聚合 P0 指标,不急着落 `daily_metrics` 缓存表。数据量变大后再增加缓存表。
迁移要求:
- 初始化必须幂等。
- 新字段必须有默认值或迁移逻辑。
- schema 变化必须同步 `store_test.go`、`api.md` 和 `current-state.md`。
## 窗口与页面
- 主窗口路由:`/#/` 重定向到 `/#/dashboard`
- 第二窗口路由:`/#/second`
- 已实现主应用骨架路由:`/#/login`、`/#/dashboard`、`/#/image-optimizer`、`/#/logs`、`/#/statistics`、`/#/settings`、`/#/components`。
- 兼容目标文档路由:`/#/business/image-optimizer`、`/#/logs/audit`、`/#/logs/app` 会重定向到当前主入口。
- 托盘菜单由 `AppService` 配置。
- 热键触发目标可以是打开主窗口、打开快捷功能或创建快速任务。
窗口策略:
- 主窗口承载长期业务操作,默认不最大化。
- 主窗口初始尺寸为 `1280x800`,最小尺寸为 `1024x720`。
- 主窗口启动时居中,并允许用户调整大小。
- 主窗口按 `window.width`、`window.height`、`window.start_state` 和 `window.remember_state` 恢复用户上次选择。
- 前端根容器使用 `width: 100%` 和 `height: 100vh`。
- 主应用布局内部使用 flex 或 grid 填满窗口。
- 阅读型内容保留最大宽度,列表、仪表盘、设置页等工作型页面自适应拉伸。
- 第二窗口保持当前小窗定位,不参与最大化、尺寸恢复和主布局填充逻辑。
实现状态:主窗口初始尺寸、居中、可调整大小、根容器和主布局填充已落地;主应用路由骨架已落地;登录 provider 边界已落地;设置模块统一 schema 已落地;主窗口尺寸和最大化状态持久化已落地。
## 关键风险
- 范围膨胀:模板容易变成“大而全平台”,必须按任务小步交付。
- Wails v3 仍是 alpha,CLI、Go 模块和 runtime 必须保持匹配。
- bindings 若与 Go 服务签名不一致,前端会在运行时失败。
- 登录 provider、AI provider 和日志模块必须有清晰边界,否则后续替换困难。
- OCR、热键、托盘依赖平台能力,跨平台修改必须分别验证。
- Vite 构建可能出现 chunk size warning,警告不等于失败,但需要避免无节制增加前端体积。