feat: 小菜记账 v1.0 - 完整功能实现

核心功能:
- 记账CRUD(支出/收入/分类/备注/日期)
- 统计分析(概览/分类占比/每日趋势)
- 预算管理(按月设置/进度条/超支提醒)
- 数据导出CSV

安全与认证:
- HMAC-SHA256签名token认证
- 用户数据隔离
- 输入验证与错误处理
- CORS配置

前端优化:
- 骨架屏加载
- 账单按日期分组
- 预算页面重构(快捷预设+Numpad)
- SvgIcon组件(H5+微信双端适配)
- 下拉刷新

后端优化:
- 共享日期工具函数
- 数据库连接池优化
- 健康检查端点
- 优雅关闭处理

技术栈:
- 前端:Uni-app (Vue 3 + Pinia)
- 后端:Node.js + Express + MySQL
This commit is contained in:
2026-05-29 16:14:15 +08:00
commit c7f29aa7a7
70 changed files with 32282 additions and 0 deletions

490
docs/development-plan.md Normal file
View File

@@ -0,0 +1,490 @@
# 小菜记账 — 小程序开发方案
> 版本: v1.0 | 日期: 2026-05-27
> UI 原型稿: `docs/mockup/index.html`
---
## 一、项目概述
| 项目 | 说明 |
|------|------|
| 产品名称 | 小菜记账 |
| 产品类型 | 个人记账微信小程序 |
| AppID | wx854804dff2928c53 |
| 设计风格 | Claymorphism (粘土风格) |
| 目标用户 | 18-35岁年轻人注重生活品质 |
---
## 二、技术架构
### 前端 (小程序)
| 技术 | 选型 | 说明 |
|------|------|------|
| 框架 | Uni-app (Vue 3 + Composition API) | 一套代码,跨端运行 |
| 状态管理 | Pinia | 轻量、TypeScript 友好 |
| 样式 | UnoCSS + SCSS | 原子化 + 变量系统 |
| 图标 | Lucide Icons (SVG) | 统一图标集 |
| 图表 | uCharts (qiun-data-charts) | 小程序端图表组件 |
| 字体 | Fredoka + Nunito | 通过 @font-face 加载 |
### 后端 (阿里云 2H2G)
| 技术 | 选型 | 说明 |
|------|------|------|
| 运行时 | Node.js 20 LTS | 轻量高效 |
| 框架 | Express.js | 简单可靠 |
| 数据库 | MySQL 8.0 | 成熟稳定,生态丰富 |
| ORM | Prisma | 类型安全,迁移方便 |
| 缓存 | 无 (内存足够) | 2G 内存可支撑 |
| 部署 | PM2 + Nginx | 进程管理 + 反向代理 |
---
## 三、功能清单
### P0 (MVP - 第一版)
| 模块 | 功能 | 说明 |
|------|------|------|
| 记账 | 添加支出/收入 | 金额、分类、日期、备注 |
| 记账 | 分类选择 | 预设 12 个分类 + 自定义 |
| 首页 | 月度总览 | 本月支出、预算进度 |
| 首页 | 近期账单 | 最近 20 条交易 |
| 统计 | 分类占比 | 环形图 |
| 统计 | 每日趋势 | 折线图 |
| 我的 | 预算设置 | 月度预算 |
| 我的 | 数据导出 | CSV 格式 |
### P1 (第二版)
| 模块 | 功能 | 说明 |
|------|------|------|
| 记账 | 图片识别 | 拍照识别金额 |
| 统计 | 周/月/年切换 | 多维度分析 |
| 我的 | 数据备份 | 云同步 |
| 我的 | 深色模式 | 主题切换 |
### P2 (第三版)
| 模块 | 功能 | 说明 |
|------|------|------|
| 高级 | 多账本 | 不同场景分类 |
| 高级 | 预算提醒 | 超支通知 |
| 高级 | 团队记账 | AA 记账 |
---
## 四、数据库设计
### MySQL 安装 (阿里云服务器)
```bash
# 安装 MySQL 8.0
sudo apt update
sudo apt install -y mysql-server
# 安全配置
sudo mysql_secure_installation
# 创建数据库和用户
sudo mysql -u root -p
CREATE DATABASE xiaocai DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'xiaocai'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON xiaocai.* TO 'xiaocai'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```
### 核心表
```sql
-- 分类表
CREATE TABLE categories (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
icon VARCHAR(50) NOT NULL,
color VARCHAR(20) NOT NULL,
type ENUM('expense', 'income') NOT NULL,
sort_order INT DEFAULT 0,
is_custom TINYINT(1) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 交易表
CREATE TABLE transactions (
id INT AUTO_INCREMENT PRIMARY KEY,
amount INT NOT NULL COMMENT '单位:分',
type ENUM('expense', 'income') NOT NULL,
category_id INT,
note VARCHAR(200),
date DATE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_date (date),
INDEX idx_type (type),
FOREIGN KEY (category_id) REFERENCES categories(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 预算表
CREATE TABLE budgets (
id INT AUTO_INCREMENT PRIMARY KEY,
amount INT NOT NULL COMMENT '单位:分',
month VARCHAR(7) NOT NULL COMMENT '格式2026-05',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_month (month)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 用户表 (预留微信登录)
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
openid VARCHAR(100) UNIQUE,
session_key VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 预设分类数据
| 分类 | 图标 (Lucide) | 颜色 | 类型 |
|------|---------------|------|------|
| 餐饮 | Coffee | #FF8C69 | 支出 |
| 饮品 | Coffee | #FF8C69 | 支出 |
| 购物 | ShoppingBag | #FFB347 | 支出 |
| 交通 | Car | #6C9BCF | 支出 |
| 住房 | Home | #7BC67E | 支出 |
| 医疗 | Heart | #FF6B6B | 支出 |
| 教育 | BookOpen | #6C9BCF | 支出 |
| 娱乐 | Film | #B39DDB | 支出 |
| 服饰 | Shirt | #FFD166 | 支出 |
| 美容 | Smile | #FF8C69 | 支出 |
| 通讯 | Smartphone | #6C9BCF | 支出 |
| 其他 | MoreHorizontal | #BFB3B3 | 支出 |
| 工资 | DollarSign | #7BC67E | 收入 |
| 副业 | TrendingUp | #7BC67E | 收入 |
| 理财 | PieChart | #7BC67E | 收入 |
| 其他收入 | Plus | #BFB3B3 | 收入 |
---
## 五、API 设计
### 基础信息
- 基础 URL: `https://your-domain.com/api`
- 认证: 微信登录 (code2session)
- 响应格式: JSON
### 接口列表
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /auth/login | 微信登录 |
| GET | /categories | 获取分类列表 |
| POST | /transactions | 添加交易 |
| GET | /transactions | 查询交易列表 |
| PUT | /transactions/:id | 更新交易 |
| DELETE | /transactions/:id | 删除交易 |
| GET | /stats/overview | 月度概览 |
| GET | /stats/category | 分类统计 |
| GET | /stats/trend | 每日趋势 |
| GET | /budget | 获取预算 |
| POST | /budget | 设置预算 |
| GET | /export/csv | 导出 CSV |
### 响应示例
```json
// 成功
{
"code": 0,
"data": { ... },
"message": "success"
}
// 失败
{
"code": 40001,
"data": null,
"message": "参数错误"
}
```
---
## 六、项目结构
```
xiaocai/
├── client/ # 小程序端
│ ├── src/
│ │ ├── pages/
│ │ │ ├── index/ # 首页
│ │ │ ├── add/ # 记账
│ │ │ ├── stats/ # 统计
│ │ │ ├── bills/ # 账单
│ │ │ └── profile/ # 我的
│ │ ├── components/
│ │ │ ├── AmountCard/
│ │ │ ├── TransactionItem/
│ │ │ ├── CategoryIcon/
│ │ │ ├── BudgetBar/
│ │ │ ├── BottomNav/
│ │ │ ├── Numpad/
│ │ │ └── Chart/
│ │ ├── stores/
│ │ │ ├── transaction.ts
│ │ │ ├── category.ts
│ │ │ └── budget.ts
│ │ ├── utils/
│ │ │ ├── format.ts
│ │ │ ├── storage.ts
│ │ │ └── request.ts
│ │ ├── static/
│ │ │ └── fonts/
│ │ ├── App.vue
│ │ ├── main.ts
│ │ ├── manifest.json
│ │ ├── pages.json
│ │ └── uni.scss
│ ├── package.json
│ └── vite.config.ts
├── server/ # 后端
│ ├── src/
│ │ ├── routes/
│ │ │ ├── auth.ts
│ │ │ ├── transaction.ts
│ │ │ ├── category.ts
│ │ │ ├── stats.ts
│ │ │ └── budget.ts
│ │ ├── db/
│ │ │ ├── schema.sql
│ │ │ └── seed.sql
│ │ ├── middleware/
│ │ │ └── auth.ts
│ │ └── index.ts
│ ├── data/ # 数据库迁移文件
│ ├── package.json
│ └── tsconfig.json
├── docs/ # 文档
│ ├── mockup/ # UI 原型
│ ├── ui-design.md # 设计规格
│ └── development-plan.md # 本文件
└── deploy/ # 部署脚本
├── nginx.conf
├── ecosystem.config.js # PM2 配置
└── setup.sh # 服务器初始化
```
---
## 七、开发计划
### 阶段一: 基础搭建 (第 1 周)
| 任务 | 说明 | 产出 |
|------|------|------|
| 项目初始化 | Uni-app 项目 + 后端项目 | 可运行的空项目 |
| 数据库设计 | MySQL 建表 + 种子数据 | 数据库就绪 |
| 微信登录 | code2session 对接 | 登录流程 |
| API 框架 | Express + 中间件 | API 可调用 |
### 阶段二: 核心功能 (第 2-3 周)
| 任务 | 说明 | 产出 |
|------|------|------|
| 记账功能 | 添加/编辑/删除交易 | 核心记账流程 |
| 分类管理 | 预设分类 + 自定义 | 12 个分类 |
| 首页展示 | 月度总览 + 账单列表 | 首页完整 |
| 预算功能 | 设置/展示预算 | 预算进度条 |
### 阶段三: 统计分析 (第 4 周)
| 任务 | 说明 | 产出 |
|------|------|------|
| 分类统计 | 环形图 + 排行 | 分类占比 |
| 趋势分析 | 折线图 | 每日趋势 |
| 数据导出 | CSV 导出 | 可导出数据 |
### 阶段四: 优化上线 (第 5 周)
| 任务 | 说明 | 产出 |
|------|------|------|
| UI 细节 | 动画、交互优化 | 精细化 |
| 性能优化 | 首屏加载、缓存 | 流畅体验 |
| 服务器部署 | Nginx + PM2 | 上线运行 |
| 微信审核 | 提交审核 | 正式发布 |
---
## 八、服务器部署方案
### 环境配置
```bash
# 系统: Ubuntu 22.04 LTS
# 配置: 2 核 CPU, 2GB 内存
# 安装 Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# 安装 MySQL 8.0
sudo apt install -y mysql-server
sudo mysql_secure_installation
# 安装 Nginx
sudo apt install -y nginx
# 安装 PM2
sudo npm install -g pm2
# 创建部署目录
sudo mkdir -p /var/www/xiaocai
sudo chown $USER:$USER /var/www/xiaocai
```
### Nginx 配置
```nginx
server {
listen 80;
server_name your-domain.com;
# 小程序 API
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# SSL (上线前配置)
# listen 443 ssl;
# ssl_certificate /path/to/cert.pem;
# ssl_certificate_key /path/to/key.pem;
}
```
### PM2 配置
```javascript
// ecosystem.config.js
module.exports = {
apps: [{
name: 'xiaocai-server',
script: './dist/index.js',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '300M',
env: {
NODE_ENV: 'production',
PORT: 3000
}
}]
};
```
### 性能预估 (2H2G)
| 指标 | 预估 |
|------|------|
| 并发用户 | 50-100 |
| QPS | 200-500 |
| 内存占用 | Node.js 150MB + MySQL 300MB |
| 响应时间 | < 100ms |
| 数据库大小 | < 100MB/年 |
**内存分配**: MySQL 约 300MBNode.js 约 150MB系统约 500MB剩余可用约 1GB。
---
## 九、微信小程序配置
### manifest.json
```json
{
"mp-weixin": {
"appid": "wx854804dff2928c53",
"setting": {
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true,
"permission": {
"scope.userLocation": {
"desc": "用于获取您的位置信息"
}
}
}
}
```
### pages.json
```json
{
"pages": [
{ "path": "pages/index/index", "style": { "navigationBarTitleText": "小菜记账" } },
{ "path": "pages/add/index", "style": { "navigationBarTitleText": "记一笔" } },
{ "path": "pages/stats/index", "style": { "navigationBarTitleText": "统计分析" } },
{ "path": "pages/bills/index", "style": { "navigationBarTitleText": "全部账单" } },
{ "path": "pages/profile/index", "style": { "navigationBarTitleText": "我的" } }
],
"tabBar": {
"color": "#BFB3B3",
"selectedColor": "#FF8C69",
"list": [
{ "pagePath": "pages/index/index", "text": "首页", "iconPath": "static/icons/home.png", "selectedIconPath": "static/icons/home-active.png" },
{ "pagePath": "pages/stats/index", "text": "统计", "iconPath": "static/icons/chart.png", "selectedIconPath": "static/icons/chart-active.png" },
{ "pagePath": "pages/bills/index", "text": "账单", "iconPath": "static/icons/bill.png", "selectedIconPath": "static/icons/bill-active.png" },
{ "pagePath": "pages/profile/index", "text": "我的", "iconPath": "static/icons/user.png", "selectedIconPath": "static/icons/user-active.png" }
]
}
}
```
---
## 十、风险与应对
| 风险 | 影响 | 应对方案 |
|------|------|----------|
| 2G 内存不足 | 服务崩溃 | 监控内存,必要时升级配置 |
| 微信审核不通过 | 延迟上线 | 提前了解审核规范 |
| 数据丢失 | 用户体验差 | 每日自动备份 MySQL (mysqldump) |
| 并发量突增 | 响应变慢 | PM2 自动重启 + 限流 |
---
## 十一、预算
| 项目 | 费用 |
|------|------|
| 阿里云服务器 | 已有 (2H2G) |
| 域名 | ¥55/年 (.com) |
| SSL 证书 | 免费 (Let's Encrypt) |
| 微信认证 | ¥300/年 (企业) |
| **总计** | ¥355/年 |
---
## 十二、下一步行动
1. **立即开始**: 初始化 Uni-app 项目 + 后端项目
2. **本周完成**: 数据库设计 + 微信登录 + API 框架
3. **下周目标**: 完成记账核心功能
4. **月底目标**: 完成全部 P0 功能,提交微信审核
---
*文档版本: v1.0 | 最后更新: 2026-05-27*

1638
docs/mockup/index.html Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,354 @@
# 小菜记账 — 设计规格书
## 概述
**产品名称**: 小菜记账 (Xiaocai Accounting)
**产品类型**: 个人记账小程序
**设计方向**: 可爱 × 高级 (Cute × Premium)
**设计风格**: Claymorphism (软3D粘土风格) + 极简主义融合
**目标平台**: 移动端优先 (微信小程序 / Web App)
---
## 设计理念
"小菜"暗示温暖、家常、轻松。设计需要传递 **「记账也可以很可爱」** 的情感,同时通过精致的细节呈现 **高级感**
### 品牌人格
- **友好温暖** — 不冰冷的财务工具,是陪你记账的小伙伴
- **精致克制** — 可爱但不幼稚,高级但不冷淡
- **轻松治愈** — 让记账从负担变成享受
---
## 色彩系统
| 角色 | 色值 | 用途 |
|------|------|------|
| Primary | `#FF8C69` | 主色调,珊瑚橙,温暖活泼 |
| Primary Light | `#FFB89A` | 浅色变体,背景装饰 |
| Primary Dark | `#E67355` | 深色变体,按下状态 |
| Secondary | `#6C9BCF` | 辅助色,柔和蓝,收入/信任 |
| Accent | `#FFD166` | 强调色,暖金,高亮点缀 |
| Background | `#FFF8F0` | 全局背景,暖奶油色 |
| Surface | `#FFFFFF` | 卡片/面板背景 |
| Surface Warm | `#FFF0E6` | 暖色卡片背景 |
| Text Primary | `#2D1B1B` | 主文字,暖深棕 |
| Text Secondary | `#8B7E7E` | 辅助文字 |
| Text Muted | `#BFB3B3` | 禁用/占位文字 |
| Success | `#7BC67E` | 收入/成功,软绿 |
| Warning | `#FFB347` | 提醒,暖橘 |
| Danger | `#FF6B6B` | 超支/删除,软红 |
| Border | `#F0E0D6` | 分割线/边框 |
### 色彩使用原则
- 主色调占界面约 15-20%,避免过度使用
- 背景保持温暖但不刺眼,`#FFF8F0` 比纯白更有亲和力
- 文字对比度确保 WCAG AA (4.5:1 以上)
- 深棕色文字替代纯黑,与整体暖色调统一
---
## 字体系统
| 用途 | 字体 | 备选 | 权重 |
|------|------|------|------|
| 标题 | Fredoka | PingFang SC (中文) | 500-700 |
| 正文 | Nunito | PingFang SC (中文) | 400-500 |
| 数字/金额 | Fredoka | - | 600-700 |
| 特殊标注 | Caveat (手写体) | - | 400-600 |
### 字号规范
| 级别 | 大小 | 用途 |
|------|------|------|
| H1 | 28px/1.3 | 页面主标题 |
| H2 | 22px/1.3 | 区块标题 |
| H3 | 18px/1.4 | 卡片标题 |
| Body L | 16px/1.6 | 正文 |
| Body | 14px/1.6 | 辅助正文 |
| Caption | 12px/1.5 | 说明文字 |
| Amount XL | 36px/1.2 | 首页总金额 |
| Amount L | 24px/1.2 | 列表金额 |
---
## UI 组件规范
### 粘土风格核心参数
- `border-radius`: 16-24px (卡片), 12-16px (按钮)
- `border`: 2-3px solid (深色边框强调立体感)
- `box-shadow`: 内阴影 + 外阴影双层结构
- 外阴影: `4px 4px 12px rgba(45, 27, 27, 0.08)`
- 内阴影: `inset -2px -2px 6px rgba(45, 27, 27, 0.04)`
- 按钮按下: `inset 2px 2px 6px rgba(45, 27, 27, 0.1)` + scale(0.97)
### 按钮
| 类型 | 样式 |
|------|------|
| Primary | 珊瑚橙背景 + 白字 + 粘土阴影 + 圆角16px |
| Secondary | 白色背景 + 3px珊瑚橙边框 + 粘土阴影 |
| Ghost | 无背景 + 珊瑚橙文字 + hover浅色背景 |
| Danger | 软红背景 + 白字 |
### 卡片
- 白色背景 + 粘土阴影
- 圆角 20px
- 内边距 16-20px
- 点击态: 轻微下沉 (translateY 2px + 阴影缩减)
### 输入框
- 圆角 14px
- 2px 边框 `#F0E0D6`,聚焦时变为 Primary
- 内阴影 `inset 1px 1px 4px rgba(45,27,27,0.04)`
- 高度 48px方便触摸
### 图标
- 使用 **Lucide Icons** (一致的 SVG 图标集)
- 尺寸: 24px (标准), 20px (小), 32px (大)
- 颜色跟随内容层级
---
## 页面结构
### 1. 首页 — 仪表盘
```
┌──────────────────────────┐
│ 👤 头像 小菜记账 📊 │ 顶栏
├──────────────────────────┤
│ 本月支出 │
│ ¥ 3,280.00 │ 金额大卡片 (粘土)
│ ━━━━━━━━━━━━━━ 65% │ 预算进度条
│ 预算剩余 ¥1,720 │
├──────────────────────────┤
│ [收入] [支出] [转账] │ 快捷操作 (3个大按钮)
├──────────────────────────┤
│ 近期账单 │
│ 🍜 午餐 -¥35 今天 │
│ ☕ 咖啡 -¥18 今天 │ 交易列表
│ 💰 工资 +¥8,000 昨天 │
│ 📦 快递 -¥28 昨天 │
├──────────────────────────┤
│ 🏠 📊 💰 👤 │ 底部导航
└──────────────────────────┘
```
### 2. 记账页 — 添加记录
- 大号金额输入区 (居中,大字体)
- 分类选择 (圆形图标网格,粘土风格)
- 日期选择
- 备注输入
- 支出/收入切换标签
### 3. 统计页 — 图表分析
- 月度总览卡片
- 分类饼图/环形图
- 日支出趋势折线图
- 分类排行榜
### 4. 我的 — 设置
- 用户头像和信息
- 预算设置
- 分类管理
- 数据导出
---
## 动效规范
| 类型 | 时长 | 缓动 | 说明 |
|------|------|------|------|
| 按钮按下 | 150ms | ease-out | 轻微下沉 + 缩放 |
| 页面切换 | 250ms | ease-in-out | 淡入 + 上移 8px |
| 数字变化 | 400ms | ease-out | 数字递增动画 |
| 列表出现 | 300ms | ease-out | 错位入场 (stagger 50ms) |
| 悬浮反馈 | 200ms | ease | 阴影加深 + 微上浮 |
### 动画原则
- 尊重 `prefers-reduced-motion`
- 不使用夸张弹跳 (粘土风格的自然按压感即可)
- 数字跳动使用 `font-variant-numeric: tabular-nums` 防止宽度变化
---
## 设计令牌系统
### 间距 (4px 基准)
| Token | 值 | 用途 |
|-------|-----|------|
| `--space-xs` | 4px | 图标与文字间距 |
| `--space-sm` | 8px | 紧凑内边距 |
| `--space-md` | 12px | 按钮内边距 |
| `--space-base` | 16px | 卡片内边距、列表间距 |
| `--space-lg` | 20px | 区块间距 |
| `--space-xl` | 24px | 页面内边距 |
| `--space-2xl` | 32px | 大区块间距 |
### 圆角
| Token | 值 | 用途 |
|-------|-----|------|
| `--radius-sm` | 8px | 标签、小按钮 |
| `--radius-md` | 12px | 输入框、普通按钮 |
| `--radius-lg` | 16px | 主按钮、分类图标 |
| `--radius-xl` | 20px | 卡片 |
| `--radius-full` | 9999px | 圆形头像、药丸标签 |
### 阴影 (粘土风格)
| Token | 值 | 用途 |
|-------|-----|------|
| `--shadow-clay` | `4px 4px 12px rgba(45,27,27,0.08), inset -2px -2px 6px rgba(45,27,27,0.04)` | 卡片默认 |
| `--shadow-clay-hover` | `6px 6px 16px rgba(45,27,27,0.12), inset -2px -2px 6px rgba(45,27,27,0.04)` | 卡片悬浮 |
| `--shadow-clay-pressed` | `inset 2px 2px 6px rgba(45,27,27,0.1)` | 按钮按下 |
| `--shadow-clay-float` | `8px 8px 24px rgba(45,27,27,0.1), inset -3px -3px 8px rgba(45,27,27,0.05)` | 浮动元素 |
---
## 组件库规范
### AmountCard (金额卡片)
显示金额的卡片容器,用于首页总览、统计概览等。
| Prop | 类型 | 说明 |
|------|------|------|
| `title` | string | 标题文字 |
| `amount` | number | 金额 (分) |
| `prefix` | `'+'` \| `'-'` \| `''` | 前缀符号 |
| `variant` | `'default'` \| `'warm'` \| `'primary'` | 样式变体 |
| `trend` | `{ value, direction }` | 趋势数据 |
变体:
- `default`: 白色背景 + 粘土阴影
- `warm`: 背景 `#FFF0E6`
- `primary`: 渐变 `#FF8C69 → #FFB89A`,文字白色
### TransactionItem (交易列表项)
| Prop | 类型 | 说明 |
|------|------|------|
| `icon` | string | Lucide 图标名 |
| `iconColor` | string | 图标颜色 |
| `iconBg` | string | 图标背景色 |
| `name` | string | 交易名称 |
| `category` | string | 分类名 |
| `time` | string | 时间 |
| `amount` | number | 金额 (分) |
| `type` | `'expense'` \| `'income'` | 类型 |
布局: 64px 高flex 对齐gap 12px。按下态: 背景 `#FFF8F0`100ms。
### CategoryIcon (分类图标)
| Prop | 类型 | 说明 |
|------|------|------|
| `name` | string | Lucide 图标名 |
| `size` | `'sm'` \| `'md'` \| `'lg'` | 尺寸 (20/24/28px) |
| `color` | string | 图标颜色 |
| `bgColor` | string | 背景色 |
| `selected` | boolean | 是否选中 |
尺寸映射:
- sm: 容器 32px图标 16px圆角 8px
- md: 容器 44px图标 22px圆角 12px
- lg: 容器 56px图标 28px圆角 14px
### BudgetBar (预算进度条)
| Prop | 类型 | 说明 |
|------|------|------|
| `total` | number | 预算总额 (分) |
| `used` | number | 已用金额 (分) |
| `showLabel` | boolean | 是否显示标签 |
轨道: 高 8px圆角 4px背景 `#F0E0D6`
填充: 渐变 `#FF8C69 → #FFB89A`,宽度 = used/total。
超支态: 填充色变为 `#FF6B6B`
动画: 宽度变化 600ms ease-out。
### BottomNav (底部导航栏)
| Prop | 类型 | 说明 |
|------|------|------|
| `current` | `'home'` \| `'stats'` \| `'profile'` | 当前页 |
| `onNavigate` | function | 导航回调 |
高度: 56px + safe-area。4 个导航项 + 中间浮动 "+" 按钮。
选中态: 图标填充 `#FF8C69`,文字 `#FF8C69` Nunito 600。
默认态: 图标线条 `#BFB3B3`,文字 `#BFB3B3` Nunito 400。
---
## 暗色模式 (v2 预留)
| Token | Light | Dark |
|-------|-------|------|
| Background | `#FFF8F0` | `#1A1412` |
| Surface | `#FFFFFF` | `#2D2422` |
| Surface Warm | `#FFF0E6` | `#3D2E2A` |
| Text Primary | `#2D1B1B` | `#F5EDE8` |
| Text Secondary | `#8B7E7E` | `#A89890` |
| Border | `#F0E0D6` | `#4A3C38` |
| Primary | `#FF8C69` | `#FF8C69` (不变) |
| Shadow | `rgba(45,27,27,0.08)` | `rgba(0,0,0,0.3)` |
---
## 技术选型建议
| 方案 | 技术栈 | 适用场景 |
|------|--------|----------|
| A | Uni-app (Vue3) + Pinia | 跨端小程序,一套代码多平台 |
| B | Taro (React) + Zustand | React 生态,跨端 |
| C | 原生微信小程序 | 纯微信生态,性能最优 |
| D | HTML + Tailwind CSS + Vanilla JS | Web App最快原型 |
**推荐 A (Uni-app)**: 跨端能力 + Vue 生态成熟 + 社区资源丰富,适合快速开发上线。
---
## 反模式 (避免)
- ❌ 使用 emoji 作为 UI 图标 → ✅ 使用 Lucide SVG 图标
- ❌ 纯黑或冷灰色文字 → ✅ 暖棕色调文字
- ❌ 扁平无层次 → ✅ 粘土阴影创造深度
- ❌ 过于幼稚 → ✅ 克制的圆角和色彩饱和度
- ❌ 文字过多 → ✅ 图标+数字为主,文字为辅
- ❌ 弹出式键盘遮挡 → ✅ 金额输入固定在键盘上方
- ❌ 忽略触摸区域 → ✅ 最小 44×44px 触摸目标
---
## 响应式与适配
### 断点
| 断点 | 宽度 | 设备 | 布局调整 |
|------|------|------|----------|
| xs | < 375px | 小屏手机 | 缩小间距,字号减 1px |
| sm | 375-414px | 标准手机 | 基准设计 |
| md | 415-768px | 大手机/小平板 | 内容区 max-width 480px 居中 |
| lg | > 768px | 平板/H5 | 双列布局,侧边导航 |
### 小程序 rpx 换算
设计稿 375px → 750rpx (1px = 2rpx)
| 设计稿 | rpx |
|--------|-----|
| 12px | 24rpx |
| 14px | 28rpx |
| 16px | 32rpx |
| 18px | 36rpx |
| 20px | 40rpx |
| 24px | 48rpx |
| 36px | 72rpx |
| 48px | 96rpx |
### H5 桌面端
- 内容区: `max-width: 420px`,居中
- 背景: `#F0E0D6` (深色底)
- 手机框: 圆角 32px + 阴影,模拟手机外观

1100
docs/ui-design.md Normal file

File diff suppressed because it is too large Load Diff