Initial commit: HealthManager full-stack health management platform
Backend: .NET 10 + PostgreSQL + EF Core + JWT + SignalR Frontend patient: React 19 + TypeScript + Vite (mobile H5) Frontend doctor: React 19 + TypeScript + Vite (desktop web)
This commit is contained in:
68
frontend-doctor/src/pages/patients/PatientListPage.tsx
Normal file
68
frontend-doctor/src/pages/patients/PatientListPage.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { api } from '../../services/api-client';
|
||||
|
||||
interface Patient {
|
||||
id: string; name: string; phone: string; gender: string;
|
||||
medicalHistory: string[]; stentDate: string;
|
||||
}
|
||||
|
||||
export function PatientListPage() {
|
||||
const [patients, setPatients] = useState<Patient[]>([]);
|
||||
const [search, setSearch] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
api.get<Patient[]>('/api/patients')
|
||||
.then((r) => setPatients(r.data))
|
||||
.catch(() => {})
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
const filtered = patients.filter((p) =>
|
||||
!search || p.name.includes(search) || p.phone.includes(search)
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={{ padding: 24 }}>
|
||||
<h2 style={{ marginBottom: 16 }}>患者管理</h2>
|
||||
|
||||
<input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="搜索姓名或手机号..."
|
||||
style={{ width: 300, padding: '8px 12px', border: '1px solid #ddd', borderRadius: 4, marginBottom: 16 }} />
|
||||
|
||||
{loading ? <div>加载中...</div> : (
|
||||
<div style={{ background: '#fff', borderRadius: 8, boxShadow: '0 1px 4px rgba(0,0,0,0.08)' }}>
|
||||
<table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 14 }}>
|
||||
<thead>
|
||||
<tr style={{ borderBottom: '2px solid #f0f0f0', textAlign: 'left' }}>
|
||||
<th style={{ padding: '12px 16px' }}>姓名</th>
|
||||
<th style={{ padding: '12px 16px' }}>手机号</th>
|
||||
<th style={{ padding: '12px 16px' }}>性别</th>
|
||||
<th style={{ padding: '12px 16px' }}>病史</th>
|
||||
<th style={{ padding: '12px 16px' }}>支架日期</th>
|
||||
<th style={{ padding: '12px 16px' }}>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{filtered.map((p) => (
|
||||
<tr key={p.id} style={{ borderBottom: '1px solid #f5f5f5' }}>
|
||||
<td style={{ padding: '10px 16px' }}>{p.name}</td>
|
||||
<td style={{ padding: '10px 16px', color: '#888' }}>{p.phone}</td>
|
||||
<td style={{ padding: '10px 16px' }}>{p.gender || '-'}</td>
|
||||
<td style={{ padding: '10px 16px' }}>{(p.medicalHistory || []).slice(0, 3).join('、') || '-'}</td>
|
||||
<td style={{ padding: '10px 16px' }}>{p.stentDate || '-'}</td>
|
||||
<td style={{ padding: '10px 16px' }}>
|
||||
<Link to={`/patients/${p.id}`} style={{ color: '#1976d2', fontSize: 13 }}>查看详情</Link>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{filtered.length === 0 && (
|
||||
<tr><td colSpan={6} style={{ padding: 24, textAlign: 'center', color: '#999' }}>暂无患者数据</td></tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user