6b684f8600
- Remove loadFromCookie that overwrites valid localStorage auth data - Set user status to idle on first login (was empty string) - Default empty status to idle instead of away Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
136 lines
3.7 KiB
TypeScript
136 lines
3.7 KiB
TypeScript
// 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
|
||
}
|
||
})
|