CMA / 淘宝买家订单导出

// ==UserScript==
// @name         淘宝买家订单导出
// @namespace    http://tampermonkey.net/
// @version      0.16
// @description  基于Greasy Fork上的一个订单管理脚本,修复了bug使得对于淘宝订单的导出功能重新可用。
// @author       CMA
// @grant        none
// @include      https://buyertrade.taobao*
// @include      https://trade.taobao*
// @include      https://trade.tmall*
// @require      https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js
// @license      MIT
// ==/UserScript==


const tbOrderListRe = /(http|https):\/\/buyertrade\.taobao.*?\/trade/g;
const tbOrderDetailRe = /(http|https):\/\/trade\.taobao.*?\/trade/g;
const tmOrderDetailRe = /(http|https):\/\/trade\.tmall.*?\/detail/g;

function addButton(element, onclickFunc, value = "按钮", width = "60px", height = "60px") {
    const button = document.createElement("input");
    button.type = "button";
    button.value = value;
    button.style.height = height;
    button.style.width = width;
    button.style.align = "center";
    button.style.marginBottom = "10px";
    button.style.marginLeft = "250px";
    button.style.color = "white";
    button.style.background = "#409EFF";
    button.style.border = "1px solid #409EFF";

    button.onclick = function () {
        onclickFunc();
    }

    element.appendChild(button);
    element.insertBefore(button, element.childNodes[0]);
}

if (tbOrderListRe.exec(document.URL)) {
    const J_bought_main = document.getElementById("J_bought_main");
    addButton(J_bought_main, addCurrentPageOrdersToList, "添加本页订单", "160px");
    addButton(J_bought_main, exportOrders, "导出订单", "160px");

}

function exportToCsv(header, data, filename) {
    let rows = "";
    let row = header.join(",");
    rows += row + "\n";

    _.forEach(data, value => {
        rows += _.replace(value.join(","), '#', '@') + "\n";
    })

    let blob = new Blob(["\ufeff" +rows],{type: 'text/csv;charset=utf-8;'});
    let encodedUrl = URL.createObjectURL(blob);
    let url = document.createElement("a");
    url.setAttribute("href", encodedUrl);
    url.setAttribute("download", filename + ".csv");
    document.body.appendChild(url);
    url.click();
}

let orderList = {}
function addCurrentPageOrdersToList() {
    const orders = document.getElementsByClassName("js-order-container");

    for (let order of orders) {

        let items = processOrder(order);

        if (!items) {
            continue;
        }

        _.forEach(items, (value, key) => {
            orderList[key] = value;
        })
    }
}

function exportOrders() {

    var header = ["订单号", "下单日期", "商品明细", "商品链接", "单价", "数量", "实付款", "状态"];

    exportToCsv(header, orderList, "淘宝订单导出")
}


function processOrder(order) {

    let output = {};
    let content = order.textContent;
    let pattern = /(\d{4}-\d{2}-\d{2})订单号: ()/;
    let result = pattern.exec(content);

    if (!result) {
        console.log('暂未发现订单!');
    }

    const date = result[1];
    const id = order.querySelector("div[data-id]").getAttribute("data-id");

    let index = 0;

    while (true) {

        let productPrefix = ".0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$0.0.1.0.0.1";
        let pricePrefix = ".0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$1.0.1.1";
        let countPrefix = ".0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$2.0.0";
        let actualPayPrefix = ".0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$4.0.0.2.0.1";
        let statusPrefix = ".0.7:$order-" + id + ".$" + id + ".0.1:1:0.$" + index + ".$5.0.0.0";

        let productQuery = order.querySelector("span[data-reactid='" + productPrefix + "']");
        let priceQuery = order.querySelector("span[data-reactid='" + pricePrefix + "']");
        let countQuery = order.querySelector("p[data-reactid='" + countPrefix + "']");
        let actualPayQuery = order.querySelector("span[data-reactid='" + actualPayPrefix + "']");
        let itemUrlQuery = order.querySelector("a[href]");

        if (countQuery === null || productQuery === null || priceQuery === null) {
            break;
        }

        let price = priceQuery.textContent;
        let count = countQuery.textContent;

        if (actualPayQuery != null) {
            var actualPay = actualPayQuery.textContent;
        }

        let itemUrl = itemUrlQuery.href

        if (index === 0) {
            let statusQuery = order.querySelector("span[data-reactid='" + statusPrefix + "']");
            var status = statusQuery.textContent;
        }

        index++;

        output[id + index] = [
            id,
            date,
            productQuery.textContent.replace(/,/g,","),
            itemUrl,
            parseFloat(price),
            count,
            actualPay,
            status,
        ]
    }

    return output;
}