首页/ mobileweb/ 小草生鲜到家/ 代码预览

💻 代码预览 · 小草生鲜到家

mw_shop · 上传者 小草网络
← 返回详情
小草生鲜到家_H5/app.js · 约 6555 字符
1// 小草生鲜到家 · 逻辑层
2const $=s=>document.querySelector(s), $$=s=>document.querySelectorAll(s);
3const store={
4  get cart(){return JSON.parse(localStorage.getItem('fr_cart')||'[]')},
5  set cart(v){localStorage.setItem('fr_cart',JSON.stringify(v))},
6  get orders(){return JSON.parse(localStorage.getItem('fr_orders')||'[]')},
7  set orders(v){localStorage.setItem('fr_orders',JSON.stringify(v))},
8  get coupons(){return JSON.parse(localStorage.getItem('fr_coupons')||'3')},
9  set coupons(v){localStorage.setItem('fr_coupons',v)}
10};
11function fmt(n){return '¥'+n.toFixed(2)}
12function cartCount(){return store.cart.reduce((s,i)=>s+i.num,0)}
13function cartTotal(){return store.cart.reduce((s,i)=>s+i.num*i.price,0)}
14function goodsById(id){return GOODS.find(g=>g.id==id)}
15function 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)}
16function addToCart(id,qty){
17  const g=goodsById(id);if(!g)return;
18  const cart=store.cart;
19  const exist=cart.find(i=>i.id===id);
20  if(exist)exist.num+=qty||1;else cart.push({id,name:g.name,emoji:g.emoji,price:g.price,unit:g.unit,num:qty||1});
21  store.cart=cart;toast('已加入购物车');
22  const c=cartCount();const el=$('.cb-count');if(el){el.textContent=c;el.style.display=c?'flex':'none'}
23  const t=$('.cb-total b');if(t)t.textContent=fmt(cartTotal());
24}
25function renderCartPage(){
26  const wrap=$('#cart-items');const cart=store.cart;
27  if(!cart.length){wrap.innerHTML='<div class="empty"><span class="e-icon">🛒</span>购物车还是空的<br>去挑点新鲜好菜吧~</div>';$('#cart-submit').style.display='none';return}
28  $('#cart-submit').style.display='block';
29  wrap.innerHTML=cart.map((i,idx)=>`
30    <div class="order-item">
31      <div class="oi-img">${i.emoji}</div>
32      <div class="oi-body">
33        <div class="oi-name">${i.name}</div>
34        <div class="oi-spec">${i.unit} · 冷链配送</div>
35        <div class="oi-foot"><span class="oi-price">${fmt(i.price*i.num)}</span>
36          <span style="display:flex;align-items:center;gap:10px">
37            <span class="sq-btn" style="width:24px;height:24px;border-radius:50%;background:#eef5e8;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer" onclick="chgQty(${idx},-1)">−</span>
38            <b style="font-size:14px">${i.num}</b>
39            <span class="sq-btn" style="width:24px;height:24px;border-radius:50%;background:#eef5e8;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer" onclick="chgQty(${idx},1)">+</span>
40          </span>
41        </div>
42      </div>
43    </div>`).join('');
44  $('#cart-total').textContent=fmt(cartTotal());
45  $('#cart-count').textContent=cartCount();
46  updSummary();
47}
48function chgQty(idx,d){
49  const cart=store.cart;cart[idx].num+=d;
50  if(cart[idx].num<=0)cart.splice(idx,1);
51  store.cart=cart;renderCartPage();
52}
53function updSummary(){
54  const total=cartTotal();
55  const coupon=store.coupons>0?5:0;
56  const ship=total>=RULES.freeShip?0:RULES.shipFee;
57  const tip=total<RULES.freeShip?'还差 '+fmt(RULES.freeShip-total)+' 免运费':'已免运费 🎉';
58  $('#ship-tip').textContent=tip;
59  $('#ship-fee').textContent=ship?'¥'+ship.toFixed(2):'免运费';
60  $('#pay-total').textContent=fmt(Math.max(0,total-coupon+ship));
61}
62function submitOrder(){
63  const cart=store.cart;
64  if(!cart.length){toast('购物车为空');return}
65  if(cartTotal()<RULES.minOrder){toast('满'+RULES.minOrder+'元才可下单');return}
66  const slot=document.querySelector('.time-slot.sel')?document.querySelector('.time-slot.sel').textContent:'立即配送';
67  const total=cartTotal();const ship=total>=RULES.freeShip?0:RULES.shipFee;
68  const o={id:'FR'+Date.now().toString().slice(-8),items:cart.map(i=>({name:i.name,emoji:i.emoji,unit:i.unit,num:i.num,price:i.price})),total:total+ship,ship,slot,time:new Date().toLocaleString('zh-CN',{hour:'2-digit',minute:'2-digit'}),status:1,addr:USER.address};
69  store.orders=[o,...store.orders];
70  store.cart=[];store.coupons=Math.max(0,store.coupons-1);
71  toast('下单成功,等待接单');
72  setTimeout(()=>location.href='orders.html',800);
73}
74function renderOrdersPage(){
75  const wrap=$('#orders-list');const orders=store.orders;
76  if(!orders.length){wrap.innerHTML='<div class="empty"><span class="e-icon">📦</span>还没有订单<br>去下一单尝尝鲜~</div>';return}
77  wrap.innerHTML=orders.map(o=>`
78    <div class="card">
79      <div style="display:flex;justify-content:space-between;font-size:12px;color:#93a58b;margin-bottom:10px">
80        <span>${o.time} · ${o.slot}</span><span style="color:var(--primary);font-weight:600">${['待支付','配送中','已完成'][o.status]}</span>
81      </div>
82      ${o.items.map(i=>'<div style="display:flex;justify-content:space-between;font-size:13px;padding:3px 0"><span>'+i.emoji+' '+i.name+' ×'+i.num+'<br><small style="color:#a9bca0">'+i.unit+'</small></span><b>'+fmt(i.price*i.num)+'</b></div>').join('')}
83      <div style="text-align:right;font-size:14px;font-weight:700;margin-top:8px;border-top:1px dashed #eee;padding-top:8px">合计 <span style="color:var(--red)">${fmt(o.total)}</span><small style="color:#93a58b;font-weight:400">${o.ship?'(含运费¥'+o.ship.toFixed(2)+')':'免运费'}</small></div>
84      <div class="status-steps">
85        ${[['已下单','✓'],['分拣中','📦'],['配送中','🛵'],['已签收','🏠']].map((s,i)=>'<div class="st '+(i<=o.status?'done':'')+'"><span class="dot">'+s[1]+'</span>'+s[0]+'</div>').join('')}
86      </div>
87      <div class="deliver-card">
88        <div class="dc-row"><span>📍 配送至</span><b>${o.addr}</b></div>
89        <div class="dc-row"><span>🚚 预计送达</span><b>${o.slot}</b></div>
90        <div class="dc-tip">💡 生鲜如遇坏果坏菜,48小时内联系客服,秒赔无理由</div>
91      </div>
92    </div>`).join('');
93}
94function renderMine(){
95  $('#u-name').textContent=USER.name;$('#u-level').textContent=USER.level;
96  $('#u-points').textContent=USER.points;$('#u-coupons').textContent=USER.coupons+store.coupons;
97  $('#u-addr').textContent=USER.address;
98  $('#m-points').textContent=USER.points;$('#m-coupons').textContent=USER.coupons+store.coupons;
99}
100