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

294
frontend/src/utils/api.ts Normal file
View File

@@ -0,0 +1,294 @@
import axios, { AxiosInstance, AxiosResponse } from 'axios'
import { userAuth, adminAuth } from './auth'
// API基础配置
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api'
// 创建axios实例
const api: AxiosInstance = axios.create({
baseURL: API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
})
// 请求拦截器 - 添加认证token
api.interceptors.request.use(
(config) => {
// 优先使用管理员token如果没有则使用用户token
let token = adminAuth.getToken()
if (!token) {
token = userAuth.getToken()
}
if (token) {
config.headers.Authorization = `Bearer ${token}`
} else {
}
return config
},
(error) => {
return Promise.reject(error)
}
)
// 响应拦截器 - 处理认证错误
api.interceptors.response.use(
(response: AxiosResponse) => {
return response
},
(error) => {
if (error.response?.status === 401) {
// Token过期或无效清除所有认证状态
userAuth.logout()
adminAuth.logout()
// 自动重定向到登录页面(如果不是已经在登录页面)
if (window.location.pathname !== '/' && window.location.pathname !== '/login') {
window.location.href = '/'
}
}
return Promise.reject(error)
}
)
// 用户认证API
export const authAPI = {
// 用户注册
async register(data: {
username: string
password: string
confirmPassword: string
}) {
// 只发送后端需要的字段
const requestData = {
username: data.username,
password: data.password,
confirmPassword: data.confirmPassword
}
const response = await api.post('/auth/register', requestData)
return response.data
},
// 用户登录
async login(data: {
username: string
password: string
}) {
try {
const response = await api.post('/auth/login', data)
return response.data
} catch (error: any) {
throw error
}
},
// 邮箱验证
async verifyEmail(token: string) {
const response = await api.post('/auth/verify-email', { token })
return response.data
},
// 重新发送验证邮件
async resendVerification(email: string) {
const response = await api.post('/auth/resend-verification', { email })
return response.data
},
// 忘记密码
async forgotPassword(email: string) {
const response = await api.post('/auth/forgot-password', { email })
return response.data
},
// 重置密码
async resetPassword(data: {
token: string
password: string
}) {
const response = await api.post('/auth/reset-password', data)
return response.data
},
// 设置TOTP
async setupTOTP() {
const response = await api.post('/auth/setup-totp')
return response.data
},
// 验证TOTP
async verifyTOTP(token: string) {
const response = await api.post('/auth/verify-totp', { token })
return response.data
},
// 获取用户信息
async getProfile() {
const response = await api.get('/auth/me')
return response.data
},
// 更新用户信息
async updateProfile(data: {
username?: string
email?: string
currentPassword?: string
newPassword?: string
}) {
const response = await api.put('/auth/profile', data)
return response.data
},
// 用户登出
async logout() {
const response = await api.post('/auth/logout')
return response.data
},
// 获取TOTP二维码
async getTOTPQRCode() {
const response = await api.get('/auth/totp/qr-code')
return response.data
},
// 启用TOTP
async enableTOTP(token: string) {
const response = await api.post('/auth/totp/enable', { token })
return response.data
},
// 禁用TOTP
async disableTOTP(password: string) {
const response = await api.post('/auth/totp/disable', { password })
return response.data
}
}
// 账号管理API
export const accountAPI = {
// 获取用户可用账号
async getUserAccounts() {
const response = await api.get('/accounts/user/assigned')
return response.data
},
// 获取账号详情
async getAccountDetails(accountId: string) {
const response = await api.get(`/accounts/${accountId}`)
return response.data
},
// 登录到网站
async loginToWebsite(accountId: string, userId: string) {
const response = await api.post(`/accounts/${accountId}/login`, { userId })
return response.data
}
}
// 管理员API
export const adminAPI = {
// 管理员登录
async login(data: { username: string; password: string }) {
const response = await api.post('/admin/login', data)
return response.data
},
// 获取用户列表
async getUsers(params?: { page?: number; limit?: number; search?: string }) {
const response = await api.get('/admin/users', { params })
return response.data
},
// 创建用户
async createUser(data: {
username: string
password: string
role: string
}) {
const response = await api.post('/admin/users', data)
return response.data
},
// 更新用户
async updateUser(userId: string, data: any) {
const response = await api.put(`/admin/users/${userId}`, data)
return response.data
},
// 更新用户账号权限
async updateUserAccounts(userId: string, accountIds: string[]) {
const response = await api.put(`/admin/users/${userId}/accounts`, { accountIds })
return response.data
},
// 删除用户
async deleteUser(userId: string) {
const response = await api.delete(`/admin/users/${userId}`)
return response.data
},
// 获取统计数据
async getStats() {
console.log('发送获取统计数据请求...')
const response = await api.get('/admin/stats')
console.log('统计数据API响应:', response.data)
return response.data
},
// 获取最近活动
async getRecentActivities() {
console.log('发送获取最近活动请求...')
const response = await api.get('/admin/activities')
console.log('最近活动API响应:', response.data)
return response.data
},
// 获取账号列表
async getAccounts(params?: { page?: number; limit?: number; search?: string; status?: string }) {
const response = await api.get('/admin/accounts', { params })
return response.data
},
// 创建账号
async createAccount(data: {
website: string
username: string
token?: string
isActive: boolean
}) {
const requestData = {
website: data.website,
accountName: data.username,
token: data.token,
isActive: data.isActive
}
const response = await api.post('/admin/accounts', requestData)
return response.data
},
// 更新账号
async updateAccount(accountId: string, data: any) {
const response = await api.put(`/admin/accounts/${accountId}`, data)
return response.data
},
// 删除账号
async deleteAccount(accountId: string) {
const response = await api.delete(`/admin/accounts/${accountId}`)
return response.data
}
}
// 路径API
export const pathAPI = {
// 获取路径
async getPaths() {
const response = await api.get('/paths')
return response.data
}
}
export default api

View File

@@ -0,0 +1,96 @@
// 认证工具函数
// 用户认证相关
export const userAuth = {
// 检查用户是否已登录
isLoggedIn(): boolean {
return !!localStorage.getItem('userToken')
},
// 获取用户token
getToken(): string | null {
return localStorage.getItem('userToken')
},
// 获取用户信息
getUserInfo(): any {
const userInfo = localStorage.getItem('userInfo')
return userInfo ? JSON.parse(userInfo) : null
},
// 设置用户登录状态
setLogin(token: string, userInfo: any): void {
localStorage.setItem('userToken', token)
localStorage.setItem('userInfo', JSON.stringify(userInfo))
},
// 清除用户登录状态
logout(): void {
localStorage.removeItem('userToken')
localStorage.removeItem('userInfo')
}
}
// 管理员认证相关
export const adminAuth = {
// 检查管理员是否已登录
isLoggedIn(): boolean {
return !!localStorage.getItem('adminToken')
},
// 获取管理员token
getToken(): string | null {
return localStorage.getItem('adminToken')
},
// 获取管理员信息
getAdminInfo(): any {
try {
const adminInfo = localStorage.getItem('adminUser')
return adminInfo ? JSON.parse(adminInfo) : null
} catch (error) {
console.error('解析管理员信息失败:', error)
// 清除可能损坏的数据
localStorage.removeItem('adminUser')
return null
}
},
// 设置管理员登录状态
setLogin(token: string, adminInfo: any): void {
try {
if (!token || !adminInfo) {
console.error('设置管理员登录状态失败token 或 adminInfo 为空')
return
}
if (!adminInfo.username) {
console.error('设置管理员登录状态失败adminInfo 缺少 username 字段')
return
}
localStorage.setItem('adminToken', token)
localStorage.setItem('adminUser', JSON.stringify(adminInfo))
console.log('管理员登录状态设置成功:', { token, adminInfo })
} catch (error) {
console.error('设置管理员登录状态失败:', error)
}
},
// 清除管理员登录状态
logout(): void {
localStorage.removeItem('adminToken')
localStorage.removeItem('adminUser')
}
}
// 验证管理员凭据
export const validateAdminCredentials = (username: string, password: string): boolean => {
// 这里可以扩展为从API验证
const validCredentials = {
username: 'admin',
password: 'admin123'
}
return username === validCredentials.username && password === validCredentials.password
}