添加项目文件。
This commit is contained in:
83
MoviconWebApi/API/ClearDataApi/Data.cs
Normal file
83
MoviconWebApi/API/ClearDataApi/Data.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using MoviconWebApi.Entities;
|
||||
|
||||
namespace MoviconWebApi.API.ClearDataApi
|
||||
{
|
||||
public static class Data
|
||||
{
|
||||
internal static async Task<List<ClearDataResponse>?> GetClearData(ClearDataRequest request, IFreeSql freeSql)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 构建查询
|
||||
var query = freeSql.Select<ClearData>();
|
||||
|
||||
// 根据设备编号过滤
|
||||
if (!string.IsNullOrWhiteSpace(request.DeviceCode))
|
||||
{
|
||||
query = query.Where(x => x.DeviceCode == request.DeviceCode);
|
||||
}
|
||||
|
||||
// 根据开始时间过滤
|
||||
if (!string.IsNullOrWhiteSpace(request.StartTime) && DateTime.TryParse(request.StartTime, out DateTime startTime))
|
||||
{
|
||||
query = query.Where(x => x.CreateTime >= startTime);
|
||||
}
|
||||
|
||||
// 根据结束时间过滤
|
||||
if (!string.IsNullOrWhiteSpace(request.EndTime) && DateTime.TryParse(request.EndTime, out DateTime endTime))
|
||||
{
|
||||
query = query.Where(x => x.CreateTime <= endTime);
|
||||
}
|
||||
|
||||
// 按创建时间降序排序
|
||||
query = query.OrderByDescending(x => x.CreateTime);
|
||||
|
||||
// 执行查询并映射到响应模型
|
||||
var result = await query.ToListAsync(x => new ClearDataResponse
|
||||
{
|
||||
DeviceCode = x.DeviceCode,
|
||||
DeviceName = x.DeviceName,
|
||||
program_process = x.program_process,
|
||||
vehicle_model = x.vehicle_model,
|
||||
locomotive_number = x.locomotive_number,
|
||||
repair_process = x.repair_process,
|
||||
component_name = x.component_name,
|
||||
part_position = x.part_position,
|
||||
part_num = x.part_num,
|
||||
part_qrid = x.part_qrid,
|
||||
AgentTank_Level = x.AgentTank_Level,
|
||||
Test_CleaningAgentTankAdd=x.Test_CleaningAgentTankAdd,
|
||||
Test_CleaningAgentTankHeat=x.Test_CleaningAgentTankHeat,
|
||||
Test_FrameworkPerModelCleaningAgentUsage = x.Test_FrameworkPerModelCleaningAgentUsage,
|
||||
Test_FrameworkPerModelWaterUsage = x.Test_FrameworkPerModelWaterUsage,
|
||||
WaterTank_Temp = x.WaterTank_Temp,
|
||||
AgentTank_Temp = x.AgentTank_Temp,
|
||||
SoakingTank1_Temp = x.SoakingTank1_Temp,
|
||||
SoakingTank2_Temp = x.SoakingTank2_Temp,
|
||||
Test_ElectricSurveillance=x.Test_ElectricSurveillance,
|
||||
Test_FrameworkPerModelCleaningDuration=x.Test_FrameworkPerModelCleaningDuration,
|
||||
Test_FrameworkProgramProcess=x.Test_FrameworkProgramProcess,
|
||||
Test_FrameworkProgramProcessPercentage=x.Test_FrameworkProgramProcessPercentage,
|
||||
Test_SteamSurveillance= x.Test_SteamSurveillance,
|
||||
Test_WaterTankAdd= x.Test_WaterTankAdd,
|
||||
Test_WaterTankHeat= x.Test_WaterTankHeat,
|
||||
WaterTank_Level=x.WaterTank_Level,
|
||||
|
||||
CreateTime = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录异常日志(可以根据实际需求添加日志记录)
|
||||
Console.WriteLine($"获取清洗数据失败:{ex.Message}");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
100
MoviconWebApi/API/ClearDataApi/Endpoint.cs
Normal file
100
MoviconWebApi/API/ClearDataApi/Endpoint.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using Azure;
|
||||
using Azure.Core;
|
||||
using FastEndpoints;
|
||||
using MoviconWebApi.API.ClearDataQrApi;
|
||||
using MoviconWebApi.Common;
|
||||
|
||||
namespace MoviconWebApi.API.ClearDataApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取清洗数据端点
|
||||
/// </summary>
|
||||
public class Endpoint : Endpoint<ClearDataRequest, ApiResponse<List<ClearDataResponse>>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,注入FreeSql实例
|
||||
/// </summary>
|
||||
/// <param name="freeSql">FreeSql实例</param>
|
||||
public Endpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
// 配置路由,支持GET和POST两种方式
|
||||
//Post("/cleardata/list");
|
||||
Get("/cleardata/listbycode");
|
||||
|
||||
// 允许匿名访问(根据实际需求可以改为需要认证)
|
||||
AllowAnonymous();
|
||||
|
||||
// 配置摘要信息(用于Swagger文档)
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取清洗数据列表";
|
||||
s.Description = "根据设备编号、开始时间、结束时间查询清洗数据";
|
||||
s.Response< ApiResponse<List<ClearDataResponse>>>(200, "成功返回清洗数据列表");
|
||||
s.Response(404, "未找到数据");
|
||||
s.Response(500, "服务器内部错误");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(ClearDataRequest request, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用Data层方法获取数据
|
||||
var dataList = await Data.GetClearData(request, _freeSql);
|
||||
|
||||
if (dataList == null || dataList.Count == 0)
|
||||
{
|
||||
// 未找到数据,返回404
|
||||
//await Send.NotFoundAsync(ct);
|
||||
//Response = dataList ?? new List<ClearDataQrResponse>();
|
||||
|
||||
//await Send.OkAsync(new List<ClearDataResponse>(), ct);
|
||||
|
||||
// 没有数据
|
||||
Response = ApiResponse<List<ClearDataResponse>>.Success(
|
||||
new List<ClearDataResponse>(),
|
||||
"暂无数据"
|
||||
);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//await Send.OkAsync(dataList, ct);
|
||||
|
||||
// 现在的代码
|
||||
Response = ApiResponse<List<ClearDataResponse>>.Success(
|
||||
dataList,
|
||||
"查询成功"
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录错误日志
|
||||
Logger.LogError(ex, "获取清洗数据失败");
|
||||
|
||||
// 返回错误响应
|
||||
Response = ApiResponse<List<ClearDataResponse>>.Error(
|
||||
"500",
|
||||
"服务器内部错误"
|
||||
);
|
||||
|
||||
//// 记录错误日志
|
||||
//Logger.LogError(ex, "获取清洗数据失败");
|
||||
|
||||
//// 返回500错误
|
||||
//await Send.ErrorsAsync(500, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
33
MoviconWebApi/API/ClearDataApi/Mapper.cs
Normal file
33
MoviconWebApi/API/ClearDataApi/Mapper.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Azure.Core;
|
||||
using FastEndpoints;
|
||||
using MoviconWebApi.Entities;
|
||||
|
||||
namespace MoviconWebApi.API.ClearDataApi
|
||||
{
|
||||
public class Mapper : Mapper<ClearDataRequest, ClearDataResponse, ClearData>
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求体映射为数据库实体
|
||||
/// </summary>
|
||||
/// <param name="r"></param>
|
||||
/// <returns></returns>
|
||||
public override ClearData ToEntity(ClearDataRequest r)
|
||||
{
|
||||
return new ClearData()
|
||||
{
|
||||
AgentTank_Level = "",
|
||||
};
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 数据库实体类映射为返回体,我这里返回体就是一个string,就没必要用
|
||||
///// </summary>
|
||||
///// <param name="e"></param>
|
||||
///// <returns></returns>
|
||||
//public override async Task<ClearDataResponse> FromEntityAsync(ClearData Model )
|
||||
//{
|
||||
// return await base.FromEntityAsync(Model,new CancellationToken());
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
61
MoviconWebApi/API/ClearDataApi/Models.cs
Normal file
61
MoviconWebApi/API/ClearDataApi/Models.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MoviconWebApi.API.ClearDataApi
|
||||
{
|
||||
public class ClearDataRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string? DeviceCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public string? StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public string? EndTime { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class ClearDataResponse
|
||||
{
|
||||
public string? DeviceCode { get; set; }
|
||||
public string? DeviceName { get; set; }
|
||||
public string? program_process { get; set; }
|
||||
public string? vehicle_model { get; set; }
|
||||
public string? locomotive_number { get; set; }
|
||||
public string? repair_process { get; set; }
|
||||
public string? component_name { get; set; }
|
||||
public string? part_position { get; set; }
|
||||
public string? part_num { get; set; }
|
||||
public string? part_qrid { get; set; }
|
||||
public string? Test_FrameworkProgramProcessPercentage { get; set; }
|
||||
public string? Test_FrameworkProgramProcess { get; set; }
|
||||
public string? Test_FrameworkPerModelCleaningDuration { get; set; }
|
||||
public string? Test_FrameworkPerModelCleaningAgentUsage { get; set; }
|
||||
public string? Test_FrameworkPerModelWaterUsage { get; set; }
|
||||
public string? WaterTank_Temp { get; set; }
|
||||
public string? AgentTank_Temp { get; set; }
|
||||
public string? WaterTank_Level { get; set; }
|
||||
public string? AgentTank_Level { get; set; }
|
||||
public string? SoakingTank1_Temp { get; set; }
|
||||
public string? SoakingTank2_Temp { get; set; }
|
||||
public string? Test_WaterTankHeat { get; set; }
|
||||
public string? Test_WaterTankAdd { get; set; }
|
||||
public string? Test_CleaningAgentTankHeat { get; set; }
|
||||
public string? Test_CleaningAgentTankAdd { get; set; }
|
||||
public string? Test_ElectricSurveillance { get; set; }
|
||||
public string? Test_SteamSurveillance { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string? CreateTime { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
293
MoviconWebApi/API/ClearDataQrApi/Data.cs
Normal file
293
MoviconWebApi/API/ClearDataQrApi/Data.cs
Normal file
@@ -0,0 +1,293 @@
|
||||
using MoviconWebApi.Entities;
|
||||
|
||||
namespace MoviconWebApi.API.ClearDataQrApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 清洗数据二维码查询数据访问层
|
||||
/// </summary>
|
||||
public static class Data
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据设备编号和部件二维码查询清洗数据
|
||||
/// </summary>
|
||||
/// <param name="request">查询请求参数</param>
|
||||
/// <param name="freeSql">FreeSql实例</param>
|
||||
/// <returns>清洗数据列表</returns>
|
||||
public static async Task<List<ClearDataQrResponse>> GetClearDataByQr(
|
||||
ClearDataQrRequest request,
|
||||
IFreeSql freeSql)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用FreeSql的Fluent API构建查询
|
||||
var query = freeSql.Select<ClearData>();
|
||||
|
||||
// 添加设备编号条件
|
||||
if (!string.IsNullOrWhiteSpace(request.DeviceCode))
|
||||
{
|
||||
query = query.Where(x => x.DeviceCode == request.DeviceCode);
|
||||
}
|
||||
|
||||
// 添加部件二维码条件
|
||||
if (!string.IsNullOrWhiteSpace(request.PartQRCode))
|
||||
{
|
||||
query = query.Where(x => x.part_qrid == request.PartQRCode);
|
||||
}
|
||||
|
||||
// 按创建时间降序排序
|
||||
query = query.OrderByDescending(x => x.CreateTime);
|
||||
|
||||
// 执行查询并映射到响应模型
|
||||
var result = await query.ToListAsync(x => new ClearDataQrResponse
|
||||
{
|
||||
DeviceCode = x.DeviceCode,
|
||||
DeviceName = x.DeviceName,
|
||||
program_process = x.program_process,
|
||||
vehicle_model = x.vehicle_model,
|
||||
locomotive_number = x.locomotive_number,
|
||||
repair_process = x.repair_process,
|
||||
component_name = x.component_name,
|
||||
part_position = x.part_position,
|
||||
part_num = x.part_num,
|
||||
part_qrid = x.part_qrid,
|
||||
AgentTank_Level = x.AgentTank_Level,
|
||||
Test_CleaningAgentTankAdd = x.Test_CleaningAgentTankAdd,
|
||||
Test_CleaningAgentTankHeat = x.Test_CleaningAgentTankHeat,
|
||||
Test_FrameworkPerModelCleaningAgentUsage = x.Test_FrameworkPerModelCleaningAgentUsage,
|
||||
Test_FrameworkPerModelWaterUsage = x.Test_FrameworkPerModelWaterUsage,
|
||||
WaterTank_Temp = x.WaterTank_Temp,
|
||||
AgentTank_Temp = x.AgentTank_Temp,
|
||||
SoakingTank1_Temp = x.SoakingTank1_Temp,
|
||||
SoakingTank2_Temp = x.SoakingTank2_Temp,
|
||||
Test_ElectricSurveillance = x.Test_ElectricSurveillance,
|
||||
Test_FrameworkPerModelCleaningDuration = x.Test_FrameworkPerModelCleaningDuration,
|
||||
Test_FrameworkProgramProcess = x.Test_FrameworkProgramProcess,
|
||||
Test_FrameworkProgramProcessPercentage = x.Test_FrameworkProgramProcessPercentage,
|
||||
Test_SteamSurveillance = x.Test_SteamSurveillance,
|
||||
Test_WaterTankAdd = x.Test_WaterTankAdd,
|
||||
Test_WaterTankHeat = x.Test_WaterTankHeat,
|
||||
WaterTank_Level = x.WaterTank_Level,
|
||||
|
||||
CreateTime = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录异常(在生产环境中应使用适当的日志框架)
|
||||
Console.WriteLine($"查询清洗数据时出错: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询清洗数据
|
||||
/// </summary>
|
||||
/// <param name="request">分页查询请求参数</param>
|
||||
/// <param name="freeSql">FreeSql实例</param>
|
||||
/// <returns>分页数据和总数</returns>
|
||||
public static async Task<(List<ClearDataQrResponse> Data, long Total)> GetClearDataPagedByQr(
|
||||
ClearDataQrPagedRequest request,
|
||||
IFreeSql freeSql)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用FreeSql的Fluent API构建查询
|
||||
var query = freeSql.Select<ClearData>();
|
||||
|
||||
// 添加设备编号条件
|
||||
if (!string.IsNullOrWhiteSpace(request.DeviceCode))
|
||||
{
|
||||
query = query.Where(x => x.DeviceCode == request.DeviceCode);
|
||||
}
|
||||
|
||||
// 添加部件二维码条件
|
||||
if (!string.IsNullOrWhiteSpace(request.PartQRCode))
|
||||
{
|
||||
query = query.Where(x => x.part_qrid == request.PartQRCode);
|
||||
}
|
||||
|
||||
// 按创建时间降序排序
|
||||
query = query.OrderByDescending(x => x.CreateTime);
|
||||
|
||||
// 获取总数
|
||||
var total = await query.CountAsync();
|
||||
|
||||
// 分页查询并映射到响应模型
|
||||
var data = await query
|
||||
.Page(request.PageIndex, request.PageSize)
|
||||
.ToListAsync(x => new ClearDataQrResponse
|
||||
{
|
||||
DeviceCode = x.DeviceCode,
|
||||
DeviceName = x.DeviceName,
|
||||
program_process = x.program_process,
|
||||
vehicle_model = x.vehicle_model,
|
||||
locomotive_number = x.locomotive_number,
|
||||
repair_process = x.repair_process,
|
||||
component_name = x.component_name,
|
||||
part_position = x.part_position,
|
||||
part_num = x.part_num,
|
||||
part_qrid = x.part_qrid,
|
||||
AgentTank_Level = x.AgentTank_Level,
|
||||
Test_CleaningAgentTankAdd = x.Test_CleaningAgentTankAdd,
|
||||
Test_CleaningAgentTankHeat = x.Test_CleaningAgentTankHeat,
|
||||
Test_FrameworkPerModelCleaningAgentUsage = x.Test_FrameworkPerModelCleaningAgentUsage,
|
||||
Test_FrameworkPerModelWaterUsage = x.Test_FrameworkPerModelWaterUsage,
|
||||
WaterTank_Temp = x.WaterTank_Temp,
|
||||
AgentTank_Temp = x.AgentTank_Temp,
|
||||
SoakingTank1_Temp = x.SoakingTank1_Temp,
|
||||
SoakingTank2_Temp = x.SoakingTank2_Temp,
|
||||
Test_ElectricSurveillance = x.Test_ElectricSurveillance,
|
||||
Test_FrameworkPerModelCleaningDuration = x.Test_FrameworkPerModelCleaningDuration,
|
||||
Test_FrameworkProgramProcess = x.Test_FrameworkProgramProcess,
|
||||
Test_FrameworkProgramProcessPercentage = x.Test_FrameworkProgramProcessPercentage,
|
||||
Test_SteamSurveillance = x.Test_SteamSurveillance,
|
||||
Test_WaterTankAdd = x.Test_WaterTankAdd,
|
||||
Test_WaterTankHeat = x.Test_WaterTankHeat,
|
||||
WaterTank_Level = x.WaterTank_Level,
|
||||
CreateTime = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return (data, total);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录异常(在生产环境中应使用适当的日志框架)
|
||||
Console.WriteLine($"分页查询清洗数据时出错: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最新的清洗数据记录
|
||||
/// </summary>
|
||||
/// <param name="request">查询请求(可包含设备编号筛选)</param>
|
||||
/// <param name="freeSql">FreeSql实例</param>
|
||||
/// <returns>最新的清洗数据记录,如果没有则返回null</returns>
|
||||
public static async Task<ClearDataQrResponse?> GetLatestClearData(
|
||||
ClearDataQrRequest request,
|
||||
IFreeSql freeSql)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用FreeSql的Fluent API构建查询
|
||||
var query = freeSql.Select<ClearData>();
|
||||
|
||||
// 添加设备编号条件(如果提供)
|
||||
if (!string.IsNullOrWhiteSpace(request.DeviceCode))
|
||||
{
|
||||
query = query.Where(x => x.DeviceCode == request.DeviceCode);
|
||||
}
|
||||
|
||||
// 添加部件二维码条件(如果提供)
|
||||
if (!string.IsNullOrWhiteSpace(request.PartQRCode))
|
||||
{
|
||||
query = query.Where(x => x.part_qrid == request.PartQRCode);
|
||||
}
|
||||
|
||||
// 按创建时间降序排序,取第一条
|
||||
var result = await query
|
||||
.OrderByDescending(x => x.CreateTime)
|
||||
.Limit(1)
|
||||
.FirstAsync(x => new ClearDataQrResponse
|
||||
{
|
||||
DeviceCode = x.DeviceCode,
|
||||
DeviceName = x.DeviceName,
|
||||
program_process = x.program_process,
|
||||
vehicle_model = x.vehicle_model,
|
||||
locomotive_number = x.locomotive_number,
|
||||
repair_process = x.repair_process,
|
||||
component_name = x.component_name,
|
||||
part_position = x.part_position,
|
||||
part_num = x.part_num,
|
||||
part_qrid = x.part_qrid,
|
||||
AgentTank_Level = x.AgentTank_Level,
|
||||
Test_CleaningAgentTankAdd = x.Test_CleaningAgentTankAdd,
|
||||
Test_CleaningAgentTankHeat = x.Test_CleaningAgentTankHeat,
|
||||
Test_FrameworkPerModelCleaningAgentUsage = x.Test_FrameworkPerModelCleaningAgentUsage,
|
||||
Test_FrameworkPerModelWaterUsage = x.Test_FrameworkPerModelWaterUsage,
|
||||
WaterTank_Temp = x.WaterTank_Temp,
|
||||
AgentTank_Temp = x.AgentTank_Temp,
|
||||
SoakingTank1_Temp = x.SoakingTank1_Temp,
|
||||
SoakingTank2_Temp = x.SoakingTank2_Temp,
|
||||
Test_ElectricSurveillance = x.Test_ElectricSurveillance,
|
||||
Test_FrameworkPerModelCleaningDuration = x.Test_FrameworkPerModelCleaningDuration,
|
||||
Test_FrameworkProgramProcess = x.Test_FrameworkProgramProcess,
|
||||
Test_FrameworkProgramProcessPercentage = x.Test_FrameworkProgramProcessPercentage,
|
||||
Test_SteamSurveillance = x.Test_SteamSurveillance,
|
||||
Test_WaterTankAdd = x.Test_WaterTankAdd,
|
||||
Test_WaterTankHeat = x.Test_WaterTankHeat,
|
||||
WaterTank_Level = x.WaterTank_Level,
|
||||
CreateTime = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录异常(在生产环境中应使用适当的日志框架)
|
||||
Console.WriteLine($"获取最新清洗数据时出错: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据部件二维码获取所有相关的清洗记录
|
||||
/// </summary>
|
||||
/// <param name="partQRCode">部件二维码</param>
|
||||
/// <param name="freeSql">FreeSql实例</param>
|
||||
/// <returns>清洗数据列表</returns>
|
||||
public static async Task<List<ClearDataQrResponse>> GetClearDataByPartQRCode(
|
||||
string partQRCode,
|
||||
IFreeSql freeSql)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用FreeSql的Fluent API构建查询
|
||||
var result = await freeSql.Select<ClearData>()
|
||||
.Where(x => x.part_qrid == partQRCode)
|
||||
.OrderByDescending(x => x.CreateTime)
|
||||
.ToListAsync(x => new ClearDataQrResponse
|
||||
{
|
||||
DeviceCode = x.DeviceCode,
|
||||
DeviceName = x.DeviceName,
|
||||
program_process = x.program_process,
|
||||
vehicle_model = x.vehicle_model,
|
||||
locomotive_number = x.locomotive_number,
|
||||
repair_process = x.repair_process,
|
||||
component_name = x.component_name,
|
||||
part_position = x.part_position,
|
||||
part_num = x.part_num,
|
||||
part_qrid = x.part_qrid,
|
||||
AgentTank_Level = x.AgentTank_Level,
|
||||
Test_CleaningAgentTankAdd = x.Test_CleaningAgentTankAdd,
|
||||
Test_CleaningAgentTankHeat = x.Test_CleaningAgentTankHeat,
|
||||
Test_FrameworkPerModelCleaningAgentUsage = x.Test_FrameworkPerModelCleaningAgentUsage,
|
||||
Test_FrameworkPerModelWaterUsage = x.Test_FrameworkPerModelWaterUsage,
|
||||
WaterTank_Temp = x.WaterTank_Temp,
|
||||
AgentTank_Temp = x.AgentTank_Temp,
|
||||
SoakingTank1_Temp = x.SoakingTank1_Temp,
|
||||
SoakingTank2_Temp = x.SoakingTank2_Temp,
|
||||
Test_ElectricSurveillance = x.Test_ElectricSurveillance,
|
||||
Test_FrameworkPerModelCleaningDuration = x.Test_FrameworkPerModelCleaningDuration,
|
||||
Test_FrameworkProgramProcess = x.Test_FrameworkProgramProcess,
|
||||
Test_FrameworkProgramProcessPercentage = x.Test_FrameworkProgramProcessPercentage,
|
||||
Test_SteamSurveillance = x.Test_SteamSurveillance,
|
||||
Test_WaterTankAdd = x.Test_WaterTankAdd,
|
||||
Test_WaterTankHeat = x.Test_WaterTankHeat,
|
||||
WaterTank_Level = x.WaterTank_Level,
|
||||
CreateTime = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录异常(在生产环境中应使用适当的日志框架)
|
||||
Console.WriteLine($"根据二维码查询清洗数据时出错: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
257
MoviconWebApi/API/ClearDataQrApi/Endpoint.cs
Normal file
257
MoviconWebApi/API/ClearDataQrApi/Endpoint.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using Azure;
|
||||
using FastEndpoints;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MoviconWebApi.Common;
|
||||
|
||||
namespace MoviconWebApi.API.ClearDataQrApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据设备编号和部件二维码查询清洗数据端点
|
||||
/// </summary>
|
||||
public class GetByQrEndpoint : Endpoint<ClearDataQrRequest, ApiResponse<List<ClearDataQrResponse>>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetByQrEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/cleardata-qr/list");
|
||||
AllowAnonymous();
|
||||
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "根据设备编号和部件二维码查询清洗数据";
|
||||
s.Description = "可以通过设备编号、部件二维码或两者组合查询清洗数据";
|
||||
s.Response<ApiResponse<List<ClearDataQrResponse>>>(200, "成功返回清洗数据列表");
|
||||
s.Response(404, "未找到数据");
|
||||
s.Response(500, "服务器内部错误");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(ClearDataQrRequest request, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dataList = await Data.GetClearDataByQr(request, _freeSql);
|
||||
|
||||
if (dataList == null || dataList.Count == 0)
|
||||
{
|
||||
Response = ApiResponse<List<ClearDataQrResponse>>.Success(
|
||||
new List<ClearDataQrResponse>(), "暂无数据");// "暂无数据"
|
||||
}
|
||||
else
|
||||
{
|
||||
Response = ApiResponse<List<ClearDataQrResponse>>.Success(
|
||||
dataList, "查询成功");// "查询成功"
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Logger.LogError(ex, "根据二维码查询清洗数据失败");
|
||||
//await Send.ErrorsAsync(500, ct);
|
||||
|
||||
Logger.LogError(ex, "根据二维码查询清洗数据失败");
|
||||
Response = ApiResponse<List<ClearDataQrResponse>>.Error(
|
||||
"500",
|
||||
"服务器内部错误"
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询清洗数据端点
|
||||
/// </summary>
|
||||
public class GetPagedByQrEndpoint : Endpoint<ClearDataQrPagedRequest, ClearDataQrPagedResponse>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetPagedByQrEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Post("/cleardata-qr/paged");
|
||||
AllowAnonymous();
|
||||
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "分页查询清洗数据";
|
||||
s.Description = "根据设备编号和部件二维码分页查询清洗数据";
|
||||
s.Response<ClearDataQrPagedResponse>(200, "成功返回分页数据");
|
||||
s.Response(500, "服务器内部错误");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(ClearDataQrPagedRequest request, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 验证分页参数
|
||||
if (request.PageIndex < 1)
|
||||
request.PageIndex = 1;
|
||||
if (request.PageSize < 1)
|
||||
request.PageSize = 20;
|
||||
if (request.PageSize > 100)
|
||||
request.PageSize = 100;
|
||||
|
||||
// 调用Data层方法,获取元组返回值
|
||||
var (data, total) = await Data.GetClearDataPagedByQr(request, _freeSql);
|
||||
|
||||
// 构建响应对象
|
||||
Response = new ClearDataQrPagedResponse
|
||||
{
|
||||
Items = data,
|
||||
TotalCount = total,
|
||||
PageIndex = request.PageIndex,
|
||||
PageSize = request.PageSize
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "分页查询清洗数据失败");
|
||||
await Send.ErrorsAsync(500, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最新清洗数据端点
|
||||
/// </summary>
|
||||
public class GetLatestByQrEndpoint : Endpoint<ClearDataQrRequest, ClearDataQrResponse>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetLatestByQrEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/cleardata-qr/latest");
|
||||
AllowAnonymous();
|
||||
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取最新的清洗数据";
|
||||
s.Description = "根据设备编号和部件二维码获取最新的一条清洗数据";
|
||||
s.Response<ClearDataQrResponse>(200, "成功返回最新清洗数据");
|
||||
s.Response(404, "未找到数据");
|
||||
s.Response(500, "服务器内部错误");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(ClearDataQrRequest request, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用重构后的方法,直接传递request对象
|
||||
var latestData = await Data.GetLatestClearData(request, _freeSql);
|
||||
|
||||
if (latestData == null)
|
||||
{
|
||||
//await Send.NotFoundAsync(ct);
|
||||
Response = latestData ?? new ClearDataQrResponse();
|
||||
}
|
||||
else
|
||||
{
|
||||
Response = latestData;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "获取最新清洗数据失败");
|
||||
await Send.ErrorsAsync(500, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据部件二维码获取所有清洗记录端点
|
||||
/// </summary>
|
||||
public class GetByPartQrCodeRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 部件二维码(必填)
|
||||
/// </summary>
|
||||
public string PartQRCode { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class GetByPartQrCodeEndpoint : Endpoint<GetByPartQrCodeRequest, List<ClearDataQrResponse>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetByPartQrCodeEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/cleardata-qr/by-qrcode/{PartQRCode}");
|
||||
AllowAnonymous();
|
||||
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "根据部件二维码获取所有清洗记录";
|
||||
s.Description = "仅根据部件二维码查询该部件的所有清洗历史记录";
|
||||
s.Response<List<ClearDataQrResponse>>(200, "成功返回清洗数据列表");
|
||||
s.Response(400, "请求参数错误");
|
||||
s.Response(404, "未找到数据");
|
||||
s.Response(500, "服务器内部错误");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(GetByPartQrCodeRequest request, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 验证参数
|
||||
if (string.IsNullOrWhiteSpace(request.PartQRCode))
|
||||
{
|
||||
AddError("PartQRCode", "部件二维码不能为空");
|
||||
await Send.ErrorsAsync(400, ct);
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用重构后的方法
|
||||
var dataList = await Data.GetClearDataByPartQRCode(request.PartQRCode, _freeSql);
|
||||
|
||||
if (dataList == null || dataList.Count == 0)
|
||||
{
|
||||
//await Send.NotFoundAsync(ct);
|
||||
Response = dataList ?? new List<ClearDataQrResponse>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Response = dataList;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "根据部件二维码查询清洗数据失败");
|
||||
await Send.ErrorsAsync(500, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
99
MoviconWebApi/API/ClearDataQrApi/Mapper.cs
Normal file
99
MoviconWebApi/API/ClearDataQrApi/Mapper.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
namespace MoviconWebApi.API.ClearDataQrApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据映射器
|
||||
/// </summary>
|
||||
public static class Mapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 将数据库实体映射到响应模型
|
||||
/// </summary>
|
||||
/// <param name="entity">数据库实体</param>
|
||||
/// <returns>响应模型</returns>
|
||||
public static ClearDataQrResponse ToResponse(dynamic entity)
|
||||
{
|
||||
if (entity == null) return null;
|
||||
|
||||
var response = new ClearDataQrResponse
|
||||
{
|
||||
DeviceCode = entity.DeviceCode?.ToString(),
|
||||
DeviceName = entity.DeviceName?.ToString(),
|
||||
program_process = entity.program_process?.ToString(),
|
||||
vehicle_model = entity.vehicle_model?.ToString(),
|
||||
locomotive_number = entity.locomotive_number?.ToString(),
|
||||
repair_process = entity.repair_process?.ToString(),
|
||||
component_name = entity.component_name?.ToString(),
|
||||
part_position = entity.part_position?.ToString(),
|
||||
part_num = entity.part_num?.ToString(),
|
||||
part_qrid = entity.part_qrid?.ToString(),
|
||||
Test_FrameworkPerModelCleaningDuration = entity.Test_FrameworkPerModelCleaningDuration?.ToString(),
|
||||
Test_FrameworkPerModelCleaningAgentUsage = entity.Test_FrameworkPerModelCleaningAgentUsage?.ToString(),
|
||||
Test_FrameworkPerModelWaterUsage = entity.Test_FrameworkPerModelWaterUsage?.ToString(),
|
||||
WaterTank_Temp = entity.WaterTank_Temp?.ToString(),
|
||||
AgentTank_Temp = entity.AgentTank_Temp?.ToString(),
|
||||
SoakingTank1_Temp = entity.SoakingTank1_Temp?.ToString(),
|
||||
SoakingTank2_Temp = entity.SoakingTank2_Temp?.ToString()
|
||||
};
|
||||
|
||||
// 处理时间字段
|
||||
if (entity.CreateTime != null)
|
||||
{
|
||||
if (entity.CreateTime is DateTime dt)
|
||||
{
|
||||
response.CreateTime = dt.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
else
|
||||
{
|
||||
response.CreateTime = entity.CreateTime.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化日期时间
|
||||
/// </summary>
|
||||
/// <param name="dateTimeString">日期时间字符串</param>
|
||||
/// <returns>格式化后的字符串</returns>
|
||||
public static string FormatDateTime(string dateTimeString)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(dateTimeString))
|
||||
return dateTimeString;
|
||||
|
||||
if (DateTime.TryParse(dateTimeString, out DateTime dateTime))
|
||||
{
|
||||
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
return dateTimeString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析数值类型
|
||||
/// </summary>
|
||||
/// <param name="value">原始值</param>
|
||||
/// <returns>数值或null</returns>
|
||||
public static double? ParseDouble(object value)
|
||||
{
|
||||
if (value == null) return null;
|
||||
|
||||
if (value is double d)
|
||||
return d;
|
||||
|
||||
if (value is float f)
|
||||
return f;
|
||||
|
||||
if (value is decimal dec)
|
||||
return (double)dec;
|
||||
|
||||
if (value is int i)
|
||||
return i;
|
||||
|
||||
if (double.TryParse(value.ToString(), out double result))
|
||||
return result;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
109
MoviconWebApi/API/ClearDataQrApi/Models.cs
Normal file
109
MoviconWebApi/API/ClearDataQrApi/Models.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
namespace MoviconWebApi.API.ClearDataQrApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 清洗数据二维码查询请求模型
|
||||
/// </summary>
|
||||
public class ClearDataQrRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string? DeviceCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部件二维码
|
||||
/// </summary>
|
||||
public string? PartQRCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清洗数据响应模型
|
||||
/// </summary>
|
||||
public class ClearDataQrResponse
|
||||
{
|
||||
public string? DeviceCode { get; set; }
|
||||
public string? DeviceName { get; set; }
|
||||
public string? program_process { get; set; }
|
||||
public string? vehicle_model { get; set; }
|
||||
public string? locomotive_number { get; set; }
|
||||
public string? repair_process { get; set; }
|
||||
public string? component_name { get; set; }
|
||||
public string? part_position { get; set; }
|
||||
public string? part_num { get; set; }
|
||||
public string? part_qrid { get; set; }
|
||||
public string? Test_FrameworkProgramProcessPercentage { get; set; }
|
||||
public string? Test_FrameworkProgramProcess { get; set; }
|
||||
public string? Test_FrameworkPerModelCleaningDuration { get; set; }
|
||||
public string? Test_FrameworkPerModelCleaningAgentUsage { get; set; }
|
||||
public string? Test_FrameworkPerModelWaterUsage { get; set; }
|
||||
public string? WaterTank_Temp { get; set; }
|
||||
public string? AgentTank_Temp { get; set; }
|
||||
public string? WaterTank_Level { get; set; }
|
||||
public string? AgentTank_Level { get; set; }
|
||||
public string? SoakingTank1_Temp { get; set; }
|
||||
public string? SoakingTank2_Temp { get; set; }
|
||||
public string? Test_WaterTankHeat { get; set; }
|
||||
public string? Test_WaterTankAdd { get; set; }
|
||||
public string? Test_CleaningAgentTankHeat { get; set; }
|
||||
public string? Test_CleaningAgentTankAdd { get; set; }
|
||||
public string? Test_ElectricSurveillance { get; set; }
|
||||
public string? Test_SteamSurveillance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public string? CreateTime { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询请求模型
|
||||
/// </summary>
|
||||
public class ClearDataQrPagedRequest : ClearDataQrRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 页码(从1开始)
|
||||
/// </summary>
|
||||
public int PageIndex { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 每页数据量
|
||||
/// </summary>
|
||||
public int PageSize { get; set; } = 20;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 分页响应模型
|
||||
/// </summary>
|
||||
public class ClearDataQrPagedResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据列表
|
||||
/// </summary>
|
||||
public List<ClearDataQrResponse> Items { get; set; } = new List<ClearDataQrResponse>();
|
||||
|
||||
/// <summary>
|
||||
/// 总记录数
|
||||
/// </summary>
|
||||
public long TotalCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前页码
|
||||
/// </summary>
|
||||
public int PageIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 每页数量
|
||||
/// </summary>
|
||||
public int PageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总页数
|
||||
/// </summary>
|
||||
public int TotalPages => PageSize > 0 ? (int)Math.Ceiling((double)TotalCount / PageSize) : 0;
|
||||
}
|
||||
}
|
||||
103
MoviconWebApi/API/ClearStaticApi/Data.cs
Normal file
103
MoviconWebApi/API/ClearStaticApi/Data.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using MoviconWebApi.Entities;
|
||||
|
||||
namespace MoviconWebApi.API.ClearStaticApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 清洗统计数据访问类
|
||||
/// </summary>
|
||||
public static class Data
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取清洗统计数据
|
||||
/// </summary>
|
||||
/// <param name="request">请求参数</param>
|
||||
/// <param name="freeSql">FreeSql实例</param>
|
||||
/// <returns>清洗统计响应</returns>
|
||||
internal static async Task<ClearStaticResponse?> GetClearStatic(ClearStaticRequest request, IFreeSql freeSql)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 获取当前日期信息
|
||||
var today = DateTime.Today;
|
||||
var firstDayOfMonth = new DateTime(today.Year, today.Month, 1);
|
||||
var firstDayOfYear = new DateTime(today.Year, 1, 1);
|
||||
|
||||
// 构建基础查询
|
||||
var query = freeSql.Select<DeviceState>();
|
||||
// 构建基础查询
|
||||
//var queryDeviceState = freeSql.Select<DeviceState>();
|
||||
|
||||
var CurRunClearData = freeSql.Select<CurRunClearState>().Where(a => a.Test_PartsEquipmentStatus == "1").OrderByDescending(a => a.CreateTime).First();
|
||||
|
||||
// 根据设备编号过滤
|
||||
if (!string.IsNullOrWhiteSpace(request.DeviceCode))
|
||||
{
|
||||
query = query.Where(x => x.DeviceCode == request.DeviceCode);
|
||||
}
|
||||
|
||||
// 计算累计作业数量
|
||||
var totalJobCount = await query.CountAsync();
|
||||
|
||||
// 计算本年度作业数
|
||||
var yearJobCount = await query
|
||||
.Where(x => x.CreateTime >= firstDayOfYear)
|
||||
.CountAsync();
|
||||
|
||||
// 计算本月作业数
|
||||
var monthJobCount = await query
|
||||
.Where(x => x.CreateTime >= firstDayOfMonth)
|
||||
.CountAsync();
|
||||
|
||||
// 计算今日作业数
|
||||
var todayJobCount = await query
|
||||
.Where(x => x.CreateTime >= today)
|
||||
.CountAsync();
|
||||
|
||||
// 计算累计作业时长
|
||||
// 注意:这里假设ClearData表中有一个字段表示清洗时长,可能需要根据实际情况调整
|
||||
var totalJobHours = await query
|
||||
.SumAsync(x => Convert.ToDecimal(x.RunTime)) / 60; // 假设时长单位是秒,转换为小时
|
||||
|
||||
// 计算本年作业时长
|
||||
var yearJobHours = await query
|
||||
.Where(x => x.CreateTime >= firstDayOfYear)
|
||||
.SumAsync(x => Convert.ToDecimal(x.RunTime)) / 60;
|
||||
|
||||
// 计算本月作业时长
|
||||
var monthJobHours = await query
|
||||
.Where(x => x.CreateTime >= firstDayOfMonth)
|
||||
.SumAsync(x => Convert.ToDecimal(x.RunTime)) / 60;
|
||||
|
||||
// 计算今日作业时长
|
||||
var todayJobHours = await query
|
||||
.Where(x => x.CreateTime >= today)
|
||||
.SumAsync(x => Convert.ToDecimal(x.RunTime)) / 60;
|
||||
|
||||
// 返回结果
|
||||
return new ClearStaticResponse
|
||||
{
|
||||
TotalJobCount = (int)totalJobCount,
|
||||
YearJobCount = (int)yearJobCount,
|
||||
MonthJobCount = (int)monthJobCount,
|
||||
TodayJobCount = (int)todayJobCount,
|
||||
TotalJobHours = Math.Round(totalJobHours, 2),
|
||||
YearJobHours = Math.Round(yearJobHours, 2),
|
||||
MonthJobHours = Math.Round(monthJobHours, 2),
|
||||
TodayJobHours = Math.Round(todayJobHours, 2),
|
||||
CurrentVehicleModel = CurRunClearData != null ? CurRunClearData.vehicle_model : "",
|
||||
CurrentLocomotiveNumber = CurRunClearData != null ? CurRunClearData.locomotive_number : "",
|
||||
CurrentRepairProcess = CurRunClearData != null ? CurRunClearData.repair_process : "",
|
||||
CurrentWheelNumber = "", // 假设part_num字段存储车轮编号
|
||||
|
||||
UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录异常日志
|
||||
Console.WriteLine($"获取清洗统计数据失败:{ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
80
MoviconWebApi/API/ClearStaticApi/Endpoint.cs
Normal file
80
MoviconWebApi/API/ClearStaticApi/Endpoint.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using Azure;
|
||||
using FastEndpoints;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MoviconWebApi.Common;
|
||||
|
||||
namespace MoviconWebApi.API.ClearStaticApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取清洗统计数据端点
|
||||
/// </summary>
|
||||
public class Endpoint : Endpoint<ClearStaticRequest, ApiResponse<ClearStaticResponse>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,注入FreeSql实例
|
||||
/// </summary>
|
||||
/// <param name="freeSql">FreeSql实例</param>
|
||||
public Endpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
// 配置路由,支持GET方式
|
||||
Get("/clearstatic/summary");
|
||||
|
||||
// 允许匿名访问(根据实际需求可以改为需要认证)
|
||||
AllowAnonymous();
|
||||
|
||||
// 配置摘要信息(用于Swagger文档)
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取清洗统计数据";
|
||||
s.Description = "根据设备编号获取清洗统计数据,包括作业数量、作业时长等";
|
||||
s.Response<ApiResponse<ClearStaticResponse>>(200, "成功返回清洗统计数据");
|
||||
s.Response(404, "未找到数据");
|
||||
s.Response(500, "服务器内部错误");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(ClearStaticRequest request, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 调用Data层方法获取数据
|
||||
var staticData = await Data.GetClearStatic(request, _freeSql);
|
||||
|
||||
if (staticData == null)
|
||||
{
|
||||
// 未找到数据,返回空数据但状态码200
|
||||
Response = ApiResponse<ClearStaticResponse>.Success(
|
||||
new ClearStaticResponse(),
|
||||
"暂无数据"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 返回统计数据
|
||||
Response = ApiResponse<ClearStaticResponse>.Success(
|
||||
staticData,
|
||||
"查询成功"
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录错误日志
|
||||
Logger.LogError(ex, "获取清洗统计数据失败");
|
||||
|
||||
// 返回错误响应
|
||||
Response = ApiResponse<ClearStaticResponse>.Error(
|
||||
"500",
|
||||
"服务器内部错误"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
28
MoviconWebApi/API/ClearStaticApi/Mapper.cs
Normal file
28
MoviconWebApi/API/ClearStaticApi/Mapper.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
namespace MoviconWebApi.API.ClearStaticApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 清洗统计数据映射工具类
|
||||
/// </summary>
|
||||
public static class Mapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化小数为两位小数的字符串
|
||||
/// </summary>
|
||||
/// <param name="value">原始值</param>
|
||||
/// <returns>格式化后的字符串</returns>
|
||||
public static string FormatDecimal(decimal value)
|
||||
{
|
||||
return value.ToString("0.00");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化日期时间为yyyy-MM-dd HH:mm:ss格式
|
||||
/// </summary>
|
||||
/// <param name="dateTime">日期时间</param>
|
||||
/// <returns>格式化后的字符串</returns>
|
||||
public static string FormatDateTime(DateTime dateTime)
|
||||
{
|
||||
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
}
|
||||
}
|
||||
84
MoviconWebApi/API/ClearStaticApi/Models.cs
Normal file
84
MoviconWebApi/API/ClearStaticApi/Models.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
namespace MoviconWebApi.API.ClearStaticApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 清洗统计请求模型
|
||||
/// </summary>
|
||||
public class ClearStaticRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string? DeviceCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清洗统计响应模型
|
||||
/// </summary>
|
||||
public class ClearStaticResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 累计作业数量
|
||||
/// </summary>
|
||||
public int TotalJobCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 本年度作业数
|
||||
/// </summary>
|
||||
public int YearJobCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 本月作业数
|
||||
/// </summary>
|
||||
public int MonthJobCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 今日作业数
|
||||
/// </summary>
|
||||
public int TodayJobCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计作业时长(时)
|
||||
/// </summary>
|
||||
public decimal TotalJobHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 本年作业时长(时)
|
||||
/// </summary>
|
||||
public decimal YearJobHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 本月作业时长(时)
|
||||
/// </summary>
|
||||
public decimal MonthJobHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 今日作业时长(时)
|
||||
/// </summary>
|
||||
public decimal TodayJobHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前机型
|
||||
/// </summary>
|
||||
public string? CurrentVehicleModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前车号
|
||||
/// </summary>
|
||||
public string? CurrentLocomotiveNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前修程
|
||||
/// </summary>
|
||||
public string? CurrentRepairProcess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 车轮编号
|
||||
/// </summary>
|
||||
public string? CurrentWheelNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public string? UpdateTime { get; set; }
|
||||
}
|
||||
}
|
||||
171
MoviconWebApi/API/DeviceAlarmApi/Data.cs
Normal file
171
MoviconWebApi/API/DeviceAlarmApi/Data.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using MoviconWebApi.Entities;
|
||||
|
||||
namespace MoviconWebApi.API.DeviceAlarmApi
|
||||
{
|
||||
public static class DeviceAlarmData
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取设备报警列表
|
||||
/// </summary>
|
||||
public static async Task<List<DeviceAlarmResponse>> GetDeviceAlarmList(
|
||||
IFreeSql freeSql,
|
||||
DeviceAlarmRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = freeSql.Select<DeviceAlarm>()
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode),
|
||||
a => a.DeviceCode == request.DeviceCode)
|
||||
.WhereIf(request.DeviceState > 0,
|
||||
a => a.DeviceState == request.DeviceState);
|
||||
|
||||
// 处理时间范围查询
|
||||
if (!string.IsNullOrWhiteSpace(request.StartTime) && DateTime.TryParse(request.StartTime, out var startTime))
|
||||
{
|
||||
query = query.Where(a => a.StartTime >= startTime);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.EndTime) && DateTime.TryParse(request.EndTime, out var endTime))
|
||||
{
|
||||
query = query.Where(a => a.EndTime <= endTime);
|
||||
}
|
||||
|
||||
var data = await query
|
||||
.OrderByDescending(a => a.StartTime)
|
||||
.ToListAsync(a => new DeviceAlarmResponse
|
||||
{
|
||||
DeviceCode = a.DeviceCode,
|
||||
DeviceName = a.DeviceName,
|
||||
DeviceState = a.DeviceState,
|
||||
AlarmMessage = a.AlarmMessage,
|
||||
StartTime = a.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
EndTime = a.EndTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return data ?? new List<DeviceAlarmResponse>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"获取设备报警数据失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备报警分页数据
|
||||
/// </summary>
|
||||
public static async Task<(List<DeviceAlarmResponse> Items, long Total)> GetDeviceAlarmPagedList(
|
||||
IFreeSql freeSql,
|
||||
DeviceAlarmPagedRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = freeSql.Select<DeviceAlarm>()
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode),
|
||||
a => a.DeviceCode == request.DeviceCode)
|
||||
.WhereIf(request.DeviceState > 0,
|
||||
a => a.DeviceState == request.DeviceState);
|
||||
|
||||
// 处理时间范围查询
|
||||
if (!string.IsNullOrWhiteSpace(request.StartTime) && DateTime.TryParse(request.StartTime, out var startTime))
|
||||
{
|
||||
query = query.Where(a => a.StartTime >= startTime);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.EndTime) && DateTime.TryParse(request.EndTime, out var endTime))
|
||||
{
|
||||
query = query.Where(a => a.EndTime <= endTime);
|
||||
}
|
||||
|
||||
var total = await query.CountAsync();
|
||||
|
||||
var data = await query
|
||||
.OrderByDescending(a => a.StartTime)
|
||||
.Page(request.PageNumber, request.PageSize)
|
||||
.ToListAsync(a => new DeviceAlarmResponse
|
||||
{
|
||||
DeviceCode = a.DeviceCode,
|
||||
DeviceName = a.DeviceName,
|
||||
DeviceState = a.DeviceState,
|
||||
AlarmMessage = a.AlarmMessage,
|
||||
StartTime = a.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
EndTime = a.EndTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return (data ?? new List<DeviceAlarmResponse>(), total);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"获取设备报警分页数据失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最新的设备报警记录
|
||||
/// </summary>
|
||||
public static async Task<DeviceAlarmResponse?> GetLatestDeviceAlarm(
|
||||
IFreeSql freeSql,
|
||||
DeviceAlarmRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = freeSql.Select<DeviceAlarm>()
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(request.DeviceCode),
|
||||
a => a.DeviceCode == request.DeviceCode)
|
||||
.WhereIf(request.DeviceState > 0,
|
||||
a => a.DeviceState == request.DeviceState);
|
||||
|
||||
var data = await query
|
||||
.OrderByDescending(a => a.StartTime)
|
||||
.FirstAsync(a => new DeviceAlarmResponse
|
||||
{
|
||||
DeviceCode = a.DeviceCode,
|
||||
DeviceName = a.DeviceName,
|
||||
DeviceState = a.DeviceState,
|
||||
AlarmMessage = a.AlarmMessage,
|
||||
StartTime = a.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
EndTime = a.EndTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"获取最新设备报警数据失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定设备的活动报警(EndTime为最大值表示未结束)
|
||||
/// </summary>
|
||||
public static async Task<List<DeviceAlarmResponse>> GetActiveAlarms(
|
||||
IFreeSql freeSql,
|
||||
string? deviceCode)
|
||||
{
|
||||
try
|
||||
{
|
||||
var query = freeSql.Select<DeviceAlarm>()
|
||||
.WhereIf(!string.IsNullOrWhiteSpace(deviceCode),
|
||||
a => a.DeviceCode == deviceCode)
|
||||
.Where(a => a.EndTime == DateTime.MaxValue || a.EndTime > DateTime.Now);
|
||||
|
||||
var data = await query
|
||||
.OrderByDescending(a => a.StartTime)
|
||||
.ToListAsync(a => new DeviceAlarmResponse
|
||||
{
|
||||
DeviceCode = a.DeviceCode,
|
||||
DeviceName = a.DeviceName,
|
||||
DeviceState = a.DeviceState,
|
||||
AlarmMessage = a.AlarmMessage,
|
||||
StartTime = a.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
EndTime = a.EndTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
});
|
||||
|
||||
return data ?? new List<DeviceAlarmResponse>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"获取活动报警数据失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
174
MoviconWebApi/API/DeviceAlarmApi/Endpoint.cs
Normal file
174
MoviconWebApi/API/DeviceAlarmApi/Endpoint.cs
Normal file
@@ -0,0 +1,174 @@
|
||||
using Azure;
|
||||
using FastEndpoints;
|
||||
using MoviconWebApi.Common;
|
||||
using MoviconWebApi.Entities;
|
||||
using System;
|
||||
|
||||
namespace MoviconWebApi.API.DeviceAlarmApi
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 设备报警列表查询端点
|
||||
/// </summary>
|
||||
public class GetDeviceAlarmListEndpoint : Endpoint<DeviceAlarmRequest, ApiResponse<List<DeviceAlarmResponse>>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetDeviceAlarmListEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/devicealarm/list");
|
||||
AllowAnonymous();
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取设备报警列表";
|
||||
s.Description = "根据设备编号、时间范围和设备状态查询设备报警";
|
||||
s.Response<ApiResponse<List<DeviceAlarmResponse>>>(200, "成功返回设备报警列表");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeviceAlarmRequest req, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await DeviceAlarmData.GetDeviceAlarmList(_freeSql, req);
|
||||
Response = ApiResponse<List<DeviceAlarmResponse>>.Success(data, "success");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response = ApiResponse<List<DeviceAlarmResponse>>.Error("500", $"获取数据失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备报警分页查询端点
|
||||
/// </summary>
|
||||
public class GetDeviceAlarmPagedEndpoint : Endpoint<DeviceAlarmPagedRequest, ApiResponse<DeviceAlarmPagedResponse>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetDeviceAlarmPagedEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Post("/devicealarm/paged");
|
||||
AllowAnonymous();
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "分页获取设备报警";
|
||||
s.Description = "根据设备编号、时间范围和设备状态分页查询设备报警";
|
||||
s.Response<ApiResponse<DeviceAlarmPagedResponse>>(200, "成功返回设备报警分页数据");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeviceAlarmPagedRequest req, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var (items, total) = await DeviceAlarmData.GetDeviceAlarmPagedList(_freeSql, req);
|
||||
var pagedResponse = new DeviceAlarmPagedResponse
|
||||
{
|
||||
Items = items,
|
||||
Total = total
|
||||
};
|
||||
Response = ApiResponse<DeviceAlarmPagedResponse>.Success(pagedResponse, "success");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response = ApiResponse<DeviceAlarmPagedResponse>.Error("500", $"获取数据失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最新设备报警端点
|
||||
/// </summary>
|
||||
public class GetLatestDeviceAlarmEndpoint : Endpoint<DeviceAlarmRequest, ApiResponse<DeviceAlarmResponse>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetLatestDeviceAlarmEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/devicealarm/latest");
|
||||
AllowAnonymous();
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取最新设备报警";
|
||||
s.Description = "根据设备编号获取最新的设备报警记录";
|
||||
s.Response<ApiResponse<DeviceAlarmResponse>>(200, "成功返回最新设备报警");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeviceAlarmRequest req, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await DeviceAlarmData.GetLatestDeviceAlarm(_freeSql, req);
|
||||
if (data == null)
|
||||
{
|
||||
Response = ApiResponse<DeviceAlarmResponse>.Error("404", "未找到设备报警记录");
|
||||
}
|
||||
else
|
||||
{
|
||||
Response = ApiResponse<DeviceAlarmResponse>.Success(data, "success");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response = ApiResponse<DeviceAlarmResponse>.Error("500", $"获取数据失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取活动报警端点
|
||||
/// </summary>
|
||||
public class GetActiveAlarmsEndpoint : Endpoint<DeviceAlarmRequest, ApiResponse<List<DeviceAlarmResponse>>>
|
||||
{
|
||||
private readonly IFreeSql _freeSql;
|
||||
|
||||
public GetActiveAlarmsEndpoint(IFreeSql freeSql)
|
||||
{
|
||||
_freeSql = freeSql;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/devicealarm/active");
|
||||
AllowAnonymous();
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取活动报警";
|
||||
s.Description = "获取指定设备的所有活动(未结束)报警";
|
||||
s.Response<ApiResponse<List<DeviceAlarmResponse>>>(200, "成功返回活动报警列表");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeviceAlarmRequest req, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await DeviceAlarmData.GetActiveAlarms(_freeSql, req.DeviceCode);
|
||||
Response = ApiResponse<List<DeviceAlarmResponse>>.Success(data, "success");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response = ApiResponse<List<DeviceAlarmResponse>>.Error("500", $"获取数据失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
42
MoviconWebApi/API/DeviceAlarmApi/Mapper.cs
Normal file
42
MoviconWebApi/API/DeviceAlarmApi/Mapper.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using MoviconWebApi.Entities;
|
||||
|
||||
namespace MoviconWebApi.API.DeviceAlarmApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备报警数据映射器
|
||||
/// </summary>
|
||||
public static class DeviceAlarmMapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 将实体映射到响应模型
|
||||
/// </summary>
|
||||
public static DeviceAlarmResponse ToResponse(this DeviceAlarm entity)
|
||||
{
|
||||
return new DeviceAlarmResponse
|
||||
{
|
||||
DeviceCode = entity.DeviceCode,
|
||||
DeviceName = entity.DeviceName,
|
||||
DeviceState = entity.DeviceState,
|
||||
AlarmMessage = entity.AlarmMessage,
|
||||
StartTime = entity.StartTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
EndTime = entity.EndTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量映射
|
||||
/// </summary>
|
||||
public static List<DeviceAlarmResponse> ToResponseList(this IEnumerable<DeviceAlarm> entities)
|
||||
{
|
||||
return entities.Select(e => e.ToResponse()).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断报警是否活动
|
||||
/// </summary>
|
||||
public static bool IsActive(this DeviceAlarm entity)
|
||||
{
|
||||
return entity.EndTime == DateTime.MaxValue || entity.EndTime > DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
96
MoviconWebApi/API/DeviceAlarmApi/Models.cs
Normal file
96
MoviconWebApi/API/DeviceAlarmApi/Models.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
namespace MoviconWebApi.API.DeviceAlarmApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备报警查询请求
|
||||
/// </summary>
|
||||
public class DeviceAlarmRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string? DeviceCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public string? StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public string? EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态(0表示返回所有状态记录)
|
||||
/// </summary>
|
||||
public int DeviceState { get; set; } = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备报警分页查询请求
|
||||
/// </summary>
|
||||
public class DeviceAlarmPagedRequest : DeviceAlarmRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 页码
|
||||
/// </summary>
|
||||
public int PageNumber { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 每页大小
|
||||
/// </summary>
|
||||
public int PageSize { get; set; } = 10;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备报警响应
|
||||
/// </summary>
|
||||
public class DeviceAlarmResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string? DeviceCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string? DeviceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态
|
||||
/// </summary>
|
||||
public int? DeviceState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报警信息
|
||||
/// </summary>
|
||||
public string? AlarmMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public string? StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public string? EndTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备报警分页响应
|
||||
/// </summary>
|
||||
public class DeviceAlarmPagedResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据列表
|
||||
/// </summary>
|
||||
public List<DeviceAlarmResponse> Items { get; set; } = new List<DeviceAlarmResponse>();
|
||||
|
||||
/// <summary>
|
||||
/// 总数
|
||||
/// </summary>
|
||||
public long Total { get; set; }
|
||||
}
|
||||
}
|
||||
218
MoviconWebApi/API/DeviceStateApi/Data.cs
Normal file
218
MoviconWebApi/API/DeviceStateApi/Data.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
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,
|
||||
a.JobNum
|
||||
});
|
||||
|
||||
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));
|
||||
long totalJobCount = lightList.Sum(x => (long)(x.JobNum ?? 0));
|
||||
|
||||
// 若该时间段内没有任何记录,返回空集合
|
||||
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 = (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
142
MoviconWebApi/API/DeviceStateApi/Endpoint.cs
Normal file
142
MoviconWebApi/API/DeviceStateApi/Endpoint.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using Azure;
|
||||
using FastEndpoints;
|
||||
using MoviconWebApi.Common;
|
||||
|
||||
namespace MoviconWebApi.API.DeviceStateApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取设备状态列表
|
||||
/// </summary>
|
||||
public class GetListEndpoint : Endpoint<DeviceStateRequest, ApiResponse<List<DeviceStateResponse>>>
|
||||
{
|
||||
private readonly IFreeSql _db;
|
||||
|
||||
public GetListEndpoint(IFreeSql db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/devicestate/list");
|
||||
AllowAnonymous();
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取设备状态列表";
|
||||
s.Description = "根据设备编号和时间范围查询设备状态数据";
|
||||
s.Response<ApiResponse<List<DeviceStateResponse>>>(200, "成功返回设备状态数据列表");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeviceStateRequest req, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await Data.GetDeviceStateListAsync(_db, req);
|
||||
Response = ApiResponse<List<DeviceStateResponse>>.Success(data, "success");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response = ApiResponse<List<DeviceStateResponse>>.Error(
|
||||
"500",
|
||||
$"查询失败: {ex.Message}",
|
||||
new List<DeviceStateResponse>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页获取设备状态
|
||||
/// </summary>
|
||||
public class GetPagedEndpoint : Endpoint<DeviceStatePagedRequest, ApiResponse<DeviceStatePagedResponse>>
|
||||
{
|
||||
private readonly IFreeSql _db;
|
||||
|
||||
public GetPagedEndpoint(IFreeSql db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Post("/devicestate/paged");
|
||||
AllowAnonymous();
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "分页获取设备状态";
|
||||
s.Description = "分页查询设备状态数据,支持设备编号和时间范围筛选";
|
||||
s.Response<ApiResponse<DeviceStatePagedResponse>>(200, "成功返回分页数据");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeviceStatePagedRequest req, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var (items, total) = await Data.GetDeviceStatePagedAsync(_db, req);
|
||||
var pagedResponse = new DeviceStatePagedResponse
|
||||
{
|
||||
Items = items,
|
||||
Total = total
|
||||
};
|
||||
Response = ApiResponse<DeviceStatePagedResponse>.Success(pagedResponse, "success");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response = ApiResponse<DeviceStatePagedResponse>.Error(
|
||||
"500",
|
||||
$"查询失败: {ex.Message}",
|
||||
new DeviceStatePagedResponse());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最新的设备状态记录
|
||||
/// </summary>
|
||||
public class GetLatestEndpoint : Endpoint<DeviceStateRequest, ApiResponse<DeviceStateResponse>>
|
||||
{
|
||||
private readonly IFreeSql _db;
|
||||
|
||||
public GetLatestEndpoint(IFreeSql db)
|
||||
{
|
||||
_db = db;
|
||||
}
|
||||
|
||||
public override void Configure()
|
||||
{
|
||||
Get("/devicestate/latest");
|
||||
AllowAnonymous();
|
||||
Summary(s =>
|
||||
{
|
||||
s.Summary = "获取最新的设备状态记录";
|
||||
s.Description = "获取指定设备的最新状态记录";
|
||||
s.Response<ApiResponse<DeviceStateResponse>>(200, "成功返回最新记录");
|
||||
s.Response<ApiResponse<DeviceStateResponse>>(404, "未找到记录");
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(DeviceStateRequest req, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await Data.GetLatestDeviceStateAsync(_db, req);
|
||||
if (data == null)
|
||||
{
|
||||
Response = ApiResponse<DeviceStateResponse>.Error("404", "未找到数据", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Response = ApiResponse<DeviceStateResponse>.Success(data, "success");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Response = ApiResponse<DeviceStateResponse>.Error(
|
||||
"500",
|
||||
$"查询失败: {ex.Message}",
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
MoviconWebApi/API/DeviceStateApi/Mapper.cs
Normal file
39
MoviconWebApi/API/DeviceStateApi/Mapper.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using MoviconWebApi.Entities;
|
||||
|
||||
namespace MoviconWebApi.API.DeviceStateApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备状态数据映射器
|
||||
/// </summary>
|
||||
public static class Mapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 将实体映射到响应模型
|
||||
/// </summary>
|
||||
public static DeviceStateResponse ToResponse(this DeviceState entity)
|
||||
{
|
||||
return new DeviceStateResponse
|
||||
{
|
||||
DeviceCode = entity.DeviceCode,
|
||||
DeviceName = entity.DeviceName,
|
||||
PowerOnTime = entity.PowerOnTime,
|
||||
RunTime = entity.RunTime,
|
||||
StandbyTime = entity.StandbyTime,
|
||||
FaultTime = entity.FaultTime,
|
||||
ShutdownTime = entity.ShutdownTime,
|
||||
UseRatio = entity.UseRatio,
|
||||
FaultNum = entity.FaultNum,
|
||||
JobNum = entity.JobNum,
|
||||
CreateTime = entity.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将实体列表映射到响应模型列表
|
||||
/// </summary>
|
||||
public static List<DeviceStateResponse> ToResponseList(this List<DeviceState> entities)
|
||||
{
|
||||
return entities?.Select(e => e.ToResponse()).ToList() ?? new List<DeviceStateResponse>();
|
||||
}
|
||||
}
|
||||
}
|
||||
116
MoviconWebApi/API/DeviceStateApi/Models.cs
Normal file
116
MoviconWebApi/API/DeviceStateApi/Models.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
namespace MoviconWebApi.API.DeviceStateApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备状态查询请求
|
||||
/// </summary>
|
||||
public class DeviceStateRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string? DeviceCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public string? StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public string? EndTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态分页请求
|
||||
/// </summary>
|
||||
public class DeviceStatePagedRequest : DeviceStateRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 页码(从1开始)
|
||||
/// </summary>
|
||||
public int PageIndex { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 每页数量
|
||||
/// </summary>
|
||||
public int PageSize { get; set; } = 10;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态响应
|
||||
/// </summary>
|
||||
public class DeviceStateResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string? DeviceCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string? DeviceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开机时长(分钟)
|
||||
/// </summary>
|
||||
public int? PowerOnTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 运行时长(分钟)
|
||||
/// </summary>
|
||||
public int? RunTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 待机时长(分钟)
|
||||
/// </summary>
|
||||
public int? StandbyTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 故障时长(分钟)
|
||||
/// </summary>
|
||||
public int? FaultTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关机时长(分钟)
|
||||
/// </summary>
|
||||
public int? ShutdownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用率
|
||||
/// </summary>
|
||||
public string? UseRatio { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 故障次数
|
||||
/// </summary>
|
||||
public int? FaultNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 作业次数
|
||||
/// </summary>
|
||||
public int? JobNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public string? CreateTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备状态分页响应
|
||||
/// </summary>
|
||||
public class DeviceStatePagedResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据列表
|
||||
/// </summary>
|
||||
public List<DeviceStateResponse> Items { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 总记录数
|
||||
/// </summary>
|
||||
public long Total { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user