lcap_tools

提供一些网页小工具,低代码开发专用

当前为 2024-07-25 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         lcap_tools
// @namespace    http://tampermonkey.net/
// @version      0.1.9
// @description  提供一些网页小工具,低代码开发专用
// @author       yuan longhui
// @match        *://*/*lcap*
// @match        *://*/*uac*
// @match        *://*/*ucs*
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAbCAYAAACJISRoAAAABHNCSVQICAgIfAhkiAAAAQtJREFUSInt1c1Kw0AUhuFTF8kFTJnAFFwKYrHQUjE0Fq2iOxG8Bn/vQ8SbEMX+oLhQ9+raXom9g0lI8roQBDdmFi0q5FsOfOdZDIdTAZAZZ27WQImUyC8ju3v7Ug1q0tva+fZ+dn4h1aAmYacreZ7/PISCPL+8orRBacPbeAyAtZaFxTpKG27v7otGUIgAbGxuo7Th4OgEgMFwhNKGVjskTdPpIA+PTyhtCMw875MJ671PtD8YudTdkCzLWFmNUNpweHyK0oZGs02SJNNDAG76w6+/UdpweXXtWnVH4jim3mihtGFpuYm11hlx3hPP86S7FomISNQJxfd91+ofWcZ/g1SgPL8lUiIF+QCIeCJE+P0wYgAAAABJRU5ErkJggg==
// @grant        GM_cookie
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// ==/UserScript==

(function () {
    'use strict';
    GM_addStyle(
        `.y-panel {
            width: 150px;
            display: flex;
            flex-direction: column;
            position: fixed;
            top: 32px;
            right: -150px;
            background-color: #a1d4e2;
            border-radius: 3px;
            transition: all 0.3s;
            cursor: pointer;
            z-index: 9999999999;
          }
        .y-panel:before {
            width: 24px;
            height: 48px;
            position: absolute;
            top: calc(50% - 24px);
            left: -24px;
            background-color: #a1d4e2;
            border-radius: 48px 0px 0px 48px;
            border: 1px solid #5ac6aa;
            border-right: none;
            content: \"\";
            opacity: 0.8;
            cursor: pointer;
            z-index: 9999999999;
        }
        .y-panel:hover {
            right: 0;
        }
        .y-panel > .y-panel-btn {
            position: relative;
            border: 1px solid #fff;
            border-radius: 3px;
            cursor: pointer;
            font-size: 12px;
            font-weight: bold;
            margin: 4px 5px;
            padding: 2px 5px;
            text-align: center;
            user-select: none;
            background-color: #f0f0f0;
            z-index: 9999999999;
        }
        .y-panel-btn:hover {
            box-shadow: 0 0 5px rgba(0, 0, 0, 0.8);
        }
        .y-panel-input {
            height: 24px;
            margin: 5px 4px;
            border-radius: 3px;
        }
        .y-panel ::-webkit-input-placeholder {
            color: rgba(0, 0, 0, 0.5);
            padding-left: 5px;
            font-size: 12px;
        }
        .y-panel-btn_delete {
            padding: 0px 3px;
            color: #000;
            font-size: 10px;
            position: absolute;
            right: 3px;
            top: 1px;
            background-color: #88befc;
        }
        .y-panel-btn_delete:hover {
            color: #fff;
            background-color: #F3629C;
        }`
    );

    /**
     * type BUTTON_TYPE = {
     *   text: string
     *   onclick: () => void
     *   type?: 'function' | 'normal'
     *   password?: string
     *   isStored?: boolean
     * }
     */

    // 可以在这里配置常用工号,例如:
    const name_map = ['袁龙辉10331290', '孟香君00268638', '郭绍云10286708']
    //const name_map = []
    // 本地存储的工号
    const stored_name_map = GM_listValues().map(item => GM_getValue(item))

    function register(btns) {
        const yPanel = document.querySelector('.y-panel')
        if (yPanel) {
            yPanel.parentNode.removeChild(yPanel)
        }
        const container = document.createElement("div");
        container.className = "y-panel";
        document.body.appendChild(container);
        // 生成基本功能的按钮
        generateBasicBtn(btns, container)
        // 添加跳转按钮
        addJumpBtn(container)
        // 添加创建员工信息输入框
        generateEmpInfoInput(container)
    };

    // 功能1 点击按钮清空cookie并刷新页面
    function func_clearCookies() {
        const cookies = document.cookie.split(';').map(cookie => cookie.trim().split('=')[0]);
        cookies.forEach(item => {
            GM_cookie.delete({ name: item });
        })
        location.reload();
    }

    // 功能2 切换cookie的语言
    function func_changeLang() {
        const currentUrl = new URL(window.location.href)
        const params = currentUrl.searchParams
        if (params.get('lang')) {
            params.set('lang', params.get('lang') === 'zh' ? 'en' : 'zh')
            window.history.replaceState({}, '', currentUrl)
        }
        const cookies = document.cookie.split(';').map(cookie => cookie.trim());
        cookies.forEach(cookie => {
            const [name, value] = cookie.trim().split('=')
            if (name.includes('Language')) {
                GM_cookie.delete({ name });
                GM.cookie.set({
                    name,
                    value: value === 'zh_CN' ? 'en_US' : 'zh_CN'
                })
            }
        })
        location.reload();
    }

    // 功能3 登录
    function func_login(empInfo, password = '1') {
        const empNo = empInfo.match(/\d+/)[0] // 取出工号
        const empNoInput = document.getElementById('input-loginname')
        if (!empNoInput) return
        const passwordInput = document.getElementById('input-password')
        const login_btn = document.getElementsByClassName("el-button login-btn el-button--primary")[0]
        var event = new Event('input', {
            bubbles: true,
            cancelable: true,
        });
        empNoInput.value = empNo
        empNoInput.dispatchEvent(event);
        passwordInput.value = password
        passwordInput.dispatchEvent(event);
        login_btn.click()
    }

    // 在name新增删除后刷新面板
    function util_refreshPanel() {
        const current_stored_name_map = GM_listValues().map(item => GM_getValue(item))
        const current_btn_map = getBasicBtnMap(current_stored_name_map)
        register(current_btn_map)
    }

    // 添加跳转按钮
    function addJumpBtn(container) {
        // 主机名、端口号、路径、查询参数、hash
        const { hostname, port, pathname, searchParams, hash } = new URL(window.location.href);
        // 获取url中#之后的内容
        const hashParts = hash.slice(2).split('/')
        // 获取url中的app、bizObject、page
        const hashObject = {
            app: hashParts.indexOf('app') !== -1 ? hashParts[hashParts.indexOf('app') + 1] : null,
            bizObject: hashParts.indexOf('bizObject') !== -1 ? hashParts[hashParts.indexOf('bizObject') + 1] : null,
            page: hashParts.indexOf('page') !== -1 ? hashParts[hashParts.indexOf('page') + 1] : null
        }
        const host = port ? `${hostname}:${port}` : hostname
        // 微服务信息 如:zte-paas-lcap-frontendcli
        const microServiceInfo = pathname.slice(1).split('/')[0]
        // 设计态的微服务路径
        const design_path = microServiceInfo.includes('frontendrenderdemo')
            ? microServiceInfo.replace('frontendrenderdemo', 'frontendcli')
            : microServiceInfo
        // 布局、实体、应用主页url
        const layoutUrl = `https://${host}/${design_path}/layout-designer.html?lang=zh`
        const entityUrl = `https://${host}/${design_path}/entity-designer.html?lang=zh`
        const mainPageUrl = `https://${host}/${design_path}/index.html#/platform/applicationdevelopment`
        // 当前为布局设计器的运行态
        if (searchParams.get('bizObject') && searchParams.get('bizObject') !== 'null') {
            generateJumpBtn([
                {
                    text: 'to->当前布局',
                    title: '适用于表单页,列表页跳转之后需要切换一下布局',
                    toUrl: `${layoutUrl}${hash}/bizObject/${searchParams.get('bizObject')}`
                },
                {
                    text: 'to->当前实体',
                    toUrl: `${entityUrl}#/app/${hashObject.app}/bizObject/${searchParams.get('bizObject')}`
                }
            ], container)
        }
        // 当前为自定义页面的运行态
        else if (searchParams.get('bizObject') === 'null') {
            generateJumpBtn([
                {
                    text: 'to->当前页面设计',
                    toUrl: `${layoutUrl}#/app/${hashObject.app}/page/${hashObject.page}`
                }
            ], container)
        }
        // 当前为布局设计器的设计态
        else if (pathname.includes(`${design_path}/layout-designer.html`) && hashObject.bizObject) {
            generateJumpBtn([
                {
                    text: 'to->当前实体',
                    toUrl: `${entityUrl}#/app/${hashObject.app}/bizObject/${hashObject.bizObject}`
                }
            ], container)
        }
        // 当前为设计器的设计态或者运行态
        if (hashObject.app) {
            generateJumpBtn([
                { text: 'to->应用主页', toUrl: `${mainPageUrl}/${hashObject.app}` }
            ], container)
        }
        // 当前不是本地环境,需要跳转本地环境调试
        if (hostname !== 'local.zte.com.cn'
            && (pathname.includes('zte-paas-lcap-frontendcli')
                || pathname.includes('zte-paas-lcap-frontendrenderdemo')
                || pathname.includes('zte-paas-lcap-promgr')
                || pathname.includes('zte-paas-lcap-promc'))) {
            let url = new URL(window.location.href)
            url.host = 'local.zte.com.cn';
            if (pathname.includes('zte-paas-lcap-frontendcli')) {
                url.host += ':8080';
            } else if (pathname.includes('zte-paas-lcap-frontendrenderdemo')) {
                url.host += ':8081';
            } else if (pathname.includes('zte-paas-lcap-promgr')) {
                url.host += ':8086';
            } else if (pathname.includes('zte-paas-lcap-promc')) {
                url.host += ':8082';
            }
            generateJumpBtn([
                { text: '切换到本地调试', toUrl: url.toString() }
            ], container)
        }
    }

    // 创建基本的按钮(登录账号按钮等)
    function generateBasicBtn(btns, container) {
        btns.forEach(btn => {
            const button = document.createElement("button");
            button.textContent = btn.text;
            button.className = "y-panel-btn";
            button.onclick = btn.onclick;
            container.appendChild(button);
            if (btn.isStored) {
                const delete_btn = document.createElement("button");
                delete_btn.textContent = 'x';
                delete_btn.className = 'y-panel-btn_delete';
                delete_btn.onclick = (e) => {
                    e.stopPropagation()
                    GM_deleteValue(btn.text)
                    util_refreshPanel()
                };
                button.appendChild(delete_btn);
            }
            if (btn.password) {
                button.title = btn?.password
            }
            button.style.backgroundColor = btn.type === 'function' && '#5ac6aa'
        });
    }

    // 创建额外的按钮(跳转按钮等)
    function generateJumpBtn(btns, container) {
        btns.forEach(btn => {
            const button = document.createElement("button");
            button.textContent = btn.text;
            button.className = "y-panel-btn";
            button.style.backgroundColor = '#5ac6aa'
            button.onclick = () => {
                if (btn.toUrl) {
                    // 不能使用window.open,低代码项目的代码里有判断是否是通过这个api打开的页面的判断逻辑,会导致接口报错(-_-)
                    const a = document.createElement('a');
                    a.href = btn.toUrl;
                    a.target = '_blank';
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                }
            };
            if (btn.title) {
                button.title = btn.title
            }
            container.appendChild(button);
        })
    }

    // 创建员工信息输入框
    function generateEmpInfoInput(container) {
        const empInfo_input = document.createElement("input");
        empInfo_input.className = 'y-panel-input'
        empInfo_input.placeholder = '输入姓名+工号, 回车~'
        container.appendChild(empInfo_input);
        empInfo_input.addEventListener('keydown', (event) => {
            if (event.key === 'Enter') {
                // TODO 校验格式
                GM_setValue(empInfo_input.value, empInfo_input.value)
                func_login(empInfo_input.value)
                util_refreshPanel()
            }
        });
    }

    // 构建基础按钮列表(基础功能+姓名)
    function getBasicBtnMap(stored_name_map) {
        return [
            {
                text: '清空Cookie并刷新',
                type: 'function',
                onclick: () => func_clearCookies()
            },
            {
                text: '切换cookie的语言',
                type: 'function',
                onclick: () => func_changeLang()
            },
            // 可以通过修改func_login的参数,添加自定义的工号和密码
            // {
            //     text: '袁龙辉10331290',
            //     password: '1',
            //     onclick: () => func_login('袁龙辉10331290', '1')
            // },
            ...name_map.map(name => {
                return {
                    text: name,
                    password: '1',
                    onclick: () => func_login(name)
                }
            }),
            ...stored_name_map.map(name => {
                return {
                    text: name,
                    isStored: true,
                    password: '1',
                    onclick: () => func_login(name)
                }
            })
        ]
    }

    // 入口函数
    (function init() {
        const initial_btn_map = getBasicBtnMap(stored_name_map)
        register(initial_btn_map)
    })()

})();