From 0ae46edcd3926cf57966cd7a701ac455af2cf5ab Mon Sep 17 00:00:00 2001 From: liguoyang Date: Thu, 6 Mar 2025 15:43:39 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E6=9C=80=E5=A4=A7=E8=BF=9E=E7=BB=AD?= =?UTF-8?q?=E6=8E=92=E7=8F=AD=E6=8E=A7=E5=88=B6=E5=A2=9E=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/WorkGridsController.cs | 10 ++- .../Request/WorkGridGainfoPageRequest.cs | 10 +++ .../Response/WorkGridGainfoPageResponse.cs | 62 +++++++++++++++++++ .../WorkGridScheduleMaximumConsecutiveDto.cs | 21 +++++++ .../Services/IWorkGridScheduleService.cs | 2 + .../WorkGrids/Services/IWorkGridService.cs | 7 +++ .../Implements/WorkGridScheduleService.cs | 38 ++++++++++++ .../Services/Implements/WorkGridService.cs | 41 ++++++++++++ 8 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 Src/Dlhis.Basic/WorkGrids/Request/WorkGridGainfoPageRequest.cs create mode 100644 Src/Dlhis.Basic/WorkGrids/Response/WorkGridGainfoPageResponse.cs create mode 100644 Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs diff --git a/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs b/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs index 71eae8e6..08c422f5 100644 --- a/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs +++ b/Src/Dlhis.Basic/WorkGrids/Controllers/WorkGridsController.cs @@ -31,6 +31,13 @@ public class WorkGridsController : ControllerBase _workGridScheduleService = workGridScheduleService; } + [HttpGet("gainfo-selections")] + public async Task> GetPageAsync([FromQuery] WorkGridGainfoPageRequest request) + { + return await _workGridService.GetPageAsync(request); + } + + /// /// 保存 /// @@ -53,7 +60,7 @@ public class WorkGridsController : ControllerBase { return await _workGridService.GetPageAsync(request); } - + /// /// 修改网格管理者 /// @@ -125,6 +132,7 @@ public class WorkGridsController : ControllerBase /// /// [HttpPost("user/schedule/save")] + [Transactional] public async Task SaveScheduleAsync(WorkGridScheduleSaveRequest request) { await _workGridScheduleService.SaveAsync(request); diff --git a/Src/Dlhis.Basic/WorkGrids/Request/WorkGridGainfoPageRequest.cs b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridGainfoPageRequest.cs new file mode 100644 index 00000000..a1acfdd3 --- /dev/null +++ b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridGainfoPageRequest.cs @@ -0,0 +1,10 @@ +using Kurisu.AspNetCore.DataAccess.Dto; +namespace Dlhis.Basic.WorkGrids.Request; + +public class WorkGridGainfoPageRequest : PageDto +{ + /// + /// 查询日期内的连续排数 + /// + public DateTime Date { get; set; } = DateTime.Today; +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/WorkGrids/Response/WorkGridGainfoPageResponse.cs b/Src/Dlhis.Basic/WorkGrids/Response/WorkGridGainfoPageResponse.cs new file mode 100644 index 00000000..caa22963 --- /dev/null +++ b/Src/Dlhis.Basic/WorkGrids/Response/WorkGridGainfoPageResponse.cs @@ -0,0 +1,62 @@ +using Dlhis.Entity.Basic.Enums; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Basic.WorkGrids.Response; + +public class WorkGridGainfoPageResponse +{ + public long Id { get; set; } + + public string No { get; set; } + + /// + /// 人员类型 + /// + public GainfoUserTypeEnumType? Type { get; set; } + + /// + /// 姓名 + /// + public string Name { get; set; } + + /// + /// 工号 + /// + public string Code { get; set; } + + /// + /// 性别 + /// + public GenderEnumType Gender { get; set; } + + public string GenderDesc => Gender.GetDescription(); + + /// + /// 部门编码 + /// + public string DepartmentNo { get; set; } + + /// + /// 部门名称 + /// + public string DepartmentName { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } + + /// + /// 有工作网格 + /// + public bool HasWorkGrid => WorkGridName.IsPresent(); + /// + /// 网格名称 + /// + public string WorkGridName { get; set; } + + /// + /// 最大连续排班信息 + /// + public WorkGridScheduleMaximumConsecutiveDto MaximumConsecutiveSchedules { get; set; } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs b/Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs new file mode 100644 index 00000000..4301c336 --- /dev/null +++ b/Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs @@ -0,0 +1,21 @@ +namespace Dlhis.Basic.WorkGrids.Response; + +public class WorkGridScheduleMaximumConsecutiveDto +{ + public string UserCode { get; set; } + + /// + /// 连续次数 + /// + public int Count { get; set; } + + /// + /// 开始日期 + /// + public DateOnly Start { get; set; } + + /// + /// 结束日期 + /// + public DateOnly End { get; set; } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs b/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs index 5dfd2345..e1f89a95 100644 --- a/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs +++ b/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs @@ -21,4 +21,6 @@ public interface IWorkGridScheduleService : IScopeDependency Task> GetAttendancePageAsync(WorkGridScheduleAttendancePageRequest request); Task ManuallyUploadAsync(List logIds); + + Task> MaximumConsecutiveUserCodesAsync(List userCodes, int days, DateOnly date); } \ No newline at end of file diff --git a/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridService.cs b/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridService.cs index 0270987f..9916a093 100644 --- a/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridService.cs +++ b/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridService.cs @@ -9,6 +9,13 @@ namespace Dlhis.Basic.WorkGrids.Services; /// public interface IWorkGridService : IScopeDependency { + /// + /// 人员选择接口 + /// + /// + /// + Task> GetPageAsync(WorkGridGainfoPageRequest request); + /// /// 保存 /// diff --git a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs index 60f700a5..cca1ce30 100644 --- a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs +++ b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridScheduleService.cs @@ -62,6 +62,9 @@ public class WorkGridScheduleService : IWorkGridScheduleService await _dbContext.InsertAsync(toInserts); + var maximumConsecutiveDtos = await MaximumConsecutiveUserCodesAsync(request.UserCodes, 11, request.Date); + maximumConsecutiveDtos.ThrowIfExists(maximumConsecutiveDtos.Select(x => $"{x.UserCode}已经连续排班10天({x.Start}-{x.End}),不可继续排班").Join("\r\n")); + await _operateLog.LogAsync(OperateLogType.WorkGrid, $"新增网格({workGrid.Name}){request.Date.ToString("yyyy-M-d")}的{request.PeriodType.GetDescription()}人员:{request.UserCodes.Join(",")}"); } @@ -206,4 +209,39 @@ public class WorkGridScheduleService : IWorkGridScheduleService await _operateLog.LogAsync(OperateLogType.WorkGrid, $"重提上传考勤:{requests.Select(x => x.Id).Join(",")}"); } + + public async Task> MaximumConsecutiveUserCodesAsync(List userCodes, int days, DateOnly date) + { + var p = userCodes.Select(x => $"@param{x}").Join(","); + var values = userCodes.ToDictionary(x => $"param{x}", x => x); + + values.Add("date", date.ToString("yyyy-MM-dd")); + values.Add("days", days.ToString()); + + var sql = $@" +WITH ranked_dates AS (SELECT UserCode, + date, + ROW_NUMBER() OVER (PARTITION BY UserCode ORDER BY date) AS rn + FROM WorkGridSchedules where UserCode in ({p}) + GROUP BY UserCode, date), + grouped AS (SELECT UserCode, + date, + DATE_SUB(date, INTERVAL rn DAY) AS grp + FROM ranked_dates), + streaks AS (SELECT UserCode, + grp, + COUNT(*) AS streak_days, + MIN(date) AS start_date, + MAX(date) AS end_date + FROM grouped + GROUP BY UserCode, grp + HAVING streak_days >= @days) +SELECT UserCode, streak_days as Count, start_date as Start, end_date as End +FROM streaks where @date>= start_date and @date<= end_date; + +"; + + var data = await _dbContext.Client.Ado.SqlQueryAsync(sql, values); + return data; + } } \ No newline at end of file diff --git a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs index cebce3af..0e147314 100644 --- a/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs +++ b/Src/Dlhis.Basic/WorkGrids/Services/Implements/WorkGridService.cs @@ -3,6 +3,7 @@ using Dlhis.Basic.WorkGrids.Request; using Dlhis.Basic.WorkGrids.Response; using Dlhis.Constants; using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Basic.Enums; using Dlhis.Entity.Common.Enums; using Kurisu.AspNetCore.Authentication.Abstractions; using Kurisu.AspNetCore.DataAccess.Dto; @@ -18,17 +19,57 @@ public class WorkGridService : IWorkGridService { private readonly IDbContext _dbContext; private readonly ICurrentUser _currentUser; + private readonly IWorkGridScheduleService _workGridScheduleService; private readonly IOperateLog _operateLog; public WorkGridService(IDbContext dbContext, ICurrentUser currentUser, + IWorkGridScheduleService workGridScheduleService, IOperateLog operateLog) { _dbContext = dbContext; _currentUser = currentUser; + _workGridScheduleService = workGridScheduleService; _operateLog = operateLog; } + /// + public async Task> GetPageAsync(WorkGridGainfoPageRequest request) + { + var factory = _currentUser.GetStringTenantId(); + + var r = await _dbContext.Queryable() + .LeftJoin((x, dept) => x.DepartmentNo == dept.No) + .LeftJoin((x, dept, wgu) => x.Code == wgu.UserCode) + .LeftJoin((x, dept, wgu, wg) => wgu.WorkGridCode == wg.Code) + .Where(x => x.Factory == factory && (x.Type == GainfoUserTypeEnumType.Normal || x.Type == GainfoUserTypeEnumType.SecurityWhite)) + .WhereIF(request.Search.IsPresent(), x => x.Code == request.Search || x.Name.Contains(request.Search)) + .Select((x, dept, wgu, wg) => new WorkGridGainfoPageResponse + { + Id = x.Id, + No = x.No, + Type = x.Type, + Name = x.Name, + Code = x.Code, + Gender = x.Gender, + DepartmentNo = x.DepartmentNo, + DepartmentName = dept.Name, + Remark = x.Remark, + WorkGridName = wg.Name, + }) + .ToPageListAsync(request); + + var userCodes = r.Data.Select(x => x.Code).ToList(); + var maximumConsecutiveUserCodes = await _workGridScheduleService.MaximumConsecutiveUserCodesAsync(userCodes, 1, DateOnly.FromDateTime(request.Date)); + + foreach (var item in r.Data) + { + item.MaximumConsecutiveSchedules = maximumConsecutiveUserCodes.FirstOrDefault(x => x.UserCode == item.Code); + } + + return r; + } + /// public async Task SaveAsync(List requests) {