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

View File

@@ -0,0 +1,66 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { request } from '@/utils/request'
import { getCurrentMonth } from '@/utils/format'
export interface Overview {
expense: number
income: number
count: number
daily: number
}
export interface CategoryStat {
id: number
name: string
icon: string
color: string
amount: number
count: number
}
export interface TrendPoint {
date: string
amount: number
}
export const useStatsStore = defineStore('stats', () => {
const overview = ref<Overview>({ expense: 0, income: 0, count: 0, daily: 0 })
const categoryStats = ref<CategoryStat[]>([])
const trendData = ref<TrendPoint[]>([])
async function fetchOverview(month?: string) {
try {
overview.value = await request<Overview>({
url: '/stats/overview',
data: { month: month || getCurrentMonth() }
})
} catch {
overview.value = { expense: 0, income: 0, count: 0, daily: 0 }
}
}
async function fetchCategoryStats(month?: string, type: string = 'expense') {
try {
categoryStats.value = await request<CategoryStat[]>({
url: '/stats/category',
data: { month: month || getCurrentMonth(), type }
})
} catch {
categoryStats.value = []
}
}
async function fetchTrend(month?: string, type: string = 'expense') {
try {
trendData.value = await request<TrendPoint[]>({
url: '/stats/trend',
data: { month: month || getCurrentMonth(), type }
})
} catch {
trendData.value = []
}
}
return { overview, categoryStats, trendData, fetchOverview, fetchCategoryStats, fetchTrend }
})