using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Utilities; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using YunDa.Server.Communication.Framework; using YunDa.Server.ISMSTcp.Domain; using YunDa.Server.ISMSTcp.Interfaces; using YunDa.Server.ISMSTcp.Models; using YunDa.Server.ISMSTcp.Services; using YunDa.SOMS.DataTransferObject.GeneralInformation.ProtectionDeviceInfoDto; using YunDa.SOMS.Redis.Repositories; namespace YunDa.Server.ISMSTcp.Controllers { /// /// 查询API控制器 /// [ApiController] [Route("api")] public class QueryController : ControllerBase { private readonly ILogger _logger; private readonly IQueryService _queryService; private readonly IWebSocketMessageBroadcaster _webSocketBroadcaster; private readonly IRedisRepository _protectionDeviceCommInfoOutputredisRepository; private readonly WebApiRequest _webApiRequest; private readonly ITcpClient _tcpClient; private readonly TelemeteringHandle _telemeteringHandle; private readonly TelesignalisationHandle _telesignalisationHandle; private readonly GwErrorRatioService _gwErrorRatioService; private readonly VirtualTerminalHandler _virtualTerminalHandler; /// /// 构造函数 /// /// 日志记录器 /// 查询服务 /// WebSocket消息广播器 /// 保护装置通信信息Redis仓储 /// Web API请求服务 /// TCP客户端 /// 遥测数据处理服务 public QueryController( ILogger logger, IQueryService queryService, IRedisRepository protectionDeviceCommInfoOutputredisRepository, IWebSocketMessageBroadcaster webSocketBroadcaster, WebApiRequest webApiRequest, ITcpClient tcpClient, TelemeteringHandle telemeteringHandle, TelesignalisationHandle telesignalisationHandle, GwErrorRatioService gwErrorRatioService, VirtualTerminalHandler virtualTerminalHandler) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _queryService = queryService ?? throw new ArgumentNullException(nameof(queryService)); _protectionDeviceCommInfoOutputredisRepository = protectionDeviceCommInfoOutputredisRepository ?? throw new ArgumentNullException(nameof(protectionDeviceCommInfoOutputredisRepository)); _webSocketBroadcaster = webSocketBroadcaster ?? throw new ArgumentNullException(nameof(webSocketBroadcaster)); _webApiRequest = webApiRequest ?? throw new ArgumentNullException(nameof(webApiRequest)); _tcpClient = tcpClient ?? throw new ArgumentNullException(nameof(tcpClient)); _telemeteringHandle = telemeteringHandle ?? throw new ArgumentNullException(nameof(telemeteringHandle)); _telesignalisationHandle = telesignalisationHandle ?? throw new ArgumentNullException(nameof(telesignalisationHandle)); _gwErrorRatioService = gwErrorRatioService ?? throw new ArgumentNullException(nameof(gwErrorRatioService)); _virtualTerminalHandler = virtualTerminalHandler ?? throw new ArgumentNullException(nameof(virtualTerminalHandler)); } /// /// 处理查询请求 /// /// 定值参数 /// 故障报告参数 /// 波形配置参数 /// 波形文件参数 /// 装置版本参数 /// 取消令牌 /// 查询结果 [HttpGet] public async Task ProcessQuery( [FromQuery] string? dz = null, [FromQuery] string? faultRpt = null, [FromQuery] string? waveCfg = null, [FromQuery] string? waveDat = null, [FromQuery] string? version = null, CancellationToken cancellationToken = default) { try { LogQueryRequest(dz, faultRpt, waveCfg, waveDat, version); var result = await DetermineAndExecuteQueryAsync(dz, faultRpt, waveCfg, waveDat, version, cancellationToken); return CreateActionResult(result); } catch (OperationCanceledException) { return HandleOperationCanceled(); } catch (Exception ex) { return HandleUnexpectedException(ex); } } /// /// 记录查询请求日志 /// /// 定值参数 /// 故障报告参数 /// 波形配置参数 /// 波形文件参数 /// 装置版本参数 private void LogQueryRequest(string? dz, string? faultRpt, string? waveCfg, string? waveDat, string? version) { _logger.LogWarning("收到查询请求 - dz:{Dz}, faultRpt:{FaultRpt}, waveCfg:{WaveCfg}, waveDat:{WaveDat}, version:{Version}", dz, faultRpt, waveCfg, waveDat, version); } /// /// 确定查询类型并执行相应的查询 /// /// 定值参数 /// 故障报告参数 /// 波形配置参数 /// 波形文件参数 /// 装置版本参数 /// 取消令牌 /// 查询结果 private async Task> DetermineAndExecuteQueryAsync( string? dz, string? faultRpt, string? waveCfg, string? waveDat, string? version, CancellationToken cancellationToken) { //_logger.LogWarning("收到查询命令: {Item}", yxItem?.ToString()); if (!string.IsNullOrEmpty(dz)) { return await ExecuteSettingValueQueryAsync(dz, cancellationToken); } else if (!string.IsNullOrEmpty(faultRpt)) { return await ExecuteFaultReportQueryAsync(faultRpt, cancellationToken); } else if (!string.IsNullOrEmpty(waveCfg)) { return await ExecuteWaveConfigQueryAsync(waveCfg, cancellationToken); } else if (!string.IsNullOrEmpty(waveDat)) { return await ExecuteWaveDataQueryAsync(waveDat, cancellationToken); } else if (!string.IsNullOrEmpty(version)) { return await ExecuteVersionQueryAsync(version, cancellationToken); } else { return WebResult.InvalidParameter(); } } /// /// 执行定值查询 /// /// 查询参数 /// 取消令牌 /// 查询结果 private async Task> ExecuteSettingValueQueryAsync(string parameter, CancellationToken cancellationToken) { return await _queryService.ProcessRequestAsync(parameter, "dz", "定值", cancellationToken); } /// /// 执行故障报告查询 /// /// 查询参数(格式:GetFaultRptByTime|2025-08-20 00:00|2025-08-20 23:59) /// 取消令牌 /// 查询结果 private async Task> ExecuteFaultReportQueryAsync(string parameter, CancellationToken cancellationToken) { return await _queryService.ProcessRequestAsync(parameter, "faultRpt", "故障报告", cancellationToken); } /// /// 执行波形配置查询 /// /// 查询参数 /// 取消令牌 /// 查询结果 private async Task> ExecuteWaveConfigQueryAsync(string parameter, CancellationToken cancellationToken) { return await _queryService.ProcessRequestAsync(parameter, "waveCfg", "波形配置", cancellationToken); } /// /// 执行波形文件查询 /// /// 查询参数 /// 取消令牌 /// 查询结果 private async Task> ExecuteWaveDataQueryAsync(string parameter, CancellationToken cancellationToken) { return await _queryService.ProcessRequestAsync(parameter, "waveDat", "波形文件", cancellationToken); } /// /// 执行装置版本查询 /// /// 查询参数 /// 取消令牌 /// 查询结果 private async Task> ExecuteVersionQueryAsync(string parameter, CancellationToken cancellationToken) { return await _queryService.ProcessRequestAsync(parameter, "version", "装置版本", cancellationToken); } /// /// 创建ActionResult响应 /// /// 查询结果 /// ActionResult private IActionResult CreateActionResult(WebResult result) { return StatusCode(result.StatusCode, result); } /// /// 处理操作取消异常 /// /// ActionResult private IActionResult HandleOperationCanceled() { _logger.LogWarning("查询请求被取消"); return StatusCode(504, "请求超时"); } /// /// 处理未预期的异常 /// /// 异常信息 /// ActionResult private IActionResult HandleUnexpectedException(Exception ex) { _logger.LogError(ex, "处理查询请求时发生异常"); return StatusCode(500, $"服务器内部错误: {ex.Message}"); } private List GetValidZzCmd(string cmdName, List ids) { const int maxLength = 250; var cmds = new List(); // 开始构建 string prefix = cmdName + "|"; // 固定前缀 int prefixLength = prefix.Length; var currentIds = new List(); int currentLength = prefixLength; // 当前命令的长度(含前缀) foreach (var id in ids) { // 如果添加这个ID会超长,则先生成一个命令 int idLength = (currentIds.Count == 0 ? id.Length : (1 + id.Length)); // 第一个ID不需要 '#' if (currentLength + idLength > maxLength) { // 将当前批次加入 cmds cmds.Add(prefix + string.Join("#", currentIds)); // 清空并重建 currentIds.Clear(); currentLength = prefixLength; } // 添加新的 ID currentIds.Add(id); currentLength += idLength; } // 收尾:如果还有剩余 IDs,生成最后一个命令 if (currentIds.Count > 0) { cmds.Add(prefix + string.Join("#", currentIds)); } return cmds; } /// /// 根据数据ID召唤遥测数据 /// /// 召唤结果 /// /// 示例请求:POST /* {      "id": [ "YCB001211132", "YCB001177030", ],      "times": 10 } */ /// [HttpPost("CallYCByDataId")] public async Task CallYCByDataId( [FromBody] ZzDataRequestModel request, CancellationToken cancellationToken = default) { var id = request.Id; var times = request.Times; id.RemoveAll(string.IsNullOrWhiteSpace); //string cmd = string.Format("CallYCByDataID|{0}", string.Join("#", id)); //System.Console.WriteLine($"发送遥测命令:{cmd}"); var cmds = GetValidZzCmd("CallYCByDataID", id); try { // 参数验证 if (id.Count == 0) { return BadRequest(new { success = false, message = "未提供数据ID", timestamp = DateTime.Now }); } _logger.LogInformation("收到遥测数据召唤请求 - cmd: {cmd}", string.Join("#", id)); // 发送TCP消息 DateTime cmdTime = DateTime.Now; int sucessCount = 0; if(request.TimeWindowType == 1 || request.TimeWindowType == 2) { for (int i = 0; i < times; i++) { bool isSuccess = true; foreach (var cmd in cmds) { var sendResult = await SendTcpMessageAsync(cmd, cancellationToken); isSuccess &= sendResult.Success; if (!isSuccess) { break; } else { await Task.Delay(5); } } if (isSuccess) { sucessCount++; } await Task.Delay(1000); } } else { sucessCount = 10; } if (times - sucessCount < 3) { List? ycDataList = null; var sw = Stopwatch.StartNew(); while (sw.ElapsedMilliseconds < 10 * 1000) { ycDataList = await _telemeteringHandle.GetYCDataByDataIds(id, times, request.TimeWindowType, cancellationToken, cmdTime); if (ycDataList.Count == id.Count) break; await Task.Delay(100); } if (ycDataList?.Count == id.Count) { return Ok(new { success = true, message = "获取遥测数据成功", data = ycDataList, count = ycDataList.Count, timestamp = DateTime.Now }); } else { return StatusCode(500, new { success = false, message = "发送命令成功,获取遥测数据超时", timestamp = DateTime.Now }); } } else { return StatusCode(500, new { success = false, message = $"发送命令失败", timestamp = DateTime.Now }); } } catch (OperationCanceledException) { _logger.LogWarning("遥测数据召唤请求被取消 - cmd: {cmd}", string.Join("#", id)); return StatusCode(504, new { success = false, message = "请求超时", timestamp = DateTime.Now }); } catch (Exception ex) { _logger.LogError(ex, "处理遥测数据召唤请求时发生异常 - cmd: {cmd}", string.Join("#", id)); return StatusCode(500, new { success = false, message = $"服务器内部错误: {ex.Message}", timestamp = DateTime.Now }); } } /// /// 根据数据ID召唤遥信数据 /// /// 召唤结果 /// /// 示例请求:POST /* {      "id": [ "YCB001211132", "YCB001177030", ],      "times": 10 } */ /// [HttpPost("CallYXByDataId")] public async Task CallYXByDataId( [FromBody] ZzDataRequestModel request, CancellationToken cancellationToken = default) { var ids = request.Id; var times = request.Times; ids.RemoveAll(string.IsNullOrWhiteSpace); try { // 参数验证 if (ids.Count == 0) { return BadRequest(new { success = false, message = "未提供数据ID", timestamp = DateTime.Now }); } var dataList = await _telesignalisationHandle.GetYXDataByDataIds(ids, times, request.TimeWindowType, cancellationToken); return Ok(new { success = true, message = "获取遥信数据成功", data = dataList, count = dataList.Count, timestamp = DateTime.Now }); } catch(Exception ex) { return StatusCode(500, new { success = false, message = $"获取遥信数据失败: {ex.Message}", timestamp = DateTime.Now }); } } /// 根据网关Id获取网关通信状态 [HttpPost("CallGatewayByDataId")] public async Task CallGatewayByDataId( [FromBody] ZzDataRequestModel request, CancellationToken cancellationToken = default) { var ids = request.Id; var times = request.Times; ids.RemoveAll(string.IsNullOrWhiteSpace); try { // 参数验证 if (ids.Count == 0) { return BadRequest(new { success = false, message = "未提供网关ID", timestamp = DateTime.Now }); } var dataList = await _gwErrorRatioService.GetDataByIds(ids, times, cancellationToken); return Ok(new { success = true, message = "获取网关通信状态成功", data = dataList, count = dataList.Count, timestamp = DateTime.Now }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = $"获取网关通信状态失败: {ex.Message}", timestamp = DateTime.Now }); } } /// 根据Id获取虚点数据 [HttpPost("CallVAByDataId")] public async Task CallVAByDataId( [FromBody] ZzDataRequestModel request, CancellationToken cancellationToken = default) { var ids = request.Id; var times = request.Times; ids.RemoveAll(string.IsNullOrWhiteSpace); try { // 参数验证 if (ids.Count == 0) { return BadRequest(new { success = false, message = "未提供ID", timestamp = DateTime.Now }); } var dataList = await _virtualTerminalHandler.GetDataByIds(ids, times, request.TimeWindowType, cancellationToken); return Ok(new { success = true, message = "获取虚点数据成功", data = dataList, count = dataList.Count, timestamp = DateTime.Now }); } catch (Exception ex) { return StatusCode(500, new { success = false, message = $"获取虚点数据失败: {ex.Message}", timestamp = DateTime.Now }); } } /// /// 发送TCP消息 /// /// 消息内容 /// 取消令牌 /// 发送结果 private async Task<(bool Success, string ErrorMessage)> SendTcpMessageAsync(string message, CancellationToken cancellationToken) { try { // 检查TCP连接状态 if (_queryService == null) { return (false, "查询服务未初始化"); } // 使用QueryService的TCP客户端发送消息 // 注意:这里直接通过ITcpClient发送,不需要等待响应 var tcpClient = GetTcpClientFromQueryService(); if (tcpClient == null) { return (false, "TCP客户端未初始化"); } if (!tcpClient.IsConnected) { return (false, "TCP连接未建立"); } var sendResult = await tcpClient.SendMessageAsync(message, cancellationToken); if (!sendResult) { return (false, "TCP消息发送失败"); } return (true, string.Empty); } catch (Exception ex) { _logger.LogError(ex, "发送TCP消息时发生异常"); return (false, ex.Message); } } /// /// 从QueryService获取TCP客户端 /// /// TCP客户端实例 private ITcpClient GetTcpClientFromQueryService() { return _tcpClient; } /// /// 获取服务状态 /// /// 服务状态 [HttpGet("status")] public IActionResult GetStatus() { try { var status = new { IsQueryInProgress = _queryService.IsQueryInProgress, Timestamp = DateTime.Now, Status = "Running" }; return Ok(status); } catch (Exception ex) { _logger.LogError(ex, "获取服务状态时发生异常"); return StatusCode(500, $"获取状态失败: {ex.Message}"); } } /// /// 健康检查端点 /// /// 健康状态 [HttpGet("health")] public IActionResult HealthCheck() { return Ok("Healthy"); } /// /// HTTP消息转发到WebSocket /// 支持ThingJS语法的事件和数据转发 /// /// 转发请求 /// 取消令牌 /// 转发结果 [HttpPost("forward-to-websocket")] public async Task ForwardToWebSocket([FromBody] object request, CancellationToken cancellationToken = default) { try { // 参数验证 if (request == null) { return BadRequest(new { message = "请求体不能为空" }); } var jsonData = JToken.FromObject(request); // 🔧 修复:智能确定目标分组,而不是硬编码为"thing" var targetGroups = DetermineTargetGroupsFromMessage(jsonData); // 处理检修状态消息 await ProcessMaintenanceStatusMessage(jsonData); var forwardResults = new List(); // 转发到所有确定的目标分组 foreach (var targetGroup in targetGroups) { try { await _webSocketBroadcaster.PushToGroupAsync(targetGroup, "ex", jsonData, useRawData: true); forwardResults.Add($"{targetGroup}: 成功"); _logger.LogDebug("消息已成功转发到WebSocket分组: {Group}", targetGroup); } catch (Exception groupEx) { forwardResults.Add($"{targetGroup}: 失败 - {groupEx.Message}"); _logger.LogError(groupEx, "转发消息到分组 {Group} 失败", targetGroup); } } _logger.LogInformation("消息转发完成 - 目标分组: {Groups}, 结果: {Results}", string.Join(", ", targetGroups), string.Join("; ", forwardResults)); return Ok(new { success = true, message = "消息转发完成", targetGroups = targetGroups, results = forwardResults, timestamp = DateTime.UtcNow }); } catch (JsonException jsonEx) { _logger.LogError(jsonEx, "解析JSON数据时发生错误"); return BadRequest(new { message = $"JSON格式错误: {jsonEx.Message}" }); } catch (Exception ex) { _logger.LogError(ex, "转发消息到WebSocket时发生异常"); return StatusCode(500, new { message = $"服务器内部错误: {ex.Message}" }); } } /// /// 根据消息内容确定目标分组 /// /// 消息数据 /// 目标分组列表 private List DetermineTargetGroupsFromMessage(JToken jsonData) { var targetGroups = new List(); try { // 检查消息是否包含检修状态信息 if (IsMaintenanceStatusMessage(jsonData)) { // 检修状态消息发送到thing分组进行处理 targetGroups.Add("thing"); return targetGroups; } // 检查消息类型并确定分组 var messageType = DetermineMessageType(jsonData); switch (messageType.ToUpper()) { case "YC": case "TELEMETERING": targetGroups.Add("YC"); break; case "YX": case "TELESIGNALISATION": targetGroups.Add("YX"); break; case "ALARM": case "ALERT": targetGroups.Add("ALERT"); break; case "COMMSTATE": targetGroups.Add("COMMSTATE"); break; case "THING": default: // 默认发送到thing分组 targetGroups.Add("thing"); break; } // 同时发送到ALL分组以保持兼容性 if (!targetGroups.Contains("ALL")) { targetGroups.Add("ALL"); } } catch (Exception ex) { _logger.LogWarning(ex, "确定目标分组时发生错误,使用默认分组"); targetGroups.Clear(); targetGroups.Add("thing"); } return targetGroups; } /// /// 判断是否为检修状态消息 /// /// 消息数据 /// 是否为检修状态消息 private bool IsMaintenanceStatusMessage(JToken jsonData) { try { if (jsonData is JObject obj) { // 检查是否包含检修状态的键值对 foreach (var property in obj.Properties()) { if (property.Value?.ToString().Contains("检修") == true) { return true; } } } } catch (Exception ex) { _logger.LogDebug(ex, "检查检修状态消息时发生错误"); } return false; } /// /// 确定消息类型 /// /// 消息数据 /// 消息类型 private string DetermineMessageType(JToken jsonData) { try { // 检查消息中是否包含类型字段 if (jsonData["type"] != null) { return jsonData["type"].ToString(); } if (jsonData["messageType"] != null) { return jsonData["messageType"].ToString(); } // 根据数据结构推断类型 if (jsonData["AlarmLevel"] != null || jsonData["AlarmType"] != null) { return "ALARM"; } if (jsonData["ResultValue"] != null && jsonData["ResultTime"] != null) { return "YC"; // 遥测数据 } if (jsonData["Value"] != null && jsonData["Time"] != null) { return "YX"; // 遥信数据 } } catch (Exception ex) { _logger.LogDebug(ex, "确定消息类型时发生错误"); } return "THING"; // 默认类型 } /// /// 处理检修状态消息 /// /// 消息数据 /// 处理任务 private async Task ProcessMaintenanceStatusMessage(JToken jsonData) { try { if (IsMaintenanceStatusMessage(jsonData) && jsonData is JObject obj) { var maintenanceData = new Dictionary(); foreach (var property in obj.Properties()) { var value = property.Value?.ToString(); if (!string.IsNullOrEmpty(value)) { maintenanceData[property.Name] = value; } } if (maintenanceData.Any()) { _logger.LogInformation("检测到检修状态消息: {MaintenanceData}", string.Join(", ", maintenanceData.Select(kvp => $"{kvp.Key}={kvp.Value}"))); // 🔧 更新Redis中的设备检修状态 await UpdateDeviceMaintenanceStatusInRedis(maintenanceData); } } } catch (Exception ex) { _logger.LogError(ex, "处理检修状态消息时发生错误"); } } /// /// 🔧 新增:更新Redis中的设备检修状态 /// /// 检修状态数据 /// 处理任务 private async Task UpdateDeviceMaintenanceStatusInRedis(Dictionary maintenanceData) { try { const string protectionDeviceCommInfoRedisKey = "protectionDeviceCommInfo"; foreach (var kvp in maintenanceData) { var twinId = kvp.Key; var maintenanceStatus = kvp.Value; var isInMaintenance = maintenanceStatus.Contains("检修"); try { // 使用TwinIdApiService查询TwinId对应的EquipmentInfoId var equipmentInfoId = await _webApiRequest.GetTwIdAsync(twinId); // 从Redis获取所有保护装置通信信息 var allDevices = await _protectionDeviceCommInfoOutputredisRepository.HashSetGetAllAsync(protectionDeviceCommInfoRedisKey); // 查找匹配的设备 var targetDevice = allDevices.FirstOrDefault(d => d.EquipmentInfoId == equipmentInfoId); if (targetDevice != null) { // 更新检修状态 targetDevice.IsMaintenance = isInMaintenance; // 更新Redis中的数据 await _protectionDeviceCommInfoOutputredisRepository.HashSetUpdateOneAsync( protectionDeviceCommInfoRedisKey, targetDevice.DeviceAddr.ToString(), targetDevice); _logger.LogInformation("已更新设备检修状态 - TwinId: {TwinId}, EquipmentInfoId: {EquipmentInfoId}, IsMaintenance: {IsMaintenance}", twinId, equipmentInfoId, isInMaintenance); } else { _logger.LogWarning("未找到对应的保护装置设备 - EquipmentInfoId: {EquipmentInfoId}", equipmentInfoId); } } catch (Exception ex) { _logger.LogError(ex, "更新设备检修状态失败 - TwinId: {TwinId}", twinId); } } } catch (Exception ex) { _logger.LogError(ex, "更新Redis中的设备检修状态时发生错误"); } } /// /// 解析ThingJS语法的数据 /// /// 原始数据字符串 /// 解析后的数据 private object ParseThingJSData(string data) { try { // 检查是否是ThingJS语法(以#开头) if (data.StartsWith("#")) { // 解析ThingJS语法,例如 #UINO_T1 var thingId = data.Substring(1); // 移除#前缀 return new { type = "thing", thingId = thingId, selector = data, originalData = data }; } // 尝试解析为JSON try { return JsonConvert.DeserializeObject(data); } catch { // 如果不是JSON,返回原始字符串 return data; } } catch (Exception ex) { _logger.LogWarning(ex, "解析ThingJS数据时发生警告,返回原始数据: {Data}", data); return data; } } /// /// 根据事件名称和数据确定目标分组 /// /// 事件名称 /// 数据内容 /// 目标分组名称 private string DetermineTargetGroup(string eventName, string data) { // 根据事件名称确定分组 var eventLower = eventName.ToLower(); if (eventLower.Contains("yc") || eventLower.Contains("telemetering")) { return WebSocketGroups.YC; } if (eventLower.Contains("yx") || eventLower.Contains("telesignalisation")) { return WebSocketGroups.YX; } if (eventLower.Contains("alarm") || eventLower.Contains("alert")) { return WebSocketGroups.ALERT; } if (eventLower.Contains("comm") || eventLower.Contains("communication")) { return WebSocketGroups.COMMSTATE; } // 检查是否是Thing相关的事件 if (data.StartsWith("#") || eventLower.Contains("thing")) { return "thing"; // Thing专用分组 } // 默认发送到ALL分组 return WebSocketGroups.ALL; } ///// ///// 获取召唤的遥测数据 ///// ///// 数据ID字符串,格式:DataID1#DataID2#DataID3#...... ///// 取消令牌 ///// 遥测数据列表 ///// ///// 示例请求:GET /api/GetCollectedYCData?dataIds=001#002#003 ///// //[HttpGet("GetCollectedYCData")] //public async Task GetCollectedYCData( // [FromQuery] string dataIds, // CancellationToken cancellationToken = default) //{ // try // { // // 参数验证 // if (string.IsNullOrWhiteSpace(dataIds)) // { // return BadRequest(new // { // success = false, // message = "参数 dataIds 不能为空", // timestamp = DateTime.Now // }); // } // _logger.LogInformation("收到获取遥测数据请求 - dataIds: {DataIds}", dataIds); // // 解析DataId列表 // var dataIdList = dataIds.Split('#', StringSplitOptions.RemoveEmptyEntries) // .Select(id => id.Trim()) // .Where(id => !string.IsNullOrWhiteSpace(id)) // .ToList(); // if (dataIdList.Count == 0) // { // return BadRequest(new // { // success = false, // message = "未提供有效的数据ID", // timestamp = DateTime.Now // }); // } // // 从TelemeteringHandle获取数据 // var ycDataList = _telemeteringHandle.GetYCDataByDataIds(dataIdList); // _logger.LogInformation("获取遥测数据成功 - 请求DataId数: {RequestCount}, 返回数据数: {ResultCount}", // dataIdList.Count, ycDataList.Count); // return Ok(new // { // success = true, // message = "获取遥测数据成功", // data = ycDataList, // count = ycDataList.Count, // timestamp = DateTime.Now // }); // } // catch (OperationCanceledException) // { // _logger.LogWarning("获取遥测数据请求被取消 - dataIds: {DataIds}", dataIds); // return StatusCode(504, new // { // success = false, // message = "请求超时", // timestamp = DateTime.Now // }); // } // catch (Exception ex) // { // _logger.LogError(ex, "获取遥测数据时发生异常 - dataIds: {DataIds}", dataIds); // return StatusCode(500, new // { // success = false, // message = $"服务器内部错误: {ex.Message}", // timestamp = DateTime.Now // }); // } //} } }