kazelee
昨天 fc25dda9baf3b5f4df23d35914f3dd343cf492e3
api/ApiHelper.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using HH.WCS.Mobox3.DSZSH.core;
using HH.WCS.Mobox3.DSZSH.models;
@@ -8,6 +9,7 @@
using HH.WCS.Mobox3.DSZSH.wms;
using Newtonsoft.Json;
using SqlSugar;
using Swashbuckle.Swagger;
@@ -24,6 +26,8 @@
        /// <returns></returns>
        public static SimpleResult GoodpackOffline(GoodpackOfflineInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.M满箱下线入库.Info();
            const string preLog = "API:满箱下线入库:";
            const string cntrType = "好运箱";
@@ -35,71 +39,41 @@
                // 检查货品容器表:是否已经存在贴标机传递的待入库物料信息
                // TODO:数量,规格是否也参与比对?
                var cgDetail = db.Queryable<TN_CG_Detail>().Where(d => d.S_ITEM_CODE == model.ItemCode && d.S_BATCH_NO == model.BatchNo && d.N_ITEM_STATE == 1 && d.S_ITEM_STATE == "待检").First();
                var cgDetail = db.Queryable<TN_CG_Detail>()
                    .Where(d => d.S_ITEM_CODE == model.ItemCode && d.S_BATCH_NO == model.BatchNo
                             && d.N_ITEM_STATE == 1 && d.S_ITEM_STATE == "待检").First();
                if (cgDetail == null) {
                    return NewSimpleResult(1, preLog + $"没有在[货品明细表]中找到[物料编码='{model.ItemCode}',批次号='{model.BatchNo}']的物料!请检查:PDA扫码物料信息与贴标机传递的信息是否一致!要求:物料状态='待检'");
                    return NewSimpleResult(1, preLog + LogMsg.CgDetailNotFound(item: model.ItemCode) + $"物料状态='待检';" +
                        $"请检查:PDA扫码物料信息与贴标机传递的信息是否一致!!");
                }
                // 查询起点货位:数量=0
                var startLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_CODE == model.StartLoc && taskInfo.StartAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).First();
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, preLog + $"没有找到起点货位'{model.StartLoc}'!要求:锁状态='无',当前容器数量=0,所在库区={LogObject(taskInfo.StartAreas)}");
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                }
                // 和满托下线入库的逻辑一致,由于容器移动不会更改绑定信息,所以必须删除旧数据
                var old = WCSHelper.GetLocCntrCg(cgDetail.S_CNTR_CODE, skipCgDetail: true);
                // 绑定货位容器,起点货位当前数量=1
                var locCntrRel = WCSHelper.BindLocCntr(ref startLoc, cgDetail.S_CNTR_CODE);
                var locCntrRel = WCSHelper.BindLocCntr(startLoc, cgDetail.S_CNTR_CODE);
                locCntrRel.S_CNTR_TYPE = cntrType;
                // 查询终点货位
                // Order:按货位层数,从小到大排列
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && taskInfo.EndAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).OrderBy(l => new { l.N_LAYER }).First();
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: taskInfo.EndAreas))
                    .OrderBy(l => new { l.N_LAYER }).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的终点货位!要求:锁状态='无',当前容器数量=0,所在库区={LogObject(taskInfo.EndAreas)}");
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                // 更新[起点/终点]锁状态,创建任务
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                using (var tran = db.Ado.UseTran()) {
                    // 删除/更新旧[货位/容器/物料]信息
                    if (old.LocCntrRel != null && db.Deleteable(old.LocCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"删除[旧货位容器关系]失败!数据:{LogObject(old.LocCntrRel)}");
                    }
                    if (old.Location != null && db.Updateable(old.Location).UpdateColumns(l => new { l.N_CURRENT_NUM, l.T_MODIFY }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[旧货位|当前容器数量]失败!货位='{old.Location.S_CODE}',数量=>{old.Location.N_CURRENT_NUM}");
                    }
                    // 插入新绑定的[货位-容器]表
                    if (db.Insertable(locCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"插入[容器货位绑定表]失败!数据:{LogObject(locCntrRel)}");
                    }
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    Old = old,
                    New = new LocCntrCg { LocCntrRel = locCntrRel },
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -113,84 +87,51 @@
        /// <returns></returns>
        public static SimpleResult EmptyInboundPallet(EmptyInboundInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.K空托入库.Info();
            const string preLog = "API:空托入库:";
            const string cntrType = "托盘";
            try {
                // 查询起点货位:数量=0
                var startLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_CODE == model.StartLoc && taskInfo.StartAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).First();
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(1, preLog + $"没有找到起点货位'{model.StartLoc}'!要求:锁状态='无';当前容器数量=0;所在库区={LogObject(taskInfo.StartAreas)}");
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                }
                // 查询容器表:容器类型字段
                var cntr = db.Queryable<TN_Container>().Where(c => c.S_CODE == model.CntrCode).First();
                if (cntr == null) {
                    return NewSimpleResult(2, preLog + $"容器'{model.CntrCode}'在[容器表]中不存在,请在前台页面中维护!");
                }
                if (cntr.S_TYPE != cntrType) {
                    return NewSimpleResult(3, preLog + $"容器'{model.CntrCode}'在[容器表]中的类型为'{cntr.S_TYPE}',与输入的容器类型'{cntrType}'不同!");
                (ok, msg) = WMSHelper.CheckCntrType(model.CntrCode, cntrType, out var cntr);
                if (!ok) {
                    return NewSimpleResult(3, preLog + msg);
                }
                
                // 空箱入库时,如果存在旧的绑定数据,删除
                var old = WCSHelper.GetLocCntrCg(model.CntrCode);
                // 绑定货位容器,起点货位当前数量=1
                var locCntrRel = WCSHelper.BindLocCntr(ref startLoc, cntr.S_CODE);
                // 绑定货位容器
                var locCntrRel = WCSHelper.BindLocCntr(startLoc, cntr.S_CODE);
                locCntrRel.S_CNTR_TYPE = cntrType;
                // 查询终点货位
                // Order:层数从低到高,行,列
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && taskInfo.EndAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).OrderBy(l => new { l.N_LAYER, l.N_ROW, l.N_COL }).First();
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: taskInfo.EndAreas))
                    .OrderBy(l => new { l.N_LAYER, l.N_ROW, l.N_COL }).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的终点货位!要求:锁状态='无';当前容器数量=0;所在库区={LogObject(taskInfo.EndAreas)}");
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                // 起点终点上锁,创建任务
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                using (var tran = db.Ado.UseTran()) {
                    if (old.CgDetail != null && db.Deleteable(old.CgDetail).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"删除[旧物料信息]失败!数据:{LogObject(old.CgDetail)}");
                    }
                    if (old.LocCntrRel != null && db.Deleteable(old.LocCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"删除[旧货位容器关系]失败!数据:{LogObject(old.LocCntrRel)}");
                    }
                    if (old.Location != null && db.Updateable(old.Location).UpdateColumns(l => new { l.N_CURRENT_NUM, l.T_MODIFY }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[旧货位|当前容器数量]失败!货位='{old.Location.S_CODE}',数量=>{old.Location.N_CURRENT_NUM}");
                    }
                    if (db.Insertable(locCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"插入[货位容器绑定表]失败!数据:{LogObject(locCntrRel)}");
                    }
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    Old = old,
                    New = new LocCntrCg { LocCntrRel = locCntrRel },
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -203,81 +144,46 @@
        /// <returns></returns>
        public static SimpleResult EmptyInboundGoodpack(EmptyInboundInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.K空箱入库.Info();
            const string preLog = "API:空箱入库:";
            const string cntrType = "好运箱";
            try {
                // 查询起点货位:数量=0
                var startLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y").Where(l => l.S_CODE == model.StartLoc && taskInfo.StartAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).First();
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(1, preLog + $"没有找到起点货位'{model.StartLoc}'!要求:锁状态='无';当前容器数量=0;所在库区={LogObject(taskInfo.StartAreas)}");
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                }
                // 查询容器表:容器类型字段
                var cntr = db.Queryable<TN_Container>().Where(c => c.S_CODE == model.CntrCode).First();
                if (cntr == null) {
                    return NewSimpleResult(1, $"容器'{model.CntrCode}'在[容器表]中不存在,请在前台页面中维护!");
                }
                if (cntr.S_TYPE != cntrType) {
                    return NewSimpleResult(2, preLog + $"容器'{model.CntrCode}'在[容器表]中的类型是'{cntr.S_TYPE},不是'{cntrType}'!");
                (ok, msg) = WMSHelper.CheckCntrType(model.CntrCode, cntrType, out var cntr);
                if (!ok) {
                    return NewSimpleResult(3, preLog + msg);
                }
                // 空箱入库时,如果存在旧的绑定数据,删除
                var old = WCSHelper.GetLocCntrCg(model.CntrCode);
                // 绑定货位容器,起点货位当前数量=1
                var locCntrRel = WCSHelper.BindLocCntr(ref startLoc, model.CntrCode);
                var locCntrRel = WCSHelper.BindLocCntr(startLoc, model.CntrCode);
                locCntrRel.S_CNTR_TYPE = cntrType;
                // 查询终点货位
                // Order:层数从低到高,行,列
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y").Where(l => taskInfo.EndAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).OrderBy(l => new { l.N_LAYER, l.N_ROW, l.N_COL }).First();
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: taskInfo.EndAreas))
                    .OrderBy(l => new { l.N_LAYER, l.N_ROW, l.N_COL }).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的终点货位!要求:锁状态='无';当前容器数量=0;所在库区={LogObject(taskInfo.EndAreas)}");
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                using (var tran = db.Ado.UseTran()) {
                    if (old.CgDetail != null && db.Deleteable(old.CgDetail).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"删除[旧物料信息]失败!数据:{LogObject(old.CgDetail)}");
                    }
                    if (old.LocCntrRel != null && db.Deleteable(old.LocCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"删除[旧货位容器关系]失败!数据:{LogObject(old.LocCntrRel)}");
                    }
                    if (old.Location != null && db.Updateable(old.Location).UpdateColumns(l => new { l.N_CURRENT_NUM, l.T_MODIFY }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[旧货位|当前容器数量]失败!货位='{old.Location.S_CODE}',数量=>{old.Location.N_CURRENT_NUM}");
                    }
                    if (db.Insertable(locCntrRel).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"插入[货位容器关系]失败:" + LogObject(locCntrRel));
                    }
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    Old = old,
                    New = new LocCntrCg { LocCntrRel = locCntrRel },
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -291,18 +197,17 @@
        /// <returns></returns>
        public static SimpleResult EmptyOnlinePallet(EmptyOnlinePalletInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.K空托上线出库.Info();
            const string preLog = "API:空托上线出库:";
            const string cntrType = "托盘";
            try {
                // 查询容器表:容器类型字段
                var cntr = db.Queryable<TN_Container>().Where(c => c.S_CODE == model.CntId).First();
                if (cntr == null) {
                    return NewSimpleResult(1, $"容器'{model.CntId}'在[容器表]中不存在,请在前台页面中维护!");
                }
                if (cntr.S_TYPE != cntrType) {
                    return NewSimpleResult(2, preLog + $"容器'{model.CntId}'在[容器表]中的类型是'{cntr.S_TYPE},不是'{cntrType}'!");
                (ok, msg) = WMSHelper.CheckCntrType(model.CntId, cntrType, out var cntr);
                if (!ok) {
                    return NewSimpleResult(1, preLog + msg);
                }
                var needUpdateContainer = false;
@@ -318,47 +223,31 @@
                    return NewSimpleResult(3, $"容器'{model.CntId}'已经与物料类型'{cntr.S_SPEC}'绑定,无法用于装载物料'{model.ItemCode}'!");
                }
                var startLoc = db.Queryable<TN_Location>().LeftJoin<TN_Loc_Container>((l, c) => l.S_CODE == c.S_LOC_CODE).Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y").Where((l, c) => taskInfo.StartAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 1 && c.S_CNTR_CODE == model.CntId && c.S_CNTR_TYPE == cntrType).First();
                var startLoc = db.Queryable<TN_Location>().LeftJoin<TN_Loc_Container>((l, c) => l.S_CODE == c.S_LOC_CODE)
                    .Where(DbExpr.StartLoc(areas: taskInfo.StartAreas))
                    .Where((l, c) => c.S_CNTR_CODE == model.CntId && c.S_CNTR_TYPE == cntrType).First();
                if (startLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的起点货位!要求:锁状态='无';当前容器数量=1;所在库区={LogObject(taskInfo.StartAreas)},绑定容器编码='{model.CntId}',绑定容器类型='{cntrType}'");
                    return NewSimpleResult(3, preLog + LogMsg.StartLocNotFound(areas: taskInfo.StartAreas) +
                        $"绑定容器编码='{model.CntId}';绑定容器类型='{cntrType}';");
                }
                // 查询终点货位
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y").Where(l => taskInfo.EndAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).First();
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: taskInfo.EndAreas)).First();
                if (endLoc == null) {
                    return NewSimpleResult(5, preLog + $"没有找到合适的终点货位!要求:锁状态='无';当前容器数量=0;所在库区={LogObject(taskInfo.EndAreas)}");
                    return NewSimpleResult(5, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                var task = WCSHelper.BuildTask(startLoc, endLoc, model.CntId, taskInfo.TaskName);
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
                cntr.S_SOURCE = task.S_CODE; // 用任务号作为容器更新的依据
                cntr.T_MODIFY = DateTime.Now;
                using (var tran = db.Ado.UseTran()) {
                    if (needUpdateContainer && db.Updateable(cntr).UpdateColumns(c => new { c.S_SPEC, c.S_SOURCE, c.T_MODIFY }).ExecuteCommand() <= 0) {
                        return NewSimpleResult(500, preLog + $"更新[容器表]失败!数据:{LogObject(cntr)}");
                    }
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    ContainerToUpdate = needUpdateContainer ? cntr : null,
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -372,53 +261,41 @@
        /// <returns></returns>
        public static SimpleResult EmptyOnlineGoodpack(EmptyOnlineGoodpackInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.K空箱上线出库.Info();
            const string preLog = "API:空箱上线出库:";
            const string cntrType = "好运箱";
            try {
                var cntr = db.Queryable<TN_Container>().Where(c => c.S_CODE == model.CntId).First();
                if (cntr == null) {
                    return NewSimpleResult(1, preLog + $"容器'{model.CntId}'在[容器表]中不存在,请在前台页面中维护!");
                }
                if (cntr.S_TYPE != cntrType) {
                    return NewSimpleResult(2, preLog + $"容器'{model.CntId}'在[容器表]中的类型='{cntr.S_TYPE}',不是'{cntrType}'!");
                // 查询容器表:容器类型字段
                (ok, msg) = WMSHelper.CheckCntrType(model.CntId, cntrType, out var cntr);
                if (!ok) {
                    return NewSimpleResult(3, preLog + msg);
                }
                var startLoc = db.Queryable<TN_Location>().LeftJoin<TN_Loc_Container>((l, c) => l.S_CODE == c.S_LOC_CODE).Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y").Where((l, c) => taskInfo.StartAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 1 && c.S_CNTR_CODE == model.CntId && c.S_CNTR_TYPE == cntrType).First();
                var startLoc = db.Queryable<TN_Location>().LeftJoin<TN_Loc_Container>((l, c) => l.S_CODE == c.S_LOC_CODE)
                    .Where(DbExpr.StartLoc(areas: taskInfo.StartAreas))
                    .Where((l, c) => c.S_CNTR_CODE == model.CntId && c.S_CNTR_TYPE == cntrType).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, preLog + $"没有找到合适的起点货位!要求:锁状态='无',当前容器数量=1,所在库区={LogObject(taskInfo.StartAreas)},绑定容器编码='{model.CntId}',绑定容器类型='{cntrType}'");
                    return NewSimpleResult(2, preLog + preLog + LogMsg.StartLocNotFound(areas: taskInfo.StartAreas) +
                        $"绑定容器编码='{model.CntId}';绑定容器类型='{cntrType}';");
                }
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y")
                    .Where(l => taskInfo.EndAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的终点货位!要求:锁状态='无',当前容器数量=0,所在库区={LogObject(taskInfo.EndAreas)}");
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                var task = WCSHelper.BuildTask(startLoc, endLoc, model.CntId, taskInfo.TaskName);
                using (var tran = db.Ado.UseTran()) {
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -432,6 +309,8 @@
        /// <returns></returns>
        public static SimpleResult QualifiedBack(QualifiedBackInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.C抽检合格回库.Info();
            const string preLog = "API:抽检合格回库";
@@ -439,59 +318,38 @@
                var cgDetail = db.Queryable<TN_CG_Detail>()
                    .Where(d => d.S_ITEM_CODE == model.ItemCode && d.S_CNTR_CODE == model.CntrCode).First();
                if (cgDetail == null) {
                    return NewSimpleResult(2, preLog + "没有找到待回库的抽检物料:" + LogObject(model));
                    return NewSimpleResult(2, preLog + LogMsg.CgDetailNotFound(item: model.ItemCode, cntr: model.CntrCode));
                }
                var locCntrRel = db.Queryable<TN_Loc_Container>().Where(c => c.S_CNTR_CODE == cgDetail.S_CNTR_CODE).First();
                if (locCntrRel == null) {
                    return NewSimpleResult(3, preLog + $"容器{model.CntrCode}在货位容器关系表中不存在");
                    return NewSimpleResult(3, preLog + LogMsg.LocCntrRelNotFound(cntr: cgDetail.S_CNTR_CODE));
                }
                var startLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_CODE == locCntrRel.S_LOC_CODE && taskInfo.StartAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 1).First();
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLoc(locCntrRel.S_LOC_CODE, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(4, preLog + $"没有找到合适的起点货位!要求:锁状态='无',当前容器数量=1,所在库区={LogObject(taskInfo.StartAreas)}");
                    return NewSimpleResult(4, preLog + LogMsg.StartLocNotFound(locCntrRel.S_LOC_CODE, taskInfo.StartAreas));
                }
                var endAreas = locCntrRel.S_CNTR_CODE == "托盘" ? taskInfo.EndAreas_Pallet : taskInfo.EndAreas_Goodpack;
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && endAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).First();
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: endAreas)).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的终点货位!要求:锁状态='无',当前容器数量=0,所在库区={LogObject(endAreas)}");
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: endAreas));
                }
                cgDetail.N_ITEM_STATE = 0;
                cgDetail.S_ITEM_STATE = "合格";
                cgDetail.T_MODIFY = DateTime.Now;
                var cntId = locCntrRel.S_CNTR_CODE;
                var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskInfo.TaskName);
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                using (var tran = db.Ado.UseTran()) {
                    if (db.Updateable(cgDetail).UpdateColumns(it => new { it.N_ITEM_STATE, it.S_ITEM_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[物料明细表]失败!物料号='{cgDetail.S_ITEM_CODE}',物料状态=>'合格'");
                    }
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    CgDetailToUpdate = cgDetail,
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -505,6 +363,8 @@
        /// <returns></returns>
        public static SimpleResult UnqualifiedShift(UnqualifiedShiftInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.C抽检不合格移库.Info();
            const string preLog = "API:抽检不合格移库:";
@@ -516,56 +376,36 @@
                var cgDetail = db.Queryable<TN_CG_Detail>()
                    .Where(d => d.S_ITEM_CODE == model.ItemCode && d.S_CNTR_CODE == model.CntrCode).First();
                if (cgDetail == null) {
                    return NewSimpleResult(2, preLog + $"没有在[物料明细表]中找到物料!要求:物料编码='{model.ItemCode}',容器编码='{model.CntrCode}'");
                    return NewSimpleResult(2, preLog + LogMsg.CgDetailNotFound(item: model.ItemCode, cntr: model.CntrCode));
                }
                var locCntrRel = db.Queryable<TN_Loc_Container>().Where(c => c.S_CNTR_CODE == cgDetail.S_CNTR_CODE).First();
                if (locCntrRel == null) {
                    return NewSimpleResult(3, preLog + $"在[货位容器关系表]中没有找到容器'{model.CntrCode}'!");
                    return NewSimpleResult(3, preLog + LogMsg.LocCntrRelNotFound(cntr: cgDetail.S_CNTR_CODE));
                }
                // 查询起点货位:数量=1
                var startLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_CODE == locCntrRel.S_LOC_CODE && taskInfo.StartAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 1).First();
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLoc(locCntrRel.S_LOC_CODE, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(1, preLog + $"没有找到起点货位'{locCntrRel.S_LOC_CODE}'!要求:锁状态='无';当前容器数量=1;所在库区={LogObject(taskInfo.StartAreas)}");
                    return NewSimpleResult(1, preLog + LogMsg.StartLocNotFound(locCntrRel.S_LOC_CODE, taskInfo.StartAreas));
                }
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_AREA_CODE == model.EndArea && l.N_CURRENT_NUM == 0).First();
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: new List<string> { model.EndArea })).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的终点货位!要求:锁状态='无',当前容器数量=0,所在库区='{model.EndArea}'");
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: new List<string> { model.EndArea }));
                }
                cgDetail.N_ITEM_STATE = 2;
                cgDetail.S_ITEM_STATE = "不合格";
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                using (var tran = db.Ado.UseTran()) {
                    if (db.Updateable(cgDetail).UpdateColumns(it => new { it.N_ITEM_STATE, it.S_ITEM_STATE }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[货品明细表]失败!物料号='{cgDetail}',物料状态=>'{cgDetail.S_ITEM_STATE}'");
                    }
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    CgDetailToUpdate = cgDetail,
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -579,56 +419,36 @@
        /// <returns></returns>
        public static SimpleResult RestBack(RestBackInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.W尾料回库.Info();
            const string preLog = "API:尾料回库:";
            
            try {
                var startLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_CODE == model.StartLoc && l.N_CURRENT_NUM == 1).First();
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLoc(model.StartLoc)).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, $"没有找到起点货位'{model.StartLoc}'!要求:锁状态='无';当前容器数量=1");
                    return NewSimpleResult(2, LogMsg.StartLocNotFound(model.StartLoc));
                }
                var locCntrRel = db.Queryable<TN_Loc_Container>().Where(c => c.S_LOC_CODE == model.StartLoc).First();
                if (locCntrRel == null) {
                    return NewSimpleResult(3, preLog + $"没有找到起点货位{model.StartLoc}所绑定的容器");
                    return NewSimpleResult(3, preLog + LogMsg.LocCntrRelNotFound(loc: model.StartLoc));
                }
                var endAreas = locCntrRel.S_CNTR_CODE == "托盘" ? taskInfo.EndAreas_Pallet : taskInfo.EndAreas_Goodpack;
                var endLoc = db.Queryable<TN_Location>().Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && endAreas.Contains(l.S_AREA_CODE) && l.N_CURRENT_NUM == 0).First();
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: endAreas)).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + $"没有找到合适的终点货位!要求:锁状态='无',当前容器数量=0,所在库区={LogObject(endAreas)}");
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: endAreas));
                }
                var cntId = locCntrRel.S_CNTR_CODE;
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                WCSHelper.LockStartLoc(ref startLoc);
                WCSHelper.LockEndLoc(ref endLoc);
                var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskInfo.TaskName);
                using (var tran = db.Ado.UseTran()) {
                    //if (db.Insertable(locCntrRel).ExecuteCommand() <= 0) {
                    //    tran.RollbackTran();
                    //    return NewSimpleResult(500, preLog + $"插入[容器货位绑定表]失败!数据:{LogObject(locCntrRel)}");
                    //}
                    // 更新[起点/终点]锁状态,创建任务
                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[起点货位锁状态]失败!起点='{startLoc.S_CODE}',锁状态=>'出库锁'");
                    }
                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"更新[终点货位锁状态]失败!终点='{endLoc.S_CODE}',锁状态=>'入库锁'");
                    }
                    if (db.Insertable(task).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return NewSimpleResult(500, preLog + $"生成任务'{task.S_TYPE}'失败!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                    }
                    // 提交数据库更改
                    tran.CommitTran();
                    return NewSimpleResult(0, preLog + $"生成任务'{task.S_TYPE}'成功!任务号={task.S_CODE},容器号={task.S_CNTR_CODE},起点={task.S_START_LOC},终点={task.S_END_LOC}");
                }
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
                });
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
@@ -642,6 +462,8 @@
        /// <returns></returns>
        public static SimpleResult FinishedOutbound(FinishedOutboundInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.C成品胶出库.Info();
            const string preLog = "API:成品胶出库:";
@@ -702,6 +524,8 @@
        /// <returns></returns>
        public static SimpleResult FinishedOutboundForce(FinishedOutboundInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.C成品胶出库.Info();
            const string preLog = "API:成品胶出库:";
@@ -829,9 +653,10 @@
        }
        private static string GenerateOrderNo(string snType, string prefix) {
            var id = SYSHelper.GetSerialNumber(snType, prefix);
            var date = DateTime.Now.ToString("yyMMdd");
            return $"{prefix}{date}-{id.ToString().PadLeft(4, '0')}";
            //var id = SYSHelper.GetSerialNumberResetByDay(snType, prefix);
            //var date = DateTime.Now.ToString("yyMMdd");
            //return $"{prefix}{date}-{id.ToString().PadLeft(4, '0')}";
            return SYSHelper.GenerateSN(snType, prefix, "yyMMdd");
        }
        /// <summary>
@@ -841,6 +666,8 @@
        /// <returns></returns>
        public static MesResult CgInfoSync(CgInfoSyncInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            const string preLog = "API:博实下发物料信息:";
            const string cntrType = "好运箱";
@@ -858,16 +685,9 @@
                    return NewMesResult(400, preLog + $"物料数量'{model.ItemNum}'不合法!要求:物料数量>0");
                }
                // TEMP 目前流程:对博实下发的信息也进行检查,未找到就报错,后面有需求再更改
                var cntr = db.Queryable<TN_Container>()
                    .Where(c => c.S_CODE == model.CntrCode) // 对于前台程序而言,S_CODE就是主键,维护时必定唯一
                    .First();
                if (cntr == null) {
                    return NewMesResult(1, preLog + $"容器'{model.CntrCode}'在[容器表]中不存在,请在前台页面中维护!");
                }
                if (cntr.S_TYPE != cntrType) {
                    return NewMesResult(2, preLog + $"容器'{model.CntrCode}'在[容器表]中的类型为'{cntr.S_TYPE}',与当前容器类型'{cntrType}'不同!");
                (ok, msg) = WMSHelper.CheckCntrType(model.CntrCode, cntrType, out var cntr);
                if (!ok) {
                    return NewMesResult(1, preLog + msg);
                }
                // 将下发的信息先存储到CG表中 (此时托盘没有与产线处的货位绑定)