- 新增 useDictionary hook 支持字典 API 获取 + fallback 降级 - DoctorList 科室/职称改用 useDictionary (health_department/health_title) - FollowUpTaskList 随访类型改用 useDictionary (health_follow_up_type) - ConsultationList 咨询类型改用 useDictionary (health_consultation_type) - FamilyMembersTab 家庭关系改用 useDictionary (health_relationship)
159 lines
5.3 KiB
TypeScript
159 lines
5.3 KiB
TypeScript
import { useCallback, useEffect, useState } from 'react';
|
|
import { Table, Button, Form, Input, Select, Drawer, message, Popconfirm, Space } from 'antd';
|
|
import { PlusOutlined } from '@ant-design/icons';
|
|
import { patientApi, type FamilyMember, type CreateFamilyMemberReq } from '../../../api/health/patients';
|
|
import { AuthButton } from '../../../components/AuthButton';
|
|
import { useDictionary } from '../../../hooks/useDictionary';
|
|
|
|
const RELATIONSHIP_FALLBACK = [
|
|
{ label: '父母', value: 'parent' },
|
|
{ label: '配偶', value: 'spouse' },
|
|
{ label: '子女', value: 'child' },
|
|
{ label: '兄弟姐妹', value: 'sibling' },
|
|
{ label: '其他', value: 'other' },
|
|
];
|
|
|
|
interface Props {
|
|
patientId: string;
|
|
}
|
|
|
|
export function FamilyMembersTab({ patientId }: Props) {
|
|
const { options: RELATIONSHIP_OPTIONS } = useDictionary('health_relationship', RELATIONSHIP_FALLBACK);
|
|
const [members, setMembers] = useState<FamilyMember[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
const [editingMember, setEditingMember] = useState<FamilyMember | null>(null);
|
|
const [form] = Form.useForm();
|
|
|
|
const fetchMembers = useCallback(async () => {
|
|
setLoading(true);
|
|
try {
|
|
const data = await patientApi.listFamilyMembers(patientId);
|
|
setMembers(data);
|
|
} catch {
|
|
message.error('加载家属列表失败');
|
|
}
|
|
setLoading(false);
|
|
}, [patientId]);
|
|
|
|
useEffect(() => { fetchMembers(); }, [fetchMembers]);
|
|
|
|
const handleSubmit = async (values: CreateFamilyMemberReq) => {
|
|
try {
|
|
if (editingMember) {
|
|
await patientApi.updateFamilyMember(patientId, editingMember.id, { ...values, version: editingMember.version });
|
|
message.success('家属信息已更新');
|
|
} else {
|
|
await patientApi.createFamilyMember(patientId, values);
|
|
message.success('家属已添加');
|
|
}
|
|
setDrawerOpen(false);
|
|
setEditingMember(null);
|
|
form.resetFields();
|
|
fetchMembers();
|
|
} catch (err: unknown) {
|
|
const msg = (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败';
|
|
message.error(msg);
|
|
}
|
|
};
|
|
|
|
const handleDelete = async (memberId: string) => {
|
|
try {
|
|
await patientApi.deleteFamilyMember(patientId, memberId);
|
|
message.success('已删除');
|
|
fetchMembers();
|
|
} catch {
|
|
message.error('删除失败');
|
|
}
|
|
};
|
|
|
|
const openCreate = () => {
|
|
setEditingMember(null);
|
|
form.resetFields();
|
|
setDrawerOpen(true);
|
|
};
|
|
|
|
const openEdit = (member: FamilyMember) => {
|
|
setEditingMember(member);
|
|
form.setFieldsValue({
|
|
name: member.name,
|
|
relationship: member.relationship,
|
|
phone: member.phone,
|
|
id_number: member.id_number,
|
|
notes: member.notes,
|
|
});
|
|
setDrawerOpen(true);
|
|
};
|
|
|
|
const columns = [
|
|
{ title: '姓名', dataIndex: 'name', key: 'name' },
|
|
{
|
|
title: '关系', dataIndex: 'relationship', key: 'relationship',
|
|
render: (v: string) => RELATIONSHIP_OPTIONS.find(r => r.value === v)?.label || v,
|
|
},
|
|
{ title: '电话', dataIndex: 'phone', key: 'phone' },
|
|
{ title: '身份证号', dataIndex: 'id_number', key: 'id_number' },
|
|
{ title: '备注', dataIndex: 'notes', key: 'notes', ellipsis: true },
|
|
{
|
|
title: '操作', key: 'actions', width: 150,
|
|
render: (_: unknown, record: FamilyMember) => (
|
|
<Space>
|
|
<AuthButton code="health.patient.manage">
|
|
<Button type="link" size="small" onClick={() => openEdit(record)}>编辑</Button>
|
|
</AuthButton>
|
|
<AuthButton code="health.patient.manage">
|
|
<Popconfirm title="确认删除?" onConfirm={() => handleDelete(record.id)}>
|
|
<Button type="link" size="small" danger>删除</Button>
|
|
</Popconfirm>
|
|
</AuthButton>
|
|
</Space>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<>
|
|
<div style={{ marginBottom: 16 }}>
|
|
<AuthButton code="health.patient.manage">
|
|
<Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>添加家属</Button>
|
|
</AuthButton>
|
|
</div>
|
|
<Table
|
|
columns={columns}
|
|
dataSource={members}
|
|
rowKey="id"
|
|
loading={loading}
|
|
pagination={false}
|
|
size="small"
|
|
/>
|
|
<Drawer
|
|
title={editingMember ? '编辑家属' : '添加家属'}
|
|
open={drawerOpen}
|
|
onClose={() => { setDrawerOpen(false); setEditingMember(null); }}
|
|
width={400}
|
|
>
|
|
<Form form={form} onFinish={handleSubmit} layout="vertical">
|
|
<Form.Item name="name" label="姓名" rules={[{ required: true, message: '请输入姓名' }]}>
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item name="relationship" label="关系" rules={[{ required: true, message: '请选择关系' }]}>
|
|
<Select options={RELATIONSHIP_OPTIONS} placeholder="选择关系" />
|
|
</Form.Item>
|
|
<Form.Item name="phone" label="电话">
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item name="id_number" label="身份证号">
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item name="notes" label="备注">
|
|
<Input.TextArea rows={2} />
|
|
</Form.Item>
|
|
<Form.Item>
|
|
<Button type="primary" htmlType="submit">{editingMember ? '更新' : '添加'}</Button>
|
|
</Form.Item>
|
|
</Form>
|
|
</Drawer>
|
|
</>
|
|
);
|
|
}
|