- // ==UserScript==
- // @name dxm
- // @namespace https://greasyfork.org/zh-CN/scripts/462551
- // @version 2.64
- // @author Huang
- // @description 统计当前订单件数 & 针对区域定价的报关金额进行批量填充
- // @license MIT
- // @icon https://www.google.com/s2/favicons?sz=64&domain=dianxiaomi.com
- // @match https://www.dianxiaomi.com/order/*
- // @grant GM_addStyle
- // @run-at document-start
- // ==/UserScript==
-
- (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const o=document.createElement("style");o.textContent=t,document.head.append(o)})(" h3.total-num{color:#007bff;position:absolute;left:200px;top:7px;font-size:13px}#orderListTable tr.goodsId{position:relative}.operation-btns{position:absolute;left:300px;top:4px}.operation-btns a{color:#28a745;font-size:13px;margin-right:20px}#dxmOrderDetailDiv{display:none}.total-count{color:red;line-height:30px;font-size:13px;margin-left:10px}.pkg-types{color:gray;line-height:30px;font-size:13px;margin-left:10px} ");
-
- (function () {
- 'use strict';
-
- var __defProp = Object.defineProperty;
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
- var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
- 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;
- }
- static isGpsrCountry(countryCode) {
- const countries = ["奥地利", "比利时", "保加利亚", "塞浦路斯", "克罗地亚", "捷克共和国", "丹麦", "爱沙尼亚", "芬兰", "法国", "德国", "希腊", "匈牙利", "爱尔兰", "意大利", "拉脱维亚", "立陶宛", "卢森堡", "马耳他", "荷兰", "波兰", "葡萄牙", "罗马尼亚", "斯洛伐克", "斯洛文尼亚", "西班牙", "瑞典"];
- return countries.includes(countryCode);
- }
- /**
- * 从URL中提取指定键的查询参数值。
- * @param {string} url - 包含查询参数的URL。
- * @param {string} key - 要提取值的查询参数键。
- * @returns {string|null} - 指定键的查询参数值,如果不存在则返回null。
- */
- static getUrlKeyValuePairs(url, key) {
- const pairs = {};
- const parts = url.split("?")[1].split("&");
- for (const part of parts) {
- const [key2, value] = part.split("=");
- pairs[key2] = value;
- }
- return pairs[key] || null;
- }
- static isiPad() {
- const ua = navigator.userAgent;
- const platform = navigator.platform;
- if (/iPad/i.test(ua) || platform === "iPad") {
- return true;
- }
- return platform === "MacIntel" && navigator.maxTouchPoints > 1;
- }
- }
- const _Declare = class _Declare {
- 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();
- });
- }
- // 准备要在报关列表用到的数据
- static prepareData() {
- let t = [], that = this, _reg = /[^0-9.]/g;
- $(`input[name='packageId']`).each(function() {
- if ($(this).prop("checked")) {
- let common = $(this).closest("tr").next().children();
- const isJIT = $(this).closest("tr").next()[0].getAttribute("data-platform").includes("Choice");
- if (!isJIT) {
- let eleList = common.eq(0).find("tr");
- let rightPrice = common.eq(1).text().replace(_reg, "");
- rightPrice = Number(rightPrice);
- let singleItem = eleList.length == 1;
- if (singleItem) {
- let leftPrice = eleList.find("p:contains('USD')").text().replace(_reg, "");
- leftPrice = Number(leftPrice);
- let finalPrice = leftPrice < rightPrice ? leftPrice : rightPrice;
- t.push(finalPrice);
- } else {
- eleList.each((i, e) => t.push($(e).find("p:contains('USD')").text().replace(_reg, "")));
- }
- }
- 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);
- });
- }
- };
- __publicField(_Declare, "finalDeclareValues", []);
- let Declare = _Declare;
- class Summary {
- constructor(url) {
- this.curURL = url;
- if (Utils.isiPad() === false) {
- this.compute();
- }
- this.total();
- this.packageTypes();
- this.addGpsrTag();
- }
- /**
- * 判断当前url是否可以追踪物流信息。
- * @returns {boolean} - 如果可以追踪物流信息,则返回true,否则返回false。
- */
- ifCanTrack() {
- let ifTargetURL = this.curURL.includes("list.htm");
- if (ifTargetURL) {
- let state = Utils.getUrlKeyValuePairs(this.curURL, "state");
- if (state === "shipped") {
- return true;
- }
- return false;
- }
- return false;
- }
- // 统计订单件数
- compute() {
- let titleRows = document.querySelectorAll(".goodsId");
- titleRows.forEach((titleRow) => {
- let total = 0;
- let nextElement = titleRow.nextElementSibling;
- this.addFreightAndTrackElements(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>`);
- });
- }
- addFreightAndTrackElements(contentRow, titleRow, total) {
- const baseURL = `https://csp.aliexpress.com/m_apps`;
- const operationDiv = $('<div class="operation-btns"></div>');
- let orderId = contentRow.querySelector(".tableOrderId a").innerText;
- const freightLink = $(`<a target='_blank' href='${baseURL}/logistic/create_ship_cn?trade_order_id=${orderId}'>查看运费</a>`);
- operationDiv.append(freightLink);
- let ifCanTrack = this.ifCanTrack();
- if (ifCanTrack) {
- const logisticsLink = $(`<a target='_blank' href='${baseURL}/logistics/tracking?tradeOrderId=${orderId}'>物流轨迹</a>`);
- operationDiv.append(logisticsLink);
- }
- $(titleRow).append(operationDiv);
- }
- total() {
- let total = 0;
- let pieceSpans = document.querySelector("#orderListTable").querySelectorAll('[class^="circularSpan"]');
- if (pieceSpans.length == 0) return;
- pieceSpans.forEach((pieceSpan) => {
- let num = parseInt(pieceSpan.textContent);
- total += num;
- });
- let existingTotal = document.querySelector(".total-count");
- if (existingTotal) {
- existingTotal.remove();
- }
- $("#allClassification").append(`<span class="total-count">Total: ${total} 件</span>`);
- }
- packageTypes() {
- let pkgs = document.querySelectorAll(".buyerSelectProvider");
- if (pkgs.length == 0) return;
- let economy = 0, saver = 0, standard = 0;
- pkgs.forEach((pkg) => {
- if (pkg.textContent.includes("Economy")) {
- economy++;
- } else if (pkg.textContent.includes("Saver")) {
- saver++;
- } else if (pkg.textContent.includes("Standard")) {
- standard++;
- }
- });
- let existingTotal = document.querySelector(".pkg-types");
- if (existingTotal) {
- existingTotal.remove();
- }
- $("#allClassification").append(`<span class="pkg-types">经济: ${economy}个 简易: ${saver}个 标准: ${standard}个</span>`);
- }
- addGpsrTag() {
- let titleRows = document.querySelectorAll(".goodsId");
- titleRows.forEach((titleRow) => {
- let nextElement = titleRow.nextElementSibling;
- let tag = $(nextElement).find('a[onclick^="dxmOrderDetail("]').next();
- let country = tag.closest("td").prev().children().last().text().replace(/「|」/g, "");
- let isGSPR = Utils.isGpsrCountry(country);
- if (isGSPR) {
- tag.append(`<span class="squareSpanOra">G</span>`);
- }
- });
- }
- }
- class LookDetail {
- constructor(responseTags) {
- this.DETAIL_PAGE_URL = `https://csp.aliexpress.com/apps/order/detail?orderId=`;
- this.detailTags = Utils.htmlParser(responseTags);
- this.main();
- }
- main() {
- var strongElements = this.detailTags.querySelectorAll("strong");
- strongElements.forEach((ele) => {
- let text = ele.textContent;
- if (text.includes("站点")) {
- if (text.includes("半托管")) {
- this.jump2AliOrderDetail(strongElements, "平台编号");
- } else {
- this.jump2AliOrderDetail(strongElements, "订单号");
- }
- }
- });
- }
- jump2AliOrderDetail(strongElements, splitText) {
- strongElements.forEach((viceEle) => {
- let orderNumTag = viceEle.textContent;
- if (orderNumTag.includes(splitText)) {
- let orderId = orderNumTag.split(splitText)[1].replace(":", "");
- let url = `${this.DETAIL_PAGE_URL}${orderId}`;
- $("#orderDetailClose1").click();
- window.open(url);
- }
- });
- }
- }
- const originalOpen = XMLHttpRequest.prototype.open;
- const originalSend = XMLHttpRequest.prototype.send;
- XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
- this._requestUrl = url;
- return originalOpen.apply(this, arguments);
- };
- XMLHttpRequest.prototype.send = function(body) {
- const handleResponse = () => {
- if (this.readyState === 4 && this.status >= 200 && this.status < 300) {
- const { _requestUrl: url, responseText: data } = this;
- if (!data) return;
- Declare.init();
- const delay = 50;
- const keywords = ["list.htm", "splitList.htm", "mergeList.htm", "searchPackage.htm"];
- if (keywords.some((u) => url.includes(u))) setTimeout(() => new Summary(url), delay);
- if (url.includes("showBatchCustoms.htm")) setTimeout(() => Declare.fillValues(), delay);
- if (url.includes("detail.htm")) setTimeout(() => new LookDetail(data), delay);
- }
- };
- this.addEventListener("readystatechange", handleResponse);
- return originalSend.apply(this, arguments);
- };
-
- })();