refactor 优化命名和结构,注释

This commit is contained in:
2025-06-30 14:20:26 +08:00
parent 6fd0a2b1ef
commit 221d985850
24 changed files with 368 additions and 205 deletions

View File

@@ -10,21 +10,60 @@ namespace Dlhis.Basic.WorkGrids.Services;
/// </summary>
public interface IWorkGridScheduleService : IScopeDependency
{
/// <summary>
/// 保存网格排班信息
/// </summary>
/// <param name="request">排班保存请求参数</param>
Task SaveAsync(WorkGridScheduleSaveRequest request);
/// <summary>
/// 移除网格排班信息
/// </summary>
/// <param name="request">排班移除请求参数</param>
Task RemoveAsync(WorkGridScheduleSaveRequest request);
/// <summary>
/// 获取指定网格、日期和时段的排班列表
/// </summary>
/// <param name="workGridCode">网格编码</param>
/// <param name="date">日期</param>
/// <param name="periodType">时段类型</param>
/// <returns>排班列表</returns>
Task<List<WorkGridScheduleResponse>> GetListAsync(Guid workGridCode, DateOnly date, WorkGridTimePeriodEnumType? periodType);
/// <summary>
/// 获取指定网格和日期范围的排班汇总列表
/// </summary>
/// <param name="workGridCode">网格编码</param>
/// <param name="start">开始日期</param>
/// <param name="end">结束日期</param>
/// <returns>排班汇总列表</returns>
Task<IEnumerable<WorkGridScheduleSummaryResponse>> GetListSummaryAsync(Guid workGridCode, DateOnly start, DateOnly end);
/// <summary>
/// 获取排班考勤分页数据
/// </summary>
/// <param name="request">考勤分页请求参数</param>
/// <returns>排班考勤分页数据</returns>
Task<Pagination<WorkGridScheduleAttendancePageResponse>> GetAttendancePageAsync(WorkGridScheduleAttendancePageRequest request);
/// <summary>
/// 获取所有排班考勤分页数据
/// </summary>
/// <param name="request">考勤分页请求参数</param>
/// <returns>排班考勤分页数据</returns>
Task<Pagination<WorkGridScheduleAttendancePageResponse>> GetAllAttendancePageAsync(WorkGridScheduleAttendancePageRequest request);
/// <summary>
/// 手动上传考勤日志
/// </summary>
/// <param name="logIds">考勤日志ID列表</param>
Task ManuallyUploadAsync(List<long> logIds);
Task<List<WorkGridScheduleMaximumConsecutiveDto>> MaximumConsecutiveUserCodesAsync(List<string> userCodes, int days, DateOnly date);
/// <summary>
/// 测试接口
/// </summary>
/// <param name="request">排班保存请求参数</param>
/// <returns>测试结果</returns>
Task<object> TestAsync(WorkGridScheduleSaveRequest request);
}

View File

@@ -1,5 +1,7 @@
using Dlhis.Basic.Common.ApiLog.Services;
using Dlhis.Basic.Common.Message;
using Dlhis.Basic.Common.Message.Requests;
using Dlhis.Basic.Common.Message.Services;
using Dlhis.Basic.WorkGrids.Repositories;
using Dlhis.Basic.WorkGrids.Request;
using Dlhis.Basic.WorkGrids.Response;
using Dlhis.Constants;
@@ -27,6 +29,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
private readonly IOperateLog _operateLog;
private readonly ILogger<WorkGridScheduleService> _logger;
private readonly IJinkoApiService _jinkoApiService;
private readonly IWorkGridScheduleRepository _workGridScheduleRepository;
private readonly ICurrentUser _currentUser;
public WorkGridScheduleService(IDbContext dbContext,
@@ -34,6 +37,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
IOperateLog operateLog,
ILogger<WorkGridScheduleService> logger,
IJinkoApiService jinkoApiService,
IWorkGridScheduleRepository workGridScheduleRepository,
ICurrentUser currentUser)
{
_dbContext = dbContext;
@@ -41,6 +45,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
_operateLog = operateLog;
_logger = logger;
_jinkoApiService = jinkoApiService;
_workGridScheduleRepository = workGridScheduleRepository;
_currentUser = currentUser;
}
@@ -61,7 +66,11 @@ public class WorkGridScheduleService : IWorkGridScheduleService
.SingleAsync();
workGrid.ThrowIfNull("工作网格不存在");
var timeSetting = await _dbContext.Queryable<WorkGridTimePeriodEntity>().Where(x => x.Type == request.PeriodType).Select(x => new { x.Start, x.Before }).SingleAsync();
var timeSetting = await _dbContext.Queryable<WorkGridTimePeriodEntity>()
.Where(x => x.Type == request.PeriodType)
.Select(x => new { x.Start, x.Before })
.SingleAsync();
timeSetting.ThrowIfNull("工作网格时间尚未配置,无法操作");
var currentLimit = request.Date.ToDateTime(timeSetting.Start.Add(-TimeSpan.FromHours(1)));
@@ -103,8 +112,8 @@ public class WorkGridScheduleService : IWorkGridScheduleService
existsUserCodes.ThrowIfExists(existsUserCodes.Join(",") + $"在{dateAfter.ToString("yyyy-MM-dd")}已存在{WorkGridTimePeriodEnumType.Day.GetDescription()}");
}
var maximumConsecutiveDtos = await MaximumConsecutiveUserCodesAsync(request.UserCodes, workGrid.MaxConsecutiveLimitCount, request.Date);
maximumConsecutiveDtos.ThrowIfExists(maximumConsecutiveDtos.Select(x => $"{x.UserCode}已经连续排班{workGrid.MaxConsecutiveLimitCount}天({x.Start}-{x.End}),禁止排班").Join("\r\n"));
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
{
@@ -120,12 +129,15 @@ public class WorkGridScheduleService : IWorkGridScheduleService
try
{
var gainfos = await _dbContext.Queryable<GainfoEntity>().Where(x => request.UserCodes.Contains(x.Code)).Select(x => new { x.Code, x.Name }).ToListAsync();
foreach (var gainfo in gainfos)
var codeAndNameList = await _dbContext.Queryable<GainfoEntity>().Where(x => request.UserCodes.Contains(x.Code))
.Select(x => new { x.Code, x.Name })
.ToListAsync();
foreach (var gainfo in codeAndNameList)
{
try
{
await _jinkoApiService.SendWorkMessageAsync(new JinkoSendWorkMessageRequest
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<string> { gainfo.Code }
@@ -210,7 +222,7 @@ public class WorkGridScheduleService : IWorkGridScheduleService
{
try
{
await _jinkoApiService.SendWorkMessageAsync(new JinkoSendWorkMessageRequest
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<string> { gainfo.Code }
@@ -432,44 +444,4 @@ public class WorkGridScheduleService : IWorkGridScheduleService
}
}
}
public async Task<List<WorkGridScheduleMaximumConsecutiveDto>> MaximumConsecutiveUserCodesAsync(List<string> userCodes, int days, DateOnly date)
{
var p = userCodes.Select(x => $"@param{x.Replace("-", "A_")}").Join(",");
var values = userCodes.ToDictionary(x => $"param{x.Replace("-", "A_")}", x => x);
values.Add("dateBefore", date.AddDays(-1).ToString("yyyy-MM-dd"));
values.Add("dateAfter", date.AddDays(1).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 IsDeleted = 0 and 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 (@dateBefore >= start_date
and @dateBefore <= end_date)
or (@dateAfter >= start_date
and @dateAfter <= end_date);
";
var data = await _dbContext.Client.Ado.SqlQueryAsync<WorkGridScheduleMaximumConsecutiveDto>(sql, values);
return data;
}
}

View File

@@ -1,6 +1,8 @@
using Dlhis.Basic.Common.ApiLog.Services;
using Dlhis.Basic.WorkGrids.Repositories;
using Dlhis.Basic.WorkGrids.Request;
using Dlhis.Basic.WorkGrids.Response;
using Dlhis.Basic.WorkGrids.Validations;
using Dlhis.Constants;
using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Basic.Enums;
@@ -19,17 +21,20 @@ public class WorkGridService : IWorkGridService
{
private readonly IDbContext _dbContext;
private readonly ICurrentUser _currentUser;
private readonly IWorkGridScheduleService _workGridScheduleService;
private readonly IWorkGridValidateService _workGridValidateService;
private readonly IWorkGridScheduleRepository _workGridScheduleRepository;
private readonly IOperateLog _operateLog;
public WorkGridService(IDbContext dbContext,
ICurrentUser currentUser,
IWorkGridScheduleService workGridScheduleService,
IWorkGridValidateService workGridValidateService,
IWorkGridScheduleRepository workGridScheduleRepository,
IOperateLog operateLog)
{
_dbContext = dbContext;
_currentUser = currentUser;
_workGridScheduleService = workGridScheduleService;
_workGridValidateService = workGridValidateService;
_workGridScheduleRepository = workGridScheduleRepository;
_operateLog = operateLog;
}
@@ -38,7 +43,7 @@ public class WorkGridService : IWorkGridService
{
var factory = _currentUser.GetStringTenantId();
var r = await _dbContext.Queryable<GainfoEntity>()
var pagination = await _dbContext.Queryable<GainfoEntity>()
.LeftJoin<DepartmentEntity>((x, dept) => x.DepartmentNo == dept.No)
.LeftJoin<WorkGridUserEntity>((x, dept, wgu) => x.Code == wgu.UserCode)
.LeftJoin<WorkGridEntity>((x, dept, wgu, wg) => wgu.WorkGridCode == wg.Code)
@@ -59,50 +64,29 @@ public class WorkGridService : IWorkGridService
})
.ToPageListAsync(request);
var userCodes = r.Data.Select(x => x.Code).ToList();
if (userCodes.Any())
var userCodeList = pagination.Data.Select(x => x.Code).ToList();
if (userCodeList.Any())
{
var maximumConsecutiveUserCodes = await _workGridScheduleService.MaximumConsecutiveUserCodesAsync(userCodes, 1, DateOnly.FromDateTime(request.Date));
var maximumConsecutiveUserCodeList = await _workGridScheduleRepository.MaximumConsecutiveUserCodesAsync(userCodeList, 1, DateOnly.FromDateTime(request.Date));
foreach (var item in r.Data)
foreach (var item in pagination.Data)
{
item.MaximumConsecutiveSchedules = maximumConsecutiveUserCodes.FirstOrDefault(x => x.UserCode == item.Code);
item.MaximumConsecutiveSchedules = maximumConsecutiveUserCodeList.FirstOrDefault(x => x.UserCode == item.Code);
}
}
return r;
return pagination;
}
/// <inheritdoc />
public async Task SaveAsync(List<WorkGridSaveRequest> requests)
{
var factory = _currentUser.GetStringTenantId();
await _workGridValidateService.ValidateSaveAsync(requests);
var insertGrids = new List<string>();
var updateGrids = new List<string>();
var leaderUserCodes = requests.Select(x => x.LeaderUserCode).Distinct().ToList();
var existsUserInfos = await _dbContext.Queryable<GainfoEntity>()
.Where(x => leaderUserCodes.Contains(x.Code))
.Select(x => new { x.Code, x.Factory })
.ToListAsync();
var excludeCodes = existsUserInfos.Where(x => x.Factory != factory).Select(x => x.Code).ToList();
excludeCodes.ThrowIfExists($"工号:{excludeCodes.Join(",")}不属于当前厂区");
var existsUserCodes = existsUserInfos.Select(x => x.Code).ToList();
var notExistsUserCodes = leaderUserCodes.Except(existsUserCodes).ToList();
notExistsUserCodes.ThrowIfExists($"工号:{notExistsUserCodes.Join(",")}不存在");
foreach (var request in requests)
{
if (await _dbContext.Queryable<WorkGridEntity>().Where(x => x.Name == request.Name)
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
.AnyAsync())
{
true.ThrowIfTrue($"网格区域名称[{request.Name}]重复");
}
if (!request.Id.HasValue)
{
var exists = await _dbContext.Queryable<WorkGridEntity>()
@@ -145,7 +129,6 @@ public class WorkGridService : IWorkGridService
await _operateLog.LogAsync(OperateLogType.WorkGrid, "修改网格:" + updateGrids.Join("\r\n"));
}
/// <inheritdoc />
public async Task<Pagination<WorkGridPageResponse>> GetPageAsync(WorkGridPageRequest request)
{
var role = _currentUser.GetRole();
@@ -190,7 +173,6 @@ public class WorkGridService : IWorkGridService
.ToPageListAsync(request);
}
/// <inheritdoc />
public async Task ChangeAsync(string from, string to)
{
if (await _dbContext.Queryable<WorkGridEntity>().Where(x => x.LeaderUserCode == to).AnyAsync())
@@ -216,7 +198,6 @@ public class WorkGridService : IWorkGridService
await _operateLog.LogAsync(OperateLogType.WorkGrid, $"网格({workGrid.Name})修改负责人{from}->{to}");
}
/// <inheritdoc />
public async Task<WorkGridUserPageResponse> GetMyWorkGridAsync(WorkGridPageRequest request)
{
var currentUserCode = _currentUser.GetUserClaim(UserClaimConstants.JinkoCode);
@@ -253,11 +234,11 @@ public class WorkGridService : IWorkGridService
var userCodes = myWorkGrid.UserInfos.Select(x => x.Code).ToList();
if (userCodes.Any())
{
var maximumConsecutiveUserCodes = await _workGridScheduleService.MaximumConsecutiveUserCodesAsync(userCodes, 1, DateOnly.FromDateTime(request.Date));
var maximumConsecutiveUserCodeList = await _workGridScheduleRepository.MaximumConsecutiveUserCodesAsync(userCodes, 1, DateOnly.FromDateTime(request.Date));
foreach (var item in myWorkGrid.UserInfos)
{
item.MaximumConsecutiveSchedules = maximumConsecutiveUserCodes.FirstOrDefault(x => x.UserCode == item.Code);
item.MaximumConsecutiveSchedules = maximumConsecutiveUserCodeList.FirstOrDefault(x => x.UserCode == item.Code);
}
}
}
@@ -265,7 +246,6 @@ public class WorkGridService : IWorkGridService
return myWorkGrid;
}
/// <inheritdoc />
public async Task AssignAsync(WorkGridUserAssignRequest request)
{
var currentFactory = _currentUser.GetStringTenantId();