feat: login
This commit is contained in:
22
composables/useDefer.ts
Normal file
22
composables/useDefer.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
export const useDefer = (maxFrame: number = 1000) => {
|
||||
const frame = ref(1)
|
||||
let rafId: number
|
||||
|
||||
function updateFrame() {
|
||||
rafId = requestAnimationFrame(() => {
|
||||
frame.value++
|
||||
if (frame.value > maxFrame) return
|
||||
updateFrame()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateFrame()
|
||||
})
|
||||
onUnmounted(() => {
|
||||
cancelAnimationFrame(rafId)
|
||||
})
|
||||
return (n: number) => {
|
||||
return frame.value >= n
|
||||
}
|
||||
}
|
||||
21
composables/useFetchWrapped.ts
Normal file
21
composables/useFetchWrapped.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import {useFormPayload} from "~/composables/useFormPayload";
|
||||
|
||||
export const useFetchWrapped = <TypeReq, TypeResp>(
|
||||
action: string,
|
||||
payload?: TypeReq,
|
||||
options?: {
|
||||
method?: 'GET' | 'POST'
|
||||
headers?: Record<string, string>
|
||||
baseURL?: string
|
||||
}
|
||||
) => {
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
return $fetch<TypeResp>('/', {
|
||||
baseURL: options?.baseURL || runtimeConfig.public.API_BASE,
|
||||
method: options?.method || 'POST',
|
||||
query: {
|
||||
s: action
|
||||
},
|
||||
body: useFormPayload(payload as object)
|
||||
})
|
||||
}
|
||||
10
composables/useFormPayload.ts
Normal file
10
composables/useFormPayload.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export const useFormPayload = (payload: object) => {
|
||||
const formData = new FormData()
|
||||
for (const dataKey in payload) {
|
||||
if (payload.hasOwnProperty(dataKey)) {
|
||||
// @ts-ignore
|
||||
formData.append(dataKey, payload[dataKey])
|
||||
}
|
||||
}
|
||||
return formData
|
||||
}
|
||||
64
composables/useLoginState.ts
Normal file
64
composables/useLoginState.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import {useFetchWrapped} from "~/composables/useFetchWrapped";
|
||||
|
||||
export const useLoginState = defineStore('loginState', () => {
|
||||
const is_logged_in = ref(false)
|
||||
const token = ref<string | null>(null)
|
||||
const user = ref<UserSchema>({} as UserSchema)
|
||||
|
||||
const checkSession = () => {
|
||||
return new Promise<boolean>(resolve => {
|
||||
if (!token.value) return resolve(false)
|
||||
useFetchWrapped<AuthedRequest, BaseResponse<resp.user.CheckSession>>('App.User_User.CheckSession', {
|
||||
token: token.value,
|
||||
user_id: user.value.id
|
||||
}).then(res => {
|
||||
if (res.ret !== 200) {
|
||||
resolve(false)
|
||||
return
|
||||
}
|
||||
resolve(res.data.is_login)
|
||||
// update global state
|
||||
is_logged_in.value = res.data.is_login
|
||||
}).catch(err => resolve(false))
|
||||
})
|
||||
}
|
||||
|
||||
const updateProfile = () => {
|
||||
return new Promise<UserSchema>((resolve, reject) => {
|
||||
if (!token.value) return reject('token is empty')
|
||||
useFetchWrapped<AuthedRequest, BaseResponse<resp.user.Profile>>('App.User_User.Profile', {
|
||||
token: token.value,
|
||||
user_id: user.value.id
|
||||
}).then(res => {
|
||||
if (res.ret !== 200) {
|
||||
reject(res.msg || '未知错误')
|
||||
return
|
||||
}
|
||||
user.value = res.data.profile
|
||||
resolve(res.data.profile)
|
||||
}).catch(err => reject(err || '未知错误'))
|
||||
})
|
||||
}
|
||||
|
||||
const logout = () => new Promise<void>(resolve => {
|
||||
token.value = null
|
||||
user.value = {} as UserSchema
|
||||
is_logged_in.value = false
|
||||
resolve()
|
||||
})
|
||||
|
||||
return {
|
||||
is_logged_in,
|
||||
token,
|
||||
user,
|
||||
checkSession,
|
||||
updateProfile,
|
||||
logout
|
||||
}
|
||||
}, {
|
||||
persist: {
|
||||
key: 'xsh_assistant_persisted_state',
|
||||
storage: persistedState.localStorage,
|
||||
paths: ['token', 'user']
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user