From e110cd5c5d7cc06b2e12b14c9cbc875994a3c4a9 Mon Sep 17 00:00:00 2001
From: wangxiaogang <1433729587@qq.com>
Date: Thu, 4 Jun 2026 17:06:02 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=A8=E9=9D=A2=E4=BF=AE=E5=A4=8D=202?=
=?UTF-8?q?2=20=E9=A1=B9=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
严重 Bug:
- NaN 金额校验绕过(add 页面 parseFloat 空字符串)
- 4 个页面补充 waitForReady(add/budget/category-manage/group-manage)
- 导出 Loading 遮罩不消失(profile exportData 缺 hideLoading)
- Store 吞掉请求错误不 re-throw(transaction/stats/budget/user)
- 分类排序 SQL 拼接改参数化查询(category PUT /sort)
- 备份接口添加管理员权限检查(backup requireAdmin)
中等问题:
- 群组加入竞态条件改为 INSERT IGNORE
- 统计页切月/切Tab添加 loadSeq 防竞态
- stats store 补全 loading 状态 + Overview 初始值补全 7 字段
- 保存成功后返回不再弹「放弃修改」确认框
- 群组管理创建/加入添加 saving 双重提交保护
- 预算页添加 onShow 刷新
- 服务端输入校验(name/color/invite_code/微信code)
UI/样式:
- 触摸目标: bell/nav-back/nav-save→88rpx, avatar-badge→64rpx, action-btn→80rpx
- :active 反馈: bell/profile-card/identity-card/id-manage/arrow/action-btn/group-btn/cat-info
- 内联样式改动态绑定(4处 spacer 使用 capsuleRight)
- FAB 文字+改用 Icon 组件
- prefers-reduced-motion 动画降级(Skeleton/profile/budget/add)
- 胶囊适配(add/category-manage/group-manage)
- CategoryIcon !important 改为 iconStyle 计算属性
文档:
- CLAUDE.md 补充 SaveSuccess/ChartWrapper 组件 + category/budget/index API
---
CLAUDE.md | 7 +-
client/src/api/stats.ts | 3 +
client/src/api/transaction.ts | 2 +
.../components/CategoryIcon/CategoryIcon.vue | 3 +-
.../components/ChartWrapper/ChartWrapper.vue | 2 +-
client/src/components/Skeleton/Skeleton.vue | 6 ++
.../TransactionItem/TransactionItem.vue | 68 +++++++++++++++++--
client/src/pages/add/index.vue | 19 ++++--
client/src/pages/bills/index.vue | 14 ++++
client/src/pages/budget/index.vue | 25 +++++++
client/src/pages/category-manage/index.vue | 26 +++----
client/src/pages/group-manage/index.vue | 33 +++++++--
client/src/pages/index/index.vue | 15 ++--
client/src/pages/profile-edit/index.vue | 20 ++++--
client/src/pages/profile/index.vue | 21 +++++-
client/src/pages/stats/index.vue | 29 +++++---
client/src/stores/budget.ts | 3 +-
client/src/stores/stats.ts | 24 +++++--
client/src/stores/transaction.ts | 3 +-
client/src/stores/user.ts | 1 +
server/src/routes/auth.ts | 4 +-
server/src/routes/backup.ts | 20 +++++-
server/src/routes/category.ts | 29 ++++++--
server/src/routes/group.ts | 21 +++---
server/src/routes/transaction.ts | 4 +-
25 files changed, 314 insertions(+), 88 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 86eb176..c3721e7 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -75,8 +75,10 @@ client/src/
├── components/ # 公共组件
│ ├── BudgetBar/ # 预算进度条
│ ├── CategoryIcon/ # 分类图标 (首字+颜色)
+│ ├── ChartWrapper/ # uCharts 图表封装
│ ├── Icon/ # 图标组件 (PNG 映射)
│ ├── Numpad/ # 数字键盘
+│ ├── SaveSuccess/ # 保存成功动画
│ ├── Skeleton/ # 骨架屏
│ └── TransactionItem/ # 交易列表项
├── stores/ # Pinia stores
@@ -89,9 +91,12 @@ client/src/
├── api/ # API 封装
│ ├── auth.ts # 登录接口
│ ├── transaction.ts # 交易接口
+│ ├── category.ts # 分类接口
+│ ├── budget.ts # 预算接口
│ ├── stats.ts # 统计接口
│ ├── user.ts # 用户信息接口 (含头像上传)
-│ └── group.ts # 群组接口
+│ ├── group.ts # 群组接口
+│ └── index.ts # barrel 导出
├── utils/
│ ├── format.ts # 金额/日期格式化
│ ├── request.ts # HTTP 请求封装 (401 自动重登录+队列重试)
diff --git a/client/src/api/stats.ts b/client/src/api/stats.ts
index 482eb7f..1165250 100644
--- a/client/src/api/stats.ts
+++ b/client/src/api/stats.ts
@@ -4,8 +4,11 @@ import { request } from '@/utils/request'
export interface Overview {
expense: number
income: number
+ expenseCount: number
+ incomeCount: number
count: number
daily: number
+ dailyIncome: number
}
/** 分类统计 */
diff --git a/client/src/api/transaction.ts b/client/src/api/transaction.ts
index 5f0e5e4..bb130d5 100644
--- a/client/src/api/transaction.ts
+++ b/client/src/api/transaction.ts
@@ -3,6 +3,7 @@ import { request } from '@/utils/request'
/** 交易记录 */
export interface Transaction {
id: number
+ user_id: number
amount: number
type: 'expense' | 'income'
category_id: number
@@ -13,6 +14,7 @@ export interface Transaction {
category_color?: string
group_id?: number | null
creator_nickname?: string
+ creator_avatar?: string
}
/** 交易列表响应 */
diff --git a/client/src/components/CategoryIcon/CategoryIcon.vue b/client/src/components/CategoryIcon/CategoryIcon.vue
index 439b224..e873533 100644
--- a/client/src/components/CategoryIcon/CategoryIcon.vue
+++ b/client/src/components/CategoryIcon/CategoryIcon.vue
@@ -19,7 +19,7 @@ const sizeMap = { sm: 64, md: 88, lg: 112 }
const fontMap = { sm: 28, md: 36, lg: 48 }
const iconStyle = computed(() => ({
- background: props.bgColor || (props.color + '15'),
+ background: props.selected ? '#FFE8E0' : (props.bgColor || (props.color + '15')),
width: (sizeMap[props.size || 'md']) + 'rpx',
height: (sizeMap[props.size || 'md']) + 'rpx',
}))
@@ -43,6 +43,5 @@ const fontSize = computed(() => (fontMap[props.size || 'md']) + 'rpx')
.selected {
border-color: #FF8C69;
- background: #FFE8E0 !important;
}
diff --git a/client/src/components/ChartWrapper/ChartWrapper.vue b/client/src/components/ChartWrapper/ChartWrapper.vue
index 0c99479..08d2fee 100644
--- a/client/src/components/ChartWrapper/ChartWrapper.vue
+++ b/client/src/components/ChartWrapper/ChartWrapper.vue
@@ -53,7 +53,7 @@ function buildConfig(ctx: any, canvas2d: boolean, cssWidth: number, cssHeight: n
height: cssHeight,
animation: true,
background: '#FFFFFF',
- padding: [20, 20, 20, 20],
+ padding: [10, 10, 10, 10],
fontSize: 10,
fontColor: '#8B7E7E',
title: { show: false },
diff --git a/client/src/components/Skeleton/Skeleton.vue b/client/src/components/Skeleton/Skeleton.vue
index ef1e1f2..16911c8 100644
--- a/client/src/components/Skeleton/Skeleton.vue
+++ b/client/src/components/Skeleton/Skeleton.vue
@@ -37,4 +37,10 @@ const style = computed(() => ({
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
+
+@media (prefers-reduced-motion: reduce) {
+ .skeleton {
+ animation: none;
+ }
+}
diff --git a/client/src/components/TransactionItem/TransactionItem.vue b/client/src/components/TransactionItem/TransactionItem.vue
index ab56da3..a561384 100644
--- a/client/src/components/TransactionItem/TransactionItem.vue
+++ b/client/src/components/TransactionItem/TransactionItem.vue
@@ -8,7 +8,13 @@
@touchmove="!disableSwipe && onTouchMove($event)"
@touchend="!disableSwipe && onTouchEnd()"
>
+
+
+
+ {{ item.creator_nickname?.[0] }}
+
{{ item.note || item.category_name || '未分类' }}
- {{ item.category_name || '未分类' }}{{ hideDate ? '' : ' · ' + formatDate(item.date) }}
+
+ {{ item.creator_nickname }} ·
+ {{ item.category_name || '未分类' }}{{ hideDate ? '' : ' · ' + formatDate(item.date) }}
+
{{ item.type === 'expense' ? '-' : '+' }}{{ formatAmount(item.amount) }}
@@ -27,14 +36,16 @@