|
|
@@ -0,0 +1,123 @@
|
|
|
+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<typeof enterpriseAuthClient.me.$get, 200>
|
|
|
+type EnterpriseLoginRequest = InferRequestType<typeof enterpriseAuthClient.login.$post>['json']
|
|
|
+
|
|
|
+interface EnterpriseAuthContextType {
|
|
|
+ user: EnterpriseUser | null
|
|
|
+ login: (data: EnterpriseLoginRequest) => Promise<EnterpriseUser>
|
|
|
+ logout: () => Promise<void>
|
|
|
+ isLoading: boolean
|
|
|
+ isLoggedIn: boolean
|
|
|
+}
|
|
|
+
|
|
|
+const EnterpriseAuthContext = createContext<EnterpriseAuthContextType | undefined>(undefined)
|
|
|
+
|
|
|
+const queryClient = new QueryClient()
|
|
|
+
|
|
|
+export const EnterpriseAuthProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
+ const queryClient = useQueryClient()
|
|
|
+
|
|
|
+ const { data: user, isLoading } = useQuery<EnterpriseUser | null, Error>({
|
|
|
+ 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<EnterpriseUser, Error, EnterpriseLoginRequest>({
|
|
|
+ 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<void, Error>({
|
|
|
+ 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 <EnterpriseAuthContext.Provider value={value}>{children}</EnterpriseAuthContext.Provider>
|
|
|
+}
|
|
|
+
|
|
|
+export const useEnterpriseAuth = () => {
|
|
|
+ const context = useContext(EnterpriseAuthContext)
|
|
|
+ if (context === undefined) {
|
|
|
+ throw new Error('useEnterpriseAuth must be used within an EnterpriseAuthProvider')
|
|
|
+ }
|
|
|
+ return context
|
|
|
+}
|
|
|
+
|
|
|
+export { queryClient }
|