test(web): 添加健康模块 msw handlers — 患者告警预约医生 4 组 mock API
This commit is contained in:
@@ -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,
|
||||
];
|
||||
|
||||
128
apps/web/src/test/mocks/healthHandlers.ts
Normal file
128
apps/web/src/test/mocks/healthHandlers.ts
Normal 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);
|
||||
}),
|
||||
];
|
||||
Reference in New Issue
Block a user