2025-11-01 09:24:26 +08:00
|
|
|
|
# AI 记账应用框架
|
|
|
|
|
|
|
|
|
|
|
|
基于《项目设计蓝图》与《UI 设计规范》搭建的前后端 Monorepo。当前版本提供可运行的基础框架、示例数据与 API 接口骨架,现已补齐账户认证、预算管理、交易通知入库等核心流程,便于继续迭代为完整的 AI 记账应用。
|
|
|
|
|
|
|
|
|
|
|
|
## 项目结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
├── apps
|
|
|
|
|
|
│ ├── backend # Node.js + Express + TypeScript,提供 REST API 骨架
|
|
|
|
|
|
│ └── frontend # Vue 3 + Vite + TailwindCSS,包含移动端风格 UI
|
|
|
|
|
|
├── pnpm-workspace.yaml
|
|
|
|
|
|
├── package.json
|
|
|
|
|
|
└── README.md
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 快速开始
|
|
|
|
|
|
|
2025-11-10 14:14:51 +08:00
|
|
|
|
1. 复制环境变量模板:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cp apps/backend/.env.example apps/backend/.env.local
|
|
|
|
|
|
```
|
|
|
|
|
|
若使用本地 MongoDB,请根据实际连接串调整 `MONGODB_URI`(例如 `mongodb://127.0.0.1:27017/ai-bill`)。
|
|
|
|
|
|
2. 安装依赖:
|
2025-11-01 09:24:26 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
pnpm install
|
|
|
|
|
|
```
|
2025-11-10 14:14:51 +08:00
|
|
|
|
3. (可选)启动内置 MongoDB(需 Docker 环境):
|
2025-11-01 09:24:26 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
pnpm db:up
|
|
|
|
|
|
pnpm --filter backend seed # 首次运行:写入默认用户/预算/交易
|
|
|
|
|
|
```
|
|
|
|
|
|
结束后可通过 `pnpm db:down` 停止容器。
|
2025-11-10 14:14:51 +08:00
|
|
|
|
4. 启动后端(默认端口 4000):
|
2025-11-01 09:24:26 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
pnpm dev:backend
|
|
|
|
|
|
```
|
2025-11-10 14:14:51 +08:00
|
|
|
|
5. 启动前端(默认端口 5173):
|
2025-11-01 09:24:26 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
pnpm dev:frontend
|
|
|
|
|
|
```
|
2025-11-10 14:14:51 +08:00
|
|
|
|
6. 或者并行启动:
|
2025-11-01 09:24:26 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
pnpm dev
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 后端说明(apps/backend)
|
|
|
|
|
|
- 技术栈:Express、TypeScript、Zod、Mongoose、Pino。
|
|
|
|
|
|
- `.env.example` 给出了基础环境变量;开发时可复制为 `.env.local`。
|
2025-11-10 14:14:51 +08:00
|
|
|
|
- **必须** 连接 MongoDB:如使用内置 `docker-compose`,可直接使用 `MONGODB_URI=mongodb://mongo:27017/ai-bill`。
|
|
|
|
|
|
- 所有 `/api` 接口(除 `/api/auth/*` 与签名校验的 `/api/transactions/notification`)均需要 `Authorization: Bearer <accessToken>` 访问。
|
2025-11-01 09:24:26 +08:00
|
|
|
|
- 核心 API:
|
|
|
|
|
|
- `POST /api/auth/login|register|refresh|logout|forgot-password`
|
|
|
|
|
|
- `GET /api/transactions`、`POST /api/transactions`、`PATCH /api/transactions/:id`、`DELETE /api/transactions/:id`
|
|
|
|
|
|
- `POST /api/transactions/notification`(HMAC 签名校验的通知入库)
|
|
|
|
|
|
- `GET /api/analysis/habits`(基于实时交易聚合)与 `POST /api/analysis/calories`
|
|
|
|
|
|
- `GET /api/budgets`、`POST /api/budgets`、`PATCH /api/budgets/:id`、`DELETE /api/budgets/:id`
|
|
|
|
|
|
- `GET /api/notifications/status`(返回 webhook 地址、密钥提示、通知包名白名单及最近入库信息)
|
|
|
|
|
|
- `pnpm --filter backend build` 进行编译,`pnpm --filter backend lint` 执行 ESLint。
|
|
|
|
|
|
|
2025-11-10 14:14:51 +08:00
|
|
|
|
### Docker Compose 快速部署
|
|
|
|
|
|
|
|
|
|
|
|
项目根目录提供 `Dockerfile` 与 `docker-compose.yml`,可一键启动 MongoDB + 后端服务:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docker compose up -d
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
默认暴露端口:
|
|
|
|
|
|
- `mongodb://localhost:27017`(数据库名 `ai-bill`)
|
|
|
|
|
|
- `http://localhost:4000/api`(后端 API)
|
|
|
|
|
|
|
|
|
|
|
|
请在生产环境中覆盖 `docker-compose.yml` 中的占位密钥(`JWT_SECRET`、`NOTIFICATION_WEBHOOK_SECRET` 等),或使用 `env_file` 注入。
|
|
|
|
|
|
|
2025-11-01 09:24:26 +08:00
|
|
|
|
## 前端说明(apps/frontend)
|
|
|
|
|
|
- 技术栈:Vue 3、TypeScript、Pinia、Vue Router、@tanstack/vue-query、TailwindCSS。
|
|
|
|
|
|
- UI 与交互设计遵循 `UI设计规范 design_system.md` 与 `ui_mockup.html`。
|
|
|
|
|
|
- 关键页面与能力:
|
|
|
|
|
|
- 仪表盘:展示当月收入/支出统计、预算剩余、快捷操作。
|
|
|
|
|
|
- 交易列表:支持按类型筛选、新增、备注、删除,区分数据来源(手动/通知/OCR/AI)。
|
|
|
|
|
|
- AI 分析:实时消费洞察 + 卡路里估算对话体验。
|
|
|
|
|
|
- 设置中心:账户信息、偏好开关、预算卡片管理(新增/删除、阈值滑杆)。
|
|
|
|
|
|
- 认证流程:登录/注册/找回密码,提供「体验模式」快捷入口。
|
|
|
|
|
|
- 默认通过 Axios 访问后端 API,无法连接时自动回退到本地示例数据。
|
|
|
|
|
|
- 若需要跨端访问,可在 `apps/frontend/.env.local` 中调整 `VITE_API_BASE_URL`(默认指向 `http://localhost:4000/api`)。
|
|
|
|
|
|
- 构建与预览:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
pnpm --filter frontend build
|
|
|
|
|
|
pnpm --filter frontend preview
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 下一步建议
|
|
|
|
|
|
- 接入真实登录态(JWT 校验、刷新、登出)、以及通知监听插件(Android `NotificationListenerService`)调用示例。
|
|
|
|
|
|
- 引入 OCR / LLM 能力(Google Vision、Gemini 等)补齐票据识别与消费分析的真实数据链路。
|
|
|
|
|
|
- 补充自动化测试:Vitest(前端组件/状态)、Jest + Supertest(后端 API)、Playwright(端到端流程)。
|
|
|
|
|
|
- 优化移动端体验:离线缓存、渐进式加载、通知权限引导流程。
|
2025-11-03 11:25:39 +08:00
|
|
|
|
|
2025-11-10 14:14:51 +08:00
|
|
|
|
## 部署指引(后端)
|
|
|
|
|
|
|
|
|
|
|
|
### 方案一:自建服务器 + Docker Compose
|
|
|
|
|
|
1. 准备 `.env` 文件(建议基于 `apps/backend/.env.example` 修改),确保密钥使用随机字符串:
|
|
|
|
|
|
```
|
|
|
|
|
|
NODE_ENV=production
|
|
|
|
|
|
HOST=0.0.0.0
|
|
|
|
|
|
PORT=4000
|
|
|
|
|
|
MONGODB_URI=mongodb://mongo:27017/ai-bill
|
|
|
|
|
|
JWT_SECRET=<随机 64 位字符串>
|
|
|
|
|
|
JWT_REFRESH_SECRET=<随机 64 位字符串>
|
|
|
|
|
|
NOTIFICATION_WEBHOOK_SECRET=<与客户端一致的 HMAC 密钥>
|
|
|
|
|
|
```
|
|
|
|
|
|
2. 运行 `docker compose up -d`,Dockerfile 会自动构建并启动后端。
|
|
|
|
|
|
3. 如需对外提供 HTTPS,可在服务器前再挂一层 Nginx/Traefik。
|
|
|
|
|
|
|
|
|
|
|
|
### 方案二:托管平台(Railway / Fly.io / Render 等)
|
|
|
|
|
|
1. 连接 Git 仓库,选择 Node 运行时;
|
|
|
|
|
|
2. 配置上述环境变量;
|
|
|
|
|
|
3. 构建命令 `pnpm install && pnpm --filter backend build`;启动命令 `node apps/backend/dist/main.js`;
|
|
|
|
|
|
4. 平台提供的 HTTPS 域名可直接写入前端/安卓配置。
|
|
|
|
|
|
|
|
|
|
|
|
### 部署后验证
|
|
|
|
|
|
1. 访问 `GET /api/health`(或 `/api/notifications/status`)确认服务正常;
|
|
|
|
|
|
2. 更新前端配置:`VITE_API_BASE_URL`、`gradle.properties`(Android)指向云端地址;
|
|
|
|
|
|
3. 使用 curl 或 Android 真机测试通知上报流程。
|
|
|
|
|
|
|
|
|
|
|
|
## 下一步规划(roadmap)
|
|
|
|
|
|
- **数据解析**:完善通知正则识别逻辑、自动识别金额/类型/分类、提供幂等处理;
|
|
|
|
|
|
- **多用户与权限**:前后端对接真实登录,支持注销、Token 刷新、路由守卫;
|
|
|
|
|
|
- **体验优化**:交易/预算手动刷新、错误反馈 Toast、个性化偏好按钮交互优化;
|
|
|
|
|
|
- **原生能力**:Android 完善通知权限引导、OCR 插件、摄像头票据扫描;
|
|
|
|
|
|
- **部署与监控**:完善 Dockerfile/CI/CD、引入日志告警、Grafana/Prometheus 监控;
|
|
|
|
|
|
- **扩展功能**:预算提醒、AI 分析历史记录、账本导出、团队共享账本。
|
|
|
|
|
|
|
2025-11-03 11:25:39 +08:00
|
|
|
|
## 功能调试指南
|
|
|
|
|
|
|
|
|
|
|
|
### 通知监听接口调试
|
|
|
|
|
|
后端已提供 `POST /api/transactions/notification` 接口,通过 HMAC-SHA256 校验签名后写入交易。调试步骤:
|
|
|
|
|
|
1. 在后端启动(`pnpm dev:backend`)前,确认 `.env.local` 中的 `NOTIFICATION_WEBHOOK_SECRET`、`HOST=0.0.0.0` 配置,前端使用相同局域网地址;
|
|
|
|
|
|
2. 构造签名:`payload = packageName|title|body|timestamp`;`signature = HMAC-SHA256(payload, secret)`,示例脚本:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
secret="38f71dbf99ab510d970165e43979f945f992848406117c8597a892837331a853"
|
|
|
|
|
|
package="com.eg.android.AlipayGphone"
|
|
|
|
|
|
title="支付宝到账"
|
|
|
|
|
|
body="到账 88.88 元"
|
|
|
|
|
|
timestamp=$(date +%s000)
|
|
|
|
|
|
|
|
|
|
|
|
payload="${package}|${title}|${body}|${timestamp}"
|
|
|
|
|
|
signature=$(printf '%s' "$payload" | openssl dgst -sha256 -hex -hmac "$secret" | awk '{print $2}')
|
|
|
|
|
|
|
|
|
|
|
|
curl -X POST "http://<后端IP>:4000/api/transactions/notification" \
|
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
|
-d "{
|
|
|
|
|
|
\"packageName\": \"${package}\",
|
|
|
|
|
|
\"title\": \"${title}\",
|
|
|
|
|
|
\"body\": \"${body}\",
|
|
|
|
|
|
\"receivedAt\": ${timestamp},
|
|
|
|
|
|
\"signature\": \"${signature}\"
|
|
|
|
|
|
}"
|
|
|
|
|
|
```
|
|
|
|
|
|
3. 返回 `202` 表示接口验证成功;前端「设置中心 → 通知监听」卡片会显示入库次数、最近时间,并在交易列表里出现新的 `pending` 记录。
|
|
|
|
|
|
4. 若要模拟多条通知,可调整 `packageName`、金额或时间戳;若签名不匹配,后端会返回 `401` 并在日志输出 “Notification signature mismatch”。
|
|
|
|
|
|
|
|
|
|
|
|
### Android 打包与真机测试
|
|
|
|
|
|
前端目前为 Web 工程,可通过 Capacitor 集成 Android 壳。建议步骤:
|
|
|
|
|
|
1. 在 `apps/frontend` 下安装 Capacitor:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
pnpm add @capacitor/core @capacitor/cli @capacitor/android
|
|
|
|
|
|
pnpm add -D @capacitor/assets
|
|
|
|
|
|
pnpm cap init # 或使用现有配置
|
|
|
|
|
|
pnpm cap add android
|
|
|
|
|
|
```
|
|
|
|
|
|
在 `capacitor.config.ts` 中配置开发服务器地址、`webDir: 'dist'`。
|
|
|
|
|
|
新增通知监听后,需要在 `apps/frontend/android/gradle.properties`(或运行 `gradlew` 时的命令行)写入:
|
|
|
|
|
|
```
|
|
|
|
|
|
API_BASE_URL=http://<你的后端IP>:4000/api
|
|
|
|
|
|
NOTIFICATION_WEBHOOK_SECRET=<与后端一致的 HMAC 密钥>
|
|
|
|
|
|
```
|
|
|
|
|
|
2. 开发模式:`pnpm dev:frontend -- --host 0.0.0.0` + `pnpm dev:backend`,将手机/模拟器连接同一局域网,Capacitor `server.url` 指向 `http://<电脑IP>:5173`,即可在真机上加载开发版 Web 页面。
|
|
|
|
|
|
3. 生产版打包:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
pnpm --filter frontend build
|
|
|
|
|
|
pnpm cap copy android
|
|
|
|
|
|
```
|
|
|
|
|
|
打开 `apps/frontend/android/`,在 Android Studio 中构建(`Build > Build APK(s)`),或生成签名 APK。
|
|
|
|
|
|
4. 原生通知监听:在 Android 工程里实现 `NotificationListenerService`(或接入自定义插件)将捕获的通知调用上述 webhook(HMAC 签名规则一致),即可验证完整通知→后端→前端流程。
|
|
|
|
|
|
|
|
|
|
|
|
A 自带的调试技巧包括:
|
|
|
|
|
|
- `adb reverse tcp:4000 tcp:4000` / `adb reverse tcp:5173 tcp:5173`(模拟器访问电脑服务);
|
|
|
|
|
|
- `adb shell cmd notification post -S bigtext <package> <title> <text>`(模拟通知);
|
|
|
|
|
|
- 使用 Android Studio Network Inspector/Logcat 观察上传请求;后端终端输出或 `GET /api/notifications/status` 查看最新入库情况。
|