56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import { defineStore } from 'pinia'
|
||
import { ref, computed } from 'vue'
|
||
import { authService } from '@/api/services'
|
||
import { getItem, setItem, removeItem, StorageKeys } from '@/utils/storage'
|
||
|
||
export const useAuthStore = defineStore('auth', () => {
|
||
const accessToken = ref<string | null>(getItem(StorageKeys.accessToken))
|
||
const userId = ref<string | null>(getItem(StorageKeys.userId))
|
||
const isNewUser = ref(false)
|
||
|
||
const isLoggedIn = computed(() => !!accessToken.value)
|
||
|
||
function applyTokens(data: { accessToken?: string; refreshToken?: string; userId?: string; isNewUser?: boolean }) {
|
||
if (data.accessToken) {
|
||
accessToken.value = data.accessToken
|
||
setItem(StorageKeys.accessToken, data.accessToken)
|
||
}
|
||
if (data.refreshToken) setItem(StorageKeys.refreshToken, data.refreshToken)
|
||
if (data.userId) {
|
||
userId.value = data.userId
|
||
setItem(StorageKeys.userId, data.userId)
|
||
}
|
||
isNewUser.value = !!data.isNewUser
|
||
}
|
||
|
||
/**
|
||
* 演示登录:以 `demo_openid_xx` 作为 code 直连 Mock Provider,
|
||
* 无需微信环境即可切换到预置演示用户(见实施计划 D2 / 登录策略)。
|
||
*/
|
||
async function loginByDemoCode(code: string) {
|
||
const data = await authService.demoLogin({ code })
|
||
applyTokens(data)
|
||
return data
|
||
}
|
||
|
||
function clearSession() {
|
||
accessToken.value = null
|
||
userId.value = null
|
||
removeItem(StorageKeys.accessToken)
|
||
removeItem(StorageKeys.refreshToken)
|
||
removeItem(StorageKeys.userId)
|
||
removeItem(StorageKeys.userStatusSnapshot)
|
||
}
|
||
|
||
async function logout() {
|
||
try {
|
||
await authService.logout()
|
||
} catch {
|
||
/* best-effort */
|
||
}
|
||
clearSession()
|
||
}
|
||
|
||
return { accessToken, userId, isNewUser, isLoggedIn, loginByDemoCode, applyTokens, clearSession, logout }
|
||
})
|