小账本 - 系统模块及详细功能说明文档
目录
- 系统概述
- 技术架构
- 模块清单
- 页面功能详细说明
- 数据模型
- 核心Store
- 工具函数
- 样式规范
- 业务流程
系统概述
项目简介
小账本是一款简洁易用的个人记账应用,采用现代化的前端技术栈开发,支持多端运行(H5、微信小程序等)。应用专注于提供流畅的记账体验,同时支持记录每日心情,帮助用户更好地了解自己的消费习惯和情绪状态。

核心特性
- 多端支持:基于 uni-app 框架,支持 H5、小程序等多端运行
- 数据持久化:使用 IndexedDB 本地存储,数据安全可靠
- 心情记录:支持记录每日心情,提供情绪追踪功能
- 统计分析:提供收支统计、分类分析、心情统计等多维度数据展示
- 简洁易用:界面简洁,操作直观,记账流程顺畅
技术架构
技术栈
| 类别 | 技术 | 版本 | 说明 |
|---|
| Node.js | Node.js | >= 18.0.0 | 运行环境 |
| 前端框架 | Vue | 3.5.39 | 采用 Composition API |
| 构建工具 | Vite | 6.x | 快速的开发构建体验 |
| 跨端框架 | uni-app | 3.x | 支持多端运行 |
| 状态管理 | Pinia | 3.0.4 | 轻量级状态管理 |
| Vue DevTools | @vue/devtools-api | 7.7.9 | Vue 开发者工具 |
| 本地存储 | IndexedDB | - | 浏览器本地数据库 |
| 样式预处理 | SCSS | - | 变量、混合等高级特性 |
| 图表绘制 | Canvas 2D | - | 自定义统计图表 |
Node.js 版本要求
- 最低版本:Node.js 18.0.0
- 推荐版本:Node.js 20.x LTS
核心依赖版本详情
| 依赖名称 | 版本 | 用途 |
|---|
| vue | 3.5.39 | Vue 核心框架 |
| @vue/compiler-core | 3.5.39 | Vue 编译器核心 |
| @vue/compiler-dom | 3.5.39 | Vue DOM 编译器 |
| @vue/compiler-sfc | 3.5.39 | Vue SFC 编译器 |
| @vue/reactivity | 3.5.39 | Vue 响应式系统 |
| @vue/runtime-core | 3.5.39 | Vue 运行时核心 |
| @vue/runtime-dom | 3.5.39 | Vue DOM 运行时 |
| @vue/shared | 3.5.39 | Vue 共享工具函数 |
| pinia | 3.0.4 | 状态管理 |
| @vue/devtools-api | 7.7.9 | Vue DevTools 接口 |
| @babel/parser | 7.29.7 | JavaScript 解析器 |
| @babel/types | 7.29.7 | Babel 类型定义 |
| postcss | 8.5.15 | CSS 处理工具 |
| nanoid | 3.3.15 | 唯一 ID 生成 |
| picocolors | 1.1.1 | 命令行颜色输出 |
| source-map-js | 1.2.1 | SourceMap 处理 |
开发环境依赖
| 依赖名称 | 版本 | 用途 |
|---|
| @dcloudio/types | - | uni-app TypeScript 类型定义 |
| @types/node | - | Node.js TypeScript 类型定义 |
| typescript | - | TypeScript 编译 |
| sass | - | SCSS 编译 |
项目目录结构
account-app/
├── pages/ # 页面文件
│ ├── home/
│ │ └── index.vue # 首页
│ ├── record/
│ │ ├── add.vue # 添加记账记录
│ │ ├── edit.vue # 编辑记账记录
│ │ ├── list.vue # 记账记录列表
│ │ └── search.vue # 搜索记账记录
│ ├── calendar/
│ │ └── index.vue # 日历视图
│ ├── stats/
│ │ └── index.vue # 统计分析
│ └── category/
│ └── manage.vue # 分类管理
├── stores/ # Pinia 状态管理
│ ├── record.js # 记账记录 Store
│ └── category.js # 分类 Store
├── components/ # 公共组件
│ └── WeatherWidget.vue # 天气组件
├── utils/ # 工具函数
│ ├── index.js # 通用工具函数
│ └── db.js # IndexedDB 数据库操作
├── static/ # 静态资源
├── styles/ # 样式文件
│ └── common.scss # 公共样式
├── uni.scss # uni-app 全局变量
├── App.vue # 应用入口
├── main.js # 主入口文件
└── manifest.json # 应用配置
模块清单
一级模块
| 模块名称 | 文件路径 | 功能描述 |
|---|
| 首页模块 | pages/home/index.vue | 展示收支概况、最近记录、快速入口 |
| 记账模块 | pages/record/* | 添加、编辑、列表、搜索记账记录 |
| 日历模块 | pages/calendar/index.vue | 日历视图展示记录 |
| 统计模块 | pages/stats/index.vue | 数据统计和可视化 |
| 分类模块 | pages/category/manage.vue | 分类管理 |
| 天气模块 | components/WeatherWidget.vue | 显示天气信息 |
二级模块(Store)
| 模块名称 | 文件路径 | 功能描述 |
|---|
| 记录Store | stores/record.js | 记账数据管理、统计计算 |
| 分类Store | stores/category.js | 分类数据管理 |
二级模块(工具)
| 模块名称 | 文件路径 | 功能描述 |
|---|
| 数据库模块 | utils/db.js | IndexedDB 封装 |
| 工具函数 | utils/index.js | 格式化、日期处理等 |
页面功能详细说明
1. 首页 (pages/home/index.vue)
功能概述
首页是用户打开应用的第一个页面,承担着数据总览和功能导航的作用。

模块结构
┌─────────────────────────────────────┐
│ 小账本 ✦ [天气组件] │ <- 顶部标题区
├─────────────────────────────────────┤
│ 早上好 / 下午好 / 晚上好 │ <- 问候语
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐│
│ │ 本月结余 ││ <- 收支卡片
│ │ ¥12,345.00 ││
│ │ [📈 收入 ¥20,000] [📉 支出 ¥7,655]││
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │ 📝 │ │ 🔥 │ │ 🏆 │ │ <- 快速统计
│ │ ¥256 │ │ 45 │ │ 餐饮 │ │
│ │今日支出│ │本月笔数│ │最多分类│ │
│ └───────┘ └───────┘ └───────┘ │
├─────────────────────────────────────┤
│ 最近记录 查看全部 │
├─────────────────────────────────────┤
│ 🍜 餐饮 · 午餐 🍀 ¥35.00 │ <- 记录列表
│ 🚗 交通 · 地铁 ¥5.00 │
│ 🛍️ 购物 · 衣服 ¥299.00 │
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 显示本月结余 | 从 Store 获取 monthBalance 计算当月收支差 | P0 |
| 2 | 显示本月收入 | 从 Store 获取 monthIncome 汇总收入 | P0 |
| 3 | 显示本月支出 | 从 Store 获取 monthExpense 汇总支出 | P0 |
| 4 | 显示今日支出 | 从 Store 获取 todayExpense 计算当天支出 | P1 |
| 5 | 显示本月笔数 | 从 Store 获取 monthRecordCount 统计记录数 | P1 |
| 6 | 显示最多分类 | 从 Store 获取 topExpenseCategory 找出支出最多分类 | P1 |
| 7 | 问候语 | 根据当前时间显示"早上好/下午好/晚上好" | P2 |
| 8 | 最近记录列表 | 从 Store 获取 recentRecords 显示最近5条 | P0 |
| 9 | 跳转记账页 | 点击添加按钮跳转到 add.vue | P0 |
| 10 | 跳转列表页 | 点击"查看全部"跳转到 list.vue | P1 |
| 11 | 跳转日历页 | 点击日历图标跳转到 calendar/index.vue | P1 |
| 12 | 跳转统计页 | 点击统计图标跳转到 stats/index.vue | P1 |
| 13 | 编辑记录 | 点击记录项跳转到 edit.vue | P1 |
| 14 | 加载状态 | 数据未初始化时显示加载提示 | P1 |
| 15 | 心情显示 | 记录列表显示心情表情 | P2 |
交互说明
- 添加按钮:点击后带参数
?type=expense 跳转,方便用户快速记账 - 记录点击:跳转到编辑页面,传递记录 ID 作为参数
- 查看全部:跳转到记账列表页面
- 天气组件:显示当前天气信息(可选功能)
2. 记账添加页面 (pages/record/add.vue)
功能概述
记账添加页面是核心记账功能的入口,用户可以快速添加支出或收入记录,并记录当日心情。

模块结构
┌─────────────────────────────────────┐
│ 记一笔 ✦ │ <- 页面标题
├─────────────────────────────────────┤
│ [ 支出 ] [ 收入 ] │ <- 类型切换
├─────────────────────────────────────┤
│ ¥ 0.00 │ <- 金额输入
├─────────────────────────────────────┤
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │🍜 │ │🚗 │ │🛍️│ │🎮 │ │🏠 │ │ <- 分类选择
│ │餐饮│ │交通│ │购物│ │娱乐│ │住房│ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │💊 │ │📚 │ │📱 │ │🍪 │ │🏃 │ │
│ │医疗│ │教育│ │通讯│ │零食│ │运动│ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
├─────────────────────────────────────┤
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │😀│ │😊│ │😐│ │😔│ │😭│ │ <- 心情选择
│ │开心│ │愉快│ │一般│ │难过│ │伤心│ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
│ ┌───┐ │
│ │😡│ │
│ │生气│ │
│ └───┘ │
├─────────────────────────────────────┤
│ 📅 今天 今天 │ <- 日期选择
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐│
│ │ 添加备注(可选)... ││ <- 备注输入
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ [ 保存记录 ] │ <- 提交按钮
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 类型切换 | 切换支出/收入类型,刷新分类列表 | P0 |
| 2 | 金额输入 | 输入记账金额,支持小数 | P0 |
| 3 | 分类选择 | 点击选择分类,选中高亮 | P0 |
| 4 | 心情选择 | 选择当日心情(6种表情),默认选择第一个 | P0 |
| 5 | 日期选择 | 点击打开日期选择器 | P1 |
| 6 | 备注输入 | 可选输入,最多100字 | P2 |
| 7 | 保存记录 | 验证数据并保存到 Store | P0 |
| 8 | 返回首页 | 保存成功后自动返回 | P1 |
心情选项配置
| 表情 | 名称 | 值 |
|---|
| 😀 | 开心 | ‘😀’ |
| 😊 | 愉快 | ‘😊’ |
| 😐 | 一般 | ‘😐’ |
| 😔 | 难过 | ‘😔’ |
| 😭 | 伤心 | ‘😭’ |
| 😡 | 生气 | ‘😡’ |
验证规则
| 字段 | 规则 | 错误提示 |
|---|
| 金额 | 必须 > 0 | “请输入金额” |
| 分类 | 必须选择 | “请选择分类” |
交互说明
- 类型切换:切换支出/收入时重置已选分类
- 分类选择:单选,点击后高亮显示
- 心情选择:单选,默认选中第一个"开心"
- 日期选择:默认当天,支持补录
- 保存成功:显示提示后延迟返回上一页
3. 记账编辑页面 (pages/record/edit.vue)
功能概述
编辑页面用于修改已有的记账记录,支持完整的数据回显和更新。

模块结构
┌─────────────────────────────────────┐
│ [‹] 编辑记录 │ <- 头部导航
├─────────────────────────────────────┤
│ [ 支出 ] [ 收入 ] │ <- 类型切换
├─────────────────────────────────────┤
│ ¥ 35.00 │ <- 金额输入(回显)
├─────────────────────────────────────┤
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │🍜✓│ │🚗 │ │🛍️│ │🎮 │ │🏠 │ │ <- 分类选择(回显)
│ │餐饮│ │交通│ │购物│ │娱乐│ │住房│ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
├─────────────────────────────────────┤
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │😀 │ │😊✓│ │😐│ │😔│ │😭│ │ <- 心情选择(回显)
│ │开心│ │愉快│ │一般│ │难过│ │伤心│ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
├─────────────────────────────────────┤
│ 📅 2024-01-15 补录 │ <- 日期选择
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐│
│ │ 午餐 ││ <- 备注输入(回显)
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ [ 删除记录 ] │ <- 删除按钮
│ [ 保存修改 ] │ <- 提交按钮
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 加载记录 | 根据 URL 参数 ID 加载记录数据 | P0 |
| 2 | 类型切换 | 切换支出/收入类型 | P0 |
| 3 | 金额回显 | 显示原金额值 | P0 |
| 4 | 分类回显 | 高亮显示原分类 | P0 |
| 5 | 心情回显 | 高亮显示原心情 | P0 |
| 6 | 日期回显 | 显示原日期 | P1 |
| 7 | 备注回显 | 显示原备注 | P1 |
| 8 | 更新记录 | 保存修改后的数据 | P0 |
| 9 | 删除记录 | 弹出确认后删除记录 | P1 |
数据回显逻辑
编辑页面加载时:
1. 从 URL 参数获取 record ID
2. 在 Store 中查找对应记录
3. 填充表单字段:
- recordType = record.type
- amount = record.amount
- selectedCatId = record.catId
- selectedMood = record.mood || ''
- selectedDate = record.date
- note = record.note
交互说明
- 返回按钮:返回上一页
- 删除按钮:弹出确认对话框,确认后删除并返回
- 保存按钮:验证数据后更新记录
4. 记账列表页面 (pages/record/list.vue)
功能概述
列表页面展示所有记账记录,支持多种筛选条件和操作功能。

模块结构
┌─────────────────────────────────────┐
│ [‹] 记账列表 [🔍] │ <- 头部导航
├─────────────────────────────────────┤
│ 全部 支出 收入 今天 本周 本月 │ <- 筛选标签
├─────────────────────────────────────┤
│ 今天 ▼ ¥350 │ <- 日期分组
│ ┌───┐ 🍜餐饮 · 午餐🍀 ¥35.00 [✏️🗑️]│
│ ┌───┐ 🚗交通 · 地铁 ¥5.00 [✏️🗑️]│
│ ┌───┐ 🛍️购物 · 衣服 ¥310.00 [✏️🗑️]│
├─────────────────────────────────────┤
│ 昨天 ▼ ¥120 │
│ ┌───┐ 🍜餐饮 · 晚餐 ¥80.00 [✏️🗑️]│
│ ┌───┐ 🎮娱乐 · 电影 ¥40.00 [✏️🗑️]│
├─────────────────────────────────────┤
│ 1月15日 ▼ ¥500 │
│ ┌───┐ 🏠住房 · 房租 ¥500.00 [✏️🗑️]│
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 全部筛选 | 显示所有记录 | P1 |
| 2 | 支出筛选 | 仅显示支出记录 | P1 |
| 3 | 收入筛选 | 仅显示收入记录 | P1 |
| 4 | 今天筛选 | 仅显示今天的记录 | P1 |
| 5 | 本周筛选 | 仅显示本周的记录 | P1 |
| 6 | 本月筛选 | 仅显示本月的记录 | P1 |
| 7 | 日期分组 | 按日期分组显示记录 | P0 |
| 8 | 当日汇总 | 显示每天的支出和收入 | P1 |
| 9 | 心情显示 | 显示记录的心情表情 | P2 |
| 10 | 编辑记录 | 点击编辑按钮跳转到编辑页 | P0 |
| 11 | 删除记录 | 点击删除按钮删除记录 | P1 |
| 12 | 跳转搜索 | 点击搜索图标跳转搜索页 | P1 |
| 13 | 空状态 | 无记录时显示提示 | P1 |
筛选条件配置
| 值 | 标签 | 筛选逻辑 |
|---|
| all | 全部 | 无筛选 |
| expense | 支出 | type === ‘expense’ |
| income | 收入 | type === ‘income’ |
| today | 今天 | date === todayStr |
| week | 本周 | date in currentWeek |
| month | 本月 | date.startsWith(currentMonth) |
金额显示规则
| 类型 | 格式 | 颜色 |
|---|
| 支出 | ¥XX.XX | 珊瑚色 ($joy-coral-600) |
| 收入 | +¥XX.XX | 薄荷绿 ($joy-mint-600) |
交互说明
- 筛选切换:点击标签切换筛选条件
- 记录点击:点击记录项跳转编辑页
- 编辑按钮:点击跳转编辑页
- 删除按钮:点击弹出确认后删除
5. 搜索页面 (pages/record/search.vue)
功能概述
搜索页面提供关键词检索功能,方便用户快速找到特定记录。

模块结构
┌─────────────────────────────────────┐
│ [搜索记账记录...] [取消] │ <- 搜索栏
├─────────────────────────────────────┤
│ 📝 输入关键词搜索 │ <- 空状态
│ 搜索记录名称、备注等 │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ [午餐支出...] [取消] │ <- 搜索栏(输入中)
├─────────────────────────────────────┤
│ 今天 ▼ ¥35 │
│ 🍜餐饮 · 午餐🍀 ¥35.00 │
├─────────────────────────────────────┤
│ 昨天 ▼ ¥80 │
│ 🍜餐饮 · 午餐 ¥80.00 │
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 关键词输入 | 实时搜索输入 | P0 |
| 2 | 分类名称搜索 | 匹配分类名称 | P0 |
| 3 | 备注搜索 | 匹配备注内容 | P0 |
| 4 | 心情搜索 | 匹配心情表情 | P1 |
| 5 | 日期分组 | 搜索结果按日期分组 | P1 |
| 6 | 当日汇总 | 显示每天收支 | P1 |
| 7 | 无结果提示 | 未匹配时显示提示 | P1 |
| 8 | 取消返回 | 点击取消返回上一页 | P1 |
| 9 | 编辑记录 | 点击搜索结果编辑 | P1 |
搜索范围
| 字段 | 说明 |
|---|
| 分类名称 | 匹配记录的分类名称 |
| 备注 | 匹配记录的备注内容 |
6. 日历页面 (pages/calendar/index.vue)
功能概述
日历视图以月历形式展示记账记录,直观显示每日收支情况。

模块结构
┌─────────────────────────────────────┐
│ 日历视图 ✦ │
│ [◀] 2024年1月 [▶] │ <- 月份导航
├─────────────────────────────────────┤
│ 日 一 二 三 四 五 六 │ <- 星期标题
├─────────────────────────────────────┤
│ 1 2 3 4 5 6 │
│ ▼ ▼ ▼ ▼ ▼ ▼ ▼ │ <- 日期格子
│ ¥150 ¥80 ¥200 ¥120 ¥50 ¥300 │ <- 日支出
├─────────────────────────────────────┤
│ ▼ 点击日期查看详情 │ <- 操作提示
├─────────────────────────────────────┤
│ 1月15日(周一) ▼ ¥350 │
│ 🍜餐饮 · 午餐🍀 ¥35.00 │
│ 🚗交通 · 地铁 ¥5.00 │
│ 🛍️购物 · 衣服 ¥310.00 │
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 月份导航 | 显示当前月份,支持切换 | P0 |
| 2 | 月份切换 | 上一月/下一月 | P0 |
| 3 | 日期格子 | 显示日期数字 | P0 |
| 4 | 当日标记 | 高亮显示今天 | P1 |
| 5 | 有记录标记 | 有记录的日期显示圆点 | P1 |
| 6 | 日支出显示 | 显示每天的支出金额 | P1 |
| 7 | 记录列表 | 点击日期显示当天记录 | P0 |
| 8 | 心情显示 | 显示记录的心情表情 | P2 |
| 9 | 空状态 | 无记录时显示提示 | P1 |
日期状态
| 状态 | 样式 |
|---|
| 今天 | 背景高亮 |
| 有记录 | 底部圆点标记 |
| 无记录 | 默认样式 |
| 选中 | 边框高亮 |
7. 统计页面 (pages/stats/index.vue)
功能概述
统计页面提供多维度的数据统计和可视化展示。

模块结构
┌─────────────────────────────────────┐
│ 统计分析 ✦ │
│ [ 日 ] [ 周 ] [ 月 ] [ 年 ] │ <- 周期切换
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐│
│ │ 📈 收支曲线图 ││ <- 图表区域
│ │ ╱╲ ╱╲ ││
│ │ ╱ ╲__╱ ╲__╱ ││
│ │ 支出曲线 ││
│ │ ╱╲ ││
│ │ ╱╲╱ ╲__╱ ││
│ │ ╱ ╲__╱ ││
│ │收入曲线 ││
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ 支出分类统计 │
│ ┌─────────────────────────────────┐│
│ │ 🍜 餐饮 ¥2,500 ████████ 35% ││
│ │ 🚗 交通 ¥800 ████ 15% ││
│ │ 🛍️ 购物 ¥1,200 █████ 25% ││
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ 收入分类统计 │
│ ┌─────────────────────────────────┐│
│ │ 💰 工资 ¥8,000 ████████ 80% ││
│ │ 💼 兼职 ¥2,000 ███ 20% ││
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ 心情统计 │
│ ┌─────────────────────────────────┐│
│ │ 😀 开心 15次 ████████ 30% ││
│ │ 😊 愉快 12次 ██████ 24% ││
│ │ 😐 一般 10次 █████ 20% ││
│ │ 😔 难过 8次 ████ 16% ││
│ │ 😭 伤心 3次 ██ 6% ││
│ │ 😡 生气 2次 █ 4% ││
│ └─────────────────────────────────┘│
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 日统计 | 显示当天的收支数据 | P0 |
| 2 | 周统计 | 显示本周的收支数据 | P1 |
| 3 | 月统计 | 显示本月的收支数据 | P1 |
| 4 | 年统计 | 显示本年的收支数据 | P1 |
| 5 | 支出曲线 | 绘制支出曲线图(橙色) | P0 |
| 6 | 收入曲线 | 绘制收入曲线图(绿色) | P0 |
| 7 | 曲线阴影 | 曲线下方填充阴影 | P2 |
| 8 | 支出分类统计 | 显示支出分类占比 | P0 |
| 9 | 收入分类统计 | 显示收入分类占比 | P1 |
| 10 | 心情统计 | 显示心情占比 | P0 |
| 11 | 统计次数 | 显示各心情的记录次数 | P1 |
| 12 | 进度条 | 可视化展示占比 | P1 |
周期配置
| 值 | 标签 | 数据范围 |
|---|
| day | 日 | 当天 |
| week | 周 | 本周一至周日 |
| month | 月 | 本月1日至月末 |
| year | 年 | 本年1月至12月 |
图表配置
| 元素 | 配置 |
|---|
| 画布尺寸 | 宽度100%,高度200px |
| 边距 | 上20,右10,下30,左10 |
| 曲线宽度 | 2px |
| 阴影宽度 | 6px |
| 支出颜色 | 橙色 $joy-coral-500 |
| 收入颜色 | 绿色 $joy-mint-500 |
8. 分类管理页面 (pages/category/manage.vue)
功能概述
分类管理页面用于管理支出和收入的分类,支持增删改操作。




模块结构
┌─────────────────────────────────────┐
│ [‹] 分类管理 │ <- 头部导航
├─────────────────────────────────────┤
│ ┌─────────────────────────────────┐│
│ │ 👤 用户头像 ││ <- 用户信息
│ │ 点击更换头像 ││
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ 支出分类 │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │🍜✓│ │🚗 │ │🛍️│ │🎮 │ │🏠 │ │ <- 分类列表
│ │餐饮│ │交通│ │购物│ │娱乐│ │住房│ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │💊 │ │📚 │ │📱 │ [+ 添加] │
│ └─────────────────────────────────┘│
├─────────────────────────────────────┤
│ 收入分类 │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │💰✓│ │💼 │ │📈 │ │🧧 │ │
│ │工资│ │兼职│ │投资│ │红包│ │
│ └───┘ └───┘ └───┘ └───┘ │
│ [+ 添加] │
└─────────────────────────────────────┘
功能点清单
| 序号 | 功能点 | 描述 | 优先级 |
|---|
| 1 | 用户头像 | 显示用户头像 | P2 |
| 2 | 更换头像 | 点击更换头像图片 | P2 |
| 3 | 支出分类列表 | 显示所有支出分类 | P0 |
| 4 | 收入分类列表 | 显示所有收入分类 | P0 |
| 5 | 添加分类 | 添加新的分类 | P1 |
| 6 | 编辑分类 | 编辑分类名称/图标 | P1 |
| 7 | 删除分类 | 删除不需要的分类 | P1 |
| 8 | 分类统计 | 显示各分类使用次数 | P1 |
默认支出分类
| ID | 名称 | 图标 | 颜色索引 |
|---|
| e1 | 餐饮 | 🍜 | 0 |
| e2 | 交通 | 🚗 | 1 |
| e3 | 购物 | 🛍️ | 2 |
| e4 | 娱乐 | 🎮 | 3 |
| e5 | 住房 | 🏠 | 4 |
| e6 | 医疗 | 💊 | 5 |
| e7 | 教育 | 📚 | 6 |
| e8 | 通讯 | 📱 | 7 |
| e9 | 零食 | 🍪 | 8 |
| e10 | 运动 | 🏃 | 9 |
| e11 | 宠物 | 🐾 | 10 |
| e12 | 其他 | 💡 | 11 |
默认收入分类
| ID | 名称 | 图标 | 颜色索引 |
|---|
| i1 | 工资 | 💰 | 0 |
| i2 | 兼职 | 💼 | 1 |
| i3 | 投资 | 📈 | 2 |
| i4 | 红包 | 🧧 | 3 |
| i5 | 退款 | 🔄 | 4 |
| i6 | 其他 | ✨ | 5 |
数据模型
记账记录 (Record)
interface Record {
id: number;
type: 'expense' | 'income';
catId: string;
amount: number;
date: string;
hour: number;
note: string;
mood: string;
}
分类 (Category)
interface Category {
id: string;
name: string;
icon: string;
type: 'expense' | 'income';
colorIdx: number;
}
分类颜色配置
const expenseColors = [
{ bg: '#FFF5F5', color: '#E53E3E' },
{ bg: '#FFF5EB', color: '#ED8936' },
]
const incomeColors = [
{ bg: '#F0FFF4', color: '#38A169' },
{ bg: '#E6FFFA', color: '#319795' },
]
核心Store
1. 记录Store (stores/record.js)
状态定义
| 状态 | 类型 | 说明 |
|---|
| records | ref([]) | 记账记录列表 |
| nextId | ref(1) | 下一个记录ID |
| initialized | ref(false) | 数据是否已初始化 |
计算属性
| 属性 | 类型 | 说明 |
|---|
| monthBalance | computed | 本月结余(收入-支出) |
| monthIncome | computed | 本月收入总额 |
| monthExpense | computed | 本月支出总额 |
| todayExpense | computed | 今日支出金额 |
| monthRecordCount | computed | 本月记录笔数 |
| topExpenseCategory | computed | 本月支出最多分类 |
| recentRecords | computed | 最近5条记录 |
| moodBreakdown | computed | 心情统计数据 |
| categoryBreakdown | computed | 分类统计数据 |
方法列表
| 方法 | 参数 | 返回值 | 说明 |
|---|
| initDB | - | Promise | 初始化数据库 |
| addRecord | type, catId, amount, date, note, hour, mood | Record | 添加记录 |
| updateRecord | id, type, catId, amount, date, note, hour, mood | Record|null | 更新记录 |
| deleteRecord | id | boolean | 删除记录 |
| getGroupedRecords | filter? | GroupedRecords[] | 获取分组记录 |
2. 分类Store (stores/category.js)
状态定义
| 状态 | 类型 | 说明 |
|---|
| expenseCats | ref([]) | 支出分类列表 |
| incomeCats | ref([]) | 收入分类列表 |
方法列表
| 方法 | 参数 | 返回值 | 说明 |
|---|
| getCatById | catId, type | Category|undefined | 根据ID获取分类 |
| getCatColor | catId, type | ColorConfig | 获取分类颜色 |
| addCategory | type, name, icon | void | 添加分类 |
| deleteCategory | catId, type | void | 删除分类 |
工具函数
1. 格式化函数 (utils/index.js)
| 函数 | 参数 | 返回值 | 说明 |
|---|
| formatMoney | amount, prefix? | string | 格式化金额,如 ¥1,234.00 |
| formatDate | date? | string | 格式化日期为 YYYY-MM-DD |
| formatDateShort | dateStr, todayStr? | string | 格式化日期为中文,如 今天、昨天、1月15日 |
| getGreeting | - | string | 获取问候语 |
| getWeekday | date | string | 获取星期中文 |
| getDateBadge | selectedDate, today? | string | 获取日期徽章文本 |
| generateId | - | string | 生成唯一ID |
2. 数据库函数 (utils/db.js)
| 函数 | 参数 | 返回值 | 说明 |
|---|
| openDB | - | Promise | 打开数据库 |
| addRecord | record | Promise | 添加/更新记录 |
| getAllRecords | - | Promise<Record[]> | 获取所有记录 |
| getRecordsByDate | date | Promise<Record[]> | 按日期获取记录 |
| deleteRecord | id | Promise | 删除记录 |
| getMaxId | - | Promise | 获取最大ID |
样式规范
全局变量 (uni.scss)
// 珊瑚色系(支出、主题)
$joy-coral-50: #FFF5F5;
$joy-coral-100: #FED7D7;
$joy-coral-500: #F56565;
$joy-coral-600: #E53E3E;
// 薄荷绿系(收入、正向)
$joy-mint-50: #F0FFF4;
$joy-mint-100: #C6F6D5;
$joy-mint-500: #48BB78;
$joy-mint-600: #38A169;
// 中性色系
$joy-neutral-0: #FFFFFF;
$joy-neutral-50: #F7FAFC;
$joy-neutral-100: #EDF2F7;
$joy-neutral-200: #E2E8F0;
$joy-neutral-400: #A0AEC0;
$joy-neutral-600: #718096;
$joy-neutral-800: #2D3748;
$joy-neutral-900: #1A202C;
分类颜色数组
categoryColors.expense = [
{ bg: '#FFE8DA', text: '#9C4A28' },
{ bg: '#D8ECF8', text: '#4A98B8' },
{ bg: '#E8D8F5', text: '#8864A8' },
{ bg: '#F5E8D0', text: '#B89058' },
{ bg: '#D4F5E6', text: '#2C8858' },
{ bg: '#FFF5F0', text: '#B85E34' },
{ bg: '#F0F8FF', text: '#4A98B8' },
{ bg: '#F8F0FF', text: '#8864A8' },
{ bg: '#FFF8F0', text: '#B89058' },
{ bg: '#F0FFF8', text: '#2C8858' },
{ bg: '#FFE8DA', text: '#9C4A28' },
{ bg: '#F5F0EA', text: '#585048' },
]
categoryColors.income = [
{ bg: '#D4F5E6', text: '#2C8858' },
{ bg: '#FFE8DA', text: '#9C4A28' },
{ bg: '#D8ECF8', text: '#4A98B8' },
{ bg: '#F5E8D0', text: '#B89058' },
{ bg: '#E8D8F5', text: '#8864A8' },
{ bg: '#F5F0EA', text: '#585048' },
]
业务流程
1. 添加记录流程
开始
│
▼
┌──────────────────┐
│ 打开添加页面 │
│ type=expense │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 选择记录类型 │
│ 支出/收入 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 输入金额 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 选择分类 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 选择心情(默认) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 选择日期(默认) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 输入备注(可选) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 点击保存 │
└────────┬─────────┘
│
▼
┌────┴────┐
│ 验证通过?│
└────┬────┘
否 │ 是
│ │ │
▼ │ ▼
┌────┐ │ ┌──────────────────┐
│提示│ │ │ 保存到Store │
│错误│ │ └────────┬─────────┘
└────┘ │ │
│ ▼
│ ┌──────────────────┐
│ │ 持久化到IndexedDB│
│ └────────┬─────────┘
│ │
│ ▼
│ ┌──────────────────┐
│ │ 显示成功提示 │
│ └────────┬─────────┘
│ │
│ ▼
│ ┌──────────────────┐
└──│ 返回上一页 │
└──────────────────┘
2. 编辑记录流程
开始
│
▼
┌──────────────────┐
│ 从列表点击记录 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 跳转编辑页面 │
│ 传递 record ID │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 根据ID加载记录 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 回显所有字段 │
└────────┬─────────┘
│
▼
┌────┴────┐
│ 用户修改?│
└────┬────┘
否 │ 是
│ │ │
▼ │ ▼
┌────┐ │ ┌──────────────────┐
│跳过│ │ │ 修改字段值 │
└────┘ │ └────────┬─────────┘
│ │
│ ▼
┌────┴────┐
│ 点击操作?│
└────┬────┘
保存 │ 删除 │ 取消
│ │ │ │
▼ │ ▼ │
┌────┐ │ ┌────┐ ┌────┐
│验证│ │ │确认│ │返回│
└─┬──┘ │ └──┬─┘ └────┘
│ │ │
▼ │ ▼
┌────┐ │ ┌────┐
│保存│ │ │删除│
└─┬──┘ │ └─┬──┘
│ │ │
▼ │ ▼
┌────┐ │ ┌────┐
│返回│ │ │返回│
└────┘ │ └────┘
3. 数据持久化流程
应用启动
│
▼
┌──────────────────┐
│ 执行 initDB() │
└────────┬─────────┘
│
▼
┌────┴────┐
│ 数据库存在?│
└────┬────┘
是 │ 否
│ │ │
▼ │ ▼
┌────┐ │ ┌──────────────────┐
│加载│ │ │ 创建默认数据 │
│数据│ │ └────────┬─────────┘
└─┬──┘ │ │
│ │ ▼
│ │ ┌──────────────────┐
│ │ │ 写入模拟数据 │
│ │ └────────┬─────────┘
│ │ │
│ ▼ ▼
│ ┌──────────────────┐
└──│ 设置 initialized │
└────────┬─────────┘
│
▼
┌────────────────┐
│ 数据准备就绪 │
└────────────────┘
附录
版本信息
- 文档版本:v1.0
- 更新日期:2026-06-30
- 文档状态:完成
更新记录
| 日期 | 版本 | 更新内容 |
|---|
| 2026-06-30 | v1.0 | 初始版本 |