- 新增 12 个核心页面原型(登录/首页/咨询/预约/商城/健康等) - 新增医生端分包原型(核心 + 临床两个分包) - 新增 AI 客服对话页原型 - 新增 MP UI 优化指南文档 - 更新 wiki 基础设施和小程序文档
440 lines
23 KiB
HTML
440 lines
23 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>HMS 小程序 — 健康记录</title>
|
||
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
body { background: #1a1a1a; font-family: -apple-system, 'PingFang SC', sans-serif; display: flex; flex-direction: column; align-items: center; padding: 40px 20px; gap: 24px; }
|
||
.page-title { color: #999; font-size: 13px; letter-spacing: 0.15em; text-transform: uppercase; }
|
||
.note { color: #666; font-size: 12px; max-width: 800px; text-align: center; line-height: 1.8; }
|
||
.screens { display: flex; gap: 36px; flex-wrap: wrap; justify-content: center; align-items: flex-start; }
|
||
.screen-wrap { display: flex; flex-direction: column; align-items: center; gap: 12px; }
|
||
.screen-label { color: #888; font-size: 12px; font-style: italic; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="page-title">HMS 小程序 · 健康记录</div>
|
||
<div class="note">温润东方风设计系统 — 个人中心健康记录模块。5 个屏幕:健康记录列表、诊断记录、用药记录、检查报告列表、报告详情。</div>
|
||
<div id="root"></div>
|
||
|
||
<script type="text/babel">
|
||
// ─── iOS 设备框 ───
|
||
const iosFrameStyles = {
|
||
wrapper: { display: 'inline-block', padding: 12, background: '#000', borderRadius: 60, boxShadow: '0 0 0 2px #1f2937, 0 20px 60px rgba(0,0,0,0.3)', position: 'relative' },
|
||
screen: { position: 'relative', borderRadius: 48, overflow: 'hidden', background: '#fff' },
|
||
statusBar: { position: 'absolute', top: 0, left: 0, right: 0, height: 54, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 32px', fontSize: 16, fontWeight: 600, fontFamily: '-apple-system, "SF Pro Text", sans-serif', zIndex: 20, pointerEvents: 'none' },
|
||
dynamicIsland: { position: 'absolute', top: 12, left: '50%', transform: 'translateX(-50%)', width: 124, height: 36, background: '#000', borderRadius: 999, zIndex: 30 },
|
||
content: { position: 'absolute', top: 54, left: 0, right: 0, bottom: 34, overflow: 'auto' },
|
||
homeIndicator: { position: 'absolute', bottom: 10, left: '50%', transform: 'translateX(-50%)', width: 140, height: 5, background: 'rgba(0,0,0,0.3)', borderRadius: 999, zIndex: 10 },
|
||
};
|
||
|
||
function IosFrame({ children, width = 360, height = 780, time = '9:41', battery = 85, darkStatus = false }) {
|
||
const statusColor = darkStatus ? '#fff' : '#000';
|
||
return (
|
||
<div style={iosFrameStyles.wrapper}>
|
||
<div style={{ ...iosFrameStyles.screen, width, height }}>
|
||
<div style={{ ...iosFrameStyles.statusBar, color: statusColor }}>
|
||
<span>{time}</span>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
||
<svg width="16" height="12" viewBox="0 0 16 12" fill="none"><path d="M8 11.5a1 1 0 100-2 1 1 0 000 2z" fill={statusColor}/><path d="M3 7.5a7 7 0 0110 0" stroke={statusColor} strokeWidth="1.3" fill="none" strokeLinecap="round"/><path d="M1 4.5a11 11 0 0114 0" stroke={statusColor} strokeWidth="1.3" fill="none" strokeLinecap="round" opacity="0.7"/></svg>
|
||
<div style={{ width: 26, height: 12, border: `1.5px solid ${statusColor}`, borderRadius: 3, padding: 1, position: 'relative' }}>
|
||
<div style={{ width: `${battery}%`, height: '100%', background: statusColor, borderRadius: 1 }} />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style={iosFrameStyles.dynamicIsland} />
|
||
<div style={iosFrameStyles.content}>{children}</div>
|
||
<div style={iosFrameStyles.homeIndicator} />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 设计 Token ───
|
||
const T = {
|
||
pri: '#C4623A', priL: '#F0DDD4', priD: '#8B3E1F',
|
||
bg: '#F5F0EB', card: '#FFFFFF', surface: '#EDE8E2',
|
||
tx: '#2D2A26', tx2: '#5A554F', tx3: '#78716C',
|
||
bd: '#E8E2DC', bdL: '#F0EBE5',
|
||
acc: '#5B7A5E', accL: '#E8F0E8',
|
||
wrn: '#C4873A', wrnL: '#FFF3E0',
|
||
dan: '#B54A4A', danL: '#FDEAEA',
|
||
serif: "Georgia, 'Times New Roman', serif",
|
||
sans: "-apple-system, 'PingFang SC', sans-serif",
|
||
r: 16, rSm: 12, rXs: 8,
|
||
};
|
||
|
||
// ─── 通用组件 ───
|
||
function NavBar({ title }) {
|
||
return (
|
||
<div style={{ height: 44, display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', background: T.bg, borderBottom: `1px solid ${T.bdL}`, flexShrink: 0 }}>
|
||
<svg style={{ position: 'absolute', left: 16 }} width="24" height="24" viewBox="0 0 24 24" fill="none" stroke={T.tx} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M15 18l-6-6 6-6"/>
|
||
</svg>
|
||
<span style={{ fontFamily: T.serif, fontSize: 18, fontWeight: 700, color: T.tx }}>{title}</span>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function Tag({ label, color = T.acc, bg = T.accL }) {
|
||
return (
|
||
<span style={{ display: 'inline-block', fontSize: 11, color, background: bg, padding: '2px 8px', borderRadius: 6, fontWeight: 500 }}>{label}</span>
|
||
);
|
||
}
|
||
|
||
// ─── 屏幕1:健康记录列表 ───
|
||
function HealthRecordList() {
|
||
const records = [
|
||
{ date: '5月8日', time: '09:30', type: '体征记录', tagColor: T.acc, tagBg: T.accL, summary: '血压 130/85, 心率 72, 血糖 5.6', icon: '♥' },
|
||
{ date: '5月6日', time: '14:00', type: '化验单', tagColor: T.pri, tagBg: T.priL, summary: '血常规:血红蛋白 110g/L', icon: '📋' },
|
||
{ date: '5月1日', time: '10:00', type: '体征记录', tagColor: T.acc, tagBg: T.accL, summary: '血压 128/82, 心率 70', icon: '♥' },
|
||
{ date: '4月28日', time: '16:00', type: '体检报告', tagColor: T.wrn, tagBg: T.wrnL, summary: '年度体检(综合)', icon: '📄' },
|
||
];
|
||
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, display: 'flex', flexDirection: 'column' }}>
|
||
<NavBar title="健康记录" />
|
||
<div style={{ flex: 1, overflow: 'auto', padding: '20px 20px 24px' }}>
|
||
{/* 顶部摘要 */}
|
||
<div style={{ background: T.card, borderRadius: T.r, padding: '18px 20px', marginBottom: 24, boxShadow: '0 2px 12px rgba(0,0,0,0.04)' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||
<div>
|
||
<div style={{ fontSize: 13, color: T.tx3, marginBottom: 4 }}>本月记录</div>
|
||
<div style={{ fontFamily: T.serif, fontSize: 28, fontWeight: 700, color: T.pri }}>12</div>
|
||
</div>
|
||
<div style={{ display: 'flex', gap: 16 }}>
|
||
<div style={{ textAlign: 'center' }}>
|
||
<div style={{ fontSize: 11, color: T.tx3, marginBottom: 2 }}>体征</div>
|
||
<div style={{ fontSize: 16, fontWeight: 600, color: T.tx }}>8</div>
|
||
</div>
|
||
<div style={{ width: 1, background: T.bdL }} />
|
||
<div style={{ textAlign: 'center' }}>
|
||
<div style={{ fontSize: 11, color: T.tx3, marginBottom: 2 }}>化验</div>
|
||
<div style={{ fontSize: 16, fontWeight: 600, color: T.tx }}>3</div>
|
||
</div>
|
||
<div style={{ width: 1, background: T.bdL }} />
|
||
<div style={{ textAlign: 'center' }}>
|
||
<div style={{ fontSize: 11, color: T.tx3, marginBottom: 2 }}>报告</div>
|
||
<div style={{ fontSize: 16, fontWeight: 600, color: T.tx }}>1</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 时间线 */}
|
||
<div style={{ position: 'relative', paddingLeft: 24 }}>
|
||
{/* 竖线 */}
|
||
<div style={{ position: 'absolute', left: 7, top: 6, bottom: 6, width: 2, background: `linear-gradient(to bottom, ${T.pri} 0%, ${T.bd} 100%)`, borderRadius: 1 }} />
|
||
|
||
{records.map((rec, i) => (
|
||
<div key={i} style={{ position: 'relative', marginBottom: i < records.length - 1 ? 20 : 0 }}>
|
||
{/* 圆点 */}
|
||
<div style={{ position: 'absolute', left: -24, top: 4, width: 16, height: 16, borderRadius: 8, background: T.card, border: `3px solid ${T.pri}`, zIndex: 1 }} />
|
||
|
||
{/* 日期行 */}
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
|
||
<span style={{ fontSize: 13, fontWeight: 600, color: T.tx }}>{rec.date}</span>
|
||
<span style={{ fontSize: 12, color: T.tx3 }}>{rec.time}</span>
|
||
<Tag label={rec.type} color={rec.tagColor} bg={rec.tagBg} />
|
||
</div>
|
||
|
||
{/* 卡片 */}
|
||
<div style={{ background: T.card, borderRadius: T.rSm, padding: '14px 16px', boxShadow: '0 1px 8px rgba(0,0,0,0.04)' }}>
|
||
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
|
||
<span style={{ fontSize: 18, lineHeight: 1 }}>{rec.icon}</span>
|
||
<div style={{ flex: 1 }}>
|
||
<div style={{ fontSize: 14, fontWeight: 500, color: T.tx, marginBottom: 4 }}>{rec.type}</div>
|
||
<div style={{ fontSize: 13, color: T.tx2, lineHeight: 1.5 }}>{rec.summary}</div>
|
||
</div>
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={T.tx3} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M9 18l6-6-6-6"/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 屏幕2:诊断记录 ───
|
||
function DiagnosisRecords() {
|
||
const diagnoses = [
|
||
{ name: '高血压 II 级', date: '2024-03-15', doctor: '王医生', dept: '心内科', status: '进行中', statusColor: T.wrn, statusBg: T.wrnL },
|
||
{ name: '2型糖尿病', date: '2023-08-20', doctor: '李医生', dept: '内分泌科', status: '已控制', statusColor: T.acc, statusBg: T.accL },
|
||
{ name: '慢性肾病 III 期', date: '2023-05-10', doctor: '张医生', dept: '肾内科', status: '进行中', statusColor: T.wrn, statusBg: T.wrnL },
|
||
];
|
||
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, display: 'flex', flexDirection: 'column' }}>
|
||
<NavBar title="诊断记录" />
|
||
<div style={{ flex: 1, overflow: 'auto', padding: '20px 20px 24px' }}>
|
||
|
||
{/* 统计栏 */}
|
||
<div style={{ display: 'flex', gap: 12, marginBottom: 20 }}>
|
||
<div style={{ flex: 1, background: T.card, borderRadius: T.rSm, padding: '14px 16px', textAlign: 'center', boxShadow: '0 1px 8px rgba(0,0,0,0.04)' }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 22, fontWeight: 700, color: T.wrn }}>2</div>
|
||
<div style={{ fontSize: 12, color: T.tx3, marginTop: 2 }}>进行中</div>
|
||
</div>
|
||
<div style={{ flex: 1, background: T.card, borderRadius: T.rSm, padding: '14px 16px', textAlign: 'center', boxShadow: '0 1px 8px rgba(0,0,0,0.04)' }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 22, fontWeight: 700, color: T.acc }}>1</div>
|
||
<div style={{ fontSize: 12, color: T.tx3, marginTop: 2 }}>已控制</div>
|
||
</div>
|
||
</div>
|
||
|
||
{diagnoses.map((d, i) => (
|
||
<div key={i} style={{ background: T.card, borderRadius: T.r, padding: '18px 20px', marginBottom: 14, boxShadow: '0 2px 12px rgba(0,0,0,0.04)' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 10 }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 16, fontWeight: 700, color: T.tx, lineHeight: 1.3 }}>{d.name}</div>
|
||
<Tag label={d.status} color={d.statusColor} bg={d.statusBg} />
|
||
</div>
|
||
<div style={{ fontSize: 12, color: T.tx3, marginBottom: 8 }}>诊断日期:{d.date}</div>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={T.tx3} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/>
|
||
<circle cx="12" cy="7" r="4"/>
|
||
</svg>
|
||
<span style={{ fontSize: 13, color: T.tx2 }}>{d.doctor} · {d.dept}</span>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 屏幕3:用药记录 ───
|
||
function MedicationRecords() {
|
||
const currentMeds = [
|
||
{ name: '缬沙坦', dose: '80mg', freq: '每日一次', note: '早餐后', forDisease: '高血压', active: true },
|
||
{ name: '二甲双胍', dose: '500mg', freq: '每日两次', note: '', forDisease: '糖尿病', active: true },
|
||
];
|
||
|
||
const historyMeds = [
|
||
{ name: '阿莫西林', dose: '250mg', freq: '每日三次', note: '7天', forDisease: '呼吸道感染', active: false },
|
||
];
|
||
|
||
function MedCard({ med }) {
|
||
return (
|
||
<div style={{ background: T.card, borderRadius: T.rSm, padding: '16px 18px', marginBottom: 10, boxShadow: '0 1px 8px rgba(0,0,0,0.04)', borderLeft: `3px solid ${med.active ? T.acc : T.bd}` }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 8 }}>
|
||
<div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
|
||
<span style={{ fontFamily: T.serif, fontSize: 16, fontWeight: 700, color: T.tx }}>{med.name}</span>
|
||
<span style={{ fontSize: 14, color: T.tx2 }}>{med.dose}</span>
|
||
</div>
|
||
<Tag label={med.active ? '用药中' : '已停药'} color={med.active ? T.acc : T.tx3} bg={med.active ? T.accL : T.surface} />
|
||
</div>
|
||
<div style={{ fontSize: 13, color: T.tx2, marginBottom: 6 }}>
|
||
{med.freq}{med.note ? ` · ${med.note}` : ''}
|
||
</div>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke={T.tx3} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M9 11l3 3L22 4"/>
|
||
</svg>
|
||
<span style={{ fontSize: 12, color: T.tx3 }}>{med.forDisease}</span>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, display: 'flex', flexDirection: 'column' }}>
|
||
<NavBar title="用药记录" />
|
||
<div style={{ flex: 1, overflow: 'auto', padding: '20px 20px 24px' }}>
|
||
|
||
{/* 当前用药 */}
|
||
<div style={{ fontSize: 13, fontWeight: 600, color: T.tx3, marginBottom: 12, letterSpacing: '0.05em' }}>当前用药</div>
|
||
{currentMeds.map((med, i) => <MedCard key={i} med={med} />)}
|
||
|
||
{/* 分隔 */}
|
||
<div style={{ height: 24 }} />
|
||
|
||
{/* 历史用药 */}
|
||
<div style={{ fontSize: 13, fontWeight: 600, color: T.tx3, marginBottom: 12, letterSpacing: '0.05em' }}>历史用药</div>
|
||
{historyMeds.map((med, i) => <MedCard key={i} med={med} />)}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 屏幕4:检查报告列表 ───
|
||
function ExamReportList() {
|
||
const reports = [
|
||
{ type: '血常规', date: '5月6日', abnormal: 2, tagBg: T.wrnL, tagColor: T.wrn, tagLabel: '2项异常' },
|
||
{ type: '肝功能', date: '5月6日', abnormal: 0, tagBg: T.accL, tagColor: T.acc, tagLabel: '全部正常' },
|
||
{ type: '肾功能', date: '5月6日', abnormal: 1, tagBg: T.wrnL, tagColor: T.wrn, tagLabel: '1项异常' },
|
||
{ type: '尿常规', date: '4月20日', abnormal: 0, tagBg: T.accL, tagColor: T.acc, tagLabel: '全部正常' },
|
||
];
|
||
|
||
const typeColors = {
|
||
'血常规': { bg: '#FDE8E8', color: '#C53030' },
|
||
'肝功能': { bg: '#E8F0E8', color: '#5B7A5E' },
|
||
'肾功能': { bg: '#FFF3E0', color: '#C4873A' },
|
||
'尿常规': { bg: '#E8E0F0', color: '#7A5B8A' },
|
||
};
|
||
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, display: 'flex', flexDirection: 'column' }}>
|
||
<NavBar title="检查报告" />
|
||
<div style={{ flex: 1, overflow: 'auto', padding: '20px 20px 24px' }}>
|
||
|
||
{/* 筛选标签 */}
|
||
<div style={{ display: 'flex', gap: 8, marginBottom: 18, overflowX: 'auto' }}>
|
||
{['全部', '异常', '正常'].map((f, i) => (
|
||
<div key={i} style={{ padding: '6px 16px', borderRadius: 999, fontSize: 13, fontWeight: 500, background: i === 0 ? T.pri : T.card, color: i === 0 ? '#fff' : T.tx2, whiteSpace: 'nowrap', boxShadow: i === 0 ? 'none' : '0 1px 4px rgba(0,0,0,0.06)' }}>
|
||
{f}
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{reports.map((r, i) => {
|
||
const tc = typeColors[r.type] || { bg: T.surface, color: T.tx2 };
|
||
return (
|
||
<div key={i} style={{ background: T.card, borderRadius: T.r, padding: '16px 18px', marginBottom: 12, boxShadow: '0 2px 12px rgba(0,0,0,0.04)' }}>
|
||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||
{/* 类型标签 */}
|
||
<div style={{ width: 48, height: 48, borderRadius: T.rSm, background: tc.bg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
||
<span style={{ fontSize: 13, fontWeight: 600, color: tc.color }}>{r.type.slice(0, 1)}</span>
|
||
</div>
|
||
|
||
<div style={{ flex: 1 }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }}>
|
||
<span style={{ fontSize: 15, fontWeight: 600, color: T.tx }}>{r.type}</span>
|
||
<Tag label={r.tagLabel} color={r.tagColor} bg={r.tagBg} />
|
||
</div>
|
||
<div style={{ fontSize: 12, color: T.tx3 }}>检查日期:{r.date}</div>
|
||
</div>
|
||
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={T.tx3} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M9 18l6-6-6-6"/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 屏幕5:报告详情(血常规) ───
|
||
function ReportDetail() {
|
||
const header = {
|
||
type: '血常规',
|
||
date: '2026年5月6日 14:00',
|
||
org: 'HMS 健康管理中心',
|
||
};
|
||
|
||
const items = [
|
||
{ name: '白细胞', value: '6.8', unit: '×10⁹/L', range: '3.5-9.5', status: 'normal' },
|
||
{ name: '红细胞', value: '4.2', unit: '×10¹²/L', range: '4.3-5.8', status: 'low' },
|
||
{ name: '血红蛋白', value: '110', unit: 'g/L', range: '130-175', status: 'low' },
|
||
{ name: '血小板', value: '210', unit: '×10⁹/L', range: '125-350', status: 'normal' },
|
||
{ name: '中性粒细胞', value: '65', unit: '%', range: '40-75', status: 'normal' },
|
||
];
|
||
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, display: 'flex', flexDirection: 'column' }}>
|
||
<NavBar title="报告详情" />
|
||
<div style={{ flex: 1, overflow: 'auto', padding: '20px 20px 24px' }}>
|
||
|
||
{/* 报告头部 */}
|
||
<div style={{ background: `linear-gradient(135deg, ${T.pri} 0%, ${T.priD} 100%)`, borderRadius: T.r, padding: '20px 22px', marginBottom: 20, color: '#fff', position: 'relative', overflow: 'hidden' }}>
|
||
<div style={{ position: 'absolute', top: -20, right: -20, width: 80, height: 80, borderRadius: 40, background: 'rgba(255,255,255,0.08)' }} />
|
||
<div style={{ fontFamily: T.serif, fontSize: 20, fontWeight: 700, marginBottom: 8 }}>{header.type}</div>
|
||
<div style={{ fontSize: 13, opacity: 0.85, marginBottom: 4 }}>{header.date}</div>
|
||
<div style={{ fontSize: 12, opacity: 0.7 }}>{header.org}</div>
|
||
</div>
|
||
|
||
{/* 异常提示 */}
|
||
<div style={{ background: T.wrnL, borderRadius: T.rSm, padding: '12px 16px', marginBottom: 18, display: 'flex', alignItems: 'center', gap: 8 }}>
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={T.wrn} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||
<path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/>
|
||
<line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
|
||
</svg>
|
||
<span style={{ fontSize: 13, color: T.wrn, fontWeight: 500 }}>2 项指标偏低,请关注</span>
|
||
</div>
|
||
|
||
{/* 指标列表 */}
|
||
<div style={{ background: T.card, borderRadius: T.r, overflow: 'hidden', boxShadow: '0 2px 12px rgba(0,0,0,0.04)' }}>
|
||
{/* 表头 */}
|
||
<div style={{ display: 'flex', padding: '12px 18px', borderBottom: `1px solid ${T.bdL}`, fontSize: 11, color: T.tx3, fontWeight: 600 }}>
|
||
<div style={{ flex: 1 }}>指标</div>
|
||
<div style={{ width: 52, textAlign: 'center' }}>结果</div>
|
||
<div style={{ width: 56, textAlign: 'center' }}>单位</div>
|
||
<div style={{ width: 64, textAlign: 'center' }}>参考范围</div>
|
||
<div style={{ width: 48, textAlign: 'center' }}>状态</div>
|
||
</div>
|
||
|
||
{items.map((item, i) => {
|
||
const isAbnormal = item.status !== 'normal';
|
||
return (
|
||
<div key={i} style={{
|
||
display: 'flex',
|
||
padding: '14px 18px',
|
||
alignItems: 'center',
|
||
borderBottom: i < items.length - 1 ? `1px solid ${T.bdL}` : 'none',
|
||
background: isAbnormal ? T.wrnL : 'transparent',
|
||
borderLeft: isAbnormal ? `3px solid ${T.wrn}` : '3px solid transparent',
|
||
}}>
|
||
<div style={{ flex: 1, fontSize: 13, fontWeight: 500, color: T.tx }}>{item.name}</div>
|
||
<div style={{ width: 52, textAlign: 'center', fontSize: 14, fontWeight: 600, color: isAbnormal ? T.wrn : T.tx }}>{item.value}</div>
|
||
<div style={{ width: 56, textAlign: 'center', fontSize: 11, color: T.tx3 }}>{item.unit}</div>
|
||
<div style={{ width: 64, textAlign: 'center', fontSize: 11, color: T.tx3 }}>{item.range}</div>
|
||
<div style={{ width: 48, textAlign: 'center' }}>
|
||
{isAbnormal ? (
|
||
<span style={{ fontSize: 11, color: T.wrn, fontWeight: 600 }}>↓偏低</span>
|
||
) : (
|
||
<span style={{ fontSize: 11, color: T.acc }}>正常</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
{/* 底部按钮 */}
|
||
<div style={{ marginTop: 24 }}>
|
||
<div style={{ background: T.pri, borderRadius: T.rSm, padding: '14px 0', textAlign: 'center', color: '#fff', fontSize: 15, fontWeight: 600, boxShadow: `0 4px 16px rgba(196,98,58,0.3)` }}>
|
||
咨询医生
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 组装 ───
|
||
function App() {
|
||
const screens = [
|
||
{ label: '1 · 健康记录列表', component: <HealthRecordList /> },
|
||
{ label: '2 · 诊断记录', component: <DiagnosisRecords /> },
|
||
{ label: '3 · 用药记录', component: <MedicationRecords /> },
|
||
{ label: '4 · 检查报告', component: <ExamReportList /> },
|
||
{ label: '5 · 报告详情', component: <ReportDetail /> },
|
||
];
|
||
|
||
return (
|
||
<div class="screens">
|
||
{screens.map((s, i) => (
|
||
<div class="screen-wrap" key={i}>
|
||
<IosFrame width={360} height={780}>{s.component}</IosFrame>
|
||
<div class="screen-label">{s.label}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
|
||
</script>
|
||
</body>
|
||
</html> |