222 lines
9.3 KiB
C#
222 lines
9.3 KiB
C#
using MoviconWebApi.Entities;
|
||
|
||
namespace MoviconWebApi.API.DeviceStateApi
|
||
{
|
||
public static class Data
|
||
{
|
||
/// <summary>
|
||
/// 获取设备状态列表
|
||
/// </summary>
|
||
public static async Task<List<DeviceStateResponse>> GetDeviceStateListAsync(
|
||
IFreeSql db,
|
||
DeviceStateRequest request)
|
||
{
|
||
try
|
||
{
|
||
// 1) 校验时间范围
|
||
var hasStart = DateTime.TryParse(request.StartTime, out var startTime);
|
||
var hasEnd = DateTime.TryParse(request.EndTime, out var endTime);
|
||
|
||
if (!hasStart || !hasEnd)
|
||
{
|
||
// 未提供有效时间范围,返回空列表(遵循列表查询返回空集合不返回404的约定)
|
||
return new List<DeviceStateResponse>();
|
||
}
|
||
|
||
if (endTime < startTime)
|
||
{
|
||
// 纠正时间顺序或直接返回空
|
||
return new List<DeviceStateResponse>();
|
||
}
|
||
|
||
var totalMinutes = (endTime - startTime).TotalMinutes;
|
||
if (totalMinutes <= 0)
|
||
{
|
||
return new List<DeviceStateResponse>();
|
||
}
|
||
|
||
// 2) 基础查询(按设备、时间过滤)
|
||
var baseQuery = db.Select<DeviceState>()
|
||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode), x => x.DeviceCode == request.DeviceCode)
|
||
.Where(x => x.CreateTime >= startTime && x.CreateTime <= endTime);
|
||
|
||
// 3) 聚合统计:仅选择必要字段到内存做聚合,避免类型不兼容问题
|
||
var lightList = await baseQuery.ToListAsync(a => new
|
||
{
|
||
a.PowerOnTime,
|
||
a.RunTime,
|
||
a.StandbyTime,
|
||
a.FaultTime,
|
||
a.ShutdownTime,
|
||
a.FaultNum
|
||
});
|
||
|
||
long totalPowerOn = lightList.Sum(x => (long)(x.PowerOnTime ?? 0));
|
||
long totalRun = lightList.Sum(x => (long)(x.RunTime ?? 0));
|
||
long totalStandby = lightList.Sum(x => (long)(x.StandbyTime ?? 0));
|
||
long totalFault = lightList.Sum(x => (long)(x.FaultTime ?? 0));
|
||
long totalShutdown = lightList.Sum(x => (long)(x.ShutdownTime ?? 0));
|
||
long totalFaultCount = lightList.Sum(x => (long)(x.FaultNum ?? 0));
|
||
// 作业次数:来自当前搜索时间内 ClearData 的记录数
|
||
long totalJobCount = await db.Select<ClearData>()
|
||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode), x => x.DeviceCode == request.DeviceCode)
|
||
.Where(x => x.CreateTime >= startTime && x.CreateTime <= endTime)
|
||
.CountAsync();
|
||
|
||
// 若该时间段内没有任何记录,返回空集合
|
||
var hasAnyData = (totalPowerOn + totalRun + totalStandby + totalFault + totalShutdown + totalFaultCount + totalJobCount) > 0;
|
||
if (!hasAnyData)
|
||
{
|
||
return new List<DeviceStateResponse>();
|
||
}
|
||
|
||
// 4) 计算使用率:默认按(开机+运行+待机+故障)/ 时间段总分钟
|
||
var usedMinutes = totalPowerOn + totalRun + totalStandby + totalFault; // 排除关机
|
||
double ratio = usedMinutes <= 0 ? 0 : Math.Min(100.0, Math.Max(0.0, usedMinutes * 100.0 / totalMinutes));
|
||
var useRatioText = $"{Math.Round(ratio, 2)}%";
|
||
|
||
// 5) 获取设备名称(取时间段内最新一条的名称,避免跨设备统计导致名称混淆)
|
||
string? deviceName = null;
|
||
try
|
||
{
|
||
deviceName = await db.Select<DeviceState>()
|
||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode), x => x.DeviceCode == request.DeviceCode)
|
||
.Where(x => x.CreateTime >= startTime && x.CreateTime <= endTime)
|
||
.OrderByDescending(x => x.CreateTime)
|
||
.FirstAsync(x => x.DeviceName);
|
||
}
|
||
catch
|
||
{
|
||
// 忽略设备名获取失败,不影响主逻辑
|
||
}
|
||
|
||
// 6) 组装单条汇总结果
|
||
var summary = new DeviceStateResponse
|
||
{
|
||
DeviceCode = string.IsNullOrWhiteSpace(request.DeviceCode) ? null : request.DeviceCode,
|
||
DeviceName = deviceName,
|
||
PowerOnTime = (int)totalPowerOn,
|
||
RunTime = (int)totalRun,
|
||
StandbyTime = (int)totalStandby,
|
||
FaultTime = (int)totalFault,
|
||
ShutdownTime = (int)totalShutdown,
|
||
UseRatio = useRatioText,
|
||
FaultNum = (int)totalFaultCount,
|
||
JobNum = totalJobCount > int.MaxValue ? int.MaxValue : (int)totalJobCount,
|
||
CreateTime = endTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||
};
|
||
|
||
return new List<DeviceStateResponse> { summary };
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw new Exception($"查询设备状态数据失败: {ex.Message}", ex);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 分页获取设备状态
|
||
/// </summary>
|
||
public static async Task<(List<DeviceStateResponse>, long)> GetDeviceStatePagedAsync(
|
||
IFreeSql db,
|
||
DeviceStatePagedRequest request)
|
||
{
|
||
try
|
||
{
|
||
var query = db.Select<DeviceState>()
|
||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode),
|
||
a => a.DeviceCode == request.DeviceCode);
|
||
|
||
if (!string.IsNullOrWhiteSpace(request.StartTime) &&
|
||
DateTime.TryParse(request.StartTime, out var startTime))
|
||
{
|
||
query = query.Where(a => a.CreateTime >= startTime);
|
||
}
|
||
|
||
if (!string.IsNullOrWhiteSpace(request.EndTime) &&
|
||
DateTime.TryParse(request.EndTime, out var endTime))
|
||
{
|
||
query = query.Where(a => a.CreateTime <= endTime);
|
||
}
|
||
|
||
var total = await query.CountAsync();
|
||
|
||
var data = await query
|
||
.OrderByDescending(a => a.CreateTime)
|
||
.Page(request.PageIndex, request.PageSize)
|
||
.ToListAsync(a => new DeviceStateResponse
|
||
{
|
||
DeviceCode = a.DeviceCode,
|
||
DeviceName = a.DeviceName,
|
||
PowerOnTime = a.PowerOnTime,
|
||
RunTime = a.RunTime,
|
||
StandbyTime = a.StandbyTime,
|
||
FaultTime = a.FaultTime,
|
||
ShutdownTime = a.ShutdownTime,
|
||
UseRatio = a.UseRatio,
|
||
FaultNum = a.FaultNum,
|
||
JobNum = a.JobNum,
|
||
CreateTime = a.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||
});
|
||
|
||
return (data ?? new List<DeviceStateResponse>(), total);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw new Exception($"分页查询设备状态数据失败: {ex.Message}", ex);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取最新的设备状态记录
|
||
/// </summary>
|
||
public static async Task<DeviceStateResponse?> GetLatestDeviceStateAsync(
|
||
IFreeSql db,
|
||
DeviceStateRequest request)
|
||
{
|
||
try
|
||
{
|
||
var query = db.Select<DeviceState>()
|
||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode),
|
||
a => a.DeviceCode == request.DeviceCode);
|
||
|
||
if (!string.IsNullOrWhiteSpace(request.StartTime) &&
|
||
DateTime.TryParse(request.StartTime, out var startTime))
|
||
{
|
||
query = query.Where(a => a.CreateTime >= startTime);
|
||
}
|
||
|
||
if (!string.IsNullOrWhiteSpace(request.EndTime) &&
|
||
DateTime.TryParse(request.EndTime, out var endTime))
|
||
{
|
||
query = query.Where(a => a.CreateTime <= endTime);
|
||
}
|
||
|
||
var data = await query
|
||
.OrderByDescending(a => a.CreateTime)
|
||
.FirstAsync(a => new DeviceStateResponse
|
||
{
|
||
DeviceCode = a.DeviceCode,
|
||
DeviceName = a.DeviceName,
|
||
PowerOnTime = a.PowerOnTime,
|
||
RunTime = a.RunTime,
|
||
StandbyTime = a.StandbyTime,
|
||
FaultTime = a.FaultTime,
|
||
ShutdownTime = a.ShutdownTime,
|
||
UseRatio = a.UseRatio,
|
||
FaultNum = a.FaultNum,
|
||
JobNum = a.JobNum,
|
||
CreateTime = a.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||
});
|
||
|
||
return data;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw new Exception($"查询最新设备状态数据失败: {ex.Message}", ex);
|
||
}
|
||
}
|
||
}
|
||
}
|