chengsc
2025-03-17 7642a3e183b5a584d1da5eb6b48e0f9cb2b5c68c
修改问题
1个文件已添加
10个文件已修改
1591 ■■■■■ 已修改文件
HTML/views/SOSetting/ExportNotice.html 78 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Pda/View/HouseDataSetting/BoxDevanning.html 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/Model/ModelVm/PdaVm/PdaCrVm.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.BLL/BllPdaServer/PdaCrServer.cs 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.BLL/BllSoServer/ExportNoticeServer.cs 1158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.BLL/BllSoServer/WaveMageServer.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.Entity/LogEntity/LogTask.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.IBLL/IBllSoServer/IExportNoticeServer.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/WMS.IBLL/IPdaServer/IPdaCrServer.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/Wms/Controllers/DownApiController.cs 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Wms/Wms/Controllers/PdaCrController.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HTML/views/SOSetting/ExportNotice.html
@@ -130,7 +130,7 @@
                    </div>
                    <!-- 确认出库口弹窗 -->
                    <div class="layui-inline" id="divPickingArea" style="display: none; padding-top: 10px;">
                        <div class="layui-inline">
                        <!-- <div class="layui-inline">
                            <label class="layui-form-label">拆垛方式</label>
                            <div class="layui-input-inline" style="width: 220px;">
                                <select name="UnstackWay" id="UnstackWay" lay-filter="UnstackWay" lay-search>
@@ -138,7 +138,7 @@
                                    <option value="1">PDA拆垛</option>
                                </select>
                            </div>
                        </div>
                        </div> -->
                        <!-- <div class="layui-inline DivLoadingArea" style="margin-top: 10px;">
                            <label class="layui-form-label">装车口</label>
                            <div class="layui-input-inline" style="width: 220px;">
@@ -158,8 +158,6 @@
                                    <option value=""></option>
                                    <option value="1">1</option>
                                    <option value="2">2</option>
                                    <option value="3">3</option>
                                    <option value="4">4</option>
                                </select>
                            </div>
                        </div>
@@ -340,7 +338,11 @@
                    </script>
                    <!-- #endregion -->
                </div>
<!-- if(d.Type == "1" && (d.Status == '2' || d.Status == '3')){
                                        html += `<a class="layui-btn layui-btn-normal layui-btn-xs outClass" lay-event="beiLiaoOutKu">
                                            <i class="layui-icon layui-icon-ok"></i>备料
                                        </a>`;
                                    } -->
                <script type="text/html" id="table-content-list">
                        {{# function GetBtn1(d){
                                var html = ''; 
@@ -365,11 +367,7 @@
                                                    <i class="layui-icon layui-icon-delete"></i>取消分配
                                                </a>`;
                                    }
                                    if(d.Type == "1" && (d.Status == '2' || d.Status == '3')){
                                        html += `<a class="layui-btn layui-btn-normal layui-btn-xs outClass" lay-event="beiLiaoOutKu">
                                            <i class="layui-icon layui-icon-ok"></i>备料
                                        </a>`;
                                    }
                                    if( d.Status == '2' || d.Status == '3'){
                                        html += `<a class="layui-btn layui-btn-normal layui-btn-xs outClass" lay-event="outKu">
                                                    <i class="layui-icon layui-icon-ok"></i>出库
@@ -1274,50 +1272,8 @@
                        area: ['1200px', '90%'],
                    });
                } else if (obj.event === 'outKu') {
                    $("#UnstackWay").val(0)
                    $("#UnstackWay").attr("disabled", false);
                    //$("#LoadingArea").val('')
                    $("#PickingArea").val('')
                    $('.DivLoadingArea').show()
                    form.render('select');
                    var param = {
                        soNo: SoNo
                    };
                    if (orderType == "0") {
                        // 判断是否需要拆箱,需要拆箱就需要选择出库口
                        sendData(IP + "/BllSo/IsNeedUnpack", param, 'get', function (res) {
                            if (res.code == 0) { //成功
                                if (res.data == "1") {
                                    isNeedUnpack = '1'
                                    $('.DivPickingArea2').show()
                                } else {
                                    isNeedUnpack = '0'
                                    $('.DivPickingArea2').hide()
                                }
                                if ($('#UnstackWay').val() == '1') {
                                    $('.DivPickingArea2').show()
                                }
                                outFunction(data.SONo)
                            } else { //不成功
                                layer.msg(res.msg, {
                                    icon: 2,
                                    time: 2000 //2秒关闭(如果不配置,默认是3秒)
                                }, function () {
                                    return;
                                });
                            }
                        });
                    } else {
                        $("#UnstackWay").val(1)
                        $("#UnstackWay").attr("disabled", true);
                        form.render('select');
                        $('.DivLoadingArea').hide()
                        outFunction(data.SONo)
                    }
                    $("#PickingArea").val('');
                    outFunction(data.SONo);
                } else if (obj.event === 'beiLiaoOutKu') {
                    if (orderType != "1") {
@@ -1430,6 +1386,7 @@
            //选择出库口弹窗方法
            function outFunction(soNo) {
                layer.open({
                    type: 1,
                    title: '确认出库口',
@@ -1449,16 +1406,7 @@
                                });
                                return;
                            }
                            // if ($('#UnstackWay').val() == '0') {
                            //     if ($('#LoadingArea').val() == '') {
                            //         layer.msg("请选择装车口", {
                            //             icon: 2,
                            //             time: 2000 //2秒关闭(如果不配置,默认是3秒)
                            //         });
                            //         isChongFu = true;
                            //         return;
                            //     }
                            // }
                            console.log($("#PickingArea").val())
                            if ($("#PickingArea").val() == '') {
                                layer.msg("请选择出库口", {
@@ -1470,7 +1418,7 @@
                            }
                            var param = {
                                soNo: soNo,
                                unstackingMode: $('#UnstackWay').val(),
                                //unstackingMode: $('#UnstackWay').val(),
                                outMode: pa,
                                //loadingAddre: $('#LoadingArea').val()
                            };
Pda/View/HouseDataSetting/BoxDevanning.html
New file
@@ -0,0 +1,159 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="user-scalable=0,width=device-width,initial-scale=1.0" />
        <!-- <meta name="viewport" content="width=device-width, initial-scale=0.665, minimum-scale=0.5, maximum-scale=2.0, user-scalable=no" /> -->
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Boxline PDA</title>
        <link rel="stylesheet" href="/layui/css/layui.css" />
        <link rel="stylesheet" href="/css/style.css" />
        <script src="/js/adaptive.js"></script>
        <link rel="stylesheet" href="/css/my.css" />
        <link rel="stylesheet" href="/css/adapter.css" />
        <style type="text/css">
            .layout-bill-info {
                height: 255px;
            }
            .layout-tbl-submit {
                margin-top: 10px;
            }
        </style>
    </head>
    <body>
        <div id="" class="main-content">
            <div id="" class="layout-title">
                <table border="" cellspacing="" cellpadding="">
                    <tr>
                        <td class="img-back"><a href="../index.html"><img src="/assets/back.jpg" ></a></td>
                        <td class="title-text">拆箱换标</td>
                        <td class="title-menu-icon"><img id="menuImg" src="/assets/menu.jpg" ></td>
                    </tr>
                </table>
            </div>
            <div id="" class="layout-sub-content">
                <div id="menuList" class="menu">
                    <ul class="" style="text-align: center;">
                        <li><a href="../index.html">主页</a></li>
                        <!-- <li><a href="productEnterConfirm.html">入库信息确认</a></li> -->
                        <li><a href="../login.html">重新登录</a></li>
                    </ul>
                </div>
                <div id="" class="layout-bill-info">
                    <form class="layui-form" action="">
                        <div id="BOX" class="layui-form-item layout-input">
                            <label class="layui-form-label" lang>外箱条码:</label>
                            <div class="layui-input-block">
                                <input id="BOXCODE" type="text" lay-verify="required" lang langholder
                                    placeholder="请扫描外箱条码" autocomplete="off" class="layui-input">
                            </div>
                        </div>
                        <div id="layout-boxcode" class="layui-form-item layout-input">
                            <label class="layui-form-label">拆箱数量:</label>
                            <div class="layui-input-block">
                                <input id="devanQty" type="number" lang langholder
                                placeholder="请输入拆箱数量" autocomplete="off" class="layui-input"
                                oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
                            </div>
                        </div>
                        <table class="layout-tbl-submit" border="" cellspacing="" cellpadding="">
                            <tr>
                                <td style="width: 23%;"></td>
                                <td>
                                    <button class="layout-btn layout-btn-red" lang type="button" lay-submit
                                        lay-filter="formUnbind">拆箱</button>
                                </td>
                                <td style="width: 33%;"></td>
                            </tr>
                        </table>
                    </form>
                </div>
            </div>
        </div>
        <script src="/js/jquery-3.5.1.min.js"></script>
        <script src="/layui/layui.js"></script>
        <script src="/js/public.js"></script>
        <script src="/js/jquery.cookie.js"></script>
        <script>
            layui.use(['form', 'jquery'], function() {
                var form = layui.form
                $("#menuImg").click(function(e){
                    //console.log("menuImg")
                    e.stopPropagation()
                    if($("#menuList").is(":hidden")){
                        $("#menuList").show()
                    }else{
                        $("#menuList").hide()
                    }
                })
                $('body').click(function(){
                    // //console.log("body")
                    $("#menuList").hide()
                })
                var isChongFu = true;
                form.on('submit(formUnbind)', function(data) {
                    if (!$("#devanQty").val()) {
                        layer.msg('请扫描托盘条码', {
                            icon: 2,
                            time: 2000 //2秒关闭(如果不配置,默认是3秒)
                        });
                        return;
                    }
                    if (!$("#BOXCODE").val()) {
                        layer.msg('请扫描外箱条码', {
                            icon: 2,
                            time: 2000 //2秒关闭(如果不配置,默认是3秒)
                        });
                        return;
                    }
                    if (isChongFu == true) {
                        isChongFu = false;
                        var param = {
                            "DevanQty": $("#devanQty").val(),
                            "BoxNo": $("#BOXCODE").val(),
                        }
                        sendData(IP + "/PdaCr/AddLableByDevanning", param, 'post', function(res) {
                            if (res.code == 0) { //成功
                                layer.msg("解绑成功", {
                                    icon: 1,
                                    time: 2000 //2秒关闭(如果不配置,默认是3秒)
                                }, function () {
                                    tableData = null
                                    $("#devanQty").val('')
                                    $("#BOXCODE").val('')
                                    isChongFu = true;
                                });
                            } else { //不成功
                                layer.msg(res.msg, {
                                    icon: 2,
                                    time: 2000 //2秒关闭(如果不配置,默认是3秒)
                                }, function() {isChongFu = true;});
                            }
                        });
                        return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
                    }else{
                        layer.msg("请勿重复点击", {
                            icon: 2,
                            time: 2000 //2秒关闭(如果不配置,默认是3秒)
                        });
                    }
                });
                // form.verify({
                //     stock: [/^[\S]{6}$/, '托盘条码必须为六位字符']
                // });
            })
        </script>
    </body>
</html>
Wms/Model/ModelVm/PdaVm/PdaCrVm.cs
@@ -75,4 +75,11 @@
        public string PalletNo { get; set; }
        public string BoxNo { get; set; }
    }
    public class PdaDevaningVm
    {
        public decimal DevanQty { get; set; }
        public string BoxNo { get; set; }
    }
}
Wms/WMS.BLL/BllPdaServer/PdaCrServer.cs
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Dm;
using Model.ModelDto.BllCheckDto;
using Model.ModelDto.PdaDto;
using SqlSugar;
@@ -1164,5 +1166,88 @@
            }
        }
        #endregion
        #region 箱码拆箱贴标
        /// <summary>
        /// 拆箱添加标签
        /// </summary>
        /// <param name="boxNo"></param>
        /// <param name="devanQty"></param>
        /// <param name="userId"></param>
        public void AddLableByDevanning(string boxNo, decimal devanQty, int userId)
        {
            try
            {
                if (string.IsNullOrEmpty(boxNo))
                {
                    throw new Exception("箱码不能为空");
                }
                //开启事务
                Db.BeginTran();
                //库存箱支明细信息
                var boxList = Db.Queryable<DataBoxInfo>().Where(w => w.IsDel == "0" && w.BoxNo == boxNo).ToList();
                if (boxList.Count != 1)
                {
                    throw new Exception("该箱码信息错误,存在多个此箱码信息");
                }
                var boxInfo = boxList.First();
                if (boxInfo.Qty<=devanQty)
                {
                    throw new Exception("拆箱数量大等于当前箱内数量");
                }
                boxInfo.Qty -= devanQty;
                boxInfo.BitBoxMark = "1";
                //更新箱码库存表
                Db.Updateable(boxInfo).ExecuteCommand();
                var boxStr = boxInfo.BoxNo.Substring(0, boxInfo.BoxNo.Length - 6);//获取箱码前缀-除后六位流水外
                var maxBoxCode = Db.Queryable<BllBoxInfo>().Where(m => m.BoxNo.Contains(boxStr) && m.IsDel == "0" && m.Origin == "WMS生成").Max(a => a.BoxNo);
                var boxNoNew = maxBoxCode.Substring(0, maxBoxCode.Length - 6) + (int.Parse(maxBoxCode.Substring(maxBoxCode.Length - 6, 6)) + 1).ToString().PadLeft(6, '0');
                // 添加新箱码信息
                var boxModel = new DataBoxInfo()
                {
                    StockDetailId = boxInfo.StockDetailId,
                    PalletNo = boxInfo.PalletNo,
                    BoxNo = boxNoNew,
                    Qty = devanQty,
                    FullQty = boxInfo.FullQty,
                    Status = "2",//0:未组托  1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货
                    LotNo = boxInfo.LotNo,
                    LotText = boxInfo.LotText,
                    SkuNo = boxInfo.SkuNo,
                    SkuName = boxInfo.SkuName,
                    Standard = boxInfo.Standard,
                    SupplierLot = boxInfo.SupplierLot,
                    InspectStatus = boxInfo.InspectStatus,
                    InspectMark = boxInfo.InspectMark,
                    BitBoxMark = "1",
                    ProductionTime = boxInfo.ProductionTime,
                    ExpirationTime = boxInfo.ExpirationTime,
                    CreateUser = 0,
                    CreateTime = DateTime.Now
                };
                Db.Insertable(boxModel).ExecuteCommand();
                //添加操作日志
                new OperationCrServer().AddLogOperationCr("库内作业", "操作日志", boxNo, "编辑", $"拆箱贴标:原箱码:{boxNo}拆箱,添加新箱码{boxNoNew}", userId);
                //提交事务
                Db.CommitTran();
            }
            catch (Exception e)
            {
                //回滚事务
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        #endregion
    }
}
Wms/WMS.BLL/BllSoServer/ExportNoticeServer.cs
@@ -26,12 +26,16 @@
using System.Runtime.Intrinsics.X86;
using ZXing.OneD;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using Model.ModelDto.LogDto;
namespace WMS.BLL.BllSoServer
{
    public class ExportNoticeServer : DbHelper<BllExportNotice>, IExportNoticeServer
    {
        private static readonly SqlSugarScope Db = DataContext.Db;
        private readonly object IssueOutLock = new object();
        public ExportNoticeServer() : base(Db)
        {
        }
@@ -2419,12 +2423,9 @@
                        Dictionary<int, decimal> stockQtyDic = new Dictionary<int, decimal>();//托出库物品数
                        var qty = 0m;
                        var house = "";
                        if (notice.Type == "0")
                        {
                            house = "W01";
                        }
                        //分配货物
                        qty += assign.AllotPallets(stockDetail, needQty, pNum, bNum, stockQtyDic, house);
                        qty += assign.AllotPallets(stockDetail, needQty, pNum, bNum, stockQtyDic, notice.WareHouseNo);
                        foreach (var sc in stockQtyDic)
                        {
                            var s = stockDetail.FirstOrDefault(m => m.Id == sc.Key);
@@ -2967,6 +2968,1153 @@
        #endregion
        #region 下发出库、出库完成、重新下发任务、取消任务、异常处理
        public string GetHouseBySo(string soNo)
        {
            try
            {
                var notcie = Db.Queryable<BllExportNotice>().First(m=>m.IsDel == "0" && m.SONo == soNo);
                if (notcie == null)
                {
                    throw new Exception("未查询到出库单信息");
                }
                return notcie.WareHouseNo;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        public List<OutCommandDto> IssueOutHouseLk(string soNo, string outMode, int userId, string url, out string str)
        {
            try
            {
                var outDto1 = new List<OutCommandDto>(); //出库数据的集合(深度为1的储位)
                //记录错误信息的集合 //1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库
                var flagList = new List<int>();
                var com = new Common();
                var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0");
                if (notice == null)
                {
                    throw new Exception($"未找到{soNo}出库单信息");
                }
                if (notice.WareHouseNo != "W02")
                {
                    throw new Exception("仓库号错误");
                }
                //所有要出库的出库分配信息(未下发的信息和待拣货的信息)
                var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == soNo && (a.Status == "0" || a.Status == "2")).ToList();
                if (list.Count == 0) //判断是否有需要下发的出库流水
                {
                    throw new Exception("当前出库单据无需要下发的托盘");
                }
                #region 集合
                //要出库的托盘集合
                var outLpnList = list.Select(m => m.PalletNo).ToList();
                //要出库的明细集合
                var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList();
                //物料编码表
                var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0");
                //包装表
                var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0");
                Db.BeginTran();
                try
                {
                    List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库
                    //循环分配的信息生成出库任务
                    foreach (var item in list)
                    {
                        var taskNoStr = "";
                        // 储位号
                        var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo;
                        #region 判断
                        //判断托盘是否在库内
                        if (string.IsNullOrWhiteSpace(locateNo)) //库外
                        {
                            //判断托盘是否在入库中
                            var imBl = com.GetImTask(item.PalletNo);
                            if (imBl != null)
                            {
                                flagList.Add(4);
                                continue;
                            }
                            //判断是否是已经出过库又回库(状态为待拣货的)
                            if (item.Status == "0")
                            {
                                //如果不在仓库内,当前分配信息直接更新出库完成
                                item.Status = "2";//状态
                                item.OutMode = outMode;//出库口
                                Db.Updateable(item).ExecuteCommand();
                                var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
                                if (noticeDetail != null) //更新出库单据的下发数量
                                {
                                    noticeDetail.FactQty += item.Qty;
                                    Db.Updateable(noticeDetail).ExecuteCommand();
                                }
                                //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
                                if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
                                {
                                    var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
                                    if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
                                    {
                                        notice.Status = "3"; //变更状态为正在执行
                                        Db.Updateable(notice).ExecuteCommand();
                                    }
                                }
                            }
                            flagList.Add(0);
                            continue;
                        }
                        var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息
                        if (locate == null)
                        {
                            flagList.Add(2);
                            continue;
                        }
                        //判断储位标志是否为损坏
                        if (locate.Flag == "2")
                        {
                            flagList.Add(3);
                            continue;
                        }
                        #endregion
                        if (locate.Status == "1") //有物品
                        {
                            #region 添加出库任务
                            var taskNo = new Common().GetMaxNo("TK");
                            var exTask = new LogTask    //出库任务
                            {
                                TaskNo = taskNo,
                                Sender = "WMS",
                                Receiver = "WCS",
                                IsSuccess = 0, //是否下发成功 0失败 1成功
                                StartLocat = locate.LocatNo,//起始位置
                                EndLocat = outMode,//目标位置
                                PalletNo = item.PalletNo,//托盘码
                                IsSend = 1,//是否可再次下发
                                IsCancel = 1,//是否可取消
                                IsFinish = 1,//是否可完成
                                Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                Status = "0",//任务状态0:等待执行1正在执行2执行完成
                                OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                Msg = "从" + locate.LocatNo + "到" + outMode + "的出库任务", //关键信息
                            };
                            Db.Insertable(exTask).ExecuteCommand();
                            logTaskList.Add(exTask);
                            outDto1.Add(new OutCommandDto()
                            {
                                PalletNo = item.PalletNo,//托盘号
                                StartLocate = locate.LocatNo, // 起始位置
                                StartRoadway = locate.RoadwayNo,//其实巷道
                                EndLocate = outMode, // 目标位置
                                TaskNo = exTask.TaskNo, // 任务号
                                TaskType = "1",// 任务类型 (出库)0入 1出 2移
                                OutMode = outMode,  //出库口
                                Order = 1,
                                //UnstackingMode = "unstackingMode2",//拣货方式 0机器拆托出  1 人工拣货出
                                //CompleteQty = outCount2,  //拆的件数
                                //BoxexQty = outCount,      //总件数
                            });
                            taskNoStr = exTask.TaskNo;
                            #endregion
                            #region 改变数据
                            if (item.Status == "0")//判断托盘是否下发过
                            {
                                var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
                                if (noticeDetail != null) //更新出库单据的下发数量
                                {
                                    noticeDetail.FactQty += item.Qty;
                                    Db.Updateable(noticeDetail).ExecuteCommand();
                                }
                                //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
                                if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
                                {
                                    var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
                                    if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
                                    {
                                        notice.Status = "3"; //变更状态为正在执行
                                        Db.Updateable(notice).ExecuteCommand();
                                    }
                                }
                            }
                            locate.Status = "3"; //要出库的储位改变状态 正在出库
                            Db.Updateable(locate).ExecuteCommand();
                            item.TaskNo = taskNoStr; // 出库分配信息中更新任务号
                            item.Status = "1"; // 出库分配信息状态改为正在执行
                            //item.UnstackingMode = unstackingMode2;//拆垛方式
                            item.OutMode = outMode;//出库口
                            //item.LoadingAddre = unstackingMode2 == "0" ? loadingAddre : "";//装车口
                            Db.Updateable(item).ExecuteCommand();
                            #endregion
                            flagList.Add(0);
                        }
                        else if (locate.Status == "3") //出库中
                        {
                            #region 改变数据
                            //判断是否是已经出过库又回库(状态为待拣货的 1)
                            if (item.Status == "0")
                            {
                                var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
                                if (noticeDetail != null) //更新出库单据的下发数量
                                {
                                    noticeDetail.FactQty += item.Qty;
                                    Db.Updateable(noticeDetail).ExecuteCommand();
                                }
                                //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
                                if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
                                {
                                    var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
                                    if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
                                    {
                                        notice.Status = "3"; //变更状态为正在执行
                                        Db.Updateable(notice).ExecuteCommand();
                                    }
                                }
                            }
                            var taskNo = Db.Queryable<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo);
                            if (taskNo == null)
                            {
                                taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库
                            }
                            if (taskNo == null)
                            {
                                throw new Exception($"托盘号:{item.PalletNo},出库异常");
                            }
                            item.TaskNo = taskNo.TaskNo;
                            item.Status = "1"; // 出库分配信息状态改为正在执行
                            item.OutMode = item.OutMode;//出库口
                            //item.UnstackingMode = unstackingMode2;//拆垛模式
                            Db.Updateable(item).ExecuteCommand();
                            flagList.Add(0);
                            #endregion
                        }
                        else if (locate.Status == "5") //移出中
                        {
                            flagList.Add(1);
                        }
                    }
                    //添加操作日志记录
                    var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", soNo, "出库", $"点击出库按钮出库单号为:{soNo}的出库单", userId);
                    Db.CommitTran();
                    str = string.Empty;
                    if (flagList.Count(m => m == 0) > 0)
                    {
                        str += "0.下发成功、";
                    }
                    if (flagList.Count(m => m == 1) > 0)
                    {
                        str += "1.当前要出库的储位正在移出、";
                    }
                    if (flagList.Count(m => m == 2) > 0)
                    {
                        str += "2.出库的托盘储位信息错误(在储位表中未查询到)、";
                    }
                    if (flagList.Count(m => m == 3) > 0)
                    {
                        str += "4.储位损坏不能出库、";
                    }
                    if (flagList.Count(m => m == 4) > 0)
                    {
                        str += "3.要出库的托盘正在入库、";
                    }
                    if (flagList.Count(m => m == 5) > 0)
                    {
                        str += "3.要出库的托盘正在拆托请稍后下发、";
                    }
                    if (outDto1.Count > 0)
                    {
                        // 正式运行程序放开
                        var list2 = outDto1.Select(m => m.TaskNo).ToList();
                        var jsonData = JsonConvert.SerializeObject(outDto1);
                        string response = "";
                        try
                        {
                            var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                            //response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
                            var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                            //////解析返回数据
                            //var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
                            //if (wcsModel.StatusCode == 0)
                            //{
                            //    //更改任务的发送返回时间//
                                new TaskServer().EditTaskIssueOk(list2, time1, time2);
                                str += "下发成功";
                            //}
                            //if (wcsModel.StatusCode == -1)
                            //{
                            //    new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
                            //    throw new Exception(wcsModel.Msg);
                            //}
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(ex.Message);
                        }
                    }
                    return outDto1;
                }
                catch (Exception e)
                {
                    Db.RollbackTran();
                    throw new Exception(e.Message);
                }
                #endregion
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        public List<OutCommandDto> IssueOutHouseMk(string soNo, string outMode, int userId, string url, out string str)
        {
            try
            {
                #region 集合
                var outDto1 = new List<OutCommandDto>(); //先出库数据的集合(深度为1的储位)
                var outDto2 = new List<OutCommandDto>(); //后出库数据的集合(深度为2的储位)
                var moveDto = new List<OutCommandDto>(); //要移库数据的集合
                //记录错误信息的集合
                var flagList = new List<int>();//1:当前要出库的储位正在移出、2 出库的托盘储位信息错误(在储位表中未查询到)、3储位损坏不能出库、4 要出库的托盘正在入库
                #endregion
                var com = new Common();
                var notice = Db.Queryable<BllExportNotice>().First(m => m.SONo == soNo && m.IsDel == "0");
                if (notice == null)
                {
                    throw new Exception($"未找到{soNo}出库单信息");
                }
                //所有要出库的出库分配信息(未下发的信息和待拣货的信息)
                var list = Db.Queryable<BllExportAllot>().Where(a => a.IsDel == "0" && a.SONo == soNo && (a.Status == "0" || a.Status == "2")).ToList();
                if (list.Count == 0) //判断是否有需要下发的出库流水
                {
                    throw new Exception("当前出库单据无需要下发的托盘");
                }
                #region 集合
                //要出库的托盘集合
                var outLpnList = list.Select(m => m.PalletNo).ToList();
                //要出库的明细集合
                var outStockDetail = Db.Queryable<DataStockDetail>().Where(m => m.IsDel == "0" && outLpnList.Contains(m.PalletNo)).ToList();
                //所有要出库的储位集合
                var locateListStrs = outStockDetail.Where(m=> !string.IsNullOrWhiteSpace(m.LocatNo)).Select(m => m.LocatNo).Distinct().ToList();
                //物料编码表
                var skuList = Db.Queryable<SysMaterials>().Where(w => w.IsDel == "0");
                //包装表
                var packagList = Db.Queryable<SysPackag>().Where(w => w.IsDel == "0");
                Db.BeginTran();
                try
                {
                    List<LogTask> logTaskList = new List<LogTask>();//此次出库任务集合,为应对同托盘不同物料出库
                    //循环分配的信息生成出库任务
                    foreach (var item in list)
                    {
                        var taskNoStr = "";
                        string toLocation = string.Empty;//目标位置
                        // 储位号
                        var locateNo = outStockDetail.First(m => m.PalletNo == item.PalletNo).LocatNo;
                        #region 判断托盘是否在库内
                        //判断托盘是否在库内
                        if (string.IsNullOrWhiteSpace(locateNo)) //库外
                        {
                            if (notice.Type == "0")
                            {
                                flagList.Add(5);
                                continue;
                            }
                            //判断托盘是否在入库中
                            var imBl = com.GetImTask(item.PalletNo);
                            if (imBl != null)
                            {
                                flagList.Add(4);
                                continue;
                            }
                            //判断是否是已经出过库又回库(状态为待拣货的 1)
                            if (item.Status == "0")
                            {
                                //如果不在仓库内,当前分配信息直接更新出库完成
                                item.Status = "2";//状态
                                item.OutMode = outMode;//出库口
                                Db.Updateable(item).ExecuteCommand();
                                var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
                                if (noticeDetail != null) //更新出库单据的下发数量
                                {
                                    noticeDetail.FactQty += item.Qty;
                                    Db.Updateable(noticeDetail).ExecuteCommand();
                                }
                                //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
                                if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
                                {
                                    var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
                                    if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
                                    {
                                        notice.Status = "3"; //变更状态为正在执行
                                        Db.Updateable(notice).ExecuteCommand();
                                    }
                                }
                            }
                            flagList.Add(0);
                            continue;
                        }
                        //判断储位
                        var locate = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == locateNo && m.IsDel == "0");//当前出库的储位信息
                        if (locate == null)
                        {
                            flagList.Add(2);
                            continue;
                        }
                        //判断储位标志是否为损坏
                        if (locate.Flag == "2")
                        {
                            flagList.Add(3);
                            continue;
                        }
                        #endregion
                        if (locate.Status == "1") //有物品
                        {
                            var row1 = int.Parse(locate.LocatNo.Substring(2,2));
                            var row2 = int.Parse(locate.AisleOne.Substring(2, 2));
                            //需要移库的信息
                            var NeedMoveInfo = IsNeedMoveLocate(locate, locateListStrs, out int isOut);
                            if (isOut == 1)
                            {
                                //巷道组中有入库或移入的储位,或者是当前储位前有储位未下发成功的任务
                                flagList.Add(2);
                                continue;
                            }
                            if (NeedMoveInfo.Count > 0)//需要移库
                            {
                                //判断库内空储位是否够
                                var okRoad = Db.Queryable<SysStorageRoadway>().Where(m => m.Status == "0" && m.IsDel == "0" && m.WareHouseNo == notice.WareHouseNo).Select(m => m.RoadwayNo).ToList();
                                var nullSlotNum = Db.Queryable<SysStorageLocat>().Count(m => m.RoadwayNo != locate.RoadwayNo && okRoad.Contains(m.RoadwayNo) && m.Status == "0");
                                //判断空储位的数量是否大于需要移库的数量
                                if (nullSlotNum >= NeedMoveInfo.Count)
                                {
                                    var isYk = false;
                                    foreach (var s in NeedMoveInfo)
                                    {
                                        //储位列
                                        var rows = int.Parse(s.Substring(2,2));
                                        //获取移库储位
                                        var moveAddress = GetMiJiMoveAddress(s, locate.AisleOne);
                                        var tary = Db.Queryable<DataStockDetail>().First(m => m.LocatNo == s);
                                        if (string.IsNullOrWhiteSpace(moveAddress)) // 判断是否获取到移库的库位
                                        {
                                            isYk = true;
                                            flagList.Add(5);//出库前有货物,需移库但未查询到空储位
                                            break; //没有移库的库位了
                                        }
                                        else
                                        {
                                            //判断托盘有没有回移的任务
                                            //var hy = GetHyTask(item.ExportStockCode);
                                            //if (hy != null)
                                            //{
                                            //    var hyentity = dataContext.WmsExportTask.FirstOrDefault(m => m.TaskId == hy.TaskId);
                                            //    if (hyentity != null)
                                            //    {
                                            //        isYk = true;
                                            //        msgList.Add(6);//出库前有货物,需移库但是回移托盘
                                            //        break; //没有移库的库位了
                                            //    }
                                            //}
                                            var ykTaskNo = new Common().GetMaxNo("TK");
                                            var ykTask = new LogTask    //出库任务
                                            {
                                                TaskNo = ykTaskNo,
                                                Sender = "WMS",
                                                Receiver = "WCS",
                                                IsSuccess = 0, //是否下发成功 0失败 1成功
                                                StartLocat = s,//起始位置
                                                EndLocat = moveAddress,//outMode,//目标位置
                                                PalletNo = tary.PalletNo,//托盘码
                                                IsSend = 1,//是否可再次下发
                                                IsCancel = 1,//是否可取消
                                                IsFinish = 1,//是否可完成
                                                Type = "2",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                                Status = "0",//任务状态0:等待执行1正在执行2执行完成
                                                OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                                Msg = "从" + locate.LocatNo + "到" + toLocation + "的出库任务", //关键信息
                                            };
                                            Db.Insertable(ykTask).ExecuteCommand();
                                            logTaskList.Add(ykTask);
                                            outDto1.Add(new OutCommandDto()
                                            {
                                                PalletNo = item.PalletNo,//托盘号
                                                StartLocate = locate.LocatNo, // 起始位置
                                                StartRoadway = locate.RoadwayNo,//其实巷道
                                                EndLocate = toLocation,//outMode, // 目标位置
                                                TaskNo = ykTaskNo, // 任务号
                                                TaskType = "1",// 任务类型 (出库)0入 1出 2移
                                                Order = Math.Abs(row2 - rows),
                                            });
                                            var slotChange = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == s);
                                            var slotChange2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == moveAddress);
                                            slotChange.Status = "5"; //改变状态(正在出库)
                                            slotChange2.Status = "4"; // 改变状态(正在移入)
                                            Db.Updateable(slotChange).ExecuteCommand();
                                            Db.Updateable(slotChange2).ExecuteCommand();
                                        }
                                    }
                                    if (isYk)
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    flagList.Add(5);
                                    break;
                                }
                            }
                            #region 添加出库任务
                            var taskNo = new Common().GetMaxNo("TK");
                            var exTask = new LogTask    //出库任务
                            {
                                TaskNo = taskNo,
                                Sender = "WMS",
                                Receiver = "WCS",
                                IsSuccess = 0, //是否下发成功 0失败 1成功
                                StartLocat = locate.LocatNo,//起始位置
                                EndLocat = toLocation,//outMode,//目标位置
                                PalletNo = item.PalletNo,//托盘码
                                IsSend = 1,//是否可再次下发
                                IsCancel = 1,//是否可取消
                                IsFinish = 1,//是否可完成
                                Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                Status = "0",//任务状态0:等待执行1正在执行2执行完成
                                OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                Msg = "从" + locate.LocatNo + "到" + toLocation + "的出库任务", //关键信息
                            };
                            Db.Insertable(exTask).ExecuteCommand();
                            logTaskList.Add(exTask);
                            outDto1.Add(new OutCommandDto()
                            {
                                PalletNo = item.PalletNo,//托盘号
                                StartLocate = locate.LocatNo, // 起始位置
                                StartRoadway = locate.RoadwayNo,//其实巷道
                                EndLocate = toLocation,//outMode, // 目标位置
                                TaskNo = exTask.TaskNo, // 任务号
                                TaskType = "1",// 任务类型 (出库)0入 1出 2移
                                OutMode = toLocation,  //出库口
                                Order = Math.Abs(row2 - row1),
                            });
                            taskNoStr = exTask.TaskNo;
                            #endregion
                            #region 改变数据
                            if (item.Status == "0")//判断托盘是否下发过
                            {
                                var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
                                if (noticeDetail != null) //更新出库单据的下发数量
                                {
                                    noticeDetail.FactQty += item.Qty;
                                    Db.Updateable(noticeDetail).ExecuteCommand();
                                }
                                //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
                                if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
                                {
                                    var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
                                    if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
                                    {
                                        notice.Status = "3"; //变更状态为正在执行
                                        Db.Updateable(notice).ExecuteCommand();
                                    }
                                }
                            }
                            locate.Status = "3"; //要出库的储位改变状态 正在出库
                            Db.Updateable(locate).ExecuteCommand();
                            item.TaskNo = taskNoStr; // 出库分配信息中更新任务号
                            item.Status = "1"; // 出库分配信息状态改为正在执行
                            //item.UnstackingMode = unstackingMode2;//拆垛方式
                            item.OutMode = outMode;//出库口
                            //item.LoadingAddre = unstackingMode2 == "0" ? loadingAddre : "";//装车口
                            Db.Updateable(item).ExecuteCommand();
                            #endregion
                            flagList.Add(0);
                        }
                        else if (locate.Status == "3") //出库中
                        {
                            #region 改变数据
                            //判断是否是已经出过库又回库(状态为待拣货的 1)
                            if (item.Status == "0")
                            {
                                var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.Id == item.SODetailNo);
                                if (noticeDetail != null) //更新出库单据的下发数量
                                {
                                    noticeDetail.FactQty += item.Qty;
                                    Db.Updateable(noticeDetail).ExecuteCommand();
                                }
                                //var notice2 = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == item.SONo);
                                if (notice.Status == "0" || notice.Status == "1" || notice.Status == "2")
                                {
                                    var detailList = Db.Queryable<BllExportNoticeDetail>().Where(m => m.IsDel == "0" && m.SONo == item.SONo).ToList();
                                    if (detailList.Count(m => m.Qty >= m.AllotQty) > 0)
                                    {
                                        notice.Status = "3"; //变更状态为正在执行
                                        Db.Updateable(notice).ExecuteCommand();
                                    }
                                }
                            }
                            var taskNo = Db.Queryable<LogTask>().First(m => m.OrderType == "1" && m.TaskNo != item.TaskNo && m.Status == "1" && m.PalletNo == item.PalletNo);
                            if (taskNo == null)
                            {
                                taskNo = logTaskList.FirstOrDefault(m => m.PalletNo == item.PalletNo);//当前有同托盘不同物料出库
                            }
                            if (taskNo == null)
                            {
                                throw new Exception($"托盘号:{item.PalletNo},出库异常");
                            }
                            item.TaskNo = taskNo.TaskNo;
                            item.Status = "1"; // 出库分配信息状态改为正在执行
                            item.OutMode = item.OutMode;//出库口
                            //item.UnstackingMode = unstackingMode2;//拆垛模式
                            Db.Updateable(item).ExecuteCommand();
                            flagList.Add(0);
                            #endregion
                        }
                        else if (locate.Status == "5") //移出中
                        {
                            flagList.Add(1);
                        }
                    }
                    outDto1.AddRange(moveDto);
                    outDto1.AddRange(outDto2);
                    //添加操作日志记录
                    var k = new OperationSOServer().AddLogOperationSo("出库作业", "出库单据", soNo, "出库", $"点击出库按钮出库单号为:{soNo}的出库单", userId);
                    Db.CommitTran();
                    str = string.Empty;
                    if (flagList.Count(m => m == 0) > 0)
                    {
                        str += "0.下发成功、";
                    }
                    if (flagList.Count(m => m == 1) > 0)
                    {
                        str += "1.当前要出库的储位正在移出、";
                    }
                    if (flagList.Count(m => m == 2) > 0)
                    {
                        str += "2.出库的托盘储位信息错误(在储位表中未查询到)、";
                    }
                    if (flagList.Count(m => m == 3) > 0)
                    {
                        str += "4.储位损坏不能出库、";
                    }
                    if (flagList.Count(m => m == 4) > 0)
                    {
                        str += "3.要出库的托盘正在入库、";
                    }
                    if (flagList.Count(m => m == 5) > 0)
                    {
                        str += "3.要出库的托盘正在拆托请稍后下发、";
                    }
                    if (outDto1.Count > 0)
                    {
                        // 正式运行程序放开
                        var list2 = outDto1.Select(m => m.TaskNo).ToList();
                        var jsonData = JsonConvert.SerializeObject(outDto1);
                        string response = "";
                        try
                        {
                            //var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                            //response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
                            //var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                            //////解析返回数据
                            //var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
                            //if (wcsModel.StatusCode == 0)
                            //{
                            //    //更改任务的发送返回时间//
                            //    new TaskServer().EditTaskIssueOk(list2, time1, time2);
                            //    str += "下发成功";
                            //}
                            //if (wcsModel.StatusCode == -1)
                            //{
                            //    new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
                            //    throw new Exception(wcsModel.Msg);
                            //}
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(ex.Message);
                        }
                    }
                    return outDto1;
                }
                catch (Exception e)
                {
                    Db.RollbackTran();
                    throw new Exception(e.Message);
                }
                #endregion
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 判断是否需要进行移库操作
        /// </summary>
        /// <param name="oldAddress">要出库的库位地址</param>
        /// <param name="aisle">通道口</param>
        /// <param name="addressList">要出口的储位集合</param>
        /// <param name="isOut">是否出库 1:有未下发的任务在前面</param>
        /// <returns>需要移库的集合(如果为空则不需移库)</returns>
        private List<string> IsNeedMoveLocate(SysStorageLocat lcoate,List<string> locateStrList, out int isOut)
        {
            var nowAddress = new List<string>(); //需要移库的集合
            // 010101 派列层
            //var bol = String.CompareOrdinal(lcoate.LocatNo, lcoate.AisleOne);
            var sArray = lcoate.LocatNo.Substring(4,2);
            var row = int.Parse(sArray);//储位列
            var sArray2 = lcoate.AisleOne.Substring(4, 2);
            var row2 = int.Parse(sArray2); //通道口列
            isOut = 0;
            var bol = row2 - row > 0;
            //同组的储位集合
            var slotList = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == lcoate.RoadwayNo).ToList();
            List<string> list;
            if (bol)
            {
                //储位小于通道口   倒序
                list = slotList.Where(m => m.Column < row2 && m.Column > row).Select(m => m.LocatNo).ToList();
            }
            else
            {
                //储位大于通道口   正序
                list = slotList.Where(m => m.Column > row2 && m.Column < row).Select(m => m.LocatNo).ToList();
            }
            if (list.Any())
            {
                //排除掉同巷道组中要出库的储位
                if (locateStrList.Count != 0)
                {
                    list = list.Where(m => !locateStrList.Contains(m)).ToList();
                }
                //判断是否有入库中或正在移入的
                var s = slotList.Where(m => list.Contains(m.LocatNo) && (m.Status == "2" || m.Status == "4")).Select(m => m.LocatNo).ToList();
                if (s.Count > 0)
                {
                    isOut = 1;
                    return nowAddress;
                }
                //判断是否有在当前储位前未下发的任务(防止撞车)
                var w = Db.Queryable<LogTask>().Where(m => list.Contains(m.StartLocat) && m.IsSuccess == 0).Select(m => m.StartLocat).ToList();
                if (w.Count > 0)
                {
                    isOut = 1;
                    return nowAddress;
                }
                if (bol)
                {
                    //储位小于通道口   倒序
                    nowAddress = slotList.Where(m => list.Contains(m.LocatNo) && m.Status == "1").OrderByDescending(m => m.LocatNo).Select(m => m.LocatNo).ToList();
                }
                else
                {
                    //储位大于通道口   正序
                    nowAddress = slotList.Where(m => list.Contains(m.LocatNo) && m.Status == "1").OrderBy(m => m.LocatNo).Select(m => m.LocatNo).ToList();
                }
                if (nowAddress.Count > 0)
                {
                    return nowAddress;
                }
            }
            else
            {
                return nowAddress;
            }
            return nowAddress;
        }
        /// <summary>
        /// 获取移库目标库位 密集库
        /// </summary>
        /// <param name="oldAddress">需要移动的库位地址</param>
        /// <param name="slotOut">需要移动的库位的出口中转位</param>
        /// <param name="billCode">出库单据或是波次单据</param>
        /// <param name="flags">中转口</param>
        /// <param name="refLanWayId">需回移的巷道id</param>
        /// <param name="refLanOutCode">需回移的巷道中转口</param>
        /// <returns>目标库位地址 为"" 直接下发两次出库指令</returns>
        public string GetMiJiMoveAddress(string oldAddress, string slotOut)
        {
            var newAddress = ""; //新库位
            var newLaneWayAddress = ""; //新巷道口库位
            // 获取移库目标储位
            //
            var sArray = oldAddress.Substring(4,2);
            var ceng = int.Parse(sArray);
            //
            var sArray2 = slotOut.Substring(2, 2);
            var row2 = sArray2;
            //十字口
            var shiKou = new List<string>()
            {
                slotOut,
                "070501",
                "071301",
                "070502",
                "071302",
            };
            var shiKou3 = new List<addreClass>();
            foreach (var item in shiKou)
            {
                var a = item.Substring(4, 2);
                var b = item.Substring(2, 2);
                if (int.Parse(a) != ceng) continue;
                var s = Math.Abs(int.Parse(b) - int.Parse(row2));
                if (shiKou3.Any(m => m.distNum == s)) continue;
                shiKou3.Add(new addreClass()
                {
                    slotCode = item,
                    distNum = s
                });
            }
            //根据十字口差值最小的排序
            shiKou3 = shiKou3.OrderBy(m => m.distNum).ToList();
                /**
                //1 移动到最近的空储位,必须回移。
                //根据四向车移动轨迹计算出最近空储位。
                //出库完成后根据批次号 生产日期 出口计算回移储位。
                //2 移动适合存放的组,系统自动计算是否回移。
                //根据批次号 生产日期 出口 物料等计算出移库目标储位
                //出库完成后,判断是否有比当前库位更合适的存储储位,有移动,无不移动。
                */
                var oldSlot = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == oldAddress);
                if (oldSlot == null)
                {
                    throw new Exception("未能找到储位信息");
                }
                #region 1不需要回移的
                //后期库存托盘表改了后需要加筛选条件托盘的状态(退货/预拣)
                var tray1 = Db.Queryable<DataStockDetail>().Where(m => m.LocatNo == oldAddress).ToList();
                //根据物料、批次、托盘状态(退货/预拣/暂存等)分组判断
                var d = tray1.GroupBy(m => new { m.SkuNo, m.LotNo, m.PalletTags });
                var location = string.Empty;
                if (d.Any())
                {
                    //旧储位同组的储位集合
                    var slotList = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == oldSlot.RoadwayNo).Select(m => m.LocatNo).ToList();
                    foreach (var item in d)
                    {
                        foreach (var item2 in item)
                        {
                            var okLan = Db.Queryable<SysStorageRoadway>().Where(m => m.Status == "0" && m.IsDel == "0").Select(m => m.RoadwayNo).ToList();
                            var tray2 = Db.Queryable<DataStockDetail>().Where(m => m.SkuNo == item2.SkuNo
                            && m.LotNo == item2.LotNo && !slotList.Contains(m.LocatNo) && m.PalletTags == item2.PalletTags && okLan.Contains(m.RoadwayNo)).ToList();
                            foreach (var s in tray2)
                            {
                                if (string.IsNullOrWhiteSpace(s.RoadwayNo))//判断是否在库外,如是跳过
                                {
                                    continue;
                                }
                                var lan = Db.Queryable<SysStorageLocat>().Where(m => m.RoadwayNo == s.RoadwayNo).OrderBy(m => m.LocatNo).ToList();
                                //判断是否有入库中、出库中、移入中、移出中
                                if (lan.Count(m => m.Status == "2" || m.Status == "3" || m.Status == "4" || m.Status == "5") > 0)
                                {
                                    continue;
                                }
                                if (lan.Count(m => m.Status == "0") > 0)
                                {
                                    var bol = GetBecomingLocation(s.RoadwayNo, ref location);
                                    if (bol && !string.IsNullOrWhiteSpace(location))
                                    {
                                        newAddress = location;
                                        return newAddress;
                                    }
                                }
                            }
                        }
                    }
                }
                #endregion
                #region 2需要回移的
                ////如果没有找到合适的储位
                //if (string.IsNullOrWhiteSpace(newAddress))
                //{
                //    foreach (var s in shiKou3)
                //    {
                //        var r = int.Parse(s.slotCode.Substring(0, 2));
                //        var l = int.Parse(s.slotCode.Substring(2, 2));
                //        var c = int.Parse(s.slotCode.Substring(4, 2));
                //        //查询空储位
                //        var sqlString = $@"select LocatNo,Row,Column,Layer,(ABS(Row-{r}) + ABS(Column-{l}) ) as distNum
                //                from SysStorageLocat where (AisleOneRow  = {r} or AisleTwoRow = {r}) and Status in (0) and
                //                 RoadwayNo !='{oldSlot.RoadwayNo}' and RoadwayNo not in(select RoadwayNo from SysStorageRoadway where Status = 1) order by distNum,SlotCode";
                //        var addressModels = dataContext.ExecuteQuery<addreClass>(sqlString).ToList();
                //        foreach (var item in addressModels)
                //        {                            、
                //            newAddress = item.slotCode;
                //            var dz = newAddress.Split(new char[] { '-' });
                //            var l1 = dz[1];
                //            var c1 = dz[0];
                //            newLaneWayAddress = $"{c1}-{l1}-{a[2]}";
                //            flags = newLaneWayAddress;
                //            var slotModel = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == item.slotCode);
                //            var lan = dataContext.WmsBaseSlot.Where(m => m.SlotLanewayId == slotModel.SlotLanewayId).ToList();
                //            if (slotModel.SlotRow > int.Parse(a[2]))
                //            {
                //                // 取最上面一排
                //                lan = lan.OrderBy(m => m.SlotCode).ToList();
                //                for (int i = 0; i < lan.Count; i++)
                //                {
                //                    var slot = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == lan[i].SlotCode);
                //                    if (slot.SlotStatus == 0)
                //                    {
                //                        if (i == lan.Count - 1)
                //                        {
                //                            newAddress = lan[lan.Count - 1].SlotCode;
                //                            break;
                //                        }
                //                        else
                //                        {
                //                            continue;
                //                        }
                //                    }
                //                    else
                //                    {
                //                        newAddress = lan[i - 1].SlotCode;
                //                        break;
                //                    }
                //                }
                //            }
                //            else
                //            {
                //                // 取最下面一排
                //                lan = lan.OrderByDescending(m => m.SlotCode).ToList();
                //                for (int i = 0; i < lan.Count; i++)
                //                {
                //                    var slot = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == lan[i].SlotCode);
                //                    if (slot.SlotStatus == 0)
                //                    {
                //                        if (i == lan.Count - 1)
                //                        {
                //                            newAddress = lan[lan.Count - 1].SlotCode;
                //                            break;
                //                        }
                //                        else
                //                        {
                //                            continue;
                //                        }
                //                    }
                //                    else
                //                    {
                //                        newAddress = lan[i - 1].SlotCode;
                //                        break;
                //                    }
                //                }
                //            }
                //            //添加回移任务
                //            AddHyTask(oldAddress, newAddress, newLaneWayAddress, oldSlot.SlotLanewayId, slotOut, billCode);
                //            refLanWayId = slotModel.SlotLanewayId;
                //            refLanOutCode = newLaneWayAddress;
                //            //9:锁定储位
                //            var updateSlot = dataContext.WmsBaseSlot.Where(m => m.SlotLanewayId == slotModel.SlotLanewayId).ToList();
                //            var newAddressRow = dataContext.WmsBaseSlot.FirstOrDefault(m => m.SlotCode == newAddress);
                //            if (newAddressRow.SlotRow > int.Parse(a[2]))
                //            {
                //                updateSlot = updateSlot.Where(m => m.SlotRow < newAddressRow.SlotRow && m.SlotRow > int.Parse(a[2])).OrderBy(m => m.SlotCode).ToList();
                //            }
                //            else
                //            {
                //                updateSlot = updateSlot.Where(m => m.SlotRow > newAddressRow.SlotRow && m.SlotRow < int.Parse(a[2])).OrderByDescending(m => m.SlotCode).ToList();
                //            }
                //            foreach (var source in updateSlot)
                //            {
                //                if (source.SlotCode == newAddress)
                //                {
                //                    continue;
                //                }
                //                if (source.SlotStatus == 0)
                //                {
                //                    source.SlotStatus = 8;
                //                }
                //            }
                //            if (updateSlot.Count <= 0)
                //            {
                //                refLanWayId = "";
                //                refLanOutCode = "";
                //            }
                //            dataContext.SubmitChanges();
                //            return newAddress;
                //        }
                //    }
                //}
                return newAddress;
                #endregion
        }
        /// <summary>
        /// 获取移库合适的储位 密集库
        /// </summary>
        /// <param name="laneWayId">合适组的巷道号</param>
        /// <param name="location">分配储位</param>
        /// <returns>true:存在合适储位   False:不存在合适储位</returns>
        private bool GetBecomingLocation(string laneWayId, ref string location)
        {
            bool bl = false;
            // 循环判断当前组是否有剩余储位
            string sqlString = string.Empty;
            location = "";
            // 判断储位组是否有空储位   关联库存明细表可防止储位状态不准确避免造成满入异常//not in ('1','2','4','6','7','8')
            sqlString = $"select LocatNo,Column,AisleOne from SysStorageLocat where RoadwayNo = {laneWayId} and Status in ('0') and LocatNo not in (select LocatNo from DataStockDetail where RoadwayNo = { laneWayId}) order by Row;";
            var slotModel =Db.SqlQueryable<LocateInfo>(sqlString).ToList();
            if (slotModel.Count == 0)
            {
                bl = false;
            }
            else  // 存在空储位
            {
                // 判断当前组合适的储位地址
                var numstr = slotModel[0].AisleOne.Substring(4,2);
                int aisleRow = int.Parse(numstr);
                if (slotModel[0].Column > aisleRow)
                {
                    // 取最上面一排
                    location = slotModel[0].LocatNo;
                }
                else
                {
                    // 取最下面一排
                    location = slotModel[slotModel.Count - 1].LocatNo;
                }
                bl = true;
            }
            return bl;
        }
        private class addreClass
        {
            public string slotCode { get; set; }
            public int distNum { get; set; }
        }
        public class LocateInfo
        {
            public string LocatNo { get; set; }
            public int Column { get; set; }
            public string AisleOne { get; set; }
        }
        #endregion
        #endregion
Wms/WMS.BLL/BllSoServer/WaveMageServer.cs
@@ -480,12 +480,8 @@
                        Dictionary<string, int> zxQtyDic = new Dictionary<string, int>();//托出整箱数
                        //分配货物
                        //assign.AllocatePallets(stocks, pNum, bNum, needQty, stockQtyDic, zxQtyDic);
                        var house = "";
                        if (notice.Type == "0")
                        {
                            house = "W01";
                        }
                        var qty = assign.AllotPallets(stockDetail, decimal.Parse(needQty.ToString()), pNum, bNum, stockQtyDic,"");
                        var qty = assign.AllotPallets(stockDetail, decimal.Parse(needQty.ToString()), pNum, bNum, stockQtyDic, notice.WareHouseNo);
                       
                        foreach (var sc in stockQtyDic)
                        {
Wms/WMS.Entity/LogEntity/LogTask.cs
@@ -35,7 +35,7 @@
        /// <summary>
        /// Desc:是否下发成功
        /// Default:
        /// Default: 0失败 1成功
        /// Nullable:True
        /// </summary>           
        public int? IsSuccess {get;set;}
Wms/WMS.IBLL/IBllSoServer/IExportNoticeServer.cs
@@ -155,6 +155,34 @@
        #endregion
        //------------------------------------------------------------------------------------------
        /// <summary>
        /// 获取出库单的仓库信息
        /// </summary>
        /// <param name="soNo">出库单号</param>
        /// <returns>出库单的仓库号</returns>
        string GetHouseBySo(string soNo);
        /// <summary>
        /// 下发出库 立库
        /// </summary>
        /// <param name="soNo">出库单</param>
        /// <param name="outMode">出库口</param>
        /// <param name="userId">下发人</param>
        /// <param name="url">下发路径</param>
        /// <param name="str">返回提示String</param>
        /// <returns>出库集合</returns>
        List<OutCommandDto> IssueOutHouseLk(string soNo, string outMode, int userId, string url, out string str);
        /// <summary>
        /// 下发出库 密集库
        /// </summary>
        /// <param name="soNo">出库单</param>
        /// <param name="outMode">出库口</param>
        /// <param name="userId">下发人</param>
        /// <param name="url">下发路径</param>
        /// <param name="str">返回提示String</param>
        /// <returns>出库集合</returns>
        List<OutCommandDto> IssueOutHouseMk(string soNo, string outMode, int userId, string url, out string str);
        /// <summary>
        /// 下发出库(调用cs接口给他库位地址)
Wms/WMS.IBLL/IPdaServer/IPdaCrServer.cs
@@ -150,5 +150,13 @@
        /// <param name="userId"></param>
        public void LingxingUnbind(string palletNo, string boxNo, int userId);
        #endregion
        #region 箱码拆箱贴标
        //箱码拆箱添加标签信息
        void AddLableByDevanning(string boxNo,decimal devanQty, int userId);
        #endregion
    }
}
Wms/Wms/Controllers/DownApiController.cs
@@ -19,6 +19,7 @@
using Utility;
using System.Threading.Tasks;
using Model.ModelVm.BllCheckVm;
using System.Collections.Generic;
namespace Wms.Controllers
{
@@ -101,7 +102,7 @@
        /// <returns></returns>
        [Authorize]
        [HttpGet]
        public IActionResult IssueOutHouse(string soNo, string unstackingMode, string outMode, string loadingAddre)
        public IActionResult IssueOutHouse(string soNo, string outMode)
        {
            try
            {
@@ -121,11 +122,23 @@
                //{
                //    return Ok(new { code = 1, msg = "请选择出库口" });
                //}
                var house = _exNoticeSvc.GetHouseBySo(soNo);
                if (house == "W01")
                {
                var list = _exNoticeSvc.IssueOutHouse(soNo, unstackingMode, outMode, loadingAddre, int.Parse(userId), _config.WcsHost + _config.IssueComApiUrl, out string str);
                    return Ok(new { code = 0, msg = "str" });
                }
                else if (house == "W02")
                {
                    var list = _exNoticeSvc.IssueOutHouseLk(soNo, outMode, int.Parse(userId), _config.WcsHost + _config.IssueComApiUrl, out string str);
                return Ok(new { code = 0, msg = str, data = list });
                    return Ok(new { code = 0, msg = str, data = list });
                }
                else
                {
                    return Ok(new { code = 1, msg = "仓库信息错误,请核实单据信息"});
                }
            }
            catch (Exception e)
            {
Wms/Wms/Controllers/PdaCrController.cs
@@ -282,5 +282,42 @@
            }
        }
        #endregion
        #region 拆箱贴标
        /// <summary>
        /// 拆箱贴标
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddLableByDevanning(PdaDevaningVm model)
        {
            try
            {
                //获取当前登录的用户ID
                var claimsIdentity = this.User.Identity as ClaimsIdentity;
                if (claimsIdentity == null)
                {
                    return Ok(new { code = 1, msg = "未获取到当前操作人信息" });
                }
                var userId = claimsIdentity.FindFirst(ClaimTypes.Name)?.Value;
                if (string.IsNullOrWhiteSpace(userId))
                {
                    return Ok(new { code = 1, msg = "未获取到当前操作人信息" });
                }
                var uId = int.Parse(userId);
                _pdaCrSvc.AddLableByDevanning(model.BoxNo, model.DevanQty,uId);
                return Ok(new { data = "", code = 0, msg = "成功" });
            }
            catch (Exception e)
            {
                return Ok(new { data = "", code = 1, msg = $"异常:{e.Message}" });
            }
        }
        #endregion
    }
}