小草宠物美容_H5/app.js · 约 4992 字符
1// 小草宠物美容 · 逻辑层
2const $=s=>document.querySelector(s), $$=s=>document.querySelectorAll(s);
3const store={
4 get orders(){return JSON.parse(localStorage.getItem('pg_orders')||'[]')},
5 set orders(v){localStorage.setItem('pg_orders',JSON.stringify(v))},
6 get coupons(){return JSON.parse(localStorage.getItem('pg_coupons')||JSON.stringify(COUPONS))},
7 set coupons(v){localStorage.setItem('pg_coupons',JSON.stringify(v))}
8};
9function fmt(n){return '¥'+n.toFixed(0)}
10function 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,.78);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)}
11/* 预约 */
12let BK={pet:PETS[0].id,service:null,time:null};
13function renderPets(){
14 $('#pet-list').innerHTML=PETS.map(p=>`
15 <div class="pet-card${p.id===BK.pet?' sel':''}" onclick="BK.pet=${p.id};renderPets()">
16 <div class="pc-emoji">${p.emoji}</div>
17 <div class="pc-name">${p.name}</div>
18 <div class="pc-meta">${p.type} · ${p.age} · ${p.weight}</div>
19 </div>`).join('');
20}
21function renderService(){
22 $('#svc-list').innerHTML=SERVICES.map((s,i)=>`
23 <div class="service-card">
24 <div class="sc-emoji">${s.emoji}</div>
25 <div class="sc-body">
26 <div class="sc-name">${s.name} <span class="badge ${s.tags.includes('热门')?'badge-hot':s.tags.includes('新客推荐')?'badge-sale':'badge-new'}">${s.tags[0]}</span></div>
27 <div class="sc-desc">${s.desc}</div>
28 <div class="sc-meta">⏱️ ${s.time}</div>
29 <div class="sc-foot"><span class="sc-price"><em>¥</em>${s.price}</span>
30 <span class="sc-add" onclick="BK.service=${i};$$('.sc-add').forEach(x=>x.textContent='预约');$$('.sc-add').forEach((x,idx)=>x.style.background=(idx===${i})?'var(--primary)':'var(--primary-light)');$$('.sc-add').forEach((x,idx)=>x.style.color=(idx===${i})?'#fff':'var(--primary-dark)');this.textContent='已选';toast('已选择「${s.name}」')">预约</span></div>
31 </div>
32 </div>`).join('');
33}
34function renderTimes(){
35 $('#time-grid').innerHTML=TIMES.map(t=>{
36 const full=FULL_TIMES.includes(t);
37 return '<div class="time-cell'+(full?' full':'')+'" onclick="'+(full?"toast('该时段已约满,试试其他时段')":"BK.time='"+t+"';$$('.time-cell').forEach(x=>x.classList.remove('sel'));this.classList.add('sel')")+'">'+t+'</div>';
38 }).join('');
39}
40function submitBook(){
41 if(BK.service===null){toast('请先选择服务项目');return}
42 if(!BK.time){toast('请选择到店时段');return}
43 const svc=SERVICES[BK.service];const pet=PETS.find(p=>p.id===BK.pet);
44 const deposit=Math.round(svc.price*0.3);
45 const o={id:'PG'+Date.now().toString().slice(-8),service:svc.name,emoji:svc.emoji,pet:pet.name,petEmoji:pet.emoji,time:BK.time+' · 明天',price:svc.price,deposit,store:STORES[0].name,status:'待确认',step:0,date:new Date().toLocaleString('zh-CN',{month:'numeric',day:'numeric'})};
46 store.orders=[o,...store.orders];
47 store.coupons=store.coupons.slice(1);
48 toast('预约提交成功,定金 '+fmt(deposit)+' 元');
49 setTimeout(()=>location.href='orders.html',800);
50}
51function renderOrdersPage(){
52 const wrap=$('#order-list');const orders=store.orders;
53 const steps=[['待确认','✓'],['已确认','✓'],['服务中','🛁'],['已完成','🎉']];
54 if(!orders.length){wrap.innerHTML='<div class="empty"><span class="e-icon">🐾</span>还没有预约<br>带毛孩子来洗个香香吧~</div>';return}
55 wrap.innerHTML=orders.map(o=>`
56 <div class="order-card">
57 <div class="oc-head"><span>${o.date} · 预约号 ${o.id}</span><span class="oc-status">● ${o.status}</span></div>
58 <div class="oc-body"><span class="oc-emoji">${o.emoji}</span>
59 <div><div class="oc-name">${o.petEmoji} ${o.pet} · ${o.service}</div><div class="oc-meta">${o.store} · ${o.time}</div></div>
60 <div class="oc-price">¥${o.price}</div>
61 </div>
62 <div class="oc-steps">
63 ${steps.map((s,i)=>'<div class="os '+(i<o.step?'done':i===o.step?'now':'')+'"><span class="dot">'+s[1]+'</span>'+s[0]+'</div>').join('')}
64 </div>
65 <div style="font-size:11px;color:#b39a80;margin-top:8px">💡 已付定金 ¥${o.deposit},服务完成后支付尾款</div>
66 </div>`).join('');
67 $('#diary-list').innerHTML=DIARY.map(d=>'<div class="diary-item"><div class="di-emoji">'+d.emoji+'</div><div class="di-text">'+d.text+'</div></div>').join('');
68}
69function renderMine(){
70 $('#u-name').textContent=USER.name;$('#u-level').textContent=USER.level+' · '+USER.pet;
71 $('#m-points').textContent=USER.points;$('#m-balance').textContent=USER.balance;
72 $('#m-coupons').textContent=USER.coupons+store.coupons.length;
73 $('#m-times').textContent=USER.times;
74}
75