From 07b7d8426afed3c0c89a4bfe1b8c41686752017a Mon Sep 17 00:00:00 2001 From: geh <1923421292@qq.com> Date: Mon, 1 Dec 2025 10:24:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=BD=E5=B7=A5=E4=BA=BA=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SUBQHSE_V2025-11-30-gh(施工人力).sql | 99 +++++++++ .../JDGL/SGManPower/ManPowerPlan.aspx.cs | 2 +- .../JDGL/SGManPower/ManPowerPlanGrid.aspx.cs | 2 +- .../JDGL/SGManPower/ManPowerStat.aspx | 1 + .../JDGL/SGManPower/ManPowerStat.aspx.cs | 80 +++++-- .../JDGL/SGManPower/ManPowerWork.aspx.cs | 2 +- .../JDGL/SGManPower/ManPowerWorkChart.aspx.cs | 109 +++++----- .../JDGL/SGManPower/ManPowerWorkGrid.aspx.cs | 199 ++++++------------ SGGL/Model/Model.cs | 179 ++++++++++++++++ SGGL/WebAPI/Controllers/IDP/IDPController.cs | 99 +++++++++ SGGL/WebAPI/Filter/TestPermissionAttribute.cs | 1 + 11 files changed, 561 insertions(+), 212 deletions(-) create mode 100644 DataBase/版本日志/SUBQHSE_V2025-11-30-gh(施工人力).sql diff --git a/DataBase/版本日志/SUBQHSE_V2025-11-30-gh(施工人力).sql b/DataBase/版本日志/SUBQHSE_V2025-11-30-gh(施工人力).sql new file mode 100644 index 00000000..7c972a50 --- /dev/null +++ b/DataBase/版本日志/SUBQHSE_V2025-11-30-gh(施工人力).sql @@ -0,0 +1,99 @@ +CREATE TABLE [dbo].[SitePerson_Checking_Statistics] ( + [ProjectId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [UnitId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [UnitName] nvarchar(200) COLLATE Chinese_PRC_CI_AS NULL, + [WorkAreaId] nvarchar(max) COLLATE Chinese_PRC_CI_AS NULL, + [WorkAreaName] nvarchar(max) COLLATE Chinese_PRC_CI_AS NULL, + [WorkPostId] nvarchar(50) COLLATE Chinese_PRC_CI_AS NULL, + [WorkPostName] nvarchar(100) COLLATE Chinese_PRC_CI_AS NULL, + [IntoOutTime] datetime NULL, + [num] int NULL +) +ON [PRIMARY] +GO + +ALTER TABLE [dbo].[SitePerson_Checking_Statistics] SET (LOCK_ESCALATION = TABLE) +GO + +CREATE NONCLUSTERED INDEX [ProjectId_Index] +ON [dbo].[SitePerson_Checking_Statistics] ( + [ProjectId] ASC +) +GO + +CREATE NONCLUSTERED INDEX [UnitId_Index] +ON [dbo].[SitePerson_Checking_Statistics] ( + [UnitId] ASC +) +GO + +CREATE NONCLUSTERED INDEX [NonClusteredIndex-20220601-105641] +ON [dbo].[SitePerson_Checking_Statistics] ( + [ProjectId] ASC, + [IntoOutTime] ASC +) +GO + +CREATE NONCLUSTERED INDEX [WorkPostId_Index] +ON [dbo].[SitePerson_Checking_Statistics] ( + [WorkPostId] ASC +) +GO + +CREATE NONCLUSTERED INDEX [IntoOutTime_Index] +ON [dbo].[SitePerson_Checking_Statistics] ( + [IntoOutTime] ASC +) +go + + + + + + + + +INSERT INTO dbo.SitePerson_Checking_Statistics ( + ProjectId, + UnitId, + UnitName, + WorkAreaId, + WorkAreaName, + WorkPostId, + WorkPostName, + IntoOutTime, + num + ) + SELECT + a.ProjectId, + b.UnitId, + b.UnitName, + b.WorkAreaId, + b.WorkAreaName, + p.WorkPostId, + w.WorkPostName, + CAST(b.IntoOutTime AS DATE) AS IntoOutTime, + COUNT(1) AS num + FROM ( + SELECT + PersonId, + CAST(IntoOutTime AS DATE) AS IntoOutTime, + MAX(CheckingId) AS MaxCheckingId, + ProjectId + FROM SitePerson_Checking + GROUP BY PersonId, CAST(IntoOutTime AS DATE), ProjectId + ) a + JOIN SitePerson_Checking b ON a.MaxCheckingId = b.CheckingId + LEFT JOIN SitePerson_Person p ON a.PersonId = p.PersonId + LEFT JOIN Base_WorkPost w ON p.WorkPostId = w.WorkPostId + LEFT JOIN Base_Project bp ON a.ProjectId = bp.ProjectId + where bp.ProjectState='1' + GROUP BY + a.ProjectId, + b.UnitId, + b.UnitName, + b.WorkAreaId, + b.WorkAreaName, + p.WorkPostId, + w.WorkPostName, + CAST(b.IntoOutTime AS DATE);"; \ No newline at end of file diff --git a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlan.aspx.cs b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlan.aspx.cs index 118a9e01..ebe5ea12 100644 --- a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlan.aspx.cs +++ b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlan.aspx.cs @@ -18,7 +18,7 @@ namespace FineUIPro.Web.JDGL.SGManPower { BLL.UnitService.GetUnit(this.drpUnit, this.CurrUser.LoginProjectId, true);//单位 this.txtStartTime.Text = string.Format("{0:yyyy-MM-dd}", DateTime.Now.AddDays(-30)); - this.txtEndTime.Text = string.Format("{0:yyyy-MM-dd}", DateTime.Now.AddDays(30)); + this.txtEndTime.Text = string.Format("{0:yyyy-MM-dd}", DateTime.Now); DropMainContractCode_SelectedIndexChanged(null, null); } } diff --git a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlanGrid.aspx.cs b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlanGrid.aspx.cs index a738cc01..2e52061e 100644 --- a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlanGrid.aspx.cs +++ b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerPlanGrid.aspx.cs @@ -448,7 +448,7 @@ namespace FineUIPro.Web.JDGL.SGManPower // 版本参数 if (drpVersion.SelectedValue != Const._Null && !string.IsNullOrEmpty(drpVersion.SelectedValue)) { - urlParams += "&drpVersion=" + drpVersion.SelectedValue; + urlParams += "&Version=" + drpVersion.SelectedValue; } PageContext.RegisterStartupScript( diff --git a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx index c71072eb..fb1c86b7 100644 --- a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx +++ b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx @@ -317,6 +317,7 @@ $('input[name="data-filter"]').change(function() { var dataType = $(this).val(); toggleYearSelect(dataType); + loadAndRenderCharts(dataType); }); // 监听年份下拉框变化事件 diff --git a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx.cs b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx.cs index c23658a0..973c8503 100644 --- a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx.cs +++ b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerStat.aspx.cs @@ -82,9 +82,58 @@ namespace FineUIPro.Web.JDGL.SGManPower businessColumn.xFontNum = 8; // 延迟执行查询,只获取需要的数据 - var actualBaseQuery = Funs.DB.T_d_EmployInOutRecord.Where(x => - x.ProjectId == this.CurrUser.LoginProjectId); + // var actualBaseQuery = Funs.DB.T_d_EmployInOutRecord.Where(x => + // x.ProjectId == this.CurrUser.LoginProjectId); + // var query = from spc in Funs.DB.SitePerson_Checking + // where spc.ProjectId == this.CurrUser.LoginProjectId + // select new + // { + // IntoOutTime = spc.IntoOutTime.Value.Date, + // spc.PersonId, + // spc.UnitId, + // } + // into a + // group a by new { a.PersonId, a.IntoOutTime, a.UnitId } + // into g + // select new + // { + // g.Key.PersonId, + // g.Key.UnitId, + // g.Key.IntoOutTime, + // num = g.Count() + // }; + // //关联人员表 + // var actualBaseQuery = (from x in query + // join y in Funs.DB.SitePerson_Person on x.PersonId equals y.PersonId into yInto + // from y in yInto.DefaultIfEmpty() + // select new + // { + // x.PersonId, + // x.IntoOutTime, + // x.UnitId, + // x.num, + // PostId = y.WorkPostId, + // } + // ); + + var actualBaseQuery = from spc in Funs.DB.SitePerson_Checking_Statistics + where spc.ProjectId == this.CurrUser.LoginProjectId + group spc by new + { + spc.UnitId, + spc.WorkPostId, + spc.IntoOutTime + } into g + select new + { + UnitId = g.Key.UnitId, + WorkPostId = g.Key.WorkPostId, + IntoOutTime = g.Key.IntoOutTime, + num = g.Sum(item => item.Num) + }; + + var planBaseQuery = Funs.DB.JDGL_SGManPower.Where(x => x.ProjectId == this.CurrUser.LoginProjectId); @@ -107,14 +156,14 @@ namespace FineUIPro.Web.JDGL.SGManPower else if (chartTitle == "施工单位管理人员统计分析") { actualBaseQuery = - actualBaseQuery.Where(x => Units.Contains(x.UnitId) && workPosts.Contains(x.PostId)); + actualBaseQuery.Where(x => Units.Contains(x.UnitId) && workPosts.Contains(x.WorkPostId)); planBaseQuery = planBaseQuery.Where(x => Units.Contains(x.UnitId) && workPosts.Contains(x.WorkPostId)); } else if (chartTitle == "作业人员统计分析") { actualBaseQuery = - actualBaseQuery.Where(x => Units.Contains(x.UnitId) && !workPosts.Contains(x.PostId)); + actualBaseQuery.Where(x => Units.Contains(x.UnitId) && !workPosts.Contains(x.WorkPostId)); planBaseQuery = planBaseQuery.Where(x => Units.Contains(x.UnitId) && !workPosts.Contains(x.WorkPostId)); } @@ -127,7 +176,7 @@ namespace FineUIPro.Web.JDGL.SGManPower { int selectedYear = int.Parse(year); actualBaseQuery = actualBaseQuery.Where(x => - x.RecordDate.HasValue && x.RecordDate.Value.Year == selectedYear); + x.IntoOutTime.Value.Year == selectedYear); planBaseQuery = planBaseQuery.Where(x => x.PlanDate.HasValue && x.PlanDate.Value.Year == selectedYear); } @@ -135,9 +184,9 @@ namespace FineUIPro.Web.JDGL.SGManPower { int selectedYear = int.Parse(year); int selectedMonth = int.Parse(month); - actualBaseQuery = actualBaseQuery.Where(x => x.RecordDate.HasValue && - x.RecordDate.Value.Year == selectedYear && - x.RecordDate.Value.Month == selectedMonth); + actualBaseQuery = actualBaseQuery.Where(x => + x.IntoOutTime.Value.Year == selectedYear && + x.IntoOutTime.Value.Month == selectedMonth); planBaseQuery = planBaseQuery.Where(x => x.PlanDate.HasValue && x.PlanDate.Value.Year == selectedYear && x.PlanDate.Value.Month == selectedMonth); @@ -152,14 +201,13 @@ namespace FineUIPro.Web.JDGL.SGManPower case "annual": // 按月分组(年度视图显示每个月的数据) var actualAnnualQuery = from x in actualBaseQuery - where x.RecordDate.HasValue - group x by new { x.RecordDate.Value.Year, x.RecordDate.Value.Month } + group x by new { x.IntoOutTime.Value.Year, x.IntoOutTime.Value.Month } into g select new { Year = g.Key.Year, Month = g.Key.Month, - ActualCount = g.Count() + ActualCount = g.Sum(x => x.num) }; var planAnnualQuery = from x in planBaseQuery @@ -185,15 +233,14 @@ namespace FineUIPro.Web.JDGL.SGManPower case "monthly": // 按天分组(月度视图显示每天的数据) var actualMonthlyQuery = from x in actualBaseQuery - where x.RecordDate.HasValue - group x by new { x.RecordDate.Value.Year, x.RecordDate.Value.Month, x.RecordDate.Value.Day } + group x by new { x.IntoOutTime.Value.Year, x.IntoOutTime.Value.Month, x.IntoOutTime.Value.Day } into g select new { Year = g.Key.Year, Month = g.Key.Month, Day = g.Key.Day, - ActualCount = g.Count() + ActualCount = g.Sum(x => x.num) }; var planMonthlyQuery = from x in planBaseQuery @@ -221,14 +268,13 @@ namespace FineUIPro.Web.JDGL.SGManPower default: // 按月分组(默认情况) var actualDefaultQuery = from x in actualBaseQuery - where x.RecordDate.HasValue - group x by new { x.RecordDate.Value.Year, x.RecordDate.Value.Month } + group x by new { x.IntoOutTime.Value.Year, x.IntoOutTime.Value.Month } into g select new { Year = g.Key.Year, Month = g.Key.Month, - ActualCount = g.Count() + ActualCount = g.Sum(x => x.num) }; var planDefaultQuery = from x in planBaseQuery diff --git a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWork.aspx.cs b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWork.aspx.cs index 2d546e52..10729369 100644 --- a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWork.aspx.cs +++ b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWork.aspx.cs @@ -15,7 +15,7 @@ namespace FineUIPro.Web.JDGL.SGManPower { BLL.UnitService.GetUnit(this.drpUnit, this.CurrUser.LoginProjectId, true);//单位 this.txtStartTime.Text = string.Format("{0:yyyy-MM-dd}", DateTime.Now.AddDays(-30)); - this.txtEndTime.Text = string.Format("{0:yyyy-MM-dd}", DateTime.Now.AddDays(30)); + this.txtEndTime.Text = string.Format("{0:yyyy-MM-dd}", DateTime.Now); DropMainContractCode_SelectedIndexChanged(null, null); } } diff --git a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkChart.aspx.cs b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkChart.aspx.cs index 810b4f5d..622b8705 100644 --- a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkChart.aspx.cs +++ b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkChart.aspx.cs @@ -30,7 +30,7 @@ namespace FineUIPro.Web.JDGL.SGManPower string startTime = Request.Params["StartTime"]; string endTime = Request.Params["EndTime"]; string workPostId = Request.Params["WorkPostId"]; - string unitWorkId = Request.Params["UnitWorkId"]; + string workAreaId = Request.Params["WorkAreaId"]; // 检查必要参数 if (string.IsNullOrEmpty(startTime) || string.IsNullOrEmpty(endTime)) @@ -42,87 +42,84 @@ namespace FineUIPro.Web.JDGL.SGManPower DateTime startDate = Convert.ToDateTime(startTime); DateTime endDate = Convert.ToDateTime(endTime); - // 使用原生SQL查询直接在数据库中进行聚合计算,提高性能 - string strSql = @" - SELECT e.UnitId, e.PostId, e.RecordDate, p.WorkAreaId as UnitWorkId - FROM T_d_EmployInOutRecord e INNER JOIN SitePerson_Person p ON e.IDCardNo = p.IdentityCard AND e.ProjectId = p.ProjectId - WHERE e.PostId IS NOT NULL AND e.PostId != '' - AND e.ProjectId = @ProjectId - AND e.RecordDate >= @StartDate - AND e.RecordDate <= @EndDate"; - - var parameters = new List - { - new SqlParameter("@ProjectId", this.CurrUser.LoginProjectId), - new SqlParameter("@StartDate", startDate), - new SqlParameter("@EndDate", endDate) - }; - + var getData = Funs.DB.SitePerson_Checking_Statistics.Where(x => + x.ProjectId == this.CurrUser.LoginProjectId && x.IntoOutTime >= startDate && x.IntoOutTime <= endDate); + // 添加单位筛选条件 if (!string.IsNullOrEmpty(unitId) && unitId != Const._Null) { - strSql += " AND e.UnitId = @UnitId"; - parameters.Add(new SqlParameter("@UnitId", unitId)); + getData = getData.Where(x => x.UnitId == unitId); } - + // 添加岗位筛选条件 if (!string.IsNullOrEmpty(workPostId) && workPostId != Const._Null) { - strSql += " AND e.PostId = @WorkPostId"; - parameters.Add(new SqlParameter("@WorkPostId", workPostId)); + getData = getData.Where(x => x.WorkPostId == workPostId); } - - // 执行查询 - var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray()); + + DataTable dt = this.LINQToDataTable(getData.ToList()); // 创建一个新的DataTable来存储处理后的数据 DataTable processedDt = dt.Clone(); foreach (System.Data.DataRow row in dt.Rows) { - string ids = row["UnitWorkId"] != DBNull.Value ? row["UnitWorkId"].ToString() : string.Empty; - if (!string.IsNullOrEmpty(ids)) - { - string[] unitWorkIdArray = ids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string id in unitWorkIdArray) - { - // 往processedDt里面添加数据,每个UnitWorkId一行 - DataRow newRow = processedDt.NewRow(); - newRow["UnitId"] = row["UnitId"]; - newRow["PostId"] = row["PostId"]; - newRow["RecordDate"] = row["RecordDate"]; - newRow["UnitWorkId"] = id.Trim(); - processedDt.Rows.Add(newRow); - } - } - else - { + // 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; + // a++; + // processedDt.Rows.Add(newRow); + // } + // } + // else + // { DataRow newRow = processedDt.NewRow(); newRow["UnitId"] = row["UnitId"]; - newRow["PostId"] = row["PostId"]; - newRow["RecordDate"] = row["RecordDate"]; - newRow["UnitWorkId"] = string.Empty; + 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; processedDt.Rows.Add(newRow); - } + // } } - // 确定要用于后续处理的数据源 IEnumerable dataSource = processedDt.AsEnumerable(); // 如果选择了特定的装置进行筛选 - if (!string.IsNullOrEmpty(unitWorkId) && unitWorkId != Const._Null) + if (!string.IsNullOrEmpty(workAreaId) && workAreaId != Const._Null) { - dataSource = dataSource.Where(x => x["UnitWorkId"] != DBNull.Value && x["UnitWorkId"].ToString() == unitWorkId); + dataSource = dataSource.Where(x => x["WorkAreaId"] != DBNull.Value && x["WorkAreaId"].ToString() == workAreaId); } + + var da = dataSource.ToList(); //针对dt中的数据进行分组 var data = dataSource .GroupBy(row => new { - RecordDate = row["RecordDate"] + IntoOutTime = row["IntoOutTime"] }).Select(group => new { - RecordDate = group.Key.RecordDate, - RecordCount = group.Count() - }).ToList(); + IntoOutTime = group.Key.IntoOutTime, + RecordCount = group.Sum(row => row["num"] != DBNull.Value ? Convert.ToInt32(row["num"]) : 0) + }).OrderBy(x => x.IntoOutTime).ToList(); // 如果没有数据,显示提示信息 @@ -155,13 +152,13 @@ namespace FineUIPro.Web.JDGL.SGManPower // 添加数据点 foreach (var item in data) { - if (item.RecordDate != null) + if (item.IntoOutTime != null) { - DateTime recordDate = Convert.ToDateTime(item.RecordDate); + DateTime IntoOutTime = Convert.ToDateTime(item.IntoOutTime); Model.DataSourcePoint point = new Model.DataSourcePoint { - PointText = recordDate.ToString("MM-dd"), + PointText = IntoOutTime.ToString("MM-dd"), PointValue = item.RecordCount.ToString() }; dataSourceTeam.DataSourcePoints.Add(point); diff --git a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkGrid.aspx.cs b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkGrid.aspx.cs index 72d206bf..e59fef56 100644 --- a/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkGrid.aspx.cs +++ b/SGGL/FineUIPro.Web/JDGL/SGManPower/ManPowerWorkGrid.aspx.cs @@ -39,13 +39,13 @@ namespace FineUIPro.Web.JDGL.SGManPower // 添加隐藏列来存储额外的ID信息 GridTable.Columns.Add("UnitId"); - GridTable.Columns.Add("UnitWorkId"); + GridTable.Columns.Add("WorkAreaId"); GridTable.Columns.Add("WorkPostId"); ListItem[] list = new ListItem[5]; list[0] = new ListItem("序号", "SerialNumber"); list[1] = new ListItem("单位", "UnitName"); - list[2] = new ListItem("装置", "UnitWorkName"); + list[2] = new ListItem("装置", "WorkAreaName"); list[3] = new ListItem("岗位", "WorkPostName"); list[4] = new ListItem("累计", "TotalCount"); @@ -160,14 +160,14 @@ namespace FineUIPro.Web.JDGL.SGManPower { GridTable.Columns.Add("Id"); GridTable.Columns.Add("UnitId"); - GridTable.Columns.Add("UnitWorkId"); + GridTable.Columns.Add("WorkAreaId"); GridTable.Columns.Add("WorkPostId"); // 添加动态日期列(这部分已经在InitGrid中定义了) ListItem[] list = new ListItem[5]; list[0] = new ListItem("序号", "SerialNumber"); list[1] = new ListItem("单位", "UnitName"); - list[2] = new ListItem("装置", "UnitWorkName"); + list[2] = new ListItem("装置", "WorkAreaName"); list[3] = new ListItem("岗位", "WorkPostName"); list[4] = new ListItem("累计", "TotalCount"); foreach (var item in list) @@ -183,89 +183,69 @@ namespace FineUIPro.Web.JDGL.SGManPower GridTable.Rows.Clear(); } - // 使用原生SQL查询来提高性能,直接在数据库层面进行分组统计 - string strSql = @" - SELECT e.UnitId, e.PostId, e.RecordDate, p.WorkAreaId as UnitWorkId - FROM T_d_EmployInOutRecord e INNER JOIN SitePerson_Person p ON e.IDCardNo = p.IdentityCard AND e.ProjectId = p.ProjectId - WHERE e.PostId IS NOT NULL AND e.PostId != '' - AND e.ProjectId = @ProjectId - AND e.RecordDate >= @StartDate - AND e.RecordDate <= @EndDate"; - - var parameters = new List - { - new System.Data.SqlClient.SqlParameter("@ProjectId", this.CurrUser.LoginProjectId), - new System.Data.SqlClient.SqlParameter("@StartDate", Convert.ToDateTime(StartTime)), - new System.Data.SqlClient.SqlParameter("@EndDate", Convert.ToDateTime(EndTime)) - }; - - if (UnitId != Const._Null) - { - strSql += " AND e.UnitId = @UnitId"; - parameters.Add(new System.Data.SqlClient.SqlParameter("@UnitId", UnitId)); - } - - if (drpWorkPost.SelectedValue != Const._Null) - { - strSql += " AND e.PostId = @PostId"; - parameters.Add(new System.Data.SqlClient.SqlParameter("@PostId", drpWorkPost.SelectedValue)); - } - - // 执行查询获取分组数据 - var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray()); - + 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()); // 创建一个新的DataTable来存储处理后的数据 DataTable processedDt = dt.Clone(); foreach (System.Data.DataRow row in dt.Rows) { - string ids = row["UnitWorkId"] != DBNull.Value ? row["UnitWorkId"].ToString() : string.Empty; - if (!string.IsNullOrEmpty(ids)) - { - string[] unitWorkIdArray = ids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string unitWorkId in unitWorkIdArray) - { - // 往processedDt里面添加数据,每个UnitWorkId一行 - DataRow newRow = processedDt.NewRow(); - newRow["UnitId"] = row["UnitId"]; - newRow["PostId"] = row["PostId"]; - newRow["RecordDate"] = row["RecordDate"]; - newRow["UnitWorkId"] = unitWorkId.Trim(); - processedDt.Rows.Add(newRow); - } - } - else - { + // 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 + // { DataRow newRow = processedDt.NewRow(); newRow["UnitId"] = row["UnitId"]; - newRow["PostId"] = row["PostId"]; - newRow["RecordDate"] = row["RecordDate"]; - newRow["UnitWorkId"] = string.Empty; + 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; processedDt.Rows.Add(newRow); - } + // } } //针对dt中的数据进行分组 var data = processedDt.AsEnumerable() - .GroupBy(row => new { - UnitId = row["UnitId"], - PostId = row["PostId"], - UnitWorkId = row["UnitWorkId"], - RecordDate = row["RecordDate"] - }).Select(group => new + .Select(row => new { - UnitId = group.Key.UnitId, - PostId = group.Key.PostId, - UnitWorkId = group.Key.UnitWorkId, - RecordDate = group.Key.RecordDate, - RecordCount = group.Count() + UnitId = row["UnitId"], + UnitName = row["UnitName"], + WorkPostId = row["WorkPostId"], + WorkPostName = row["WorkPostName"], + WorkAreaId = row["WorkAreaId"], + WorkAreaName = row["WorkAreaName"], + IntoOutTime = row["IntoOutTime"], + num = row["num"], }).ToList(); var data1 = data; // 如果选择了特定的装置进行筛选 if (drpUnitWork.SelectedValue != Const._Null) { - data1 = data.Where(x => x.UnitWorkId.ToString() == drpUnitWork.SelectedValue).ToList(); + data1 = data.Where(x => x.WorkAreaId.ToString() == drpUnitWork.SelectedValue).ToList(); } // 将数据转换为更易处理的格式 @@ -273,23 +253,26 @@ namespace FineUIPro.Web.JDGL.SGManPower var groupedDict = new Dictionary(); foreach (var item in data1) { - string key = $"{item.UnitId}_{item.PostId}_{item.UnitWorkId}"; - DateTime recordDate = Convert.ToDateTime(item.RecordDate); - int count = Convert.ToInt32(item.RecordCount); + string key = $"{item.UnitId}_{item.WorkPostId}_{item.WorkAreaId}"; + DateTime IntoOutTime = Convert.ToDateTime(item.IntoOutTime); + int count = Convert.ToInt32(item.num); if (!groupedDict.ContainsKey(key)) { dynamic group = new System.Dynamic.ExpandoObject(); group.UnitId = item.UnitId; - group.PostId = item.PostId; - group.UnitWorkId = item.UnitWorkId; + group.UnitName = item.UnitName; + group.WorkPostId = item.WorkPostId; + group.WorkPostName = item.WorkPostName; + group.WorkAreaId = item.WorkAreaId; + group.WorkAreaName = item.WorkAreaName; group.DailyCounts = new Dictionary(); group.TotalCount = 0; groupedDict[key] = group; groupedData.Add(group); } - groupedDict[key].DailyCounts[recordDate] = count; + groupedDict[key].DailyCounts[IntoOutTime] = count; groupedDict[key].TotalCount += count; } @@ -298,47 +281,6 @@ namespace FineUIPro.Web.JDGL.SGManPower // 分页处理 var pagedData = groupedData.Skip(Grid1.PageSize * Grid1.PageIndex).Take(Grid1.PageSize).ToList(); - // 只获取当前页需要的单位和岗位信息,避免加载全部数据 - var unitIds = pagedData.Where(x => x.UnitId != null).Select(x => x.UnitId.ToString()).Distinct().ToList(); - var postIds = pagedData.Where(x => x.PostId != null).Select(x => x.PostId.ToString()).Distinct().ToList(); - var unitWorkIds = pagedData.Where(x => x.UnitWorkId != null).Select(x => x.UnitWorkId.ToString()).Distinct().ToList(); - - var units = new Dictionary(); - var workPosts = new Dictionary(); - var unitWorks = new Dictionary(); - - if (unitIds.Any()) - { - var unitQuery = from u in Funs.DB.Base_Unit - where unitIds.Contains(u.UnitId) - select new { u.UnitId, u.UnitName }; - foreach (var u in unitQuery) - { - units[u.UnitId] = u.UnitName; - } - } - - if (postIds.Any()) - { - var postQuery = from p in Funs.DB.Base_WorkPost - where postIds.Contains(p.WorkPostId) - select new { p.WorkPostId, p.WorkPostName }; - foreach (var p in postQuery) - { - workPosts[p.WorkPostId] = p.WorkPostName; - } - } - if (unitWorkIds.Any()) - { - var unitWorkQuery = from p in Funs.DB.WBS_UnitWork - where unitWorkIds.Contains(p.UnitWorkId) - select new { p.UnitWorkId, p.UnitWorkName }; - foreach (var p in unitWorkQuery) - { - unitWorks[p.UnitWorkId] = p.UnitWorkName; - } - } - foreach (var group in pagedData) { DataRow row = GridTable.NewRow(); @@ -348,31 +290,16 @@ namespace FineUIPro.Web.JDGL.SGManPower row["SerialNumber"] = GridTable.Rows.Count + 1; // 序号 // 单位信息 - string unitName = ""; - if (group.UnitId != null && units.ContainsKey(group.UnitId.ToString())) - { - unitName = units[group.UnitId.ToString()]; - } - row["UnitName"] = unitName; + row["UnitName"] = group.UnitName ?? ""; row["UnitId"] = group.UnitId ?? (object)DBNull.Value; // 装置信息 - string unitWorkName = ""; - if (group.UnitWorkId != null && unitWorks.ContainsKey(group.UnitWorkId.ToString())) - { - unitWorkName = unitWorks[group.UnitWorkId.ToString()]; - } - row["UnitWorkName"] = unitWorkName; - row["UnitWorkId"] = group.UnitWorkId ?? (object)DBNull.Value; + row["WorkAreaName"] = group.WorkAreaName ?? ""; + row["WorkAreaId"] = group.WorkAreaId ?? (object)DBNull.Value; // 岗位信息 - string workPostName = ""; - if (group.PostId != null && workPosts.ContainsKey(group.PostId.ToString())) - { - workPostName = workPosts[group.PostId.ToString()]; - } - row["WorkPostName"] = workPostName; - row["WorkPostId"] = group.PostId ?? (object)DBNull.Value; + row["WorkPostName"] = group.WorkPostName ?? ""; + row["WorkPostId"] = group.WorkPostId ?? (object)DBNull.Value; // 每日数量填充 foreach (var kvp in group.DailyCounts) @@ -531,7 +458,7 @@ namespace FineUIPro.Web.JDGL.SGManPower // 添加装置参数(如果已选择) if (drpUnitWork.SelectedValue != Const._Null && !string.IsNullOrEmpty(drpUnitWork.SelectedValue)) { - urlParams += "&UnitWorkId=" + drpUnitWork.SelectedValue; + urlParams += "&WorkAreaId=" + drpUnitWork.SelectedValue; } PageContext.RegisterStartupScript( diff --git a/SGGL/Model/Model.cs b/SGGL/Model/Model.cs index 09778dd5..f15143e0 100644 --- a/SGGL/Model/Model.cs +++ b/SGGL/Model/Model.cs @@ -8892,6 +8892,14 @@ namespace Model } } + public System.Data.Linq.Table SitePerson_Checking_Statistics + { + get + { + return this.GetTable(); + } + } + public System.Data.Linq.Table SitePerson_DayReport { get @@ -350663,6 +350671,177 @@ namespace Model } } + [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.SitePerson_Checking_Statistics")] + public partial class SitePerson_Checking_Statistics + { + + private string _ProjectId; + + private string _UnitId; + + private string _UnitName; + + private string _WorkAreaId; + + private string _WorkAreaName; + + private string _WorkPostId; + + private string _WorkPostName; + + private System.Nullable _IntoOutTime; + + private System.Nullable _Num; + + public SitePerson_Checking_Statistics() + { + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ProjectId", DbType="NVarChar(50)")] + public string ProjectId + { + get + { + return this._ProjectId; + } + set + { + if ((this._ProjectId != value)) + { + this._ProjectId = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitId", DbType="NVarChar(50)")] + public string UnitId + { + get + { + return this._UnitId; + } + set + { + if ((this._UnitId != value)) + { + this._UnitId = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitName", DbType="NVarChar(200)")] + public string UnitName + { + get + { + return this._UnitName; + } + set + { + if ((this._UnitName != value)) + { + this._UnitName = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_WorkAreaId", DbType="NVarChar(MAX)", UpdateCheck=UpdateCheck.Never)] + public string WorkAreaId + { + get + { + return this._WorkAreaId; + } + set + { + if ((this._WorkAreaId != value)) + { + this._WorkAreaId = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_WorkAreaName", DbType="NVarChar(MAX)", UpdateCheck=UpdateCheck.Never)] + public string WorkAreaName + { + get + { + return this._WorkAreaName; + } + set + { + if ((this._WorkAreaName != value)) + { + this._WorkAreaName = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_WorkPostId", DbType="NVarChar(50)")] + public string WorkPostId + { + get + { + return this._WorkPostId; + } + set + { + if ((this._WorkPostId != value)) + { + this._WorkPostId = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_WorkPostName", DbType="NVarChar(100)")] + public string WorkPostName + { + get + { + return this._WorkPostName; + } + set + { + if ((this._WorkPostName != value)) + { + this._WorkPostName = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_IntoOutTime", DbType="DateTime")] + public System.Nullable IntoOutTime + { + get + { + return this._IntoOutTime; + } + set + { + if ((this._IntoOutTime != value)) + { + this._IntoOutTime = value; + } + } + } + + [global::System.Data.Linq.Mapping.ColumnAttribute(Name="num", Storage="_Num", DbType="Int")] + public System.Nullable Num + { + get + { + return this._Num; + } + set + { + if ((this._Num != value)) + { + this._Num = value; + } + } + } + } + [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.SitePerson_DayReport")] public partial class SitePerson_DayReport : INotifyPropertyChanging, INotifyPropertyChanged { diff --git a/SGGL/WebAPI/Controllers/IDP/IDPController.cs b/SGGL/WebAPI/Controllers/IDP/IDPController.cs index c9f921b5..c790a2da 100644 --- a/SGGL/WebAPI/Controllers/IDP/IDPController.cs +++ b/SGGL/WebAPI/Controllers/IDP/IDPController.cs @@ -2,6 +2,8 @@ using Model; using System; using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; using System.Linq; using System.Threading.Tasks; using System.Web.Http; @@ -200,5 +202,102 @@ namespace WebAPI.Controllers } #endregion + + + + #region 统计考勤人员考勤数据 + + /// + /// 统计考勤人员考勤数据 + /// + /// + [HttpPost] + public Model.ReturnData SynSitePersonCheckingStatistics() + { + var responeData = new Model.ReturnData(); + responeData.time = DateTime.Now.ToString(); + using (SqlConnection Connection = new SqlConnection(Funs.ConnString)) + { + try + { + string sql = @" + TRUNCATE TABLE dbo.SitePerson_Checking_Statistics; + + INSERT INTO dbo.SitePerson_Checking_Statistics ( + ProjectId, + UnitId, + UnitName, + WorkAreaId, + WorkAreaName, + WorkPostId, + WorkPostName, + IntoOutTime, + num + ) + SELECT + a.ProjectId, + b.UnitId, + b.UnitName, + b.WorkAreaId, + b.WorkAreaName, + p.WorkPostId, + w.WorkPostName, + CAST(b.IntoOutTime AS DATE) AS IntoOutTime, + COUNT(1) AS num + FROM ( + SELECT + PersonId, + CAST(IntoOutTime AS DATE) AS IntoOutTime, + MAX(CheckingId) AS MaxCheckingId, + ProjectId + FROM SitePerson_Checking + GROUP BY PersonId, CAST(IntoOutTime AS DATE), ProjectId + ) a + JOIN SitePerson_Checking b ON a.MaxCheckingId = b.CheckingId + LEFT JOIN SitePerson_Person p ON a.PersonId = p.PersonId + LEFT JOIN Base_WorkPost w ON p.WorkPostId = w.WorkPostId + LEFT JOIN Base_Project bp ON a.ProjectId = bp.ProjectId + where bp.ProjectState='1' + GROUP BY + a.ProjectId, + b.UnitId, + b.UnitName, + b.WorkAreaId, + b.WorkAreaName, + p.WorkPostId, + w.WorkPostName, + CAST(b.IntoOutTime AS DATE);"; + + Connection.Open(); + SqlCommand command = new SqlCommand(sql, Connection) + { + CommandTimeout = 0, + CommandType = CommandType.Text + }; + int result = command.ExecuteNonQuery(); + responeData.message = $"执行成功,共插入 {result} 条记录"; + } + catch (SqlException sqlEx) + { + responeData.code = 0; + responeData.message = $"数据库操作失败: {sqlEx.Message}"; + } + catch (Exception ex) + { + responeData.code = 0; + responeData.message = $"执行失败: {ex.Message}"; + } + finally + { + Connection.Close(); + } + } + + return responeData; + } + + #endregion + + } } \ No newline at end of file diff --git a/SGGL/WebAPI/Filter/TestPermissionAttribute.cs b/SGGL/WebAPI/Filter/TestPermissionAttribute.cs index 5f615e6a..df4e59ad 100644 --- a/SGGL/WebAPI/Filter/TestPermissionAttribute.cs +++ b/SGGL/WebAPI/Filter/TestPermissionAttribute.cs @@ -94,6 +94,7 @@ namespace WebAPI.Filter "IDP*SynIDPPreRunData", "IDP*SynOADesignDrawingDataBlueprintInfo", "IDP*SynOADesignDrawingDataPrintInfo", + "IDP*SynSitePersonCheckingStatistics", "JGZL*getUserList", "JGZL*getProjedtList", "JGZL*getUnitWorkListByProjectId",