kazelee
2025-05-12 968d603a08117e7e6707ffe07c6da9c325e36c08
完成并测试抽检出库的逻辑,修复相关问题
6个文件已添加
22个文件已修改
5个文件已删除
906 ■■■■ 已修改文件
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/142d45e0-bdbd-4ea2-8872-a4527bb762c2.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/6f64c2b7-09d5-4b3c-9a79-72745b90527c.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/99192c56-0abe-4e3f-b3f8-5389c9d993a4.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/b73147f2-b5c8-4121-b1aa-5fa60c01a097.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/b9ecb874-f2d6-4f8b-b5d4-8934da36989f.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/bed55563-1884-46d9-8f7f-fb19ae6beec5.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/dd1ab403-8a29-4f20-93da-995fa81d8fa6.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/ee67d919-8fb8-437c-9ad5-1a7b40e37bbd.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
Consts/SpotStateCode.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Controllers/DebugController.cs 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Controllers/MoboxController.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Dtos/Request/AgvRequest.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Dtos/Request/MoboxRequest.cs 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3.DSZSH.csproj 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Helpers/LogHelper.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Helpers/Model/TaskHelper.cs 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/BaseModel.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/DebugModel.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/TN_CG_Detail.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/TN_Check_Detail.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/TN_Check_Order.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/TN_Outbound_Detail.cs 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/TN_Outbound_Order.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/TN_Outbound_Task.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Models/TN_Task.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Program.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServiceCore/CheckCore.cs 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServiceCore/OutboundCore.cs 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServiceCore/TaskCore.cs 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Services/AgvService.cs 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Services/DebugService.cs 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Services/MoboxService.cs 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/config.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/142d45e0-bdbd-4ea2-8872-a4527bb762c2.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/6f64c2b7-09d5-4b3c-9a79-72745b90527c.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/99192c56-0abe-4e3f-b3f8-5389c9d993a4.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/b73147f2-b5c8-4121-b1aa-5fa60c01a097.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/b9ecb874-f2d6-4f8b-b5d4-8934da36989f.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/bed55563-1884-46d9-8f7f-fb19ae6beec5.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/dd1ab403-8a29-4f20-93da-995fa81d8fa6.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/ee67d919-8fb8-437c-9ad5-1a7b40e37bbd.vsidx
Binary files differ
Consts/SpotStateCode.cs
New file
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HH.WCS.Mobox3.DSZSH.Consts {
    /// <summary>
    /// 单据任务状态
    /// </summary>
    /// <remarks>
    /// N_B_STATE<br/>
    /// 业务状态:0等待执行 1已执行待生成任务 2任务执行中 3任务完成
    /// </remarks>
    public class SpotStateCode {
        public const int 待执行 = 0;
        public const int 已执行待生成任务 = 1;
        /// <summary>
        /// 对于Order:所有Detail都创建了任务,才进入此状态<br/>
        /// 对于Detail:只要创建了任务,就进入此状态
        /// </summary>
        public const int 任务执行中 = 2;
        public const int 任务执行完成 = 3;
    }
}
Controllers/DebugController.cs
@@ -35,41 +35,9 @@
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("BuildDB")]
        public string BuildDB()
        {
            try
            {
                var db = DbHelper.GetDbClient();
                //db.CodeFirst.InitTables<WCSTask>(); //所有库都支持
                //db.CodeFirst.InitTables<Zone>();
                //db.CodeFirst.InitTables<Area>();
                //db.CodeFirst.InitTables<Location>();
                //db.CodeFirst.InitTables<LocCntrRel>();
                //db.CodeFirst.InitTables<Container>();
                //db.CodeFirst.InitTables<SYSHelper.OI_SYS_MAXID>();
                db.CodeFirst.InitTables<TN_CG_Detail>();
                db.CodeFirst.InitTables<TN_WorkOrder>();
                db.CodeFirst.InitTables<TN_CAR_IN>();
                db.CodeFirst.InitTables<TN_Task_Action>();
                db.CodeFirst.InitTables<TN_Task>();
                db.CodeFirst.InitTables<TN_Location>();
                db.CodeFirst.InitTables<TN_Loc_Container>();
                db.CodeFirst.InitTables<TN_Outbound_Order>();
                db.CodeFirst.InitTables<TN_Outbound_Detail>();
                db.CodeFirst.InitTables<TN_Outbound_Task>();
            }
            catch (Exception ex)
            {
                LogHelper.Info($"发生了异常");
                return "初始化数据库错误" + ex.Message;
            }
            //return res ? "成功" : "失败";
            return "成功";
        [Route("CreateDatabase")]
        public string CreateDatabase() {
            return DebugService.CreateDatabase();
        }
        [HttpPost]
Controllers/MoboxController.cs
@@ -120,11 +120,12 @@
        }
        /// <summary>
        /// 创建抽检单(可能由PDA/WMS自行完成)
        /// 创建抽检单
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public SimpleResult CreateCheckOrder(CreateCheckOrderInfo model) {
        public SimpleResult CreateCheckOrder(CreateCheckOrderInfo model) {
            return MoboxService.CreateCheckOrder(model);
        }
Dtos/Request/AgvRequest.cs
@@ -33,7 +33,7 @@
            /// 请求码
            /// </summary>
            public string apply_code { get; set; }
            public string task_no { set; get; }
            public string TaskNo { set; get; }
        }
    }
}
Dtos/Request/MoboxRequest.cs
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json;
namespace HH.WCS.Mobox3.DSZSH.Dtos.Request {
    public class MoboxRequest {
@@ -95,10 +89,14 @@
        public class EmptyOnlineGoodpackInfo : StartCntEndInfo { }
        public class CreateCheckOrderInfo {
            public string No { get; set; }
            public string CgId { get; set; }
            public string ItemName { get; set; }
            public string BatchNo { get; set; }
            public string Qty { get; set; }
            /// <summary>
            /// 抽检数量
            /// </summary>
            public int Count { get; set; }
            public string EndArea { get; set; }
        }
        #endregion
@@ -113,20 +111,21 @@
            /// </summary>
            public string No { get; set; }
            public bool Forced { get; set; }
            public List<FinishedOutboundDetailInfo> OutboundDetails { get; set; }
        }
        public class FinishedOutboundDetailInfo {
            public string CgCode { get; set; }
            public string CgId { get; set; }
            public string CgName { get; set; }
            public string PatchNo { get; set; }
            public string BatchNo { get; set; }
            public string CntrType { get; set; }
            public int Qty { get; set; }
            public int Count { get; set; }
            public string EndArea { get; set; }
            //public bool Forced { get; set; }
            /// <summary>
            /// 是否强制出库
            /// </summary>
            public bool Forced { get; set; }
        }
        #endregion
        //------------------------------------------------------------------------------
HH.WCS.Mobox3.DSZSH.csproj
@@ -222,12 +222,14 @@
    <Compile Include="Consts\AreaName.cs" />
    <Compile Include="Consts\LockStateCode.cs" />
    <Compile Include="Consts\LockStateName.cs" />
    <Compile Include="Consts\SpotStateCode.cs" />
    <Compile Include="Consts\TaskName.cs" />
    <Compile Include="Controllers\DebugController.cs" />
    <Compile Include="Controllers\ErpController.cs" />
    <Compile Include="Controllers\MoboxController.cs" />
    <Compile Include="Controllers\AgvController.cs" />
    <Compile Include="AppStart\SwaggerControllerDescProvider.cs" />
    <Compile Include="Models\DebugModel.cs" />
    <Compile Include="Dtos\Request\DebugRequest.cs" />
    <Compile Include="Dtos\Response\BaseResponse.cs" />
    <Compile Include="Dtos\Response\DebugResponse.cs" />
@@ -236,13 +238,12 @@
    <Compile Include="Helpers\PathHelper.cs" />
    <Compile Include="Helpers\ResultHelper.cs" />
    <Compile Include="Helpers\DbHelper.cs" />
    <Compile Include="Models\DebugModel.cs" />
    <Compile Include="Models\TN_Check_Detail.cs" />
    <Compile Include="Models\TN_Check_Order.cs" />
    <Compile Include="Models\TN_Inbound_Order.cs" />
    <Compile Include="Models\TN_Order_Task.cs" />
    <Compile Include="Models\TN_Outbound_Order.cs" />
    <Compile Include="Models\TN_Outbound_Detail.cs" />
    <Compile Include="Models\TN_Outbound_Task.cs" />
    <Compile Include="ServiceCore\CheckCore.cs" />
    <Compile Include="ServiceCore\OutboundCore.cs" />
    <Compile Include="Services\DebugService.cs" />
@@ -302,7 +303,6 @@
  </ItemGroup>
  <ItemGroup>
    <None Include="debug\outbound_order.csv" />
    <Content Include="readme.dev.md" />
    <Content Include="readme.md" />
    <EmbeddedResource Include="swagger.js">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -320,6 +320,8 @@
      <Install>false</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <ItemGroup />
  <ItemGroup>
    <Folder Include="Dtos\Internal\" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
Helpers/LogHelper.cs
@@ -74,7 +74,7 @@
        #region 自定义方法
        public static void InfoEx(Exception ex) {
            Info($"发生了异常:{ex.Message}");
            Info($"异常:{ex.Message}");
        } 
        public static void InfoApi(string taskType, object model) {
Helpers/Model/TaskHelper.cs
@@ -56,6 +56,7 @@
                N_SCHEDULE_TYPE = 1,
                N_B_STATE = 0,
                S_CNTR_CODE = cnt,
                T_START_TIME = DateTime.Now,
            };
            var db = DbHelper.GetDbClient();
@@ -238,103 +239,7 @@
        private static object locLocker = new object();
        /// <summary>
        /// 推送任务
        /// </summary>
        /// <param name="mst"></param>
        internal static bool SendTask(TN_Task mst)
        {
            var result = false;
            var start = "0"; var end = "0";
            var taskType = mst.S_TYPE.Trim();
            if (mst.N_B_STATE == 0) {
                if (mst.N_SCHEDULE_TYPE == 1)//通过NDC,hosttoagv调度设备
                {
                    start = LocationHelper.GetAgvSite(mst.S_START_LOC);
                    end = LocationHelper.GetAgvSite(mst.S_END_LOC);
                    if (mst.S_TYPE == "空托下线堆叠")
                    {
                        end = LocationHelper.GetAgvSite(mst.S_END_LOC,true);
                    }
                    LogHelper.Info($"NDC推送任务 {mst.S_CODE};" + "start=" + start + "end= " + end);
                    var startLoc = LocationHelper.GetLoc(mst.S_START_LOC);
                    var endLoc = LocationHelper.GetLoc(mst.S_END_LOC);
                    var dic = new List<param>();
                    dic.Add(new param() { name = "IKey", value = "IKey" });
                    dic.Add(new param() { name = "From", value = start.ToString() });
                    dic.Add(new param() { name = "To", value = end.ToString() });
                    dic.Add(new param() { name = "FUNC", value = startLoc.N_LAYER.ToString() });
                    dic.Add(new param() { name = "Ctype", value = "0" });
                    if (mst.S_TYPE == "余料下线入库" || mst.S_TYPE == "人工拆盘入库")
                    {
                        dic.Add(new param() { name = "DATA", value = "1024" });
                    }
                    else
                    {
                        dic.Add(new param() { name = "DATA", value = "0" });
                    }
                    var res = NDCApi.AddOrderNew(1, 1, mst.S_CODE, dic);//添加新命令
                    if (res != null && (res.err_code == 0 || res.err_code == 50009))
                    {
                        //推送成功,修改任务优先级
                        mst.N_B_STATE = 1;
                        mst.S_B_STATE = TN_Task.GetStateStr(1);
                        UpdateStatus(mst);//更新任务状态
                        result = true;
                        LogHelper.Info($"NDC推送任务成功 {mst.S_CODE}start= {mst.S_START_LOC} + end = {mst.S_END_LOC}");
                    }
                    else
                    {
                        LogHelper.Info($"NDC推送任务失败 {mst.S_CODE};Res:" + JsonConvert.SerializeObject(res));
                    }
                }
                else if (mst.N_SCHEDULE_TYPE == 5)//通过杭奥调度设备
                {
                    //调第三方接口
                    var model = new HanAo.TaskInfoModel
                    {
                        requestPk = mst.S_CODE,
                        frmPos = mst.S_START_LOC,
                        toPos = mst.S_END_LOC,
                        trkType = mst.S_OP_NAME == "入库" ? "1" : "2",
                        contNo = mst.S_CNTR_CODE
                    };
                    if (HanAo.CreateOrder(model)) {
                        mst.N_B_STATE = 1;
                        UpdateStatus(mst);
                        LogHelper.Info($"杭奥推送任务成功 {mst.S_CODE};" + "start=" + model.frmPos + "end= " + model.toPos);
                    }
                    else
                    {
                        LogHelper.Info($"杭奥推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(model));
                    }
                }
                else if (mst.N_SCHEDULE_TYPE == 3) //通过国自调度设备
                {
                    var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = mst.S_START_LOC, dst = mst.S_END_LOC }), "p2p");
                    if (code > 0) {
                        //更新任务状态
                        mst.N_B_STATE = 1;
                        mst.S_EQ_TASK_CODE = code.ToString();
                        UpdateStatus(mst);
                        UpdateEQNo(mst);
                        LogHelper.Info($"国自推送任务成功 {mst.S_CODE};" + "start=" + mst.S_START_LOC + "end= " + mst.S_END_LOC);
                    }
                    else
                    {
                        LogHelper.Info($"国自推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(mst));
                    }
                }
            }
            return result;
        }
        internal static bool UpdateStatus(TN_Task task, string status) {
@@ -344,6 +249,8 @@
            res = db.Updateable(task).UpdateColumns(it => new { it.S_B_STATE }).ExecuteCommand() > 0;
            return res;
        }
        internal static bool UpdateStatus(TN_Task task) {
            var res = false;
            var db = DbHelper.GetDbClient();
@@ -353,7 +260,7 @@
            return res;
        }
        internal static bool UpdateEQNo(TN_Task task) {
        internal static bool UpdateEqNo(TN_Task task) {
            var res = false;
            var db = DbHelper.GetDbClient();
            task.T_MODIFY = DateTime.Now;
Models/BaseModel.cs
@@ -37,9 +37,6 @@
        /// <summary>
        /// 数据状态:编辑、定版
        /// </summary>
        /// <remarks>
        /// 如果具体表单中需要指明状态,用 S_B_STATE 代替
        /// </remarks>
        public string S_STATE { get; set; } = "编辑";
    }
}
Models/DebugModel.cs
@@ -5,9 +5,6 @@
using System.Threading.Tasks;
namespace HH.WCS.Mobox3.DSZSH.Models {
    /// <summary>
    /// Debug使用的数据模型
    /// </summary>
    public class DebugModel {
        public class LocCntrCg {
            public string LocCode { get; set; }
Models/TN_CG_Detail.cs
@@ -4,9 +4,6 @@
    /// <summary>
    /// 【框架】物料-容器 关系表
    /// </summary>
    /// <remarks>
    /// CG = Cargo Goods 货物商品
    /// </remarks>
    [SugarTable("TN_CG_Detail")]
    public class TN_CG_Detail : BaseModel {
        /// <summary>
@@ -27,17 +24,11 @@
        /// <summary>
        /// 货品状态:0合格 1待检 2不合格 3正在检验;下线即待检
        /// </summary>
        /// <remarks>
        /// 算法:数字越小越优先,合格>待检>不合格>正在检验(直接否定)
        /// </remarks>
        public string S_ITEM_STATE { get; set; } = "待检";
        /// <summary>
        /// 货品状态_字典:0合格 1待检 2不合格 3正在检验;下线即待检
        /// 货品状态:0合格 1待检 2不合格 3正在检验;下线即待检
        /// </summary>
        /// <remarks>
        /// 算法:数字越小越优先,合格>待检>不合格>正在检验(直接否定)
        /// </remarks>
        public int N_ITEM_STATE { get; set; } = 1;
        /// <summary>
Models/TN_Check_Detail.cs
New file
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
namespace HH.WCS.Mobox3.DSZSH.Models {
    /// <summary>
    /// 抽检单明细
    /// </summary>
    [SugarTable("TN_Check_Detail")]
    public class TN_Check_Detail : BaseModel {
        public string S_NO { get; set; }
        public string S_CG_ID { get; set; }
        public string S_ITEM_NAME { get; set; }
        public string S_BATCH_NO { get; set; }
        public string S_END_AREA { get; set; }
        /// <summary>
        /// 业务状态:0等待执行 1已执行待生成任务 2任务执行中 3任务完成
        /// </summary>
        public int N_B_STATE { get; set; } = 1; // 创建即执行
    }
}
Models/TN_Check_Order.cs
@@ -12,14 +12,15 @@
    /// </summary>
    [SugarTable("TN_Check_Order")]
    public class TN_Check_Order : BaseModel {
        public string S_NO { get; set; }
        public string S_CG_ID { get; set; }
        public string S_ITEM_NAME { get; set; }
        public string S_BATCH_NO { get; set; }
        public int N_QTY { get; set; }
        public int N_COUNT { get; set; }
        public string S_END_AREA { get; set; }
        /// <summary>
        /// 抽检单状态:0未执行 1执行中 2完成
        /// 业务状态:0等待执行 1已执行待生成任务 2任务执行中 3任务完成
        /// </summary>
        public int N_B_STATE { get; set; } = 0;
        public int N_B_STATE { get; set; } = 0; // 创建后需要确认执行
    }
}
Models/TN_Outbound_Detail.cs
@@ -11,15 +11,10 @@
        /// </summary>
        public string S_NO { get; set; }
        ///// <summary>
        ///// 行号
        ///// </summary>
        //public int N_ROW_NO { get; set; }
        /// <summary>
        /// 业务状态:0等待 1正在执行 2已完成
        /// 业务状态:0等待执行 1已执行待生成任务 2任务执行中 3任务完成
        /// </summary>
        public int N_B_STATE { get; set; } = 0;
        public int N_B_STATE { get; set; } = 1; // 创建即执行
        /// <summary>
        /// 物料号
@@ -35,11 +30,6 @@
        /// 出库货品数量(整数,用于生成任务数)
        /// </summary>
        public int N_QTY { get; set; }
        /// <summary>
        /// 已出库的货品数量
        /// </summary>
        public int N_O_QTY { get; set; } = 0;
        /// <summary>
        /// 终点库区(由WMS下发任务时指定)
Models/TN_Outbound_Order.cs
@@ -14,9 +14,29 @@
        public string S_NO { get; set; }
        /// <summary>
        /// 业务状态:0等待 1正在执行 2已完成
        /// 业务状态:0等待执行 1已执行待生成任务 2任务执行中 3任务完成
        /// </summary>
        public int N_B_STATE { get; set; } = 0;
        public int N_B_STATE { get; set; } = 1; // 创建即执行
        /// <summary>
        /// 物料号
        /// </summary>
        public string S_CG_ID { get; set; }
        /// <summary>
        /// 批次号
        /// </summary>
        public string S_BATCH_NO { get; set; }
        /// <summary>
        /// 出库货品数量(整数,用于生成任务数)
        /// </summary>
        public int N_COUNT { get; set; }
        /// <summary>
        /// 终点库区(由WMS下发任务时指定)
        /// </summary>
        public string S_END_AREA { get; set; }
        /// <summary>
        /// 是否强制出库:0不强制 1强制
Models/TN_Outbound_Task.cs
File was deleted
Models/TN_Task.cs
@@ -38,8 +38,14 @@
        /// </summary>
        public string S_END_LOC { get; set; }
    
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime? T_START_TIME { get; set; }
        /// <summary>
        /// 完成时间
        /// </summary>
        public DateTime? T_END_TIME { get; set; }
        /// <summary>
Program.cs
@@ -127,9 +127,9 @@
            {
                List<Task> tasks = new List<Task>();
                tasks.Add(GetTask(OutboundCore.CheckOutboundOrder));
                tasks.Add(GetTask(CheckCore.CheckOrderState));
                tasks.Add(GetTask(OutboundCore.CheckOutboundTask));
                tasks.Add(GetTask(OutboundCore.CheckOrderState));
                // 添加任务推送线程
@@ -144,7 +144,8 @@
                Task.WaitAll(tasks.ToArray());
            }
            public void Stop() { Console.WriteLine("work stopped"); }
            private Task GetTask(Action action)
            private Task GetTask(Action action, int intervalMs = 3000)
            {
                var task = Task.Run(() =>
                {
@@ -158,7 +159,7 @@
                        {
                            LogHelper.Error(ex.Message, ex);
                        }
                        Thread.Sleep(3000);
                        Thread.Sleep(intervalMs);
                    }
                });
                return task;
ServiceCore/CheckCore.cs
@@ -9,62 +9,103 @@
using HH.WCS.Mobox3.DSZSH.Helpers.Model;
using HH.WCS.Mobox3.DSZSH.Models;
using Org.BouncyCastle.Asn1.X509;
namespace HH.WCS.Mobox3.DSZSH.ServiceCore {
    /// <summary>
    /// 定时轮询任务:抽检业务核心
    /// </summary>
    public class CheckCore {
        /// <summary>
        /// 轮询查看抽检单是否有执行中的项目
        /// </summary>
        public void CheckOrderState() {
        public static void CheckOrderState() {
            var db = DbHelper.GetDbClient();
            try {
                var orderList = db.Queryable<TN_Check_Order>()
                    .Where(c => c.N_B_STATE == 0)
                    .OrderBy(c => c.T_CREATE).ToList();
                var order = db.Queryable<TN_Check_Order>()
                    .Where(c => c.N_B_STATE == SpotStateCode.已执行待生成任务)
                    .OrderBy(c => c.T_CREATE, SqlSugar.OrderByType.Asc).First();
                using (var tran = db.Ado.UseTran()) {
                    foreach (var order in orderList) {
                        var startLocList = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail>
                            ((l, c, d) => l.S_CODE == c.S_LOC_CODE && c.S_CNTR_CODE == d.S_CNTR_CODE)
                            .Where((l, c, d) => d.S_CG_ID == order.S_CG_ID && d.S_BATCH_NO == order.S_BATCH_NO)
                            .Select((l, c) => new { Location = l, Container = c })
                            .Take(order.N_QTY).ToList(); // 获取指定数量的货位数,随机抽取故无需排序
                if (order == null) {
                    LogHelper.Info("暂无待执行的抽检单");
                    return;
                }
                        if (startLocList.Count < order.N_QTY) {
                            LogHelper.Info($"轮询 | 当前可抽检的物料数量 {startLocList.Count} 无法满足抽检单数量 {order.N_QTY} 要求");
                            return;
                var detailList = db.Queryable<TN_Check_Detail>()
                    .Where(d => d.S_NO == order.S_NO && d.N_B_STATE == SpotStateCode.已执行待生成任务).ToList();
                if (detailList.Count == 0) {
                    order.N_B_STATE = SpotStateCode.任务执行中;
                    db.Updateable<TN_Check_Order>(order).UpdateColumns(it => it.N_B_STATE).ExecuteCommand();
                    return;
                }
                foreach (var detail in detailList) {
                    var startLocCntrRel = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail>
                        ((l, c, d) => l.S_CODE == c.S_LOC_CODE && c.S_CNTR_CODE == d.S_CNTR_CODE)
                        .Where((l, c, d) => d.S_CG_ID == detail.S_CG_ID && d.S_BATCH_NO == detail.S_BATCH_NO)
                        .Select((l, c) => c) // 选择 LocCntrRel
                        .First(); // 随机抽检,不排序
                    if (startLocCntrRel == null) {
                        LogHelper.Info("没有找到合适的起点货位");
                        continue;
                    }
                    var endLoc = db.Queryable<TN_Location>()
                        .Where(l => l.S_AREA_CODE == detail.S_END_AREA)
                        .Where(ExprHelper.LocIsFree)
                        .Where(ExprHelper.LocIsEmpty).First();
                    if (endLoc == null) {
                        LogHelper.Info("查询:没有找到合适的终点货位");
                        continue;
                    }
                    using (var tran = db.Ado.UseTran()) {
                        detail.N_B_STATE = SpotStateCode.任务执行中;
                        if (db.Updateable<TN_Check_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            LogHelper.Info($"更新失败:修改抽检单明细表状态为完成");
                        }
                        var endLocList = db.Queryable<TN_Location>()
                            .Where(l => l.S_AREA_CODE == order.S_END_AREA)
                            .Where(ExprHelper.LocIsFree)
                            .Where(ExprHelper.LocIsEmpty)
                            .Take(order.N_QTY).ToList(); // 获取指定数量的货位数
                        if (endLocList.Count < order.N_QTY) {
                            LogHelper.Info($"轮询 | 终点区域可用货位 {startLocList.Count} 无法满足抽检单数量 {order.N_QTY} 要求");
                            return;
                        if (TaskHelper.LogCreateTask(startLocCntrRel.S_LOC_CODE, startLocCntrRel.S_CNTR_CODE,
                            endLoc.S_CODE, TaskName.抽检)) {
                            tran.CommitTran();
                        }
                        // TODO 参考出库,如果要求任务顺序也要新创建表存储,有需求再更新
                        for (var i = 0; i < order.N_QTY; i++) {
                            if (!TaskHelper.LogCreateTask(startLocList[i].Location.S_CODE, startLocList[i].Container.S_CNTR_CODE,
                                endLocList[i].S_CODE, TaskName.抽检)) {
                                tran.RollbackTran();
                            }
                        else {
                            tran.RollbackTran();
                        }
                        order.N_B_STATE = 1;
                        db.Updateable<TN_Check_Order>(endLocList).UpdateColumns(c => c.N_B_STATE);
                        tran.CommitTran();
                    }
                    }
                }
            }
            catch (Exception ex) {
                LogHelper.InfoEx(ex);
            }
        }
        public static void UpdateTaskState(int spotStateCode) {
            var db = DbHelper.GetDbClient();
            var detail = db.Queryable<TN_Check_Detail>()
                .First(d => d.N_B_STATE == SpotStateCode.任务执行中);
            if (detail == null) {
                LogHelper.Info("当前没有执行中的抽检单明细项目");
                return;
            }
            using (var tran = db.Ado.UseTran()) {
                detail.N_B_STATE = spotStateCode;
                db.Updateable<TN_Check_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand();
                if (db.Queryable<TN_Check_Detail>().Count(d => d.S_NO == detail.S_NO && d.N_B_STATE == 2) ==
                    db.Queryable<TN_Check_Detail>().Count(d => d.S_NO == detail.S_NO)) {
                    if (db.Updateable<TN_Check_Order>().SetColumns(it => it.N_B_STATE == SpotStateCode.任务执行完成)
                        .Where(it => it.S_NO == detail.S_NO)
                        .ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        LogHelper.Info("修改Order状态错误");
                    }
                }
                tran.CommitTran();
            }
        }
    }
}
ServiceCore/OutboundCore.cs
@@ -1,171 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HH.WCS.Mobox3.DSZSH.Consts;
using HH.WCS.Mobox3.DSZSH.Helpers;
using HH.WCS.Mobox3.DSZSH.Helpers.Model;
using HH.WCS.Mobox3.DSZSH.Models;
using Newtonsoft.Json;
namespace HH.WCS.Mobox3.DSZSH.ServiceCore {
    /// <summary>
    /// 定时轮询任务:出库业务核心
    /// </summary>
    public class OutboundCore {
        /// <summary>
        /// 后台轮询出库单/出库明细单,生成出库任务表
        /// </summary>
        public static void CheckOutboundOrder() {
        public static void CheckOrderState() {
            var db = DbHelper.GetDbClient();
            try {
                // 查找所有的 等待出库 的 出库单,按 先创建先处理 排序
                var orders = db.Queryable<TN_Outbound_Order>()
                    .Where(o => o.N_B_STATE == 0)
                    .OrderBy(o => o.T_CREATE)
                    .Mapper(
                        o => o.Details, // 将子表数据映射到主表的 Details 属性
                        o => o.S_NO,    // 主表关联字段
                        d => d.S_NO     // 子表关联字段
                    )
                    .ToList();
                var order = db.Queryable<TN_Outbound_Order>()
                    .Where(c => c.N_B_STATE == SpotStateCode.已执行待生成任务)
                    .OrderBy(c => c.T_CREATE, SqlSugar.OrderByType.Asc).First();
                if (orders.Count == 0) {
                    LogHelper.Info("轮询 | 当前没有等待执行的出库单");
                if (order == null) {
                    LogHelper.Info("轮询:暂无待执行的出库单");
                    return;
                }
                using (var tran = db.Ado.UseTran()) {
                    foreach (var o in orders) {
                        foreach (var d in o.Details) {
                            for (int i = 0; i < d.N_QTY; i++) {
                                var task = new TN_Outbound_Task {
                                    S_CG_ID = d.S_CG_ID,
                                    S_END_AREA = d.S_END_AREA,
                                    N_FORCE = o.N_FORCE,
                                    S_BATCH_NO = d.S_BATCH_NO,
                                    N_STATE = 0
                                };
                                if (db.Insertable<TN_Outbound_Task>(task).ExecuteCommand() <= 0) {
                                    tran.RollbackTran();
                                    LogHelper.Info("插入任务出错");
                                    return;
                                }
                            }
                            d.N_B_STATE = 1;
                            if (db.Updateable<TN_Outbound_Detail>(d).UpdateColumns(c => c.N_B_STATE).ExecuteCommand() > 0) {
                                LogHelper.Info("更新 N_B_STATE 成功");
                            }
                            else {
                                tran.RollbackTran();
                                LogHelper.Info("更新 N_B_STATE 失败");
                                return;
                            }
                        }
                        o.N_B_STATE = 1;
                        if (db.Updateable<TN_Outbound_Order>(o).UpdateColumns(c => c.N_B_STATE).ExecuteCommand() > 0) {
                            LogHelper.Info("更新 N_B_STATE 成功");
                        }
                        else {
                            tran.RollbackTran();
                            LogHelper.Info("更新 N_B_STATE 失败");
                            return;
                        }
                    }
                    tran.CommitTran();
                }
            }
            catch (Exception ex) {
                LogHelper.InfoEx(ex);
                throw;
            }
        }
        /// <summary>
        /// 轮询出库
        /// </summary>
        public static void CheckOutboundTask() {
            var db = DbHelper.GetDbClient();
            try {
                var task = db.Queryable<TN_Outbound_Task>()
                    .Where(t => t.N_STATE == 0).First();
                if (task == null) {
                    LogHelper.Info("轮询 | 出库任务队列 暂无待执行的任务");
                if (db.Queryable<TN_Outbound_Detail>()
                    .First(d => d.S_NO == order.S_NO && d.N_B_STATE == SpotStateCode.任务执行中) != null) {
                    LogHelper.Debug("轮询:上一个出库任务仍在进行中");
                    return;
                }
                var headTask = task;
                if (headTask.N_STATE != 0) {
                    LogHelper.Info("轮询 | 出库任务队列 队头任务尚未完成");
                var detail = db.Queryable<TN_Outbound_Detail>()
                    .Where(d => d.S_NO == order.S_NO && d.N_B_STATE == SpotStateCode.已执行待生成任务)
                    .OrderBy(d => d.T_CREATE, SqlSugar.OrderByType.Asc).First();
                if (detail == null) {
                    //order.N_B_STATE = SpotStateCode.任务执行中;
                    LogHelper.Info("轮询出库:暂无待执行的任务");
                    return;
                }
                var locCntr = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail>
                var startLocCntrRel = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail>
                    ((l, c, d) => l.S_CODE == c.S_LOC_CODE && c.S_CNTR_CODE == d.S_CNTR_CODE)
                    // 筛选要求的物料编码和批次号
                    .Where((l, c, d) => d.S_CG_ID == headTask.S_CG_ID && d.S_BATCH_NO == headTask.S_BATCH_NO)
                    .Where((l, c, d) => d.S_CG_ID == detail.S_CG_ID && d.S_BATCH_NO == detail.S_BATCH_NO)
                    // 如果不是强制出库,物料状态必须必须合格
                    // 否则,只要不是正在检验的物料即可
                    .Where((l, c, d) => (headTask.N_FORCE == 0 && d.N_ITEM_STATE == 0 && d.S_ITEM_STATE == "合格")
                        || (headTask.N_FORCE != 0 && d.N_ITEM_STATE != 3 && d.S_ITEM_STATE != "正在检验"))
                    // 物料状态对应的数字,越小越优先
                    // 否则,只要不是 正在检验 的物料即可
                    .Where((l, c, d) => (detail.N_FORCE == 0 && d.N_ITEM_STATE == 0 && d.S_ITEM_STATE == "合格")
                        || (detail.N_FORCE != 0 && d.N_ITEM_STATE != 3 && d.S_ITEM_STATE != "正在检验"))
                    // 排序:数字越小越优先,合格>待检>不合格
                    .OrderBy((l, c, d) => d.N_ITEM_STATE)
                    .OrderBy(l => l.N_LAYER)
                    .Select((l, c) => new { Location = l, Container = c }).First();
                if (locCntr == null) {
                    LogHelper.Info("轮询 | 不存在符合条件的物料货位");
                    .Select((l, c) => c).First();
                if (startLocCntrRel == null) {
                    LogHelper.Info("轮询:出库:没有找到合适的起点货位");
                    return;
                }
                var endLoc = db.Queryable<TN_Location>()
                    .Where(l => l.S_AREA_CODE == headTask.S_END_AREA)
                    .Where(l => l.S_AREA_CODE == detail.S_END_AREA)
                    .Where(ExprHelper.LocIsFree)
                    .Where(ExprHelper.LocIsEmpty)
                    .OrderBy(l => l.S_CODE)
                    .First();
                    .Where(ExprHelper.LocIsEmpty).First();
                if (endLoc == null) {
                    LogHelper.Info("轮询 | 不存在符合条件的出库终点库位");
                    LogHelper.Info("轮询:出库:没有找到合适的终点货位");
                    return;
                }
                using (var tran = db.Ado.UseTran()) {
                    if (TaskHelper.LogCreateTask(locCntr.Location.S_CODE, locCntr.Container.S_CNTR_CODE, endLoc.S_CODE, TaskName.成品胶出库)) {
                        task.N_STATE = 1;
                        if (db.Updateable<TN_Outbound_Task>(task).UpdateColumns(c => c.N_STATE).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            LogHelper.Info("修改出库任务状态错误");
                        }
                        else {
                            tran.CommitTran();
                            LogHelper.Info("修改出库任务状态成功");
                        }
                    detail.N_B_STATE = SpotStateCode.任务执行中;
                    if (db.Updateable<TN_Outbound_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        LogHelper.Info($"轮询:出库:更新失败:修改明细表状态为完成");
                    }
                    if (TaskHelper.LogCreateTask(startLocCntrRel.S_LOC_CODE, startLocCntrRel.S_CNTR_CODE,
                        endLoc.S_CODE, TaskName.成品胶出库)) {
                        tran.CommitTran();
                    }
                    else {
                        tran.RollbackTran();
                    }
                }
            }
            catch (Exception ex) {
                LogHelper.InfoEx(ex);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="state"></param>
        public static void UpdateTaskState(int state = 2) {
        public static void UpdateTaskState(int spotStateCode) {
            var db = DbHelper.GetDbClient();
            var detail = db.Queryable<TN_Outbound_Detail>()
                    .First(d => d.N_B_STATE == SpotStateCode.任务执行中);
            if (detail == null) {
                LogHelper.Info("当前没有执行中的出库单明细项目");
                return;
            }
            using (var tran = db.Ado.UseTran()) {
                detail.N_B_STATE = spotStateCode;
                db.Updateable<TN_Outbound_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand();
                if (db.Queryable<TN_Outbound_Detail>().Count(d => d.S_NO == detail.S_NO && d.N_B_STATE == 2) ==
                    db.Queryable<TN_Outbound_Detail>().Count(d => d.S_NO == detail.S_NO)) {
                    if (db.Updateable<TN_Check_Order>().SetColumns(it => it.N_B_STATE == SpotStateCode.任务执行完成)
                        .Where(it => it.S_NO == detail.S_NO)
                        .ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        LogHelper.Info("修改Order状态错误");
                    }
                }
                tran.CommitTran();
            }
        }
    }
ServiceCore/TaskCore.cs
@@ -7,6 +7,9 @@
using static HH.WCS.Mobox3.DSZSH.Dtos.Request.AgvRequest;
using static HH.WCS.Mobox3.DSZSH.Dtos.Response.AgvResponse;
using HH.WCS.Mobox3.DSZSH.Dispatch;
using HH.WCS.Mobox3.DSZSH.Models;
using System.Collections.Generic;
namespace HH.WCS.Mobox3.DSZSH.ServiceCore {
    internal class TaskCore {
@@ -21,7 +24,7 @@
            if (list.Count > 0) {
                list.ForEach(task => {
                    // 使用自定义任务推送
                    TaskHelper.SendTask(task); // 调度NDC或杭奥或国自设备
                    SendTask(task); // 调度NDC或杭奥或国自设备
                    //TaskProcess.SendGZTask(task); // 调度国自设备
                });
            }
@@ -29,5 +32,94 @@
                LogHelper.Info("暂无任务");
            }
        }
        /// <summary>
        /// 推送任务
        /// </summary>
        /// <param name="mst"></param>
        internal static bool SendTask(TN_Task mst) {
            var result = false;
            var start = "0"; var end = "0";
            var taskType = mst.S_TYPE.Trim();
            if (mst.N_B_STATE == 0) {
                if (mst.N_SCHEDULE_TYPE == 1)//通过NDC,hosttoagv调度设备
                {
                    start = LocationHelper.GetAgvSite(mst.S_START_LOC);
                    end = LocationHelper.GetAgvSite(mst.S_END_LOC);
                    if (mst.S_TYPE == "空托下线堆叠") {
                        end = LocationHelper.GetAgvSite(mst.S_END_LOC, true);
                    }
                    LogHelper.Info($"NDC推送任务 {mst.S_CODE};" + "start=" + start + "end= " + end);
                    var startLoc = LocationHelper.GetLoc(mst.S_START_LOC);
                    var endLoc = LocationHelper.GetLoc(mst.S_END_LOC);
                    var dic = new List<param>();
                    dic.Add(new param() { name = "IKey", value = "IKey" });
                    dic.Add(new param() { name = "From", value = start.ToString() });
                    dic.Add(new param() { name = "To", value = end.ToString() });
                    dic.Add(new param() { name = "FUNC", value = startLoc.N_LAYER.ToString() });
                    dic.Add(new param() { name = "Ctype", value = "0" });
                    if (mst.S_TYPE == "余料下线入库" || mst.S_TYPE == "人工拆盘入库") {
                        dic.Add(new param() { name = "DATA", value = "1024" });
                    }
                    else {
                        dic.Add(new param() { name = "DATA", value = "0" });
                    }
                    var res = NDCApi.AddOrderNew(1, 1, mst.S_CODE, dic);//添加新命令
                    if (res != null && (res.err_code == 0 || res.err_code == 50009)) {
                        //推送成功,修改任务优先级
                        mst.N_B_STATE = 1;
                        mst.S_B_STATE = TN_Task.GetStateStr(1);
                        TaskHelper.UpdateStatus(mst);//更新任务状态
                        result = true;
                        LogHelper.Info($"NDC推送任务成功 {mst.S_CODE}start= {mst.S_START_LOC} + end = {mst.S_END_LOC}");
                    }
                    else {
                        LogHelper.Info($"NDC推送任务失败 {mst.S_CODE};Res:" + JsonConvert.SerializeObject(res));
                    }
                }
                else if (mst.N_SCHEDULE_TYPE == 5)//通过杭奥调度设备
                {
                    //调第三方接口
                    var model = new HanAo.TaskInfoModel {
                        requestPk = mst.S_CODE,
                        frmPos = mst.S_START_LOC,
                        toPos = mst.S_END_LOC,
                        trkType = mst.S_OP_NAME == "入库" ? "1" : "2",
                        contNo = mst.S_CNTR_CODE
                    };
                    if (HanAo.CreateOrder(model)) {
                        mst.N_B_STATE = 1;
                        TaskHelper.UpdateStatus(mst);
                        LogHelper.Info($"杭奥推送任务成功 {mst.S_CODE};" + "start=" + model.frmPos + "end= " + model.toPos);
                    }
                    else {
                        LogHelper.Info($"杭奥推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(model));
                    }
                }
                else if (mst.N_SCHEDULE_TYPE == 3) //通过国自调度设备
                {
                    var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = mst.S_START_LOC, dst = mst.S_END_LOC }), "p2p");
                    if (code > 0) {
                        //更新任务状态
                        mst.N_B_STATE = 1;
                        mst.S_EQ_TASK_CODE = code.ToString();
                        TaskHelper.UpdateStatus(mst);
                        TaskHelper.UpdateEqNo(mst);
                        LogHelper.Info($"国自推送任务成功 {mst.S_CODE};" + "start=" + mst.S_START_LOC + "end= " + mst.S_END_LOC);
                    }
                    else {
                        LogHelper.Info($"国自推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(mst));
                    }
                }
            }
            return result;
        }
    }
}
Services/AgvService.cs
@@ -11,6 +11,8 @@
using static HH.WCS.Mobox3.DSZSH.Dtos.Request.AgvRequest;
using static HH.WCS.Mobox3.DSZSH.Dtos.Response.AgvResponse;
using System.Threading.Tasks;
using HH.WCS.Mobox3.DSZSH.ServiceCore;
namespace HH.WCS.Mobox3.DSZSH.Services {
    public class AgvService {
@@ -55,7 +57,7 @@
        }
        /// <summary>
        /// 执行 AGV 任务,查询不到任务返回 <see langword="false"/>(私有方法,内部调用)
        /// 执行 AGV 任务,查询不到任务返回 <see langword="false"/>
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
@@ -81,7 +83,11 @@
                    TaskHelper.UpdateStatus(TN_Task, "取货完成"); // 任务状态改成取货完成
                    TaskHelper.OperateStatus(TN_Task, 4); // 起点容器货位解绑,解锁起点
                    if (TN_Task.S_TYPE == TaskName.成品胶出库) {
                        var nextOutboundTask = Task.Run(() => {
                            OutboundCore.UpdateTaskState(SpotStateCode.任务执行完成);
                        });
                    }
                    break;
                case AgvStateCode.开始卸货:
@@ -93,6 +99,13 @@
                    break;
                case AgvStateCode.完成:
                    TaskHelper.End(TN_Task); // 任务状态改成结束
                    if (TN_Task.S_TYPE == TaskName.抽检) {
                        var checkCompleteTask = Task.Run(() => {
                            CheckCore.UpdateTaskState(SpotStateCode.任务执行完成);
                        });
                    }
                    break;
                case AgvStateCode.异常:
                    TaskHelper.OperateStatus(TN_Task, 7); // 异常处理
@@ -115,15 +128,17 @@
            ModbusHelper.Relink();
            try {
                var prodLineInfo = AppStart.Settings.Config.ProductionLines[0];
                var prodLineDevice = new ProductionLineDevice(prodLineInfo.PlcIp, prodLineInfo.PlcPort);
                if (!prodLineDevice.LoadDeviceStateOk()) {
                    LogHelper.Info("加载设备信息失败");
                }
                var tn_task = db.Queryable<TN_Task>().First(a => a.S_CODE == model.task_no);
                var tn_task = db.Queryable<TN_Task>().First(a => a.S_CODE == model.TaskNo);
                if (tn_task == null) {
                    LogHelper.Info($"任务号 '{model.task_no}' 不存在");
                    LogHelper.Info($"任务号 '{model.TaskNo}' 不存在");
                }
                // 待修改:补充不同分支AGV判断
Services/DebugService.cs
@@ -16,6 +16,7 @@
using static HH.WCS.Mobox3.DSZSH.Dtos.Request.DebugRequest;
using static HH.WCS.Mobox3.DSZSH.Dtos.Response.AgvResponse;
using static HH.WCS.Mobox3.DSZSH.Dtos.Response.DebugResponse;
using static HH.WCS.Mobox3.DSZSH.Models.DebugModel;
namespace HH.WCS.Mobox3.DSZSH.Services {
    public class DebugService {
@@ -79,22 +80,24 @@
        /// 初始数据库建立
        /// </summary>
        /// <returns></returns>
        public string CreateDatabase() {
        public static string CreateDatabase() {
            try {
                var db = DbHelper.GetDbClient();
                db.CodeFirst.InitTables<TN_CG_Detail>();
                db.CodeFirst.InitTables<TN_WorkOrder>();
                db.CodeFirst.InitTables<TN_CAR_IN>();
                //db.CodeFirst.InitTables<SYSHelper.OI_SYS_MAXID>();
                db.CodeFirst.InitTables<TN_Task_Action>();
                db.CodeFirst.InitTables<TN_Task>();
                db.CodeFirst.InitTables<TN_Location>();
                db.CodeFirst.InitTables<TN_Loc_Container>();
                //db.CodeFirst.InitTables<TN_CG_Detail>();
                //db.CodeFirst.InitTables<TN_WorkOrder>();
                //db.CodeFirst.InitTables<TN_CAR_IN>();
                ////db.CodeFirst.InitTables<SYSHelper.OI_SYS_MAXID>();
                //db.CodeFirst.InitTables<TN_Task_Action>();
                //db.CodeFirst.InitTables<TN_Task>();
                //db.CodeFirst.InitTables<TN_Location>();
                //db.CodeFirst.InitTables<TN_Loc_Container>();
                db.CodeFirst.InitTables<TN_Outbound_Order>();
                db.CodeFirst.InitTables<TN_Outbound_Detail>();
                db.CodeFirst.InitTables<TN_Outbound_Task>();
                //db.CodeFirst.InitTables<TN_Outbound_Order>();
                //db.CodeFirst.InitTables<TN_Outbound_Detail>();
                //db.CodeFirst.InitTables<TN_Check_Order>();
                db.CodeFirst.InitTables<TN_Check_Detail>();
            }
            catch (Exception ex) {
                LogHelper.Info($"发生了异常");
@@ -118,12 +121,12 @@
                    BadDataFound = context => { }  // 处理错误数据
                };
                var locCntrCgList = new List<DebugModel.LocCntrCg>();
                var locCntrCgList = new List<LocCntrCg>();
                using (var reader = new StreamReader(filePath))
                using (var csv = new CsvReader(reader, configuration)) {
                    // 读取记录
                    locCntrCgList = csv.GetRecords<DebugModel.LocCntrCg>().ToList();
                    locCntrCgList = csv.GetRecords<LocCntrCg>().ToList();
                }
                using (var tran = db.UseTran()) {
Services/MoboxService.cs
@@ -383,24 +383,48 @@
            }
        }
        /// <summary>
        /// 创建抽检单
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static SimpleResult CreateCheckOrder(CreateCheckOrderInfo model) {
            var db = DbHelper.GetDbClient();
            try {
                // 绑定操作:插入出库单、所有的出库单明细
                using (var tran = db.Ado.UseTran()) {
                var order = new TN_Check_Order {
                    S_CG_ID = model.CgId,
                    S_ITEM_NAME = model.ItemName,
                    S_BATCH_NO = model.BatchNo,
                    N_QTY = model.Qty,
                    S_END_AREA = model.EndArea,
                };
                    var order = new TN_Check_Order {
                        S_NO = model.No,
                        S_CG_ID = model.CgId,
                        S_ITEM_NAME = model.ItemName,
                        S_BATCH_NO = model.BatchNo,
                        N_COUNT = model.Count,
                        S_END_AREA = model.EndArea,
                    };
                if (db.Insertable<TN_Check_Order>(order).ExecuteCommand() > 0) {
                    return BuildSimpleResult(0, "插入抽检单成功:" + JsonConvert.SerializeObject(order));
                    if (db.Insertable<TN_Check_Order>(order).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return BuildSimpleResult(2, "生成 抽检单 失败:" + JsonConvert.SerializeObject(order));
                    }
                    for (int i = 0; i < model.Count; i++) {
                        var detail = new TN_Check_Detail {
                            S_NO = model.No,
                            S_CG_ID = model.CgId,
                            S_BATCH_NO = model.BatchNo,
                            S_END_AREA = model.EndArea
                        };
                        if (db.Insertable<TN_Check_Detail>(detail).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return BuildSimpleResult(3, "生成 抽检单明细 失败:" + JsonConvert.SerializeObject(detail));
                        }
                    }
                    tran.CommitTran();
                }
                else {
                    return BuildSimpleResult(2, "插入抽检单失败:" + JsonConvert.SerializeObject(order));
                }
                return BuildSimpleResult(0, $"创建 抽检单 成功:单号 {model.No}");
            }
            catch (Exception ex) {
                return BuildSimpleEx(ex);
@@ -425,13 +449,12 @@
                    return BuildSimpleResult(2, "出库单号不能为空");
                }
                if (model.OutboundDetails.Count == 0) {
                    return BuildSimpleResult(2, "出库单明细没有项目");
                }
                using (var tran = db.Ado.UseTran()) {
                    var order = new TN_Outbound_Order {
                        S_NO = model.No,
                        S_CG_ID = model.CgId,
                        S_BATCH_NO = model.BatchNo,
                        S_END_AREA = model.EndArea,
                        N_FORCE = model.Forced ? 1 : 0
                    };
@@ -440,16 +463,16 @@
                        return BuildSimpleResult(3, "生成出库单失败:" + JsonConvert.SerializeObject(order));
                    }
                    foreach (var detail in model.OutboundDetails) {
                        var newDetail = new TN_Outbound_Detail {
                            S_NO = order.S_NO,
                            S_CG_ID = detail.CgCode,
                            S_BATCH_NO = detail.PatchNo,
                            N_QTY = detail.Qty,
                            N_FORCE = order.N_FORCE,
                            S_END_AREA = detail.EndArea
                    for (int i = 0; i < model.Count; i++) {
                        var detail = new TN_Outbound_Detail {
                            S_NO = model.No,
                            S_CG_ID = model.CgId,
                            S_BATCH_NO = model.BatchNo,
                            N_FORCE = model.Forced ? 1 : 0,
                            S_END_AREA = model.EndArea
                        };
                        if (db.Insertable<TN_Outbound_Detail>(newDetail).ExecuteCommand() <= 0) {
                        if (db.Insertable<TN_Outbound_Detail>(detail).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return BuildSimpleResult(4, "生成出库单明细失败:" + JsonConvert.SerializeObject(detail));
                        }
@@ -488,19 +511,22 @@
                        return BuildSimpleResult(3, "生成出库单失败:" + JsonConvert.SerializeObject(order));
                    }
                    foreach (var detail in model.OutboundDetails) {
                        var newDetail = new TN_Outbound_Detail {
                            S_NO = order.S_NO,
                            S_CG_ID = detail.CgCode,
                            S_BATCH_NO = detail.PatchNo,
                            N_QTY = detail.Qty,
                            N_FORCE = order.N_FORCE
                    for (int i = 0; i < model.Count; i++) {
                        var detail = new TN_Outbound_Detail {
                            S_NO = model.No,
                            S_CG_ID = model.CgId,
                            S_BATCH_NO = model.BatchNo,
                            N_FORCE = model.Forced ? 1 : 0,
                            S_END_AREA = model.EndArea
                        };
                        if (db.Insertable<TN_Inbound_Order>(order).ExecuteCommand() <= 0) {
                        if (db.Insertable<TN_Outbound_Detail>(detail).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return BuildSimpleResult(4, "生成出库单明细失败:" + JsonConvert.SerializeObject(detail));
                        }
                    }
                    tran.CommitTran();
                }
                return BuildSimpleResult(0, "生成出库单成功");
config/config.json
@@ -99,7 +99,7 @@
        },
        {
            "Name": "抽检"
        }
        },
        {
            "Name": "成品胶出库"
        },