- 新增 12 个核心页面原型(登录/首页/咨询/预约/商城/健康等) - 新增医生端分包原型(核心 + 临床两个分包) - 新增 AI 客服对话页原型 - 新增 MP UI 优化指南文档 - 更新 wiki 基础设施和小程序文档
211 lines
13 KiB
HTML
211 lines
13 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:.15em;text-transform:uppercase}
|
||
.note{color:#666;font-size:12px;max-width:800px;text-align:center;line-height:1.8}
|
||
.screens{display:flex;gap:32px;flex-wrap:wrap;justify-content:center;align-items:flex-start}
|
||
.screen-wrap{display:flex;flex-direction:column;align-items:center;gap:10px}
|
||
.screen-label{color:#888;font-size:11px;font-style:italic}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="page-title">HMS 小程序 · 积分商城分包</div>
|
||
<div class="note">商品详情 + 兑换确认 + 订单列表 + 咨询聊天详情</div>
|
||
<div id="root"></div>
|
||
<script type="text/babel">
|
||
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};
|
||
|
||
const F={w:{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'},s:{position:'relative',borderRadius:48,overflow:'hidden',background:'#fff'},c:{position:'absolute',top:54,left:0,right:0,bottom:34,overflow:'auto'}};
|
||
function Frame({children,w=370,h=800}){
|
||
return(<div style={F.w}><div style={{...F.s,width:w,height:h}}>
|
||
<div style={{position:'absolute',top:0,left:0,right:0,height:54,display:'flex',alignItems:'center',justifyContent:'space-between',padding:'0 32px',fontSize:16,fontWeight:600,zIndex:20,pointerEvents:'none',color:'#000'}}>
|
||
<span>9:41</span>
|
||
<div style={{display:'flex',alignItems:'center',gap:6}}><div style={{width:26,height:12,border:'1.5px solid #000',borderRadius:3,padding:1}}><div style={{width:'85%',height:'100%',background:'#000',borderRadius:1}}/></div></div>
|
||
</div>
|
||
<div style={{position:'absolute',top:12,left:'50%',transform:'translateX(-50%)',width:124,height:36,background:'#000',borderRadius:999,zIndex:30}}/>
|
||
<div style={F.c}>{children}</div>
|
||
<div style={{position:'absolute',bottom:10,left:'50%',transform:'translateX(-50%)',width:140,height:5,background:'rgba(0,0,0,0.3)',borderRadius:999,zIndex:10}}/>
|
||
</div></div>);
|
||
}
|
||
|
||
function Nav({t}){
|
||
return(<div style={{height:44,display:'flex',alignItems:'center',justifyContent:'center',borderBottom:`1px solid ${T.bdL}`,position:'relative'}}>
|
||
<span style={{position:'absolute',left:16,color:T.pri,fontSize:20}}>‹</span>
|
||
<span style={{fontFamily:T.serif,fontSize:18,fontWeight:700,color:T.tx}}>{t}</span>
|
||
</div>);
|
||
}
|
||
|
||
function Tag({label,color=T.acc,bg=T.accL}){
|
||
return <span style={{display:'inline-block',padding:'2px 8px',borderRadius:6,fontSize:11,fontWeight:600,color,background:bg}}>{label}</span>;
|
||
}
|
||
|
||
// ── 屏幕1: 商品详情 ──
|
||
function ProductDetail(){
|
||
return(<div style={{background:T.bg,fontFamily:T.sans}}>
|
||
<Nav t="商品详情"/>
|
||
<div style={{background:T.surface,height:280,display:'flex',alignItems:'center',justifyContent:'center'}}>
|
||
<div style={{width:180,height:180,borderRadius:T.r,background:T.bd,display:'flex',alignItems:'center',justifyContent:'center',flexDirection:'column',gap:8}}>
|
||
<div style={{fontSize:36,opacity:.3}}>🩺</div>
|
||
<span style={{fontSize:12,color:T.tx3}}>智能血压计</span>
|
||
</div>
|
||
</div>
|
||
<div style={{padding:20,background:T.card,borderRadius:'20px 20px 0 0',marginTop:-16,position:'relative'}}>
|
||
<div style={{fontFamily:T.serif,fontSize:20,fontWeight:700,color:T.tx,marginBottom:8}}>智能血压计</div>
|
||
<div style={{display:'flex',alignItems:'baseline',gap:10,marginBottom:16}}>
|
||
<span style={{fontFamily:T.serif,fontSize:24,fontWeight:700,color:T.pri}}>1,200 积分</span>
|
||
<span style={{fontSize:14,color:T.tx3,textDecoration:'line-through'}}>¥199</span>
|
||
</div>
|
||
<div style={{fontSize:13,color:T.tx2,lineHeight:1.8,marginBottom:20}}>医用级精度,蓝牙连接手机自动记录数据,支持多人使用。大屏显示,操作简便,适合家庭日常监测。</div>
|
||
<div style={{display:'flex',flexDirection:'column',gap:10,padding:'14px 16px',background:T.bg,borderRadius:T.rSm,marginBottom:16}}>
|
||
{[['品牌','乐心'],['规格','臂式'],['库存','36件']].map(([k,v])=>(
|
||
<div key={k} style={{display:'flex',justifyContent:'space-between',fontSize:13}}><span style={{color:T.tx3}}>{k}</span><span style={{color:T.tx,fontWeight:500}}>{v}</span></div>
|
||
))}
|
||
</div>
|
||
<div style={{padding:12,background:T.wrnL,borderRadius:T.rSm,borderLeft:`3px solid ${T.wrn}`}}>
|
||
<div style={{fontSize:12,color:T.wrn,fontWeight:600,marginBottom:4}}>温馨提示</div>
|
||
<div style={{fontSize:11,color:T.tx2,lineHeight:1.6}}>积分兑换商品不支持退换货,请确认需求后再兑换。商品将在 7 个工作日内寄出。</div>
|
||
</div>
|
||
</div>
|
||
<div style={{position:'sticky',bottom:0,background:T.card,borderTop:`1px solid ${T.bdL}`,padding:'12px 20px',display:'flex',alignItems:'center',gap:12}}>
|
||
<div style={{width:48,height:48,border:`1px solid ${T.bd}`,borderRadius:T.rSm,display:'flex',alignItems:'center',justifyContent:'center',fontSize:20}}>♡</div>
|
||
<div style={{flex:1,height:48,background:T.pri,borderRadius:T.r,display:'flex',alignItems:'center',justifyContent:'center',color:'#fff',fontFamily:T.serif,fontSize:16,fontWeight:700}}>立即兑换</div>
|
||
</div>
|
||
</div>);
|
||
}
|
||
|
||
// ── 屏幕2: 兑换确认 ──
|
||
function ExchangeConfirm(){
|
||
return(<div style={{background:T.bg,fontFamily:T.sans}}>
|
||
<Nav t="确认兑换"/>
|
||
<div style={{padding:16}}>
|
||
<div style={{display:'flex',gap:12,padding:14,background:T.card,borderRadius:T.r,marginBottom:16,boxShadow:'0 1px 4px rgba(0,0,0,0.04)'}}>
|
||
<div style={{width:72,height:72,borderRadius:T.rSm,background:T.surface,display:'flex',alignItems:'center',justifyContent:'center',fontSize:24}}>🩺</div>
|
||
<div style={{flex:1}}>
|
||
<div style={{fontFamily:T.serif,fontSize:15,fontWeight:700,color:T.tx,marginBottom:4}}>智能血压计</div>
|
||
<div style={{fontSize:13,color:T.pri,fontWeight:600}}>1,200 积分</div>
|
||
<div style={{fontSize:11,color:T.tx3,marginTop:2}}>×1</div>
|
||
</div>
|
||
</div>
|
||
<div style={{padding:16,background:T.card,borderRadius:T.r,marginBottom:16}}>
|
||
<div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10}}>
|
||
<span style={{fontSize:14,fontWeight:600,color:T.tx}}>收货信息</span>
|
||
<span style={{fontSize:12,color:T.pri,fontWeight:500}}>修改地址 ›</span>
|
||
</div>
|
||
<div style={{fontSize:13,color:T.tx,fontWeight:500,marginBottom:2}}>张三 · 138****1234</div>
|
||
<div style={{fontSize:12,color:T.tx3,lineHeight:1.5}}>北京市朝阳区建国路88号健康大厦12层</div>
|
||
</div>
|
||
<div style={{padding:16,background:T.card,borderRadius:T.r,marginBottom:24}}>
|
||
<div style={{fontSize:14,fontWeight:600,color:T.tx,marginBottom:12}}>兑换明细</div>
|
||
{[['商品积分','1,200'],['运费','¥0.00'],['应扣积分','1,200'],['剩余积分','80']].map(([k,v],i)=>(
|
||
<div key={k} style={{display:'flex',justifyContent:'space-between',paddingBottom:i<3?8:0,marginBottom:i<3?8:0,borderBottom:i<3?`1px dashed ${T.bdL}`:'none'}}>
|
||
<span style={{fontSize:13,color:T.tx3}}>{k}</span>
|
||
<span style={{fontSize:13,color:i===2?T.pri:i===3?T.acc:T.tx,fontWeight:i>=2?600:400}}>{v}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<div style={{height:50,background:T.pri,borderRadius:T.r,display:'flex',alignItems:'center',justifyContent:'center',color:'#fff',fontFamily:T.serif,fontSize:16,fontWeight:700}}>确认兑换</div>
|
||
</div>
|
||
</div>);
|
||
}
|
||
|
||
// ── 屏幕3: 订单列表 ──
|
||
function OrderList(){
|
||
const tabs=['全部','待发货','已发货','已完成'];
|
||
const orders=[
|
||
{id:'HX20260515001',name:'智能血压计',pts:'1,200',status:'待发货',statusBg:T.wrnL,statusColor:T.wrn,date:'2026-05-15'},
|
||
{id:'HX20260510002',name:'维生素D3 60粒',pts:'360',status:'已发货',statusBg:T.accL,statusColor:T.acc,date:'2026-05-10'},
|
||
{id:'HX20260428003',name:'健康手册',pts:'150',status:'已完成',statusBg:T.bg,statusColor:T.tx3,date:'2026-04-28'},
|
||
];
|
||
return(<div style={{background:T.bg,fontFamily:T.sans}}>
|
||
<Nav t="兑换记录"/>
|
||
<div style={{display:'flex',padding:'0 16px',gap:0,background:T.card,borderBottom:`1px solid ${T.bdL}`}}>
|
||
{tabs.map((t,i)=>(
|
||
<div key={t} style={{flex:1,textAlign:'center',padding:'12px 0',fontSize:13,fontWeight:i===0?600:400,color:i===0?T.pri:T.tx3,borderBottom:i===0?`2px solid ${T.pri}`:'2px solid transparent'}}>{t}</div>
|
||
))}
|
||
</div>
|
||
<div style={{padding:16,display:'flex',flexDirection:'column',gap:12}}>
|
||
{orders.map(o=>(
|
||
<div key={o.id} style={{padding:16,background:T.card,borderRadius:T.r,boxShadow:'0 1px 4px rgba(0,0,0,0.04)'}}>
|
||
<div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:10}}>
|
||
<span style={{fontSize:11,color:T.tx3}}>订单号 {o.id}</span>
|
||
<Tag label={o.status} color={o.statusColor} bg={o.statusBg}/>
|
||
</div>
|
||
<div style={{display:'flex',justifyContent:'space-between',alignItems:'center'}}>
|
||
<div>
|
||
<div style={{fontSize:14,fontWeight:600,color:T.tx,marginBottom:2}}>{o.name}</div>
|
||
<div style={{fontSize:12,color:T.tx3}}>{o.date}</div>
|
||
</div>
|
||
<div style={{fontFamily:T.serif,fontSize:16,fontWeight:700,color:T.pri}}>{o.pts} <span style={{fontSize:11,fontWeight:400}}>积分</span></div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>);
|
||
}
|
||
|
||
// ── 屏幕4: 咨询聊天详情 ──
|
||
function ChatDetail(){
|
||
const Bubble=({left,children})=>(
|
||
<div style={{display:'flex',justifyContent:left?'flex-start':'flex-end',padding:'0 16px',marginBottom:10}}>
|
||
<div style={{maxWidth:'75%',padding:'10px 14px',borderRadius:left?'4px 16px 16px 16px':'16px 4px 16px 16px',background:left?T.card:T.priL,color:T.tx,fontSize:13,lineHeight:1.6}}>{children}</div>
|
||
</div>
|
||
);
|
||
return(<div style={{background:T.bg,fontFamily:T.sans,height:'100%',display:'flex',flexDirection:'column'}}>
|
||
<div style={{height:44,display:'flex',alignItems:'center',justifyContent:'center',borderBottom:`1px solid ${T.bdL}`,position:'relative',background:T.card}}>
|
||
<span style={{position:'absolute',left:16,color:T.pri,fontSize:20}}>‹</span>
|
||
<div style={{display:'flex',alignItems:'center',gap:8}}>
|
||
<span style={{fontFamily:T.serif,fontSize:16,fontWeight:700,color:T.tx}}>王医生 · 心内科</span>
|
||
<div style={{width:8,height:8,background:T.acc,borderRadius:'50%'}}/>
|
||
</div>
|
||
</div>
|
||
<div style={{flex:1,overflow:'auto',padding:'16px 0'}}>
|
||
<div style={{textAlign:'center',fontSize:11,color:T.tx3,marginBottom:16}}>今天 10:32</div>
|
||
<Bubble left>化验结果已出,您的血红蛋白偏低(95g/L),属于轻度贫血。</Bubble>
|
||
<Bubble left={false}>需要怎么处理呢?严重吗?</Bubble>
|
||
<Bubble left>不算严重,建议补充铁剂,配合维生素C促进吸收。我给您开个处方:</Bubble>
|
||
<div style={{padding:'0 16px',marginBottom:10}}>
|
||
<div style={{padding:14,background:T.card,borderRadius:T.r,borderLeft:`3px solid ${T.acc}`}}>
|
||
<div style={{fontSize:12,color:T.acc,fontWeight:600,marginBottom:6}}>处方建议</div>
|
||
<div style={{fontSize:14,fontWeight:600,color:T.tx,marginBottom:4}}>硫酸亚铁片</div>
|
||
<div style={{fontSize:12,color:T.tx2,lineHeight:1.5}}>用法:每次1片,每日3次,饭后服用</div>
|
||
<div style={{fontSize:11,color:T.tx3,marginTop:6}}>疗程:4周后复查血常规</div>
|
||
</div>
|
||
</div>
|
||
<Bubble left={false}>好的,谢谢王医生!</Bubble>
|
||
</div>
|
||
<div style={{padding:'10px 16px',background:T.card,borderTop:`1px solid ${T.bdL}`,display:'flex',alignItems:'center',gap:10}}>
|
||
<div style={{flex:1,height:40,background:T.bg,borderRadius:20,padding:'0 16px',display:'flex',alignItems:'center',fontSize:13,color:T.tx3}}>输入消息…</div>
|
||
<div style={{width:40,height:40,background:T.pri,borderRadius:20,display:'flex',alignItems:'center',justifyContent:'center',color:'#fff',fontSize:16}}>↑</div>
|
||
</div>
|
||
</div>);
|
||
}
|
||
|
||
// ── 渲染 ──
|
||
const screens=[
|
||
{label:'1 · 商品详情',el:<ProductDetail/>},
|
||
{label:'2 · 兑换确认',el:<ExchangeConfirm/>},
|
||
{label:'3 · 订单列表',el:<OrderList/>},
|
||
{label:'4 · 咨询聊天详情',el:<ChatDetail/>},
|
||
];
|
||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||
<div class="screens">
|
||
{screens.map((s,i)=>(
|
||
<div class="screen-wrap" key={i}>
|
||
<Frame w={370} h={800}>{s.el}</Frame>
|
||
<div class="screen-label">{s.label}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
);
|
||
</script>
|
||
</body>
|
||
</html> |