BevelExcute.cs 21.8 KB
using AutoMapper.Execution;
using FreeSql;
using HHECS.Application.Enums;
using HHECS.Application.Service;
using HHECS.BLL.EquipmentExcute.Marking;
using HHECS.BLL.Services;
using HHECS.BllModel;
using HHECS.Communication;
using HHECS.Communication.PLC;
using HHECS.Dal;
using HHECS.Dal.Repository;
using HHECS.DAL;
using HHECS.DAL.Repository;
using HHECS.Executor.EquipmentHandler;
using HHECS.Infrastructure.CommonHelper;
using HHECS.Infrastructure.Enums;
using HHECS.Infrastructure.Notice;
using HHECS.Model.Entities;
using HHECS.Model.Enums;
using HHECS.Model.Enums.Machine;
using HHECS.Model.Enums.Warehouse;
using HHHECS.Model.Enums;
using Microsoft.Data.SqlClient;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using Opc.Ua;
using Org.BouncyCastle.Asn1.X509;
using System;
using System.Collections.Generic;
using System.Linq;
using static FreeSql.Internal.GlobalFilter;

namespace HHECS.BLL.EquipmentExcute.Machine
{
    /// <summary>
    /// 切割机处理类
    /// </summary>
    public class BevelExcute : StationExecute
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeSpace"></param>
        /// <param name="origin"></param>
        /// <param name="referer"></param>
        /// <param name="sendNoneGoodsPointsUrl"></param>
        public BevelExcute(EquipmentType equipmentType, string origin, string referer, string sendNoneGoodsPointsUrl) : base(equipmentType)
        {
            this.origin = origin;
            this.referer = referer;
            this.callMaterialUrl = sendNoneGoodsPointsUrl;
        }

        /// <summary>
        /// 执行上料完成
        /// 注意:allEquipments引用所有设备,此为共享应用
        /// </summary>
        /// <param name="station"></param>
        /// <param name="allEquipments"></param>
        /// <param name="plc"></param>
        /// <returns></returns>
        public override BllResult ExcuteArrive(Equipment station, List<Equipment> allEquipments, PLCCore plc, User user)
        {
            try
            {//只处理isAuto为true的工单
                var cutPlanTaskRepository = new CutPlanTaskRepository();
                var arriveBarcode = station[StationProps.ArriveBarcode.ToString()];
                var number = station[StationProps.ArriveRealAddress.ToString()];
                var cutPlanTask = new CutPlanTask();
                if (string.IsNullOrEmpty(arriveBarcode.Value))
                {
                    var cutPlanTasks = cutPlanTaskRepository.Where(t => t.IsAuto && t.NextStationAddress == station.SelfAddress && t.Status == 60).OrderBy(t => t.Id).ToList();
                    if (cutPlanTasks.Count < 1)
                    {
                        var msg = cutPlanTasks.Count > 1 ? $"{cutPlanTasks.Count}条未使用的" : $"没有找到已经到达的管材";
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】设备【{station.Name}】位置到达失败,切割方案存在{msg}");
                    }
                    cutPlanTask = cutPlanTasks[0];
                }
                else
                {
                    var convertResult = int.TryParse(arriveBarcode.Value, out int BarCode);
                    if (!convertResult)
                    {
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】的设备【{station.Name}】 位置到达失败,切割方案ID【{arriveBarcode.Value}】转化为整数失败!");
                    }
                    if (BarCode < 1)
                    {
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】的设备【{station.Name}】位置到达失败,切割方案ID【{arriveBarcode.Value}】不能小于1!");
                    }

                    cutPlanTask = cutPlanTaskRepository.Where(t => t.Id == BarCode).First();
                    if (cutPlanTask == null)
                    {
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】设备【{station.Name}】位置到达失败,没有找到切割明细");
                    }
                }
                //已经坡口次数,不包括缓存工位,用于确定左坡口还是右坡口
                //if (!station.Code.Contains("Cache"))
                //{
                //    cutPlanTask.BevelCount += 1;
                //}
                //var bevelCount = cutPlanTask.PipeEnd.Count(c => c == 'V').ToString();

                cutPlanTask.NowStation = station.Code;
                cutPlanTask.NowStationAddress = station.SelfAddress;
                cutPlanTask.NextStation = string.Empty;
                cutPlanTask.NextStationAddress = "0";
                cutPlanTask.Status = 30;
                cutPlanTask.UpdateTime = DateTime.Now;
                cutPlanTask.UpdateBy = user.UserCode;
                if (station.LineCode == "MinPipeLine")
                {
                    //大于400 走坡口流程
                    cutPlanTask.Status = cutPlanTask.IsAuto ? 30 : 100;
                }
                var angle = 250;
                if (cutPlanTask.ResidualCode.Contains("37.5"))
                {
                    angle = 375;
                }
                using (var uw = DALHelper.GetFreeSql().CreateUnitOfWork())
                {
                    try
                    {
                        cutPlanTaskRepository.UnitOfWork = uw;
                        cutPlanTaskRepository.Update(cutPlanTask);

                        BllResult sendResult = SendAckToPlc(station, plc, StationMessageFlag.WCSPLCACK, StationLoadStatus.ArriveReply, number.Value, cutPlanTask.Id.ToString(), cutPlanTask.BevelCount.ToString(), angle, 0, cutPlanTask.CuttingLength, cutPlanTask.OuterDiameter, cutPlanTask.Thickness);
                        if (sendResult.Success)
                        {
                            uw.Commit();
                            return BllResultFactory.Success($"处理工位【{station.WorkStationCode}】设备【{station.Name}】位置到达成功,工单id【{cutPlanTask.Id.ToString()}】信息写入设备成功");
                        }
                        else
                        {
                            uw.Rollback();
                            return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】设备【{station.Name}】位置到达失败,工单id【{cutPlanTask.Id.ToString()}】信息写入设备失败,原因:{sendResult.Msg}");
                        }
                    }
                    catch (Exception ex)
                    {
                        uw.Rollback();
                        return BllResultFactory.Exception(ex, $"处理工位【{station.WorkStationCode}】的设备【{station.Name}】位置到达的时候,处理工单id【{cutPlanTask.Id.ToString()}】信息发生异常,原因:{ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                return BllResultFactory.Exception(ex, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】位置到达失败时候,异常原因:{ex.Message}");
            }
        }

        /// <summary>
        /// 执行地址请求,余料和废料不请求,切割机直接翻到切割下料台
        /// 注意:allEquipments引用所有设备,此为共享应用
        /// </summary>
        /// <param name="station"></param>
        /// <param name="allEquipments"></param>
        /// <param name="plc"></param>
        /// <returns></returns>
        public override BllResult ExcuteRequest(Equipment station, List<Equipment> allEquipments, PLCCore plc, User user)
        {
            try
            {
                var address = station.GoAddress;
                var cutPlanTaskRepository = new CutPlanTaskRepository();
                var cutPlanTask = new CutPlanTask();
                var requestBarcode = station[StationProps.RequestBarcode.ToString()];
                var requestNumber = station[StationProps.RequestNumber.ToString()];
                if (string.IsNullOrEmpty(requestBarcode.Value))
                {
                    var cutPlanTasks = cutPlanTaskRepository.Where(t => t.Status == 30 && t.NowStationAddress == station.SelfAddress && t.IsAuto).ToList();
                    if (cutPlanTasks.Count < 1)
                    {
                        var msg = cutPlanTasks.Count > 1 ? $"有{cutPlanTasks.Count}条已经开始切割的管材" : $"没有找到已经开始切割的管材";
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失,切割方案{msg}");
                    }
                    cutPlanTask = cutPlanTasks[0];

                }
                else
                {
                    var convertResult = int.TryParse(requestBarcode.Value, out int BarCode);
                    if (!convertResult)
                    {
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】的设备【{station.Name}】 地址请求失败,工序任务ID【{requestBarcode.Value}】转化为整数失败!");
                    }
                    if (BarCode < 1)
                    {
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】的设备【{station.Name}】 地址请求失败,工序任务ID【{requestBarcode.Value}】不能小于1!");
                    }
                    cutPlanTask = cutPlanTaskRepository.Where(t => t.Id == BarCode).First();
                    if (cutPlanTask == null)
                    {
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,没有找到切割明细");
                    }

                }
                //下个工位
                if (station.LineCode == "MinPipeLine")
                {
                    cutPlanTask.NextStationAddress = "0";
                    cutPlanTask.Status = 100;
                }
                else
                {
                    var nextequipmentCodes = new List<Equipment>();
                    var bevelEquipments = allEquipments.Where(t => t.EquipmentTypeId == station.NextEquipmentTypeId && !t.Code.Contains("Cache")).OrderBy(t => t.Id).ToList();
                    if (station.Code.Contains("BevelCache"))
                    {
                        if (cutPlanTask.BevelCount == 0)
                        {
                            //直接下料需要检查 坡口机是不是在执行,坡口机执行工单的长度如果大于2m,则等待
                            bevelEquipments = CutExcute.ChekBevelLength(station, allEquipments, ref bevelEquipments, cutPlanTaskRepository);
                            if (bevelEquipments.Any())
                            {
                                return BllResultFactory.Create(BllResultCode.Warning, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,坡口存在工件过长,不能直接下料");
                            }
                            else
                            {
                                //无需坡口,直接下料
                                cutPlanTask.Status = 100;
                                cutPlanTask.NextStationAddress = "2010";

                            }
                        }
                        else if (cutPlanTask.BevelCount == 2)
                        {
                            //去缓存或者去左坡口
                            var bevelSteps = allEquipments.Where(t => t.Code == "Max_LeftBevel").OrderBy(t => t.Id).ToList();
                            var result = CutExcute.ChekEquipment(station, allEquipments, cutPlanTask, ref bevelSteps, cutPlanTaskRepository);
                            if (result.Success)
                            {
                                cutPlanTask.Status = 60;
                                cutPlanTask.NextStationAddress = result.Data[0].SelfAddress;
                                cutPlanTask.NextStation = result.Data[0].Code;
                            }
                            else
                            {
                                return BllResultFactory.Create(BllResultCode.Warning, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,{result.Msg}");
                            }
                        }
                        else if (cutPlanTask.BevelCount == 1)
                        {
                            //如果只需要坡口1次则判断长度如果大于2m则优先去右坡口,右坡口存在则再去左坡口
                            var leftBevel = allEquipments.Where(t => t.Code == "Max_LeftBevel").First();
                            var rightBevel = allEquipments.Where(t => t.Code == "Max_RightBevel").First();
                            var bevelSteps = allEquipments.Where(t => t.EquipmentTypeId == station.NextEquipmentTypeId&&!t.Code.Contains("Cache")).OrderBy(t => t.Id).ToList();
                            //if (cutPlanTask.CuttingLength > leftBevel.ColumnIndex)
                            //{
                            //}
                            int index = bevelSteps.IndexOf(rightBevel);
                            // 如果找到该元素
                            if (index != -1)
                                // 删除该元素
                                bevelSteps.RemoveAt(index);
                            // 将元素插入到第一个位置
                            bevelSteps.Insert(0, rightBevel);
                            var result = CutExcute.ChekEquipment(station, allEquipments, cutPlanTask, ref bevelSteps, cutPlanTaskRepository);
                            if (result.Success)
                            {
                                cutPlanTask.Status = 60;
                                cutPlanTask.NextStationAddress = result.Data[0].SelfAddress;
                                cutPlanTask.NextStation = result.Data[0].Code;
                            }
                            else
                            {
                                return BllResultFactory.Create(BllResultCode.Warning, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,{result.Msg}");
                            }
                        }
                    }
                    else if (station.Code == "Max_LeftBevel")
                    {
                        if (cutPlanTask.BevelCount == 2)
                        {
                            //去右坡口
                            var bevelSteps = allEquipments.Where(t => t.Code == "Max_RightBevel").OrderBy(t => t.Id).ToList();
                            var result = CutExcute.ChekEquipment(station, allEquipments, cutPlanTask, ref bevelSteps, cutPlanTaskRepository);
                            if (result.Success)
                            {
                                cutPlanTask.Status = 60;
                                cutPlanTask.NextStationAddress = result.Data[0].SelfAddress;
                                cutPlanTask.NextStation = result.Data[0].Code;
                            }
                            else
                            {
                                return BllResultFactory.Create(BllResultCode.Warning, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,{result.Msg}");
                            }
                        }
                        else if (cutPlanTask.BevelCount == 1)
                        {
                            bevelEquipments = bevelEquipments.Where(t => t.Code == "Max_RightBevel").ToList();
                            //直接下料需要检查 右坡口机是不是在执行,坡口机执行工单的长度如果大于2m,则等待
                            bevelEquipments = CutExcute.ChekBevelLength(station, allEquipments, ref bevelEquipments, cutPlanTaskRepository);
                            if (bevelEquipments.Any())
                            {
                                return BllResultFactory.Create(BllResultCode.Warning, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,坡口存在工件过长,不能直接下料");
                            }
                            else
                            {
                                //无需坡口,直接下料
                                cutPlanTask.Status = 100;
                                cutPlanTask.NextStationAddress = "2010";
                            }
                        }
                    }
                    else if (station.Code == "Max_RightBevel")
                    {
                        //检查rgv是否空闲,下个工位下线
                        cutPlanTask.NextStationAddress = station.GoAddress;
                        cutPlanTask.Status = 100;
                    }
                    else
                    {
                        return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,当前设备不属于坡口工序");
                    }
                    var rgv = allEquipments.Find(t => t.Code.Contains("RGV"));
                    var rgvStatus = rgv[StationProps.RGVStatus.ToString()];
                    if (rgvStatus.Value != EquipmentStatus.空闲.GetIndexString())
                    {
                        return BllResultFactory.Create(BllResultCode.Warning, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,原因:RGV状态不是空闲");
                    }
                    //检查RGV是否有正在下料的任务//&& t.NextStationAddress == "2010"
                    var cutPlanTasks = cutPlanTaskRepository.Where(t => t.Status == 60 && t.IsAuto&& t.LineCode == "MaxPipeLine").ToList();
                    if (cutPlanTasks.Any())
                    {
                        return BllResultFactory.Create(BllResultCode.Warning, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,原因:RGV存在下料任务请等待");
                    }
                }
                using (var uw = DALHelper.GetFreeSql().CreateUnitOfWork())
                {
                    try
                    {

                        cutPlanTaskRepository.UnitOfWork = uw;
                        cutPlanTaskRepository.Update(cutPlanTask);


                        var sendResult = SendAddressReplyToPlc(station, plc, StationMessageFlag.WCSAddressReply, StationLoadStatus.Default, requestNumber.Value, cutPlanTask.Id.ToString(), cutPlanTask.NextStationAddress, "0", 0, cutPlanTask.CuttingLength, cutPlanTask.OuterDiameter, cutPlanTask.Thickness);
                        if (sendResult.Success)
                        {
                            uw.Commit();
                            return BllResultFactory.Success($"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求成功,工单id【{cutPlanTask.Id}】信息写入设备成功");
                        }
                        else
                        {
                            uw.Rollback();
                            return BllResultFactory.Error($"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,工单id【{cutPlanTask.Id}】信息写入设备失败,原因:{sendResult.Msg}");
                        }
                    }
                    catch (Exception ex)
                    {
                        uw.Rollback();
                        return BllResultFactory.Exception(ex, $"处理工位【{station.WorkStationCode}】的设备【{station.Name}】地址请求失败,处理工单id【{cutPlanTask.Id}】信息发生异常,原因:{ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                return BllResultFactory.Exception(ex, $"处理工位【{station.WorkStationCode}】设备【{station.Name}】地址请求失败,异常原因:{ex.Message}");
            }

        }


        public static string Chek(Equipment equipment, List<Equipment> allEquipments, CutPlanTaskRepository cutPlanTaskRepository, Equipment nextStation)
        {
            var msg = "";
            var leftTask = cutPlanTaskRepository.Where(t => t.Status < 100 && t.Status > 0 && t.IsAuto && t.NowStation == nextStation.SelfAddress).ToList();
            if (leftTask.Any())
            {
                return msg = $"处理工位【{equipment.WorkStationCode}】设备【{equipment.Name}】地址请求失败,左坡口存在任务[{leftTask[0].Id}]";
            }
            var OperationModel = nextStation[StationProps.OperationModel.ToString()];
            var TotalError = nextStation[StationProps.TotalError.ToString()];
            var AllowEntry = nextStation[StationProps.AllowEntry.ToString()];
            if (OperationModel.Value != OperationModelFlag.Online.GetIndexString() || TotalError.Value != TotalErrorFlag.Normal.GetIndexString() || AllowEntry.Value != StationAllowEntry.Allow.GetIndexString())
            {
                var tempMsg = "";
                if (OperationModel.Value != OperationModelFlag.Online.GetIndexString())
                {
                    tempMsg += $"联机、";
                }
                if (TotalError.Value != TotalErrorFlag.Normal.GetIndexString())
                {
                    tempMsg += $"无故障、";
                }
                if (AllowEntry.Value != StationAllowEntry.Allow.GetIndexString())
                {
                    tempMsg += $"允许放货";
                }
                return msg = $"处理工位【{equipment.WorkStationCode}】设备【{equipment.Name}】地址请求失败,-{nextStation.Code}工位不满足[{tempMsg}-{nextStation.Name}设备信号异常";
            }
            return msg = string.Empty;
        }
    }
}