Files
MoviconHub/MoviconWebApi/API/DeviceStateApi/Data.cs
2025-10-30 12:02:12 +08:00

222 lines
9.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}
}