app.js · 约 40785 字符
1/* ===== 安行e修 · 电动车维修 H5 · 应用逻辑 ===== */2(function ($) {3 'use strict';45 var ROUTES = ['home','diagnose','repair','rescue','quote','track','parts','tradein','battery','stores','member','coupons','orders','profile'];6 var CUR = 'home';78 // ---------- demo 数据 ----------9 var STORES = [10 {em:'🏪',name:'安行e修 · 旗舰服务中心',addr:'高新区科技路 88 号',dis:'0.8km',open:true,queue:2,tags:['换电池','补胎','控制器','全车检']},11 {em:'🔧',name:'安行e修 · 社区快修店(丈八)',addr:'雁塔区丈八北路 21 号',dis:'1.3km',open:true,queue:0,tags:['上门','补胎','刹车']},12 {em:'🛵',name:'安行e修 · 校园店(师大路)',addr:'碑林区师大路 3 号',dis:'2.1km',open:false,queue:0,tags:['学生优惠','保养']},13 {em:'⚡',name:'安行e修 · 24h 救援站(曲江)',addr:'曲江新区雁南二路',dis:'3.4km',open:true,queue:1,tags:['道路救援','夜间']},14 {em:'🏬',name:'安行e修 · 形象店(赛格)',addr:'碑林区长安路 123 号',dis:'4.0km',open:true,queue:3,tags:['以旧换新','电池升级']}15 ];1617 var PARTS = {18 '电池':[19 {em:'🔋',nm:'天能 铅酸电池 60V20Ah',now:329,old:399,mem:true,ev:'次日达 · 原厂编码'},20 {em:'🔋',nm:'超威 锂电池 48V24Ah',now:699,old:899,mem:true,ev:'原厂正品 · 质保 1 年'},21 {em:'⚡',nm:'星恒 锂电 60V30Ah',now:1080,old:1280,mem:false,ev:'续航升级 · 适配多车型'}22 ],23 '轮胎':[24 {em:'🛞',nm:'正新 真空胎 3.00-10',now:69,old:89,mem:true,ev:'耐磨防刺 · 包安装'},25 {em:'🛞',nm:'建大 内外胎套装',now:45,old:60,mem:false,ev:'加厚防扎'},26 {em:'🛞',nm:'朝阳 真空胎 90/90-10',now:79,old:99,mem:true,ev:'静音节电'}27 ],28 '控制器':[29 {em:'🎛️',nm:'通用 矢量控制器 60V',now:189,old:239,mem:true,ev:'防溜坡 · 软启动'},30 {em:'🎛️',nm:'九号原厂控制器',now:299,old:359,mem:false,ev:'原厂匹配'}31 ],32 '刹车片':[33 {em:'🛑',nm:'前后刹车片套装',now:32,old:45,mem:true,ev:'陶瓷配方 · 低噪'},34 {em:'🛑',nm:'刹车线总成',now:18,old:25,mem:false,ev:'加长防断'}35 ],36 '充电器':[37 {em:'🔌',nm:'智能充电器 60V 3A',now:59,old:79,mem:true,ev:'充满自停 · 防过充'},38 {em:'🔌',nm:'快充充电器 72V',now:99,old:129,mem:false,ev:'1.5h 快充'}39 ],40 '塑壳':[41 {em:'🪟',nm:'前围/面板(通用)',now:39,old:55,mem:false,ev:'多色可选'},42 {em:'🪟',nm:'后尾箱+支架',now:65,old:89,mem:true,ev:'加大 35L'}43 ]44 };4546 var QUOTE = {47 '电池':{part:'电池检测 ¥25 / 铅酸更换 ¥260-480 / 锂电升级 ¥680-1280',labor:30,traffic:3,note:'以旧换新旧电池可抵 ¥30-80'},48 '轮胎':{part:'真空胎更换 ¥68-120 / 内外胎修补 ¥15-30',labor:20,traffic:3,note:'补胎 15 元起,当天可取'},49 '刹车':{part:'刹车片 ¥30-60 / 刹车线 ¥15-25',labor:25,traffic:3,note:'涉及安全,建议到店检测'},50 '电机':{part:'电机维修 ¥120-260 / 电机更换 ¥380-880',labor:50,traffic:5,note:'进水/退磁为主要故障'},51 '控制器':{part:'控制器更换 ¥180-320',labor:40,traffic:3,note:'飞车/不走车多为控制器'},52 '灯光':{part:'大灯/转向灯 ¥10-40',labor:15,traffic:0,note:'多为线路或灯泡'},53 '其他':{part:'全车线路检修 ¥40-80',labor:30,traffic:3,note:'漏电/亏电排查'}54 };5556 var DIAG = {57 '刹车':[58 {s:'刹车异响',lv:'轻',cause:'刹车片磨损或沾油',fix:'清理刹车片表面油污;磨损超 1.5mm 需更换刹车片(¥30-60)。'},59 {s:'刹车偏软/失灵',lv:'重',cause:'刹车线松弛或刹车油不足',fix:'立即停用!预约上门/到店调紧刹车线或补充刹车油,安全优先。'},60 {s:'刹车距离变长',lv:'中',cause:'刹车皮老化、轮毂变形',fix:'更换刹车皮并校正轮毂,建议同步检查轮胎气压。'},61 {s:'把手回弹慢',lv:'轻',cause:'回位弹簧疲劳',fix:'上润滑油或更换回位弹簧(¥10-20)。'}62 ],63 '电池':[64 {s:'续航明显下降',lv:'中',cause:'电池硫化/容量衰减',fix:'先做免费电池健康检测,衰减>30% 建议以旧换新(旧电可抵 ¥30-80)。'},65 {s:'充电发热鼓包',lv:'重',cause:'电芯失衡/充电器故障',fix:'立刻停用并远离火源!更换电池与智能充电器(防过充)。'},66 {s:'充不满电',lv:'轻',cause:'充电器或接口接触不良',fix:'清洁充电口,更换智能充电器(充满自停)。'},67 {s:'电量显示跳变',lv:'轻',cause:'线路虚接/仪表故障',fix:'检查电池输出端接线,必要时更换仪表。'}68 ],69 '电机':[70 {s:'拧把不走车',lv:'重',cause:'电机/控制器/霍尔故障',fix:'多为控制器或霍尔损坏,预约检测(控制器 ¥180-320)。'},71 {s:'行驶中异响',lv:'中',cause:'轴承磨损/进杂物',fix:'更换电机轴承或清理,进水需拆检(¥120-260)。'},72 {s:'动力突然减弱',lv:'中',cause:'退磁/相线接触不良',fix:'检测磁钢,必要时电机维修或更换。'}73 ],74 '轮胎':[75 {s:'扎钉漏气',lv:'轻',cause:'异物穿刺',fix:'真空胎可补(¥15-30),伤及侧壁建议更换(¥68-120)。'},76 {s:'胎压不足',lv:'轻',cause:'慢撒气/气门嘴老化',fix:'充气并检漏,更换气门嘴(¥10-20)。'},77 {s:'爆胎/鼓包',lv:'重',cause:'老化/超载',fix:'立即更换轮胎,检查轮毂是否变形。'}78 ],79 '控制器':[80 {s:'拧把无反应',lv:'重',cause:'控制器损坏/转把故障',fix:'先查转把电压,再判定控制器(¥180-320)。'},81 {s:'飞车/自动加速',lv:'重',cause:'控制器 MOS 击穿',fix:'立即断电!更换控制器,禁止继续骑行。'},82 {s:'限速异常',lv:'轻',cause:'参数丢失',fix:'重新刷写控制器参数即可。'}83 ],84 '灯光':[85 {s:'大灯不亮',lv:'轻',cause:'灯泡/线路',fix:'更换灯泡(¥10-20),检查保险与接线。'},86 {s:'转向灯不闪',lv:'轻',cause:'闪光器故障',fix:'更换闪光继电器(¥15-30)。'},87 {s:'仪表灯全灭',lv:'中',cause:'主线束断电',fix:'检查空气开关与总保险。'}88 ],89 '其他':[90 {s:'全车没电',lv:'重',cause:'总保险/空开跳闸',fix:'合上空开或更换总保险;仍无效需查主线束。'},91 {s:'异味/冒烟',lv:'重',cause:'线路短路',fix:'立即断电远离!预约上门排查线路。'},92 {s:'异响/松动',lv:'轻',cause:'塑壳/螺丝松动',fix:'紧固全车螺丝,卡扣复位。'}93 ]94 };9596 var BATTERY = {score:82, life:'约 2 年 3 个月', health:[97 {d:'2026-08-12',t:'健康度 82%,建议均衡充电',s:'良'},98 {d:'2026-06-01',t:'夏季高温,注意避免暴晒充电',s:'提示'},99 {d:'2026-03-15',t:'健康度 88%,状态优秀',s:'优'}100 ]};101102 var COUPONS = {103 av:[104 ['减20','满100','全平台维修通用','2026.09.30'],105 ['免','上门费','任意上门维修服务','2026.08.31'],106 ['减50','电池换新','以旧换新专享','2026.10.15']107 ],108 my:[109 ['减10','新人','首单专享','2026.09.01'],110 ['免','检测费','电池健康检测','2026.12.31']111 ]112 };113114 var MEMBER = {lv:'金卡会员', no:'EVR 8800 1234 5678', points:1280, growth:760,115 benefits:['全场配件 9 折','上门费全免','生日礼金 ¥30','积分兑好礼','专属客服','以旧换新加倍补贴'],116 exchange:[['🪖','安全头盔','200 积分'],['🧥','防雨骑行服','350 积分'],['☂️','雨衣','150 积分'],['🔌','充电优惠券','100 积分']]117 };118119 var SEED_ORDERS = [120 {id:'WX20260812A1',type:'上门维修',veh:'雅迪 冠能',desc:'后轮异响 / 刹车偏软',status:'进行中',step:3,time:'08-12 14:20',mech:'张师傅 · 4.9分',fee:88,parts:[['刹车片更换','¥45'],['工时费','¥40'],['上门费','¥3']]},121 {id:'WX20260730B2',type:'电池检测',veh:'爱玛 小蜜豆',desc:'续航明显下降',status:'已完成',step:5,time:'07-30 10:05',mech:'李师傅 · 4.8分',fee:25,parts:[['电池健康检测','¥25']]},122 {id:'WX20260718C3',type:'道路救援',veh:'九号 C系列',desc:'半路没电抛锚',status:'已完成',step:5,time:'07-18 19:40',mech:'王师傅 · 5.0分',fee:0,parts:[['道路救援上门','三包内免费']]}123 ];124125 var VEHICLES = [126 ['雅迪 冠能','车架号 A1B2C3****后六位','整车三包内',true],127 ['爱玛 小蜜豆','车架号 D4E5F6****后六位','已超保',false]128 ];129130 // ---------- 工具 ----------131 function go(h){ location.hash = h; }132 window.go = go;133 function goAttr(h){ return 'onclick="go(\'' + h + '\')"'; }134 function alertAttr(t){ return 'onclick="toast(\'' + t + '\')"'; }135 window.toast = function(msg){136 var t = document.querySelector('.toast');137 if(!t){ t = document.createElement('div'); t.className='toast'; document.body.appendChild(t); }138 t.textContent = msg; t.classList.add('show');139 clearTimeout(window.__tt); window.__tt = setTimeout(function(){ t.classList.remove('show'); }, 1600);140 };141 window.chipTap = function(el){ $(el).siblings().removeClass('on'); $(el).addClass('on'); };142143 function lsGet(k,def){ try{ var v = localStorage.getItem(k); return v?JSON.parse(v):def; }catch(e){ return def; } }144 function lsSet(k,v){ try{ localStorage.setItem(k,JSON.stringify(v)); }catch(e){} }145 function getOrders(){ return SEED_ORDERS.concat(lsGet('evr_orders',[])); }146147 // ---------- 顶部栏 ----------148 function homeTop(){149 return '<div class="topbar home">'150 + '<div class="loc" ' + goAttr('profile') + '>西安<span class="arr">▾</span></div>'151 + '<div class="search" ' + goAttr('diagnose') + '>🔍 搜故障 / 搜服务 / 搜门店</div>'152 + '<div class="bell" ' + alertAttr('暂无新消息') + '>🔔</div>'153 + '</div>';154 }155 function innTop(title, back){156 back = back || 'home';157 return '<div class="topbar"><div class="back" ' + goAttr(back) + '>‹</div>'158 + '<div class="ttl">' + title + '</div><div class="right" ' + goAttr(back) + '>完成</div></div>';159 }160 function tabbar(active){161 var items = [['home','🏠','首页'],['diagnose','🧭','自诊'],['repair','🛠️','报修'],['parts','🛒','配件'],['profile','👤','我的']];162 var h = '<div class="tabbar">';163 items.forEach(function(it){164 var on = (it[0]===active)?' on':'';165 h += '<div class="tb'+on+'" '+goAttr(it[0])+'><div class="ic">'+it[1]+'</div><div class="lb">'+it[2]+'</div></div>';166 });167 h += '</div>'; return h;168 }169170 // ---------- 首页 ----------171 function grid(){172 var items = [173 ['🧭','故障自诊','diagnose'],['🛠️','在线报修','repair'],['🆘','道路救援','rescue'],174 ['🧾','透明报价','quote'],['🔋','电池健康','battery'],['♻️','以旧换新','tradein'],175 ['🛒','配件商城','parts'],['🏪','门店网点','stores']176 ];177 var h = '<div class="grid">';178 items.forEach(function(it){ h += '<div class="it" '+goAttr(it[2])+'><div class="ic">'+it[0]+'</div><div class="lb">'+it[1]+'</div></div>'; });179 h += '</div>'; return h;180 }181 function homeBody(){182 var h = '<div class="banner"><h3>新用户首单立减 ¥20</h3><p>专业电动车维修 · 透明报价 · 全程录像</p>'183 + '<span class="tag">点击领取新人券包</span></div>';184 h += '<div class="rescue-cta" '+goAttr('rescue')+'><div class="em">🆘</div><div class="tx"><b>一键道路救援</b><span>3 分钟响应 · 29 分钟极速必达</span></div></div>';185 h += grid();186 h += '<div class="sec"><div class="sec-h"><div class="t">限时特惠</div><div class="more" '+goAttr('coupons')+'>领券 ›</div></div>'187 + '<div class="promo">'188 + '<div class="p a" '+goAttr('member')+'><h4>开通会员 9 折</h4><span>配件终身 9 折</span></div>'189 + '<div class="p b" '+goAttr('tradein')+'><h4>以旧换新补贴</h4><span>旧电最高抵 ¥80</span></div>'190 + '</div></div>';191 // 附近门店192 h += '<div class="sec"><div class="sec-h"><div class="t">附近门店</div><div class="more" '+goAttr('stores')+'>全部 ›</div></div>';193 STORES.slice(0,2).forEach(function(s){194 h += '<div class="card row" '+goAttr('stores')+'><div class="av">'+s.em+'</div>'195 + '<div style="flex:1"><div class="nm">'+s.name+'</div><div class="meta">'+s.addr+' · '+s.dis+' · '+(s.open?'🟢营业':'🔴休息')+'</div></div>'196 + '<div class="go">导航</div></div>';197 });198 h += '</div>';199 // 养车知识200 h += '<div class="sec"><div class="sec-h"><div class="t">养车小知识</div></div>'201 + '<div class="card"><div style="font-weight:700;margin-bottom:6px">🔋 电池这样用更耐用</div>'202 + '<div class="hint" style="margin-top:0">① 电量剩 20% 及时充电;② 避免高温暴晒下充电;③ 长期不用每月补电一次;④ 使用充满自停的智能充电器。</div></div></div>';203 // 公告204 h += '<div class="sec"><div class="card row" style="margin-top:12px"><div class="av" style="background:linear-gradient(135deg,#fff4e6,#ffe6cc)">📢</div>'205 + '<div style="flex:1"><div class="nm" style="font-size:14px">新国标合规置换活动开启</div><div class="meta">超标车以旧换新享政府补贴,门店可代办</div></div></div></div>';206 return h;207 }208209 // ---------- 故障自诊 ----------210 var DG_CAT = '刹车';211 function diagnoseBody(){212 var cats = Object.keys(DIAG);213 var h = '<div class="sec" style="padding-top:14px"><div class="sec-h"><div class="t">选择故障部位</div></div><div class="chips" id="dgcat">';214 cats.forEach(function(c){ h += '<div class="chip'+(c===DG_CAT?' on':'')+'" data-c="'+c+'">'+c+'</div>'; });215 h += '</div></div><div class="sec"><div class="sec-h"><div class="t">勾选具体症状</div></div><div class="chips" id="dgsym">';216 DIAG[DG_CAT].forEach(function(d){ h += '<div class="chip" data-s="'+d.s+'">'+d.s+'</div>'; });217 h += '</div><div id="dgres"></div></div>';218 return h;219 }220 function bindDiagnose(){221 $('#dgcat .chip').off('click').on('click', function(){222 DG_CAT = $(this).data('c');223 $('#dgcat .chip').removeClass('on'); $(this).addClass('on');224 var hh = ''; DIAG[DG_CAT].forEach(function(d){ hh += '<div class="chip" data-s="'+d.s+'">'+d.s+'</div>'; });225 $('#dgsym').html(hh); bindSym();226 });227 bindSym();228 }229 function bindSym(){230 $('#dgsym .chip').off('click').on('click', function(){231 var s = $(this).data('s');232 var list = DIAG[DG_CAT];233 var d = list.filter(function(x){return x.s===s;})[0] || list[0];234 var lvColor = d.lv==='重'?'#dc2626':(d.lv==='中'?'#ff7a00':'#0f766e');235 var html = '<div class="diag-res"><span class="lv" style="color:'+lvColor+'">严重程度:'+d.lv+'</span>'236 + '<h4>可能原因:'+d.cause+'</h4>'237 + '<p>建议处理:'+d.fix+'</p>'238 + '<div class="fix">💡 自诊提示:以上为常见成因参考,最终以技师检测为准。需要立即处理?</div>'239 + '<div class="btn" '+goAttr('repair')+'>一键报修 / 预约</div></div>';240 $('#dgres').html(html);241 });242 }243244 // ---------- 在线报修 ----------245 function repairBody(){246 var h = '<div class="frm">'247 + '<div class="fld"><label>关联车辆</label><select id="rveh">';248 VEHICLES.forEach(function(v){ h += '<option>'+v[0]+'</option>'; });249 h += '<option>暂不关联 / 其他车型</option></select></div>';250 h += '<div class="fld"><label>故障描述</label><input id="rdesc" placeholder="如:后轮异响、刹车偏软"></div>';251 h += '<div class="fld" style="flex-direction:column;align-items:flex-start"><label style="margin-bottom:8px">上传照片(可选)</label><div class="chips" id="rpics">'252 + '<div class="chip" data-p="整车">整车</div><div class="chip" data-p="故障部位">故障部位</div><div class="chip" data-p="仪表盘">仪表盘</div><div class="chip" data-p="车架号">车架号</div></div></div>';253 h += '<div class="fld" style="flex-direction:column;align-items:flex-start"><label style="margin-bottom:8px">服务方式</label><div class="chips" id="rmode">'254 + '<div class="chip on" data-m="上门维修">上门维修</div><div class="chip" data-m="到店维修">到店维修</div><div class="chip" data-m="邮寄维修">邮寄维修</div></div></div>';255 h += '<div class="fld" style="flex-direction:column;align-items:flex-start"><label style="margin-bottom:8px">预约时间</label><div class="chips" id="rtime">'256 + '<div class="chip on" data-t="立即">尽快上门</div><div class="chip" data-t="今天">今天</div><div class="chip" data-t="明天">明天</div><div class="chip" data-t="7天内">未来 7 天</div></div></div>';257 h += '<div class="fld"><label>联系人</label><input id="rname" placeholder="如:张先生"></div>';258 h += '<div class="fld"><label>手机号</label><input id="rphone" placeholder="11 位手机号"></div>';259 h += '<div class="fld"><label>地址</label><input id="raddr" placeholder="定位或手动输入"></div>';260 h += '</div>';261 h += '<div class="fee"><span>预估费用(到店为准)</span><b>¥0 起</b></div>';262 h += '<div class="card hint" style="margin-top:12px">📹 工程师全程录像 · 先修后付 · 配件一件一码 · 价格透明无隐形收费。</div>';263 h += '<div class="btn" id="rsubmit">提交报修工单</div>';264 return h;265 }266 function bindRepair(){267 $('#rpics .chip,#rmode .chip,#rtime .chip').off('click').on('click', function(){ chipTap(this); });268 $('#rsubmit').off('click').on('click', function(){269 var desc = $('#rdesc').val() || '(未填写,技师将现场检测)';270 var veh = $('#rveh').val();271 var mode = $('#rmode .chip.on').data('m');272 var time = $('#rtime .chip.on').data('t');273 var id = 'WX' + Date.now().toString().slice(-8).toUpperCase();274 var order = {id:id,type:mode,veh:veh,desc:desc,status:'已接单',step:1,time:nowStr(),mech:'系统派单中',fee:0,parts:[['待现场检测','—']]};275 var arr = lsGet('evr_orders',[]); arr.unshift(order); lsSet('evr_orders',arr);276 toast('报修提交成功,工单 '+id);277 setTimeout(function(){ go('track?id='+id); }, 700);278 });279 }280 function nowStr(){ var d=new Date(); var p=function(n){return (n<10?'0':'')+n;}; return (d.getMonth()+1)+'-'+p(d.getDate())+' '+p(d.getHours())+':'+p(d.getMinutes()); }281282 // ---------- 道路救援 ----------283 function rescueBody(){284 var h = '<div class="card"><div style="font-weight:700;margin-bottom:8px">📍 当前位置</div>'285 + '<div class="hint" style="margin-top:0">科技路 88 号 · 安行e修旗舰中心附近(已自动定位)</div></div>';286 h += '<div class="sec" style="padding-top:0"><div class="sec-h"><div class="t">选择救援类型</div></div><div class="chips" id="rstype">'287 + '<div class="chip on" data-r="半路抛锚">半路抛锚</div><div class="chip" data-r="没电了">没电了</div><div class="chip" data-r="爆胎">爆胎</div><div class="chip" data-r="其他">其他</div></div></div>';288 h += '<div class="card row"><div class="av" style="background:linear-gradient(135deg,#fff4e6,#ffe6cc)">🧑🔧</div>'289 + '<div style="flex:1"><div class="nm">王师傅 · 5.0分</div><div class="meta">距您 0.8km · 已接 412 单 · 持证上岗</div></div>'290 + '<div class="go" '+alertAttr('已联系技师')+'>联系</div></div>';291 h += '<div class="steps" style="padding:0 14px;margin-top:12px"><div class="s on"><div class="dot">✓</div><div class="lb">已接单</div></div>'292 + '<div class="s on"><div class="dot">✓</div><div class="lb">已出发</div></div>'293 + '<div class="s"><div class="dot">3</div><div class="lb">到达现场</div></div>'294 + '<div class="s"><div class="dot">4</div><div class="lb">现场处理</div></div></div>';295 h += '<div class="map"><span class="pin a">📍</span><span class="pin b">🛵</span><span class="route">实时轨迹 · 预计 12 分钟抵达</span></div>';296 h += '<div class="card" style="margin-top:12px;display:flex;justify-content:space-between;align-items:center"><div><div style="font-weight:700">预估到达</div><div class="hint" style="margin-top:2px">29 分钟极速必达 · 7×24 小时</div></div><div style="color:var(--accent);font-weight:800;font-size:18px">12 分钟</div></div>';297 h += '<div class="btn" '+alertAttr('救援请求已发送')+'>立即呼叫救援</div>';298 return h;299 }300 function bindRescue(){ $('#rstype .chip').off('click').on('click', function(){ chipTap(this); }); }301302 // ---------- 透明报价 ----------303 function quoteBody(){304 var cats = Object.keys(QUOTE);305 var h = '<div class="frm">'306 + '<div class="fld"><label>品牌</label><select id="qbrand"><option>雅迪</option><option>爱玛</option><option>小牛</option><option>九号</option><option>台铃</option><option>其他</option></select></div>'307 + '<div class="fld" style="flex-direction:column;align-items:flex-start"><label style="margin-bottom:8px">故障类别</label><div class="chips" id="qcat">';308 cats.forEach(function(c,i){ h += '<div class="chip'+(i===0?' on':'')+'" data-c="'+c+'">'+c+'</div>'; });309 h += '</div></div></div>';310 h += '<div id="qres"></div>';311 h += '<div class="card hint" style="margin-top:12px">📋 报价为标准化区间参考,最终以到店/上门检测结果为准;三包期内相关项目免费。</div></div>';312 return h;313 }314 function renderQuote(){315 var cat = $('#qcat .chip.on').data('c') || '电池';316 var q = QUOTE[cat];317 var partLow = (q.part.match(/¥(\d+)/)||[])[1] || '0';318 var total = (parseInt(partLow,10)||0) + q.labor + q.traffic;319 var html = '<div class="card"><div style="font-weight:700;margin-bottom:8px">💰 '+cat+' · 透明报价明细</div>'320 + '<div class="fees">'321 + '<div class="fr"><span>配件费(参考)</span><span>'+q.part+'</span></div>'322 + '<div class="fr"><span>工时费</span><span>¥'+q.labor+'</span></div>'323 + '<div class="fr"><span>上门/交通</span><span>'+(q.traffic?('¥'+q.traffic):'免费')+'</span></div>'324 + '<div class="fr tot"><span>预估合计(起)</span><span>¥'+total+'</span></div>'325 + '</div>'326 + (q.note?'<div class="fix" style="margin-top:10px;background:#e8f6ff;color:#0b6fb8">💡 '+q.note+'</div>':'')327 + '<div class="btn" '+goAttr('repair')+'>按此报价预约维修</div></div>';328 $('#qres').html(html);329 }330 function bindQuote(){ $('#qcat .chip').off('click').on('click', function(){ chipTap(this); renderQuote(); }); renderQuote(); }331332 // ---------- 服务进度 ----------333 function trackBody(q){334 var orders = getOrders();335 if(q && q.id){ return orderDetail(q.id); }336 if(!orders.length) return '<div class="empty">暂无工单,去报修试试~</div>';337 var h = '';338 orders.forEach(function(o){339 h += '<div class="ord" '+goAttr('track?id='+o.id)+'>'340 + '<div class="oic">🛠️</div>'341 + '<div class="mid"><div class="ti">'+o.type+'</div><div class="ln">'+o.veh+' · '+o.desc+'</div><div class="tm">'+o.time+' · 单号 '+o.id+'</div></div>'342 + '<div class="rt"><div class="st">'+o.status+'</div><div class="amt">'+(o.fee?('¥'+o.fee):'—')+'</div></div>'343 + '</div>';344 });345 return h;346 }347 function orderDetail(id){348 var all = getOrders();349 var o = all.filter(function(x){return x.id===id;})[0] || all[0];350 var labels = ['已接单','已出发','已到达','维修中','已完成'];351 var h = '<div class="card"><div style="font-size:13px;color:var(--mut)">工单号 '+o.id+'</div>'352 + '<div style="font-size:18px;font-weight:800;margin:6px 0">'+o.type+'</div>'353 + '<div class="steps">';354 labels.forEach(function(l,idx){355 h += '<div class="s'+(idx < o.step?' on':'')+'"><div class="dot">'+(idx<o.step?'✓':(idx+1))+'</div><div class="lb">'+l+'</div></div>';356 });357 h += '</div></div>';358 h += '<div class="card row"><div class="av" style="background:linear-gradient(135deg,#fff4e6,#ffe6cc)">🧑🔧</div>'359 + '<div style="flex:1"><div class="nm">'+o.mech+'</div><div class="meta">陕A·'+ (o.id.slice(-4)) +' · 已为您服务多次</div></div>'360 + '<div class="go" '+alertAttr('已联系技师')+'>联系</div></div>';361 h += '<div class="map"><span class="pin a">📍</span><span class="pin b">🏪</span><span class="route">实时轨迹 · '+(o.status==='已完成'?'服务已完成':'预计 12 分钟抵达')+'</span></div>';362 h += '<div class="card"><div style="font-weight:700;margin-bottom:8px">费用明细</div><div class="fees">';363 (o.parts||[]).forEach(function(p){ h += '<div class="fr"><span>'+p[0]+'</span><span>'+p[1]+'</span></div>'; });364 if(o.fee){ h += '<div class="fr tot"><span>合计</span><span>¥'+o.fee+'</span></div>'; }365 h += '</div></div>';366 h += '<div class="card" style="display:flex;justify-content:space-between;align-items:center"><div>📹 维修全程录像</div><div style="color:var(--brand);font-weight:700" '+alertAttr('录像已加密保存')+'>查看 ›</div></div>';367 h += '<div class="btn" '+alertAttr('感谢您的评价')+'>完成并评价</div>';368 return h;369 }370371 // ---------- 配件商城 ----------372 var P_CAT = '电池';373 function partsBody(){374 var cats = Object.keys(PARTS);375 var h = '<div class="catbar" id="pcat">';376 cats.forEach(function(c){ h += '<div class="c'+(c===P_CAT?' on':'')+'" data-c="'+c+'">'+c+'</div>'; });377 h += '</div><div id="pgrid" class="pgrid"></div>';378 return h;379 }380 function renderParts(){381 var list = PARTS[P_CAT] || [];382 var h = '';383 list.forEach(function(p){384 h += '<div class="pcard" '+alertAttr('已加入购物车')+'>'385 + '<div class="em">'+p.em+'</div><div class="nm">'+p.nm+'</div>'386 + '<div class="tag">原厂正品</div>'387 + '<div class="pr"><span class="now">¥'+p.now+'</span>'+(p.old?'<span class="old">¥'+p.old+'</span>':'')+(p.mem?'<span class="mem">会员价</span>':'')+'</div>'388 + '<div class="ev">'+p.ev+'</div></div>';389 });390 $('#pgrid').html(h);391 }392 function bindParts(){ $('#pcat .c').off('click').on('click', function(){ P_CAT=$(this).data('c'); $('#pcat .c').removeClass('on'); $(this).addClass('on'); renderParts(); }); renderParts(); }393394 // ---------- 以旧换新 ----------395 function tradeinBody(){396 var h = '<div class="card"><div style="font-weight:700;margin-bottom:10px">♻️ 旧电池估价</div>'397 + '<div class="fld"><label>电池规格</label><select id="tcap"><option>48V12Ah</option><option>48V20Ah</option><option>60V20Ah</option><option selected>60V32Ah</option><option>72V32Ah</option></select></div>'398 + '<div class="fld"><label>使用时长</label><select id="tage"><option>1 年内</option><option selected>1-2 年</option><option>2-3 年</option><option>3 年以上</option></select></div>'399 + '<div class="fld"><label>外观状态</label><select id="tcon"><option>完好无鼓包</option><option selected>轻微磨损</option><option>鼓包/老化</option></select></div>'400 + '</div>'401 + '<div id="tres"></div>'402 + '<div class="card" style="margin-top:12px"><div style="font-weight:700;margin-bottom:10px">🔋 换新方案(含补贴)</div>'403 + '<div class="ord" style="margin-top:0;cursor:default"><div class="oic">🔋</div><div class="mid"><div class="ti">天能 铅酸 60V20Ah</div><div class="ln">新国标合规 · 原厂质保 1 年</div></div><div class="rt"><div class="st">补贴 ¥50</div><div class="amt">¥329</div></div></div>'404 + '<div class="ord" style="cursor:default"><div class="oic">⚡</div><div class="mid"><div class="ti">星恒 锂电 60V30Ah</div><div class="ln">续航升级 · 轻量化</div></div><div class="rt"><div class="st">补贴 ¥80</div><div class="amt">¥1080</div></div></div>'405 + '</div>'406 + '<div class="card hint" style="margin-top:12px">📋 超标电动车可享政府以旧换新补贴,门店协助办理新国标合规置换与上牌。</div>'407 + '<div class="btn" '+goAttr('stores')+'>预约到店置换</div>';408 return h;409 }410 function renderTradein(){411 var base = {'48V12Ah':60,'48V20Ah':90,'60V20Ah':120,'60V32Ah':150,'72V32Ah':180}[$('#tcap').val()] || 100;412 var ageCut = {'1 年内':0,'1-2 年':20,'2-3 年':45,'3 年以上':70}[$('#tage').val()] || 20;413 var conCut = {'完好无鼓包':0,'轻微磨损':10,'鼓包/老化':30}[$('#tcon').val()] || 10;414 var price = Math.max(20, base - ageCut - conCut);415 var html = '<div class="fee"><span>旧电池回收估价</span><b>¥'+price+'</b></div>'416 + '<div class="hint" style="margin-top:8px">💡 旧电池含铅/锂可回收利用,由门店统一环保回收;估价仅供参考,以到店检测为准。</div>';417 $('#tres').html(html);418 }419 function bindTradein(){ $('#tcap,#tage,#tcon').off('change').on('change', renderTradein); renderTradein(); }420421 // ---------- 电池健康 ----------422 function batteryBody(){423 var h = '<div class="gauge"><div class="sc">'+BATTERY.score+'</div><div class="lb">电池健康度</div>'424 + '<div class="tip">预计可用 '+BATTERY.life+'</div></div>';425 h += '<div class="sec"><div class="sec-h"><div class="t">容量保持率</div><div class="more">82%</div></div>'426 + '<div class="hbar"><i style="width:82%"></i></div>'427 + '<div class="sec-h" style="margin-top:14px"><div class="t">内阻状态</div><div class="more">正常</div></div>'428 + '<div class="hbar"><i style="width:68%"></i></div></div>';429 h += '<div class="sec"><div class="sec-h"><div class="t">保养建议</div></div>'430 + '<div class="card"><div class="hint" style="margin-top:0">① 保持电量 20%-90% 区间循环;② 每 3 个月做一次均衡充电;③ 长期停放每月补电;④ 避免低温/高温充电。</div></div></div>';431 h += '<div class="sec"><div class="sec-h"><div class="t">健康记录</div><div class="more" '+goAttr('tradein')+'>以旧换新 ›</div></div><div class="hist">';432 BATTERY.health.forEach(function(x){433 h += '<div class="h"><div style="flex:1"><div style="font-weight:600;font-size:13px">'+x.t+'</div><div class="d">'+x.d+'</div></div><b>'+x.s+'</b></div>';434 });435 h += '</div></div>';436 h += '<div class="btn" '+goAttr('quote')+'>预约电池检测(¥25)</div>';437 return h;438 }439440 // ---------- 门店网点 ----------441 function storesBody(){442 var h = '<div class="map" style="height:140px;margin:12px 14px 0"><span class="pin a">📍</span><span class="pin b">🏪</span><span class="route">为您找到 '+STORES.length+' 家门店 · 最近 0.8km</span></div>';443 h += '<div class="sec" style="padding-top:0">';444 STORES.forEach(function(s){445 h += '<div class="store" '+goAttr('rescue')+'>'446 + '<div class="em">'+s.em+'</div>'447 + '<div class="mid"><div class="nm">'+s.name+'</div><div class="ln">'+s.addr+'</div>'448 + '<div class="tags">'+s.tags.map(function(t){return '<span>'+t+'</span>';}).join('')+'</div></div>'449 + '<div class="rt"><div class="st" style="color:'+(s.open?'#0f766e':'#dc2626')+'">'+(s.open?'🟢营业':'🔴休息')+'</div><div class="dis">'+(s.queue?('排队 '+s.queue+' 人'):'无需等待')+'</div></div>'450 + '</div>';451 });452 h += '</div>';453 return h;454 }455456 // ---------- 会员中心 ----------457 function memberBody(){458 var h = '<div class="mcard"><span class="lv">'+MEMBER.lv+'</span><div class="no">'+MEMBER.no+'</div>'459 + '<div class="row2"><div class="c"><b>'+MEMBER.points+'</b><span>我的积分</span></div>'460 + '<div class="c"><b>'+MEMBER.growth+'</b><span>成长值</span></div>'461 + '<div class="c"><b>9折</b><span>配件折扣</span></div></div></div>';462 h += '<div class="sec"><div class="sec-h"><div class="t">会员权益</div></div><div class="grid" style="margin-top:0">';463 MEMBER.benefits.forEach(function(b){ h += '<div class="it"><div class="ic" style="background:linear-gradient(135deg,#e6f6ff,#d6eefc)">✅</div><div class="lb">'+b+'</div></div>'; });464 h += '</div></div>';465 h += '<div class="sec"><div class="sec-h"><div class="t">积分兑好礼</div><div class="more" '+alertAttr('已兑换')+'>兑换 ›</div></div><div class="grid" style="margin-top:0">';466 MEMBER.exchange.forEach(function(e){ h += '<div class="it" '+alertAttr('兑换成功')+'><div class="ic" style="background:linear-gradient(135deg,#fff4e6,#ffe6cc)">'+e[0]+'</div><div class="lb">'+e[1]+'</div><div class="lb" style="color:var(--brand)">'+e[2]+'</div></div>'; });467 h += '</div></div>';468 h += '<div class="card" style="margin:12px 14px 0;display:flex;justify-content:space-between;align-items:center"><div>💰 会员储值(充 100 送 10)</div><div style="color:var(--brand);font-weight:700" '+alertAttr('前往储值')+'>储值 ›</div></div>';469 h += '<div class="btn" '+goAttr('parts')+'>去配件商城享会员价</div>';470 return h;471 }472473 // ---------- 优惠券 ----------474 function couponRow(c,claimed){475 return '<div class="coupon"><div class="lf"><b>'+c[0]+'</b><span>'+c[1]+'</span></div>'476 + '<div class="mid"><div class="t">'+c[2]+'</div><div class="d">有效期至 '+c[3]+'</div></div>'477 + '<div class="rt" '+(claimed?alertAttr('已使用'):goAttr('repair'))+'>'+(claimed?'已领取':'领取')+'</div></div>';478 }479 function couponsBody(){480 var h = '<div class="tabs" id="ctabs"><div class="tb on" data-k="可领">可领取</div><div class="tb" data-k="我的">我的优惠券</div></div><div id="clist">';481 COUPONS.av.forEach(function(c){ h += couponRow(c,false); });482 h += '</div>';483 return h;484 }485 function bindCoupons(){486 $('#ctabs .tb').off('click').on('click', function(){487 $('#ctabs .tb').removeClass('on'); $(this).addClass('on');488 var k = $(this).data('k');489 var html = '';490 if(k==='可领'){ COUPONS.av.forEach(function(c){ html += couponRow(c,false); }); }491 else { COUPONS.my.forEach(function(c){ html += couponRow(c,true); }); }492 $('#clist').html(html);493 });494 }495496 // ---------- 我的工单 ----------497 function ordersBody(){498 var keys = ['全部','进行中','已完成'];499 var h = '<div class="tabs" id="otabs">';500 keys.forEach(function(k,i){ h += '<div class="tb'+(i===0?' on':'')+'" data-k="'+k+'">'+k+'</div>'; });501 h += '</div><div id="olist"></div>'502 + '<div class="card row" style="margin:12px 14px 0;cursor:pointer" '+alertAttr('三包状态:整车 12 个月 / 电池 24 个月')+'><div class="av" style="background:linear-gradient(135deg,#eafbf0,#d2f5e0)">📑</div><div style="flex:1"><div class="nm" style="font-size:14px">三包状态查询</div><div class="meta">点击查看车辆质保信息</div></div><div class="go">查询</div></div>';503 setTimeout(function(){ renderOrders('全部'); }, 0);504 return h;505 }506 function renderOrders(tab){507 var arr = getOrders();508 if(tab==='进行中') arr = arr.filter(function(o){return o.status!=='已完成';});509 else if(tab==='已完成') arr = arr.filter(function(o){return o.status==='已完成';});510 var html = arr.length? '' : '<div class="empty">暂无相关工单</div>';511 arr.forEach(function(o){512 html += '<div class="ord" '+goAttr('track?id='+o.id)+'>'513 + '<div class="oic">🛠️</div>'514 + '<div class="mid"><div class="ti">'+o.type+'</div><div class="ln">'+o.veh+' · '+o.desc+'</div><div class="tm">'+o.time+'</div></div>'515 + '<div class="rt"><div class="st">'+o.status+'</div><div class="amt">'+(o.fee?('¥'+o.fee):'—')+'</div></div></div>';516 });517 $('#olist').html(html);518 }519 function bindOrders(){ $('#otabs .tb').off('click').on('click', function(){ $('#otabs .tb').removeClass('on'); $(this).addClass('on'); renderOrders($(this).data('k')); }); }520521 // ---------- 我的 ----------522 function vehRow(v){523 return '<div class="veh"><div class="em">🛵</div><div class="mid"><div class="nm">'+v[0]+'</div><div class="ln">'+v[1]+'</div></div>'524 + '<div class="badge '+(v[3]?'ok':'no')+'">'+(v[3]?'🟢':'🔴')+v[2]+'</div></div>';525 }526 function profileBody(){527 var h = '<div class="me-h"><div class="av">🛵</div><div><div class="nm">安行e修用户</div><div class="vip">💎 '+MEMBER.lv+'</div></div></div>';528 h += '<div class="me-grid">'529 + mg('🛠️','我的工单','orders') + mg('🎟️','优惠券','coupons') + mg('🔋','电池健康','battery') + mg('🏪','门店','stores')530 + mg('💎','会员中心','member') + mg('♻️','以旧换新','tradein') + mg('🧾','透明报价','quote') + mg('⚙️','设置','profile')531 + '</div>';532 h += '<div class="sec" style="padding-top:0"><div class="sec-h"><div class="t">我的车辆</div><div class="more" '+alertAttr('已添加车辆')+'>+ 绑定</div></div>';533 VEHICLES.forEach(function(v){ h += vehRow(v); });534 h += '</div>';535 h += '<div class="sec"><div class="sec-h"><div class="t">帮助与反馈</div></div>';536 h += '<div class="fb" '+goAttr('rescue')+'><div class="em">🆘</div><div class="mid"><div class="t">紧急道路救援</div><div class="d">半路抛锚?一键呼叫</div></div><div class="st">立即 ›</div></div>';537 h += '<div class="fb" '+alertAttr('已提交反馈')+'><div class="em">💬</div><div class="mid"><div class="t">意见反馈 / 投诉</div><div class="d">服务不满意?告诉我们</div></div><div class="st">去评价 ›</div></div>';538 h += '<div class="fb" '+alertAttr('客服在线 9:00-21:00')+'><div class="em">📞</div><div class="mid"><div class="t">在线客服</div><div class="d">9:00 - 21:00 实时在线</div></div><div class="st">联系 ›</div></div>';539 h += '<div class="fb" '+alertAttr('安行e修 · 电动车维修专家')+'><div class="em">ℹ️</div><div class="mid"><div class="t">关于我们</div><div class="d">专业 · 透明 · 全程录像</div></div><div class="st"> ›</div></div>';540 h += '</div>';541 h += '<div class="invite" '+alertAttr('邀请链接已复制')+'><div class="em">🎁</div><div class="tx"><b>邀请好友得礼金</b><span>每邀请 1 人得 ¥5,可叠加</span></div><div class="btn2">立即邀请</div></div>';542 return h;543 }544 function mg(ic,lb,to){ return '<div class="it" '+goAttr(to)+'><div class="ic">'+ic+'</div><div class="lb">'+lb+'</div></div>'; }545546 // ---------- 页面表 ----------547 var PAGES = {548 home: function(){ return {top:homeTop(), body:homeBody(), tab:true}; },549 diagnose: function(){ return {top:innTop('故障自诊'), body:diagnoseBody(), bind:bindDiagnose, tab:true}; },550 repair: function(){ return {top:innTop('在线报修'), body:repairBody(), bind:bindRepair, tab:true}; },551 rescue: function(){ return {top:innTop('道路救援'), body:rescueBody(), bind:bindRescue}; },552 quote: function(){ return {top:innTop('透明报价'), body:quoteBody(), bind:bindQuote}; },553 track: function(q){ return {top:innTop('服务进度'), body:trackBody(q)}; },554 parts: function(){ return {top:innTop('配件商城'), body:partsBody(), bind:bindParts, tab:true}; },555 tradein: function(){ return {top:innTop('以旧换新'), body:tradeinBody(), bind:bindTradein}; },556 battery: function(){ return {top:innTop('电池健康'), body:batteryBody()}; },557 stores: function(){ return {top:innTop('门店网点'), body:storesBody()}; },558 member: function(){ return {top:innTop('会员中心'), body:memberBody()}; },559 coupons: function(){ return {top:innTop('优惠券'), body:couponsBody(), bind:bindCoupons}; },560 orders: function(){ return {top:innTop('我的工单'), body:ordersBody(), bind:bindOrders, tab:true}; },561 profile: function(){ return {top:innTop('我的'), body:profileBody(), tab:true}; }562 };563564 // ---------- 路由 ----------565 function parseHash(){566 var h = location.hash.replace(/^#/,'');567 if(!h) h = 'home';568 var q = {}; var qi = h.indexOf('?');569 if(qi>=0){ var qs = h.substr(qi+1); h = h.substr(0,qi); qs.split('&').forEach(function(p){ var kv=p.split('='); q[decodeURIComponent(kv[0])]=decodeURIComponent(kv[1]||''); }); }570 return {name:h, q:q};571 }572 function render(){573 var p = parseHash();574 var name = ROUTES.indexOf(p.name)>=0 ? p.name : 'home';575 CUR = name;576 var v = PAGES[name](p.q);577 var html = (v.top||'') + '<div class="page">' + (v.body||'') + '</div>' + (v.tab? tabbar(name):'');578 $('#app').html(html);579 if(v.bind) v.bind();580 $('.page').scrollTop(0);581 }582 $(window).on('hashchange', render);583 $(function(){ render(); });584})(jQuery);585