Files
fire_goal/docs/03-架构设计.md
T
ilaandClaude Sonnet 4.6 d558da51a6 add project docs and research materials; update arch doc with WSL2 dev setup
- docs/: 6 development documents (PRD, tech selection, architecture, risks, roadmap, design workflow)
- research/: FIRE background materials, personal plan, Excel calculator
- 03-架构设计.md: add Section 8 documenting WSL2 → Windows browser dev environment (Vite host config, access URLs, mobile debugging tip)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 09:21:04 +08:00

170 lines
9.1 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.
# 03 · 架构设计
> 用户端(uni-app 多端) + 管理后台(Web) + 腾讯云 VPS 后端(Go·域名·certbot HTTPS) + 本地优先同步。
## 一、整体架构图
```
用户端(unibest / uni-app · Vue3) 后端(腾讯云 VPS · Docker · HTTPS)
┌─────────────────────────────┐ ┌────────────────────────────┐
│ ① 每日打卡 │ │ 域名 + Nginx + certbot │
│ ② 目标进度 & 净资产曲线 │ HTTPS │ Go + Gin + GORM │
│ ③ FIRE 测算器 │ ─REST→ │ ├─ JWT 单用户鉴权 │
│ ④ 持仓 & 分红跟踪 │ ←同步─ │ ├─ API: 打卡/快照/持仓/设置 │
│ 本地缓存(离线优先) │ │ └─ SQLite(纯Go驱动·可备份) │
└─────────────────────────────┘ └────────────────────────────┘
│ 由同一个 Go 进程托管 ▲
├─ 浏览器 → 网页 / PWA │ html/template
├─ 云打包 → Android (.apk/.aab) │ 渲染(共用DB)
└─ 云打包 → iOS (.ipa,需苹果账号) ┌─────────────────────────┐
│ 管理后台(Web · 电脑端) │
│ Gin html/template + │
│ HTMX + Alpine + Tabler │
│ 无构建·数据增删改查/报表 │
└─────────────────────────┘
```
## 二、前端结构
- **页面**:四大模块各一主页面 + 设置页,普通 vue 页面(不碰 nvue)。
- **图表**:统一用 qiun-data-charts,图表页避免 nvue,数据做抽稀。
- **状态/数据层**:本地优先,所有读写先走"存储抽象层",再异步同步到后端。
### 存储抽象层(关键设计)
各端存储能力不同,必须封装统一接口,内部用条件编译分端实现:
| 端 | 底层实现 | 注意 |
|---|---|---|
| H5 | IndexedDB(大数据)/ localStorage | localStorage ~5MB 上限 |
| App | uni.storage / 原生 SQLite 插件 | 历史快照/流水量大时用 SQLite |
| 小程序 | uni.storage | 总量约 10MB,存流水易爆 |
```
interface Store {
get(key), set(key, val), query(table, filter), bulkSave(...)
}
// #ifdef H5 → IndexedDB 实现
// #ifdef APP-PLUS → SQLite/uni.storage 实现
// #ifdef MP → uni.storage 实现
```
## 三、后端结构(腾讯云 VPS · Go)
- **技术栈**:**Go + Gin(Web)+ GORM(ORM)+ SQLite**(纯 Go 驱动 `modernc.org/sqlite`,免 CGO,编译/部署最省心)+ **JWT** 鉴权。
- **部署**:编译为**单个静态二进制**,Docker 化部署到腾讯云 VPS;前置 **Nginx 反向代理**,由 **certbot(Let's Encrypt)** 签发并自动续期 HTTPS。
- **域名**:使用用户已有域名,解析到 VPS 公网 IP。
- **数据表(初版)**:`checkins`(打卡)、`snapshots`(资产快照)、`holdings`(持仓)、`settings`(参数)、`users`(单用户)。
- **接口**:标准 REST(增删改查 + 拉取增量),全程 HTTPS;用户端与管理后台**共用同一套 API**。
- **备份**:SQLite 单文件,定时备份到对象存储/本地。
> 为什么用 Go 而非 Node:单二进制、内存占用小、Docker 镜像可压到几 MB,**更适合常驻的小 VPS 自托管**;前后端经 REST/JSON 解耦,后端语言对 uni-app 前端无影响。
## 三-B、管理后台(Web 管理端 · 无构建)
- **定位**:电脑端网页,给本人用来**增删改查数据、查看报表、调整参数**(如目标本金、提取率、收益率假设)。
- **技术(无构建)**:**Gin html/template 服务端渲染 + HTMX(局部刷新)+ Alpine.js(小交互)+ Tabler 后台模板(Bootstrap5,自带登录/侧边栏/仪表盘/表格/表单皮肤)+ Chart.js(图表)**。全部走 `<script>`/`<link>` 引入,**不需要 Node 工具链、不需要 build**。
- **骨架**:直接采用 **Tabler** 现成页面(登录、侧边栏布局、仪表盘卡片、表格表单),相当于 admin 端的 unibest。
- **托管**:由**同一个 Go 进程**直接渲染并提供(路由如 `/admin/*`);模板与静态资源用 `//go:embed` 打进二进制 → 部署仍是单文件。
- **数据**:与用户端**共用同一个 Go 后端与 SQLite**(HTMX 路由返回 HTML 片段,不另起服务)。
- **鉴权**:JWT/会话,单用户。
- **范围**:单人自管,不做多用户/复杂权限。
> 为什么不用 Vue3+Element Plus:那需要独立 build 流水线和 `admin/` 子项目。管理端本质是 CRUD+报表,用 HTMX 超媒体方案**零构建、Go 一把托管**,仓库更简单、部署仍单二进制。
## 四、同步策略(刻意从简)
单用户场景不追求复杂冲突合并:
1. **本地优先**:所有操作先写本地、立即可用、离线可用。
2. **时间戳 + 后写覆盖**:每条记录带 `updatedAt`,同步时以较新者为准。
3. **后端为历史数据权威源**:本地仅作缓存,换设备从后端拉全量。
> 不使用 uniCloud(绑定 DCloud 云,非自托管),坚持自建 VPS 后端。
## 五、各端后端连通性注意
> 已有「域名 + certbot 正经 HTTPS」后,App / H5 的后端要求**全部满足**;小程序只剩"域名备案 + 配置合法域名白名单"一步。
| 端 | 对后端要求 | 当前状态(VPS + 域名 + certbot) |
|---|---|---|
| H5 | 需处理 CORS | ✅ 同域部署或配置 CORS 即可 |
| App | 正经 HTTPS | ✅ certbot 证书满足,不再有自签被拒问题 |
| 小程序 | 强制 HTTPS + **备案域名** + 合法域名白名单 | ⚠️ HTTPS 已满足;仅需**域名 ICP 备案**(腾讯云可办)+ 小程序后台配 request 合法域名 |
## 六、HTTPS 与安全(腾讯云 VPS)
- **HTTPS**:域名解析到 VPS → Nginx 占用 80/443 → `certbot --nginx` 签发证书 → 自动续期(`certbot renew` cron/timer)。
- **安全加固(后端已暴露公网,务必做)**:
- 仅开放必要端口(80/443/SSH),其余用腾讯云安全组 + 防火墙关闭;
- 强 Token/密码鉴权,接口加速率限制,**强制 HTTPS(HTTP 301 跳转)**;
- SSH 改密钥登录、装 fail2ban;
- SQLite 定时备份;财务数据在公网,敏感字段可考虑加密存储。
## 七、部署形态
- **开发期**:WSL 内 `pnpm dev:h5` 跑 unibest 前端实时预览;`go run` 起 Go 后端(同时托管管理后台 `/admin`,改模板刷新即见,无需 build)。
- **自用期**:Go 后端二进制 Docker 跑在**腾讯云 VPS**(Nginx + certbot HTTPS),管理后台由 Go 进程自身托管;用户端 H5 静态文件由 Nginx 同域托管;手机装 PWA。
- **App 期**:HBuilderX 云打包出 Android/iOS。
## 八、WSL2 开发环境配置
> 在 WSL2 Ubuntu 中开发,Windows 浏览器中预览——这是本项目的标准开发模式。
### 原理
WSL2 会自动将内部端口转发到 Windows 的 `localhost`,所以 WSL2 里启动的 dev server,Windows 浏览器直接用 `http://localhost:端口` 访问,热更新也正常生效。
### 必须的 Vite 配置
Vite 默认只监听 `127.0.0.1`(WSL2 内部),需改为监听所有网卡,否则 Windows 浏览器无法访问。
在 `app/vite.config.ts` 中添加:
```ts
server: {
host: '0.0.0.0', // 允许 WSL2 外部(Windows)访问
port: 5173,
},
```
或临时用命令行参数(不改配置时):
```bash
pnpm dev:h5 --host
```
### 访问方式
| 场景 | 地址 |
|---|---|
| Windows 浏览器调试 | `http://localhost:5173` |
| 手机扫码调试(同 WiFi) | `http://<Windows局域网IP>:5173`(`ipconfig` 查 WiFi 的 IPv4) |
> 注意:手机调试时用的是 **Windows 的局域网 IP**,不是 WSL2 的内部 IP(`172.x.x.x`)。
### 开发流程示意
```
WSL2 Ubuntu
├─ pnpm dev:h5 --host → Vite 监听 0.0.0.0:5173
└─ go run . → Go 后端监听 0.0.0.0:8080
↓ WSL2 自动转发
Windows
├─ Chrome localhost:5173 ✅ 前端热更新正常
└─ 接口请求 localhost:8080 ✅ 后端 API 正常
```
## 九、代码仓库结构(建议)
```
fire_goal/
├─ app/ # unibest 用户端(uni-app,需 build 出 H5/App)
├─ server/ # Go 后端(Gin + GORM + SQLite)
│ ├─ templates/ # 管理后台 html/template(无构建)
│ └─ static/ # htmx/alpine/tabler/chart.js 等,//go:embed 进二进制
├─ deploy/ # Dockerfile / docker-compose / Nginx / certbot 脚本
└─ docs/ # 本文档目录
```
> 管理后台不再是独立子项目,已并入 `server/`(模板 + 静态资源),与后端同进程、同部署。