using System; using System.Collections.Generic; using System.Linq; using Model; using System.Data; namespace BLL { public class SGManPowerService { /// /// 检查并发送人力资源预警 /// public static List CheckAndSendPersonWarning(string userId) { var responeData = new Model.ResponeData(); // 合并两个集合 var allItems = new List(); var projects = Funs.DB.Base_Project.Where(p => p.ProjectState == BLL.Const.ProjectState_1).ToList(); foreach (var project in projects) { // 检查管理人员到期未到岗情况 var items1 = CheckManagerNotArrived(project.ProjectId); // 检查作业人员人力偏差情况 var items2 = CheckWorkerDeviation(project.ProjectId); if (items1 != null) { allItems.AddRange(items1); } if (items2 != null) { allItems.AddRange(items2); } } if (!string.IsNullOrEmpty(userId)) { //过滤出指定用户的数据 allItems = allItems.Where(x => x.UserId == userId).ToList(); } return allItems; } /// /// 检查管理人员到期未到岗情况(超过一周发出预警) /// /// 项目ID private static IEnumerable CheckManagerNotArrived(string projectId) { //获取计划的最新版本 var version = "1"; var sgMan = Funs.DB.JDGL_SGManPower.Where(x => x.ProjectId == projectId).OrderByDescending(x => x.Version) .FirstOrDefault(); if (sgMan != null) { version = sgMan.Version; } // 先获取计划表超过一周的管理岗位有哪些 var dataList = (from x in Funs.DB.JDGL_SGManPower join p in Funs.DB.Base_WorkPost on x.WorkPostId equals p.WorkPostId into pp from y in pp.DefaultIfEmpty() where x.ProjectId == projectId && (y.PostType == "4" || y.PostType == "1") && x.PlanDate <= DateTime.Now.AddDays(-7) && x.Version == version select x).ToList(); var lItems = new List(); //循环检查实际考勤中的人数 foreach (var data in dataList) { //根据人员计划表获取计划中的管理人员数 int num = getInOutRecordNum(data); if (data.Quantity > num) { lItems = SendManagerWarning(data.UnitId, projectId, data.WorkPostId, data.UnitWorkId, data.PlanDate, data.Quantity, num); } } return lItems; } //获取实际考勤人员数 private static int getInOutRecordNum(JDGL_SGManPower sgManPower) { 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 = @RecordDate AND e.UnitId = @UnitId AND e.PostId = @PostId"; var parameters = new List { new System.Data.SqlClient.SqlParameter("@ProjectId", sgManPower.ProjectId), new System.Data.SqlClient.SqlParameter("@RecordDate", sgManPower.PlanDate), new System.Data.SqlClient.SqlParameter("@UnitId", sgManPower.UnitId), new System.Data.SqlClient.SqlParameter("@PostId", sgManPower.WorkPostId), }; // 执行查询获取分组数据 var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray()); // 创建一个新的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 { DataRow newRow = processedDt.NewRow(); newRow["UnitId"] = row["UnitId"]; newRow["PostId"] = row["PostId"]; newRow["RecordDate"] = row["RecordDate"]; newRow["UnitWorkId"] = string.Empty; processedDt.Rows.Add(newRow); } } // 确定要用于后续处理的数据源 IEnumerable dataSource = processedDt.AsEnumerable(); if (string.IsNullOrEmpty(sgManPower.UnitWorkId)) { dataSource = dataSource.Where(x => x["UnitWorkId"] == null); } else { dataSource = dataSource.Where(x => x["UnitWorkId"] != DBNull.Value && x["UnitWorkId"].ToString() == sgManPower.UnitWorkId); } return dataSource.Count(); } /// /// 发送管理人员预警 /// /// 项目ID /// 单位id private static List SendManagerWarning(string unitId, string projectId, string workPostId, string unitWorkId, DateTime? planDate, int? quantity, int num) { // 发送预警信息 var toDoItems = new List(); var unitWorks = (from x in Funs.DB.WBS_UnitWork where x.UnitWorkId == unitWorkId select new { x.UnitWorkId, x.UnitWorkName }).FirstOrDefault(); var projectUnits = (from x in Funs.DB.Project_ProjectUnit join y in Funs.DB.Base_Unit on x.UnitId equals y.UnitId where x.UnitId == unitId select new { x.UnitId, y.UnitName, x.UnitType }).FirstOrDefault(); if (projectUnits != null) { List toUserIds = new List(); // 施工单位人员推送至施工单位项目经理和总包单位施工经理 if (projectUnits.UnitType == Const.ProjectUnitType_2) // 施工分包单位 { // 获取施工单位项目经理 var constructionManagers = (from x in Funs.DB.Project_ProjectUser where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true && x.RoleId.Contains(Const.ProjectManager) select x).ToList(); if (constructionManagers.Count > 0) { foreach (var projectUser in constructionManagers) { toUserIds.Add(projectUser.UserId); } } // 获取总包单位施工经理 var generalContractorUnit = Funs.DB.Project_ProjectUnit.FirstOrDefault(pu => pu.ProjectId == projectId && pu.UnitType == Const.ProjectUnitType_1); // 总包单位 if (generalContractorUnit != null) { var constructionManagerGCs = (from x in Funs.DB.Project_ProjectUser where x.ProjectId == projectId && x.UnitId == generalContractorUnit.UnitId && x.IsPost == true && x.RoleId.Contains(Const.ConstructionManager) select x).ToList(); if (constructionManagerGCs.Count > 0) { foreach (var projectUser in constructionManagerGCs) { toUserIds.Add(projectUser.UserId); } } } } // 总包单位人员推送到总包单位施工经理和项目经理 else if (projectUnits.UnitType == Const.ProjectUnitType_1) // 总包单位 { // 获取总包单位施工经理 var constructionManagers = (from x in Funs.DB.Project_ProjectUser where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true && x.RoleId.Contains(Const.ConstructionManager) select x).ToList(); if (constructionManagers.Count() > 0) { foreach (var projectUser in constructionManagers) { toUserIds.Add(projectUser.UserId); } } // 获取总包单位项目经理 var projectManagers = (from x in Funs.DB.Project_ProjectUser where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true && x.RoleId.Contains(Const.ProjectManager) select x).ToList(); if (projectManagers.Count() > 0) { foreach (var projectUser in projectManagers) { toUserIds.Add(projectUser.UserId); } } } string warningContent = string.Empty; if (unitWorks != null) { warningContent = $"{projectUnits.UnitName}单位{unitWorks.UnitWorkName}装置计划{string.Format("{0:yyyy-MM-dd}", planDate)}投入人力{quantity}人,实际考勤为{num}人。"; } else { warningContent = $"{projectUnits.UnitName}单位计划{string.Format("{0:yyyy-MM-dd}", planDate)}投入人力{quantity}人,实际考勤为{num}人。"; } string urlParams = "JDGL/SGManPower/SGWarningDetails.aspx?projectId=" + projectId; // 添加单位参数(如果已选择) if (!string.IsNullOrEmpty(unitId)) { urlParams += "&unitId=" + unitId; } // 添加装置参数(如果已选择) if (!string.IsNullOrEmpty(unitWorkId)) { urlParams += "&unitWorkId=" + unitWorkId; } // 添加岗位参数(如果已选择) if (!string.IsNullOrEmpty(workPostId)) { urlParams += "&workPostId=" + workPostId; } // 添加时间参数 if (planDate.HasValue) { urlParams += "&planDate=" + string.Format("{0:yyyy-MM-dd}", planDate); } // 添加岗位参数(如果已选择) if (quantity.HasValue) { urlParams += "&quantity=" + quantity.Value; } // 添加岗位参数(如果已选择) if (num >= 0) { urlParams += "&num=" + num; } else { urlParams += "&num=0"; } foreach (var userId in toUserIds) { Model.ToDoItem toDoItem = new Model.ToDoItem(); toDoItem.DataId = SQLHelper.GetNewID(typeof(Model.ToDoItem)); toDoItem.MenuId = ""; toDoItem.MenuName = "管理人员到岗预警"; toDoItem.ProjectCode = ""; toDoItem.Content = warningContent; toDoItem.UserId = userId; toDoItem.UserName = UserService.GetUserNameByUserId(userId); toDoItem.DataTime = DateTime.Now; toDoItem.DataTimeStr = DateTime.Now.ToString("yyyy-MM-dd"); toDoItem.PCUrl = urlParams; toDoItems.Add(toDoItem); } } return toDoItems; } // /// // /// 检查作业人员人力偏差情况(一周内累计偏差值超过计划的10%) // /// // /// 项目ID private static IEnumerable CheckWorkerDeviation(string projectId) { //获取计划的最新版本 var version = "1"; var sgMan = Funs.DB.JDGL_SGManPower.Where(x => x.ProjectId == projectId).OrderByDescending(x => x.Version) .FirstOrDefault(); if (sgMan != null) { version = sgMan.Version; } //当前时间 var endDate = DateTime.Now; //当前时间前7天 var startDate = DateTime.Now.AddDays(-7); // 先获取计划表一周的作业岗位有哪些 var dataList = (from x in Funs.DB.JDGL_SGManPower join p in Funs.DB.Base_WorkPost on x.WorkPostId equals p.WorkPostId into pp from y in pp.DefaultIfEmpty() where x.ProjectId == projectId && (y.PostType == "2" || y.PostType == "3") && x.PlanDate >= startDate && x.PlanDate <= endDate && x.Version == version group x by new { x.UnitId, x.UnitWorkId, x.WorkPostId } into g select new { UnitId = g.Key.UnitId, UnitWorkId = g.Key.UnitWorkId, WorkPostId = g.Key.WorkPostId, QuantitySum = g.Sum(x => x.Quantity) }).ToList(); var lItems = new List(); //循环检查实际考勤中的人数 foreach (var data in dataList) { //根据人员计划表获取计划中的作业人员数 int num = getInOutRecordNum1(data.UnitId, data.UnitWorkId, data.WorkPostId, projectId); // 计算偏差百分比 if (data.QuantitySum != 0) { double deviationPercentage = Math.Abs((double)((data.QuantitySum - num) / data.QuantitySum)); // 如果偏差超过10%,发出预警 if (deviationPercentage > 0.1) { lItems = SendWorkerDeviationWarning(data.UnitId, projectId, data.WorkPostId, data.UnitWorkId, startDate, endDate, data.QuantitySum, num); } } } return lItems; } //获取实际考勤人员数 private static int getInOutRecordNum1(string unitId, string unitWorkId, string workPostId, string projectId) { 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.UnitId = @UnitId AND e.PostId = @PostId AND e.RecordDate >= @StartDate AND e.RecordDate <= @EndDate"; var parameters = new List { new System.Data.SqlClient.SqlParameter("@ProjectId", projectId), new System.Data.SqlClient.SqlParameter("@UnitId", unitId), new System.Data.SqlClient.SqlParameter("@PostId", workPostId), new System.Data.SqlClient.SqlParameter("@StartDate", DateTime.Now.AddDays(-7)), new System.Data.SqlClient.SqlParameter("@EndDate", DateTime.Now), }; // 执行查询获取分组数据 var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray()); // 创建一个新的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 { DataRow newRow = processedDt.NewRow(); newRow["UnitId"] = row["UnitId"]; newRow["PostId"] = row["PostId"]; newRow["RecordDate"] = row["RecordDate"]; newRow["UnitWorkId"] = string.Empty; processedDt.Rows.Add(newRow); } } // 确定要用于后续处理的数据源 IEnumerable dataSource = processedDt.AsEnumerable(); if (string.IsNullOrEmpty(unitWorkId)) { dataSource = dataSource.Where(x => x["UnitWorkId"] == null); } else { dataSource = dataSource.Where(x => x["UnitWorkId"] != DBNull.Value && x["UnitWorkId"].ToString() == unitWorkId); } return dataSource.Count(); } /// /// 发送作业人员偏差预警 /// /// 项目ID /// 单位ID /// 计划总人数 /// 实际总人数 /// 偏差百分比 private static List SendWorkerDeviationWarning(string unitId, string projectId, string workPostId, string unitWorkId, DateTime? startDate, DateTime? endDate, int? quantity, int num) { // 发送预警信息 var toDoItems = new List(); List toUserIds = new List(); var unitWorks = (from x in Funs.DB.WBS_UnitWork where x.UnitWorkId == unitWorkId select new { x.UnitWorkId, x.UnitWorkName }).FirstOrDefault(); var projectUnits = (from x in Funs.DB.Project_ProjectUnit join y in Funs.DB.Base_Unit on x.UnitId equals y.UnitId where x.UnitId == unitId select new { x.UnitId, y.UnitName, x.UnitType }).FirstOrDefault(); // 获取施工单位项目经理 var constructionManagers = (from x in Funs.DB.Project_ProjectUser where x.ProjectId == projectId && x.UnitId == unitId && x.IsPost == true && x.RoleId.Contains(Const.ProjectManager) select x).ToList(); if (constructionManagers.Count > 0) { foreach (var projectUser in constructionManagers) { toUserIds.Add(projectUser.UserId); } } // 获取总包单位施工经理 var generalContractorUnit = Funs.DB.Project_ProjectUnit.FirstOrDefault(pu => pu.ProjectId == projectId && pu.UnitType == Const.ProjectUnitType_1); // 总包单位 if (generalContractorUnit != null) { var constructionManagerGCs = (from x in Funs.DB.Project_ProjectUser where x.ProjectId == projectId && x.UnitId == generalContractorUnit.UnitId && x.IsPost == true && x.RoleId.Contains(Const.ConstructionManager) select x).ToList(); if (constructionManagerGCs.Count > 0) { foreach (var projectUser in constructionManagerGCs) { toUserIds.Add(projectUser.UserId); } } } // 构建预警信息内容 string warningContent = string.Empty; if (unitWorks != null) { warningContent = $"{projectUnits.UnitName}单位{unitWorks.UnitWorkName}装置计划投入人力{quantity}人,实际考勤为{num}人。"; } else { warningContent = $"{projectUnits.UnitName}单位计划投入人力{quantity}人,实际考勤为{num}人。"; } string urlParams = "JDGL/SGManPower/SGWarningDetails.aspx?projectId=" + projectId; // 添加单位参数(如果已选择) if (!string.IsNullOrEmpty(unitId)) { urlParams += "&unitId=" + unitId; } // 添加装置参数(如果已选择) if (!string.IsNullOrEmpty(unitWorkId)) { urlParams += "&unitWorkId=" + unitWorkId; } // 添加岗位参数(如果已选择) if (!string.IsNullOrEmpty(workPostId)) { urlParams += "&workPostId=" + workPostId; } // 添加时间参数 if (startDate.HasValue && endDate.HasValue) { urlParams += "&planDate=" + string.Format("{0:yyyy-MM-dd}", startDate) + "~" + string.Format("{0:yyyy-MM-dd}", endDate); } // 添加岗位参数(如果已选择) if (quantity.HasValue) { urlParams += "&quantity=" + quantity.Value; } // 添加岗位参数(如果已选择) if (num >= 0) { urlParams += "&num=" + num; } else { urlParams += "&num=0"; } // 发送预警信息 foreach (var userId in toUserIds) { Model.ToDoItem toDoItem = new Model.ToDoItem(); toDoItem.DataId = SQLHelper.GetNewID(typeof(Model.ToDoItem)); toDoItem.MenuId = ""; toDoItem.MenuName = "人力资源偏差预警"; toDoItem.ProjectCode = ""; toDoItem.Content = warningContent; toDoItem.UserId = userId; toDoItem.UserName = UserService.GetUserNameByUserId(userId); toDoItem.DataTime = DateTime.Now; toDoItem.DataTimeStr = DateTime.Now.ToString("yyyy-MM-dd"); toDoItem.PCUrl = urlParams; toDoItems.Add(toDoItem); } return toDoItems; } } }