Archery Dynamic DB Name Setter

插入 custom-db-selector 并动态设置 db_name

// ==UserScript==
// @name         Archery Dynamic DB Name Setter
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  插入 custom-db-selector 并动态设置 db_name
// @license      MIT
// @match        http://archery.dachensky.com/sqlquery/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // 数据库映射配置
    const dbMapping = {
        "skg_wt": {
            instanceName: "千聊工具业务库-只读",
            dbName: "skg_wt"
        },
        "coupon": {
            instanceName: "otherDB业务库-只读",
            dbName: "coupon"
        },
        "ql_comment": {
            instanceName: "otherDB业务库-只读",
            dbName: "ql_comment"
        },
        "ql_ops_weapp": {
            instanceName: "otherDB业务库-只读",
            dbName: "ql_ops_weapp"
        },
        "ql_pay": {
            instanceName: "otherDB业务库-只读",
            dbName: "ql_pay"
        },
        "ql_speak": {
            instanceName: "otherDB业务库-只读",
            dbName: "ql_speak"
        },
        "ql_unity": {
            instanceName: "otherDB业务库-只读",
            dbName: "ql_unity"
        },
        "qlchat_crm": {
            instanceName: "otherDB业务库-只读",
            dbName: "qlchat_crm"
        },
        "qlchat_bigdata_feedback": {
            instanceName: "大数据bigdata-feedback库-只读",
            dbName: "qlchat_bigdata_feedback"
        },
        "ql_censor": {
            instanceName: "审核数据库[ql_censor]-只读",
            dbName: "ql_censor"
        },
        "mongo_qlchat": {
            instanceName: "千聊工具-mongodb数据库[qlchat]-只读",
            dbName: "qlchat"
        },
    };

    // 插入选择器
    function insertSelector() {
        const instanceGroup = document.querySelector('#instance_name')?.closest('.form-group');
        if (!instanceGroup || document.getElementById('custom-db-selector')) return;

        // 创建选择器
        const selector = document.createElement('select');
        selector.id = 'custom-db-selector';
        selector.style.marginBottom = '10px';
        selector.className = 'form-control';
        selector.innerHTML = `
       <option value="">请选择数据库</option>
       <option value="skg_wt">skg_wt</option>
       <option value="ql_pay">ql_pay</option>
       <option value="qlchat_crm">qlchat_crm</option>
       <option value="ql_unity">ql_unity</option>
       <option value="qlchat_bigdata_feedback">qlchat_bigdata_feedback</option>
       <option value="ql_ops_weapp">ql_ops_weapp</option>
       <option value="ql_speak">ql_speak</option>
       <option value="ql_censor">ql_censor</option>
       <option value="ql_comment">ql_comment</option>
       <option value="coupon">coupon</option>
       <option value="mongo_qlchat">qlchat</option>
    `;

        // 插入选择器到目标位置
        instanceGroup.parentNode.insertBefore(selector, instanceGroup);

        // 页面加载时,设置上一次记录的值
        const lastSelectedValue = localStorage.getItem('customDbSelectorValue');
        if (lastSelectedValue && dbMapping[lastSelectedValue]) {
            selector.value = lastSelectedValue;
            setInstanceName(dbMapping[lastSelectedValue].instanceName);
        }

        // 监听选择器变化
        selector.addEventListener('change', function () {
            const selectedValue = this.value;
            if (dbMapping[selectedValue]) {
                setInstanceName(dbMapping[selectedValue].instanceName);
                localStorage.setItem('customDbSelectorValue', selectedValue); // 记录选择器的值
            }
        });
    }

    // 设置 instance_name
    function setInstanceName(instanceName) {
        const instanceSelect = document.querySelector('#instance_name');
        if (instanceSelect) {
            const instanceOptions = instanceSelect.querySelectorAll('option');
            instanceOptions.forEach(option => {
                if (option.textContent === instanceName) {
                    instanceSelect.value = option.value;
                    instanceSelect.dispatchEvent(new Event('change', { bubbles: true }));
                }
            });
        }
    }

    // 设置 db_name
    function setDbName(dbName) {
        const dbSelect = document.querySelector('#db_name');
        if (dbSelect) {
            const dbOptions = dbSelect.querySelectorAll('option');
            dbOptions.forEach(option => {
                if (option.value === dbName) {
                    dbSelect.value = option.value;
                    dbSelect.dispatchEvent(new Event('change', { bubbles: true }));
                }
            });
        }
    }

    // 使用 MutationObserver 监听 `db_name` 父节点的变化
    function observeDbNameChanges() {
        const dbGroup = document.querySelector('#db_name')?.closest('.form-group');
     
        if (dbGroup) {
            let timeoutId; // 用于防抖处理
            let lastSelectedValue = null; // 记录上一次选择器的值

            const observer = new MutationObserver(() => {
             
                clearTimeout(timeoutId); // 清除之前的定时器
                timeoutId = setTimeout(() => {
                    const selectedValue = document.getElementById('custom-db-selector')?.value;

                    // 只有当选择器的值发生变化时才执行设置
                    if (selectedValue !== lastSelectedValue) {
                        lastSelectedValue = selectedValue; // 更新记录的值

                        if (dbMapping[selectedValue]) {
                            const newDbName = dbMapping[selectedValue].dbName;

                            // 设置 db_name 的值
                            setDbName(newDbName);
                        }
                    }
                }, 200); // 防抖时间设置为200ms
            });

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

    function handleAceEditorPersistence() {
        const editor = ace.edit("sql_content_editor"); // 获取 Ace Editor 实例
        const storageKey = 'aceEditorContent';

        // 页面加载时,自动填写上次记录的内容
        const savedContent = localStorage.getItem(storageKey);
        
        if (savedContent !== null) {
            editor.setValue(savedContent, -1); // 使用 Ace Editor 的 setValue 方法设置内容
        }

        // 监听内容变化事件,实时保存内容到 localStorage
        editor.getSession().on('change', () => {
            const currentContent = editor.getValue(); // 获取当前编辑器内容
            localStorage.setItem(storageKey, currentContent);
        });
    }

    // 记录上一次执行的 SQL
    let lastExecutedSQL = '';
    // 初始化功能
    function initSQLExecution() {
        const sqlButton = document.getElementById('btn-sqlquery');
        const sqlEditor = ace.edit("sql_content_editor"); // 获取 Ace Editor 实例

        if (!sqlButton || !sqlEditor) return;

        // 监听 SQL 查询按钮点击事件
        sqlButton.addEventListener('mousedown', () => {
            let selectedSQL = sqlEditor.session.getTextRange(sqlEditor.getSelectionRange()).trim();
            let currentSQL = selectedSQL || sqlEditor.getValue().split(';')[0].trim(); // 如果没有选中 SQL,则取第一条

            console.log('currentSql', currentSQL);
            if (currentSQL !== lastExecutedSQL) {
                // 如果 SQL 不一样,新增 tab 页面
                tab_add();
                lastExecutedSQL = currentSQL; // 更新记录的 SQL
            }
        }, true);
    }

    // 监听页面加载完成后绑定事件
    function bindEventAfterScriptsLoaded() {
        const targetNode = document.body; // 监听整个 body
        const observer = new MutationObserver(() => {
            const scripts = document.querySelectorAll('script');
            let allScriptsLoaded = true;

            // 检查是否所有 script 标签都加载完成
            scripts.forEach(script => {
                if (!script.src && script.innerHTML.trim() === '') {
                    allScriptsExecuted = false;
                }
            });

            if (allScriptsLoaded) {
                console.log('所有 script 标签加载完成,绑定事件');
                observer.disconnect(); // 停止观察
                initSQLExecution(); // 执行绑定事件逻辑
            }
        });

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

    // 初始化脚本
    function init() {
        insertSelector();
        observeDbNameChanges();
        handleAceEditorPersistence();
        bindEventAfterScriptsLoaded();
    }

    // 等待页面加载完成后执行
    window.addEventListener('load', init);
})();