// ==UserScript== // @name 网购优惠查询小助手,淘宝、天猫、京东隐藏优惠券自动查询,搜索结果优惠券信息直接展示,无需进入详情页,快速对比同款优惠信息,持续维护中 // @name:zh 网购优惠查询小助手,淘宝、天猫、京东隐藏优惠券自动查询,搜索结果优惠券信息直接展示,无需进入详情页,快速对比同款优惠信息,持续维护中 // @name:zh-TW 網購優惠查詢小助手,淘寶、天貓、京东隱藏優惠券自動查詢,搜索結果優惠券信息直接展示,無需進入詳情頁,快速對比同款優惠信息,持續維護中 // @description 网购优惠查询小助手功能:1,淘宝、天猫商品详情页自动显示优惠券信息,包括隐藏优惠券的信息,点击领券按钮可快速领取优惠券。2.淘宝、天猫、京东搜索商品列表,每个商品自动显示优惠券面额,为你提供快速对比的效果! // @description:zh 网购优惠查询小助手功能:1,淘宝、天猫商品详情页自动显示优惠券信息,包括隐藏优惠券的信息,点击领券按钮可快速领取优惠券。2.淘宝、天猫、京东搜索商品列表,每个商品自动显示优惠券面额,为你提供快速对比的效果! // @description:zh-TW 網購優惠查詢小助手功能:1,淘寶、天貓商品詳情頁自動顯示優惠券信息,包括隱藏優惠券的信息,點擊領券按鈕可快速領取優惠券。2.淘寶、天貓、京東搜索商品列表,每個商品自動顯示優惠券面額,爲你提供快速對比的效果! // @namespace coupon // @version 1.76 // @author zhihu // @license End-User License Agreement // @match *://*.taobao.com/* // @match *://*.tmall.com/* // @match *://chaoshi.detail.tmall.com/* // @match *://*.tmall.hk/* // @match *://*.liangxinyao.com/* // @match *://*.jd.com/* // @match *://*.jd.hk/* // @match *://*.yiyaojd.com/* // @match *://*.vip.com/* // @match *://*.vipglobal.hk/* // @exclude *://login.taobao.com/* // @exclude *://login.tmall.com/* // @exclude *://uland.taobao.com/* // @exclude *://pages.tmall.com/* // @exclude *://wq.jd.com/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant GM_xmlhttpRequest // @grant GM.xmlHttpRequest // @grant GM_getValue // @grant GM.getValue // @grant GM_setValue // @grant GM.setValue // @antifeature referral-link 【此提示为GreasyFork代码规范要求含有查券功能的脚本必须添加,请知悉!】 // @connect api.zhihupe.com // @grant unsafeWindow // ==/UserScript== (function() { 'use strict'; //全局对象 const window = unsafeWindow||window; const API_DOMAIN = 'https://api.zhihupe.com'; //const API_DOMAIN = 'http://127.0.0.1:7001'; //---------------------------公共方法开始--------------------------- const Utils = { //兼容 Tampermonkey | Violentmonkey | Greasymonkey 4.0+ getValue:function(name, value) { if (typeof GM_getValue === "function") { return GM_getValue(name, value); } else { return GM.getValue(name, value); } }, //兼容 Tampermonkey | Violentmonkey | Greasymonkey 4.0+ setValue:function(name, value) { if (typeof GM_setValue === "function") { GM_setValue(name, value); } else { GM.setValue(name, value); } }, /** * 添加css * @params {String||Array} css - css样式 */ appendStyle(css){ let style = document.createElement('style'); if(css instanceof Array){ style.textContent = css.join(''); }else{ style.textContent = css } style.type = 'text/css'; let doc = document.head || document.documentElement; doc.appendChild(style); }, /** * 添加js文件 * @params {String} url - js文件地址 */ appendScript:function(type,content) { let script = document.createElement('script'); if(type === 'url'){ script.src = content; }else{ script.innerHTML = content; } var docu = document.body; docu.appendChild(script); }, getQueryParam(query,url = ''){ let search = '' if(url&&url.indexOf('?' !== -1)){ search = url.split('?').slice(1).join(); }else{ search = window.location.search.replace('?','') } const queryArr = search.split('&'); let param = null; queryArr.forEach(item => { const paramArr = item.split('='); if(paramArr[0] === query){ param = paramArr[1]; } }); return param; }, getUrlid(url) { var id =""; if (url.indexOf("?") != -1) { url = url.split("?")[0] } if (url.indexOf("#") != -1) { url = url.split("#")[0] } var text = url.split("/"); id = text[text.length - 1]; id = id.replace(".html", ""); return id }, monitorElement(attr){ let attrArr = []; if(attr instanceof Array&&attr.length > 0){ attrArr = [...attr]; }else{ attrArr.push(attr) } let element = null; return new Promise((resolve, reject) => { attrArr.forEach(ele =>{ let timer = null,count = 0; element = document.querySelector(ele); timer = setInterval(()=>{ if(element){ clearInterval(timer); resolve(element); } if(count > 50){ clearInterval(timer); reject('未找到元素节点'); } element = document.querySelector(ele); count ++ },200) }) }) } } const initData = { wenku:{ codeInputElement:"#code", loginCode:"123456", }, coupon:{ shopGuideGroupText:'捡漏导购Q群', shopGuideGroup:'188872170', hasCouponBtnText:'领券购买', noCouponBtnText:'直接购买', noCommissionBtnText:'搜索同款优惠', buyUrl:'http://tool.wezhicms.com/coupon/getscan.php', tbShortUrlApi:'https://api.shop.xuelg.com/?id={ID}&m=shangpin', tbShortUrlApiReqQuery: 'shorturl', blackElement:['.coupon-wrap','#toolbar-qrcode'], taobao:{ detailCouponMountElement:['.SecurityPrice--securityPrice--25lJx-X','.Price--root--1CrVGjc'], searchGoodsCardElement:['.Content--content--sgSCZ12 .Card--doubleCardWrapper--L2XFE73','.Content--content--sgSCZ12 .Card--doubleCardWrapperMall--uPmo5Bz','.J_TItems .item .photo a'] }, tmall:{ detailCouponMountElement:['.SecurityPrice--securityPrice--25lJx-X','.Price--root--1CrVGjc'] }, tmallcs:{ searchGoodsCardElement:['.feeds-list .feeds-item a'] }, jd:{ detailCouponMountElement:'#J-summary-top', searchGoodsCardElement:['.J-goods-list .gl-i-wrap .p-img a','.jSearchListArea .jItem .jPic a'] } } } class Coupon{ //优惠券查询地址 couponApiUrl = ''; //优惠券展示节点 initElement = null; get isHasCoupon(){ return this.couponInfo?.couponAmount > 0; } constructor(platform){ this.platform = platform; //优惠券信息 let couponInfo = {}; Object.defineProperty(this,'couponInfo',{ set(value){ couponInfo = value; //更新优惠券信息 this.updateCouponHtml(); }, get(){ return couponInfo; } }) } /* 获取优惠券信息 return {Promise} */ getCouponInfo(){ if(!this.goodsId) throw new TypeError('商品ID获取失败'); if(!this.couponApiUrl) throw new TypeError('优惠券查询链接不存在'); return new Promise((resolve, reject) => { fetch(this.couponApiUrl,{ method:'GET', mode:'cors', }).then(r=>r.json()).then(response=>{ if(response.code === 1){ resolve(response.data) }else{ reject(new TypeError(response.message)) } }).catch(err=>{ reject(err) }) }); } getTbShortUrl(id){ const api = initData.coupon.tbShortUrlApi.replace('{ID}',id) return new Promise((resolve, reject) => { fetch(api,{ method:'GET', mode:'cors', }).then(r=>r.json()).then(response=>{ resolve(response[initData.coupon.tbShortUrlApiReqQuery]) }).catch(err=>{ reject(err) }) }); } /* *插入优惠券节点 * params {ElementObject} 定位元素对象 * params {String} position 插入位置 */ async appendCouponElement(element,position = "afterend"){ //插入css this.css&&Utils.appendStyle(this.css) //插入Html this.initElement = this.loadingElement||null; if(this.initElement)element.insertAdjacentElement(position,this.initElement); } async updateCouponHtml(){ if(this.initElement){ this.initElement.innerHTML = this.couponHtml //添加关闭二维码事件 const qr = document.querySelectorAll('.closeQr'); if(qr.length > 0){ console.log(qr) Array.from(qr).forEach(e=>{e.onclick = ()=> e.parentNode.style.display = 'none'}) } } } async updateCouponErrorHtml(){ if(this.initElement)this.initElement.innerHTML = this.couponHtml } } class DetailCoupon extends Coupon{ css = ` .zhihu-coupon:hover .zhihu-scan{ display:block!important; } ` get mobileAppText(){ let text = '手机淘宝'; switch (this.platform) { case 'tmall': case 'taobao': text = '手机淘宝' break; case 'jd': text = '手机京东或微信' break; } return text; } get couponHtml(){ let couponHtml = '暂未发现优惠券', tipsText = initData.coupon.shopGuideGroupText + ':' + initData.coupon.shopGuideGroup, btnText = initData.coupon.noCouponBtnText, buyLink = `${initData.coupon.buyUrl}?link=${this.couponInfo.shortUrl}&platform=${encodeURIComponent(this.mobileAppText)}`, qrcodebox = `
${this.qrcodeHtml}
` if(this.isHasCoupon){ couponHtml = ` 优惠券: ${Math.round(this.couponInfo.couponAmount)} `; tipsText = `${this.couponInfo.couponStartTime} - ${this.couponInfo.couponEndTime}`; btnText = initData.coupon.hasCouponBtnText; }else if(this.noCommission){ couponHtml = '暂未发现优惠券'; buyLink = ''; btnText = initData.coupon.noCommissionBtnText; qrcodebox = ''; } return `
${couponHtml}
${tipsText}
${btnText}
${this.qrcodeHtml}
${qrcodebox} ` } get loadingElement(){ const div = document.createElement('div'); div.classList = 'zhihu-coupon'; div.style = 'background-image: url(https://gw.alicdn.com/tfs/TB16d.1ykPoK1RjSZKbXXX1IXXa-665-115.png); position: relative; font-family: HelveticaNeue-Bold, "Helvetica Neue"; width: 426px; height: 75px; background-size: 100%, 100%; background-repeat: no-repeat; margin: 10px 0px 10px 10px; display: flex; align-items: center;' div.innerHTML = `
正在搜索优惠券···
`; return div; } get qrcodeHtml(){ if(!this.couponInfo?.shortUrl) return ''; return `
${this.mobileAppText}扫一扫,享优惠
` } constructor(platform){ super(platform); this.addCouponElement(); } async addCouponElement(){ try { //获取商品ID和优惠券API链接 if(this.platform == 'taobao'||this.platform == 'tmall'){ this.goodsId = Utils.getQueryParam('id')||null; const shortUrl = await this.getTbShortUrl(this.goodsId); console.log(shortUrl) this.couponApiUrl = API_DOMAIN + '/api/coupon/info?platform=taobao' + '&id=' + shortUrl }else if(this.platform === 'jd'){ this.goodsId = Utils.getUrlid(window.location.href)||null; this.couponApiUrl = API_DOMAIN + '/api/coupon/info?platform=jd' + '&id=' + this.goodsId; } //添加优惠券元素 const attr = initData.coupon[this.platform]['detailCouponMountElement']; console.log(initData.coupon[this.platform]) const element = await Utils.monitorElement(attr); this.appendCouponElement(element); //获取商品优惠券 this.couponInfo = await this.getCouponInfo(); } catch (error) { //添加无佣金状态 this.noCommission = true; //更新无佣金html this.updateCouponErrorHtml() console.log(error) } } } class SearchCoupon extends Coupon{ get couponHtml(){ let html = `暂无优惠` if(this.isHasCoupon){ html = `有券:减${this.couponInfo.couponAmount}元` } return html } get loadingElement(){ const div = document.createElement('div'); div.style = 'position: absolute;top: 10px;right: 10px;z-index: 99999999;font-size: 12px;'; div.innerHTML = ` 正在搜索优惠 `; return div; } constructor(element,platform){ super(platform); this.addCouponElement(element) } async addCouponElement(element){ try { //获取商品ID和优惠券API链接 if(this.platform == 'taobao'||this.platform == 'tmallcs'){ const href = element.getAttribute('href'); this.goodsId = Utils.getQueryParam('id',href)||null; const shortUrl = await this.getTbShortUrl(this.goodsId); console.log(shortUrl) this.couponApiUrl = API_DOMAIN + '/api/coupon/search?platform=taobao' + '&id=' + shortUrl }else if(this.platform === 'jd'){ const href = element.getAttribute('href'); this.goodsId = Utils.getUrlid(href)||null; this.couponApiUrl = API_DOMAIN + '/api/coupon/search?platform=jd' + '&id=' + this.goodsId; } element.style.position = 'relative'; //添加优惠券节点 this.appendCouponElement(element,'beforeend'); //获取商品优惠券 this.couponInfo = await this.getCouponInfo(); } catch (error) { console.log(error) //更新无佣金html this.updateCouponErrorHtml() console.log(error.message) } } } async function getInitData(){ const request = ()=>{ return new Promise((resolve, reject) => { fetch(API_DOMAIN + '/api/coupon/init',{ method:'GET', mode:'cors', }).then(r=>r.json()).then(response=>{ if(response.code === 1){ resolve(response.data) }else{ resolve(null) } }).catch(err=>{ resolve(null) }) }) } const _initData = await request(); _initData&&(initData.coupon = {..._initData}); } async function detailCouponInit(platform = 'taobao'){ await getInitData(); new DetailCoupon(platform); //移除节点 if(initData.coupon.blackElement instanceof Array && initData.coupon.blackElement.length > 0){ const blackElement = initData.coupon.blackElement; blackElement.forEach(item => { Utils.monitorElement(item).then(selector=>{ selector.remove() }) }) } } async function searchCouponInit(platform = 'taobao'){ await getInitData(); if(!(initData.coupon?.[platform]?.searchGoodsCardElement instanceof Array)||initData.coupon?.[platform]?.searchGoodsCardElement.length === 0) return //class数组 const clss = initData.coupon[platform].searchGoodsCardElement; //监听商品卡片 setInterval(()=>{ //遍历class数组 for (let i = 0; i < clss.length; i++) { const elements = document.querySelectorAll(clss[i]); if(elements&&elements.length > 0){ Array.from(elements).forEach(element=>{ if(element.classList.contains('zhihu-coupon-added')) return; //添加class标记 element.classList.add('zhihu-coupon-added'); new SearchCoupon(element,platform); }) } } },1500) } async function zhihuWenkuInit(){ sessionStorage.setItem('zhihu_sign',true); } //网址匹配 const siteMap = [ { match:['item.taobao.com/item.htm.*'], platform:'taobao', initFunc:detailCouponInit }, { match:['detail.tmall.com/item.htm.*','detail.tmall.hk/hk/item.htm.*'], platform:'tmall', initFunc:detailCouponInit }, { match:['item.jd.com/.*','npcitem.jd.hk/.*'], platform:'jd', initFunc:detailCouponInit }, { match:['s.taobao.com/search.*','suning.tmall.com/category.*'], platform:'taobao', initFunc:searchCouponInit }, { match:['pages.tmall.com/wow/an/cs/search.*'], platform:'tmallcs', initFunc:searchCouponInit }, { match:['search.jd.com/Search.*','list.jd.com/list.html.*','mall.jd.com/view_search.*'], platform:'jd', initFunc:searchCouponInit }, { match:['wenku.zhihupe.com/tool/index.*','wenku.zhihupe.com/#.*'], initFunc:zhihuWenkuInit } ] //生成正则表达式 function createReg(arr){ return new RegExp(arr.join('|')) } //根据网址匹配 for (const site of siteMap) { let reg = createReg(site.match) let host = window.location.hostname + window.location.pathname let result = reg.test(host) if(result){ let platform = site.platform||''; return site.initFunc(platform); } } // Your code here... })();;