using DevExpress.Data;
using DevExpress.Utils;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.BandedGrid;
using DevExpress.XtraGrid.Views.BandedGrid.ViewInfo;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraTab;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Columns;
using DevExpress.XtraTreeList.Nodes;
using Lskj.Business;
using Lskj.Business.Impl;
using Lskj.Control;
using Lskj.Control.Model;
using Lskj.Data;
using Lskj.Model;
using Lskj.Util;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Lskj.Control
{
public partial class FrmProductSched : UserControl
{
public bool TreeMultiHeader;
public bool isAddBottom;
public Control.BandedGridControlEx bandGcBottom;
public ProductDataModel DataModel;
public FrmProductSched()
{
InitializeComponent();
}
public void InitializeControl(DynamicFrmProductSchedModel mainModel)
{
GetControlData(mainModel);
InitSpiltLocation();
InitControlView();
InitControlEvents();
SetControlData();
}
///
/// 获取数据
///
public void GetControlData(DynamicFrmProductSchedModel mainModel)
{
DataModel = new ProductDataModel();
DataModel.TopSysModel = mainModel;
DataRow topSysRow = MainImpl.GetSystemdllTab(DataModel.TopSysModel.ModuleCode);
DataModel.TopModuleModel = new ModuleModel(topSysRow);
DataModel.TopModuleModel.ParmaryKey = BaseImpl.GetBasePrimaryKey(DataModel.TopSysModel.ModuleCode);
DataModel.TopGridColumns = BaseModuleImpl.GetBaseGridColumns(DataModel.TopSysModel.ModuleCode);
DataModel.TopRightMenus = BaseModuleImpl.GetBaseGridRightMenus(DataModel.TopModuleModel.FormKey);
DataModel.TopRowColors = BaseModuleImpl.GetBaseGridRowColors(DataModel.TopModuleModel.FormKey);
DataModel.TopSearchTab = BaseModuleImpl.GetCustomQueryFields(DataModel.TopModuleModel.CondKey);
DataModel.TopSchemesTable = BaseModuleImpl.GetSchemesList(DataModel.TopSysModel.ModuleId);
if (DataModel.TopModuleModel.TreeAutoMultiHeader == 1)
{
DataModel.TopSearchObj = new MyControl(DataModel.TopModuleModel.MenuSql, treebandGcTop);
}
else
{
DataModel.TopSearchObj = new MyControl(DataModel.TopModuleModel.MenuSql, bandGcTop);
}
DataModel.TopSearchObj.Model = DataModel.TopSysModel;
DataTable detailsTab = BaseModuleImpl.GetBaseDetailPages(DataModel.TopSysModel.ModuleCode);//明细数据
List detailsTablist = new List();
if (detailsTab != null)
{
foreach (DataRow item in detailsTab.Rows)
{
GridDetailModel detailModel = new GridDetailModel(item, null, GridCustomColumnStruct.BaseDetailGridView);
DataTable gridColumns = ReportImpl.GetReportDetailColumns(DataModel.TopSysModel.ModuleCode, item["id"] + "");//获取报表明细列
detailModel.GridColumns = gridColumns;
if (detailModel.Orderid == -1)//序号为-1固定配置右键
{
string moduleCode = detailModel.UnionModule;
DataModel.RightDetailModel = detailModel;
DataModel.RightSysModel = new DynamicModel(new string[] { DataModel.TopSysModel.FormText, DataModel.TopSysModel.UserId, DataModel.TopSysModel.UserName, DataModel.TopSysModel.Privilege, moduleCode });
DataRow sysRow = MainImpl.GetSystemdllTab(DataModel.RightSysModel.ModuleCode);
DataModel.RightModuleModel = new ModuleModel(sysRow);
DataModel.RightModuleModel.ParmaryKey = BaseImpl.GetBasePrimaryKey(DataModel.RightSysModel.ModuleCode);
DataModel.RightGridColumns = BaseModuleImpl.GetBaseGridColumns(DataModel.RightSysModel.ModuleCode);
DataModel.RightRightMenus = BaseModuleImpl.GetBaseGridRightMenus(DataModel.TopModuleModel.FormKey);
DataModel.RightRowColors = BaseModuleImpl.GetBaseGridRowColors(DataModel.TopModuleModel.FormKey);
}
else
{
detailsTablist.Add(detailModel);
}
}
tabBottom.Model = DataModel.TopSysModel;
tabBottom.InitTabPages(detailsTablist);
this.isAddBottom = detailsTablist.Where(o => o.displayMode != 1 && o.rightVisible != 1 && o.Orderid == -2).ToList().Count > 0;
}
}
///
/// 设置数据
///
public void SetControlData()
{
}
///
/// 初始化控件
///
public void InitControlView()
{
//搜索控件
bool fixedQuery = DataModel.TopSearchTab == null || DataModel.TopSearchTab.Rows.Count == 0;
TreeMultiHeader = DataModel.TopModuleModel.TreeAutoMultiHeader == 1;
if (!fixedQuery)
{
this.pl_mainSearch.Height = DataModel.TopSearchObj.InitSearchControl(DataModel.TopSearchTab, this.pl_search, true, DataModel.TopSchemesTable, DataModel.TopSysModel);
this.pl_search.Width = DataModel.TopSearchObj.ParentPanel.Controls.Cast().Max(n => n.Location.X + n.Width) + 5;
}
//构建树表格
if (TreeMultiHeader)//若为多表头树表格模式
{
treebandGcTop.Expansion = "3";
treebandGcTop.Model = DataModel.TopSysModel;
treebandGcTop.moduleModel = DataModel.TopModuleModel;
treebandGcTop.SetEditColumns(DataModel.TopGridColumns, GridCustomColumnStruct.BaseMainGridView + DataModel.TopModuleModel.FormKey);
treebandGcTop.SetGridRightMenus(BaseModuleImpl.GetBaseGridRightMenus(DataModel.TopModuleModel.ModeCode), DataModel.TopSysModel,this.OnGridViewRightCallBack);
treebandGcTop.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.TopModuleModel.ModeCode));
bandGcTop.Visible = false;
}
else
{
//上方表格
bandGcTop.Model = DataModel.TopSysModel;
bandGcTop.SetEditColumns(DataModel.TopGridColumns, GridCustomColumnStruct.BaseMainGridView + DataModel.TopModuleModel.FormKey);
bandGcTop.SetGridRightMenus(BaseModuleImpl.GetBaseGridRightMenus(DataModel.TopModuleModel.ModeCode), DataModel.TopSysModel,this.OnGridViewRightCallBack);
bandGcTop.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.TopModuleModel.ModeCode));
bandGcTop.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.TopModuleModel.ModeCode));
treebandGcTop.Visible = false;
}
if (TreeMultiHeader)
{
AddDataColumns(treebandGcTop);
}
else
{
AddDataColumns(bandGcTop);
}
if (DataModel.TopModuleModel.HasReport)
{
flowLayoutPanel.Visible = false;
}
if (isAddBottom)
{
GridControlEx gridControl = tabBottom.TabControlObj.TabPages[0].Tag as GridControlEx;
bandGcBottom = gridControl as BandedGridControlEx;
AddDataColumns(bandGcBottom);
foreach (GridBand gridBand in bandGcBottom.BandedView.Bands)
{
gridBand.OptionsBand.AllowSize = false;
foreach (BandedGridColumn bandedGridColumn in gridBand.Columns)
{
bandedGridColumn.OptionsColumn.AllowSize = false;
}
}
if (TreeMultiHeader)
{
OnBandedViewColumnWidthChanged(treebandGcTop.TreeListObj, null);
}
else
{
OnBandedViewColumnWidthChanged(bandGcTop.BandedView, null);
}
}
if (tabBottom.TabControlObj.TabPages.Count == 0)
{
splitLeftControl.PanelVisibility = DevExpress.XtraEditors.SplitPanelVisibility.Panel1;
}
//右侧表格
if (!string.IsNullOrEmpty(DataModel.RightSysModel.ModuleCode))
{
DataRow moduleInformation = MainImpl.GetSystemdllTab(DataModel.RightSysModel.ModuleCode);
if (moduleInformation == null)
{
MessageUtil.Show("没有找到编号为" + DataModel.RightSysModel.ModuleCode + "的模块信息");
return;
}
DataModel.RightDetailModel.SystemModel = new ModuleModel(moduleInformation);
gcRight.OnSaveGridCallBack += OnDetailSaveGridCallBack;
gcRight.Name = "gridEx";
gcRight.IsDetail = true;
gcRight.Dock = DockStyle.Fill;
gcRight.OperShortMode =false; // 不显示简短模式
gcRight.VisibleSearchPanel = false;
DataTable rightDt = BaseModuleImpl.GetBaseGridRightMenus(DataModel.RightSysModel.ModuleCode, ModuleType.MrpClickBtn);
gcRight.VisibleOperPanel = !DataModel.RightDetailModel.IsReadOnly;
gcRight.InitializeControl(DataModel.RightDetailModel.SystemModel, DataModel.RightSysModel);
gcRight.GridControlObj.Tag = DataModel.RightDetailModel;
if (DataModel.RightDetailModel.IsCheck == 1)//加载复选框
{
GridDragGrid.GridAddCheckBox(gcRight.GridControlObj.GridView);
}
}
}
///
/// 右侧表格保存回调
///
///
///
private void OnDetailSaveGridCallBack(object sender, EventArgs e)
{
DataModel.TopSearchObj.ButtonObj.PerformClick();
}
///
/// 绑定控件事件
///
public void InitControlEvents()
{
splitLeftControl.SplitterPositionChanged += OnSplitContainerPositionChanged;
splitMainControl.SplitterPositionChanged += OnSplitContainerPositionChanged;
DataModel.TopSearchObj.OnDataSourceBindCallBack += OnDataSourceBindCallBack;
DataModel.TopSearchObj.OnSearchBeforeCallBack += OnSearchBeforeCallBack; ;
DataModel.TopSearchObj.OnSearchAfterCallBack += OnSearchAfterCallBack;
if (bandGcBottom != null)
{
bandGcBottom.BandedView.LeftCoordChanged += OnBandedViewLeftCoordChanged;
bandGcBottom.BandedView.CustomDrawColumnHeader += OnCustomDrawColumnHeader;
}
if (TreeMultiHeader)
{
// 改为TreeList的事件绑定
treebandGcTop.TreeListObj.BandWidthChanged += OnBandedViewColumnWidthChanged;
treebandGcTop.TreeListObj.ColumnWidthChanged += OnBandedViewColumnWidthChanged; // 宽度改变事件
treebandGcTop.TreeListObj.LeftCoordChanged += OnBandedViewLeftCoordChanged; // 水平滚动事件
treebandGcTop.TreeListObj.FocusedNodeChanged += OnFocusedNodeChanged; // 单元格点击事件
treebandGcTop.TreeListObj.KeyDown += OnTreeListKeyDown; // 键盘事件
treebandGcTop.TreeListObj.CustomDrawFooterCell += OnTreeListCustomDrawFooterCell; // 自定义绘制Footer事件
treebandGcTop.TreeListObj.CustomDrawColumnHeader += OnTreeListCustomDrawColumnHeader; // 自定义绘制列头事件
treebandGcTop.TreeListObj.ShowingEditor += OnTreeListShowingEditor; // 编辑器显示前事件
treebandGcTop.TreeListObj.InvalidValueException += OnInvalidValueException; ;
}
else
{
bandGcTop.BandedView.BandWidthChanged += OnBandedViewColumnWidthChanged;
bandGcTop.BandedView.ColumnWidthChanged += OnBandedViewColumnWidthChanged;
bandGcTop.BandedView.LeftCoordChanged += OnBandedViewLeftCoordChanged;
bandGcTop.BandedView.RowCellClick += OnBandedViewRowCellClick;
bandGcTop.BandedView.KeyDown += OnBandedViewKeyDown;
bandGcTop.BandedView.CustomDrawFooterCell += OnCustomDrawFooterCell;
bandGcTop.BandedView.CustomDrawColumnHeader += OnCustomDrawColumnHeader;
bandGcTop.BandedView.ShowingEditor += OnShowingEditor;
bandGcTop.BandedView.InvalidValueException += OnInvalidValueException;
}
btnSave.Click += OnBtnSaveClick;
}
///
/// 判断单元格是否可以编辑
///
///
///
private void OnRightShowingEditor(object sender, CancelEventArgs e)
{
var view = sender as GridView;
if (view == null) return;
DataRow row = gcRight.GridControlObj.GetViewFocusedDataRow();
if (row == null) { e.Cancel = true; return; } // 没有行也不让编辑
// —— 1. 解析 day 字段 ——
if (!DateTime.TryParse(row["day"]?.ToString(), out DateTime dayDate))
{
e.Cancel = true; // 无法解析日期 → 禁止编辑
return;
}
// —— 2. 超过 7 天的行不可编辑 ——
if (dayDate.AddDays(7) <= DateTime.Today)
{
e.Cancel = true;
return;
}
}
///
/// 判断单元格是否可以编辑
///
///
///
private void OnShowingEditor(object sender, CancelEventArgs e)
{
BandedGridView view = sender as BandedGridView;
if (view == null) return;
if (DataModel.TopModuleModel.HasReport)//报表所有的都不能编辑
{
e.Cancel = true; // 取消编辑,单元格变灰
}
DataRow dataRow = view.GetFocusedDataRow();
if (dataRow == null) return;
string bj_tig = dataRow["bj_tig"]?.ToString() ?? "";
if (bj_tig == "0")
{
e.Cancel = true; // 取消编辑,单元格变灰
}
else
{
string billDocumentId = view.GetRowCellValue(view.FocusedRowHandle, DataModel.TopModuleModel.ParmaryKey) + "";
// 新方式 (精准替代原有取值方式)
DateTime date;
if (DataModel.columnDateMapping.TryGetValue(view.FocusedColumn, out date))
{
string columnName = date.ToString("yyyy-MM-dd");
// 检查该行的 billdocument_id 是否在字典中
if (DataModel.nonEditableCells.ContainsKey(billDocumentId))
{
HashSet showDays = DataModel.nonEditableCells[billDocumentId];
// 如果列名(日期)在 showday_list 里,则禁用编辑
if (showDays.Contains(columnName))
{
e.Cancel = true; // 取消编辑,单元格变灰
}
}
}
}
}
///
/// 判断TreeList单元格是否可以编辑(精准适配原BandedGridView逻辑)
///
private void OnTreeListShowingEditor(object sender, CancelEventArgs e)
{
if (DataModel.TopModuleModel.HasReport)//报表所有的都不能编辑
{
e.Cancel = true; // 取消编辑,单元格变灰
}
TreeList treeList = sender as TreeList;
string bj_tig = treeList.FocusedNode.GetValue("bj_tig")?.ToString() ?? "";
if (treeList == null || treeList.FocusedNode == null) return;
if (bj_tig == "0")
{
e.Cancel = true; // 取消编辑,单元格变灰
}
else
{
string billDocumentId = treeList.FocusedNode.GetValue(DataModel.TopModuleModel.ParmaryKey)?.ToString() ?? "";
DateTime date;
if (DataModel.columnDateMapping.TryGetValue(treeList.FocusedColumn, out date))
{
string columnName = date.ToString("yyyy-MM-dd");
// 检查该行的 billdocument_id 是否在字典中
if (DataModel.nonEditableCells.ContainsKey(billDocumentId))
{
HashSet showDays = DataModel.nonEditableCells[billDocumentId];
// 如果列名(日期)在 showday_list 里,则禁用编辑
if (showDays.Contains(columnName))
{
e.Cancel = true; // 取消编辑,单元格变灰
}
}
}
}
}
///
/// 保存按钮点击时
///
///
///
private void OnBtnSaveClick(object sender, EventArgs e)
{
if (TreeMultiHeader)
{
treebandGcTop.GridView.PostEditor();
}
else
{
bandGcTop.BandedView.PostEditor();
}
if (!string.IsNullOrEmpty(DataModel.TopModuleModel.MenuTable))
{
SaveGridRecord();
}
if (SaveDatePlanRecord())
{
DataModel.TopSearchObj.ButtonObj.PerformClick();
}
}
///
/// 保存主表数据
///
///
public bool SaveGridRecord()
{
string tableName = DataModel.TopModuleModel.MenuTable;
string Autogrowcolumn = BaseImpl.GetResult(string.Format("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.columns WHERE TABLE_NAME='{0}' AND COLUMNPROPERTY(OBJECT_ID('{0}'),COLUMN_NAME,'IsIdentity')=1", tableName)) + "";
DataTable DatabasePropertySheet = BaseImpl.GetDataTableResult(string.Format("select COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH from information_schema.columns where table_name = '{0}'", tableName));//数据库属性表
string SaveErrorMessage = "失败列表:\r\n";
if (string.IsNullOrEmpty(tableName))
{
MessageUtil.Show(ResourceKeys.MenuTableNameIsNull);
return false;
}
List mList = new List();
DataTable dataTable = TreeMultiHeader ? treebandGcTop.GetGridViewDataSource() : bandGcTop.BandedView.GridControl.DataSource as DataTable;
DataRow[] modifiedRows = dataTable
.Rows
.Cast()
.Where(x => x.RowState == DataRowState.Modified || x.RowState == DataRowState.Added)
.ToArray();
if (modifiedRows == null || modifiedRows.Length == 0)
{
MessageUtil.Show(ResourceKeys.UnUpdateData);
return false;
}
else
{
DataColumnCollection columns = BaseImpl.GetTableColumns(tableName).Columns;
foreach (DataRow row in modifiedRows)
{
string updateSql = "update {0} set {1} where {2}='{3}';";
string insertSql = "insert into {0}({1}) values({2});";
string updateFields = string.Empty;
string insertFields = string.Empty;
string insertValues = string.Empty;
BaseSaveModel model = new BaseSaveModel()
{
MenuCode = DataModel.TopSysModel.ModuleCode,
TableName = tableName,
KeyField = DataModel.TopModuleModel.ParmaryKey,
NewVer = DataModel.TopModuleModel.NewVer
};
foreach (DataColumn col in columns)
{
// 区分大小写匹配列
DataRow hasContainRow = DataModel.TopGridColumns.Rows.Cast().FirstOrDefault(x => (x["fieldname"] + "").ToLower() == col.ColumnName.ToLower());
if (hasContainRow != null && col.ColumnName != DataModel.TopModuleModel.ParmaryKey && !col.ColumnName.Equals("id") && Autogrowcolumn.ToLower() != col.ColumnName.ToLower())
{
if (row.RowState == DataRowState.Modified && string.IsNullOrEmpty(DataModel.TopModuleModel.CustomColumnSQL))
{
string newValue = row[col.ColumnName, DataRowVersion.Current] + "";
string oldValue = row[col.ColumnName, DataRowVersion.Original] + "";
//如果是修改状态,没有改变的值就不拼接,以免造成多人同时修改同一行不同列的值混乱情况
if (oldValue != newValue)
{
if ((col.DataType == typeof(DateTime)) && (row[col.ColumnName] + "" == ""))
{
updateFields += string.Format("[{0}]=null,", col.ColumnName);
}
else
{
if (col.DataType == typeof(Decimal) && string.IsNullOrWhiteSpace((row[col.ColumnName] + "").Replace("'", "''")))
{
updateFields += string.Format("[{0}]='{1}',", col.ColumnName, 0);
}
else
{
updateFields += string.Format("[{0}]=N'{1}',", col.ColumnName, (row[col.ColumnName] + "").Replace("'", "''"));
}
}
}
}
else if (row.RowState == DataRowState.Added || (row.RowState == DataRowState.Modified && !string.IsNullOrEmpty(DataModel.TopModuleModel.CustomColumnSQL)))
{
// 动态生成列,保存时默认全部为新增
string fieldValue = (row[col.ColumnName] + "").Replace("'", "''");
insertFields += "[" + col.ColumnName + "],";
if (!string.IsNullOrWhiteSpace(fieldValue))
{
insertValues += col.DataType == typeof(DateTime) ? "'" + Convert.ToDateTime(fieldValue).ToString("yyyy-MM-dd HH:mm:ss") + "'," : "N'" + fieldValue + "',";
}
else
{
if (col.DataType == typeof(Decimal) || col.DataType == typeof(Int32))
insertValues += "0,";
else if (col.DataType == typeof(DateTime))
insertValues += "NULL,";
else
insertValues += "'',";
}
}
SaveErrorMessage = SaveErrorMessage + DatabaseFormatJudgment.SaveOrModifyBalidation(DataModel.TopGridColumns, DatabasePropertySheet, row, col, (row[col.ColumnName] + "").Replace("'", "''"));
}
}
// 检查是否保存主键字段
if (row.RowState == DataRowState.Added && !insertFields.Contains(DataModel.TopModuleModel.ParmaryKey) && !"ID".Equals(DataModel.TopModuleModel.ParmaryKey, StringComparison.OrdinalIgnoreCase))
{
// 跳过自动增长列处理
if (Autogrowcolumn.ToLower() != DataModel.TopModuleModel.ParmaryKey.ToLower())
{
insertFields += DataModel.TopModuleModel.ParmaryKey + ",";
insertValues += "N'" + row[DataModel.TopModuleModel.ParmaryKey] + "',";
}
}
updateFields = updateFields.TrimEnd(',');
insertFields = insertFields.TrimEnd(',');
insertValues = insertValues.TrimEnd(',');
if (!string.IsNullOrEmpty(updateFields))
{
model.FieldValue = row[DataModel.TopModuleModel.ParmaryKey] + "";
model.BaseSaveType = SaveType.Update;
model.BaseSql = string.Format(updateSql, tableName, updateFields, DataModel.TopModuleModel.ParmaryKey, row[DataModel.TopModuleModel.ParmaryKey]);
}
if (!string.IsNullOrEmpty(insertFields))
{
model.BaseSaveType = SaveType.Add;
model.FieldValue = row[DataModel.TopModuleModel.ParmaryKey] + "";
model.BaseSql = string.Format(insertSql, tableName, insertFields, insertValues);
}
if (!string.IsNullOrWhiteSpace(model.BaseSql)) mList.Add(model);
}
try
{
if (mList.Count == 0)
{
return true;
}
string retuenMsg = "";
string apiRetMsg = "";
// 批量保存数据
if (BaseModuleImpl.SaveBaseGridData(mList, out retuenMsg, out apiRetMsg))
{
return true;
}
else
{
StringBuilder builder = new StringBuilder();
builder.Append("失败列表\r\n");
foreach (BaseSaveModel item in mList)
{
if (!string.IsNullOrEmpty(item.FaultMsg))
SaveErrorMessage += item.FaultMsg + "\r\n";
}
LogHelper.Instance.WriteLog(builder.ToString());
MessageUtil.Show(SaveErrorMessage);
return false;
}
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
return false;
}
}
}
///
/// 保存日期数据
///
private bool SaveDatePlanRecord()
{
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast().Where(n => n is LabelComboxEdit).Cast().FirstOrDefault(); // 获取第一个符合条件的控件
string typeDate = "0";
if (dataTypeControl != null)
{
LabelComboxEdit labelAutoTextEdit = dataTypeControl as LabelComboxEdit;
typeDate = labelAutoTextEdit.EditValue;
}
// 获取主数据源,假设已绑定到 gridControl1
DataTable mainDataSource = TreeMultiHeader ? treebandGcTop.GetGridViewDataSource() : bandGcTop.BandedView.GridControl.DataSourceTable();
if (mainDataSource == null)
{
return true;
}
// 当前操作用户(例如从全局获取)
string currentUser = ERPInfo.Instance.UserName;
DataTable tvp = new DataTable();
tvp.Columns.Add("billdocument_id", typeof(string));
tvp.Columns.Add("showday", typeof(string));
tvp.Columns.Add("amount", typeof(decimal));
tvp.Columns.Add("operatorname", typeof(string));
// 遍历主数据源所有行,仅处理已修改行
foreach (DataRow row in mainDataSource.Rows)
{
if (row.RowState == DataRowState.Modified)
{
// 获取关联的 keyvalue(用于匹配 mps_dayplantab.billdocument_id)
string key = row["keyvalue"].ToString();
// 遍历每个列,处理虚拟列(列名格式必须为 "yyyy-MM-dd")
foreach (DataColumn col in mainDataSource.Columns)
{
// 忽略固定字段
if (col.ColumnName == "ID" || col.ColumnName == "keyvalue" || col.ColumnName == "Name")
continue;
// 仅处理列名符合完整日期格式的虚拟列
if (!Regex.IsMatch(col.ColumnName, @"^\d{4}-\d{2}-\d{2}$"))
continue;
// 比较原始值和当前值
object originalValue = row[col, DataRowVersion.Original];
object currentValue = row[col, DataRowVersion.Current];
if (!object.Equals(originalValue, currentValue))
{
decimal newAmount = 0m;
if (row[col] != DBNull.Value && !string.IsNullOrWhiteSpace(row[col].ToString()))
{
decimal.TryParse(row[col].ToString(), out newAmount);
}
DataRow dr = tvp.NewRow();
dr["billdocument_id"] = key;
dr["showday"] = col.ColumnName; // 列名如 "2025-03-06"
dr["amount"] = newAmount;
dr["operatorname"] = currentUser;
tvp.Rows.Add(dr);
}
}
}
}
if (tvp.Rows.Count == 0)
{
return true;
}
// 调用存储过程保存变更数据
string msg;
int ret = SaveDayPlanChanges(tvp, typeDate, out msg);
if (ret == 1)
{
MessageUtil.Show("保存成功:" + msg);
return true;
}
else
{
MessageUtil.Show("保存失败:" + msg);
return false;
}
}
///
/// 保存日计划变更数据(批量保存)。
/// 调用存储过程 usp_MergeDayPlanChanges,将所有变更记录一次性提交到数据库。
/// 通过 TVP 参数传递数据,同时捕获输出参数 @msg 和返回值。
///
/// 包含所有变更记录的 DataTable,必须与 dbo.DayPlanChangeType 定义一致
/// 输出提示信息,存储过程执行后的返回消息
/// 存储过程返回值,成功返回 1,失败返回 0
public int SaveDayPlanChanges(DataTable tvp, string typeDate, out string message)
{
// 创建输出参数 @msg
SqlParameter pMsg = new SqlParameter("@msg", SqlDbType.VarChar, 2000)
{
Direction = ParameterDirection.Output
};
// 创建返回值参数 @return
SqlParameter returnValue = new SqlParameter("@return", SqlDbType.Int)
{
Direction = ParameterDirection.ReturnValue
};
// 创建 TVP 参数,名称必须与存储过程参数一致
SqlParameter tvpParam = new SqlParameter("@DayPlanChanges", SqlDbType.Structured)
{
TypeName = "dbo.DayPlanChangeType",
Value = tvp
};
// 创建 typeDate 参数并传入存储过程
SqlParameter typeDateParam = new SqlParameter("@TypeDate", SqlDbType.VarChar, 10)
{
Value = typeDate
};
// 构造参数数组
SqlParameter[] parameters = new SqlParameter[] { tvpParam, typeDateParam, pMsg, returnValue };
// 执行存储过程,此处调用 ExecuteNonQuery 即可,不需要返回数据集
// 请确保 BaseImpl.ExecProcedure 方法能够传递参数并执行存储过程
BaseImpl.ExecProcedure("usp_MergeDayPlanChanges", parameters);
// 获取输出参数 @msg 中的提示信息
message = pMsg.Value.ToString();
// 获取存储过程的返回值
int result = Convert.ToInt32(returnValue.Value);
return result;
}
///
/// 单元格点击刷新当前行数据
///
///
///
private void OnBandedViewRowCellClick(object sender, RowCellClickEventArgs e)
{
try
{
GridDetailModel model = DataModel.RightDetailModel;
DataRow rowItem = bandGcTop.BandedView.GetFocusedDataRow();
if (rowItem != null)
{
BaseUserControl baseUserControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast().Where(n => n is LabelDateEdit).FirstOrDefault();
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast().Where(n => n is LabelComboxEdit).Cast().FirstOrDefault(); // 获取第一个符合条件的控件
string typeDate = "0";
LabelDateEdit labelDateEdit = null;
if (baseUserControl != null)
{
labelDateEdit = baseUserControl as LabelDateEdit;
}
if (dataTypeControl != null)
{
LabelComboxEdit labelAutoTextEdit = dataTypeControl as LabelComboxEdit;
typeDate = labelAutoTextEdit.EditValue;
}
string searchSql = this.GetSearchSql(model, rowItem, false);
string isweekcond = DataModel.TopModuleModel.HasReport ? "" : $"and isWeek='{typeDate}'";
searchSql = $"{ReplaceHelper.ReplaceWhereCond(searchSql)} and day >= '{labelDateEdit.TextEdit.DateTime.ToString("yyyy-MM-dd")}' {isweekcond}";
gcRight.GridControlObj.LastSearchSql = searchSql;
// 4) 让 Grid 用这张表,并把 adapter 存起来
gcRight.GridControlObj.SetGridViewDataSource(BaseImpl.GetDataTableResult(searchSql));
if (e != null)
{
if (labelDateEdit != null)
{
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
DataRow focusedRow = bandGcTop.BandedView.GetFocusedDataRow();
DataTable dataDayPlan = gcRight.GridControlObj.GridControl.DataSourceTable().Copy();
if (DataModel.TopModuleModel.HasReport) UpdateRowWithDayPlan(focusedRow, dataDayPlan, dateTime);
}
}
this.SetDetailGridDataSource(rowItem);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
///
/// TreeList聚焦节点改变刷新当前行数据(精确移植原点击事件逻辑)
///
private void OnFocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
{
try
{
GridDetailModel model = DataModel.RightDetailModel;
if (e.Node != null)
{
DataRow rowItem = (treebandGcTop.TreeListObj.GetDataRecordByNode(e.Node) as DataRowView)?.Row;
if (rowItem != null)
{
BaseUserControl baseUserControl = DataModel.TopSearchObj.ParentPanel.Controls
.Cast()
.FirstOrDefault(n => n is LabelDateEdit);
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls
.Cast()
.FirstOrDefault(n => n is LabelComboxEdit) as BaseUserControl;
string typeDate = "0";
LabelDateEdit labelDateEdit = baseUserControl as LabelDateEdit;
if (dataTypeControl != null && dataTypeControl is LabelComboxEdit labelAutoTextEdit)
{
typeDate = labelAutoTextEdit.EditValue;
}
if (labelDateEdit == null) return;
string searchSql = this.GetSearchSql(model, rowItem, false);
string isweekcond = DataModel.TopModuleModel.HasReport ? "" : $"and isWeek='{typeDate}'";
searchSql = $"{ReplaceHelper.ReplaceWhereCond(searchSql)} and day >= '{labelDateEdit.TextEdit.DateTime:yyyy-MM-dd}' {isweekcond}";
gcRight.GridControlObj.SetGridViewDataSource(BaseImpl.GetDataTableResult(searchSql));
// 更新行数据逻辑
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
DataTable dataDayPlan = gcRight.GridControlObj.GridControl.DataSourceTable().Copy();
if (DataModel.TopModuleModel.HasReport) UpdateRowWithDayPlan(rowItem, dataDayPlan, dateTime);
this.SetDetailGridDataSource(rowItem);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
///
/// 说明:下面多数据源刷新
/// 创建人:王一帆
/// 创建日期:2017-12-19
/// 修改人:
/// 修改日期:
/// 修改备注:
/// 版本:1.0
///
public void SetDetailGridDataSource(DataRow rowItem, XtraTabPage tabPage = null)
{
if (tabPage != null)
{
this.SetTabPageDataSource(tabPage, rowItem);
}
else
{
foreach (XtraTabPage page in this.tabBottom.TabControlObj.TabPages)
{
if (rowItem != null && page != null)
{
this.SetTabPageDataSource(page, rowItem);
}
}
}
}
protected void SetTabPageDataSource(XtraTabPage tabPage, DataRow rowItem)
{
GridDetailModel model = this.tabBottom.GetGridDetailModel(tabPage);
if (model.Orderid == -2) return;
Object moduleObject = tabPage.Controls.Cast