schangxiang@126.com
2025-04-17 37184b1d1ac000a6ee40e397e2336b213e705902
CC/iWareCC_ASRS/Common/Helper/MyExtendHelper.cs
@@ -1,17 +1,22 @@
using iWareCommon.Common.Globle;
using Admin.NET.Application;
using iWareCC.SrmService;
using iWareCC.StationService;
using iWareCommon.Common.Globle;
using iWareCommon.Utils;
using iWareModel;
using iWareModel.EnumType.XiGangPublicCommon;
using iWareSql.DataAccess;
using iWareSql.DBModel;
using iWareSql.WmsDBModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XiGang.Core.Model;
using LogType = iWareCommon.Utils.LogType;
namespace iWareCC.Common.Helper
{
@@ -20,6 +25,252 @@
    /// </summary>
    public class MyExtendHelper
    {
        /// <summary>
        /// 验证某个包 是否只有一个UPI
        /// </summary>
        /// <param name="wmsDB"></param>
        /// <param name="upi"></param>
        /// <returns>true:只有一个 </returns>
        public static bool IsOnlyOneInPackage(WmsDBModel wmsDB, string upi)
        {
            var upiObj = wmsDB.mes_batchOrderUPI_new.Where(x => x.UPI == upi).FirstOrDefault();
            if (upiObj != null)
            {
                var num = wmsDB.mes_batchOrderUPI_new.Where(x => x.PackageCode == upiObj.PackageCode).Count();
                if (num == 1)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 公共的控制请求对象字典
        /// </summary>
        public static IDictionary<string, ControlRequest> controlRequestDicts = new Dictionary<string, ControlRequest>();
        /// <summary>
        /// 公共的控制请求对象字典赋值
        /// </summary>
        /// <param name="placeNo"></param>
        /// <param name="result"></param>
        /// <param name="msg"></param>
        public static void SetValueControlRequestDicts(string placeNo, bool result, string msg)
        {
            if (controlRequestDicts.ContainsKey(placeNo))
            {
                controlRequestDicts[placeNo].IsSuccess = result;
                controlRequestDicts[placeNo].LastTime = DateTime.Now;
                controlRequestDicts[placeNo].PlaceNo = placeNo;
                if (result)
                {
                    controlRequestDicts[placeNo].Count = 0;
                    controlRequestDicts[placeNo].ErrMsg = "";
                }
                else
                {
                    controlRequestDicts[placeNo].Count++;
                    controlRequestDicts[placeNo].ErrMsg = msg;
                }
            }
            else
            {
                if (result)
                {
                    controlRequestDicts.Add(placeNo, new ControlRequest()
                    {
                        PlaceNo = placeNo,
                        Count = 0,
                        LastTime = DateTime.Now,
                        ErrMsg = msg,
                        IsSuccess = result
                    });
                }
                else
                {
                    controlRequestDicts.Add(placeNo, new ControlRequest()
                    {
                        PlaceNo = placeNo,
                        Count = 1,
                        LastTime = DateTime.Now,
                        ErrMsg = msg,
                        IsSuccess = result
                    });
                }
            }
        }
        /// <summary>
        /// 验证是否允许给PLC发报警
        /// </summary>
        /// <param name="placeNo"></param>
        /// <returns></returns>
        public static bool ValidateIsAllowRequest(string placeNo, LogType logType)
        {
            if (controlRequestDicts.ContainsKey(placeNo))
            {
                if (controlRequestDicts[placeNo].IsSuccess == false)
                {
                    //var diff = DateTime.Now - controlRequestDicts[placeNo].LastTime;
                    //if (diff.Seconds <= 10)
                    //{//如果连续请求在10秒内,则认为 不需要再次请求
                    //    WZ.Useful.Commons.LogTextHelper.WriteLine("CommonControl", "ValidateIsAllowRequest", "如果连续请求在10秒内,则认为 不需要再次请求,间隔" + diff.Seconds + "秒,placeNo:" + placeNo);
                    //    return false;
                    //}
                    if (controlRequestDicts[placeNo].Count <= 5)
                    {//如果连续请求在5次内,则认为 不需要再次请求
                        var msg = "如果连续请求在5次内,则认为 不需要再次请求,间隔" + controlRequestDicts[placeNo].Count + "个,placeNo:" + placeNo;
                        Log4NetHelper.WriteInfoLog(logType, msg);
                        return false;
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// 生成最新的任务号
        /// </summary>
        /// <param name="wmsDB"></param>
        /// <param name="rbTaskTypeEnum"></param>
        /// <param name="plcTaskNo"></param>
        /// <returns></returns>
        public static string GetNewTaskNo(WmsDBModel wmsDB, RbTaskTypeEnum rbTaskTypeEnum, string plcTaskNo)
        {
            //判断如果任务号跟上一个任务号重复,就自动减去1
            var lastTask = wmsDB.wms_rbline_task.Where(x => x.RbTaskType == (int)rbTaskTypeEnum).OrderByDescending(x => x.Id).FirstOrDefault();
            if (lastTask != null && lastTask.TaskNo == plcTaskNo)
            {
                plcTaskNo = (Convert.ToInt32(plcTaskNo) - 1).ToString();
            }
            else
            {
            }
            return plcTaskNo;
        }
        /// <summary>
        /// 写入 报警信息
        /// </summary>
        /// <param name="warningAddress"></param>
        /// <returns></returns>
        public static async Task<iWareCC.StationService.SdaResEntity> WriteBoolPlcDataForWarning(string warningAddress)
        {
            using (StationServiceClient client = new StationServiceClient())
            {
                var res = await client.WriteBoolPlcDataAsync((int)EDevice.Station, "3000|" + warningAddress, true);
                return res;
            }
        }
        /// <summary>
        /// 处理 表 mes_order_gather
        /// </summary>
        /// <param name="wmsDB"></param>
        /// <param name="package"></param>
        /// <param name="qitaoValue"></param>
        /// <param name="_UnlinePerson"></param>
        /// <param name="errMsg"></param>
        /// <returns></returns>
        public static bool HandlerOrderGather(WmsDBModel wmsDB, mes_package_gather package, string qitaoValue, string _UnlinePerson, out string errMsg)
        {
            errMsg = "";
            //处理表  mes_order_gather
            if (package == null)
            {
                return true;
            }
            var isAddOrder = false;
            var packageList = wmsDB.mes_package_gather.Where(x => x.Info5 == package.Info5).ToList();
            if (packageList == null || packageList?.Count == 0)
            {
                errMsg = $"没有找到生产单号{package.Info5}的汇总数据";
                return false;
            }
            var order = wmsDB.mes_order_gather.Where(x => x.Info5 == package.Info5).FirstOrDefault();
            if (order != null)
            {
            }
            else
            {
                order = new mes_order_gather()
                {
                    Id = Yitter.IdGenerator.YitIdHelper.NextId(),
                    Info5 = package.Info5,
                    OrderId = package.OrderId,
                    PlanNo = package.PlanNo,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    CreateUserName = SysGloble.WCSSystem,
                    UpdateUserName = SysGloble.WCSSystem
                };
                isAddOrder = true;
            }
            order.PackageNum = packageList.Count();
            order.UnLinePackageNum = packageList.Where(x => x.UpiStatus == (int)UpiStatusEnum.已下线).Count();
            if (order.UnLinePackageNum > order.PackageNum)
            {
                order.UnLinePackageNum = order.PackageNum;
            }
            order.NgPackageNum = packageList.Where(x => x.UpiStatus == (int)UpiStatusEnum.已下线 && x.UpiFlag == (int)UpiFlagEnum.NG).Count();
            if (order.NgPackageNum > order.PackageNum)
            {
                order.NgPackageNum = order.PackageNum;
            }
            order.NoUnLinePackageNum = order.PackageNum - order.UnLinePackageNum;
            order.AllPackageArea = packageList.Sum(x => Convert.ToDecimal(x.Info13));
            order.ScanPackageArea = packageList.Where(x => x.UpiStatus == (int)UpiStatusEnum.已下线 && x.UpiFlag == (int)UpiFlagEnum.正常).Sum(x => Convert.ToDecimal(x.Info13));
            order.NoScanPackageArea = order.AllPackageArea - order.ScanPackageArea;
            /*
            var order_unLine = false;
            //查询下一个包是不是属于该订单
            var newLineQueue = wmsDB.mes_package_linequeue.OrderBy(x => x.Id).FirstOrDefault();
            if (newLineQueue != null && newLineQueue.Info5 != order.Info5)
            {
                //表示是 切换 新订单了,该订单要更新为 已下线。
                order_unLine = true;
            }
            else
            {
                //判断该订单是否已下线
                if (order.PackageNum == order.UnLinePackageNum)
                {
                    order_unLine = true;
                }
            }
            //判断该订单是否已下线
            if (order_unLine)
            {
                order.IsUnline = true;
                order.UnlineTime = DateTime.Now;
                order.UnlinePerson = _UnlinePerson;
            }
            else
            {
                order.IsUnline = false;
            }
            //*/
            if (isAddOrder)
            {
                wmsDB.mes_order_gather.Add(order);
            }
            return true;
        }
        /// <summary>
        /// 配置缺料原因
@@ -517,270 +768,6 @@
        #endregion
        /// <summary>
        /// 新建转运任务
        /// </summary>
        /// <param name="flag">1:转移到1014位置 2:转移到立体库中  3:1009到1011 4:立体库到1014位置 </param>
        /// <param name="rgvEDevice">RGV设备号</param>
        /// <param name="user"></param>
        /// <param name="store"></param>
        /// <returns></returns>
        public static FunRetEntity AddTransferTask(AddTransferTaskEnum flag, EDevice rgvEDevice, SysUser user, V_AllStore store)
        {
            FunRetEntity fr = new FunRetEntity();
            var errMsg = "";
            var remark = "新增转运任务";
            try
            {
                #region 事务
                #endregion
                using (DbModel edm = new DbModel())
                {
                    //增加验证 【EditBy shaocx,2022-04-28】
                    switch (flag)
                    {
                        case AddTransferTaskEnum.位置1011转移到1014位置:
                        case AddTransferTaskEnum.位置1011转移到立体库中:
                            //去掉这个验证,前面允许创建任务就创建吧 【EditBy shaocx,2022-05-15】
                            /*
                            var isAllow = IsAllowCreateTaskForInStore(edm, ref errMsg);
                                if (!isAllow)
                                {
                                    return FunRetEntity.Fail(errMsg);
                                }
                                //*/
                            break;
                    }
                    using (var trans = edm.Database.BeginTransaction())
                    {
                        try
                        {
                            Task_Main mainTask = new Task_Main();
                            mainTask.IsVirtual = false;//非虚拟入库
                            mainTask.TaskNo = TaskNoHelper.GenerateTaskNo("TR");
                            mainTask.TaskName = "空托转运";
                            #region 获取任务起点
                            //起点
                            var realSourcePlace = "";
                            Base_Station sourcePlace = null;
                            if (flag == AddTransferTaskEnum.立体库到1014位置)
                            {//4:立体库到1014位置
                                var srmStore = MyExtendHelper.FindStoreForEmptySalverTo1014(edm, ref errMsg);
                                if (srmStore == null)
                                {
                                    return FunRetEntity.Fail(errMsg);
                                }
                                store = ClassHelper.RotationMapping<V_AllStore, V_Store>(srmStore);
                                sourcePlace = StationHandler.GetPlaceByPlaceId(store.StationId, edm);
                                realSourcePlace = sourcePlace.SrmStationCode;
                                //记录区域 [EditBy shaocx,2022-05-02]
                                var device = BusinessHelper.GetSrmDeviceByPlaceNo(sourcePlace.SrmStationCode);
                                mainTask.Area = ((int)device).ToString();
                            }
                            else if (flag == AddTransferTaskEnum.位置1014到1020)
                            {//5:位置1014到1020
                                sourcePlace = StationHandler.GetPlaceByPlaceId(store.StationId, edm);
                                realSourcePlace = sourcePlace.RgvStationCode;
                            }
                            else
                            {
                                var getSourcePlaceResult = StationHandler.GetTargtStationForAddTransferTask(edm, rgvEDevice, ref errMsg, ref sourcePlace);
                                if (getSourcePlaceResult.result == false) return getSourcePlaceResult;
                                realSourcePlace = sourcePlace.RgvStationCode;
                            }
                            mainTask.SourcePlace = sourcePlace.Id;
                            mainTask.RealSourcePlace = realSourcePlace;
                            #endregion
                            #region 获取中间点和目标点
                            Base_Station toPlace = null;
                            Base_Station midPlace = null;
                            var getMidToPlaceResult = MainTaskHandler.GetMidToPlaceForAddTransferTask(sourcePlace, flag, edm, ref errMsg, ref toPlace, ref midPlace, ref mainTask);
                            if (getMidToPlaceResult.result == false) return getMidToPlaceResult;
                            #endregion
                            SetTaskTypeStateAndInOutFlagForMainTask(flag, ref mainTask);
                            Base_Salver salver = null;
                            Base_Material newMaterial = null;
                            if (store == null)
                            {//新建物料,新建托盘,新建绑定关系
                                //绑定托盘和站点的关系
                                //新建物料
                                var salverStackCount = GetSalverStackCountForBackToStore();
                                if (salverStackCount == 0)
                                {
                                    //报错
                                    return FunRetEntity.Fail("根据1009站点的光电获取返回立体库的托盘数为0");
                                }
                                newMaterial = MaterialHandler.CreateEmptySlaverMaterial(edm, "空托盘转运时创建", salverStackCount);
                                //判断托盘是否存在,如果存在,就不需要重建,如果不存在,就新建托盘
                                salver = SalverHandler.CreateVirtualSalver(edm, "空托盘转运");
                                if (!string.IsNullOrEmpty(errMsg))
                                {
                                    return FunRetEntity.Fail(errMsg);
                                }
                                //绑定托盘和物料的关系
                                Salver_Material_Handler.CreateCvIRelation(edm, user.Name, salver, newMaterial, remark);
                                //绑定托盘和站点的关系
                                Salver_Station_Handler.CreateCvPRelation(edm, user.Name, salver, sourcePlace, Salver_V_Station_StateEnum.入库绑定, remark);
                            }
                            else
                            {
                                salver = SalverHandler.GetSalveById(edm, store.SalverId);
                                newMaterial = MaterialHandler.GetMaterialById(edm, store.MaterialId);
                            }
                            mainTask.SalverId = salver.Id;
                            mainTask.SalverCode = salver.SalverCode;
                            mainTask.MaterialId = newMaterial.Id;
                            //物料信息
                            MainTaskHandler.SetMaterialForMainTask(ref mainTask, newMaterial);
                            //序列号和订货号赋值  [Editby shaocx,2022-04-05]
                            mainTask.SerialNumber = "";
                            mainTask.OrderNo = "";
                            mainTask.CreateTime = mainTask.ModifyTime = mainTask.StartTime = DateTime.Now;
                            mainTask.CreateBy = mainTask.ModifyBy = user.Name;
                            mainTask.CreateId = mainTask.ModifyId = user.ID;
                            mainTask.OperationRemark = "添加";
                            string taskSequenceGuid = "";
                            mainTask.TaskSequence = MainTaskHandler.GenerateTaskSequence(edm, ref taskSequenceGuid);//生成任务序列号
                            mainTask.TaskSequenceGuid = taskSequenceGuid;
                            edm.Task_Main.Add(mainTask);
                            edm.SaveChanges();//保存一次,此时mainTask的自增ID就有值了
                            var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask();
                            var createTime = DateTime.Now;
                            if (flag == AddTransferTaskEnum.位置1011转移到1014位置)
                            {//转移到1014位置
                                //创建RGV任务
                                FunRetEntity fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.RGV, user.Name, 1, DeviceTaskTypeEnum.空托转运到拆盘机入口, mainTask, salver, sourcePlace, toPlace, remark);
                                if (fre.result == false)
                                {
                                    throw new Exception(fr.resMsg);
                                }
                            }
                            else if (flag == AddTransferTaskEnum.位置1011转移到立体库中)
                            {//转移到立体库中
                                //创建RGV任务
                                FunRetEntity fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.RGV, user.Name, 1, DeviceTaskTypeEnum.空托转运到立体库, mainTask, salver, sourcePlace, midPlace, remark);
                                if (fre.result == false)
                                {
                                    throw new Exception(fr.resMsg);
                                }
                                //创建堆垛机任务
                                fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.堆垛机, user.Name, 2, DeviceTaskTypeEnum.空托转运到立体库, mainTask, salver, midPlace, toPlace, remark);
                                if (fre.result == false)
                                {
                                    throw new Exception(fr.resMsg);
                                }
                            }
                            else if (flag == AddTransferTaskEnum.位置1009到位置1011)
                            {// 3:1009到1011
                                //创建RGV任务
                                FunRetEntity fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.RGV, user.Name, 1, DeviceTaskTypeEnum.空托缓存位转运, mainTask, salver, sourcePlace, toPlace, remark);
                                if (fre.result == false)
                                {
                                    throw new Exception(fr.resMsg);
                                }
                            }
                            else if (flag == AddTransferTaskEnum.立体库到1014位置)
                            {//4:立体库到1014位置
                                //创建堆垛机任务
                                FunRetEntity fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.堆垛机, user.Name, 1, DeviceTaskTypeEnum.立库空托到拆盘机入口, mainTask, salver, sourcePlace, midPlace, remark);
                                if (fre.result == false)
                                {
                                    throw new Exception(fr.resMsg);
                                }
                                //创建RGV任务
                                fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.RGV, user.Name, 2, DeviceTaskTypeEnum.立库空托到拆盘机入口, mainTask, salver, midPlace, toPlace, remark);
                                if (fre.result == false)
                                {
                                    throw new Exception(fr.resMsg);
                                }
                            }
                            else if (flag == AddTransferTaskEnum.位置1014到1020)
                            {//5:1014到1020位置
                                //创建RGV任务
                                FunRetEntity fre = PartTaskHandler.CreatePartTask(createTime, plcTaskNo, edm, EDeviceType.RGV, user.Name, 1, DeviceTaskTypeEnum.拆盘机入口到拆盘机, mainTask, salver, sourcePlace, toPlace, remark);
                                if (fre.result == false)
                                {
                                    throw new Exception(fr.resMsg);
                                }
                            }
                            edm.SaveChanges();//第二次保存
                            trans.Commit();//事务提交
                        }
                        catch (Exception ex)
                        {
                            trans.Rollback();
                            throw ex;
                        }
                    }
                    return FunRetEntity.Success("成功");
                }
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
        private static void SetTaskTypeStateAndInOutFlagForMainTask(AddTransferTaskEnum flag, ref Task_Main mainTask)
        {
            var _InOutFlag = default(MainInOutFlagEnum);
            var _taskType = default(MainTaskTypeEnum);
            var _taskState = default(MainTaskStatusEnum);
            switch (flag)
            {
                case AddTransferTaskEnum.立体库到1014位置:
                    _taskType = MainTaskTypeEnum.自动出库;
                    _taskState = MainTaskStatusEnum.出库中;
                    _InOutFlag = MainInOutFlagEnum.出库;
                    break;
                case AddTransferTaskEnum.位置1009到位置1011:
                case AddTransferTaskEnum.位置1011转移到1014位置:
                case AddTransferTaskEnum.位置1014到1020:
                    _taskType = MainTaskTypeEnum.空托转运;
                    _taskState = MainTaskStatusEnum.待转运;
                    _InOutFlag = MainInOutFlagEnum.转运;
                    break;
                case AddTransferTaskEnum.位置1011转移到立体库中:
                    _taskType = MainTaskTypeEnum.自动入库;
                    _taskState = MainTaskStatusEnum.入库中;
                    _InOutFlag = MainInOutFlagEnum.入库;
                    break;
                default:
                    throw new Exception("不支持的类型");
            }
            mainTask.TaskType = Convert.ToInt32(_taskType);
            mainTask.TaskTypeName = _taskType.ToString();
            mainTask.TaskState = Convert.ToInt32(_taskState);
            mainTask.TaskStateName = _taskState.ToString();
            mainTask.InOutFlag = (int)_InOutFlag;
            mainTask.InOutFlagName = _InOutFlag.ToString();
        }
        /// <summary>
        /// 是否允许给1014发送目标点是1014的任务
        /// </summary>
        /// <param name="context"></param>
@@ -889,58 +876,7 @@
        public static FunRetEntity DoHandler(DbModel context, V_AllStore store, EDevice rgvStationCode)
        {
            try
            {
                SysUser user = new SysUser()
                {
                    ID = 0,
                    Name = SysGloble.WCSSystem
                };
                if (rgvStationCode == EDevice.空托缓存1011)
                {
                    //判断1014是否有空位
                    var queryRgvStationCode = ((int)EDevice.拆盘机入口1014).ToString();
                    V_AllStore my1014Store = null;
                    var isAllow = MyExtendHelper.IsAllowSendTaskToPlace1014(context, queryRgvStationCode, ref my1014Store);
                    if (isAllow)
                    {
                        return AddTransferTask(AddTransferTaskEnum.位置1011转移到1014位置, rgvStationCode, user, store);
                    }
                    else
                    {
                        //寻找立体库是否有库存
                        return AddTransferTask(AddTransferTaskEnum.位置1011转移到立体库中, rgvStationCode, user, store);
                    }
                    //*/
                    //var isGD_HasCatogryForRgvStattion = IsGD_HasCatogryForRgvStattion(queryRgvStationCode);
                    //var store_1014_count = context.V_AllStore.Where(x => x.RgvStationCode == queryRgvStationCode).Count();
                    //if (store_1014_count > 0 || isGD_HasCatogryForRgvStattion)
                    //{
                    //}
                    //else
                    //{//1014无货,创建任务
                    //    return MainTaskHandler.AddTransferTask(AddTransferTaskEnum.转移到1014位置, rgvStationCode, user, store);
                    //}
                }
                else if (rgvStationCode == EDevice.空托缓存1009)
                {
                    return AddTransferTask(AddTransferTaskEnum.位置1009到位置1011, rgvStationCode, user, store);
                }
                else if (rgvStationCode == EDevice.拆盘机入口1014)
                {//拆盘机入口1014处新建从立体库叫托盘任务
                    return AddTransferTask(AddTransferTaskEnum.立体库到1014位置, rgvStationCode, user, store);
                }
                else if (rgvStationCode == EDevice.拆盘机1020)
                {// 从1014到1020
                    return AddTransferTask(AddTransferTaskEnum.位置1014到1020, rgvStationCode, user, store);
                }
                return null;
            }
            catch (Exception ex)
            {
                return FunRetEntity.Fail("新增空托盘转运任务异常:" + ex.Message);
            }
            return null;
        }
        /// <summary>