13 changed files with 920 additions and 67 deletions
@ -0,0 +1,150 @@ |
|||||
|
import {Cell} from '@nutui/nutui-react-taro' |
||||
|
import navTo from "@/utils/common"; |
||||
|
import Taro from '@tarojs/taro' |
||||
|
import {View, Text} from '@tarojs/components' |
||||
|
import {ArrowRight, ShieldCheck, LogisticsError, Location, Reward, Tips, Ask, Setting, Scan} from '@nutui/icons-react-taro' |
||||
|
import {useUser} from '@/hooks/useUser' |
||||
|
|
||||
|
const UserCell = () => { |
||||
|
const {logoutUser, isCertified, hasRole, isAdmin} = useUser(); |
||||
|
|
||||
|
const onLogout = () => { |
||||
|
Taro.showModal({ |
||||
|
title: '提示', |
||||
|
content: '确定要退出登录吗?', |
||||
|
success: function (res) { |
||||
|
if (res.confirm) { |
||||
|
// 使用 useUser hook 的 logoutUser 方法
|
||||
|
logoutUser(); |
||||
|
Taro.reLaunch({ |
||||
|
url: '/pages/index/index' |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<View className={'px-4'}> |
||||
|
<Cell.Group divider={true} description={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Text style={{marginTop: '12px'}}>我的服务</Text> |
||||
|
</View> |
||||
|
}> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Scan size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>门店核销</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/wallet/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
style={{ |
||||
|
display: 'none' |
||||
|
}} |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<LogisticsError size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>我的钱包</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/wallet/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Location size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>收货地址</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/address/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<ShieldCheck size={16} color={isCertified() ? '#52c41a' : '#666'}/> |
||||
|
<Text className={'pl-3 text-sm'}>实名认证</Text> |
||||
|
{isCertified() && ( |
||||
|
<Text className={'pl-2 text-xs text-green-500'}>已认证</Text> |
||||
|
)} |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/userVerify/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Ask size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>常见问题</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/help/index') |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Tips size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>关于我们</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/about/index') |
||||
|
}} |
||||
|
/> |
||||
|
</Cell.Group> |
||||
|
<Cell.Group divider={true} description={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Text style={{marginTop: '12px'}}>账号管理</Text> |
||||
|
</View> |
||||
|
}> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title="账号安全" |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => navTo('/user/profile/profile', true)} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title="退出登录" |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={onLogout} |
||||
|
/> |
||||
|
</Cell.Group> |
||||
|
</View> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
export default UserCell |
@ -0,0 +1,249 @@ |
|||||
|
import {Button} from '@nutui/nutui-react-taro' |
||||
|
import {Avatar, Tag} from '@nutui/nutui-react-taro' |
||||
|
import {getUserInfo, getWxOpenId} from '@/api/layout'; |
||||
|
import Taro from '@tarojs/taro'; |
||||
|
import {useEffect, useState} from "react"; |
||||
|
import {User} from "@/api/system/user/model"; |
||||
|
import navTo from "@/utils/common"; |
||||
|
import {TenantId} from "@/config/app"; |
||||
|
import {getMyAvailableCoupons} from "@/api/shop/shopUserCoupon"; |
||||
|
import {useUser} from "@/hooks/useUser"; |
||||
|
|
||||
|
function UserCard() { |
||||
|
const {getDisplayName, getRoleName} = useUser(); |
||||
|
const [IsLogin, setIsLogin] = useState<boolean>(false) |
||||
|
const [userInfo, setUserInfo] = useState<User>() |
||||
|
const [couponCount, setCouponCount] = useState(0) |
||||
|
// const [pointsCount, setPointsCount] = useState(0)
|
||||
|
const [giftCount, setGiftCount] = useState(0) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
||||
|
Taro.getSetting({ |
||||
|
success: (res) => { |
||||
|
if (res.authSetting['scope.userInfo']) { |
||||
|
// 用户已经授权过,可以直接获取用户信息
|
||||
|
console.log('用户已经授权过,可以直接获取用户信息') |
||||
|
reload(); |
||||
|
} else { |
||||
|
// 用户未授权,需要弹出授权窗口
|
||||
|
console.log('用户未授权,需要弹出授权窗口') |
||||
|
showAuthModal(); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, []); |
||||
|
|
||||
|
const loadUserStats = (userId: number) => { |
||||
|
// 加载优惠券数量
|
||||
|
getMyAvailableCoupons() |
||||
|
.then((coupons: any) => { |
||||
|
setCouponCount(coupons?.length || 0) |
||||
|
}) |
||||
|
.catch((error: any) => { |
||||
|
console.error('Coupon count error:', error) |
||||
|
}) |
||||
|
|
||||
|
// 加载积分数量
|
||||
|
console.log(userId) |
||||
|
// getUserPointsStats(userId)
|
||||
|
// .then((res: any) => {
|
||||
|
// setPointsCount(res.currentPoints || 0)
|
||||
|
// })
|
||||
|
// .catch((error: any) => {
|
||||
|
// console.error('Points stats error:', error)
|
||||
|
// })
|
||||
|
// 加载礼品劵数量
|
||||
|
setGiftCount(0) |
||||
|
// pageUserGiftLog({userId, page: 1, limit: 1}).then(res => {
|
||||
|
// setGiftCount(res.count || 0)
|
||||
|
// })
|
||||
|
} |
||||
|
|
||||
|
const reload = () => { |
||||
|
Taro.getUserInfo({ |
||||
|
success: (res) => { |
||||
|
const avatar = res.userInfo.avatarUrl; |
||||
|
setUserInfo({ |
||||
|
avatar, |
||||
|
nickname: res.userInfo.nickName, |
||||
|
sexName: res.userInfo.gender == 1 ? '男' : '女' |
||||
|
}) |
||||
|
getUserInfo().then((data) => { |
||||
|
if (data) { |
||||
|
setUserInfo(data) |
||||
|
setIsLogin(true); |
||||
|
Taro.setStorageSync('UserId', data.userId) |
||||
|
|
||||
|
// 加载用户统计数据
|
||||
|
if (data.userId) { |
||||
|
loadUserStats(data.userId) |
||||
|
} |
||||
|
|
||||
|
// 获取openId
|
||||
|
if (!data.openid) { |
||||
|
Taro.login({ |
||||
|
success: (res) => { |
||||
|
getWxOpenId({code: res.code}).then(() => { |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}).catch(() => { |
||||
|
console.log('未登录') |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const showAuthModal = () => { |
||||
|
Taro.showModal({ |
||||
|
title: '授权提示', |
||||
|
content: '需要获取您的用户信息', |
||||
|
confirmText: '去授权', |
||||
|
cancelText: '取消', |
||||
|
success: (res) => { |
||||
|
if (res.confirm) { |
||||
|
// 用户点击确认,打开授权设置页面
|
||||
|
openSetting(); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
const openSetting = () => { |
||||
|
// Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。
|
||||
|
Taro.openSetting({ |
||||
|
success: (res) => { |
||||
|
if (res.authSetting['scope.userInfo']) { |
||||
|
// 用户授权成功,可以获取用户信息
|
||||
|
reload(); |
||||
|
} else { |
||||
|
// 用户拒绝授权,提示授权失败
|
||||
|
Taro.showToast({ |
||||
|
title: '授权失败', |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/* 获取用户手机号 */ |
||||
|
const handleGetPhoneNumber = ({detail}: {detail: {code?: string, encryptedData?: string, iv?: string}}) => { |
||||
|
const {code, encryptedData, iv} = detail |
||||
|
Taro.login({ |
||||
|
success: function () { |
||||
|
if (code) { |
||||
|
Taro.request({ |
||||
|
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone', |
||||
|
method: 'POST', |
||||
|
data: { |
||||
|
code, |
||||
|
encryptedData, |
||||
|
iv, |
||||
|
notVerifyPhone: true, |
||||
|
refereeId: 0, |
||||
|
sceneType: 'save_referee', |
||||
|
tenantId: TenantId |
||||
|
}, |
||||
|
header: { |
||||
|
'content-type': 'application/json', |
||||
|
TenantId |
||||
|
}, |
||||
|
success: function (res) { |
||||
|
if (res.data.code == 1) { |
||||
|
Taro.showToast({ |
||||
|
title: res.data.message, |
||||
|
icon: 'error', |
||||
|
duration: 2000 |
||||
|
}) |
||||
|
return false; |
||||
|
} |
||||
|
// 登录成功
|
||||
|
Taro.setStorageSync('access_token', res.data.data.access_token) |
||||
|
Taro.setStorageSync('UserId', res.data.data.user.userId) |
||||
|
setUserInfo(res.data.data.user) |
||||
|
setIsLogin(true) |
||||
|
} |
||||
|
}) |
||||
|
} else { |
||||
|
console.log('登录失败!') |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<div className={'header-bg pt-20'}> |
||||
|
<div className={'p-4'}> |
||||
|
<div |
||||
|
className={'user-card w-full flex flex-col justify-around rounded-xl shadow-sm'} |
||||
|
style={{ |
||||
|
background: 'linear-gradient(to bottom, #ffffff, #ffffff)', // 这种情况建议使用类名来控制样式(引入外联样式)
|
||||
|
// width: '720rpx',
|
||||
|
// margin: '10px auto 0px auto',
|
||||
|
height: '170px', |
||||
|
// borderRadius: '22px 22px 0 0',
|
||||
|
}} |
||||
|
> |
||||
|
<div className={'user-card-header flex w-full justify-between items-center pt-4'}> |
||||
|
<div className={'flex items-center mx-4'}> |
||||
|
{ |
||||
|
IsLogin ? ( |
||||
|
<Avatar size="large" src={userInfo?.avatar} shape="round"/> |
||||
|
) : ( |
||||
|
<Button className={'text-black'} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}> |
||||
|
<Avatar size="large" src={userInfo?.avatar} shape="round"/> |
||||
|
</Button> |
||||
|
) |
||||
|
} |
||||
|
<div className={'user-info flex flex-col px-2'}> |
||||
|
<div className={'py-1 text-black font-bold'}>{getDisplayName()}</div> |
||||
|
{IsLogin ? ( |
||||
|
<div className={'grade text-xs py-1'}> |
||||
|
<Tag type="success" round> |
||||
|
<div className={'p-1'}> |
||||
|
{getRoleName()} |
||||
|
</div> |
||||
|
</Tag> |
||||
|
</div> |
||||
|
) : ''} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className={'mx-4 text-sm px-3 py-1 text-black border-gray-400 border-solid border-2 rounded-3xl'} |
||||
|
onClick={() => navTo('/user/profile/profile', true)}> |
||||
|
{'个人资料'} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div className={'flex justify-around mt-1'}> |
||||
|
<div className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/wallet/wallet', true)}> |
||||
|
<span className={'text-sm text-gray-500'}>余额</span> |
||||
|
<span className={'text-xl'}>¥ {userInfo?.balance || '0.00'}</span> |
||||
|
</div> |
||||
|
<div className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/coupon/index', true)}> |
||||
|
<span className={'text-sm text-gray-500'}>优惠券</span> |
||||
|
<span className={'text-xl'}>{couponCount}</span> |
||||
|
</div> |
||||
|
<div className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/gift/index', true)}> |
||||
|
<span className={'text-sm text-gray-500'}>礼品卡</span> |
||||
|
<span className={'text-xl'}>{giftCount}</span> |
||||
|
</div> |
||||
|
{/*<div className={'item flex justify-center flex-col items-center'}>*/} |
||||
|
{/* <span className={'text-sm text-gray-500'}>积分</span>*/} |
||||
|
{/* <span className={'text-xl'}>{pointsCount}</span>*/} |
||||
|
{/*</div>*/} |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default UserCard; |
@ -0,0 +1,186 @@ |
|||||
|
import {Cell} from '@nutui/nutui-react-taro' |
||||
|
import navTo from "@/utils/common"; |
||||
|
import Taro from '@tarojs/taro' |
||||
|
import {View, Text} from '@tarojs/components' |
||||
|
import {ArrowRight, ShieldCheck, LogisticsError, Location, Reward, Tips, Ask, Setting, Scan} from '@nutui/icons-react-taro' |
||||
|
import {useUser} from '@/hooks/useUser' |
||||
|
|
||||
|
const UserCell = () => { |
||||
|
const {logoutUser, isCertified, hasRole, isAdmin} = useUser(); |
||||
|
|
||||
|
const onLogout = () => { |
||||
|
Taro.showModal({ |
||||
|
title: '提示', |
||||
|
content: '确定要退出登录吗?', |
||||
|
success: function (res) { |
||||
|
if (res.confirm) { |
||||
|
// 使用 useUser hook 的 logoutUser 方法
|
||||
|
logoutUser(); |
||||
|
Taro.reLaunch({ |
||||
|
url: '/pages/index/index' |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<View className={'px-4'}> |
||||
|
|
||||
|
{/*是否分销商*/} |
||||
|
{!hasRole('dealer') && !isAdmin() && ( |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
style={{ |
||||
|
backgroundImage: 'linear-gradient(to right bottom, #54a799, #177b73)', |
||||
|
}} |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}} onClick={() => navTo('/dealer/index', true)}> |
||||
|
<Reward className={'text-orange-100 '} size={16}/> |
||||
|
<Text style={{fontSize: '16px'}} className={'pl-3 text-orange-100 font-medium'}>开通会员</Text> |
||||
|
<Text className={'text-white opacity-80 pl-3'}>享优惠</Text> |
||||
|
</View> |
||||
|
} |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
/> |
||||
|
)} |
||||
|
|
||||
|
{/*是否管理员*/} |
||||
|
{isAdmin() && ( |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
style={{ |
||||
|
backgroundImage: 'linear-gradient(to right bottom, #ff8e0c, #ed680d)', |
||||
|
}} |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}} onClick={() => navTo('/admin/article/index', true)}> |
||||
|
<Setting className={'text-orange-100 '} size={16}/> |
||||
|
<Text style={{fontSize: '16px'}} className={'pl-3 text-orange-100 font-medium'}>管理中心</Text> |
||||
|
</View> |
||||
|
} |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
/> |
||||
|
)} |
||||
|
|
||||
|
<Cell.Group divider={true} description={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Text style={{marginTop: '12px'}}>我的服务</Text> |
||||
|
</View> |
||||
|
}> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Scan size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>门店核销</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/wallet/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
style={{ |
||||
|
display: 'none' |
||||
|
}} |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<LogisticsError size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>我的钱包</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/wallet/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Location size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>收货地址</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/address/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<ShieldCheck size={16} color={isCertified() ? '#52c41a' : '#666'}/> |
||||
|
<Text className={'pl-3 text-sm'}>实名认证</Text> |
||||
|
{isCertified() && ( |
||||
|
<Text className={'pl-2 text-xs text-green-500'}>已认证</Text> |
||||
|
)} |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/userVerify/index', true) |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Ask size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>常见问题</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/help/index') |
||||
|
}} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Tips size={16}/> |
||||
|
<Text className={'pl-3 text-sm'}>关于我们</Text> |
||||
|
</View> |
||||
|
} |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => { |
||||
|
navTo('/user/about/index') |
||||
|
}} |
||||
|
/> |
||||
|
</Cell.Group> |
||||
|
<Cell.Group divider={true} description={ |
||||
|
<View style={{display: 'inline-flex', alignItems: 'center'}}> |
||||
|
<Text style={{marginTop: '12px'}}>账号管理</Text> |
||||
|
</View> |
||||
|
}> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title="账号安全" |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={() => navTo('/user/profile/profile', true)} |
||||
|
/> |
||||
|
<Cell |
||||
|
className="nutui-cell-clickable" |
||||
|
title="退出登录" |
||||
|
align="center" |
||||
|
extra={<ArrowRight color="#cccccc" size={18}/>} |
||||
|
onClick={onLogout} |
||||
|
/> |
||||
|
</Cell.Group> |
||||
|
</View> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
export default UserCell |
@ -0,0 +1,102 @@ |
|||||
|
import {loginBySms} from "@/api/passport/login"; |
||||
|
import {useState} from "react"; |
||||
|
import Taro from '@tarojs/taro' |
||||
|
import {Popup} from '@nutui/nutui-react-taro' |
||||
|
import {UserParam} from "@/api/system/user/model"; |
||||
|
import {Button} from '@nutui/nutui-react-taro' |
||||
|
import {Form, Input} from '@nutui/nutui-react-taro' |
||||
|
import {Copyright, Version} from "@/config/app"; |
||||
|
const UserFooter = () => { |
||||
|
const [openLoginByPhone, setOpenLoginByPhone] = useState(false) |
||||
|
const [clickNum, setClickNum] = useState<number>(0) |
||||
|
const [FormData, setFormData] = useState<UserParam>( |
||||
|
{ |
||||
|
phone: undefined, |
||||
|
password: undefined |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
const onLoginByPhone = () => { |
||||
|
setFormData({}) |
||||
|
setClickNum(clickNum + 1); |
||||
|
if (clickNum > 10) { |
||||
|
setOpenLoginByPhone(true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const closeLoginByPhone = () => { |
||||
|
setClickNum(0) |
||||
|
setOpenLoginByPhone(false) |
||||
|
} |
||||
|
|
||||
|
// 提交表单
|
||||
|
const submitByPhone = (values: any) => { |
||||
|
loginBySms({ |
||||
|
phone: values.phone, |
||||
|
code: values.code |
||||
|
}).then(() => { |
||||
|
setOpenLoginByPhone(false); |
||||
|
setTimeout(() => { |
||||
|
Taro.reLaunch({ |
||||
|
url: '/pages/index/index' |
||||
|
}) |
||||
|
},1000) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<div className={'text-center py-4 w-full text-gray-300'} onClick={onLoginByPhone}> |
||||
|
<div className={'text-xs text-gray-400 py-1'}>当前版本:{Version}</div> |
||||
|
<div className={'text-xs text-gray-400 py-1'}>Copyright © { new Date().getFullYear() } {Copyright}</div> |
||||
|
</div> |
||||
|
|
||||
|
<Popup |
||||
|
style={{width: '350px', padding: '10px'}} |
||||
|
visible={openLoginByPhone} |
||||
|
closeOnOverlayClick={false} |
||||
|
closeable={true} |
||||
|
onClose={closeLoginByPhone} |
||||
|
> |
||||
|
<Form |
||||
|
style={{width: '350px',padding: '10px'}} |
||||
|
divider |
||||
|
initialValues={FormData} |
||||
|
labelPosition="left" |
||||
|
onFinish={(values) => submitByPhone(values)} |
||||
|
footer={ |
||||
|
<div |
||||
|
style={{ |
||||
|
display: 'flex', |
||||
|
justifyContent: 'center', |
||||
|
width: '100%' |
||||
|
}} |
||||
|
> |
||||
|
<Button nativeType="submit" block style={{backgroundColor: '#000000',color: '#ffffff'}}> |
||||
|
提交 |
||||
|
</Button> |
||||
|
</div> |
||||
|
} |
||||
|
> |
||||
|
<Form.Item |
||||
|
label={'手机号码'} |
||||
|
name="phone" |
||||
|
required |
||||
|
rules={[{message: '手机号码'}]} |
||||
|
> |
||||
|
<Input placeholder="请输入手机号码" maxLength={11} type="text"/> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
label={'短信验证码'} |
||||
|
name="code" |
||||
|
required |
||||
|
rules={[{message: '短信验证码'}]} |
||||
|
> |
||||
|
<Input placeholder="请输入短信验证码" maxLength={6} type="text"/> |
||||
|
</Form.Item> |
||||
|
</Form> |
||||
|
</Popup> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
export default UserFooter |
@ -0,0 +1,69 @@ |
|||||
|
import {useEffect} from "react"; |
||||
|
import navTo from "@/utils/common"; |
||||
|
import {View, Text} from '@tarojs/components'; |
||||
|
import {ArrowRight, Wallet, Comment, Transit, Refund, Package} from '@nutui/icons-react-taro'; |
||||
|
|
||||
|
function UserOrder() { |
||||
|
|
||||
|
const reload = () => { |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
useEffect(() => { |
||||
|
reload() |
||||
|
}, []); |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<View className={'px-4 pb-2'}> |
||||
|
<View |
||||
|
className={'user-card w-full flex flex-col justify-around rounded-xl shadow-sm'} |
||||
|
style={{ |
||||
|
background: 'linear-gradient(to bottom, #ffffff, #ffffff)', // 这种情况建议使用类名来控制样式(引入外联样式)
|
||||
|
// margin: '10px auto 0px auto',
|
||||
|
height: '120px', |
||||
|
// borderRadius: '22px 22px 0 0',
|
||||
|
}} |
||||
|
> |
||||
|
<View className={'title-bar flex justify-between pt-2'}> |
||||
|
<Text className={'title font-medium px-4'}>我的订单</Text> |
||||
|
<View className={'more flex items-center px-2'} onClick={() => navTo('/user/order/order', true)}> |
||||
|
<Text className={'text-xs text-gray-500'}>全部订单</Text> |
||||
|
<ArrowRight color="#cccccc" size={12}/> |
||||
|
</View> |
||||
|
</View> |
||||
|
<View className={'flex justify-around pb-1'}> |
||||
|
<View className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/order/order?statusFilter=0', true)}> |
||||
|
<Wallet size={26} className={'font-normal text-gray-500'}/> |
||||
|
<Text className={'text-sm text-gray-600 py-1'}>待付款</Text> |
||||
|
</View> |
||||
|
<View className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/order/order?statusFilter=1', true)}> |
||||
|
<Package size={26} className={'text-gray-500 font-normal'}/> |
||||
|
<Text className={'text-sm text-gray-600 py-1'}>待发货</Text> |
||||
|
</View> |
||||
|
<View className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/order/order?statusFilter=3', true)}> |
||||
|
<Transit size={24} className={'text-gray-500 font-normal'}/> |
||||
|
<Text className={'text-sm text-gray-600 py-1'}>待收货</Text> |
||||
|
</View> |
||||
|
<View className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/order/order?statusFilter=5', true)}> |
||||
|
<Comment size={24} className={'text-gray-500 font-normal'}/> |
||||
|
<Text className={'text-sm text-gray-600 py-1'}>已完成</Text> |
||||
|
</View> |
||||
|
<View className={'item flex justify-center flex-col items-center'} |
||||
|
onClick={() => navTo('/user/order/order?statusFilter=6', true)}> |
||||
|
<Refund size={26} className={'font-normal text-gray-500'}/> |
||||
|
<Text className={'text-sm text-gray-600 py-1'}>退货/售后</Text> |
||||
|
</View> |
||||
|
</View> |
||||
|
</View> |
||||
|
</View> |
||||
|
</> |
||||
|
|
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default UserOrder; |
@ -0,0 +1,3 @@ |
|||||
|
export default definePageConfig({ |
||||
|
navigationBarTitleText: '管理中心' |
||||
|
}) |
@ -0,0 +1,25 @@ |
|||||
|
import {useEffect} from 'react' |
||||
|
import {useUser} from "@/hooks/useUser"; |
||||
|
import {Text} from '@tarojs/components'; |
||||
|
|
||||
|
function Admin() { |
||||
|
const { |
||||
|
isAdmin |
||||
|
} = useUser(); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
}, []); |
||||
|
|
||||
|
if (!isAdmin()) { |
||||
|
return ( |
||||
|
<Text>您不是管理员</Text> |
||||
|
); |
||||
|
} |
||||
|
return ( |
||||
|
<> |
||||
|
<Text>待开发...</Text> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default Admin |
Loading…
Reference in new issue