Files
hms/apps/miniprogram/src/services/appointment.ts
iven d623f8b2ff fix: V1 测试版本端到端验证修复 — 6 CRITICAL + 3 HIGH 问题全量修复
修复项:
- fix(db): 迁移 149 — 修复 Admin 角色权限绑定被迁移链破坏 (FE-C1)
- fix(health): 4 个 handler 添加空名称验证 — Doctor/Article/AlertRule/Tag (API-C1~C4)
- fix(health): Stats 仪表盘 new_this_week 查询修复 — SeaORM date_trunc bug (FE-C2)
- fix(server): 添加安全响应头 — X-Frame-Options/CSP/XSS-Protection/Referrer-Policy (SEC-H1)
- fix(mp): 预约创建契约修复 — notes/reason 字段映射 + 移除 schedule_id (MP-H1)
- fix(mp): 咨询会话 subject/last_message 字段改为可选 (MP-H3)
- fix(ai): AiConfig Default derive 替代手写 impl (clippy)

测试报告:
- 8 维度端到端测试全部完成 (后端 87 用例 / 前端 30 页面 / 小程序 80+ API / 安全 20 项 / 性能 20 端点)
- 多角色 7 角色 49 检查 100% 通过
- 综合测试报告 + 专家评估报告
2026-05-18 10:24:40 +08:00

107 lines
2.8 KiB
TypeScript

import { api } from './request';
export interface Appointment {
id: string;
patient_name: string;
doctor_name: string;
department?: string;
appointment_date: string;
start_time: string;
end_time: string;
status: string;
version: number;
}
export interface Doctor {
id: string;
name: string;
department: string;
title?: string;
}
export interface DoctorSchedule {
id: string;
doctor_id: string;
date: string;
start_time: string;
end_time: string;
max_appointments: number;
current_appointments: number;
available_count: number;
}
export async function listAppointments(patientId?: string, page = 1) {
return api.get<{ data: Appointment[]; total: number }>('/health/appointments', {
page,
page_size: 20,
...(patientId && { patient_id: patientId }),
});
}
export async function getAppointment(id: string) {
return api.get<Appointment>(`/health/appointments/${id}`);
}
export async function createAppointment(data: {
patient_id: string;
doctor_id: string;
appointment_date: string;
start_time: string;
end_time: string;
notes?: string;
appointment_type?: string;
}) {
return api.post<Appointment>('/health/appointments', data);
}
export async function cancelAppointment(id: string, version: number) {
return api.put(`/health/appointments/${id}/status`, {
status: 'cancelled',
version,
});
}
export async function getDoctorSchedules(doctorId: string, startDate: string, endDate: string) {
const resp = await api.get<{ data: DoctorSchedule[]; total: number }>('/health/doctor-schedules', {
doctor_id: doctorId,
start_date: startDate,
end_date: endDate,
page_size: 50,
});
// 计算可用号源数
for (const s of resp.data) {
s.available_count = s.available_count ?? (s.max_appointments - s.current_appointments);
}
return resp;
}
export async function listDoctors(department?: string) {
return api.get<{ data: Doctor[]; total: number }>('/health/doctors', {
page_size: 100,
...(department && { department }),
});
}
export async function calendarView(startDate: string, endDate: string, doctorId?: string) {
const raw = await api.get<{ date: string; schedules: DoctorSchedule[] }[]>(
'/health/doctor-schedules/calendar',
{
start_date: startDate,
end_date: endDate,
...(doctorId && { doctor_id: doctorId }),
},
);
// 后台返回按日期分组的嵌套结构,展平为扁平数组并计算 available_count
const flat: DoctorSchedule[] = [];
for (const day of (raw as unknown as { date: string; schedules: DoctorSchedule[] }[])) {
for (const s of day.schedules) {
flat.push({
...s,
date: s.date || day.date,
available_count: s.available_count ?? (s.max_appointments - s.current_appointments),
});
}
}
return flat;
}