kazelee
2025-05-12 968d603a08117e7e6707ffe07c6da9c325e36c08
ServiceCore/OutboundCore.cs
@@ -1,171 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HH.WCS.Mobox3.DSZSH.Consts;
using HH.WCS.Mobox3.DSZSH.Helpers;
using HH.WCS.Mobox3.DSZSH.Helpers.Model;
using HH.WCS.Mobox3.DSZSH.Models;
using Newtonsoft.Json;
namespace HH.WCS.Mobox3.DSZSH.ServiceCore {
    /// <summary>
    /// 定时轮询任务:出库业务核心
    /// </summary>
    public class OutboundCore {
        /// <summary>
        /// 后台轮询出库单/出库明细单,生成出库任务表
        /// </summary>
        public static void CheckOutboundOrder() {
        public static void CheckOrderState() {
            var db = DbHelper.GetDbClient();
            try {
                // 查找所有的 等待出库 的 出库单,按 先创建先处理 排序
                var orders = db.Queryable<TN_Outbound_Order>()
                    .Where(o => o.N_B_STATE == 0)
                    .OrderBy(o => o.T_CREATE)
                    .Mapper(
                        o => o.Details, // 将子表数据映射到主表的 Details 属性
                        o => o.S_NO,    // 主表关联字段
                        d => d.S_NO     // 子表关联字段
                    )
                    .ToList();
                var order = db.Queryable<TN_Outbound_Order>()
                    .Where(c => c.N_B_STATE == SpotStateCode.已执行待生成任务)
                    .OrderBy(c => c.T_CREATE, SqlSugar.OrderByType.Asc).First();
                if (orders.Count == 0) {
                    LogHelper.Info("轮询 | 当前没有等待执行的出库单");
                if (order == null) {
                    LogHelper.Info("轮询:暂无待执行的出库单");
                    return;
                }
                using (var tran = db.Ado.UseTran()) {
                    foreach (var o in orders) {
                        foreach (var d in o.Details) {
                            for (int i = 0; i < d.N_QTY; i++) {
                                var task = new TN_Outbound_Task {
                                    S_CG_ID = d.S_CG_ID,
                                    S_END_AREA = d.S_END_AREA,
                                    N_FORCE = o.N_FORCE,
                                    S_BATCH_NO = d.S_BATCH_NO,
                                    N_STATE = 0
                                };
                                if (db.Insertable<TN_Outbound_Task>(task).ExecuteCommand() <= 0) {
                                    tran.RollbackTran();
                                    LogHelper.Info("插入任务出错");
                                    return;
                                }
                            }
                            d.N_B_STATE = 1;
                            if (db.Updateable<TN_Outbound_Detail>(d).UpdateColumns(c => c.N_B_STATE).ExecuteCommand() > 0) {
                                LogHelper.Info("更新 N_B_STATE 成功");
                            }
                            else {
                                tran.RollbackTran();
                                LogHelper.Info("更新 N_B_STATE 失败");
                                return;
                            }
                        }
                        o.N_B_STATE = 1;
                        if (db.Updateable<TN_Outbound_Order>(o).UpdateColumns(c => c.N_B_STATE).ExecuteCommand() > 0) {
                            LogHelper.Info("更新 N_B_STATE 成功");
                        }
                        else {
                            tran.RollbackTran();
                            LogHelper.Info("更新 N_B_STATE 失败");
                            return;
                        }
                    }
                    tran.CommitTran();
                }
            }
            catch (Exception ex) {
                LogHelper.InfoEx(ex);
                throw;
            }
        }
        /// <summary>
        /// 轮询出库
        /// </summary>
        public static void CheckOutboundTask() {
            var db = DbHelper.GetDbClient();
            try {
                var task = db.Queryable<TN_Outbound_Task>()
                    .Where(t => t.N_STATE == 0).First();
                if (task == null) {
                    LogHelper.Info("轮询 | 出库任务队列 暂无待执行的任务");
                if (db.Queryable<TN_Outbound_Detail>()
                    .First(d => d.S_NO == order.S_NO && d.N_B_STATE == SpotStateCode.任务执行中) != null) {
                    LogHelper.Debug("轮询:上一个出库任务仍在进行中");
                    return;
                }
                var headTask = task;
                if (headTask.N_STATE != 0) {
                    LogHelper.Info("轮询 | 出库任务队列 队头任务尚未完成");
                var detail = db.Queryable<TN_Outbound_Detail>()
                    .Where(d => d.S_NO == order.S_NO && d.N_B_STATE == SpotStateCode.已执行待生成任务)
                    .OrderBy(d => d.T_CREATE, SqlSugar.OrderByType.Asc).First();
                if (detail == null) {
                    //order.N_B_STATE = SpotStateCode.任务执行中;
                    LogHelper.Info("轮询出库:暂无待执行的任务");
                    return;
                }
                var locCntr = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail>
                var startLocCntrRel = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail>
                    ((l, c, d) => l.S_CODE == c.S_LOC_CODE && c.S_CNTR_CODE == d.S_CNTR_CODE)
                    // 筛选要求的物料编码和批次号
                    .Where((l, c, d) => d.S_CG_ID == headTask.S_CG_ID && d.S_BATCH_NO == headTask.S_BATCH_NO)
                    .Where((l, c, d) => d.S_CG_ID == detail.S_CG_ID && d.S_BATCH_NO == detail.S_BATCH_NO)
                    // 如果不是强制出库,物料状态必须必须合格
                    // 否则,只要不是正在检验的物料即可
                    .Where((l, c, d) => (headTask.N_FORCE == 0 && d.N_ITEM_STATE == 0 && d.S_ITEM_STATE == "合格")
                        || (headTask.N_FORCE != 0 && d.N_ITEM_STATE != 3 && d.S_ITEM_STATE != "正在检验"))
                    // 物料状态对应的数字,越小越优先
                    // 否则,只要不是 正在检验 的物料即可
                    .Where((l, c, d) => (detail.N_FORCE == 0 && d.N_ITEM_STATE == 0 && d.S_ITEM_STATE == "合格")
                        || (detail.N_FORCE != 0 && d.N_ITEM_STATE != 3 && d.S_ITEM_STATE != "正在检验"))
                    // 排序:数字越小越优先,合格>待检>不合格
                    .OrderBy((l, c, d) => d.N_ITEM_STATE)
                    .OrderBy(l => l.N_LAYER)
                    .Select((l, c) => new { Location = l, Container = c }).First();
                if (locCntr == null) {
                    LogHelper.Info("轮询 | 不存在符合条件的物料货位");
                    .Select((l, c) => c).First();
                if (startLocCntrRel == null) {
                    LogHelper.Info("轮询:出库:没有找到合适的起点货位");
                    return;
                }
                var endLoc = db.Queryable<TN_Location>()
                    .Where(l => l.S_AREA_CODE == headTask.S_END_AREA)
                    .Where(l => l.S_AREA_CODE == detail.S_END_AREA)
                    .Where(ExprHelper.LocIsFree)
                    .Where(ExprHelper.LocIsEmpty)
                    .OrderBy(l => l.S_CODE)
                    .First();
                    .Where(ExprHelper.LocIsEmpty).First();
                if (endLoc == null) {
                    LogHelper.Info("轮询 | 不存在符合条件的出库终点库位");
                    LogHelper.Info("轮询:出库:没有找到合适的终点货位");
                    return;
                }
                using (var tran = db.Ado.UseTran()) {
                    if (TaskHelper.LogCreateTask(locCntr.Location.S_CODE, locCntr.Container.S_CNTR_CODE, endLoc.S_CODE, TaskName.成品胶出库)) {
                        task.N_STATE = 1;
                        if (db.Updateable<TN_Outbound_Task>(task).UpdateColumns(c => c.N_STATE).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            LogHelper.Info("修改出库任务状态错误");
                        }
                        else {
                            tran.CommitTran();
                            LogHelper.Info("修改出库任务状态成功");
                        }
                    detail.N_B_STATE = SpotStateCode.任务执行中;
                    if (db.Updateable<TN_Outbound_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        LogHelper.Info($"轮询:出库:更新失败:修改明细表状态为完成");
                    }
                    if (TaskHelper.LogCreateTask(startLocCntrRel.S_LOC_CODE, startLocCntrRel.S_CNTR_CODE,
                        endLoc.S_CODE, TaskName.成品胶出库)) {
                        tran.CommitTran();
                    }
                    else {
                        tran.RollbackTran();
                    }
                }
            }
            catch (Exception ex) {
                LogHelper.InfoEx(ex);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="state"></param>
        public static void UpdateTaskState(int state = 2) {
        public static void UpdateTaskState(int spotStateCode) {
            var db = DbHelper.GetDbClient();
            var detail = db.Queryable<TN_Outbound_Detail>()
                    .First(d => d.N_B_STATE == SpotStateCode.任务执行中);
            if (detail == null) {
                LogHelper.Info("当前没有执行中的出库单明细项目");
                return;
            }
            using (var tran = db.Ado.UseTran()) {
                detail.N_B_STATE = spotStateCode;
                db.Updateable<TN_Outbound_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand();
                if (db.Queryable<TN_Outbound_Detail>().Count(d => d.S_NO == detail.S_NO && d.N_B_STATE == 2) ==
                    db.Queryable<TN_Outbound_Detail>().Count(d => d.S_NO == detail.S_NO)) {
                    if (db.Updateable<TN_Check_Order>().SetColumns(it => it.N_B_STATE == SpotStateCode.任务执行完成)
                        .Where(it => it.S_NO == detail.S_NO)
                        .ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        LogHelper.Info("修改Order状态错误");
                    }
                }
                tran.CommitTran();
            }
        }
    }