100 lines
2.9 KiB
TypeScript
100 lines
2.9 KiB
TypeScript
import { create } from 'zustand'
|
||
import Taro from '@tarojs/taro'
|
||
import { registerApi, wxLoginApi } from '@/services/auth'
|
||
import type { RegisterParams, WxLoginParams } from '@/services/auth'
|
||
import type { User } from '@/types/user'
|
||
|
||
/** 存储 key */
|
||
const STORAGE_KEYS = {
|
||
TOKEN: 'auth_token',
|
||
USER: 'auth_user',
|
||
} as const
|
||
|
||
/** 从本地存储恢复登录态 */
|
||
function loadFromStorage(): { user: User | null; token: string | null } {
|
||
try {
|
||
const storedToken = Taro.getStorageSync(STORAGE_KEYS.TOKEN)
|
||
const storedUser = Taro.getStorageSync(STORAGE_KEYS.USER)
|
||
if (storedToken && storedUser) {
|
||
return { token: storedToken, user: JSON.parse(storedUser) }
|
||
}
|
||
} catch {
|
||
// 存储数据损坏,清除并视为未登录
|
||
try { Taro.removeStorageSync(STORAGE_KEYS.TOKEN) } catch { /* noop */ }
|
||
try { Taro.removeStorageSync(STORAGE_KEYS.USER) } catch { /* noop */ }
|
||
}
|
||
return { user: null, token: null }
|
||
}
|
||
|
||
/** 登录 / 注册成功后持久化 token 与用户信息 */
|
||
function persistAuth(token: string, user: User): void {
|
||
try {
|
||
Taro.setStorageSync(STORAGE_KEYS.TOKEN, token)
|
||
Taro.setStorageSync(STORAGE_KEYS.USER, JSON.stringify(user))
|
||
} catch {
|
||
// storage 写入失败不阻塞登录流程
|
||
}
|
||
}
|
||
|
||
interface AuthState {
|
||
user: User | null
|
||
token: string | null
|
||
loading: boolean
|
||
login: (params: WxLoginParams) => Promise<void>
|
||
/** 微信注册(手机号授权 + 门店编码绑定门店) */
|
||
register: (params: RegisterParams) => Promise<void>
|
||
logout: () => void
|
||
/** 更新用户信息(用于编辑资料后同步 store) */
|
||
setUser: (user: User) => void
|
||
}
|
||
|
||
const useAuthStore = create<AuthState>((set) => {
|
||
// 初始化时从 storage 恢复
|
||
const initial = loadFromStorage()
|
||
|
||
return {
|
||
user: initial.user,
|
||
token: initial.token,
|
||
loading: !!(initial.token && initial.user), // 已恢复则立即 ready
|
||
|
||
/** 登录(仅已注册用户可登录,未注册由页面引导去注册) */
|
||
login: async (params: WxLoginParams) => {
|
||
const res = await wxLoginApi(params)
|
||
const { token, user } = res.data
|
||
set({ user, token })
|
||
persistAuth(token, user)
|
||
},
|
||
|
||
/** 注册:POST /mini/auth/register */
|
||
register: async (params: RegisterParams) => {
|
||
const res = await registerApi(params)
|
||
const { token, user } = res.data
|
||
set({ user, token })
|
||
persistAuth(token, user)
|
||
},
|
||
|
||
/** 退出登录 */
|
||
logout: () => {
|
||
set({ user: null, token: null })
|
||
try {
|
||
Taro.removeStorageSync(STORAGE_KEYS.TOKEN)
|
||
Taro.removeStorageSync(STORAGE_KEYS.USER)
|
||
} catch {
|
||
// noop
|
||
}
|
||
},
|
||
|
||
/** 更新用户信息(编辑资料后同步 store + storage) */
|
||
setUser: (user: User) => {
|
||
set({ user })
|
||
try {
|
||
Taro.setStorageSync(STORAGE_KEYS.USER, JSON.stringify(user))
|
||
} catch {
|
||
// storage 写入失败不阻塞
|
||
}
|
||
},
|
||
}
|
||
})
|
||
|
||
export default useAuthStore
|