- 管理员订单列表:新增 admin_list_orders 不按 patient_id 过滤 - 分配医生:添加 doctor_profile 存在性验证防止孤立关联 - 标签管理:将软删除+插入包裹在事务中防止标签丢失 - HealthDataProvider:标记为 experimental,改进错误消息 - 预约 CAS:添加注释说明匹配字段与唯一索引的关系 - 小程序 DTO:inputVitalSign 映射 indicator_type 到结构化字段 - 小程序数据隔离:listAppointments/listTasks 添加 patient_id 参数 - 小程序字段名:family-add 修复 birthday → birth_date
114 lines
3.3 KiB
TypeScript
114 lines
3.3 KiB
TypeScript
import { api } from './request';
|
||
|
||
export interface VitalSignInput {
|
||
indicator_type: string;
|
||
value: number;
|
||
measured_at?: string;
|
||
note?: string;
|
||
extra?: Record<string, number>;
|
||
}
|
||
|
||
export interface TodaySummary {
|
||
blood_pressure?: { systolic: number; diastolic: number; status: string; reference_range?: string };
|
||
heart_rate?: { value: number; status: string; reference_range?: string };
|
||
blood_sugar?: { value: number; status: string; reference_range?: string };
|
||
weight?: { value: number; status: string; reference_range?: string };
|
||
}
|
||
|
||
export async function getTodaySummary() {
|
||
return api.get<TodaySummary>('/health/vital-signs/today');
|
||
}
|
||
|
||
/**
|
||
* 提交生命体征数据。
|
||
* 小程序使用简单的 indicator_type + value 模型,
|
||
* 后端 CreateVitalSignsReq 期望结构化字段(systolic_bp_morning 等)。
|
||
* 此函数负责将指示器类型映射到后端结构化格式。
|
||
*/
|
||
export async function inputVitalSign(patientId: string, data: VitalSignInput) {
|
||
const today = new Date().toISOString().slice(0, 10);
|
||
const body: Record<string, unknown> = { record_date: today };
|
||
|
||
switch (data.indicator_type) {
|
||
case 'blood_pressure':
|
||
if (data.extra?.systolic) body.systolic_bp_morning = data.extra.systolic;
|
||
if (data.extra?.diastolic) body.diastolic_bp_morning = data.extra.diastolic;
|
||
break;
|
||
case 'heart_rate':
|
||
body.heart_rate = Math.round(data.value);
|
||
break;
|
||
case 'weight':
|
||
body.weight = data.value;
|
||
break;
|
||
case 'blood_sugar':
|
||
body.blood_sugar = data.value;
|
||
break;
|
||
case 'water_intake':
|
||
body.water_intake_ml = Math.round(data.value);
|
||
break;
|
||
case 'urine_output':
|
||
body.urine_output_ml = Math.round(data.value);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (data.note) body.notes = data.note;
|
||
return api.post(`/health/patients/${patientId}/vital-signs`, body);
|
||
}
|
||
|
||
export async function getTrend(indicator: string, range: string) {
|
||
return api.get<{ indicator: string; data_points: { date: string; value: number }[] }>(
|
||
'/health/vital-signs/trend',
|
||
{ indicator, range },
|
||
);
|
||
}
|
||
|
||
// ---- Daily Monitoring (日常监测) ----
|
||
|
||
export interface DailyMonitoring {
|
||
id: string;
|
||
patient_id: string;
|
||
record_date: string;
|
||
morning_bp_systolic: number | null;
|
||
morning_bp_diastolic: number | null;
|
||
evening_bp_systolic: number | null;
|
||
evening_bp_diastolic: number | null;
|
||
weight: number | null;
|
||
blood_sugar: number | null;
|
||
fluid_intake: number | null;
|
||
urine_output: number | null;
|
||
notes: string | null;
|
||
created_at: string;
|
||
updated_at: string;
|
||
version: number;
|
||
}
|
||
|
||
export interface CreateDailyMonitoringReq {
|
||
patient_id: string;
|
||
record_date: string;
|
||
morning_bp_systolic?: number;
|
||
morning_bp_diastolic?: number;
|
||
evening_bp_systolic?: number;
|
||
evening_bp_diastolic?: number;
|
||
weight?: number;
|
||
blood_sugar?: number;
|
||
fluid_intake?: number;
|
||
urine_output?: number;
|
||
notes?: string;
|
||
}
|
||
|
||
export async function createDailyMonitoring(data: CreateDailyMonitoringReq) {
|
||
return api.post<DailyMonitoring>('/health/daily-monitoring', data);
|
||
}
|
||
|
||
export async function listDailyMonitoring(
|
||
patientId: string,
|
||
params?: { page?: number; page_size?: number },
|
||
) {
|
||
return api.get<{ data: DailyMonitoring[]; total: number }>(
|
||
`/health/patients/${patientId}/daily-monitoring`,
|
||
params,
|
||
);
|
||
}
|