fix(user): 修复用户页面组件状态刷新和水票余额显示问题

- 在订单确认页面添加水票模板购买数量限制逻辑
- 为用户页面添加dealerViewKey状态确保子组件正确刷新
- 交换用户卡片中水票和余额的位置显示正确数据
- 移除自动跳转邀请注册页面逻辑改用显式跳转
- 添加预期失败场景的日志过滤避免不必要的错误输出
This commit is contained in:
2026-02-28 20:28:18 +08:00
parent 64d30e1b62
commit ab61aa9ee0
4 changed files with 40 additions and 34 deletions

View File

@@ -3,7 +3,7 @@ import Taro from '@tarojs/taro';
import { User } from '@/api/system/user/model';
import { getUserInfo, updateUserInfo, loginByOpenId } from '@/api/layout';
import { TenantId } from '@/config/app';
import {getStoredInviteParams, handleInviteRelation} from '@/utils/invite';
import { handleInviteRelation } from '@/utils/invite';
// 用户Hook
export const useUser = () => {
@@ -44,15 +44,10 @@ export const useUser = () => {
reject(new Error('自动登录失败'));
}
}).catch(_ => {
// 首次注册,跳转到邀请注册页面
const pages = Taro.getCurrentPages();
const currentPage = pages[pages.length - 1];
const inviteParams = getStoredInviteParams()
if (currentPage?.route !== 'dealer/apply/add' && inviteParams?.inviter) {
return Taro.navigateTo({
url: '/dealer/apply/add'
});
}
// 登录失败(通常是新用户尚未注册/未绑定手机号等)。
// 这里不做任何“自动跳转”,避免用户点击「我的」时被强制带到分销/申请页,体验割裂。
// 需要登录的页面请使用 utils/auth 的 ensureLoggedIn / goToRegister 做显式跳转。
reject(new Error('autoLoginByOpenId failed'));
});
},
fail: reject
@@ -60,7 +55,11 @@ export const useUser = () => {
});
return res;
} catch (error) {
console.error('自动登录失败:', error);
const msg = error instanceof Error ? error.message : String(error);
// 新用户首次进入、未绑定手机号等场景属于“预期失败”,避免刷屏报错。
if (msg !== 'autoLoginByOpenId failed') {
console.error('自动登录失败:', error);
}
return null;
}
};

View File

@@ -335,13 +335,9 @@ const UserCard = forwardRef<any, any>((_, ref) => {
<View className={'py-2'}>
<View className={'flex justify-around mt-1'}>
<View className={'item flex justify-center flex-col items-center'}
onClick={() => navTo('/user/wallet/wallet', true)}>
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}></Text>
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.balance || '0.00'}</Text>
</View>
<View className={'item flex justify-center flex-col items-center'}>
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}></Text>
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.points || 0}</Text>
onClick={() => navTo('/user/ticket/index', true)}>
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}></Text>
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{ticketTotal}</Text>
</View>
<View className={'item flex justify-center flex-col items-center'}
onClick={() => navTo('/user/coupon/index', true)}>
@@ -349,9 +345,13 @@ const UserCard = forwardRef<any, any>((_, ref) => {
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.coupons || 0}</Text>
</View>
<View className={'item flex justify-center flex-col items-center'}
onClick={() => navTo('/user/ticket/index', true)}>
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}></Text>
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{ticketTotal}</Text>
onClick={() => navTo('/user/wallet/wallet', true)}>
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}></Text>
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.balance || '0.00'}</Text>
</View>
<View className={'item flex justify-center flex-col items-center'}>
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}></Text>
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.points || 0}</Text>
</View>
</View>
</View>

View File

@@ -1,4 +1,4 @@
import {useEffect, useRef} from 'react'
import {useEffect, useRef, useState} from 'react'
import {PullToRefresh} from '@nutui/nutui-react-taro'
import UserCard from "./components/UserCard";
import UserOrder from "./components/UserOrder";
@@ -14,12 +14,15 @@ function User() {
const userCardRef = useRef<any>()
const themeStyles = useThemeStyles();
// TabBar 页在小程序里通常不会销毁;从“注册/申请”页返回时需要触发子组件重新初始化/拉取最新状态。
const [dealerViewKey, setDealerViewKey] = useState(0)
// 下拉刷新处理
const handleRefresh = async () => {
if (userCardRef.current?.handleRefresh) {
await userCardRef.current.handleRefresh()
}
setDealerViewKey(v => v + 1)
}
useEffect(() => {
@@ -30,6 +33,7 @@ function User() {
userCardRef.current?.reloadStats?.()
// 个人资料(头像/昵称)可能在其它页面被修改,这里确保返回时立刻刷新
userCardRef.current?.reloadUserInfo?.()
setDealerViewKey(v => v + 1)
})
return (
@@ -58,7 +62,7 @@ function User() {
</View>
<UserCard ref={userCardRef}/>
<UserOrder/>
<IsDealer/>
<IsDealer key={dealerViewKey}/>
<UserGrid/>
<UserFooter/>
</PullToRefresh>

View File

@@ -853,17 +853,20 @@ const OrderConfirm = () => {
<View className={'flex justify-between items-center'}>
<Text className={'text-red-500'}>{goods.price}</Text>
<View className={'flex flex-col items-end gap-1'}>
<ConfigProvider theme={customTheme}>
<InputNumber
value={quantity}
min={isTicketTemplateActive ? minBuyQty : 1}
max={goods.stock || 999}
step={10}
readOnly
disabled={((goods.canBuyNumber ?? 0) !== 0) && !isTicketTemplateActive}
onChange={handleQuantityChange}
/>
</ConfigProvider>
<ConfigProvider theme={customTheme}>
<InputNumber
value={quantity}
min={isTicketTemplateActive ? minBuyQty : 1}
max={goods.stock || 999}
step={10}
readOnly
disabled={
(((goods.canBuyNumber ?? 0) !== 0) && !isTicketTemplateActive) ||
(isTicketTemplateActive && minBuyQty === 1)
}
onChange={handleQuantityChange}
/>
</ConfigProvider>
{goods.stock !== undefined && (
<Text className={'text-xs text-gray-400'}>
{goods.stock}