Files
lserp_cs_6.0/插件库/Lskj.ProductSched/FrmProductSched.cs
T
tdx 1d1a02033b SVN r335
SVN-Revision: r335
2025-03-16 08:31:13 +00:00

1113 lines
55 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using DevExpress.Data;
using DevExpress.Utils;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.BandedGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using Lskj.Business.Impl;
using Lskj.Control;
using Lskj.Control.Model;
using Lskj.Data;
using Lskj.Model;
using Lskj.ProductSched;
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.ProductiSched
{
public partial class FrmProductSched : UserControl
{
public ProductDataModel DataModel;
public FrmProductSched()
{
InitializeComponent();
}
/// <summary>
/// 界面加载时
/// </summary>
public void OnLoad(DynamicProductSchedModel mainModel)
{
GetControlData(mainModel);
InitSpiltLocation();
InitControlView();
InitControlEvents();
SetControlData();
}
/// <summary>
/// 获取数据
/// </summary>
public void GetControlData(DynamicProductSchedModel 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);
DataModel.TopSearchObj = new MyControl(DataModel.TopModuleModel.MenuSql, bandGcTop);
DataModel.TopSearchObj.Model = DataModel.TopSysModel;
DataTable detailsTab = BaseModuleImpl.GetBaseDetailPages(DataModel.TopSysModel.ModuleCode);
if (detailsTab != null)
{
if (detailsTab.Rows.Count > 1)
{
string moduleCode = detailsTab.Rows[0]["unionModule"] + "";
DataModel.BottomDetailModel = new GridDetailModel(detailsTab.Rows[0], null, GridCustomColumnStruct.BaseDetailGridView);
DataModel.BottomSysModel = new DynamicModel(new string[] { DataModel.TopSysModel.FormText, DataModel.TopSysModel.UserId, DataModel.TopSysModel.UserName, DataModel.TopSysModel.Privilege, moduleCode });
DataRow sysRow = MainImpl.GetSystemdllTab(DataModel.BottomSysModel.ModuleCode);
DataModel.BottomModuleModel = new ModuleModel(sysRow);
DataModel.BottomModuleModel.ParmaryKey = BaseImpl.GetBasePrimaryKey(DataModel.BottomSysModel.ModuleCode);
DataModel.BottomGridColumns = BaseModuleImpl.GetBaseGridColumns(DataModel.BottomSysModel.ModuleCode);
DataModel.BottomRightMenus = BaseModuleImpl.GetBaseGridRightMenus(DataModel.TopModuleModel.FormKey);
DataModel.BottomRowColors = BaseModuleImpl.GetBaseGridRowColors(DataModel.TopModuleModel.FormKey);
}
if (detailsTab.Rows.Count > 1)
{
string moduleCode = detailsTab.Rows[1]["unionModule"] + "";
DataModel.RightDetailModel = new GridDetailModel(detailsTab.Rows[1], null, GridCustomColumnStruct.BaseDetailGridView);
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
{
string moduleCode = detailsTab.Rows[0]["unionModule"] + "";
DataModel.RightDetailModel = new GridDetailModel(detailsTab.Rows[0], null, GridCustomColumnStruct.BaseDetailGridView);
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);
}
}
}
/// <summary>
/// 设置数据
/// </summary>
public void SetControlData()
{
}
/// <summary>
/// 初始化控件
/// </summary>
public void InitControlView()
{
//搜索控件
bool fixedQuery = DataModel.TopSearchTab == null || DataModel.TopSearchTab.Rows.Count == 0;
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<System.Windows.Forms.Control>().Max(n => n.Location.X + n.Width) + 5;
}
//上方表格
bandGcTop.Model = DataModel.TopSysModel;
bandGcTop.SetEditColumns(DataModel.TopGridColumns, GridCustomColumnStruct.BaseMainGridView + DataModel.TopModuleModel.FormKey);
bandGcTop.SetGridRightMenus(BaseModuleImpl.GetBaseGridRightMenus(DataModel.TopModuleModel.FormKey), DataModel.TopSysModel);
bandGcTop.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.TopModuleModel.FormKey));
AddDataColumns(bandGcTop);
if (DataModel.TopModuleModel.HasReport)
{
flowLayoutPanel.Visible = false;
}
//下方表格
if (DataModel.BottomSysModel != null && !string.IsNullOrEmpty(DataModel.BottomSysModel.ModuleCode))
{
bandGcBottom.Model = DataModel.BottomSysModel;
bandGcBottom.SetEditColumns(DataModel.BottomGridColumns, GridCustomColumnStruct.BaseMainGridView + DataModel.BottomModuleModel.FormKey);
bandGcBottom.SetGridRightMenus(BaseModuleImpl.GetBaseGridRightMenus(DataModel.BottomModuleModel.FormKey), DataModel.BottomSysModel);
bandGcBottom.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.BottomModuleModel.FormKey));
AddDataColumns(bandGcBottom);
foreach (GridBand gridBand in bandGcBottom.BandedView.Bands)
{
gridBand.OptionsBand.AllowSize = false;
foreach (BandedGridColumn bandedGridColumn in gridBand.Columns)
{
bandedGridColumn.OptionsColumn.AllowSize = false;
}
}
bandGcBottom.BandedView.OptionsBehavior.Editable = false;
OnBandedViewColumnWidthChanged(bandGcTop.BandedView, null);
}
else
{
splitLeftControl.PanelVisibility = DevExpress.XtraEditors.SplitPanelVisibility.Panel1;
}
//右侧表格
if (!string.IsNullOrEmpty(DataModel.RightSysModel.ModuleCode))
{
gcRight.Model = DataModel.RightSysModel;
gcRight.SetEditColumns(DataModel.RightGridColumns, GridCustomColumnStruct.BaseMainGridView + DataModel.RightModuleModel.FormKey);
gcRight.SetGridRightMenus(BaseModuleImpl.GetBaseGridRightMenus(DataModel.RightModuleModel.FormKey), DataModel.RightSysModel);
gcRight.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.RightModuleModel.FormKey));
}
}
/// <summary>
/// 绑定控件事件
/// </summary>
public void InitControlEvents()
{
splitLeftControl.SplitterPositionChanged += OnSplitContainerPositionChanged;
splitMainControl.SplitterPositionChanged += OnSplitContainerPositionChanged;
DataModel.TopSearchObj.OnDataSourceBindCallBack += OnDataSourceBindCallBack;
DataModel.TopSearchObj.OnSearchAfterCallBack += OnSearchAfterCallBack;
bandGcTop.BandedView.BandWidthChanged += OnBandedViewColumnWidthChanged;
bandGcTop.BandedView.ColumnWidthChanged += OnBandedViewColumnWidthChanged;
bandGcTop.BandedView.LeftCoordChanged += OnBandedViewLeftCoordChanged;
bandGcBottom.BandedView.LeftCoordChanged += OnBandedViewLeftCoordChanged;
bandGcTop.BandedView.RowCellClick += OnBandedViewRowCellClick;
bandGcTop.BandedView.KeyDown += OnBandedViewKeyDown;
bandGcTop.BandedView.CustomDrawFooterCell += OnCustomDrawFooterCell;
bandGcTop.BandedView.CustomDrawColumnHeader += OnCustomDrawColumnHeader;
bandGcBottom.BandedView.CustomDrawColumnHeader += OnCustomDrawColumnHeader;
btnSave.Click += OnBtnSaveClick;
}
/// <summary>
/// 保存按钮点击时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnBtnSaveClick(object sender, EventArgs e)
{
if (SaveGridRecord())
{
if (SaveDatePlanRecord())
{
DataModel.TopSearchObj.ButtonObj.PerformClick();
}
}
}
/// <summary>
/// 保存主表数据
/// </summary>
/// <param name="isErrorTips"></param>
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<BaseSaveModel> mList = new List<BaseSaveModel>();
DataRow[] modifiedRows = (bandGcTop.BandedView.GridControl.DataSource as DataTable)
.Rows
.Cast<DataRow>()
.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<DataRow>().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;
}
}
}
/// <summary>
/// 保存日期数据
/// </summary>
private bool SaveDatePlanRecord()
{
// 获取主数据源,假设已绑定到 gridControl1
DataTable mainDataSource = 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, out msg);
if (ret == 1)
{
MessageUtil.Show("保存成功:" + msg);
return true;
}
else
{
MessageUtil.Show("保存失败:" + msg);
return false;
}
}
/// <summary>
/// 保存日计划变更数据(批量保存)。
/// 调用存储过程 usp_MergeDayPlanChanges,将所有变更记录一次性提交到数据库。
/// 通过 TVP 参数传递数据,同时捕获输出参数 @msg 和返回值。
/// </summary>
/// <param name="tvp">包含所有变更记录的 DataTable,必须与 dbo.DayPlanChangeType 定义一致</param>
/// <param name="message">输出提示信息,存储过程执行后的返回消息</param>
/// <returns>存储过程返回值,成功返回 1,失败返回 0</returns>
public int SaveDayPlanChanges(DataTable tvp, 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
};
// 构造参数数组
SqlParameter[] parameters = new SqlParameter[] { tvpParam, pMsg, returnValue };
// 执行存储过程,此处调用 ExecuteNonQuery 即可,不需要返回数据集
// 请确保 DBUtil.ExecuteNonQuery 方法能够传递参数并执行存储过程
BaseImpl.ExecProcedure("usp_MergeDayPlanChanges", parameters);
// 获取输出参数 @msg 中的提示信息
message = pMsg.Value.ToString();
// 获取存储过程的返回值
int result = Convert.ToInt32(returnValue.Value);
return result;
}
/// <summary>
/// 单元格点击刷新当前行数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnBandedViewRowCellClick(object sender, RowCellClickEventArgs e)
{
try
{
GridDetailModel model = DataModel.RightDetailModel;
DataRow rowItem = bandGcTop.BandedView.GetFocusedDataRow();
if (rowItem != null)
{
string searchSql = this.GetSearchSql(model, rowItem, false);
gcRight.SetGridViewDataSource(BaseImpl.GetDataTableResult(searchSql));
if (e != null)
{
BaseUserControl baseUserControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<BaseUserControl>().Where(n => n is LabelDateEdit).FirstOrDefault();
if (baseUserControl != null)
{
LabelDateEdit labelDateEdit = baseUserControl as LabelDateEdit;
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
DataRow focusedRow = bandGcTop.BandedView.GetFocusedDataRow();
DataTable dataDayPlan = gcRight.GridControl.DataSourceTable().Copy();
UpdateRowWithDayPlan(focusedRow, dataDayPlan, dateTime);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 获取查询sql
/// </summary>
/// <param name="model"></param>
/// <param name="rowItem"></param>
/// <param name="isLeft"></param>
/// <returns></returns>
private string GetSearchSql(GridDetailModel model, DataRow rowItem, bool isLeft = false)
{
string fieldName = !string.IsNullOrEmpty(model.UnionParentField) && rowItem.Table.Columns.Contains(model.UnionParentField) ? model.UnionParentField : DataModel.TopModuleModel.ParmaryKey;
string sqlValue = model.IsReadOnly || model.IsChart ? model.DetailSql : DataModel.RightModuleModel.MenuSql;
sqlValue = ReplaceHelper.ReplaceRowParam(rowItem, sqlValue);
DataRow row = bandGcTop.GetViewFocusedDataRow();
if (row != null && isLeft)
{
//先替换左侧选中行,在替换主表
sqlValue = ReplaceHelper.ReplaceRowParam(row, sqlValue);
}
if (ReplaceHelper.IsSelect(sqlValue) && !string.IsNullOrEmpty(model.UnionValue))
{
string Conditions = string.Empty;
//是左侧选中行,并且没有替换字段,则使用主表选中行
Conditions = isLeft ? rowItem.Table.Columns.Contains(fieldName) ? rowItem[fieldName] + "" : row[fieldName] + "" : rowItem[fieldName] + "";
sqlValue = ReplaceHelper.ReplaceWhereCond(sqlValue) + string.Format(" and {0}='{1}'", model.UnionValue, Conditions);
}
if (!string.IsNullOrEmpty(model.UnionCond))
{
string UnionCond = ReplaceHelper.ReplaceRowParam(rowItem, model.UnionCond);
sqlValue += UnionCond;
}
return sqlValue;
}
/// <summary>
/// 宽度改变时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnBandedViewColumnWidthChanged(object sender, EventArgs e)
{
if (sender == bandGcTop.BandedView && bandGcBottom.Visible)
{
int allWidth = 0;
foreach (GridBand gridBand in bandGcTop.BandedView.Bands)
{
if (gridBand.Columns.Count == 1 && gridBand.Columns[0].Name.Contains("DDay_"))
{
break;
}
else
{
allWidth += gridBand.Width;
}
}
List<BandedGridColumn> bandedColumnList = new List<BandedGridColumn>();
foreach (GridBand gridBand in bandGcBottom.BandedView.Bands)
{
if (gridBand.Columns.Count == 1 && gridBand.Columns[0].Name.Contains("DDay_"))
{
break;
}
else
{
bandedColumnList.AddRange(gridBand.Columns.Cast<BandedGridColumn>());
}
}
if (bandedColumnList.Count > 0)
{
int perWidth = allWidth / bandedColumnList.Count;
foreach (BandedGridColumn bandedGridColumn in bandedColumnList)
{
bandedGridColumn.Width = perWidth;
}
}
}
}
/// <summary>
/// 水平滚动条改变时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnBandedViewLeftCoordChanged(object sender, EventArgs e)
{
if (sender == bandGcTop.BandedView)
{
bandGcBottom.BandedView.LeftCoord = bandGcTop.BandedView.LeftCoord;
}
else if (sender == bandGcBottom.BandedView)
{
bandGcTop.BandedView.LeftCoord = bandGcBottom.BandedView.LeftCoord;
}
}
/// <summary>
/// 搜索条件绑定完成后
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnDataSourceBindCallBack(object sender, EventArgs e)
{
BaseUserControl baseUserControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<BaseUserControl>().Where(n => n is LabelDateEdit).FirstOrDefault();
if (baseUserControl != null)
{
LabelDateEdit labelDateEdit = baseUserControl as LabelDateEdit;
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
UpdateDynamicColumns(bandGcTop, dateTime);
UpdateDynamicColumns(bandGcBottom, dateTime);
}
}
/// <summary>
/// 搜索后事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnSearchAfterCallBack(object sender, EventArgs e)
{
BaseUserControl baseUserControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<BaseUserControl>().Where(n => n is LabelDateEdit).FirstOrDefault();
if (baseUserControl != null)
{
LabelDateEdit labelDateEdit = baseUserControl as LabelDateEdit;
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
UpdateDynamicColumns(bandGcTop, dateTime);
UpdateDynamicColumns(bandGcBottom, dateTime);
DataTable dataMain = bandGcTop.GridControl.DataSourceTable().Copy();
DataTable dataDetail = bandGcTop.GridControl.DataSourceTable().Copy();
bandGcTop.GridControl.DataSource = null;
string sqlValue = DataModel.RightModuleModel.MenuSql;
sqlValue = $"{ReplaceHelper.ReplaceWhereCond(sqlValue)} and day >= '{dateTime.ToString("yyyy-MM-dd")}'";
DataTable dataDayPlan = BaseImpl.GetDataTableResult(sqlValue);
MergeMainDataWithDayPlan(dataMain, dataDayPlan, dateTime);
bandGcTop.BandedView.GridControl.DataSource = dataMain;
if (bandGcBottom.Visible)
{
DataTable bottomTab = BuildCTable(dataDetail, dataDayPlan, dateTime, 93);
bandGcBottom.BandedView.GridControl.DataSource = bottomTab;
}
OnBandedViewRowCellClick(bandGcTop.BandedView, null);
}
}
/// <summary>
/// 获取数据源缓存
/// </summary>
/// <param name="cachesDic"></param>
/// <param name="dynamicModel"></param>
public void GetDataCaches(Dictionary<object, Hashtable> cachesDic)
{
//获取通用数据
Task<ModuleModel> sysModelTask = cachesDic.GetTask<ModuleModel>(this, "SysModel");
Task<DynamicModel> dynamicModelTask = cachesDic.GetTask<DynamicModel>(this, "DynamicModel");
Task<List<GridDetailModel>> detailsTask = cachesDic.GetTask<List<GridDetailModel>>(this, "Details");
Task<bool> getDataCachesTask = cachesDic.AddTask(this, "DataCaches", new Task<bool>(() =>
{
ModuleModel sysModel = sysModelTask.Result;
DynamicModel dynamicModel = dynamicModelTask.Result;
//创建数据
if (sysModel != null && dynamicModel != null)
{
Task<DataRow> menuConfigTabTask = cachesDic.AddTask(this, "MenuConfigTab", new Task<DataRow>(() =>
{
return BaseImpl.GetMenuConfigTab(dynamicModel.ModuleId); //获取菜单其他配置
}));
if (dynamicModel is DynamicExcelModel)//isExcel
{
Task<string> basePrimaryKeyTask = cachesDic.AddTask(this, "BasePrimaryKey", new Task<string>(() =>
{
return BaseImpl.GetBasePrimaryKey(dynamicModel.ModuleCode);
}));
Task<DataTable> gridColumnsTask = cachesDic.AddTask(this, "GridColumns", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridColumns(dynamicModel.ModuleCode);
}));
}
else
{
//构建主表数据
}
}
return true;
}));
}
/// <summary>
/// 添加虚拟日期列
/// </summary>
private void AddDataColumns(BandedGridControlEx bandedGridControlEx)
{
if (bandedGridControlEx == bandGcTop)
{
bandedGridControlEx.BandedView.OptionsView.ShowFooter = true;
}
foreach (GridBand gridBand in bandedGridControlEx.BandedView.Bands)
{
gridBand.Fixed = FixedStyle.Left;
}
for (int i = 0; i < 93; i++)
{
GridBand gridBand = new GridBand();
gridBand.Name = $"Day_{i}";
gridBand.Caption = "";
gridBand.OptionsBand.AllowMove = false;
gridBand.OptionsBand.AllowSize = false;
gridBand.AppearanceHeader.Options.UseFont = true;
gridBand.AppearanceHeader.Font = new Font("宋体", 9, FontStyle.Bold);
gridBand.AppearanceHeader.Options.UseTextOptions = true;
gridBand.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
bandedGridControlEx.BandedView.Bands.Add(gridBand);
BandedGridColumn gridColumn = new BandedGridColumn();
gridColumn.AppearanceCell.Options.UseTextOptions = true;
gridColumn.AppearanceCell.TextOptions.HAlignment = HorzAlignment.Center;
gridColumn.AppearanceHeader.Options.UseTextOptions = true;
gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
gridColumn.OptionsColumn.AllowMove = false;
gridColumn.OptionsColumn.AllowSize = false;
gridColumn.OptionsFilter.AllowFilter = false;
gridColumn.OptionsColumn.AllowMerge = DefaultBoolean.False;
gridColumn.OptionsColumn.AllowSort = DefaultBoolean.False;
gridColumn.FieldName = $"DDay_{i}";
gridColumn.Width = 70;
gridColumn.DisplayFormat.FormatType = FormatType.Numeric;
gridColumn.DisplayFormat.FormatString = "{0:#,##0.####}";
gridColumn.Visible = false;
if (bandedGridControlEx == bandGcTop)
{
gridColumn.SummaryItem.SummaryType = SummaryItemType.Sum;
gridColumn.SummaryItem.DisplayFormat = "{0:#,##0.####}";
}
gridBand.Columns.Add(gridColumn);
}
}
/// <summary>
/// 根据日期修改列状态
/// </summary>
/// <param name="currentDate"></param>
private void UpdateDynamicColumns(BandedGridControlEx bandedGridControlEx, DateTime currentDate)
{
// 定义三个月的结束日期:起始日期加3个月减1天
DateTime endDate = currentDate.AddMonths(3).AddDays(-1);
bandedGridControlEx.BandedView.BeginUpdate();
try
{
for (int i = 0; i < 93; i++)
{
// 以构建列时的命名规则 "Day_{i}" 查找对应的 GridBand
string bandTitle = $"Day_{i}";
GridBand gridBand = bandedGridControlEx.BandedView.Bands.Cast<GridBand>().FirstOrDefault(x => x.Name == bandTitle);
if (gridBand == null)
{
continue;
}
// 假定每个 GridBand 下只有一个子列
BandedGridColumn gridColumn = gridBand.Columns.Count > 0 ? gridBand.Columns[0] : null;
if (gridColumn == null)
{
continue;
}
// 当前列对应的日期 = 起始日期加 i 天
DateTime dateForColumn = currentDate.AddDays(i);
if (dateForColumn <= endDate)
{
gridBand.Caption = dateForColumn.ToString("MM-dd");
gridBand.Visible = true;
gridColumn.FieldName = dateForColumn.ToString("yyyy-MM-dd");
gridColumn.Caption = GetChineseWeekDayNumber(dateForColumn);
gridColumn.Tag = dateForColumn;
if (bandedGridControlEx == bandGcTop)
{
if (dateForColumn.Date < DateTime.Now.Date)
{
gridColumn.OptionsColumn.AllowEdit = false;
}
else
{
gridColumn.OptionsColumn.AllowEdit = true;
}
}
gridColumn.Visible = true;
}
else
{
gridBand.Visible = false;
gridColumn.Visible = false;
}
}
}
finally
{
bandedGridControlEx.BandedView.EndUpdate();
}
}
/// <summary>
/// 构建带日期的数据源
/// </summary>
/// <param name="dataMain"></param>
/// <param name="dataDayPlan"></param>
/// <param name="startDate"></param>
/// <returns></returns>
private DataTable MergeMainDataWithDayPlan(DataTable dataMain, DataTable dataDayPlan, DateTime startDate)
{
string rightPrimaryKey = DataModel.RightModuleModel.ParmaryKey;
string topPrimaryKey = DataModel.TopModuleModel.ParmaryKey;
DateTime endDate = startDate.AddMonths(3).AddDays(-1); // 计算结束日期
// **1. 预索引 dataDayPlan 数据(billdocument_id -> 该 key 相关的所有行)**
Dictionary<string, List<DataRow>> dayPlanMap = new Dictionary<string, List<DataRow>>();
foreach (DataRow row in dataDayPlan.Rows)
{
string billId = row[rightPrimaryKey].ToString();
if (!dayPlanMap.ContainsKey(billId))
{
dayPlanMap[billId] = new List<DataRow>();
}
dayPlanMap[billId].Add(row);
}
// **2. 预构建主数据的列**
for (DateTime dt = startDate; dt <= endDate; dt = dt.AddDays(1))
{
string colName = dt.ToString("yyyy-MM-dd");
if (!dataMain.Columns.Contains(colName))
{
dataMain.Columns.Add(colName, typeof(decimal)); // 确保列存在
}
}
// **3. 预构建数据填充映射表**
Dictionary<string, Dictionary<string, decimal>> dataMap = new Dictionary<string, Dictionary<string, decimal>>();
foreach (DataRow row in dataMain.Rows)
{
string key = row[topPrimaryKey].ToString();
if (!dataMap.ContainsKey(key))
{
dataMap[key] = new Dictionary<string, decimal>();
}
// **查找 key 关联的时间数据**
if (dayPlanMap.ContainsKey(key))
{
foreach (DataRow dayRow in dayPlanMap[key])
{
if (dayRow["day"] != DBNull.Value)
{
DateTime dayValue = Convert.ToDateTime(dayRow["day"]);
string colName = dayValue.ToString("yyyy-MM-dd");
if (dayValue >= startDate && dayValue <= endDate && dataMain.Columns.Contains(colName))
{
decimal.TryParse(dayRow["amount"] + "", out decimal amountValue);
dataMap[key][colName] = amountValue;
}
}
}
}
}
// **4. 一次性填充 DataTable(避免逐行赋值带来的性能问题)**
foreach (DataRow row in dataMain.Rows)
{
string key = row[topPrimaryKey].ToString();
if (dataMap.ContainsKey(key))
{
foreach (var col in dataMap[key])
{
row[col.Key] = col.Value;
}
}
}
return dataMain;
}
/// <summary>
/// 构建带日期的数据源
/// </summary>
/// <param name="focusedRow"></param>
/// <param name="dataDayPlan"></param>
/// <param name="startDate"></param>
/// <returns></returns>
private void UpdateRowWithDayPlan(DataRow focusedRow, DataTable dataDayPlan, DateTime startDate)
{
string rightPrimaryKey = DataModel.RightModuleModel.ParmaryKey;
string topPrimaryKey = DataModel.TopModuleModel.ParmaryKey;
DateTime endDate = startDate.AddMonths(3).AddDays(-1); // 计算结束日期
// **1. 预索引 dataDayPlan 数据(billdocument_id -> 该 key 相关的所有行)**
Dictionary<string, List<DataRow>> dayPlanMap = new Dictionary<string, List<DataRow>>();
foreach (DataRow row in dataDayPlan.Rows)
{
string billId = row[rightPrimaryKey].ToString();
if (!dayPlanMap.ContainsKey(billId))
{
dayPlanMap[billId] = new List<DataRow>();
}
dayPlanMap[billId].Add(row);
}
// **2. 预构建主数据的列**
for (DateTime dt = startDate; dt <= endDate; dt = dt.AddDays(1))
{
string colName = dt.ToString("yyyy-MM-dd");
if (!focusedRow.Table.Columns.Contains(colName))
{
focusedRow.Table.Columns.Add(colName, typeof(decimal)); // 确保列存在
}
}
// **3. 预构建数据填充映射表**
Dictionary<string, Dictionary<string, decimal>> dataMap = new Dictionary<string, Dictionary<string, decimal>>();
string key = focusedRow[topPrimaryKey].ToString();
if (!dataMap.ContainsKey(key))
{
dataMap[key] = new Dictionary<string, decimal>();
}
// **查找 key 关联的时间数据**
if (dayPlanMap.ContainsKey(key))
{
foreach (DataRow dayRow in dayPlanMap[key])
{
if (dayRow["day"] != DBNull.Value)
{
DateTime dayValue = Convert.ToDateTime(dayRow["day"]);
string colName = dayValue.ToString("yyyy-MM-dd");
if (dayValue >= startDate && dayValue <= endDate && focusedRow.Table.Columns.Contains(colName))
{
decimal.TryParse(dayRow["amount"] + "", out decimal amountValue);
dataMap[key][colName] = amountValue;
}
}
}
}
// **4. 一次性填充 DataTable(避免逐行赋值带来的性能问题)**
if (dataMap.ContainsKey(key))
{
foreach (var col in dataMap[key])
{
focusedRow[col.Key] = col.Value;
}
}
}
/// <summary>
/// 日期对照
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
private string GetChineseWeekDayNumber(DateTime date)
{
switch (date.DayOfWeek)
{
case DayOfWeek.Monday: return "一";
case DayOfWeek.Tuesday: return "二";
case DayOfWeek.Wednesday: return "三";
case DayOfWeek.Thursday: return "四";
case DayOfWeek.Friday: return "五";
case DayOfWeek.Saturday: return "六";
case DayOfWeek.Sunday: return "日";
default: return "";
}
}
/// <summary>
/// 初始化位置
/// </summary>
private void InitSpiltLocation()
{
try
{
string splitLeftWidth = IniHelper.Read(string.Format("ProductSched_SplitLeft_{0}", DataModel.TopSysModel.ModuleCode));
if (!string.IsNullOrEmpty(splitLeftWidth))
{
splitLeftControl.SplitterPosition = Convert.ToInt32(splitLeftWidth);
}
string splitMainWidth = IniHelper.Read(string.Format("ProductSched_SplitMain_{0}", DataModel.TopSysModel.ModuleCode));
if (!string.IsNullOrEmpty(splitMainWidth))
{
splitMainControl.SplitterPosition = Convert.ToInt32(splitMainWidth);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 分隔条位置改变时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnSplitContainerPositionChanged(object sender, EventArgs e)
{
try
{
if (DataModel.TopSysModel != null)
{
IniHelper.Write(string.Format("ProductSched_SplitLeft_{0}", DataModel.TopSysModel.ModuleCode), splitLeftControl.SplitterPosition + "");
IniHelper.Write(string.Format("ProductSched_SplitMain_{0}", DataModel.TopSysModel.ModuleCode), splitMainControl.SplitterPosition + "");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 合计显示居中设置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnCustomDrawFooterCell(object sender, FooterCellCustomDrawEventArgs e)
{
e.Appearance.TextOptions.HAlignment = HorzAlignment.Center;
}
/// <summary>
/// 表头颜色设置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnCustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e)
{
if (e.Column != null && e.Column.Tag != null && e.Column.Tag is DateTime dateTime)
{
if (dateTime.DayOfWeek == DayOfWeek.Saturday || dateTime.DayOfWeek == DayOfWeek.Sunday)
{
e.Appearance.ForeColor = Color.Red;
}
}
}
/// <summary>
/// 按键点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnBandedViewKeyDown(object sender, KeyEventArgs e)
{
BandedGridView bandedGridView = (BandedGridView)sender;
if (e.KeyCode == Keys.F7)
{
GridColumn column = bandedGridView.FocusedColumn;
GridColumnModel model = column.Tag as GridColumnModel;
if (column != null && column.OptionsColumn.AllowEdit && bandedGridView.RowCount > 0 && bandedGridView.OptionsBehavior.Editable)
{
// 允许操作
GridCell[] SelectCells = bandedGridView.GetSelectedCells();
if (SelectCells.Length > 0)
{
object obj = bandedGridView.GetRowCellValue(SelectCells[0].RowHandle, SelectCells[0].Column);
if (MessageUtil.Show("是否替换所选单元格值?", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
WaitForm.ShowForm("数据填充中");
if (obj != null)
{
foreach (GridCell gridCell in SelectCells)
{
if (gridCell.Column.Tag != null && gridCell.Column.Tag is DateTime dateTime)
{
if (dateTime.Date >= DateTime.Now.Date)
{
bandedGridView.SetRowCellValue(gridCell.RowHandle, gridCell.Column, obj);
}
}
}
bandedGridView.PostEditor();
e.Handled = true;
}
WaitForm.HideForm();
}
}
}
}
}
/// <summary>
/// 构建下方数据
/// </summary>
/// <param name="dtA"></param>
/// <param name="dtPlan"></param>
/// <param name="startDate"></param>
/// <param name="daysCount"></param>
/// <returns></returns>
public DataTable BuildCTable(DataTable dtA, DataTable dtPlan, DateTime startDate, int daysCount)
{
try
{
// 1. 按“产地”分组
// key: 产地; value: Tuple(总产能, 系数, keyvalue集合)
var groupDict = dtA.AsEnumerable()
.GroupBy(r => r.Field<string>("产地"))
.ToDictionary(
g => g.Key,
g => new
{
TotalCapacity = g.First().Field<decimal>("总产能"),
Coefficient = g.First().Field<decimal>("系数"),
KeyValues = g.Select(r => r.Field<string>("keyvalue")).Distinct().ToList()
}
);
// 2. 构建 C 表结构:固定字段“产地”、“产能”,以及动态日期列(格式 "yyyy-MM-dd"
DataTable dtC = new DataTable();
dtC.Columns.Add("产地", typeof(string));
dtC.Columns.Add("总产能", typeof(decimal));
List<string> dateColumns = new List<string>();
for (int i = 0; i < daysCount; i++)
{
DateTime d = startDate.AddDays(i);
string colName = d.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
dtC.Columns.Add(colName, typeof(decimal));
dateColumns.Add(colName);
}
// 3. 预处理 dtPlan:转换 day 字段为 "yyyy-MM-dd" 字符串,方便后续匹配
var planRows = dtPlan.AsEnumerable()
.Select(r => new
{
BillId = r.Field<string>("billdocument_id"),
ShowDay = r.Field<DateTime>("day").ToString("yyyy-MM-dd", CultureInfo.InvariantCulture),
Amount = r.Field<decimal>("amount")
})
.ToList();
// 4. 遍历每个分组,构造 C 表行数据
foreach (var kvp in groupDict)
{
string origin = kvp.Key;
decimal totalCapacity = kvp.Value.TotalCapacity;
decimal coefficient = kvp.Value.Coefficient;
List<string> keyValues = kvp.Value.KeyValues;