2025-08-21 11:37:06 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using Model;
|
|
|
|
|
|
using System.Data;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace BLL
|
|
|
|
|
|
{
|
|
|
|
|
|
public class SGManPowerService
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 检查并发送人力资源预警
|
|
|
|
|
|
/// </summary>
|
2025-10-28 17:20:48 +08:00
|
|
|
|
public static List<ToDoItem> CheckAndSendPersonWarning(string userId)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
var responeData = new Model.ResponeData();
|
|
|
|
|
|
// 合并两个集合
|
|
|
|
|
|
var allItems = new List<ToDoItem>();
|
|
|
|
|
|
var projects = Funs.DB.Base_Project.Where(p => p.ProjectState == BLL.Const.ProjectState_1).ToList();
|
2025-10-28 17:20:48 +08:00
|
|
|
|
foreach (var project in projects)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 检查管理人员到期未到岗情况
|
2025-11-11 11:09:49 +08:00
|
|
|
|
var items1 = CheckHistoricalContinuousShortage(project.ProjectId);
|
2025-08-21 11:37:06 +08:00
|
|
|
|
|
2025-10-28 17:20:48 +08:00
|
|
|
|
// 检查作业人员人力偏差情况
|
|
|
|
|
|
var items2 = CheckWorkerDeviation(project.ProjectId);
|
2025-08-21 11:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-10-28 17:20:48 +08:00
|
|
|
|
if (items1 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
allItems.AddRange(items1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (items2 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
allItems.AddRange(items2);
|
|
|
|
|
|
}
|
2025-08-21 11:37:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-28 17:20:48 +08:00
|
|
|
|
if (!string.IsNullOrEmpty(userId))
|
2025-08-21 11:37:06 +08:00
|
|
|
|
{
|
2025-10-28 17:20:48 +08:00
|
|
|
|
//过滤出指定用户的数据
|
|
|
|
|
|
allItems = allItems.Where(x => x.UserId == userId).ToList();
|
2025-08-21 11:37:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-28 17:20:48 +08:00
|
|
|
|
return allItems;
|
2025-08-21 11:37:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
#region 检查所有历史数据中连续一周以上人力不足的情况
|
2025-08-21 11:37:06 +08:00
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 检查所有历史数据中连续一周以上人力不足的情况
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static IEnumerable<ToDoItem> CheckHistoricalContinuousShortage(string projectId)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
{
|
2025-12-05 14:37:05 +08:00
|
|
|
|
string strSql = @"WITH LatestVersions AS (
|
|
|
|
|
|
SELECT ProjectId, MAX(Version) AS MaxVersion
|
|
|
|
|
|
FROM JDGL_SGManPower
|
|
|
|
|
|
WHERE ProjectId = @ProjectId
|
|
|
|
|
|
GROUP BY ProjectId
|
|
|
|
|
|
),
|
|
|
|
|
|
PlanVsActual AS (
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
p.ProjectId,
|
|
|
|
|
|
p.UnitId,
|
|
|
|
|
|
p.UnitWorkId,
|
|
|
|
|
|
p.WorkPostId,
|
|
|
|
|
|
p.PlanDate,
|
|
|
|
|
|
p.Quantity AS PlanQuantity,
|
|
|
|
|
|
ISNULL(a.num, 0) AS num,
|
|
|
|
|
|
CASE WHEN ISNULL(a.num, 0) < p.Quantity THEN 1 ELSE 0 END AS IsShortage,
|
|
|
|
|
|
lv.MaxVersion
|
|
|
|
|
|
FROM JDGL_SGManPower p
|
|
|
|
|
|
INNER JOIN LatestVersions lv ON p.ProjectId = lv.ProjectId AND p.Version = lv.MaxVersion
|
|
|
|
|
|
LEFT JOIN ( SELECT ProjectId,UnitId,WorkPostId,IntoOutTime,WorkAreaId,num FROM SitePerson_Checking_Statistics ) a ON p.ProjectId = a.ProjectId
|
|
|
|
|
|
AND p.UnitId = a.UnitId
|
|
|
|
|
|
AND p.WorkPostId = a.WorkPostId
|
|
|
|
|
|
AND p.PlanDate = a.IntoOutTime
|
|
|
|
|
|
AND (CHARINDEX(',' + p.UnitWorkId + ',', ',' + ISNULL(a.WorkAreaId, '') + ',') > 0
|
|
|
|
|
|
OR (ISNULL(a.WorkAreaId, '') = '' AND ISNULL(p.UnitWorkId, '') = ''))
|
|
|
|
|
|
WHERE p.ProjectId = @ProjectId AND p.PlanDate <= GETDATE()
|
|
|
|
|
|
),
|
|
|
|
|
|
ShortageWithRowNum AS (
|
|
|
|
|
|
SELECT *,
|
|
|
|
|
|
ROW_NUMBER() OVER (
|
|
|
|
|
|
PARTITION BY ProjectId, UnitId, UnitWorkId, WorkPostId
|
|
|
|
|
|
ORDER BY PlanDate
|
|
|
|
|
|
) AS RowNum
|
|
|
|
|
|
FROM PlanVsActual
|
|
|
|
|
|
WHERE IsShortage = 1
|
|
|
|
|
|
),
|
|
|
|
|
|
ContinuousGroups AS (
|
|
|
|
|
|
SELECT *,
|
|
|
|
|
|
DATEADD(DAY, -RowNum, PlanDate) AS GroupId
|
|
|
|
|
|
FROM ShortageWithRowNum
|
|
|
|
|
|
),
|
|
|
|
|
|
ContinuousCounts AS (
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
ProjectId,
|
|
|
|
|
|
UnitId,
|
|
|
|
|
|
UnitWorkId,
|
|
|
|
|
|
WorkPostId,
|
|
|
|
|
|
GroupId,
|
|
|
|
|
|
COUNT(*) AS ContinuousDays,
|
|
|
|
|
|
MIN(PlanDate) AS StartDate,
|
|
|
|
|
|
MAX(PlanDate) AS EndDate,
|
|
|
|
|
|
SUM(PlanQuantity) as PlanQuantity,
|
|
|
|
|
|
SUM(num) as num,
|
|
|
|
|
|
MaxVersion
|
|
|
|
|
|
FROM ContinuousGroups
|
|
|
|
|
|
GROUP BY ProjectId, UnitId, UnitWorkId, WorkPostId, GroupId,MaxVersion
|
|
|
|
|
|
)
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
ProjectId,
|
|
|
|
|
|
UnitId,
|
|
|
|
|
|
UnitWorkId,
|
|
|
|
|
|
WorkPostId,
|
|
|
|
|
|
ContinuousDays,
|
|
|
|
|
|
MaxVersion,
|
|
|
|
|
|
StartDate,
|
|
|
|
|
|
EndDate,PlanQuantity,num
|
|
|
|
|
|
FROM ContinuousCounts
|
|
|
|
|
|
WHERE ContinuousDays >= 7";
|
2025-08-21 11:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
var parameters = new List<System.Data.SqlClient.SqlParameter>
|
|
|
|
|
|
{
|
2025-12-05 14:37:05 +08:00
|
|
|
|
new System.Data.SqlClient.SqlParameter("@ProjectId", projectId)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
};
|
2025-12-05 14:37:05 +08:00
|
|
|
|
var warningItems = new List<ToDoItem>();
|
2025-08-21 11:37:06 +08:00
|
|
|
|
var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray());
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
foreach (DataRow row in dt.Rows)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
{
|
2025-12-05 14:37:05 +08:00
|
|
|
|
warningItems.AddRange(SendManagerWarning(row["UnitId"].ToString(), row["ProjectId"].ToString(),
|
|
|
|
|
|
row["WorkPostId"].ToString(), row["UnitWorkId"].ToString(),
|
|
|
|
|
|
Convert.ToDateTime(row["StartDate"]), Convert.ToDateTime(row["EndDate"]),
|
|
|
|
|
|
Convert.ToInt32(row["PlanQuantity"]), Convert.ToInt32(row["num"])));
|
2025-08-21 11:37:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
return warningItems;
|
|
|
|
|
|
}
|
2025-08-21 11:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 发送管理人员预警
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="projectId">项目ID</param>
|
|
|
|
|
|
/// <param name="unitId">单位id</param>
|
2025-10-28 17:20:48 +08:00
|
|
|
|
private static List<ToDoItem> SendManagerWarning(string unitId, string projectId, string workPostId,
|
2025-11-11 11:09:49 +08:00
|
|
|
|
string unitWorkId, DateTime? startDate, DateTime? endDate, int? quantity, int num)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 发送预警信息
|
|
|
|
|
|
var toDoItems = new List<ToDoItem>();
|
|
|
|
|
|
|
|
|
|
|
|
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<string> toUserIds = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
// 施工单位人员推送至施工单位项目经理和总包单位施工经理
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2025-10-28 17:20:48 +08:00
|
|
|
|
warningContent =
|
2025-11-11 11:09:49 +08:00
|
|
|
|
$"{projectUnits.UnitName}单位{unitWorks.UnitWorkName}装置计划{string.Format("{0:yyyy-MM-dd}", startDate)}~{string.Format("{0:yyyy-MM-dd}", endDate)}投入人力{quantity}人,实际考勤为{num}人。";
|
2025-10-28 17:20:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
warningContent =
|
2025-11-11 11:09:49 +08:00
|
|
|
|
$"{projectUnits.UnitName}单位计划{string.Format("{0:yyyy-MM-dd}", startDate)}~{string.Format("{0:yyyy-MM-dd}", endDate)}投入人力{quantity}人,实际考勤为{num}人。";
|
2025-10-28 17:20:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 11:09:49 +08:00
|
|
|
|
string urlParams = "JDGL/SGManPower/SGWarningDetailsEdit.aspx?projectId=" + projectId;
|
2025-10-28 17:20:48 +08:00
|
|
|
|
// 添加单位参数(如果已选择)
|
|
|
|
|
|
if (!string.IsNullOrEmpty(unitId))
|
|
|
|
|
|
{
|
|
|
|
|
|
urlParams += "&unitId=" + unitId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加装置参数(如果已选择)
|
|
|
|
|
|
if (!string.IsNullOrEmpty(unitWorkId))
|
|
|
|
|
|
{
|
|
|
|
|
|
urlParams += "&unitWorkId=" + unitWorkId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加岗位参数(如果已选择)
|
|
|
|
|
|
if (!string.IsNullOrEmpty(workPostId))
|
|
|
|
|
|
{
|
|
|
|
|
|
urlParams += "&workPostId=" + workPostId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加时间参数
|
2025-11-11 11:09:49 +08:00
|
|
|
|
if (startDate.HasValue)
|
2025-10-28 17:20:48 +08:00
|
|
|
|
{
|
2025-11-11 11:09:49 +08:00
|
|
|
|
urlParams += "&startTime=" + string.Format("{0:yyyy-MM-dd}", startDate);
|
2025-10-28 17:20:48 +08:00
|
|
|
|
}
|
2025-12-05 14:37:05 +08:00
|
|
|
|
|
2025-11-11 11:09:49 +08:00
|
|
|
|
// 添加时间参数
|
|
|
|
|
|
if (endDate.HasValue)
|
2025-10-28 17:20:48 +08:00
|
|
|
|
{
|
2025-11-11 11:09:49 +08:00
|
|
|
|
urlParams += "&endTime=" + string.Format("{0:yyyy-MM-dd}", endDate);
|
2025-10-28 17:20:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
foreach (var userId in toUserIds)
|
|
|
|
|
|
{
|
|
|
|
|
|
Model.ToDoItem toDoItem = new Model.ToDoItem();
|
|
|
|
|
|
toDoItem.DataId = SQLHelper.GetNewID(typeof(Model.ToDoItem));
|
|
|
|
|
|
toDoItem.MenuId = "";
|
|
|
|
|
|
toDoItem.MenuName = "管理人员到岗预警";
|
2025-10-28 17:20:48 +08:00
|
|
|
|
toDoItem.ProjectCode = "";
|
2025-08-21 11:37:06 +08:00
|
|
|
|
toDoItem.Content = warningContent;
|
|
|
|
|
|
toDoItem.UserId = userId;
|
|
|
|
|
|
toDoItem.UserName = UserService.GetUserNameByUserId(userId);
|
|
|
|
|
|
toDoItem.DataTime = DateTime.Now;
|
|
|
|
|
|
toDoItem.DataTimeStr = DateTime.Now.ToString("yyyy-MM-dd");
|
2025-10-28 17:20:48 +08:00
|
|
|
|
toDoItem.PCUrl = urlParams;
|
2025-08-21 11:37:06 +08:00
|
|
|
|
toDoItems.Add(toDoItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return toDoItems;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 检查作业人员人力偏差情况
|
|
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
// /// <summary>
|
2025-12-05 14:37:05 +08:00
|
|
|
|
// /// 检查作业人员人力偏差情况(一周内(连续7天不是最近七天)累计偏差值超过计划的10%)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
// /// </summary>
|
|
|
|
|
|
// /// <param name="projectId">项目ID</param>
|
|
|
|
|
|
private static IEnumerable<ToDoItem> CheckWorkerDeviation(string projectId)
|
|
|
|
|
|
{
|
2025-12-05 14:37:05 +08:00
|
|
|
|
string strSql = @"WITH LatestVersions AS (
|
|
|
|
|
|
SELECT ProjectId, MAX(Version) AS MaxVersion
|
|
|
|
|
|
FROM JDGL_SGManPower
|
|
|
|
|
|
WHERE ProjectId = @ProjectId
|
|
|
|
|
|
GROUP BY ProjectId
|
|
|
|
|
|
),
|
|
|
|
|
|
PlanVsActual AS (
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
p.ProjectId,
|
|
|
|
|
|
p.UnitId,
|
|
|
|
|
|
p.UnitWorkId,
|
|
|
|
|
|
p.WorkPostId,
|
|
|
|
|
|
p.PlanDate,
|
|
|
|
|
|
p.Quantity AS PlanQuantity,
|
|
|
|
|
|
ISNULL(a.num, 0) AS num,
|
|
|
|
|
|
CASE
|
|
|
|
|
|
WHEN p.Quantity > 0 AND ABS(CAST((p.Quantity - ISNULL(a.num, 0)) AS FLOAT) / p.Quantity) > 0.1
|
|
|
|
|
|
THEN 1
|
|
|
|
|
|
ELSE 0
|
|
|
|
|
|
END AS HasDeviation,
|
|
|
|
|
|
lv.MaxVersion
|
|
|
|
|
|
FROM JDGL_SGManPower p
|
|
|
|
|
|
INNER JOIN LatestVersions lv ON p.ProjectId = lv.ProjectId AND p.Version = lv.MaxVersion
|
|
|
|
|
|
LEFT JOIN (
|
|
|
|
|
|
SELECT ProjectId,UnitId,WorkPostId,IntoOutTime,WorkAreaId,num
|
|
|
|
|
|
FROM SitePerson_Checking_Statistics
|
|
|
|
|
|
) a ON p.ProjectId = a.ProjectId
|
|
|
|
|
|
AND p.UnitId = a.UnitId
|
|
|
|
|
|
AND p.WorkPostId = a.WorkPostId
|
|
|
|
|
|
AND p.PlanDate = a.IntoOutTime
|
|
|
|
|
|
AND (CHARINDEX(',' + p.UnitWorkId + ',', ',' + ISNULL(a.WorkAreaId, '') + ',') > 0
|
|
|
|
|
|
OR (ISNULL(a.WorkAreaId, '') = '' AND ISNULL(p.UnitWorkId, '') = ''))
|
|
|
|
|
|
WHERE p.ProjectId = @ProjectId AND p.PlanDate <= GETDATE()
|
|
|
|
|
|
),
|
|
|
|
|
|
DeviationWithRowNum AS (
|
|
|
|
|
|
SELECT *,
|
|
|
|
|
|
ROW_NUMBER() OVER (
|
|
|
|
|
|
PARTITION BY ProjectId, UnitId, UnitWorkId, WorkPostId
|
|
|
|
|
|
ORDER BY PlanDate
|
|
|
|
|
|
) AS RowNum
|
|
|
|
|
|
FROM PlanVsActual
|
|
|
|
|
|
WHERE HasDeviation = 1
|
|
|
|
|
|
),
|
|
|
|
|
|
ContinuousGroups AS (
|
|
|
|
|
|
SELECT *,
|
|
|
|
|
|
DATEADD(DAY, -RowNum, PlanDate) AS GroupId
|
|
|
|
|
|
FROM DeviationWithRowNum
|
|
|
|
|
|
),
|
|
|
|
|
|
ContinuousCounts AS (
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
ProjectId,
|
|
|
|
|
|
UnitId,
|
|
|
|
|
|
UnitWorkId,
|
|
|
|
|
|
WorkPostId,
|
|
|
|
|
|
GroupId,
|
|
|
|
|
|
COUNT(*) AS ContinuousDays,
|
|
|
|
|
|
MIN(PlanDate) AS StartDate,
|
|
|
|
|
|
MAX(PlanDate) AS EndDate,
|
|
|
|
|
|
SUM(PlanQuantity) as TotalPlanQuantity,
|
|
|
|
|
|
SUM(num) as num,
|
|
|
|
|
|
MaxVersion
|
|
|
|
|
|
FROM ContinuousGroups
|
|
|
|
|
|
GROUP BY ProjectId, UnitId, UnitWorkId, WorkPostId, GroupId, MaxVersion
|
|
|
|
|
|
)
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
ProjectId,
|
|
|
|
|
|
UnitId,
|
|
|
|
|
|
UnitWorkId,
|
|
|
|
|
|
WorkPostId,
|
|
|
|
|
|
ContinuousDays,
|
|
|
|
|
|
MaxVersion,
|
|
|
|
|
|
StartDate,
|
|
|
|
|
|
EndDate,
|
|
|
|
|
|
TotalPlanQuantity,
|
|
|
|
|
|
num
|
|
|
|
|
|
FROM ContinuousCounts
|
|
|
|
|
|
WHERE ContinuousDays >= 7";
|
2025-08-21 11:37:06 +08:00
|
|
|
|
|
|
|
|
|
|
var parameters = new List<System.Data.SqlClient.SqlParameter>
|
|
|
|
|
|
{
|
2025-12-05 14:37:05 +08:00
|
|
|
|
new System.Data.SqlClient.SqlParameter("@ProjectId", projectId)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
var warningItems = new List<ToDoItem>();
|
2025-08-21 11:37:06 +08:00
|
|
|
|
var dt = SQLHelper.GetDataTableRunText(strSql, parameters.ToArray());
|
|
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
foreach (DataRow row in dt.Rows)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
{
|
2025-12-05 14:37:05 +08:00
|
|
|
|
warningItems.AddRange(SendWorkerDeviationWarning(
|
|
|
|
|
|
row["UnitId"].ToString(),
|
|
|
|
|
|
row["ProjectId"].ToString(),
|
|
|
|
|
|
row["WorkPostId"].ToString(),
|
|
|
|
|
|
row["UnitWorkId"].ToString(),
|
|
|
|
|
|
Convert.ToDateTime(row["StartDate"]),
|
|
|
|
|
|
Convert.ToDateTime(row["EndDate"]),
|
|
|
|
|
|
Convert.ToInt32(row["TotalPlanQuantity"]),
|
|
|
|
|
|
Convert.ToInt32(row["num"])
|
|
|
|
|
|
));
|
2025-08-21 11:37:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
return warningItems;
|
2025-08-21 11:37:06 +08:00
|
|
|
|
}
|
2025-12-05 14:37:05 +08:00
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 发送作业人员偏差预警
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="projectId">项目ID</param>
|
|
|
|
|
|
/// <param name="unitId">单位ID</param>
|
|
|
|
|
|
/// <param name="planTotal">计划总人数</param>
|
|
|
|
|
|
/// <param name="actualTotal">实际总人数</param>
|
|
|
|
|
|
/// <param name="deviationPercentage">偏差百分比</param>
|
2025-10-28 17:20:48 +08:00
|
|
|
|
private static List<ToDoItem> SendWorkerDeviationWarning(string unitId, string projectId, string workPostId,
|
2025-12-05 14:37:05 +08:00
|
|
|
|
string unitWorkId, DateTime? startDate, DateTime? endDate, int? quantity, int num)
|
2025-08-21 11:37:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 发送预警信息
|
|
|
|
|
|
var toDoItems = new List<ToDoItem>();
|
|
|
|
|
|
List<string> toUserIds = new List<string>();
|
2025-10-28 17:20:48 +08:00
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-28 17:20:48 +08:00
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
// 获取总包单位施工经理
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-28 17:20:48 +08:00
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
// 构建预警信息内容
|
|
|
|
|
|
string warningContent = string.Empty;
|
|
|
|
|
|
if (unitWorks != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
warningContent =
|
|
|
|
|
|
$"{projectUnits.UnitName}单位{unitWorks.UnitWorkName}装置计划投入人力{quantity}人,实际考勤为{num}人。";
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
warningContent = $"{projectUnits.UnitName}单位计划投入人力{quantity}人,实际考勤为{num}人。";
|
|
|
|
|
|
}
|
2025-10-28 17:20:48 +08:00
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
// 发送预警信息
|
|
|
|
|
|
foreach (var userId in toUserIds)
|
|
|
|
|
|
{
|
|
|
|
|
|
Model.ToDoItem toDoItem = new Model.ToDoItem();
|
|
|
|
|
|
toDoItem.DataId = SQLHelper.GetNewID(typeof(Model.ToDoItem));
|
|
|
|
|
|
toDoItem.MenuId = "";
|
|
|
|
|
|
toDoItem.MenuName = "人力资源偏差预警";
|
2025-10-28 17:20:48 +08:00
|
|
|
|
toDoItem.ProjectCode = "";
|
2025-08-21 11:37:06 +08:00
|
|
|
|
toDoItem.Content = warningContent;
|
|
|
|
|
|
toDoItem.UserId = userId;
|
|
|
|
|
|
toDoItem.UserName = UserService.GetUserNameByUserId(userId);
|
|
|
|
|
|
toDoItem.DataTime = DateTime.Now;
|
|
|
|
|
|
toDoItem.DataTimeStr = DateTime.Now.ToString("yyyy-MM-dd");
|
2025-10-28 17:20:48 +08:00
|
|
|
|
toDoItem.PCUrl = urlParams;
|
2025-08-21 11:37:06 +08:00
|
|
|
|
toDoItems.Add(toDoItem);
|
|
|
|
|
|
}
|
2025-10-28 17:20:48 +08:00
|
|
|
|
|
2025-08-21 11:37:06 +08:00
|
|
|
|
return toDoItems;
|
|
|
|
|
|
}
|
2025-11-11 11:09:49 +08:00
|
|
|
|
|
2025-12-05 14:37:05 +08:00
|
|
|
|
#endregion
|
2025-08-21 11:37:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|