forked from gxwebsoft/mp-10550
feat(user): 添加用户卡片统计数据接口和优化性能
- 新增 UserCardStats 接口定义余额/积分/优惠券/礼品卡数据结构 - 实现 getUserCardStats 函数聚合返回用户卡片统计数据 - 替换原有多个独立请求为单一聚合接口提升性能 - 修改 useUserData Hook 使用新聚合接口并调整数据类型 - 移除废弃的 pageShopOrder 和相关 API 导入 - 优化用户登录后自动刷新卡片统计数据逻辑
This commit is contained in:
@@ -43,6 +43,15 @@ export interface UserOrderStats {
|
|||||||
total: number
|
total: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用户卡片统计(个人中心头部:余额/积分/优惠券/礼品卡)
|
||||||
|
export interface UserCardStats {
|
||||||
|
balance: string
|
||||||
|
points: number
|
||||||
|
coupons: number
|
||||||
|
giftCards: number
|
||||||
|
lastUpdateTime?: string
|
||||||
|
}
|
||||||
|
|
||||||
// 用户完整数据
|
// 用户完整数据
|
||||||
export interface UserDashboard {
|
export interface UserDashboard {
|
||||||
balance: UserBalance
|
balance: UserBalance
|
||||||
@@ -108,6 +117,17 @@ export async function getUserOrderStats() {
|
|||||||
return Promise.reject(new Error(res.message))
|
return Promise.reject(new Error(res.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户卡片统计(一次性返回余额/积分/可用优惠券/未使用礼品卡数量)
|
||||||
|
*/
|
||||||
|
export async function getUserCardStats() {
|
||||||
|
const res = await request.get<ApiResult<UserCardStats>>('/user/card/stats')
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户完整仪表板数据(一次性获取所有数据)
|
* 获取用户完整仪表板数据(一次性获取所有数据)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { UserOrderStats } from '@/api/user';
|
import { getUserOrderStats, UserOrderStats } from '@/api/user';
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import {pageShopOrder} from "@/api/shop/shopOrder";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单统计Hook
|
* 订单统计Hook
|
||||||
@@ -31,20 +30,17 @@ export const useOrderStats = () => {
|
|||||||
if(!Taro.getStorageSync('UserId')){
|
if(!Taro.getStorageSync('UserId')){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO 读取订单数量
|
|
||||||
const pending = await pageShopOrder({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), statusFilter: 0})
|
// 聚合接口:一次请求返回各状态数量(后台按用户做了缓存)
|
||||||
const paid = await pageShopOrder({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), statusFilter: 1})
|
const stats = await getUserOrderStats();
|
||||||
const shipped = await pageShopOrder({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), statusFilter: 3})
|
|
||||||
const completed = await pageShopOrder({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), statusFilter: 5})
|
|
||||||
const refund = await pageShopOrder({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), statusFilter: 6})
|
|
||||||
const total = await pageShopOrder({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId')})
|
|
||||||
setOrderStats({
|
setOrderStats({
|
||||||
pending: pending?.count || 0,
|
pending: stats?.pending || 0,
|
||||||
paid: paid?.count || 0,
|
paid: stats?.paid || 0,
|
||||||
shipped: shipped?.count || 0,
|
shipped: stats?.shipped || 0,
|
||||||
completed: completed?.count || 0,
|
completed: stats?.completed || 0,
|
||||||
refund: refund?.count || 0,
|
refund: stats?.refund || 0,
|
||||||
total: total?.count || 0
|
total: stats?.total || 0
|
||||||
})
|
})
|
||||||
|
|
||||||
if (showToast) {
|
if (showToast) {
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react'
|
import { useState, useEffect, useCallback } from 'react'
|
||||||
import {pageShopUserCoupon} from "@/api/shop/shopUserCoupon";
|
|
||||||
import {pageShopGift} from "@/api/shop/shopGift";
|
|
||||||
import {useUser} from "@/hooks/useUser";
|
import {useUser} from "@/hooks/useUser";
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import {getUserInfo} from "@/api/layout";
|
import { getUserCardStats } from '@/api/user'
|
||||||
|
|
||||||
interface UserData {
|
interface UserData {
|
||||||
balance: number
|
balance: string
|
||||||
points: number
|
points: number
|
||||||
coupons: number
|
coupons: number
|
||||||
giftCards: number
|
giftCards: number
|
||||||
@@ -24,7 +22,7 @@ interface UseUserDataReturn {
|
|||||||
loading: boolean
|
loading: boolean
|
||||||
error: string | null
|
error: string | null
|
||||||
refresh: () => Promise<void>
|
refresh: () => Promise<void>
|
||||||
updateBalance: (newBalance: number) => void
|
updateBalance: (newBalance: string) => void
|
||||||
updatePoints: (newPoints: number) => void
|
updatePoints: (newPoints: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,18 +41,14 @@ export const useUserData = (): UseUserDataReturn => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 并发请求所有数据
|
// 聚合接口:一次请求返回余额/积分/优惠券/礼品卡统计(后端可按用户做缓存)
|
||||||
const [userDataRes, couponsRes, giftCardsRes] = await Promise.all([
|
const stats = await getUserCardStats()
|
||||||
getUserInfo(),
|
|
||||||
pageShopUserCoupon({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), status: 0}),
|
|
||||||
pageShopGift({ page: 1, limit: 1, userId: Taro.getStorageSync('UserId'), status: 0})
|
|
||||||
])
|
|
||||||
|
|
||||||
const newData: UserData = {
|
const newData: UserData = {
|
||||||
balance: userDataRes?.balance || 0.00,
|
balance: stats?.balance || '0.00',
|
||||||
points: userDataRes?.points || 0,
|
points: stats?.points || 0,
|
||||||
coupons: couponsRes?.count || 0,
|
coupons: stats?.coupons || 0,
|
||||||
giftCards: giftCardsRes?.count || 0,
|
giftCards: stats?.giftCards || 0,
|
||||||
orders: {
|
orders: {
|
||||||
pending: 0,
|
pending: 0,
|
||||||
paid: 0,
|
paid: 0,
|
||||||
@@ -78,7 +72,7 @@ export const useUserData = (): UseUserDataReturn => {
|
|||||||
}, [fetchUserData])
|
}, [fetchUserData])
|
||||||
|
|
||||||
// 更新余额(本地更新,避免频繁请求)
|
// 更新余额(本地更新,避免频繁请求)
|
||||||
const updateBalance = useCallback((newBalance: number) => {
|
const updateBalance = useCallback((newBalance: string) => {
|
||||||
setData(prev => prev ? { ...prev, balance: newBalance } : null)
|
setData(prev => prev ? { ...prev, balance: newBalance } : null)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ const UserCard = forwardRef<any, any>((_, ref) => {
|
|||||||
setUserInfo(data)
|
setUserInfo(data)
|
||||||
setIsLogin(true);
|
setIsLogin(true);
|
||||||
Taro.setStorageSync('UserId', data.userId)
|
Taro.setStorageSync('UserId', data.userId)
|
||||||
|
// 登录态已就绪后刷新卡片统计(余额/积分/券/礼品卡)
|
||||||
|
refresh().then()
|
||||||
|
|
||||||
// 获取openId
|
// 获取openId
|
||||||
if (!data.openid) {
|
if (!data.openid) {
|
||||||
@@ -162,6 +164,8 @@ const UserCard = forwardRef<any, any>((_, ref) => {
|
|||||||
Taro.setStorageSync('UserId', res.data.data.user.userId)
|
Taro.setStorageSync('UserId', res.data.data.user.userId)
|
||||||
setUserInfo(res.data.data.user)
|
setUserInfo(res.data.data.user)
|
||||||
setIsLogin(true)
|
setIsLogin(true)
|
||||||
|
// 登录态已就绪后刷新卡片统计(余额/积分/券/礼品卡)
|
||||||
|
refresh().then()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {PullToRefresh} from '@nutui/nutui-react-taro'
|
|||||||
import UserCard from "./components/UserCard";
|
import UserCard from "./components/UserCard";
|
||||||
import UserOrder from "./components/UserOrder";
|
import UserOrder from "./components/UserOrder";
|
||||||
import UserFooter from "./components/UserFooter";
|
import UserFooter from "./components/UserFooter";
|
||||||
import {useUserData} from "@/hooks/useUserData";
|
|
||||||
import {View} from '@tarojs/components';
|
import {View} from '@tarojs/components';
|
||||||
import './user.scss'
|
import './user.scss'
|
||||||
import IsDealer from "./components/IsDealer";
|
import IsDealer from "./components/IsDealer";
|
||||||
@@ -12,14 +11,11 @@ import UserGrid from "@/pages/user/components/UserGrid";
|
|||||||
|
|
||||||
function User() {
|
function User() {
|
||||||
|
|
||||||
const {refresh} = useUserData()
|
|
||||||
const userCardRef = useRef<any>()
|
const userCardRef = useRef<any>()
|
||||||
const themeStyles = useThemeStyles();
|
const themeStyles = useThemeStyles();
|
||||||
|
|
||||||
// 下拉刷新处理
|
// 下拉刷新处理
|
||||||
const handleRefresh = async () => {
|
const handleRefresh = async () => {
|
||||||
await refresh()
|
|
||||||
// 如果 UserCard 组件有自己的刷新方法,也可以调用
|
|
||||||
if (userCardRef.current?.handleRefresh) {
|
if (userCardRef.current?.handleRefresh) {
|
||||||
await userCardRef.current.handleRefresh()
|
await userCardRef.current.handleRefresh()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user