refactor(user): 优化用户权限检查和界面显示逻辑
- 移除邀请人ID表单项并注释相关代码 - 注释掉邀请信息检测成功提示弹窗功能 - 在开发、生产、测试环境中添加本地API调试配置选项 - 添加分销商角色权限检查,非分销商无法查看客户列表 - 使用useRef避免重复显示无权限提示 - 在客户列表页面添加权限验证和加载状态处理 - 移除用户卡片中的余额、积分、优惠券、礼品卡等显示组件 - 简化用户角色名称获取逻辑,优先使用用户角色数组第一个角色名称 - 优化用户信息加载和权限验证流程
This commit is contained in:
@@ -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',
|
||||
}
|
||||
|
||||
14
src/app.ts
14
src/app.ts
@@ -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('❌ 未检测到邀请参数')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
{/* 搜索栏 */}
|
||||
|
||||
@@ -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 '超级管理员';
|
||||
}
|
||||
if(hasRole('admin')){
|
||||
return '管理员';
|
||||
}
|
||||
if(hasRole('staff')){
|
||||
return '员工';
|
||||
}
|
||||
if(hasRole('vip')){
|
||||
return 'VIP会员';
|
||||
}
|
||||
return '注册用户';
|
||||
return userInfo?.roles?.[0]?.roleName || userInfo?.roleName || '业务员'
|
||||
}
|
||||
|
||||
// 检查用户是否已实名认证
|
||||
const isCertified = () => {
|
||||
return user?.certification === true;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user