Files
gamegroup2/frontend/src/stores/user.ts
T

136 lines
3.7 KiB
TypeScript
Raw Normal View History

// src/stores/user.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { User, UserStatus, WorkSchedule } from '@/types'
import { pb, getCurrentUser, isAuthenticated, logout as pbLogout } from '@/api/pocketbase'
import { getUser, updateUserStatus, updateWorkSchedule } from '@/api/users'
export const useUserStore = defineStore('user', () => {
// 状态
const user = ref<User | null>(null)
const loading = ref(false)
// 计算属性
const isLoggedIn = computed(() => isAuthenticated() && user.value !== null)
const userStatus = computed(() => user.value?.status || 'idle')
const userId = computed(() => user.value?.id || '')
// 初始化用户信息
async function initUser() {
if (!isAuthenticated()) {
user.value = null
return
}
try {
loading.value = true
const authUser = getCurrentUser() as User
// 获取完整用户信息
user.value = await getUser(authUser.id)
} catch (error) {
console.error('初始化用户信息失败:', error)
user.value = null
} finally {
loading.value = false
}
}
// 登录
async function login(email: string, password: string) {
try {
loading.value = true
await pb.collection('users').authWithPassword(email, password)
await initUser()
// 首次登录设置默认状态为空闲
if (user.value && !user.value.status) {
await setStatus('idle')
}
} catch (error: any) {
throw new Error('邮箱或密码错误')
} finally {
loading.value = false
}
}
// 注册
async function register(data: { email: string; password: string; passwordConfirm: string; username: string }) {
try {
loading.value = true
await pb.collection('users').create(data)
await login(data.email, data.password)
} catch (error: any) {
const validation = error?.data?.data || error?.data
if (validation) {
const messages: string[] = []
if (validation.email) messages.push('邮箱无效或已被使用')
if (validation.username) messages.push('用户名无效或已被使用')
if (validation.password) messages.push('密码不符合要求')
if (messages.length > 0) throw new Error(messages.join(''))
}
throw new Error(error.message || '注册失败')
} finally {
loading.value = false
}
}
// 登出
function logout() {
pbLogout()
user.value = null
}
// 更新状态
async function setStatus(status: UserStatus, note?: string) {
try {
const updated = await updateUserStatus(status, note)
if (user.value) {
user.value.status = status
user.value.statusNote = note
}
return updated
} catch (error: any) {
throw new Error(error.message || '更新状态失败')
}
}
// 更新工作时间
async function setWorkSchedule(schedule: WorkSchedule) {
try {
const updated = await updateWorkSchedule(schedule)
if (user.value) {
user.value.workdays = schedule.workdays
user.value.workStartTime = schedule.workStartTime
user.value.nextWorkTime = updated.nextWorkTime
}
return updated
} catch (error: any) {
throw new Error(error.message || '更新工作时间失败')
}
}
// 检查并自动更新工作时间状态
function checkWorkSchedule() {
if (!user.value || !user.value.nextWorkTime) return
const now = Math.floor(Date.now() / 1000)
if (now >= user.value.nextWorkTime && user.value.status === 'idle') {
setStatus('working')
}
}
return {
user,
loading,
isLoggedIn,
userStatus,
userId,
initUser,
login,
register,
logout,
setStatus,
setWorkSchedule,
checkWorkSchedule
}
})