fix(order): 修复订单与用户页面登录校验和跳转逻辑

- 订单列表页未登录时弹出登录引导弹窗,而非直接跳转
- 登录页登录成功添加订单列表为白名单,支持登录后回跳订单页
- 我的页面菜单和订单按钮未登录时增加登录弹窗拦截
- 需登录菜单项添加 requireAuth 标记并视觉降级为半透明
- 订单快捷入口增加登录拦截和登录后回跳逻辑
- 修改“联系电话”为新号码,更新联系信息
This commit is contained in:
2026-07-14 01:48:12 +08:00
parent fd03ed80fd
commit 596fa27d60
5 changed files with 57 additions and 15 deletions

View File

@@ -112,7 +112,22 @@ adapter `/list` 接口忽略分页,一次返回全部收藏;前端 `listShop
页面缺少登录校验——`useEffect` 直接调用 `loadOrders`,未登录时 `user?.userId``undefined`,后端未按用户过滤直接返回了订单。 页面缺少登录校验——`useEffect` 直接调用 `loadOrders`,未登录时 `user?.userId``undefined`,后端未按用户过滤直接返回了订单。
### 修改 ### 修改
- **`src/pages/order/list.tsx`**采用项目标准模式 A与 commission.tsx 等页面一致): - **`src/pages/order/list.tsx`**
1.`useUser()` 获取 `isLoggedIn` 1.`useUser()` 获取 `isLoggedIn`
2. `useEffect``if (!isLoggedIn)` 守卫 → `Taro.navigateTo('/passport/login')` + return 2. `useEffect`未登录时调用 `requireLogin({ action: 'viewOrder', redirect: '/pages/order/list', content: '登录后才能查看订单,是否前往登录?' })` 弹窗引导,而不是直接跳转
3. render 中 `if (!isLoggedIn) return null` 3. render 中 `if (!isLoggedIn) return null` 兜底,避免未登录时渲染订单内容
- **`src/passport/login.tsx`**:登录成功后的 `tabBarUrls` 白名单补全 `pages/order/list`,确保从订单入口登录后能 `switchTab` 回订单页
## 我的页面未登录可点击需登录功能 Bug 修复2026-07-14
### 问题
`pages/user/user` 未登录时,点击「我的订单」下的按钮(待付款/待发货/待收货/已完成、「全部订单」、以及菜单中的「升级VIP会员」「我的钱包」「收货地址」「我的收藏」都能直接跳转页面。
### 修改
- **`src/pages/user/user.tsx`**
1. 导入 `requireLogin` from `@/utils/login-guard`
2. 给需要登录的菜单项加 `requireAuth: true` 标记升级VIP会员/门店中心/我的钱包/收货地址/我的收藏)
3. 新增 `handleMenuClick(item)``requireAuth` 项调用 `requireLogin` 弹窗拦截,已登录才 `navigateTo`
4. 新增 `handleOrderTabClick(status)``handleViewAllOrders()`:订单入口 `requireLogin` 拦截,并加 `redirect: '/pages/order/list'` 让登录后回跳订单页
5. 未登录时需登录的菜单项和订单按钮加 `opacity-50` 视觉降级
6. 「帮助中心」「设置」不需要登录,保持原样

View File

@@ -8,6 +8,7 @@ import { OrderListStatus, OrderListTabText } from '@/types/order'
import OrderCard from '@/components/common/OrderCard' import OrderCard from '@/components/common/OrderCard'
import EmptyState from '@/components/common/EmptyState' import EmptyState from '@/components/common/EmptyState'
import LoadMore from '@/components/common/LoadMore' import LoadMore from '@/components/common/LoadMore'
import { requireLogin } from '@/utils/login-guard'
definePageConfig({ definePageConfig({
navigationBarTitleText: '我的订单', navigationBarTitleText: '我的订单',
@@ -105,7 +106,7 @@ const OrderListPage: React.FC = () => {
// 切换 tab 时加载数据 // 切换 tab 时加载数据
useEffect(() => { useEffect(() => {
if (!isLoggedIn) { if (!isLoggedIn) {
Taro.navigateTo({ url: '/passport/login' }) requireLogin({ action: 'viewOrder', redirect: '/pages/order/list', content: '登录后才能查看订单,是否前往登录?' })
return return
} }
if (!tabStates[tabIndex].initialized) { if (!tabStates[tabIndex].initialized) {

View File

@@ -62,7 +62,7 @@ const AboutPage: React.FC = () => {
{[ {[
{ label: '经营部名称', value: '玉林市玉州区鑫龙家电经营部' }, { label: '经营部名称', value: '玉林市玉州区鑫龙家电经营部' },
{ label: '经营地址', value: '大新里南718号' }, { label: '经营地址', value: '大新里南718号' },
{ label: '联系电话', value: '13260472256' }, { label: '联系电话', value: '18269229683' },
{ label: '营业时间', value: '9:00 ~ 18:00' }, { label: '营业时间', value: '9:00 ~ 18:00' },
].map((item, idx) => ( ].map((item, idx) => (
<View key={idx} className='flex items-start justify-between'> <View key={idx} className='flex items-start justify-between'>

View File

@@ -9,6 +9,7 @@ import { getMyClerk } from '@/api/shop/shopStoreUser'
import { listUserRole } from '@/api/system/userRole' import { listUserRole } from '@/api/system/userRole'
import type { UserRole } from '@/api/system/userRole/model' import type { UserRole } from '@/api/system/userRole/model'
import { checkAndCacheVipStatus } from '@/utils/vip' import { checkAndCacheVipStatus } from '@/utils/vip'
import { requireLogin } from '@/utils/login-guard'
import MemberBadge from '@/components/business/MemberBadge' import MemberBadge from '@/components/business/MemberBadge'
const UserPage: React.FC = () => { const UserPage: React.FC = () => {
@@ -98,13 +99,13 @@ const UserPage: React.FC = () => {
const menuItems = [ const menuItems = [
// 升级VIP会员 - 醒目样式 // 升级VIP会员 - 醒目样式
{ icon: '👑', label: '升级VIP会员', url: '/pages/user/vip-upgrade/index', highlight: true }, { icon: '👑', label: '升级VIP会员', url: '/pages/user/vip-upgrade/index', highlight: true, requireAuth: true },
// 门店中心:仅门店店员/店长显示(通过 /shop/shop-store-user/my 判断) // 门店中心:仅门店店员/店长显示(通过 /shop/shop-store-user/my 判断)
...(storeInfo ? [{ icon: '🏪', label: '门店中心', url: '/pages/store/center/index' }] : []), ...(storeInfo ? [{ icon: '🏪', label: '门店中心', url: '/pages/store/center/index', requireAuth: true }] : []),
{ icon: '💰', label: '我的钱包', url: '/pages/user/wallet' }, { icon: '💰', label: '我的钱包', url: '/pages/user/wallet', requireAuth: true },
{ icon: '📍', label: '收货地址', url: '/pages/user/address-list' }, { icon: '📍', label: '收货地址', url: '/pages/user/address-list', requireAuth: true },
// { icon: '⭐', label: '积分明细', url: '/pages/user/points-record' }, // { icon: '⭐', label: '积分明细', url: '/pages/user/points-record' },
{ icon: '❤️', label: '我的收藏', url: '/pages/user/favorite-list/index' }, { icon: '❤️', label: '我的收藏', url: '/pages/user/favorite-list/index', requireAuth: true },
// { icon: '🕐', label: '浏览历史', url: '/pages/user/history-list/index' }, // { icon: '🕐', label: '浏览历史', url: '/pages/user/history-list/index' },
{ icon: '❓', label: '帮助中心', url: '/pages/user/help-center/index' }, { icon: '❓', label: '帮助中心', url: '/pages/user/help-center/index' },
// { icon: '🔔', label: '消息通知', url: '/pages/index/notification' }, // { icon: '🔔', label: '消息通知', url: '/pages/index/notification' },
@@ -121,6 +122,30 @@ const UserPage: React.FC = () => {
} }
} }
// 菜单项点击:需要登录的功能先拦截
const handleMenuClick = (item: typeof menuItems[number]) => {
if ((item as any).requireAuth) {
if (!requireLogin({
action: 'viewOrder',
redirect: item.url,
content: `登录后才能使用「${item.label}」功能,是否前往登录?`
})) return
}
Taro.navigateTo({ url: item.url })
}
// 订单快捷入口点击:需要登录
const handleOrderTabClick = (status: number) => {
if (!requireLogin({ action: 'viewOrder', redirect: '/pages/order/list', content: '登录后才能查看订单,是否前往登录?' })) return
Taro.setStorageSync('order_tab', status)
Taro.switchTab({ url: '/pages/order/list' })
}
const handleViewAllOrders = () => {
if (!requireLogin({ action: 'viewOrder', redirect: '/pages/order/list', content: '登录后才能查看订单,是否前往登录?' })) return
Taro.switchTab({ url: '/pages/order/list' })
}
const loading = cardStatsLoading || orderStatsLoading const loading = cardStatsLoading || orderStatsLoading
// 是否有可用数据(缓存或请求结果),用于判断是否需要骨架屏 // 是否有可用数据(缓存或请求结果),用于判断是否需要骨架屏
@@ -232,7 +257,7 @@ const UserPage: React.FC = () => {
<View className='bg-white rounded-xl mx-3 mt-3 p-4'> <View className='bg-white rounded-xl mx-3 mt-3 p-4'>
<View className='flex justify-between items-center mb-3'> <View className='flex justify-between items-center mb-3'>
<Text className='text-base font-medium text-gray-800'></Text> <Text className='text-base font-medium text-gray-800'></Text>
<Text className='text-xs text-gray-400' onClick={() => Taro.switchTab({ url: '/pages/order/list' })}> <Text className='text-xs text-gray-400' onClick={handleViewAllOrders}>
{'>'} {'>'}
</Text> </Text>
</View> </View>
@@ -245,8 +270,8 @@ const UserPage: React.FC = () => {
].map(item => ( ].map(item => (
<View <View
key={item.status} key={item.status}
className='flex flex-col items-center py-2 relative' className={`flex flex-col items-center py-2 relative ${!isLoggedIn ? 'opacity-50' : ''}`}
onClick={() => { Taro.setStorageSync('order_tab', item.status); Taro.switchTab({ url: '/pages/order/list' }) }} onClick={() => handleOrderTabClick(item.status)}
> >
<Text className='text-xl mb-1'>{item.icon}</Text> <Text className='text-xl mb-1'>{item.icon}</Text>
<Text className='text-xs text-gray-600'>{item.label}</Text> <Text className='text-xs text-gray-600'>{item.label}</Text>
@@ -267,11 +292,11 @@ const UserPage: React.FC = () => {
key={item.label} key={item.label}
className={`flex items-center justify-between px-4 py-3 ${ className={`flex items-center justify-between px-4 py-3 ${
idx < menuItems.length - 1 ? 'border-b border-gray-50' : '' idx < menuItems.length - 1 ? 'border-b border-gray-50' : ''
} ${(item as any).highlight ? '' : ''}`} } ${(item as any).highlight ? '' : ''} ${!isLoggedIn && (item as any).requireAuth ? 'opacity-50' : ''}`}
style={(item as any).highlight ? { style={(item as any).highlight ? {
background: 'linear-gradient(135deg, #fef3c7 0%, #fde68a 100%)', background: 'linear-gradient(135deg, #fef3c7 0%, #fde68a 100%)',
} : {}} } : {}}
onClick={() => Taro.navigateTo({ url: item.url })} onClick={() => handleMenuClick(item)}
> >
<View className='flex items-center gap-3'> <View className='flex items-center gap-3'>
<View className={`${(item as any).highlight ? 'w-8 h-8 rounded-lg flex items-center justify-center text-lg' : ''}`} style={(item as any).highlight ? { background: 'linear-gradient(135deg, #f59e0b, #d97706)' } : {}}> <View className={`${(item as any).highlight ? 'w-8 h-8 rounded-lg flex items-center justify-center text-lg' : ''}`} style={(item as any).highlight ? { background: 'linear-gradient(135deg, #f59e0b, #d97706)' } : {}}>

View File

@@ -145,6 +145,7 @@ const Login = () => {
'/pages/shop/index', '/pages/shop/index',
'/pages/points/index', '/pages/points/index',
'/pages/user/user', '/pages/user/user',
'/pages/order/list',
] ]
const pure = redirectUrl.split('?')[0] const pure = redirectUrl.split('?')[0]