using MoviconWebApi.Entities;
namespace MoviconWebApi.API.DeviceStateApi
{
public static class Data
{
///
/// 获取设备状态列表
///
public static async Task> 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();
}
if (endTime < startTime)
{
// 纠正时间顺序或直接返回空
return new List();
}
var totalMinutes = (endTime - startTime).TotalMinutes;
if (totalMinutes <= 0)
{
return new List();
}
// 2) 基础查询(按设备、时间过滤)
var baseQuery = db.Select()
.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()
.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();
}
// 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()
.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 { summary };
}
catch (Exception ex)
{
throw new Exception($"查询设备状态数据失败: {ex.Message}", ex);
}
}
///
/// 分页获取设备状态
///
public static async Task<(List, long)> GetDeviceStatePagedAsync(
IFreeSql db,
DeviceStatePagedRequest request)
{
try
{
var query = db.Select()
.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(), total);
}
catch (Exception ex)
{
throw new Exception($"分页查询设备状态数据失败: {ex.Message}", ex);
}
}
///
/// 获取最新的设备状态记录
///
public static async Task GetLatestDeviceStateAsync(
IFreeSql db,
DeviceStateRequest request)
{
try
{
var query = db.Select()
.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);
}
}
}
}