using Dlhis.Basic.Organization.Services; using Dlhis.Basic.Summary.Dto; using Dlhis.Basic.Summary.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Enums; using Dlhis.Entity.Device.Entities; using Kurisu.SqlSugar.Services; namespace Dlhis.Basic.Summary.Services.Implements; public class SummaryService : ISummaryService { private readonly IDbContext _dbContext; private readonly IGainfoStore _gainfoStore; public SummaryService(IDbContext dbContext, IGainfoStore gainfoStore) { _dbContext = dbContext; _gainfoStore = gainfoStore; } public async Task GetAttendanceSummaryAsync() { var now = DateTime.Now; var currentDay = DateTime.Today.AddDays(1).AddSeconds(-1); var before30Day = DateTime.Today.AddDays(-29); var before7Day = DateTime.Today.AddDays(-6); var devices = await _dbContext.Queryable().ToListAsync(); var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList(); var deviceRegistries = await _dbContext.Queryable() .LeftJoin((x, d) => x.DeviceUniqueNo == d.UniqueNo) .Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo)) .Select((x, d) => new { d.HeartbeatInterval, x.LastHeartbeatTime }) .ToListAsync(); var workingGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).ToListAsync(); var leaveGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Leave).ToListAsync(); return new AttendanceSummaryResponse { DeviceSummary = new AttendanceDeviceSummary { Total = devices.Count, EnableCount = devices.Where(x => x.Enable).Count(), OnlineCount = deviceRegistries.Where(x => { if (x.HeartbeatInterval <= 0) { return false; } return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now; }).Count(), Trend = FixTrend(devices.Where(x => x.CreateTime >= before30Day && x.CreateTime <= currentDay) .GroupBy(x => x.CreateTime.Date) .Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before30Day, currentDay) }, AttendanceDetailSummary = new AttendanceDetailSummary { Employed = workingGainfos.Count, Unemployed = leaveGainfos.Count, GainfoTrend = new GainfoTrendResponse { EmployedTrend = FixTrend(workingGainfos.Where(x => x.CreateTime >= before7Day && x.CreateTime <= currentDay) .GroupBy(x => x.CreateTime.Date) .Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before7Day, currentDay), UnemployedTrend = FixTrend(leaveGainfos.Where(x => x.CreateTime >= before7Day && x.CreateTime <= currentDay) .GroupBy(x => x.CreateTime.Date) .Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before7Day, currentDay), } } }; } private static List FixTrend(IEnumerable dtos, DateTime start, DateTime end) { var result = dtos.ToList(); start = start.Date; end = end.Date; var currentDate = start; while (currentDate <= end) { if (result.Any(x => x.Date == currentDate)) { currentDate = currentDate.AddDays(1); continue; } result.Add(new TrendDto { Date = currentDate, Count = 0 }); currentDate = currentDate.AddDays(1); } return result.OrderBy(x => x.Date).ToList(); } }