Files
OpenFlare/frontend/contexts/user-context.tsx
T
ryan 48d414e197 裁剪
swagger

移除 merchant

swagger

改造首页内容为通用后台管理系统定位

- 修改首页标题从 'LINUX DO Credit' 改为 'Modern Platform'
- 更新副标题为 '为二次开发而生'
- 更新首页描述为通用平台的特点
- 更新首页特性标签为 '开箱即用、高度可扩展、工业级基建'
- 修改展示卡片为技术栈和二次开发相关
- 更新开发者示例代码为通用的注册和 API Key 获取示例
- 更新页脚品牌名为 'Modern Platform'
- 调整页脚导航链接为通用平台相关内容

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

去除遗留

裁剪
移除 /api/v1/user/pay-key 相关代码

- 删除后端 UpdatePayKey 处理器函数和 UpdatePayKeyRequest 结构体
- 删除 User 模型中的 PayKey 字段
- 删除 User.VerifyPayKey 方法
- 删除 EncryptPayKeyFailed 错误常量
- 删除 /api/v1/user/pay-key PUT 路由
- 删除 OAuth 返回中的 IsPayKey 字段
- 删除前端 UserService.updatePayKey 方法
- 删除前端所有支付密钥 UI 和逻辑
- 更新相关的导出和注释

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

去除遗留

api 修正

系统配置

前端裁剪

后端裁剪

init
2026-06-08 20:34:28 +08:00

166 lines
4.1 KiB
TypeScript

"use client"
import { createContext, useContext, useState, useEffect, useRef, useCallback, ReactNode } from 'react'
import services from '@/lib/services'
import { User, TrustLevel, PayLevel } from '@/lib/services/auth/types'
/** 用户状态接口 */
interface UserState {
user: User | null
loading: boolean
error: string | null
}
/** 用户上下文接口 */
interface UserContextValue extends UserState {
refetch: () => Promise<void>
getTrustLevelLabel: (trustLevel: TrustLevel) => string
getPayLevelLabel: (payLevel: PayLevel) => string
logout: () => Promise<void>
}
/** 信任等级映射 */
const TRUST_LEVEL_LABELS: Record<TrustLevel, string> = {
[TrustLevel.New]: '新用户',
[TrustLevel.Basic]: '基本用户',
[TrustLevel.Member]: '成员',
[TrustLevel.Regular]: '活跃用户',
[TrustLevel.Leader]: '领导者',
}
/** 支付等级映射 */
const PAY_LEVEL_LABELS: Record<PayLevel, string> = {
[PayLevel.BlackGold]: '黑金',
[PayLevel.WhiteGold]: '白金',
[PayLevel.Gold]: '黄金',
[PayLevel.Ordinary]: '普通',
}
/** 用户上下文 */
const UserContext = createContext<UserContextValue | undefined>(undefined)
/**
* 用户Provider组件
*
* @param {React.ReactNode} children - 用户 Provider 的子元素
* @returns {React.ReactNode} 用户 Provider 组件
* @example
* ```tsx
* <UserProvider>
* <UserContext.Provider value={{ user, loading, error, refetch, updatePayKey, getTrustLevelLabel, getPayLevelLabel, logout }}>
* {children}
* </UserContext.Provider>
* </UserProvider>
* ```
*/
export function UserProvider({ children }: { children: ReactNode }) {
const [state, setState] = useState<UserState>({
user: null,
loading: true,
error: null,
})
const isMountedRef = useRef(true)
/** 获取信任等级标签 */
const getTrustLevelLabel = useCallback((trustLevel: TrustLevel): string => {
return TRUST_LEVEL_LABELS[trustLevel] || '未知'
}, [])
/** 获取支付等级标签 */
const getPayLevelLabel = useCallback((payLevel: PayLevel): string => {
return PAY_LEVEL_LABELS[payLevel] || '未知'
}, [])
/** 获取用户信息 */
const fetchUser = useCallback(async () => {
try {
setState(prev => ({ ...prev, loading: true, error: null }))
const user = await services.auth.getUserInfo()
if (!isMountedRef.current) return
setState({ user, loading: false, error: null })
} catch (error) {
if (!isMountedRef.current) return
setState({
user: null,
loading: false,
error: error instanceof Error ? error.message : '获取用户信息失败',
})
}
}, [])
/** 重新获取用户信息 */
const refetch = useCallback(async () => {
await fetchUser()
}, [fetchUser])
/** 用户登出 */
const logout = useCallback(async () => {
try {
await services.auth.logout()
if (!isMountedRef.current) return
setState({ user: null, loading: false, error: null })
window.location.href = '/login'
} catch (error) {
if (!isMountedRef.current) {
throw error
}
const errorMessage = error instanceof Error ? error.message : '登出失败'
setState(prev => ({
...prev,
error: errorMessage,
}))
throw new Error(errorMessage)
}
}, [])
/** 组件挂载时获取用户信息 */
useEffect(() => {
isMountedRef.current = true
fetchUser()
return () => {
isMountedRef.current = false
}
}, [fetchUser])
return (
<UserContext.Provider
value={{
...state,
refetch,
getTrustLevelLabel,
getPayLevelLabel,
logout,
}}
>
{children}
</UserContext.Provider>
)
}
/**
* 使用用户上下文的Hook
*
* @returns {UserContextValue} 用户上下文值
* @example
* ```tsx
* const { user, loading, error, refetch, updatePayKey, getTrustLevelLabel, getPayLevelLabel, logout } = useUser()
* ```
*/
export function useUser(): UserContextValue {
const context = useContext(UserContext)
if (context === undefined) {
throw new Error('useUser must be used within a UserProvider')
}
return context
}