EquipmentStatusUpdateBackgroundService.cs 5.87 KB
using HHECS.DAQShared.Common.Enums;
using HHECS.DAQShared.Common.Utils;
using HHECS.DAQShared.Dto;
using HHECS.DAQShared.Models;

namespace HHECS.DAQServer.Services
{
    public class EquipmentStatusUpdateBackgroundService : BackgroundService
    {
        private readonly IFreeSql _freeSql;
        private readonly DataCacheService _dataCacheService;
        private readonly CommonService _commonService;
        private readonly ILogger<EquipmentStatusUpdateBackgroundService> _logger;
        private readonly int _limit = 1000;

        public EquipmentStatusUpdateBackgroundService(IFreeSql freeSql, DataCacheService dataCacheService,
            CommonService commonService, ILogger<EquipmentStatusUpdateBackgroundService> logger)
        {
            _freeSql = freeSql;
            _dataCacheService = dataCacheService;
            _commonService = commonService;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    //每10秒执行一次
                    await Task.Delay(10000, stoppingToken);
                    using var equipmentStatusRecordRepository = _freeSql.GetRepository<EquipmentStatusRecord>();
                    var temps = _dataCacheService.EquipmentStatusDictionary.Where(x => _commonService.TimestampConvertToLocalDateTime(x.Value.Timestamp) >= DateTime.Now.AddMinutes(-5)).ToList();

                    //按照设定的数量进行分组
                    var groups = new List<List<KeyValuePair<string, EquipmentDataDto>>>();
                    for (int i = 0; i < temps.Count; i += _limit)
                    {
                        var group = temps.Skip(i).Take(_limit).ToList();
                        groups.Add(group);
                    }

                    //待更新数据
                    var waitUpdateItem = new List<EquipmentStatusRecord>();
                    foreach (var group in groups)
                    {
                        var allEquipmentSN = group.Select(x => x.Key).ToList();
                        var equipmentStatusItems = equipmentStatusRecordRepository.Where(x => allEquipmentSN.Contains(x.EquipmentCode)).ToList();
                        var equipments = _freeSql.Queryable<EquipmentExtend>().Where(x => allEquipmentSN.Contains(x.Code)).ToList(x => new EquipmentExtend
                        {
                            Id = x.Id,
                            Code = x.Code,
                            EquipmentTypeId = x.EquipmentTypeId,
                        });

                        var equipmentTypeIds = equipments.Select(x => x.EquipmentTypeId).Distinct().ToList();
                        var equipmentTypes = _freeSql.Queryable<EquipmentTypeExtend>().Where(x => equipmentTypeIds.Contains(x.Id)).ToList(x => new EquipmentTypeExtend
                        {
                            Id = x.Id,
                            Code = x.Code,
                        });

                        foreach (var item in equipmentStatusItems)
                        {
                            var temp = group.Find(x => x.Key == item.EquipmentCode).Value;
                            if (item.UpdateTime < _commonService.TimestampConvertToLocalDateTime(temp.Timestamp))
                            {
                                var currentEquipment = equipments.Find(x => x.Code == item.EquipmentCode);
                                var currentEquipmentType = equipmentTypes.Find(x => x.Id == currentEquipment.EquipmentTypeId);
                                _ = Enum.TryParse<EquipmentTypeConst>(currentEquipmentType.Code, out var equipmetTypeEnum);
                                var currentEquipmentProps = _freeSql.Queryable<EquipmentPropExtend>().Where(x => x.EquipmentId == currentEquipment.Id).ToList(x => new EquipmentPropExtend
                                {
                                    Id = x.Id,
                                    EquipmentTypePropTemplateCode = x.EquipmentTypePropTemplateCode,
                                    Address = x.Address,
                                });
                                var statusResult = EquipmentStatusHelper.GetEquipmentStatus(equipmetTypeEnum, currentEquipmentProps, temp.Reported);
                                if (!statusResult.Success)
                                {
                                    continue;
                                }

                                var currentStatus = statusResult.Data.ToString();
                                equipmentStatusRecordRepository.Attach(item);
                                //状态有变更
                                if (item.Status != currentStatus || item.CreateTime.Date != DateTime.Now.Date)
                                {
                                    item.CreateTime = DateTime.Now;
                                }
                                item.Status = currentStatus;
                                item.UpdateTime = _commonService.TimestampConvertToLocalDateTime(temp.Timestamp);
                                item.StatusDuration = 0;
                                item.HandleTime = DateTime.Now;
                                waitUpdateItem.Add(item);
                            }
                        }
                    }

                    //分批更新
                    for (int i = 0; i < waitUpdateItem.Count; i += _limit)
                    {
                        var temp2s = waitUpdateItem.Skip(i).Take(_limit).ToList();
                        equipmentStatusRecordRepository.Update(temp2s);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"[{nameof(EquipmentStatusUpdateBackgroundService)}]线程异常:{ex.Message}");
                }
            }
        }
    }
}