forked from gxwebsoft/mp-10550
- 新增优惠券卡片对齐修复文档 - 新增优惠券状态显示调试文档 - 新增优惠券组件警告修复文档- 更新用ShopInfo Hook字段迁移文档 - 更新Arguments关键字修复文档
250 lines
8.3 KiB
TypeScript
250 lines
8.3 KiB
TypeScript
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 {getUserPointsStats} from "@/api/user/points";
|
||
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)
|
||
})
|
||
|
||
// 加载积分数量
|
||
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;
|