feat(web): 家属管理 Tab — 列表+添加/编辑/删除家属
This commit is contained in:
@@ -30,6 +30,7 @@ import { FollowUpTab } from './components/FollowUpTab';
|
||||
import { DeviceReadingsTab } from './components/DeviceReadingsTab';
|
||||
import { PointsAccountTab } from './components/PointsAccountTab';
|
||||
import { AiSuggestionTab } from './components/AiSuggestionTab';
|
||||
import { FamilyMembersTab } from './components/FamilyMembersTab';
|
||||
import { DailyMonitoringTab } from './components/DailyMonitoringTab';
|
||||
import { GENDER_OPTIONS, BLOOD_TYPE_OPTIONS } from '../../constants/health';
|
||||
import { useThemeMode } from '../../hooks/useThemeMode';
|
||||
@@ -297,6 +298,11 @@ export default function PatientDetail() {
|
||||
</Descriptions>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'family',
|
||||
label: '家属管理',
|
||||
children: id ? <FamilyMembersTab patientId={id} /> : null,
|
||||
},
|
||||
{
|
||||
key: 'health',
|
||||
label: '健康数据',
|
||||
|
||||
156
apps/web/src/pages/health/components/FamilyMembersTab.tsx
Normal file
156
apps/web/src/pages/health/components/FamilyMembersTab.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
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';
|
||||
|
||||
const RELATIONSHIP_OPTIONS = [
|
||||
{ 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 [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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user