feat(miniprogram): 医生端 API 服务层 — 7 个模块
新增医生端完整 API 调用层:alerts / appointment / consultation / dashboard / followup / labReport / patient
This commit is contained in:
39
apps/miniprogram/src/services/doctor/alerts.ts
Normal file
39
apps/miniprogram/src/services/doctor/alerts.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { api } from '../request';
|
||||||
|
|
||||||
|
// ── Alerts (doctor view) ────────────────────────────
|
||||||
|
|
||||||
|
export interface Alert {
|
||||||
|
id: string;
|
||||||
|
patient_id: string;
|
||||||
|
rule_id: string;
|
||||||
|
severity: string;
|
||||||
|
title: string;
|
||||||
|
detail?: Record<string, unknown>;
|
||||||
|
status: string;
|
||||||
|
acknowledged_by?: string;
|
||||||
|
acknowledged_at?: string;
|
||||||
|
resolved_at?: string;
|
||||||
|
created_at: string;
|
||||||
|
version: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listAlerts(params?: {
|
||||||
|
patient_id?: string;
|
||||||
|
status?: string;
|
||||||
|
page?: number;
|
||||||
|
page_size?: number;
|
||||||
|
}) {
|
||||||
|
return api.get<{ data: Alert[]; total: number }>('/health/alerts', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function acknowledgeAlert(id: string, version: number) {
|
||||||
|
return api.put<Alert>(`/health/alerts/${id}/acknowledge`, { version });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function dismissAlert(id: string, version: number) {
|
||||||
|
return api.put<Alert>(`/health/alerts/${id}/dismiss`, { version });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function resolveAlert(id: string, version: number) {
|
||||||
|
return api.put<Alert>(`/health/alerts/${id}/resolve`, { version });
|
||||||
|
}
|
||||||
12
apps/miniprogram/src/services/doctor/appointment.ts
Normal file
12
apps/miniprogram/src/services/doctor/appointment.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { api } from '../request';
|
||||||
|
|
||||||
|
// ── Appointments (doctor view) ─────────────────────
|
||||||
|
|
||||||
|
export async function listAppointments(params?: {
|
||||||
|
page?: number;
|
||||||
|
page_size?: number;
|
||||||
|
status?: string;
|
||||||
|
date?: string;
|
||||||
|
}) {
|
||||||
|
return api.get<{ data: any[]; total: number }>('/health/appointments', params);
|
||||||
|
}
|
||||||
76
apps/miniprogram/src/services/doctor/consultation.ts
Normal file
76
apps/miniprogram/src/services/doctor/consultation.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import { api } from '../request';
|
||||||
|
|
||||||
|
// ── Consultation (doctor view) ─────────────────────
|
||||||
|
|
||||||
|
export interface ConsultationSession {
|
||||||
|
id: string;
|
||||||
|
patient_id: string;
|
||||||
|
patient_name?: string;
|
||||||
|
doctor_id: string | null;
|
||||||
|
consultation_type: string;
|
||||||
|
status: string;
|
||||||
|
subject: string | null;
|
||||||
|
last_message: string | null;
|
||||||
|
last_message_at: string | null;
|
||||||
|
unread_count_doctor?: number;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConsultationMessage {
|
||||||
|
id: string;
|
||||||
|
session_id: string;
|
||||||
|
sender_id: string;
|
||||||
|
sender_role: string;
|
||||||
|
content_type: string;
|
||||||
|
content: string;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listSessions(params?: {
|
||||||
|
page?: number;
|
||||||
|
page_size?: number;
|
||||||
|
status?: string;
|
||||||
|
}) {
|
||||||
|
return api.get<{ data: ConsultationSession[]; total: number }>(
|
||||||
|
'/health/consultation-sessions',
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getSession(id: string) {
|
||||||
|
return api.get<ConsultationSession>(`/health/consultation-sessions/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listMessages(sessionId: string, params?: { page?: number; page_size?: number; after_id?: string }) {
|
||||||
|
return api.get<{ data: ConsultationMessage[]; total: number }>(
|
||||||
|
`/health/consultation-sessions/${sessionId}/messages`,
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendMessage(sessionId: string, content: string, contentType = 'text') {
|
||||||
|
return api.post<ConsultationMessage>('/health/consultation-messages', {
|
||||||
|
session_id: sessionId,
|
||||||
|
content_type: contentType,
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function markSessionRead(sessionId: string) {
|
||||||
|
return api.put<void>(`/health/consultation-sessions/${sessionId}/read`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function closeSession(sessionId: string) {
|
||||||
|
return api.put<void>(`/health/consultation-sessions/${sessionId}/close`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConsultationStats {
|
||||||
|
total_sessions: number;
|
||||||
|
pending_reply: number;
|
||||||
|
avg_response_time_minutes?: number | null;
|
||||||
|
this_month: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getConsultationStats() {
|
||||||
|
return api.get<ConsultationStats>('/health/admin/statistics/consultations');
|
||||||
|
}
|
||||||
17
apps/miniprogram/src/services/doctor/dashboard.ts
Normal file
17
apps/miniprogram/src/services/doctor/dashboard.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { api } from '../request';
|
||||||
|
|
||||||
|
// ── Dashboard ──────────────────────────────────────
|
||||||
|
|
||||||
|
export interface DoctorDashboard {
|
||||||
|
total_patients: number;
|
||||||
|
active_sessions: number;
|
||||||
|
unread_messages: number;
|
||||||
|
pending_follow_ups: number;
|
||||||
|
today_consultations: number;
|
||||||
|
pending_lab_review: number;
|
||||||
|
today_appointments: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getDashboard() {
|
||||||
|
return api.get<DoctorDashboard>('/health/doctor/dashboard');
|
||||||
|
}
|
||||||
70
apps/miniprogram/src/services/doctor/followup.ts
Normal file
70
apps/miniprogram/src/services/doctor/followup.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import { api } from '../request';
|
||||||
|
|
||||||
|
// ── Follow-up (doctor view) ────────────────────────
|
||||||
|
|
||||||
|
export interface FollowUpTask {
|
||||||
|
id: string;
|
||||||
|
patient_id: string;
|
||||||
|
patient_name?: string;
|
||||||
|
assigned_to?: string;
|
||||||
|
follow_up_type: string;
|
||||||
|
planned_date: string;
|
||||||
|
content_template?: string;
|
||||||
|
status: string;
|
||||||
|
created_at: string;
|
||||||
|
version: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FollowUpRecord {
|
||||||
|
id: string;
|
||||||
|
task_id: string;
|
||||||
|
executed_by?: string;
|
||||||
|
executed_date: string;
|
||||||
|
result?: string;
|
||||||
|
patient_condition?: string;
|
||||||
|
medical_advice?: string;
|
||||||
|
next_follow_up_date?: string;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listFollowUpTasks(params?: {
|
||||||
|
page?: number;
|
||||||
|
page_size?: number;
|
||||||
|
status?: string;
|
||||||
|
patient_id?: string;
|
||||||
|
}) {
|
||||||
|
return api.get<{ data: FollowUpTask[]; total: number }>('/health/follow-up-tasks', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getFollowUpTask(id: string) {
|
||||||
|
return api.get<FollowUpTask>(`/health/follow-up-tasks/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateFollowUpTask(id: string, data: Record<string, unknown>, version: number) {
|
||||||
|
return api.put<FollowUpTask>(`/health/follow-up-tasks/${id}`, { ...data, version });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createFollowUpRecord(taskId: string, data: {
|
||||||
|
result?: string;
|
||||||
|
patient_condition?: string;
|
||||||
|
medical_advice?: string;
|
||||||
|
next_follow_up_date?: string;
|
||||||
|
}) {
|
||||||
|
return api.post<FollowUpRecord>(`/health/follow-up-tasks/${taskId}/records`, { task_id: taskId, ...data });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listFollowUpRecords(params?: { task_id?: string; page?: number }) {
|
||||||
|
return api.get<{ data: FollowUpRecord[]; total: number }>('/health/follow-up-records', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FollowUpStats {
|
||||||
|
total_tasks: number;
|
||||||
|
completed: number;
|
||||||
|
pending: number;
|
||||||
|
overdue: number;
|
||||||
|
completion_rate?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getFollowUpStats() {
|
||||||
|
return api.get<FollowUpStats>('/health/admin/statistics/follow-ups');
|
||||||
|
}
|
||||||
49
apps/miniprogram/src/services/doctor/labReport.ts
Normal file
49
apps/miniprogram/src/services/doctor/labReport.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { api } from '../request';
|
||||||
|
|
||||||
|
// ── Lab Report (doctor view) ───────────────────────
|
||||||
|
|
||||||
|
export interface LabReportItem {
|
||||||
|
id: string;
|
||||||
|
report_date: string;
|
||||||
|
report_type: string;
|
||||||
|
status: string;
|
||||||
|
abnormal_count?: number;
|
||||||
|
reviewed_by?: string;
|
||||||
|
reviewed_at?: string;
|
||||||
|
doctor_notes?: string;
|
||||||
|
version: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LabReportDetail extends LabReportItem {
|
||||||
|
items?: {
|
||||||
|
name: string;
|
||||||
|
value: number;
|
||||||
|
unit?: string;
|
||||||
|
reference_min?: number;
|
||||||
|
reference_max?: number;
|
||||||
|
is_abnormal?: boolean;
|
||||||
|
}[];
|
||||||
|
image_urls?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listLabReports(patientId: string, params?: { page?: number; page_size?: number }) {
|
||||||
|
return api.get<{ data: LabReportItem[]; total: number }>(
|
||||||
|
`/health/patients/${patientId}/lab-reports`,
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getLabReport(patientId: string, reportId: string) {
|
||||||
|
return api.get<LabReportDetail>(`/health/patients/${patientId}/lab-reports/${reportId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function reviewLabReport(
|
||||||
|
patientId: string,
|
||||||
|
reportId: string,
|
||||||
|
data: { doctor_notes?: string; version: number },
|
||||||
|
) {
|
||||||
|
return api.put<LabReportDetail>(
|
||||||
|
`/health/patients/${patientId}/lab-reports/${reportId}/review`,
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
}
|
||||||
84
apps/miniprogram/src/services/doctor/patient.ts
Normal file
84
apps/miniprogram/src/services/doctor/patient.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import { api } from '../request';
|
||||||
|
|
||||||
|
// ── Patient (doctor view) ──────────────────────────
|
||||||
|
|
||||||
|
export interface PatientItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
gender?: string;
|
||||||
|
birth_date?: string;
|
||||||
|
phone?: string;
|
||||||
|
status?: string;
|
||||||
|
tags?: { id: string; name: string; color?: string }[];
|
||||||
|
last_visit_date?: string;
|
||||||
|
version: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PatientDetail extends PatientItem {
|
||||||
|
blood_type?: string;
|
||||||
|
allergy_history?: string;
|
||||||
|
medical_history_summary?: string;
|
||||||
|
emergency_contact_name?: string;
|
||||||
|
emergency_contact_phone?: string;
|
||||||
|
source?: string;
|
||||||
|
notes?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HealthSummary {
|
||||||
|
patient_id: string;
|
||||||
|
latest_vital_signs?: {
|
||||||
|
record_date: string;
|
||||||
|
systolic_bp?: number;
|
||||||
|
diastolic_bp?: number;
|
||||||
|
heart_rate?: number;
|
||||||
|
weight?: number;
|
||||||
|
blood_sugar?: number;
|
||||||
|
} | null;
|
||||||
|
latest_lab_report?: {
|
||||||
|
id: string;
|
||||||
|
report_date: string;
|
||||||
|
report_type: string;
|
||||||
|
abnormal_count?: number;
|
||||||
|
} | null;
|
||||||
|
pending_follow_ups?: number;
|
||||||
|
upcoming_appointments?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PatientTag {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
color?: string;
|
||||||
|
is_system?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listPatients(params?: {
|
||||||
|
page?: number;
|
||||||
|
page_size?: number;
|
||||||
|
search?: string;
|
||||||
|
tag_id?: string;
|
||||||
|
}) {
|
||||||
|
return api.get<{ data: PatientItem[]; total: number }>('/health/patients', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getPatient(id: string) {
|
||||||
|
return api.get<PatientDetail>(`/health/patients/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getHealthSummary(patientId: string) {
|
||||||
|
return api.get<HealthSummary>(`/health/patients/${patientId}/health-summary`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listPatientTags() {
|
||||||
|
return api.get<{ data: PatientTag[]; total: number }>('/health/patient-tags');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PatientStats {
|
||||||
|
total_patients: number;
|
||||||
|
new_this_month: number;
|
||||||
|
new_this_week: number;
|
||||||
|
active_this_month: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getPatientStats() {
|
||||||
|
return api.get<PatientStats>('/health/admin/statistics/patients');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user