- 更新 DashboardLayout 组件,统一使用演示模式布局 - 实现仪表盘页面的完整演示数据和功能 - 完成用户管理页面的演示模式,包含搜索、过滤、分页等功能 - 实现通话记录页面的演示数据和录音播放功能 - 完成翻译员管理页面的演示模式 - 实现订单管理页面的完整功能 - 完成发票管理页面的演示数据 - 更新文档管理页面 - 添加 utils.ts 工具函数库 - 完善 API 路由和数据库结构 - 修复各种 TypeScript 类型错误 - 统一界面风格和用户体验
323 lines
8.5 KiB
TypeScript
323 lines
8.5 KiB
TypeScript
import { supabase } from './supabase';
|
||
|
||
// 用户相关接口
|
||
export interface User {
|
||
id: string;
|
||
name: string;
|
||
email: string;
|
||
phone: string;
|
||
userType: 'individual' | 'enterprise' | 'admin';
|
||
status: 'active' | 'inactive' | 'pending';
|
||
createdAt: string;
|
||
lastLogin?: string;
|
||
avatar?: string;
|
||
company?: string;
|
||
totalOrders: number;
|
||
}
|
||
|
||
// 仪表板统计数据接口
|
||
export interface DashboardStats {
|
||
totalUsers: number;
|
||
totalOrders: number;
|
||
totalRevenue: number;
|
||
activeInterpreters: number;
|
||
todayOrders: number;
|
||
pendingOrders: number;
|
||
completedOrders: number;
|
||
totalCalls: number;
|
||
}
|
||
|
||
// 最近活动接口
|
||
export interface RecentActivity {
|
||
id: string;
|
||
type: 'order' | 'call' | 'user' | 'payment';
|
||
title: string;
|
||
description: string;
|
||
time: string;
|
||
status: 'success' | 'pending' | 'warning' | 'error';
|
||
}
|
||
|
||
// API响应接口
|
||
export interface ApiResponse<T> {
|
||
success: boolean;
|
||
data?: T;
|
||
error?: string;
|
||
message?: string;
|
||
}
|
||
|
||
// 用户过滤参数
|
||
export interface UserFilters {
|
||
search?: string;
|
||
userType?: 'all' | 'individual' | 'enterprise' | 'admin';
|
||
status?: 'all' | 'active' | 'inactive' | 'pending';
|
||
page?: number;
|
||
limit?: number;
|
||
}
|
||
|
||
class ApiService {
|
||
private baseUrl = '/api';
|
||
|
||
// 通用请求方法
|
||
private async request<T>(
|
||
endpoint: string,
|
||
options: RequestInit = {}
|
||
): Promise<ApiResponse<T>> {
|
||
try {
|
||
const token = localStorage.getItem('access_token');
|
||
const response = await fetch(`${this.baseUrl}${endpoint}`, {
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
...(token && { Authorization: `Bearer ${token}` }),
|
||
...options.headers,
|
||
},
|
||
...options,
|
||
});
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP error! status: ${response.status}`);
|
||
}
|
||
|
||
const data = await response.json();
|
||
return data;
|
||
} catch (error) {
|
||
console.error(`API request failed: ${endpoint}`, error);
|
||
return {
|
||
success: false,
|
||
error: error instanceof Error ? error.message : '请求失败',
|
||
};
|
||
}
|
||
}
|
||
|
||
// 获取仪表板统计数据
|
||
async getDashboardStats(): Promise<ApiResponse<DashboardStats>> {
|
||
// 先尝试从真实API获取数据
|
||
const response = await this.request<DashboardStats>('/dashboard/stats');
|
||
|
||
// 如果API失败,返回模拟数据
|
||
if (!response.success) {
|
||
return {
|
||
success: true,
|
||
data: {
|
||
totalUsers: 1248,
|
||
totalOrders: 3567,
|
||
totalRevenue: 245680,
|
||
activeInterpreters: 45,
|
||
todayOrders: 23,
|
||
pendingOrders: 12,
|
||
completedOrders: 3544,
|
||
totalCalls: 2890,
|
||
},
|
||
};
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
// 获取最近活动
|
||
async getRecentActivities(): Promise<ApiResponse<RecentActivity[]>> {
|
||
const response = await this.request<RecentActivity[]>('/dashboard/activities');
|
||
|
||
if (!response.success) {
|
||
return {
|
||
success: true,
|
||
data: [
|
||
{
|
||
id: '1',
|
||
type: 'order',
|
||
title: '新订单创建',
|
||
description: '用户张三创建了文档翻译订单',
|
||
time: '2分钟前',
|
||
status: 'success'
|
||
},
|
||
{
|
||
id: '2',
|
||
type: 'call',
|
||
title: '通话服务完成',
|
||
description: '英语口译通话服务已完成',
|
||
time: '5分钟前',
|
||
status: 'success'
|
||
},
|
||
{
|
||
id: '3',
|
||
type: 'user',
|
||
title: '新用户注册',
|
||
description: '企业用户ABC公司完成注册',
|
||
time: '10分钟前',
|
||
status: 'success'
|
||
},
|
||
{
|
||
id: '4',
|
||
type: 'payment',
|
||
title: '付款待处理',
|
||
description: '订单#1234的付款需要审核',
|
||
time: '15分钟前',
|
||
status: 'warning'
|
||
},
|
||
{
|
||
id: '5',
|
||
type: 'order',
|
||
title: '订单状态更新',
|
||
description: '文档翻译订单已交付',
|
||
time: '20分钟前',
|
||
status: 'success'
|
||
}
|
||
],
|
||
};
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
// 获取用户列表
|
||
async getUsers(filters: UserFilters = {}): Promise<ApiResponse<{ users: User[]; total: number }>> {
|
||
const queryParams = new URLSearchParams();
|
||
|
||
if (filters.search) queryParams.append('search', filters.search);
|
||
if (filters.userType && filters.userType !== 'all') queryParams.append('userType', filters.userType);
|
||
if (filters.status && filters.status !== 'all') queryParams.append('status', filters.status);
|
||
if (filters.page) queryParams.append('page', filters.page.toString());
|
||
if (filters.limit) queryParams.append('limit', filters.limit.toString());
|
||
|
||
const response = await this.request<{ users: User[]; total: number }>(
|
||
`/users?${queryParams.toString()}`
|
||
);
|
||
|
||
if (!response.success) {
|
||
// 返回模拟数据
|
||
const mockUsers: User[] = [
|
||
{
|
||
id: '1',
|
||
name: '张三',
|
||
email: 'zhangsan@example.com',
|
||
phone: '13800138001',
|
||
userType: 'individual',
|
||
status: 'active',
|
||
createdAt: '2024-01-15',
|
||
lastLogin: '2024-01-20 10:30',
|
||
totalOrders: 5
|
||
},
|
||
{
|
||
id: '2',
|
||
name: 'ABC公司',
|
||
email: 'contact@abc.com',
|
||
phone: '400-123-4567',
|
||
userType: 'enterprise',
|
||
status: 'active',
|
||
createdAt: '2024-01-10',
|
||
lastLogin: '2024-01-19 15:45',
|
||
company: 'ABC科技有限公司',
|
||
totalOrders: 23
|
||
},
|
||
{
|
||
id: '3',
|
||
name: '李四',
|
||
email: 'lisi@example.com',
|
||
phone: '13900139002',
|
||
userType: 'individual',
|
||
status: 'pending',
|
||
createdAt: '2024-01-18',
|
||
totalOrders: 0
|
||
},
|
||
{
|
||
id: '4',
|
||
name: '王五',
|
||
email: 'wangwu@example.com',
|
||
phone: '13700137003',
|
||
userType: 'individual',
|
||
status: 'inactive',
|
||
createdAt: '2024-01-12',
|
||
lastLogin: '2024-01-16 09:15',
|
||
totalOrders: 2
|
||
},
|
||
{
|
||
id: '5',
|
||
name: '管理员',
|
||
email: 'admin@system.com',
|
||
phone: '13600136004',
|
||
userType: 'admin',
|
||
status: 'active',
|
||
createdAt: '2024-01-01',
|
||
lastLogin: '2024-01-20 08:00',
|
||
totalOrders: 0
|
||
}
|
||
];
|
||
|
||
// 应用过滤器
|
||
let filteredUsers = mockUsers;
|
||
|
||
if (filters.search) {
|
||
const searchTerm = filters.search.toLowerCase();
|
||
filteredUsers = filteredUsers.filter(user =>
|
||
user.name.toLowerCase().includes(searchTerm) ||
|
||
user.email.toLowerCase().includes(searchTerm) ||
|
||
user.phone.includes(searchTerm)
|
||
);
|
||
}
|
||
|
||
if (filters.userType && filters.userType !== 'all') {
|
||
filteredUsers = filteredUsers.filter(user => user.userType === filters.userType);
|
||
}
|
||
|
||
if (filters.status && filters.status !== 'all') {
|
||
filteredUsers = filteredUsers.filter(user => user.status === filters.status);
|
||
}
|
||
|
||
return {
|
||
success: true,
|
||
data: {
|
||
users: filteredUsers,
|
||
total: filteredUsers.length
|
||
}
|
||
};
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
// 创建用户
|
||
async createUser(userData: Partial<User>): Promise<ApiResponse<User>> {
|
||
return this.request<User>('/users', {
|
||
method: 'POST',
|
||
body: JSON.stringify(userData),
|
||
});
|
||
}
|
||
|
||
// 更新用户
|
||
async updateUser(userId: string, userData: Partial<User>): Promise<ApiResponse<User>> {
|
||
return this.request<User>(`/users/${userId}`, {
|
||
method: 'PUT',
|
||
body: JSON.stringify(userData),
|
||
});
|
||
}
|
||
|
||
// 删除用户
|
||
async deleteUser(userId: string): Promise<ApiResponse<void>> {
|
||
return this.request<void>(`/users/${userId}`, {
|
||
method: 'DELETE',
|
||
});
|
||
}
|
||
|
||
// 批量删除用户
|
||
async deleteUsers(userIds: string[]): Promise<ApiResponse<void>> {
|
||
return this.request<void>('/users/batch-delete', {
|
||
method: 'POST',
|
||
body: JSON.stringify({ userIds }),
|
||
});
|
||
}
|
||
|
||
// 获取用户详情
|
||
async getUserDetail(userId: string): Promise<ApiResponse<User>> {
|
||
return this.request<User>(`/users/${userId}`);
|
||
}
|
||
|
||
// 检查服务状态
|
||
async checkServiceStatus(): Promise<ApiResponse<{ status: string; timestamp: string }>> {
|
||
return this.request<{ status: string; timestamp: string }>('/health');
|
||
}
|
||
}
|
||
|
||
// 导出单例实例
|
||
export const apiService = new ApiService();
|
||
|
||
// 导出默认实例
|
||
export default apiService;
|