首页/ mobileweb/ 小草K歌/ 代码预览

💻 代码预览 · 小草K歌

mw_ent · 上传者 小草网络
← 返回详情
小草K歌_H5/app.js · 约 5902 字符
1// 小草K歌 · 逻辑层
2const $=s=>document.querySelector(s), $$=s=>document.querySelectorAll(s);
3const store={
4  get queue(){return JSON.parse(localStorage.getItem('kt_queue')||'[]')},
5  set queue(v){localStorage.setItem('kt_queue',JSON.stringify(v))},
6  get orders(){return JSON.parse(localStorage.getItem('kt_orders')||'[]')},
7  set orders(v){localStorage.setItem('kt_orders',JSON.stringify(v))},
8  get coupons(){return JSON.parse(localStorage.getItem('kt_coupons')||JSON.stringify(COUPONS))},
9  set coupons(v){localStorage.setItem('kt_coupons',JSON.stringify(v))}
10};
11function fmt(n){return '¥'+n.toFixed(0)}
12function toast(msg){const t=document.createElement('div');t.textContent=msg;t.style.cssText='position:fixed;top:20%;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.85);color:#fff;padding:10px 20px;border-radius:20px;font-size:13px;z-index:999;transition:opacity .3s';document.body.appendChild(t);setTimeout(()=>{t.style.opacity='0';setTimeout(()=>t.remove(),300)},1200)}
13/* 点歌 */
14function addSong(id){
15  const s=SONGS.find(x=>x.id==id);if(!s)return;
16  const q=store.queue;
17  if(q.find(i=>i.id===id)){toast('「'+s.name+'」已在歌单');return}
18  q.push(s);store.queue=q;
19  toast('已点歌:'+s.name);
20  refreshPlaying();
21}
22function refreshPlaying(){
23  const bar=$('#playing-bar');
24  if(bar){
25    const q=store.queue;
26    bar.style.display=q.length?'flex':'none';
27    $('#pb-song').textContent=q.length?q[0].name+' - '+q[0].singer:'';
28    $('#pb-count').textContent='已点 '+q.length+' 首';
29  }
30}
31function renderSongs(){
32  const q=store.queue;
33  $('#song-list').innerHTML=SONGS.map(s=>`
34    <div class="song-row">
35      <span class="sr-rank">${s.rank<4?'🔥':''}${s.rank}</span>
36      <div style="flex:1"><div class="sr-name">${s.name}</div><div class="sr-singer">${s.singer} · ${s.cat}</div></div>
37      <span class="sr-add" onclick="addSong(${s.id})">点歌</span>
38    </div>`).join('');
39  $('#queue-list').innerHTML=q.length?q.map(s=>`
40    <div class="song-row"><span class="sr-rank">🎵</span>
41    <div style="flex:1"><div class="sr-name">${s.name}</div><div class="sr-singer">${s.singer}</div></div>
42    <span class="sr-add" onclick="const q=store.queue;store.queue=q.filter(i=>i.id!==${s.id});renderSongs();refreshPlaying()">删除</span></div>`).join(''):'<div class="empty">歌单还是空的<br>点几首热歌开嗓吧~</div>';
43}
44/* 包厢 */
45let BK={room:null,slot:0};
46function renderRooms(){
47  $('#room-grid').innerHTML=ROOMS.map((r,i)=>`
48    <div class="room-item">
49      <span class="badge ${r.tag==='hot'?'badge-hot':r.tag==='new'?'badge-new':''} ri-tag">${r.tag==='hot'?'热门':r.tag==='new'?'新装':''}</span>
50      <div class="ri-emoji">${r.emoji}</div>
51      <div class="ri-name">${r.name}</div>
52      <div class="ri-meta">${r.seats} · ${r.desc}</div>
53      <div class="ri-price">¥${r.price}<small style="font-size:10px;color:#6f67a0">/${r.unit}</small></div>
54    </div>`).join('');
55  $('#time-tabs').innerHTML=TIME_SLOTS.map((t,i)=>'<span class="time-tab'+(i===0?' sel':'')+'" onclick="BK.slot='+i+';$$('.time-tab').forEach(x=>x.classList.remove('sel'));this.classList.add('sel')">'+t.name+' '+t.time+' <b style="color:var(--gold)">'+t.discount+'</b></span>').join('');
56}
57function submitRoom(){
58  if(BK.room===null){toast('请选择包厢房型');return}
59  const r=ROOMS[BK.room];const t=TIME_SLOTS[BK.slot];
60  const deposit=Math.round(r.price*2*0.3);
61  const o={id:'KT'+Date.now().toString().slice(-8),room:r.name,emoji:r.emoji,slot:t.name+'('+t.time+')',price:r.price*2,deposit,status:'待开房',time:new Date().toLocaleString('zh-CN',{month:'numeric',day:'numeric',hour:'2-digit',minute:'2-digit'})};
62  store.orders=[o,...store.orders];store.coupons=store.coupons.slice(1);
63  toast('包厢预订成功,定金 '+fmt(deposit)+' 元');
64  setTimeout(()=>location.href='order.html',800);
65}
66function renderOrders(){
67  const wrap=$('#order-list');const orders=store.orders;
68  const steps=[['待开房','✓'],['已开房','🎤'],['欢唱中','🎶'],['已结账','💳']];
69  if(!orders.length){wrap.innerHTML='<div class="empty"><span class="e-icon">🎤</span>还没有订单<br>开个包厢high起来~</div>';return}
70  wrap.innerHTML=orders.map(o=>`
71    <div class="order-card">
72      <div class="oc-head"><span>${o.time} · 订单号 ${o.id}</span><span class="oc-status">● ${o.status}</span></div>
73      <div class="oc-body"><span class="oc-emoji">${o.emoji}</span>
74        <div><div class="oc-name">${o.room} · ${o.slot}</div><div class="oc-meta">已付定金 ¥${o.deposit} · 到店核销开房</div></div>
75        <div class="oc-price">¥${o.price}</div>
76      </div>
77      <div class="oc-steps" style="display:flex;justify-content:space-between;margin-top:12px">${steps.map((s,i)=>'<div style="text-align:center;font-size:10px;color:#8b83b5;flex:1"><div style="width:20px;height:20px;border-radius:50%;background:'+(i<=0?'linear-gradient(135deg,#7c3aed,#22d3ee)':'#2a2350')+';margin:0 auto 3px;display:flex;align-items:center;justify-content:center;font-size:11px;color:#fff">'+s[1]+'</div>'+s[0]+'</div>').join('')}</div>
78    </div>`).join('');
79  $('#timer-card').innerHTML='<div class="tc-time">02:35</div><div class="tc-body"><b>欢唱剩余时间</b><br>房间:豪华房 A08 · 已欢唱 1小时25分<br>可在线加时 / 续订酒水</div><button class="btn btn-primary" style="width:auto;padding:8px 16px;font-size:12px" onclick="toast('已发送加时申请,店员正在处理')">加时</button>';
80}
81function renderMine(){
82  $('#u-name').textContent=USER.name;$('#u-level').textContent=USER.level+' · 累计欢唱 '+USER.times+' 次';
83  $('#m-points').textContent=USER.points;$('#m-balance').textContent=USER.balance;
84  $('#m-coupons').textContent=USER.coupons+store.coupons.length;
85  $('#m-times').textContent=USER.times;
86}
87