test(web): 添加健康模块 msw handlers — 患者告警预约医生 4 组 mock API

This commit is contained in:
iven
2026-05-03 23:01:57 +08:00
parent 8f7f75ac25
commit 120df86e58
2 changed files with 141 additions and 1 deletions

View File

@@ -1,4 +1,10 @@
import { http, HttpResponse } from 'msw';
import {
patientHandlers,
alertHandlers,
appointmentHandlers,
doctorHandlers,
} from './healthHandlers';
const TOKEN_EXPIRES = 3600;
@@ -27,4 +33,10 @@ export const authHandlers = [
),
];
export const handlers = [...authHandlers];
export const handlers = [
...authHandlers,
...patientHandlers,
...alertHandlers,
...appointmentHandlers,
...doctorHandlers,
];

View File

@@ -0,0 +1,128 @@
import { http, HttpResponse, delay } from 'msw';
const DEFAULT_PAGE_SIZE = 20;
function paginatedResponse<T>(items: T[], total: number, page: number, pageSize = DEFAULT_PAGE_SIZE) {
return HttpResponse.json({
success: true,
data: {
data: items,
total,
page,
page_size: pageSize,
total_pages: Math.ceil(total / pageSize),
},
});
}
// --- 患者列表 ---
const mockPatients = Array.from({ length: 25 }, (_, i) => ({
id: `patient-${i + 1}`,
name: `测试患者${i + 1}`,
gender: i % 2 === 0 ? 'male' : 'female',
birth_date: '1990-01-15',
blood_type: 'A',
status: 'active',
verification_status: i < 20 ? 'verified' : 'pending',
source: 'manual',
created_at: '2026-04-01T10:00:00Z',
updated_at: '2026-04-01T10:00:00Z',
version: 1,
}));
export const patientHandlers = [
http.get('/api/v1/health/patients', async ({ request }) => {
await delay(50);
const url = new URL(request.url);
const page = Number(url.searchParams.get('page') || 1);
const pageSize = Number(url.searchParams.get('page_size') || DEFAULT_PAGE_SIZE);
const start = (page - 1) * pageSize;
const items = mockPatients.slice(start, start + pageSize);
return paginatedResponse(items, mockPatients.length, page, pageSize);
}),
http.get('/api/v1/health/patients/:id', async ({ params }) => {
await delay(50);
const patient = mockPatients.find((p) => p.id === params.id);
if (!patient) return HttpResponse.json({ success: false, error: 'Not found' }, { status: 404 });
return HttpResponse.json({ success: true, data: { ...patient, notes: '', allergy_history: '', medical_history_summary: '' } });
}),
];
// --- 告警列表 ---
const mockAlerts = Array.from({ length: 12 }, (_, i) => ({
id: `alert-${i + 1}`,
patient_id: `patient-${i + 1}`,
patient_name: `测试患者${i + 1}`,
alert_type: i % 3 === 0 ? 'vital_sign' : i % 3 === 1 ? 'lab_result' : 'overdue_followup',
severity: (['low', 'medium', 'high'] as const)[i % 3],
status: i < 8 ? 'active' : 'resolved',
message: `告警消息 ${i + 1}`,
created_at: '2026-04-01T10:00:00Z',
updated_at: '2026-04-01T10:00:00Z',
version: 1,
}));
export const alertHandlers = [
http.get('/api/v1/health/alerts', async ({ request }) => {
await delay(50);
const url = new URL(request.url);
const page = Number(url.searchParams.get('page') || 1);
const pageSize = Number(url.searchParams.get('page_size') || DEFAULT_PAGE_SIZE);
return paginatedResponse(mockAlerts.slice(0, pageSize), mockAlerts.length, page, pageSize);
}),
];
// --- 预约列表 ---
const mockAppointments = Array.from({ length: 15 }, (_, i) => ({
id: `appt-${i + 1}`,
patient_id: `patient-${i + 1}`,
patient_name: `测试患者${i + 1}`,
doctor_id: `doctor-${(i % 5) + 1}`,
doctor_name: `测试医生${(i % 5) + 1}`,
appointment_date: '2026-05-10',
start_time: '09:00',
end_time: '09:30',
status: (['pending', 'confirmed', 'completed', 'cancelled'] as const)[i % 4],
type: 'follow_up',
notes: '',
created_at: '2026-04-01T10:00:00Z',
updated_at: '2026-04-01T10:00:00Z',
version: 1,
}));
export const appointmentHandlers = [
http.get('/api/v1/health/appointments', async ({ request }) => {
await delay(50);
const url = new URL(request.url);
const page = Number(url.searchParams.get('page') || 1);
const pageSize = Number(url.searchParams.get('page_size') || DEFAULT_PAGE_SIZE);
return paginatedResponse(mockAppointments.slice(0, pageSize), mockAppointments.length, page, pageSize);
}),
];
// --- 医生列表 ---
const mockDoctors = Array.from({ length: 8 }, (_, i) => ({
id: `doctor-${i + 1}`,
user_id: `user-doc-${i + 1}`,
name: `测试医生${i + 1}`,
department: '内科',
title: '主治医师',
specialization: '心血管内科',
phone: `1380000${String(i + 1).padStart(4, '0')}`,
email: `doctor${i + 1}@test.com`,
status: 'online',
created_at: '2026-04-01T10:00:00Z',
updated_at: '2026-04-01T10:00:00Z',
version: 1,
}));
export const doctorHandlers = [
http.get('/api/v1/health/doctors', async ({ request }) => {
await delay(50);
const url = new URL(request.url);
const page = Number(url.searchParams.get('page') || 1);
const pageSize = Number(url.searchParams.get('page_size') || DEFAULT_PAGE_SIZE);
return paginatedResponse(mockDoctors.slice(0, pageSize), mockDoctors.length, page, pageSize);
}),
];