using DevExpress.XtraEditors;
|
using Gs.DevApp.ToolBox;
|
using Newtonsoft.Json;
|
using System;
|
using System.Windows.Forms;
|
|
namespace Gs.DevApp.DevFrm.Sys
|
{
|
/// <summary>
|
/// 看板节点编辑窗体
|
/// </summary>
|
public partial class SimpleKanBanEdit : DevExpress.XtraEditors.XtraForm
|
{
|
private string _webServiceName = "MesSimpleManager/";
|
private string _strId = ""; // 当前编辑的节点ID(为空表示新增)
|
private string _strFid = ""; // 父节点ID
|
private int _nodeLevel = 0; // 节点层级
|
private bool _isEditMode = false; // 是否为编辑模式
|
private bool _isLoading = false; // 是否正在加载数据
|
|
/// <summary>
|
/// 保存成功后的回调事件
|
/// </summary>
|
public event EventHandler<UpdateParentEventArgs> UpdateParent;
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
/// <param name="strId">节点ID,为空表示新增</param>
|
/// <param name="strFid">父节点ID,为空表示根节点</param>
|
public SimpleKanBanEdit(string strId, string strFid)
|
{
|
InitializeComponent();
|
rgNodeType.EditValueChanged += RgNodeType_EditValueChanged;
|
_strId = strId;
|
_strFid = strFid;
|
_isEditMode = !string.IsNullOrEmpty(_strId);
|
|
// 设置窗体标题
|
this.Text = _isEditMode ? "编辑看板节点" : "新增看板节点";
|
|
// 初始化节点类型选项(0=根目录, 1=看板目录, 2=看板内容)
|
rgNodeType.Properties.Items.Clear();
|
rgNodeType.Properties.Items.Add(new DevExpress.XtraEditors.Controls.RadioGroupItem(0, "根目录"));
|
rgNodeType.Properties.Items.Add(new DevExpress.XtraEditors.Controls.RadioGroupItem(1, "看板目录"));
|
rgNodeType.Properties.Items.Add(new DevExpress.XtraEditors.Controls.RadioGroupItem(2, "看板内容"));
|
|
// 保存按钮
|
btnSave.Click += BtnSave_Click;
|
|
// 取消按钮
|
btnCancel.Click += (s, e) => { this.Close(); };
|
|
// 初始化默认值
|
seSortOrder.Value = 0;
|
seCarouselDuration.Value = 10;
|
chkIsExpanded.Checked = false;
|
chkIsEnabled.Checked = true;
|
|
// 加载数据
|
if (_isEditMode)
|
{
|
LoadModel();
|
}
|
else
|
{
|
// 新增模式:根据父节点计算当前节点层级并设置节点类型
|
InitNodeLevelAndType();
|
}
|
}
|
|
|
/// <summary>
|
/// 新增模式:初始化节点层级
|
/// 规则:
|
/// - node_level = 0:根节点
|
/// - node_level >= 1:非根节点
|
/// </summary>
|
private void InitNodeLevelAndType()
|
{
|
if (string.IsNullOrEmpty(_strFid))
|
{
|
// 无父节点,说明是根节点
|
_nodeLevel = 0;
|
}
|
else
|
{
|
// 有父节点,基于父节点层级 +1
|
try
|
{
|
var _obj = new { Id = long.Parse(_strFid) };
|
var json = JsonConvert.SerializeObject(_obj);
|
var strReturn = UtilityHelper.HttpPost("", _webServiceName + "GetModel", json);
|
var dd = UtilityHelper.ReturnToDynamic(strReturn);
|
|
if (dd.rtnCode > 0 && dd.rtnData != null)
|
{
|
int parentNodeLevel = dd.rtnData.nodeLevel != null
|
? Convert.ToInt32(dd.rtnData.nodeLevel)
|
: 0;
|
|
_nodeLevel = parentNodeLevel + 1;
|
}
|
else
|
{
|
_nodeLevel = 1;
|
}
|
}
|
catch
|
{
|
_nodeLevel = 1;
|
}
|
}
|
|
// 根据层级初始化 NodeType & 控件状态
|
SetNodeTypeByLevel();
|
}
|
|
/// <summary>
|
/// 根据节点层级设置节点类型
|
/// - node_level = 0:只能选 0(根目录),整个控件禁用
|
/// - node_level >= 1:只能选 1 / 2,根目录项灰掉不可选
|
/// </summary>
|
private void SetNodeTypeByLevel()
|
{
|
// 先统一启用控件,后面按情况处理
|
rgNodeType.Enabled = true;
|
|
if (_nodeLevel == 0)
|
{
|
// 根节点:只能是根目录
|
rgNodeType.EditValue = 0;
|
rgNodeType.Enabled = false;
|
}
|
else
|
{
|
// 非根节点:不能选“根目录(0)”
|
DisableRootNodeTypeItem();
|
|
// 如果当前值是 0,强制切到默认值
|
if (rgNodeType.EditValue == null ||
|
Convert.ToInt32(rgNodeType.EditValue) == 0)
|
{
|
rgNodeType.EditValue = 1; // 默认“看板目录”
|
}
|
}
|
|
SetControlsByNodeType();
|
}
|
|
/// <summary>
|
/// 禁用 NodeType=0(根目录)选项
|
/// </summary>
|
private void DisableRootNodeTypeItem()
|
{
|
foreach (DevExpress.XtraEditors.Controls.RadioGroupItem item in rgNodeType.Properties.Items)
|
{
|
if (Convert.ToInt32(item.Value) == 0)
|
{
|
item.Enabled = false;
|
break;
|
}
|
}
|
}
|
private void LoadModel()
|
{
|
try
|
{
|
var _obj = new { Id = long.Parse(_strId) };
|
var json = JsonConvert.SerializeObject(_obj);
|
var strReturn = UtilityHelper.HttpPost("", _webServiceName + "GetModel", json);
|
var dd = UtilityHelper.ReturnToDynamic(strReturn);
|
|
if (dd.rtnCode > 0 && dd.rtnData != null)
|
{
|
var m = dd.rtnData;
|
|
// 1. 基础赋值
|
txtCode.Text = m.code != null ? m.code.ToString() : "";
|
txtTitle.Text = m.title != null ? m.title.ToString() : "";
|
txtUrl.Text = m.url != null ? m.url.ToString() : "";
|
_isLoading = true;
|
|
_nodeLevel = m.nodeLevel != null ? Convert.ToInt32(m.nodeLevel) : 0;
|
if (m.parentId != null) _strFid = m.parentId.ToString();
|
|
|
if (m.nodeType != null)
|
{
|
int type = Convert.ToInt32(m.nodeType);
|
rgNodeType.EditValue = type;
|
|
// 获取子节点数量 (从存储过程新增的字段)
|
int childCount = m.childCount != null ? Convert.ToInt32(m.childCount) : 0;
|
|
// 逻辑判断
|
if (type == 0)
|
{
|
// 根目录:永远不可修改
|
rgNodeType.Properties.ReadOnly = true;
|
}
|
else
|
{
|
|
if (childCount > 0)
|
{
|
rgNodeType.Properties.ReadOnly = true;
|
// 可以给用户一个提示(Tooltip)或在保存时体现,这里仅控制UI只读
|
}
|
else
|
{
|
rgNodeType.Properties.ReadOnly = false;
|
}
|
}
|
}
|
|
|
SetControlsByNodeType(); // 刷新界面
|
_isLoading = false;
|
|
// 其他字段
|
if (m.carouselDuration != null) seCarouselDuration.Value = Convert.ToInt32(m.carouselDuration);
|
if (m.sortOrder != null) seSortOrder.Value = Convert.ToInt32(m.sortOrder);
|
chkIsExpanded.Checked = m.isExpanded != null && Convert.ToBoolean(m.isExpanded);
|
chkIsEnabled.Checked = m.isEnabled != null && Convert.ToBoolean(m.isEnabled);
|
}
|
else
|
{
|
MsgHelper.ShowError("加载数据失败:" + dd.rtnMsg);
|
}
|
}
|
catch (Exception ex)
|
{
|
MsgHelper.ShowError("加载数据异常:" + ex.Message);
|
}
|
}
|
|
/// <summary>
|
/// 根据节点层级(node_level)设置 URL 和轮播时长显示状态
|
/// </summary>
|
private void SetControlsByNodeType()
|
{
|
int nodeType = Convert.ToInt32(rgNodeType.EditValue);
|
// 只有 nodeType == 2(看板内容)才显示
|
bool show = (nodeType == 2);
|
|
SetUrlAndDurationVisible(show);
|
}
|
/// <summary>
|
/// 类型更改自动刷新
|
/// </summary>
|
private void RgNodeType_EditValueChanged(object sender, EventArgs e)
|
{
|
SetControlsByNodeType();
|
}
|
/// <summary>
|
/// 设置 URL 和轮播时长的显示状态
|
/// </summary>
|
private void SetUrlAndDurationVisible(bool visible)
|
{
|
// 控制可见性
|
layoutControlItem4.Visibility = visible
|
? DevExpress.XtraLayout.Utils.LayoutVisibility.Always
|
: DevExpress.XtraLayout.Utils.LayoutVisibility.Never;
|
|
layoutControlItem5.Visibility = visible
|
? DevExpress.XtraLayout.Utils.LayoutVisibility.Always
|
: DevExpress.XtraLayout.Utils.LayoutVisibility.Never;
|
|
// 控制可编辑状态
|
txtUrl.Enabled = visible;
|
seCarouselDuration.Enabled = visible;
|
|
if (!visible)
|
{
|
// 不可见时清空
|
txtUrl.Text = string.Empty;
|
seCarouselDuration.Value = 0;
|
}
|
else
|
{
|
// 可见时给默认值
|
if (seCarouselDuration.Value <= 0)
|
{
|
seCarouselDuration.Value = 5; // 默认 5 秒
|
}
|
}
|
}
|
|
/// <summary>
|
/// 保存按钮点击事件
|
/// </summary>
|
private void BtnSave_Click(object sender, EventArgs e)
|
{
|
// 验证必填项
|
if (string.IsNullOrWhiteSpace(txtTitle.Text))
|
{
|
MsgHelper.Warning("名称不能为空!");
|
txtTitle.Focus();
|
return;
|
}
|
|
// 节点类型为看板内容时,URL不能为空
|
if ((int)rgNodeType.EditValue == 2 && string.IsNullOrWhiteSpace(txtUrl.Text))
|
{
|
MsgHelper.Warning("看板内容的URL地址不能为空!");
|
txtUrl.Focus();
|
return;
|
}
|
|
try
|
{
|
// 构建保存对象
|
var _obj = new
|
{
|
Id = string.IsNullOrEmpty(_strId) ? 0 : long.Parse(_strId),
|
ParentId = string.IsNullOrEmpty(_strFid) ? (long?)null : long.Parse(_strFid),
|
NodeType = (int)rgNodeType.EditValue,
|
Code = string.IsNullOrWhiteSpace(txtCode.Text) ? null : txtCode.Text.Trim(),
|
Title = txtTitle.Text.Trim(),
|
Url = string.IsNullOrWhiteSpace(txtUrl.Text) ? null : txtUrl.Text.Trim(),
|
CarouselDuration = (int)rgNodeType.EditValue == 2 ? (int?)seCarouselDuration.Value : null,
|
IsExpanded = chkIsExpanded.Checked,
|
IsEnabled = chkIsEnabled.Checked,
|
SortOrder = (int)seSortOrder.Value
|
};
|
|
var json = JsonConvert.SerializeObject(_obj);
|
var strReturn = UtilityHelper.HttpPost("", _webServiceName + "SaveModel", json);
|
var dd = UtilityHelper.ReturnToDynamic(strReturn);
|
|
if (dd.rtnCode > 0)
|
{
|
MsgHelper.ShowInformation("保存成功!");
|
|
// 触发父窗体刷新事件
|
UpdateParent?.Invoke(this, new UpdateParentEventArgs());
|
|
this.Close();
|
}
|
else
|
{
|
MsgHelper.ShowError("保存失败:" + dd.rtnMsg);
|
}
|
}
|
catch (Exception ex)
|
{
|
MsgHelper.ShowError("保存异常:" + ex.Message);
|
}
|
}
|
}
|
}
|