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:
490
docs/development-plan.md
Normal file
490
docs/development-plan.md
Normal 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 约 300MB,Node.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
1638
docs/mockup/index.html
Normal file
File diff suppressed because it is too large
Load Diff
354
docs/superpowers/specs/2026-05-27-xiaocai-design.md
Normal file
354
docs/superpowers/specs/2026-05-27-xiaocai-design.md
Normal 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
1100
docs/ui-design.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user