<%@ Page Language="C#" MasterPageFile="Main.Master" AutoEventWireup="true" CodeFile="recordDesign.aspx.cs" Inherits="eFrameWork.Manage.recordDesign" %>
<%@ Register Src="GroupMenu.ascx" TagPrefix="uc1" TagName="GroupMenu" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<script>
var act = "<%=act%>";
window.onload=function()
{


};
function recordView(RecordID)
{
    var url = "recordView.aspx?RecordID="+RecordID;
    layer.open({
        anim: 4,//设置出现的动画效果 4 1 2 0
        type: 2,
        skin: 'layui-layer-rim', //加上边框
        title: "查看记录集",
        maxmin: false,
        shadeClose: true, //点击遮罩关闭层
        area: ['75%', '80%'],
        content: url,
        success: function (layero, index) { },
        cancel: function (index, layero) { },
        end: function (index) {  }
    });
};
</script>
<uc1:GroupMenu runat="server" ID="GroupMenu" />
 <script src="../Plugins/jsplumb/jsplumb.2.15.6.min.js"></script>

<div class="nav">您当前位置：<a href="Default.aspx">首页</a> -> 数据集</div>
<style>
.container {display: flex;height: 100%;}    
.container * {box-sizing: border-box;}    
/* 左侧面板样式 */
.left-panel {width: 260px;background-color: white;border-right: 1px solid #ddd;display: flex;flex-direction: column;box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);}
.panel-header {padding: 10px;background-color: #3498db;color: white;}
.panel-header h2 {margin: 0;font-size: 1.3rem;}
.search-box {padding: 15px;border-bottom: 1px solid #eee;}
.search-box input {width: 100%;padding: 10px;border: 1px solid #ddd;border-radius: 4px;font-size: 14px;}
.table-list {flex: 1;overflow-y: auto;padding: 10px;user-select: none;}
.table-item {background-color: #f8f9fa;border: 1px solid #e9ecef;border-radius: 6px;padding: 15px;margin-bottom: 10px;cursor: grab;transition: all 0.3s;}
.table-item:hover {background-color: #e8f4fd;border-color: #3498db;transform: translateY(-2px);box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);}
.table-item h3 {margin: 0 0 10px 0;color: #2c3e50;font-size: 1.1rem;}        
.table-fields {font-size: 0.85rem;color: #6c757d;}
.field {display: flex;justify-content: space-between;padding: 3px 0;border-bottom: 1px dotted #eee;}
.field:last-child {border-bottom: none;}
        
/* 右侧工作区样式 */
.right-panel {flex: 1;display: flex;flex-direction: column;background-color: #f8f9fa;}
.toolbar {padding:0px 10px 8px 10px;background-color: white;border-bottom: 1px solid #ddd;display: flex;justify-content: space-between;align-items: center;box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);}        
.toolbar h1 {color: #2c3e50;font-size: 1.5rem;margin: 0;}
.toolbar-controls {display: flex;gap: 10px;}        
button {padding: 8px 16px;background-color: #3498db;color: white;border: none;border-radius: 4px;cursor: pointer;transition: background-color 0.3s;font-size: 14px;}
button:hover {background-color: #2980b9;}
button.secondary {background-color: #6c757d;}
button.secondary:hover {background-color: #5a6268;}
.editor-result{flex: 1;position: relative;overflow: auto;background-image: linear-gradient(#e5e5e5 1px, transparent 1px),linear-gradient(90deg, #e5e5e5 1px, transparent 1px);background-size: 20px 20px;/*user-select: none;*/}
/* 表样式 */
.table {position: absolute;width: 250px;background-color: white;border: 1px solid #ddd;border-radius: 8px;box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);cursor: move;z-index: 10;}
.tableselected{border:1px solid #1c96e8;box-shadow: 0 10px 10px rgba(41,103,190,.38);;}
.table-header {background-color: #3498db;color: white;padding: 12px;border-radius: 8px 8px 0 0;font-weight: bold;text-align: center;display: flex;justify-content: space-between;align-items: center;}        
.table-name {flex: 1;text-align: center;}
.table-close {cursor: pointer;font-weight: bold;padding: 0 5px;transition: color 0.2s;}
.table-close:hover {color: #e74c3c;}
.table-fields-container {padding: 10px;/*max-height: 250px;overflow-y: auto;*/}
.field {padding: 6px 0;border-bottom: 1px solid #f0f0f0;display: flex;justify-content: space-between;position: relative;}

.field:last-child {border-bottom: none;}
.field-name {font-weight: 500; }

.field .field-name {cursor:pointer; padding-right:15px;}
.field .field-name:hover {background:url("../Plugins/eControls/default/images/bdmap_edit.gif") no-repeat right center; background-size:14px 14px;}
.field .field-name img {border:0px solid #000;width:14px;height:14px;margin-right:6px; vertical-align:middle;background:url("../Plugins/eControls/default/images/checkbox.gif") no-repeat center center;}
.field .field-name img.selected { background:url("../Plugins/eControls/default/images/checkbox_selected.gif") no-repeat center center;}
.table-fields-container .field-name{font-size:12px;}
.field-type {color: #7f8c8d;font-size: 0.85em;}        
.endpoints {position: absolute;top: 0;bottom: 0;width: 12px;}        
.left-endpoints {left: -6px;}
.right-endpoints {right: -6px;}
.endpoint {width: 12px;height: 12px;border-radius: 50%;background-color: #3498db;position: absolute;cursor: pointer;z-index: 10;/*transition: all 0.2s;*/}        
.endpoint:hover {/*background-color: #2980b9;transform: scale(1.2);*/}
.jtk-endpoint-connected circle {fill: #2980b9;}        
 /* 连接线样式 */
.jtk-connector {z-index: 5;}
.jtk-endpoint {z-index: 10;}        
.connection-label {background-color: white;padding: 6px 12px;border-radius: 15px;border: 1px solid #3498db;font-size: 12px;cursor: pointer;z-index: 20;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);transition: all 0.2s;font-weight: 600;color: #2c3e50;min-width: 100px;text-align: center;}
.connection-label:hover {background-color: #f0f7ff;transform: scale(1.05);box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);}
/* 选中连接线样式 */
.jtk-connector.selected path {stroke: #e74c3c !important;stroke-width: 3px !important;}        
/* JSON输出区域 */
.json-output {padding: 15px;background-color: white;border-top: 1px solid #ddd;max-height: 300px;overflow-y: auto;}
.json-title {font-weight: bold;margin-bottom: 10px;color: #2c3e50;}
#json-data {font-family: monospace;font-size: 14px;white-space: pre-wrap;background-color: #f8f9fa;padding: 10px;border-radius: 4px;border: 1px solid #e9ecef;}	
.table-connection {stroke-width: 3;stroke: #3498db;}
.txtLabel{position: absolute;transform: translate(-50%, -50%);background-color: #3498db;color:#fff;padding: 4px 8px;border-radius: 4px;border: 1px solid #3498db;font-size: 14px;cursor: pointer; font-weight:bold;}	
.joinmenu{position: absolute;right: 0px;z-index: 192012458;background-color: #fff;width: 142px;top: -300px;box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2);border: 1px solid #C4D2DD;border-radius: 3px;padding: 6px;list-style-type: none;}
.joinmenu li{line-height:32px; background-color:#fff;cursor:pointer;border: 1px solid transparent;border-radius: 4px;padding-left:15px;font-size:14px;}
.joinmenu li:hover{border: 1px solid #267ef0;background-color:#3498db;color:#fff;font-weight:bold;}


/*重写*/
.table-list2{
flex:none;
display: flex;
flex-wrap: wrap;
/*justify-content: space-between;gap: 10px;*/


}
.table-item2 {
flex: 1 1 calc(50% - 10px);
display: list-item;
justify-content: center;
align-items: center;

padding:5px 5px 10px 5px;
height:30px;
margin-right: 10px; /* 水平间隙 */
  margin-bottom: 10px; /* 垂直间隙 */
overflow:hidden;
text-overflow: ellipsis;
}
.table-item2 .field-name{margin-bottom:10px;display:block;}

.table-list3{
  display: grid;
  /*grid-template-columns: repeat(2, 1fr);  每行两个项目 */
  grid-template-columns: 1fr 1fr;
  /*grid-template-rows: 50px 50px;*/   
  grid-template-rows:33px; /* 第一个网格项固定高度 */
  grid-auto-rows: 33px; /* 之后的所有网格项都固定高度 */   
  gap: 6px; /* 设置间隙 */
}

.table-item4{padding:5px;margin-bottom:0px;height:33px;white-space: nowrap;text-overflow: ellipsis; /* 显示省略号 */overflow:hidden;font-size:14px;}

    .table-item {padding:5px;margin-bottom:2px;
    }


.items
{
border:0px solid #000;
display: grid;  grid-gap:10px;
	
	  grid-template-columns: repeat(auto-fill, 150px);
	  padding:20px; background-color:#fff;
}
.items li
{
display:flex;flex-direction: column;
border:1px solid #ddd;pos3ition:relative;box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);cursor: move;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;border-radius: 5px;

background-color: #fff;
height:60px; text-align:center;justify-content:center;
}
.items li i {display:none;width:20px;height:20px;position:absolute;top:0px;right:1px; border:0px solid #ff0000;cursor:pointer;background:url(../Plugins/eControls/default/images/eFrameTab_close_cur.gif) no-repeat center center;}
.items li.cur,
.items li:hover { transform: translateY(-2px);
border: 1px solid #1677ff;
box-shadow: 0 10px 25px rgba(41,103,190,.38);
}
.items li:hover i {display:inline-block;}

</style>
<ul class="joinmenu">
<li>inner join</li>
<li>left join</li>
<li>right join</li>
<li>full join</li>
</ul>
    <div class="container">
        <!-- 左侧面板 -->
        <div class="left-panel">
            <div class="panel-header">
                <h2>表、视图</h2>
            </div>
            <div class="search-box">
                <input type="text" id="search-tables" placeholder="搜索表...">
            </div>			
            <div class="table-list" id="table-list">
                <!-- 表项将通过JavaScript动态添加 -->
            </div>
           

        </div>
        
        <!-- 右侧工作区 -->
        <div class="right-panel">
            <div class="toolbar">
                <h1><%=record.Name %></h1>
                <div class="toolbar-controls">
                    <button id="export-json" style="display:none;">导出JSON</button>
                    <button id="import-json" style="display:none;">导入JSON</button>

                   
                    <button id="btn-relation" onclick="switcharea('editor-container');">关系</button>
                    <button id="btn-position" onclick="switcharea('editor-container1');">位置</button>
                    <button id="view-result" onclick="switcharea('editor-container2');">结果</button>
                    
                       <button id="Button2" onclick="recordView('<%=RecordID %>');">查看</button>
                    <button id="clear-all" class="export-json">清空</button>
                </div>
            </div>
            <div id="editor-container" class="editor-result" style="disp4lay:none;">
                <!-- 表将通过JavaScript动态添加 -->
				 <svg id="tableConnections" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;"></svg>				 
            </div>
             <div id="editor-container1" class="editor-result" style="display:none;">
                 <div style="background-color:#fff;padding-left:10px;line-height:35px;">显示：</div>
                 <ul id="show-fields" class="items"></ul>
                 <div style="background-color:#fff;padding-left:10px;line-height:35px;">条件：</div>
                 <ul id="cond-fields" class="items"></ul>
                 <div style="background-color:#fff;padding-left:10px;line-height:35px;">排序：</div>
                 <ul id="order-fields" class="items"></ul>
             </div>
             <div id="editor-container2" class="editor-result" style="display:none;">
                 <div style="margin:10px 20px;">SQL语句：<br />
                 <textarea id="resultSql" name="textarea" style="width:75%;height:150px;" onblur="updatesql(this);"><%=record.resultSql %></textarea>
                 </div>
                  <div style="margin:10px 20px;">参考：<br />
                      <div id="tempSql" style=" background-color:#fff;border:1px solid #ddd;padding:10px;"><%=record.tempSql %></div>
                 </div>
                 <div style="margin:10px 20px;">结果：
                     <div id="resultTable">
                     <%=record.resultTable %>
                         </div>
                 </div>

             </div>
             <!-- 
             <div class="json-output">
                <div class="json-title">关系JSON:</div>
                <div id="json-data">暂无数据</div>
            </div>
              -->
        </div>
    </div>

<script>
    function updatesql(obj)
    {
        var url = document.location.href;
        url = url.addquerystring("act", "updatesql");
        $.ajax({
            type: 'post',
            url: url,
            data: { sql:$(obj).val() },
            dataType: "json",
            success: function (data) {
                if(data.resultTable)
                {
                    $("#resultTable").html(data.resultTable);
                }
            }
        });
    }

    function switcharea(id)
    {
        $(".editor-result").hide();
        $("#"+id).show();
    }

    var jsPlumbInstance = jsPlumb.getInstance();
    function initializeJsPlumb() {
        jsPlumbInstance.reset();
        jsPlumbInstance = jsPlumb.getInstance({
            Connector: ["Bezier", { curviness: 50 }],
            PaintStyle: {
                stroke: "#3498db",
                strokeWidth: 2
            },
            HoverPaintStyle: {
                stroke: "#2980b9",
                strokeWidth: 3
            },
            EndpointStyle: {
                radius: 5,
                fill: "#3498db"
            },
            EndpointHoverStyle: {
                fill: "#2980b9"
            },
            Container: "editor-container"
        });
        // 连接建立时的处理		
        jsPlumbInstance.bind("connection", function (info) {

            if (isImport) { return; }
            var connection = info.connection;
            var sourceTableId = info.sourceEndpoint.element.getAttribute('data-table');// connection.endpoints[0].getElement().id;
            var targetTableId = info.targetEndpoint.element.getAttribute('data-table');//connection.endpoints[1].getElement().id;

            // 生成连接ID
            var connectionId = "conn-" + Date.now();
            connection.id = connectionId;
            // 存储连接数据
            var snum = parseInt(sourceTableId.replace("table-", ""));
            var tnum = parseInt(targetTableId.replace("table-", ""));
            if (snum < tnum) {
                connections[connectionId] = {
                    id: connectionId,
                    sourceId: sourceTableId,
                    targetId: targetTableId,
                    //joinType: "INNER JOIN",
                    //sourceName: tables[sourceTableId].name,
                    //targetName: tables[targetTableId].name,
                    //sourceCode: tables[sourceTableId].code,
                    //targetCode: tables[targetTableId].code,
                    sourceField: info.sourceEndpoint.element.getAttribute('data-field'),
                    targetField: info.targetEndpoint.element.getAttribute('data-field')
                };
            }
            else {
                connections[connectionId] = {
                    id: connectionId,
                    sourceId: targetTableId,
                    targetId: sourceTableId,
                    //joinType: "INNER JOIN",
                    //sourceName: tables[targetTableId].name,
                    //targetName: tables[sourceTableId].name,
                    //sourceCode: tables[targetTableId].code,
                    //targetCode: tables[sourceTableId].code,
                    sourceField: info.targetEndpoint.element.getAttribute('data-field'),
                    targetField: info.sourceEndpoint.element.getAttribute('data-field')
                };
            }
            checkTableLink(sourceTableId, targetTableId);
            // 更新JSON显示
            updateJsonDisplay();
        });
        // 取消连接建立时的处理
        jsPlumbInstance.bind("connectionDetached", function (info) {

            var connection = info.connection;
            var sourceId = info.sourceEndpoint.element.getAttribute('data-table');
            var targetId = info.targetEndpoint.element.getAttribute('data-table');

            var snum = parseInt(sourceId.replace("table-", ""));
            var tnum = parseInt(targetId.replace("table-", ""));
            if (snum > tnum) {
                var tmp = sourceId;
                sourceId = targetId;
                targetId = tmp;
            }

            delete connections[info.connection.id];
            var ct = 0;
            Object.keys(connections).forEach(function (conid) {
                if (connections[conid].sourceId == sourceId && connections[conid].targetId == targetId) {
                    ct++;
                }
            });
            if (ct == 0) {
                for (var i = linkTypes.length - 1; i >= 0; i--) {
                    if (linkTypes[i].sourceId == sourceId && linkTypes[i].targetId == targetId) {
                        var labelid = "txt_" + linkTypes[i].sourceId + "_" + linkTypes[i].targetId;
                        var tmp = document.getElementById(labelid);
                        if (tmp != null) { tmp.remove(); }
                        linkTypes.splice(i, 1);
                    }
                }
            }
            updateTableLinks();//更新表与表的联合类型
            // 更新JSON显示
            updateJsonDisplay();

        });


        // 连接选择处理
        jsPlumbInstance.bind("click", function (connection, e) {
            e.stopPropagation();
            // 清除之前的选择
            if (selectedConnection) {
                selectedConnection.removeClass("selected");
            }
            // 选中当前连接
            connection.addClass("selected");
            selectedConnection = connection;
        });
    }
    var loaded=false;
    // 表ID计数器
    var tableCounter = 0;

    // 连接类型选项
    var joinTypes = ["INNER JOIN", "LEFT JOIN", "RIGHT JOIN", "FULL JOIN"];
    var isImport = false;
    // 存储表数据
    var tables = {};
    // 存储连接数据
    var connections = {};
    //连接类型
    var linkTypes = [];
    // 当前选中的连接
    var selectedConnection = null;
    var selectedTable = null;
    // 左侧可用的表模板
    var availableTables = <%=TableViews%>;
    var availableTables2 = [
        {
            name: "用户表",
            code: "users",
            fields: [
                { name: 'id', type: 'INT' },
                { name: 'username', type: 'VARCHAR(50)' },
                { name: 'email', type: 'VARCHAR(100)' },
                { name: 'created_at', type: 'DATETIME' }
            ]
        },
        {
            name: "订单表",
            code: "orders",
            fields: [
                { name: 'id', type: 'INT' },
                { name: 'user_id', type: 'INT' },
                { name: 'amount', type: 'DECIMAL(10,2)' },
                { name: 'status', type: 'VARCHAR(20)' },
                { name: 'order_date', type: 'DATETIME' }
            ]
        },
        {
            name: "产品表",
            code: "products",
            fields: [
                { name: 'id', type: 'INT' },
                { name: 'name', type: 'VARCHAR(100)' },
                { name: 'price', type: 'DECIMAL(10,2)' },
                { name: 'category', type: 'VARCHAR(50)' }
            ]
        },
        {
            name: "",
            code: "orderdetails",
            fields: [
                { name: 'id', type: 'INT' },
                { name: 'order_id', type: 'INT' },
                { name: 'product_id', type: 'INT' },
                { name: 'quantity', type: 'INT' },
                { name: 'price', type: 'DECIMAL(10,2)' }
            ]
        },
        {
            name: "分类表",
            code: "class",
            fields: [
                { name: 'id', type: 'INT' },
                { name: 'name', type: 'VARCHAR(50)' },
                { name: 'description', type: 'TEXT' }
            ]
        }
    ];

    function getEventObject() {
        var evt, src;
        if (window.event) {
            evt = window.event;
            src = evt.srcElement;
        }
        else {
            var o = arguments.callee;
            var e;
            while (o != null) {
                e = o.arguments[0];
                if (e && (e.constructor == Event || e.constructor == MouseEvent)) {
                    evt = e;
                    src = evt.target;
                    break;
                }
                o = o.caller;
            }
        }
        return src;
    };

    // 初始化左侧表列表
    function initTableList() {
        var tableList = document.getElementById('table-list');
        tableList.innerHTML = '';

        availableTables.forEach(function (table) {
            var tableItem = document.createElement('div');
            tableItem.className = 'table-item';
            tableItem.setAttribute("data-name", table.name);//增加
            tableItem.setAttribute("data-code", table.code);//增加
            tableItem.setAttribute("data-type", (typeof(table.type)=="string" ? table.type : ""));//增加

            var text= table.name.length > 0 && table.name != table.code ? table.code + " (" + table.name + ")" :  table.code;
            tableItem.title = text;
            tableItem.draggable = true;
            tableItem.innerHTML = "<span class=\"field-name\">" + text + "</span>";

    
            // 添加拖拽事件
            tableItem.addEventListener('dragstart', function (e) {
                //alert( JSON.stringify(table));
                e.dataTransfer.setData('text/plain', JSON.stringify(table));
            });

            tableList.appendChild(tableItem);
        });
    }

    // 初始化工作区拖放
    function initDropZone() {
        var editorContainer = document.getElementById('editor-container');

        editorContainer.addEventListener('dragover', function (e) {
            e.preventDefault();
        });

        editorContainer.addEventListener('drop', function (e) {
            e.preventDefault();
            var tableData = JSON.parse(e.dataTransfer.getData('text/plain'));

            // 计算放置位置
            var rect = editorContainer.getBoundingClientRect();
            var x = e.clientX - rect.left - 110; // 表宽度的一半
            var y = e.clientY - rect.top - 30;  // 表高度的一半
            addTable(tableData.name, tableData.code, tableData.type, tableData.fields, { x: x, y: y });

        });
        editorContainer.addEventListener('click', function (e) {//菜单 

            var menu = document.querySelector('.joinmenu');
            menu.style.top = '-300px';


            $(".table").removeClass("tableselected");
            selectedTable = null;

            e.preventDefault();
        });

        document.querySelector('.joinmenu').addEventListener('click', function () {
            var src = getEventObject();
            window.elabel.innerText = src.innerText;
            var sourceId = window.elabel.getAttribute("sourceId");
            var targetId = window.elabel.getAttribute("targetId");

            for (var i = 0; i < linkTypes.length; i++) {
                if (linkTypes[i].sourceId == sourceId && linkTypes[i].targetId == targetId) {
                    linkTypes[i].joinType = src.innerText;
                    break;
                }
            }
            var menu = document.querySelector('.joinmenu');
            menu.style.top = '-300px';
            // 更新JSON显示
            updateJsonDisplay();
            e.preventDefault();
        });
    }
    function switchShow(obj,tableId,code)
    {
        var table= tables[tableId];
        table.fields.forEach(function (field) {
            if(field.code.toLowerCase()==code.toLowerCase())
            {
                field.show=obj.checked;
            }
        });
        // 更新JSON显示
        updateJsonDisplay();
    }
    // 添加表到工作区
    function addTable(name, code,type, fields, position) {
        tableCounter++;
        var tableId = "table-" + tableCounter;
        var tableName = name;
        var tableCode = code;
        var tableType = type;

        if(fields.length==0)
        {
            var url=document.location.href;
            url=url.addquerystring("act","getdata");
            url=url.addquerystring("code",code);
            $.ajax({
                type: 'get',
                async: false,
                url:  url,
                dataType: "json",
                success: function(data)
                {

                    fields=data;
                    availableTables.forEach(function (table) {
                        if(table.fields.length==0 && table.code.toLowerCase() == code.toLowerCase())
                        {
                            table.fields=data;
                        }
                    });
                }
            });	
        }

        // 创建表HTML
        var tableElement = document.createElement('div');
        tableElement.id = tableId;
        tableElement.className = 'table';

        // 位置
        var x = position ? position.x : Math.floor(Math.random() * 600);
        var y = position ? position.y : Math.floor(Math.random() * 300);

        x=x.toString().split(".")[0];
        y=y.toString().split(".")[0];

        tableElement.style.left = x + "px";
        tableElement.style.top = y + "px";

        // 表头
        var tableHeader = document.createElement('div');
        tableHeader.className = 'table-header';
        var text= tableName.length > 0 && tableName != tableCode ?  tableCode + " (" + tableName + ")" : tableCode ;
        tableHeader.innerHTML ="<div class=\"table-name\" code=\"" + tableCode + "\">" + text + "</div>" +
               "<div class=\"table-close\">×</div>";

        // 字段区域
        var tableFields = document.createElement('div');
        tableFields.className = 'table-fields-container';
        //console.log("fields",fields);
        fields.forEach(function (field) {
            
            var fieldElement = document.createElement('div');
            fieldElement.className = 'field';
            fieldElement.setAttribute("data-table", tableId);//增加
            fieldElement.setAttribute("data-field", field.name);//增加

            var fieldName = document.createElement('span');
            fieldName.addEventListener('clicked', function(e) {
                
                var src=getEventObject();
                e.stopPropagation();//阻止事件冒泡
                var obj=$(this);
                var par=$(this).parent();
                var tableId=par.attr("data-table");
                var code=par.attr("data-field");
                var table=tables[tableId];
                var fields=table["fields"];
                var field=null;
                fields.forEach(function(item) {
                    if(item.code.toLowerCase() == code.toLowerCase())
                    {
                        field=item;
                    }
                });
               
                if(src.tagName=="IMG")
                {
                    field.show= $(src).hasClass("selected") ? false : true;

                    if(field.show)
                    {
                        $(src).addClass("selected");
                    }
                    else
                    {
                        $(src).removeClass("selected");
                    }                  

                    updateJsonDisplay();  // 更新JSON显示
                    return true;
                }
               // alert(src.tagName);

                //alert(JSON.stringify(field));

                var html='<table border="0" cellspacing="0" cellpadding="8">';
                html+='<tr>';
                html+='<td colspan="2" style="border-bottom:1px solid #ccc;"><label><input type="checkbox" id="show" name="show" value="1"'+ (field.show ? ' checked="checked"' : '') +'>显示</label></td>';
                html+='</tr>';
                html+='<tr>';
                html+='<td width="60" style="border-bottom:1px solid #ccc;">别名</td>';
                html+='<td width="146" style="border-bottom:1px solid #ccc;"><input type="text" id="asname" name="asname" value="'+ field.asname +'" style="border:1px solid #ddd;padding:5px;"></td>';
                html+='</tr>';
                html+='<tr>';
                html+='<td style="border-bottom:1px solid #ccc;">条件</td>';
                html+='<td style="border-bottom:1px solid #ccc;"><input type="text" id="cond" name="cond" value="'+ field.cond.replace(/"/g, '&quot;').replace(/'/g, '&#39;') +'" style="border:1px solid #ddd;padding:5px;"></td>';
                html+='</tr>';
                html+='<tr>';
                html+='<td colspan="2" style="border-bottom:1px solid #ccc;"><label><input type="checkbox" id="group" name="group" value="1"'+ (field.group ? ' checked="checked"' : '') +'>分组</label></td>';
                html+='</tr>';


                html+='<tr>';
                html+='<td style="border-bottom:1px solid #ccc;">分组类型</td>';
                html+='<td style="border-bottom:1px solid #ccc;"><select id="grouptype" name="grouptype">';
                html+='<option value="">无</option>';
                html+='<option value="sum"'+ (field.grouptype=='sum' ? ' selected' : '') +'>sum</option>';
                html+='<option value="max"'+ (field.grouptype=='max' ? ' selected' : '') +'>max</option>';
                html+='<option value="min"'+ (field.grouptype=='min' ? ' selected' : '') +'>min</option>';
                html+='<option value="avg"'+ (field.grouptype=='avg' ? ' selected' : '') +'>avg</option>';
                html+='</select>';
                html+='</td>';


                html+='<tr>';
                html+='<td style="border-bottom:1px solid #ccc;">排序</td>';
                html+='<td style="border-bottom:1px solid #ccc;"><select id="order" name="order">';
                html+='<option value="">无</option>';
                html+='<option value="asc"'+ (field.order=='asc' ? ' selected' : '') +'>升序</option>';
                html+='<option value="desc"'+ (field.order=='desc' ? ' selected' : '') +'>降序</option>';
                html+='</select>';
                html+='</td>';
                html+='</tr>';
                html+='</table>';

                layer.open({
                    type: 1 //Page层类型
	                ,title:this.innerText
	                ,skin: 'layui-layer-prompt'
	                ,moveOut:true
	                ,shadeClose: true
                    ,btn:["确定","取消"]	
                    ,area : ["360px" , "360px"]  
                    ,content: html
                    //,content: '<div>地址：<input id="url" type="text" class="layui-layer-input" value="" onblur="flinkblur(this);" placeholder="连接地址">名称：<input style="margin-top:10px;" id="name" type="text" class="layui-layer-input" value="" placeholder="连接名称"></div>'
                    ,yes: function(index, layero){
                        field.show=$(layero).find("#show").get(0).checked;
                        if(field.show)
                        {
                            obj.find("img").addClass("selected");
                        }
                        else
                        {
                            obj.find("img").removeClass("selected");
                        }

                        field.asname=$(layero).find("#asname").val();
                        field.cond=$(layero).find("#cond").val();
                        field.group=$(layero).find("#group").get(0).checked;
                        field.grouptype=$(layero).find("#grouptype").val();

                        field.order=$(layero).find("#order").val();
                        obj.html('<img'+ (field.show ? ' class="selected"' : '' ) +' src="../images/none.gif" />' + field.code  + (field.asname.length>0 ? ' (' +  field.asname+  ')' : '') );
                        layer.close(index);                      
                        updateJsonDisplay();  // 更新JSON显示
                    }
                });




            });
            fieldName.addEventListener('click', function(e) {
                
                var src=getEventObject();
                e.stopPropagation();//阻止事件冒泡
                var obj=$(this);
                var par=$(this).parent();
                var tableId=par.attr("data-table");
                var code=par.attr("data-field");
                var table=tables[tableId];
                var fields=table["fields"];
                var field=null;
                fields.forEach(function(item) {
                    if(item.code.toLowerCase() == code.toLowerCase())
                    {
                        field=item;
                    }
                });
               
                if(src.tagName=="IMG")
                {
                    field.show= $(src).hasClass("selected") ? false : true;

                    if(field.show)
                    {
                        $(src).addClass("selected");
                    }
                    else
                    {
                        $(src).removeClass("selected");
                    }                  
                    changeIndex();
                    updateJsonDisplay();  // 更新JSON显示
                    return true;
                }
                // alert(src.tagName);

                //alert(JSON.stringify(field));

                var html='<table width="100%" border="0" cellspacing="0" cellpadding="8">';
                html+='<colgroup>';
                html+='<col width="130" />';
                html+='<col width="150" />';
                html+='<col width="150" />';
                html+='<col width="80" />';
                html+='<col width="100" />';
                html+='<col width="90" />';
                html+='</colgroup>';
                html+='<thead>';
                html+='<tr>';
                html+='<td style="border-bottom:1px solid #ccc;" width="80">字段</td>';
                html+='<td style="border-bottom:1px solid #ccc;">别名</td>';
                html+='<td style="border-bottom:1px solid #ccc;">条件</td>';
                html+='<td style="border-bottom:1px solid #ccc;">分组</td>';
                html+='<td style="border-bottom:1px solid #ccc;">分组方式</td>';
                html+='<td style="border-bottom:1px solid #ccc;">排序</td>';
                html+='</tr>';
                html+='</thead>';
                html+='<tbody>';
                fields.forEach(function(item) {
                    html+='<tr data-field="'+ item.code +'">';
                    html+='<td style="border-bottom:1px solid #ccc;"><label><input type="checkbox" id="show" name="show" value="1"'+ (item.show ? ' checked="checked"' : '') +'>'+  item.code  + (item.asname.length>0 ? ' (' +  item.asname+  ')' : '')  +'</label></td>';
                    html+='<td style="border-bottom:1px solid #ccc;"><input type="text" id="asname" name="asname" value="'+ item.asname +'" style="width:100%;border:1px solid #ddd;padding:5px;"></td>';
                    html+='<td style="border-bottom:1px solid #ccc;"><input type="text" id="cond" name="cond" value="'+ item.cond.replace(/"/g, '&quot;').replace(/'/g, '&#39;') +'" style="width:100%;border:1px solid #ddd;padding:5px;"></td>';
                    html+='<td style="border-bottom:1px solid #ccc;"><label><input type="checkbox" id="group" name="group" value="1"'+ (item.group ? ' checked="checked"' : '') +'>分组</label></td>';
                    html+='<td style="border-bottom:1px solid #ccc;">';
                    html+='<select id="grouptype" name="grouptype">';
                    html+='<option value="">无</option>';
                    html+='<option value="sum"'+ (item.grouptype=='sum' ? ' selected' : '') +'>sum</option>';
                    html+='<option value="max"'+ (item.grouptype=='max' ? ' selected' : '') +'>max</option>';
                    html+='<option value="min"'+ (item.grouptype=='min' ? ' selected' : '') +'>min</option>';
                    html+='<option value="avg"'+ (item.grouptype=='avg' ? ' selected' : '') +'>avg</option>';
                    html+='</select>';
                    html+='</td>';
                    html+='<td style="border-bottom:1px solid #ccc;"><select id="order" name="order">';
                    html+='<option value="">无</option>';
                    html+='<option value="asc"'+ (item.order=='asc' ? ' selected' : '') +'>升序</option>';
                    html+='<option value="desc"'+ (item.order=='desc' ? ' selected' : '') +'>降序</option>';
                    html+='</select>';
                    html+='</td>';
                    html+='</tr>';
                });
                html+='</tbody>';
                html+='</table>';

                layer.open({
                    type: 1 //Page层类型
	                ,title:tables[tableId].code
	                ,skin: 'layui-layer-prompt'
	                ,moveOut:true
	                ,shadeClose: true
                    ,btn:["确定","取消"]	
                    ,area : ["900px" , "70%"]  
                    ,content: html
                    ,yes: function(index, layero){

                        $(layero).find("tbody tr").each(function(index, el) {
                            var tr=$(this);
                            var _code=tr.attr("data-field");
                            fields.forEach(function(item) {
                                if(item.code.toLowerCase() == _code.toLowerCase())
                                {
                                    item.show = tr.find("#show").get(0).checked;
                                    if(item.show)
                                    {
                                        $("div[data-table='"+ tableId +"'][data-field='"+ _code +"'] img").addClass("selected");
                                    }
                                    else
                                    {
                                        $("div[data-table='"+ tableId +"'][data-field='"+ _code +"'] img").removeClass("selected");
                                    }
                                    item.asname = tr.find("#asname").val();
                                    if(item.asname.length==0)
                                    {
                                        $("div[data-table='"+ tableId +"'][data-field='"+ _code +"'] .field-name span").html(_code);
                                    }
                                    else
                                    {
                                        $("div[data-table='"+ tableId +"'][data-field='"+ _code +"'] .field-name span").html(_code + " (" +item.asname + ")");
                                    }
                                    item.cond = tr.find("#cond").val();
                                    item.order = tr.find("#order").val();
                                    item.group = tr.find("#group").get(0).checked;
                                    item.grouptype = tr.find("#grouptype").val();
                                }
                            });

                        });
                        layer.close(index);
                        updateJsonDisplay();  // 更新JSON显示
                        changeIndex();
                    }
                });




            });
            fieldName.className = 'field-name';
           // if(field.show) fieldName.className +=" field-nameselected";
            //fieldName.textContent = field.name;

            var text=field.name.length > 0 && field.name != field.code ?  field.name + " (" + field.code + ")" : field.code ;
            if(field.name == field.code && field.asname.length > 0) 
            {
                text= field.code +  " (" + field.asname + ")";
            }

           // fieldName.innerHTML='<label><input type="checkbox" name="checkbox" value="0" onchange="switchShow(this,\''+ tableId +'\',\''+ field.code +'\');"'+ (field.show? ' checked="checked"' : '') +' />'+ text +'</label>';
            fieldName.innerHTML='<img'+ (field.show ? ' class="selected"' : '' ) +' src="../images/none.gif" /><span>' + text+ '</span>';

            var fieldType = document.createElement('span');
            fieldType.className = 'field-type';
            fieldType.textContent = field.type;

            fieldElement.appendChild(fieldName);
            fieldElement.appendChild(fieldType);
            tableFields.appendChild(fieldElement);
        });

        // 端点容器
        var leftEndpoints = document.createElement('div');
        leftEndpoints.className = 'endpoints left-endpoints';

        var rightEndpoints = document.createElement('div');
        rightEndpoints.className = 'endpoints right-endpoints';

        // 组装表
        tableElement.appendChild(tableHeader);
        tableElement.appendChild(tableFields);
        tableElement.appendChild(leftEndpoints);
        tableElement.appendChild(rightEndpoints);

        // 添加到编辑器
        document.getElementById('editor-container').appendChild(tableElement);

        tableElement.addEventListener('click', function (e) {

            $(".table").removeClass("tableselected");
            $(this).addClass("tableselected");
            selectedTable = this;
            //e.preventDefault();
            e.stopPropagation();//阻止事件冒泡
        });
        //

        // 存储表数据
        tables[tableId] = {
            id: tableId,
            name: tableName,
            code: tableCode,
            type: tableType,
            fields: fields,
            position: { x: x, y: y }
        };
        // 使表可拖拽
        jsPlumbInstance.draggable(tableId, {
            containment: false,//禁止超出容器
            drag: function (params) {
                updateTableLinks();//更新表与表的联合类型
            },
            stop: function () {
                // 更新表位置
                var rect = tableElement.getBoundingClientRect();
                var containerRect = document.getElementById('editor-container').getBoundingClientRect();

                var nx=rect.left - containerRect.left;
                nx=nx.toString().split(".")[0];
                var ny=rect.top - containerRect.top;
                ny=ny.toString().split(".")[0];
                tables[tableId].position = {
                    x: parseInt(nx),
                    y: parseInt(ny)
                };
                updateTableLinks();//更新表与表的联合类型
                // 更新JSON显示
                updateJsonDisplay();
            }
        });

        // 添加端点
        //setTimeout(function(){
        addEndpoints(tableId, fields);
        //},500);


        // 添加关闭按钮事件
        var closeBtn = tableElement.querySelector('.table-close');
        closeBtn.addEventListener('click', function () {
            removeTable(tableId);
        });

        // 更新JSON显示
        updateJsonDisplay();

        return tableId;
    }


    // 移除表 - 修复端点删除问题

    function removeTable(tableId) {
        if (!tables[tableId]) return;
        Object.keys(connections).forEach(function (key) {
            var conn = connections[key];
            if (conn.sourceId == tableId || conn.targetId == tableId) {
                delete connections[key];
            }
        });
        for (var i = linkTypes.length - 1; i >= 0; i--) {
            var _link = linkTypes[i];
            if (_link.sourceId == tableId || _link.targetId == tableId) {
                var labelid = "txt_" + _link.sourceId + "_" + _link.targetId;
                var tmp = document.getElementById(labelid);
                if (tmp == null) {
                    labelid = "txt_" + _link.targetId + "_" + _link.sourceId;
                    tmp = document.getElementById(labelid);
                }
                if (tmp) { tmp.remove(); }
                linkTypes.splice(i, 1);
            }
        }
        //txtLabel txt_table-1_table-2
        // 移除表的可拖拽功能
        jsPlumbInstance.draggable(tableId, "destroy");
        // 从DOM中删除表
        var tableElement = document.getElementById(tableId);
        var leftElements = tableElement.querySelectorAll('.left-endpoints .endpoint');
        for (var i = leftElements.length - 1; i >= 0; i--) {
            var field = leftElements[i];
            var endpoints = jsPlumbInstance.getEndpoints(field.id);
            endpoints.forEach(function (endpoint) {
                //jsPlumbInstance.deleteEndpoint(endpoint);
                //jsPlumbInstance.removeEndpoint(endpoint);
            });
            //field.remove();
        }



        if (tableElement) {
            jsPlumbInstance.remove(tableElement);
            tableElement.remove();
        }
        //删除最大ID时，重新初始ID
        var num = parseInt(tableId.replace("table-", ""));
        if (num == tableCounter) { tableCounter--; }

        // 从数据中删除表
        delete tables[tableId];
        // 如果选中的连接属于被删除的表，清除选中状态
        if (selectedConnection &&
            (selectedConnection.endpoints[0].getElement().id === tableId ||
             selectedConnection.endpoints[1].getElement().id === tableId)) {
            selectedConnection = null;
        }
        if (Object.keys(tables).length == 0) {
            tableCounter = 0;
        }
        updateTableLinks();//更新表与表的联合类型
        // 更新JSON显示
        updateJsonDisplay();
    }


    // 添加端点（简化版 - 移除端点标签）
    function addEndpoints(tableId, fields) {
        var tableElement = document.getElementById(tableId);
        var leftEndpoints = tableElement.querySelector('.left-endpoints');
        var rightEndpoints = tableElement.querySelector('.right-endpoints');

        // 清空现有端点
        leftEndpoints.innerHTML = '';
        rightEndpoints.innerHTML = '';

        // 获取字段元素
        var fieldElements = tableElement.querySelectorAll('.field');
        // 添加左侧端点和右侧端点
        fieldElements.forEach(function (fieldElement, index) {
            var field = fields[index];

            // 计算字段在表中的垂直位置（居中）
            var fieldRect = fieldElement.getBoundingClientRect();
            var tableRect = tableElement.getBoundingClientRect();
            var fieldCenterY = (fieldRect.top + fieldRect.bottom) / 2 - tableRect.top;
            var relativeY = fieldCenterY / tableRect.height;

            // 创建左侧端点

            var rndleftEndpointId = tableId + "-left-" + fieldElement.getAttribute('data-field') + Date.now();
            var leftEndpointId = tableId + "-left-" + fieldElement.getAttribute('data-field');


            var leftEndpoint = document.createElement('div');
            leftEndpoint.id = rndleftEndpointId;
            leftEndpoint.setAttribute('data-id', leftEndpointId);
            leftEndpoint.setAttribute('data-table', fieldElement.getAttribute('data-table'));
            leftEndpoint.setAttribute('data-field', fieldElement.getAttribute('data-field'));
            leftEndpoint.className = 'endpoint';
            leftEndpoint.style.top = (fieldCenterY - 6) + "px";
            leftEndpoints.appendChild(leftEndpoint);


            jsPlumbInstance.addEndpoint(rndleftEndpointId, {
                //anchor: [0, relativeY, -1, 0],
                //anchor: "Left",
                anchor: [0, 0.5, 0, 0, 7, 1],
                endpoint: "Dot",
                isSource: true,
                isTarget: true,
                //uuid: "left-" + Date.now(),
                maxConnections: -1,
                multipleDrop: true, // 只允许一个连接点被拖动到这个端点上。
                paintStyle: { fill: "#2ecc71", radius: 6 }//e74c3c
            }, { id: leftEndpointId }
            );


            // 创建右侧端点
            var rndrightEndpointId = tableId + "-right-" + fieldElement.getAttribute('data-field') + Date.now();
            var rightEndpointId = tableId + "-right-" + fieldElement.getAttribute('data-field');
            //tmp=document.getElementById(rightEndpointId);
            //if(tmp){tmp.remove(); alert("2:" + rightEndpointId);}		

            var rightEndpoint = document.createElement('div');
            rightEndpoint.id = rndrightEndpointId;
            rightEndpoint.setAttribute('data-id', rightEndpointId);
            rightEndpoint.setAttribute('data-table', fieldElement.getAttribute('data-table'));
            rightEndpoint.setAttribute('data-field', fieldElement.getAttribute('data-field'));
            rightEndpoint.className = 'endpoint';
            rightEndpoint.style.top = (fieldCenterY - 6) + "px";
            rightEndpoints.appendChild(rightEndpoint);
            //alert(rightEndpointId);
            // 添加jsPlumb右侧端点
            // tableId + "-right-" + index;
            //jsPlumbInstance.deleteEndpoint(rightEndpointId);
            jsPlumbInstance.addEndpoint(rndrightEndpointId, {
                //anchor: [1, relativeY, 1, 0],
                anchor: [0, 0.5, 0, 0, 7, 1],
                endpoint: "Dot",
                isSource: true,
                isTarget: true,
                //uuid: "right-" + Date.now(),
                maxConnections: -1,
                multipleDrop: true, // 只允许一个连接点被拖动到这个端点上。
                paintStyle: { fill: "#2ecc71", radius: 6 }//e74c3c
            }, { id: rightEndpointId }
            );

            //jsPlumbInstance.revalidate(leftEndpointId);//强制重新计算元素位置


        });
        //jsPlumbInstance.repaintEverything();
    };


    //更新表与表的联合类型
    function updateTableLinks() {
        var svg = document.getElementById('tableConnections');
        svg.innerHTML = '';
        for (var i = 0; i < linkTypes.length; i++) {
            var sourceTable = document.getElementById(linkTypes[i].sourceId);
            var targetTable = document.getElementById(linkTypes[i].targetId);
            if (sourceTable && targetTable) {
                var sourceRect = sourceTable.getBoundingClientRect();
                var targetRect = targetTable.getBoundingClientRect();
                var svgRect = svg.getBoundingClientRect();

                var sourceX = sourceRect.left + sourceRect.width - svgRect.left;
                var sourceY = sourceRect.top + 20 - svgRect.top;//sourceRect.top + sourceRect.height / 2 - svgRect.top;
                var targetX = targetRect.left - svgRect.left;
                var targetY = targetRect.top + 20 - svgRect.top;//targetRect.top + targetRect.height / 2 - svgRect.top;

                // 绘制连线
                var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
                var midX = (sourceX + targetX) / 2;

                path.setAttribute("d", "M " + sourceX + " " + sourceY + " C " + midX + " " + sourceY + ", " + midX + " " + targetY + ", " + targetX + " " + targetY);
                path.setAttribute("class", "table-connection");
                path.setAttribute("fill", "none");
                path.setAttribute("stroke-dasharray", "5,5");

                svg.appendChild(path);


                // 添加连接标签
                var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
                text.setAttribute("x", midX);
                text.setAttribute("y", (sourceY + targetY) / 2 - 10);
                text.setAttribute("text-anchor", "middle");
                text.setAttribute("font-size", "12");
                text.setAttribute("fill", "#3498db");
                text.textContent = "joinType";
                //svg.appendChild(text);

                var labelid = "txt_" + linkTypes[i].sourceId + "_" + linkTypes[i].targetId;

                var label = document.getElementById(labelid);
                if (!label) {
                    label = document.createElement("div");
                    label.id = labelid;
                    label.setAttribute("sourceId", linkTypes[i].sourceId);
                    label.setAttribute("targetId", linkTypes[i].targetId);


                    //alert(linkTypes[i].joinType);
                    label.style.left = midX + "px";
                    label.style.top = ((sourceY + targetY) / 2 - 10) + "px";
                    label.innerHTML = linkTypes[i].joinType;
                    label.className = "txtLabel";
                    // 添加点击事件以编辑连接类型
                    label.addEventListener('click', function (e) {
                        e.stopPropagation();
                        //showJoinTypeSelector(connection.id, e.clientX, e.clientY);
                        var menu = document.querySelector('.joinmenu');
                        menu.style.left = (e.clientX - menu.offsetWidth) + 'px';
                        menu.style.top = (e.clientY + 10 + ($(".eLayout_top_fixed").length > 0 ? -66 : 0)) + 'px';
                        //menu.style.top = (e.clientY + 10) + 'px';
                        window.elabel = this;
                        //alert(sourceTable + ":" + targetTable);
                    });
                    document.getElementById('editor-container').appendChild(label);

                }
                else {
                    label.style.left = midX + "px";
                    label.style.top = ((sourceY + targetY) / 2 - 10) + "px";
                }

            }
        }
    };

    function checkTableLink(sourceId, targetId) {
        var snum = parseInt(sourceId.replace("table-", ""));
        var tnum = parseInt(targetId.replace("table-", ""));
        if (snum > tnum) {
            var tmp = sourceId;
            sourceId = targetId;
            targetId = tmp;
        }
        var has = false;

        for (var i = 0; i < linkTypes.length; i++) {
            if (linkTypes[i].sourceId == sourceId && linkTypes[i].targetId == targetId) {
                has = true;
                break;
            }
        }
        if (!has) {
            linkTypes.push({ sourceId: sourceId, targetId: targetId, joinType: "inner join" });
        }
        updateTableLinks();//更新表与表的联合类型
    };



    // 点击空白区域取消选中
    document.getElementById('editor-container').addEventListener('click', function (e) {
        if (e.target === this) {
            if (selectedConnection) {
                selectedConnection.removeClass("selected");
                selectedConnection = null;
            }
        }
    });

    // 删除键处理
    document.addEventListener('keyup', function (e) {

        if (e.key === 'Delete' && selectedConnection) {
            var connectionId = selectedConnection.id;
            //更新表与表之间的线
            var conn = connections[connectionId];
            var ct = 0;
            Object.keys(connections).forEach(function (conid) {
                if (connections[conid].sourceId == conn.sourceId && connections[conid].targetId == conn.targetId) {
                    ct++;
                }
            });
            if (ct == 1) {
                for (var i = linkTypes.length - 1; i >= 0; i--) {
                    if (linkTypes[i].sourceId == conn.sourceId && linkTypes[i].targetId == conn.targetId) {
                        var labelid = "txt_" + linkTypes[i].sourceId + "_" + linkTypes[i].targetId;
                        document.getElementById(labelid).remove();
                        //delete linkTypes[i];
                        linkTypes.splice(i, 1);
                    }
                }
            }
            updateTableLinks();//更新表与表的联合类型

            // 删除连接
            jsPlumbInstance.deleteConnection(selectedConnection);

            // 从连接数据中移除
            delete connections[connectionId];

            // 清除选中状态
            selectedConnection = null;

            // 更新JSON显示
            updateJsonDisplay();
        }

    });
    //改变字段顺序
    function changeIndex()
    {
        $("#show-fields li").remove();
        $("#cond-fields li").remove();
        $("#order-fields li").remove();
        var showctrls = new Array();//显示
        var condctrls = new Array();//条件
        var orderctrls = new Array();//排序
        Object.values(tables).forEach(function(table) 
        {
            for(var i=0;i<table.fields.length;i++)
            {
                if(table.fields[i]["show"])
                {
                    if(table.fields[i].showindex.length==0)
                    {
                        table.fields[i].showindex="99";
                    }
                    var showli = document.createElement('li');
                    showli.innerHTML = table.fields[i].code + ( table.fields[i].asname.length>0 ? ' ('+  table.fields[i].asname +')' : '');
                    showli.setAttribute("data-id", table.id);//增加
                    showli.setAttribute("data-code", table.fields[i].code);//增加
                    showli.setAttribute("showindex",  parseInt(table.fields[i].showindex));//增加
                    showctrls.push(showli);
                }
                if(table.fields[i]["cond"].length>0)
                {
                    if(table.fields[i].condindex.length==0)
                    {
                        table.fields[i].condindex="99";
                    }
                    var condli = document.createElement('li');
                    condli.innerHTML = table.fields[i].code + ( table.fields[i].asname.length>0 ? ' ('+  table.fields[i].asname +')' : '');
                    condli.setAttribute("data-id", table.id);//增加
                    condli.setAttribute("data-code", table.fields[i].code);//增加
                    condli.setAttribute("condindex",   parseInt(table.fields[i].condindex));//增加
                    condctrls.push(condli);
                }
                if(table.fields[i]["order"].length>0)
                {
                    if(table.fields[i].orderindex.length==0)
                    {
                        table.fields[i].orderindex="99";
                    }
                    var orderli = document.createElement('li');
                    orderli.innerHTML = table.fields[i].code + ( table.fields[i].asname.length>0 ? ' ('+  table.fields[i].asname +')' : '');
                    orderli.setAttribute("data-id", table.id);//增加
                    orderli.setAttribute("data-code", table.fields[i].code);//增加
                    orderli.setAttribute("orderindex",   parseInt(table.fields[i].orderindex));//增加
                    orderctrls.push(orderli);
                }
            }
        });
        showctrls = showctrls.sort(function (a, b) {return $(a).attr('showindex') -  $(b).attr('showindex') ;});
        condctrls = condctrls.sort(function (a, b) {return  $(a).attr('condindex') -  $(b).attr('condindex') ;});
        orderctrls = orderctrls.sort(function (a, b) {return $(a).attr('orderindex') -  $(b).attr('orderindex');});
        $.each(showctrls, function (index, el) {$("#show-fields").append(el);});
        $.each(condctrls, function (index, el) {$("#cond-fields").append(el);});
        $.each(orderctrls, function (index, el) {$("#order-fields").append(el);});
        $("#show-fields li").arrangeable2({
            dragEnd: function () {
                $('#show-fields li').each(function(i,el)
                {
                    var tableId=$(this).attr("data-id");
                    var code=$(this).attr("data-code");
                    var table=tables[tableId];
                    var fields=table["fields"];
                    fields.forEach(function(item) {
                        if(item.code.toLowerCase() == code.toLowerCase())
                        {
                            item["showindex"]=i+1;
                        }
                    });
                });
                updateJsonDisplay();
            }
        });
        $("#cond-fields li").arrangeable2({
            dragEnd: function () {
                $('#cond-fields li').each(function(i,el)
                {
                    var tableId=$(this).attr("data-id");
                    var code=$(this).attr("data-code");
                    var table=tables[tableId];
                    var fields=table["fields"];
                    fields.forEach(function(item) {
                        if(item.code.toLowerCase() == code.toLowerCase())
                        {
                            item["condindex"]=i+1;
                        }
                    });
                });
                updateJsonDisplay();
            }
        });
        $("#order-fields li").arrangeable2({
            dragEnd: function () {
                $('#order-fields li').each(function(i,el)
                {
                    var tableId=$(this).attr("data-id");
                    var code=$(this).attr("data-code");
                    var table=tables[tableId];
                    var fields=table["fields"];

                    fields.forEach(function(item) {
                        if(item.code.toLowerCase() == code.toLowerCase())
                        {
                            item["orderindex"]=i+1;
                        }
                    });
                    //alert($(this).attr("data-id"));
                });
                updateJsonDisplay();
            }
        });
    };
    // 更新JSON显示
    function updateJsonDisplay() 
    {
        //alert( JSON.stringify(tables));
        var data = {
            tables: tables,
            linkTypes: linkTypes,
            connections: connections
        };
        var outobj=document.getElementById('json-data');
        if(outobj)
        {
            outobj.textContent = JSON.stringify(data, null, 2);
        }       
        if(!loaded){return;}
       
        var url = document.location.href;
        url = url.addquerystring("act", "update");
        $.ajax({
            type: 'post',
            url: url,
            data: { json: JSON.stringify(data) },
            dataType: "json",
            success: function (data) {
                if(data.resultTable)
                {
                    $("#resultTable").html(data.resultTable);
                }
                if(data.tempSql)
                {
                    $("#tempSql").html(data.tempSql);
                }
            }
        });
        //alert(JSON.stringify(data, null, 2));
      
    }

    // 导出JSON
    document.getElementById('export-json').addEventListener('click', function () {
        var data = {
            tables: tables,
            linkTypes: linkTypes,
            connections: connections
        };

        var jsonString = JSON.stringify(data, null, 2);
        var blob = new Blob([jsonString], { type: 'application/json' });
        var url = URL.createObjectURL(blob);

        var a = document.createElement('a');
        a.href = url;
        a.download = 'database-relationships.json';
        a.click();

        URL.revokeObjectURL(url);
    });

    // 导入JSON
    document.getElementById('import-json').addEventListener('click', function () {
        var jsonData = prompt("请输入JSON数据:");
        if (jsonData) {
            try {
                importJson(JSON.parse(jsonData));
            } catch (e) {
                alert("JSON格式错误!");
            }
        }
    });

    // 导入JSON
    function importJson(data) {
        isImport = true;
        // 清空当前状态
        clearAll();

        // 恢复表
        if (data.tables) {
            Object.values(data.tables).forEach(function (table) 
            {
                for(var i=0;i<table.fields.length;i++)
                {
                    //无字段增加
                    if(typeof(table.fields[i]["showindex"])=="undefined")
                    {
                        table.fields[i]["showindex"]=999;
                    }
                    if(typeof(table.fields[i]["condindex"])=="undefined")
                    {
                        table.fields[i]["condindex"]=999;
                    }
                    if(typeof(table.fields[i]["orderindex"])=="undefined")
                    {
                        table.fields[i]["orderindex"]=999;
                    }
                    if(typeof(table.fields[i]["group"])=="undefined")
                    {
                        table.fields[i]["group"]=false;
                    }
                    if(typeof(table.fields[i]["grouptype"])=="undefined")
                    {
                        table.fields[i]["grouptype"]="";
                    }
                    
                }
                addTable(table.name, table.code, (typeof(table.type)=="string" ? table.type : "table"), table.fields, table.position);
            });
        }
        if (data.linkTypes) {
            for (var i = 0; i < data.linkTypes.length; i++) {
                linkTypes.push({ sourceId: data.linkTypes[i].sourceId, targetId: data.linkTypes[i].targetId, joinType: data.linkTypes[i].joinType });
            }

        }

        if (data.connections) {

            Object.values(data.connections).forEach(function (conn) {

                var sourceTable = document.getElementById(conn.sourceId);
                var targetTable = document.getElementById(conn.targetId);


                //按位置
                var sourcepoint =  parseFloat(tables[conn.sourceId].position.x) < parseFloat(tables[conn.targetId].position.x) ? "right" : "left";
                var targetpoint = parseFloat(tables[conn.sourceId].position.x) < parseFloat(tables[conn.targetId].position.x) ? "left" : "right";

 

                var sourceField = sourceTable.querySelectorAll('[data-id="' + conn.sourceId + '-' + sourcepoint + '-' + conn.sourceField + '"]');
                var targetField = targetTable.querySelectorAll('[data-id="' + conn.targetId + '-' + targetpoint + '-' + conn.targetField + '"]');
                if (sourceField && targetField) {
                    var connection = jsPlumbInstance.connect({
                        source: sourceField,
                        target: targetField,
                        id: conn.id,
                        anchor: [[0, 0.5, 0, 0, 7, 1], [0, 0.5, 0, 0, 7, 1]]
                    });
                    connection.id = conn.id;
                }


                connections[conn.id] = {
                    id: conn.id,
                    sourceId: conn.sourceId,
                    targetId: conn.targetId,
                    //sourceName: tables[conn.sourceId].name,
                    //targetName: tables[conn.targetId].name,
                    //sourceCode: tables[conn.sourceId].code,
                    //targetCode: tables[conn.targetId].code,
                    sourceField: conn.sourceField,
                    targetField: conn.targetField
                };
            });

        }
        isImport = false;
        updateTableLinks();//更新表与表的联合类型
        updateJsonDisplay();
    };

    // 清空所有
    document.getElementById('clear-all').addEventListener('click', function () {
        if (confirm("确定要清空工作区吗?")) {
            clearAll();
        }
    });

    // 清空工作区 - 修复端点删除问题
    function clearAll() {




        // 删除所有连接
        jsPlumbInstance.deleteEveryConnection();



        Object.keys(tables).forEach(function (tableId) {

            var tableElement = document.getElementById(tableId);
            var leftElements = tableElement.querySelectorAll('.left-endpoints .endpoint');
            for (var i = leftElements.length - 1; i >= 0; i--) {
                var field = leftElements[i];
                var endpoints = jsPlumbInstance.getEndpoints(field.id);
                endpoints.forEach(function (endpoint) {
                    jsPlumbInstance.deleteEndpoint(endpoint);
                });
            }


            var rightElements = tableElement.querySelectorAll('.right-endpoints .endpoint');
            rightElements.forEach(function (field) {
                var endpoints = jsPlumbInstance.getEndpoints(field.id);
                endpoints.forEach(function (endpoint) {
                    jsPlumbInstance.deleteEndpoint(endpoint);
                });
            });
        });
        // 删除所有表
        document.getElementById('editor-container').innerHTML = '<svg id="tableConnections" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;"></svg>';//SVG也会被删除


        // 重置数据
        Object.keys(tables).forEach(function (key) { delete tables[key]; });
        Object.keys(connections).forEach(function (key) { delete connections[key]; });

        for (var i = linkTypes.length - 1; i >= 0; i--) {
            linkTypes.splice(i, 1);
        }

        initializeJsPlumb();
        // 重置计数器
        tableCounter = 0;
        // 清除选中状态
        selectedConnection = null;
        updateTableLinks();//更新表与表的联合类型
        // 更新JSON显示
        updateJsonDisplay();
    }

    // 初始化搜索功能
    document.getElementById('search-tables').addEventListener('input', function (e) {
        var searchTerm = e.target.value.toLowerCase();
        var tableItems = document.querySelectorAll('.table-item');

        tableItems.forEach(function (item) {
            var code = item.getAttribute("data-code").toLowerCase();
            var name = item.getAttribute("data-name").toLowerCase();
            if (code.indexOf(searchTerm) !== -1 || name.indexOf(searchTerm) !== -1) {
                item.style.display = 'block';
            } else {
                item.style.display = 'none';
            }
        });
    });

    // 初始化应用
    window.onload = function () {
      
        initializeJsPlumb();
        initTableList();
        initDropZone();

        // 添加示例表到工作区
        //addTable("用户表", availableTables[0].code, availableTables[0].fields, { x: 100, y: 100 });
        //addTable("订单表", availableTables[1].code, availableTables[1].fields, { x: 400, y: 100 });
        var data =<%=record.relationJson%>;

        //console.log("data",data);
        importJson(data);
        loaded=true;
        //显示列的顺序
        changeIndex();
    };

    </script>

</asp:Content>