lowerCodeHelper

低代码平台助手

当前为 2023-12-01 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         lowerCodeHelper
// @namespace    http://tampermonkey.net/
// @version      0.1
// @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)
        }
    }
})(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", "101")
                                rtNode.setAttribute("y", "45")
                                rtNode.textContent = "RT:" + log.rt
                            }
                        }
                    })
                }
            }, 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);
            }
        });
    }
})();