kazelee
3 天以前 63e94e068622d4ef843cee0d19d4f2d231316304
完善查询语句, 日志记录的封装
6个文件已修改
1个文件已添加
1个文件已删除
858 ■■■■■ 已修改文件
HH.WCS.Mobox3.DSZSH.csproj 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/ApiHelper.cs 102 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
process/TaskProcess.cs 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/DbExpr.cs 152 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/LocationHelper.cs 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/LogBox.cs 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/LogMsg.cs 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/WMSHelper.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3.DSZSH.csproj
@@ -273,7 +273,7 @@
    <Compile Include="util\WebHelper.cs" />
    <Compile Include="wms\DbTran.cs" />
    <Compile Include="wms\LocationHelper.cs" />
    <Compile Include="wms\LogBox.cs" />
    <Compile Include="wms\LogMsg.cs" />
    <Compile Include="wms\DbExpr.cs" />
    <Compile Include="wms\SYSHelper.cs" />
    <Compile Include="Program.cs" />
api/ApiHelper.cs
@@ -39,16 +39,17 @@
                // 检查货品容器表:是否已经存在贴标机传递的待入库物料信息
                // TODO:数量,规格是否也参与比对?
                var cgDetail = db.Queryable<TN_CG_Detail>().Where(d => d.S_ITEM_CODE == model.ItemCode && d.S_BATCH_NO == model.BatchNo
                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(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, preLog + LogBox.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                }
                // 和满托下线入库的逻辑一致,由于容器移动不会更改绑定信息,所以必须删除旧数据
@@ -57,11 +58,10 @@
                var locCntrRel = WCSHelper.BindLocCntr(startLoc, cgDetail.S_CNTR_CODE);
                locCntrRel.S_CNTR_TYPE = cntrType;
                // 查询终点货位
                // Order:按货位层数,从小到大排列
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: taskInfo.EndAreas)).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 + LogBox.EndLocNotFound(null, taskInfo.EndAreas));
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
@@ -98,7 +98,7 @@
                // 查询起点货位:数量=0
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, preLog + LogBox.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                }
                // 查询容器表:容器类型字段
@@ -119,7 +119,7 @@
                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 + LogBox.EndLocNotFound(null, taskInfo.EndAreas));
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                // 起点终点上锁,创建任务
@@ -152,10 +152,9 @@
            const string cntrType = "好运箱";
            try {
                // 查询起点货位:数量=0
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, preLog + LogBox.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                }
                // 查询容器表:容器类型字段
@@ -167,16 +166,13 @@
                // 空箱入库时,如果存在旧的绑定数据,删除
                var old = WCSHelper.GetLocCntrCg(model.CntrCode);
                // 绑定货位容器,起点货位当前数量=1
                var locCntrRel = WCSHelper.BindLocCntr(startLoc, model.CntrCode);
                locCntrRel.S_CNTR_TYPE = cntrType;
                // 查询终点货位
                // Order:层数从低到高,行,列
                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));
                }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
@@ -228,15 +224,17 @@
                    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));
                }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
@@ -282,15 +280,18 @@
                    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));
                }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
@@ -323,31 +324,30 @@
                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.BuildTaskWithLocLock(startLoc, endLoc, cntId, taskInfo.TaskName);
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    CgDetailToUpdate = cgDetail,
@@ -382,23 +382,22 @@
                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;
@@ -432,20 +431,20 @@
            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 task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
@@ -672,6 +671,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 = "好运箱";
@@ -689,16 +690,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表中 (此时托盘没有与产线处的货位绑定) 
process/TaskProcess.cs
@@ -23,12 +23,12 @@
            if (load) {
                Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}");
                LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}");
                LocationHelper.UnbindLocCntr(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList());
                UnbindLocCntr(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList());
            }
            else {
                Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}");
                LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}");
                LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList());
                BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList());
            }
        }
@@ -42,13 +42,13 @@
                //根据客户现场要求,如果取货完成任务失败人工拉到终点,我们就当卸货完成处理;如果是人工拉走到其它区域,我们就解锁终点,删除托盘。
                //终点绑定
                BufferLocUpdate(mst, false);
                LocationHelper.UnLockLoc(mst.S_END_LOC);
                UnLockLoc(mst.S_END_LOC);
            }
            else {
                //起点终点解锁
                LocationHelper.UnLockLoc(mst.S_START_LOC);
                LocationHelper.UnLockLoc(mst.S_END_LOC);
                UnLockLoc(mst.S_START_LOC);
                UnLockLoc(mst.S_END_LOC);
            }
@@ -99,6 +99,164 @@
            }
        }
        /// <summary>
        /// 取货完解锁起点,卸货完解锁终点,可检验锁的来源,也可以不校验
        /// </summary>
        /// <param name="loc"></param>
        /// <returns></returns>
        public static bool UnLockLoc(string loc) {
            LogHelper.Info("UnLockLoc:" + loc);
            var res = false;
            var db = new SqlHelper<object>().GetInstance();
            var model = db.Queryable<TN_Location>().Where(a => a.S_CODE == loc).First();
            if (model != null) {
                model.S_LOCK_STATE = "无";
                model.N_LOCK_STATE = 0;
                model.S_LOCK_OP = "";
                model.T_MODIFY = System.DateTime.Now;
                res = db.Updateable(model).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() > 0;
                LogHelper.Info("UnLockLoc:解锁结果" + res);
            }
            else {
                LogHelper.Info("UnLockLoc 失败" + loc);
            }
            return res;
        }
        /// <summary>
        /// 货位解绑容器
        /// </summary>
        /// <param name="loc"></param>
        /// <param name="cntrs"></param>
        /// <returns></returns>
        public static string UnbindLocCntr(string loc, List<string> cntrs) {
            var db = new SqlHelper<object>().GetInstance();
            var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}";
            try {
                var lcrList = db.Queryable<TN_Loc_Container>().Where(a => cntrs.Contains(a.S_CNTR_CODE) && a.S_LOC_CODE == loc).ToList();
                if (lcrList.Count == 0) {
                    LogHelper.Info($"货位无需解绑容器,在数据库中未找到{JsonConvert.SerializeObject(cntrs)}相关的货位容器关系表信息");
                }
                cntrs = lcrList.Select(a => a.S_CNTR_CODE).ToList();
                var log = JsonConvert.SerializeObject(cntrs);
                var location = db.Queryable<TN_Location>().First(a => a.S_CODE == loc);
                if (location != null) {
                    location.N_CURRENT_NUM = 0;
                    location.S_LOCK_STATE = "无";
                    location.N_LOCK_STATE = 0;
                    using (var tran = db.Ado.UseTran()) {
                        if (db.Deleteable<TN_Loc_Container>().Where(it => cntrs.Contains(it.S_CNTR_CODE) && it.S_LOC_CODE == loc).ExecuteCommand() > 0) {
                            LogHelper.Info($"删除货位容器关系表成功,{log}");
                        }
                        else {
                            tran.RollbackTran();
                            LogHelper.Info($"删除货位容器关系表失败,{log}");
                            return "货位解绑容器失败," + logs;
                        }
                        log = JsonConvert.SerializeObject(location);
                        if (db.Updateable(location).UpdateColumns(it => new { it.N_CURRENT_NUM, it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand() > 0) {
                            tran.CommitTran();
                            LogHelper.Info($"更新货位表成功,{log}");
                        }
                        else {
                            tran.RollbackTran();
                            LogHelper.Info($"更新货位表失败,{log}");
                            return "货位解绑容器失败," + logs;
                        }
                    }
                }
                else {
                    LogHelper.Info($"在数据库中未找到该货位,无需更新,货位:{loc}");
                }
                return "货位解绑容器成功," + logs;
            }
            catch (Exception ex) {
                LogHelper.Info($"发生了异常,货位解绑容器失败,{ex.Message}");
                return "货位绑定容器失败," + logs;
            }
        }
        /// <summary>
        /// 货位绑定容器
        /// </summary>
        /// <param name="loc"></param>
        /// <param name="cntrs"></param>
        /// <returns></returns>
        public static string BindingLoc(string loc, List<string> cntrs) {
            var db = new SqlHelper<object>().GetInstance();
            var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}";
            try {
                // 删除已经绑定过的容器记录
                var lcrList = db.Queryable<TN_Loc_Container>().Where(a => cntrs.Contains(a.S_CNTR_CODE) && a.S_LOC_CODE == loc).ToList();
                if (lcrList.Count > 0) {
                    cntrs = cntrs.Except(lcrList.Select(a => a.S_CNTR_CODE).ToList()).ToList();
                }
                var bindLocCntList = new List<TN_Loc_Container>();
                foreach (var item in cntrs) {
                    // 针对容器类型添加的新逻辑
                    var cntr = db.Queryable<TN_Container>().Where(c => c.S_CODE == item).First();
                    if (cntr == null) {
                        LogHelper.Info($"货位解绑时,容器{item}没有在容器信息表中查到,不记录容器类型");
                        bindLocCntList.Add(new TN_Loc_Container() { S_LOC_CODE = loc, S_CNTR_CODE = item });
                    }
                    else {
                        bindLocCntList.Add(new TN_Loc_Container() { S_LOC_CODE = loc, S_CNTR_CODE = item, S_CNTR_TYPE = cntr.S_TYPE });
                    }
                }
                var log = JsonConvert.SerializeObject(bindLocCntList);
                using (var tran = db.Ado.UseTran()) {
                    if (db.Insertable(bindLocCntList).ExecuteCommand() <= 0) {
                        db.RollbackTran();
                        LogHelper.Info($"插入货位容器关系表失败,{log}");
                        return "货位绑定容器失败," + logs;
                    }
                    LogHelper.Info($"插入货位容器关系表成功,{log}");
                    var location = db.Queryable<TN_Location>().First(a => a.S_CODE == loc);
                    if (location != null) {
                        location.N_CURRENT_NUM += cntrs.Count;
                        location.S_LOCK_STATE = "无";
                        location.N_LOCK_STATE = 0;
                        log = JsonConvert.SerializeObject(location);
                        if (db.Updateable(location).UpdateColumns(it => new { it.N_CURRENT_NUM, it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand() > 0) {
                            db.CommitTran();
                            LogHelper.Info($"更新货位表成功,{log}");
                        }
                        else {
                            db.RollbackTran();
                            LogHelper.Info($"更新货位表失败,{log}");
                            return "货位绑定容器失败," + logs;
                        }
                    }
                    else {
                        db.RollbackTran();
                        LogHelper.Info($"未找到该货位{loc},或者已锁定,{log}");
                    }
                }
                return "货位绑定容器成功," + logs;
            }
            catch (Exception ex) {
                LogHelper.Info($"发生了异常,货位绑定容器失败,");
                return "货位绑定容器失败," + ex.Message;
            }
        }
        private static object locLocker = new object();
wms/DbExpr.cs
@@ -15,7 +15,7 @@
    /// </summary>
    public class DbExpr {
        /// <summary>
        /// 通用货位筛选表达式
        /// 通用 [ 货位 ] 筛选
        /// </summary>
        /// <remarks><code><![CDATA[
        /// l => l.C_ENABLE == "Y" 
@@ -29,18 +29,19 @@
        /// <param name="areas"></param>
        /// <param name="curNum"></param>
        /// <returns></returns>
        public static Expression<Func<TN_Location, bool>> LocFilter(int @lock = 0, string name = "", List<string> areas = null, int curNum = 0) {
        public static Expression<Func<TN_Location, bool>> LocFilter(int @lock, string name, List<string> areas, int curNum) {
            Expression<Func<TN_Location, bool>> expr = l => l.C_ENABLE == "Y"; // 已启用
            if (@lock >= 0) {
                Expression<Func<TN_Location, bool>> newExpr = l => l.N_LOCK_STATE == @lock && l.S_LOCK_STATE == TN_Location.GetLockStateStr(@lock);
                Expression<Func<TN_Location, bool>> newExpr =
                    l => l.N_LOCK_STATE == @lock && l.S_LOCK_STATE == TN_Location.GetLockStateStr(@lock);
                expr = Expression.Lambda<Func<TN_Location, bool>>(Expression.AndAlso(expr.Body, newExpr.Body), expr.Parameters[0]);
            }
            if (!string.IsNullOrEmpty(name)) {
                Expression<Func<TN_Location, bool>> newExpr = l => l.S_CODE == name;
                expr = Expression.Lambda<Func<TN_Location, bool>>(Expression.AndAlso(expr.Body, newExpr.Body), expr.Parameters[0]);
            }
            if (areas != null && areas.Count == 0) {
            if (areas != null && areas.Count > 0) {
                Expression<Func<TN_Location, bool>> newExpr = l => areas.Contains(l.S_AREA_CODE);
                expr = Expression.Lambda<Func<TN_Location, bool>>(Expression.AndAlso(expr.Body, newExpr.Body), expr.Parameters[0]);
            }
@@ -66,23 +67,28 @@
        /// <param name="areas"></param>
        /// <returns></returns>
        public static Expression<Func<TN_Location, bool>> StartLocUnbind(string name = "", List<string> areas = null) {
            Expression<Func<TN_Location, bool>> expr =
                l => l.C_ENABLE == "Y" && l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.N_CURRENT_NUM == 0;
            if (!string.IsNullOrEmpty(name)) {
                Expression<Func<TN_Location, bool>> newExpr = l => l.S_CODE == name;
                expr = Expression.Lambda<Func<TN_Location, bool>>(Expression.AndAlso(expr.Body, newExpr.Body), expr.Parameters[0]);
            }
            if (areas != null && areas.Count > 0) {
                Expression<Func<TN_Location, bool>> newExpr = l => areas.Contains(l.S_AREA_CODE);
                expr = Expression.Lambda<Func<TN_Location, bool>>(Expression.AndAlso(expr.Body, newExpr.Body), expr.Parameters[0]);
            }
            return expr;
            return LocFilter(0, name, areas, 0);
        }
        /// <summary>
        ///
        /// 起点货位 ( 已绑定 )
        /// </summary>
        /// <remarks><code><![CDATA[
        /// l => l.C_ENABLE == "Y"
        ///   && l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无"
        ///   && l.S_CODE == name
        ///   && areas.Contains(l.S_AREA_CODE)
        ///   && l.N_CURRENT_NUM == 1
        /// ]]></code></remarks>
        /// <param name="name"></param>
        /// <param name="areas"></param>
        /// <returns></returns>
        public static Expression<Func<TN_Location, bool>> StartLoc(string name = "", List<string> areas = null) {
            return LocFilter(0, name, areas, 1);
        }
        /// <summary>
        /// 终点货位
        /// </summary>
        /// <remarks><code><![CDATA[
        /// l => l.C_ENABLE == "Y" 
@@ -95,115 +101,7 @@
        /// <param name="areas"></param>
        /// <returns></returns>
        public static Expression<Func<TN_Location, bool>> EndLoc(string name = "", List<string> areas = null) {
            Expression<Func<TN_Location, bool>> expr =
                l => l.C_ENABLE == "Y" && l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.N_CURRENT_NUM == 0;
            if (!string.IsNullOrEmpty(name)) {
                Expression<Func<TN_Location, bool>> newExpr = l => l.S_CODE == name;
                expr = Expression.Lambda<Func<TN_Location, bool>>(Expression.AndAlso(expr.Body, newExpr.Body), expr.Parameters[0]);
            }
            if (areas != null && areas.Count > 0) {
                Expression<Func<TN_Location, bool>> newExpr = l => areas.Contains(l.S_AREA_CODE);
                expr = Expression.Lambda<Func<TN_Location, bool>>(Expression.AndAlso(expr.Body, newExpr.Body), expr.Parameters[0]);
            }
            return expr;
            return LocFilter(0, name, areas, 0);
        }
    }
    #region 旧查询类 ( 搁置 )
    /// <summary>
    /// [ 数据库查询 ] 帮助类
    /// </summary>
    /// <remarks><b>[ 搁置 ]</b> 类与方法暂时设为私有<br/><b>[ 理由 ]</b> 引用外部 db 存在风险 ; 不适用于联表查询场景 , 不够灵活</remarks>
    class DbQuery {
        /// <summary>
        /// 构建 [ 货位 ] 查询表达式 : 筛选条件 : 锁状态 / 名称 / 货区 / 当前容器数量 ( 默认筛选已启用货位 )
        /// </summary>
        /// <param name="db">调用区域的 SqlSugarClient</param>
        /// <param name="lock">锁状态 ( 小于 0 时忽略 )</param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <param name="curNum">当前数量 ( 小于 0 时忽略 )</param>
        /// <returns></returns>
        static ISugarQueryable<TN_Location> Loc(SqlSugarClient db, int @lock, string name, List<string> areas, int curNum) {
            var query = db.Queryable<TN_Location>().Where(l => l.C_ENABLE == "Y"); // 已启用
            if (@lock >= 0) {
                query = query.Where(l => l.N_LOCK_STATE == @lock && l.S_LOCK_STATE == TN_Location.GetLockStateStr(@lock));
            }
            if (!string.IsNullOrEmpty(name)) {
                query = query.Where(l => l.S_CODE == name);
            }
            if (areas != null && areas.Count != 0) {
                query = query.Where(l => areas.Contains(l.S_AREA_CODE));
            }
            if (curNum >= 0) {
                query = query.Where(l => l.N_CURRENT_NUM == curNum);
            }
            return query;
        }
        /// <summary>
        /// 构建 [ 起点货位 ( 绑定前 ) ] 查询表达式 : 筛选条件 : 名称 / 货区 ( 默认筛选 : 已启用 / 未上锁 / 当前容器数量 = 0 )
        /// </summary>
        /// <param name="db">调用区域的 SqlSugarClient</param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <returns></returns>
        static ISugarQueryable<TN_Location> StartLocUnbind(SqlSugarClient db, string name, List<string> areas) {
            var query = db.Queryable<TN_Location>().Where(l => l.C_ENABLE == "Y" && l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == TN_Location.GetLockStateStr(0) && l.N_CURRENT_NUM == 0); // 已启用,未上锁,当前容器数量=0(初始未绑定容器)
            if (!string.IsNullOrEmpty(name)) {
                query = query.Where(l => l.S_CODE == name);
            }
            if (areas != null && areas.Count != 0) {
                query = query.Where(l => areas.Contains(l.S_AREA_CODE));
            }
            return query;
        }
        /// <summary>
        /// 构建 [ 起点货位 ( 绑定后 ) ] 查询表达式 : 筛选条件 : 名称 / 货区 ( 默认筛选 : 已启用 / 未上锁 / 当前容器数量 = 1 )
        /// </summary>
        /// <param name="db">调用区域的 SqlSugarClient</param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <returns></returns>
        static ISugarQueryable<TN_Location> StartLoc(SqlSugarClient db, string name, List<string> areas) {
            var query = db.Queryable<TN_Location>().Where(l => l.C_ENABLE == "Y" && l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == TN_Location.GetLockStateStr(0) && l.N_CURRENT_NUM == 1); // 已启用,未上锁,当前容器数量=1(已绑定容器)
            if (!string.IsNullOrEmpty(name)) {
                query = query.Where(l => l.S_CODE == name);
            }
            if (areas != null && areas.Count != 0) {
                query = query.Where(l => areas.Contains(l.S_AREA_CODE));
            }
            return query;
        }
        /// <summary>
        /// 构建 [ 终点货位 ] 查询表达式 : 筛选条件 : 名称 / 货区 ( 默认筛选 : 已启用 / 未上锁 / 当前容器数量 = 0 )
        /// </summary>
        /// <param name="db">调用区域的 SqlSugarClient</param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <returns></returns>
        static ISugarQueryable<TN_Location> EndLoc(SqlSugarClient db, string name, List<string> areas) {
            var query = db.Queryable<TN_Location>().Where(l => l.C_ENABLE == "Y" && l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == TN_Location.GetLockStateStr(0) && l.N_CURRENT_NUM == 0); // 已启用,未上锁,当前容器数量=0(未绑定容器)
            if (!string.IsNullOrEmpty(name)) {
                query = query.Where(l => l.S_CODE == name);
            }
            if (areas != null && areas.Count != 0) {
                query = query.Where(l => areas.Contains(l.S_AREA_CODE));
            }
            return query;
        }
    }
    #endregion
}
wms/LocationHelper.cs
@@ -103,181 +103,6 @@
            return db.Queryable<TN_Location>().Where(a => a.S_CODE.Trim() == code).First();
        }
        /// <summary>
        /// 取货完解锁起点,卸货完解锁终点,可检验锁的来源,也可以不校验
        /// </summary>
        /// <param name="loc"></param>
        /// <returns></returns>
        public static bool UnLockLoc(string loc)
        {
            LogHelper.Info("UnLockLoc:" + loc);
            var res = false;
            var db = new SqlHelper<object>().GetInstance();
            var model = db.Queryable<TN_Location>().Where(a => a.S_CODE == loc).First();
            if (model != null)
            {
                model.S_LOCK_STATE = "无";
                model.N_LOCK_STATE = 0;
                model.S_LOCK_OP = "";
                model.T_MODIFY = System.DateTime.Now;
                res = db.Updateable(model).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() > 0;
                LogHelper.Info("UnLockLoc:解锁结果" + res);
            }
            else
            {
                LogHelper.Info("UnLockLoc 失败" + loc);
            }
            return res;
        }
        /// <summary>
        /// 货位解绑容器
        /// </summary>
        /// <param name="loc"></param>
        /// <param name="cntrs"></param>
        /// <returns></returns>
        public static string UnbindLocCntr(string loc, List<string> cntrs)
        {
            var db = new SqlHelper<object>().GetInstance();
            var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}";
            try
            {
                var lcrList = db.Queryable<TN_Loc_Container>().Where(a => cntrs.Contains(a.S_CNTR_CODE) && a.S_LOC_CODE == loc).ToList();
                if (lcrList.Count == 0) {
                    LogHelper.Info($"货位无需解绑容器,在数据库中未找到{JsonConvert.SerializeObject(cntrs)}相关的货位容器关系表信息");
                }
                cntrs = lcrList.Select(a => a.S_CNTR_CODE).ToList();
                var log = JsonConvert.SerializeObject(cntrs);
                var location = db.Queryable<TN_Location>().First(a => a.S_CODE == loc);
                if (location != null)
                {
                    location.N_CURRENT_NUM = 0;
                    location.S_LOCK_STATE = "无";
                    location.N_LOCK_STATE = 0;
                    using (var tran = db.Ado.UseTran())
                    {
                        if (db.Deleteable<TN_Loc_Container>().Where(it => cntrs.Contains(it.S_CNTR_CODE) && it.S_LOC_CODE == loc).ExecuteCommand() > 0)
                        {
                            LogHelper.Info($"删除货位容器关系表成功,{log}");
                        }
                        else
                        {
                            tran.RollbackTran();
                            LogHelper.Info($"删除货位容器关系表失败,{log}");
                            return "货位解绑容器失败," + logs;
                        }
                        log = JsonConvert.SerializeObject(location);
                        if (db.Updateable(location).UpdateColumns(it => new { it.N_CURRENT_NUM, it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand() > 0) {
                            tran.CommitTran();
                            LogHelper.Info($"更新货位表成功,{log}");
                        }
                        else {
                            tran.RollbackTran();
                            LogHelper.Info($"更新货位表失败,{log}");
                            return "货位解绑容器失败," + logs;
                        }
                    }
                }
                else
                {
                    LogHelper.Info($"在数据库中未找到该货位,无需更新,货位:{loc}");
                }
                return "货位解绑容器成功," + logs;
            }
            catch (Exception ex)
            {
                LogHelper.Info($"发生了异常,货位解绑容器失败,{ex.Message}");
                return "货位绑定容器失败," + logs;
            }
        }
        /// <summary>
        /// 货位绑定容器
        /// </summary>
        /// <param name="loc"></param>
        /// <param name="cntrs"></param>
        /// <returns></returns>
        public static string BindingLoc(string loc, List<string> cntrs)
        {
            var db = new SqlHelper<object>().GetInstance();
            var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}";
            try
            {
                // 删除已经绑定过的容器记录
                var lcrList = db.Queryable<TN_Loc_Container>().Where(a => cntrs.Contains(a.S_CNTR_CODE) && a.S_LOC_CODE == loc).ToList();
                if (lcrList.Count > 0) {
                    cntrs = cntrs.Except(lcrList.Select(a => a.S_CNTR_CODE).ToList()).ToList();
                }
                var bindLocCntList = new List<TN_Loc_Container>();
                foreach (var item in cntrs) {
                    // 针对容器类型添加的新逻辑
                    var cntr = db.Queryable<TN_Container>().Where(c => c.S_CODE == item).First();
                    if (cntr == null) {
                        LogHelper.Info($"货位解绑时,容器{item}没有在容器信息表中查到,不记录容器类型");
                        bindLocCntList.Add(new TN_Loc_Container() { S_LOC_CODE = loc, S_CNTR_CODE = item });
                    }
                    else {
                        bindLocCntList.Add(new TN_Loc_Container() { S_LOC_CODE = loc, S_CNTR_CODE = item, S_CNTR_TYPE = cntr.S_TYPE });
                    }
                }
                var log = JsonConvert.SerializeObject(bindLocCntList);
                using (var tran = db.Ado.UseTran())
                {
                    if (db.Insertable(bindLocCntList).ExecuteCommand() <= 0) {
                        db.RollbackTran();
                        LogHelper.Info($"插入货位容器关系表失败,{log}");
                        return "货位绑定容器失败," + logs;
                    }
                    LogHelper.Info($"插入货位容器关系表成功,{log}");
                    var location = db.Queryable<TN_Location>().First(a => a.S_CODE == loc);
                    if (location != null)
                    {
                        location.N_CURRENT_NUM += cntrs.Count;
                        location.S_LOCK_STATE = "无";
                        location.N_LOCK_STATE = 0;
                        log = JsonConvert.SerializeObject(location);
                        if (db.Updateable(location).UpdateColumns(it => new { it.N_CURRENT_NUM, it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand() > 0)
                        {
                            db.CommitTran();
                            LogHelper.Info($"更新货位表成功,{log}");
                        }
                        else
                        {
                            db.RollbackTran();
                            LogHelper.Info($"更新货位表失败,{log}");
                            return "货位绑定容器失败," + logs;
                        }
                    }
                    else
                    {
                        db.RollbackTran();
                        LogHelper.Info($"未找到该货位{loc},或者已锁定,{log}");
                    }
                }
                return "货位绑定容器成功," + logs;
            }
            catch (Exception ex)
            {
                LogHelper.Info($"发生了异常,货位绑定容器失败,");
                return "货位绑定容器失败," + ex.Message;
            }
        }
    }
}
wms/LogBox.cs
File was deleted
wms/LogMsg.cs
New file
@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using HH.WCS.Mobox3.DSZSH.models;
using Newtonsoft.Json;
namespace HH.WCS.Mobox3.DSZSH.util {
    /// <summary>
    /// [ 日志信息 ] 构造类
    /// </summary>
    public static class LogMsg {
        /// <summary>
        /// <c>"没有找到{desc}货位!!要求:锁状态='@lock';货位名称='name';所在库区=[areas];当前容器数量=curNum;"</c>
        /// </summary>
        /// <remarks><b>[ 注意 ]</b> 原则上至少有 1 个限制条件</remarks>
        /// <param name="desc">货位描述 ( 起点 / 终点 )</param>
        /// <param name="lock">锁状态 ( 小于 0 时忽略 )</param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <param name="curNum">当前数量 ( 小于 0 时忽略 )</param>
        /// <returns></returns>
        public static string LocNotFound(string desc, int @lock, string name, List<string> areas, int curNum) {
            var res = $"没有找到{desc}货位!!要求:";
            if (@lock >= 0) {
                res += $"锁状态='{TN_Location.GetLockStateStr(@lock)}';";
            }
            if (!string.IsNullOrEmpty(name)) {
                res += $"货位名称='{name}';";
            }
            if (areas != null && areas.Count != 0) {
                res += $"所在库区={JsonConvert.SerializeObject(areas)};";
            }
            if (curNum >= 0) {
                res += $"当前容器数量={curNum};";
            }
            return res;
        }
        /// <summary>
        /// <c>"没有找到起点货位!!要求:锁状态='无';货位名称='name';所在库区=[areas];当前容器数量=curNum;"</c>
        /// </summary>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <param name="curNum">当前数量 ( 小于 0 时忽略 )</param>
        /// <returns></returns>
        public static string StartLocNotFound(string name = "", List<string> areas = null, int curNum = 1) {
            return LocNotFound("起点", 0, name, areas, curNum);
        }
        /// <summary>
        /// <c>"没有找到起点货位!!要求:锁状态='无';货位名称='name';所在库区=[areas];当前容器数量=0;"</c>
        /// </summary>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <returns></returns>
        public static string StartLocUnbindNotFound(string name = "", List<string> areas = null) {
            return LocNotFound("起点", 0, name, areas, 0);
        }
        /// <summary>
        /// <c>"没有找到终点货位!!要求:锁状态='无';货位名称='name';所在库区=[areas];当前容器数量=curNum;"</c>
        /// </summary>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <param name="curNum">当前数量 ( 小于 0 时忽略 )</param>
        /// <returns></returns>
        public static string EndLocNotFound(string name = "", List<string> areas = null, int curNum = 0) {
            return LocNotFound("终点", 0, name, areas, curNum);
        }
        /// <summary>
        /// <c>"没有找到[货位容器绑定]信息!!要求:货位='loc';容器='cntr';"</c>
        /// </summary>
        /// <remarks><b>[ 注意 ]</b> 原则上至少有 1 个限制条件</remarks>
        /// <param name="loc"></param>
        /// <param name="cntr"></param>
        /// <returns></returns>
        public static string LocCntrRelNotFound(string loc = "", string cntr = "") {
            var res = $"没有找到[货位容器绑定]信息!!要求:";
            if (!string.IsNullOrEmpty(loc)) {
                res += $"货位='{loc}';";
            }
            if (!string.IsNullOrEmpty(cntr)) {
                res += $"容器='{cntr}';";
            }
            return res;
        }
        /// <summary>
        /// <c>"没有找到[容器货品明细]信息!!要求:容器='cntr';物料='item';"</c>
        /// </summary>
        /// <remarks><b>[ 注意 ]</b> 原则上至少有 1 个限制条件</remarks>
        /// <param name="cntr"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static string CgDetailNotFound(string cntr = "", string item = "") {
            var res = $"没有找到[容器货品明细]信息!!要求:";
            if (!string.IsNullOrEmpty(cntr)) {
                res += $"容器='{cntr}';";
            }
            if (!string.IsNullOrEmpty(item)) {
                res += $"物料='{item}';";
            }
            return res;
        }
    }
}
wms/WMSHelper.cs
@@ -32,7 +32,7 @@
                return (false, $"容器'{cntrCode}'在[容器表]中不存在,请在前台页面中维护!!");
            }
            if (cntr.S_TYPE != cntrType) {
                return (false, $"容器'{cntrCode}'在[容器表]中的类型为'{cntr.S_TYPE}',与输入的容器类型'{cntrType}'不同!!");
                return (false, $"容器'{cntrCode}'在[容器表]中的类型为'{cntr.S_TYPE}',与当前流程所需容器类型'{cntrType}'不同!!");
            }
            return (true, "检查容器类型成功!!");
        }