Greasy Fork

Greasy Fork is available in English.

dxm

统计当前订单件数 & 针对区域定价的报关金额进行批量填充

当前为 2024-05-30 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         dxm
// @namespace    http://greasyfork.icu/zh-CN/scripts/462551
// @version      1.7
// @description  统计当前订单件数 & 针对区域定价的报关金额进行批量填充
// @author       Huang
// @match        https://www.dianxiaomi.com/order/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=dianxiaomi.com
// @grant        GM_addStyle
// @license MIT
// ==/UserScript==

(function () {

    class Utils {
        // 模拟input
        static tEvent (b, a) {
            if (b) {
                window.newhtmlevents = window.newhtmlevents || document.createEvent("HTMLEvents");
                newhtmlevents.initEvent(a, true, true);
                return b.dispatchEvent(newhtmlevents)
            }
        }
        static simulateInput (ele, val) {
            this.tEvent(ele, 'click')
            this.tEvent(ele, 'input')
            ele.value = val
            this.tEvent(ele, "keyup")
            this.tEvent(ele, "change")
            this.tEvent(ele, "blur")
        }

        static htmlParser (htmlString) {
            let parser = new DOMParser();
            let doc = parser.parseFromString(htmlString, 'text/html');

            return doc
        }
    }

    class LookDetail {
        constructor(responseTags) {
            this.DETAIL_PAGE_URL = `https://csp.aliexpress.com/apps/order/detail?orderId=`;
            this.detailTags = Utils.htmlParser(responseTags)

            this.main()
        }

        main () {
            let that = this
            // 查找所有的strong元素
            var strongElements = this.detailTags.querySelectorAll('strong');

            // 遍历所有strong标签,查找包含特定文本的元素
            strongElements.forEach(function (ele) {
                let text = ele.textContent
                if (text.includes('站点')) {

                    if (text.includes('半托管')) {
                        that.uniFeature(strongElements, '平台编号')

                    } else {//不是半托,目前为pop单
                        that.uniFeature(strongElements, '订单号')
                    }
                }
            });

        }

        uniFeature (strongElements, splitText) {
            let that = this;

            strongElements.forEach(function (viceEle) {
                let orderNumTag = viceEle.textContent

                if (orderNumTag.includes(splitText)) {
                    let orderId = orderNumTag.split(splitText)[1].replace(':', '')
                    let url = `${that.DETAIL_PAGE_URL}${orderId}`

                    // 直接在css里不让该元素显示了,所以不用再关闭
                    // $('#orderDetailClose1').click()
                    window.open(url)
                }
            })
        }

    }

    class Summary {
        constructor() {
            this.compute()
        }

        // 统计订单件数
        compute () {
            let titleRows = document.querySelectorAll('.goodsId')

            titleRows.forEach(titleRow => {
                let total = 0;
                let nextElement = titleRow.nextElementSibling;
                this.lookFreight(nextElement, titleRow)

                while (nextElement && !nextElement.classList.contains('goodsId')) {
                    let numBoxes = nextElement.querySelectorAll('[class^="circularSpan"]')

                    for (let numBox of numBoxes) {
                        let num = parseInt(numBox.textContent)
                        total += num
                    }
                    nextElement = nextElement.nextElementSibling;
                }
                titleRow.insertAdjacentHTML("beforeend", `<h3 class='total-num'>${total}件</h3>`)

            })
        }

        // 查看运费
        lookFreight (contentRow, titleRow) {
            let orderId = contentRow.querySelector('.tableOrderId a').innerText

            titleRow.insertAdjacentHTML("beforeend", `<a class='look-freight' target='_blank' href='https://sg-cgmp.aliexpress.com/aex-seller-center/logistic/createLogistic?trade_order_id=${orderId}'>查看运费</a>`)
        }

    }


    class Declare {
        static finalDeclareValues = []

        static init () {
            // 从 批量操作 -> 批量报关信息  操作时的步骤
            $(document).off('click', `a[onclick="showBatchCustoms();"]`)
            $(document).on('click', `a[onclick="showBatchCustoms();"]`, () => {
                Declare.prepareData()
            })

            // 直接申请运单号时的步骤
            Declare.applyTrackingDirect()
        }

        static applyTrackingDirect () {
            // 移除原有的申请运单号事件
            $(`button[onclick="batchMoveProcessed();"]`).each(function () {
                $(this).attr('onclick', null)
            })

            // 添加自动化流程
            $(document).off('click', "[id^='moveProcessBtn']")
            $(document).on('click', "[id^='moveProcessBtn']", () => {
                let isCheckedAnyone = $(`#showSelCheckboxNum`).length > 0
                if (!isCheckedAnyone) {
                    $.fn.message({ type: "error", msg: "请至少选择一个订单ya" })
                    return
                }

                Declare.prepareData()
                showBatchCustoms()

                setTimeout(() => {
                    executeBatchCustom(1)

                    // https://www.dianxiaomi.com/static/js/orderIndex.js?v=vh72.03  4708行
                    // $("#orderbatchCustomsInfo").customModal("hide")
                    $('a[data-close="modal"]').click()
                }, 1000)
            })
        }

        // 准备要在报关列表用到的数据
        static prepareData () {
            let t = [], that = this
            $(`input[name='packageId']`).each(function () {
                if ($(this).prop('checked')) {
                    let eleList = $(this).closest('tr').next().children().eq(0).find('tr')
                    if (eleList.length == 1) {//当前订单只有一件时以订单总金额为准
                        let singlePrice = $(eleList[0]).closest('td').next().text().replace(/[^0-9.]/g, "")
                        t.push(singlePrice)
                    } else {
                        eleList.each((i, e) => t.push($(e).find("p:contains('USD')").text().replace(/[^0-9.]/g, "")))
                    }
                    that.finalDeclareValues = t
                }
            })
        }

        static fillValues () {
            let that = this
            const [chsName, engName, weight] = ['狗衣服', 'Dog Clothes', 50]
            $(`input[name="declaredValues"]`).each(function (index) {
                Utils.simulateInput($(this).get(0), that.finalDeclareValues[index])
            })

            $(`input[name="nameChs"]`).each(function (index) {
                if ($(this).val() == '') Utils.simulateInput($(this).get(0), chsName)
            })

            $(`input[name="nameEns"]`).each(function (index) {
                if ($(this).val() == '') Utils.simulateInput($(this).get(0), engName)
            })

            $(`input[name="weights"]`).each(function (index) {
                let curVal = $(this).val()
                if (curVal == '' || curVal == 0) Utils.simulateInput($(this).get(0), weight)
            })
        }
    }


    jQuery.ajaxPrefilter(function (options, originalOptions, jqXHR) {
        const { url } = options
        const keywords = ['list.htm', 'splitList.htm', 'mergeList.htm', 'searchPackage.htm']
        for (const curURL of keywords) {
            jqXHR.done(function (data) {
                if (!data) return
                Declare.init()
                if (url.includes(curURL)) setTimeout(() => { new Summary() }, 50)
                if (url.includes('showBatchCustoms.htm')) setTimeout(function () { Declare.fillValues() }, 50)
                if (url.includes('detail.htm')) setTimeout(() => new LookDetail(data), 50);
            })
        }
    })


    let css = `
    h3.total-num {
        color: #007bff;
        position: absolute;
        left: 200px;
        top: 7px;
        font-size:13px;
    }
    #orderListTable tr.goodsId {
        position: relative;
    }
    .look-freight{
        color: #28a745;
        position: absolute;
        left: 300px;
        top: 4px;
        font-size:13px;
    }
    #dxmOrderDetailDiv{
        display:none
    }
    `
    GM_addStyle(css)
})()