feat 设备批量导入
This commit is contained in:
@@ -199,7 +199,17 @@ public class DevicesController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取近期30天新增设备数
|
/// 获取门禁在线/离线设备详情列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("dooroffline")]
|
||||||
|
public async Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync([FromQuery] GetDoorOfflineRequest request)
|
||||||
|
{
|
||||||
|
return await _deviceService.GetDoorOfflineAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取近期30天考勤新增设备数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("recentnumbers")]
|
[HttpGet("recentnumbers")]
|
||||||
@@ -208,4 +218,15 @@ public class DevicesController : ControllerBase
|
|||||||
return await _deviceService.GetRecentNumbersAsync();
|
return await _deviceService.GetRecentNumbersAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量导入设备信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("bulkUploads")]
|
||||||
|
public async Task BulkUploadsAsync([FromForm] BulkUploadsRequest request)
|
||||||
|
{
|
||||||
|
await _deviceService.BulkUploadsAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
10
Src/Dlhis.Basic/Device/Request/BulkUploadsRequest.cs
Normal file
10
Src/Dlhis.Basic/Device/Request/BulkUploadsRequest.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Dlhis.Basic.Device.Request
|
||||||
|
{
|
||||||
|
public class BulkUploadsRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设备信息文件
|
||||||
|
/// </summary>
|
||||||
|
public IFormFile FormFile { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
76
Src/Dlhis.Basic/Device/Request/ImportDeviceSaveRequest.cs
Normal file
76
Src/Dlhis.Basic/Device/Request/ImportDeviceSaveRequest.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Request
|
||||||
|
{
|
||||||
|
public class ImportDeviceSaveRequest
|
||||||
|
{
|
||||||
|
|
||||||
|
public long? Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备唯一号
|
||||||
|
/// </summary>
|
||||||
|
public string UniqueNo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模板code
|
||||||
|
/// </summary>
|
||||||
|
public Guid TemplateCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 供应商信息
|
||||||
|
/// </summary>
|
||||||
|
public string Supplier { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备功能
|
||||||
|
/// </summary>
|
||||||
|
public List<DeviceFuncEnumType> Funcs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备类型 DeviceTypeEnumType
|
||||||
|
/// </summary>
|
||||||
|
public DeviceTypeEnumType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 心跳间隔
|
||||||
|
/// </summary>
|
||||||
|
public int HeartbeatInterval { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部署点
|
||||||
|
/// </summary>
|
||||||
|
public string DeployPlace { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部署坐标
|
||||||
|
/// </summary>
|
||||||
|
public string DeployPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部署方向
|
||||||
|
/// </summary>
|
||||||
|
public string DeployDirection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接信息
|
||||||
|
/// </summary>
|
||||||
|
public string ConnectionInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否启用
|
||||||
|
/// </summary>
|
||||||
|
public bool Enable { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否作为考勤设备
|
||||||
|
/// </summary>
|
||||||
|
public bool AsAttendance { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点code
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PlaceeCode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
9
Src/Dlhis.Basic/Device/Response/GetDoorOfflineRequest.cs
Normal file
9
Src/Dlhis.Basic/Device/Response/GetDoorOfflineRequest.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Response
|
||||||
|
{
|
||||||
|
public class GetDoorOfflineRequest : PageDto
|
||||||
|
{
|
||||||
|
public bool IsOnAndOff { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,11 @@ public interface IDeviceService : IScopeDependency
|
|||||||
|
|
||||||
Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndofflineRequest request);
|
Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndofflineRequest request);
|
||||||
|
|
||||||
|
Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync(GetDoorOfflineRequest request);
|
||||||
|
|
||||||
Task<List<RecentNumberResponse>> GetRecentNumbersAsync();
|
Task<List<RecentNumberResponse>> GetRecentNumbersAsync();
|
||||||
|
|
||||||
|
Task BulkUploadsAsync(BulkUploadsRequest request);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,12 @@ using Kurisu.SqlSugar.Extensions;
|
|||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MySqlX.XDevAPI.Relational;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using NPOI.OpenXmlFormats;
|
||||||
|
using NPOI.SS.UserModel;
|
||||||
|
using NPOI.XSSF.UserModel;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Services.Implements;
|
namespace Dlhis.Basic.Device.Services.Implements;
|
||||||
@@ -123,6 +127,53 @@ public class DeviceService : IDeviceService
|
|||||||
await GenerateUploadRecordLogForBeginTimeAsync(entity);
|
await GenerateUploadRecordLogForBeginTimeAsync(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量导入
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task BulkUploadsAsync(BulkUploadsRequest request)
|
||||||
|
{
|
||||||
|
var lst = ImportFromExcel(request.FormFile);
|
||||||
|
var places = await _dbContext.Queryable<BusinessPlaceEntity>().ToListAsync();
|
||||||
|
|
||||||
|
foreach (var form in lst)
|
||||||
|
{
|
||||||
|
if (form.PlaceeCode != null)
|
||||||
|
{
|
||||||
|
var place = places.Where(x => x.Code == form.PlaceeCode).FirstOrDefault();
|
||||||
|
place.ThrowIfNull($"该设备{form.UniqueNo}配置的营业点营业点不存在!");
|
||||||
|
}
|
||||||
|
//插入
|
||||||
|
var exists = await _dbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == form.UniqueNo)
|
||||||
|
.AnyAsync();
|
||||||
|
exists.ThrowIfTrue("唯一号已经存在");
|
||||||
|
var template = await CheckTemplateExistsAsync(form.TemplateCode);
|
||||||
|
await CheckTemplateFieldAsync(form.TemplateCode, form.ConnectionInfo);
|
||||||
|
|
||||||
|
var saveEntity = form.Adapt<DeviceEntity>();
|
||||||
|
saveEntity.Code = Guid.NewGuid();
|
||||||
|
await _dbContext.InsertAsync(saveEntity);
|
||||||
|
//保存注册信息
|
||||||
|
var regis = await _dbContext.Queryable<DeviceRegistryEntity>()
|
||||||
|
.Where(x => x.DeviceUniqueNo == form.UniqueNo)
|
||||||
|
.FirstAsync();
|
||||||
|
if(regis == null)
|
||||||
|
{
|
||||||
|
var custCode = places.Where(x => x.Code == form.PlaceeCode).Select(x => x.CustomCode).FirstOrDefault();
|
||||||
|
regis = new DeviceRegistryEntity
|
||||||
|
{
|
||||||
|
DeviceUniqueNo = form.UniqueNo,
|
||||||
|
LastHeartbeatTime = DateTime.Now,
|
||||||
|
RegisterTime = DateTime.Now,
|
||||||
|
BusinessPlaceCode = form.PlaceeCode,
|
||||||
|
BusinessPlaceCustomCode = custCode
|
||||||
|
};
|
||||||
|
await _dbContext.InsertAsync(regis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//******************************************************** help methods **********************************************************
|
//******************************************************** help methods **********************************************************
|
||||||
|
|
||||||
private async Task GenerateUploadRecordLogForBeginTimeAsync(DeviceEntity entity)
|
private async Task GenerateUploadRecordLogForBeginTimeAsync(DeviceEntity entity)
|
||||||
@@ -343,7 +394,7 @@ public class DeviceService : IDeviceService
|
|||||||
//离线
|
//离线
|
||||||
var offpage = await _dbContext.Queryable<DeviceEntity>()
|
var offpage = await _dbContext.Queryable<DeviceEntity>()
|
||||||
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
.Where(d => d.Type == DeviceTypeEnumType.Attendance && d.Enable)
|
.Where(d => d.Type == DeviceTypeEnumType.Attendance)
|
||||||
.Where(d => offids.Contains(d.Id))
|
.Where(d => offids.Contains(d.Id))
|
||||||
.Select((d, dt) => new DevicePageResponse
|
.Select((d, dt) => new DevicePageResponse
|
||||||
{
|
{
|
||||||
@@ -361,7 +412,7 @@ public class DeviceService : IDeviceService
|
|||||||
|
|
||||||
var page = await _dbContext.Queryable<DeviceEntity>()
|
var page = await _dbContext.Queryable<DeviceEntity>()
|
||||||
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
.Where(d => d.Type == DeviceTypeEnumType.Attendance && d.Enable)
|
.Where(d => d.Type == DeviceTypeEnumType.Attendance)
|
||||||
.Where(d => onids.Contains(d.Id))
|
.Where(d => onids.Contains(d.Id))
|
||||||
.Select((d, dt) => new DevicePageResponse
|
.Select((d, dt) => new DevicePageResponse
|
||||||
{
|
{
|
||||||
@@ -375,6 +426,51 @@ public class DeviceService : IDeviceService
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync(GetDoorOfflineRequest request)
|
||||||
|
{
|
||||||
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Door).ToListAsync();
|
||||||
|
|
||||||
|
var offDevices = await GetOfflineDevicesCount(devices);
|
||||||
|
var offids = offDevices.Select(x => x.Id).ToList();
|
||||||
|
|
||||||
|
if (request.IsOnAndOff)
|
||||||
|
{
|
||||||
|
//离线
|
||||||
|
var offpage = await _dbContext.Queryable<DeviceEntity>()
|
||||||
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
|
.Where(d => d.Type == DeviceTypeEnumType.Door)
|
||||||
|
.Where(d => offids.Contains(d.Id))
|
||||||
|
.Select((d, dt) => new DevicePageResponse
|
||||||
|
{
|
||||||
|
FuncsStr = d.Funcs.ToString(),
|
||||||
|
Brand = dt.Brand,
|
||||||
|
Type = d.Type,
|
||||||
|
|
||||||
|
}, true)
|
||||||
|
.ToPageListAsync(request);
|
||||||
|
return offpage;
|
||||||
|
}
|
||||||
|
//在线
|
||||||
|
var ids = devices.Select(x => x.Id).ToList();
|
||||||
|
List<long> onids = ids.Except(offids).ToList();
|
||||||
|
|
||||||
|
var page = await _dbContext.Queryable<DeviceEntity>()
|
||||||
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
|
.Where(d => d.Type == DeviceTypeEnumType.Door)
|
||||||
|
.Where(d => onids.Contains(d.Id))
|
||||||
|
.Select((d, dt) => new DevicePageResponse
|
||||||
|
{
|
||||||
|
FuncsStr = d.Funcs.ToString(),
|
||||||
|
Brand = dt.Brand,
|
||||||
|
Type = d.Type,
|
||||||
|
|
||||||
|
}, true)
|
||||||
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<List<RecentNumberResponse>> GetRecentNumbersAsync()
|
public async Task<List<RecentNumberResponse>> GetRecentNumbersAsync()
|
||||||
{
|
{
|
||||||
//获取近30天并转化为"yyyy-MM-dd"集合
|
//获取近30天并转化为"yyyy-MM-dd"集合
|
||||||
@@ -387,7 +483,7 @@ public class DeviceService : IDeviceService
|
|||||||
times.Add(dateString);
|
times.Add(dateString);
|
||||||
}
|
}
|
||||||
|
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
||||||
|
|
||||||
var list = new List<RecentNumberResponse>();
|
var list = new List<RecentNumberResponse>();
|
||||||
times.ForEach(time =>
|
times.ForEach(time =>
|
||||||
@@ -403,5 +499,68 @@ public class DeviceService : IDeviceService
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
private List<ImportDeviceSaveRequest> ImportFromExcel(IFormFile formFile)
|
||||||
|
{
|
||||||
|
var requests = new List<ImportDeviceSaveRequest>();
|
||||||
|
|
||||||
|
using (var stream = formFile.OpenReadStream())
|
||||||
|
{
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook(stream);
|
||||||
|
ISheet sheet = workbook.GetSheetAt(0);
|
||||||
|
|
||||||
|
for (int rowIdx = 1; rowIdx <= sheet.LastRowNum; rowIdx++)
|
||||||
|
{
|
||||||
|
IRow row = sheet.GetRow(rowIdx);
|
||||||
|
if (row == null) continue;
|
||||||
|
|
||||||
|
var request = new ImportDeviceSaveRequest();
|
||||||
|
|
||||||
|
request.UniqueNo = row.GetCell(0).ToString();
|
||||||
|
request.TemplateCode = Guid.Parse(row.GetCell(1).ToString());
|
||||||
|
request.Supplier = row.GetCell(2).ToString();
|
||||||
|
|
||||||
|
var funs = new List<DeviceFuncEnumType>();
|
||||||
|
var fs = row.GetCell(3).ToString().Split(',');
|
||||||
|
foreach (string str in fs)
|
||||||
|
{
|
||||||
|
switch (str)
|
||||||
|
{
|
||||||
|
case "1":
|
||||||
|
funs.Add(DeviceFuncEnumType.Face);
|
||||||
|
break;
|
||||||
|
case "2":
|
||||||
|
funs.Add(DeviceFuncEnumType.Card);
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
funs.Add(DeviceFuncEnumType.QrCode);
|
||||||
|
break;
|
||||||
|
case "4":
|
||||||
|
funs.Add(DeviceFuncEnumType.Control);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.Funcs = funs;
|
||||||
|
request.Type = (DeviceTypeEnumType)Enum.Parse(typeof(DeviceTypeEnumType), row.GetCell(4).ToString());
|
||||||
|
request.HeartbeatInterval = int.Parse(row.GetCell(5).ToString());
|
||||||
|
request.DeployPlace = row.GetCell(6).ToString();
|
||||||
|
request.DeployPosition = row.GetCell(7).ToString();
|
||||||
|
request.DeployDirection = row.GetCell(8).ToString();
|
||||||
|
request.ConnectionInfo = row.GetCell(9).ToString();
|
||||||
|
request.Enable = Convert.ToBoolean(Convert.ToInt32(row.GetCell(10).ToString()));
|
||||||
|
request.AsAttendance = Convert.ToBoolean(Convert.ToInt32(row.GetCell(11).ToString()));
|
||||||
|
if (row.GetCell(12) != null)
|
||||||
|
{
|
||||||
|
request.PlaceeCode = Guid.Parse(row.GetCell(12)?.ToString());
|
||||||
|
}
|
||||||
|
requests.Add(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requests;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Kurisu.AspNetCore" Version="0.6.1" />
|
<PackageReference Include="Kurisu.AspNetCore" Version="0.6.1" />
|
||||||
|
<PackageReference Include="NPOI" Version="2.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dlhis.Basic.Summary.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
|
using Dlhis.Basic.Summary.Response;
|
||||||
using Dlhis.Basic.Summary.Services;
|
using Dlhis.Basic.Summary.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -26,4 +27,14 @@ public class SummariesController : ControllerBase
|
|||||||
{
|
{
|
||||||
return await _summaryService.GetAttendanceSummaryAsync();
|
return await _summaryService.GetAttendanceSummaryAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 门禁首页数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("door-summary")]
|
||||||
|
public async Task<DoorHomeDataResponse> GetDoorHomeDataAsync()
|
||||||
|
{
|
||||||
|
return await _summaryService.GetDoorHomeDataAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
Src/Dlhis.Basic/Summary/Response/DoorHomeDataResponse.cs
Normal file
11
Src/Dlhis.Basic/Summary/Response/DoorHomeDataResponse.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Dlhis.Basic.Summary.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Summary.Response
|
||||||
|
{
|
||||||
|
public class DoorHomeDataResponse
|
||||||
|
{
|
||||||
|
public int OffNum { get; set; }
|
||||||
|
public int TotalNum { get; set; }
|
||||||
|
public List<TrendDto> Trend { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
using Dlhis.Basic.Summary.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
|
using Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Summary.Services;
|
namespace Dlhis.Basic.Summary.Services;
|
||||||
|
|
||||||
public interface ISummaryService : IScopeDependency
|
public interface ISummaryService : IScopeDependency
|
||||||
{
|
{
|
||||||
Task<AttendanceSummaryResponse> GetAttendanceSummaryAsync();
|
Task<AttendanceSummaryResponse> GetAttendanceSummaryAsync();
|
||||||
|
|
||||||
|
Task<DoorHomeDataResponse> GetDoorHomeDataAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dlhis.Basic.Organization.Services;
|
using Dlhis.Basic.Device.Response;
|
||||||
|
using Dlhis.Basic.Organization.Services;
|
||||||
using Dlhis.Basic.Summary.Dto;
|
using Dlhis.Basic.Summary.Dto;
|
||||||
using Dlhis.Basic.Summary.Response;
|
using Dlhis.Basic.Summary.Response;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
using Dlhis.Entity.Basic.Entity;
|
||||||
@@ -81,6 +82,42 @@ public class SummaryService : ISummaryService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
List<string> 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;
|
||||||
|
}
|
||||||
|
|
||||||
private static List<TrendDto> FixTrend(IEnumerable<TrendDto> dtos, DateTime start, DateTime end)
|
private static List<TrendDto> FixTrend(IEnumerable<TrendDto> dtos, DateTime start, DateTime end)
|
||||||
{
|
{
|
||||||
var result = dtos.ToList();
|
var result = dtos.ToList();
|
||||||
@@ -104,4 +141,49 @@ public class SummaryService : ISummaryService
|
|||||||
|
|
||||||
return result.OrderBy(x => x.Date).ToList();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user