first commit

This commit is contained in:
2025-07-08 00:52:10 +08:00
commit aa2416c5d6
69 changed files with 16628 additions and 0 deletions

View File

@@ -0,0 +1,248 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { adminAPI } from '@/utils/api'
import { adminAuth } from '@/utils/auth'
import type { User, PaginatedResponse } from '@/types'
export const useAdminStore = defineStore('admin', () => {
// 状态
const admin = ref<User | null>(null)
const token = ref<string | null>(null)
const loading = ref(false)
const error = ref<string | null>(null)
const users = ref<User[]>([])
const pagination = ref({
page: 1,
limit: 10,
total: 0,
totalPages: 0
})
// 计算属性
const isLoggedIn = computed(() => !!token.value && !!admin.value)
// 初始化认证状态
const initAuth = () => {
const storedToken = adminAuth.getToken()
const storedAdmin = adminAuth.getAdminInfo()
if (storedToken && storedAdmin) {
token.value = storedToken
admin.value = storedAdmin
}
}
// 管理员登录
const login = async (data: { username: string; password: string }) => {
loading.value = true
error.value = null
try {
const response = await adminAPI.login(data)
// 保存认证信息
token.value = response.token
admin.value = response.admin
adminAuth.setLogin(response.token, response.admin)
return response
} catch (err: any) {
error.value = err.response?.data?.message || '登录失败'
throw err
} finally {
loading.value = false
}
}
// 管理员登出
const logout = async () => {
loading.value = true
error.value = null
try {
// 清除本地状态
token.value = null
admin.value = null
users.value = []
adminAuth.logout()
} catch (err) {
console.warn('Admin logout failed:', err)
} finally {
loading.value = false
}
}
// 获取用户列表
const loadUsers = async (params?: { page?: number; limit?: number; search?: string }) => {
loading.value = true
error.value = null
try {
const response = await adminAPI.getUsers(params)
users.value = response.users
pagination.value = response.pagination
return response
} catch (err: any) {
error.value = err.response?.data?.message || '获取用户列表失败'
throw err
} finally {
loading.value = false
}
}
// 创建用户
const createUser = async (data: {
username: string
password: string
role: string
}) => {
loading.value = true
error.value = null
try {
const response = await adminAPI.createUser(data)
// 重新加载用户列表
await loadUsers()
return response
} catch (err: any) {
error.value = err.response?.data?.message || '创建用户失败'
throw err
} finally {
loading.value = false
}
}
// 更新用户
const updateUser = async (userId: string, data: any) => {
loading.value = true
error.value = null
try {
const response = await adminAPI.updateUser(userId, data)
// 重新加载用户列表
await loadUsers()
return response
} catch (err: any) {
error.value = err.response?.data?.message || '更新用户失败'
throw err
} finally {
loading.value = false
}
}
// 更新用户账号权限
const updateUserAccounts = async (userId: string, accountIds: string[]) => {
loading.value = true
error.value = null
try {
const response = await adminAPI.updateUserAccounts(userId, accountIds)
// 重新加载用户列表
await loadUsers()
return response
} catch (err: any) {
error.value = err.response?.data?.message || '更新用户账号权限失败'
throw err
} finally {
loading.value = false
}
}
// 删除用户
const deleteUser = async (userId: string) => {
loading.value = true
error.value = null
try {
const response = await adminAPI.deleteUser(userId)
// 重新加载用户列表
await loadUsers()
return response
} catch (err: any) {
error.value = err.response?.data?.message || '删除用户失败'
throw err
} finally {
loading.value = false
}
}
// 获取统计数据
const getStats = async () => {
loading.value = true
error.value = null
try {
const response = await adminAPI.getStats()
return response
} catch (err: any) {
error.value = err.response?.data?.message || '获取统计数据失败'
throw err
} finally {
loading.value = false
}
}
// 获取最近活动
const getRecentActivities = async () => {
loading.value = true
error.value = null
try {
const response = await adminAPI.getRecentActivities()
return response
} catch (err: any) {
error.value = err.response?.data?.message || '获取最近活动失败'
throw err
} finally {
loading.value = false
}
}
// 获取账号列表
const getAccounts = async (params?: { page?: number; limit?: number; search?: string; status?: string }) => {
loading.value = true
error.value = null
try {
const response = await adminAPI.getAccounts(params)
return response
} catch (err: any) {
error.value = err.response?.data?.message || '获取账号列表失败'
throw err
} finally {
loading.value = false
}
}
// 清除错误
const clearError = () => {
error.value = null
}
return {
// 状态
admin,
token,
loading,
error,
users,
pagination,
// 计算属性
isLoggedIn,
// 方法
initAuth,
login,
logout,
loadUsers,
createUser,
updateUser,
updateUserAccounts,
deleteUser,
getStats,
getRecentActivities,
getAccounts,
clearError
}
})

247
frontend/src/stores/auth.ts Normal file
View File

@@ -0,0 +1,247 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { authAPI } from '@/utils/api'
import { userAuth } from '@/utils/auth'
import type { User } from '@/types'
export const useAuthStore = defineStore('auth', () => {
// 状态
const user = ref<User | null>(null)
const token = ref<string | null>(null)
const loading = ref(false)
const error = ref<string | null>(null)
// 计算属性
const isLoggedIn = computed(() => !!token.value && !!user.value)
// 初始化认证状态
const initAuth = () => {
const storedToken = userAuth.getToken()
const storedUser = userAuth.getUserInfo()
if (storedToken && storedUser) {
token.value = storedToken
user.value = storedUser
} else {
}
}
// 用户注册
const register = async (data: {
username: string
password: string
confirmPassword: string
}) => {
loading.value = true
error.value = null
try {
const response = await authAPI.register(data)
return response
} catch (err: any) {
error.value = err.response?.data?.message || '注册失败'
throw err
} finally {
loading.value = false
}
}
// 用户登录
const login = async (data: {
username: string
password: string
}) => {
loading.value = true
error.value = null
try {
const response = await authAPI.login(data)
// 保存认证信息
token.value = response.token
user.value = response.user
userAuth.setLogin(response.token, response.user)
return response
} catch (err: any) {
throw err
} finally {
loading.value = false
}
}
// 邮箱验证
const verifyEmail = async (token: string) => {
loading.value = true
error.value = null
try {
const response = await authAPI.verifyEmail(token)
return response
} catch (err: any) {
error.value = err.response?.data?.message || '邮箱验证失败'
throw err
} finally {
loading.value = false
}
}
// 重新发送验证邮件
const resendVerification = async (email: string) => {
loading.value = true
error.value = null
try {
const response = await authAPI.resendVerification(email)
return response
} catch (err: any) {
error.value = err.response?.data?.message || '发送验证邮件失败'
throw err
} finally {
loading.value = false
}
}
// 忘记密码
const forgotPassword = async (email: string) => {
loading.value = true
error.value = null
try {
const response = await authAPI.forgotPassword(email)
return response
} catch (err: any) {
error.value = err.response?.data?.message || '发送重置邮件失败'
throw err
} finally {
loading.value = false
}
}
// 重置密码
const resetPassword = async (data: {
token: string
password: string
}) => {
loading.value = true
error.value = null
try {
const response = await authAPI.resetPassword(data)
return response
} catch (err: any) {
error.value = err.response?.data?.message || '重置密码失败'
throw err
} finally {
loading.value = false
}
}
// 设置TOTP
const setupTOTP = async () => {
loading.value = true
error.value = null
try {
const response = await authAPI.setupTOTP()
return response
} catch (err: any) {
error.value = err.response?.data?.message || '设置二步验证失败'
throw err
} finally {
loading.value = false
}
}
// 验证TOTP
const verifyTOTP = async (totpToken: string) => {
loading.value = true
error.value = null
try {
const response = await authAPI.verifyTOTP(totpToken)
// 更新用户信息
if (user.value && token.value) {
user.value.totpEnabled = true
userAuth.setLogin(token.value, user.value)
}
return response
} catch (err: any) {
error.value = err.response?.data?.message || '验证失败'
throw err
} finally {
loading.value = false
}
}
// 获取用户信息
const getProfile = async () => {
loading.value = true
error.value = null
try {
const response = await authAPI.getProfile()
user.value = response.user
if (token.value) {
userAuth.setLogin(token.value, response.user)
}
return response
} catch (err: any) {
error.value = err.response?.data?.message || '获取用户信息失败'
throw err
} finally {
loading.value = false
}
}
// 用户登出
const logout = async () => {
loading.value = true
error.value = null
try {
await authAPI.logout()
} catch (err: any) {
console.error('登出API调用失败:', err)
} finally {
// 清除本地状态
token.value = null
user.value = null
userAuth.logout()
loading.value = false
}
}
// 清除错误
const clearError = () => {
error.value = null
}
return {
// 状态
user,
token,
loading,
error,
// 计算属性
isLoggedIn,
// 方法
initAuth,
register,
login,
verifyEmail,
resendVerification,
forgotPassword,
resetPassword,
setupTOTP,
verifyTOTP,
getProfile,
logout,
clearError
}
})