编辑页面

修改后将从当前时间重新计算过期时间

提交后订单将推送至食堂,制作开始前可取消

合计
¥${(amount+pack).toFixed(2)}
`; }; /* ---- 提交成功 ---- */ SCREENS.success = () => { const o = state.live || { no:'HP202610090023', period:'中餐', eta:'12:20', amount:39.00 }; return `
✅

订单提交成功

订单已推送至${o.period}食堂
预计 ${o.eta} 送达 ${state.ward.bed}

订单号${o.no}
配送地址${state.ward.building} ${state.ward.floor} ${state.ward.bed}
实付金额${money(o.amount)}
当前状态待制作

制作开始前可在订单详情中取消订单

`; }; /* ---- 非订餐时段 ---- */ SCREENS.closed = () => `
🌙

当前非订餐时间

今日订餐服务已结束
下次可订餐时段如下,请合理安排

🍳 早餐06:00 - 08:30
🍱 中餐10:30 - 12:30
🍲 晚餐16:30 - 18:30

非订餐时段仍可浏览菜品、查看订单与健康饮食文章

`; /* ---- 订单列表 ---- */ function statusSteps(cur, tags=true){ const labels = tags ? ['待制作','制作中','已取餐','配送中','已送达'] : STATUS; return `
${labels.map((s,i)=>`
${i<=cur?'✓':i+1}
${s}
`).join('')}
`; } SCREENS.orders = () => { const live = state.live; const isCurrent = state.orderTab==='current'; const hist = state.orders; return `
进行中${live&&live.status<4?' ●':''}
历史订单
${isCurrent ? (live && live.status<4 ? `
${STATUS[live.status]}${live.no}
${statusSteps(live.status)}
${live.dishes.map(([id,q])=>{const d=dish(id);return `
${d.emoji}
${d.name}×${q}
`}).join('')}
配送至 ${state.ward.building} ${state.ward.floor} ${state.ward.bed} ¥${live.amount.toFixed(2)}
${live.status<4 ? `
▶ 模拟:推进配送状态
` : ''} ` : `
🍽️暂无进行中的订单
`) : ` ${hist.map(o=>`
已送达${o.no}
${o.dishes.map(([id,q])=>{const d=dish(id);return `
${d.emoji}
${d.name}×${q}
`}).join('')}
${o.time} · ${o.period} ¥${o.amount.toFixed(2)}
`).join('')} `}
`; }; /* ---- 订单详情 ---- */ SCREENS.orderDetail = () => { const o = state.live || { no:'HP202610090023', status:1, amount:39, eta:'12:20', period:'中餐', dishes:[] }; const isDone = o.status>=4; return `

${isDone?'订单已完成':'订单进行中'}

${isDone?'感谢您的使用,祝早日康复':'预计 '+o.eta+' 送达 · 请留意配送员电话'}

配送信息
配送地址${state.ward.building} ${state.ward.floor} ${state.ward.bed}
患者姓名${state.ward.name?esc(state.ward.name):'—'}
联系电话${esc(state.ward.phone)}
订单备注${state.remark?esc(state.remark):'无'}
菜品明细
${o.dishes.map(([id,q])=>{const d=dish(id);return `
${d.emoji}
${d.name} ×${q} ${money(d.price*q)}
`}).join('')}
包装费¥1.00
优惠-¥2.00 住院患者立减
实付金额${money(o.amount)}
订单信息
订单号${o.no}
下单时间2026-10-09 11:48
餐次${o.period}
支付方式${state.payMethod}
${o.status<4 ? `
` : `
`}`; }; /* ---- 健康专区 ---- */ SCREENS.zones = () => `

健康饮食专区

按住院人群分类的营养知识库
点击专区查看对应饮食指导与食谱

${ZONES.map(z=>`
${z.icon}
${z.name}
${z.count} 篇饮食指导
`).join('')}
今日推荐
🍚
糖尿病患者的进餐顺序
先菜、再肉、后主食,有助于平稳餐后血糖波动。
🫀
高血压患者的每日食盐该怎么控?
推荐每人每日食盐不超过 5g,隐形盐更需警惕。
`; /* ---- 专区文章列表 ---- */ SCREENS.zoneList = () => { const z = ZONES.find(x=>x.id===state.zoneView) || ZONES[0]; const list = ARTICLES[z.id] || []; return `
${z.icon}
${z.name}
${list.length} 篇饮食知识与食谱
${list.map((a,i)=>`
${a.g}
${a.t}
${a.s}
`).join('')}
`; }; /* ---- 文章详情 ---- */ SCREENS.article = () => { const z = ZONES.find(x=>x.id===state.zoneView) || ZONES[0]; const a = state.articleView || (ARTICLES[z.id]||[])[0] || {t:'',s:'',g:''}; const fav = state.favorite.includes('art:'+a.t); return `
${z.name}

${esc(a.t)}

营养科 · 2026-10-09 · 阅读 1.2万

${esc(a.s)}

为什么要重视饮食管理

住院期间的身体恢复与日常饮食密切相关。合理的膳食结构不仅能提供充足的能量与营养素,还能减轻代谢负担,帮助药物与治疗更好地发挥作用。

具体建议

住院点餐怎么选

在本小程序「营养套餐」分类中,已按高血压、糖尿病、孕产妇、老年等人群预先搭配好套餐,一键选择即可,尽量少选腌制品、油炸与浓汤类菜品。

本文内容仅供参考,具体饮食方案请以主管医师与营养师建议为准。

`; }; /* ---- 个人中心 ---- */ SCREENS.me = () => `
${state.logged?'🐱':'🙂'}
${state.logged?(state.ward.name?esc(state.ward.name):'微信用户'):'未登录'}
${state.logged?'已通过微信授权登录':'点击登录,同步您的订单与收藏'}
🏥我的病房信息› ${state.ward.building} ${state.ward.floor} ${state.ward.bed}
📦我的订单›
⭐我的收藏›
📞联系客服›
💬意见反馈›
账户
${state.logged ? `` : ``}

版本 v2.0.1 · 医院后勤膳食服务

`; /* ---- 我的收藏 ---- */ SCREENS.favorites = () => { const arts = state.favorite.filter(f=>f.startsWith('art:')).map(f=>f.slice(4)); const dis = state.favorite.filter(f=>!f.startsWith('art:')); if(!arts.length && !dis.length) return `
⭐还没有收藏内容
收藏的菜品与健康文章会出现在这里
`; return `
${dis.length?`
收藏的菜品
${dis.map(id=>{const d=dish(id);return `
${d.emoji}
${d.name}
${d.desc}
${money(d.price)}
`}).join('')}
`:''} ${arts.length?`
收藏的文章
${arts.map(t=>{const z=ZONES.find(x=>(ARTICLES[x.id]||[]).some(a=>a.t===t))||ZONES[0]; const a=(ARTICLES[z.id]||[]).find(a=>a.t===t)||{g:'📖'}; return `
${a.g}
${esc(t)}
${z.name}
`}).join('')}
`:''}
`; }; /* ---- 意见反馈 ---- */ SCREENS.feedback = () => `
反馈类型
${['餐品口味','配送速度','服务态度','菜品分量','包装卫生','其他'].map((t,i)=> `${t}`).join('')}
详细描述
📎 可上传图片(选填)
+
联系电话(选填)${esc(state.ward.phone)}
`; /* ---- 联系客服 ---- */ SCREENS.service = () => `
☎️
食堂订餐服务热线
0755-8888 6666
服务时间 06:00 - 19:00
营养科咨询0755-8888 6688
配送问题反馈0755-8888 6699
现场服务台住院部 1 楼食堂窗口

如遇配送异常,请同时提供订单号以便快速处理

`; /* ================== 主渲染 ================== */ function render(){ const p = current(); const s = $('#screen'); s.innerHTML = (SCREENS[p.page] || (()=>'
页面不存在
'))(); s.classList.remove('fade'); void s.offsetWidth; s.classList.add('fade'); renderChrome(p); renderSitemapActive(p.page); s.scrollTop = 0; } function renderSitemapActive(page){ const map = { ward:['ward'], wardEdit:['wardEdit'], home:['home'], dish:['dish'], cart:['cart'], confirm:['confirm'], success:['success'], closed:['closed'], orders:['orders'], orderDetail:['orderDetail'], zones:['zones'], zoneList:['zoneList'], article:['article'], me:['me'], favorites:['favorites'], feedback:['feedback'], service:['service'], scan:['scan'], login:['login'] }; const keys = map[page] || []; document.querySelectorAll('.sm-item').forEach(el=>el.classList.toggle('on', keys.includes(el.dataset.nav))); } /* ================== 手势 / 交互 ================== */ function popup(html){ const l = $('#layer'); l.innerHTML = `
${html}
`; } $('#layer').addEventListener('click', e=>{ if(e.target.closest('[data-stop]')) return; if(e.target.classList.contains('mask')) $('#layer').innerHTML=''; }); document.addEventListener('click', e=>{ // 页面地图 const sm = e.target.closest('.sm-item'); if(sm){ const t = sm.dataset.nav; if(TABS.includes(t)) tabTo(t); else { stack=[{page:t}]; render(); } return; } // 底部标签 const tab = e.target.closest('.tab'); if(tab){ state.orderTab='current'; tabTo(tab.dataset.tab); return; } const go = e.target.closest('[data-tab-go]'); if(go){ tabTo(go.dataset.tabGo); return; } const navEl = e.target.closest('[data-nav]'); if(navEl){ const id = navEl.dataset.id; const page = navEl.dataset.nav; const params = {}; if(id){ if(page==='dish') params.dishView = id; if(page==='zoneList') params.zoneView = id; } nav(page, params); return; } const cat = e.target.closest('[data-cat]'); if(cat){ state.cat_ = cat.dataset.cat; render(); return; } const per = e.target.closest('[data-period]'); if(per){ state.session = per.dataset.p; document.querySelectorAll('#segPeriod button').forEach(b=>b.classList.toggle('on', b.dataset.p===state.session)); if(TABS.includes(current().page)) render(); toast('已切换为「'+PERIODS[state.session].name+'」'); return; } const ot = e.target.closest('[data-otab]'); if(ot){ state.orderTab = ot.dataset.otab; render(); return; } const fb = e.target.closest('[data-fb]'); if(fb){ state.fbType = fb.dataset.fb; render(); return; } const act = e.target.closest('[data-act]'); if(!act) return; const id = act.dataset.id; switch(act.dataset.act){ case 'back': back(); break; case 'scan': nav('login'); break; case 'login': state.logged = true; if(!state.ward.name) state.ward.name = '张桂芬'; stack=[{page:'ward'}]; render(); toast('登录成功'); break; case 'skipLogin': stack=[{page:'ward'}]; render(); break; case 'logout': state.logged=false; render(); toast('已退出登录'); break; case 'toggleSave': state.ward.save = !state.ward.save; render(); break; case 'wardSubmit': { const w = state.ward; if(!w.building||!w.floor||!w.bed){ toast('请完整选择楼栋/楼层/床位'); return; } if(!w.name.trim()){ toast('请填写患者姓名'); return; } w.filled = true; stack=[{page:'home'}]; state.activeTab='home'; render(); toast('病房信息已保存'); break; } case 'inc': state.cart[id]=(state.cart[id]||0)+1; render(); break; case 'dec': { const q=(state.cart[id]||0)-1; if(q<=0) delete state.cart[id]; else state.cart[id]=q; render(); break; } case 'openCart': stack.push({page:'cart'}); render(); break; case 'clearCart': state.cart={}; render(); toast('购物车已清空'); break; case 'submit': { const items = Object.entries(state.cart).filter(([,q])=>q>0); if(!items.length){ toast('购物车为空'); return; } const amount = +(cartTotal()+1).toFixed(2); state.live = { no:'HP'+Date.now().toString().slice(-12), status:0, amount, eta:'12:20', period:PERIODS[state.session].name, dishes: items.map(([i,q])=>[i,q]) }; state.cart={}; state.remark=''; stack=[{page:'success'}]; render(); break; } case 'advance': { if(!state.live) return; state.live.status = Math.min(4, state.live.status+1); if(state.live.status===4){ state.orders.unshift({no:state.live.no, status:4, dishes:state.live.dishes, amount:state.live.amount, time:'2026-10-09 11:48', period:state.live.period, rated:false}); state.live = null; state.orderTab='history'; } render(); toast(state.live? '状态已更新:'+STATUS[state.live.status] : '订单已完成'); break; } case 'cancel': popup(`

确认取消订单?

制作开始前可取消,退款将原路返回

`); break; case 'doCancel': state.live = null; $('#layer').innerHTML=''; state.orderTab='current'; stack=[{page:'orders'}]; render(); toast('订单已取消'); break; case 'closePop': $('#layer').innerHTML=''; break; case 'fav': { const d = state.dishView, i = state.favorite.indexOf(d); if(i>=0){ state.favorite.splice(i,1); toast('已取消收藏'); } else { state.favorite.push(d); toast('已加入收藏'); } render(); break; } case 'favArt': { const t = 'art:'+act.dataset.t, i = state.favorite.indexOf(t); if(i>=0){ state.favorite.splice(i,1); toast('已取消收藏'); } else { state.favorite.push(t); toast('已加入收藏'); } render(); break; } case 'openArticle': state.articleView = (ARTICLES[state.zoneView]||[])[+act.dataset.i]; nav('article'); break; case 'openFavArt': { state.zoneView = act.dataset.z; state.articleView = (ARTICLES[act.dataset.z]||[]).find(a=>a.t===act.dataset.t); nav('article'); break; } case 'rebuy': { const o = state.orders.find(x=>x.no===act.dataset.no) || state.live; if(!o) return; state.cart = {}; o.dishes.forEach(([i,q])=>state.cart[i]=(state.cart[i]||0)+q); tabTo('home'); toast('已加入购物车,可直接结算'); break; } case 'rate': toast('感谢您的评价 ⭐⭐⭐⭐⭐'); break; case 'home': tabTo('home'); break; case 'contact': nav('service'); break; case 'call': toast('正在呼叫 0755-8888 6666…'); break; case 'submitFb': toast('反馈已提交,我们会尽快处理'); setTimeout(()=>{ stack=[{page:'me'}]; render(); }, 700); break; } }); // 表单联动 document.addEventListener('change', e=>{ const sel = e.target.closest('[data-sel]'); if(sel){ const k = sel.dataset.sel; if(k==='building'){ state.ward.building = sel.value; state.ward.floor=''; state.ward.bed=''; } else if(k==='floor'){ state.ward.floor = sel.value; state.ward.bed=''; } else if(k==='bed'){ state.ward.bed = sel.value; } render(); return; } }); document.addEventListener('input', e=>{ const inp = e.target.closest('[data-inp]'); if(!inp) return; const k = inp.dataset.inp; if(k==='remark') state.remark = inp.value; else state.ward[k] = inp.value; }); /* 时段按钮 */ document.querySelectorAll('#segPeriod button').forEach(b=>{ b.addEventListener('click', ()=>{ state.session = b.dataset.p; document.querySelectorAll('#segPeriod button').forEach(x=>x.classList.toggle('on', x===b)); if(TABS.includes(current().page)) render(); toast('模拟时段:'+PERIODS[state.session].name); }); }); /* 初始 */ render();
取消
访问码: ac56njmx