MEST QRCode

美尔斯通二维码

当前为 2022-10-24 提交的版本,查看 最新版本

// ==UserScript==
// @name         MEST QRCode
// @namespace    joyings.com.cn
// @version      1.2.2
// @description  美尔斯通二维码
// @author       zmz125000
// @match       http://*/mest/*
// @icon          http://www.google.com/s2/favicons?domain=openwrt.org
// @grant        none
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.js
// @license     MIT
// ==/UserScript==

(function () {
    'use strict';

    // Your code here...
    addPrintButtons();
    window.fastPrint = true;

    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    function unsecuredCopyToClipboard(text) {
        const textArea = document.createElement("textarea");
        textArea.value = text;
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();
        try {
            document.execCommand('copy');
        } catch (err) {
            console.error('Unable to copy to clipboard', err);
        }
        document.body.removeChild(textArea);
    }

    // 添加按钮、快速复制文本
    async function addPrintButtons() {
        if ($('[role="group"]')[0]) {
            for (let elm of $('[class="custom-tree-node"]', $('[role="group"]')[0])) {
                if (!elm.hasAttribute('helper')) {
                    elm.addEventListener('click', async function () {
                        await sleep(100);
                        // 设为100条
                        while (!$('[class="el-scrollbar__view el-select-dropdown__list"]')[0]) {
                            await sleep(50);
                        }
                        $('li', $('[class="el-scrollbar__view el-select-dropdown__list"]')).last().click()
                        await sleep(100);
                        while ($('[class="el-loading-mask"]')[0] && $('[class="el-loading-mask"]')[0].getAttribute("style") == 'display: none;') {
                            await sleep(100);
                        }
                        while (!$('tbody')[0]) {
                            await sleep(100);
                        }
                        // 自动复制
                        if (!$('tbody')[0].hasAttribute('helper')) {
                            $('tbody')[0].addEventListener('click', function (e) {
                                const cell = e.target.closest('td');
                                if (cell) {
                                    let headerText = $('[class="has-gutter"]')[0].rows.item(0).cells.item(cell.cellIndex).firstChild.textContent;
                                    let sval = cell.childNodes[0].innerText;
                                    unsecuredCopyToClipboard(sval);
                                    setInput(headerText, sval);
                                }
                            });
                            $('tbody')[0].setAttribute('helper', true);
                        }
                        elm.setAttribute('helper', true);
                    })
                }
            }
        }
        if (!$('div[class="el-tabs__item is-top is-active is-closable"]:contains("自定义报表")')[0] || !$('input[placeholder="输入关键字进行过滤"]')[0]) {
            await sleep(500);
            // addPrintButtons();
        } else if (!$('button:contains("打印")')[0]) {
            let btnRow = $('button:contains("导出")')[0].parentElement;
            // var btn = document.createElement('button');
            // btn.setAttribute('id', 'printTableBtn');
            // btn.setAttribute('type', 'button');
            // btn.onclick = makeQRCode;
            // btn.appendChild(document.createTextNode('生成二维码并打印'));

            // var btn2 = document.createElement('button');
            // btn2.setAttribute('id', 'printTableBtn');
            // btn2.setAttribute('type', 'button');
            // btn2.onclick = formatAndPrint;
            // btn2.appendChild(document.createTextNode('直接打印'));

            var btn3 = document.createElement('button');
            btn3.setAttribute('type', 'button');
            btn3.onclick = generateAndPrint;
            btn3.appendChild(document.createTextNode('打印生产单'));

            var btn8 = document.createElement('button');
            btn8.setAttribute('title', '快速打印');
            btn8.setAttribute('id', 'fastPrintBtn');
            btn8.setAttribute('type', 'button');
            btn8.onclick = toggleFastPrint;
            btn8.appendChild(document.createTextNode(window.fastPrint ? "✔" : "✘"));

            btnRow.appendChild(btn3);
            btnRow.appendChild(btn8);
        }
        if (!$('button:contains("重置")')[0].hasAttribute('helper')) {
            $('button:contains("重置")')[0].addEventListener('click', function (e) {
                $('[class="el-tree-node is-expanded is-current is-focusable"]')[0].click()
            });
            $('button:contains("重置")')[0].setAttribute('helper', true);
        }
        await sleep(500);
        addPrintButtons();
    }

    function setInput(label, value) {
        if ($('label:contains(' + label + ')')[0]) {
            $('input', $('label:contains(' + label + ')')[0].nextSibling)[0].value = value;
            $('input', $('label:contains(' + label + ')')[0].nextSibling)[0].dispatchEvent(new Event('input', {
                bubbles: true
            }));
        }
    }

    function toggleFastPrint() {
        if (window.fastPrint) {
            window.fastPrint = false;
            document.getElementById("fastPrintBtn").firstChild.nodeValue = "✘";
        } else {
            window.fastPrint = true;
            document.getElementById("fastPrintBtn").firstChild.nodeValue = "✔";
        }
    }

    async function makeQRCode() {
        let bodyRows = document.querySelectorAll('[class="cell el-tooltip"]')[0].closest('table').lastChild.rows;
        const qrIndex = $('th:contains("二维码")')[0].cellIndex;
        if (!qrIndex) {
            return;
        }
        let qrCell = null;
        for (let row of bodyRows) {
            qrCell = row.cells.item(qrIndex);
            let qrDiv = $('#qrBoxDiv', qrCell)[0];
            if (qrDiv) {
                qrCell.removeChild(qrDiv);
            }
            qrDiv = document.createElement('div');
            qrDiv.setAttribute('id', 'qrBoxDiv');
            qrCell.appendChild(qrDiv);

            let str = $('div', row.cells.item(qrIndex))[0].textContent;
            new QRCode(qrDiv, {
                text: str,
                width: 96,
                height: 96
            });
        }
        while ($('img', qrCell)[0].getAttribute('style') == "display: none;") {
            await sleep(100);
        }
        formatAndPrint();
    }

    async function formatAndPrint() {
        var header = $('thead')[0].firstChild;
        var body = document.querySelectorAll('[class="cell el-tooltip"]')[0].closest('tbody').cloneNode(true);
        var bodyRows = body.rows;

        // cleanup table elements
        var tbl = document.createElement('table');

        for (let row of bodyRows) {
            // tr
            row.removeAttribute('class');
            for (let cell of row.cells) {
                // td
                cell.removeAttribute('class');
                cell.removeAttribute('rowspan');
                cell.removeAttribute('colspan');
                // td-div
                cell.firstChild.removeAttribute('class');
                cell.firstChild.removeAttribute('style');
            }
        }

        var printContents = body.innerHTML;
        var pageTemplate = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/paper-css/0.3.0/paper.css">\n<style>@page { size: A4 }</style>\n<body class="A5">\n<section class="sheet padding-10mm">\n';
        // add contents here
        pageTemplate += "<table>" + printContents + "</table>";
        pageTemplate += '\n</section>\n</body>';
        var w = window.open();
        w.document.write(pageTemplate);
        await sleep(500);
        w.print();
        // w.close();
    }

    async function getFullTable() {
        var tbody = document.createElement('table');
        let nextBodyRows = $('tr', $('tbody')[0]);
        for (let tr of nextBodyRows) {
            tbody.appendChild(tr.cloneNode(true));
        }
        var oldValue = $('div', $('tbody')[0].rows.item(0).cells.item(2))[0].textContent;
        while (!$('[class="btn-next"]')[0].getAttribute("disabled")) {
            $('[class="btn-next"]')[0].click();
            await sleep(100);
            while ($('div', $('tbody')[0].rows.item(0).cells.item(2))[0].textContent == oldValue) {
                await sleep(100);
            }
            let nextBodyRows = $('tr', $('tbody')[0]);
            for (let tr of nextBodyRows) {
                tbody.appendChild(tr.cloneNode(true));
            }
            oldValue = $('div', $('tbody')[0].rows.item(0).cells.item(2))[0].textContent;
        }
        return tbody;
    }

    // 打印生产单
    async function generateAndPrint() {
        if (!$('input', $('label:contains("订单号")')[0].nextSibling)[0].value && !$('input', $('label:contains("生产单号")')[0].nextSibling)[0].value && !$('input', $('label:contains("产品编码")')[0].nextSibling)[0].value && !$('input', $('label:contains("产品名")')[0].nextSibling)[0].value) {
            alert("未输入订单号/生产单号/产品编号/产品名,请先设置至少一项筛选条件");
            return;
        }

        var tbody = null;
        await getFullTable().then(t => {
            tbody = t;
        })

        const orderNoIndex = $('th:contains("订单号")')[0].cellIndex;
        const customerIndex = $('th:contains("客户名")')[0].cellIndex;
        const billDateIndex = $('th:contains("单据日期")')[0].cellIndex;
        const billDeliveryIndex = $('th:contains("发货日期")')[0].cellIndex;
        const productCodeIndex = $('th:contains("产品编码")')[0].cellIndex;
        const productNameIndex = $('th:contains("产品名")')[0].cellIndex;
        const productAliasIndex = $('th:contains("产品别名")')[0].cellIndex;
        const productSpecsIndex = $('th:contains("产品规格")')[0].cellIndex;
        const scdIndex = $('th:contains("生产单号")')[0].cellIndex;
        const orderQuantityIndex = $('th:contains("下单数")')[0].cellIndex;
        const processIndex = $('th:contains("工序名")')[0].cellIndex;
        const semiIndex = $('th:contains("工件名")')[0].cellIndex;
        const plannedQuantityIndex = $('th:contains("加工数")')[0].cellIndex;
        const productPlannedQuantityIndex = $('th:contains("生产数")')[0].cellIndex;
        const workshopIndex = $('th:contains("车间")')[0].cellIndex;
        // 物料
        const materialCodeIndex = $('th:contains("物料编码")')[0].cellIndex;
        const materialNameIndex = $('th:contains("物料名")')[0].cellIndex;
        const materialAliasIndex = $('th:contains("物料别名")')[0].cellIndex;
        const materialSpecsIndex = $('th:contains("物料规格")')[0].cellIndex;
        const semiSpecsIndex = $('th:contains("工件尺寸")')[0].cellIndex;
        const materialQIndex = $('th:contains("领料数")')[0].cellIndex;
        const materialUnitIndex = $('th:contains("计量单位")')[0].cellIndex;

        var bodyRows = tbody.rows;
        let oldSCD = ''
        let atable = [];
        var currentTable = null;
        for (let tr of bodyRows) {
            let cSCD = $('div', tr.cells.item(scdIndex))[0].textContent;
            if (cSCD != oldSCD) {
                currentTable = document.createElement('table');
                atable.push(currentTable);
            }
            currentTable.appendChild(tr.cloneNode(true));
            oldSCD = cSCD;
        }
        for (let t of atable) {
            let htmlContent = `${htmlTemplate}`;
            let w = null;
            let iframe = null;
            if (window.fastPrint) {
                iframe = document.createElement('iframe');
                document.body.appendChild(iframe);
                iframe.contentWindow.document.open();
                iframe.contentWindow.document.write(htmlTemplate);
                w = iframe.contentWindow;
            } else {
                w = window.open();
                w.document.write(htmlTemplate);
            }
            let map = new Map();
            let trCells = t.rows.item(0).cells;
            map.set('customerName', trCells.item(customerIndex));
            map.set('orderNo', trCells.item(orderNoIndex));
            map.set('productCode', trCells.item(productCodeIndex));
            map.set('productName', trCells.item(productNameIndex));
            map.set('ProductNameCell', trCells.item(productNameIndex));
            map.set('productAlias', trCells.item(productAliasIndex));
            map.set('productSpecs', trCells.item(productSpecsIndex));
            map.set('SCD', trCells.item(scdIndex));
            map.set('SCDCell', trCells.item(scdIndex));
            map.set('orderQuantity', trCells.item(orderQuantityIndex));
            map.set('plannedQuantity', trCells.item(productPlannedQuantityIndex));
            map.set('orderDate', trCells.item(billDateIndex));
            map.set('deliveryDate', trCells.item(billDeliveryIndex));

            // for (let item of map) {
            //    $('#' + item[0], htmlContent)[0].textContent = $('div', item[1])[0].textContent;
            // }

            // 填信息
            for (let item of map) {
                $('#' + item[0], w.document)[0].textContent = $('div', item[1])[0].textContent;
            }

            var today = new Date();
            var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
            var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
            $('#printTime', w.document)[0].textContent = date + ' ' + time;
            new QRCode($('#SCDQR', w.document)[0], {
                text: $('div', map.get('SCD'))[0].textContent,
                width: 128,
                height: 128
            });

            var tBodyRows = t.rows;
            var processTable = $('#procedureTable', w.document)[0];
            var materialTable = $('#materialTable', w.document)[0];
            var wIndex = 2;
            var mIndex = 1;
            for (let row of tBodyRows) {
                let process = $('div', row.cells.item(processIndex))[0].textContent;
                const semi = $('div', row.cells.item(semiIndex))[0].textContent;
                const plannedQuantity = $('div', row.cells.item(plannedQuantityIndex))[0].textContent;
                const workshop = $('div', row.cells.item(workshopIndex))[0].textContent;

                // 填物料表体
                let materialCode = $('div', row.cells.item(materialCodeIndex))[0].textContent;
                if (materialCode.startsWith('01-')) {
                    let materialCode = $('div', row.cells.item(materialCodeIndex))[0].textContent;
                    let materialName = $('div', row.cells.item(materialNameIndex))[0].textContent;
                    let materialAlias = $('div', row.cells.item(materialAliasIndex))[0].textContent;
                    let materialSpecs = $('div', row.cells.item(materialSpecsIndex))[0].textContent;
                    let semiSpecs = $('div', row.cells.item(semiSpecsIndex))[0].textContent;
                    let materialQ = $('div', row.cells.item(materialQIndex))[0].textContent;
                    let materialUnit = $('div', row.cells.item(materialUnitIndex))[0].textContent;
                    let tr = materialTable.insertRow(mIndex++);
                    tr.insertCell(0).innerHTML = wIndex - 1 + '.' + process;
                    tr.insertCell(1).innerHTML = materialCode;
                    tr.insertCell(2).innerHTML = materialName;
                    tr.insertCell(3).innerHTML = materialSpecs;
                    tr.insertCell(4).innerHTML = semiSpecs;
                    tr.insertCell(5).innerHTML = plannedQuantity;
                    tr.insertCell(6).innerHTML = materialQ;
                    tr.insertCell(7).innerHTML = materialUnit;
                    process = '🅐' + process;
                }

                // 填工序卡表体
                let tr = processTable.insertRow(wIndex++);
                tr.insertCell(0).innerHTML = wIndex - 2;
                tr.insertCell(1).innerHTML = process;
                let semiCell = tr.insertCell(2);
                semiCell.innerHTML = semi;
                semiCell.setAttribute('class', 'semiCell');
                tr.insertCell(3).innerHTML = plannedQuantity;
                tr.insertCell(4).innerHTML = '';
                tr.insertCell(5).innerHTML = '';
                tr.insertCell(6).innerHTML = '';
                tr.insertCell(7).innerHTML = workshop;
                // let qrCell = tr.insertCell(6);
                // var qrDiv = document.createElement('div');
                // new QRCode(qrDiv, {
                //     text: process,
                //     width: 64,
                //     height: 64
                // });
                // qrCell.appendChild(qrDiv);
            }
            await sleep(100);
            if (window.fastPrint) {
                w.print();
                w.close();
                document.body.removeChild(iframe);
            }
        }
    }

    var htmlTemplate = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/paper-css/0.3.0/paper.css">' +
        '' +
        '<body class="A4" style="height: auto;">' +
        '    <section class="sheet padding-10mm" style="height: auto;">' +
        '        <p align=center style="margin-top: -5px;"><span class=title lang=ZH-CN>车间生产任务单</span></p>' +
        '        <div align=center>' +
        '            <div id="leftbox">' +
        '                <p align=left><label>客户名: </label><span id="customerName"></span></p>' +
        '                <p align=left><label>订单号: </label><span id="orderNo"></span></p>' +
        '                <p align=left><label>产品编码: </label><span id="productCode"></span></p>' +
        '                <p align=left><label>产品名: </label><span id="productName"></span></p>' +
        '                <p align=left><label>产品别名: </label><span id="productAlias"></span></p>' +
        '                <p align=left><label>产品规格: </label><span id="productSpecs"></span></p>' +
        '                <p align=left><label>生产单号: </label><span id="SCD"></span></p>' +
        '                <p align=left><label>客户下单数: </label><span id="orderQuantity"></span></p>' +
        '                <p align=left><label>计划生产数: </label><span id="plannedQuantity"></span></p>' +
        '                <p align=left><label>订单日期: </label><span id="orderDate"></span></p>' +
        '                <p align=left><label>交货日期: </label><span id="deliveryDate"></span></p>' +
        '                <p align=left><label>打印时间: </label><span id="printTime"></span></p>' +
        '            </div>' +
        '' +
        '            <div id="rightbox">' +
        '                <table id="materialTable" style="font-size:small;">' +
        '                    <tr>' +
        '                        <th>工序</th>' +
        '                        <th>物料编号</th>' +
        '                        <th>物料名称</th>' +
        '                        <th>物料规格</th>' +
        '                        <th>开料尺寸</th>' +
        '                        <th>开料数</th>' +
        '                        <th>用量</th>' +
        '                        <th>单位</th>' +
        '                    </tr>' +
        '                </table>' +
        '                <div style="margin-top: 20px;" id="SCDQR"></div>' +
        '            </div>' +
        '        </div>' +
        '        <div style="clear: both;"></div>' +
        '        <div style="margin-top: 10px;" align=center>' +
        '            <table id="procedureTable" style="font-size:small;">' +
        '                <thead>' +
        '                    <tr>' +
        '                        <td colspan="8" style="font-size: medium;"><span>产品名: </span> <span' +
        '                                id="ProductNameCell"></span>&nbsp;' +
        '                        </td>' +
        '                </thead>' +
        '                <tfoot>' +
        '                    <tr>' +
        '                        <td colspan="8" style="font-size: medium;"><span>车间生产单号: </span><span id="SCDCell"></span>&nbsp;' +
        '                        </td>' +
        '                    </tr>' +
        '                </tfoot>' +
        '                </tr>' +
        '                <tr>' +
        '                    <th>#</th>' +
        '                    <th>工序</th>' +
        '                    <th>工序内容</th>' +
        '                    <th>数量</th>' +
        '                    <th style="min-width: 15mm;">开工数</th>' +
        '                    <th style="min-width: 15mm;">完工数</th>' +
        '                    <th style="min-width: 15mm;">生产员</th>' +
        '                    <th>车间</th>' +
        '                </tr>' +
        '            </table>' +
        '        </div>' +
        '    </section>' +
        '</body>' +
        '<style>' +
        '    @page {' +
        '        size: A4' +
        '    }' +
        '' +
        '    #leftbox {' +
        '        float: left;' +
        '        margin-top: 20px;' +
        '        margin-bottom: 40px;' +
        '        width: 35%;' +
        '    }' +
        '' +
        '    #rightbox {' +
        '        float: right;' +
        '        margin-top: 30px;' +
        '        width: 65%;' +
        '    }' +
        '' +
        '    .title {' +
        '        text-align: center;' +
        '        font-size: large;' +
        '    }' +
        '' +
        '    p {' +
        '        margin-bottom: -10px;' +
        '        font-size: 90%;' +
        '    }' +
        '' +
        '    table,' +
        '    th,' +
        '    td {' +
        '        border: 1px solid black;' +
        '        word-wrap: break-word;' +
        '    }' +
        '' +
        '    .semiCell {' +
        '        max-width: 90mm;' +
        '    }' +
        '' +
        '    table {' +
        '        page-break-inside: auto' +
        '    }' +
        '' +
        '    td {' +
        '        font-size: smaller;' +
        '    }' +
        '' +
        '    tr {' +
        '        page-break-inside: avoid;' +
        '        page-break-after: auto' +
        '    }' +
        '' +
        '    thead {' +
        '        display: table-header-group' +
        '    }' +
        '' +
        '    tfoot {' +
        '        display: table-footer-group' +
        '    }' +
        '</style>';
})();