<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <base th:href="${#request.getContextPath() + '/'}">
    <meta charset="utf-8">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
    <link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
    <link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
    <link rel="stylesheet" href="assets/js/vendor/zTree3/css/metroStyle/metroStyle.css"/>
    <link rel="stylesheet" href="assets/layuiadmin/style/common.css" media="all">
    <link rel="stylesheet" href="assets/js/vendor/codemirror/codemirror.css" media="all">
    <link rel="stylesheet" href="assets/js/vendor/codemirror/addon/hint/show-hint.css"/>
    <link rel="stylesheet" href="assets/css/query-default.css">
</head>
<body>
<div class="layui-anim layui-anim-fadein">
    <div class="layui-card">
        <div class="layui-card-header">
            <div id="connectionBtnBox" class="layui-btn-group">
                <button id="connectionBtn" class="layui-btn layui-btn-xs" style="display: none;">打开连接</button>
                <button id="closeConnectionBtn" class="layui-btn layui-btn-xs layui-btn-danger" style="display: none;">关闭连接</button>
            </div>
        </div>
        <div class="layui-card-body left-tree-wrap">
            <div class="layui-row">
                <div class="layui-col-xs2">
                    <div id="leftTreeWrap">
                        <ul id="leftTree" class="ztree"></ul>
                    </div>
                </div>
                <div class="layui-col-xs10">
                    <div id="queryBox">
                        <div id="queryTopBox">
                            <div id="queryTopOptionBox">
                                <button id="runSqlBtn" class="layui-btn layui-btn-xs">运行</button>
                                只能运行一条SQL语句
                            </div>
                            <textarea id="queryTop"></textarea>
                        </div>
                        <div id="tableBottomBox">
                            <div class="layui-tab">
                                <ul class="layui-tab-title">
                                    <li class="layui-this">查询结果</li>
                                </ul>
                                <div class="layui-tab-content">
                                    <div class="layui-tab-item layui-show">
                                        <table class="layui-hide" id="dataTableBottom" lay-filter="dataTableBottom"></table>
                                    </div>
                                </div>
                            </div>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div id="zTreeSchemataRightMenu">
        <ul>
            <li id="openSchemataBtn">打开</li>
            <li id="closeSchemataBtn" style="display: none;">关闭</li>
            <li id="refreshSchemataBtn" style="display: none;">刷新</li>
        </ul>
    </div>
</div>
<script src="assets/js/vendor/codemirror/codemirror.js"></script>
<script src="assets/js/vendor/codemirror/mode/sql/sql.js"></script>
<script src="assets/js/vendor/codemirror/addon/hint/show-hint.js"></script>
<script src="assets/js/vendor/codemirror/addon/hint/sql-hint.js"></script>
<script src="assets/js/vendor/codemirror/addon/selection/active-line.js"></script>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
    var common;
    layui.config({
        base: 'assets/layuiadmin/'
    }).extend({
        index: 'lib/index'
    }).use(['index', 'table', 'laypage', 'util', 'ztree', 'common'], function() {
        common = layui.common;
        var $ = layui.$;
        var $win = $(window);
        var dataTable = layui.table;
        var laypage = layui.laypage;
        var util = layui.util;
        var resizeTimeout = null;
        var zTree = null;
        var mysqlId = top.restAjax.params(window.location.href).mysqlId;
        var rightSelectedTreeNode = null;
        var queryTopEditor = null;
        var queryTopEditorSqlTables = {}
        var queryResultTable = null;

        function initSize() {
            $('#leftTreeWrap').css({
                height: $win.height() - 44,
                overflow: 'auto'
            });
            $('#queryTopBox').css({
                height: $win.height() / 2 - 80,
            });
            $('#tableBottomBox').css({
                height: $win.height() / 2 + 35,
            });
        }

        function initQueryTop() {
            if(queryTopEditor) {
                return;
            }
            $('#queryTopBox').css('visibility', 'visible');
            queryTopEditor = CodeMirror.fromTextArea(document.getElementById('queryTop'), {
                mode: 'text/x-mysql',
                indentWithTabs: true,
                smartIndent: true,
                lineNumbers: true,
                matchBrackets : true,
                autofocus: true,
                hintOptions: {
                    completeSingle: false,
                    completeOnSingleClick: true,
                    tables: queryTopEditorSqlTables
                },
                indentUnit: 4,
                lineWrapping: true,
                autofocus: false,
            });
            queryTopEditor.setSize('auto', ($win.height() / 2 - 115) + 'px');
            queryTopEditor.on("inputRead", function(value) {
                if (!value.state.completionActive) {
                    var cursor = value.getCursor();
                    cursor = value.getTokenAt(cursor);
                    var cursorValue = '';
                    cursor.string.match(/^[.`\w@]\w*$/) && (cursorValue = cursor.string);
                    0 < cursorValue.length && CodeMirror.commands.autocomplete(value)
                }
            });
        }

        /**
         * 初始化表格（下）
         * @param schemata
         * @param table
         */
        function initTableBottom(schemata, table, page, limit) {
            var loadLayerIndex;
            top.restAjax.get(top.restAjax.path('api/mysql/jdbc/listpage-data/{mysqlId}/{schemata}/{table}', [mysqlId, schemata, table]), {
                page: page ? page : 1,
                limit: limit ? limit : 20
            }, null, function(code, data) {
                var cols = [];
                var datas = [];
                for(var i = 0, item; item = data.rows[i++];) {
                    if(i === 1) {
                        for(var k in item) {
                            cols.push({
                                field: k, width: 180, title: k, align:'center',
                                templet: function(row) {
                                    var rowData = row[this.field];
                                    if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
                                        return '-';
                                    }
                                    return rowData;
                                }
                            })
                        }
                    }
                    datas.push(item);
                }
                if(!data.curr) {
                    queryResultTable = dataTable.render({
                        elem: '#dataTableBottom',
                        id: 'dataTableBottom',
                        width: '100%',
                        height: $win.height() / 2 + 6,
                        cols: [cols],
                        data: datas,
                        page: {
                            count: data.total,
                            curr: 1,
                            layout: ['limit', 'count', 'first',  'prev', 'page', 'last',  'next', 'skip'],
                            groups: 4,
                            limit: 20,
                            limits: [20, 40, 60, 80, 100, 200],
                            jump: function(obj, first) {
                                if(data.page == obj.curr) {
                                    return;
                                }
                                console.log(obj.curr);
                                initTableBottom(schemata, table, obj.curr, obj.limit);
                            }
                        },
                    });
                } else {
                    queryResultTable.render({
                        cols: [cols],
                        data: datas,
                    })
                }
            }, function(code, data) {
                top.dialog.msg(data.msg);
            }, function() {
                loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
            }, function() {
                top.dialog.close(loadLayerIndex);
            });
        }
        function initTableBottom1(schemata, table) {
            var loadLayerIndex;
            top.restAjax.get(top.restAjax.path('api/mysql/jdbc/list-field/{mysqlId}/{schemata}/{table}', [mysqlId, schemata, table]), {}, null, function(code, data) {
                var cols = [];
                for(var i = 0, item; item = data[i++];) {
                    cols.push({
                        field: item.COLUMN_NAME, width: 180, title: item.COLUMN_NAME, align:'center',
                        templet: function(row) {
                            var rowData = row[this.field];
                            if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
                                return '-';
                            }
                            return rowData;
                        }
                    })
                }
                dataTable.render({
                    elem: '#dataTableBottom',
                    id: 'dataTableBottom',
                    url: top.restAjax.path('api/mysql/jdbc/listpage-data/{mysqlId}/{schemata}/{table}', [mysqlId, schemata, table]),
                    width: '100%',
                    height: $win.height() / 2 + 6,
                    limit: 20,
                    limits: [20, 40, 60, 80, 100, 200],
                    request: {
                        pageName: 'page',
                        limitName: 'rows'
                    },
                    cols: [cols],
                    page: true,
                    parseData: function(data) {
                        // 对结果转义，正常显示html代码
                        for(var i = 0, item; item = data.rows[i++]; ) {
                            for(k in item) {
                                item[k] = util.escape(item[k]);
                            }
                        }
                        return {
                            'code': 0,
                            'msg': '',
                            'count': data.total,
                            'data': data.rows
                        };
                    },
                });
            }, function(code, data) {
                top.dialog.msg(data.msg);
            }, function() {
                loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
            }, function() {
                top.dialog.close(loadLayerIndex);
            });
        }

        /**
         * 隐藏数据库右键菜单
         */
        function hideZTreeSchemataRightMenu() {
            rightSelectedTreeNode = null;
            $('#zTreeSchemataRightMenu').css('visibility', 'hidden');
            $(document.body).unbind('mousedown');
        }

        /**
         * 显示数据库右键菜单
         * @param treeNode
         * @param x
         * @param y
         */
        function showZTreeSchemataRightMenu(treeNode, x, y) {
            rightSelectedTreeNode = treeNode;
            if(treeNode.children) {
                $("#openSchemataBtn").hide();
                $("#closeSchemataBtn").show();
                $("#refreshSchemataBtn").show();
            } else {
                $("#openSchemataBtn").show();
                $("#closeSchemataBtn").hide();
                $("#refreshSchemataBtn").hide();
            }
            y += document.body.scrollTop;
            x += document.body.scrollLeft;
            $('#zTreeSchemataRightMenu').css({'top': y +'px', 'left': x + 'px', 'visibility': 'visible'});
        }


        /**
         * 初始化表
         * @param schemataTreeNode
         */
        function initTable(schemataTreeNode) {
            top.restAjax.get(top.restAjax.path('api/mysql/jdbc/list-table/{mysqlId}/{schemata}', [mysqlId, schemataTreeNode.id]), {}, null, function(code, data) {
                zTree.removeChildNodes(schemataTreeNode);
                var tableTreeNodes = [];
                for(var i = 0, item; item = data[i++];) {
                    queryTopEditorSqlTables[schemataTreeNode.id].push(item.TABLE_NAME);
                    queryTopEditorSqlTables[item.TABLE_NAME] = [];
                    tableTreeNodes.push({
                        id: item.TABLE_NAME,
                        name: item.TABLE_NAME,
                        pId: schemataTreeNode.id,
                        nodeType: 'table',
                        icon: 'assets/images/tree/tree-table.png'
                    });
                }
                zTree.addNodes(schemataTreeNode, tableTreeNodes);
            }, function(code, data) {
                top.dialog.msg(data.msg);
            }, function() {
                loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
            }, function() {
                top.dialog.close(loadLayerIndex);
            });
        }

        /**
         * 初始化树
         */
        function initThree() {
            var setting = {
                async: {
                    enable: true,
                    autoLoad: true,
                    type: 'get',
                    url: top.restAjax.path('api/mysql/jdbc/list-schemata/{mysqlId}', [mysqlId]),
                    autoParam: ['id'],
                    otherParam: {},
                    dataFilter: function (treeId, parentNode, childNodes) {
                        if (!childNodes) return null;
                        for(var i = 0, item; item = childNodes[i++];) {
                            queryTopEditorSqlTables[item.SCHEMA_NAME] = [];
                            item.id = item.SCHEMA_NAME;
                            item.name = item.SCHEMA_NAME;
                            item.pId = '0';
                            item.url = 'javascript:void(0);';
                            item.icon = 'assets/images/tree/tree-database.png';
                            item.nodeType = 'schemata';
                        }
                        return childNodes;
                    }
                },
                callback: {
                    onClick: function (event, treeId, treeNode) {
                        if(!treeNode) {
                            return;
                        }
                        // 数据库单点无效
                        if(treeNode.nodeType == 'schemata') {
                            return;
                        }
                        initTableBottom(treeNode.pId, treeNode.id);
                        initQueryTop();
                        return false;
                    },
                    onDblClick: function(event, treeId, treeNode) {
                        if(!treeNode) {
                            return;
                        }
                        // 表双点无效
                        if(treeNode.nodeType == 'table') {
                            return;
                        }
                        initTable(treeNode);
                        return false;
                    },
                    onRightClick: function(event, treeId, treeNode) {
                        if(!treeNode) {
                            return;
                        }
                        // 表右键无效
                        if(treeNode.nodeType == 'table') {
                            return;
                        }
                        showZTreeSchemataRightMenu(treeNode, event.clientX, event.clientY);
                    }
                },
            };
            zTree = $.fn.zTree.init($("#leftTree"), setting);
        }

        // 关闭连接
        function closeConnection() {
            var loadLayerIndex;
            $('#closeConnectionBtn').hide();
            top.restAjax.get(top.restAjax.path('api/mysql/jdbc/close-connection/{mysqlId}', [mysqlId]), {}, null, function(code, data) {
                window.location.reload();
            }, function(code, data) {
                $('#closeConnectionBtn').show();
                top.dialog.msg(data.msg);
            }, function() {
                loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
            }, function() {
                top.dialog.close(loadLayerIndex);
            });
        }

        // 打开连接
        function openConnection(callback) {
            var loadLayerIndex;
            $('#connectionBtn').hide();
            top.restAjax.get(top.restAjax.path('api/mysql/jdbc/open-connection/{mysqlId}', [mysqlId]), {}, null, function(code, data) {
                $('#closeConnectionBtn').show();
                callback();
            }, function(code, data) {
                $('#connectionBtn').show();
                top.dialog.msg(data.msg);
            }, function() {
                loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
            }, function() {
                top.dialog.close(loadLayerIndex);
            });
        }

        // 是否连接
        function isConnected(callback) {
            var loadLayerIndex;
            top.restAjax.get(top.restAjax.path('api/mysql/jdbc/is-connected/{mysqlId}', [mysqlId]), {}, null, function(code, data) {
                if(!data.data) {
                    $('#connectionBtn').show();
                    return;
                }
                $('#closeConnectionBtn').show();
                callback();
            }, function(code, data) {
                $('#connectionBtn').show();
                top.dialog.msg(data.msg);
            }, function() {
                loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
            }, function() {
                top.dialog.close(loadLayerIndex);
            });
        }

        initSize();
        isConnected(function() {
            initThree();
        });

        $('#connectionBtn').on('click', function() {
            openConnection(function() {
                initThree();
            });
        });

        $('#closeConnectionBtn').on('click', function() {
            closeConnection();
        });

        $('#openSchemataBtn').on('click', function() {
            initTable(rightSelectedTreeNode);
            hideZTreeSchemataRightMenu();
        })
        $('#closeSchemataBtn').on('click', function() {
            zTree.removeChildNodes(rightSelectedTreeNode);
            hideZTreeSchemataRightMenu();
        })
        $('#refreshSchemataBtn').on('click', function() {
            initTable(rightSelectedTreeNode);
            hideZTreeSchemataRightMenu();
        })

        $('#runSqlBtn').on('click', function() {
            var sql = queryTopEditor.getValue();
            if(!sql) {
                top.dialog.msg('请输入SQL');
                return;
            }
            var loadLayerIndex;
            top.restAjax.get(top.restAjax.path('api/mysql/jdbc/is-connected/{mysqlId}', [mysqlId]), {}, null, function(code, data) {
                if(!data.data) {
                    $('#connectionBtn').show();
                    return;
                }
                $('#closeConnectionBtn').show();
                callback();
            }, function(code, data) {
                $('#connectionBtn').show();
                top.dialog.msg(data.msg);
            }, function() {
                loadLayerIndex = top.dialog.msg(top.dataMessage.loading, {icon: 16, time: 0, shade: 0.3});
            }, function() {
                top.dialog.close(loadLayerIndex);
            });
        });

        // 事件 - 页面变化
        $win.on('resize', function() {
            clearTimeout(resizeTimeout);
            resizeTimeout = setTimeout(function() {
                initSize();
            }, 500);
        });
    });
</script>
</body>
</html>