fix(user): 修复「我的」页订单数量统计显示为 0 的问题

- 修正 UserOrderStats 接口字段与后端 DTO 完全对齐
- getUserOrderStats() 读取后端真实字段,数值使用 Number(x) 兜底
- 「我的订单」快捷入口 count 和 status 与 OrderListStatus 枚举对齐
- localStorage 缓存 key 升级至 v3,避免旧缓存干扰冷启动渲染
- 保证所有跳转订单列表的入口传递正确 status 参数,防止跳转错误的 tab
This commit is contained in:
2026-07-15 22:52:08 +08:00
parent 501e79eed7
commit ad616943c8
4 changed files with 58 additions and 18 deletions

View File

@@ -265,3 +265,16 @@
- 注意:宽度仍由容器 `w-full` + `mx-3` 边距控制,不直接套用后台 `width` 像素值;高度按比例缩放适配不同屏幕 - 注意:宽度仍由容器 `w-full` + `mx-3` 边距控制,不直接套用后台 `width` 像素值;高度按比例缩放适配不同屏幕
## 修复「我的」页订单数量统计全为 0 的 bug
- 文件:`src/api/shop/shopUserCard/index.ts``src/api/shop/shopUserCard/model/index.ts``src/pages/user/user.tsx`
- 根因:前后端字段名不匹配
- 后端 `/api/user/orders/stats` 返回 `UserOrderStats` DTO 字段:`total/waitPay/waitDeliver/waitVerify/waitReceive/waitComment/completed/refund/deleted/canceled`(参见 `com.gxwebsoft.shop.dto.UserOrderStats`
- 前端 `getUserOrderStats()` 却读取 `pending/paid/shipped/completed`,导致 `pending/paid/shipped` 永远 undefined → 兜底为 0只有 `completed` 字段名巧合一致才有数
- 附带 buguser.tsx「我的订单」快捷入口的 `status` 值写的是 0/1/2/3`OrderListStatus`0待付款 1待发货 3待收货 5已完成不一致点击「待收货」「已完成」会跳到订单列表页错误的 tab
- 修复:
1. `UserOrderStats` 接口字段与后端 DTO 完全对齐(含 total/waitPay/waitDeliver/waitVerify/waitReceive/waitComment/completed/refund/deleted/canceled
2. `getUserOrderStats()` 改读后端真实字段,并用 `Number(d.x) || 0` 兜底
3. user.tsx 订单快捷入口 count 改用 `waitPay/waitDeliver/waitReceive/completed`status 改为 `0/1/3/5``OrderListStatus` 对齐
4. localStorage 缓存 key 从 `user_order_stats_v2` 升级到 `v3`,让旧格式缓存自动失效,避免冷启动先渲染旧格式导致仍是 0
- 关键约定:`OrderListStatus` 是前端订单 Tab 筛选状态的唯一真相源(-1全部/0待付款/1待发货/2待核销/3待收货/4待评价/5已完成/6退款/7已删除所有跳订单列表的入口传 status 都要对齐它

View File

@@ -33,25 +33,39 @@ export async function getUserCardStats(): Promise<UserCardStats> {
/** /**
* 获取用户订单统计 * 获取用户订单统计
* 后端接口:/api/user/orders/stats60s 缓存) * 后端接口:/api/user/orders/stats60s 缓存)
* 字段与后端 UserOrderStats DTO 对齐waitPay/waitDeliver/waitReceive/completed 等
*/ */
export async function getUserOrderStats(): Promise<UserOrderStats> { export async function getUserOrderStats(): Promise<UserOrderStats> {
try { try {
const res = await request.get<ApiResult<any>>('/user/orders/stats') const res = await request.get<ApiResult<any>>('/user/orders/stats')
if (res.code === 0 && res.data) { if (res.code === 0 && res.data) {
const d = res.data
return { return {
pending: res.data.pending || 0, total: Number(d.total) || 0,
paid: res.data.paid || 0, waitPay: Number(d.waitPay) || 0,
shipped: res.data.shipped || 0, waitDeliver: Number(d.waitDeliver) || 0,
completed: res.data.completed || 0, waitVerify: Number(d.waitVerify) || 0,
waitReceive: Number(d.waitReceive) || 0,
waitComment: Number(d.waitComment) || 0,
completed: Number(d.completed) || 0,
refund: Number(d.refund) || 0,
deleted: Number(d.deleted) || 0,
canceled: Number(d.canceled) || 0,
} }
} }
} catch (e) { } catch (e) {
console.error('获取订单统计失败:', e) console.error('获取订单统计失败:', e)
} }
return { return {
pending: 0, total: 0,
paid: 0, waitPay: 0,
shipped: 0, waitDeliver: 0,
waitVerify: 0,
waitReceive: 0,
waitComment: 0,
completed: 0, completed: 0,
refund: 0,
deleted: 0,
canceled: 0,
} }
} }

View File

@@ -9,9 +9,20 @@ export interface UserCardStats {
giftCards: number giftCards: number
} }
/**
* 用户订单状态数量统计
* 字段与后端 com.gxwebsoft.shop.dto.UserOrderStats 对齐
* statusFilter-1全部 0待支付 1待发货 2待核销 3待收货 4待评价 5已完成 6退款 7已删除 8已取消
*/
export interface UserOrderStats { export interface UserOrderStats {
pending: number // 待付款 total: number // 全部(不含已取消)
paid: number // 待发货 waitPay: number // 待付款statusFilter=0
shipped: number // 待收货 waitDeliver: number // 待发货statusFilter=1
completed: number // 已完成 waitVerify: number // 待核销statusFilter=2
waitReceive: number // 待收货statusFilter=3
waitComment: number // 待评价statusFilter=4
completed: number // 已完成statusFilter=5
refund: number // 退款/售后statusFilter=6
deleted: number // 已删除statusFilter=7
canceled: number // 已取消statusFilter=8
} }

View File

@@ -41,7 +41,8 @@ const UserPage: React.FC = () => {
cacheKey: 'user_order_stats', cacheKey: 'user_order_stats',
cacheTime: 30 * 1000, cacheTime: 30 * 1000,
onSuccess: (data) => { onSuccess: (data) => {
Taro.setStorageSync('user_order_stats_v2', data) // v3: 字段结构变更(与后端 UserOrderStats DTO 对齐),旧版 v2 缓存自动失效
Taro.setStorageSync('user_order_stats_v3', data)
}, },
}) })
@@ -51,7 +52,7 @@ const UserPage: React.FC = () => {
// 冷启动优化:先从 localStorage 读取缓存即时展示,消除骨架屏 // 冷启动优化:先从 localStorage 读取缓存即时展示,消除骨架屏
const cachedCardStats = Taro.getStorageSync('user_card_stats_v2') const cachedCardStats = Taro.getStorageSync('user_card_stats_v2')
if (cachedCardStats) mutateCardStats(cachedCardStats) if (cachedCardStats) mutateCardStats(cachedCardStats)
const cachedOrderStats = Taro.getStorageSync('user_order_stats_v2') const cachedOrderStats = Taro.getStorageSync('user_order_stats_v3')
if (cachedOrderStats) mutateOrderStats(cachedOrderStats) if (cachedOrderStats) mutateOrderStats(cachedOrderStats)
// 然后发起网络请求stale-while-revalidate 后台刷新) // 然后发起网络请求stale-while-revalidate 后台刷新)
runCardStats() runCardStats()
@@ -78,7 +79,7 @@ const UserPage: React.FC = () => {
if (cachedCardStats) { if (cachedCardStats) {
mutateCardStats(cachedCardStats) mutateCardStats(cachedCardStats)
} }
const cachedOrderStats = Taro.getStorageSync('user_order_stats_v2') const cachedOrderStats = Taro.getStorageSync('user_order_stats_v3')
if (cachedOrderStats) { if (cachedOrderStats) {
mutateOrderStats(cachedOrderStats) mutateOrderStats(cachedOrderStats)
} }
@@ -263,10 +264,11 @@ const UserPage: React.FC = () => {
</View> </View>
<View className='grid grid-cols-4 gap-2'> <View className='grid grid-cols-4 gap-2'>
{[ {[
{ icon: '💳', label: '待付款', status: 0, count: orderStats?.pending }, // status 与 OrderListStatus 对齐0待付款 1待发货 3待收货 5已完成
{ icon: '📦', label: '待发货', status: 1, count: orderStats?.paid }, { icon: '💳', label: '待付款', status: 0, count: orderStats?.waitPay },
{ icon: '🚚', label: '待货', status: 2, count: orderStats?.shipped }, { icon: '📦', label: '待货', status: 1, count: orderStats?.waitDeliver },
{ icon: '', label: '已完成', status: 3, count: orderStats?.completed }, { icon: '🚚', label: '待收货', status: 3, count: orderStats?.waitReceive },
{ icon: '✅', label: '已完成', status: 5, count: orderStats?.completed },
].map(item => ( ].map(item => (
<View <View
key={item.status} key={item.status}