172 lines
4.8 KiB
JavaScript
172 lines
4.8 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { computed, ref } from 'vue'
|
|
import { AUTH_API, TOKEN_KEY, REFRESH_TOKEN_KEY, USER_INFO_KEY } from '@/config/api'
|
|
import { request, parseResponseJson } from '@/utils/request'
|
|
import { buildMiniEncryptedLoginBody } from '@/utils/loginRsa'
|
|
|
|
const PAGE_PATHS = {
|
|
login: '/pages/login/login',
|
|
home: '/pages/home/home'
|
|
}
|
|
|
|
export const useUserStore = defineStore('user', () => {
|
|
const token = ref('')
|
|
const refreshToken = ref('')
|
|
const userInfo = ref(null)
|
|
const isLoading = ref(false)
|
|
|
|
function normalizeUserInfo(raw) {
|
|
if (!raw || typeof raw !== 'object') return raw || null
|
|
const avatarUrl =
|
|
raw.avatarUrl != null && String(raw.avatarUrl).trim()
|
|
? String(raw.avatarUrl).trim()
|
|
: raw.avatar_url != null && String(raw.avatar_url).trim()
|
|
? String(raw.avatar_url).trim()
|
|
: ''
|
|
return {
|
|
...raw,
|
|
avatarUrl
|
|
}
|
|
}
|
|
|
|
const isLoggedIn = computed(() => !!token.value && !!userInfo.value)
|
|
const userRole = computed(() => userInfo.value?.role || '')
|
|
const homePath = computed(() => PAGE_PATHS.home)
|
|
|
|
function checkLoginStatus() {
|
|
const savedToken = uni.getStorageSync(TOKEN_KEY)
|
|
const savedUserInfo = uni.getStorageSync(USER_INFO_KEY)
|
|
const savedRefreshToken = uni.getStorageSync(REFRESH_TOKEN_KEY)
|
|
const normalizedToken =
|
|
typeof savedToken === 'string' ? savedToken.trim() : savedToken ? String(savedToken).trim() : ''
|
|
|
|
let normalizedUserInfo = null
|
|
if (typeof savedUserInfo === 'string') {
|
|
try {
|
|
normalizedUserInfo = normalizeUserInfo(JSON.parse(savedUserInfo))
|
|
} catch (error) {
|
|
normalizedUserInfo = null
|
|
}
|
|
} else if (savedUserInfo && typeof savedUserInfo === 'object') {
|
|
normalizedUserInfo = normalizeUserInfo(savedUserInfo)
|
|
}
|
|
|
|
if (normalizedToken && normalizedUserInfo) {
|
|
token.value = normalizedToken
|
|
refreshToken.value = typeof savedRefreshToken === 'string' ? savedRefreshToken : ''
|
|
userInfo.value = normalizedUserInfo
|
|
return
|
|
}
|
|
|
|
token.value = ''
|
|
refreshToken.value = ''
|
|
userInfo.value = null
|
|
}
|
|
|
|
function setLoginInfo(data) {
|
|
token.value = data.token || ''
|
|
refreshToken.value = data.refreshToken || ''
|
|
userInfo.value = normalizeUserInfo(data.userInfo || null)
|
|
uni.setStorageSync(TOKEN_KEY, token.value)
|
|
uni.setStorageSync(REFRESH_TOKEN_KEY, refreshToken.value)
|
|
uni.setStorageSync(USER_INFO_KEY, userInfo.value)
|
|
}
|
|
|
|
async function login(params) {
|
|
isLoading.value = true
|
|
try {
|
|
const encryptedBody = await buildMiniEncryptedLoginBody(params.username, params.password)
|
|
const res = await request({
|
|
url: AUTH_API.LOGIN,
|
|
method: 'POST',
|
|
data: encryptedBody
|
|
})
|
|
const result = parseResponseJson(res)
|
|
if (result && result.code === 200 && result.data) {
|
|
setLoginInfo({
|
|
token: result.data.token,
|
|
refreshToken: result.data.refreshToken,
|
|
userInfo: result.data.userInfo
|
|
})
|
|
return true
|
|
}
|
|
uni.showToast({ title: (result && result.message) || '登录失败', icon: 'none' })
|
|
return false
|
|
} catch (error) {
|
|
uni.showToast({
|
|
title: (error && error.message) || '网络请求失败',
|
|
icon: 'none'
|
|
})
|
|
return false
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
function clearLoginInfo() {
|
|
token.value = ''
|
|
refreshToken.value = ''
|
|
userInfo.value = null
|
|
uni.removeStorageSync(TOKEN_KEY)
|
|
uni.removeStorageSync(REFRESH_TOKEN_KEY)
|
|
uni.removeStorageSync(USER_INFO_KEY)
|
|
}
|
|
|
|
async function logout() {
|
|
try {
|
|
await request({
|
|
url: AUTH_API.LOGOUT,
|
|
method: 'POST'
|
|
})
|
|
} catch (error) {
|
|
// ignore
|
|
} finally {
|
|
clearLoginInfo()
|
|
uni.reLaunch({ url: PAGE_PATHS.login })
|
|
}
|
|
}
|
|
|
|
function navigateToHome() {
|
|
uni.reLaunch({ url: homePath.value })
|
|
}
|
|
|
|
function updateUserInfo(info) {
|
|
if (!userInfo.value || !info) return
|
|
userInfo.value = normalizeUserInfo({ ...userInfo.value, ...info })
|
|
uni.setStorageSync(USER_INFO_KEY, userInfo.value)
|
|
}
|
|
|
|
async function refreshUserInfo() {
|
|
if (!token.value || !String(token.value).trim()) return
|
|
try {
|
|
const res = await request({
|
|
url: AUTH_API.CURRENT_USER,
|
|
method: 'GET'
|
|
})
|
|
const result = parseResponseJson(res)
|
|
if (result.code !== 200 || !result.data) return
|
|
userInfo.value = normalizeUserInfo(result.data)
|
|
uni.setStorageSync(USER_INFO_KEY, userInfo.value)
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
return {
|
|
token,
|
|
refreshToken,
|
|
userInfo,
|
|
isLoading,
|
|
isLoggedIn,
|
|
userRole,
|
|
homePath,
|
|
checkLoginStatus,
|
|
login,
|
|
logout,
|
|
clearLoginInfo,
|
|
navigateToHome,
|
|
updateUserInfo,
|
|
refreshUserInfo
|
|
}
|
|
})
|