forked from gxwebsoft/mp-10550
feat(user): 添加用户信息实时同步和刷新功能
- 在个人中心页面添加用户信息实时刷新机制 - 实现用户头像和昵称修改后的同步更新 - 新增 reloadUserInfo 方法用于重新加载用户数据 - 添加本地存储同步机制保持用户信息一致性 - 优化登录状态管理和用户数据显示逻辑 - 整合微信 OpenID 获取流程到用户信息刷新过程
This commit is contained in:
@@ -17,7 +17,7 @@ import { saveStorageByLoginUser } from '@/utils/server'
|
|||||||
|
|
||||||
const UserCard = forwardRef<any, any>((_, ref) => {
|
const UserCard = forwardRef<any, any>((_, ref) => {
|
||||||
const {data, refresh} = useUserData()
|
const {data, refresh} = useUserData()
|
||||||
const {getDisplayName, isAdmin} = useUser();
|
const {loadUserFromStorage} = useUser();
|
||||||
const [IsLogin, setIsLogin] = useState<boolean>(false)
|
const [IsLogin, setIsLogin] = useState<boolean>(false)
|
||||||
const [userInfo, setUserInfo] = useState<User>()
|
const [userInfo, setUserInfo] = useState<User>()
|
||||||
const [ticketTotal, setTicketTotal] = useState<number>(0)
|
const [ticketTotal, setTicketTotal] = useState<number>(0)
|
||||||
@@ -25,9 +25,14 @@ const UserCard = forwardRef<any, any>((_, ref) => {
|
|||||||
const themeStyles = useThemeStyles();
|
const themeStyles = useThemeStyles();
|
||||||
const canShowScanButton = (() => {
|
const canShowScanButton = (() => {
|
||||||
const v: any = (userInfo as any)?.isAdmin
|
const v: any = (userInfo as any)?.isAdmin
|
||||||
return isAdmin() || v === true || v === 1 || v === '1'
|
return v === true || v === 1 || v === '1'
|
||||||
})()
|
})()
|
||||||
|
|
||||||
|
const getDisplayName = () => {
|
||||||
|
if (!userInfo) return IsLogin ? '用户' : '点击登录'
|
||||||
|
return userInfo.nickname || (userInfo as any).realName || (userInfo as any).username || (IsLogin ? '用户' : '点击登录')
|
||||||
|
}
|
||||||
|
|
||||||
// 角色名称:优先取用户 roles 数组的第一个角色名称
|
// 角色名称:优先取用户 roles 数组的第一个角色名称
|
||||||
const getRoleName = () => {
|
const getRoleName = () => {
|
||||||
return userInfo?.roles?.[0]?.roleName || userInfo?.roleName || '注册用户'
|
return userInfo?.roles?.[0]?.roleName || userInfo?.roleName || '注册用户'
|
||||||
@@ -45,10 +50,46 @@ const UserCard = forwardRef<any, any>((_, ref) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const syncUserToStorage = (u: User) => {
|
||||||
|
// Keep storage up-to-date for other places that read user info synchronously.
|
||||||
|
Taro.setStorageSync('User', u)
|
||||||
|
if (u?.userId) Taro.setStorageSync('UserId', u.userId)
|
||||||
|
if (u?.nickname) Taro.setStorageSync('WxNickName', u.nickname)
|
||||||
|
}
|
||||||
|
|
||||||
|
const reloadUserInfo = async () => {
|
||||||
|
try {
|
||||||
|
const u = await getUserInfo()
|
||||||
|
if (u) {
|
||||||
|
setUserInfo(u)
|
||||||
|
setIsLogin(true)
|
||||||
|
syncUserToStorage(u)
|
||||||
|
// Refresh this hook instance's state from storage (defensive).
|
||||||
|
await loadUserFromStorage()
|
||||||
|
|
||||||
|
// 获取openId(不阻塞 UI 刷新)
|
||||||
|
if (!u.openid) {
|
||||||
|
Taro.login({
|
||||||
|
success: (res) => {
|
||||||
|
getWxOpenId({code: res.code}).catch(() => {})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Not logged in / token expired: keep UI in "not login" state.
|
||||||
|
// Other error handling is done in request interceptor / callers.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
handleRefresh: () => reloadStats(true),
|
handleRefresh: async () => {
|
||||||
reloadStats
|
await reloadUserInfo()
|
||||||
|
await reloadStats(true)
|
||||||
|
},
|
||||||
|
reloadStats,
|
||||||
|
reloadUserInfo
|
||||||
}))
|
}))
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -97,30 +138,15 @@ const UserCard = forwardRef<any, any>((_, ref) => {
|
|||||||
nickname: res.userInfo.nickName,
|
nickname: res.userInfo.nickName,
|
||||||
sexName: res.userInfo.gender == 1 ? '男' : '女'
|
sexName: res.userInfo.gender == 1 ? '男' : '女'
|
||||||
})
|
})
|
||||||
getUserInfo().then((data) => {
|
reloadUserInfo()
|
||||||
if (data) {
|
.then(() => {
|
||||||
setUserInfo(data)
|
|
||||||
setIsLogin(true);
|
|
||||||
// Keep local storage user info in sync so other hooks (e.g. unified scan) can read admin flags.
|
|
||||||
Taro.setStorageSync('User', data)
|
|
||||||
Taro.setStorageSync('UserId', data.userId)
|
|
||||||
// 登录态已就绪后刷新卡片统计(余额/积分/券/水票)
|
// 登录态已就绪后刷新卡片统计(余额/积分/券/水票)
|
||||||
refresh().then()
|
refresh().then()
|
||||||
reloadTicketTotal()
|
reloadTicketTotal()
|
||||||
|
})
|
||||||
// 获取openId
|
.catch(() => {
|
||||||
if (!data.openid) {
|
console.log('未登录')
|
||||||
Taro.login({
|
})
|
||||||
success: (res) => {
|
|
||||||
getWxOpenId({code: res.code}).then(() => {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
console.log('未登录')
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ function User() {
|
|||||||
// 每次进入/切回个人中心都刷新一次统计(包含水票数量)
|
// 每次进入/切回个人中心都刷新一次统计(包含水票数量)
|
||||||
useDidShow(() => {
|
useDidShow(() => {
|
||||||
userCardRef.current?.reloadStats?.()
|
userCardRef.current?.reloadStats?.()
|
||||||
|
// 个人资料(头像/昵称)可能在其它页面被修改,这里确保返回时立刻刷新
|
||||||
|
userCardRef.current?.reloadUserInfo?.()
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user