kazelee
20 小时以前 fc25dda9baf3b5f4df23d35914f3dd343cf492e3
优化WCSHelper / 序列号生成逻辑 , 添加强制任务处理模块
10个文件已修改
1个文件已添加
1个文件已删除
383 ■■■■ 已修改文件
App_Start/SwaggerControllerDescProvider.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3.DSZSH.csproj 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/ApiHelper.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/DebugController.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/ForceController.cs 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
core/WCSCore.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
process/TaskProcess.cs 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/LogHelper.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/DbTran.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/LocationHelper.cs 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/SYSHelper.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
wms/WCSHelper.cs 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
App_Start/SwaggerControllerDescProvider.cs
@@ -15,9 +15,7 @@
        private static ConcurrentDictionary<string, SwaggerDocument> _cache = new ConcurrentDictionary<string, SwaggerDocument>();
        private readonly string _xmlPath;
        /// <summary>
        ///
        /// </summary>
        /// <summary></summary>
        /// <param name="swaggerProvider"></param>
        /// <param name="xmlpath">xml文档路径</param>
        public SwaggerCacheProvider(ISwaggerProvider swaggerProvider, string xmlpath)
@@ -34,10 +32,9 @@
            {
                srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
                srcDoc.vendorExtensions = new Dictionary<string, object>
            {
                { "ControllerDesc", GetControllerDesc() }
            };
                srcDoc.vendorExtensions = new Dictionary<string, object> {
                    { "ControllerDesc", GetControllerDesc() }
                };
                _cache.TryAdd(cacheKey, srcDoc);
            }
            return srcDoc;
HH.WCS.Mobox3.DSZSH.csproj
@@ -228,6 +228,7 @@
    <Compile Include="api\ApiModel.cs" />
    <Compile Include="api\DebugController.cs" />
    <Compile Include="api\ErpController.cs" />
    <Compile Include="api\ForceController.cs" />
    <Compile Include="api\MesController.cs" />
    <Compile Include="api\MoboxController.cs" />
    <Compile Include="api\AgvController.cs" />
@@ -272,7 +273,6 @@
    <Compile Include="util\LogHelper.cs" />
    <Compile Include="util\WebHelper.cs" />
    <Compile Include="wms\DbTran.cs" />
    <Compile Include="wms\LocationHelper.cs" />
    <Compile Include="wms\LogMsg.cs" />
    <Compile Include="wms\DbExpr.cs" />
    <Compile Include="wms\SYSHelper.cs" />
api/ApiHelper.cs
@@ -77,7 +77,6 @@
            }
            catch (Exception ex) {
                return NewSimpleResult(ex, preLog);
            }
        }
@@ -239,16 +238,11 @@
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
                if (needUpdateContainer) {
                    cntr.S_SOURCE = task.S_CODE; // 用任务号作为容器更新的依据
                    cntr.T_MODIFY = DateTime.Now;
                }
                else {
                    cntr = null;
                }
                cntr.S_SOURCE = task.S_CODE; // 用任务号作为容器更新的依据
                cntr.T_MODIFY = DateTime.Now;
                (ok, msg) = DbTran.CreateTask(new CreateTaskObj {
                    ContainerToUpdate = cntr,
                    ContainerToUpdate = needUpdateContainer ? cntr : null,
                    StartLocToUpdate = startLoc,
                    EndLocToUpdate = endLoc,
                    TaskToInsert = task,
@@ -659,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>
api/DebugController.cs
@@ -113,7 +113,7 @@
            try {
                // 查询起点货位:数量=0
                var startLoc = db.Queryable<TN_Location>().LeftJoin<TN_Loc_Container>((l, c) => l.S_CODE == c.S_LOC_CODE)
                    .Where((l,c) => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_CODE == model.StartLoc && l.N_CURRENT_NUM == 1 && c.S_CNTR_CODE == model.CntrCode).First();
                    .Where((l, c) => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "无" && l.C_ENABLE == "Y" && l.S_CODE == model.StartLoc && l.N_CURRENT_NUM == 1 && c.S_CNTR_CODE == model.CntrCode).First();
                if (startLoc == null) {
                    return $"没有找到起点货位'{model.StartLoc}'!要求:锁状态='无',当前容器数量=1";
                }
@@ -143,12 +143,11 @@
                        return "数据库操作失败!";
                    }
                    tran.CommitTran() ;
                    tran.CommitTran();
                    return "数据库操作成功";
                }
            }
            catch (Exception ex) {
                return ex.Message;
            }
        }
api/ForceController.cs
New file
@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using HH.WCS.Mobox3.DSZSH.models;
using HH.WCS.Mobox3.DSZSH.util;
using HH.WCS.Mobox3.DSZSH.wms;
using static HH.WCS.Mobox3.DSZSH.api.ApiModel;
using static HH.WCS.Mobox3.DSZSH.util.Config;
namespace HH.WCS.Mobox3.DSZSH.api {
    /// <summary>
    /// 应急/特殊情况的强制操作流程
    /// </summary>
    [RoutePrefix("force")]
    public class ForceController : ApiController {
        /// <summary>
        /// 强制创建任务并下发
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("ForceInbound")]
        public SimpleResult ForceCreateTask(ForceModel.ForceCreateTaskInfo model) {
            return ForceService.ForceCreateTask(model);
        }
        public SimpleResult ForceAddCgDetail() {
            return NewSimpleResult(0, "");
        }
    }
    public class ForceService {
        public static SimpleResult ForceCreateTask(ForceModel.ForceCreateTaskInfo model) {
            var db = new SqlHelper<object>().GetInstance();
            var (ok, msg) = (false, string.Empty);
            var taskInfo = ETask.M满箱下线入库.Info();
            const string preLog = "DEBUG:强制创建任务:";
            try {
                var startLoc = db.Queryable<TN_Location>().Where(DbExpr.StartLocUnbind(model.StartLoc, taskInfo.StartAreas)).First();
                if (startLoc == null) {
                    return NewSimpleResult(2, preLog + LogMsg.StartLocUnbindNotFound(model.StartLoc, taskInfo.StartAreas));
                }
                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 + LogMsg.EndLocNotFound(areas: taskInfo.EndAreas));
                }
                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
                (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);
            }
        }
    }
    public class ForceModel {
        public class ForceCreateTaskInfo {
            public string StartLoc { get; set; }
            public string EndLoc { get; set; }
            public string CntId { get; set; } // 可为空
        }
    }
}
core/WCSCore.cs
@@ -61,10 +61,10 @@
                    WCSHelper.Begin(TN_Task, model.forklift_no); // 已推送的任务的状态改成执行
                    break;
                case 3: // 开始取货
                    WCSHelper.UpdateStatus(TN_Task, "开始取货"); // 任务状态改成开始取货
                    WCSHelper.UpdateTaskState(TN_Task, "开始取货"); // 任务状态改成开始取货
                    break;
                case 4: // 取货完成
                    WCSHelper.UpdateStatus(TN_Task, "取货完成"); // 任务状态改成取货完成
                    WCSHelper.UpdateTaskState(TN_Task, "取货完成"); // 任务状态改成取货完成
                    TaskProcess.OperateStatus(TN_Task, 4); // 起点容器货位解绑,解锁起点
                    if (TN_Task.S_TYPE == ETask.C成品胶出库.Name()) {
@@ -78,10 +78,10 @@
                    break;
                case 5: // 开始卸货
                    WCSHelper.UpdateStatus(TN_Task, "开始卸货"); // 任务状态改成开始卸货
                    WCSHelper.UpdateTaskState(TN_Task, "开始卸货"); // 任务状态改成开始卸货
                    break;
                case 6: // 卸货完成
                    WCSHelper.UpdateStatus(TN_Task, "卸货完成"); // 任务状态改成卸货完成
                    WCSHelper.UpdateTaskState(TN_Task, "卸货完成"); // 任务状态改成卸货完成
                    TaskProcess.OperateStatus(TN_Task, 6); // 终点容器货位绑定,解锁终点
                    break;
                case 2: // 完成
process/TaskProcess.cs
@@ -283,12 +283,12 @@
            var taskType = mst.S_TYPE.Trim();
            if (mst.N_B_STATE == 0) {
                start = LocationHelper.GetAgvSite(mst.S_START_LOC);
                end = LocationHelper.GetAgvSite(mst.S_END_LOC);
                start = WCSHelper.GetAgvSite(mst.S_START_LOC);
                end = WCSHelper.GetAgvSite(mst.S_END_LOC);
                LogHelper.Info($"NDC推送任务:{mst.S_CODE};start='{start}',end='{end}'");
                var startLoc = LocationHelper.GetLoc(mst.S_START_LOC);
                var endLoc = LocationHelper.GetLoc(mst.S_END_LOC);
                var startLoc = WCSHelper.GetLocation(mst.S_START_LOC);
                var endLoc = WCSHelper.GetLocation(mst.S_END_LOC);
                var dic = new List<param>();
                dic.Add(new param() { name = "IKey", value = "IKey" });
                dic.Add(new param() { name = "From", value = start.ToString() });
@@ -301,7 +301,7 @@
                    //推送成功,修改任务优先级
                    mst.N_B_STATE = 1;
                    mst.S_B_STATE = TN_Task.GetStateStr(1);
                    WCSHelper.UpdateStatus(mst);//更新任务状态
                    WCSHelper.UpdateTaskState(mst);//更新任务状态
                    result = true;
                    LogHelper.Info($"NDC推送任务成功:{mst.S_CODE};start='{mst.S_START_LOC}',end='{mst.S_END_LOC}'");
                }
@@ -320,8 +320,8 @@
            if (mst.N_B_STATE == 0) {
                //var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = mst.S_START_LOC, dst = mst.S_END_LOC }), "p2p");
                start = LocationHelper.GetAgvSite(mst.S_START_LOC);
                end = LocationHelper.GetAgvSite(mst.S_END_LOC);
                start = WCSHelper.GetAgvSite(mst.S_START_LOC);
                end = WCSHelper.GetAgvSite(mst.S_END_LOC);
                var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = start, dst = end }), "p2pdst", "pgapi");
@@ -330,8 +330,8 @@
                    mst.N_B_STATE = 1;
                    mst.S_B_STATE = TN_Task.GetStateStr(1);
                    mst.S_EQ_TASK_CODE = code.ToString();
                    WCSHelper.UpdateStatus(mst);
                    WCSHelper.UpdateEQNo(mst);
                    WCSHelper.UpdateTaskState(mst);
                    WCSHelper.UpdateEqTaskNo(mst);
                    LogHelper.Info($"国自推送任务成功 {mst.S_CODE};" + "start=" + mst.S_START_LOC + "end= " + mst.S_END_LOC);
                }
                else {
@@ -353,7 +353,7 @@
            };
            if (HanAo.CreateOrder(model)) {
                mst.N_B_STATE = 1;
                WCSHelper.UpdateStatus(mst);
                WCSHelper.UpdateTaskState(mst);
                LogHelper.Info($"杭奥推送任务成功 {mst.S_CODE};" + "start=" + model.frmPos + "end= " + model.toPos);
                return true;
            }
util/LogHelper.cs
@@ -10,11 +10,10 @@
using NLog.Targets;
namespace HH.WCS.Mobox3.DSZSH.util {
    public class LogHelper
    {
    public class LogHelper {
        public static Dictionary<string, ILogger> loggers = new Dictionary<string, ILogger>();
        #region 初始方法
        #region 初始方法 ( Error 默认不使用 )
        public static void Debug(string message, string name = "") {
            ILogger logger = null;
            if (loggers.Keys.Contains(name)) {
@@ -92,8 +91,7 @@
        #endregion
    }
    internal class LogFactory
    {
    internal class LogFactory {
        /// <summary>
        /// 通过配置文件配置日志
        /// </summary>
wms/DbTran.cs
@@ -20,7 +20,7 @@
        /// 数据库事务处理 ( 创建任务 )
        /// </summary>
        /// <remarks><b>[ 要求 ]</b> obj ≠ null<br/>
        /// <b>[ 注意 ]</b> 所有的数据库操作 , 都会在对象 = null 时选择跳过 , 且不会报错 , 除了 TaskToInsert ;
        /// <b>[ 注意 ]</b> 所有的数据库操作 , 都会在对象 = null 时选择跳过 , 且不会报错 ( 除了 TaskToInsert )
        /// <br/>如果存在某个必须完成的数据库操作 , 需在调用时确保该对象 ≠ null</remarks>
        /// <param name="obj"></param>
        /// <returns></returns>
wms/LocationHelper.cs
File was deleted
wms/SYSHelper.cs
@@ -12,24 +12,34 @@
    /// <summary>
    /// [ 序列号生成 ] 帮助类
    /// </summary>
    internal class SYSHelper {
    public class SYSHelper {
        private static object locker = new object();
        internal static int GetSerialNumber(string snType, string prefix) {
        /// <summary>
        /// <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>
        /// <returns></returns>
        public static string GenerateSN(string snType, string prefix, string dateFormat = "yyMM", int length = 4) {
            var header = $"{prefix}{DateTime.Now.ToString(dateFormat)}-";
            var res = GetSerialNumber(snType, header);
            if (res == 0) return "";
            else {
                return $"{header}{res.ToString().PadLeft(length, '0')}";
            }
        }
        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) {
                    if (sId.CN_T_LAST < DateTime.Today) {
                        sId.CN_N_MAX = 1;
                    }
                    else {
                        sId.CN_N_MAX++;
                    }
                    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) {
                    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;
                    }
                }
@@ -37,7 +47,6 @@
                    //插入表
                    sId = new OI_SYS_MAXID { CN_S_TYPE = snType, CN_S_PRE = prefix, CN_N_MAX = 1 };
                    result = db.Insertable(sId).ExecuteCommand() > 0 ? 1 : 0;
                }
            }
            return result;
wms/WCSHelper.cs
@@ -14,20 +14,65 @@
    /// <summary>
    /// [ 通用业务 ] 帮助类
    /// </summary>
    internal class WCSHelper {
        internal static string GenerateTaskNo() {
            var id = SYSHelper.GetSerialNumber("任务号", "TN");
            var date = DateTime.Now.ToString("yyMMdd");
            return $"TN{date}{id.ToString().PadLeft(4, '0')}";
    public class WCSHelper {
        #region LocationHelper
        private static Dictionary<string, TN_Location> _locationDict = null;
        static WCSHelper() {
            var db = new SqlHelper<object>().GetInstance();
            try {
                //初始化Location加入到字典缓存
                _locationDict = new Dictionary<string, TN_Location>();
                var locList = db.Queryable<TN_Location>().ToList();
                foreach (var loc in locList) {
                    if (!_locationDict.ContainsKey(loc.S_CODE)) {
                        _locationDict.Add(loc.S_CODE, loc);
                    }
                }
            }
            catch (Exception ex) {
                LogHelper.InfoEx(ex, "WCSHelper:初始化Location到字典缓存");
            }
        }
        internal static bool UpdateStatus(TN_Task task, string status) {
        public static TN_Location GetLocation(string locCode, bool useDict = true) {
            if (useDict && _locationDict.Keys.Contains(locCode)) {
                return _locationDict[locCode.Trim()];
            }
            var db = new SqlHelper<object>().GetInstance();
            return db.Queryable<TN_Location>().Where(l => l.S_CODE == locCode).First();
        }
        public static string GetAgvSite(string locCode, bool useDict = true) {
            if (useDict && _locationDict.Keys.Contains(locCode)) {
                return _locationDict[locCode.Trim()].S_AGV_SITE;
            }
            var db = new SqlHelper<object>().GetInstance();
            var loc = db.Queryable<TN_Location>().Where(l => l.S_CODE == locCode).First();
            return loc == null ? "0" : loc.S_AGV_SITE;
        }
        #endregion
        #region 任务创建 / 下发 / 查询
        internal static string GenerateTaskNo() {
            //var id = SYSHelper.GetSerialNumberResetByDay("任务号", "TN");
            //var date = DateTime.Now.ToString("yyMMdd");
            //return $"TN{date}{id.ToString().PadLeft(4, '0')}";
            return SYSHelper.GenerateSN("任务号", "TN", "yyMMdd");
        }
        internal static bool UpdateTaskState(TN_Task task, string state) {
            var res = false;
            var db = new SqlHelper<TN_Task>().GetInstance();
            task.S_B_STATE = status;
            task.S_B_STATE = state;
            res = db.Updateable(task).UpdateColumns(it => new { it.S_B_STATE }).ExecuteCommand() > 0;
            return res;
        }
        internal static bool UpdateStatus(TN_Task task) {
        internal static bool UpdateTaskState(TN_Task task) {
            var res = false;
            var db = new SqlHelper<TN_Task>().GetInstance();
            task.S_B_STATE = TN_Task.GetStateStr(task.N_B_STATE);
@@ -35,25 +80,21 @@
            res = db.Updateable(task).UpdateColumns(it => new { it.N_B_STATE, it.S_B_STATE, it.T_MODIFY }).ExecuteCommand() > 0;
            return res;
        }
        internal static bool UpdateEQNo(TN_Task task) {
        internal static bool UpdateEqTaskNo(TN_Task task) {
            var res = false;
            var db = new SqlHelper<TN_Task>().GetInstance();
            task.T_MODIFY = DateTime.Now;
            db.Updateable(task).UpdateColumns(it => new { it.S_EQ_TASK_CODE, it.T_MODIFY }).ExecuteCommand();
            res = db.Updateable(task).UpdateColumns(it => new { it.S_EQ_TASK_CODE, it.T_MODIFY }).ExecuteCommand() > 0;
            return res;
        }
        internal static TN_Task GetTask(string no) {
        internal static TN_Task GetTask(string taskNo) {
            var db = new SqlHelper<TN_Task>().GetInstance();
            var task = db.Queryable<TN_Task>().Where(a => a.S_CODE == no).First();
            var task = db.Queryable<TN_Task>().Where(a => a.S_CODE == taskNo).First();
            return task;
        }
        public static string GetAgvSite(string locCode) {
            var db = new SqlHelper<object>().GetInstance();
            var loc = db.Queryable<TN_Location>().Where(l => l.S_CODE == locCode).First();
            return loc == null ? "0" : loc.S_AGV_SITE;
        }
        }
        #endregion
        #region 容器相关信息 查询 / 绑定
        /// <summary>
@@ -217,15 +258,17 @@
        /// <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) {
        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 任务分发 / 执行 / 记录
        internal static bool CheckActionRecordExist(string no, int code) {
            var db = new SqlHelper<TN_Task_Action>().GetInstance();
            return db.Queryable<TN_Task_Action>().Count(a => a.S_TASK_CODE == no && a.N_ACTION_CODE == code) > 0;
@@ -277,7 +320,8 @@
        internal static List<TN_Task> GetWaitingTaskList() {
            var db = new SqlHelper<object>().GetInstance();
            return db.Queryable<TN_Task>().Where(a => a.N_B_STATE == 0 && (a.S_B_STATE == "等待" || a.S_B_STATE == "待推送")).ToList();
        }
        }
        #endregion
    }
    /// <summary>