refactor(web): 迁移 3 个健康页面错误处理到 useApiRequest — 消除内联 catch/message.error
- PatientList: handleCreateOrEdit/handleDelete/openEditModal 使用 execute - AppointmentList: handleStatusChange(2处)/handleSubmit 使用 execute - FollowUpTaskList: handleCreate/handleRecordSubmit/handleAssign/handleDelete 使用 execute - 移除不再需要的 message 导入(PatientList/FollowUpTaskList)
This commit is contained in:
@@ -28,6 +28,7 @@ import { DrawerForm } from '../../components/DrawerForm';
|
||||
import { EntityName } from '../../components/EntityName';
|
||||
import { formatDateTime } from '../../utils/format';
|
||||
import { usePaginatedData } from '../../hooks/usePaginatedData';
|
||||
import { useApiRequest } from '../../hooks/useApiRequest';
|
||||
|
||||
/** 预约类型选项 */
|
||||
const APPOINTMENT_TYPE_OPTIONS = [
|
||||
@@ -127,6 +128,8 @@ export default function AppointmentList() {
|
||||
},
|
||||
});
|
||||
|
||||
const { execute } = useApiRequest();
|
||||
|
||||
const handleFilterChange = useCallback(
|
||||
(key: keyof AppointmentFilters, value: unknown) => {
|
||||
setFilters((prev) => ({ ...prev, [key]: value }));
|
||||
@@ -168,17 +171,15 @@ export default function AppointmentList() {
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
try {
|
||||
await appointmentApi.updateStatus(record.id, {
|
||||
const result = await execute(
|
||||
() => appointmentApi.updateStatus(record.id, {
|
||||
status: newStatus,
|
||||
version: record.version,
|
||||
...(newStatus === 'cancelled' && { cancel_reason: cancelReason }),
|
||||
});
|
||||
message.success('状态更新成功');
|
||||
refresh();
|
||||
} catch {
|
||||
message.error('状态更新失败');
|
||||
}
|
||||
}),
|
||||
'状态更新成功',
|
||||
);
|
||||
if (result !== null) refresh();
|
||||
},
|
||||
});
|
||||
} else {
|
||||
@@ -188,16 +189,14 @@ export default function AppointmentList() {
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
try {
|
||||
await appointmentApi.updateStatus(record.id, {
|
||||
const result = await execute(
|
||||
() => appointmentApi.updateStatus(record.id, {
|
||||
status: newStatus,
|
||||
version: record.version,
|
||||
});
|
||||
message.success('状态更新成功');
|
||||
refresh();
|
||||
} catch {
|
||||
message.error('状态更新失败');
|
||||
}
|
||||
}),
|
||||
'状态更新成功',
|
||||
);
|
||||
if (result !== null) refresh();
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -246,27 +245,26 @@ export default function AppointmentList() {
|
||||
message.warning('请选择医护');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setSubmitting(true);
|
||||
const req: CreateAppointmentReq = {
|
||||
patient_id: selectedPatientId,
|
||||
doctor_id: selectedDoctorId,
|
||||
appointment_date: (values.appointment_date as Dayjs).format('YYYY-MM-DD'),
|
||||
start_time: (values.start_time as Dayjs).format('HH:mm'),
|
||||
end_time: (values.end_time as Dayjs).format('HH:mm'),
|
||||
appointment_type: (values.appointment_type as string) || 'outpatient',
|
||||
notes: (values.notes as string) || undefined,
|
||||
};
|
||||
await appointmentApi.create(req);
|
||||
message.success('预约创建成功');
|
||||
setSubmitting(true);
|
||||
const req: CreateAppointmentReq = {
|
||||
patient_id: selectedPatientId,
|
||||
doctor_id: selectedDoctorId,
|
||||
appointment_date: (values.appointment_date as Dayjs).format('YYYY-MM-DD'),
|
||||
start_time: (values.start_time as Dayjs).format('HH:mm'),
|
||||
end_time: (values.end_time as Dayjs).format('HH:mm'),
|
||||
appointment_type: (values.appointment_type as string) || 'outpatient',
|
||||
notes: (values.notes as string) || undefined,
|
||||
};
|
||||
const result = await execute(
|
||||
() => appointmentApi.create(req),
|
||||
'预约创建成功',
|
||||
);
|
||||
setSubmitting(false);
|
||||
if (result !== null) {
|
||||
setDrawerOpen(false);
|
||||
setSelectedPatientId(undefined);
|
||||
setSelectedDoctorId(undefined);
|
||||
refresh();
|
||||
} catch {
|
||||
message.error('创建预约失败');
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
DatePicker,
|
||||
Space,
|
||||
Popconfirm,
|
||||
message,
|
||||
} from 'antd';
|
||||
import { PlusOutlined, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
|
||||
@@ -24,6 +23,7 @@ import { EntityName } from '../../components/EntityName';
|
||||
import { DrawerForm } from '../../components/DrawerForm';
|
||||
import { formatDate, formatDateTime } from '../../utils/format';
|
||||
import { usePaginatedData } from '../../hooks/usePaginatedData';
|
||||
import { useApiRequest } from '../../hooks/useApiRequest';
|
||||
|
||||
const STATUS_OPTIONS = [
|
||||
{ value: 'pending', label: '待处理' },
|
||||
@@ -90,6 +90,8 @@ export default function FollowUpTaskList() {
|
||||
defaultFilters: {},
|
||||
});
|
||||
|
||||
const { execute } = useApiRequest();
|
||||
|
||||
// Create task modal
|
||||
const [createOpen, setCreateOpen] = useState(false);
|
||||
const [createLoading, setCreateLoading] = useState(false);
|
||||
@@ -113,26 +115,30 @@ export default function FollowUpTaskList() {
|
||||
|
||||
// Create task
|
||||
const handleCreate = async () => {
|
||||
let values: CreateFollowUpTaskReq;
|
||||
try {
|
||||
const values = await createForm.validateFields();
|
||||
setCreateLoading(true);
|
||||
const plannedDate = values.planned_date;
|
||||
await followUpApi.createTask({
|
||||
values = await createForm.validateFields();
|
||||
} catch (err: unknown) {
|
||||
if (err && typeof err === 'object' && 'errorFields' in err) return;
|
||||
return;
|
||||
}
|
||||
setCreateLoading(true);
|
||||
const plannedDate = values.planned_date;
|
||||
const result = await execute(
|
||||
() => followUpApi.createTask({
|
||||
patient_id: values.patient_id,
|
||||
follow_up_type: values.follow_up_type,
|
||||
planned_date: dayjs.isDayjs(plannedDate) ? plannedDate.format('YYYY-MM-DD') : plannedDate,
|
||||
assigned_to: values.assigned_to,
|
||||
content_template: values.content_template,
|
||||
});
|
||||
message.success('随访任务创建成功');
|
||||
}),
|
||||
'随访任务创建成功',
|
||||
);
|
||||
setCreateLoading(false);
|
||||
if (result !== null) {
|
||||
setCreateOpen(false);
|
||||
createForm.resetFields();
|
||||
refresh(page);
|
||||
} catch (err: unknown) {
|
||||
if (err && typeof err === 'object' && 'errorFields' in err) return; // form validation
|
||||
message.error('创建随访任务失败');
|
||||
} finally {
|
||||
setCreateLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,9 +150,9 @@ export default function FollowUpTaskList() {
|
||||
|
||||
const handleRecordSubmit = async (values: Record<string, unknown>) => {
|
||||
if (!activeTask) return;
|
||||
try {
|
||||
setRecordLoading(true);
|
||||
await followUpApi.createRecord(activeTask.id, {
|
||||
setRecordLoading(true);
|
||||
const result = await execute(
|
||||
() => followUpApi.createRecord(activeTask.id, {
|
||||
executed_date: (values.executed_date as dayjs.Dayjs).format('YYYY-MM-DD'),
|
||||
result: values.result as string,
|
||||
patient_condition: values.patient_condition as string,
|
||||
@@ -154,15 +160,14 @@ export default function FollowUpTaskList() {
|
||||
next_follow_up_date: values.next_follow_up_date
|
||||
? (values.next_follow_up_date as dayjs.Dayjs).format('YYYY-MM-DD')
|
||||
: undefined,
|
||||
});
|
||||
message.success('随访记录填写成功');
|
||||
}),
|
||||
'随访记录填写成功',
|
||||
);
|
||||
setRecordLoading(false);
|
||||
if (result !== null) {
|
||||
setRecordOpen(false);
|
||||
setActiveTask(null);
|
||||
refresh(page);
|
||||
} catch {
|
||||
message.error('填写随访记录失败');
|
||||
} finally {
|
||||
setRecordLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -178,35 +183,37 @@ export default function FollowUpTaskList() {
|
||||
|
||||
const handleAssign = async () => {
|
||||
if (!assignTask) return;
|
||||
let values: { assigned_to: string };
|
||||
try {
|
||||
const values = await assignForm.validateFields();
|
||||
setAssignLoading(true);
|
||||
const req: UpdateFollowUpTaskReq & { version: number } = {
|
||||
assigned_to: values.assigned_to,
|
||||
version: assignTask.version,
|
||||
};
|
||||
await followUpApi.updateTask(assignTask.id, req);
|
||||
message.success('分配成功');
|
||||
values = await assignForm.validateFields();
|
||||
} catch (err: unknown) {
|
||||
if (err && typeof err === 'object' && 'errorFields' in err) return;
|
||||
return;
|
||||
}
|
||||
setAssignLoading(true);
|
||||
const req: UpdateFollowUpTaskReq & { version: number } = {
|
||||
assigned_to: values.assigned_to,
|
||||
version: assignTask.version,
|
||||
};
|
||||
const result = await execute(
|
||||
() => followUpApi.updateTask(assignTask.id, req),
|
||||
'分配成功',
|
||||
);
|
||||
setAssignLoading(false);
|
||||
if (result !== null) {
|
||||
setAssignOpen(false);
|
||||
setAssignTask(null);
|
||||
refresh(page);
|
||||
} catch (err: unknown) {
|
||||
if (err && typeof err === 'object' && 'errorFields' in err) return;
|
||||
message.error('分配失败');
|
||||
} finally {
|
||||
setAssignLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Delete
|
||||
const handleDelete = async (record: FollowUpTask) => {
|
||||
try {
|
||||
await followUpApi.deleteTask(record.id, record.version);
|
||||
message.success('删除成功');
|
||||
refresh(page);
|
||||
} catch {
|
||||
message.error('删除失败');
|
||||
}
|
||||
const result = await execute(
|
||||
() => followUpApi.deleteTask(record.id, record.version),
|
||||
'删除成功',
|
||||
);
|
||||
if (result !== null) refresh(page);
|
||||
};
|
||||
|
||||
// --- Columns ---
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
Select,
|
||||
Popconfirm,
|
||||
DatePicker,
|
||||
message,
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined,
|
||||
@@ -29,6 +28,7 @@ import { AuthButton } from '../../components/AuthButton';
|
||||
import { PageContainer } from '../../components/PageContainer';
|
||||
import { DrawerForm } from '../../components/DrawerForm';
|
||||
import { usePaginatedData } from '../../hooks/usePaginatedData';
|
||||
import { useApiRequest } from '../../hooks/useApiRequest';
|
||||
import { calcAge, formatDateTime } from '../../utils/format';
|
||||
import { dayjs } from '../../utils/dayjs';
|
||||
|
||||
@@ -53,6 +53,9 @@ export default function PatientList() {
|
||||
const [editingPatient, setEditingPatient] = useState<PatientDetail | null>(null);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||
|
||||
// ---- API 请求 Hook ----
|
||||
const { execute } = useApiRequest();
|
||||
|
||||
// ---- 分页数据 Hook ----
|
||||
const {
|
||||
data: patients,
|
||||
@@ -125,39 +128,36 @@ export default function PatientList() {
|
||||
notes: values.notes as string | undefined,
|
||||
};
|
||||
|
||||
try {
|
||||
if (editingPatient) {
|
||||
const req: UpdatePatientReq & { version: number } = {
|
||||
...payload,
|
||||
version: editingPatient.version,
|
||||
};
|
||||
await patientApi.update(editingPatient.id, req);
|
||||
message.success('患者信息更新成功');
|
||||
} else {
|
||||
const successMsg = editingPatient ? '患者信息更新成功' : '患者创建成功';
|
||||
const result = await execute(
|
||||
async () => {
|
||||
if (editingPatient) {
|
||||
const req: UpdatePatientReq & { version: number } = {
|
||||
...payload,
|
||||
version: editingPatient.version,
|
||||
};
|
||||
return patientApi.update(editingPatient.id, req);
|
||||
}
|
||||
const req: CreatePatientReq = payload;
|
||||
await patientApi.create(req);
|
||||
message.success('患者创建成功');
|
||||
}
|
||||
return patientApi.create(req);
|
||||
},
|
||||
successMsg,
|
||||
'操作失败',
|
||||
);
|
||||
if (result !== null) {
|
||||
closeModal();
|
||||
refresh();
|
||||
} catch (err: unknown) {
|
||||
const errorMsg =
|
||||
(err as { response?: { data?: { message?: string } } })?.response?.data
|
||||
?.message || '操作失败';
|
||||
message.error(errorMsg);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
try {
|
||||
const patient = patients.find((p) => p.id === id);
|
||||
const version = patient?.version ?? 0;
|
||||
await patientApi.delete(id, version);
|
||||
message.success('患者已删除');
|
||||
refresh();
|
||||
} catch {
|
||||
message.error('删除失败');
|
||||
}
|
||||
const patient = patients.find((p) => p.id === id);
|
||||
const version = patient?.version ?? 0;
|
||||
const result = await execute(
|
||||
() => patientApi.delete(id, version),
|
||||
'患者已删除',
|
||||
);
|
||||
if (result !== null) refresh();
|
||||
};
|
||||
|
||||
const openCreateModal = () => {
|
||||
@@ -166,12 +166,14 @@ export default function PatientList() {
|
||||
};
|
||||
|
||||
const openEditModal = async (record: PatientListItem) => {
|
||||
try {
|
||||
const detail = await patientApi.get(record.id);
|
||||
const detail = await execute(
|
||||
() => patientApi.get(record.id),
|
||||
undefined,
|
||||
'获取患者详情失败',
|
||||
);
|
||||
if (detail) {
|
||||
setEditingPatient(detail);
|
||||
setModalOpen(true);
|
||||
} catch {
|
||||
message.error('获取患者详情失败');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user