CNCEC_SUBQHSE_WUHUAN/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkGrid.aspx.cs

751 lines
27 KiB
C#
Raw Normal View History

2025-08-11 14:21:24 +08:00
using BLL;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
namespace FineUIPro.Web.JDGL.SGManPower
{
public partial class ManPowerWorkGrid : PageBase
{
#region Page_Init
// 注意动态创建的代码需要放置于Page_Init不是Page_Load这样每次构造页面时都会执行
protected void Page_Init(object sender, EventArgs e)
{
InitGrid();
}
public DataTable GridTable = new DataTable();
private void InitGrid()
{
FineUIPro.BoundField bf;
FineUIPro.RenderField rf;
FineUIPro.TextBox txTextBox;
// 设置Grid的编辑属性
Grid1.AllowCellEditing = true;
Grid1.ClicksToEdit = 1;
Grid1.EnableAfterEditEvent = true;
UnitId = Request.Params["UnitId"];
StartTime = Request.Params["StartTime"];
EndTime = Request.Params["EndTime"];
GridTable.Columns.Add("Id");
// 添加隐藏列来存储额外的ID信息
GridTable.Columns.Add("UnitId");
2025-12-01 10:24:34 +08:00
GridTable.Columns.Add("WorkAreaId");
2025-08-11 14:21:24 +08:00
GridTable.Columns.Add("WorkPostId");
2025-08-21 11:37:06 +08:00
ListItem[] list = new ListItem[5];
2025-08-11 14:21:24 +08:00
list[0] = new ListItem("序号", "SerialNumber");
list[1] = new ListItem("单位", "UnitName");
2025-12-01 10:24:34 +08:00
list[2] = new ListItem("装置", "WorkAreaName");
2025-08-21 11:37:06 +08:00
list[3] = new ListItem("岗位", "WorkPostName");
list[4] = new ListItem("累计", "TotalCount");
2025-08-11 14:21:24 +08:00
foreach (var item in list)
{
bf = new FineUIPro.BoundField();
bf.ColumnID = item.Value;
bf.DataField = item.Value;
bf.HeaderText = item.Text;
bf.HeaderTextAlign = TextAlign.Center;
bf.TextAlign = TextAlign.Center;
bf.Locked = true;
Grid1.Columns.Add(bf);
GridTable.Columns.Add(item.Value);
}
// 动态获取日期范围
DateTime startDate = Convert.ToDateTime(StartTime);
DateTime endDate = Convert.ToDateTime(EndTime);
var dateRange = Enumerable.Range(0, (endDate - startDate).Days + 1)
.Select(i => startDate.AddDays(i))
.ToList();
// 按年分组日期
var groupedByYear = dateRange.GroupBy(d => d.Year)
.OrderBy(g => g.Key)
.ToList();
foreach (var yearGroup in groupedByYear)
{
GroupField yearGroupField = new GroupField();
yearGroupField.HeaderText = $"{yearGroup.Key}年";
yearGroupField.TextAlign = TextAlign.Center;
// 按月分组
var groupedByMonth = yearGroup.GroupBy(d => d.Month)
.OrderBy(g => g.Key)
.ToList();
foreach (var monthGroup in groupedByMonth)
{
GroupField monthGroupField = new GroupField();
monthGroupField.HeaderText = $"{monthGroup.Key}月";
monthGroupField.TextAlign = TextAlign.Center;
// 添加具体日期的列
foreach (var date in monthGroup.OrderBy(d => d))
{
bf = new FineUIPro.BoundField();
bf.ColumnID = date.ToString("yyyy-MM-dd");
bf.DataField = date.ToString("yyyy-MM-dd");
bf.HeaderText = date.ToString("dd");
bf.HeaderTextAlign = TextAlign.Center;
bf.TextAlign = TextAlign.Center;
monthGroupField.Columns.Add(bf);
GridTable.Columns.Add(date.ToString("yyyy-MM-dd"));
}
yearGroupField.Columns.Add(monthGroupField);
}
Grid1.Columns.Add(yearGroupField);
}
}
#endregion
public string UnitId
{
get => (string)ViewState["UnitId"];
set => ViewState["UnitId"] = value;
}
public string StartTime
{
get => (string)ViewState["StartTime"];
set => ViewState["StartTime"] = value;
}
public string EndTime
{
get => (string)ViewState["EndTime"];
set => ViewState["EndTime"] = value;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Funs.DropDownPageSize(this.ddlPageSize);
// 设置Grid的PageSize与下拉框默认值一致
Grid1.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue);
WorkPostService.InitWorkPostDropDownList(this.drpWorkPost, true); //岗位
2025-08-21 11:37:06 +08:00
UnitWorkService.InitUnitWorkDownList(drpUnitWork, this.CurrUser.LoginProjectId, true); //单位工程(装置)
2025-08-11 14:21:24 +08:00
// 绑定表格
this.BindGrid();
}
}
#region
/// <summary>
/// 绑定数据
/// </summary>
private void BindGrid()
{
// 清空现有数据
GridTable.Clear();
// 重新添加列定义(保持列结构)
if (GridTable.Columns.Count == 0)
{
GridTable.Columns.Add("Id");
GridTable.Columns.Add("UnitId");
2025-12-01 10:24:34 +08:00
GridTable.Columns.Add("WorkAreaId");
2025-08-11 14:21:24 +08:00
GridTable.Columns.Add("WorkPostId");
// 添加动态日期列这部分已经在InitGrid中定义了
2025-08-21 11:37:06 +08:00
ListItem[] list = new ListItem[5];
2025-08-11 14:21:24 +08:00
list[0] = new ListItem("序号", "SerialNumber");
list[1] = new ListItem("单位", "UnitName");
2025-12-01 10:24:34 +08:00
list[2] = new ListItem("装置", "WorkAreaName");
2025-08-21 11:37:06 +08:00
list[3] = new ListItem("岗位", "WorkPostName");
list[4] = new ListItem("累计", "TotalCount");
2025-08-11 14:21:24 +08:00
foreach (var item in list)
{
GridTable.Columns.Add(item.Value);
}
// 日期列会在InitGrid中添加这里不需要重复添加
}
else
{
// 清空行数据但保持列结构
GridTable.Rows.Clear();
}
2025-12-01 10:24:34 +08:00
var getData = Funs.DB.SitePerson_Checking_Statistics.Where(x =>
x.ProjectId == this.CurrUser.LoginProjectId && x.IntoOutTime >= Convert.ToDateTime(StartTime) && x.IntoOutTime <= Convert.ToDateTime(EndTime));
DataTable dt = this.LINQToDataTable(getData.ToList());
2025-08-21 11:37:06 +08:00
// 创建一个新的DataTable来存储处理后的数据
DataTable processedDt = dt.Clone();
foreach (System.Data.DataRow row in dt.Rows)
{
2025-12-01 10:24:34 +08:00
// string ids = row["WorkAreaId"] != DBNull.Value ? row["WorkAreaId"].ToString() : string.Empty;
// string names = row["WorkAreaName"] != DBNull.Value ? row["WorkAreaName"].ToString() : string.Empty;
// if (!string.IsNullOrEmpty(names))
// {
// string[] unitWorkNameArray = names.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
// string[] unitWorkIdArray = ids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
// for (var i = 0; i < unitWorkNameArray.Length; i++)
// {
// // 往processedDt里面添加数据每个UnitWorkId一行
// DataRow newRow = processedDt.NewRow();
// newRow["UnitId"] = row["UnitId"];
// newRow["UnitName"] = row["UnitName"];
// newRow["WorkPostId"] = row["WorkPostId"];
// newRow["WorkPostName"] = row["WorkPostName"];
// newRow["IntoOutTime"] = row["IntoOutTime"] ?? DBNull.Value;
// newRow["WorkAreaId"] = unitWorkIdArray[i].Trim();
// newRow["WorkAreaName"] = unitWorkNameArray[i].Trim();
// newRow["num"] = row["num"] != DBNull.Value ? Convert.ToInt32(row["num"]) : 0;
// processedDt.Rows.Add(newRow);
// }
// }
// else
// {
2025-08-21 11:37:06 +08:00
DataRow newRow = processedDt.NewRow();
newRow["UnitId"] = row["UnitId"];
2025-12-01 10:24:34 +08:00
newRow["UnitName"] = row["UnitName"];
newRow["WorkPostId"] = row["WorkPostId"];
newRow["WorkPostName"] = row["WorkPostName"];
newRow["IntoOutTime"] = row["IntoOutTime"] ?? DBNull.Value;
newRow["WorkAreaId"] = row["WorkAreaId"];
newRow["WorkAreaName"] = row["WorkAreaName"];
newRow["num"] = row["num"] != DBNull.Value ? Convert.ToInt32(row["num"]) : 0;
2025-08-21 11:37:06 +08:00
processedDt.Rows.Add(newRow);
2025-12-01 10:24:34 +08:00
// }
2025-08-21 11:37:06 +08:00
}
//针对dt中的数据进行分组
var data = processedDt.AsEnumerable()
2025-12-01 10:24:34 +08:00
.Select(row => new
2025-08-21 11:37:06 +08:00
{
2025-12-01 10:24:34 +08:00
UnitId = row["UnitId"],
UnitName = row["UnitName"],
WorkPostId = row["WorkPostId"],
WorkPostName = row["WorkPostName"],
WorkAreaId = row["WorkAreaId"],
WorkAreaName = row["WorkAreaName"],
IntoOutTime = row["IntoOutTime"],
num = row["num"],
2025-08-21 11:37:06 +08:00
}).ToList();
var data1 = data;
// 如果选择了特定的装置进行筛选
if (drpUnitWork.SelectedValue != Const._Null)
{
2025-12-01 10:24:34 +08:00
data1 = data.Where(x => x.WorkAreaId.ToString() == drpUnitWork.SelectedValue).ToList();
2025-08-21 11:37:06 +08:00
}
2025-08-11 14:21:24 +08:00
// 将数据转换为更易处理的格式
var groupedData = new List<dynamic>();
var groupedDict = new Dictionary<string, dynamic>();
2025-08-21 11:37:06 +08:00
foreach (var item in data1)
2025-08-11 14:21:24 +08:00
{
2025-12-01 10:24:34 +08:00
string key = $"{item.UnitId}_{item.WorkPostId}_{item.WorkAreaId}";
DateTime IntoOutTime = Convert.ToDateTime(item.IntoOutTime);
int count = Convert.ToInt32(item.num);
2025-08-11 14:21:24 +08:00
if (!groupedDict.ContainsKey(key))
{
dynamic group = new System.Dynamic.ExpandoObject();
2025-08-21 11:37:06 +08:00
group.UnitId = item.UnitId;
2025-12-01 10:24:34 +08:00
group.UnitName = item.UnitName;
group.WorkPostId = item.WorkPostId;
group.WorkPostName = item.WorkPostName;
group.WorkAreaId = item.WorkAreaId;
group.WorkAreaName = item.WorkAreaName;
2025-08-11 14:21:24 +08:00
group.DailyCounts = new Dictionary<DateTime, int>();
group.TotalCount = 0;
groupedDict[key] = group;
groupedData.Add(group);
}
2025-12-01 10:24:34 +08:00
groupedDict[key].DailyCounts[IntoOutTime] = count;
2025-08-11 14:21:24 +08:00
groupedDict[key].TotalCount += count;
}
Grid1.RecordCount = groupedData.Count();
// 分页处理
var pagedData = groupedData.Skip(Grid1.PageSize * Grid1.PageIndex).Take(Grid1.PageSize).ToList();
foreach (var group in pagedData)
{
DataRow row = GridTable.NewRow();
// 基本信息
row["Id"] = Guid.NewGuid().ToString(); // 生成唯一ID用于行标识
row["SerialNumber"] = GridTable.Rows.Count + 1; // 序号
// 单位信息
2025-12-01 10:24:34 +08:00
row["UnitName"] = group.UnitName ?? "";
2025-08-11 14:21:24 +08:00
row["UnitId"] = group.UnitId ?? (object)DBNull.Value;
2025-08-21 11:37:06 +08:00
// 装置信息
2025-12-01 10:24:34 +08:00
row["WorkAreaName"] = group.WorkAreaName ?? "";
row["WorkAreaId"] = group.WorkAreaId ?? (object)DBNull.Value;
2025-08-21 11:37:06 +08:00
2025-08-11 14:21:24 +08:00
// 岗位信息
2025-12-01 10:24:34 +08:00
row["WorkPostName"] = group.WorkPostName ?? "";
row["WorkPostId"] = group.WorkPostId ?? (object)DBNull.Value;
2025-08-11 14:21:24 +08:00
// 每日数量填充
foreach (var kvp in group.DailyCounts)
{
string dateColumnId = kvp.Key.ToString("yyyy-MM-dd");
// 确保列存在
if (GridTable.Columns.Contains(dateColumnId))
{
row[dateColumnId] = kvp.Value;
}
}
// 设置累计数量
row["TotalCount"] = group.TotalCount;
GridTable.Rows.Add(row);
}
Grid1.DataSource = GridTable;
Grid1.DataBind();
// 计算汇总数据
OutputSummaryData();
}
#region
/// <summary>
/// 计算合计
/// </summary>
private void OutputSummaryData()
{
// 创建用于存储合计值的对象
JObject summary = new JObject();
// 设置固定列的合计值
summary.Add("UnitName", "合计");
// 计算TotalCount列的合计值
int totalCountSum = 0;
foreach (DataRow row in GridTable.Rows)
{
if (row["TotalCount"] != DBNull.Value && row["TotalCount"] != null)
{
int value;
if (int.TryParse(row["TotalCount"].ToString(), out value))
{
totalCountSum += value;
}
}
}
summary.Add("TotalCount", totalCountSum.ToString());
// 计算日期列的合计值
foreach (DataColumn column in GridTable.Columns)
{
// 检查是否为日期列(格式为 yyyy-MM-dd
DateTime date;
if (DateTime.TryParseExact(column.ColumnName, "yyyy-MM-dd", null,
System.Globalization.DateTimeStyles.None, out date))
{
// 计算该列的合计值
int columnSum = 0;
foreach (DataRow row in GridTable.Rows)
{
if (row[column.ColumnName] != DBNull.Value && row[column.ColumnName] != null)
{
int value;
if (int.TryParse(row[column.ColumnName].ToString(), out value))
{
columnSum += value;
}
}
}
summary.Add(column.ColumnName, columnSum.ToString());
}
}
// 设置汇总数据
Grid1.SummaryData = summary;
}
#endregion
#endregion
#region GV
/// <summary>
/// 分页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Grid1_PageIndexChange(object sender, GridPageEventArgs e)
{
this.Grid1.PageIndex = e.NewPageIndex;
this.BindGrid();
}
/// <summary>
/// 排序
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Grid1_Sort(object sender, GridSortEventArgs e)
{
this.Grid1.SortDirection = e.SortDirection;
this.Grid1.SortField = e.SortField;
this.BindGrid();
}
/// <summary>
/// 分页显示条数下拉框
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
Grid1.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue);
this.BindGrid();
}
#endregion
#region
/// <summary>
/// 查询
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
protected void btnQuery_OnClick(object sender, EventArgs e)
{
BindGrid();
}
/// <summary>
/// 统计图表
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
protected void btnGetChart_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(UnitId) && !string.IsNullOrEmpty(StartTime) && !string.IsNullOrEmpty(EndTime))
{
// 构建基础URL参数
string urlParams = string.Format("UnitId={0}&StartTime={1}&EndTime={2}", UnitId, StartTime, EndTime);
// 添加岗位参数(如果已选择)
if (drpWorkPost.SelectedValue != Const._Null && !string.IsNullOrEmpty(drpWorkPost.SelectedValue))
{
urlParams += "&WorkPostId=" + drpWorkPost.SelectedValue;
}
2025-08-21 11:37:06 +08:00
// 添加装置参数(如果已选择)
if (drpUnitWork.SelectedValue != Const._Null && !string.IsNullOrEmpty(drpUnitWork.SelectedValue))
{
2025-12-01 10:24:34 +08:00
urlParams += "&WorkAreaId=" + drpUnitWork.SelectedValue;
2025-08-21 11:37:06 +08:00
}
2025-08-11 14:21:24 +08:00
PageContext.RegisterStartupScript(
2025-08-21 11:37:06 +08:00
Window2.GetShowReference(string.Format("ManPowerWorkChart.aspx?{0}", urlParams), "人力考勤图表"));
2025-08-11 14:21:24 +08:00
}
else
{
ShowNotify("请先选确保时间范围已设置", MessageBoxIcon.Warning);
}
}
#endregion
#region
/// <summary>
/// 关闭弹出窗
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Window1_Close(object sender, WindowCloseEventArgs e)
{
BindGrid();
}
#endregion
#region
/// 导出按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnOut_Click(object sender, EventArgs e)
{
Response.ClearContent();
string filename = Funs.GetNewFileName();
Response.AddHeader("content-disposition",
"attachment; filename=" +
System.Web.HttpUtility.UrlEncode("现场考勤人力表" + filename, System.Text.Encoding.UTF8) + ".xls");
Response.ContentType = "application/excel";
Response.ContentEncoding = System.Text.Encoding.UTF8;
this.BindGrid();
// 生成并写入Excel表格
Response.Write(GetGridTableHtml(Grid1));
Response.End();
}
/// <summary>
/// 导出方法 - 支持多级表头
/// </summary>
/// <param name="grid"></param>
/// <returns></returns>
/// <summary>
private string GetGridTableHtml(Grid grid)
{
StringBuilder sb = new StringBuilder();
MultiHeaderTable mht = new MultiHeaderTable();
mht.ResolveMultiHeaderTable(grid.Columns);
sb.Append("<meta http-equiv=\"Content-Type\" content=\"application/vnd.ms-excel;charset=utf-8\"/>");
sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");
// 生成多级表头
foreach (List<object[]> rows in mht.MultiTable)
{
sb.Append("<tr>");
foreach (object[] cell in rows)
{
int rowspan = 1;
int colspan = Convert.ToInt32(cell[1]);
GridColumn column = cell[2] as GridColumn;
// 对于锁定列固定列确保rowspan为3
if (column.Locked)
{
rowspan = 3;
}
sb.AppendFormat("<th{0}{1}{2}>{3}</th>",
" rowspan=\"" + rowspan + "\"",
colspan != 1 ? " colspan=\"" + colspan + "\"" : "",
colspan != 1 ? " style=\"text-align:center;\"" : "",
column.HeaderText);
}
sb.Append("</tr>");
}
// 生成数据行
foreach (GridRow row in grid.Rows)
{
sb.Append("<tr>");
foreach (GridColumn column in mht.Columns)
{
string html = row.Values[column.ColumnIndex].ToString();
// 特殊处理固定列
if (column.ColumnID == "UnitName")
{
html = row.Values[column.ColumnIndex].ToString();
}
else if (column.ColumnID == "WorkPostName")
{
html = row.Values[column.ColumnIndex].ToString();
}
else if (column.ColumnID == "TotalCount")
{
html = row.Values[column.ColumnIndex].ToString();
}
// 处理日期列(格式为 yyyy-MM-dd
else if (DateTime.TryParseExact(column.ColumnID, "yyyy-MM-dd", null,
System.Globalization.DateTimeStyles.None, out _))
{
html = row.Values[column.ColumnIndex].ToString();
}
sb.AppendFormat("<td>{0}</td>", html);
}
sb.Append("</tr>");
}
// 添加合计行
if (grid.SummaryData != null)
{
sb.Append("<tr style=\"font-weight:bold;\">");
foreach (GridColumn column in mht.Columns)
{
string summaryValue = "";
// 检查SummaryData中是否有该列的合计值
if (grid.SummaryData.Properties().Any(p => p.Name == column.ColumnID))
{
var property = grid.SummaryData.Properties().FirstOrDefault(p => p.Name == column.ColumnID);
if (property != null)
{
summaryValue = property.Value.ToString();
}
}
else if (column.ColumnID == "UnitName")
{
summaryValue = "合计";
}
sb.AppendFormat("<td>{0}</td>", summaryValue);
}
sb.Append("</tr>");
}
sb.Append("</table>");
return sb.ToString();
}
#region
/// <summary>
/// 处理多表头的类
/// </summary>
public class MultiHeaderTable
{
// 包含 rowspancolspan 的多表头,方便生成 HTML 的 table 标签
public List<List<object[]>> MultiTable = new List<List<object[]>>();
// 最终渲染的列数组
public List<GridColumn> Columns = new List<GridColumn>();
public void ResolveMultiHeaderTable(GridColumnCollection columns)
{
List<object[]> row = new List<object[]>();
foreach (GridColumn column in columns)
{
object[] cell = new object[4];
cell[0] = 1; // rowspan
cell[1] = 1; // colspan
cell[2] = column;
cell[3] = null;
row.Add(cell);
}
ResolveMultiTable(row, 0);
ResolveColumns(row);
}
private void ResolveColumns(List<object[]> row)
{
foreach (object[] cell in row)
{
GroupField groupField = cell[2] as GroupField;
if (groupField != null && groupField.Columns.Count > 0)
{
List<object[]> subrow = new List<object[]>();
foreach (GridColumn column in groupField.Columns)
{
subrow.Add(new object[]
{
1,
1,
column,
groupField
});
}
ResolveColumns(subrow);
}
else
{
Columns.Add(cell[2] as GridColumn);
}
}
}
private void ResolveMultiTable(List<object[]> row, int level)
{
List<object[]> nextrow = new List<object[]>();
foreach (object[] cell in row)
{
GroupField groupField = cell[2] as GroupField;
if (groupField != null && groupField.Columns.Count > 0)
{
// 如果当前列包含子列,则更改当前列的 colspan以及增加父列向上递归的colspan
cell[1] = Convert.ToInt32(groupField.Columns.Count);
PlusColspan(level - 1, cell[3] as GridColumn, groupField.Columns.Count - 1);
foreach (GridColumn column in groupField.Columns)
{
nextrow.Add(new object[]
{
1,
1,
column,
groupField
});
}
}
else
{
// 如果当前列不包含子列但不是最末级列不是叶子节点则增加rowspan
if (level > 0)
{
cell[0] = level + 1;
}
}
}
MultiTable.Add(row);
if (nextrow.Count > 0)
{
ResolveMultiTable(nextrow, level + 1);
}
}
private void PlusColspan(int level, GridColumn column, int colspan)
{
if (level < 0)
{
return;
}
foreach (List<object[]> rows in MultiTable)
{
foreach (object[] cells in rows)
{
if (cells[2] == column)
{
cells[1] = Convert.ToInt32(cells[1]) + colspan;
PlusColspan(level - 1, cells[3] as GridColumn, colspan);
break;
}
}
}
}
}
#endregion
#endregion
}
}