Greasy Fork is available in English.

Temu Enhancement

给temu半托管订单页面增加复制订单号后八位、添加备注的功能.

// ==UserScript==
// @name         Temu Enhancement
// @namespace    http://noobbei.top
// @version      1.5.1
// @description  给temu半托管订单页面增加复制订单号后八位、添加备注的功能.
// @author       noobbei
// @match        https://agentseller.temu.com/mmsos/orders*
// @grant        GM_setClipboard
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    let toastQueue = []; // 用来存放待显示的toast消息
    let isToastShowing = false; // 标志当前是否有toast正在显示

    const toastDuration = 3000; // toast显示时长
    const columnNum = 1; // 自定义列序号

    const style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = `
        .toast {
            visibility: hidden;
            min-width: 250px;
            margin-left: -125px;
            background-color: #333;
            color: #fff;
            text-align: center;
            border-radius: 5px;
            padding: 16px;
            position: fixed;
            z-index: 1;
            left: 50%;
            top: 100px;
            font-size: 17px;
        }

        .toast.show {
            visibility: visible;
            -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
            animation: fadein 0.5s, fadeout 0.5s 2.5s;
        }
        button {
            background-color: green;
            color: white;
            border: none;
            padding: 5px 10px;
            margin-top: 5px;
            cursor: pointer;
        }
        button.clear {
            background-color: red;
            margin-left: 5px;
        }
    `;
    document.head.appendChild(style);

    // 创建toast容器
    const toastElem = document.createElement('div');
    toastElem.className = 'toast';
    document.body.appendChild(toastElem);

    // 显示Toast提示
    function showToast(message) {
        // 将消息添加到队列中
        toastQueue.push(message);

        // 如果已经有toast正在显示,就返回,等待当前toast完成显示
        if (isToastShowing) {
            return;
        }

        // 显示队列中的第一个消息
        showNextToast();
    }

    function showNextToast() {
        // 检查队列是否为空
        if (toastQueue.length === 0) {
            isToastShowing = false;
            return;
        }

        // 标记为正在显示toast
        isToastShowing = true;

        // 从队列中取出第一个消息
        // 设置并显示toast消息
        toastElem.textContent = toastQueue.shift();
        toastElem.className = 'toast show';

        // 设置定时器,在3秒后隐藏toast并显示下一个消息
        setTimeout(() => {
            toastElem.className = toastElem.className.replace('show', '');
            // 在隐藏动画完成后显示下一个toast
            setTimeout(() => {
                showNextToast();
            }, 500); // 假设 fadeout 动画持续0.5秒
        }, toastDuration);
    }

    // 添加备注信息表头
    function addRemarksColumnHeader() {
        const tableHeaderRow = document.querySelector('tr[data-testid="beast-core-table-header-tr"]');
        if (tableHeaderRow) {
            const newTh = document.createElement('th');
            newTh.setAttribute('data-testid', 'beast-core-table-th');
            newTh.className = 'TB_th_123 TB_cellTextAlignLeft_123';
            newTh.innerHTML = '<span>备注信息</span>';

            tableHeaderRow.insertBefore(newTh, tableHeaderRow.children[columnNum]);
        }
    }

    // 添加备注信息输入框到每一行
    function addRemarksColumn() {
        const tableRows = document.querySelectorAll('tr[data-testid="beast-core-table-body-tr"]');
        tableRows.forEach(row => {
            if (!row.querySelector('td[data-testid="remarks-td"]')) {
                const newTd = document.createElement('td');
                newTd.setAttribute('data-testid', 'remarks-td');
                newTd.className = 'TB_td_123 TB_cellTextAlignLeft_123 TB_cellVerticalAlignMiddle_123';

                const textArea = document.createElement('textarea');
                textArea.placeholder = '输入备注信息';
                textArea.rows = 3;
                textArea.style.width = '100%';
                textArea.style.boxSizing = 'border-box';
                textArea.style.resize = 'vertical'; // 允许垂直调整大小

                const saveButton = document.createElement('button');
                saveButton.textContent = '保存';

                const clearButton = document.createElement('button');
                clearButton.textContent = '清除';
                clearButton.className = 'clear';

                const orderDiv = row.querySelector('._14UExBi_').querySelector('div:not(._366FCNFx)'); // 假设订单号在第一列
                const orderId = orderDiv ? orderDiv.textContent.trim() : '';

                saveButton.addEventListener('click', () => {
                    const note = textArea.value;
                    if (note) {
                        // 提取PO编号后8位并添加字母P
                        const expiryDate = new Date();
                        showToast(orderId + '=' + expiryDate)
                        expiryDate.setDate(expiryDate.getDate() + 20);
                        const data = {
                            note: note,
                            expiry: expiryDate.getTime()
                        };
                        localStorage.setItem(orderId, JSON.stringify(data));
                        showToast('备注已保存');
                    } else {
                        showToast('请输入备注信息');
                    }
                });

                // 清除按钮点击事件
                clearButton.addEventListener('click', () => {
                    textArea.value = ''; // 清空文本域

                    // 删除本地存储中的数据
                    localStorage.removeItem(orderId);
                    showToast('备注已清除');

                });

                newTd.appendChild(textArea);
                newTd.appendChild(saveButton);
                newTd.appendChild(clearButton);
                row.insertBefore(newTd, row.children[columnNum]);

                // 加载保存的备注信息
                const savedData = localStorage.getItem(orderId);
                if (savedData) {
                    const {note} = JSON.parse(savedData);
                    textArea.value = note;
                }
            }
        });
    }

    function addCopySvg(target) {
        // 提取PO编号后8位并添加字母P
        const poDiv = target.querySelector('div:not(._366FCNFx)');
        const poText = poDiv ? poDiv.textContent.trim() : '';
        const newPoText = 'P' + poText.slice(-8);
        if (!newPoText) return; // 如果没有找到PO编号,则不继续

        // 检查SVG是否已经添加
        if (target.querySelector('.custom-svg-container')) return;

        // 添加SVG到目标元素
        const existingSvgDiv = target.querySelector('._366FCNFx');
        if (existingSvgDiv) {
            let svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            svgElement.style.marginLeft = '8px';
            svgElement.setAttribute('viewBox', '0 0 1024 1024');
            svgElement.setAttribute('width', '1em');
            svgElement.setAttribute('height', '1em');
            svgElement.setAttribute('role', 'img');
            svgElement.setAttribute('class', 'dqraW_jf');
            svgElement.setAttribute('fill', 'currentColor');
            svgElement.innerHTML = '<path d="M768 219.4c60.6 0 109.7 49.1 109.7 109.7l0 512c0 60.6-49.1 109.7-109.7 109.8l-438.9 0c-60.6 0-109.7-49.1-109.7-109.8l0-512c0-60.6 49.1-109.7 109.7-109.7l438.9 0z m0 87.8l-438.9 0c-12.1 0-21.9 9.8-21.9 21.9l0 512c0 12.1 9.8 21.9 21.9 22l438.9 0c12.1 0 21.9-9.8 21.9-22l0-512c0-12.1-9.8-21.9-21.9-21.9z m-182.9-277.9c24.2 0 43.9 19.6 43.9 43.8 0 24.2-19.6 43.9-43.9 43.9l-365.7 0c-56.6 0-102.4 45.8-102.4 102.4l0 548.6c0 24.2-19.6 43.9-43.9 43.9-24.2 0-43.9-19.6-43.8-43.9l0-548.6c0-105 85.1-190.2 190.1-190.1z"></path>';

            svgElement.addEventListener('click', () => {
                GM_setClipboard(newPoText);
                showToast('复制成功: ' + newPoText);
            });

            let svgDiv = document.createElement('div');
            svgDiv.setAttribute('class', 'custom-svg-container');
            svgDiv.setAttribute('title', `复制 【${newPoText}】`);
            svgDiv.appendChild(svgElement);

            existingSvgDiv.appendChild(svgDiv);
        }
    }

    // 增加列宽
    function insertColIntoColgroup() {
        const colgroup = document.querySelector('colgroup');
        if (colgroup) {
            const newCol = document.createElement('col');
            newCol.style.width = '200px';

            colgroup.insertBefore(newCol, colgroup.children[1]);
        }
    }

    function main() {
        insertColIntoColgroup();
        addRemarksColumnHeader();
        addRemarksColumn();

        document.querySelectorAll('._14UExBi_').forEach(addCopySvg);


    }

    // 监听表格的变化
    const tableBody = document.querySelector('tbody[data-testid="beast-core-table-body-tbody"]');
    if (tableBody) {
        const observer = new MutationObserver(mutations => {
            for (const mutation of mutations) {
                if (mutation.type === 'childList') {
                    main();
                }
            }
        });

        observer.observe(tableBody, {childList: true, subtree: true});
    }

    // 等待DOM加载完成后运行初始化函数
    window.addEventListener('load', main);

})();