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,71 @@
<template>
<view class="numpad">
<view class="key" v-for="key in keys" :key="key" @tap="onKeyTap(key)">
<text class="key-text">{{ key }}</text>
</view>
<view class="key fn" @tap="emit('delete')">
<SvgIcon name="trash" :size="36" color="#FF8C69" />
</view>
<view class="key eq" @tap="emit('confirm')">
<SvgIcon name="check" :size="36" color="#FFFFFF" />
</view>
</view>
</template>
<script setup lang="ts">
import SvgIcon from '@/components/SvgIcon/SvgIcon.vue'
const keys = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0', '00']
const emit = defineEmits(['input', 'delete', 'confirm'])
function onKeyTap(key: string) {
emit('input', key)
}
</script>
<style lang="scss" scoped>
.numpad {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16rpx;
padding: 0 32rpx;
}
.key {
height: 96rpx;
border-radius: 24rpx;
background: #FFF8F0;
display: flex;
align-items: center;
justify-content: center;
&:active {
background: #F0E0D6;
}
}
.key-text {
font-family: 'Fredoka', sans-serif;
font-size: 44rpx;
font-weight: 500;
color: #2D1B1B;
}
.key.fn {
background: #FFE8E0;
&:active {
background: #FFD0C0;
}
}
.key.eq {
background: linear-gradient(135deg, #FF8C69, #E67355);
box-shadow: 0 4rpx 16rpx rgba(255, 140, 105, 0.3);
&:active {
background: #E67355;
}
}
</style>