using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using DOAN.Model.Bydlms; using DOAN.Model.Bydlms.Dto; using DOAN.Service.Bydlms.IBydlmsService; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using SqlSugar; namespace DOAN.Tasks.TaskScheduler { public class BackgroundTask : IHostedService, IDisposable { private readonly HttpClient _httpClient; // HTTP客户端实例 private readonly IBydAlarmMsgService _bydAlarmMsgService; private readonly IBydProductionStationService _BydProductionStationService; private readonly IBydDeviceService _BydDeviceService; private readonly SqlSugarClient _db; // SqlSugar 客户端实例 private Timer _timer; // 定时器实例 public BackgroundTask( IBydAlarmMsgService bydAlarmMsgService, IBydProductionStationService bydProductionStationService, IBydDeviceService bydDeviceService, SqlSugarClient db ) { _httpClient = new HttpClient(); // 初始化HTTP客户端 _bydAlarmMsgService = bydAlarmMsgService; _BydProductionStationService = bydProductionStationService; _BydDeviceService = bydDeviceService; _db = db; } /// /// 启动后台服务并设置定时器。 /// /// 用于通知操作应取消的 CancellationToken。 /// 表示异步操作的任务。 public Task StartAsync(CancellationToken cancellationToken) { // 设置定时器,立即开始第一次执行,并每隔10秒重复一次 _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); return Task.CompletedTask; } /// /// 定时器触发时调用的方法。 /// /// 传递给回调方法的对象。 private void DoWork(object state) { // 异步执行后台任务 _ = ExecuteBackgroundTaskAsync(); } /// /// 执行具体的后台任务逻辑。 /// /// 表示异步操作的任务。 private async Task ExecuteBackgroundTaskAsync() { var BaseUrl = "http://10.17.2.198:3000/mock/24"; var AlarmsUrl = "/api/product/Product_Information?System001_Warning"; var StationPassesUrl = "/api/product/Product_Information?Product003_PassStation"; var DeviceDataCollectionUrl = "/api/product/Product_Information?serviceId=Product005_EquipmentStatus"; var AttendanceRecordsUrl = "http://10.17.2.198:3000/mock/24/api/product/Product_Information?System001_Warning"; try { Console.BackgroundColor = ConsoleColor.Green; Console.WriteLine("后台任务执行!"); // 报警信息转发 await ProcessAlarms(BaseUrl + AlarmsUrl); // TODO 过站信息转发 await ProcessStationPasses(BaseUrl + StationPassesUrl); // TODO 设备数采信息转发 // await ProcessDeviceDataCollection(BaseUrl + DeviceDataCollectionUrl); // TODO 考勤打卡信息转发 // await ProcessAttendanceRecords(AttendanceRecordsUrl); } catch (HttpRequestException e) { // 捕获并处理HTTP请求异常 HandleHttpRequestException(e); } catch (Exception e) { // 捕获并处理其他异常 HandleGeneralException(e); } } /// /// 处理报警信息转发。 /// /// API URL。 /// 表示异步操作的任务。 private async Task ProcessAlarms(string url) { int maxPageSize = 50; try { using (var tran = _db.Ado.UseTran()) { // 获取报警未上传信息 var alarmUploadData = _bydAlarmMsgService.GetList( new BydAlarmMsgQueryDto { IsUpload = 0, PageSize = maxPageSize } ); List alarmList = alarmUploadData.Result; bool hasMoreData = alarmUploadData.TotalNum > maxPageSize; if (alarmList.Count > 0) { // 发送HTTP请求并获取响应内容 AlarmUploadData uploadData = new() { serviceId = alarmList[0].ServiceId, factoryCode = alarmList[0].FactoryCode, //data = alarmList }; string responseBody = await SendRequestAsync(url, uploadData); // 标记报警信息已上传 int result = _bydAlarmMsgService.MarkAlarmIsUpload(alarmList); if (result == 0) { Console.WriteLine("报警信息上传失败!======== " + responseBody); throw new Exception("Failed to mark alarms as uploaded."); } else { Console.WriteLine("报警信息上传成功!======== " + responseBody); // 输出响应内容到控制台 } } // 提交事务 tran.CommitTran(); } } catch (Exception ex) { throw; } } /// /// 处理过站信息转发。 /// /// 表示异步操作的任务。 private async Task ProcessStationPasses(string url) { int maxPageSize = 50; try { using (var tran = _db.Ado.UseTran()) { // 获取过站未上传信息 var pageData = _BydProductionStationService.GetList( new BydProductionStationQueryDto { IsUpload = 0, PageSize = maxPageSize } ); List list = pageData.Result; if (list.Count > 0) { // 发送HTTP请求并获取响应内容 ProductionStationUploadData uploadData = new() { AutoBindBatchMaterial = true, serviceId = "Product003_PassStation", factoryCode = "ZZG4", requestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), MesUrl = "http://zz-mes-fddl01.byd.com/", MesVersion = "3", Remote = "10.79.80.56", Timer = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), Uuid = Guid.NewGuid().ToString(), RePushSend = 0, //data = list }; string responseBody = await SendRequestAsync(url, uploadData); // 标记信息已上传 var updateRes = _db.Updateable(list) .SetColumns(it => it.IsUpload == 1) // .UpdateColumns(it => new { it.IsUpload }) .ExecuteCommand(); if (updateRes == 0) { Console.WriteLine("过站信息上传失败!======== " + responseBody); throw new Exception("Failed to mark alarms as uploaded."); } else { Console.WriteLine("过站信息上传成功!======== " + responseBody); } } // 提交事务 tran.CommitTran(); } } catch (Exception ex) { throw; } } /// /// 处理设备数采信息转发。 /// /// 表示异步操作的任务。 private async Task ProcessDeviceDataCollection(string url) { int maxPageSize = 50; try { using (var tran = _db.Ado.UseTran()) { // 获取未上传信息 var pageData = _BydDeviceService.GetList( new BydDeviceQueryDto { PageSize = maxPageSize } ); List list = pageData.Result; if (list.Count > 0) { // 发送HTTP请求并获取响应内容 DeviceUploadData uploadData = new() { serviceId = "Product005_EquipmentStatus", factoryCode = list[0].FactoryCode }; string responseBody = await SendRequestAsync(url, uploadData); // 标记信息已上传 /*int result = _bydAlarmMsgService.MarkAlarmIsUpload(list); if (result == 0) { Console.WriteLine("设备数采信息上传失败!======== " + responseBody); throw new Exception("Failed to mark alarms as uploaded."); } else { Console.WriteLine("设备数采信息上传成功!======== " + responseBody); }*/ } // 提交事务 tran.CommitTran(); } } catch (Exception ex) { throw; } } /// /// 处理考勤打卡信息转发。 /// /// 表示异步操作的任务。 private async Task ProcessAttendanceRecords(string url) { try { using (var tran = _db.Ado.UseTran()) { // 获取未上传信息 var alarmUploadData = _bydAlarmMsgService.GetList( new BydAlarmMsgQueryDto { IsUpload = 0, PageSize = 50 } ); List alarmList = alarmUploadData.Result; if (alarmList.Count > 0) { // 发送HTTP请求并获取响应内容 AlarmUploadData uploadData = new() { serviceId = alarmList[0].ServiceId, factoryCode = alarmList[0].FactoryCode, //data = alarmList }; string responseBody = await SendRequestAsync(url, uploadData); // 标记信息已上传 int result = _bydAlarmMsgService.MarkAlarmIsUpload(alarmList); if (result == 0) { Console.WriteLine("考勤打卡信息上传失败!======== " + responseBody); throw new Exception("Failed to mark alarms as uploaded."); } else { Console.WriteLine("考勤打卡信息上传成功!======== " + responseBody); // 输出响应内容到控制台 } } // 提交事务 tran.CommitTran(); } } catch (Exception ex) { throw; } } /// /// 发送HTTP POST请求并返回响应内容。 /// /// API URL。 /// 要发送的数据对象。 /// API响应的内容字符串。 private async Task SendRequestAsync(string url, object data) { // 将数据对象序列化为JSON字符串 var jsonData = JsonConvert.SerializeObject(data); var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); // 创建HTTP请求消息 using (var request = new HttpRequestMessage(HttpMethod.Post, url)) { request.Content = content; // 设置请求体内容 request.Headers.Add("appId", "61320D6EEF5A48B7C32149DF991BED41"); // 添加请求头 request.Headers.Add("appKey", "85725BB0BCCEE8DB1AE2D5A48D393ABE"); // 添加请求头 // 发送HTTP请求并获取响应 HttpResponseMessage response = await _httpClient.SendAsync(request); // 确保响应状态码成功 if (!response.IsSuccessStatusCode) { throw new HttpRequestException( $"Request failed with status code: {response.StatusCode}" ); } // 读取并返回响应内容 return await response.Content.ReadAsStringAsync(); } } /// /// 处理HTTP请求异常。 /// /// 捕获的HttpRequestException异常。 private void HandleHttpRequestException(HttpRequestException exception) { Console.WriteLine($"HTTP Request Error: {exception.Message}"); // 可以在这里添加日志记录或其他处理逻辑 } /// /// 处理一般异常。 /// /// 捕获的一般异常。 private void HandleGeneralException(Exception exception) { Console.WriteLine($"General Error: {exception.Message}"); // 可以在这里添加日志记录或其他处理逻辑 } /// /// 停止后台服务。 /// /// 用于通知操作应取消的 CancellationToken。 /// 表示异步操作的任务。 public Task StopAsync(CancellationToken cancellationToken) { // 更改定时器的状态以停止进一步的执行 _timer?.Change(Timeout.Infinite, 0); return Task.CompletedTask; } /// /// 释放资源。 /// public void Dispose() { // 释放定时器资源 _timer?.Dispose(); // 释放HTTP客户端资源 _httpClient.Dispose(); } } }