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,37 @@
export function formatAmount(fen: number): string {
const yuan = (fen / 100).toFixed(2)
return '¥ ' + yuan.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
export function formatDate(date: string): string {
// Parse YYYY-MM-DD as local time to avoid timezone off-by-one
const parts = date.split('-').map(Number)
const d = new Date(parts[0], parts[1] - 1, parts[2])
const now = new Date()
// Reset time portion for accurate day diff
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
const target = new Date(d.getFullYear(), d.getMonth(), d.getDate())
const diff = Math.floor((today.getTime() - target.getTime()) / 86400000)
if (diff === 0) return '今天'
if (diff === 1) return '昨天'
if (diff === 2) return '前天'
return `${d.getMonth() + 1}${d.getDate()}`
}
export function formatMonth(date: string): string {
const [year, month] = date.split('-')
return `${year}${parseInt(month)}`
}
export function getCurrentMonth(): string {
const d = new Date()
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
}
export function formatAmountRaw(fen: number): string {
const yuan = (fen / 100).toFixed(2)
return yuan.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}