fix(api): 替换所有接口请求的域名为 guilixu-api.websoft.top
- 将获取 STS Token 的接口地址由 paopao-api 改为 guilixu-api - 更新图片上传接口地址为新的 guilixu-api 域名 - 修改用户推广页面中邀请码链接和二维码接口的域名 - 更改注册页微信登录接口请求的域名为 guilixu-api
This commit is contained in:
135
src/contexts/UserContext.tsx
Normal file
135
src/contexts/UserContext.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
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, loginByOpenId } from '@/api/layout'
|
||||
import { saveStorageByLoginUser, clearStorageByLoginUser } from '@/utils/server'
|
||||
import { TenantId } from '@/config/app'
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
// 情况3: 没有本地token,尝试静默登录(老用户自动登录)
|
||||
try {
|
||||
const loginResult = await new Promise<{ access_token?: string; user?: User }>((resolve, reject) => {
|
||||
Taro.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
loginByOpenId({ code: res.code, tenantId: TenantId })
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
} else {
|
||||
reject(new Error('no code'))
|
||||
}
|
||||
},
|
||||
fail: reject,
|
||||
})
|
||||
})
|
||||
// 静默登录成功(老用户),自动完成登录
|
||||
if (loginResult?.access_token && loginResult?.user) {
|
||||
saveStorageByLoginUser(loginResult.access_token, loginResult.user)
|
||||
setUser(loginResult.user)
|
||||
}
|
||||
} catch {
|
||||
// 静默登录失败(非老用户或网络问题),保持未登录状态
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user