r103/app.js · 约 27933 字符
1/* ===== 小草车辆上门快修 H5 · 应用逻辑 ===== */2(function ($) {3 'use strict';45 var ROUTES = ['home','wash','maintain','tire','jump','spark','parts','partdetail','order','orders','orderdetail','me','wallet','message','store'];6 var CUR = 'home';7 var ORD_TAB = '进行中';89 // ---- 服务项目(上门洗车/保养/补胎/搭电/火花塞 + 易损件)----10 var SERVICES = {11 wash: { em:'🚿', nm:'上门洗车', g1:'#2B5CFF', g2:'#5C8BFF', price:'39', unit:'次', tags:['随叫随到','精洗打蜡','无痕水痕'],12 desc:'专业技师携带移动洗车设备上门,含车身预洗、泡沫精洗、轮毂清洁、内饰吸尘、玻璃除渍、车身打蜡,省去您排队洗车的时间。',13 include:['外观精洗 + 轮胎轮毂清洁','内饰吸尘 + 仪表台擦拭','玻璃去油膜 + 车身打蜡','约 40 分钟 · 不限车型'],14 steps:['在线下单','技师接单','上门服务','验收评价'], note:'服务范围:西安主城区,雨雪天气顺延。' },15 maintain:{ em:'🔧', nm:'上门保养', g1:'#16A34A', g2:'#86EFAC', price:'199', unit:'次', tags:['原厂机油','机滤赠送','质保半年'],16 desc:'技师携带正品机油机滤上门,按车型匹配保养方案,含放油、换机滤、加注新油、全车基础检查,全程可视、用量透明。',17 include:['正品机油(按车型匹配)','机油滤芯免费更换','玻璃水补充','全车 22 项基础检查'],18 steps:['在线下单','确认车型机油','上门保养','电子工单'], note:'支持各大品牌机油,价格随容量浮动。' },19 tire: { em:'🛞', nm:'上门补胎', g1:'#F97316', g2:'#FDBA74', price:'59', unit:'条', tags:['蘑菇钉补','流动补胎','夜间可约'],20 desc:'扎钉漏气不用愁,技师携带补胎机与蘑菇钉上门,内补更耐久,也可现场换备胎,安全返程无忧。',21 include:['拆胎 + 内补(蘑菇钉)','动平衡校正','胎压检测充气','换备胎(如需)'],22 steps:['在线下单','定位车辆','上门补胎','恢复胎压'], note:'胎壁破损/鼓包建议更换新胎。' },23 jump: { em:'🔋', nm:'上门搭电', g1:'#0EA5E9', g2:'#7DD3FC', price:'49', unit:'次', tags:['极速响应','无损搭电','电瓶检测'],24 desc:'电瓶亏电打不着火?技师携带应急电源上门搭电启动,并检测电瓶健康度,给出更换建议。',25 include:['应急搭电启动','电瓶电压检测','发电机充电检测','亏电原因排查'],26 steps:['在线下单','确认位置','上门搭电','点火成功'], note:'若电瓶老化严重,可现场更换蓄电池。' },27 spark: { em:'⚡', nm:'上门换火花塞', g1:'#7C3AED', g2:'#C4B5FD', price:'129', unit:'套', tags:['原厂匹配','4支装','动力提升'],28 desc:'怠速抖动、加速无力、油耗升高?多为火花塞老化。技师按车型匹配原厂规格,全套更换,恢复点火效率。',29 include:['原厂规格火花塞 4 支','旧件拆除 + 新件安装','点火间隙校准','试车确认'],30 steps:['在线下单','确认车型','上门更换','试车验收'], note:'缸数不同数量不同,价格以实际为准。' },31 brake: { em:'🛑', nm:'刹车片更换', g1:'#DC2626', g2:'#FCA5A5', price:'159', unit:'副', tags:['陶瓷片','原厂匹配','刹车保养'],32 desc:'刹车异响、制动距离变长,及时更换刹车片关乎安全。原厂规格陶瓷片,含刹车分泵润滑与复位。',33 include:['原厂规格刹车片','分泵导向销润滑','刹车盘清洁','制动测试'],34 steps:['在线下单','确认车型','上门更换','制动测试'], note:'前/后片独立计价,以实际为准。' },35 wiper: { em:'🌧️', nm:'雨刮器更换', g1:'#0EA5E9', g2:'#7DD3FC', price:'39', unit:'对', tags:['静音胶条','无损安装','雨天清晰'],36 desc:'刮水留痕、跳动异响?原车接口雨刮一对,技师上门 2 分钟换好,雨天视野更清晰。',37 include:['原车接口雨刮 1 对','旧件拆除','刮拭测试','支架清洁'],38 steps:['在线下单','确认车型','上门更换','刮拭测试'], note:'无骨/有骨按车型匹配。' },39 bulb: { em:'💡', nm:'灯泡更换', g1:'#F59E0B', g2:'#FCD34D', price:'29', unit:'只', tags:['原厂同款','亮度升级','即换即走'],40 desc:'近光/远光/示宽灯不亮,存在安全隐患。原厂规格灯泡或 LED 升级,技师上门更换并调试。',41 include:['原厂/LED 灯泡','旧件拆除','光束角度调试','功能确认'],42 steps:['在线下单','确认灯位','上门更换','功能确认'], note:'LED 升级需另加差价。' },43 cabin: { em:'🌀', nm:'空调滤芯更换', g1:'#10B981', g2:'#A7F3D0', price:'49', unit:'个', tags:['防PM2.5','活性炭','清爽空气'],44 desc:'车内异味、空调出风小?空调滤芯该换了。活性炭防 PM2.5 滤芯,改善车内空气质量。',45 include:['活性炭空调滤芯','旧件拆除','风道简单清洁','出风测试'],46 steps:['在线下单','确认车型','上门更换','出风测试'], note:'部分车型需拆手套箱,技师熟练操作。' },47 oilfilter:{ em:'⚙️', nm:'机油滤芯更换', g1:'#475569', g2:'#CBD5E1', price:'39', unit:'个', tags:['正品滤芯','搭配保养','密封无忧'],48 desc:'单独更换机油滤芯,或配合上门保养使用。原厂规格,全新密封圈,杜绝渗漏。',49 include:['原厂规格机滤','密封圈更换','安装扭力校准','无渗漏检查'],50 steps:['在线下单','确认车型','上门更换','渗漏检查'], note:'多与上门保养组合下单更划算。' },51 battery: { em:'🔋', nm:'蓄电池更换', g1:'#2563EB', g2:'#93C5FD', price:'299', unit:'块', tags:['以旧换新','上门安装','质保1年'],52 desc:'频繁亏电、启动无力,电瓶寿命将尽。原厂规格蓄电池以旧换新,上门安装并检测充电系统。',53 include:['原厂规格蓄电池','旧电池回收','端子紧固防氧化','充电系统检测'],54 steps:['在线下单','确认型号','上门更换','系统检测'], note:'以旧换新价,旧电瓶折价回收。' },55 coolant: { em:'🧊', nm:'防冻液更换', g1:'#0891B2', g2:'#67E8F9', price:'99', unit:'次', tags:['原厂标号','循环更换','防沸防冻'],56 desc:'防冻液变质易致开锅、锈蚀。原厂标号循环更换,保护发动机冷却系统。',57 include:['原厂标号防冻液','旧液排放','循环清洗','液位校准'],58 steps:['在线下单','确认车型','上门更换','液位校准'], note:'不同颜色防冻液切勿混加。' },59 belt: { em:'⛓️', nm:'皮带更换', g1:'#9333EA', g2:'#D8B4FE', price:'179', unit:'根', tags:['原厂规格','异响消除','张紧校准'],60 desc:'皮带异响、裂纹,存在断裂风险。原厂规格正时/附件皮带更换,张紧轮校准。',61 include:['原厂规格皮带','张紧轮检查','轨迹校准','异响排除'],62 steps:['在线下单','确认车型','上门更换','异响排除'], note:'正时皮带建议按里程定期更换。' }63 };64 function svByKey(k) { return SERVICES[k] || SERVICES.wash; }6566 // ---- 订单数据 ----67 var ORDERS = {68 '进行中': [69 ['🔧','上门保养 · 大众朗逸', '今天 15:00 · 高新路 12 号', '07-29', '技师出发中', '¥199'],70 ['🛞','上门补胎 · 本田飞度', '明天 10:30 · 科技路', '07-28', '已接单', '¥59']71 ],72 '已完成': [73 ['🚿','上门洗车 · 丰田卡罗拉', '07-26 · 已完成好评', '07-26', '已完成', '¥39'],74 ['⚡','上门换火花塞 · 宝马3系', '07-22 · 动力恢复', '07-22', '已完成', '¥129']75 ],76 '已取消': [77 ['🔋','上门搭电 · 奥迪A4L', '07-18 · 自行解决', '07-18', '已取消', '¥49']78 ]79 };80 var MSG = {81 '服务动态': [82 ['🔧','保养提醒', '您的上门保养 今天 15:00 高新路', '07-29'],83 ['🛞','技师已接单', '补胎技师 小李 正在赶往现场', '07-28']84 ],85 '平台通知': [86 ['📢','夏季养车专场', '7月 上门保养立减 50,含全车检查', '07-28'],87 ['🎉','新用户首单券', '注册即领 ¥30 上门服务券', '07-25']88 ],89 '活动推送': [90 ['🔥','易损件团购', '刹车片/雨刮 限时 8 折', '07-24'],91 ['🏆','老带新有礼', '推荐好友下单各得 ¥20', '07-22']92 ]93 };9495 // ---- 小工具 ----96 function go(h) { location.hash = h; }97 window.go = go;98 function goAttr(h) { return 'onclick="go(\'' + h + '\')"'; }99 function alertAttr(t) { return 'onclick="alert(\'' + t + '\')"'; }100 function chipTap(el) { $(el).siblings().removeClass('on'); $(el).addClass('on'); }101102 // ---- 顶部栏 ----103 function homeTop() {104 return '<div class="topbar home">'105 + '<div class="loc" ' + goAttr('store') + '>西安<span class="arr">▾</span></div>'106 + '<div class="search" ' + goAttr('parts') + '>🔍 搜索洗车 / 保养 / 补胎</div>'107 + '<div class="bell" ' + goAttr('message') + '>🔔</div>'108 + '</div>';109 }110 function innTop(title, back) {111 back = back || 'home';112 return '<div class="topbar">'113 + '<div class="back" ' + goAttr(back) + '>‹</div>'114 + '<div class="ttl">' + title + '</div>'115 + '<div class="right"></div>'116 + '</div>';117 }118 function tabbar(active) {119 var items = [['home','🏠','首页'],['parts','🛠️','服务'],['orders','📋','订单'],['me','👤','我的']];120 var h = '<div class="tabbar">';121 items.forEach(function (it) {122 var on = (it[0] === active) ? ' on' : '';123 h += '<div class="tb' + on + '" ' + goAttr(it[0]) + '><div class="ic">' + it[1] + '</div><div class="lb">' + it[2] + '</div></div>';124 });125 return h + '</div>';126 }127128 // ---- 首页 ----129 function banner() {130 return '<div class="banner">'131 + '<h3>小草上门快修 · 足不出户养车</h3>'132 + '<p>洗车 / 保养 / 补胎 / 搭电 / 易损件更换,全城极速上门</p>'133 + '<span class="tag">新用户首单立减 ¥30</span>'134 + '</div>';135 }136 function quickGrid() {137 var items = [138 ['🚿','上门洗车','wash'],['🔧','上门保养','maintain'],['🛞','上门补胎','tire'],139 ['🔋','上门搭电','jump'],['⚡','换火花塞','spark'],['🛑','刹车片','brake'],140 ['🌧️','雨刮器','wiper'],['💡','灯泡','bulb']141 ];142 var h = '<div class="grid">';143 items.forEach(function (it) {144 h += '<div class="it" ' + goAttr(it[2]) + '><div class="ic">'+it[0]+'</div><div class="lb">'+it[1]+'</div></div>';145 });146 return h + '</div>';147 }148 function coreServices() {149 var keys = ['wash','maintain','tire','jump','spark'];150 var h = '<div class="sec-h"><div class="t">核心上门服务</div><div class="more" ' + goAttr('parts') + '>全部 ›</div></div><div class="svcards">';151 keys.forEach(function (k) { h += svCard(k); });152 return h + '</div>';153 }154 function svCard(k) {155 var s = SERVICES[k];156 return '<div class="svcard" ' + goAttr(k) + '>'157 + '<div class="ico" style="background:linear-gradient(135deg,'+s.g1+','+s.g2+')">'+s.em+'</div>'158 + '<div class="mid"><div class="nm">'+s.nm+'</div><div class="ds">'+s.tags[0]+' · '+s.tags[1]+'</div></div>'159 + '<div class="rt"><div class="pr"><i>¥</i>'+s.price+'<i>起</i></div><div class="go">预约 ›</div></div>'160 + '</div>';161 }162 function promise() {163 var items = [['🚀','极速上门','平均 30 分钟到达'],['✅','正品保障','原厂件 · 假一赔十'],['🛡️','服务质保','保养半年无忧'],['💬','透明计价','下单前知总价']];164 var h = '<div class="sec-h"><div class="t">为什么选小草</div></div><div class="svcards" style="margin-top:8px">';165 items.forEach(function (it) {166 h += '<div class="svcard"><div class="ico" style="background:linear-gradient(135deg,#2B5CFF,#00C2A8)">'+it[0]+'</div>'167 + '<div class="mid"><div class="nm">'+it[1]+'</div><div class="ds">'+it[2]+'</div></div></div>';168 });169 return h + '</div>';170 }171 function homeBody() { return banner() + quickGrid() + coreServices() + promise(); }172173 // ---- 通用服务详情 ----174 function serviceDetailBody(s, backRoute, svcKey) {175 backRoute = backRoute || 'parts';176 svcKey = svcKey || '';177 var steps = s.steps;178 var incl = s.include.map(function (x) { return '<div class="ds" style="padding:5px 0;font-size:13.5px;color:#555">✓ '+x+'</div>'; }).join('');179 var h = '<div class="detail-img" style="background:linear-gradient(135deg,'+s.g1+','+s.g2+')">'+s.em180 + '<div class="price-tag"><span>'+s.nm+'</span><b>¥'+s.price+'</b><i>'+s.unit+'起</i></div>'181 + '<div class="dot">上门服务</div></div>';182 h += '<div style="margin:0 14px">';183 h += '<div class="card" style="margin-top:-12px;position:relative">'184 + '<div style="font-size:17px;font-weight:800">'+s.nm+'</div>'185 + '<div class="tags" style="margin-top:8px">'+s.tags.map(function(x){return '<span>'+x+'</span>';}).join('')+'</div>'186 + '</div>';187 h += '<div class="card"><div class="h">服务流程</div><div class="steps">';188 steps.forEach(function (st, idx) {189 h += '<div class="s'+(idx<2?' on':'')+'"><div class="dot">'+(idx<2?'✓':(idx+1))+'</div><div class="lb">'+st+'</div></div>';190 });191 h += '</div></div>';192 h += '<div class="card"><div class="h">服务包含</div>'+incl+'</div>';193 h += '<div class="card"><div class="h">服务说明</div><div class="detail-desc">'+s.desc+'</div></div>';194 h += '<div class="card seller"><div class="av">👨🔧</div><div><div class="nm">小草认证技师 · 王师傅</div><div class="meta">从业 9 年 · 上门服务 3000+ 单</div></div><div class="go" ' + alertAttr('已为您接通技师') + '>联系</div></div>';195 h += '</div>';196 h += '<div class="btn" ' + goAttr('order?svc='+ svcKey) + '>立即预约</div>';197 h += '<div class="btn orange" ' + alertAttr('已加入购物车') + '>加入收藏</div>';198 return h;199 }200 function svDetailRoute(key) {201 var s = svByKey(key);202 return { top: innTop(s.nm), body: serviceDetailBody(s, 'parts', key), tab: false };203 }204205 // ---- 易损件列表(parts 服务大厅)----206 function partsBody() {207 var groups = [208 { t: '五大核心上门', ks: ['wash','maintain','tire','jump','spark'] },209 { t: '易损件更换', ks: ['brake','wiper','bulb','cabin','oilfilter','battery','coolant','belt'] }210 ];211 var h = '';212 groups.forEach(function (g) {213 h += '<div class="sec-h"><div class="t">'+g.t+'</div></div><div class="svcards" style="margin-top:8px">';214 g.ks.forEach(function (k) { var s = SERVICES[k];215 h += '<div class="svcard" ' + goAttr('partdetail?id='+k) + '>'216 + '<div class="ico" style="background:linear-gradient(135deg,'+s.g1+','+s.g2+')">'+s.em+'</div>'217 + '<div class="mid"><div class="nm">'+s.nm+'</div><div class="ds">'+s.tags[0]+' · '+s.tags[1]+'</div></div>'218 + '<div class="rt"><div class="pr"><i>¥</i>'+s.price+'<i>起</i></div><div class="go">预约 ›</div></div>'219 + '</div>';220 });221 h += '</div>';222 });223 return h;224 }225226 // ---- 预约下单 ----227 function orderBody(q) {228 var key = (q && q.svc) || 'wash';229 var s = svByKey(key);230 return '<div class="bookinfo">'231 + '<div class="ico" style="background:linear-gradient(135deg,'+s.g1+','+s.g2+')">'+s.em+'</div>'232 + '<div class="mid"><div class="nm">'+s.nm+'</div><div class="pr">¥'+s.price+' '+s.unit+'起</div></div></div>'233 + '<div class="frm">'234 + fld('联系人', 'text', '请输入您的称呼')235 + fld('手机号', 'tel', '请输入 11 位手机号')236 + fld('车型', 'text', '如:大众 朗逸 1.5L')237 + '<div class="fld"><label>服务地址</label>'238 + '<input id="addr" type="text" placeholder="小区/写字楼 + 门牌,技师上门"></div>'239 + '<div class="fld"><label>期望时间</label><select><option>今天 下午</option><option>今天 晚上</option><option>明天 上午</option><option>明天 下午</option><option>周末 全天</option></select></div>'240 + '<div class="fld"><label>支付方式</label><select><option>到店/上门 微信支付</option><option>会员余额支付</option><option>到付现金</option></select></div>'241 + fld('备注', 'text', '如:车停地库 B2')242 + '</div>'243 + '<div class="card" style="margin:12px 14px 0;font-size:13px;color:#8a8f9c;line-height:1.7">🛡️ 提交后系统就近派单,技师将在 10 分钟内确认并电话联系您,服务完成验收后付款。</div>'244 + '<div class="btn" onclick="submitOrder()">提交预约 · ¥'+s.price+' 起</div>';245 }246 window.submitOrder = function () {247 var addr = ($('#addr').val() || '').trim();248 if (!addr) { alert('请填写服务地址,方便技师上门'); $('#addr').focus(); return; }249 alert('预约提交成功!技师将尽快与您联系 🔧');250 go('orders');251 };252253 // ---- 订单列表 ----254 function ordList(tab) {255 var arr = ORDERS[tab] || [];256 if (!arr.length) return '<div class="empty">暂无'+tab+'记录</div>';257 var h = '';258 arr.forEach(function (o, i) {259 h += '<div class="ord" ' + goAttr('orderdetail?i='+i+'&tab='+encodeURIComponent(tab)) + '>'260 + '<div class="oic">'+o[0]+'</div>'261 + '<div class="mid"><div class="ti">'+o[1]+'</div><div class="ln">'+o[2]+'</div><div class="tm">'+o[3]+'</div></div>'262 + '<div class="rt"><div class="st">'+o[4]+'</div><div class="amt">'+o[5]+'</div></div>'263 + '</div>';264 });265 return h;266 }267 function ordersBody() {268 var keys = ['进行中','已完成','已取消'];269 var t = '<div class="tabs" id="otabs">';270 keys.forEach(function (k) { t += '<div class="tb'+(k===ORD_TAB?' on':'')+'" data-k="'+k+'">'+k+'</div>'; });271 t += '</div><div id="olist">' + ordList(ORD_TAB) + '</div>';272 return t;273 }274 function bindOrders() {275 $('#otabs .tb').off('click').on('click', function () {276 ORD_TAB = $(this).data('k');277 $('#otabs .tb').removeClass('on'); $(this).addClass('on');278 $('#olist').html(ordList(ORD_TAB));279 });280 }281282 // ---- 订单详情 ----283 function orderDetailBody(q) {284 var tab = (q && q.tab) || '进行中';285 var i = parseInt((q && q.i) || '0', 10);286 var o = (ORDERS[tab] || ORDERS['进行中'])[i] || ORDERS['进行中'][0];287 var steps = [288 ['已下单','您已提交预约'],289 ['已接单','技师确认并联系'],290 ['服务中','技师上门作业'],291 ['已完成','验收评价']292 ];293 var cur = (o[4] === '已完成') ? 3 : (o[4] === '已接单' ? 1 : (o[4] === '技师出发中' ? 2 : (o[4] === '已取消' ? 0 : 1)));294 var h = '<div class="card" style="margin-top:12px;display:flex;gap:12px">'295 + '<div class="ico" style="width:48px;height:48px;font-size:24px;background:linear-gradient(135deg,#2B5CFF,#5C8BFF);border-radius:12px;display:flex;align-items:center;justify-content:center;color:#fff">'+o[0]+'</div>'296 + '<div><div style="font-weight:700;font-size:15px">'+o[1]+'</div><div style="font-size:12px;color:#9aa0ac;margin-top:3px">'+o[2]+'</div></div>'297 + '<div style="margin-left:auto;color:#2B5CFF;font-weight:700;font-size:13px">'+o[4]+'</div></div>';298 h += '<div class="card"><div class="h">服务进度</div><div class="steps">';299 steps.forEach(function (st, idx) {300 h += '<div class="s'+(idx<=cur?' on':'')+'"><div class="dot">'+(idx<cur?'✓':(idx+1))+'</div><div class="lb">'+st[0]+'</div></div>';301 });302 h += '</div></div>';303 h += '<div class="card"><div class="h">订单信息</div>'304 + '<div class="detail-desc">下单时间:'+o[3]+' | 订单号:XC'+(100000+i)+'<br>'305 + '服务地址:西安市 '+(o[2].split('·')[1]||'')+'<br>'306 + '支付方式:微信支付 | 实付金额:<b>'+o[5]+'</b><br>'307 + '备注:请保持电话畅通,技师将准时上门。</div></div>';308 if (o[4] !== '已取消') {309 h += '<div class="btn" ' + alertAttr('已联系技师') + '>联系技师</div>';310 h += '<div class="btn orange" ' + alertAttr('已提交评价') + '>评价服务</div>';311 }312 return h;313 }314315 // ---- 个人中心 ----316 function mg(ic, lb, to) { return '<div class="it" ' + goAttr(to) + '><div class="ic">'+ic+'</div><div class="lb">'+lb+'</div></div>'; }317 function meBody() {318 var h = '<div class="me-h"><div class="av">🧑</div><div><div class="nm">小草车友</div><div class="vip">👑 认证会员</div></div></div>';319 h += '<div class="me-grid">'320 + mg('📋','我的订单','orders') + mg('🚗','我的爱车','store') + mg('🎟️','优惠券','wallet') + mg('💰','我的钱包','wallet')321 + mg('🔔','消息中心','message') + mg('🏬','门店地址','store') + mg('📍','上门记录','orders') + mg('⚙️','设置','me')322 + '</div>';323 h += '<div class="invite"><div class="em">🎁</div><div class="tx"><b>推荐好友养车赚佣金</b><span>每成功 1 单,返现最高 ¥30</span></div><div class="btn2" ' + alertAttr('已复制专属海报') + '>立即推广</div></div>';324 return h;325 }326327 // ---- 钱包 / 优惠券 ----328 function walletBody() {329 var top = '<div class="wallet-top"><div class="bal">账户余额(元)</div><div class="num">128.50</div>'330 + '<div class="acts"><div>优惠券<b>5</b></div><div>积分<b>860</b></div><div>储值卡<b>1</b></div></div></div>';331 var cs = [332 ['满 50 减 30', '上门服务通用', '2026.08.31 到期', '#FF7A00'],333 ['免上门费券', '保养订单立免', '2026.08.15 到期', '#2B5CFF'],334 ['易损件 8 折', '刹车片/雨刮专用', '2026.09.01 到期', '#10B981'],335 ['新人立减 30', '首单专享', '2026.09.10 到期', '#7C3AED']336 ];337 var h = top + '<div class="sec-h"><div class="t">我的优惠券</div><div class="more" ' + alertAttr('已领取全部') + '>领取 ›</div></div>';338 cs.forEach(function (c) {339 var sp = c[0].split(' ');340 h += '<div class="coupon">'341 + '<div class="vr" style="background:linear-gradient(135deg,'+c[3]+',#ff9a6b)"><b>'+sp[1]+'</b><span>'+sp[0]+'</span></div>'342 + '<div class="mid"><div class="ti">'+c[1]+'</div><div class="ln">'+c[2]+'</div></div>'343 + '<div class="use" ' + alertAttr('已使用') + '>去使用</div></div>';344 });345 return h;346 }347348 // ---- 消息中心 ----349 function msgList(arr) {350 var h = '';351 arr.forEach(function (m) {352 var cls = m[0] === '📢' ? 'a' : (m[0] === '🔧' || m[0] === '🛞' ? 'b' : 'c');353 h += '<div class="msg"><div class="mic '+cls+'">'+m[0]+'</div><div class="mid"><div class="ti">'+m[1]+'<span class="tm">'+m[3]+'</span></div><div class="sn">'+m[2]+'</div></div></div>';354 });355 return h;356 }357 function messageBody() {358 var keys = ['服务动态','平台通知','活动推送'];359 var t = '<div class="tabs" id="mtabs">';360 keys.forEach(function (k, i) { t += '<div class="tb'+(i===0?' on':'')+'" data-k="'+k+'">'+k+'</div>'; });361 t += '</div><div id="mlist">' + msgList(MSG[keys[0]]) + '</div>';362 return t;363 }364 function bindMessage() {365 $('#mtabs .tb').off('click').on('click', function () {366 $('#mtabs .tb').removeClass('on'); $(this).addClass('on');367 var k = $(this).data('k');368 $('#mlist').html(msgList(MSG[k]));369 });370 }371372 // ---- 门店 / 关于 ----373 function storeBody() {374 var stores = [375 ['🏬','小草高新店','科技路 18 号 高新万达 2 号楼 · 09:00-20:00'],376 ['🏬','小草雁塔店','小寨西路 26 号 赛格国际 8F · 09:30-21:00'],377 ['🏬','小草未央店','凤城二路 9 号 经发大厦 1F · 09:00-20:00']378 ];379 var h = '<div class="sec-h" style="margin-top:14px"><div class="t">门店 / 服务网点</div><div class="more" ' + alertAttr('已为您导航') + '>导航 ›</div></div>';380 stores.forEach(function (s) {381 h += '<div class="store"><div class="lo">'+s[0]+'</div><div class="mid"><div class="nm">'+s[1]+'</div><div class="ln">'+s[2]+'</div></div><div class="op" ' + alertAttr('已致电门店') + '>电话</div></div>';382 });383 h += '<div class="sec-h" style="margin-top:14px"><div class="t">关于小草上门快修</div></div>';384 h += '<div class="card about"><b>小草车辆上门快修</b> 是西安本地一站式汽车上门养护平台,提供'385 + '<b>上门洗车、上门保养、上门补胎、上门搭电、上门换火花塞</b> 等核心服务,'386 + '并覆盖 <b>刹车片、雨刮器、灯泡、空调滤芯、机油滤芯、蓄电池、防冻液、皮带</b> 等易损件更换。'387 + '技师均持证上岗、携带原厂配件与移动设备,<b>30 分钟极速上门、价格透明、服务质保</b>,'388 + '让车主足不出户完成养车。平台已服务 <b>10 万+</b> 车主,好评率 98.6%。</div>';389 return h;390 }391392 // ---- 表单通用 ----393 function fld(label, type, ph) {394 return '<div class="fld"><label>'+label+'</label><input type="'+type+'" placeholder="'+ph+'"></div>';395 }396397 // ---- 页面表 ----398 var PAGES = {399 home: function () { return { top: homeTop(), body: homeBody(), tab: true }; },400 wash: function () { return svDetailRoute('wash'); },401 maintain: function () { return svDetailRoute('maintain'); },402 tire: function () { return svDetailRoute('tire'); },403 jump: function () { return svDetailRoute('jump'); },404 spark: function () { return svDetailRoute('spark'); },405 parts: function () { return { top: innTop('服务大厅'), body: partsBody(), tab: true }; },406 partdetail: function (q) { var k = (q && q.id) || 'brake'; return { top: innTop('服务详情'), body: serviceDetailBody(svByKey(k), 'parts', k), tab: false }; },407 order: function (q) { return { top: innTop('预约下单'), body: orderBody(q) }; },408 orders: function () { return { top: innTop('我的订单'), body: ordersBody(), bind: bindOrders, tab: true }; },409 orderdetail:function (q) { return { top: innTop('订单详情'), body: orderDetailBody(q) }; },410 me: function () { return { top: innTop('个人中心'), body: meBody(), tab: true }; },411 wallet: function () { return { top: innTop('钱包 / 优惠券'), body: walletBody() }; },412 message: function () { return { top: innTop('消息中心'), body: messageBody(), bind: bindMessage, tab: true }; },413 store: function () { return { top: innTop('门店 / 关于'), body: storeBody() }; }414 };415416 // ---- 路由 ----417 function parseHash() {418 var h = location.hash.replace(/^#/, '');419 if (!h) h = 'home';420 var q = {};421 var qi = h.indexOf('?');422 if (qi >= 0) {423 var qs = h.substr(qi + 1); h = h.substr(0, qi);424 qs.split('&').forEach(function (p) {425 var kv = p.split('=');426 q[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1] || '');427 });428 }429 return { name: h, q: q };430 }431 function render() {432 var p = parseHash();433 var name = ROUTES.indexOf(p.name) >= 0 ? p.name : 'home';434 CUR = name;435 var v = PAGES[name](p.q);436 var html = (v.top || '') + '<div class="page">' + (v.body || '') + '</div>' + (v.tab ? tabbar(name) : '');437 $('#app').html(html);438 if (v.bind) v.bind();439 $('.page').scrollTop(0);440 }441442 $(window).on('hashchange', render);443 $(function () { render(); });444})(jQuery);445