S6ProcessInspectionFlowSeed.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. using System.Diagnostics;
  2. using System.Text.Json;
  3. using Admin.NET.Plugin.AiDOP.Entity;
  4. using Admin.NET.Plugin.AiDOP.Manufacturing;
  5. using Admin.NET.Plugin.ApprovalFlow;
  6. using Admin.NET.Plugin.ApprovalFlow.Service;
  7. using Yitter.IdGenerator;
  8. using ApprovalFlowEntity = Admin.NET.Plugin.ApprovalFlow.ApprovalFlow;
  9. namespace Admin.NET.Plugin.AiDOP.Infrastructure;
  10. /// <summary>
  11. /// S6 Phase 1D 过程检验单(Phase 1C bill)审核流程种子(幂等)。
  12. ///
  13. /// 桥接:让 ado_s6_process_inspection_bill 接入 ApprovalFlow(BizType=S6_PROCESS_INSPECTION)。
  14. /// 复用 IpqcInspectionFlowSeed 已建的角色(ROLE_S6_IPQC_SUPERVISOR/QUALITY_ENGINEER)与处置表 ado_s6_ipqc_quality_disposition,
  15. /// 本种子只:① 确保引擎/处置表存在(CodeFirst 幂等)② 注册 BizType ③ 发布流程定义
  16. /// (start→N1_SUBMIT(Initiator 发起人)→N2_SUP_REVIEW(主管)→GW_RESULT(disposition_required==1→N3 / 否则→end)→N3_QE_DISPOSITION(QE)→end)。
  17. /// N1=发起人本人(提交审核人),无需检验员角色成员;N2/N3 复用 IPQC 主管/QE 角色。已发布则跳过(幂等)。
  18. /// </summary>
  19. public static class S6ProcessInspectionFlowSeed
  20. {
  21. public static void EnsureSeed(ISqlSugarClient db)
  22. {
  23. try
  24. {
  25. db.CodeFirst.InitTables(
  26. typeof(ApprovalBizType),
  27. typeof(ApprovalFlowEntity),
  28. typeof(ApprovalFlowVersion));
  29. db.CodeFirst.InitTables(typeof(AdoS6IpqcQualityDisposition));
  30. EnsureBizType(db);
  31. EnsurePublishedFlow(db);
  32. }
  33. catch (Exception ex)
  34. {
  35. Trace.TraceWarning("S6 process inspection review flow seed: " + ex);
  36. }
  37. }
  38. private static void EnsureBizType(ISqlSugarClient db)
  39. {
  40. var exists = db.Queryable<ApprovalBizType>().Any(x => x.Code == S6ProcessInspectionFlowConst.BizType);
  41. if (exists) return;
  42. db.Insertable(new ApprovalBizType
  43. {
  44. Id = YitIdHelper.NextId(),
  45. Code = S6ProcessInspectionFlowConst.BizType,
  46. Name = "过程检验单(Phase1C)审核",
  47. Remark = "S6 过程检验单(ado_s6_process_inspection_bill) 提交审核→主管→质量处置 审批流",
  48. IsEnabled = true,
  49. CreateTime = DateTime.Now,
  50. UpdateTime = DateTime.Now,
  51. }).ExecuteCommand();
  52. }
  53. private static void EnsurePublishedFlow(ISqlSugarClient db)
  54. {
  55. var orgIds = db.Queryable<SysOrg>()
  56. .Select(x => x.Id).ToList()
  57. .Where(x => x > 0).Distinct().ToList();
  58. if (orgIds.Count == 0) orgIds.Add(0);
  59. var now = DateTime.Now;
  60. var flowJson = BuildFlowJson();
  61. foreach (var orgId in orgIds)
  62. {
  63. var existing = db.Queryable<ApprovalFlowEntity>()
  64. .Where(x => x.BizType == S6ProcessInspectionFlowConst.BizType && x.OrgId == orgId && x.IsPublished && !x.IsDelete)
  65. .OrderByDescending(x => x.Version)
  66. .First();
  67. if (existing != null) continue; // 已发布则跳过(幂等)
  68. var flow = new ApprovalFlowEntity
  69. {
  70. Id = YitIdHelper.NextId(),
  71. Code = $"S6PI_{orgId}",
  72. Name = "过程检验单(Phase1C)审核",
  73. BizType = S6ProcessInspectionFlowConst.BizType,
  74. FormJson = "{}",
  75. FlowJson = flowJson,
  76. Status = 1,
  77. Remark = "系统默认流程 v1:开始-提交审核(发起人)-检验主管审核-网关(质量结果)-质量处置-结束",
  78. Version = 1,
  79. IsPublished = true,
  80. OrgId = orgId,
  81. CreateTime = now,
  82. UpdateTime = now,
  83. };
  84. db.Insertable(flow).ExecuteCommand();
  85. db.Insertable(new ApprovalFlowVersion
  86. {
  87. Id = YitIdHelper.NextId(),
  88. FlowId = flow.Id,
  89. Version = flow.Version,
  90. FlowJson = flow.FlowJson,
  91. FormJson = flow.FormJson,
  92. PublishTime = now,
  93. PublisherName = "系统初始化",
  94. CreateTime = now,
  95. UpdateTime = now,
  96. }).ExecuteCommand();
  97. }
  98. }
  99. private static string BuildFlowJson()
  100. {
  101. var item = new ApprovalFlowItem
  102. {
  103. Nodes = new List<ApprovalFlowNodeItem>
  104. {
  105. new()
  106. {
  107. Id = "start", Type = "bpmn:startEvent", X = 100, Y = 120,
  108. Properties = new FlowProperties { NodeName = "开始" },
  109. Text = new FlowTextItem { X = 100, Y = 154, Value = "开始" },
  110. },
  111. new()
  112. {
  113. Id = S6ProcessInspectionFlowConst.NodeSubmit, Type = "bpmn:userTask", X = 300, Y = 120,
  114. Properties = new FlowProperties
  115. {
  116. NodeName = "提交审核",
  117. ApproverType = nameof(ApproverTypeEnum.Initiator),
  118. ApproverIds = "",
  119. ApproverNames = "发起人",
  120. MultiApproveMode = "Any",
  121. },
  122. Text = new FlowTextItem { X = 300, Y = 154, Value = "提交审核" },
  123. },
  124. new()
  125. {
  126. Id = S6ProcessInspectionFlowConst.NodeSupervisor, Type = "bpmn:userTask", X = 500, Y = 120,
  127. Properties = new FlowProperties
  128. {
  129. NodeName = "检验主管审核",
  130. ApproverType = nameof(ApproverTypeEnum.Role),
  131. ApproverIds = S6ProcessInspectionFlowConst.RoleSupervisorId.ToString(),
  132. ApproverNames = "过程检验主管",
  133. MultiApproveMode = "Any",
  134. },
  135. Text = new FlowTextItem { X = 500, Y = 154, Value = "检验主管审核" },
  136. },
  137. new()
  138. {
  139. Id = S6ProcessInspectionFlowConst.GatewayResult, Type = "bpmn:exclusiveGateway", X = 660, Y = 120,
  140. Properties = new FlowProperties
  141. {
  142. NodeName = "质量结果分流",
  143. Conditions = new List<GatewayCondition>
  144. {
  145. new()
  146. {
  147. Expression = "disposition_required == 1",
  148. TargetNodeId = S6ProcessInspectionFlowConst.NodeDisposition,
  149. IsDefault = false,
  150. Label = "不合格转质量处置",
  151. },
  152. new()
  153. {
  154. TargetNodeId = "end",
  155. IsDefault = true,
  156. Label = "合格完成",
  157. },
  158. },
  159. },
  160. Text = new FlowTextItem { X = 660, Y = 154, Value = "质量结果分流" },
  161. },
  162. new()
  163. {
  164. Id = S6ProcessInspectionFlowConst.NodeDisposition, Type = "bpmn:userTask", X = 820, Y = 120,
  165. Properties = new FlowProperties
  166. {
  167. NodeName = "质量处置",
  168. ApproverType = nameof(ApproverTypeEnum.Role),
  169. ApproverIds = S6ProcessInspectionFlowConst.RoleQualityEngineerId.ToString(),
  170. ApproverNames = "过程检验质量工程师",
  171. MultiApproveMode = "Any",
  172. },
  173. Text = new FlowTextItem { X = 820, Y = 154, Value = "质量处置" },
  174. },
  175. new()
  176. {
  177. Id = "end", Type = "bpmn:endEvent", X = 980, Y = 120,
  178. Properties = new FlowProperties { NodeName = "结束" },
  179. Text = new FlowTextItem { X = 980, Y = 154, Value = "结束" },
  180. },
  181. },
  182. Edges = new List<ApprovalFlowEdgeItem>
  183. {
  184. BuildEdge("edge-start-n1", "start", S6ProcessInspectionFlowConst.NodeSubmit, 140, 120, 260, 120),
  185. BuildEdge("edge-n1-n2", S6ProcessInspectionFlowConst.NodeSubmit, S6ProcessInspectionFlowConst.NodeSupervisor, 340, 120, 460, 120),
  186. BuildEdge("edge-n2-gw", S6ProcessInspectionFlowConst.NodeSupervisor, S6ProcessInspectionFlowConst.GatewayResult, 540, 120, 640, 120),
  187. BuildEdge("edge-gw-n3", S6ProcessInspectionFlowConst.GatewayResult, S6ProcessInspectionFlowConst.NodeDisposition, 680, 120, 780, 120),
  188. BuildEdge("edge-gw-end", S6ProcessInspectionFlowConst.GatewayResult, "end", 680, 120, 960, 120),
  189. BuildEdge("edge-n3-end", S6ProcessInspectionFlowConst.NodeDisposition, "end", 860, 120, 960, 120),
  190. }
  191. };
  192. return JsonSerializer.Serialize(item);
  193. }
  194. private static ApprovalFlowEdgeItem BuildEdge(string id, string source, string target, float sx, float sy, float ex, float ey)
  195. {
  196. return new ApprovalFlowEdgeItem
  197. {
  198. Id = id, Type = "bpmn:sequenceFlow", SourceNodeId = source, TargetNodeId = target,
  199. StartPoint = new FlowEdgePointItem { X = sx, Y = sy },
  200. EndPoint = new FlowEdgePointItem { X = ex, Y = ey },
  201. Properties = new FlowProperties(),
  202. PointsList = new List<FlowEdgePointItem> { new() { X = sx, Y = sy }, new() { X = ex, Y = ey } },
  203. };
  204. }
  205. }