04a703c2fd
SVN-Revision: r393
2397 lines
111 KiB
C#
2397 lines
111 KiB
C#
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.Base;
|
||
using DevExpress.XtraGrid.Views.Grid;
|
||
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.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 bool TreeMultiHeader;
|
||
public bool isAddBottom;
|
||
public Control.BandedGridControlEx bandGcBottom;
|
||
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);
|
||
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<GridDetailModel> detailsTablist = new List<GridDetailModel>();
|
||
if (detailsTab != null)
|
||
{
|
||
foreach (DataRow item in detailsTab.Rows)
|
||
{
|
||
GridDetailModel detailModel = new GridDetailModel(item,null, GridCustomColumnStruct.BaseDetailGridView);
|
||
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;
|
||
|
||
//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;
|
||
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<System.Windows.Forms.Control>().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);
|
||
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);
|
||
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);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
splitLeftControl.PanelVisibility = DevExpress.XtraEditors.SplitPanelVisibility.Panel1;
|
||
}
|
||
//下方表格
|
||
//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.ModeCode), DataModel.BottomSysModel);
|
||
// bandGcBottom.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.BottomModuleModel.ModeCode));
|
||
// 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;
|
||
// if (TreeMultiHeader)
|
||
// {
|
||
// OnBandedViewColumnWidthChanged(treebandGcTop.TreeListObj, null);
|
||
|
||
// }
|
||
// else
|
||
// {
|
||
// OnBandedViewColumnWidthChanged(bandGcTop.BandedView, null);
|
||
// }
|
||
//}
|
||
|
||
//右侧表格
|
||
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.ModeCode), DataModel.RightSysModel);
|
||
gcRight.SetGridRowColors(BaseModuleImpl.GetBaseGridRowColors(DataModel.RightModuleModel.ModeCode));
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 绑定控件事件
|
||
/// </summary>
|
||
public void InitControlEvents()
|
||
{
|
||
splitLeftControl.SplitterPositionChanged += OnBandedViewColumnWidthChanged;
|
||
splitMainControl.SplitterPositionChanged += OnSplitContainerPositionChanged;
|
||
DataModel.TopSearchObj.OnDataSourceBindCallBack += OnDataSourceBindCallBack;
|
||
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;
|
||
}
|
||
/// <summary>
|
||
/// 判断单元格是否可以编辑
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void OnShowingEditor(object sender, CancelEventArgs e)
|
||
{
|
||
BandedGridView view = sender as BandedGridView;
|
||
if (view == null) return;
|
||
|
||
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<string> showDays = DataModel.nonEditableCells[billDocumentId];
|
||
|
||
// 如果列名(日期)在 showday_list 里,则禁用编辑
|
||
if (showDays.Contains(columnName))
|
||
{
|
||
e.Cancel = true; // 取消编辑,单元格变灰
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 判断TreeList单元格是否可以编辑(精准适配原BandedGridView逻辑)
|
||
/// </summary>
|
||
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<string> showDays = DataModel.nonEditableCells[billDocumentId];
|
||
|
||
// 如果列名(日期)在 showday_list 里,则禁用编辑
|
||
if (showDays.Contains(columnName))
|
||
{
|
||
e.Cancel = true; // 取消编辑,单元格变灰
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存按钮点击时
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void OnBtnSaveClick(object sender, EventArgs e)
|
||
{
|
||
if (!string.IsNullOrEmpty(DataModel.TopModuleModel.MenuTable))
|
||
{
|
||
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>();
|
||
DataTable dataTable = TreeMultiHeader ? treebandGcTop.GetGridViewDataSource() : bandGcTop.BandedView.GridControl.DataSource as DataTable;
|
||
DataRow[] modifiedRows = 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()
|
||
{
|
||
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<System.Windows.Forms.Control>().Where(n => n is LabelComboxEdit).Cast<BaseUserControl>().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;
|
||
}
|
||
}
|
||
/// <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, 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;
|
||
}
|
||
|
||
/// <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)
|
||
{
|
||
BaseUserControl baseUserControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<BaseUserControl>().Where(n => n is LabelDateEdit).FirstOrDefault();
|
||
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<System.Windows.Forms.Control>().Where(n => n is LabelComboxEdit).Cast<BaseUserControl>().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.SetGridViewDataSource(BaseImpl.GetDataTableResult(searchSql));
|
||
if (e != null)
|
||
{
|
||
if (labelDateEdit != null)
|
||
{
|
||
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
|
||
DataRow focusedRow = bandGcTop.BandedView.GetFocusedDataRow();
|
||
DataTable dataDayPlan = gcRight.GridControl.DataSourceTable().Copy();
|
||
if (DataModel.TopModuleModel.HasReport) UpdateRowWithDayPlan(focusedRow, dataDayPlan, dateTime);
|
||
}
|
||
}
|
||
this.SetDetailGridDataSource(rowItem);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine(ex.Message);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// TreeList聚焦节点改变刷新当前行数据(精确移植原点击事件逻辑)
|
||
/// </summary>
|
||
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<BaseUserControl>()
|
||
.FirstOrDefault(n => n is LabelDateEdit);
|
||
|
||
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls
|
||
.Cast<System.Windows.Forms.Control>()
|
||
.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.SetGridViewDataSource(BaseImpl.GetDataTableResult(searchSql));
|
||
|
||
// 更新行数据逻辑
|
||
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
|
||
DataTable dataDayPlan = gcRight.GridControl.DataSourceTable().Copy();
|
||
if (DataModel.TopModuleModel.HasReport) UpdateRowWithDayPlan(rowItem, dataDayPlan, dateTime);
|
||
this.SetDetailGridDataSource(rowItem);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine(ex.Message);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// <para>说明:下面多数据源刷新</para>
|
||
/// <para>创建人:王一帆</para>
|
||
/// <para>创建日期:2017-12-19 </para>
|
||
/// <para>修改人:</para>
|
||
/// <para>修改日期:</para>
|
||
/// <para>修改备注:</para>
|
||
/// <para>版本:1.0</para>
|
||
/// </summary>
|
||
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<Object>().FirstOrDefault();
|
||
ModuleGridEx moduleGridEx = null;
|
||
if (moduleObject is ModuleGridEx)
|
||
{
|
||
moduleGridEx = moduleObject as ModuleGridEx;
|
||
}
|
||
if (rowItem != null && model != null)
|
||
{
|
||
if (!string.IsNullOrEmpty(model.UnionModule) && (string.IsNullOrEmpty(model.UnionValue) && string.IsNullOrEmpty(model.UnionCond))) return;
|
||
if (tabPage.Tag is FrmWebBrowser)
|
||
{
|
||
// 加载网页
|
||
FrmWebBrowser webView = tabPage.Tag as FrmWebBrowser;
|
||
string url = ReplaceHelper.ReplaceRowParam(rowItem, ReplaceHelper.ReplaceUserInfo(model.DetailSql));
|
||
url = url.StartsWith("http") ? url : SystemInfo.Instance.OAUrl + url;
|
||
//webView.FrmLoad(url);
|
||
webView.LoadUrl(url);
|
||
webView.Dock = DockStyle.Fill;
|
||
webView.Tag = model;
|
||
}
|
||
else if (tabPage.Tag is FrmWebBrowser2)
|
||
{
|
||
// 加载网页
|
||
FrmWebBrowser2 webView = tabPage.Tag as FrmWebBrowser2;
|
||
string url = ReplaceHelper.ReplaceRowParam(rowItem, ReplaceHelper.ReplaceUserInfo(model.DetailSql));
|
||
url = url.StartsWith("http") ? url : SystemInfo.Instance.OAUrl + url;
|
||
webView.LoadUrl(url);
|
||
webView.Dock = DockStyle.Fill;
|
||
webView.Tag = model;
|
||
}
|
||
else if (tabPage.Tag is FrmMiniBlink)
|
||
{
|
||
// 加载网页
|
||
FrmMiniBlink webView = tabPage.Tag as FrmMiniBlink;
|
||
string url = ReplaceHelper.ReplaceRowParam(rowItem, ReplaceHelper.ReplaceUserInfo(model.DetailSql));
|
||
url = url.StartsWith("http") ? url : SystemInfo.Instance.OAUrl + url;
|
||
webView.LoadUrl(url);
|
||
webView.Dock = DockStyle.Fill;
|
||
webView.Tag = model;
|
||
}
|
||
else if (tabPage.Tag is TabMultipledetails)
|
||
{
|
||
TabMultipledetails tabMultipledetails = tabPage.Tag as TabMultipledetails;
|
||
tabMultipledetails.SetConditionValues(rowItem);
|
||
GridControlEx grdExMain = (tabMultipledetails.SplitMain.Panel1.Tag as GridControlEx);
|
||
GridDetailModel MainModel = grdExMain.Tag as GridDetailModel;
|
||
string searchMainSql = this.GetSearchSql(MainModel, rowItem);
|
||
DataTable firstTable = MainImpl.GetDataTableResult(searchMainSql);
|
||
grdExMain.LastSearchSql = searchMainSql;
|
||
grdExMain.SetGridViewDataSource(firstTable);
|
||
if (tabMultipledetails.SplitMain.Panel2.Tag is GridControlEx)
|
||
{
|
||
GridControlEx grdExAdditional = (tabMultipledetails.SplitMain.Panel2.Tag as GridControlEx);
|
||
GridDetailModel AdditionalModel = grdExAdditional.Tag as GridDetailModel;
|
||
string searchAddSql = this.GetSearchSql(AdditionalModel, rowItem);
|
||
if (!MainModel.IsUnioDetail)
|
||
{
|
||
grdExAdditional.LastSearchSql = searchAddSql;
|
||
grdExAdditional.SetGridViewDataSource(MainImpl.GetDataTableResult(searchAddSql));
|
||
}
|
||
//右侧是左侧的明细,左侧没有数据时。右侧赋空值(因为无法触发左侧行改变事件)
|
||
if (MainModel.IsUnioDetail && firstTable.Rows.Count == 0)
|
||
{
|
||
grdExAdditional.LastSearchSql = "";
|
||
grdExAdditional.SetGridViewDataSource(new DataTable());
|
||
}
|
||
}
|
||
else if (tabMultipledetails.SplitMain.Panel2.Tag is ChartControlEx)
|
||
{
|
||
ChartControlEx grdExAdditional = (tabMultipledetails.SplitMain.Panel2.Tag as ChartControlEx);
|
||
GridDetailModel AdditionalModel = grdExAdditional.Tag as GridDetailModel;
|
||
string searchAddSql = this.GetSearchSql(AdditionalModel, rowItem);
|
||
DataTable table = MainImpl.GetDataTableResult(searchAddSql);
|
||
grdExAdditional.CreateChart(table);
|
||
}
|
||
|
||
tabPage.Text = MainModel.DetailName + "(" + firstTable.Rows.Count + "条)";
|
||
tabPage.Appearance.Header.ForeColor = firstTable.Rows.Count > 0 ? Color.Red : Color.FromArgb(0, 0, 0);
|
||
}
|
||
else
|
||
{
|
||
if (model.IsDrag)
|
||
{
|
||
return;
|
||
}
|
||
string searchSql = this.GetSearchSql(model, rowItem);
|
||
if (tabPage.Tag is GridControlEx)
|
||
{
|
||
(tabPage.Tag as GridControlEx).LastSearchSql = searchSql;
|
||
}
|
||
//DataTable dataTable = MainImpl.GetDataTableResult(searchSql);//明细数据源
|
||
if (model.DynamicDetails && rowItem.Table.Columns.Contains("DisplayColumns")) //
|
||
{
|
||
this.tabBottom.SetGridDisplayColumns(tabPage, rowItem["DisplayColumns"] + "");
|
||
}
|
||
this.tabBottom.SetGridDataSource(tabPage, MainImpl.GetDataTableResult(searchSql));
|
||
if (tabPage.Tag is GridControlEx && (tabPage.Tag as GridControlEx).ParentControl != null)
|
||
(tabPage.Tag as GridControlEx).ParentControl.SetAllControlValue(rowItem);
|
||
//配置明细直接根据条件加载
|
||
if (model.SystemModel != null && 1 == model.SystemModel.isFirstLoad)
|
||
{
|
||
(tabPage.Tag as GridControlEx).ParentControl.SearchGrid();
|
||
tabPage.Text = model.DetailName + "(" + (tabPage.Tag as GridControlEx).ParentControl.GridRowCount + "条)";
|
||
}
|
||
}
|
||
if (moduleGridEx != null) moduleGridEx.ParentButtonState(rowItem);
|
||
}
|
||
}
|
||
/// <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 = TreeMultiHeader ? treebandGcTop.GetViewFocusedDataRow() : 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>
|
||
/// 宽度改变事件处理,兼容BandedGridView和TreeList
|
||
/// </summary>
|
||
private void OnBandedViewColumnWidthChanged(object sender, EventArgs e)
|
||
{
|
||
if (bandGcBottom.Visible)
|
||
{
|
||
int allWidth = 0;
|
||
|
||
// 如果sender为原有的BandedView类型
|
||
if (sender == bandGcTop.BandedView)
|
||
{
|
||
foreach (GridBand gridBand in bandGcTop.BandedView.Bands)
|
||
{
|
||
if (gridBand.Columns.Count == 1 && gridBand.Columns[0].Name.Contains("DDay_"))
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
allWidth += gridBand.Width;
|
||
}
|
||
}
|
||
}
|
||
// 如果sender为TreeList类型
|
||
else if (sender is TreeList treeListSender)
|
||
{
|
||
foreach (TreeListBand band in treeListSender.Bands)
|
||
{
|
||
if (band.Columns.Count == 1 && band.Columns[0].Name.Contains("DDay_"))
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
foreach (TreeListColumn treeListColumn in band.Columns)
|
||
{
|
||
if (treeListColumn.Visible) allWidth += treeListColumn.Width;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return; // 非预期sender类型时直接退出
|
||
}
|
||
|
||
// 调整底部bandGcBottom的列宽(始终为BandedGridView类型)
|
||
List<BandedGridColumn> bottomColumnList = new List<BandedGridColumn>();
|
||
foreach (GridBand gridBand in bandGcBottom.BandedView.Bands)
|
||
{
|
||
if (gridBand.Columns.Count == 1 && gridBand.Columns[0].Name.Contains("DDay_"))
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
bottomColumnList.AddRange(gridBand.Columns.Cast<BandedGridColumn>());
|
||
}
|
||
}
|
||
|
||
// 按计算好的宽度均分调整
|
||
if (bottomColumnList.Count > 0)
|
||
{
|
||
int perWidth = allWidth / bottomColumnList.Count;
|
||
foreach (BandedGridColumn bandedGridColumn in bottomColumnList)
|
||
{
|
||
bandedGridColumn.Width = perWidth;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 水平滚动条改变时
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void OnBandedViewLeftCoordChanged(object sender, EventArgs e)
|
||
{
|
||
if (!isAddBottom) return;
|
||
if (sender == bandGcTop.BandedView)
|
||
{
|
||
bandGcBottom.BandedView.LeftCoord = bandGcTop.BandedView.LeftCoord;
|
||
}
|
||
else if (sender is TreeList treeListSender)
|
||
{
|
||
// 使用TreeList的LeftCoord属性同步BandedView的LeftCoord
|
||
bandGcBottom.BandedView.LeftCoord = treeListSender.LeftCoord;
|
||
}
|
||
else if (sender == bandGcBottom.BandedView)
|
||
{
|
||
if (TreeMultiHeader)
|
||
{
|
||
|
||
treebandGcTop.TreeListObj.LeftCoord = bandGcBottom.BandedView.LeftCoord;
|
||
}
|
||
else
|
||
{
|
||
bandGcTop.BandedView.LeftCoord = bandGcBottom.BandedView.LeftCoord;
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 记录展开的节点
|
||
/// </summary>
|
||
public void GetTreeExpanded()
|
||
{
|
||
DataModel.treeListNodes.Clear();
|
||
foreach (TreeListNode n in this.treebandGcTop.TreeListObj.Nodes)
|
||
{
|
||
setRecursive(n);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 递归进行遍历节点
|
||
/// </summary>
|
||
/// <param name="treeNode"></param>
|
||
public void setRecursive(TreeListNode treeNode)
|
||
{
|
||
if (treeNode.Expanded) DataModel.treeListNodes.Add(treeNode);
|
||
// Visit each node recursively.
|
||
foreach (TreeListNode tn in treeNode.Nodes)
|
||
{
|
||
setRecursive(tn);
|
||
}
|
||
}
|
||
/// <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();
|
||
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<System.Windows.Forms.Control>().Where(n => n is LabelComboxEdit).Cast<BaseUserControl>().FirstOrDefault(); // 获取第一个符合条件的控件
|
||
string typeDate = "0";
|
||
if (dataTypeControl != null)
|
||
{
|
||
LabelComboxEdit labelAutoTextEdit = dataTypeControl as LabelComboxEdit;
|
||
typeDate = labelAutoTextEdit.EditValue;
|
||
}
|
||
|
||
if (baseUserControl != null)
|
||
{
|
||
LabelDateEdit labelDateEdit = baseUserControl as LabelDateEdit;
|
||
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
|
||
if(isAddBottom)UpdateDynamicColumns(bandGcBottom, dateTime, typeDate);
|
||
if (TreeMultiHeader)
|
||
{
|
||
UpdateDynamicColumns(treebandGcTop, dateTime, typeDate);
|
||
}
|
||
else
|
||
{
|
||
UpdateDynamicColumns(bandGcTop, dateTime, typeDate);
|
||
}
|
||
}
|
||
}
|
||
/// <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();
|
||
BaseUserControl dataTypeControl = DataModel.TopSearchObj.ParentPanel.Controls.Cast<System.Windows.Forms.Control>().Where(n => n is LabelComboxEdit).Cast<BaseUserControl>().FirstOrDefault(); // 获取第一个符合条件的控件
|
||
string typeDate = "0";
|
||
if (dataTypeControl != null)
|
||
{
|
||
LabelComboxEdit labelAutoTextEdit = dataTypeControl as LabelComboxEdit;
|
||
typeDate = labelAutoTextEdit.EditValue;
|
||
}
|
||
if (baseUserControl != null)
|
||
{
|
||
LabelDateEdit labelDateEdit = baseUserControl as LabelDateEdit;
|
||
if (typeDate == "1")
|
||
{
|
||
DateTime endDate = labelDateEdit.TextEdit.DateTime.AddMonths(3).AddDays(-1); // 计算结束日期
|
||
int weekIndex = 0;
|
||
DateTime weekStart = GetStartOfWeek(labelDateEdit.TextEdit.DateTime); // 获取本周的周一日期
|
||
labelDateEdit.TextEdit.DateTime = weekStart;
|
||
}
|
||
DateTime dateTime = labelDateEdit.TextEdit.DateTime;
|
||
if (TreeMultiHeader)
|
||
{
|
||
UpdateDynamicColumns(treebandGcTop, dateTime, typeDate);
|
||
}
|
||
else
|
||
{
|
||
UpdateDynamicColumns(bandGcTop, dateTime, typeDate);
|
||
}
|
||
if (isAddBottom) UpdateDynamicColumns(bandGcBottom, dateTime, typeDate);
|
||
DataTable dataMain = null;
|
||
DataTable dataDetail = null;
|
||
if (TreeMultiHeader)
|
||
{
|
||
dataMain = treebandGcTop.GetGridViewDataSource().Copy();
|
||
dataDetail = treebandGcTop.GetGridViewDataSource().Copy();
|
||
//treebandGcTop.TreeListObj.DataSource = null;
|
||
}
|
||
else
|
||
{
|
||
dataMain = bandGcTop.GridControl.DataSourceTable().Copy();
|
||
dataDetail = bandGcTop.GridControl.DataSourceTable().Copy();
|
||
bandGcTop.GridControl.DataSource = null;
|
||
}
|
||
|
||
string sqlValue = DataModel.RightModuleModel.MenuSql;
|
||
string isweekcond = DataModel.TopModuleModel.HasReport ? "" : $"and isWeek='{typeDate}'";
|
||
sqlValue = $"{ReplaceHelper.ReplaceWhereCond(sqlValue)} and day >= '{dateTime.ToString("yyyy-MM-dd")}' {isweekcond}";
|
||
DataTable dataDayPlan = BaseImpl.GetDataTableResult(sqlValue);
|
||
if (isAddBottom)
|
||
{
|
||
DataTable bottomTab = BuildCTable(dataDetail, dataDayPlan, dateTime, 93);
|
||
bandGcBottom.BandedView.GridControl.DataSource = bottomTab;
|
||
}
|
||
MergeMainDataWithDayPlan(dataMain, dataDayPlan, dateTime, typeDate);
|
||
if (!TreeMultiHeader)
|
||
{
|
||
bandGcTop.BandedView.GridControl.DataSource = dataMain;
|
||
OnBandedViewRowCellClick(bandGcTop.BandedView, null);
|
||
}
|
||
else
|
||
{
|
||
treebandGcTop.SetGridViewDataSource(dataMain);
|
||
}
|
||
}
|
||
string query = @"
|
||
SELECT
|
||
billdocument_id,
|
||
STUFF((SELECT ',' + CAST(showday AS VARCHAR(MAX))
|
||
FROM mps_dayplantab AS sub WITH(NOLOCK)
|
||
WHERE sub.billdocument_id = main.billdocument_id
|
||
AND sub.update_tig = 1
|
||
FOR XML PATH('')), 1, 1, '') AS showday_list
|
||
FROM mps_dayplantab AS main WITH(NOLOCK)
|
||
GROUP BY billdocument_id;";
|
||
DataTable dt = BaseImpl.GetDataTableResult(query);
|
||
foreach (DataRow row in dt.Rows)
|
||
{
|
||
string billDocumentId = row["billdocument_id"] + "";
|
||
string showDayList = row["showday_list"].ToString();
|
||
|
||
if (!string.IsNullOrEmpty(showDayList))
|
||
{
|
||
HashSet<string> daysSet = new HashSet<string>(showDayList.Split(','));
|
||
DataModel.nonEditableCells[billDocumentId] = daysSet;
|
||
}
|
||
}
|
||
}
|
||
/// <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 = DevExpress.XtraGrid.Columns.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 = DevExpress.Data.SummaryItemType.Sum;
|
||
gridColumn.SummaryItem.DisplayFormat = "{0:#,##0.####}";
|
||
}
|
||
gridBand.Columns.Add(gridColumn);
|
||
}
|
||
// 现在添加15个周列
|
||
for (int i = 93; i < 108; i++) // 新增15个周列
|
||
{
|
||
GridBand gridBand = new GridBand();
|
||
gridBand.Name = $"Week_{i - 93}";
|
||
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 = $"WWeek_{i - 93}";
|
||
gridColumn.Width = 140;
|
||
gridColumn.DisplayFormat.FormatType = FormatType.Numeric;
|
||
gridColumn.DisplayFormat.FormatString = "{0:#,##0.####}";
|
||
gridColumn.Visible = false;
|
||
if (bandedGridControlEx == bandGcTop)
|
||
{
|
||
gridColumn.SummaryItem.SummaryType = DevExpress.Data.SummaryItemType.Sum;
|
||
gridColumn.SummaryItem.DisplayFormat = "{0:#,##0.####}";
|
||
}
|
||
gridBand.Columns.Add(gridColumn);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 添加多表头树结构模式的虚拟日期列(基于TreeList)
|
||
/// </summary>
|
||
/// <summary>
|
||
/// 添加虚拟日期列(树的多表头模式)
|
||
/// </summary>
|
||
/// <summary>
|
||
/// 添加虚拟日期列(树的多表头模式)
|
||
/// </summary>
|
||
private void AddDataColumns(TreeBandedGridControlEx bandedGridControlEx)
|
||
{
|
||
// 核心优化代码:暂停数据源绑定和界面刷新
|
||
bandedGridControlEx.TreeListObj.BeginUpdate();
|
||
bandedGridControlEx.TreeListObj.LockReloadNodes(); // 阻止节点数据重载(关键优化)
|
||
try
|
||
{
|
||
if (bandedGridControlEx == treebandGcTop)
|
||
{
|
||
bandedGridControlEx.TreeListObj.OptionsView.ShowSummaryFooter = true;
|
||
}
|
||
|
||
foreach (TreeListBand fixedBand in bandedGridControlEx.TreeListObj.Bands)
|
||
{
|
||
fixedBand.Fixed = DevExpress.XtraTreeList.Columns.FixedStyle.Left;
|
||
}
|
||
|
||
// 添加93个日列
|
||
for (int i = 0; i < 93; i++)
|
||
{
|
||
TreeListBand dayBand = new TreeListBand
|
||
{
|
||
Name = $"Day_{i}",
|
||
Caption = "",
|
||
OptionsBand = { AllowMove = false, AllowSize = false },
|
||
AppearanceHeader = {
|
||
Options = { UseFont = true, UseTextOptions = true },
|
||
Font = new Font("宋体", 9, FontStyle.Bold),
|
||
TextOptions = { HAlignment = HorzAlignment.Center }
|
||
}
|
||
};
|
||
bandedGridControlEx.TreeListObj.Bands.Add(dayBand);
|
||
|
||
TreeListColumn dayColumn = new TreeListColumn
|
||
{
|
||
FieldName = $"DDay_{i}",
|
||
Width = 70,
|
||
Visible = false,
|
||
OptionsColumn = {
|
||
AllowMove = false,
|
||
AllowSize = false,
|
||
AllowSort = false,
|
||
AllowEdit = false
|
||
},
|
||
AppearanceCell = { TextOptions = { HAlignment = HorzAlignment.Center }, Options = { UseTextOptions = true } },
|
||
AppearanceHeader = { TextOptions = { HAlignment = HorzAlignment.Center }, Options = { UseTextOptions = true } },
|
||
Format = { FormatType = FormatType.Numeric, FormatString = "{0:#,##0.####}" }
|
||
};
|
||
|
||
if (bandedGridControlEx == treebandGcTop)
|
||
{
|
||
dayColumn.AllNodesSummary = true;
|
||
dayColumn.SummaryFooter = DevExpress.XtraTreeList.SummaryItemType.Sum;
|
||
dayColumn.SummaryFooterStrFormat = "{0:#,##0.####}";
|
||
}
|
||
|
||
dayBand.Columns.Add(dayColumn);
|
||
bandedGridControlEx.TreeListObj.Columns.Add(dayColumn);
|
||
}
|
||
|
||
// 添加15个周列
|
||
for (int i = 93; i < 108; i++)
|
||
{
|
||
TreeListBand weekBand = new TreeListBand
|
||
{
|
||
Name = $"Week_{i - 93}",
|
||
Caption = "",
|
||
OptionsBand = { AllowMove = false, AllowSize = false },
|
||
AppearanceHeader = {
|
||
Options = { UseFont = true, UseTextOptions = true },
|
||
Font = new Font("宋体", 9, FontStyle.Bold),
|
||
TextOptions = { HAlignment = HorzAlignment.Center }
|
||
}
|
||
};
|
||
bandedGridControlEx.TreeListObj.Bands.Add(weekBand);
|
||
|
||
TreeListColumn weekColumn = new TreeListColumn
|
||
{
|
||
FieldName = $"WWeek_{i - 93}",
|
||
Width = 140,
|
||
Visible = false,
|
||
OptionsColumn = {
|
||
AllowMove = false,
|
||
AllowSize = false,
|
||
AllowSort = false,
|
||
AllowEdit = false
|
||
},
|
||
AppearanceCell = { TextOptions = { HAlignment = HorzAlignment.Center }, Options = { UseTextOptions = true } },
|
||
AppearanceHeader = { TextOptions = { HAlignment = HorzAlignment.Center }, Options = { UseTextOptions = true } },
|
||
Format = { FormatType = FormatType.Numeric, FormatString = "{0:#,##0.####}" }
|
||
};
|
||
|
||
if (bandedGridControlEx == treebandGcTop)
|
||
{
|
||
weekColumn.AllNodesSummary = true;
|
||
weekColumn.SummaryFooter = DevExpress.XtraTreeList.SummaryItemType.Sum;
|
||
weekColumn.SummaryFooterStrFormat = "{0:#,##0.####}";
|
||
}
|
||
|
||
weekBand.Columns.Add(weekColumn);
|
||
//bandedGridControlEx.TreeListObj.Columns.Add(weekColumn);
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
bandedGridControlEx.TreeListObj.UnlockReloadNodes(); // 重新允许节点加载数据
|
||
bandedGridControlEx.TreeListObj.EndUpdate(); // 一次性完成所有刷新
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 创建TreeList统一的列
|
||
/// </summary>
|
||
private TreeListColumn CreateTreeListColumn(string fieldName, int width)
|
||
{
|
||
var column = new TreeListColumn
|
||
{
|
||
Name = $"col_{fieldName}",
|
||
FieldName = fieldName,
|
||
Caption = fieldName,
|
||
Width = width,
|
||
Visible = true,
|
||
OptionsColumn =
|
||
{
|
||
AllowMove = false,
|
||
AllowSize = false,
|
||
AllowSort = false,
|
||
AllowEdit = false
|
||
},
|
||
AppearanceHeader =
|
||
{
|
||
TextOptions = { HAlignment = HorzAlignment.Center },
|
||
Font = new Font("宋体", 9, FontStyle.Bold)
|
||
},
|
||
AppearanceCell =
|
||
{
|
||
TextOptions = { HAlignment = HorzAlignment.Center }
|
||
},
|
||
Format =
|
||
{
|
||
FormatType = FormatType.Numeric,
|
||
FormatString = "{0:#,##0.####}"
|
||
}
|
||
};
|
||
|
||
return column;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 配置列的汇总项
|
||
/// </summary>
|
||
private void SetupColumnSummary(TreeListColumn column)
|
||
{
|
||
column.SummaryFooter = DevExpress.XtraTreeList.SummaryItemType.Sum;
|
||
column.SummaryFooterStrFormat = "{0:#,##0.####}";
|
||
}
|
||
|
||
|
||
#region 类型切换日期展示方法
|
||
/// <summary>
|
||
/// 构建带日期或周期
|
||
/// </summary>
|
||
/// <param name="bandedGridControlEx"></param>
|
||
/// <param name="currentDate"></param>
|
||
/// <param name="typeDate"></param>
|
||
private void UpdateDynamicColumns(BandedGridControlEx bandedGridControlEx, DateTime currentDate, string typeDate = "0")
|
||
{
|
||
bandedGridControlEx.BandedView.BeginUpdate();
|
||
try
|
||
{
|
||
if (typeDate == "1")
|
||
{
|
||
UpdateWeeklyColumns(bandedGridControlEx, currentDate);
|
||
}
|
||
else
|
||
{
|
||
UpdateDailyColumns(bandedGridControlEx, currentDate);
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
bandedGridControlEx.BandedView.EndUpdate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新TreeList控件的动态列
|
||
/// </summary>
|
||
private void UpdateDynamicColumns(TreeBandedGridControlEx bandedGridControlEx, DateTime currentDate, string typeDate = "0")
|
||
{
|
||
try
|
||
{
|
||
if (typeDate == "1")
|
||
{
|
||
UpdateWeeklyColumns(bandedGridControlEx, currentDate);
|
||
}
|
||
else
|
||
{
|
||
UpdateDailyColumns(bandedGridControlEx, currentDate);
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 按照周结构生成列
|
||
/// </summary>
|
||
/// <param name="grid"></param>
|
||
/// <param name="currentDate"></param>
|
||
private void UpdateWeeklyColumns(BandedGridControlEx grid, DateTime currentDate)
|
||
{
|
||
DateTime endDate = currentDate.AddMonths(3).AddDays(-1); // 计算结束日期
|
||
int weekIndex = 0;
|
||
DateTime weekStart = GetStartOfWeek(currentDate); // 获取本周的周一日期
|
||
|
||
// 查找并更新15个虚拟的周列
|
||
while (weekStart <= endDate && weekIndex < 15)
|
||
{
|
||
DateTime weekEnd = weekStart.AddDays(6); // 周日的日期是周一 + 6 天
|
||
|
||
// 查找现有的虚拟周列(Week_0, Week_1, ..., Week_14)
|
||
string bandTitle = $"Week_{weekIndex}";
|
||
GridBand weekBand = grid.BandedView.Bands.Cast<GridBand>()
|
||
.FirstOrDefault(b => b.Name == bandTitle);
|
||
|
||
if (weekBand != null && weekBand.Columns.Count > 0)
|
||
{
|
||
BandedGridColumn weekColumn = weekBand.Columns[0];
|
||
weekBand.Visible = true;
|
||
// 设置周列表头:例如 "03-01至03-07"
|
||
weekBand.Caption = $"{weekStart:MM-dd}至{weekEnd:MM-dd}";
|
||
weekColumn.FieldName = weekStart.ToString("yyyy-MM-dd");
|
||
// 设置列的内容为“第几周”
|
||
weekColumn.Caption = $"第{GetWeekOfYear(weekStart)}周";
|
||
|
||
// 设置列的宽度
|
||
weekColumn.Width = 140;
|
||
// 设置该列的Tag为周的开始日期(便于后续操作)
|
||
DataModel.columnDateMapping[weekColumn] = weekStart;
|
||
// 设置是否允许编辑
|
||
if (weekEnd >= DateTime.Today)
|
||
{
|
||
weekColumn.OptionsColumn.AllowEdit = true;
|
||
}
|
||
else
|
||
{
|
||
weekColumn.OptionsColumn.AllowEdit = false;
|
||
}
|
||
|
||
weekColumn.Visible = true; // 显示该列
|
||
}
|
||
|
||
// 更新到下一周
|
||
weekStart = weekEnd.AddDays(1); // 下一周的周一
|
||
weekIndex++;
|
||
}
|
||
|
||
// 隐藏多余的周列(超过15周的列)
|
||
foreach (int i in Enumerable.Range(weekIndex, 15 - weekIndex))
|
||
{
|
||
GridBand band = grid.BandedView.Bands.Cast<GridBand>()
|
||
.FirstOrDefault(b => b.Name == $"Week_{i}");
|
||
if (band != null) band.Visible = false;
|
||
}
|
||
|
||
// 隐藏所有包含 Day_ 的列
|
||
foreach (var band in grid.BandedView.Bands.Cast<GridBand>())
|
||
{
|
||
if (band.Name.StartsWith("Day_"))
|
||
{
|
||
band.Visible = false;
|
||
foreach (BandedGridColumn column in band.Columns)
|
||
{
|
||
column.Visible = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 更新TreeList控件的周列
|
||
/// </summary>
|
||
private void UpdateWeeklyColumns(TreeBandedGridControlEx grid, DateTime currentDate)
|
||
{
|
||
grid.TreeListObj.BeginInit();
|
||
DateTime endDate = currentDate.AddMonths(3).AddDays(-1);
|
||
int weekIndex = 0;
|
||
DateTime weekStart = GetStartOfWeek(currentDate);
|
||
|
||
while (weekStart <= endDate && weekIndex < 15)
|
||
{
|
||
DateTime weekEnd = weekStart.AddDays(6);
|
||
|
||
string bandTitle = $"Week_{weekIndex}";
|
||
TreeListBand weekBand = grid.TreeListObj.Bands.Cast<TreeListBand>()
|
||
.FirstOrDefault(b => b.Name == bandTitle);
|
||
|
||
if (weekBand != null && weekBand.Columns.Count > 0)
|
||
{
|
||
TreeListColumn weekColumn = weekBand.Columns[0];
|
||
weekBand.Visible = true;
|
||
|
||
weekBand.Caption = $"{weekStart:MM-dd}至{weekEnd:MM-dd}";
|
||
weekColumn.FieldName = weekStart.ToString("yyyy-MM-dd");
|
||
weekColumn.Caption = $"第{GetWeekOfYear(weekStart)}周";
|
||
weekColumn.Width = 140;
|
||
// 新优化方式(使用字典存储)
|
||
DataModel.columnDateMapping[weekColumn] = weekStart;
|
||
weekColumn.OptionsColumn.AllowEdit = weekEnd >= DateTime.Today;
|
||
weekColumn.Visible = true;
|
||
}
|
||
|
||
weekStart = weekEnd.AddDays(1);
|
||
weekIndex++;
|
||
}
|
||
|
||
foreach (int i in Enumerable.Range(weekIndex, 15 - weekIndex))
|
||
{
|
||
TreeListBand band = grid.TreeListObj.Bands.Cast<TreeListBand>()
|
||
.FirstOrDefault(b => b.Name == $"Week_{i}");
|
||
if (band != null) band.Visible = false;
|
||
}
|
||
|
||
foreach (var band in grid.TreeListObj.Bands.Cast<TreeListBand>())
|
||
{
|
||
if (band.Name.StartsWith("Day_"))
|
||
{
|
||
band.Visible = false;
|
||
foreach (TreeListColumn column in band.Columns)
|
||
{
|
||
column.Visible = false;
|
||
}
|
||
}
|
||
}
|
||
grid.TreeListObj.EndInit();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取给定日期所在周的开始日期(周一)。
|
||
/// </summary>
|
||
private DateTime GetStartOfWeek(DateTime date)
|
||
{
|
||
// 这里假设一周是从周一开始的
|
||
int diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7;
|
||
DateTime startOfWeek = date.AddDays(-diff);
|
||
return startOfWeek.Date; // 返回周一的日期
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 计算某个日期属于这一年的第几周
|
||
/// </summary>
|
||
/// <param name="date">日期</param>
|
||
/// <returns>周数</returns>
|
||
private int GetWeekOfYear(DateTime date)
|
||
{
|
||
var cultureInfo = new CultureInfo("zh-CN");
|
||
var calendar = cultureInfo.Calendar;
|
||
return calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
|
||
}
|
||
|
||
|
||
|
||
|
||
private void UpdateDailyColumns(BandedGridControlEx grid, DateTime currentDate)
|
||
{
|
||
// 原有的日处理逻辑(保持原代码不变)
|
||
DateTime endDate = currentDate.AddMonths(3).AddDays(-1);
|
||
grid.BandedView.BeginUpdate();
|
||
|
||
// 处理每天的列(现有逻辑)
|
||
for (int i = 0; i < 93; i++)
|
||
{
|
||
// 以构建列时的命名规则 "Day_{i}" 查找对应的 GridBand
|
||
string bandTitle = $"Day_{i}";
|
||
GridBand gridBand = grid.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.Width = 70;
|
||
// 新优化方式(使用字典存储)
|
||
DataModel.columnDateMapping[gridColumn] = dateForColumn;
|
||
if (grid == 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;
|
||
}
|
||
}
|
||
//隐藏所有包含 week_ 的列
|
||
foreach (var band in grid.BandedView.Bands.Cast<GridBand>())
|
||
{
|
||
if (band.Name.StartsWith("Week_"))
|
||
{
|
||
band.Visible = false;
|
||
foreach (BandedGridColumn column in band.Columns)
|
||
{
|
||
column.Visible = false;
|
||
}
|
||
}
|
||
}
|
||
grid.BandedView.EndUpdate();
|
||
}
|
||
/// <summary>
|
||
/// 更新TreeList控件的日列
|
||
/// </summary>
|
||
private void UpdateDailyColumns(TreeBandedGridControlEx grid, DateTime currentDate)
|
||
{
|
||
DateTime endDate = currentDate.AddMonths(3).AddDays(-1);
|
||
|
||
// 核心优化代码:暂停数据源绑定和界面刷新
|
||
grid.TreeListObj.BeginInit();
|
||
grid.TreeListObj.BeginUpdate();
|
||
grid.TreeListObj.LockReloadNodes(); // 阻止节点数据重载(关键优化)
|
||
|
||
try
|
||
{
|
||
for (int i = 0; i < 93; i++)
|
||
{
|
||
string bandTitle = $"Day_{i}";
|
||
TreeListBand treeListBand = grid.TreeListObj.Bands.Cast<TreeListBand>().FirstOrDefault(x => x.Name == bandTitle);
|
||
if (treeListBand == null)
|
||
continue;
|
||
|
||
TreeListColumn treeListColumn = treeListBand.Columns.Count > 0 ? treeListBand.Columns[0] : null;
|
||
if (treeListColumn == null)
|
||
continue;
|
||
|
||
DateTime dateForColumn = currentDate.AddDays(i);
|
||
if (dateForColumn <= endDate)
|
||
{
|
||
treeListBand.Caption = dateForColumn.ToString("MM-dd");
|
||
treeListBand.Visible = true;
|
||
|
||
treeListColumn.FieldName = dateForColumn.ToString("yyyy-MM-dd"); // 保留原逻辑不变
|
||
treeListColumn.Caption = GetChineseWeekDayNumber(dateForColumn);
|
||
treeListColumn.Width = 70;
|
||
// 关键优化:改为外部字典缓存
|
||
DataModel.columnDateMapping[treeListColumn] = dateForColumn;
|
||
//treeListColumn.Tag = dateForColumn;
|
||
|
||
if (grid == treebandGcTop)
|
||
{
|
||
treeListColumn.OptionsColumn.AllowEdit = dateForColumn.Date >= DateTime.Now.Date;
|
||
}
|
||
|
||
treeListColumn.Visible = true;
|
||
}
|
||
else
|
||
{
|
||
treeListBand.Visible = false;
|
||
treeListColumn.Visible = false;
|
||
}
|
||
}
|
||
|
||
foreach (var band in grid.TreeListObj.Bands.Cast<TreeListBand>())
|
||
{
|
||
if (band.Name.StartsWith("Week_"))
|
||
{
|
||
band.Visible = false;
|
||
foreach (TreeListColumn column in band.Columns)
|
||
{
|
||
column.Visible = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
grid.TreeListObj.UnlockReloadNodes(); // 重新允许节点加载数据
|
||
grid.TreeListObj.EndUpdate(); // 一次性完成所有刷新
|
||
grid.TreeListObj.EndInit();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
/// <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 typeDate = "0")
|
||
{
|
||
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);
|
||
|
||
// 如果日期已存在,则累加金额;否则直接赋值
|
||
if (dataMap[key].ContainsKey(colName))
|
||
{
|
||
dataMap[key][colName] += amountValue; // 累加金额
|
||
}
|
||
else
|
||
{
|
||
dataMap[key][colName] = amountValue; // 直接赋值
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// **4. 如果有报告(HasReport 为 true)且 typeDate 为 "1",合并同一周的数据**
|
||
if (DataModel.TopModuleModel.HasReport && typeDate == "1")
|
||
{
|
||
int weekIndex = 0;
|
||
DateTime tempStartDate = startDate;
|
||
|
||
while (tempStartDate <= endDate && weekIndex < 15)
|
||
{
|
||
DateTime weekEnd = tempStartDate.AddDays(6); // 计算本周的周日
|
||
|
||
// 为每个 key 存储合并的数据
|
||
Dictionary<string, decimal> weekSumMap = new Dictionary<string, decimal>();
|
||
|
||
// 查找当前周的所有列(如 03-01, 03-02, ...)
|
||
string weekColumnPrefix = $"{tempStartDate:yyyy-MM-dd}";
|
||
|
||
// 对每一天的列进行累加,合并到这一周的第一天
|
||
for (DateTime dt = tempStartDate; dt <= weekEnd && dt <= endDate; dt = dt.AddDays(1))
|
||
{
|
||
string colName = dt.ToString("yyyy-MM-dd"); // 使用 yyyy-MM-dd 格式
|
||
if (dataMain.Columns.Contains(colName))
|
||
{
|
||
foreach (DataRow row in dataMain.Rows)
|
||
{
|
||
string key = row[topPrimaryKey].ToString();
|
||
if (dataMap.ContainsKey(key) && dataMap[key].ContainsKey(colName))
|
||
{
|
||
// 累加数据并更新 weekSumMap
|
||
if (!weekSumMap.ContainsKey(key))
|
||
{
|
||
weekSumMap[key] = 0;
|
||
}
|
||
weekSumMap[key] += dataMap[key][colName]; // 累加当前列的数据
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 将合并的数据写入到周一(即第一天)的列
|
||
string firstDayCol = tempStartDate.ToString("yyyy-MM-dd"); // 使用 yyyy-MM-dd 格式
|
||
|
||
// 为每个 key 更新其对应的合并数据
|
||
foreach (DataRow row in dataMain.Rows)
|
||
{
|
||
string key = row[topPrimaryKey].ToString();
|
||
if (weekSumMap.ContainsKey(key))
|
||
{
|
||
row[firstDayCol] = weekSumMap[key]; // 设置周一的值为合并后的总和
|
||
}
|
||
}
|
||
|
||
// 隐藏其他非周一的列
|
||
for (DateTime dt = tempStartDate.AddDays(1); dt <= weekEnd && dt <= endDate; dt = dt.AddDays(1))
|
||
{
|
||
string colName = dt.ToString("yyyy-MM-dd"); // 使用 yyyy-MM-dd 格式
|
||
if (dataMain.Columns.Contains(colName))
|
||
{
|
||
dataMain.Columns[colName].ColumnMapping = MappingType.Hidden; // 将非周一列隐藏
|
||
}
|
||
}
|
||
|
||
// 更新到下一周
|
||
tempStartDate = weekEnd.AddDays(1); // 下一周的周一
|
||
weekIndex++;
|
||
}
|
||
}
|
||
|
||
// **5. 一次性填充 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);
|
||
// 如果日期已存在,则累加金额;否则直接赋值
|
||
if (dataMap[key].ContainsKey(colName))
|
||
{
|
||
dataMap[key][colName] += amountValue; // 累加金额
|
||
}
|
||
else
|
||
{
|
||
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>
|
||
/// TreeList合计行单元格居中显示
|
||
/// </summary>
|
||
private void OnTreeListCustomDrawFooterCell(object sender, DevExpress.XtraTreeList.CustomDrawFooterCellEventArgs e)
|
||
{
|
||
e.Appearance.TextOptions.HAlignment = HorzAlignment.Center;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 表头颜色设置
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void OnCustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e)
|
||
{
|
||
// 判断列的Tag是否为 DateTime
|
||
if (e.Column != null)
|
||
{
|
||
if (e.Column.Caption.StartsWith("第"))
|
||
{
|
||
return; // 跳过周列
|
||
}
|
||
DateTime dateTime;
|
||
if (DataModel.columnDateMapping.TryGetValue(e.Column, out dateTime))
|
||
{
|
||
|
||
// 判断日期是否为周末(星期六或星期日)
|
||
if (dateTime.DayOfWeek == DayOfWeek.Saturday || dateTime.DayOfWeek == DayOfWeek.Sunday)
|
||
{
|
||
// 设置表头文字颜色为红色
|
||
e.Appearance.ForeColor = Color.Red;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// TreeList表头颜色自定义绘制(精准适配原BandedGridView逻辑)
|
||
/// </summary>
|
||
private void OnTreeListCustomDrawColumnHeader(object sender, DevExpress.XtraTreeList.CustomDrawColumnHeaderEventArgs e)
|
||
{
|
||
|
||
// 判断列的Tag是否为 DateTime
|
||
if (e.Column != null)
|
||
{
|
||
if (e.Column.Caption.StartsWith("第"))
|
||
{
|
||
return; // 跳过周列
|
||
}
|
||
DateTime dateTime;
|
||
if (DataModel.columnDateMapping.TryGetValue(e.Column, out 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)
|
||
{
|
||
// 判断列的Tag是否为 DateTime
|
||
if (gridCell.Column != null)
|
||
{
|
||
DateTime dateTime;
|
||
if (DataModel.columnDateMapping.TryGetValue(gridCell.Column, out dateTime))
|
||
{
|
||
|
||
// 判断日期是否为周末(星期六或星期日)
|
||
if (dateTime.Date >= DateTime.Now.Date)
|
||
{
|
||
bandedGridView.SetRowCellValue(gridCell.RowHandle, gridCell.Column, obj);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
bandedGridView.PostEditor();
|
||
e.Handled = true;
|
||
}
|
||
WaitForm.HideForm();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// TreeList按键事件处理,精准移植原BandedGridView的F7快速填充逻辑
|
||
/// </summary>
|
||
private void OnTreeListKeyDown(object sender, KeyEventArgs e)
|
||
{
|
||
TreeList treeList = sender as TreeList;
|
||
if (treeList == null || !treeList.OptionsBehavior.Editable) return;
|
||
|
||
if (e.KeyCode == Keys.F7)
|
||
{
|
||
// 使用你框架中定义的精准方法来获取选中的单元格集合
|
||
List<TreeListCell> selectedCells = treeList.GetSelectedCells();
|
||
|
||
if (selectedCells != null && selectedCells.Count > 0)
|
||
{
|
||
// 以第一个选中单元格作为赋值基准值
|
||
TreeListCell firstCell = selectedCells[0];
|
||
object valueToSet = firstCell.Node.GetValue(firstCell.Column);
|
||
|
||
if (valueToSet != null && MessageUtil.Show("是否替换所选单元格值?", MessageBoxButtons.YesNo) == DialogResult.Yes)
|
||
{
|
||
WaitForm.ShowForm("数据填充中");
|
||
|
||
foreach (TreeListCell cell in selectedCells)
|
||
{
|
||
if (cell.Column.OptionsColumn.AllowEdit)
|
||
{
|
||
if (DataModel.columnDateMapping.TryGetValue(cell.Column, out DateTime dateTime))
|
||
{
|
||
// 日期必须大于等于今天才允许赋值
|
||
if (dateTime.Date >= DateTime.Now.Date)
|
||
{
|
||
cell.Node.SetValue(cell.Column, valueToSet);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
treeList.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;
|
||
|
||
DataRow newRow = dtC.NewRow();
|
||
newRow["产地"] = origin;
|
||
newRow["总产能"] = totalCapacity;
|
||
|
||
// 对每个动态日期列,从 dtPlan 中查找 billdocument_id 在 keyValues 内,
|
||
// 且 ShowDay 等于当前列名的记录,将 amount 累加后再乘以系数
|
||
foreach (string dateCol in dateColumns)
|
||
{
|
||
decimal sumAmount = planRows
|
||
.Where(pr => keyValues.Contains(pr.BillId) && pr.ShowDay == dateCol)
|
||
.Sum(pr => pr.Amount);
|
||
// 乘以系数得到实际值
|
||
newRow[dateCol] = sumAmount * coefficient;
|
||
}
|
||
dtC.Rows.Add(newRow);
|
||
}
|
||
return dtC;
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return default;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 纠正输入异常
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void OnInvalidValueException(object sender, InvalidValueExceptionEventArgs e)
|
||
{
|
||
if (e.Value.Equals(""))
|
||
{
|
||
e.ExceptionMode = ExceptionMode.Ignore;
|
||
}
|
||
}
|
||
}
|
||
}
|