- mp-11-doctor-core 设计交付包(截图 + tokens) - mp-13/mp-14 新原型 HTML - design-handoff skill 设计规格文档 - .gitignore 排除 dist-h5/test-results/uploads 等构建产物
245 lines
12 KiB
HTML
245 lines
12 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: 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">温润东方风设计系统 — 未登录用户的首页。品牌 Hero + 服务特色 + 健康资讯 + 底部注册/登录引导。TabBar 仅展示首页/健康/商城/我的四个入口。</div>
|
||
<div id="root"></div>
|
||
|
||
<script type="text/babel">
|
||
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 = 370, height = 800, 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 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>
|
||
);
|
||
}
|
||
|
||
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,
|
||
};
|
||
|
||
// ─── TabBar ───
|
||
function TabBar({ active = 0 }) {
|
||
const tabs = [
|
||
{ label: '首页', icon: '⌂' },
|
||
{ label: '健康', icon: '♡' },
|
||
{ label: '商城', icon: '◉' },
|
||
{ label: '我的', icon: '◎' },
|
||
];
|
||
return (
|
||
<div style={{
|
||
position: 'absolute', bottom: 0, left: 0, right: 0,
|
||
background: T.card, borderTop: `1px solid ${T.bdL}`,
|
||
display: 'flex', height: 80, paddingBottom: 20, zIndex: 10,
|
||
}}>
|
||
{tabs.map((tab, i) => (
|
||
<div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 2 }}>
|
||
<span style={{ fontSize: 20, color: i === active ? T.pri : T.tx3, lineHeight: 1 }}>{tab.icon}</span>
|
||
<span style={{ fontSize: 10, color: i === active ? T.pri : T.tx3, fontWeight: i === active ? 600 : 400 }}>{tab.label}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── 访客首页 ───
|
||
function GuestHome() {
|
||
const articles = [
|
||
{ title: '高血压患者的日常管理指南', date: '2026-05-15' },
|
||
{ title: '如何科学控制血糖水平', date: '2026-05-12' },
|
||
{ title: '透析患者的饮食注意事项', date: '2026-05-08' },
|
||
];
|
||
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, display: 'flex', flexDirection: 'column', position: 'relative' }}>
|
||
<div style={{ flex: 1, overflow: 'auto', paddingBottom: 80 }}>
|
||
{/* ── 轮播图(模拟 Swiper)── */}
|
||
<div style={{ position: 'relative', height: 200, overflow: 'hidden' }}>
|
||
{/* Slide 1 */}
|
||
<div style={{
|
||
position: 'absolute', inset: 0,
|
||
background: `linear-gradient(135deg, ${T.priD} 0%, ${T.pri} 60%, ${T.priL} 100%)`,
|
||
}} />
|
||
{/* 装饰圆 */}
|
||
<div style={{ position: 'absolute', top: -20, right: -10, width: 120, height: 120, borderRadius: 60, background: 'rgba(255,255,255,0.08)' }} />
|
||
|
||
<div style={{ position: 'relative', zIndex: 1, height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '0 24px' }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 24, fontWeight: 700, color: '#fff', marginBottom: 6 }}>
|
||
专业健康管理
|
||
</div>
|
||
<div style={{ fontSize: 14, color: 'rgba(255,255,255,0.8)' }}>
|
||
AI 驱动个性化健康方案
|
||
</div>
|
||
</div>
|
||
|
||
{/* 分页指示器 */}
|
||
<div style={{ position: 'absolute', bottom: 12, left: '50%', transform: 'translateX(-50%)', display: 'flex', gap: 6 }}>
|
||
<div style={{ width: 18, height: 4, borderRadius: 2, background: '#fff' }} />
|
||
<div style={{ width: 6, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
<div style={{ width: 6, height: 4, borderRadius: 2, background: 'rgba(255,255,255,0.4)' }} />
|
||
</div>
|
||
</div>
|
||
|
||
{/* ── 健康资讯 ── */}
|
||
<div style={{ padding: '24px 20px 0' }}>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 18, fontWeight: 700, color: T.tx }}>健康资讯</div>
|
||
<span style={{ fontSize: 13, color: T.tx3 }}>查看全部 ›</span>
|
||
</div>
|
||
|
||
{articles.map((a, i) => (
|
||
<div key={i} style={{
|
||
background: T.card, borderRadius: T.r, padding: 16, marginBottom: 10,
|
||
boxShadow: '0 1px 4px rgba(45,42,38,0.06)',
|
||
display: 'flex', alignItems: 'center', gap: 14,
|
||
}}>
|
||
<div style={{
|
||
width: 64, height: 64, borderRadius: T.rSm,
|
||
background: [T.priL, T.accL, T.wrnL][i % 3],
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
flexShrink: 0,
|
||
}}>
|
||
<span style={{ fontSize: 22, color: [T.pri, T.acc, T.wrn][i % 3] }}>
|
||
{['♥', '◇', '✦'][i % 3]}
|
||
</span>
|
||
</div>
|
||
<div style={{ flex: 1, minWidth: 0 }}>
|
||
<div style={{ fontSize: 15, fontWeight: 600, color: T.tx, marginBottom: 4, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
||
{a.title}
|
||
</div>
|
||
<div style={{ fontSize: 12, color: T.tx3 }}>{a.date}</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* ── 底部注册引导 ── */}
|
||
<div style={{ padding: '24px 20px 24px' }}>
|
||
<div style={{
|
||
background: T.card, borderRadius: T.r, padding: 20,
|
||
boxShadow: '0 1px 4px rgba(45,42,38,0.06)',
|
||
textAlign: 'center',
|
||
}}>
|
||
<div style={{ fontFamily: T.serif, fontSize: 16, fontWeight: 700, color: T.tx, marginBottom: 6 }}>
|
||
加入我们
|
||
</div>
|
||
<div style={{ fontSize: 13, color: T.tx2, marginBottom: 16, lineHeight: 1.5 }}>
|
||
注册后即可使用签到、积分商城等全部功能
|
||
</div>
|
||
<div style={{
|
||
height: 48, borderRadius: 24, background: T.pri,
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
boxShadow: `0 4px 16px rgba(196,98,58,0.3)`,
|
||
}}>
|
||
<span style={{ fontSize: 16, fontWeight: 600, color: '#fff' }}>注册 / 登录</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* TabBar */}
|
||
<TabBar active={0} />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// ─── TabBar 其他页面占位(灰色提示) ───
|
||
function PlaceholderTab({ title, icon }) {
|
||
return (
|
||
<div style={{ height: '100%', background: T.bg, display: 'flex', flexDirection: 'column', position: 'relative' }}>
|
||
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 12, padding: 20 }}>
|
||
<div style={{ width: 64, height: 64, borderRadius: 32, background: T.surface, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||
<span style={{ fontSize: 28, color: T.tx3 }}>{icon}</span>
|
||
</div>
|
||
<div style={{ fontSize: 16, fontWeight: 600, color: T.tx2 }}>登录后查看{title}</div>
|
||
<div style={{ fontSize: 13, color: T.tx3, textAlign: 'center', lineHeight: 1.5 }}>
|
||
请先登录以使用完整服务
|
||
</div>
|
||
<div style={{
|
||
marginTop: 8, height: 44, padding: '0 32px',
|
||
background: T.pri, borderRadius: 22,
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
boxShadow: `0 4px 16px rgba(196,98,58,0.3)`,
|
||
}}>
|
||
<span style={{ fontSize: 15, fontWeight: 600, color: '#fff' }}>去登录</span>
|
||
</div>
|
||
</div>
|
||
<TabBar active={1} />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function App() {
|
||
return (
|
||
<div className="screens">
|
||
<div className="screen-wrap">
|
||
<span className="screen-label">访客首页</span>
|
||
<IosFrame time="9:41" battery={85} darkStatus={true}>
|
||
<GuestHome />
|
||
</IosFrame>
|
||
</div>
|
||
<div className="screen-wrap">
|
||
<span className="screen-label">未登录 Tab 占位</span>
|
||
<IosFrame time="9:42" battery={84}>
|
||
<PlaceholderTab title="健康数据" icon="♡" />
|
||
</IosFrame>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
|
||
</script>
|
||
</body>
|
||
</html>
|