refactor(user): 优化用户权限检查和界面显示逻辑

- 移除邀请人ID表单项并注释相关代码
- 注释掉邀请信息检测成功提示弹窗功能
- 在开发、生产、测试环境中添加本地API调试配置选项
- 添加分销商角色权限检查,非分销商无法查看客户列表
- 使用useRef避免重复显示无权限提示
- 在客户列表页面添加权限验证和加载状态处理
- 移除用户卡片中的余额、积分、优惠券、礼品卡等显示组件
- 简化用户角色名称获取逻辑,优先使用用户角色数组第一个角色名称
- 优化用户信息加载和权限验证流程
This commit is contained in:
2026-02-03 16:54:09 +08:00
parent 217f3556fc
commit 07d35d48d7
6 changed files with 72 additions and 63 deletions

View File

@@ -3,18 +3,21 @@ export const ENV_CONFIG = {
// 开发环境
development: {
API_BASE_URL: 'https://cms-api.websoft.top/api',
// API_BASE_URL: 'http://127.0.0.1:9200/api',
APP_NAME: '开发环境',
DEBUG: 'true',
},
// 生产环境
production: {
API_BASE_URL: 'https://cms-api.websoft.top/api',
// API_BASE_URL: 'http://127.0.0.1:9200/api',
APP_NAME: '南南佐顿门窗',
DEBUG: 'false',
},
// 测试环境
test: {
API_BASE_URL: 'https://cms-api.websoft.top/api',
// API_BASE_URL: 'http://127.0.0.1:9200/api',
APP_NAME: '测试环境',
DEBUG: 'true',
}

View File

@@ -74,13 +74,13 @@ function App(props: { children: any; }) {
trackInviteSource(inviteParams.source || 'unknown', parseInt(inviteParams.inviter || '0'))
// 显示邀请提示
setTimeout(() => {
Taro.showToast({
title: `检测到邀请信息 ID:${inviteParams.inviter}`,
icon: 'success',
duration: 3000
})
}, 1000)
// setTimeout(() => {
// Taro.showToast({
// title: `检测到邀请信息 ID:${inviteParams.inviter}`,
// icon: 'success',
// duration: 3000
// })
// }, 1000)
} else {
console.log('❌ 未检测到邀请参数')

View File

@@ -411,9 +411,9 @@ const AddUserAddress = () => {
>
<View className={'bg-gray-100 h-3'}></View>
<CellGroup style={{padding: '4px 0'}}>
<Form.Item name="refereeId" label="邀请人ID" initialValue={FormData?.refereeId} required>
<Input placeholder="邀请人ID"/>
</Form.Item>
{/*<Form.Item name="refereeId" label="邀请人ID" initialValue={FormData?.refereeId} required>*/}
{/* <Input placeholder="邀请人ID"/>*/}
{/*</Form.Item>*/}
<Form.Item name="phone" label="手机号" initialValue={FormData?.phone} required>
<View className="flex items-center justify-between">
<Input

View File

@@ -1,4 +1,4 @@
import {useState, useEffect, useCallback} from 'react'
import {useState, useEffect, useCallback, useRef} from 'react'
import {View, Text} from '@tarojs/components'
import Taro, {useDidShow} from '@tarojs/taro'
import {Loading, InfiniteLoading, Empty, Space, Tabs, TabPane, Tag, Button, SearchBar} from '@nutui/nutui-react-taro'
@@ -16,6 +16,7 @@ import FixedButton from "@/components/FixedButton";
import navTo from "@/utils/common";
import {pageShopDealerApply, removeShopDealerApply, updateShopDealerApply} from "@/api/shop/shopDealerApply";
import {addShopDealerRecord} from "@/api/shop/shopDealerRecord";
import {useUser} from "@/hooks/useUser";
// 扩展User类型添加客户状态和保护天数
interface CustomerUser extends UserType {
@@ -32,6 +33,23 @@ const CustomerIndex = () => {
const [page, setPage] = useState(1)
const [hasMore, setHasMore] = useState(true)
// 非分销商不允许查看客户列表
const {hasRole, loading: userLoading} = useUser()
const canView = hasRole('dealer')
const roleCheckFinished = !userLoading
const noPermissionShownRef = useRef(false)
useEffect(() => {
if (!roleCheckFinished || canView) return
if (noPermissionShownRef.current) return
noPermissionShownRef.current = true
Taro.showToast({
title: '没有查看权限',
icon: 'none',
duration: 1500
})
}, [roleCheckFinished, canView])
// Tab配置
const tabList = getStatusOptions();
@@ -330,22 +348,24 @@ const CustomerIndex = () => {
})
}
// 初始化数据
// 初始化统计数据
useEffect(() => {
fetchCustomerData(activeTab, true).then();
if (!roleCheckFinished || !canView) return;
fetchStatusCounts().then();
}, []);
}, [roleCheckFinished, canView]);
// 当activeTab变化时重新获取数据
useEffect(() => {
if (!roleCheckFinished || !canView) return;
setList([]); // 清空列表
setPage(1); // 重置页码
setHasMore(true); // 重置加载状态
fetchCustomerData(activeTab, true);
}, [activeTab]);
}, [activeTab, roleCheckFinished, canView]);
// 监听页面显示,当从其他页面返回时刷新数据
useDidShow(() => {
if (!roleCheckFinished || !canView) return;
// 刷新当前tab的数据和统计信息
setList([]);
setPage(1);
@@ -543,6 +563,30 @@ const CustomerIndex = () => {
);
};
if (!roleCheckFinished) {
return (
<View className="bg-white flex items-center justify-center">
<Loading/>
<Text className="text-gray-500 ml-2">...</Text>
</View>
);
}
if (!canView) {
return (
<View className="bg-white flex flex-col items-center justify-center p-4">
<Empty description="没有查看权限"/>
<Button
size="small"
style={{marginTop: '12px'}}
onClick={() => Taro.navigateBack()}
>
</Button>
</View>
);
}
return (
<View className="min-h-screen bg-gray-50">
{/* 搜索栏 */}

View File

@@ -10,6 +10,7 @@ export const useUser = () => {
const [user, setUser] = useState<User | null>(null);
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [loading, setLoading] = useState(true);
const [userInfo] = useState<User>()
// 自动登录通过OpenID
const autoLoginByOpenId = async () => {
@@ -256,23 +257,10 @@ export const useUser = () => {
return user?.nickname || user?.realName || user?.username || '未登录';
};
// 获取用户显示的角色(同步版本)
// 角色名称:优先取用户 roles 数组的第一个角色名称
const getRoleName = () => {
if(hasRole('superAdmin')){
return '超级管理员';
return userInfo?.roles?.[0]?.roleName || userInfo?.roleName || '业务员'
}
if(hasRole('admin')){
return '管理员';
}
if(hasRole('staff')){
return '员工';
}
if(hasRole('vip')){
return 'VIP会员';
}
return '注册用户';
}
// 检查用户是否已实名认证
const isCertified = () => {
return user?.certification === true;

View File

@@ -1,6 +1,6 @@
import {Button} from '@nutui/nutui-react-taro'
import {Avatar, Tag} from '@nutui/nutui-react-taro'
import {View, Text} from '@tarojs/components'
import {Avatar} from '@nutui/nutui-react-taro'
import {View} from '@tarojs/components'
import {Scan} from '@nutui/icons-react-taro';
import {getWxOpenId} from '@/api/layout';
import Taro from '@tarojs/taro';
@@ -8,7 +8,6 @@ import {useEffect} from "react";
import navTo from "@/utils/common";
import {TenantId} from "@/config/app";
import {useUser} from "@/hooks/useUser";
import {useUserData} from "@/hooks/useUserData";
function UserCard() {
const {
@@ -17,10 +16,8 @@ function UserCard() {
isLoggedIn,
loginUser,
fetchUserInfo,
getDisplayName,
getRoleName
getDisplayName
} = useUser();
const {data} = useUserData();
useEffect(() => {
// Taro.getSetting获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
@@ -180,12 +177,10 @@ function UserCard() {
<View className={'user-info flex flex-col px-2'}>
<View className={'py-1 text-black font-bold max-w-28'}>{getDisplayName()}</View>
{isLoggedIn ? (
<View className={'grade text-xs py-1'}>
<Tag type="success" round>
<Text className={'p-1'}>
{getRoleName()}
</Text>
</Tag>
<View className={'grade text-xs py-0'}>
{/*<Text className={'p-1'}>*/}
{/* {getRoleName()}*/}
{/*</Text>*/}
</View>
) : ''}
</View>
@@ -198,27 +193,6 @@ function UserCard() {
</View>
</View>
</View>
{/*<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-sm text-gray-500'}>余额</Text>*/}
{/* <Text className={'text-xl'}>{data?.balance || '0.00'}</Text>*/}
{/* </View>*/}
{/* <View className={'item flex justify-center flex-col items-center'}>*/}
{/* <Text className={'text-sm text-gray-500'}>积分</Text>*/}
{/* <Text className={'text-xl'}>{data?.points || 0}</Text>*/}
{/* </View>*/}
{/* <View className={'item flex justify-center flex-col items-center'}*/}
{/* onClick={() => navTo('/user/coupon/index', true)}>*/}
{/* <Text className={'text-sm text-gray-500'}>优惠券</Text>*/}
{/* <Text className={'text-xl'}>{data?.coupons || 0}</Text>*/}
{/* </View>*/}
{/* <View className={'item flex justify-center flex-col items-center'}*/}
{/* onClick={() => navTo('/user/gift/index', true)}>*/}
{/* <Text className={'text-sm text-gray-500'}>礼品卡</Text>*/}
{/* <Text className={'text-xl'}>{data?.giftCards || 0}</Text>*/}
{/* </View>*/}
{/*</View>*/}
</View>
</View>
</View>