kazelee
18 小时以前 2d3ee03961d6cfbde70342e8a97bc7b05d0b0dc3
wms/WCSHelper.cs
@@ -53,7 +53,7 @@
        }
        /// <summary>
        /// ![[弃用|理由:不灵活,涉及业务过于具体]]检查容器类型是否正确
        /// <!--弃用|理由:不灵活,涉及业务过于具体-->检查容器类型是否正确
        /// </summary>
        /// <param name="cntrCode"></param>
        /// <param name="cntrType"></param>
@@ -96,7 +96,7 @@
            if (locCntrRel != null) {
                location = db.Queryable<TN_Location>().Where(l => l.S_CODE == locCntrRel.S_LOC_CODE).First();
                if (location == null) {
                    LogHelper.Warn($"");
                    LogHelper.Warn($"获取容器关联信息:[货位容器关系]存在,但[货位]不存在!容器='{cntrCode}',货位='{locCntrRel.S_LOC_CODE}'");
                }
            }
            if (location != null) {
@@ -112,19 +112,39 @@
        }
        /// <summary>
        /// 绑定[货位-容器]信息
        /// [绑定[货位-容器]信息](设置货位数量为1;不会检查loc是否为null)
        /// </summary>
        /// <param name="startLoc"></param>
        /// <param name="loc"></param>
        /// <param name="cntrCode"></param>
        /// <returns></returns>
        public static TN_Loc_Container BindLocCntr(ref TN_Location startLoc, string cntrCode) {
        public static TN_Loc_Container BindLocCntr(ref TN_Location loc, string cntrCode) {
            var locCntrRel = new TN_Loc_Container {
                S_LOC_CODE = startLoc.S_CODE,
                S_LOC_CODE = loc.S_CODE,
                S_CNTR_CODE = cntrCode,
            };
            startLoc.N_CURRENT_NUM = 1;
            startLoc.T_MODIFY = DateTime.Now;
            if (loc.N_CURRENT_NUM != 0) {
                LogHelper.Warn($"绑定货位容器:程序正在尝试给[容器数量]不是0的货位,设置[容器数量]为1!货位='{loc.S_CODE}',容器数量={loc.N_CURRENT_NUM}");
            }
            loc.N_CURRENT_NUM = 1;
            loc.T_MODIFY = DateTime.Now;
            return locCntrRel;
        }
        public static TN_Loc_Container BindLocCntrs(ref TN_Location loc, List<string> cntrCodes) {
            var locCntrRel = new TN_Loc_Container {
                S_LOC_CODE = loc.S_CODE,
                S_CNTR_CODE = string.Join(",", cntrCodes)
            };
            if (loc.N_CURRENT_NUM != 0) {
                LogHelper.Warn($"绑定货位容器:程序正在尝试给[容器数量]不是0的货位,设置[容器数量]为1!货位='{loc.S_CODE}',容器数量={loc.N_CURRENT_NUM}");
            }
            loc.N_CURRENT_NUM = 1;
            loc.T_MODIFY = DateTime.Now;
            return locCntrRel;
        }
@@ -132,70 +152,102 @@
        /// <summary>
        /// 起点出库锁
        /// </summary>
        /// <remarks>要求: loc != null; 锁状态='无';</remarks>
        /// <param name="loc"></param>
        /// <param name="lockSource"></param>
        public static void LockStartLoc(ref TN_Location loc, string lockSource = "") {
            if (loc == null) {
                throw new ArgumentNullException(); // 接受货位loc为空时直接抛异常(通常不会发生)
            }
        public static void LockStartLoc(TN_Location loc, string lockSource = "") {
            if (loc.N_LOCK_STATE != 0 || loc.S_LOCK_STATE != "无") {
                LogHelper.Warn($"起点出库锁:程序正在尝试给当前[锁状态]不是'无'的货位上锁!货位='{loc.S_CODE}',锁状态=({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
                LogHelper.Warn($"起点出库锁:程序正在尝试给当前[锁状态]≠'无'的货位上锁!货位='{loc.S_CODE}',锁状态=({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
            }
            loc.N_LOCK_STATE = 2; // 起点出库锁
            loc.S_LOCK_STATE = TN_Location.GetLockStateStr(2); // 起点出库锁
            loc.S_LOCK_OP = lockSource;
            loc.T_MODIFY = System.DateTime.Now;
            LogHelper.Info($"起点出库锁:起点货位'{loc.S_CODE}'设置[出库锁]");
        }
        /// <summary>
        /// 终点入库锁
        /// </summary>
        /// <remarks>要求: loc != null; 锁状态='无';</remarks>
        /// <param name="loc"></param>
        /// <param name="lockSource"></param>
        public static void LockEndLoc(ref TN_Location loc, string lockSource = "") {
            if (loc == null) {
                throw new ArgumentNullException(); // 接受货位loc为空时直接抛异常(通常不会发生)
            }
        public static void LockEndLoc(TN_Location loc, string lockSource = "") {
            if (loc.N_LOCK_STATE != 0 || loc.S_LOCK_STATE != "无") {
                LogHelper.Warn($"起点出库锁:程序正在尝试给当前[锁状态]不是'无'的货位上锁!货位='{loc.S_CODE}',锁状态=({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
                LogHelper.Warn($"终点入库锁:程序正在尝试给当前[锁状态]≠'无'的货位上锁!货位='{loc.S_CODE}',锁状态=({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
            }
            loc.N_LOCK_STATE = 1; // 终点出库锁
            loc.S_LOCK_STATE = TN_Location.GetLockStateStr(1); // 终点出库锁
            loc.N_LOCK_STATE = 1; // 终点入库锁
            loc.S_LOCK_STATE = TN_Location.GetLockStateStr(1); // 终点入库锁
            loc.S_LOCK_OP = lockSource;
            loc.T_MODIFY = System.DateTime.Now;
            LogHelper.Info($"终点入库锁:终点货位='{loc.S_CODE}',来源='{lockSource}'");
        }
        /// <summary>
        /// 创建任务
        /// [创建任务](需确保startLoc/endLoc不为null;不会检查货位S_CODE,S_AREA_CODE属性是否合法)
        /// </summary>
        /// <param name="startLoc">起点货位:至少提供:S_CODE,S_AREA_CODE</param>
        /// <param name="endLoc">终点货位:至少提供:S_CODE,S_AREA_CODE</param>
        /// <param name="cntId">容器号</param>
        /// <param name="type">任务类型(名称)</param>
        /// <param name="pri">优先级</param>
        /// <param name="agvType">AGV类型</param>
        /// <param name="agv">AGV类型</param>
        /// <returns></returns>
        public static TN_Task BuildTask(TN_Location startLoc, TN_Location endLoc, string cntId, string type, int pri = 3, int agvType = 1) {
        public static TN_Task BuildTask(TN_Location startLoc, TN_Location endLoc, string cntId, string type, int pri = 3, int agv = 1) {
            TN_Task TN_Task = new TN_Task() {
                S_CODE = GenerateTaskNo(),
                S_START_AREA = startLoc.S_AREA_CODE,
                S_END_AREA = endLoc.S_AREA_CODE,
                S_START_LOC = startLoc.S_CODE,
                S_END_LOC = endLoc.S_CODE,
                S_CNTR_CODE = cntId,
                S_TYPE = type,
                N_PRIORITY = pri,
                N_SCHEDULE_TYPE = agvType,
                N_SCHEDULE_TYPE = agv,
                N_B_STATE = 0, // 任务创建时,默认等待
                S_CNTR_CODE = cntId,
            };
            LogHelper.Info($"创建任务:任务号='{TN_Task.S_CODE}'");
            return TN_Task;
        }
        /// <summary>
        /// [ 创建任务,并上锁 ] ( 需确保startLoc/endLoc不为null ; 不会检查货位S_CODE,S_AREA_CODE属性是否合法 )
        /// </summary>
        /// <remarks>要求 : (1) startLoc / endLoc ≠ null<br/>(2) startLoc / endLoc 存在 S_CODE , S_AREA_CODE</remarks>
        /// <param name="startLoc">起点货位 : 至少提供 : S_CODE , S_AREA_CODE</param>
        /// <param name="endLoc">终点货位 : 至少提供 : S_CODE , S_AREA_CODE</param>
        /// <param name="cntId">容器号</param>
        /// <param name="type">任务类型(名称)</param>
        /// <param name="pri">优先级</param>
        /// <param name="agv">AGV类型</param>
        /// <returns></returns>
        public static TN_Task BuildTaskWithLocLock(TN_Location startLoc, TN_Location endLoc, string cntId, string type, int pri = 3, int agv = 1) {
            TN_Task TN_Task = new TN_Task() {
                S_CODE = GenerateTaskNo(),
                S_START_AREA = startLoc.S_AREA_CODE,
                S_END_AREA = endLoc.S_AREA_CODE,
                S_START_LOC = startLoc.S_CODE,
                S_END_LOC = endLoc.S_CODE,
                S_CNTR_CODE = cntId,
                S_TYPE = type,
                N_PRIORITY = pri,
                N_SCHEDULE_TYPE = agv,
                N_B_STATE = 0, // 任务创建时,默认等待
            };
            LogHelper.Info($"创建任务:任务号='{TN_Task.S_CODE}'");
            LockStartLoc(startLoc, TN_Task.S_CODE);
            LockEndLoc(endLoc, TN_Task.S_CODE);
            return TN_Task;
        }
        internal static bool CheckActionRecordExist(string no, int code) {
            var db = new SqlHelper<TN_Task_Action>().GetInstance();