zhaowc
2025-02-28 157abc191c34e57c1b958ae74fc3de6518ca8a30
Wms/WMS.BLL/BllPdaServer/PdaCrServer.cs
@@ -1,11 +1,21 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Model.InterFaceModel;
using Model.ModelDto.BllCheckDto;
using Model.ModelDto.LogDto;
using Model.ModelDto.PdaDto;
using Model.ModelDto.SysDto;
using Model.ModelVm;
using Newtonsoft.Json;
using SqlSugar;
using Utility.Tools;
using WMS.BLL.LogServer;
using WMS.BLL.SysServer;
using WMS.DAL;
using WMS.Entity.BllAsnEntity;
using WMS.Entity.BllCheckEntity;
@@ -776,7 +786,7 @@
                var storageArea = new List<SysStorageArea>();
                if (string.IsNullOrEmpty(palletNo))
                {
                    storageArea = Db.Queryable<SysStorageArea>().Where(w => w.IsDel == "0" && w.Status == "0" && w.WareHouseNo == "W02").OrderBy(o=>o.AreaNo).ToList();
                    storageArea = Db.Queryable<SysStorageArea>().Where(w => w.IsDel == "0" && w.Status == "0" && w.WareHouseNo == "W02").OrderBy(o => o.AreaNo).ToList();
                }
                else
                {
@@ -789,16 +799,16 @@
                    {
                        throw new Exception("托盘储位信息不存在,请检查!");
                    }
                    if (models.WareHouseNo != "W02")
                    {
                        throw new Exception("该托盘未在平库内,请检查!");
                    }
                    //if (models.WareHouseNo != "W02")
                    //{
                    //    throw new Exception("该托盘未在平库内,请检查!");
                    //}
                    var storageLocat = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == models.LocatNo);
                    if (storageLocat == null)
                    {
                        throw new Exception("储位信息不存在,请检查!");
                    }
                    if (storageLocat.AreaNo.Contains("B0"))
                    {
                        storageArea = Db.Queryable<SysStorageArea>().Where(w => w.IsDel == "0" && w.Status == "0" && w.AreaNo.Contains("B0") && w.WareHouseNo == "W02").OrderBy(o => o.AreaNo).ToList();
@@ -807,7 +817,7 @@
                    {
                        storageArea = Db.Queryable<SysStorageArea>().Where(w => w.IsDel == "0" && w.Status == "0" && w.AreaNo.Contains("B1") && w.WareHouseNo == "W02").OrderBy(o => o.AreaNo).ToList();
                    }
                }
                }
                return storageArea;
            }
            catch (Exception ex)
@@ -823,7 +833,7 @@
        {
            try
            {
                var allotList = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && m.Status == "2").Select(m => m.SONo).Distinct().ToList();
                var allotList = Db.Queryable<BllExportNotice>().Where(m => m.IsDel == "0" && (m.Status == "3" || m.Status == "4")).Select(m => m.SONo).Distinct().ToList();
                return allotList;
            }
            catch (Exception ex)
@@ -880,7 +890,7 @@
        /// <param name="palletNo"></param>
        /// <param name="areaNo"></param>
        /// <param name="ruku"></param>
        public void AgvTransport(string palletNo, string areaNo, string ruku, int userId)
        public void AgvTransport(string palletNo, string areaNo, string ruku, int userId, string url, string wcsurl)
        {
            if (string.IsNullOrEmpty(palletNo))
            {
@@ -893,16 +903,17 @@
            if (!string.IsNullOrEmpty(areaNo) && !string.IsNullOrEmpty(ruku))
            {
                throw new Exception("目标区域和入库口不能同时选择!");
            }
            }
            try
            {
                string EndLocat = string.Empty;//目标位置
                string EndLocat = string.Empty,OrderTy = "";//目标位置
                var tasktype = "D00";  //小车任务类型,默认为点到点任务
                var log = Db.Queryable<LogTask>().First(w => w.IsDel == "0" && w.PalletNo == palletNo && (w.Status == "0" || w.Status == "1"));
                if (log != null)
                {
                    throw new Exception("该托盘已有小车等待执行或正在执行的任务!");
                }
                }
                var stockDetail = Db.Queryable<DataStockDetail>().First(w => w.IsDel == "0" && w.PalletNo == palletNo);
                if (stockDetail == null)
                {
@@ -915,11 +926,15 @@
                    {
                        throw new Exception("所选区域信息不存在,请检查!");
                    }
                    EndLocat = GetLocat(areaNo, stockDetail.SkuNo, stockDetail.LotNo,palletNo);
                    EndLocat = GetLocat(areaNo, stockDetail.SkuNo, stockDetail.LotNo, palletNo);
                    OrderTy = "3";//移库
                }
                else
                {
                    EndLocat = ruku;
                    OrderTy = "0";//入库
                }
                var stock = Db.Queryable<DataStock>().First(w => w.IsDel == "0" && w.SkuNo == stockDetail.SkuNo && w.LotNo == stockDetail.LotNo);
                if (stock == null)
@@ -950,9 +965,36 @@
                        throw new Exception("目标储位信息不存在,请检查!");
                    }
                }
                //开启事务
                Db.BeginTran();
                //请求WCS入库口放货确认
                if (!string.IsNullOrEmpty(ruku))
                {
                    try
                    {
                        var port = new
                        {
                            Port = EndLocat
                        };
                        var json = JsonConvert.SerializeObject(port);
                        var res = HttpHelper.DoPost(wcsurl, json, "请求WCS入库口是否可放货", "WCS");
                        //////解析返回数据
                        var ret = JsonConvert.DeserializeObject<WcsModel>(res);
                        if (ret.StatusCode == -1)
                        {
                            throw new Exception(EndLocat + "号入库口已有其他任务占用,请选择其他入库口");
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                }
                //添加出库任务
                var taskNo = new Common().GetMaxNo("TK");
@@ -970,9 +1012,9 @@
                    IsSend = 1,//是否可再次下发
                    IsCancel = 1,//是否可取消
                    IsFinish = 1,//是否可完成
                    Type = "2",//任务类型 0 入库任务 1 出库任务  2 移库任务
                    Type = OrderTy,//任务类型 0 入库任务 1 出库任务  2 移库任务
                    Status = "0",//任务状态0:等待执行1正在执行2执行完成
                    OrderType = "3",//0 入库单 1 出库单  2 盘点单  3 移库单
                    OrderType = OrderTy,//0 入库单 1 出库单  2 盘点单  3 移库单
                    CreateTime = DateTime.Now
                };
@@ -980,11 +1022,11 @@
                //修改库存明细信息
                stockDetail.Status = "4";//移库锁定
                stockDetail.LockQty = stockDetail.Qty;//锁定库存数量
                //stockDetail.LockQty = stockDetail.Qty;//锁定库存数量
                Db.Updateable(stockDetail).ExecuteCommand();
                //修改库存信息
                stock.LockQty += (decimal)stockDetail.Qty;
                Db.Updateable(stock).ExecuteCommand();
                //stock.LockQty += (decimal)stockDetail.Qty;
                //Db.Updateable(stock).ExecuteCommand();
                //修改起始储位地址状态
                storageLocat.Status = "5";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 
@@ -995,15 +1037,101 @@
                {
                    storageLocatEnd.Status = "4";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 
                    Db.Updateable(storageLocatEnd).ExecuteCommand();
                }
                }
                //添加操作日志记录
                var k = new OperationCrServer().AddLogOperationCr("PDA模块", "AGV转运", palletNo, "移库", $"PDA呼叫小车对托盘号:{palletNo}发起转运", userId);
                //提交事务
                Db.CommitTran();
                var k = new OperationCrServer().AddLogOperationCr("PDA模块", "AGV转运", palletNo, OrderTy == "0" ?"入库":"移库", $"PDA呼叫小车对托盘号:{palletNo}发起转运", userId);
                #region 呼叫小车代码
                var endlono = EndLocat;
                if (OrderTy == "0")
                {
                    tasktype = "RK0"; //入库任务
                }
                //缓存库位转换     3楼接驳位Y003_001,Y003_002,Y003_003
                if (storageLocatEnd.AreaNo == "B12")
                {
                    switch (EndLocat.ToString().Substring(4, 1))
                    {
                        case "1":
                            endlono = "Y003_0" + EndLocat.ToString().Substring(5, 2);
                            tasktype = "D00";     //点到点任务
                            break;
                        default:
                            break;
                    }
                }
                //点到点指令集合
                object[] position = new object[2];
                position[0] = new
                {
                    positionCode = stockDetail.LocatNo,
                    type = "00"
                };
                position[1] = new
                {
                    positionCode = endlono,
                    type = "00"
                };
                List<AgvSchedulingTask> agvTaskList = new List<AgvSchedulingTask>();
                AgvSchedulingTask agvTask = new AgvSchedulingTask();
                Random r = new Random();
                long ran = DateTime.Now.Ticks;
                agvTask.ReqCode = ran.ToString();
                agvTask.TaskCode = taskNo;
                agvTask.TaskTyp = tasktype;
                agvTask.PositionCodePath = position;
                agvTask.CtnrTyp = "1";
                if (tasktype == "D02")
                {
                    agvTask.CtnrNum = "10";     //叠托任务需要下发空托盘数量
                }
                agvTaskList.Add(agvTask);
                // 正式运行程序放开
                string str = "";
                var list2 = agvTaskList.Select(m => m.TaskCode).ToList();
                var jsonData = JsonConvert.SerializeObject(agvTaskList);
                jsonData = jsonData.Substring(1, jsonData.Length - 1);
                jsonData = jsonData.Substring(0, jsonData.Length - 1);
                string response = "";
                try
                {
                    var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                    response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV");
                    var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                    //////解析返回数据
                    var agvModel = JsonConvert.DeserializeObject<OutCommanAgvDto>(response);
                    if (agvModel.Code == "0")
                    {
                        //更改任务的发送返回时间//
                        new TaskServer().EditTaskIssueOk(list2, time1, time2);
                        str += "下发成功";
                    }
                    if (agvModel.Code == "1")
                    {
                        new TaskServer().EditTaskIssueNo(list2, time1, time2, agvModel.Message);
                        throw new Exception(agvModel.Message);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
                #endregion
                //提交事务
                Db.CommitTran();
            }
            catch (Exception ex)
            {
@@ -1018,7 +1146,7 @@
        /// <param name="palletNo"></param>
        /// <param name="areaNo"></param>
        /// <param name="userId"></param>
        public void AgvTransport2(string soNo,string palletNo, string areaNo, int userId)
        public List<string> AgvTransport2(string soNo, string palletNo, string areaNo,string ruku, int userId, string url)
        {
            if (string.IsNullOrEmpty(soNo))
            {
@@ -1032,6 +1160,8 @@
            {
                //开启事务
                Db.BeginTran();
                List<AgvSchedulingTask> agvTaskList = new List<AgvSchedulingTask>();
                var strList = new List<string>();//错误信息集合  //0 :部分托盘已有小车等待执行或正在执行的任务
                //出库单信息
                var notice = Db.Queryable<BllExportNotice>().First(w => w.IsDel == "0" && w.SONo == soNo);
                if (notice == null)
@@ -1051,10 +1181,11 @@
                }
                else//整个出库单叫货
                {
                    string sqlStr = $"select * from DataStockDetail where PalletNo in (select PalletNo from BllExportAllot where IsDel='0' and SONo='{soNo}')";
                    stockDetailList = Db.Ado.SqlQuery<DataStockDetail>(sqlStr).ToList();
                //    string sqlStr = $"select * from DataStockDetail where PalletNo in (select PalletNo from BllExportAllot where IsDel='0' and SONo='{soNo}')";
                //    stockDetailList = Db.Ado.SqlQuery<DataStockDetail>(sqlStr).ToList();
                    stockDetailList = Db.Queryable<DataStockDetail>().Where(w => w.IsDel == "0" && w.SONo == soNo).ToList();
                }
                if (stockDetailList.Count<=0)
                if (stockDetailList.Count <= 0)
                {
                    throw new Exception("托盘明细不存在,请检查!");
                }
@@ -1064,14 +1195,10 @@
                var stock = Db.Queryable<DataStock>().Where(w => w.IsDel == "0");//库存总表
                string EndLocat = string.Empty;//目标位置
                string hasLocatNoList = string.Empty;//已分配的储位
                foreach (var item in stockDetailList)
                {
                    //任务信息
                    var logInfo = log.First(w =>w.PalletNo == item.PalletNo);
                    if (logInfo != null)
                    {
                        throw new Exception($"托盘号:{item.PalletNo}已有小车等待执行或正在执行的任务!");
                    }
                    if (string.IsNullOrEmpty(item.LocatNo))
                    {
                        throw new Exception($"托盘号:{item.PalletNo}的储位信息不存在,请检查!");
@@ -1079,6 +1206,17 @@
                    if (item.WareHouseNo != "W02")
                    {
                        throw new Exception($"托盘号:{item.PalletNo}未在平库内,请检查!");
                    }
                    //任务信息
                    var logInfo = log.First(w => w.PalletNo == item.PalletNo);
                    if (logInfo != null)
                    {
                        if (!strList.Contains("1"))
                        {
                            strList.Add("1");
                        }
                        continue;
                        //throw new Exception($"托盘号:{item.PalletNo}已有小车等待执行或正在执行的任务!");
                    }
                    //起始储位信息
                    var storageLocatBegin = storageLocat.First(w => w.LocatNo == item.LocatNo);
@@ -1118,7 +1256,7 @@
                        Msg = string.Format("转运任务:{0}=>>{1}", item.LocatNo, EndLocat),
                        StartLocat = item.LocatNo,//起始位置
                        EndLocat = EndLocat,//目标位置
                        PalletNo = palletNo,//托盘码
                        PalletNo = item.PalletNo,//托盘码
                        IsSend = 1,//是否可再次下发
                        IsCancel = 1,//是否可取消
                        IsFinish = 1,//是否可完成
@@ -1130,9 +1268,59 @@
                    };
                    Db.Insertable(exTask).ExecuteCommand();
                    var endlono = EndLocat;
                    var tasktype = "D00";
                    //根据目的地址库区获取小车任务类型
                    switch (storageLocatEnd.AreaNo)
                    {
                        case "B13":
                            tasktype = "D02";  // 叠托任务(目的地址为空托盘收集区)
                            break;
                        case "B15":
                            tasktype = "D01";  // 拆托任务(目的地址为拣货区)
                            break;
                    }
                    //缓存库位转换     3楼原辅料Y003_001到Y003_011
                    if (storageLocatEnd.AreaNo == "B12")
                    {
                        switch (EndLocat.ToString().Substring(4, 1))
                        {
                            case "1":
                                endlono = "Y003_0" + EndLocat.ToString().Substring(5, 2);
                                break;
                            default:
                                break;
                        }
                    }
                    //点到点指令集合
                    object[] position = new object[2];
                    position[0] = new
                    {
                        positionCode = item.LocatNo,
                        type = "00"
                    };
                    position[1] = new
                    {
                        positionCode = endlono,
                        type = "00"
                    };
                    AgvSchedulingTask agvTask = new AgvSchedulingTask();
                    Random r = new Random();
                    long ran = DateTime.Now.Ticks;
                    agvTask.ReqCode = ran.ToString();
                    agvTask.TaskCode = taskNo;
                    agvTask.TaskTyp = tasktype;
                    agvTask.PositionCodePath = position;
                    agvTaskList.Add(agvTask);
                    //修改库存明细信息
                    item.Status = "4";//移库锁定
                    item.LockQty = item.Qty;//锁定库存数量
                    //item.LockQty = item.Qty;//锁定库存数量
                    Db.Updateable(item).ExecuteCommand();
                    //修改起始储位地址状态
@@ -1141,11 +1329,16 @@
                    //修改目标储位地址状态
                    storageLocatEnd.Status = "4";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中 
                    Db.Updateable(storageLocatEnd).ExecuteCommand();
                    if (!strList.Contains("0"))
                    {
                        strList.Add("0");
                    }
                    var stockInfo = stock.First(w => w.SkuNo == item.SkuNo && w.LotNo == item.LotNo);
                    //修改库存信息
                    stockInfo.LockQty += (decimal)item.Qty;//锁定数量
                    Db.Updateable(stockInfo).ExecuteCommand();
                    //var stockInfo = stock.First(w => w.SkuNo == item.SkuNo && w.LotNo == item.LotNo);
                    ////修改库存信息
                    //stockInfo.LockQty += (decimal)item.Qty;//锁定数量
                    //Db.Updateable(stockInfo).ExecuteCommand();
                }
                if (string.IsNullOrEmpty(palletNo))
                {
@@ -1157,12 +1350,52 @@
                    //添加操作日志记录
                    var k = new OperationCrServer().AddLogOperationCr("PDA模块", "AGV转运", palletNo, "移库", $"PDA呼叫小车对托盘号:{palletNo}发起转运", userId);
                }
                //提交事务
                Db.CommitTran();
                #region 呼叫小车代码
                    // 正式运行程序放开
                    string str = "";
                    var list2 = agvTaskList.Select(m => m.TaskCode).ToList();
                    var jsonData = JsonConvert.SerializeObject(agvTaskList);
                    jsonData = jsonData.Substring(1, jsonData.Length - 1);
                    jsonData = jsonData.Substring(0, jsonData.Length - 1);
                    string response = "";
                    try
                    {
                        var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                        response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运取货命令", "AGV");
                        var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                        //////解析返回数据
                        var agvModel = JsonConvert.DeserializeObject<OutCommanAgvDto>(response);
                        if (agvModel.Code == "0")
                        {
                            //更改任务的发送返回时间//
                            new TaskServer().EditTaskIssueOk(list2, time1, time2);
                            str += "下发成功";
                            //IsTrue = true;
                        }
                        if (agvModel.Code == "1")
                        {
                            new TaskServer().EditTaskIssueNo(list2, time1, time2, agvModel.Message);
                            throw new Exception(agvModel.Message);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                #endregion
                //提交事务
                Db.CommitTran();
                return strList;
            }
            catch (Exception ex)
            {
@@ -1170,6 +1403,347 @@
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 空托盘入库呼叫小车
        /// </summary>
        /// <param name="palletNo"></param>
        /// <param name="areaNo"></param>
        /// <param name="ruku"></param>
        public void AgvTransport3(string palletNo, string LocatNo, string ruku, int userId, string url, string wcsurl)
        {
            if (string.IsNullOrEmpty(palletNo))
            {
                throw new Exception("请扫描托盘条码!");
            }
            if (string.IsNullOrEmpty(ruku))
            {
                throw new Exception("请选择入库口!");
            }
            try
            {
                if (ruku == "001")
                {
                    var xlocate = Db.Queryable<SysStorageLocat>().First(w => w.Status == "0" && (w.LocatNo == "B13010101" || w.LocatNo == "B13020101" || w.LocatNo == "B13030101"));
                    if (xlocate == null)
                    {
                        throw new Exception("空托盘收集器已满");
                    }
                    ruku = Db.Queryable<SysStorageLocat>().First(w => w.Status == "0" && (w.LocatNo == "B13010101" || w.LocatNo == "B13020101" || w.LocatNo == "B13030101")).LocatNo;
                }
                if (ruku == "002")
                {
                    var dlocate = Db.Queryable<SysStorageLocat>().First(w => w.Status == "0" && (w.LocatNo == "B13040101" || w.LocatNo == "B13050101" || w.LocatNo == "B13060101"));
                    if (dlocate == null)
                    {
                        throw new Exception("空托盘收集器已满");
                    }
                    ruku = Db.Queryable<SysStorageLocat>().First(w => w.Status == "0" && (w.LocatNo == "B13040101" || w.LocatNo == "B13050101" || w.LocatNo == "B13060101")).LocatNo;
                }
                if (ruku == null)
                {
                    throw new Exception("当前托盘收集器工位无空余,请将空托盘垛入立体库");
                }
                string EndLocat = ruku;//目标位置
                string OrderTy = ruku.Length ==3 ? "0":"2";
                var tasktype = "RK0"; //入库任务
                int palnoqty = 1;
                var log = Db.Queryable<LogTask>().First(w => w.IsDel == "0" && w.PalletNo == palletNo && (w.Status == "0" || w.Status == "1"));
                if (log != null)
                {
                    throw new Exception("该托盘已有小车等待执行或正在执行的任务!");
                }
                //起始储位信息
                var storageLocat = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == LocatNo);
                if (storageLocat == null)
                {
                    throw new Exception("储位信息不存在,请检查!");
                }
                //开启事务
                Db.BeginTran();
                if (EndLocat.Length == 3)
                {
                    //请求WCS入库口放货确认
                    try
                    {
                        var port = new
                        {
                            Port = EndLocat
                        };
                        var json = JsonConvert.SerializeObject(port);
                        var res = HttpHelper.DoPost(wcsurl, json, "请求WCS入库口是否可放货", "WCS");
                        //////解析返回数据
                        var ret = JsonConvert.DeserializeObject<WcsModel>(res);
                        if (ret.StatusCode == -1)
                        {
                            throw new Exception(EndLocat + "号入库口已有其他任务占用,请选择其他入库口");
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                }
                else
                {
                    tasktype = "D02";
                    palnoqty = (int)Db.Queryable<BllPalletBind>().First(w => w.PalletNo == palletNo && w.Status == "1" && w.IsDel == "0").Qty;
                }
                //添加入库任务
                var taskNo = new Common().GetMaxNo("TK");
                var exTask = new LogTask
                {
                    TaskNo = taskNo,
                    Sender = "WMS",
                    Receiver = "AGV",
                    IsSuccess = 0, //是否下发成功 0失败 1成功
                    StartLocat = LocatNo,//起始位置
                    EndLocat = EndLocat,//目标位置
                    PalletNo = palletNo,//托盘码
                    Msg = string.Format("转运任务:{0}=>>{1}", LocatNo, EndLocat),
                    IsSend = 0,//是否可再次下发
                    IsCancel = 0,//是否可取消
                    IsFinish = 0,//是否可完成
                    Type = OrderTy,//任务类型 0 入库任务 1 出库任务  2 移库任务
                    Status = "0",//任务状态0:等待执行1正在执行2执行完成
                    OrderType = OrderTy,//0 入库单 1 出库单  2 盘点单  3 移库单
                    CreateTime = DateTime.Now
                };
                Db.Insertable(exTask).ExecuteCommand();
                //修改起始储位地址状态
                storageLocat.Status = "5";//0:空储位 1:有物品 2:入库中 3:出库中 4:移入中 5:移出中
                Db.Updateable(storageLocat).ExecuteCommand();
                //添加操作日志记录
                var k = new OperationCrServer().AddLogOperationCr("PDA模块", "空托入库", palletNo, OrderTy == "0" ? "入库" : "移库", $"PDA呼叫小车对托盘号:{palletNo}发起转运", userId);
                #region 呼叫小车代码
                //点到点指令集合
                object[] position = new object[2];
                position[0] = new
                {
                    positionCode = LocatNo,
                    type = "00"
                };
                position[1] = new
                {
                    positionCode = EndLocat,
                    type = "00"
                };
                List<AgvSchedulingTask> agvTaskList = new List<AgvSchedulingTask>();
                AgvSchedulingTask agvTask = new AgvSchedulingTask();
                Random r = new Random();
                long ran = DateTime.Now.Ticks;
                agvTask.ReqCode = ran.ToString();
                agvTask.TaskCode = taskNo;
                agvTask.TaskTyp = tasktype;
                agvTask.PositionCodePath = position;
                agvTask.CtnrTyp = palnoqty.ToString();
                agvTaskList.Add(agvTask);
                // 正式运行程序放开
                string str = "";
                var list2 = agvTaskList.Select(m => m.TaskCode).ToList();
                var jsonData = JsonConvert.SerializeObject(agvTaskList);
                jsonData = jsonData.Substring(1, jsonData.Length - 1);
                jsonData = jsonData.Substring(0, jsonData.Length - 1);
                string response = "";
                try
                {
                    var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                    response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV");
                    var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                    //////解析返回数据
                    var agvModel = JsonConvert.DeserializeObject<OutCommanAgvDto>(response);
                    if (agvModel.Code == "0")
                    {
                        //更改任务的发送返回时间//
                        new TaskServer().EditTaskIssueOk(list2, time1, time2);
                        str += "下发成功";
                    }
                    if (agvModel.Code == "1")
                    {
                        new TaskServer().EditTaskIssueNo(list2, time1, time2, agvModel.Message);
                        throw new Exception(agvModel.Message);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
                #endregion
                //提交事务
                Db.CommitTran();
            }
            catch (Exception ex)
            {
                Db.RollbackTran();
                throw new Exception(ex.Message);
            }
        }
        #region
        /// <summary>
        /// agv调度任务下发
        /// </summary>
        /// <param name="type">搬运类型</param>
        /// <param name="taskno">任务号</param>
        /// <param name="positionStart">起始地址</param>
        /// <param name="positionEnd">目的地址</param>               2
        /// <param name="url">接口URL</param>
        public OutCommanAgvDto AGVTask(string type, string taskno, string positionStart, string positionEnd ,string url)
        {
            var endlono = positionEnd;
            var tasktype = type;
            var storageLocatEnd = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == endlono && w.Flag == "0" && w.Status == "0");
            if (storageLocatEnd == null)
            {
                throw new Exception("生成的AGV任务目的地址不正确");
            }
            //根据目的地址库区获取小车任务类型
            switch (storageLocatEnd.AreaNo)
            {
                case "B13":
                    tasktype = "D02";  // 叠托任务(目的地址为空托盘收集区)
                    break;
                case "B15":
                    tasktype = "D01";  // 拆托任务(目的地址为拣货区)
                    break;
            }
            // MES申请备料,备料区库位需要转换     车间备料缓存位名称:Y003_001-->Y003_011
            if (storageLocatEnd.AreaNo == "B12")
            {
                switch (endlono.ToString().Substring(4, 1))
                {
                    case "1":
                        endlono = "Y003_0" + endlono.Substring(5, 2);
                        break;
                    default:
                        break;
                }
            }
            List<AgvSchedulingTask> agvTaskList = new List<AgvSchedulingTask>();
            object[] position = new object[2];
            position[0] = new
            {
                positionCode = positionStart,
                type = "00"
            };
            position[1] = new
            {
                positionCode = endlono,
                type = "00"
            };
            AgvSchedulingTask agvTask = new AgvSchedulingTask();
            Random r = new Random();
            long ran = DateTime.Now.Ticks;
            agvTask.ReqCode = ran.ToString();
            //agvTask.ReqCode = taskno;         //agv请求编号,需要随机生成  (最大32位)
            agvTask.TaskCode = taskno;         //任务号
            agvTask.TaskTyp = tasktype;           //搬运类型
            agvTask.PositionCodePath = position;      //起始和目的位集合
            agvTask.CtnrTyp = "1";            //容器类型,值为1
            if (tasktype == "D02")
            {
                agvTask.CtnrNum = "10";     //叠托任务需要下发空托盘数量
            }
            agvTaskList.Add(agvTask);
            string str = "";
            var list2 = agvTaskList.Select(m => m.TaskCode).ToList();
            var jsonData = JsonConvert.SerializeObject(agvTaskList);
            jsonData = jsonData.Substring(1, jsonData.Length-1);
            jsonData = jsonData.Substring(0, jsonData.Length - 1);
            try
            {
                var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                var response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV");
                //response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV");
                var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                //////解析返回数据
                var agvModel = JsonConvert.DeserializeObject<OutCommanAgvDto>(response);
                if (agvModel.Code == "0")
                {
                    //更改任务的发送返回时间//
                    new TaskServer().EditTaskIssueOk(list2, time1, time2);
                    str += "下发成功";
                }
                if (agvModel.Code == "1")
                {
                    new TaskServer().EditTaskIssueNo(list2, time1, time2, agvModel.Message);
                    throw new Exception(agvModel.Message);
                }
                return agvModel;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// agv任务取消
        /// </summary>
        /// <param name="taskno">取消任务编号</param>
        /// <param name="url">接口URL</param>
        public void cancelTask(string taskno,string url)
        {
            try
            {
                AgvCancelTask agvTaskList = new AgvCancelTask();
                Random r = new Random();
                long ran = DateTime.Now.Ticks;
                agvTaskList.ReqCode = ran.ToString();
                //agvTaskList.ReqCode = "006"; //随机生成
                agvTaskList.TaskCode = taskno.ToString();
                //agvTaskList.ReqTime = DateTime.Now.ToString();
               var jsonData = JsonConvert.SerializeObject(agvTaskList);
                var response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV");
                var agvModel = JsonConvert.DeserializeObject<cancelTaskModel>(response);
                if (agvModel.Code != "0")
                {
                    throw new Exception("下发AGV取消任务失败");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
        /// <summary>
        /// 根据区域分配储位
        /// </summary>
@@ -1177,16 +1751,16 @@
        /// <param name="skuNo"></param>
        /// <param name="lotNo"></param>
        /// <returns></returns>
        private string GetLocat(string areaNo,string skuNo,string lotNo,string palletNo,string hasLocatNoList="")
        private string GetLocat(string areaNo, string skuNo, string lotNo, string palletNo, string hasLocatNoList = "")
        {
            try
            {
                string endLocat = string.Empty;//目标储位
                //当然区域所有储位信息
                                               //当然区域所有储位信息
                var storageLocatList = Db.Queryable<SysStorageLocat>().Where(w => w.WareHouseNo == "W02" && w.AreaNo == areaNo).ToList();
                //同区域同批次物料的储位信息
                List<string> locatList = Db.Queryable<DataStockDetail>().Where(w => w.IsDel == "0" && w.SkuNo == skuNo && w.LotNo == lotNo && w.WareHouseNo == "W02" && w.AreaNo == areaNo && w.PalletNo != palletNo)
                    .OrderByDescending(o=>o.LocatNo).Select(s=>s.LocatNo).Distinct().ToList();
                    .OrderByDescending(o => o.LocatNo).Select(s => s.LocatNo).Distinct().ToList();
                foreach (var item in locatList)
                {
                    var locatInfo = storageLocatList.Where(w => w.LocatNo == item).First();
@@ -1201,13 +1775,14 @@
                if (string.IsNullOrEmpty(endLocat))
                {
                    var locatInfo3 = storageLocatList.Where(w => w.IsDel == "0" && w.Flag == "0" && w.Status == "0" && !hasLocatNoList.Contains(w.LocatNo))
                                .OrderByDescending(m => m.Layer).OrderByDescending(m=>m.Column).OrderByDescending(m=> m.Row).First();
                                .OrderByDescending(m => m.Layer).OrderByDescending(m => m.Column).OrderByDescending(m => m.Row).First();
                    if (locatInfo3 != null)
                    {
                        endLocat = locatInfo3.LocatNo;
                    }
                }
                return endLocat;
            }
            catch (Exception ex)
@@ -1215,6 +1790,341 @@
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 下发AGV任务继续执行
        /// </summary>
        /// <param name="taskno"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public void AgvContinue(string taskno,string url)
        {
            Random r = new Random();
            long ran = DateTime.Now.Ticks;
            var ReqCode = ran.ToString();
            var data = new
            {
                reqCode = ReqCode,
                taskCode = taskno
            };
            var jsonData = JsonConvert.SerializeObject(data);
            try
            {
                var response = HttpHelper.DoPost(url, jsonData, "下发给AGV继续执行命令", "AGV");
                //////解析返回数据
                var agvModel = JsonConvert.DeserializeObject<OutCommanAgvDto>(response);
                if (agvModel.Code == "1")
                {
                    throw new Exception(agvModel.Message);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion
        #region 人工转运
        //人工转运
        public void ArtificialTransport(string palletNo, string locatNo, string endLocatNo, string mesTokenUrl, string mesUrl,int userId)
        {
            if (string.IsNullOrEmpty(palletNo))
            {
                throw new Exception("请扫描托盘条码!");
            }
            if (string.IsNullOrEmpty(locatNo))
            {
                throw new Exception("请选择起始地址!");
            }
            if (string.IsNullOrEmpty(endLocatNo))
            {
                throw new Exception("请输入目标地址!");
            }
            try
            {
                #region 判断信息
                //开启事务
                Db.BeginTran();
                var stockDetail = Db.Queryable<DataStockDetail>().Where(w => w.IsDel == "0" && w.PalletNo == palletNo).ToList();
                if (stockDetail.Count == 0)
                {
                    throw new Exception("托盘上物料库存明细信息不存在,请检查!");
                }
                if (string.IsNullOrEmpty(stockDetail.First().LocatNo))
                {
                    throw new Exception("托盘储位信息不存在,请检查!");
                }
                if (stockDetail.First().WareHouseNo != "W02")
                {
                    throw new Exception("该托盘未在平库内,请检查!");
                }
                //起始储位信息
                var storageLocat = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == locatNo);
                if (storageLocat == null)
                {
                    throw new Exception("起始地址储位信息不存在,请检查!");
                }
                //目标储位信息
                var EndLocat = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == endLocatNo);
                if (EndLocat == null)
                {
                    throw new Exception("目标地址储位信息不存在,请检查!");
                }
                #endregion
                //需先判断目标地址前方是否有空储位
                storageLocat.Status = "0"; //更改起始储位
                Db.Updateable(storageLocat).ExecuteCommand();
                EndLocat.Status = "1"; //更改目标储位
                Db.Updateable(storageLocat).ExecuteCommand();
                var data = new List<RequertBeiliaoInfoModel>();
                //更改库存明细
                foreach (var item in stockDetail)
                {
                    item.LocatNo = EndLocat.LocatNo;//储位更改
                    item.WareHouseNo = EndLocat.WareHouseNo;//所属仓库更改
                    item.RoadwayNo = EndLocat.RoadwayNo;//所属巷道更改
                    item.AreaNo = EndLocat.AreaNo;//所属区域更改
                    Db.Updateable(item).ExecuteCommand();
                    if (EndLocat != null && EndLocat.AreaNo == "B12") //是否是3楼缓存区 是:删除库存
                    {
                        if (string.IsNullOrWhiteSpace(item.SONo))
                        {
                            throw new Exception("当前托盘不是拼托出库托盘");
                        }
                        var boxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.StockDetailId == item.Id).ToList();
                        if (boxInfo.Count == 0)
                        {
                            throw new Exception("托盘上物料箱码信息不存在,请检查!");
                        }
                        //var boxno = boxInfo.GroupBy(w => w.BoxNo).ToList();
                        var boxno = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.StockDetailId == item.Id).GroupBy(m => new
                        {
                            m.BoxNo,
                            m.ProductionTime,
                            m.ExpirationTime,
                        }).Select(it => new DataBoxInfo()
                        {
                            BoxNo = it.BoxNo,
                            ProductionTime = it.ProductionTime,
                            ExpirationTime = it.ExpirationTime,
                        }).ToList();
                        //记录托盘上信息给MES
                        foreach (var item2 in boxno) {
                            //var a = item.ProductionTime.ToString();
                            data.Add(new RequertBeiliaoInfoModel()
                            {
                                no = item2.BoxNo,
                                materiel_no = item.SkuNo,
                                materiel_name = item.SkuName,
                                qty = item.Qty,
                                batch = item.LotNo,
                                producttime = item2.ProductionTime.ToString().Substring(0,10),
                                expiry = item2.ExpirationTime.ToString().Substring(0, 10)
                            });
                        }
                        //库存箱码明细删除
                        Db.Deleteable(boxInfo).ExecuteCommand();
                        //删除库存托盘信息
                        Db.Deleteable(item).ExecuteCommand();
                        //更改库存总表
                        var stock = Db.Queryable<DataStock>().First(w => w.IsDel == "0" && w.SkuNo == item.SkuNo && w.LotNo == item.LotNo);
                        stock.LockQty -= (decimal)item.Qty;
                        stock.Qty -= (decimal)item.Qty;
                        Db.Updateable(stock).ExecuteCommand();
                        //更改托盘状态
                        var pallet = Db.Queryable<SysPallets>().First(m => m.IsDel == "0" && m.PalletNo == palletNo);
                        if (pallet != null)
                        {
                            pallet.Status = "0";
                            Db.Updateable(pallet).ExecuteCommand();
                        }
                    }
                }
                if (EndLocat != null && EndLocat.AreaNo == "B12")
                {
                    //获取令牌
                    //var token = new Token().GetMesToken(mesTokenUrl);
                    var token = "";
                    Dictionary<string, string> mesDic = new Dictionary<string, string>()
                    {
                        {"Authorization",token }
                    };
                    var endlono = EndLocat.LocatNo;
                    //缓存库位转换
                    switch (EndLocat.LocatNo.ToString().Substring(4, 1))
                    {
                        case "1":
                            endlono = "Y003_0" + EndLocat.LocatNo.ToString().Substring(5, 2);
                            break;
                        default:
                            break;
                    }
                    var mescode = Db.Queryable<BllExportNotice>().Where(w => w.SONo == stockDetail.First().SONo).First();
                    var mesData = new RequertBeiliaoModel()
                    {
                        morder_no = mescode.OrderCode,
                        pallet = stockDetail.First().PalletNo,
                        layer_no = endlono,
                        items = data
                    };
                    var jsonData = JsonConvert.SerializeObject(mesData);
                    //调用接口
                    var response = HttpHelper.DoPost(mesUrl, jsonData, "备料完成运至缓存区反馈至MES", "MES", mesDic);
                    var obj = JsonConvert.DeserializeObject<MesModel>(response);//解析返回数据
                    if (obj.status != "success")
                    {
                        throw new Exception("备料同步MES失败:" + obj.message);
                    }
                }
                //添加操作日志记录
                var k = new OperationCrServer().AddLogOperationCr("PDA模块", "人工转运", palletNo, "移库", $"PDA呼叫小车对托盘号:{palletNo}发起转运", userId);
                //提交事务
                Db.CommitTran();
            }
            catch (Exception ex)
            {
                Db.RollbackTran();
                throw new Exception(ex.Message);
            }
        }
        #endregion
        #region 箱码查询
        /// <summary>
        /// 箱码查询
        /// </summary>
        /// <param name="boxNo">箱码</param>
        /// <returns></returns>
        public DataBoxDto GetBoxQueryList(string boxNo)
        {
            // 实例化返回类
            DataBoxDto boxModel = new DataBoxDto();
            List<DataBoxInfoDto> list = new List<DataBoxInfoDto>();
            // 根据箱码获取箱信息
            var boxData = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo == boxNo);
            if (boxData.Count() == 0)
            {
                // 根据盒码获取箱信息
                boxData = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo2 == boxNo);
                if (boxData.Count() == 0)
                {
                    boxModel = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo3 == boxNo).Select(it => new DataBoxDto() { Qty = it.Qty }, true).First();
                    return boxModel;
                }
                list = boxData.Select(it => new DataBoxInfoDto()
                {
                    BoxNo2 = it.BoxNo3,
                    Qty2 = it.Qty
                }).ToList();
                boxData = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo2 == boxNo);
                boxModel = boxData.GroupBy(m => new
                {
                    m.BoxNo,
                    m.SkuName,
                    m.SkuNo,
                    m.LotNo,
                    m.SupplierLot,
                    m.InspectStatus
                }).Select(it => new DataBoxDto()
                {
                    BoxNo = it.BoxNo,
                    SkuName = it.SkuName,
                    SkuNo = it.SkuNo,
                    LotNo = it.LotNo,
                    SupplierLot = it.SupplierLot,
                    InspectStatus = it.InspectStatus == "0" ? "待检" : it.InspectStatus == "1" ? "合格":"不合格",
                    Qty = SqlFunc.AggregateSum(it.Qty)
                }).First();
                boxModel.InfoList = list;
                return boxModel;
            }
            else  //箱码内数据
            {
                // 处理多级码
                var num = boxData.Count(m => !string.IsNullOrWhiteSpace(m.BoxNo2));
                if (num > 0)
                {
                    list = boxData.GroupBy(m => new
                    {
                        m.BoxNo2
                    }).Select(it => new DataBoxInfoDto()
                    {
                        BoxNo2 = it.BoxNo2,
                        Qty2 = SqlFunc.AggregateSum(it.Qty)
                    }).ToList();
                }
                else
                {
                    list = boxData.Select(it => new DataBoxInfoDto()
                    {
                        BoxNo2 = SqlFunc.IsNull(it.BoxNo3,""),
                        Qty2 = it.Qty
                    }).ToList();
                }
                // 箱码信息赋值
                boxData = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo == boxNo);
                boxModel = boxData.GroupBy(m => new
                {
                    m.BoxNo,
                    m.SkuName,
                    m.SkuNo,
                    m.LotNo,
                    m.SupplierLot,
                    m.InspectStatus
                }).Select(it => new DataBoxDto()
                {
                    BoxNo = it.BoxNo,
                    SkuName = it.SkuName,
                    SkuNo = it.SkuNo,
                    LotNo = it.LotNo,
                    SupplierLot = it.SupplierLot,
                    InspectStatus = it.InspectStatus == "0" ? "待检" : it.InspectStatus == "1" ? "合格" : "不合格",
                    Qty = SqlFunc.AggregateSum(it.Qty)
                }).First();
                boxModel.InfoList = list;
                return boxModel;
            }
        }
        #endregion
    }