Files
xiaocai/CLAUDE.md
wangxiaogang 0de4c9832c feat: 请求日志 + 前端埋点系统
后端:
- 新增 logger 中间件,记录所有请求到 logs/ 目录
- 新增 /api/track 接口接收前端埋点数据

前端:
- 新增 tracker 工具,支持页面访问/操作/错误埋点
- request.ts 添加 API 错误自动埋点
- App.vue 初始化全局错误追踪

文档:
- CLAUDE.md 更新项目结构
- DEV.md 添加埋点和日志说明
2026-06-08 14:28:11 +08:00

9.8 KiB
Raw Permalink Blame History

小菜记账 (Xiaocai Accounting)

可爱 × 高级的个人记账小程序。让记账从负担变成享受。

Tech Stack

前端 (client/)

  • 框架: Uni-app (Vue 3 + Composition API)
  • 状态管理: Pinia
  • 样式: SCSS (Claymorphism 风格)
  • 图标: Lucide Icons (SVG 组件,禁止 emoji)
  • 图表: uCharts (小程序端)
  • 目标平台: 微信小程序 / H5

后端 (server/)

  • 运行时: Node.js + Express
  • 数据库: MySQL 8.0 (mysql2 连接池)
  • 认证: HMAC-SHA256 签名 token30 天过期
  • 文件上传: multer (头像,最大 2MB)
  • 备份: Node.js mysql2 导出 (不依赖 mysqldump)
  • CORS: 已配置,支持 credentials

Design System

完整设计规格: docs/superpowers/specs/2026-05-27-xiaocai-design.md

核心设计语言: Claymorphism (软3D粘土风格)

  • 主色调: 珊瑚橙 #FF8C69 — 温暖、活泼、有亲和力
  • 背景色: 暖奶油 #FFF8F0 — 比纯白更柔和
  • 文字色: 暖深棕 #2D1B1B — 不用纯黑
  • 圆角: 卡片 20px, 按钮 14-16px
  • 阴影: 双层 (外阴影 + 内阴影,模拟粘土质感)

字体

  • 英文: Fredoka (标题) + Nunito (正文)
  • 中文: PingFang SC / 系统默认
  • 数字和金额使用 Fredoka等宽数字

关键原则

  • 最小触摸目标 44×44px
  • 禁止使用 emoji 作为图标,统一使用 Icon 组件
  • 尊重 prefers-reduced-motion
  • 文字对比度 ≥ 4.5:1 (WCAG AA)

小程序胶囊适配

  • 微信小程序右上角有胶囊按钮,页面顶部右侧元素(图标、按钮)需避开
  • 使用 system.ts 导出的 capsuleRight 计算安全距离
  • 导航栏添加动态 padding: :style="{ paddingRight: capsuleRight + 'px' }"
  • 居中标题页面(统计、账单、我的)不需要处理
  • 有右侧元素的页面(首页 bell、编辑页保存按钮必须处理

Project Conventions

命名

  • 目录: kebab-case (category-manage/, transaction-item/)
  • 组件: PascalCase (AmountCard.vue, TransactionItem.vue)
  • 变量/函数: camelCase (totalExpense, formatAmount())
  • 常量: UPPER_SNAKE_CASE (MAX_BUDGET, STORAGE_KEY)
  • CSS 类: BEM 或 Tailwind 风格

文件组织

client/src/
├── pages/              # 页面 (uni-app 规范)
│   ├── index/          # 首页仪表盘
│   ├── add/            # 添加/编辑记录
│   ├── stats/          # 统计分析
│   ├── bills/          # 全部账单 (下拉刷新/上拉加载)
│   ├── profile/        # 我的(身份切换入口)
│   ├── profile-edit/   # 编辑资料(昵称+头像+签名)
│   ├── group-manage/   # 群组管理(创建/加入/退出/解散)
│   ├── category-manage/ # 分类管理
│   ├── budget/         # 预算设置
│   ├── notifications/  # 通知中心
│   ├── feedback/       # 意见反馈
│   ├── privacy/        # 隐私政策
│   └── admin/          # 管理后台 (index/users/notifications/feedback/config)
├── components/         # 公共组件
│   ├── BudgetBar/      # 预算进度条
│   ├── CategoryIcon/   # 分类图标 (首字+颜色)
│   ├── ChartWrapper/   # uCharts 图表封装
│   ├── Icon/           # 图标组件 (PNG 映射)
│   ├── Numpad/         # 数字键盘
│   ├── SaveSuccess/    # 保存成功动画
│   ├── Skeleton/       # 骨架屏
│   └── TransactionItem/ # 交易列表项
├── stores/             # Pinia stores
│   ├── transaction.ts  # 交易 CRUD (自动传递 group_id)
│   ├── category.ts     # 分类 CRUD
│   ├── budget.ts       # 预算管理
│   ├── stats.ts        # 统计概览 (自动传递 group_id)
│   ├── user.ts         # 用户信息 (昵称/头像)
│   └── group.ts        # 群组管理 (身份切换)
├── api/                # API 封装
│   ├── auth.ts         # 登录接口
│   ├── transaction.ts  # 交易接口
│   ├── category.ts     # 分类接口
│   ├── budget.ts       # 预算接口
│   ├── stats.ts        # 统计接口
│   ├── user.ts         # 用户信息接口 (含头像上传)
│   ├── group.ts        # 群组接口
│   ├── notification.ts # 通知接口
│   ├── filter.ts       # 筛选方案接口
│   ├── feedback.ts     # 反馈接口
│   ├── config.ts       # 系统配置接口
│   ├── admin.ts        # 管理后台接口
│   └── index.ts        # barrel 导出
├── utils/
│   ├── format.ts       # 金额/日期格式化
│   ├── request.ts      # HTTP 请求封装 (401 自动重登录+队列重试)
│   ├── system.ts       # 系统信息 (statusBarHeight, capsuleRight)
│   ├── app-ready.ts    # App 启动就绪机制 (waitForReady)
│   └── tracker.ts      # 前端埋点 (页面访问/操作/错误)
├── config.ts           # 全局配置 (API_BASE)
└── static/icons/       # tabBar 图标 (PNG)

server/src/
├── index.ts            # Express 入口 (CORS, JSON, 静态文件, 路由注册)
├── middleware/
│   ├── auth.ts         # HMAC token 验证 (timingSafeEqual)
│   └── logger.ts       # 请求日志 (记录到 logs/ 目录)
├── routes/
│   ├── auth.ts         # 登录 / token 签发 (返回用户信息)
│   ├── transaction.ts  # 交易 CRUD (支持 group_id 视图切换)
│   ├── category.ts     # 分类 CRUD (默认+自定义)
│   ├── budget.ts       # 预算 CRUD (按月)
│   ├── stats.ts        # 统计查询 (支持 group_id)
│   ├── user.ts         # 用户信息 + 头像上传
│   ├── group.ts        # 群组 CRUD (创建/加入/退出/解散)
│   ├── notification.ts # 通知/公告 CRUD
│   ├── filter.ts       # 筛选方案 CRUD
│   ├── feedback.ts     # 用户反馈 (提交/查询/处理)
│   ├── config.ts       # 系统配置 (公开读/管理员写)
│   ├── admin.ts        # 管理后台 (仪表盘/用户管理)
│   ├── track.ts        # 埋点数据接收
│   └── backup.ts       # 备份 API
├── utils/
│   ├── backup.ts       # Node.js 数据库备份 (gzip)
│   └── date.ts         # 日期工具
└── db/
    ├── connection.ts   # MySQL 连接池
    ├── init.ts         # 建表 + seed + 迁移 (幂等)
    ├── schema.sql      # 表结构
    └── seed.sql        # 默认分类数据 + 系统配置

数据库表

  • users — 用户 (openid, nickname, avatar_url, slogan, role)
  • categories — 分类 (user_id=0 默认, 其他=自定义)
  • transactions — 交易记录 (user_id, group_id, amount 分)
  • budgets — 预算 (user_id, month, amount)
  • groups — 群组 (name, invite_code, created_by)
  • group_members — 群组成员 (group_id, user_id, role)
  • notifications — 通知/公告 (type, title, content, is_pinned, is_urgent)
  • notification_reads — 公告已读记录 (notification_id, user_id)
  • saved_filters — 保存的筛选方案 (user_id, name, filters)
  • feedbacks — 用户反馈 (user_id, type, content, status)
  • sys_config — 系统配置 (config_key, config_value)

金额处理

  • 存储单位: 分 (整数,避免浮点精度问题)
  • 显示单位: 元 (保留两位小数)
  • 格式化: ¥ 1,234.56 (¥ 后空格,千分位分隔)
  • 收入前缀 +,支出前缀 -
  • 使用 formatAmount() 带 ¥ 前缀,formatAmountRaw() 纯数字

数据持久化

  • 前端本地存储 Key:
    • xc:token — 认证 token
    • xc:userId — 用户 ID
    • xc:nickname — 用户昵称
    • xc:avatar_url — 头像文件名
    • xc:currentGroupId — 当前选中群组 ID (null=个人模式)
  • 后端 MySQL 数据库
  • API 基础地址: config.ts 中的 API_BASE

认证流程

  • H5: 页面加载时自动 demo-login 获取 token
  • 微信小程序: App.vue onLaunch 调用 wx.login 获取 code换 token
  • Token: HMAC-SHA256 签名30 天过期
  • 401 处理: 请求入队 → 自动重登录 → 队列中所有请求重试
  • 启动就绪: app-ready.tswaitForReady() 确保页面在登录完成后才加载数据

一起记 (群组)

  • 群组仅做数据聚合,记录始终属于记录者 (user_id)
  • 个人视图: WHERE user_id = 我 (所有记录)
  • 群组视图: WHERE user_id IN (群组成员) — 统计所有群组成员的个人账单
  • 群组账单 = 所有群组成员的个人账单之和
  • 退出群组: 该用户的 group_id 设为 NULL记录回到个人视图
  • 身份切换: 「我的」页底部弹窗选择,全局生效

Git

  • 分支: mastermain (注意远程)
  • Commit 风格: 中文描述,简洁明了
    • feat: 添加记账页面
    • fix: 修复金额计算精度问题

Commands

# 前端开发 (H5)
cd client && npm run dev:h5

# 前端开发 (微信小程序)
cd client && npm run dev:mp-weixin

# 前端构建
cd client && npm run build:mp-weixin

# 后端开发
cd server && npm run dev

# 后端构建
cd server && npm run build

# 数据库初始化
cd server && npm run db:init

部署

  • 开发服务: dev.xiaocai.j35.site:3000
  • 正式服务: xiaocai.j35.site
  • MySQL: 本地 3306 端口
  • 小程序开发版自动连接 dev 服务,正式版/H5 连接线上 (config.ts)

手动部署步骤

# 1. 本地构建后端
cd server && npm run build

# 2. 复制 dist 目录到服务器
scp -r server/dist/* root@106.14.208.43:/var/www/xiaocai/

# 3. SSH 到服务器
ssh root@106.14.208.43

# 4. 安装依赖(如 node_modules 已存在可跳过)
cd /var/www/xiaocai && npm install --production

# 5. 重启服务
pm2 restart xiaocai-server
# 或直接运行
NODE_ENV=production node dist/index.js

开发

@DEV.md