- 更新 DashboardLayout 组件,统一使用演示模式布局 - 实现仪表盘页面的完整演示数据和功能 - 完成用户管理页面的演示模式,包含搜索、过滤、分页等功能 - 实现通话记录页面的演示数据和录音播放功能 - 完成翻译员管理页面的演示模式 - 实现订单管理页面的完整功能 - 完成发票管理页面的演示数据 - 更新文档管理页面 - 添加 utils.ts 工具函数库 - 完善 API 路由和数据库结构 - 修复各种 TypeScript 类型错误 - 统一界面风格和用户体验
118 lines
3.2 KiB
TypeScript
118 lines
3.2 KiB
TypeScript
import { NextApiRequest, NextApiResponse } from 'next'
|
|
import { auth, db } from './supabase'
|
|
import { Database } from '../types/database'
|
|
|
|
// 用户类型定义
|
|
export type User = Database['public']['Tables']['users']['Row']
|
|
|
|
// API响应类型
|
|
export interface ApiResponse<T = any> {
|
|
success: boolean
|
|
data?: T
|
|
error?: string
|
|
message?: string
|
|
}
|
|
|
|
// 认证中间件
|
|
export async function authenticateUser(req: NextApiRequest, res: NextApiResponse) {
|
|
try {
|
|
const user = await auth.getCurrentUser()
|
|
if (!user) {
|
|
res.status(401).json({
|
|
success: false,
|
|
error: '未登录'
|
|
})
|
|
return null
|
|
}
|
|
return user
|
|
} catch (error) {
|
|
console.error('Authentication error:', error)
|
|
res.status(401).json({
|
|
success: false,
|
|
error: '认证失败'
|
|
})
|
|
return null
|
|
}
|
|
}
|
|
|
|
// 获取用户详细信息
|
|
export async function getUserProfile(userId: string): Promise<User | null> {
|
|
try {
|
|
const users = await db.select<User>('users', '*')
|
|
return users.find(user => user.id === userId) || null
|
|
} catch (error) {
|
|
console.error('Get user profile error:', error)
|
|
return null
|
|
}
|
|
}
|
|
|
|
// 错误处理函数
|
|
export function handleApiError(res: NextApiResponse, error: unknown, context: string) {
|
|
console.error(`${context} error:`, error)
|
|
|
|
const errorMessage = error instanceof Error ? error.message : '未知错误'
|
|
|
|
// 处理Supabase特定错误
|
|
if (errorMessage.includes('Invalid login credentials')) {
|
|
return res.status(401).json({
|
|
success: false,
|
|
error: '邮箱或密码错误'
|
|
})
|
|
} else if (errorMessage.includes('Email not confirmed')) {
|
|
return res.status(401).json({
|
|
success: false,
|
|
error: '请先验证邮箱'
|
|
})
|
|
} else if (errorMessage.includes('Too many requests')) {
|
|
return res.status(429).json({
|
|
success: false,
|
|
error: '请求过于频繁,请稍后再试'
|
|
})
|
|
} else if (errorMessage.includes('User already registered')) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: '该邮箱已被注册'
|
|
})
|
|
}
|
|
|
|
return res.status(500).json({
|
|
success: false,
|
|
error: '服务器内部错误',
|
|
details: process.env.NODE_ENV === 'development' ? errorMessage : undefined
|
|
})
|
|
}
|
|
|
|
// 验证邮箱格式
|
|
export function validateEmail(email: string): boolean {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
return emailRegex.test(email)
|
|
}
|
|
|
|
// 验证密码强度
|
|
export function validatePassword(password: string): { valid: boolean; message?: string } {
|
|
if (password.length < 6) {
|
|
return { valid: false, message: '密码长度至少为6位' }
|
|
}
|
|
return { valid: true }
|
|
}
|
|
|
|
// 生成订单号
|
|
export function generateOrderNumber(): string {
|
|
return `ORD-${new Date().getFullYear()}-${String(Date.now()).slice(-6)}`
|
|
}
|
|
|
|
// 计算服务费用
|
|
export function calculateServiceCost(serviceType: string, duration?: number): number {
|
|
switch (serviceType) {
|
|
case 'phone_interpretation':
|
|
return (duration || 30) * 3 // 每分钟3元
|
|
case 'video_interpretation':
|
|
return (duration || 30) * 4 // 每分钟4元
|
|
case 'on_site_interpretation':
|
|
return (duration || 60) * 5 // 每分钟5元
|
|
case 'document_translation':
|
|
return 100 // 固定100元
|
|
default:
|
|
return 0
|
|
}
|
|
}
|