Greasy Fork is available in English.

找家纺小助手

赵木杉打钱!

// ==UserScript==
// @name         找家纺小助手
// @namespace    http://tampermonkey.net/
// @version      33333333333333333333333333333333333333333333333333
// @description  赵木杉打钱!
// @author       You
// @match        https://detail.zhaojiafang.com/goods/*
// @icon         https://i.postimg.cc/L5KDY5m1/Snipaste-2024-04-04-00-11-40.png
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';
    var colorId
    var allPriceIds = []; // 所有的价格id
    const getDataInfo = () => {
       return new Promise((resolve, reject) => {
          var id = window.location.pathname.split('/').pop();
          var xhr = new XMLHttpRequest();
          xhr.open('GET', `https://detail.zhaojiafang.com/_next/data/L1vX1I4xvT7FoWifEYxWb/goods/${id}.json?id=${id}`, true);
          xhr.responseType = 'json';
          xhr.onload = () => {
             // Check if the request was successful
             if (xhr.status === 200) {
                // Print the pageProps data
                const goodsInfo = xhr.response.pageProps.goodsInfo.spec.data; // 当前sku信息
                colorId = xhr.response.pageProps.goodsInfo.goods_detail.color_id; // 当前商品id
                const allColor = xhr.response.pageProps.goodsInfo.spec.spec[0].spec; // 所有颜色
                const allSize = xhr.response.pageProps.goodsInfo.spec.spec[1].spec; // 所有尺码
                const soldIdObj = []; // 已售罄的sku
                const unsoldIdObj = []; // 未售罄的sku
                /// 循环遍历所有的goodsInfo对象 key1是colorId key2是sizeId
                for (const key1 in goodsInfo) {
                   for (const key2 in goodsInfo[key1]) {
                      allPriceIds.push(goodsInfo[key1][key2].goods_id)
                      if (goodsInfo[key1][key2].goods_storage < 10) {
                         soldIdObj.push({ colorId: key1, sizeId: key2, state: goodsInfo[key1][key2].goods_state })
                      }
                   }
                }
                /// 循环遍历所有的goodsInfo对象 key1是colorId key2是sizeId
                for (const key1 in goodsInfo) {
                   for (const key2 in goodsInfo[key1]) {
                      if (goodsInfo[key1][key2].goods_storage >= 10) {
                         unsoldIdObj.push({ colorId: key1, sizeId: key2, state: goodsInfo[key1][key2].goods_state })
                      }
                   }
                }
                // 根据allColor allSize 对solidObj进行翻译
                const soldObj = soldIdObj.map(item => {
                   if (item.state === 0) return;
                   const color = allColor.find(color => color.sp_value_id === item.colorId).sp_value;
                   const size = allSize.find(size => size.sp_value_id === item.sizeId).sp_value;
                   const colorId = item.colorId;
                   const sizeId = item.sizeId;
                   return { color, size, colorId, sizeId }
                }).filter(item => item)
                console.log('已售罄:', soldObj)
                // 根据allColor allSize 对solidObj进行翻译
                const unsoldObj = unsoldIdObj.map(item => {
                   if (item.state === 0) return;
                   const color = allColor.find(color => color.sp_value_id === item.colorId).sp_value;
                   const size = allSize.find(size => size.sp_value_id === item.sizeId).sp_value;
                   const colorId = item.colorId;
                   const sizeId = item.sizeId;
                   return { color, size, colorId, sizeId }
                }).filter(item => item)
                console.log('未售罄:', unsoldObj)
                // 追加div展示未售罄信息
                const divUnsold = document.createElement('div');
                divUnsold.id = 'unsold';
                divUnsold.style.position = 'fixed';
                divUnsold.style.left = '0';
                divUnsold.style.top = '60%';
                divUnsold.style.transform = 'translateY(-50%)';
                divUnsold.style.zIndex = '9999';
                divUnsold.style.padding = '10px';
                divUnsold.style.backgroundColor = 'rgba(0,0,0,0.5)';
                divUnsold.style.color = '#fff';
                divUnsold.style.fontSize = '14px';
                divUnsold.style.lineHeight = '20px';
                divUnsold.style.overflow = 'auto';
                divUnsold.style.maxHeight = '80vh';
                divUnsold.style.textOverflow = 'ellipsis';
                divUnsold.style.whiteSpace = 'nowrap';
                divUnsold.style.display = 'none';
                // 根据sizeId进行分组 color用,分割 不同的sizeId进行换行展示 \n没有效果 需要新建div实现换行
                const groupBySizeIdUnsold = unsoldObj.reduce((acc, cur) => {
                   if (acc[cur.sizeId]) {
                      acc[cur.sizeId].push(cur)
                   } else {
                      acc[cur.sizeId] = [cur]
                   }
                   return acc
                }, {})
                for (const key in groupBySizeIdUnsold) {
                   const div1 = document.createElement('div');
                   div1.style.color = 'green';
                   div1.style.fontWeight = 'bolder';
                   div1.style.fontSize = '18px';
                   div1.innerText = `尺码:${allSize.find(size => size.sp_value_id === key).sp_value}(${groupBySizeIdUnsold[key].length})`;
                   divUnsold.appendChild(div1);
                   groupBySizeIdUnsold[key].forEach(item => {
                      const div2 = document.createElement('div');
                      div2.innerText = `${item.color}`;
                      divUnsold.appendChild(div2);
                   })
                }
                // 如果有div了就不追加了
                if (!document.getElementById('unsold')) {
                   document.body.appendChild(divUnsold);
                }
                // 在body中追加div垂直剧中到屏幕左侧展示售罄信息 根据sizeId进行分组
                const div = document.createElement('div');
                div.id = 'soldOut';
                div.style.position = 'fixed';
                div.style.left = '0';
                div.style.top = '60%';
                div.style.transform = 'translateY(-50%)';
                div.style.zIndex = '9999';
                div.style.padding = '10px';
                div.style.backgroundColor = 'rgba(0,0,0,0.5)';
                div.style.color = '#fff';
                div.style.fontSize = '14px';
                div.style.lineHeight = '20px';
                div.style.overflow = 'auto';
                div.style.maxHeight = '80vh';
                div.style.textOverflow = 'ellipsis';
                div.style.whiteSpace = 'nowrap';
                // 根据sizeId进行分组 color用,分割 不同的sizeId进行换行展示 \n没有效果 需要新建div实现换行
                const groupBySizeId = soldObj.reduce((acc, cur) => {
                   if (acc[cur.sizeId]) {
                      acc[cur.sizeId].push(cur)
                   } else {
                      acc[cur.sizeId] = [cur]
                   }
                   return acc
                }, {})
                for (const key in groupBySizeId) {
                   const div1 = document.createElement('div');
                   div1.style.color = 'red';
                   div1.style.fontWeight = 'bolder';
                   div1.style.fontSize = '18px';
                   div1.innerText = `尺码:${allSize.find(size => size.sp_value_id === key).sp_value}(${groupBySizeId[key].length})`;
                   div.appendChild(div1);
                   groupBySizeId[key].forEach(item => {
                      const div2 = document.createElement('div');
                      div2.innerText = `${item.color}`;
                      div.appendChild(div2);
                   })
                }
                // 如果有div了就不追加了
                if (!document.getElementById('soldOut')){
                   document.body.appendChild(div);
                }
                // 在div旁边加个按钮点击切换 显示或者隐藏
                const btn = document.createElement('button');
                btn.id = 'soldOutBtn';
                btn.innerText = '显示/隐藏';
                btn.style.position = 'absolute';
                // 优化按钮样式
                btn.style.padding = '10px';
                btn.style.backgroundColor = 'rgba(0,0,0,0.5)';
                btn.style.color = '#fff';
                btn.style.fontSize = '14px';
                btn.style.lineHeight = '20px';
                btn.style.cursor = 'pointer';
                btn.style.position = 'fixed';
                btn.style.left = '0';
                btn.style.top = '10%';
                btn.style.transform = 'translateY(-50%)';
                btn.onclick = () => {
                   if (div.style.display === 'none') {
                      div.style.display = 'block';
                      divUnsold.style.display = 'none';
                   } else {
                      div.style.display = 'none';
                      divUnsold.style.display = 'none';
                   }
                }
                if(!document.getElementById('soldOutBtn')){
                   document.body.appendChild(btn);
                }
                // 在div旁边加个按钮点击切换 展示售罄还是未售罄
                const btn2 = document.createElement('button');
                btn2.id = 'unsoldBtn';
                btn2.innerText = '售罄/未售罄';
                btn2.style.position = 'absolute';
                // 优化按钮样式
                btn2.style.padding = '10px';
                btn2.style.backgroundColor = 'rgba(0,0,0,0.5)';
                btn2.style.color = '#fff';
                btn2.style.fontSize = '14px';
                btn2.style.lineHeight = '20px';
                btn2.style.cursor = 'pointer';
                btn2.style.position = 'fixed';
                btn2.style.left = '0';
                btn2.style.top = '15%';
                btn2.style.transform = 'translateY(-50%)';
                btn2.onclick = () => {
                   if (divUnsold.style.display === 'none') {
                      divUnsold.style.display = 'block';
                      soldOut.style.display = 'none';
                   } else {
                      divUnsold.style.display = 'none';
                      soldOut.style.display = 'block';
                   }
                }
                if(!document.getElementById('unsoldBtn')) {
                   document.body.appendChild(btn2);
                }
                resolve()
             } else {
                console.error('Error:', xhr.status);
                reject()
             }
          };
          xhr.onerror = function () {
             console.error('Request failed');
          };
          xhr.send();
       })

    }
    getDataInfo().then(() => {
       console.log('获取数据成功')
    }).catch(() => {
       console.log('获取数据失败')
    })
    // 价格计算
    const priceCompute = () => {
       let skuDoms = document.getElementsByClassName('last:mb-0 mb-16')
       for (let skuDom of skuDoms) {
          skuDom.style.borderBottom = '1px solid black'
       }
       const coupon = document.getElementById('coupon').value;
       getDataInfo().then(() => {
          // 循环中给dom设置价格
          allPriceIds.forEach(id => {
             // 设置dom元素的价格 ${colorId}_goods_list_${id}_goods_price
             const dom = document.getElementById(`${colorId}_goods_list_${id}_goods_price`);
             // 已经计算过的不再计算
             if (dom) {
                if (dom.innerText.includes('券后价:')) return;
                // 成本价格
                const oldPrice = dom.innerText.replace('¥', '');
                // 设置价格:成本价格 + 利润(成本价格*0.2) + 快递费(5)+ 服务费(成本价格*0.05)+ 退运费(1.5)+ 优惠卷(10)
                let newPrice = parseFloat(oldPrice) + parseFloat(oldPrice) * 0.2 + 5 + parseFloat(oldPrice) * 0.05 + 1.5 ; // 未算优惠券价格
                let finalPrice = 0
                console.log('newPrice:', newPrice,document.getElementById('checkbox').checked,document.getElementById('checkbox2').checked)
                if(document.getElementById('checkbox').checked&&document.getElementById('checkbox2').checked){
                   if(newPrice+30>=200) {
                      finalPrice = newPrice + 30;
                   } else if(newPrice+20>=100&&newPrice+20<200) {
                      finalPrice = newPrice + 20;
                   }else if(newPrice+parseFloat(coupon)<100) {
                      finalPrice = newPrice + parseFloat(coupon);
                   }
                }else if(document.getElementById('checkbox').checked) {
                   if(newPrice+20>=100) {
                      finalPrice = newPrice + 20;
                   }else {
                      finalPrice = newPrice + parseFloat(coupon);
                   }
                }else if(document.getElementById('checkbox2').checked) {
                   if(newPrice+30>=200) {
                      finalPrice = newPrice + 30;
                   } else {
                      finalPrice = newPrice + parseFloat(coupon);
                   }
                }else{
                   finalPrice = newPrice + parseFloat(coupon);
                }
                dom.style.textWrap = 'nowrap';
                dom.innerHTML = `
                   <div>原价:${oldPrice}</div>
                   <div>无优惠:${newPrice.toFixed(2)}<span style="font-size:12px"> 利(${(parseFloat(oldPrice) * 0.2 ).toFixed(2)})</span></div>
                   <div>券:${(finalPrice-newPrice).toFixed(2)}</div>
                   <div style="color:red;font-weight:bolder">券后价:${finalPrice.toFixed(2)}</div>
                `

                // dom.innerHTML = '原价:'+oldPrice+'\n'+ '无优惠:' +newPrice + '\n' +'券后价:' +`¥${(finalPrice).toFixed(2)}`; // 保留两位小数

             }
          })
       }).catch(() => { })

    }
    // 追加优惠券金额输入框 id=coupon 默认值10
    const coupon = document.createElement('input');
    coupon.id = 'coupon';
    coupon.type = 'number';
    coupon.value = localStorage.getItem('coupon') || '0';
    coupon.style.position = 'fixed';
    coupon.style.right = '0';
    coupon.style.top = '30%';
    coupon.style.transform = 'translateY(-50%)';
    coupon.style.zIndex = '9999';
    coupon.style.padding = '10px';
    coupon.style.backgroundColor = 'rgba(0,0,0,0.5)';
    coupon.style.color = '#fff';
    coupon.style.fontSize = '14px';
    coupon.style.lineHeight = '20px';
    document.body.appendChild(coupon);

    // 增加满100-10的选择checkbox lable是满100-20
    const checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkbox.id = 'checkbox';
    checkbox.style.position = 'fixed';
    checkbox.style.right = '0';
    checkbox.style.top = '15%';
    checkbox.style.transform = 'translateY(-50%)';
    checkbox.style.zIndex = '9999';
    checkbox.style.padding = '10px';
    checkbox.style.backgroundColor = 'rgba(0,0,0,0.5)';
    checkbox.style.color = '#fff';
    checkbox.style.fontSize = '14px';
    checkbox.style.lineHeight = '20px';
    // 根据localstorage设置checkbox的状态
    if (localStorage.getItem('checkbox') === 'true') {
       checkbox.checked = true;
    }
    document.body.appendChild(checkbox);
    const lable = document.createElement('lable');
    lable.innerText = '满100-20';
    lable.style.position = 'fixed';
    lable.style.right = '2%';
    lable.style.top = '15%';
    lable.style.transform = 'translateY(-50%)';
    lable.style.zIndex = '9999';
    lable.style.padding = '10px';
    lable.style.backgroundColor = 'rgba(0,0,0,0.5)';
    lable.style.color = '#fff';
    lable.style.fontSize = '14px';
    lable.style.lineHeight = '20px';
    document.body.appendChild(lable);

    // 增加满200-20的选择checkbox lable是满200-30
    const checkbox2 = document.createElement('input');
    checkbox2.type = 'checkbox';
    checkbox2.id = 'checkbox2';
    checkbox2.style.position = 'fixed';
    checkbox2.style.right = '0';
    checkbox2.style.top = '10%';
    checkbox2.style.transform = 'translateY(-50%)';
    checkbox2.style.zIndex = '9999';
    checkbox2.style.padding = '10px';
    checkbox2.style.backgroundColor = 'rgba(0,0,0,0.5)';
    checkbox2.style.color = '#fff';
    checkbox2.style.fontSize = '14px';
    checkbox2.style.lineHeight = '20px';
    // 根据localstorage设置checkbox的状态
    if (localStorage.getItem('checkbox2') === 'true') {
       checkbox2.checked = true;
    }
    document.body.appendChild(checkbox2);
    const lable2 = document.createElement('lable');
    lable2.innerText = '满200-30';
    lable2.style.position = 'fixed';
    lable2.style.right = '2%';
    lable2.style.top = '10%';
    lable2.style.transform = 'translateY(-50%)';
    lable2.style.zIndex = '9999';
    lable2.style.padding = '10px';
    lable2.style.backgroundColor = 'rgba(0,0,0,0.5)';
    lable2.style.color = '#fff';
    lable2.style.fontSize = '14px';
    lable2.style.lineHeight = '20px';
    document.body.appendChild(lable2);

    // 当coupon checkbox checkbox2更改时触发保存到localstorage
    checkbox.onchange = () => {
       localStorage.setItem('checkbox', checkbox.checked);
       // 刷新页面
       window.location.reload();
    }
    checkbox2.onchange = () => {
       localStorage.setItem('checkbox2', checkbox2.checked);
       window.location.reload();
    }
    coupon.onchange = () => {
       localStorage.setItem('coupon', coupon.value);
       window.location.reload();
    }



    // 追加按钮 一键计算价格
    const btn = document.createElement('button');
    btn.innerText = '一键计算价格';
    btn.style.position = 'fixed';
    btn.style.right = '0';
    btn.style.top = '22%';
    btn.style.transform = 'translateY(-50%)';
    btn.style.zIndex = '9999';
    btn.style.padding = '10px';
    btn.style.backgroundColor = 'rgba(0,0,0,0.5)';
    btn.style.color = '#fff';
    btn.style.fontSize = '14px';
    btn.style.lineHeight = '20px';
    btn.style.cursor = 'pointer';
    btn.onclick = priceCompute;
    document.body.appendChild(btn);
    // Send the request
 })();