FqcInspBillFlowSeed.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. using System.Diagnostics;
  2. using System.Text.Json;
  3. using Admin.NET.Plugin.AiDOP.FinishedWarehouse;
  4. using Admin.NET.Plugin.ApprovalFlow;
  5. using Admin.NET.Plugin.ApprovalFlow.Service;
  6. using Yitter.IdGenerator;
  7. using ApprovalFlowEntity = Admin.NET.Plugin.ApprovalFlow.ApprovalFlow;
  8. namespace Admin.NET.Plugin.AiDOP.Infrastructure;
  9. /// <summary>
  10. /// S7 FQC 成品检验单 检验员+主管流程种子(幂等)。
  11. ///
  12. /// 顺序:① 角色 ROLE_S7_FQC_INSPECTOR / ROLE_S7_FQC_SUPERVISOR ② UAT 成员绑定(superAdmin.NET 同绑两角色)
  13. /// ③ ApprovalBizType(S7_FQC_INSPBILL) ④ ApprovalFlow 已发布定义(start→N1_INSPECT→N2_SUP_REVIEW→end,节点绑角色,线性无网关)。
  14. /// 全部幂等:存在则跳过,不覆盖、不删除既有角色/流程。superAdmin.NET 不存在时仅告警不崩溃。
  15. /// </summary>
  16. public static class FqcInspBillFlowSeed
  17. {
  18. public static void EnsureSeed(ISqlSugarClient db)
  19. {
  20. try
  21. {
  22. db.CodeFirst.InitTables(
  23. typeof(ApprovalBizType),
  24. typeof(ApprovalFlowEntity),
  25. typeof(ApprovalFlowVersion));
  26. EnsureRoles(db);
  27. EnsureUatMembers(db);
  28. EnsureBizType(db);
  29. EnsurePublishedFlow(db);
  30. }
  31. catch (Exception ex)
  32. {
  33. Trace.TraceWarning("S7 FQC inspbill flow seed: " + ex);
  34. }
  35. }
  36. private static void EnsureRoles(ISqlSugarClient db)
  37. {
  38. EnsureRole(db, FqcInspBillFlowConst.RoleInspectorId, FqcInspBillFlowConst.RoleInspectorCode, "成品检验员", 820);
  39. EnsureRole(db, FqcInspBillFlowConst.RoleSupervisorId, FqcInspBillFlowConst.RoleSupervisorCode, "成品检验主管", 821);
  40. }
  41. private static void EnsureRole(ISqlSugarClient db, long id, string code, string name, int orderNo)
  42. {
  43. var exists = db.Queryable<SysRole>().ClearFilter().Any(x => x.Code == code);
  44. if (exists) return;
  45. db.Insertable(new SysRole
  46. {
  47. Id = id,
  48. TenantId = SqlSugarConst.DefaultTenantId,
  49. Name = name,
  50. Code = code,
  51. OrderNo = orderNo,
  52. DataScope = DataScopeEnum.Self,
  53. Status = StatusEnum.Enable,
  54. Remark = "S7 成品检验流程角色",
  55. CreateTime = DateTime.Now,
  56. }).ExecuteCommand();
  57. }
  58. private static void EnsureUatMembers(ISqlSugarClient db)
  59. {
  60. var user = db.Queryable<SysUser>().ClearFilter()
  61. .Where(x => x.Account == FqcInspBillFlowConst.UatAccount)
  62. .First();
  63. if (user == null)
  64. {
  65. Trace.TraceWarning($"S7 FQC flow seed: UAT 账号 {FqcInspBillFlowConst.UatAccount} 不存在,跳过成员绑定(阶段2 冒烟前须指定成员)");
  66. return;
  67. }
  68. EnsureUserRole(db, user.Id, FqcInspBillFlowConst.RoleInspectorId);
  69. EnsureUserRole(db, user.Id, FqcInspBillFlowConst.RoleSupervisorId);
  70. }
  71. private static void EnsureUserRole(ISqlSugarClient db, long userId, long roleId)
  72. {
  73. var exists = db.Queryable<SysUserRole>().ClearFilter().Any(x => x.UserId == userId && x.RoleId == roleId);
  74. if (exists) return;
  75. db.Insertable(new SysUserRole
  76. {
  77. Id = YitIdHelper.NextId(),
  78. UserId = userId,
  79. RoleId = roleId,
  80. }).ExecuteCommand();
  81. }
  82. private static void EnsureBizType(ISqlSugarClient db)
  83. {
  84. var exists = db.Queryable<ApprovalBizType>().Any(x => x.Code == FqcInspBillFlowConst.BizType);
  85. if (exists) return;
  86. db.Insertable(new ApprovalBizType
  87. {
  88. Id = YitIdHelper.NextId(),
  89. Code = FqcInspBillFlowConst.BizType,
  90. Name = "成品检验单审批",
  91. Remark = "S7 成品检验单 检验员→主管 审批流",
  92. IsEnabled = true,
  93. CreateTime = DateTime.Now,
  94. UpdateTime = DateTime.Now,
  95. }).ExecuteCommand();
  96. }
  97. private static void EnsurePublishedFlow(ISqlSugarClient db)
  98. {
  99. var orgIds = db.Queryable<SysOrg>()
  100. .Select(x => x.Id)
  101. .ToList()
  102. .Where(x => x > 0)
  103. .Distinct()
  104. .ToList();
  105. if (orgIds.Count == 0) orgIds.Add(0);
  106. var now = DateTime.Now;
  107. var flowJson = BuildFlowJson();
  108. foreach (var orgId in orgIds)
  109. {
  110. var existing = db.Queryable<ApprovalFlowEntity>()
  111. .Where(x => x.BizType == FqcInspBillFlowConst.BizType && x.OrgId == orgId && x.IsPublished && !x.IsDelete)
  112. .OrderByDescending(x => x.Version)
  113. .First();
  114. // 已发布定义存在即跳过(线性 N1→N2 首版,不做版本升级)。
  115. if (existing != null) continue;
  116. var flow = new ApprovalFlowEntity
  117. {
  118. Id = YitIdHelper.NextId(),
  119. Code = $"S7FQC_{orgId}",
  120. Name = "成品检验单审批",
  121. BizType = FqcInspBillFlowConst.BizType,
  122. FormJson = "{}",
  123. FlowJson = flowJson,
  124. Status = 1,
  125. Remark = "系统默认流程 v1:开始-检验员检验-检验主管审核-结束(线性)",
  126. Version = FqcInspBillFlowConst.FlowDefinitionVersion,
  127. IsPublished = true,
  128. OrgId = orgId,
  129. CreateTime = now,
  130. UpdateTime = now,
  131. };
  132. db.Insertable(flow).ExecuteCommand();
  133. db.Insertable(new ApprovalFlowVersion
  134. {
  135. Id = YitIdHelper.NextId(),
  136. FlowId = flow.Id,
  137. Version = flow.Version,
  138. FlowJson = flow.FlowJson,
  139. FormJson = flow.FormJson,
  140. PublishTime = now,
  141. PublisherName = "系统初始化",
  142. CreateTime = now,
  143. UpdateTime = now,
  144. }).ExecuteCommand();
  145. }
  146. }
  147. private static string BuildFlowJson()
  148. {
  149. var item = new ApprovalFlowItem
  150. {
  151. Nodes = new List<ApprovalFlowNodeItem>
  152. {
  153. new()
  154. {
  155. Id = "start",
  156. Type = "bpmn:startEvent",
  157. X = 100,
  158. Y = 120,
  159. Properties = new FlowProperties { NodeName = "开始" },
  160. Text = new FlowTextItem { X = 100, Y = 154, Value = "开始" },
  161. },
  162. new()
  163. {
  164. Id = FqcInspBillFlowConst.NodeInspect,
  165. Type = "bpmn:userTask",
  166. X = 300,
  167. Y = 120,
  168. Properties = new FlowProperties
  169. {
  170. NodeName = "检验员检验",
  171. ApproverType = nameof(ApproverTypeEnum.Role),
  172. ApproverIds = FqcInspBillFlowConst.RoleInspectorId.ToString(),
  173. ApproverNames = "成品检验员",
  174. MultiApproveMode = "Any",
  175. },
  176. Text = new FlowTextItem { X = 300, Y = 154, Value = "检验员检验" },
  177. },
  178. new()
  179. {
  180. Id = FqcInspBillFlowConst.NodeSupervisor,
  181. Type = "bpmn:userTask",
  182. X = 500,
  183. Y = 120,
  184. Properties = new FlowProperties
  185. {
  186. NodeName = "检验主管审核",
  187. ApproverType = nameof(ApproverTypeEnum.Role),
  188. ApproverIds = FqcInspBillFlowConst.RoleSupervisorId.ToString(),
  189. ApproverNames = "成品检验主管",
  190. MultiApproveMode = "Any",
  191. },
  192. Text = new FlowTextItem { X = 500, Y = 154, Value = "检验主管审核" },
  193. },
  194. new()
  195. {
  196. Id = "end",
  197. Type = "bpmn:endEvent",
  198. X = 700,
  199. Y = 120,
  200. Properties = new FlowProperties { NodeName = "结束" },
  201. Text = new FlowTextItem { X = 700, Y = 154, Value = "结束" },
  202. },
  203. },
  204. Edges = new List<ApprovalFlowEdgeItem>
  205. {
  206. BuildEdge("edge-start-n1", "start", FqcInspBillFlowConst.NodeInspect, 140, 120, 260, 120),
  207. BuildEdge("edge-n1-n2", FqcInspBillFlowConst.NodeInspect, FqcInspBillFlowConst.NodeSupervisor, 340, 120, 460, 120),
  208. BuildEdge("edge-n2-end", FqcInspBillFlowConst.NodeSupervisor, "end", 540, 120, 660, 120),
  209. }
  210. };
  211. return JsonSerializer.Serialize(item);
  212. }
  213. private static ApprovalFlowEdgeItem BuildEdge(string id, string source, string target, float sx, float sy, float ex, float ey)
  214. {
  215. return new ApprovalFlowEdgeItem
  216. {
  217. Id = id,
  218. Type = "bpmn:sequenceFlow",
  219. SourceNodeId = source,
  220. TargetNodeId = target,
  221. StartPoint = new FlowEdgePointItem { X = sx, Y = sy },
  222. EndPoint = new FlowEdgePointItem { X = ex, Y = ey },
  223. Properties = new FlowProperties(),
  224. PointsList = new List<FlowEdgePointItem>
  225. {
  226. new() { X = sx, Y = sy },
  227. new() { X = ex, Y = ey },
  228. },
  229. };
  230. }
  231. }