lowerCodeHelper

低代码平台助手

Pada tanggal 01 Desember 2023. Lihat %(latest_version_link).

// ==UserScript==
// @name         lowerCodeHelper
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  低代码平台助手
// @author       Ziker
// @match        https://ops.iyunquna.com/63008/*
// @require      https://code.jquery.com/jquery-3.4.1.min.js
// @icon         https://favicon.qqsuu.cn/work.yqn.com
// @grant unsafeWindow
// @grant window.close
// @grant window.focus
// @run-at       document-body
// @noframes
// @license           AGPL License
// ==/UserScript==

window.jq = $.noConflict(true);

(function (window) {
    window.pageHelper = {
        // 等待元素可见
        async waitElementVisible(visibleTag, index, fun) {
            let node = jq(visibleTag)
            if (node === null || node[index] === null || node[index] === undefined) {
                setTimeout(() => {
                    pageHelper.waitElementVisible(visibleTag, index, fun)
                }, 500)
            } else {
                fun()
            }
        },
        getCurrentAppIndex() {
            const nodes = document.getElementsByClassName("bar-tab");
            for (let i = 0; i < nodes.length; i++) {
                if (nodes[i].className.indexOf("bar-tab-selected") > 0) {
                    return i;
                }
            }
            return -1;
        },
        getCurrentAppId() {
            const nodes = document.getElementsByClassName("tab-content-presentation-components");
            let className = nodes[this.getCurrentAppIndex()].className;
            return className.substring(className.indexOf("theia-tab-") + "theia-tab-".length);
        },
        sleep(duration) {
            return new Promise(resolve => {
                setTimeout(resolve, duration)
            })
        },
        showToast(msg, duration) {
            // 显示提示
            duration = isNaN(duration) ? 3000 : duration;
            const m = document.createElement('div');
            m.innerHTML = msg;
            m.style.cssText = "display: flex;justify-content: center;align-items: center;width:60%; min-width:180px; " +
                "background:#000000; opacity:0.98; height:auto;min-height: 50px;font-size:25px; color:#fff; " +
                "line-height:30px; text-align:center; border-radius:4px; position:fixed; top:85%; left:20%; z-index:999999;";
            document.body.appendChild(m);
            setTimeout(function () {
                const d = 0.5;
                m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
                m.style.opacity = '0';
                setTimeout(function () {
                    document.body.removeChild(m)
                }, d * 1000);
            }, duration);
        },
        copyToClipboard(text) {
            // 创建一个临时的 textarea 元素
            let textarea = document.createElement('textarea');
            // 设置 textarea 的值为要拷贝的文本内容
            textarea.value = text;
            // 将 textarea 添加到文档中
            document.body.appendChild(textarea);
            // 选中 textarea 的内容
            textarea.select();
            // 执行复制操作
            document.execCommand('copy');
            // 移除临时的 textarea 元素
            document.body.removeChild(textarea);
            this.showToast("已拷贝 " + text)
        },
        formatString(str, len, padding) {
            const diff = len - str.toString().length;
            if (diff > 0) {
                return padding.repeat(diff) + str;
            } else {
                return str;
            }
        }
    }
})(window);


(function () {
    let historyTrace = ''
    'use strict';
    jq(document).ready(function () {
        // 监听api tab变动
        waitObserve(".tabs-bar", () => {
            // 应用接口面板
            const appPanelTag = ".tab-content-presentation-components.theia-tab-" + window.pageHelper.getCurrentAppId();
            // 监听属性面板变动
            waitObserve(appPanelTag + " .p-8", () => {
                const p8 = document.querySelector(appPanelTag + " .p-8");
                const panel = p8.querySelector(".ant-form.ant-form-vertical.yqn-form");
                if (nonNull(panel) && isNull(panel.querySelector(".customScriptInfo"))) {
                    const div = document.createElement("div");
                    div.className = "customScriptInfo";
                    panel.appendChild(div)
                    // 获取当前NodeName
                    const childProcessNode = panel.querySelector("#code");
                    let nodeName = nonNull(childProcessNode) ? childProcessNode.value : p8.querySelector(".dashboard-code span").textContent
                    // 获取当前节点信息
                    getNodeInfo(nodeName, node => {
                        // 处理信息
                        const divNode = document.querySelector(appPanelTag + " .customScriptInfo");
                        // 清空显示
                        divNode.innerHTML = ""
                        // 脚本
                        if (nonNull(node.scriptId)) {
                            divNode.appendChild(createButton("脚本:" + node.scriptId, () => window.pageHelper.copyToClipboard(node.scriptId)))
                        }
                        // 入参
                        let id = node.inputScriptId;
                        const inputScriptIds = node.inputScriptIds;
                        if (nonNull(inputScriptIds)) {
                            id = nonNull(id) ? id : inputScriptIds.example;
                            id = nonNull(id) ? id : inputScriptIds.record;
                            id = nonNull(id) ? id : inputScriptIds.recordList;
                            id = nonNull(id) ? id : inputScriptIds.condition;
                            id = nonNull(id) ? id : inputScriptIds.id;
                        }
                        if (isNull(id) && nonNull(node.dslBulidData)) {
                            id = node.dslBulidData.dslScriptId;
                        }
                        if (nonNull(id)) {
                            divNode.appendChild(createButton("入参:" + id, () => window.pageHelper.copyToClipboard(id)))
                        }
                        // 条件
                        const executeScriptId = node.executeScriptId;
                        if (nonNull(executeScriptId)) {
                            divNode.appendChild(createButton("条件:" + executeScriptId, () => window.pageHelper.copyToClipboard(executeScriptId)))
                        }
                        // 校验
                        const assertScriptId = node.assertScriptId;
                        if (nonNull(assertScriptId)) {
                            divNode.appendChild(createButton("校验:" + assertScriptId, () => window.pageHelper.copyToClipboard(assertScriptId)))
                        }
                    })
                }
            })

            // 监听执行历史面板变动
            const executeHistoryBodyTag = appPanelTag + " .test-split-item.test-split-item-right .ant-table-body tbody";
            waitObserve(executeHistoryBodyTag, () => {
                const lines = document.querySelectorAll(executeHistoryBodyTag + "  .ant-table-row.ant-table-row-level-0");
                if (nonNull(lines) && isNull(lines[0].querySelector(".customer-button-div"))) {
                    const div = document.createElement("div");
                    lines[0].appendChild(div)
                    div.className = "customer-button-div";
                    div.style.display = "none"
                    getExecuteHistory(content => {
                        for (let i = 0; i < content.length; i++) {
                            const tds = lines[i].querySelectorAll("td");
                            const actionCol = tds[tds.length - 1];
                            const detailButton = actionCol.querySelectorAll("button")[0];

                            detailButton.style.display = "none"
                            actionCol.insertBefore(createButton("RT:" + content[i].rt, () => {
                                detailButton.click()
                                historyTrace = tds[3].innerText
                            }), detailButton)
                        }
                    })
                }
            })
        })

        // 监听body变动
        waitObserve("body", () => {
            // 监听执行日志流程图变动
            const processPanelTag = ".node-bpmn #canvas .bjs-container .djs-container .viewport .layer-base";
            waitObserve(processPanelTag, () => {
                const processPanel = document.querySelector(processPanelTag);
                const rtDiv = processPanel.querySelector(".customer-rt");
                if (isNull(rtDiv)) {
                    const div = document.createElement("div");
                    processPanel.appendChild(div)
                    div.className = "customer-rt";
                    div.style.display = "none"
                    getByTraceId(apiNodeLogList => {
                        for (let i = 0; i < apiNodeLogList.length; i++) {
                            const log = apiNodeLogList[i];
                            const textNode = processPanel.querySelector("[data-element-id='" + log.nodeId + "'] text");
                            if (isNull(textNode)) {
                                continue
                            }
                            const tspan = textNode.querySelector("tspan");
                            if (nonNull(tspan)) {
                                const rtNode = tspan.cloneNode(true);
                                textNode.appendChild(rtNode)
                                rtNode.setAttribute("x", "65")
                                rtNode.setAttribute("y", "15")
                                rtNode.innerHTML = window.pageHelper.formatString(log.rt, 4, '&nbsp;&nbsp;')
                            }
                        }
                    })
                }
            }, false)
        })
    })

    function nonNull(o) {
        return o !== null && o !== undefined;
    }

    function isNull(o) {
        return o === null || o === undefined;
    }

    // 等待出现并监听变化
    function waitObserve(visibleTag, fun, attributes = true) {
        window.pageHelper.waitElementVisible(visibleTag, 0, () => {
            new MutationObserver(function (mutationsList) {
                fun()
            }).observe(document.querySelector(visibleTag), {
                attributes: attributes,
                childList: true,
                subtree: true,
                characterData: true
            })
        }).then(r => {
        })
    }

    // 创建按钮
    function createButton(name, listener) {
        const button = document.createElement("button")
        button.type = "button"
        button.id = name
        button.className = "ant-btn ant-btn-link perf-tracked yqn-button yqn-link-no-padding customer-button"
        button.onclick = listener
        const span = document.createElement("span")
        span.textContent = name
        button.appendChild(span)
        return button;
    }

    // 拿流程信息
    function getNodeInfo(nodeName, fuc) {
        getNodeInfoByApiMode(0, nodeName, fuc)
    }

    const addressArr = ['', '/process', '/mq', '/job'];

    // 拿流程信息
    function getNodeInfoByApiMode(apiMode, nodeName, fuc) {
        jq.ajax({
            url: 'https://gw-ops.iyunquna.com/api/42080/api' + addressArr[apiMode] + '/details_composer?guid=6f87e073-1da1-4017-b2de-c109abcd6d123',
            method: 'POST',
            xhrFields: {
                withCredentials: true
            },
            crossDomain: true,
            contentType: 'application/json',
            data: JSON.stringify({
                "header": {
                    "xSourceAppId": "63008",
                    "guid": "6f87e073-1da1-4017-b2de-c109abcd6d123",
                    "lang": "zh",
                    "timezone": "Asia/Shanghai"
                },
                "model": {
                    "id": window.pageHelper.getCurrentAppId(),
                    "appId": new URLSearchParams(window.location.href.split('?')[1]).get('appId')
                }
            }),
            success: function (response) {
                if (response.code === 200) {
                    if (response.data === null && apiMode === 0) {
                        getNodeInfoByApiMode(apiMode + 1, nodeName, fuc)
                        getNodeInfoByApiMode(apiMode + 2, nodeName, fuc)
                        getNodeInfoByApiMode(apiMode + 3, nodeName, fuc)
                        return
                    }
                    let processDefine = JSON.parse(response.data.processDefine);
                    for (let i = 0; i < processDefine.nodes.length; i++) {
                        if (processDefine.nodes[i].code === nodeName) {
                            fuc(processDefine.nodes[i])
                            break
                        }
                    }
                }
            },
            error: function (xhr, status, error) {
                console.log('Request failed:', error);
            }
        });
    }

    // 拿历史执行数据
    function getExecuteHistory(fuc) {
        jq.ajax({
            url: 'https://gw-ops.iyunquna.com/api/42086/apiLog/list?guid=c74610c3-b840-446f-a452-f678b32a39e8',
            method: 'POST',
            xhrFields: {
                withCredentials: true
            },
            crossDomain: true,
            contentType: 'application/json',
            data: JSON.stringify({
                "header": {
                    "xSourceAppId": "63008",
                    "guid": "6f87e073-1da1-4017-b2de-c109abcd6d123",
                    "lang": "zh",
                    "timezone": "Asia/Shanghai"
                },
                "model": {
                    "apiId": window.pageHelper.getCurrentAppId(),
                    "appId": new URLSearchParams(window.location.href.split('?')[1]).get('appId')
                }
            }),
            success: function (response) {
                if (response.code === 200 && nonNull(response.data) && nonNull(response.data.content)) {
                    fuc(response.data.content)
                }
            },
            error: function (xhr, status, error) {
                console.log('Request failed:', error);
            }
        });
    }

    const apiType = ['api', 'process', 'mq', 'job'];

    // 拿 trace 执行数据
    function getByTraceId(fuc) {
        return getByTraceIdByApiMode(0, fuc)
    }

    // 拿 trace 执行数据
    function getByTraceIdByApiMode(apiMode, fuc) {
        jq.ajax({
            url: 'https://gw-ops.iyunquna.com/api/42086/apiLog/getByTraceId?guid=3862879a-b379-4171-9644-289ee637dae0',
            method: 'POST',
            xhrFields: {
                withCredentials: true
            },
            crossDomain: true,
            contentType: 'application/json',
            data: JSON.stringify({
                "header": {
                    "xSourceAppId": "63008",
                    "guid": "6f87e073-1da1-4017-b2de-c109abcd6d123",
                    "lang": "zh",
                    "timezone": "Asia/Shanghai"
                },
                "model": {
                    "appId": new URLSearchParams(window.location.href.split('?')[1]).get('appId'),
                    "env": "qa4",
                    "traceIdLike": historyTrace,
                    "apiId": window.pageHelper.getCurrentAppId(),
                    "testCaseId": null,
                    "apiTypeCode": apiMode === 0 ? "api" : apiType[apiMode]
                }
            }),
            success: function (response) {
                if (response.code === 200 && nonNull(response.data) && nonNull(response.data.apiNodeLogList) && response.data.apiNodeLogList.length !== 0) {
                    fuc(response.data.apiNodeLogList)
                } else if (apiMode === 0) {
                    getByTraceIdByApiMode(1, fuc)
                    getByTraceIdByApiMode(2, fuc)
                    getByTraceIdByApiMode(3, fuc)
                }
            },
            error: function (xhr, status, error) {
                console.log('Request failed:', error);
            }
        });
    }
})();