import { createContext, useContext, PropsWithChildren } from 'react' import Taro from '@tarojs/taro' import { enterpriseAuthClient } from '../api' import { InferResponseType, InferRequestType } from 'hono' import { QueryClient, useQuery, useMutation, useQueryClient } from '@tanstack/react-query' // 企业用户类型定义 export type EnterpriseUser = InferResponseType type EnterpriseLoginRequest = InferRequestType['json'] interface EnterpriseAuthContextType { user: EnterpriseUser | null login: (data: EnterpriseLoginRequest) => Promise logout: () => Promise isLoading: boolean isLoggedIn: boolean } const EnterpriseAuthContext = createContext(undefined) export const EnterpriseAuthProvider: React.FC = ({ children }) => { const queryClient = useQueryClient() const { data: user, isLoading } = useQuery({ queryKey: ['currentEnterpriseUser'], queryFn: async () => { const token = Taro.getStorageSync('enterprise_token') if (!token) { return null } try { const response = await enterpriseAuthClient.me.$get({}) if (response.status !== 200) { throw new Error('获取企业用户信息失败') } const user = await response.json() Taro.setStorageSync('enterpriseUserInfo', JSON.stringify(user)) return user } catch (error) { Taro.removeStorageSync('enterprise_token') Taro.removeStorageSync('enterpriseUserInfo') return null } }, staleTime: Infinity, refetchOnWindowFocus: false, refetchOnReconnect: false, }) const loginMutation = useMutation({ mutationFn: async (data) => { const response = await enterpriseAuthClient.login.$post({ json: data }) if (response.status !== 200) { throw new Error('企业登录失败') } const { token, user } = await response.json() Taro.setStorageSync('enterprise_token', token) Taro.setStorageSync('enterpriseUserInfo', JSON.stringify(user)) return user }, onSuccess: (newUser) => { queryClient.setQueryData(['currentEnterpriseUser'], newUser) }, onError: (error) => { Taro.showToast({ title: error.message || '企业登录失败,请检查手机号和密码', icon: 'none', duration: 2000, }) }, }) const logoutMutation = useMutation({ mutationFn: async () => { try { const response = await enterpriseAuthClient.logout.$post({}) if (response.status !== 200) { throw new Error('企业登出失败') } } catch (error) { console.error('Enterprise logout error:', error) } finally { Taro.removeStorageSync('enterprise_token') Taro.removeStorageSync('enterpriseUserInfo') } }, onSuccess: () => { queryClient.setQueryData(['currentEnterpriseUser'], null) Taro.redirectTo({ url: '/pages/yongren/login/index' }) }, onError: (error) => { Taro.showToast({ title: error.message || '企业登出失败', icon: 'none', duration: 2000, }) }, }) const value = { user: user || null, login: loginMutation.mutateAsync, logout: logoutMutation.mutateAsync, isLoading: isLoading || loginMutation.isPending || logoutMutation.isPending, isLoggedIn: !!user, } return {children} } export const useEnterpriseAuth = () => { const context = useContext(EnterpriseAuthContext) if (context === undefined) { throw new Error('useEnterpriseAuth must be used within an EnterpriseAuthProvider') } return context }