me10zyl / 淘金yearning小助手

// ==UserScript==
// @name         淘金yearning小助手
// @namespace    http://yilnz.com
// @version      0.0.11
// @description  帮助快捷使用yearning!
// @downloadURL  https://openuserjs.org/install/me10zyl/%E6%B7%98%E9%87%91yearning%E5%B0%8F%E5%8A%A9%E6%89%8B.user.js
// @updateURL    https://openuserjs.org/install/me10zyl/%E6%B7%98%E9%87%91yearning%E5%B0%8F%E5%8A%A9%E6%89%8B.user.js
// @require      https://openuserjs.org/src/libs/me10zyl/creeper基础类库.js
// @require      https://cdn.staticfile.org/jquery/1.11.3/jquery.min.js
// @author       allynz
// @match        http://yearning.taojinkf.com/*
// @grant        GM_addStyle
// @grant         unsafeWindow
// @license MIT
// @copyright 2020, me10zyl (https://openuserjs.org/users/me10zyl)
// ==/UserScript==

(async function() {
    'use strict';
    let version = "0.0.11";
    let KEY_ACE_CONTENT = "zyl-key-ace-content";
    let KEY_FILTER_TABLE = "zyl-key-filter-table";
    let KEY_LAST_CONNECTION = "zyl-key-last-connection";
    let KEY_LAST_SELECT_DB = "zyl-key-last-select-db";
    let KEY_HISTORY = "zyl-key-history";

    setInterval(function(){
        if(location.href == 'http://yearning.taojinkf.com/#/home'){
            location.href = 'http://yearning.taojinkf.com/#/view/query'
        }
    }, 500);

    let clickedDB = false;

    let dbInterval = setInterval(function(){
        let selectDB = $(".ivu-modal-content .ivu-cell");
        if(selectDB){
            selectDB.unbind("click").bind("click", function(){
                console.log("[helper]select : " + $(this).index());
                localStorage[KEY_LAST_CONNECTION] = $(this).index();
            });
            console.log("[helper]LAST_CONNECTION:" + localStorage[KEY_LAST_CONNECTION]);
            setTimeout(function(){
                if(!clickedDB){
                    //$(".ivu-modal-content .ivu-cell").eq(localStorage[KEY_LAST_CONNECTION]).find(".ivu-cell-link").click();
                }
                clickedDB = true;
                clearInterval(dbInterval);
            }, 300);
        }
    }, 55);

    // Your code here...
    let ace_content = await cp.findInterval(()=>document.querySelector('.ace_content'), 100);
    class AjaxInterceptor {
        constructor() {
            var RealXHROpen = XMLHttpRequest.prototype.open;
            var RealXHRSend = XMLHttpRequest.prototype.send;
            const self = this;
            XMLHttpRequest.prototype.send = function (data) {
                let realData = self.beforeAjax.call(this, data);
                RealXHRSend.call(this, realData);
            }
            XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
                this._url = url;
                RealXHROpen.apply(this, arguments);
            };
        }

        beforeAjax(){
            console.log(this);
        }
    }

    function init(){
        let ajaxInterceptor = new AjaxInterceptor();
        ajaxInterceptor.beforeAjax = beforeAjax;
    }

    function getAceSelection(){
        let selectListEle = document.querySelectorAll('.ace_selection');
        let selectList = [];
        selectListEle.forEach(e=>selectList.push(e));
        let aceContent = getAceContent();
        let splits = aceContent.split("\n");
        let result = "";
        if(selectList.length == 3){
            let tmp = selectList[2];
            selectList[2] = selectList[1];
            selectList[1] = tmp;
        }
        for(let i = 0;i < selectList.length;i++){
            let selectQ = selectList[i];
            let letterStart = parseInt(parseFloat(selectQ.style['left'])/ 7.6975);
            let styleElement = selectQ.style['width'];
            let height = parseInt(selectQ.style['height']);
            let skipNumber = parseInt(selectQ.style["top"]) / 17;
            if(height > 17){
                let lineCount = height / 17;
                let j = skipNumber;
                for( ; j < skipNumber + lineCount;j++) {
                    result += splits[j] + "\n";
                }
                skipNumber = skipNumber + lineCount;
                i = selectList.length
                selectQ = selectList[selectList.length - 1];
                letterStart = parseInt(parseFloat(selectQ.style['left'])/ 7.6975);
                styleElement = selectQ.style['width'];
            }

            let letterEnd = -1;
            if(styleElement != ""){
                letterEnd = letterStart + parseInt((parseFloat(styleElement)) / 7.6975);
            }
            if(letterEnd == -1){
                result += splits[skipNumber].substring(letterStart);
            }else {
                result += splits[skipNumber].substring(letterStart, letterEnd);
            }
            result += "\n";
        }
        return result;
    }
    unsafeWindow.getAceContent = getAceContent;
    unsafeWindow.getAceSelection = getAceSelection;

    function beforeAjax(data){

        let data2 = data;
        if(this._url == '/api/v2/query'){
            let json = JSON.parse(data);
            //let s = window.getSelection().toString();
            let s = getAceSelection();
            if(s!=null && s.trim() != ""){
                console.log('[helper]exec select sql', s)
                json.sql = s;
            }
            data2 = JSON.stringify(json);
        }

        return data2;
    }



    init();

    function _x(STR_XPATH) {
        var xresult = document.evaluate(STR_XPATH, document, null, XPathResult.ANY_TYPE, null);
        var xnodes = [];
        var xres;
        while (xres = xresult.iterateNext()) {
            xnodes.push(xres);
        }

        return xnodes;
    }
    window._x = _x;

    function sendText(text){
        $(".ace_text-input").val(text);
        var event = new Event("input", { "detail": "Example of an event" });
        // Dispatch/Trigger/Fire the event
        $(".ace_text-input")[0].dispatchEvent(event);
    }


    //document.querySelector('.ace_identifier').textContent = localStorage[KEY_ACE_CONTENT];
    let content = localStorage[KEY_ACE_CONTENT];
    if(content){
        sendText(content);
    }
    console.log('[helper]ace_content found');
    function getAceContent(){
        let text = '';
        $($(".ace_text-layer")[0]).find(".ace_line").each(function(){
            text += $(this).text() + "\n";
        });
        return text;
    }
    function saveAceContent(){
        //console.log( $($(".ace_text-layer")[0]).text());
        var text = getAceContent();
        if(text){
            localStorage[KEY_ACE_CONTENT] =  text.substring(0, text.length-1);
        }
    }
    $(".ace_text-input").keyup(saveAceContent);

    function selectLastDB(){
        var lastDB = localStorage[KEY_LAST_SELECT_DB];
        if(lastDB){
            console.log('[helper]selectDB:' + lastDB);
            $(".ivu-tree .ivu-tree-children .ivu-tree-title").each(function(){
                if($(this).text().match(lastDB)){
                    $(this).prev().click();
                }
            });
        }
    }

    function initSearch(){
        var searchInput = $("<input />");
        $(".ivu-card-head").append(searchInput);
        function triggerFilter(){
            $(".ivu-tree .ivu-tree-children").each(function(){
                if($(this).text().match(new RegExp(searchInput.val()))){
                    $(this).show();
                }else{
                    $(this).hide();
                }
            });
            if($(this).val()){
                localStorage[KEY_FILTER_TABLE] = $(this).val()
            }
        }
        searchInput.keyup(triggerFilter);
        let content =  localStorage[KEY_FILTER_TABLE];
        if(content){
            //searchInput.val(content);
            setTimeout(function(){
                triggerFilter();
                selectLastDB();
            }, 1000);
        }
    }
    initSearch();
    let currentTableName = '';

    setInterval(function(){
        $(".ivu-tree-title").each(function(){
            if($(this).prev().find("i").length==0){
                $(this).unbind('click').bind('click', function(){
                    console.log('[helper]自动获取表结构')
                    $(_x("//button//*[text()='获取表结构']")[0]).click();
                    currentTableName = $(this).text();
                });
            }
        });
    }, 500);
    let lastBtn;
    function getNewBtn(text){
        if(!lastBtn){
            lastBtn = $(_x("//button//*[text()='隐藏数据列']")[0]).parent();
        }
        let newBtn = lastBtn.clone();
        newBtn.css({'margin-left': '10px'});
        newBtn.removeClass('ivu-btn-primary').addClass('ivu-btn-info')
        newBtn.find("i").remove();
        newBtn.find("span").text(text);
        lastBtn.after(newBtn);
        return newBtn;
    }

    function getTime(fmt){
        var today = new Date();
        var date = today.getFullYear()+'-'+("" + (today.getMonth()+1)).padStart(2, '0')+'-'+today.getDate();
        var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
        if(fmt != null){
            time = fmt;
        }
        var dateTime = date+' '+time;
        return dateTime;
    }

    function initModal(html){
        var modal = $('<div class="zyl-modal"><div><div class="zyl-modal-content"><span class="close">&times;</span><p class="zyl-content"></p></div></div></div>');
        modal.find(".zyl-content").html(html);
        $(document.body).append(modal);
        var span = document.getElementsByClassName("close")[0];
        span.onclick = function() {
            modal[0].style.display = "none";
        }
        window.onclick = function(event) {
            if (event.target == modal) {
                modal[0].style.display = "none";
            }
        }
        return modal;
    }
    var historyModalContent = $("<div></div>");
    var historyModal = initModal(historyModalContent);
    getNewBtn("查看查询历史").click(function(){
        if(localStorage[KEY_HISTORY]){
            var arr = JSON.parse(localStorage[KEY_HISTORY]);
            console.log(arr);
            historyModalContent.html("");
            for(let i = arr.length-1;i >= 0;i--){
                historyModalContent.append("<div>" + arr[i] + "</div>");
            }
            historyModal.css("display","block");
        }
    });

    getNewBtn("插入模板语句").click(function(){
        if(!currentTableName){
            alert('请先选择表');
            return;
        }
        let text = "select * from " + currentTableName + "\n";
        sendText(text);
        let createTime = getCreateTime();
        if(createTime) {
            sendText('where ' + createTime + ' >= \'' + getTime('00:00:00') + '\' and ' + createTime + ' <= \'' + getTime('23:59:59') + '\'');
            sendText('\norder by ' + createTime + " desc limit 50 ");
        }else{
            sendText('order by id desc');
        }
        setTimeout(function(){
            saveAceContent()
        }, 50);
    });

    function getCreateTime(){
        let createTime = null;
        $(".ivu-table-tbody tr td:first-child").each(function(){
            if($(this).text().match(/create/)){
                createTime =  $(this).text().trim();
            }
        });
        return createTime;
    }

    function clickInsertTimeScale(){
        let dateCol = getCreateTime();
        if(dateCol){
            let text = ' where ' + dateCol + ' >= \'' + getTime('00:00:00') + '\' and ' + dateCol + ' <= \'' + getTime('23:59:59') + '\'';
            sendText(text);
        }else{
            alert('请先选择表');
        }
    }
    getNewBtn("插入时间范围").click(clickInsertTimeScale);
    let shuoming = $("<a href='javascript:void(0)' style='margin-right:15px'>淘金yearning小助手说明(v"+ version +")</a>");
    $(".header-avator-con").prepend(shuoming);
    shuoming.click(function(){
        alert("===更新日志===\n1.增加记住上次SQL功能(v0.0.1)\n2.增加筛选表功能(v0.0.1)\n3.增加上次筛选的表功能(v0.0.1)\n4.增加自动获取表结构功能(v0.0.1)\n5.增加一键插入时间范围sql功能(v0.0.1)\n6.增加一键插入模板sql功能(v0.0.1)\n7.增加自动连接最后连接功能(v0.0.2)\n8.增加自动选择最后数据库功能(v0.0.2)\n9.增加查询自动加入历史记录(v0.0.6)\n10.加入选择查询功能(v0.0.11)");
    });


    setInterval(function(){
        var text = _x("//span[contains(text(),'当前选择的库')]")[0].textContent.match(/当前选择的库:(.+)/)[1].trim();
        if(text.length != 0){
            localStorage[KEY_LAST_SELECT_DB] = text;
            //console.log('[helper]LAST_SELECT_DB:' + text);
        };
    }, 500);


    $(_x("//button//*[text()='查询']")[0]).click(function(){
        if(!localStorage[KEY_HISTORY]){
            localStorage[KEY_HISTORY] = JSON.stringify([]);
        }
        var array = JSON.parse(localStorage[KEY_HISTORY]);
        var content = getAceContent();
        if(content){
            if(array.length> 0){
                if(array[array.length-1] != content){
                    array.push(content);
                }
            }else{
                array.push(content);
            }
            localStorage[KEY_HISTORY] = JSON.stringify(array);
        }
    });

    GM_addStyle("/* The Modal (background) */  .zyl-modal {display: none; /* Hidden by default */position: fixed; /* Stay in place */z-index: 99999; /* Sit on top */left: 0;top: 0;width: 100%; /* Full width */height: 100%; /* Full height */overflow: auto; /* Enable scroll if needed */background-color: rgb(0,0,0); /* Fallback color */background-color: rgba(0,0,0,0.4); /* Black w/ opacity */}  /* Modal Content/Box */  .zyl-modal-content {background-color: #fefefe;margin: 15% auto; /* 15% from the top and centered */padding: 20px;border: 1px solid #888;width: 80%; /* Could be more or less, depending on screen size */}  /* The Close Button */  .close {color: #aaa;float: right;font-size: 28px;font-weight: bold;}  .close:hover, .close:focus {color: black;text-decoration: none;cursor: pointer;}");
})();