kazelee
昨天 fc6dd85a865c4cadae0b9a07d56e2988d2262f10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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;
 
using Newtonsoft.Json;
 
using SqlSugar;
 
namespace HH.WCS.Mobox3.DSZSH.wms {
    /// <summary>
    /// [ 数据库事务处理 ] 帮助类
    /// </summary>
    public class DbTranHelper {
        /// <summary>
        /// 数据库事务处理 ( 创建任务 )
        /// </summary>
        /// <remarks><b>[ 要求 ]</b> obj ≠ null<br/>
        /// <b>[ 注意 ]</b> 所有的数据库操作 , 都会在对象 = null 时选择跳过 , 且不会报错 , 除了 TaskToInsert ;
        /// <br/>如果存在某个必须完成的数据库操作 , 需在调用时确保该对象 ≠ null</remarks>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static (bool, string) CreateTask(CreateTaskObj obj) {
            var db = new SqlHelper<object>().GetInstance();
            try {
                using (var tran = db.Ado.UseTran()) {
                    // 更新[容器表](业务需要)
                    if (obj.ContainerToUpdate != null && db.Updateable(obj.ContainerToUpdate).UpdateColumns(c => new { c.S_SPEC, c.S_SOURCE, c.T_MODIFY }).ExecuteCommand() <= 0) {
                        return (false, $"更新[容器][规格(物料编码)]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.ContainerToUpdate)}\n");
                    }
 
                    // 更新[容器货品明细](业务需要)
                    if (obj.CgDetailToUpdate != null && db.Updateable(obj.CgDetailToUpdate).UpdateColumns(it => new { it.N_ITEM_STATE, it.S_ITEM_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"更新[容器货品明细][物料状态]失败!!物料号='{obj.CgDetailToUpdate}',物料状态=>'{obj.CgDetailToUpdate.S_ITEM_STATE}'");
                    }
 
                    #region 删除[旧]容器绑定信息
                    if (obj.Old != null) {
                        if (obj.Old.CgDetail != null && db.Deleteable(obj.Old.CgDetail).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return (false, $"删除[旧容器货品明细]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.Old.CgDetail)}\n");
                        }
                        if (obj.Old.LocCntrRel != null && db.Deleteable(obj.Old.LocCntrRel).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return (false, $"删除[旧货位容器绑定]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.Old.LocCntrRel)}\n");
                        }
                        if (obj.Old.Location != null && db.Updateable(obj.Old.Location).UpdateColumns(l => new { l.N_CURRENT_NUM, l.T_MODIFY }).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return (false, $"更新[旧货位][当前容器数量]失败!!货位='{obj.Old.Location.S_CODE}',数量=>{obj.Old.Location.N_CURRENT_NUM}");
                        }
                    }
                    #endregion
 
                    #region 添加[新]容器绑定信息
                    if (obj.New != null) {
                        if (obj.New.CgDetail != null && db.Insertable(obj.New.CgDetail).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return (false, $"插入[新容器货品明细]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.New.CgDetail)}\n");
                        }
                        if (obj.New.LocCntrRel != null && db.Insertable(obj.New.LocCntrRel).ExecuteCommand() <= 0) {
                            tran.RollbackTran();
                            return (false, $"插入[旧货位容器绑定]失败!!数据:\n\n{JsonConvert.SerializeObject(obj.New.LocCntrRel)}\n");
                        }
                        // 新货位信息通常就是 StartLoc , 在 StartLocToUpdate 中处理即可
                    }
                    #endregion
 
                    #region 创建任务 + 货位锁
                    if (obj.StartLocToUpdate != null && db.Updateable(obj.StartLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"更新[起点货位][锁状态]失败!!起点='{obj.StartLocToUpdate.S_CODE}',锁状态=>'{obj.StartLocToUpdate.S_LOCK_STATE}'");
                    }
                    if (obj.EndLocToUpdate != null && db.Updateable(obj.EndLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"更新[终点货位][锁状态]失败!!终点='{obj.EndLocToUpdate.S_CODE}',锁状态=>'{obj.EndLocToUpdate.S_LOCK_STATE}'");
                    }
                    if (obj.TaskToInsert == null) {
                        tran.RollbackTran();
                        throw new ArgumentException("数据库事务处理:待插入的[任务]为空!!"); // 待插入的任务不存在,直接抛出异常
                    }
                    if (db.Insertable(obj.TaskToInsert).ExecuteCommand() <= 0) {
                        tran.RollbackTran();
                        return (false, $"生成任务'{obj.TaskToInsert.S_TYPE}'失败!!任务号='{obj.TaskToInsert.S_CODE}',容器号='{obj.TaskToInsert.S_CNTR_CODE}',起点='{obj.TaskToInsert.S_START_LOC}',终点='{obj.TaskToInsert.S_END_LOC}'");
                    }
                    #endregion
 
                    // 提交数据库更改
                    tran.CommitTran();
                    return (true, $"生成任务'{obj.TaskToInsert.S_TYPE}'成功!!任务号='{obj.TaskToInsert.S_CODE}',容器号='{obj.TaskToInsert.S_CNTR_CODE}',起点='{obj.TaskToInsert.S_START_LOC}',终点='{obj.TaskToInsert.S_END_LOC}'");
                }
            }
            catch (Exception) {
                throw; // 由外部方法捕获处理
            }
        }
    }
 
    public class CreateTaskObj {
 
        #region 起点货位 / 终点货位 / 任务
        public TN_Location StartLocToUpdate { get; set; } = null;
        public TN_Location EndLocToUpdate { get; set; } = null;
        public TN_Task TaskToInsert { get; set; } = null;
        #endregion
 
        #region 容器绑定信息 ( 旧 / 新 )
        /// <summary>
        /// [ 旧 ] 容器绑定信息 ( 货位 / 货位容器 / 容器货品 )
        /// </summary>
        public LocCntrCg Old { get; set; } = null;
        /// <summary>
        /// [ 新 ] 容器绑定信息 ( 货位 / 货位容器 / 容器货品 )
        /// </summary>
        public LocCntrCg New { get; set; } = null; 
        #endregion
 
        public TN_Container ContainerToUpdate { get; set; } = null;
        public TN_CG_Detail CgDetailToUpdate { get; set; } = null;
    }
 
}