enterprise-auth.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { createContext, useContext, PropsWithChildren } from 'react'
  2. import Taro from '@tarojs/taro'
  3. import { enterpriseAuthClient } from '../api'
  4. import { InferResponseType, InferRequestType } from 'hono'
  5. import { QueryClient, useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
  6. // 企业用户类型定义
  7. export type EnterpriseUser = InferResponseType<typeof enterpriseAuthClient.me.$get, 200>
  8. type EnterpriseLoginRequest = InferRequestType<typeof enterpriseAuthClient.login.$post>['json']
  9. interface EnterpriseAuthContextType {
  10. user: EnterpriseUser | null
  11. login: (data: EnterpriseLoginRequest) => Promise<EnterpriseUser>
  12. logout: () => Promise<void>
  13. isLoading: boolean
  14. isLoggedIn: boolean
  15. }
  16. const EnterpriseAuthContext = createContext<EnterpriseAuthContextType | undefined>(undefined)
  17. export const EnterpriseAuthProvider: React.FC<PropsWithChildren> = ({ children }) => {
  18. const queryClient = useQueryClient()
  19. const { data: user, isLoading } = useQuery<EnterpriseUser | null, Error>({
  20. queryKey: ['currentEnterpriseUser'],
  21. queryFn: async () => {
  22. const token = Taro.getStorageSync('enterprise_token')
  23. if (!token) {
  24. return null
  25. }
  26. try {
  27. const response = await enterpriseAuthClient.me.$get({})
  28. if (response.status !== 200) {
  29. throw new Error('获取企业用户信息失败')
  30. }
  31. const user = await response.json()
  32. Taro.setStorageSync('enterpriseUserInfo', JSON.stringify(user))
  33. return user
  34. } catch (error) {
  35. Taro.removeStorageSync('enterprise_token')
  36. Taro.removeStorageSync('enterpriseUserInfo')
  37. return null
  38. }
  39. },
  40. staleTime: Infinity,
  41. refetchOnWindowFocus: false,
  42. refetchOnReconnect: false,
  43. })
  44. const loginMutation = useMutation<EnterpriseUser, Error, EnterpriseLoginRequest>({
  45. mutationFn: async (data) => {
  46. const response = await enterpriseAuthClient.login.$post({ json: data })
  47. if (response.status !== 200) {
  48. throw new Error('企业登录失败')
  49. }
  50. const { token, user } = await response.json()
  51. Taro.setStorageSync('enterprise_token', token)
  52. Taro.setStorageSync('enterpriseUserInfo', JSON.stringify(user))
  53. return user
  54. },
  55. onSuccess: (newUser) => {
  56. queryClient.setQueryData(['currentEnterpriseUser'], newUser)
  57. },
  58. onError: (error) => {
  59. Taro.showToast({
  60. title: error.message || '企业登录失败,请检查手机号和密码',
  61. icon: 'none',
  62. duration: 2000,
  63. })
  64. },
  65. })
  66. const logoutMutation = useMutation<void, Error>({
  67. mutationFn: async () => {
  68. try {
  69. const response = await enterpriseAuthClient.logout.$post({})
  70. if (response.status !== 200) {
  71. throw new Error('企业登出失败')
  72. }
  73. } catch (error) {
  74. console.error('Enterprise logout error:', error)
  75. } finally {
  76. Taro.removeStorageSync('enterprise_token')
  77. Taro.removeStorageSync('enterpriseUserInfo')
  78. }
  79. },
  80. onSuccess: () => {
  81. queryClient.setQueryData(['currentEnterpriseUser'], null)
  82. Taro.redirectTo({ url: '/pages/yongren/login/index' })
  83. },
  84. onError: (error) => {
  85. Taro.showToast({
  86. title: error.message || '企业登出失败',
  87. icon: 'none',
  88. duration: 2000,
  89. })
  90. },
  91. })
  92. const value = {
  93. user: user || null,
  94. login: loginMutation.mutateAsync,
  95. logout: logoutMutation.mutateAsync,
  96. isLoading: isLoading || loginMutation.isPending || logoutMutation.isPending,
  97. isLoggedIn: !!user,
  98. }
  99. return <EnterpriseAuthContext.Provider value={value}>{children}</EnterpriseAuthContext.Provider>
  100. }
  101. export const useEnterpriseAuth = () => {
  102. const context = useContext(EnterpriseAuthContext)
  103. if (context === undefined) {
  104. throw new Error('useEnterpriseAuth must be used within an EnterpriseAuthProvider')
  105. }
  106. return context
  107. }