MaintainJob.cs 14.7 KB
using Hh.Mes.POJO.Entity;
using Hh.Mes.POJO.EnumEntitys;
using SqlSugar;
using System;
using System.Linq;

namespace Quartz.Job.Jobs
{
    /// <summary>
    /// 保养记录生成
    /// </summary>
    public class MaintainJob : JobBase
    {
        public override void ExecuteJob(IJobExecutionContext context)
        {
            var equipments = _dbContext.Queryable<base_equipment>().Where(x => x.isEnable && !string.IsNullOrEmpty(x.equipmentMaintainRuleCode)).ToList();
            //保养规则
            var busEquipmentMaintainRuleHeads = _dbContext.Queryable<bus_equipment_maintain_rule_head>()
                .Where(x => SqlFunc.Subqueryable<base_equipment>().Where(s => s.isEnable && !string.IsNullOrEmpty(s.equipmentMaintainRuleCode) && s.equipmentMaintainRuleCode == x.equipmentRuleCode).Any())
                .ToList();

            var ruleHeadKeys = busEquipmentMaintainRuleHeads.Select(x => x.keys).ToList();
            var busEquipmentMaintainRuleDetails = _dbContext.Queryable<bus_equipment_maintain_rule_detail>()
                .Where(x => ruleHeadKeys.Contains(x.headKeys)).ToList();

            //设备部件
            var equipmentTypeCodes = equipments.Select(x => x.equipmentTypeCode).Distinct().ToList();
            var equipmentParts = _dbContext.Queryable<base_equipment_part>().Where(x => equipmentTypeCodes.Contains(x.equipmentTypeCode)).ToList();
            var busEquipmentMaintainRuleDetailIndicatorRels = _dbContext.Queryable<bus_equipment_maintain_rule_detail_indicator_rel>().ToList();
            var busEquipmentMaintainRecordTops = _dbContext.Queryable<bus_equipment_maintain_record_top>()
                .Where(x => SqlFunc.Subqueryable<base_equipment>().Where(s => s.equipmentCode == x.equipmentCode).Any())
                .ToList();

            foreach (var equipment in equipments)
            {
                try
                {
                    var ruleHead = busEquipmentMaintainRuleHeads.Where(x => x.equipmentRuleCode == equipment.equipmentMaintainRuleCode).FirstOrDefault();
                    //未匹配到维护规则,则跳过
                    if (ruleHead == null)
                    {
                        continue;
                    }

                    //无明细数据,则跳过
                    var ruleDetails = busEquipmentMaintainRuleDetails.Where(x => x.headKeys == ruleHead.keys).ToList();
                    if (ruleDetails.Count == 0)
                    {
                        continue;
                    }

                    var currentEquipmentParts = equipmentParts.Where(x => x.equipmentTypeCode == equipment.equipmentTypeCode).ToList();

                    var busEquipmentMaintainRecordTop = busEquipmentMaintainRecordTops.Where(x => x.equipmentCode == equipment.equipmentCode).FirstOrDefault();

                    //开启事务
                    _dbContext.Ado.BeginTran();
                    if (busEquipmentMaintainRecordTop == null)
                    {
                        busEquipmentMaintainRecordTop = new bus_equipment_maintain_record_top
                        {
                            keys = Guid.NewGuid(),
                            equipmentCode = equipment.equipmentCode,
                            equipmentName = equipment.equipmentName,
                            equipmentTypeCode = equipment.equipmentTypeCode,
                            factoryCode = equipment.factoryCode,
                            projectKeys = equipment.projectKeys,
                            createTime = DateTime.Now,
                            createBy = nameof(MaintainJob),
                        };
                        busEquipmentMaintainRecordTop.id = _dbContext.Insertable(busEquipmentMaintainRecordTop).ExecuteReturnIdentity();
                    }

                    var busEquipmentMaintainRecordHeads = _dbContext.Queryable<bus_equipment_maintain_record_head>()
                        .Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys).ToList();
                    var busEquipmentMaintainRecordDetails = _dbContext.Queryable<bus_equipment_maintain_record_detail>()
                        .Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys && x.status != (int)EnumMaintainStatus.Maintained).ToList();
                    foreach (var equipmentPart in currentEquipmentParts)
                    {
                        //当前部件的保养规则
                        var currentRuleDetail = ruleDetails.Where(x => x.equipmentPartCode == equipmentPart.partCode).FirstOrDefault();
                        if (currentRuleDetail == null)
                        {
                            //当前部件未配置保养规则,则跳过
                            continue;
                        }

                        var indicatorTypes = busEquipmentMaintainRuleDetailIndicatorRels.Where(x => x.ruleDetailKeys == currentRuleDetail.detailKeys).ToList();

                        //保养周期类型未设定,则跳过
                        if (indicatorTypes.Count == 0)
                        {
                            continue;
                        }

                        var busEquipmentMaintainRecordHead = busEquipmentMaintainRecordHeads.Where(x => x.partCode == equipmentPart.partCode).FirstOrDefault();
                        if (busEquipmentMaintainRecordHead == null)
                        {
                            busEquipmentMaintainRecordHead = new bus_equipment_maintain_record_head
                            {
                                topKeys = busEquipmentMaintainRecordTop.keys,
                                headKeys = Guid.NewGuid(),
                                equipmentCode = equipment.equipmentCode,
                                equipmentTypeCode = equipment.equipmentTypeCode,
                                factoryCode = equipment.factoryCode,
                                projectKeys = equipment.projectKeys,
                                partCode = equipmentPart.partCode,
                                partName = equipmentPart.partName,
                                lastMaintainTime = DateTime.Now,
                                nextMaintainTime = DateTime.Now,
                                createTime = DateTime.Now,
                                createBy = nameof(MaintainJob),
                            };
                            busEquipmentMaintainRecordHead.id = _dbContext.Insertable(busEquipmentMaintainRecordHead).ExecuteReturnIdentity();
                        }

                        //当前部件上次保养时间
                        var lastMaintainTime = _dbContext.Queryable<bus_equipment_maintain_record_detail>().Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys && x.headKeys == busEquipmentMaintainRecordHead.headKeys && x.status == (int)EnumMaintainStatus.Maintained).Max(x => x.maintainTime) ?? DateTime.Today;
                        //下次保养时间
                        var nextMaintainTime = indicatorTypes.Select(x => GetNextMaintainTime(x, lastMaintainTime)).Min();
                        if (nextMaintainTime == DateTime.MaxValue)
                        {
                            //未配置,则不生成记录
                            continue;
                        }

                        //解析保养规则,生成保养记录,待完善
                        var busEquipmentMaintainRecordDetail = busEquipmentMaintainRecordDetails.Where(x => x.headKeys == busEquipmentMaintainRecordHead.headKeys && x.partCode == equipmentPart.partCode).FirstOrDefault();
                        var nextDurationTime = (nextMaintainTime - DateTime.Now).Days;
                        //无记录,则需要新增
                        if (busEquipmentMaintainRecordDetail == null)
                        {
                            //基础数据
                            busEquipmentMaintainRecordDetail = new bus_equipment_maintain_record_detail
                            {
                                topKeys = busEquipmentMaintainRecordTop.keys,
                                headKeys = busEquipmentMaintainRecordHead.headKeys,
                                equipmentCode = equipment.equipmentCode,
                                equipmentTypeCode = equipment.equipmentTypeCode,
                                projectKeys = equipment.projectKeys,
                                factoryCode = equipment.factoryCode,
                                status = (int)EnumMaintainStatus.ToBeMaintain,
                                partCode = equipmentPart.partCode,
                                partName = equipmentPart.partName,
                                lastMaintainTime = lastMaintainTime,
                                nextMaintainTime = nextMaintainTime,
                                nextDurationTime = nextDurationTime,
                            };
                            _dbContext.Insertable(busEquipmentMaintainRecordDetail).ExecuteCommand();
                        }
                        else
                        {
                            busEquipmentMaintainRecordDetail.nextMaintainTime = nextMaintainTime;
                            busEquipmentMaintainRecordDetail.nextDurationTime = (nextMaintainTime - DateTime.Now).Days;
                            _dbContext.Updateable(busEquipmentMaintainRecordDetail).UpdateColumns(x => new
                            {
                                x.nextMaintainTime,
                                x.nextDurationTime,
                            }).ExecuteCommand();
                        }

                        //更新Head表
                        var headSumPrice = _dbContext.Queryable<bus_equipment_maintain_record_detail>().Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys && x.headKeys == busEquipmentMaintainRecordHead.headKeys && x.maintainTime != null).Sum(x => x.maintainPrice);

                        busEquipmentMaintainRecordHead.lastMaintainTime = busEquipmentMaintainRecordDetail.lastMaintainTime;
                        busEquipmentMaintainRecordHead.nextMaintainTime = nextMaintainTime;
                        busEquipmentMaintainRecordHead.nextMaintianDate = nextDurationTime;
                        busEquipmentMaintainRecordHead.sumPrice = headSumPrice;
                        busEquipmentMaintainRecordHead.updateTime = DateTime.Now;
                        busEquipmentMaintainRecordHead.updateBy = nameof(MaintainJob);
                        _dbContext.Updateable(busEquipmentMaintainRecordHead).UpdateColumns(x => new
                        {
                            x.lastMaintainTime,
                            x.nextMaintainTime,
                            x.nextMaintianDate,
                            x.sumPrice,
                            x.updateTime,
                            x.updateBy,
                        }).ExecuteCommand();
                    }

                    //更新概述表
                    var topMaintainNumber = _dbContext.Queryable<bus_equipment_maintain_record_detail>().Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys && x.status == (int)EnumMaintainStatus.Maintained).Count();

                    var topLastMaintainTime = _dbContext.Queryable<bus_equipment_maintain_record_head>().Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys).Max(x => x.lastMaintainTime);

                    var topToBeMaintainedNumber = _dbContext.Queryable<bus_equipment_maintain_record_detail>().Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys && x.status != (int)EnumMaintainStatus.Maintained).Count();

                    var topSumAmount = _dbContext.Queryable<bus_equipment_maintain_record_head>().Where(x => x.topKeys == busEquipmentMaintainRecordTop.keys).Sum(x => x.sumPrice);

                    busEquipmentMaintainRecordTop.maintainNumber = topMaintainNumber;
                    busEquipmentMaintainRecordTop.lastMaintainTime = topLastMaintainTime;
                    busEquipmentMaintainRecordTop.toBeMaintainedNumber = topToBeMaintainedNumber;
                    busEquipmentMaintainRecordTop.sumAmount = topSumAmount;
                    busEquipmentMaintainRecordTop.updateTime = DateTime.Now;
                    busEquipmentMaintainRecordTop.updateBy = nameof(MaintainJob);
                    _dbContext.Updateable(busEquipmentMaintainRecordTop).UpdateColumns(x => new
                    {
                        x.maintainNumber,
                        x.lastMaintainTime,
                        x.toBeMaintainedNumber,
                        x.sumAmount,
                        x.updateTime,
                        x.updateBy
                    }).ExecuteCommand();

                    //提交
                    _dbContext.Ado.CommitTran();
                }
                catch (Exception ex)
                {
                    //异常回滚
                    _dbContext.Ado.RollbackTran();
                    _log4net.Error($"[{nameof(MaintainJob)}]定时器异常:{ex}");
                }
            }
        }

        /// <summary>
        /// 获取下次保养时间
        /// </summary>
        /// <param name="indicatorType"></param>
        /// <param name="lastMaintainTime">上次保养时间</param>
        /// <returns></returns>
        private DateTime GetNextMaintainTime(bus_equipment_maintain_rule_detail_indicator_rel indicatorType, DateTime lastMaintainTime)
        {
            _ = int.TryParse(indicatorType.indicatorValue, out var indicatorValue);
            if (indicatorValue == 0)
            {
                return DateTime.MaxValue;
            }

            if (indicatorType.indicatorTypeName == EnumIndicatorType..ToString())
            {
                return lastMaintainTime.AddDays(indicatorValue);
            }
            else if (indicatorType.indicatorTypeName == EnumIndicatorType..ToString())
            {
                return lastMaintainTime.AddMonths(indicatorValue);
            }
            //else if (indicatorType.indicatorTypeName == EnumIndicatorType.季度.ToString())
            //{
            //    return lastMaintainTime.AddMonths(indicatorValue * 3);
            //}
            //else if (indicatorType.indicatorTypeName == EnumIndicatorType.年.ToString())
            //{
            //    return lastMaintainTime.AddYears(indicatorValue);
            //}
            else if (indicatorType.indicatorTypeName.Contains(EnumIndicatorType.公里数.ToString()))
            {
                //待定
            }
            //else if (indicatorType.indicatorTypeName == EnumIndicatorType.圈数.ToString())
            //{
            //    //待定
            //}
            //else if (indicatorType.indicatorTypeName == EnumIndicatorType.次数.ToString())
            //{
            //    //待定
            //}
            //不支持
            return DateTime.MaxValue;
        }
    }
}