Files
jinko.yikatong/Src/Dlhis.Basic/Summary/Services/Implements/SummaryService.cs

240 lines
8.9 KiB
C#

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 Dlhis.Entity.Device.Enums;
using Kurisu.Core.User.Abstractions;
using Kurisu.SqlSugar.Services;
namespace Dlhis.Basic.Summary.Services.Implements;
public class SummaryService : ISummaryService
{
private readonly IDbContext _dbContext;
private readonly IGainfoStore _gainfoStore;
private readonly ICurrentUser _currentUser;
public SummaryService(IDbContext dbContext, IGainfoStore gainfoStore, ICurrentUser currentUser)
{
_dbContext = dbContext;
_gainfoStore = gainfoStore;
_currentUser = currentUser;
}
public async Task<AttendanceSummaryResponse> GetAttendanceSummaryAsync()
{
var now = DateTime.Now;
var tenantId = _currentUser.GetStringTenantId();
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<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance))
.ToListAsync();
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
var deviceRegistries = await _dbContext.Queryable<DeviceRegistryEntity>()
.LeftJoin<DeviceEntity>((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).Where(x => x.Factory == tenantId).ToListAsync();
var leaveGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Leave).Where(x => x.Factory == tenantId).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 true;
}
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.EntryDate >= before7Day && x.EntryDate <= currentDay)
.GroupBy(x => x.EntryDate)
.Select(x => new TrendDto { Date = x.Key.Value, Count = x.Count() }), before7Day, currentDay),
UnemployedTrend = FixTrend(leaveGainfos.Where(x => x.ResignationDate >= before7Day && x.ResignationDate <= currentDay)
.GroupBy(x => x.ResignationDate)
.Select(x => new TrendDto { Date = x.Key.Value, Count = x.Count() }), before7Day, currentDay),
}
}
};
}
public async Task<DoorHomeDataResponse> GetDoorHomeDataAsync()
{
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Door).ToListAsync();
var offDevices = await GetOfflineDevicesCount(devices);
//获取近30天并转化为"yyyy-MM-dd"集合
DateTime currentDate = DateTime.Now;
var times = new List<string>();
for (int i = 0; i < 30; i++)
{
DateTime date = currentDate.AddDays(-i);
string dateString = date.ToString("yyyy-MM-dd");
times.Add(dateString);
}
var list = new List<TrendDto>();
times.ForEach(time =>
{
var count = devices.Where(x => x.CreateTime.ToString("yyyy-MM-dd") == time).Count();
var trend = new TrendDto
{
Date = DateTime.ParseExact(time, "yyyy-MM-dd", null),
Count = count,
};
list.Add(trend);
});
var res = new DoorHomeDataResponse
{
OffNum = offDevices.Count,
TotalNum = devices.Count,
Trend = list
};
return res;
}
public async Task<DoorDataResponse> GetDoorDataAsync()
{
var res = new DoorDataResponse();
var workingGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).ToListAsync();
var leaveGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Leave).ToListAsync();
res.Employed = workingGainfos.Count;
res.Unemployed = leaveGainfos.Count;
var employedTrend = new List<TrendDto>();
var unemployedTrend = new List<TrendDto>();
//获取近7天并转化为"yyyy-MM-dd"集合
var currentDate = DateTime.Now;
var times = new List<string>();
for (int i = 0; i < 7; i++)
{
DateTime date = currentDate.AddDays(-i);
string dateString = date.ToString("yyyy-MM-dd");
times.Add(dateString);
}
foreach (var time in times)
{
var emDto = new TrendDto
{
Date = DateTime.ParseExact(time, "yyyy-MM-dd", null),
Count = workingGainfos.Where(x => x.CreateTime.ToString("yyy-MM-dd") == time).ToList().Count,
};
employedTrend.Add(emDto);
var unDto = new TrendDto
{
Date = DateTime.ParseExact(time, "yyyy-MM-dd", null),
Count = leaveGainfos.Where(x => x.CreateTime.ToString("yyy-MM-dd") == time).ToList().Count,
};
unemployedTrend.Add(unDto);
}
var ginfoTrendResponse = new GainfoTrendResponse();
ginfoTrendResponse.EmployedTrend = employedTrend;
ginfoTrendResponse.UnemployedTrend = unemployedTrend;
res.GainfoTrend = ginfoTrendResponse;
employedTrend.ForEach(x => res.WeekEmployed += x.Count);
unemployedTrend.ForEach(x => res.WeekUnemployed += x.Count);
return res;
}
private static List<TrendDto> FixTrend(IEnumerable<TrendDto> 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();
}
/// <summary>
/// 获取离线设备
/// </summary>
/// <returns></returns>
private async Task<List<DeviceEntity>> GetOfflineDevicesCount(List<DeviceEntity> devices)
{
var now = DateTime.Now;
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
var deviceRegistries = await _dbContext.Queryable<DeviceRegistryEntity>()
.LeftJoin<DeviceEntity>((x, d) => x.DeviceUniqueNo == d.UniqueNo)
.Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo))
.Select((x, d) => new
{
UniqueNo = d.UniqueNo,
d.HeartbeatInterval,
x.LastHeartbeatTime
})
.ToListAsync();
var OnlineDevices = deviceRegistries
.Where(x =>
{
if (x.HeartbeatInterval <= 0)
{
return true;
}
return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now;
})
.Select(x => new
{
UniqueNo = x.UniqueNo,
})
.ToList();
var onlineUniqueNos = new List<string>();
OnlineDevices.ForEach(x => onlineUniqueNos.Add(x.UniqueNo));
var offUniqueNos = deviceUniqueNos.Except(onlineUniqueNos).ToList();
var list = devices.Where(x => offUniqueNos.Contains(x.UniqueNo)).ToList();
return list;
}
}