topfans/frontend/store/modules/user.js
2026-04-07 23:08:49 +08:00

221 lines
6.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { loginApi, registerApi, getOssPresignedUrlApi } from '@/utils/api'
import { downloadAndCacheAvatar } from '@/utils/avatarCache'
const state = {
token: uni.getStorageSync('access_token') || '',
starId: uni.getStorageSync('star_id') || null,
userInfo: (() => {
const userStr = uni.getStorageSync('user')
if (userStr) {
try {
return JSON.parse(userStr)
} catch (e) {
return null
}
}
return null
})()
}
const getters = {
isLoggedIn: (state) => {
return !!state.token
}
}
const mutations = {
SET_TOKEN(state, token) {
state.token = token
// 缓存到 storage
if (token) {
uni.setStorageSync('access_token', token)
} else {
uni.removeStorageSync('access_token')
}
},
SET_USER_INFO(state, userInfo) {
state.userInfo = userInfo
// 缓存到 storage
if (userInfo) {
uni.setStorageSync('user', JSON.stringify(userInfo))
// 单独缓存 star_id方便其他地方直接读取
const starId = userInfo?.fan_identity?.star_id ?? null
state.starId = starId
if (starId !== null) {
uni.setStorageSync('star_id', starId)
} else {
uni.removeStorageSync('star_id')
}
} else {
uni.removeStorageSync('user')
uni.removeStorageSync('star_id')
state.starId = null
}
},
CLEAR_AUTH(state) {
state.token = ''
state.userInfo = null
state.starId = null
// 清除 storage
uni.removeStorageSync('access_token')
uni.removeStorageSync('user')
uni.removeStorageSync('star_id')
// 清除登录手机号
uni.removeStorageSync('login_mobile')
}
}
const actions = {
// 登录
async login({ commit }, { mobile, password }) {
try {
const res = await loginApi(mobile, password)
if (res.code === 200 && res.data) {
// 缓存 access_token
const accessToken = res.data.access_token
uni.setStorageSync('access_token', accessToken)
commit('SET_TOKEN', accessToken)
// 缓存登录手机号
uni.setStorageSync('login_mobile', mobile)
// 缓存用户信息
const user = res.data.user
uni.setStorageSync('user', JSON.stringify(user))
commit('SET_USER_INFO', user)
// 处理头像缓存
if (user.avatar_url) {
try {
// 获取真实的预签名URL
const urlRes = await getOssPresignedUrlApi(user.avatar_url, 3600, 'avatar')
if (urlRes.code === 200 && urlRes.data && urlRes.data.url) {
// 下载并缓存头像
const localPath = await downloadAndCacheAvatar(user.avatar_url, urlRes.data.url)
// 触发头像更新事件通知Header刷新
setTimeout(() => {
uni.$emit('avatarUpdated', {
uid: user.uid,
avatarUrl: user.avatar_url,
localPath: localPath
})
}, 100)
}
} catch (avatarError) {
console.error('头像缓存失败,但不影响登录:', avatarError)
// 头像缓存失败不影响登录流程
}
}
return Promise.resolve(res)
} else {
// 返回错误信息,包含 message
return Promise.reject(new Error(res.message || '登录失败'))
}
} catch (error) {
// 处理网络错误或HTTP错误
// 如果错误响应包含 message使用它否则使用默认错误信息
if (error.message) {
return Promise.reject(new Error(error.message))
}
return Promise.reject(new Error('登录失败,请检查网络连接'))
}
},
// 注册
async register({ commit }, { mobile, password, star_id, nickname }) {
try {
const res = await registerApi(mobile, password, star_id, nickname)
if (res.code === 200 && res.data) {
// 缓存 access_token
const accessToken = res.data.access_token
uni.setStorageSync('access_token', accessToken)
commit('SET_TOKEN', accessToken)
// 缓存登录手机号
uni.setStorageSync('login_mobile', mobile)
// 缓存用户信息
const user = res.data.user
uni.setStorageSync('user', JSON.stringify(user))
commit('SET_USER_INFO', user)
// 处理头像缓存
if (user.avatar_url) {
try {
// 获取真实的预签名URL
const urlRes = await getOssPresignedUrlApi(user.avatar_url, 3600, 'avatar')
if (urlRes.code === 200 && urlRes.data && urlRes.data.url) {
// 下载并缓存头像
const localPath = await downloadAndCacheAvatar(user.avatar_url, urlRes.data.url)
// 触发头像更新事件通知Header刷新
setTimeout(() => {
uni.$emit('avatarUpdated', {
uid: user.uid,
avatarUrl: user.avatar_url,
localPath: localPath
})
}, 100)
}
} catch (avatarError) {
console.error('头像缓存失败,但不影响注册:', avatarError)
// 头像缓存失败不影响注册流程
}
}
return Promise.resolve(res)
} else {
// 处理昵称已存在的情况
if (res.code === 409) {
return Promise.reject({ code: 409, message: res.message || '昵称已存在' })
}
return Promise.reject(new Error(res.message || '注册失败'))
}
} catch (error) {
// 处理HTTP 409错误
if (error.statusCode === 409 || error.code === 409) {
return Promise.reject({ code: 409, message: error.message || '昵称已存在' })
}
return Promise.reject(error)
}
},
// 登出
logout({ commit }) {
commit('CLEAR_AUTH')
},
// 检查登录状态(从 storage 恢复)
checkLoginStatus({ commit, state }) {
// 从 storage 恢复 token
const token = uni.getStorageSync('access_token')
if (token && token !== state.token) {
commit('SET_TOKEN', token)
}
// 从 storage 恢复 userInfo
const userStr = uni.getStorageSync('user')
if (userStr) {
try {
const userInfo = JSON.parse(userStr)
if (userInfo && (!state.userInfo || JSON.stringify(userInfo) !== JSON.stringify(state.userInfo))) {
commit('SET_USER_INFO', userInfo)
}
} catch (e) {
console.error('恢复用户信息失败:', e)
}
}
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}