diff --git a/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs b/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs
index 313bd292..7bb4f8a7 100644
--- a/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs
@@ -158,6 +158,7 @@ public class WorkGridsController : ControllerBase
///
///
[HttpPost("user/schedule/remove")]
+ [Transactional]
public async Task RemoveAsyncScheduleAsync(WorkGridScheduleSaveRequest request)
{
await _workGridScheduleService.RemoveAsync(request);
diff --git a/Src/Dlhis.Basic/WorkGrids/Request/WorkGridUserRemoveRequest.cs b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridUserRemoveRequest.cs
index e5358bc5..43d98592 100644
--- a/Src/Dlhis.Basic/WorkGrids/Request/WorkGridUserRemoveRequest.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridUserRemoveRequest.cs
@@ -4,6 +4,10 @@ namespace Dlhis.Basic.WorkGrids.Request;
public class WorkGridUserRemoveRequest
{
+ ///
+ /// 网格code
+ ///
+ /// 兼容被非档案用户操作 eg:wyz要求
public Guid? WorkGridCode { get; set; }
///
diff --git a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs
index 6d1f1bf2..73aa1b2d 100644
--- a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs
@@ -58,7 +58,8 @@ public class WorkGridScheduleService : IWorkGridScheduleService
.Where(x => x.Code == request.WorkGridCode)
.Select((x, ga) => new
{
- x.Code, x.Name,
+ x.Code,
+ x.Name,
x.LeaderUserCode,
LeaderUserName = ga.Name,
x.MaxConsecutiveLimitCount
@@ -73,6 +74,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
timeSetting.ThrowIfNull("工作网格时间尚未配置,无法操作");
+ //班次开始前一个小时不可操作
var currentLimit = request.Date.ToDateTime(timeSetting.Start.Add(-TimeSpan.FromHours(1)));
(DateTime.Now >= currentLimit).ThrowIfTrue("当前时间不可修改排班信息");
@@ -84,6 +86,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
var others = request.UserCodes.Except(workGridUserCodes).ToList();
others.ThrowIfExists($"{others.Join(",")}非当前网格人员");
+ //处理排班冲突问题
var dateBefore = request.Date.AddDays(-1);
var dateAfter = request.Date.AddDays(1);
@@ -94,9 +97,11 @@ public class WorkGridScheduleService : IWorkGridScheduleService
)
.ToListAsync();
+ //重复排班
var existsUserCodes = scheduleRange.Where(x => x.Date == request.Date && request.UserCodes.Contains(x.UserCode)).Select(x => x.UserCode).ToList();
existsUserCodes.ThrowIfExists(existsUserCodes.Join(",") + "当天已存在排班");
+ //当前排班为白班,那么上一天不能存在晚班
if (request.PeriodType == WorkGridTimePeriodEnumType.Day)
{
existsUserCodes = scheduleRange
@@ -104,6 +109,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
.Select(x => x.UserCode).ToList();
existsUserCodes.ThrowIfExists(existsUserCodes.Join(",") + $"在{dateBefore.ToString("yyyy-MM-dd")}已存在{WorkGridTimePeriodEnumType.Night.GetDescription()}");
}
+ //当前排班为晚班,那么下一天不能存在白班
else if (request.PeriodType == WorkGridTimePeriodEnumType.Night)
{
existsUserCodes = scheduleRange
@@ -111,10 +117,20 @@ public class WorkGridScheduleService : IWorkGridScheduleService
.Select(x => x.UserCode).ToList();
existsUserCodes.ThrowIfExists(existsUserCodes.Join(",") + $"在{dateAfter.ToString("yyyy-MM-dd")}已存在{WorkGridTimePeriodEnumType.Day.GetDescription()}");
}
+ else
+ {
+ throw new ArgumentException("排班类型错误,请检查");
+ }
- var maximumConsecutiveListDto = await _workGridScheduleRepository.MaximumConsecutiveUserCodesAsync(request.UserCodes, workGrid.MaxConsecutiveLimitCount, request.Date);
+ //连续排班限制
+ var maximumConsecutiveListDto = await _workGridScheduleRepository.MaximumConsecutiveUserCodesAsync(
+ request.UserCodes,
+ workGrid.MaxConsecutiveLimitCount,
+ request.Date
+ );
maximumConsecutiveListDto.ThrowIfExists(maximumConsecutiveListDto.Select(x => $"{x.UserCode}已经连续排班{workGrid.MaxConsecutiveLimitCount}天({x.Start}-{x.End}),禁止排班").Join("\r\n"));
+ //数据保存
var toInserts = request.UserCodes.Select(x => new WorkGridScheduleEntity
{
WorkGridCode = request.WorkGridCode,
@@ -126,7 +142,41 @@ public class WorkGridScheduleService : IWorkGridScheduleService
await _dbContext.InsertAsync(toInserts);
await _operateLog.LogAsync(OperateLogType.WorkGrid, $"新增网格({workGrid.Name}){request.Date.ToString("yyyy-M-d")}的{request.PeriodType.GetDescription()}人员:{request.UserCodes.Join(",")}");
+ if (workGrid.Code.ToString() == "769ace3b-28fa-4c4e-ba46-fc399a25085f")
+ {
+ //推送到SAP
+ var items = toInserts.Select(x => new SyncWorkShiftDayItem
+ {
+ UserCode = x.UserCode,
+ Begin = x.Date.ToString("yyyyMMdd"),
+ End = x.Date.ToString("yyyyMMdd"),
+ Plan = request.PeriodType == WorkGridTimePeriodEnumType.Day ? "JK03" : "JK04",
+ Operate = "INS"
+ }).ToList();
+ var response = await _jinkoJipApi.SyncWorkShiftAsync(new SyncWorkShiftRequest { Items = items });
+ if (response.Items.Any(x => x.Result != "S"))
+ {
+ var errorMessages = response.Items.Where(x => x.Result != "S")
+ .Select(x => $"{x.UserCode}排班新增失败:{x.Message}").Join("\r\n");
+ throw new UserFriendlyException(errorMessages);
+ }
+
+ foreach (var workGridSchedule in toInserts)
+ {
+ var msg = response.Items.FirstOrDefault(x => x.UserCode == workGridSchedule.UserCode)?.Message;
+ await _dbContext.Updateable()
+ .SetColumns(x => x.SyncResult == msg)
+ .Where(x => x.WorkGridCode == workGrid.Code)
+ .Where(x => x.UserCode == workGridSchedule.UserCode)
+ .Where(x => x.Date == workGridSchedule.Date)
+ .Where(x => x.PeriodType == workGridSchedule.PeriodType)
+ .ExecuteCommandAsync();
+ }
+ }
+
+ //todo sub pub
+ //推送排班通知
try
{
var codeAndNameList = await _dbContext.Queryable().Where(x => request.UserCodes.Contains(x.Code))
@@ -151,7 +201,103 @@ public class WorkGridScheduleService : IWorkGridScheduleService
}
catch (Exception e)
{
- _logger.LogError("推送信息错误save,{error}", e.Message);
+ _logger.LogError("推送信息错误save:{error}", e.Message);
+ }
+ }
+
+
+ public async Task RemoveAsync(WorkGridScheduleSaveRequest request)
+ {
+ var workGrid = await _dbContext.Queryable()
+ .LeftJoin((x, ga) => x.LeaderUserCode == ga.Code)
+ .Where(x => x.Code == request.WorkGridCode)
+ .Select((x, ga) => new
+ {
+ x.Code,
+ x.Name,
+ x.LeaderUserCode,
+ LeaderUserName = ga.Name
+ })
+ .SingleAsync();
+ workGrid.ThrowIfNull("工作网格不存在");
+
+ var timeSetting = await _dbContext.Queryable()
+ .Where(x => x.Type == request.PeriodType)
+ .Select(x => new { x.Start, x.Before })
+ .SingleAsync();
+
+ //班次识别区间内禁止操作移除
+ var currentLimit = request.Date.ToDateTime(timeSetting.Start.Add(-TimeSpan.FromSeconds(timeSetting.Before)));
+ (DateTime.Now >= currentLimit).ThrowIfTrue("当前时间不可修改排班信息");
+
+ //获取需要移除的班次数据
+ var data = await _dbContext.Queryable()
+ .Where(x => x.WorkGridCode == request.WorkGridCode)
+ .Where(x => x.Date == request.Date)
+ .Where(x => x.PeriodType == request.PeriodType)
+ .Where(x => request.UserCodes.Contains(x.UserCode))
+ .ToListAsync();
+
+ if (data.Any())
+ {
+ if (workGrid.Code.ToString() == "769ace3b-28fa-4c4e-ba46-fc399a25085f")
+ {
+ //推送到SAP
+ var items = data.Select(x => new SyncWorkShiftDayItem
+ {
+ UserCode = x.UserCode,
+ Begin = x.Date.ToString("yyyyMMdd"),
+ End = x.Date.ToString("yyyyMMdd"),
+ Plan = request.PeriodType == WorkGridTimePeriodEnumType.Day ? "JK03" : "JK04",
+ Operate = "DEL"
+ }).ToList();
+
+ var response = await _jinkoJipApi.SyncWorkShiftAsync(new SyncWorkShiftRequest { Items = items });
+ if (response.Items.Any(x => x.Result != "S"))
+ {
+ var errorMessages = response.Items.Where(x => x.Result != "S")
+ .Select(x => $"{x.UserCode}排班删除失败:{x.Message}").Join("\r\n");
+ throw new UserFriendlyException(errorMessages);
+ }
+
+ foreach (var workGridSchedule in data)
+ {
+ workGridSchedule.SyncResult = response.Items.FirstOrDefault(x => x.UserCode == workGridSchedule.UserCode)?.Message;
+ }
+
+ await _dbContext.UpdateAsync(data);
+ }
+
+
+ await _dbContext.DeleteAsync(data);
+ await _operateLog.LogAsync(OperateLogType.WorkGrid, $"移除网格({workGrid.Name}){request.Date.ToString("yyyy-M-d")}的{request.PeriodType.GetDescription()}人员:{request.UserCodes.Join(",")}");
+
+ //todo sub pub
+ //推送移除通知
+ try
+ {
+ var userCodes = data.Select(x => x.UserCode).Distinct().ToList();
+ var gainfos = await _dbContext.Queryable().Where(x => userCodes.Contains(x.Code)).Select(x => new { x.Code, x.Name }).ToListAsync();
+ foreach (var gainfo in gainfos)
+ {
+ try
+ {
+ await _jinkoApiService.SendWorkMessageAsync(new DingTalkWorkMessageRequest
+ {
+ Content = $"{gainfo.Name}({gainfo.Code})你好,系统检测到你被{workGrid.Name}网格的网格长{workGrid.LeaderUserName}({workGrid.LeaderUserCode})删除了{request.Date.ToString("yyyy年MM月dd日")}{request.PeriodType.GetDescription()},如有疑问,请联系网格长!",
+ WorkCodes = new List { gainfo.Code }
+ });
+ }
+ catch (Exception e)
+ {
+ _logger.LogError("推送信息错误{code}:{error}", gainfo.Code, e.Message);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.LogError("推送信息错误remove,{error}", e.Message);
+ }
}
}
@@ -204,65 +350,6 @@ public class WorkGridScheduleService : IWorkGridScheduleService
return currentLimit;
}
-
- ///
- public async Task RemoveAsync(WorkGridScheduleSaveRequest request)
- {
- var workGrid = await _dbContext.Queryable()
- .LeftJoin((x, ga) => x.LeaderUserCode == ga.Code)
- .Where(x => x.Code == request.WorkGridCode)
- .Select((x, ga) => new
- {
- x.Code, x.Name,
- x.LeaderUserCode,
- LeaderUserName = ga.Name
- })
- .SingleAsync();
- workGrid.ThrowIfNull("工作网格不存在");
-
- var timeSetting = await _dbContext.Queryable().Where(x => x.Type == request.PeriodType).Select(x => new { x.Start, x.Before }).SingleAsync();
- var currentLimit = request.Date.ToDateTime(timeSetting.Start.Add(-TimeSpan.FromSeconds(timeSetting.Before)));
- (DateTime.Now >= currentLimit).ThrowIfTrue("当前时间不可修改排班信息");
-
- var data = await _dbContext.Queryable()
- .Where(x => x.WorkGridCode == request.WorkGridCode)
- .Where(x => x.Date == request.Date)
- .Where(x => x.PeriodType == request.PeriodType)
- .Where(x => request.UserCodes.Contains(x.UserCode))
- .ToListAsync();
-
- if (data.Any())
- {
- await _dbContext.DeleteAsync(data);
- await _operateLog.LogAsync(OperateLogType.WorkGrid, $"移除网格({workGrid.Name}){request.Date.ToString("yyyy-M-d")}的{request.PeriodType.GetDescription()}人员:{request.UserCodes.Join(",")}");
-
- try
- {
- var userCodes = data.Select(x => x.UserCode).Distinct().ToList();
- var gainfos = await _dbContext.Queryable().Where(x => userCodes.Contains(x.Code)).Select(x => new { x.Code, x.Name }).ToListAsync();
- foreach (var gainfo in gainfos)
- {
- try
- {
- await _jinkoApiService.SendWorkMessageAsync(new DingTalkWorkMessageRequest
- {
- Content = $"{gainfo.Name}({gainfo.Code})你好,系统检测到你被{workGrid.Name}网格的网格长{workGrid.LeaderUserName}({workGrid.LeaderUserCode})删除了{request.Date.ToString("yyyy年MM月dd日")}{request.PeriodType.GetDescription()},如有疑问,请联系网格长!",
- WorkCodes = new List { gainfo.Code }
- });
- }
- catch (Exception e)
- {
- _logger.LogError("推送信息错误{code}:{error}", gainfo.Code, e.Message);
- }
- }
- }
- catch (Exception e)
- {
- _logger.LogError("推送信息错误remove,{error}", e.Message);
- }
- }
- }
-
public async Task> GetListAsync(Guid workGridCode, DateOnly date, WorkGridTimePeriodEnumType? periodType)
{
var data = await _dbContext.Queryable()
@@ -294,7 +381,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
);
}
- ///
+
public async Task> GetAttendancePageAsync(WorkGridScheduleAttendancePageRequest request)
{
var jinkoCode = _currentUser.GetUserClaim(UserClaimConstants.JinkoCode);
@@ -417,8 +504,6 @@ public class WorkGridScheduleService : IWorkGridScheduleService
return page;
}
-
- ///
public async Task ManuallyUploadAsync(List logIds)
{
var sub = _currentUser.GetIntSubjectId();
diff --git a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs
index 63e3b289..a18aacd0 100644
--- a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs
@@ -258,26 +258,27 @@ public class WorkGridService : IWorkGridService
var specific = (role is "admin" or "tenant-admin" or "WGZGLY") && request.WorkGridCode.HasValue;
var currentUserCode = _currentUser.GetUserClaim(UserClaimConstants.JinkoCode);
- var myWorkGrid = await _dbContext.Queryable()
+ var workGrid = await _dbContext.Queryable()
.WhereIF(specific, x => x.Code == request.WorkGridCode)
.WhereIF(specific == false, x => x.LeaderUserCode == currentUserCode)
.SingleAsync();
var workGridUsers = await _dbContext.Queryable()
- .Where(x => x.WorkGridCode == myWorkGrid.Code)
+ .Where(x => x.WorkGridCode == workGrid.Code)
.Where(x => request.UserCodes.Contains(x.UserCode))
.ToListAsync();
+ //获取今天之后的排班信息
var date = DateOnly.FromDateTime(DateTime.Today);
var workGridSchedules = await _dbContext.Queryable()
.Where(x => x.Date > date)
- .Where(x => x.WorkGridCode == myWorkGrid.Code)
+ .Where(x => x.WorkGridCode == workGrid.Code)
.Where(x => request.UserCodes.Contains(x.UserCode))
.ToListAsync();
await _dbContext.DeleteAsync(workGridUsers);
await _dbContext.DeleteAsync(workGridSchedules);
- await _operateLog.LogAsync(OperateLogType.WorkGrid, $"从网格({myWorkGrid.Name})移除人员:{request.UserCodes.Join(",")}");
+ await _operateLog.LogAsync(OperateLogType.WorkGrid, $"从网格({workGrid.Name})移除人员:{request.UserCodes.Join(",")}");
}
}
\ No newline at end of file
diff --git a/Src/Dlhis.Entity/Basic/Entity/WorkGridScheduleEntity.cs b/Src/Dlhis.Entity/Basic/Entity/WorkGridScheduleEntity.cs
index 2b402712..74fc7b5e 100644
--- a/Src/Dlhis.Entity/Basic/Entity/WorkGridScheduleEntity.cs
+++ b/Src/Dlhis.Entity/Basic/Entity/WorkGridScheduleEntity.cs
@@ -10,7 +10,7 @@ namespace Dlhis.Entity.Basic.Entity;
///
///
[SugarTable(TableName = "WorkGridSchedules")]
-public class WorkGridScheduleEntity : SugarBaseEntity , ISoftDeleted
+public class WorkGridScheduleEntity : SugarBaseEntity, ISoftDeleted
{
///
/// 网格code
@@ -42,5 +42,11 @@ public class WorkGridScheduleEntity : SugarBaseEntity , ISoftDeleted
[SugarColumn(IsNullable = false, ColumnDescription = "是否取消", ColumnDataType = "bit")]
public bool IsCancel { get; set; }
+ ///
+ /// 同步结果
+ ///
+ [SugarColumn(IsNullable = true, ColumnDataType = "text", ColumnDescription = "同步结果")]
+ public string SyncResult { get; set; }
+
public bool IsDeleted { get; set; }
}
\ No newline at end of file
diff --git a/Src/Dlhis.Jip.Api/IJinkoJipApi.cs b/Src/Dlhis.Jip.Api/IJinkoJipApi.cs
index eeba7dbc..23214f21 100644
--- a/Src/Dlhis.Jip.Api/IJinkoJipApi.cs
+++ b/Src/Dlhis.Jip.Api/IJinkoJipApi.cs
@@ -81,4 +81,9 @@ public interface IJinkoJipApi
///
[Post("/JIP/HCM/HCM_I_PHOTO")]
Task SyncFaceToSapAsync(SyncFaceRequest request);
+
+
+ [RequestLog]
+ [Post("/JIP/HCM/HCM_I_SHIFTREP")]
+ Task SyncWorkShiftAsync(SyncWorkShiftRequest request);
}
\ No newline at end of file
diff --git a/Src/Dlhis.Jip.Api/Requests/SyncWorkShiftRequest.cs b/Src/Dlhis.Jip.Api/Requests/SyncWorkShiftRequest.cs
new file mode 100644
index 00000000..e7e0e41a
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Requests/SyncWorkShiftRequest.cs
@@ -0,0 +1,42 @@
+using Newtonsoft.Json;
+
+namespace Dlhis.Jip.Api.Requests;
+
+public class SyncWorkShiftRequest
+{
+ [JsonProperty("IT_2003")]
+ public List Items { get; set; }
+}
+
+public class SyncWorkShiftDayItem
+{
+ ///
+ /// 员工编码
+ ///
+ [JsonProperty("IV_GONGH")]
+ public string UserCode { get; set; }
+
+ ///
+ /// 开始日期 yyyyMMdd
+ ///
+ [JsonProperty("IV_BEGDA")]
+ public string Begin { get; set; }
+
+ ///
+ /// 结束日期 yyyyMMdd
+ ///
+ [JsonProperty("IV_ENDDA")]
+ public string End { get; set; }
+
+ ///
+ /// 排班计划 JK03白板 JK04夜班
+ ///
+ [JsonProperty("IV_TPROG")]
+ public string Plan { get; set; }
+
+ ///
+ /// 操作 INS / MOD /DEL
+ ///
+ [JsonProperty("IV_OP")]
+ public string Operate { get; set; }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Jip.Api/Responses/SyncWorkShiftResponse.cs b/Src/Dlhis.Jip.Api/Responses/SyncWorkShiftResponse.cs
new file mode 100644
index 00000000..8257196d
--- /dev/null
+++ b/Src/Dlhis.Jip.Api/Responses/SyncWorkShiftResponse.cs
@@ -0,0 +1,42 @@
+using Newtonsoft.Json;
+
+namespace Dlhis.Jip.Api.Responses;
+
+public class SyncWorkShiftResponse
+{
+ [JsonProperty("OT_2003")]
+ public List Items { get; set; }
+}
+
+public class SyncWorkShiftItem
+{
+ ///
+ /// 员工编码
+ ///
+ [JsonProperty("OV_GONGH")]
+ public string UserCode { get; set; }
+
+ ///
+ /// 开始日期 yyyyMMdd
+ ///
+ [JsonProperty("OV_BEGDA")]
+ public string Begin { get; set; }
+
+ ///
+ /// 结束日期 yyyyMMdd
+ ///
+ [JsonProperty("OV_ENDDA")]
+ public string End { get; set; }
+
+ ///
+ /// 排班计划 JK03白板 JK04夜班
+ ///
+ [JsonProperty("OV_TPROG")]
+ public string Plan { get; set; }
+
+ [JsonProperty("OV_MSGTY")]
+ public string Result { get; set; }
+
+ [JsonProperty("OV_MSGTXT")]
+ public string Message { get; set; }
+}
\ No newline at end of file