Files
xinlong-shop-taro/src/contexts/UserContext.tsx
赵忠林 fd03ed80fd refactor(user): 禁用 loginByOpenId 静默登录并优化登录状态控制
- 移除 UserContext 和 useUser 中的 loginByOpenId 调用及相关降级逻辑
- 无本地 token 时保持未登录状态,不再自动触发静默登录
- 清理无用导入 TenantId 和 loginByOpenId
- 订单列表页增加登录校验,未登录用户跳转登录页并阻止渲染订单
- 商城首页价格改为 Price 组件,未登录游客显示登录遮罩,单位仅登录后可见
2026-07-14 01:36:58 +08:00

111 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { createContext, useContext, useState, useEffect, type ReactNode } from 'react'
import Taro from '@tarojs/taro'
import type { User } from '@/api/system/user/model'
import { getUserInfo } from '@/api/layout'
import { saveStorageByLoginUser, clearStorageByLoginUser } from '@/utils/server'
interface UserContextType {
user: User | null
isLoggedIn: boolean
loading: boolean
loginUser: (token: string, userInfo: User) => void
logoutUser: () => void
refreshUser: () => Promise<User | null>
syncFromStorage: () => boolean
}
const UserContext = createContext<UserContextType | undefined>(undefined)
export const UserProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
const init = async () => {
const token = Taro.getStorageSync('access_token')
const userData = Taro.getStorageSync('User')
// 情况1: 有本地token和用户数据直接使用
if (token && userData) {
const parsed = typeof userData === 'string' ? JSON.parse(userData) : userData
setUser(parsed as User)
setLoading(false)
return
}
// 情况2: 有token但没有用户数据尝试从接口获取
if (token) {
try {
const userInfo = await getUserInfo()
setUser(userInfo)
setLoading(false)
return
} catch {
// token无效清除
clearStorageByLoginUser()
}
}
// 无本地token保持未登录状态已禁用静默登录
setLoading(false)
}
init()
}, [])
const loginUser = (token: string, userInfo: User) => {
saveStorageByLoginUser(token, userInfo)
setUser(userInfo)
}
const logoutUser = () => {
clearStorageByLoginUser()
setUser(null)
}
/** 从 storage 快速同步用户状态(无需网络请求),供页面 useDidShow 调用 */
const syncFromStorage = (): boolean => {
const token = Taro.getStorageSync('access_token')
const userData = Taro.getStorageSync('User')
if (token && userData) {
const parsed = typeof userData === 'string' ? JSON.parse(userData) : userData
setUser(parsed as User)
return true
}
if (!token) {
setUser(null)
}
return false
}
const refreshUser = async (): Promise<User | null> => {
if (!Taro.getStorageSync('access_token')) return null
try {
const userInfo = await getUserInfo()
const token = Taro.getStorageSync('access_token')
if (token) {
saveStorageByLoginUser(token, userInfo)
}
setUser(userInfo)
return userInfo
} catch {
return null
}
}
return (
<UserContext.Provider
value={{ user, isLoggedIn: !!user, loading, loginUser, logoutUser, refreshUser, syncFromStorage }}
>
{children}
</UserContext.Provider>
)
}
export const useUserContext = (): UserContextType => {
const context = useContext(UserContext)
if (!context) {
throw new Error('useUserContext must be used within UserProvider')
}
return context
}