// ==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);
};
})();