wxw
2025-04-24 3e19792c0061879ebe17ea04264c4c1f86bb3504
编写料斗转运功能
5个文件已修改
670 ■■■■■ 已修改文件
HTML/views/StatisticalReport/BoxInfor.html 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HTML/views/WareHouseSetting/Locate.html 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.BLL/BllTransServer/HopperTransportServer.cs 651 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.IBLL/IBllTransServer/IHopperTransportServer.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/Wms/Controllers/DownApiController.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HTML/views/StatisticalReport/BoxInfor.html
@@ -337,8 +337,9 @@
                    {field: 'LocatNo', title: '储位地址', align: 'center'},
                    {field: 'PalletNo', title: '桶号', align: 'center'},
                    {field: 'PalletStatus', title: '桶状态', align: 'center', templet: '#InspectPalletStatus'},
                    {field: 'Standard',title: '桶规格',align: 'center'},
                    {field: 'SkuNo', title: '物料编码', align: 'center'},
                    {field: 'SkuName', title: '物料名称', align: 'center'},
                    {field: 'SkuName', title: '物料名称', align: 'center'},
                    //{field: 'OwnerNo',title: '货主编码',align: 'center'},
                    //{field: 'OwnerName',title: '货主名称',align: 'center'}, 
                    //{field: 'SupplierNo',title: '供应商编码',align: 'center'},
HTML/views/WareHouseSetting/Locate.html
@@ -387,12 +387,12 @@
                            align: 'center',
                            width: 160,
                        }, 
                        // {
                        //     field: 'Layer',
                        //     title: '层',
                        //     align: 'center',
                        //     width: 70,
                        // },
                        {
                            field: 'Layer',
                            title: '层',
                            align: 'center',
                            width: 70,
                        },
                        // {
                        //     field: 'Depth',
                        //     title: '深度',
Wms/WMS.BLL/BllTransServer/HopperTransportServer.cs
@@ -1,16 +1,21 @@
using Model.InterFaceModel;
using Model.ModelDto.LogDto;
using Model.ModelDto.SysDto;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utility.Tools;
using WMS.DAL;
using WMS.Entity.Context;
using WMS.Entity.DataEntity;
using WMS.Entity.LogEntity;
using WMS.Entity.SysEntity;
using WMS.IBLL.IBllTransServer;
using static Model.InterFaceModel.RCSModel;
namespace WMS.BLL.BllTransServer
{
@@ -21,11 +26,16 @@
        private readonly object RcsLock = new object();
        /// <summary>
        /// 根据用户角色权限获取当前角色的区域
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public List<SysStorageArea> GetAreaListByUser(int userId)
        {
            try
            {
                //根据用户角色权限获取当前角色的区域
            {
                var user = Db.Queryable<SysUserInfor>().First(m=>m.IsDel == "0" && m.Id == userId);
                if (user == null)
                {
@@ -56,7 +66,12 @@
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 根据区域获取储位地址
        /// </summary>
        /// <param name="area"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public List<SysStorageLocat> GetLocatByArea(string area)
        {
            try
@@ -70,7 +85,12 @@
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 根据区域或者桶状态
        /// </summary>
        /// <param name="area"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public List<DicModel> GetPlnStatusByArea(string area)
        {
            try
@@ -129,7 +149,12 @@
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 根据桶状态获取物料编码
        /// </summary>
        /// <param name="palletStatus"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public List<string> GetSkuByStatus(string palletStatus)
        {
            try
@@ -143,7 +168,12 @@
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 根据物料编码获取批次号
        /// </summary>
        /// <param name="skuNo"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public List<string> GetLotNoBySku(string skuNo)
        {
            try
@@ -178,12 +208,12 @@
        /// <param name="areaNo">区域</param>
        /// <param name="endLocate">起始位置</param>
        /// <param name="plnStatus">桶类型 0净桶 2满桶 3脏桶 </param>
        /// <param name="standard">规格</param>
        /// <param name="standard">桶规格</param>
        /// <param name="skuNo">物料号</param>
        /// <param name="lotNo">批次</param>
        /// <param name="userId">操作人</param>
        /// <exception cref="Exception"></exception>
        public void jiaoLiaoHopper(string areaNo,string endLocate,string plnStatus,string standard,string skuNo,string lotNo,int userId)
        public void jiaoLiaoHopper(string areaNo,string endLocate,string plnStatus,string standard,string skuNo,string lotNo,string url,int userId)
        {
            try
            {
@@ -213,7 +243,7 @@
                {
                    throw new Exception("目标储位标识不是正常可用的");
                }
                if (endLocateInfo.Status!="0")
                if (endLocateInfo.Status != "0")
                {
                    throw new Exception("目标储位状态不是空储位");
                }
@@ -223,7 +253,7 @@
                //目标楼层
                var layer = endLocateInfo.Layer;
                var houseStr = layer == 3 ? "3楼中间站" : layer == 4 ? "4楼中间站" : "";
                //通过仓库名称查询仓库信息
                var house = Db.Queryable<SysWareHouse>().First(m => m.IsDel == "0" && m.WareHouseName == houseStr);
                if (house == null) 
                {
@@ -232,10 +262,12 @@
                //查找状态是未分配且储位不为空的库存信息
                var stockDetail = Db.Queryable<DataStockDetail>().Where(m => m.Status == "0" && m.WareHouseNo == house.WareHouseNo && !string.IsNullOrWhiteSpace(m.LocatNo)).ToList();
                //净桶
                if (plnStatus == "0")
                {
                    stockDetail = stockDetail.Where(m => m.PalletStatus == "0" && m.Standard == standard).OrderBy(m=>m.LocatNo).ToList();
                    stockDetail = stockDetail.Where(m => m.PalletStatus == "0" && m.Standard == standard).OrderBy(m => m.LocatNo).ToList();
                }
                //满桶
                else if (plnStatus == "2") 
                {
                    stockDetail = stockDetail.Where(m => m.PalletStatus == "2" && m.SkuNo == skuNo && m.LotNo == lotNo).OrderBy(m => m.LocatNo).ToList();
@@ -244,24 +276,52 @@
                {
                    throw new Exception("桶类型错误");
                }
                if (stockDetail == null)
                if (stockDetail == null || stockDetail.Count <= 0)
                {
                    throw new Exception("没有查询到叫料的库存信息");
                }
                //查找合适的 桶号 储位
                foreach (var item in stockDetail)
                {
                }
                //开启事务
                Db.BeginTran();
                //生产任务号
                var taskNo = new Common().GetMaxNo("TK");
                bool resultYi = false;
                #region#查找合适的 桶号 储位
                //目标仓库所有储位
                var locatList = Db.Queryable<SysStorageLocat>().Where(w => w.IsDel == "0" && w.WareHouseNo == house.WareHouseNo).ToList();
                //目标仓库所有不需要移库的储位
                var locatListWai = locatList.Where(w => string.IsNullOrEmpty(w.AisleOne)).Select(s => s.LocatNo);
                //先找不需要移库的桶
                var palletModel = stockDetail.Where(w => locatListWai.Contains(w.LocatNo)).OrderBy(o => o.UpdateTime).FirstOrDefault();
                if (palletModel == null)
                {
                    //找需要移库的桶
                    palletModel= stockDetail.Where(w => !locatListWai.Contains(w.LocatNo)).OrderBy(o => o.UpdateTime).FirstOrDefault();
                    if (palletModel == null)
                    {
                        throw new Exception("未找到对应桶信息");
                    }
                    resultYi = YikuTask(palletModel.PalletNo, taskNo, url);
                }
                #endregion
                //起始储位地址信息
                var startLoction = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.Status == "1" && w.LocatNo == palletModel.LocatNo);
                if (startLoction == null)
                {
                    throw new Exception($"起始目标储位信息不存在,桶号:{palletModel.LocatNo}");
                }
                //产生移库任务
                if (resultYi)
                {
                    taskNo = taskNo + "-1";
                }
                //添加任务
                var task = new LogTask
                var logTaskEntry = new LogTask
                {
                    TaskNo = taskNo,
                    Sender = "WMS",
                    Receiver = "WCS",
                    Receiver = "RCS",
                    IsSuccess = 0, //是否下发成功 0失败 1成功
                    StartLocat = "",//起始位置
@@ -270,18 +330,61 @@
                    IsSend = 1,//是否可再次下发
                    IsCancel = 1,//是否可取消
                    IsFinish = 1,//是否可完成
                    Type = "2",//任务类型 0 入库任务 1 出库任务  2 移库任务
                    Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                    Status = "0",//任务状态0:等待执行1正在执行2执行完成
                    OrderType = "3",//0 入库单 1 出库单  2 盘点单  3 移库单
                    CreateTime = DateTime.Now
                };
                Db.Insertable(task).ExecuteCommand();
                //调用AGV接口下发任务
                Db.Insertable(logTaskEntry).ExecuteCommand();
                //没有产生移库任务就直接给小车下发出库任务,若产生移库任务等小车把移库的桶抬起时再下发出库任务
                if (!resultYi)
                {
                    //组织下发小车任务信息
                    var task = new TaskDetial
                    {
                        Taskno = taskNo,//任务号
                        Startport = palletModel.LocatNo,//起始位置
                        Endport = endLocate,//目标位置
                        Pallno = palletModel.PalletNo,//桶号
                        Crtype = "1",//叫桶
                    };
                    string agvMsg = string.Empty;
                    //给下车下发任务
                    logTaskEntry.SendDate = DateTime.Now;//发送时间
                    var agvResult = CreateTaskForAgv(task, url, out agvMsg);
                    if (agvResult)//成功
                    {
                        //请求成功修改任务表相应字段状态
                        logTaskEntry.IsSuccess = 1;
                        logTaskEntry.IsSend = 0;
                        //logTaskEntry.IsCancel = 0;
                        logTaskEntry.BackDate = DateTime.Now;
                        logTaskEntry.Status = "1";//正在执行
                        Db.Insertable(logTaskEntry).ExecuteCommand();
                        startLoction.Status = "3";//出库中
                        Db.Updateable(startLoction).ExecuteCommand();
                        endLocateInfo.Status = "2";//入库中
                        Db.Updateable(endLocateInfo).ExecuteCommand();
                    }
                    else//失败
                    {
                        logTaskEntry.IsSuccess = 0;
                        logTaskEntry.Information = agvMsg;
                        Db.Insertable(logTaskEntry).ExecuteCommand();
                    }
                }
                //提交事务
                Db.CommitTran();
            }
            catch (Exception e)
            {
                //回滚事务
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
@@ -428,8 +531,506 @@
                throw new Exception(e.Message);
            }
        }
        private bool YikuTask(string palletNo, string taskNo, string url)
        {
            try
            {
                //分配桶的库存信息
                var palletInfo = Db.Queryable<DataStockDetail>().First(w => w.IsDel == "0" && w.PalletNo == palletNo);
                if (palletInfo == null)
                {
                    throw new Exception("未查询到分配桶的库存信息");
                }
                //判断分配的桶有没有正在执行的任务(移库中)
                var taskIng = Db.Queryable<LogTask>().First(w => w.IsDel == "0" && (w.Status == "0" || w.Status == "1") && w.PalletNo == palletNo);
                if (taskIng != null)
                {
                    throw new Exception("分配的桶有正在执行的任务,请稍后再试");
                }
                //分配桶的储位信息
                var locatInfo = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == palletInfo.LocatNo);
                if (locatInfo == null)
                {
                    throw new Exception("未查询到分配桶所在的储位信息");
                }
                string WareHouseNo = locatInfo.WareHouseNo;//所属仓库编号
                //判断该储位是否是内侧储位
                if (!string.IsNullOrEmpty(locatInfo.AisleOne))
                {
                    //判断外侧储位是否有桶
                    var palletInfoYi = Db.Queryable<DataStockDetail>().First(w => w.IsDel == "0" && w.LocatNo == locatInfo.AisleOne);
                    if (palletInfoYi != null)
                    {
                        //判断要移库的桶是否被分配
                        if (palletInfoYi.Status != "0")
                        {
                            throw new Exception("要移库的桶已被分配,请稍后再试");
                        }
                        //判断要移库的桶是否有正在执行的任务
                        var taskInfo = Db.Queryable<LogTask>().First(w => w.IsDel == "0" && (w.Status == "0" || w.Status == "1") && w.PalletNo == palletInfoYi.PalletNo);
                        if (taskInfo != null)
                        {
                            throw new Exception("要移库的桶有正在执行的任务,请稍后再试");
                        }
                        #region#给要移库的桶先移到中转储位
                        //找到中转储位所在区域
                        var transfeArea = Db.Queryable<SysStorageArea>().First(w => w.IsDel == "0" && w.WareHouseNo == WareHouseNo && w.AreaName.Contains("转运区"));
                        if (transfeArea == null)
                        {
                            throw new Exception("未找到转运区域");
                        }
                        //找到中转储位
                        var transferLocat = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.WareHouseNo == WareHouseNo && w.AreaNo == transfeArea.AreaNo);
                        if (transferLocat == null)
                        {
                            throw new Exception("没有空闲中转储位,请稍后再试");
                        }
                        #endregion
                        //任务信息
                        var logTaskEntry = new LogTask
                        {
                            TaskNo = taskNo,
                            Sender = "WMS",
                            Receiver = "RCS",
                            //IsSuccess = 1, //是否下发成功 0失败 1成功
                            SendDate = DateTime.Now,  //发送时间
                            //BackDate = DateTime.Now,  //返回时间
                            StartLocat = palletInfoYi.LocatNo,//起始位置
                            EndLocat = transferLocat.LocatNo,//目标位置
                            PalletNo = palletInfoYi.PalletNo,//托盘码
                            IsSend = 1,//是否可再次下发
                            IsCancel = 1,//是否可取消
                            IsFinish = 1,//是否可完成
                            Type = "2",//任务类型 0 入库任务 1 出库任务  2 移库任务
                            OrderType = "3",//单据类型 0 入库 1 出库 3移库
                            Status = "0",//任务状态0:等待执行1正在执行2执行完成
                            NoticeDetailNo = 0,
                            Msg = $"将桶{palletInfoYi.PalletNo}从{palletInfoYi.LocatNo}移到{transferLocat.LocatNo}", //关键信息
                            LotNo = ""//批次号
                        };
                        //组织下发小车任务信息
                        var task = new TaskDetial
                        {
                            Taskno = taskNo,//任务号
                            Startport = palletInfoYi.LocatNo,//起始位置
                            Endport = transferLocat.LocatNo,//目标位置
                            Pallno = palletInfoYi.PalletNo,//桶号
                            Crtype = "1",//叫桶
                            WareHouseNo = palletInfoYi.WareHouseNo//车间编码
                        };
                        string agvMsg = string.Empty;
                        //给下车下发任务
                        logTaskEntry.SendDate = DateTime.Now;//发送时间
                        var agvResult = CreateTaskForAgv(task, url, out agvMsg, "70");
                        if (agvResult)//成功
                        {
                            //请求成功修改任务表相应字段状态
                            logTaskEntry.IsSuccess = 1;
                            logTaskEntry.IsSend = 0;
                            //logTaskEntry.IsCancel = 0;
                            logTaskEntry.BackDate = DateTime.Now;
                            logTaskEntry.Status = "1";//正在执行
                            Db.Insertable(logTaskEntry).ExecuteCommand();
                            //修改移出储位状态
                            locatInfo.Status = "5";//移出中
                            Db.Updateable(locatInfo).ExecuteCommand();
                            //修改移入储位状态
                            transferLocat.Status = "4";//移入中
                            Db.Updateable(transferLocat).ExecuteCommand();
                        }
                        else//失败
                        {
                            logTaskEntry.IsSuccess = 0;
                            logTaskEntry.Information = agvMsg;
                            Db.Insertable(logTaskEntry).ExecuteCommand();
                            throw new Exception($"给小车下发移库任务失败,桶号:{palletInfoYi.PalletNo}");
                        }
                    }
                }
                return true;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 小车走出储位回传事件
        /// </summary>
        /// <param name="taskNo"></param>
        /// <param name="url"></param>
        /// <exception cref="Exception"></exception>
        public void OutBinAgv(string taskNo,string url)
        {
            try
            {
                //开启事务
                Db.BeginTran();
                //查找任务信息
                var logTaskInfo = Db.Queryable<LogTask>().First(w => w.IsDel == "0" && w.Status == "1" && w.TaskNo == taskNo);
                if (logTaskInfo == null)
                {
                    throw new Exception("未查询到该任务");
                }
                //起始储位地址
                var startLocatInfo = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == logTaskInfo.StartLocat);
                if (startLocatInfo == null)
                {
                    throw new Exception("未查询到起始储位地址信息");
                }
                startLocatInfo.Status = "0";//空储位
                //修改起始储位状态为空储位
                Db.Updateable(startLocatInfo).ExecuteCommand();
                //判断有无子任务
                string taskNoZ = logTaskInfo.TaskNo + "-1";
                var logTaskInfoZ = Db.Queryable<LogTask>().First(w => w.IsDel == "0" && w.Status == "0" && w.TaskNo == taskNoZ);
                if (logTaskInfoZ != null)
                {
                    //子任务起始储位信息
                    var startLocatInfoZ= Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == logTaskInfoZ.StartLocat);
                    if (startLocatInfoZ == null)
                    {
                        throw new Exception("未查询到子任务起始储位地址信息");
                    }
                    //子任务目标储位信息
                    var endLocatInfoZ = Db.Queryable<SysStorageLocat>().First(w => w.IsDel == "0" && w.LocatNo == logTaskInfoZ.EndLocat);
                    if (endLocatInfoZ == null)
                    {
                        throw new Exception("未查询到子任务目标储位地址信息");
                    }
                    //组织下发小车任务信息
                    var task = new TaskDetial
                    {
                        Taskno = taskNo,//任务号
                        Startport = logTaskInfoZ.StartLocat,//起始位置
                        Endport = logTaskInfoZ.EndLocat,//目标位置
                        Pallno = logTaskInfoZ.PalletNo,//桶号
                        Crtype = "1",//叫桶
                    };
                    string agvMsg = string.Empty;
                    //给下车下发任务
                    logTaskInfoZ.SendDate = DateTime.Now;//发送时间
                    var agvResult = CreateTaskForAgv(task, url, out agvMsg, "70");
                    if (agvResult)//成功
                    {
                        //请求成功修改任务表相应字段状态
                        logTaskInfoZ.IsSuccess = 1;
                        logTaskInfoZ.IsSend = 0;
                        //logTaskEntry.IsCancel = 0;
                        logTaskInfoZ.BackDate = DateTime.Now;
                        logTaskInfoZ.Status = "1";//正在执行
                        Db.Insertable(logTaskInfoZ).ExecuteCommand();
                        //修改移出储位状态
                        startLocatInfoZ.Status = "5";//移出中
                        Db.Updateable(startLocatInfoZ).ExecuteCommand();
                        //修改移入储位状态
                        endLocatInfoZ.Status = "4";//移入中
                        Db.Updateable(endLocatInfoZ).ExecuteCommand();
                    }
                    else//失败
                    {
                        logTaskInfoZ.IsSuccess = 0;
                        logTaskInfoZ.Information = agvMsg;
                        Db.Insertable(logTaskInfoZ).ExecuteCommand();
                        throw new Exception($"给小车下发移库任务失败,桶号:{logTaskInfoZ.PalletNo}");
                    }
                }
            }
            catch (Exception e)
            {
                //回滚事务
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 定时将中转储位上的桶移走
        /// </summary>
        /// <param name="url"></param>
        /// <exception cref="Exception"></exception>
        public void TransferBackTimer(string url)
        {
            try
            {
                //开启事务
                Db.BeginTran();
                //中间站仓库
                var transferWareHouseList = new List<string>() { "M01", "M16" };
                foreach (var itemHouseNo in transferWareHouseList)
                {
                    //找到中转储位所在区域
                    var transfeArea = Db.Queryable<SysStorageArea>().First(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.AreaName.Contains("转运区"));
                    if (transfeArea == null)
                    {
                        throw new Exception("未找到转运区域");
                    }
                    //找到中转储位
                    var transferLocatList = Db.Queryable<SysStorageLocat>().Where(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.AreaNo == transfeArea.AreaNo).ToList();
                    foreach (var locatModel in transferLocatList)
                    {
                        //储位信息
                        if (locatModel.Status != "1")
                        {
                            continue;
                        }
                        //储位上库存信息
                        var detailInfo = Db.Queryable<DataStockDetail>().First(w => w.IsDel == "0" && w.LocatNo == locatModel.LocatNo);
                        if (detailInfo == null)
                        {
                            continue;
                        }
                        //分配储位
                        var endLocatInfo = new SysStorageLocat();//目标储位
                        string areaNo = string.Empty;
                        switch (detailInfo.PalletStatus)
                        {
                            case "0"://净桶
                                //查到到净桶区域编号
                                areaNo = Db.Queryable<SysStorageArea>().Where(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.Type == "0").Select(s => s.AreaNo).First();
                                //分配储位
                                endLocatInfo = Db.Queryable<SysStorageLocat>().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0"
                                                    && w.WareHouseNo == detailInfo.WareHouseNo && w.AreaNo == areaNo)
                                                    .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First();
                                break;
                            case "2"://满桶
                                //查到到满桶区域编号
                                areaNo = Db.Queryable<SysStorageArea>().Where(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.Type == "1").Select(s => s.AreaNo).First();
                                //分配储位
                                //先查到同物料的组
                                string sql = $@"select Row from SysStorageLocat where WareHouseNo='{itemHouseNo}' and AreaNo='{areaNo}' and LocatNo in(
                                                select LocatNo from DataStockDetail where SkuNo='{detailInfo.SkuNo}' and SkuName='{detailInfo.SkuName}' and Standard='{detailInfo.Standard}' and WareHouseNo='{itemHouseNo}' and AreaNo='{areaNo}'
                                            ) group by Row";
                                List<int> RowList = Db.Ado.SqlQuery<int>(sql).ToList();
                                foreach (var rowItem in RowList)
                                {
                                    endLocatInfo = Db.Queryable<SysStorageLocat>().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0"
                                                   && w.WareHouseNo == detailInfo.WareHouseNo && w.AreaNo == areaNo && w.Row == rowItem)
                                                   .OrderByDescending(o => o.Column).First();
                                    if (endLocatInfo != null)
                                    {
                                        break;
                                    }
                                }
                                //没有找到相同物料同组的空储位
                                if (endLocatInfo == null)
                                {
                                    endLocatInfo = Db.Queryable<SysStorageLocat>().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0"
                                                   && w.WareHouseNo == detailInfo.WareHouseNo && w.AreaNo == areaNo)
                                                   .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First();
                                }
                                break;
                            case "3"://脏桶
                               //查到到脏桶区域编号
                                areaNo = Db.Queryable<SysStorageArea>().Where(w => w.IsDel == "0" && w.WareHouseNo == itemHouseNo && w.Type == "2").Select(s => s.AreaNo).First();
                                //分配储位
                                endLocatInfo = Db.Queryable<SysStorageLocat>().Where(w => w.IsDel == "0" && w.Status == "0" && w.Flag == "0"
                                                    && w.WareHouseNo == detailInfo.WareHouseNo && w.AreaNo == areaNo)
                                                    .OrderBy(o => o.Row).OrderByDescending(o => o.Column).First();
                                break;
                        }
                        //没有可用空储位
                        if (endLocatInfo == null)
                        {
                            continue;
                        }
                        var taskNo = new Common().GetMaxNo("TK");
                        //任务信息
                        var logTaskEntry = new LogTask
                        {
                            TaskNo = taskNo,
                            Sender = "WMS",
                            Receiver = "RCS",
                            //IsSuccess = 1, //是否下发成功 0失败 1成功
                            SendDate = DateTime.Now,  //发送时间
                            //BackDate = DateTime.Now,  //返回时间
                            StartLocat = detailInfo.LocatNo,//起始位置
                            EndLocat = endLocatInfo.LocatNo,//目标位置
                            PalletNo = detailInfo.PalletNo,//托盘码
                            IsSend = 1,//是否可再次下发
                            IsCancel = 1,//是否可取消
                            IsFinish = 1,//是否可完成
                            Type = "2",//任务类型 0 入库任务 1 出库任务  2 移库任务
                            OrderType = "3",//单据类型 0 入库 1 出库 3移库
                            Status = "0",//任务状态0:等待执行1正在执行2执行完成
                            NoticeDetailNo = 0,
                            Msg = $"将桶{detailInfo.PalletNo}从{detailInfo.LocatNo}移到{endLocatInfo.LocatNo}", //关键信息
                            LotNo = ""//批次号
                        };
                        //组织下发小车任务信息
                        var task = new TaskDetial
                        {
                            Taskno = taskNo,//任务号
                            Startport = detailInfo.LocatNo,//起始位置
                            Endport = endLocatInfo.LocatNo,//目标位置
                            Pallno = detailInfo.PalletNo,//桶号
                            Crtype = "2"//叫桶
                        };
                        string agvMsg = string.Empty;
                        //给下车下发任务
                        logTaskEntry.SendDate = DateTime.Now;//发送时间
                        var agvResult = CreateTaskForAgv(task, url, out agvMsg);
                        if (agvResult)//成功
                        {
                            //请求成功修改任务表相应字段状态
                            logTaskEntry.IsSuccess = 1;
                            logTaskEntry.IsSend = 0;
                            //logTaskEntry.IsCancel = 0;
                            logTaskEntry.BackDate = DateTime.Now;
                            logTaskEntry.Status = "1";//正在执行
                            Db.Insertable(logTaskEntry).ExecuteCommand();
                            //修改移出储位状态
                            locatModel.Status = "5";//移出中
                            Db.Updateable(locatModel).ExecuteCommand();
                            //修改移入储位状态
                            endLocatInfo.Status = "4";//移入中
                            Db.Updateable(endLocatInfo).ExecuteCommand();
                        }
                        else//失败
                        {
                            logTaskEntry.IsSuccess = 0;
                            logTaskEntry.Information = agvMsg;
                            Db.Insertable(logTaskEntry).ExecuteCommand();
                            throw new Exception($"给小车下发移库任务失败,桶号:{detailInfo.PalletNo}");
                        }
                    }
                }
                //提交事务
                Db.CommitTran();
            }
            catch (Exception e)
            {
                //回滚事务
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 给小车下发任务
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public bool CreateTaskForAgv(TaskDetial taskDetial, string url, out string agvMsg, string priority = null)
        {
            bool result = false;
            #region 呼叫小车代码
            List<PositionCodePath> pahtList = new List<PositionCodePath>();
            //起始位置
            PositionCodePath path1 = new PositionCodePath();
            path1.positionCode = taskDetial.Startport;
            if (taskDetial.Crtype == "1")//叫桶(桶出库)
            {
                path1.type = "05";
            }
            else if (taskDetial.Crtype == "0")//申请储位(桶入库)
            {
                path1.type = "00";
            }
            else//同车间平层搬运
            {
                path1.type = "05";
            }
            pahtList.Add(path1);
            //目标位置
            PositionCodePath path2 = new PositionCodePath();
            path2.positionCode = taskDetial.Endport;
            if (taskDetial.Crtype == "1")//叫桶(桶出库)
            {
                path2.type = "00";
            }
            else if (taskDetial.Crtype == "1")//申请储位(桶入库)
            {
                path2.type = "05";
            }
            else //同车间平层搬运
            {
                path2.type = "05";
            }
            pahtList.Add(path2);
            //下车任务单
            AgvSchedulingTask agvTask = new AgvSchedulingTask();
            agvTask.reqCode = taskDetial.Taskno;//请求编号
            agvTask.taskCode = taskDetial.Taskno;//任务号
            agvTask.ctnrCode = taskDetial.Pallno;//桶号
            agvTask.reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");//请求时间
            agvTask.wbCode = "";
            agvTask.positionCodePath = pahtList;//小车路径
            agvTask.podCode = "";
            agvTask.userCallCode = "";//taskDetial.Endport;//目标位置
            agvTask.priority = priority;//优先级
            //判断容器类型
            agvTask.ctnrTyp = "1";// 1:桶 2:桶(小) 3:托盘
            //判断任务类型
            if (taskDetial.Crtype == "1")//叫桶(桶出库)
            {
                agvTask.taskTyp = "Z3";//任务类型 线边到托盘收集器 Z1, 托盘垛申请入库 Z2
            }
            else if (taskDetial.Crtype == "0")//申请储位(桶入库)
            {
                agvTask.taskTyp = "Z4";//任务类型 线边到托盘收集器 Z1, 托盘垛申请入库 Z2
            }
            else//同车间平层搬运
            {
                agvTask.taskTyp = "Z5";
            }
            // 正式运行程序放开
            var jsonData = JsonConvert.SerializeObject(agvTask);
            string response = HttpHelper.DoPost(url, jsonData, "下发给AGV转运命令", "AGV");
            //解析返回数据
            var agvModel = JsonConvert.DeserializeObject<OutCommanAgvDto>(response);
            if (agvModel.Code == "0")
            {
                result = true;//给下车下发任务成功
                agvMsg = "";
            }
            else
            {
                string logMsg = "";
                if (taskDetial.Crtype == "1")//叫桶(桶出库)
                {
                    logMsg = "申请叫桶";
                }
                else if (taskDetial.Crtype == "0")//申请储位(桶入库)
                {
                    logMsg = "申请储位";
                }
                var logStr = $@".\log\AGV\AGV{logMsg}" + DateTime.Now.ToString("yyyyMMdd") + ".txt";
                LogFile.SaveLogToFile($"AGV{logMsg}异常:( {agvModel.Message} ),", logStr);
                agvMsg = agvModel.Message;
            }
            return result;
            #endregion
        }
    }
Wms/WMS.IBLL/IBllTransServer/IHopperTransportServer.cs
@@ -16,7 +16,7 @@
        List<string> GetLotNoBySku(string skuNo);
        List<string> GetSku();
        void jiaoLiaoHopper(string areaNo, string endLocate, string plnStatus, string standard, string skuNo, string lotNo, int userId);
        void jiaoLiaoHopper(string areaNo, string endLocate, string plnStatus, string standard, string skuNo, string lotNo, string url, int userId);
        void jiaoCheHopper(string areaNo, string StartLocate, string plnNo, string plnStatus, decimal weight, string skuNo, string lotNo, int userId);
Wms/Wms/Controllers/DownApiController.cs
@@ -1271,7 +1271,7 @@
                {
                    return Ok(new { code = 1, msg = "未获取到当前操作人信息" });
                }
                _hopper.jiaoLiaoHopper(model.AreaNo,model.LocateNo,model.PlnStatus,model.Standard,model.SkuNo,model.LotNo, int.Parse(userId));
                _hopper.jiaoLiaoHopper(model.AreaNo,model.LocateNo,model.PlnStatus,model.Standard,model.SkuNo,model.LotNo,"", int.Parse(userId));
                return Ok(new { data = model, code = 0, msg = "" });
            }