您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
目的:令工作更加便捷,完善官网不合理的部分:1、搜索栏追加商品ID直达功能,输入商品的ID,可以直达商品页面;2、添加三个二级目录到顶部导航,弥补商品页面进去了就出不来的麻烦;3、增加“预算清单”,该功能可以在不登陆帐号的情况下,输入单笔预算,策划要购买的商品,并计算预算,通过保存数据到Cookies,即使关闭浏览器下次访问仍可恢复记录。4、在列表页,默认每页100个商品;5、明显标出“非消费券”的商品;6、在商品页用蓝字显示商品ID。7、购物清单的导出导入。8、增加首页无须登陆即可访问“提货券”入口。9、完善导出清单功能,现在能供打印的清单。
// ==UserScript== // @name 中国社会扶贫网|广西特色馆 增强工具 // @namespace [email protected] // @version 0.9 // @description 目的:令工作更加便捷,完善官网不合理的部分:1、搜索栏追加商品ID直达功能,输入商品的ID,可以直达商品页面;2、添加三个二级目录到顶部导航,弥补商品页面进去了就出不来的麻烦;3、增加“预算清单”,该功能可以在不登陆帐号的情况下,输入单笔预算,策划要购买的商品,并计算预算,通过保存数据到Cookies,即使关闭浏览器下次访问仍可恢复记录。4、在列表页,默认每页100个商品;5、明显标出“非消费券”的商品;6、在商品页用蓝字显示商品ID。7、购物清单的导出导入。8、增加首页无须登陆即可访问“提货券”入口。9、完善导出清单功能,现在能供打印的清单。 // @compatible chrome // @license MIT // @author zenwuyi // @match https://xffp.digitalgx.com.cn/ // @grant none // ==/UserScript== (function() { 'use strict'; //---------------------- 全局函数开始----------------------- // 延时执行时间,本脚本必须在原网页渲染完毕后执行 const waitReadyTime = 1500; // 主色调 网站同色:#e1251b 开发版(蓝色):#042167 const mainTone = "#e1251b"; // 选择器 var q=(selectorString)=>document.querySelector(selectorString); // 复制一个元素(参数:选择器) var copyElement=(selectorString)=>{ "复制一个元素(参数:选择器)"; return q(selectorString).cloneNode(true); }; // 定义一个日志函数,便于输出日志到控制台或其他什么 var log = function(msg,selector) { if(selector&&q(selector)){ q(selector).append(msg); }else{ console.log(msg); } }; // 等待 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)) } // 返回url参数 var request = function(name){ let url = window.location.href; let reg = new RegExp("(^|bai&)"+ name +"=([^&]*)(&|$)"); let search = url.substring(url.indexOf("?")); let r = search.substr(1).match(reg); if (r!=null) return unescape(r[2]); return null; }; // 创建一个元素(元素标签,id,class,style) var c = (tagName,id,className,style)=>{ let el = document.createElement(tagName); if(id)el.id=id; if(className)el.className=className; if(style)el.style=style; return el; }; //JS操作cookies方法! //写cookies var setCookie = function(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Days*24*60*60*1000); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); } // 读cookies var getCookie = function(name) { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)){ return unescape(arr[2]); }else{ return null; } } // 公共样式表 var css={ // 初始化 "init":function(){ let patchStyle = c("style"); patchStyle.id = "patchStyle"; document.body.appendChild(patchStyle); }, // 追加 "append":function(classStyle){ q("style#patchStyle").append(classStyle); } }; // 模拟操作 function AutoJs(){ log("[AutoJs] 初始化。"); }; AutoJs.prototype={ "end":function(){ log("[AutoJs] 完成!"); }, "error":function(selector,hand,msg){ log(`[AutoJs] [error] 操作:${hand} 选择器:${selector} 信息:${msg}`); return this; }, // 模拟单击事件 "click":function(selector){ let s = q(selector); if(s){ s.click(); return this; }else{ return this.error(selector,"click","没有找到要点击的网页元素!"); } }, // 线程等待时间(毫秒) "sleep":function(interval){ for(var t = Date.now(); Date.now() - t <= interval;); return this; }, // 执行函数 "action":function(func){ if(typeof func == 'function'){ log("[AutoJs] 执行函数"); func(); }else{ log("[AutoJs] 定义的参数,其类型并不是一个函数。"); return this.end(); } return this; }, // 等待某个元素出现后执行(元素选择器,执行函数,等待次数(-1为一直等),检查间隔(默认20毫秒)) "wait":function (selector,func, times, interval) { log(`[AutoJs] 等待选择器:“${selector}” 渲染完成并执行指定函数`); let _times = times || -1, //100次 _interval = interval || 20, //20毫秒每次 _self = q(selector); let _iIntervalID; //定时器id if (_self) { //如果已经获取到了,就直接执行函数 func && func.call(_self); } else { _iIntervalID = setInterval(function () { if (!_times) { //是0就退出 clearInterval(_iIntervalID); } _times <= 0 || _times--; //如果是正数就 -- _self = q(selector); //再次选择 if (_self) { //判断是否取到 func && func.call(_self); clearInterval(_iIntervalID); } }, _interval); } return this; }, "extend":function(fn){ }, }; //--------------------- 全局函数结束 --------------------- // 购物车 var shoppingCart={ // 购物车图标 "buyCarIconHtml": '<svg t="1596793883289" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2489" width="32" height="32" style="margin:0 0 2px 0"><path d="M384 768a64 64 0 1 0 0.032 128.032A64 64 0 0 0 384 768M704 768a64 64 0 1 0 0.032 128.032A64 64 0 0 0 704 768M312.672 512l-51.424-192h560.96l-51.456 192H312.672z m583.36-224a32 32 0 0 0-32-32H244.064L209.792 128H96.032v64h64.64l145.728 544H800v-64H355.52l-25.696-96h490.048l12.16-45.376 64-238.88-0.768-0.192C895.424 290.336 896 289.28 896 288z" fill="#ffffff" p-id="2490"></path><path d="M448 448h192v-64h-192z" fill="#ffffff" p-id="2491"></path></svg>' ,// 预算 "budget":0.0, // 加车商品数量 "inCartCount":0, // 消费券合计金额 "inCartTotal_Coupon":0.0, // 非消费券合计金额 "inCartTotal_notCoupon":0.0, // 合计金额 "inCartTotal":0.0, // 剩余预算 "inCartBalance":0.0, // 总人数,控制下单数量 "peoples":0, // 购物车项 "items":[], // 显示当前的购物车数据 "showItemJson":function(){ log(JSON.stringify(this.items)); }, // 根据ID查找购物车项 "findById":function(id,sid){ sid=sid||0; // 多个类型第一个为0,第二为1,类推 for (let i = 0; i < this.items.length; i++) { if(this.items[i].id==id&&this.items[i].sid==sid){ return this.items[i]; } } return {"id":0}; }, // 商品对象的默认值 "detail_Default":{ "id":0, "sid":0, "title":"商品名称", "img":"缩略图", "price":0.0, "specifications":"规格", "buyCount":0, "stock":0, "isCoupon":false }, // 折叠购物车(强制折叠:true|强制展开:false) "buyCarBarFold":function(isTofold){ let buyCarBar = q("#buyCarBar"); let folded = buyCarBar.className.indexOf("fold")!=-1; if(isTofold==undefined) { // 根据折叠情况执行相反的操作 if(folded){ buyCarBar.classList.remove("fold"); }else{ buyCarBar.classList.add("fold"); } }else if(folded&&!isTofold){ // 已折叠的要强制展开 buyCarBar.classList.remove("fold"); }else if(!folded&&isTofold){ // 未折叠的要强制折叠 buyCarBar.classList.add("fold"); } }, "init":function(){ // 创建购物车栏 let buyCarBar = c("div"); buyCarBar.id = "buyCarBar"; css.append("#buyCarBar{display: flex;position: fixed; width: 100%;bottom: 0;height: 130px;background: #fff; border-top: 2px solid "+mainTone+";opacity: 1;}"); css.append("#buyCarBar.fold{width: 310px;border-right: 2px solid "+mainTone+";border-radius: 0 1em;}"); css.append("#buyCar_title span{cursor: pointer;}") let buyCar_titleBar = c("h1"); buyCar_titleBar.id = "buyCar_title"; css.append("#buyCar_title{display:block;width:42px;height:100%;background:"+mainTone+";color:#fff;writing-mode: tb-rl;font-size:16px;line-height: 40px;}"); // 购物车图标 buyCar_titleBar.innerHTML+=this.buyCarIconHtml; // 显示购物车数据 buyCar_titleBar.addEventListener("dblclick",()=>shoppingCart.showItemJson(),false); // 预算清单几个字 let buyCar_title = c("span"); buyCar_title.append("预算清单"); buyCar_title.addEventListener("click",()=>this.buyCarBarFold(),false); buyCar_titleBar.append(buyCar_title); // 合并入购物车栏 buyCarBar.append(buyCar_titleBar); // 购物数量小红点 let inCartCountPoint = c("div"); inCartCountPoint.id="inCartCount"; css.append("#inCartCount{z-index: 10;min-width: 0.5em;min-height: 0.5em;line-height: 0.5em;text-align: center;border-radius: 500rem;padding: 0.5em !important;position: absolute;background: "+mainTone+";border: 2px solid #fff;color: #fff;left: 30px;top: -10px;}");css.append("#inCartCount{z-index: 10;min-width: 0.5em;min-height: 0.5em;line-height: 0.5em;text-align: center;border-radius: 500rem;padding: 0.5em !important;position: absolute;background: "+mainTone+";border: 2px solid #fff;color: #fff;left: 30px;top: -10px;}"); inCartCountPoint.append(0); buyCarBar.append(inCartCountPoint); // 购物车数据栏 let dataBar = c("div","dataBar"); let dataBarText = c("div","dataBarText"); dataBarText.append("数据:"); dataBar.append(dataBarText); dataBar.append(c("i","","after")); css.append("#dataBar{color: #fff;position: absolute;top: -30px;display: flex;}"); css.append("#dataBarText{background: "+mainTone+";padding: 5px;}"); css.append("#dataBar .after{display:block;width: 0;height: 0;border-color: "+mainTone+" transparent;border-width: 0 30px 30px 0;border-style: solid;}"); buyCarBar.append(dataBar); // 购物车状态栏 let stateBar = c("ul"); stateBar.id="stateBar"; css.append("#stateBar{width:260px;height:100%;padding:5px 5px 5px 10px;font-size:14px;display: flex;flex-flow: column;flex-wrap: wrap;}"); css.append("#budget,#peoples{width: 60px;height: 2em;padding: 0 5px;}"); css.append("#stateBar button{border-radius: 0px;padding: 0 5px;line-height: 24px;border: 1px solid "+mainTone+";background-color: #fff;font-size: 12px;font-weight: 700;color: "+mainTone+";transition: background 0.2s ease 0s;margin-right: 2px;cursor: pointer;}"); css.append("#stateBar li{margin:0;padding:0;line-height: 2em;display:block;width:49%;height: 28px;}"); let lineArr = [ '<label>券预算:<input id="budget" type="tel" autocomplete="off" placeholder="请输入" class="el-input__inner"></label>', '<label>券消费:</label><label id="inCartTotal_Coupon">0</label><label>元</label>', '<label id="inCartBalanceLabel">券余额:</label><label id="inCartBalance">0</label><label>元</label>', '<label><button id="cleadBuyCart">清空</button><button id="autoPlaceOrder" enable="false">批量结算</button></label>', '<label>总人数:<input id="peoples" type="tel" autocomplete="off" placeholder="请输入" class="el-input__inner"></label>', '<label>非券共:</label><label id="inCartTotal_notCoupon">0</label><label>元</label>', '<label>总开支:</label><label id="inCartTotal">0</label><label>元</label>', '<label><button id="import">导入清单</button><button id="export">导出清单</button></label>' ]; for (let index = 0; index < lineArr.length; index++) { let line = lineArr[index]; let li = c("li"); li.innerHTML=lineArr[index]; stateBar.append(li); } // 合并入购物车栏 buyCarBar.append(stateBar); // 购物车容器 // 商品容器 buyCarBar.append(c("ul","itemsBox","itemsBox")); // 将购物车注入页面 q("body").append(buyCarBar); // 输入预算的事件 q("#budget").addEventListener("blur",()=>{ shoppingCart.budget = parseInt(q("#budget").value); // 重新计算购物车数据 shoppingCart.calculation(true); },false); // 输入人数事件 q("#peoples").addEventListener("blur",()=>{ shoppingCart.peoples = parseInt(q("#peoples").value); if(window.location.hash.indexOf("#/shopDetail")!=-1&&shoppingCart.peoples>0){ q(".addCart input").value = shoppingCart.peoples; } // 重新计算购物车数据 shoppingCart.calculation(true); },false); // 清空购物车 q("#cleadBuyCart").addEventListener("click",()=>{ if(confirm("确认要清空购物车吗?")){ this.items=[]; this.calculation(true); let itemBox = q(".itemsBox"); if(itemBox)itemBox.innerHTML = ""; } },false); // 导出清单 q("#export").addEventListener("click",()=>this.export(),false); // 批量结算 q("#autoPlaceOrder").addEventListener("click",()=>{ alert("批量结算功能后续实现。请在购物车中逐一点击,进行“单位集采”。"); },false); // 导入清单 q("#import").addEventListener("click",()=>this.import(),false); // 恢复历史记录 let history = getCookie("offlineBuyCart"); if(history!=null){ log("[增强] 恢复记录到购物车"); let json = JSON.parse(history); this.budget = json.budget; this.peoples = json.peoples; this.items = json.items; q("#peoples").value=this.peoples; q("#budget").value=this.budget; for (let i = 0; i < this.items.length; i++) { let item = this.items[i]; q("#itemsBox").append(this.createItem(item)); } this.calculation(true); } }, // 自动操作过程中,阻止用户操作页面的遮罩 "autoOperationMask":function(isShow) { let mask; if(isShow){ mask = c("div","autoOperationMask"); q("body").append(mask); }else{ q("#autoOperationMask").remove(); } }, // 导入清单 "import":function(dataStr){ // 导入必须从列表页或商品页开始,否则不会触发刷新后的事件,为何如此,尚不明确 if(window.location.hash.indexOf("#/search")==-1 &&window.location.hash.indexOf("#/shopDetail")==-1){ window.location.hash="#/search?productTypeId=107&name=%E5%88%9D%E7%BA%A7%E5%86%9C%E4%BA%A7%E5%93%81"; gxfp.loadedAction=()=>this.import(dataStr); return; } dataStr = dataStr || prompt("请输入或粘贴(CTRL+V)从本插件导出的清单字符串:"); if(!dataStr)return; let arr1 = dataStr.split("+"); let items = []; for (let i1 = 0; i1 < arr1.length; i1++) { let arr2 = arr1[i1].split("*"); switch (arr2[0]) { case "b": this.budget = parseFloat(arr2[1]); break; case "p": this.peoples = parseInt(arr2[1]); break; default: if(arr2[0].indexOf("-")!=-1){ let arr3 = arr2[0].split("-"); items.push({"id":parseInt(arr3[0]),"sid":parseInt(arr3[1]),"buyCount":parseInt(arr2[1])}); } break; } } log("[增强] 即将恢复购物车:"+JSON.stringify(items)); // "接下来会自动把导入数据还原成购物车,期间请勿对页面进行操作!" q("#cleadBuyCart").click(); for (let i = 0; i < items.length; i++) { const detail = items[i]; this.auImCartArr.push(()=>{ log(`[autojs] 自动加车:detail.id:${detail.id},detail.sid:${detail.sid},detail.buyCount:${detail.buyCount}`); shoppingCart.auImCart(detail.id,detail.sid,detail.buyCount); }); } if(this.auImCartArr.length>0) { // 用遮罩禁止用户操作 this.autoOperationMask(true); // 执行第一个导入操作 this.auImCartArr.shift()(); } }, // 自动执行的操作把导入数据还原成购物车 "auImCart":function(detailId,detailSid,buyCount){ gxfp.loadedAction=()=>{ gxfp.loadedAction=()=>{ let auto = function() { var p = new Promise(function(resolve, reject){ //做一些异步操作 let auObj = new AutoJs() .wait("#showDetailId_finish",function(){ if(detailSid>0){ q(`.choose-attrs button:nth-child(${detailSid+1})`).click(); } q(".addCart input").value=buyCount; },10000,500) .sleep(1000) .wait("#imCart",function(){gxfp.addShoppingCart(detailId)},10000,500) .sleep(1000) .end(); resolve(auObj); }); return p; }; auto() .then(function(autojsObj){ if(shoppingCart.auImCartArr.length>0){ shoppingCart.auImCartArr.shift()(); }else{ // 释放掉载入后执行函数 gxfp.loadedAction=null; // 移除遮罩恢复用户操作 shoppingCart.autoOperationMask(false); } }); }; log(`[AutoJs] 准备转到: #/shopDetail?id=${detailId}`); window.location.hash = `#/shopDetail?id=${detailId}`; }; log(`[AutoJs] 准备转到: 过渡页`); window.location.hash = "#/help"; }, // 自动导入购物车队列 "auImCartArr":[], // 导出清单 "export":function(){ // 数据格式{bx总预算,px总人数,商品id_类别sidx数量……} let dataStr = "b*"+this.budget+"+p*"+this.peoples; for (let i = 0; i < this.items.length; i++) { let item = this.items[i]; dataStr+="+"+item.id+"-"+item.sid+"*"+item.buyCount; } log("[增强] 导出:"+dataStr); let css = "h1,h2{text-align: center;margin: 0;}td{border-left:1px solid #000;border-top:1px solid #000;word-break: break-word;}td img{height:100px;max-height:100px;max-width:150px}.title{vertical-align: top;}table{margin:2em auto;border-spacing: 0;border-right:1px solid #000;border-bottom:1px solid #000}"; css+=".c1{width:150px;}.c2{width:300px}.c3{width:120px}.c4{width:180px}.c5{width:110px}" let html = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="widtd=device-widtd, initial-scale=1.0"><title>购物清单</title><style>${css}</style></head><body><h1><img src="https://xffp.digitalgx.com.cn/static/img/header-Logo2.711b7b06.png" alt="中国社会扶贫网广西特色馆"></h1><h2>购物清单(${new Date().toLocaleString()})</h2><table><tbody>`; this.items.forEach(detail => { let smallTotal = Math.round(detail.price*100*detail.buyCount)/100; html+=`<tr><td rowspan="3" class="c1"><img src="${detail.img}" alt="${detail.title}"></td><td rowspan="2" class="c2 title">商品ID:<i id="id">${detail.id}</i> ${detail.title}</td><td class="c3">单价:${detail.price}元</td><td class="c4">订单号:${""}</td><td class="c5">备注</td></tr><tr><td>数量:${detail.buyCount}份</td><td>快递单:${""}</td><td rowspan="2"> </td></tr><tr><td style="over-flow:hidden">规格:${detail.specifications}</td><td>小计:${smallTotal}元</td><td>支付方式:${(detail.isCoupon?"消费券":"转账")}</td><tr>`; }); let ofWhich=`消费券合计:${this.inCartTotal_Coupon} 人均:${Math.round(this.inCartTotal_Coupon*100/this.peoples)/100} 非消费券合计:${this.inCartTotal_notCoupon} 人均:${Math.round(this.inCartTotal_notCoupon*100/this.peoples)/100}`; html+=`<tr><td colspan="5">总计:${this.inCartTotal}元(其中:${ofWhich})</td></tr><tr><td colspan="5">预算清单导入码:${dataStr}</td></tr></tbody></table></body></html>`; let newwindow = window.open('', "_blank",''); newwindow.document.write(html); }, // 添加商品到购物车(参数商品json对象) "addItem":function(detail){ detail = detail||this.detail_Default; if(detail.id==0) { alert("商品ID没有成功传入!"); return; } log("[增强] 添加商品到购物车:"+detail.title+",规格:"+detail.specifications+",数量:"+detail.buyCount+",消费券:"+detail.isCoupon); var match = this.findById(detail.id,detail.sid); if(this.items.length==0||match.id==0) { // 添加 this.items.push(detail); q("#itemsBox").append(this.createItem(detail)); }else{ // 更新购买数量buyCount this.updateBuyCount(match,detail.buyCount+0); } // 重新计算购物车合计数 this.calculation(true); }, // 重新计算购物车合计数(是否更新购物车页面) "calculation":function(isUpdateView) { // 品种数量 this.inCartCount = this.items.length; // 购物总额 let total = 0.0; // 消费券消费金额 let inCartTotal_Coupon = 0.0; // 非消费券消费金额 let inCartTotal_notCoupon = 0.0; for (let i = 0; i < this.items.length; i++) { let item = this.items[i]; if(item.isCoupon) { // 消费券 inCartTotal_Coupon+=Math.round(item.price*100*item.buyCount)/100; }else{ // 非消费券 inCartTotal_notCoupon+=Math.round(item.price*100*item.buyCount)/100; } } // 消费券消费金额 this.inCartTotal_Coupon = Math.round(inCartTotal_Coupon*100)/100; // 非消费券消费金额 this.inCartTotal_notCoupon = Math.round(inCartTotal_notCoupon*100)/100; // 总开支 this.inCartTotal=Math.round((inCartTotal_Coupon+inCartTotal_notCoupon)*100)/100; // 消费券余额 this.inCartBalance=Math.round(this.budget*100-inCartTotal_Coupon*100)/100; // 更新购物车页面视图 if(!isUpdateView)return; q("#dataBarText").innerText="人均消费券(元):"+ (Math.round(this.budget*100/this.peoples)/100)+",开支:"+ (Math.round(inCartTotal_Coupon*100/this.peoples)/100)+",余额:"+ (Math.round(this.inCartBalance*100/this.peoples)/100)+""; q("#inCartTotal_Coupon").innerText=this.inCartTotal_Coupon; q("#inCartTotal_notCoupon").innerText = this.inCartTotal_notCoupon; q("#inCartCount").innerText=this.inCartCount; q("#inCartTotal").innerText=this.inCartTotal; if(this.inCartBalance<0){ // 超预算 log("[增强] 购物车超预算了。"); q("#inCartBalanceLabel").innerText="券超支:"; q("#inCartBalanceLabel").style="color:"+mainTone+""; q("#inCartBalance").innerText=Math.abs(this.inCartBalance); q("#inCartBalance").style="color:"+mainTone+""; }else{ // 正常消费券余额 q("#inCartBalanceLabel").innerText="券余额:"; q("#inCartBalanceLabel").style=""; q("#inCartBalance").innerText=this.inCartBalance; q("#inCartBalance").style=""; } // 保存购物车数据 setCookie("offlineBuyCart",JSON.stringify({ "budget":this.budget, "peoples":this.peoples, "items":this.items })); }, // 移除商品)(商品信息对象,是否更新总数据) "removeItem":function(detail,isUpdateItemsData){ detail = detail||this.detail_Default; if(detail.id==0) { alert("商品ID没有成功传入!"); return; } log("[增强] 从购物车删除:"+detail.title); // 从购物车移除 let box = q('.itemBox[detail-id="'+detail.id+'"][detail-sid="'+detail.sid+'"]') if(box)box.remove(); // 从数据源移除商品 if(isUpdateItemsData) { var match = this.findById(detail.id,detail.sid); if(match.id!=0){ this.items.splice(this.items.findIndex(e => e.id == detail.id && e.sid==detail.sid), 1) ; // 更新视图 this.calculation(true); } } }, // 更新购物车商品信息 "updateItem":function(detail){ let s ='.itemBox[detail-id="'+detail.id+'"][detail-sid="'+detail.sid+'"]'; let t = q(s); if(t) { q(s+' img').src = detail.img; q(s+' h2').innerHTML = this.itemTitleManage(detail.title); q(s+' h3').innerText = detail.specifications; q(s+' .price').innerText='¥'+detail.price; q(s+' .buyCount').innerText = detail.buyCount<100?"x"+detail.buyCount:detail.buyCount; } }, // 更新购买数量(+1或-1) "updateBuyCount" : function (detail,plusCount) { // 防止数据超出范围 let chkVal = detail.buyCount+plusCount; if(chkVal<1)return; if(chkVal>=1000)return; detail.buyCount+=plusCount; this.updateItem(detail); this.calculation(true); }, // 商品项的样式表 "itemCss":function(){ css.append(".itemsBox{display: flex;height: 100%;flex-wrap: wrap;align-content: flex-start;flex:1;width:0;overflow-y:scroll;}"); css.append(".itemBox{display:block;width: 296px;border: 1px solid rgb(204, 204, 204);margin: 5px 5px 0 0;padding: 3px;display: flex;height: 50px;overflow: hidden;}"); css.append(".itemBox.selected{border-color: "+mainTone+";}"); css.append(".itemBox .pic{width: 50px;height: 50px;cursor: pointer;float: left;margin-right: 5px;}"); css.append(".itemBox h2{overflow: hidden;margin-right: 5px;font-size: 12px;overflow-wrap: break-word;display: block;width: 120px;color: rgb(0, 0, 0);cursor: pointer;float: left;line-height: 140%;}"); css.append(".itemBox h3{overflow: hidden;overflow-wrap: break-word;font-size:12px;display: block;width: 55px;color: rgb(153, 153, 153);cursor: pointer;}"); css.append(".itemBox .rightBar{font-size: 12px;width: 65px;text-align: right;}"); css.append(".itemBox .rightBar button{width: 12px;height: 16px;font-size: 6px;}"); css.append(".itemBox .rightBar .buyControl{color:red;cursor: pointer;}"); css.append('.itemBox.notCoupon:after {background: #DDD;content: "非消费券";position: absolute; color: #fff;font-size: 30px;text-align: center;padding: 6px 92px;margin: -4px;z-index: -1;}'); css.append(".buyCountPlus{margin-right:5px;}"); css.append(".buyCountSubtract{margin-left:5px;}"); css.append('.item.notCoupon:before {display: block;content: "非消费券";position: absolute;background: #D0D0D0;color: #fff;font-size: 28px;padding: 232px 9px 57px 8px;text-align: right;width: 220px;z-index: -1;margin: -12px -9px;}'); css.append('.summary.notCoupon:after {content: "非 消 费 券";display: block;position: absolute; margin-top: -85px;margin-left: 200px;font-size: 56px;color: #FFF;text-shadow: #333 1px 0 0, #333 0 1px 0, #333 -1px 0 0, #333 0 -1px 0;opacity: 0.5;}'); css.append('div#autoOperationMask { position: fixed;top: 0;bottom: 0;left: 0;right: 0;z-index: 999;background: #aaa;opacity: 0.8;display: flex;align-items: center; justify-content: center;}'); css.append('div#autoOperationMask:after {content: "正在自动还原购物车,请勿操作!";font-size: 72px;}'); css.append('.searchBox .tip:before {content: "非消费券,需要微信或转账进行订货。";color: red;}'); css.append('#stateBar button[enable="false"] {border-color: #ccc;color: #ccc;cursor: not-allowed;}') }, // 向标题输出“消费券”标志 "itemTitleManage":function(detailTitle){ let xfqStr = "消费券"; let xfqIndex = detailTitle.indexOf(xfqStr); if(xfqIndex!=-1){ detailTitle = detailTitle.substring(xfqIndex+xfqStr.length); detailTitle = '<span class="el-tag el-tag--danger el-tag--mini el-tag--dark">'+xfqStr+'</span>'+detailTitle; } return detailTitle; }, // 创建商品项 "createItem":function(detail){ // 商品单项容器 let itemBox = c("li"); if(detail.isCoupon){ itemBox.className = "itemBox"; }else{ // 非消费券 itemBox.className = "itemBox notCoupon"; } itemBox.setAttribute("detail-id",detail.id); itemBox.setAttribute("detail-sid",detail.sid); // 缩略图 let img = c("img"); img.className="pic"; img.src=detail.img; img.alt=detail.title; itemBox.append(img); // 标题 let title = c("h2"); title.innerHTML=shoppingCart.itemTitleManage(detail.title); itemBox.append(title); // 规格 let stitle = c("h3"); stitle.append(detail.specifications); itemBox.append(stitle); let rightBar = c("ul"); rightBar.className="rightBar"; itemBox.append(rightBar); // 价格 let price = c("li"); price.className="price"; price.style="color:#e4393c;"; price.append("¥"+detail.price); rightBar.append(price); // 数量 let buyCountLi = c("li"); let buyCount = c("span"); buyCount.className="buyCount"; buyCount.style="color:#00f"; buyCount.append(detail.buyCount<100?"x"+detail.buyCount:detail.buyCount); // 加 buyCountLi.append((()=>{ let buyCountPlus = c("button"); buyCountPlus.className="buyCountPlus"; buyCountPlus.append("+"); buyCountPlus.addEventListener("click",()=>this.updateBuyCount(detail,1),false); return buyCountPlus; })()); // 数量 buyCountLi.append(buyCount); // 减 buyCountLi.append((()=>{ let buyCountSubtract = c("button"); buyCountSubtract.className="buyCountSubtract"; buyCountSubtract.append("-"); buyCountSubtract.addEventListener("click",()=>this.updateBuyCount(detail,-1),false); return buyCountSubtract; })()); rightBar.append(buyCountLi); // 控制删除 let buyControlLine = c("li"); let buyControl=c("span",null,"buyControl"); buyControl.append("删除"); buyControl.addEventListener("click",()=>this.removeItem(detail,true),false); buyControlLine.append("ID:"+detail.id+" "); buyControlLine.append(buyControl); rightBar.append(buyControlLine); // 点击购物车中的商品,转到商品页 let itemOmClick = ()=>this.jumpToDetail(detail.id); img.addEventListener("click",itemOmClick,false); title.addEventListener("click",itemOmClick,false); //判断元素是否出现了滚动条 let ele = q("#itemsBox"); if(ele.scrollHeight > ele.clientHeight) { //设置滚动条到最底部 ele.scrollTop = ele.scrollHeight; } return itemBox; }, "jumpToHash":function (urlHash) { // 判断是否需要切一下页面 let tag = urlHash.substring(0,urlHash.indexOf("?")); if(window.location.hash.indexOf(tag)!=-1) { // 已经在详细页面了,要切换一下页面 window.location.hash = "#/help"; setTimeout(()=>{window.location.hash = urlHash},100); }else{ // 直接跳转 window.location.hash = urlHash; } }, // 直接从当前页面跳到商品详细页 "jumpToDetail":function (detailId,detailSid) { let jHash = (detailSid) ?`#/shopDetail?id=${detailId}&sid=${detailSid}` :`#/shopDetail?id=${detailId}`; if(window.location.hash.indexOf("#/shopDetail?id=")!=-1) { // 已经在详细页面了,要切换一下页面 window.location.hash = "#/help"; setTimeout(()=>{window.location.hash = jHash;},1); }else{ // 直接跳转 window.location.hash = jHash; } }, }; var gxfp = { // 直接从当前页面跳到商品详细页 "nav":function (urlHash) { // 判断是否需要切一下页面 let tag = urlHash.substring(0,urlHash.indexOf("?")); if(window.location.hash.indexOf(tag)!=-1) { // 已经在详细页面了,要切换一下页面 window.location.hash = "#/help"; setTimeout(()=>{window.location.hash = urlHash},100); }else{ // 直接跳转 window.location.hash = urlHash; } }, "setPageSizeMax":function(){ let url = window.location.href; if(url.indexOf("search?")!=-1){ let chkNotCoupon=function(){ log("[增强] 向不支持消费券的项目添加“非消费券”标识"); let itemArr = document.querySelectorAll(".shopList .item"); for (let i = 0; i < itemArr.length; i++) { let item = itemArr[i]; if(!item.querySelector("span.el-tag")){ // 向不适用消费券的项,追加“非消费券”标识 item.classList.add("notCoupon") } } }; // 首次执行 chkNotCoupon(); // 商品列表刷新后保持标识 q(".shopList").addEventListener("DOMNodeInserted",(e)=>{ //chkNotCoupon(); //log(event.target); if(!event.target.querySelector("span.el-tag")){ // 向不适用消费券的项,追加“非消费券”标识 event.target.classList.add("notCoupon") } },false); // 每页100个 log("[增强] 将每页商品数量固定为100个/页"); let pSizeSel = q(".el-pagination__sizes div"); if(pSizeSel){ pSizeSel.click(); setTimeout(()=>{ let btn = document.querySelectorAll("body > div.el-select-dropdown.el-popper > div.el-scrollbar > div.el-select-dropdown__wrap.el-scrollbar__wrap > ul > li.el-select-dropdown__item")[4]; if(btn)btn.click(); },waitReadyTime); }else{ log("[增强] 页码控件还没准备好,等待:"+waitReadyTime+"毫秒"); setTimeout(()=>this.setPageSizeMax,waitReadyTime); } } }, "goShopDetail":function(){ if(!q("a.btn-box"))return; // 防止重复执行 if(q("#goShopDetail_finish")){ log("[增强] 商品ID直达详细页按钮已存在"); return; } log("[增强] 搜索栏添加商品ID直达详细页按钮"); // 搜索栏ID直达详细页按钮 let btn = document.createElement("button"); btn.className="button"; btn.style='border-radius: 0;right: 0px;width: 90px;height: 32px;line-height: 32px;border: none;background-color: '+mainTone+';font-size: 16px;font-weight: 700;color: #fff;transition: background .2s ease;position: absolute;top: 0;outline: none;cursor: pointer;'; let btn_name=document.createElement("span"); btn_name.append("直达商品"); btn.id="goShopDetail_finish"; btn.append(btn_name); btn.onclick=function(){ shoppingCart.jumpToDetail(q(".el-input__inner").value); }; let appendNode = function(){ if(q(".el-input__inner")) { q(".el-input__inner").placeholder="请输入内容搜索,或,输入商品ID点击“直达商品”"; q(".searchbox").append(btn); // 原来的搜索按钮左移 q(".searchbox button").style="right: 92px"; } else { log("[增强] 搜索栏没准备好,等待:"+waitReadyTime+"毫秒"); setTimeout(appendNode,waitReadyTime); } }; appendNode(); },"showDetailId":function(retry){ // 重试次数 //retry = retry || 3; // 显示商品ID let url = window.location.href; if(url.indexOf("shopDetail?id=")!=-1) { // 令滚动条回到顶部 window.scrollTo(0,0); // 防止重复执行 if(q("#showDetailId_finish")!=null)return; log("[增强] 商品详细页添加显示商品ID"); // 防止渲染未完成 if(q(".summary")==null) { if(retry>0){ log(`[增强] 商品ID没准备好,等待:${waitReadyTime}毫秒 重试:${retry}`); retry--; setTimeout(()=>this.showDetailId(retry),waitReadyTime); }else{ log("[增强] 商品ID 不存在,或已经下架。"); } return; } // 设置订购的默认数量 if(shoppingCart.peoples>0){ q(".addCart input").value = shoppingCart.peoples; } let id = request("id"); let sl=document.createElement("span"); sl.style="color: #999;font-size: 12px;margin-left: 10px;"; sl.append("商品直达ID:"); let sd=document.createElement("div"); sd.style="color:#00F"; sd.append(id); let sBox = document.createElement("div"); sBox.className="box"; sBox.id="showDetailId_finish"; sBox.append(sl); sBox.append(sd); // 显示商品直达ID q(".summary").append(sBox); // 预算加车按钮 // 检查库存 let hasCountDiv = q(".summary .box:nth-child(2) div"); let hasCount = 0; if(hasCountDiv)hasCount = parseInt(hasCountDiv.innerText); var btn = copyElement(".addcartBtn"); btn.id="imCart"; if(hasCount<=0){ // 缺货 btn.innerHTML="<span>缺货</span>"; btn.style="background-color: #fff;color: #ccc;border: 2px solid #ccc;cursor: not-allowed;"; }else{ // 加车 btn.innerHTML="<span>加入预算清单</span>"; btn.style="background-color: #fff;color: "+mainTone+";border: 2px solid "+mainTone+""; btn.removeEventListener("click",()=>{this.addShoppingCart(id)}); // 加车方法 btn.addEventListener("click",()=>{ this.addShoppingCart(id); },false); } q(".addCart").appendChild(btn); // 检查是否消费券 if(q(".title span")==null){ q(".summary").classList.add("notCoupon") } } }, // 加入购物车 "addShoppingCart":function(id){ // TODO: 加车并计算剩余预算 let arr = document.querySelectorAll(".choose-attrs button"); // 检查库存 let hasCountDiv = q(".summary .box:nth-child(2) div"); let hasCount = 0; if(hasCountDiv)hasCount = parseInt(hasCountDiv.innerText); let sid = 0; for (let i = 0; i < arr.length; i++) { if(arr[i].className.indexOf("selected")!=-1){ sid = i; break; } } shoppingCart.addItem( { "id":parseInt(id), "sid":sid, "title":q(".title").innerText, "img":q(".preview-box img").src, "price":parseFloat(q(".price").innerText), "specifications":q(".choose-attrs .selected i").innerText, "buyCount":parseInt(q(".addCart input").value), "stock":hasCount, "isCoupon":q(".title span")!=null // 是否有消费券标志 }); }, // 增加栏目导航 "navTopBar":function(){ // 追加导航(标题文本,锚点路由) if(!q(".navitems"))return; let addNav = function(title,urlHash){ let tpl = copyElement(".navitems ul li:not(.style-red)"); let link = tpl.querySelector("a"); link.href="javascript:;"; if(window.location.hash.indexOf(urlHash)!=-1){ // 当前页为选中项 link.className+=" style-red"; }else{ // 赋予单击事件 link.addEventListener("click",()=>gxfp.nav(urlHash),false); } tpl.querySelector("span").innerText=title; q(".navitems ul").append(tpl); }; addNav("初级农产品","#/search?productTypeId=107&name=%E5%88%9D%E7%BA%A7%E5%86%9C%E4%BA%A7%E5%93%81"); addNav("食品饮料","#/search?productTypeId=106&name=%E9%A3%9F%E5%93%81%E9%A5%AE%E6%96%99"); addNav("粮油干货","#/search?productTypeId=105&name=%E7%B2%AE%E6%B2%B9%E5%B9%B2%E8%B4%A7"); }, "offlineBuyCar":function(){ log("[增强] 预算清单 初始化"); shoppingCart.init(); }, // 自动折叠购物车 "autoFoldShoppingCart":function(){ let hash = window.location.hash; if(hash.indexOf("#/index")!=-1 ||hash.indexOf("#/search")!=-1 ||hash.indexOf("#/shopDetail")!=-1 ){ shoppingCart.buyCarBarFold(false); }else{ shoppingCart.buyCarBarFold(true); } }, // 无须登陆就显示“提货券”入口 "indexShowAD":function(){ if(window.location.hash.indexOf("#/index")!=-1){ q(".log-box").innerHTML+= '<a target="_blank" href="https://gxfp.digitalgx.com.cn" class="zttp"><img src="/static/img/ts.dac6a531.jpeg" alt="购买提货券(工会节日慰问品套餐,非消费券)" style="width: 100%;"></a>'; } }, "reg":function(){ // 向页面注册本工具,侦听页面改变事件,当局部刷新页面后再次执行本增强工具 log("[增强]向页面注册本工具,侦听页面改变事件,当局部刷新页面后再次执行本增强工具"); q("#app").addEventListener('DOMNodeInserted', (e) => { if(e.path.length==6){ log("[增强] 捕获到页面 #app 局部刷新"); setTimeout(()=>gxfp.load(),waitReadyTime); } }, false); }, // 每次全页刷新后执行 "load":function(){ log("[增强] 准备执行"); this.navTopBar(); this.goShopDetail(); this.showDetailId(3); this.setPageSizeMax(); this.autoFoldShoppingCart(); this.indexShowAD(); log("[增强] 公共函数执行完成"); if(this.loadedAction&& typeof this.loadedAction == "function") { log("[增强] 准备进行执行后续函数"); this.loadedAction(); } log("[增强] 完成 -----------------------"); }, "loadedAction":null, // 只运行一次的 "disposableRun":function(){ css.init(); css.append("#app .main-box .bottom-box{height:160px}"); css.append("#showDetailId_finish{display: -webkit-box;display: -ms-flexbox;display: flex;-webkit-box-align: center;-ms-flex-align: center;align-items: center;padding-bottom: 5px;}"); css.append(".sort .item{float: left;cursor: pointer;padding: 4px 15px;font-size: 12px;background: #fff;color: #606266;}") css.append(".sort .item.active{background: "+mainTone+";color: #fff;}"); shoppingCart.itemCss(); }, "start":function(){ this.disposableRun(); this.offlineBuyCar(); this.load(); this.reg(); } };//end //setInterval(gxfp.start(),waitReadyTime); setTimeout(()=>gxfp.start(),waitReadyTime); })();