huawei
20 小时以前 f0e4fa93666206c4af4a654c43148915d934c6ef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
using DevExpress.Data;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;
using Gs.DevApp.Entity;
using Gs.DevApp.ToolBox;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
 
namespace Gs.DevApp.DevFrm.Sys
{
    /// <summary>
    /// 看板目录管理 - 树形结构维护界面(用户控件)
    /// </summary>
    public partial class SimpleKanBan : DevExpress.XtraEditors.XtraUserControl
    {
        private string _webServiceName = "MesSimpleManager/";
 
        public SimpleKanBan()
        {
            InitializeComponent();
 
            // 工具栏事件绑定
            toolBarMenu1.btnLoadClick += ToolBarMenu1_btnLoadClick;
            toolBarMenu1.btnQueryClick += ToolBarMenu1_btnQueryClick;
            // TreeList 行号显示
            tlMenu.IndicatorWidth = 50;
            tlMenu.CustomDrawNodeIndicator += (s, ee) =>
            {
                if (ee.IsNodeIndicator)
                {
                    var index = ee.Node.TreeList.GetVisibleIndexByNode(ee.Node);
                    ee.Info.DisplayText = (index + 1).ToString();
                }
            };
 
            // 初始化加载数据
            getPageList();
 
            // 右键菜单事件
            tlMenu.MouseDown += TlMenu_MouseDown;
 
            // 增加子项
            toolStripMenuItemAdd.Click += (s, ee) =>
            {
                string strGuid = "";
                string strUpGuid = "";
                if (tlMenu.FocusedNode != null)
                {
                    strUpGuid = tlMenu.FocusedNode.GetValue("id").ToString();
                }
                SimpleKanBanEdit frm = new SimpleKanBanEdit(strGuid, strUpGuid);
                frm.UpdateParent += (s2, ee2) =>
                {
                    getPageList();
                    TreeListNode node = tlMenu.FindNodeByKeyID(long.Parse(strUpGuid));
                    if (node != null)
                    {
                        node.Expanded = true;
                        tlMenu.MakeNodeVisible(node);
                    }
                };
                frm.ShowDialog();
            };
 
            // 增加主项(根节点)
            toolStripMenuItemRoot.Click += (s, ee) =>
            {
                string strGuid = "";
                string strUpGuid = "";
                SimpleKanBanEdit frm = new SimpleKanBanEdit(strGuid, strUpGuid);
                frm.UpdateParent += (s2, ee2) =>
                {
                    getPageList();
                };
                frm.ShowDialog();
            };
 
            // 删除节点
            toolStripMenuItemDel.Click += (s, ee) =>
            {
                if (tlMenu.FocusedNode != null)
                {
                    string rowGuid = "";
                    string rowName = "";
                    rowGuid = tlMenu.FocusedNode.GetValue("id").ToString();
                    rowName = tlMenu.FocusedNode.GetValue("title").ToString();
                    if (string.IsNullOrEmpty(rowGuid))
                    {
                        MsgHelper.Warning("请先选择你要操作的行!");
                        return;
                    }
                    if (!MsgHelper.AskQuestion("你选择了【" + rowName + "】,确定删除吗?"))
                        return;
                    List<dynamic> lst = new List<dynamic>();
                    lst.Add(rowGuid);
                    try
                    {
                        string strJson = UtilityHelper.HttpPost("", _webServiceName + "DeleteModel", JsonConvert.SerializeObject(lst));
                        ReturnModel<dynamic> _rtn = UtilityHelper.ReturnToDynamic(strJson);
                        if (_rtn.rtnCode > 0)
                        {
                            tlMenu.DeleteNode(tlMenu.FocusedNode);
                        }
                        else
                            MsgHelper.ShowError("提示:" + _rtn.rtnMsg);
                    }
                    catch (Exception ex)
                    {
                        MsgHelper.ShowError("提示:" + ex.Message);
                    }
                }
            };
            // 创建刷新菜单项
            ToolStripMenuItem toolStripMenuItemRefresh = new ToolStripMenuItem();
            toolStripMenuItemRefresh.Text = "刷新";
            toolStripMenuItemRefresh.Click += ToolBarMenu1_btnLoadClick; // 直接调用已有刷新事件
 
            // 添加到右键菜单,不清空原有 Items
            cms1.Items.Add(toolStripMenuItemRefresh);
 
            // 编辑节点
            toolStripMenuItemEdt.Click += (s, ee) =>
            {
                string strGuid = "";
                string strUpGuid = "";
                if (tlMenu.FocusedNode != null)
                {
                    strGuid = tlMenu.FocusedNode.GetValue("id").ToString();
                    var fidValue = tlMenu.FocusedNode.GetValue("parentId");
                    strUpGuid = fidValue != null ? fidValue.ToString() : "";
                }
                SimpleKanBanEdit frm = new SimpleKanBanEdit(strGuid, strUpGuid);
                frm.UpdateParent += (s2, ee2) =>
                {
                    getPageList();
                    TreeListNode node = tlMenu.FindNodeByKeyID(long.Parse(strGuid));
                    if (node != null)
                    {
                        node.Expanded = true;
                        tlMenu.MakeNodeVisible(node);
                    }
                };
                frm.ShowDialog();
            };
        }
 
        /// <summary>
        /// 查询事件
        /// </summary>
        private void ToolBarMenu1_btnQueryClick(object sender, EventArgs e)
        {
            MsgHelper.ShowInformation("该窗体不支持查询,若想更新页面,请点击 刷新");
        }
 
        /// <summary>
        /// 刷新事件
        /// </summary>
        private void ToolBarMenu1_btnLoadClick(object sender, EventArgs e)
        {
            getPageList();
            MsgHelper.ShowInformation("刷新成功!");
        }
        /// <summary>
        /// 右键弹出菜单
        /// </summary>
        private void TlMenu_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                TreeListHitInfo hInfo = tlMenu.CalcHitInfo(new Point(e.X, e.Y));
                TreeListNode node = hInfo.Node;
                tlMenu.FocusedNode = node;
                if (hInfo.HitInfoType == HitInfoType.Cell ||
                    hInfo.HitInfoType == HitInfoType.Row ||
                    hInfo.HitInfoType == HitInfoType.RowIndent ||
                    hInfo.HitInfoType == HitInfoType.RowIndicator)
                {
                    if (node != null)
                    {
                        toolStripMenuItemAdd.Visible = true;
                        toolStripMenuItemEdt.Visible = true;
                        toolStripMenuItemDel.Visible = true;
                        toolStripMenuItemRoot.Visible = false;
                        cms1.Show(tlMenu, e.Location);
                    }
                }
                else
                {
                    toolStripMenuItemAdd.Visible = false;
                    toolStripMenuItemEdt.Visible = false;
                    toolStripMenuItemDel.Visible = false;
                    toolStripMenuItemRoot.Visible = true;
                    cms1.Show(tlMenu, e.Location);
                }
            }
        }
 
        /// <summary>
        /// 加载数据列表 - 树形结构显示
        /// </summary>
        private void getPageList()
        {
            var pgq = new PageQueryModel(1, 999999, "a.node_level", "asc", "", "");//sort_order
            var json = JsonConvert.SerializeObject(pgq);
 
            try
            {
                var strReturn = UtilityHelper.HttpPost("", _webServiceName + "GetListPage", json);
                var dd = UtilityHelper.ReturnToTablePage(strReturn);
                var dt = dd.rtnData.list; // 获取原始 DataTable
 
 
                // 检测 parentId 是否存在且类型不对
                if (dt.Columns.Contains("parentId") && dt.Columns["parentId"].DataType != typeof(long))
                {
                    // 1. 创建一个新的 Int64 类型的临时列
                    DataColumn newCol = new DataColumn("parentId_Fixed", typeof(long));
                    dt.Columns.Add(newCol);
 
                    // 2. 遍历所有行,把 String 转成 Long
                    foreach (DataRow row in dt.Rows)
                    {
                        object oldVal = row["parentId"];
                        // 只有非空值才转换,空值保持 DBNull (即根节点)
                        if (oldVal != null && oldVal != DBNull.Value && !string.IsNullOrEmpty(oldVal.ToString()))
                        {
                            if (long.TryParse(oldVal.ToString(), out long val))
                            {
                                row["parentId_Fixed"] = val;
                            }
                        }
                    }
 
                    // 3. 移除旧的 String 列
                    dt.Columns.Remove("parentId");
 
                    // 4. 把新列改名为 parentId
                    newCol.ColumnName = "parentId";
                }
             
                
                tlMenu.BeginUpdate();
 
                // 1. 绑定处理过的数据
                tlMenu.DataSource = dt;
 
                // 2. 绑定字段 (现在类型完全一致了)
                tlMenu.KeyFieldName = "id";
                tlMenu.ParentFieldName = "parentId";
             //  设置根节点 (Int64 类型的列,空值就是 DBNull)
                tlMenu.RootValue = DBNull.Value;
 
             
                string sortColName = "sortOrder";
 
                if (tlMenu.Columns[sortColName] != null)
                {
                 
                    tlMenu.ClearSorting();
 
                    tlMenu.Columns[sortColName].SortOrder = System.Windows.Forms.SortOrder.Ascending;
 
                    tlMenu.Columns[sortColName].SortIndex = 0;
                }
                tlMenu.ForceInitialize();
 
                // 4. 调用展开逻辑
                ApplyExpandState();
 
                tlMenu.EndUpdate();
                tlMenu.BestFitColumns();
 
               
 
            }
            catch (Exception ex)
            {
                tlMenu.EndUpdate();
                MsgHelper.Warning("加载失败:" + ex.Message);
            }
        }
 
        /// <summary>
        /// 根据 isExpanded (bool) 字段设置节点展开
        /// </summary>
        private void ApplyExpandState()
        {
            // 1. 先全部折叠
            tlMenu.CollapseAll();
 
            // 2. 使用 DevExpress 高效迭代器遍历
            tlMenu.NodesIterator.DoOperation(node =>
            {
                // 获取值 (注意:列名必须与 DataTable 中一致,通常是 "isExpanded")
                object val = node.GetValue("isExpanded");
 
                // 3. 判断并展开
                if (val != null && val != DBNull.Value)
                {
                    if ((bool)val)
                    {
                        node.Expanded = true;
                    }
                }
            });
        }
        /// <summary>
        /// 将动态数据转换为DataTable
        /// </summary>
        private DataTable ConvertToDataTable(dynamic sourceData)
        {
            DataTable dt = new DataTable();
 
            if (sourceData == null) return dt;
 
            // 如果已经是DataTable,直接返回
            if (sourceData is DataTable)
                return sourceData as DataTable;
 
            // 尝试从JSON数组转换
            string jsonStr = JsonConvert.SerializeObject(sourceData);
            dt = JsonConvert.DeserializeObject<DataTable>(jsonStr);
 
            return dt;
        }
 
        /// <summary>
        /// 处理parentId字段,确保树形结构正确构建
        /// 根节点(node_level=0 或 parentId为null/0)的parentId设为DBNull
        /// </summary>
        private void ProcessParentIdForTreeStructure(DataTable dt)
        {
            if (dt == null || dt.Rows.Count == 0) return;
 
            foreach (DataRow row in dt.Rows)
            {
                // 获取nodeLevel
                int nodeLevel = 0;
                if (dt.Columns.Contains("nodeLevel") && row["nodeLevel"] != DBNull.Value)
                {
                    nodeLevel = Convert.ToInt32(row["nodeLevel"]);
                }
 
                // 获取parentId
                object parentIdValue = null;
                if (dt.Columns.Contains("parentId"))
                {
                    parentIdValue = row["parentId"];
                }
 
                // 如果是根节点(nodeLevel=0 或 parentId为null/0/空),将parentId设为DBNull
                bool isRootNode = nodeLevel == 0;
                bool hasNoParent = parentIdValue == null ||
                                   parentIdValue == DBNull.Value ||
                                   string.IsNullOrEmpty(parentIdValue.ToString()) ||
                                   parentIdValue.ToString() == "0";
 
                if (isRootNode || hasNoParent)
                {
                    row["parentId"] = DBNull.Value;
                }
            }
        }
 
        /// <summary>
        /// 展开第一级节点(根节点)
        /// </summary>
        private void ExpandFirstLevelNodes()
        {
            foreach (TreeListNode node in tlMenu.Nodes)
            {
                node.Expanded = true;
            }
        }
 
    }
}