Files
hms/apps/miniprogram/src/pages/pkg-doctor-clinical/prescription/create/index.tsx
iven c9fe654d44 refactor(miniprogram): 消灭全部 any 类型 — 32处 → 0 (E3-1)
- catch (err: any) → catch (err: unknown) + instanceof Error 类型缩窄(6 文件 13 处)
- BLE 回调类型提取 BLEScanResult/BLEConnectionChangeResult/BLECharacteristicChangeResult/BLEServiceItem
- BLEManager 7 处 any 注解替换为具体接口类型
- request.ts method as any → method as ValidMethod 字面量联合类型
- appointment ScheduleItem 接口定义替代 any[]
- Taro.requestSubscribeMessage 使用类型断言替代 as any
- globalThis.__hms 使用 Record<string, unknown>
- TrendChart Canvas/useRef 保留 eslint-disable(微信 API 限制)
- 0 TS 错误,119 测试通过
2026-05-22 08:30:01 +08:00

203 lines
7.9 KiB
TypeScript

import { useState } from 'react';
import { View, Text, Input, Textarea, Picker } from '@tarojs/components';
import Taro, { useRouter } from '@tarojs/taro';
import { createDialysisPrescription } from '@/services/doctor/dialysis';
import PageShell from '@/components/ui/PageShell';
import ContentCard from '@/components/ui/ContentCard';
import { useDoctorClass } from '@/hooks/useDoctorClass';
import { useSafeTimeout } from '@/hooks/useSafeTimeout';
import './index.scss';
interface FormState {
dialyzer_model: string;
membrane_area: string;
dialysate_potassium: string;
dialysate_calcium: string;
dialysate_bicarbonate: string;
anticoagulation_type: string;
anticoagulation_dose: string;
target_ultrafiltration_ml: string;
target_dry_weight: string;
blood_flow_rate: string;
dialysate_flow_rate: string;
frequency_per_week: string;
duration_minutes: string;
vascular_access_type: string;
vascular_access_location: string;
effective_from: string;
effective_to: string;
notes: string;
}
const initialForm: FormState = {
dialyzer_model: '',
membrane_area: '',
dialysate_potassium: '',
dialysate_calcium: '',
dialysate_bicarbonate: '',
anticoagulation_type: '',
anticoagulation_dose: '',
target_ultrafiltration_ml: '',
target_dry_weight: '',
blood_flow_rate: '',
dialysate_flow_rate: '',
frequency_per_week: '',
duration_minutes: '',
vascular_access_type: '',
vascular_access_location: '',
effective_from: '',
effective_to: '',
notes: '',
};
export default function PrescriptionCreate() {
const router = useRouter();
const patientId = router.params.patientId || '';
const modeClass = useDoctorClass();
const [form, setForm] = useState<FormState>(initialForm);
const [submitting, setSubmitting] = useState(false);
const { safeSetTimeout } = useSafeTimeout();
const updateField = (key: keyof FormState, value: string) => {
setForm((prev) => ({ ...prev, [key]: value }));
};
const handleSubmit = async () => {
if (!patientId) {
Taro.showToast({ title: '缺少患者信息', icon: 'none' });
return;
}
setSubmitting(true);
const num = (v: string) => v ? Number(v) : undefined;
const payload = {
patient_id: patientId,
dialyzer_model: form.dialyzer_model || undefined,
membrane_area: num(form.membrane_area),
dialysate_potassium: num(form.dialysate_potassium),
dialysate_calcium: num(form.dialysate_calcium),
dialysate_bicarbonate: num(form.dialysate_bicarbonate),
anticoagulation_type: form.anticoagulation_type || undefined,
anticoagulation_dose: form.anticoagulation_dose || undefined,
target_ultrafiltration_ml: num(form.target_ultrafiltration_ml),
target_dry_weight: num(form.target_dry_weight),
blood_flow_rate: num(form.blood_flow_rate),
dialysate_flow_rate: num(form.dialysate_flow_rate),
frequency_per_week: num(form.frequency_per_week),
duration_minutes: num(form.duration_minutes),
vascular_access_type: form.vascular_access_type || undefined,
vascular_access_location: form.vascular_access_location || undefined,
effective_from: form.effective_from || undefined,
effective_to: form.effective_to || undefined,
notes: form.notes || undefined,
};
try {
await createDialysisPrescription(payload);
Taro.showToast({ title: '创建成功', icon: 'success' });
safeSetTimeout(() => Taro.navigateBack(), 1000);
} catch (err) {
console.warn('[doctor-prescription] 创建处方失败:', err);
Taro.showToast({ title: '创建失败', icon: 'none' });
} finally {
setSubmitting(false);
}
};
const InputField = ({ label, field, placeholder, type = 'digit' }: {
label: string; field: keyof FormState; placeholder: string; type?: string;
}) => (
<View className='form-row'>
<Text className='form-label'>{label}</Text>
<Input
className='form-input'
type={type as 'digit' | 'number' | 'text'}
placeholder={placeholder}
value={form[field]}
onInput={(e) => updateField(field, e.detail.value)}
/>
</View>
);
return (
<PageShell safeBottom={false} className={modeClass}>
{/* 透析器 */}
<ContentCard className='section'>
<Text className='section-title'></Text>
<InputField label='透析器型号' field='dialyzer_model' placeholder='请输入型号' type='text' />
<InputField label='膜面积' field='membrane_area' placeholder='m²' />
</ContentCard>
{/* 透析液 */}
<ContentCard className='section'>
<Text className='section-title'></Text>
<InputField label='钾浓度' field='dialysate_potassium' placeholder='mmol/L' />
<InputField label='钙浓度' field='dialysate_calcium' placeholder='mmol/L' />
<InputField label='碳酸氢盐' field='dialysate_bicarbonate' placeholder='mmol/L' />
</ContentCard>
{/* 抗凝 */}
<ContentCard className='section'>
<Text className='section-title'></Text>
<InputField label='抗凝类型' field='anticoagulation_type' placeholder='请输入' type='text' />
<InputField label='抗凝剂量' field='anticoagulation_dose' placeholder='请输入' type='text' />
</ContentCard>
{/* 参数 */}
<ContentCard className='section'>
<Text className='section-title'></Text>
<InputField label='目标超滤量' field='target_ultrafiltration_ml' placeholder='ml' type='number' />
<InputField label='目标干体重' field='target_dry_weight' placeholder='kg' />
<InputField label='血流速' field='blood_flow_rate' placeholder='ml/min' type='number' />
<InputField label='透析液流量' field='dialysate_flow_rate' placeholder='ml/min' type='number' />
<InputField label='每周频次' field='frequency_per_week' placeholder='次/周' type='number' />
<InputField label='每次时长' field='duration_minutes' placeholder='分钟' type='number' />
</ContentCard>
{/* 血管通路 */}
<ContentCard className='section'>
<Text className='section-title'></Text>
<InputField label='通路类型' field='vascular_access_type' placeholder='请输入' type='text' />
<InputField label='通路位置' field='vascular_access_location' placeholder='请输入' type='text' />
</ContentCard>
{/* 生效日期 */}
<ContentCard className='section'>
<Text className='section-title'></Text>
<View className='form-row'>
<Text className='form-label'></Text>
<Picker mode='date' value={form.effective_from} onChange={(e) => updateField('effective_from', e.detail.value)}>
<Text className={`form-value ${!form.effective_from ? 'placeholder' : ''}`}>
{form.effective_from || '请选择'}
</Text>
</Picker>
</View>
<View className='form-row'>
<Text className='form-label'></Text>
<Picker mode='date' value={form.effective_to} onChange={(e) => updateField('effective_to', e.detail.value)}>
<Text className={`form-value ${!form.effective_to ? 'placeholder' : ''}`}>
{form.effective_to || '请选择'}
</Text>
</Picker>
</View>
</ContentCard>
{/* 备注 */}
<ContentCard className='section'>
<Text className='section-title'></Text>
<Textarea
className='form-textarea'
placeholder='请输入备注...'
value={form.notes}
onInput={(e) => updateField('notes', e.detail.value)}
maxlength={500}
/>
</ContentCard>
<View className={`submit-btn ${submitting ? 'submit-btn--disabled' : ''}`} onClick={handleSubmit}>
<Text className='submit-btn__text'>{submitting ? '提交中...' : '创建处方'}</Text>
</View>
</PageShell>
);
}