kazelee
2 天以前 0ed390381862dea0c7fd0210d16017eb09f12da4
封装插入容器表等业务代码, 修复部分底层旧框架方法问题
14个文件已修改
298 ■■■■■ 已修改文件
.editorconfig 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/AgvController.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/ApiHelper.cs 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/ForceController.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
core/WCSCore.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/TN_Task.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/Settings.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/SqlHelper.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/DbExpr.cs 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/DbTran.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/LogMsg.cs 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/SYSHelper.cs 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/WCSHelper.cs 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/WMSHelper.cs 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.editorconfig
@@ -70,7 +70,7 @@
csharp_indent_labels = one_less_than_current
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = true
dotnet_separate_import_directive_groups =
csharp_prefer_simple_using_statement = true:suggestion
csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = block_scoped:silent
@@ -94,6 +94,12 @@
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_prefer_tuple_swap = true:suggestion
csharp_style_prefer_utf8_string_literals = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
[*.vb]
#### 命名样式 ####
@@ -175,4 +181,6 @@
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
api/AgvController.cs
@@ -6,12 +6,9 @@
using System.Security.Cryptography;
using System.Text;
using System.Web.Http;
using HH.WCS.Mobox3.DSZSH.core;
using HH.WCS.Mobox3.DSZSH.util;
using Newtonsoft.Json;
using static HH.WCS.Mobox3.DSZSH.api.ApiModel;
using static HH.WCS.Mobox3.DSZSH.dispatch.NDC;
api/ApiHelper.cs
@@ -27,6 +27,7 @@
        public static SimpleResult GoodpackOffline(GoodpackOfflineInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var obj = new CreateTaskObj();
            var taskInfo = ETask.M满箱下线入库.Info();
            const string preLog = "API:满箱下线入库:";
@@ -53,10 +54,9 @@
                }
                // 和满托下线入库的逻辑一致,由于容器移动不会更改绑定信息,所以必须删除旧数据
                var old = WCSHelper.GetLocCntrCg(cgDetail.S_CNTR_CODE, skipCgDetail: true);
                WMSHelper.FindCntrOldInfo(obj, cgDetail.S_CNTR_CODE, skipCgDetail: true);
                var locCntrRel = WCSHelper.BindLocCntr(startLoc, cgDetail.S_CNTR_CODE);
                locCntrRel.S_CNTR_TYPE = cntrType;
                var locCntrRel = WMSHelper.BindLocCntr(obj, startLoc, cgDetail.S_CNTR_CODE, cntrType);
                var endLoc = db.Queryable<TN_Location>().Where(DbExpr.EndLoc(areas: taskInfo.EndAreas))
                    .OrderBy(l => new { l.N_LAYER }).First();
@@ -64,15 +64,8 @@
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                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,
                });
                WMSHelper.CreateTask(obj, startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
                (ok, msg) = DbTran.CreateTask(obj);
                return NewSimpleResult(ok ? 0 : 500, preLog + msg);
            }
            catch (Exception ex) {
api/ForceController.cs
@@ -41,15 +41,14 @@
            const string preLog = "DEBUG:强制创建任务:";
            try {
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.LocFilter(0, model.StartLoc, null, -1)).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                    return NewSimpleResult(2, preLog + LogMsg.StartLocNotFound(model.StartLoc, null, -1));
                }
                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.LocFilter(0, model.EndLoc, null, -1)).First();
                if (endLoc == null) {
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                    return NewSimpleResult(3, preLog + LogMsg.EndLocNotFound(model.EndLoc, null, -1));
                }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
core/WCSCore.cs
@@ -58,7 +58,7 @@
            // AGV 任务 134562(7) 状态处理
            switch (model.state) {
                case 1: // 执行
                    WCSHelper.Begin(TN_Task, model.forklift_no); // 已推送的任务的状态改成执行
                    WCSHelper.SetTaskBegin(TN_Task, model.forklift_no); // 已推送的任务的状态改成执行
                    break;
                case 3: // 开始取货
                    WCSHelper.UpdateTaskState(TN_Task, "开始取货"); // 任务状态改成开始取货
@@ -85,7 +85,7 @@
                    TaskProcess.OperateStatus(TN_Task, 6); // 终点容器货位绑定,解锁终点
                    break;
                case 2: // 完成
                    WCSHelper.End(TN_Task); // 任务状态改成结束
                    WCSHelper.SetTaskEnd(TN_Task); // 任务状态改成结束
                    //if (TN_Task.S_TYPE == TaskName.抽检_出库) {
                    //    var checkCompleteTask = Task.Run(() => {
@@ -100,7 +100,7 @@
                    break;
                case 7: // 异常
                    TaskProcess.OperateStatus(TN_Task, 7); // 异常处理
                    WCSHelper.Fail(TN_Task); // 任务状态改成错误
                    WCSHelper.SetTaskFail(TN_Task); // 任务状态改成错误
                    break;
            }
models/TN_Task.cs
@@ -38,7 +38,6 @@
        /// 任务优先级
        /// </summary>
        public int N_PRIORITY { get; set; }
        public string S_EQ_TASK_CODE { get; set; }
util/Settings.cs
@@ -8,8 +8,7 @@
using Newtonsoft.Json.Linq;
namespace HH.WCS.Mobox3.DSZSH.util {
    public class Settings
    {
    public class Settings {
        public static string WebApiUrl { get; set; }
        public static string NdcApiUrl { get; set; }
        public static string ErpApiUrl { get; set; } // ERP 反馈接口URL
@@ -17,7 +16,8 @@
        public static int TcpServerPort { get; set; }
        public static Config.ErpRoute ErpRoute { get; set; }
        public static string SqlServer { get; set; }
        public static SqlSugar.DbType DbType { get; set; } = SqlSugar.DbType.SqlServer;
        public static string DbConn { get; set; }
        //public static string TcpServerIp { get; set; }
        //public static int TcpServerPort { get; set; }
        public static List<Config.ProductionLine> ProductionLines { get; set; } = new List<Config.ProductionLine>();
@@ -48,7 +48,7 @@
                ErpApiUrl = root.ErpApiUrl;
                ErpRoute = root.ErpRoute;
                TcpServerPort= root.TcpServerPort;
                SqlServer = root.SqlServer;
                DbConn = root.SqlServer;
                //TcpServerIp = root.TcpServerIp;
                //TcpServerPort = root.TcpServerPort;
                ProductionLines = root.ProductionLines;
util/SqlHelper.cs
@@ -1,28 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using SqlSugar;
namespace HH.WCS.Mobox3.DSZSH.util {
    //https://www.donet5.com/Home/Doc
    //DOC:https://www.donet5.com/Home/Doc
    //NOTE:如果用Oracle数据库,需要包Oracle.ManagedDataAccess/21.15.0,环境netframework/4.6.2(太新了4.8,有的服务器安装不上去)
    //NOTE:SqlHelper带T的原因,是旧框架编写了`Update(T model, string[] cols)`等代码(参考HH-0014_NongFu_QingXi 农夫青溪)
    public class SqlHelper<T> where T : class, new() {
        // NOTE:如果用Oracle数据库,需要包Oracle.ManagedDataAccess/21.15.0,环境netframework 4.6.2 (太新了4.8有的服务器安装不上去)
        public SqlSugarClient GetInstance(string url = "") {
        public SqlSugarClient GetInstance() {
            //创建数据库对象
            SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() {
                ConnectionString = string.IsNullOrEmpty(url) ? Settings.SqlServer : url,
                //ConnectionString = @"Data Source=192.168.1.198\sql2008;Initial Catalog=OIMobox;User ID=sa;Password=sa@2015",
                DbType = DbType.SqlServer,
                //ConnectionString = @"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=OIMobox)));User Id=system;Password=Am123123;",
                //DbType = DbType.Oracle,
                ConnectionString = Settings.DbConn,
                DbType = Settings.DbType,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute//从特性读取主键自增信息
            });
            //监控所有超过1秒的Sql
            db.Aop.OnLogExecuted = (sql, p) => {
                //执行时间超过1秒
@@ -37,13 +31,11 @@
                }
                //相当于EF的 PrintToMiniProfiler
            };
            // 配置AOP日志
            //配置AOP日志
            //db.Aop.OnLogExecuting = (sql, pars) =>
            //{
            //    Console.WriteLine(sql); // 输出纯SQL语句
            //    Console.WriteLine(sql);//输出纯SQL语句
            //};
            //每次设置数值时都去除前导后导空格
            db.Aop.DataExecuted = (value, entity) => {
                entity.EntityColumnInfos.ToList().ForEach(a => {
@@ -53,13 +45,14 @@
                    }
                });
            };
            //据转换 (ExecuteCommand才会拦截,查询不行)
            //db.Aop.DataExecuting = (value, entity) => {
            //    //var val=entity.EntityColumnInfo
            //    Console.WriteLine(entity.EntityName);
            //设置AOP中的事件处理程序
            //db.Aop.OnExecutingChangeSql = (sql, p) => {
            //    // 示例:自动过滤软删除数据
            //    if (sql.StartsWith("SELECT")) {
            //        sql += " WHERE IsDeleted = 0";
            //    }
            //    return new KeyValuePair<string, SugarParameter[]>(sql, p);
            //};
            return db;
        }
    }
wms/DbExpr.cs
@@ -24,12 +24,14 @@
        ///   && areas.Contains(l.S_AREA_CODE)
        ///   && l.N_CURRENT_NUM == curNum
        /// ]]></code></remarks>
        /// <param name="lock"></param>
        /// <param name="name"></param>
        /// <param name="areas"></param>
        /// <param name="curNum"></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 Expression<Func<TN_Location, bool>> LocFilter(int @lock, string name, List<string> areas, int curNum) {
        public static Expression<Func<TN_Location, bool>> LocFilter(int @lock = 0, string name = "",
            List<string> areas = null, int curNum = -1) {
            Expression<Func<TN_Location, bool>> expr = l => l.C_ENABLE == "Y"; // 已启用
            if (@lock >= 0) {
@@ -63,8 +65,8 @@
        ///   && areas.Contains(l.S_AREA_CODE)
        ///   && l.N_CURRENT_NUM == 0
        /// ]]></code></remarks>
        /// <param name="name"></param>
        /// <param name="areas"></param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <returns></returns>
        public static Expression<Func<TN_Location, bool>> StartLocUnbind(string name = "", List<string> areas = null) {
            return LocFilter(0, name, areas, 0);
@@ -80,11 +82,12 @@
        ///   && areas.Contains(l.S_AREA_CODE)
        ///   && l.N_CURRENT_NUM == 1
        /// ]]></code></remarks>
        /// <param name="name"></param>
        /// <param name="areas"></param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <param name="curNum">当前数量 ( 小于 0 时忽略 )</param>
        /// <returns></returns>
        public static Expression<Func<TN_Location, bool>> StartLoc(string name = "", List<string> areas = null) {
            return LocFilter(0, name, areas, 1);
        public static Expression<Func<TN_Location, bool>> StartLoc(string name = "", List<string> areas = null, int curNum = 1) {
            return LocFilter(0, name, areas, curNum);
        }
        /// <summary>
@@ -97,11 +100,12 @@
        ///   && areas.Contains(l.S_AREA_CODE)
        ///   && l.N_CURRENT_NUM == 0
        /// ]]></code></remarks>
        /// <param name="name"></param>
        /// <param name="areas"></param>
        /// <param name="name">货位名称 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="areas">所在库区列表 ( 为 null 或 [] 时忽略 )</param>
        /// <param name="curNum">当前数量 ( 小于 0 时忽略 )</param>
        /// <returns></returns>
        public static Expression<Func<TN_Location, bool>> EndLoc(string name = "", List<string> areas = null) {
            return LocFilter(0, name, areas, 0);
        public static Expression<Func<TN_Location, bool>> EndLoc(string name = "", List<string> areas = null, int curNum = 0) {
            return LocFilter(0, name, areas, curNum);
        }
    }
}
wms/DbTran.cs
@@ -119,4 +119,8 @@
        public TN_CG_Detail CgDetailToUpdate { get; set; } = null;
    }
    public class DbTranObj {
        public List<TN_Location> LocListToUpdate { get; set; }
    }
}
wms/LogMsg.cs
@@ -24,7 +24,7 @@
        /// <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) {
        public static string LocNotFound(string desc = "", int @lock = 0, string name = "", List<string> areas = null, int curNum = -1) {
            var res = $"没有找到{desc}货位!!要求:";
            if (@lock >= 0) {
@@ -44,6 +44,16 @@
        }
        /// <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>
@@ -52,16 +62,6 @@
        /// <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>
@@ -79,8 +79,8 @@
        /// <c>"没有找到[货位容器绑定]信息!!要求:货位='loc';容器='cntr';"</c>
        /// </summary>
        /// <remarks><b>[ 注意 ]</b> 原则上至少有 1 个限制条件</remarks>
        /// <param name="loc"></param>
        /// <param name="cntr"></param>
        /// <param name="loc">货位编码 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="cntr">容器编码 ( 为 null 或 "" 时忽略 )</param>
        /// <returns></returns>
        public static string LocCntrRelNotFound(string loc = "", string cntr = "") {
            var res = $"没有找到[货位容器绑定]信息!!要求:";
@@ -99,8 +99,8 @@
        /// <c>"没有找到[容器货品明细]信息!!要求:容器='cntr';物料='item';"</c>
        /// </summary>
        /// <remarks><b>[ 注意 ]</b> 原则上至少有 1 个限制条件</remarks>
        /// <param name="cntr"></param>
        /// <param name="item"></param>
        /// <param name="cntr">容器编码 ( 为 null 或 "" 时忽略 )</param>
        /// <param name="item">物料编码 ( 为 null 或 "" 时忽略 )</param>
        /// <returns></returns>
        public static string CgDetailNotFound(string cntr = "", string item = "") {
            var res = $"没有找到[容器货品明细]信息!!要求:";
@@ -111,7 +111,7 @@
            if (!string.IsNullOrEmpty(item)) {
                res += $"物料='{item}';";
            }
            return res;
        }
    }
wms/SYSHelper.cs
@@ -1,12 +1,10 @@
using HH.WCS.Mobox3.DSZSH.util;
using SqlSugar;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HH.WCS.Mobox3.DSZSH.util;
using SqlSugar;
namespace HH.WCS.Mobox3.DSZSH.wms {
    /// <summary>
@@ -15,12 +13,20 @@
    public class SYSHelper {
        private static object locker = new object();
        /// <summary>
        /// <c>"{prefix}-{DateTime.Now.ToString(dateFormat)}-{id.ToString().PadLeft(length, '0')}"</c>
        /// <c>"{prefix}-{DateTime.Now.ToString(dateFormat)}-{id.ToString().PadLeft(length,'0')}"</c>
        /// </summary>
        /// <param name="snType"></param>
        /// <param name="prefix"></param>
        /// <param name="dateFormat"></param>
        /// <param name="length"></param>
        /// <example><code><![CDATA[
        /// 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')}";
        ///     return SYSHelper.GenerateSN(snType, prefix, "yyMMdd");
        /// }
        /// ]]></code></example>
        /// <returns></returns>
        public static string GenerateSN(string snType, string prefix, string dateFormat = "yyMM", int length = 4) {
            var header = $"{prefix}{DateTime.Now.ToString(dateFormat)}-";
@@ -30,18 +36,26 @@
                return $"{header}{res.ToString().PadLeft(length, '0')}";
            }
        }
        //原框架方法,不会按日更新MAXID,现在设为私有隐藏,默认调用封装后的GenerateSN方法
        private static int GetSerialNumber(string snType, string prefix) {
            int result = 0;
            lock (locker) {
                var db = new SqlHelper<object>().GetInstance();
                var sId = db.Queryable<OI_SYS_MAXID>().Where(a => a.CN_S_TYPE.Trim() == snType && a.CN_S_PRE.Trim() == prefix).First();
                if (sId != null) {
                    //原框架逻辑(更接近Mobox的序列号生成方法)
                    sId.CN_N_MAX++;
                    if (db.Ado.ExecuteCommand($"update OI_SYS_MAXID set CN_N_MAX={sId.CN_N_MAX} " +
                        $"where CN_S_TYPE='{snType}' and CN_S_PRE='{prefix}' ") > 0) {
                        result = sId.CN_N_MAX;
                    }
                    //按日重置MAXID的逻辑(现不考虑使用)
                    //sId.CN_N_MAX = sId.CN_T_LAST < DateTime.Today ? 1 : sId.CN_N_MAX + 1;
                    //sId.CN_T_LAST = DateTime.Now;
                    //if (db.Ado.ExecuteCommand($"update OI_SYS_MAXID set CN_N_MAX={sId.CN_N_MAX}, CN_T_LAST='{sId.CN_T_LAST}' " +
                    //    $"where CN_S_TYPE='{snType}' and CN_S_PRE='{prefix}' ") > 0) {
                    //    result = sId.CN_N_MAX;
                    //}
                }
                else {
                    //插入表
@@ -51,7 +65,6 @@
            }
            return result;
        }
        [SugarTable("dbo.OI_SYS_MAXID")]
        public class OI_SYS_MAXID {
            public string CN_S_TYPE { get; set; }
wms/WCSHelper.cs
@@ -1,14 +1,10 @@
using HH.WCS.Mobox3.DSZSH.models;
using HH.WCS.Mobox3.DSZSH.util;
using HH.WCS.Mobox3.DSZSH;
using Newtonsoft.Json;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HH.WCS.Mobox3.DSZSH.models;
using HH.WCS.Mobox3.DSZSH.util;
namespace HH.WCS.Mobox3.DSZSH.wms {
    /// <summary>
@@ -58,7 +54,7 @@
        #region 任务创建 / 下发 / 查询
        internal static string GenerateTaskNo() {
            //var id = SYSHelper.GetSerialNumberResetByDay("任务号", "TN");
            //var id = SYSHelper.GetSerialNumber("任务号", "TN");
            //var date = DateTime.Now.ToString("yyMMdd");
            //return $"TN{date}{id.ToString().PadLeft(4, '0')}";
            return SYSHelper.GenerateSN("任务号", "TN", "yyMMdd");
@@ -221,8 +217,8 @@
        /// 创建任务
        /// </summary>
        /// <remarks><b>[ 要求 ]</b> startLoc / endLoc ≠ null ; 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="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>
@@ -260,12 +256,15 @@
        /// <returns></returns>
        public static TN_Task BuildTaskWithLocLock(TN_Location startLoc, TN_Location endLoc, string cntId, string type, 
            int pri = 3, int agv = 1) {
            var task = BuildTask(startLoc, endLoc, cntId, type, pri);
            LockStartLoc(startLoc, task.S_CODE);
            LockEndLoc(endLoc, task.S_CODE);
            return task;
        }
        #endregion
        #region 任务分发 / 执行 / 记录
@@ -274,7 +273,7 @@
            return db.Queryable<TN_Task_Action>().Count(a => a.S_TASK_CODE == no && a.N_ACTION_CODE == code) > 0;
        }
        internal static void Begin(TN_Task task, string forklift_no) {
        internal static void SetTaskBegin(TN_Task task, string forklift_no) {
            var db = new SqlHelper<TN_Task>().GetInstance();
            if (task != null) {
                if (task.N_B_STATE == 1 || task.N_B_STATE == 0) { // 添加当task状态为0时也可以触发
@@ -286,7 +285,7 @@
                }
            }
        }
        internal static void End(TN_Task task) {
        internal static void SetTaskEnd(TN_Task task) {
            var db = new SqlHelper<TN_Task>().GetInstance();
            if (task != null) {
                task.N_B_STATE = 3;
@@ -295,7 +294,7 @@
                db.Updateable(task).UpdateColumns(it => new { it.N_B_STATE, it.S_B_STATE, it.T_END_TIME }).ExecuteCommand();
            }
        }
        internal static void Fail(TN_Task task) {
        internal static void SetTaskFail(TN_Task task) {
            var db = new SqlHelper<TN_Task>().GetInstance();
            if (task != null) {
                //判断有没有取货完成,没有就变成失败。有取货完成默认完成了 (跟据项目而定,有些项目人工拉走了也没有放到终点) 。
wms/WMSHelper.cs
@@ -4,13 +4,11 @@
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using HH.WCS.Mobox3.DSZSH.models;
using HH.WCS.Mobox3.DSZSH.util;
using Newtonsoft.Json;
using static HH.WCS.Mobox3.DSZSH.api.ApiModel;
using static HH.WCS.Mobox3.DSZSH.util.Config;
namespace HH.WCS.Mobox3.DSZSH.wms {
    /// <summary>
@@ -36,5 +34,78 @@
            }
            return (true, "检查容器类型成功!!");
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="locCode"></param>
        /// <param name="areas"></param>
        /// <param name="startLoc"></param>
        /// <returns></returns>
        public static (bool, string) FindStartLocUnbind(string locCode, List<string> areas, out TN_Location startLoc) {
            var db = new SqlHelper<object>().GetInstance();
            startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(locCode, areas)).First();
            if (startLoc == null) {
                return (false, LogMsg.StartLocUnbindNotFound(locCode, areas));
            }
            return (true, "");
        }
        /// <summary>
        /// 根据容器号 , 查找旧的货位 / 货位绑定 / 物料信息 ( 将待删除 / 更新数据写入 obj )
        /// </summary>
        /// <remarks><code><![CDATA[obj.Old = oldLocCntrCg;]]></code></remarks>
        /// <param name="obj"></param>
        /// <param name="cntrCode"></param>
        /// <param name="skipCgDetail"></param>
        /// <returns></returns>
        public static LocCntrCg FindCntrOldInfo(CreateTaskObj obj, string cntrCode, bool skipCgDetail = true) {
            var oldLocCntrCg = WCSHelper.GetLocCntrCg(cntrCode, skipCgDetail);
            obj.Old = oldLocCntrCg;
            return oldLocCntrCg;
        }
        /// <summary>
        /// 绑定货位容器 ( 修改 [ 货位容器表 ] [ 货位类型 ] = cntrType ; 将 [ 待插入 ] 货位容器关系 加入到 obj 中 )
        /// </summary>
        /// <remarks><code><![CDATA[obj.New = new LocCntrCg { LocCntrRel = locCntrRel };]]></code></remarks>
        /// <param name="obj"></param>
        /// <param name="loc"></param>
        /// <param name="cntrCode"></param>
        /// <param name="cntrType"></param>
        /// <returns></returns>
        public static TN_Loc_Container BindLocCntr(CreateTaskObj obj, TN_Location loc, string cntrCode, string cntrType = "") {
            var locCntrRel = WCSHelper.BindLocCntr(loc, cntrCode);
            if (!string.IsNullOrEmpty(cntrType)) {
                locCntrRel.S_CNTR_TYPE = cntrType;
            }
            obj.New = new LocCntrCg { LocCntrRel = locCntrRel };
            return locCntrRel;
        }
        /// <summary>
        /// 创建任务 ( 构造任务项 / 起点终点上锁 ; 将 插入任务 / 更新货位 的对象写入 obj )
        /// </summary>
        /// <remarks><code><![CDATA[
        /// obj.TaskToInsert = task;
        /// obj.StartLocToUpdate = startLoc;
        /// obj.EndLocToUpdate = endLoc;
        /// ]]></code></remarks>
        /// <param name="obj"></param>
        /// <param name="startLoc"></param>
        /// <param name="endLoc"></param>
        /// <param name="cntId"></param>
        /// <param name="type"></param>
        /// <param name="pri"></param>
        /// <param name="agv"></param>
        public static TN_Task CreateTask(CreateTaskObj obj, TN_Location startLoc, TN_Location endLoc, string cntId, string type,
            int pri = 3, int agv = 1) {
            var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, type, pri);
            WCSHelper.LockStartLoc(startLoc, task.S_CODE);
            WCSHelper.LockEndLoc(endLoc, task.S_CODE);
            obj.TaskToInsert = task;
            obj.StartLocToUpdate = startLoc;
            obj.EndLocToUpdate = endLoc;
            return task;
        }
    }
}