diff --git a/Src/Dlhis.Basic/Common/Holiday/Controller/HolidaysController.cs b/Src/Dlhis.Basic/Common/Holiday/Controller/HolidaysController.cs
index 75cd31b0..eb6f589b 100644
--- a/Src/Dlhis.Basic/Common/Holiday/Controller/HolidaysController.cs
+++ b/Src/Dlhis.Basic/Common/Holiday/Controller/HolidaysController.cs
@@ -52,18 +52,6 @@ public class HolidaysController : ControllerBase
[HttpGet("remote-ip")]
public string GetRemoteIp()
{
- // 检查是否在Kubernetes环境中
- var isKubernetes = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("KUBERNETES_SERVICE_HOST"));
-
- if (isKubernetes)
- {
- var forwardedFor = HttpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
- if (!string.IsNullOrEmpty(forwardedFor))
- {
- return forwardedFor.Split(',').First().Trim();
- }
- }
-
return HttpContext.Connection.RemoteIpAddress?.ToString();
}
}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Common/Message/MessagesController.cs b/Src/Dlhis.Basic/Common/Message/Controller/MessagesController.cs
similarity index 61%
rename from Src/Dlhis.Basic/Common/Message/MessagesController.cs
rename to Src/Dlhis.Basic/Common/Message/Controller/MessagesController.cs
index ffb95678..dd3ce314 100644
--- a/Src/Dlhis.Basic/Common/Message/MessagesController.cs
+++ b/Src/Dlhis.Basic/Common/Message/Controller/MessagesController.cs
@@ -1,6 +1,8 @@
-using Microsoft.AspNetCore.Mvc;
+using Dlhis.Basic.Common.Message.Requests;
+using Dlhis.Basic.Common.Message.Services;
+using Microsoft.AspNetCore.Mvc;
-namespace Dlhis.Basic.Common.Message;
+namespace Dlhis.Basic.Common.Message.Controller;
[Route("api/[controller]")]
@@ -16,7 +18,7 @@ public class MessagesController : ControllerBase
[HttpPost("dingtalk/workmessage")]
- public async Task SendWorkMessageAsync(JinkoSendWorkMessageRequest request)
+ public async Task SendWorkMessageAsync(DingTalkWorkMessageRequest request)
{
await _jinkoApiService.SendWorkMessageAsync(request);
}
diff --git a/Src/Dlhis.Basic/Common/Message/IJinkoApiService.cs b/Src/Dlhis.Basic/Common/Message/IJinkoApiService.cs
deleted file mode 100644
index 7b1f9485..00000000
--- a/Src/Dlhis.Basic/Common/Message/IJinkoApiService.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Dlhis.Basic.Common.Message;
-
-public interface IJinkoApiService : ISingletonDependency
-{
- Task SendWorkMessageAsync(JinkoSendWorkMessageRequest request);
-}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Common/Message/JinkoSendWorkMessageRequest.cs b/Src/Dlhis.Basic/Common/Message/JinkoSendWorkMessageRequest.cs
deleted file mode 100644
index 5353e28a..00000000
--- a/Src/Dlhis.Basic/Common/Message/JinkoSendWorkMessageRequest.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Dlhis.Basic.Common.Message;
-
-public class JinkoSendWorkMessageRequest
-{
- ///
- /// 发送内容
- ///
- public string Content { get; set; }
-
- ///
- /// 工号
- ///
- public List WorkCodes { get; set; }
-}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Common/Message/Requests/DingTalkWorkMessageRequest.cs b/Src/Dlhis.Basic/Common/Message/Requests/DingTalkWorkMessageRequest.cs
new file mode 100644
index 00000000..ce96b358
--- /dev/null
+++ b/Src/Dlhis.Basic/Common/Message/Requests/DingTalkWorkMessageRequest.cs
@@ -0,0 +1,18 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Dlhis.Basic.Common.Message.Requests;
+
+public class DingTalkWorkMessageRequest
+{
+ ///
+ /// 工号
+ ///
+ [MinLength(1, ErrorMessage = "{0}不能为空")]
+ public List WorkCodes { get; set; }
+
+ ///
+ /// 发送内容
+ ///
+ [Required(ErrorMessage = "{0}不能为空")]
+ public string Content { get; set; }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Common/Message/JinkoOaResponse.cs b/Src/Dlhis.Basic/Common/Message/Responses/JinkoOaResponse.cs
similarity index 89%
rename from Src/Dlhis.Basic/Common/Message/JinkoOaResponse.cs
rename to Src/Dlhis.Basic/Common/Message/Responses/JinkoOaResponse.cs
index 301c100f..8f4fb9ed 100644
--- a/Src/Dlhis.Basic/Common/Message/JinkoOaResponse.cs
+++ b/Src/Dlhis.Basic/Common/Message/Responses/JinkoOaResponse.cs
@@ -1,4 +1,4 @@
-namespace Dlhis.Basic.Common.Message
+namespace Dlhis.Basic.Common.Message.Responses
{
public class JinkoOaResponse
{
@@ -12,11 +12,10 @@ namespace Dlhis.Basic.Common.Message
public T Data { get; set; }
}
-
public class JinkoOaInfo
{
public int Id { get; set; }
public string Email { get; set; }
public string Lastname { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Common/Message/Services/IJinkoApiService.cs b/Src/Dlhis.Basic/Common/Message/Services/IJinkoApiService.cs
new file mode 100644
index 00000000..2efc0314
--- /dev/null
+++ b/Src/Dlhis.Basic/Common/Message/Services/IJinkoApiService.cs
@@ -0,0 +1,8 @@
+using Dlhis.Basic.Common.Message.Requests;
+
+namespace Dlhis.Basic.Common.Message.Services;
+
+public interface IJinkoApiService : ISingletonDependency
+{
+ Task SendWorkMessageAsync(DingTalkWorkMessageRequest request);
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Common/Message/JinkoApiService.cs b/Src/Dlhis.Basic/Common/Message/Services/Implements/JinkoApiService.cs
similarity index 69%
rename from Src/Dlhis.Basic/Common/Message/JinkoApiService.cs
rename to Src/Dlhis.Basic/Common/Message/Services/Implements/JinkoApiService.cs
index 07390ff7..d8bec022 100644
--- a/Src/Dlhis.Basic/Common/Message/JinkoApiService.cs
+++ b/Src/Dlhis.Basic/Common/Message/Services/Implements/JinkoApiService.cs
@@ -1,11 +1,13 @@
using System.Text;
using Dlhis.Basic.Common.ApiLog.Services;
+using Dlhis.Basic.Common.Message.Requests;
+using Dlhis.Basic.Common.Message.Responses;
using Dlhis.Entity.Common.Enums;
using Kurisu.AspNetCore.Utils.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
-namespace Dlhis.Basic.Common.Message;
+namespace Dlhis.Basic.Common.Message.Services.Implements;
public class JinkoApiService : IJinkoApiService
{
@@ -24,49 +26,51 @@ public class JinkoApiService : IJinkoApiService
private async Task GetTokenAsync()
{
var token = string.Empty;
- if (string.IsNullOrEmpty(token))
+ if (!token.IsEmpty())
{
- var httpClient = _httpClientFactory.CreateClient("jinko.httpclient");
-
- var form = new FormUrlEncodedContent(new Dictionary
- {
- { "appkey", _appKey },
- { "appsecret", _appSecret }
- });
-
- //appkey=dingumelppews6rah7x9&appsecret=nsWfJTVjYesHVzrLiP-t1TQqMQvC1L_kZNfXfnIyzcXK4pCTfKprkjZcxAbsDR_l
- var response = await httpClient.GetStringAsync($"/gettoken?{await form.ReadAsStringAsync()}");
- var jObj = JObject.Parse(response);
- (jObj.Value("errcode") == "0").ThrowIfFalse(jObj.Value("errmsg"));
-
- token = jObj.Value("access_token");
+ return token;
}
+ var httpClient = _httpClientFactory.CreateClient("jinko.httpclient");
+
+ var form = new FormUrlEncodedContent(new Dictionary
+ {
+ { "appkey", _appKey },
+ { "appsecret", _appSecret }
+ });
+
+ //eg: appkey=dingumelppews6rah7x9&appsecret=nsWfJTVjYesHVzrLiP-t1TQqMQvC1L_kZNfXfnIyzcXK4pCTfKprkjZcxAbsDR_l
+ var response = await httpClient.GetStringAsync($"/gettoken?{await form.ReadAsStringAsync()}");
+ var jObj = JObject.Parse(response);
+ (jObj.Value("errcode") == "0").ThrowIfFalse(jObj.Value("errmsg"));
+
+ token = jObj.Value("access_token");
+
return token;
}
- public async Task SendWorkMessageAsync(JinkoSendWorkMessageRequest request)
+ public async Task SendWorkMessageAsync(DingTalkWorkMessageRequest request)
{
request.Content.IsEmpty().ThrowIfTrue("发送内容不能为空");
var token = await GetTokenAsync();
var users = await GetJinkoOaInfoByWorkCodes(request.WorkCodes);
- var userStringIds = string.Join(",", users.Select(x => x.Id));
- (userStringIds.Length > 100).ThrowIfTrue("超出消息接受人数,length > 100");
+ var userIds = users.Select(x => x.Id).Join(",");
+ (userIds.Length > 100).ThrowIfTrue("超出消息接受人数,length > 100");
var body = new
{
agent_id = _agentId,
- userid_list = userStringIds,
+ userid_list = userIds,
msg = new
{
msgtype = "text",
text = new
{
content = request.Content
- },
- },
+ }
+ }
}.ToJson();
var httpClient = _httpClientFactory.CreateClient("jinko.httpclient");
@@ -76,11 +80,8 @@ public class JinkoApiService : IJinkoApiService
var response = await httpClient.PostAsync(url, content);
var jsonResponse = await response.Content.ReadAsStringAsync();
- //_logger.LogInformation("请求参数:{Request} \r\n 钉钉请求参数:{DingTalkRequest} \r\n 钉钉响应:{DingTalkResponse}", JsonConvert.SerializeObject(request), body, jsonResponse);
-
- var jObj = JObject.Parse(jsonResponse);
- (jObj.Value("errcode") == "0").ThrowIfFalse(jObj.Value("errmsg"));
-
+ var jObject = JObject.Parse(jsonResponse);
+ (jObject.Value("errcode") == "0").ThrowIfFalse(jObject.Value("errmsg"));
using var scope = _serviceProvider.CreateScope();
var ol = scope.ServiceProvider.GetService();
diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionAnalyzeService.cs
index 827020d1..f6da70f8 100644
--- a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionAnalyzeService.cs
+++ b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionAnalyzeService.cs
@@ -196,7 +196,7 @@ public class DevicePermissionAnalyzeService : IDevicePermissionAnalyzeService
AssignTypeEnumType.Group => analyzePack.UserGainfoGroupCodes.Select(x => x.ToString()),
AssignTypeEnumType.Department => RecursionHelper.HandlerDepartmentPreviousCodes(analyzePack.UserDepartment, departments).Select(x => analyzePack.UserFactory + ":" + x).ToList(),
AssignTypeEnumType.Tenant => new List { analyzePack.UserFactory },
- AssignTypeEnumType.Role => throw new ArgumentOutOfRangeException(),
+ AssignTypeEnumType.Role => throw new NotSupportedException("不支持角色分配"),
_ => throw new ArgumentOutOfRangeException()
};
diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs
index d6fabd88..10050f1a 100644
--- a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs
+++ b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs
@@ -517,6 +517,7 @@ public class DevicePermissionService : IDevicePermissionService
{
var now = DateTime.Now;
+ // 获取与指定设备关联的分组编码
var groupCodes = await _dbContext.Queryable()
.Where(x => SqlFunc.Subqueryable()
.Where(p => p.GroupCode == x.Code)
@@ -525,25 +526,30 @@ public class DevicePermissionService : IDevicePermissionService
.Select(x => x.Code)
.ToListAsync();
+ // 获取与分组相关联的区域编码及类型
var areaCodes = await _dbContext.Queryable()
.LeftJoin((x, y) => x.CustomCode == y.CustomCode)
.Where(x => groupCodes.Contains(x.DeviceGroupCode))
.Select((x, y) => new { x.CustomCode, y.Type })
.ToListAsync();
+ // 根据区域类型筛选出门区和厂区的区域编码
var doorAreaCodes = areaCodes.Where(p => p.Type == AppointmentAreaEnumType.Door).Select(p => p.CustomCode).ToList();
var workplaceAreaCodes = areaCodes.Where(p => p.Type == AppointmentAreaEnumType.Workplace).Select(p => p.CustomCode).ToList();
+ // 查询当前时间段内已到访的访客预约明细
var details = await _dbContext.Queryable()
.Where(x => (x.IsEnterDoorArea && now >= x.DoorStart && now <= x.DoorEnd && x.DoorStatus == VisitorAppointmentDetailStatusEnumType.Arrived)
|| x.IsEnterWorkplace && now >= x.WorkplaceStart && now <= x.WorkplaceEnd && x.WorkplaceStatus == VisitorAppointmentDetailStatusEnumType.Arrived)
.ToListAsync();
+ //到访门区或厂区的访客编号列表
return details.Where(x =>
(x.IsEnterDoorArea && doorAreaCodes.Contains(x.ApplyDoorArea))
|| (x.IsEnterWorkplace && workplaceAreaCodes.Any(p => x.ApplyWorkplaceAreas.Contains(p)))
)
.Select(x => x.UserNo)
+ .Distinct()
.ToList();
}
}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs
index 69c9db9e..b19bb912 100644
--- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs
+++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs
@@ -1,4 +1,5 @@
-using Dlhis.Basic.Common.Message;
+using Dlhis.Basic.Common.Message.Requests;
+using Dlhis.Basic.Common.Message.Services;
using Dlhis.Basic.Organization.Comparers;
using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Basic.Enums;
@@ -186,7 +187,7 @@ public class GainfoUpdateService : IGainfoUpdateService
});
}
- private GainfoEntity GainfoSapToGainfo(GainfoSapEntity item)
+ private static GainfoEntity GainfoSapToGainfo(GainfoSapEntity item)
{
var info = new GainfoEntity
{
@@ -319,20 +320,24 @@ public class GainfoUpdateService : IGainfoUpdateService
{
var resignationDate = DateOnly.FromDateTime(gainfo.ModifiedTime);
- var workGridSchedules = await _dbContext.Queryable().Where(x => x.UserCode == gainfo.Code)
+ var workGridSchedules = await _dbContext.Queryable()
+ .Where(x => x.UserCode == gainfo.Code)
.Where(x => x.Date >= resignationDate)
.ToListAsync();
if (workGridSchedules.Any())
{
var dates = workGridSchedules.Select(x => $"{x.Date.ToString("yyyy年-MM月-dd日")}的{x.PeriodType.GetDescription()}").Join(",");
- var workGrid = await _dbContext.Queryable().Where(x => x.Code == workGridUser.WorkGridCode).Select(x => new
- {
- x.LeaderUserCode, x.Name
- }).SingleAsync();
- var content = $"{workGrid.Name}的网格长,你好,检测到你网格中 {gainfo.Name}({gainfo.Code}),因发生离职或者异动,现已经删除该员工{dates}的排班信息,请前往系统处理!";
+ var workGrid = await _dbContext.Queryable()
+ .Where(x => x.Code == workGridUser.WorkGridCode)
+ .Select(x => new
+ {
+ x.LeaderUserCode, x.Name
+ }).SingleAsync();
- await _dingTalkApi.SendWorkMessageAsync(new JinkoSendWorkMessageRequest
+ var content = $"{workGrid.Name}的网格长,你好,检测到你网格中 {gainfo.Name}({gainfo.Code}),因发生离职或者异动,现已经删除该员工{dates}的排班信息,请前往系统处理!";
+
+ await _dingTalkApi.SendWorkMessageAsync(new DingTalkWorkMessageRequest
{
Content = content,
WorkCodes = new List { workGrid.LeaderUserCode }
@@ -364,30 +369,39 @@ public class GainfoUpdateService : IGainfoUpdateService
await _dbContext.Client.Insertable(gainfo).AS("GainfoLeave").ExecuteCommandAsync();
}
- await _dbContext.Deleteable().Where(x => x.UserNo == gainfo.No).ExecuteCommandAsync();
- await _dbContext.Deleteable().Where(x => x.AssignType == AssignTypeEnumType.User && x.AssignValue == gainfo.No).ExecuteCommandAsync();
+ await _dbContext.Deleteable()
+ .Where(x => x.UserNo == gainfo.No)
+ .ExecuteCommandAsync();
+ await _dbContext.Deleteable()
+ .Where(x => x.AssignType == AssignTypeEnumType.User && x.AssignValue == gainfo.No)
+ .ExecuteCommandAsync();
- var workGridUser = await _dbContext.Queryable().Where(x => x.UserCode == gainfo.Code).SingleAsync();
+ var workGridUser = await _dbContext.Queryable()
+ .Where(x => x.UserCode == gainfo.Code)
+ .SingleAsync();
if (workGridUser != null)
{
try
{
var resignationDate = DateOnly.FromDateTime(gainfo.ResignationDate!.Value);
- var workGridSchedules = await _dbContext.Queryable().Where(x => x.UserCode == gainfo.Code)
+ var workGridSchedules = await _dbContext.Queryable()
+ .Where(x => x.UserCode == gainfo.Code)
.Where(x => x.Date >= resignationDate)
.ToListAsync();
if (workGridSchedules.Any())
{
var dates = workGridSchedules.Select(x => $"{x.Date.ToString("yyyy年-MM月-dd日")}的{x.PeriodType.GetDescription()}").Join(",");
- var workGrid = await _dbContext.Queryable().Where(x => x.Code == workGridUser.WorkGridCode).Select(x => new
- {
- x.LeaderUserCode, x.Name
- }).SingleAsync();
+ var workGrid = await _dbContext.Queryable()
+ .Where(x => x.Code == workGridUser.WorkGridCode)
+ .Select(x => new
+ {
+ x.LeaderUserCode, x.Name
+ }).SingleAsync();
var content = $"{workGrid.Name}的网格长,你好,检测到你网格中 {gainfo.Name}({gainfo.Code}),因发生离职或者异动,现已经删除该员工{dates}的排班信息,请前往系统处理!";
- await _dingTalkApi.SendWorkMessageAsync(new JinkoSendWorkMessageRequest
+ await _dingTalkApi.SendWorkMessageAsync(new DingTalkWorkMessageRequest
{
Content = content,
WorkCodes = new List { workGrid.LeaderUserCode }
diff --git a/Src/Dlhis.Basic/Program.cs b/Src/Dlhis.Basic/Program.cs
index 6bca2ab1..93573d15 100644
--- a/Src/Dlhis.Basic/Program.cs
+++ b/Src/Dlhis.Basic/Program.cs
@@ -7,9 +7,7 @@ class Program
{
static void Main(string[] args)
{
- KurisuHost.Builder(args)
- //.EnableAppSettingsReload()
- .RunKurisu();
+ KurisuHost.Builder(args).RunKurisu();
}
}
@@ -29,7 +27,7 @@ public class Startup : DefaultStartup
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
-
+
base.ConfigureServices(services);
services.AddRedis();
diff --git a/Src/Dlhis.Basic/WorkGrids/Repositories/IWorkGridScheduleRepository.cs b/Src/Dlhis.Basic/WorkGrids/Repositories/IWorkGridScheduleRepository.cs
new file mode 100644
index 00000000..84fcaa64
--- /dev/null
+++ b/Src/Dlhis.Basic/WorkGrids/Repositories/IWorkGridScheduleRepository.cs
@@ -0,0 +1,15 @@
+using Dlhis.Basic.WorkGrids.Response;
+
+namespace Dlhis.Basic.WorkGrids.Repositories;
+
+public interface IWorkGridScheduleRepository : IScopeDependency
+{
+ ///
+ /// 获取用户在指定天数内最大连续排班信息
+ ///
+ /// 用户编码列表
+ /// 天数s
+ /// 日期
+ /// 最大连续排班信息列表
+ Task> MaximumConsecutiveUserCodesAsync(List userCodes, int days, DateOnly date);
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/WorkGrids/Repositories/Implements/WorkGridScheduleRepository.cs b/Src/Dlhis.Basic/WorkGrids/Repositories/Implements/WorkGridScheduleRepository.cs
new file mode 100644
index 00000000..6175ca55
--- /dev/null
+++ b/Src/Dlhis.Basic/WorkGrids/Repositories/Implements/WorkGridScheduleRepository.cs
@@ -0,0 +1,62 @@
+using Dlhis.Basic.WorkGrids.Response;
+using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
+using Kurisu.AspNetCore.Utils.Extensions;
+
+namespace Dlhis.Basic.WorkGrids.Repositories.Implements;
+
+public class WorkGridScheduleRepository : IWorkGridScheduleRepository
+{
+ private readonly IDbContext _dbContext;
+
+ public WorkGridScheduleRepository(IDbContext dbContext)
+ {
+ _dbContext = dbContext;
+ }
+
+ public async Task> MaximumConsecutiveUserCodesAsync(List userCodes, int days, DateOnly date)
+ {
+ var userCodesStr = userCodes.Select(x => $"@param{x.Replace("-", "A_")}").Join(",");
+ var parameters = userCodes.ToDictionary(x => $"param{x.Replace("-", "A_")}", x => x);
+
+ parameters.Add("dateBefore", date.AddDays(-1).ToString("yyyy-MM-dd"));
+ parameters.Add("dateAfter", date.AddDays(1).ToString("yyyy-MM-dd"));
+ parameters.Add("days", days.ToString());
+
+ /* 1.用户按日期排序,标记序号
+ * 2.将日期减去序号,需要得出结果一致 == 数据连续 == 连续排班
+ * 3.根据减去序号后的日期分组,统计连续排班的天数
+ * 4.数据过滤,取当前排班的前后一天
+ *
+ * 根据以上结果,获取连续排班天数大于等于指定天数的用户
+ */
+ 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 ({userCodesStr})
+ 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)
+";
+
+ return await _dbContext.Client.Ado.SqlQueryAsync(sql, parameters);
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Basic/WorkGrids/Request/WorkGridPageRequest.cs b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridPageRequest.cs
index eb7bd538..811a3d55 100644
--- a/Src/Dlhis.Basic/WorkGrids/Request/WorkGridPageRequest.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridPageRequest.cs
@@ -5,7 +5,7 @@ namespace Dlhis.Basic.WorkGrids.Request;
public class WorkGridPageRequest : PageDto
{
///
- /// 网格code,不传则取我的网格
+ /// 网格code,默认为当前用户网格
///
public Guid? WorkGridCode { get; set; }
diff --git a/Src/Dlhis.Basic/WorkGrids/Request/WorkGridScheduleSaveRequest.cs b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridScheduleSaveRequest.cs
index 359ace8b..b4d3dae5 100644
--- a/Src/Dlhis.Basic/WorkGrids/Request/WorkGridScheduleSaveRequest.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Request/WorkGridScheduleSaveRequest.cs
@@ -18,7 +18,7 @@ public class WorkGridScheduleSaveRequest : IValidatableObject
///
/// 班次
///
- [EnumDataType(typeof(WorkGridTimePeriodEnumType))]
+ [EnumDataType(typeof(WorkGridTimePeriodEnumType), ErrorMessage = "班次类型错误")]
public WorkGridTimePeriodEnumType PeriodType { get; set; }
///
@@ -27,7 +27,7 @@ public class WorkGridScheduleSaveRequest : IValidatableObject
[MinLength(1, ErrorMessage = "人员不可为空")]
public List UserCodes { get; set; }
- ///
+
public IEnumerable Validate(ValidationContext validationContext)
{
var now = DateTime.Now;
diff --git a/Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs b/Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs
index 4301c336..2454dac1 100644
--- a/Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Response/WorkGridScheduleMaximumConsecutiveDto.cs
@@ -1,5 +1,11 @@
+using Dlhis.Basic.WorkGrids.Repositories;
+
namespace Dlhis.Basic.WorkGrids.Response;
+///
+/// 连续排班信息
+/// 的方法返回类型
+///
public class WorkGridScheduleMaximumConsecutiveDto
{
public string UserCode { get; set; }
diff --git a/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs b/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs
index d32bd128..1c31dcb3 100644
--- a/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs
+++ b/Src/Dlhis.Basic/WorkGrids/Services/IWorkGridScheduleService.cs
@@ -10,21 +10,60 @@ namespace Dlhis.Basic.WorkGrids.Services;
///
public interface IWorkGridScheduleService : IScopeDependency
{
+ ///
+ /// 保存网格排班信息
+ ///
+ /// 排班保存请求参数
Task SaveAsync(WorkGridScheduleSaveRequest request);
+ ///
+ /// 移除网格排班信息
+ ///
+ /// 排班移除请求参数
Task RemoveAsync(WorkGridScheduleSaveRequest request);
+ ///
+ /// 获取指定网格、日期和时段的排班列表
+ ///
+ /// 网格编码
+ /// 日期
+ /// 时段类型
+ /// 排班列表
Task> GetListAsync(Guid workGridCode, DateOnly date, WorkGridTimePeriodEnumType? periodType);
+ ///
+ /// 获取指定网格和日期范围的排班汇总列表
+ ///
+ /// 网格编码
+ /// 开始日期
+ /// 结束日期
+ /// 排班汇总列表
Task> GetListSummaryAsync(Guid workGridCode, DateOnly start, DateOnly end);
+ ///
+ /// 获取排班考勤分页数据
+ ///
+ /// 考勤分页请求参数
+ /// 排班考勤分页数据
Task> GetAttendancePageAsync(WorkGridScheduleAttendancePageRequest request);
+ ///
+ /// 获取所有排班考勤分页数据
+ ///
+ /// 考勤分页请求参数
+ /// 排班考勤分页数据
Task> GetAllAttendancePageAsync(WorkGridScheduleAttendancePageRequest request);
+ ///
+ /// 手动上传考勤日志
+ ///
+ /// 考勤日志ID列表
Task ManuallyUploadAsync(List logIds);
- Task> MaximumConsecutiveUserCodesAsync(List userCodes, int days, DateOnly date);
-
+ ///
+ /// 测试接口
+ ///
+ /// 排班保存请求参数
+ /// 测试结果
Task