- 新增 12 个核心页面原型(登录/首页/咨询/预约/商城/健康等) - 新增医生端分包原型(核心 + 临床两个分包) - 新增 AI 客服对话页原型 - 新增 MP UI 优化指南文档 - 更新 wiki 基础设施和小程序文档
322 lines
18 KiB
HTML
322 lines
18 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: 600px; text-align: center; line-height: 1.8; }
|
||
.screens { display: flex; gap: 48px; 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">访客端设计:未登录用户看到的是品牌展示+功能引导+登录转化。首页轮播+资讯+功能卡片,"我的"页面显示登录引导。</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 = 393, height = 852, time = '9:41', battery = 85, darkStatus = false }) {
|
||
const sc = darkStatus ? '#fff' : '#000';
|
||
return (
|
||
<div style={iosFrameStyles.wrapper}>
|
||
<div style={{ ...iosFrameStyles.screen, width, height }}>
|
||
<div style={{ ...iosFrameStyles.statusBar, color: sc }}>
|
||
<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={sc}/><path d="M3 7.5a7 7 0 0110 0" stroke={sc} strokeWidth="1.3" fill="none" strokeLinecap="round"/><path d="M1 4.5a11 11 0 0114 0" stroke={sc} strokeWidth="1.3" fill="none" strokeLinecap="round" opacity="0.7"/></svg>
|
||
<div style={{ width: 26, height: 12, border: `1.5px solid ${sc}`, borderRadius: 3, padding: 1 }}><div style={{ width: `${battery}%`, height: '100%', background: sc, 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,
|
||
};
|
||
|
||
// ─── 访客首页:轮播1 — 品牌形象 ───
|
||
function GuestSlide1() {
|
||
return (
|
||
<div style={{ height: '100%', background: `linear-gradient(135deg, ${T.pri} 0%, ${T.priD} 60%, #5A3A2A 100%)`, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: '0 24px 60px', position: 'relative' }}>
|
||
{/* 装饰圆 */}
|
||
<div style={{ position: 'absolute', top: 40, right: -20, width: 160, height: 160, borderRadius: 80, background: 'rgba(255,255,255,0.08)' }} />
|
||
<div style={{ position: 'absolute', top: 80, right: 20, width: 80, height: 80, borderRadius: 40, background: 'rgba(255,255,255,0.06)' }} />
|
||
<div style={{ position: 'absolute', bottom: 120, left: -30, width: 120, height: 120, borderRadius: 60, background: 'rgba(255,255,255,0.05)' }} />
|
||
{/* 内容 */}
|
||
<div style={{ position: 'relative', zIndex: 2 }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 32, fontWeight: 700, color: '#fff', marginBottom: 8, lineHeight: 1.2 }}>温润守护</div>
|
||
<div style={{ fontFamily: T.serif, fontSize: 32, fontWeight: 700, color: '#fff', marginBottom: 16, lineHeight: 1.2 }}>健康同行</div>
|
||
<div style={{ fontSize: 14, color: 'rgba(255,255,255,0.8)', lineHeight: 1.6 }}>专业的健康管理平台<br/>让每一位患者享受智能化的关怀服务</div>
|
||
</div>
|
||
{/* 指示点 */}
|
||
<div style={{ display: 'flex', gap: 6, marginTop: 20 }}>
|
||
<div style={{ width: 24, height: 4, borderRadius: 2, background: '#fff' }} />
|
||
<div style={{ width: 8, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
<div style={{ width: 8, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 访客首页:完整页 ───
|
||
function GuestHome() {
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, overflowY: 'auto' }}>
|
||
{/* 轮播区域 */}
|
||
<div style={{ height: 280, position: 'relative' }}>
|
||
<GuestSlide1 />
|
||
</div>
|
||
|
||
{/* 健康资讯 */}
|
||
<div style={{ padding: '20px 20px 0' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
|
||
<span style={{ fontFamily: T.serif, fontSize: 18, fontWeight: 700, color: T.tx }}>健康资讯</span>
|
||
<span style={{ fontSize: 13, color: T.tx3 }}>更多 ›</span>
|
||
</div>
|
||
|
||
{/* 带封面的文章 */}
|
||
{[
|
||
{ title: '高血压患者日常饮食指南', summary: '科学饮食,轻松控制血压水平', hasCover: true },
|
||
{ title: '血液透析的日常注意事项', summary: '透析患者必知的生活管理要点', hasCover: true },
|
||
].map((article, i) => (
|
||
<div key={i} style={{ background: T.card, borderRadius: T.r, overflow: 'hidden', marginBottom: 10, boxShadow: '0 1px 4px rgba(45,42,38,0.04)', display: 'flex' }}>
|
||
<div style={{ width: 110, minHeight: 80, background: T.surface, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||
<span style={{ fontSize: 11, color: T.tx3 }}>配图</span>
|
||
</div>
|
||
<div style={{ padding: '12px 14px', flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||
<div style={{ fontSize: 15, fontWeight: 600, color: T.tx, marginBottom: 4, lineHeight: 1.4 }}>{article.title}</div>
|
||
<div style={{ fontSize: 13, color: T.tx2, lineHeight: 1.5 }}>{article.summary}</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
{/* 功能介绍卡片 — 3 个横排 */}
|
||
<div style={{ fontFamily: T.serif, fontSize: 18, fontWeight: 700, color: T.tx, marginTop: 20, marginBottom: 12 }}>我们的服务</div>
|
||
<div style={{ display: 'flex', gap: 10 }}>
|
||
{[
|
||
{ icon: '健', title: '健康数据管理', desc: '记录体征', bg: T.accL, color: T.acc },
|
||
{ icon: '约', title: '智能预约排班', desc: '在线预约', bg: T.priL, color: T.pri },
|
||
{ icon: '智', title: 'AI 健康分析', desc: '趋势解读', bg: T.wrnL, color: T.wrn },
|
||
].map((item, i) => (
|
||
<div key={i} style={{ flex: 1, background: T.card, borderRadius: T.r, padding: 16, textAlign: 'center', boxShadow: '0 1px 4px rgba(45,42,38,0.04)' }}>
|
||
<div style={{ width: 40, height: 40, borderRadius: 20, background: item.bg, display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 8px' }}>
|
||
<span style={{ fontFamily: T.serif, fontSize: 18, fontWeight: 700, color: item.color }}>{item.icon}</span>
|
||
</div>
|
||
<div style={{ fontSize: 13, fontWeight: 600, color: T.tx, marginBottom: 2 }}>{item.title}</div>
|
||
<div style={{ fontSize: 12, color: T.tx3 }}>{item.desc}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* 登录引导 */}
|
||
<div style={{ padding: '28px 20px 40px', textAlign: 'center' }}>
|
||
<div style={{ fontSize: 14, color: T.tx3, marginBottom: 16 }}>登录后即可使用完整健康管理服务</div>
|
||
<div style={{ height: 52, borderRadius: 14, background: T.pri, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 17, fontWeight: 600, boxShadow: `0 4px 16px rgba(196,98,58,0.3)` }}>立即登录</div>
|
||
</div>
|
||
|
||
{/* TabBar — 无选中态 */}
|
||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 80, background: '#fff', borderTop: `1px solid ${T.bdL}`, display: 'flex', alignItems: 'center', justifyContent: 'space-around', paddingBottom: 10 }}>
|
||
{['首页','健康','消息','我的'].map((t, i) => (
|
||
<div key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2, color: i === 0 ? T.pri : T.tx3, fontSize: 10 }}>
|
||
<div style={{ width: 24, height: 24, borderRadius: 6, background: i === 0 ? T.pri : T.surface, display: 'flex', alignItems: 'center', justifyContent: 'center', color: i === 0 ? '#fff' : T.tx3, fontSize: 12 }} />
|
||
<span>{t}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 访客首页:轮播2 — 智慧健康 ───
|
||
function GuestSlide2() {
|
||
return (
|
||
<div style={{ height: '100%', background: `linear-gradient(135deg, ${T.acc} 0%, #3A5A3E 60%, #2A3A2E 100%)`, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: '0 24px 60px', position: 'relative' }}>
|
||
<div style={{ position: 'absolute', top: 50, right: 10, width: 140, height: 140, borderRadius: 70, background: 'rgba(255,255,255,0.08)' }} />
|
||
<div style={{ position: 'relative', zIndex: 2 }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 32, fontWeight: 700, color: '#fff', marginBottom: 16, lineHeight: 1.2 }}>智慧健康管理</div>
|
||
<div style={{ fontSize: 14, color: 'rgba(255,255,255,0.8)', lineHeight: 1.6 }}>AI 驱动个性化健康方案<br/>智能分析您的健康趋势</div>
|
||
</div>
|
||
<div style={{ display: 'flex', gap: 6, marginTop: 20 }}>
|
||
<div style={{ width: 8, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
<div style={{ width: 24, height: 4, borderRadius: 2, background: '#fff' }} />
|
||
<div style={{ width: 8, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 访客首页:轮播3 — 就医体验 ───
|
||
function GuestSlide3() {
|
||
return (
|
||
<div style={{ height: '100%', background: `linear-gradient(135deg, #6B8E9B 0%, #3A5A6A 60%, #2A3A4A 100%)`, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: '0 24px 60px', position: 'relative' }}>
|
||
<div style={{ position: 'absolute', top: 60, left: 20, width: 100, height: 100, borderRadius: 50, background: 'rgba(255,255,255,0.06)' }} />
|
||
<div style={{ position: 'relative', zIndex: 2 }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 32, fontWeight: 700, color: '#fff', marginBottom: 16, lineHeight: 1.2 }}>温馨就医环境</div>
|
||
<div style={{ fontSize: 14, color: 'rgba(255,255,255,0.8)', lineHeight: 1.6 }}>舒适安全的治疗体验<br/>专业团队全程陪伴</div>
|
||
</div>
|
||
<div style={{ display: 'flex', gap: 6, marginTop: 20 }}>
|
||
<div style={{ width: 8, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
<div style={{ width: 8, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
<div style={{ width: 24, height: 4, borderRadius: 2, background: '#fff' }} />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 访客"我的"页面 ───
|
||
function GuestProfile() {
|
||
const menuGroups = [
|
||
{
|
||
title: '健康服务',
|
||
items: [
|
||
{ label: '健康资讯', icon: '文', bg: T.priL, color: T.pri },
|
||
{ label: '关于我们', icon: '关', bg: T.accL, color: T.acc },
|
||
],
|
||
},
|
||
{
|
||
title: '支持',
|
||
items: [
|
||
{ label: '帮助中心', icon: '帮', bg: T.surface, color: T.tx3 },
|
||
{ label: '意见反馈', icon: '反', bg: T.surface, color: T.tx3 },
|
||
{ label: '设置', icon: '齿', bg: T.surface, color: T.tx3 },
|
||
],
|
||
},
|
||
];
|
||
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, overflowY: 'auto' }}>
|
||
<div style={{ padding: '20px 20px 100px' }}>
|
||
{/* 未登录用户卡片 */}
|
||
<div style={{ background: T.card, borderRadius: T.r, padding: 20, boxShadow: '0 2px 12px rgba(45,42,38,0.06)', marginBottom: 16, display: 'flex', alignItems: 'center', gap: 16 }}>
|
||
<div style={{ width: 60, height: 60, borderRadius: 30, background: T.surface, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
||
<span style={{ fontFamily: T.serif, fontSize: 28, fontWeight: 700, color: T.tx3 }}>?</span>
|
||
</div>
|
||
<div style={{ flex: 1 }}>
|
||
<div style={{ fontSize: 22, fontWeight: 700, color: T.tx, fontFamily: T.serif, marginBottom: 2 }}>未登录</div>
|
||
<div style={{ fontSize: 14, color: T.tx3 }}>点击登录,开启健康管理之旅</div>
|
||
</div>
|
||
<span style={{ color: T.tx3, fontSize: 16 }}>›</span>
|
||
</div>
|
||
|
||
{/* 登录引导卡 */}
|
||
<div style={{ background: `linear-gradient(135deg, ${T.priL} 0%, #E8C8B8 100%)`, borderRadius: T.r, padding: 20, marginBottom: 24, display: 'flex', alignItems: 'center', gap: 16 }}>
|
||
<div style={{ flex: 1 }}>
|
||
<div style={{ fontSize: 16, fontWeight: 600, color: T.tx, marginBottom: 4 }}>登录享受完整服务</div>
|
||
<div style={{ fontSize: 13, color: T.tx2, lineHeight: 1.5 }}>体征记录 · 智能分析 · 在线咨询 · 预约挂号</div>
|
||
</div>
|
||
<div style={{ height: 44, padding: '0 20px', borderRadius: T.rSm, background: T.pri, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 15, fontWeight: 600, flexShrink: 0 }}>登录</div>
|
||
</div>
|
||
|
||
{/* 分组菜单 */}
|
||
{menuGroups.map((group, gi) => (
|
||
<div key={gi} style={{ marginBottom: 14 }}>
|
||
<div style={{ fontSize: 14, fontWeight: 600, color: T.tx2, marginBottom: 8, paddingLeft: 4 }}>{group.title}</div>
|
||
<div style={{ background: T.card, borderRadius: T.r, overflow: 'hidden', boxShadow: '0 1px 4px rgba(45,42,38,0.04)' }}>
|
||
{group.items.map((item, ii) => (
|
||
<div key={ii} style={{
|
||
display: 'flex', alignItems: 'center', gap: 14, padding: '14px 16px',
|
||
borderBottom: ii < group.items.length - 1 ? `1px solid ${T.bdL}` : 'none',
|
||
}}>
|
||
<div style={{ width: 36, height: 36, borderRadius: T.rSm, background: item.bg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
||
<span style={{ fontFamily: T.serif, fontSize: 16, fontWeight: 700, color: item.color }}>{item.icon}</span>
|
||
</div>
|
||
<span style={{ flex: 1, fontSize: 15, color: T.tx }}>{item.label}</span>
|
||
<span style={{ color: T.tx3, fontSize: 14 }}>›</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* TabBar */}
|
||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 80, background: '#fff', borderTop: `1px solid ${T.bdL}`, display: 'flex', alignItems: 'center', justifyContent: 'space-around', paddingBottom: 10 }}>
|
||
{['首页','健康','消息','我的'].map((t, i) => (
|
||
<div key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2, color: i === 3 ? T.pri : T.tx3, fontSize: 10 }}>
|
||
<div style={{ width: 24, height: 24, borderRadius: 6, background: i === 3 ? T.pri : T.surface, display: 'flex', alignItems: 'center', justifyContent: 'center', color: i === 3 ? '#fff' : T.tx3, fontSize: 12 }} />
|
||
<span>{t}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 渲染 ───
|
||
function App() {
|
||
return (
|
||
<div className="screens">
|
||
<div className="screen-wrap">
|
||
<span className="screen-label">访客首页 — 轮播 1</span>
|
||
<IosFrame time="9:41" battery={85} darkStatus={true}>
|
||
<GuestSlide1 />
|
||
</IosFrame>
|
||
</div>
|
||
<div className="screen-wrap">
|
||
<span className="screen-label">访客首页 — 完整页</span>
|
||
<IosFrame time="9:41" battery={85}>
|
||
<GuestHome />
|
||
</IosFrame>
|
||
</div>
|
||
<div className="screen-wrap">
|
||
<span className="screen-label">访客首页 — 轮播 2</span>
|
||
<IosFrame time="9:41" battery={85} darkStatus={true}>
|
||
<GuestSlide2 />
|
||
</IosFrame>
|
||
</div>
|
||
<div className="screen-wrap">
|
||
<span className="screen-label">访客首页 — 轮播 3</span>
|
||
<IosFrame time="9:41" battery={85} darkStatus={true}>
|
||
<GuestSlide3 />
|
||
</IosFrame>
|
||
</div>
|
||
<div className="screen-wrap">
|
||
<span className="screen-label">访客"我的"页面</span>
|
||
<IosFrame time="9:41" battery={85}>
|
||
<GuestProfile />
|
||
</IosFrame>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
|
||
</script>
|
||
</body>
|
||
</html>
|