| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- using System.Diagnostics;
- using System.Text.Json;
- using Admin.NET.Plugin.AiDOP.Entity;
- using Admin.NET.Plugin.AiDOP.MaterialWarehouse;
- using Admin.NET.Plugin.ApprovalFlow;
- using Admin.NET.Plugin.ApprovalFlow.Service;
- using Yitter.IdGenerator;
- using ApprovalFlowEntity = Admin.NET.Plugin.ApprovalFlow.ApprovalFlow;
- namespace Admin.NET.Plugin.AiDOP.Infrastructure;
- /// <summary>
- /// S5 来料检验单 检验员+主管流程种子(幂等)。
- ///
- /// 顺序:① 角色 ROLE_S5_IQC_INSPECTOR / ROLE_S5_IQC_SUPERVISOR ② UAT 成员绑定(superAdmin.NET 同绑两角色)
- /// ③ ApprovalBizType(S5_IQC_INSPBILL) ④ ApprovalFlow 已发布定义(start→N1_INSPECT→N2_SUP_REVIEW→end,节点绑角色)。
- /// 全部幂等:存在则跳过,不覆盖、不删除既有角色/流程。superAdmin.NET 不存在时仅告警不崩溃。
- /// </summary>
- public static class IqcInspBillFlowSeed
- {
- public static void EnsureSeed(ISqlSugarClient db)
- {
- try
- {
- db.CodeFirst.InitTables(
- typeof(ApprovalBizType),
- typeof(ApprovalFlowEntity),
- typeof(ApprovalFlowVersion));
- // D' SQE 处置表(CodeFirst 建表,无 SQL)
- db.CodeFirst.InitTables(typeof(AdoS5IqcSqeDisposition));
- EnsureRoles(db);
- EnsureUatMembers(db);
- EnsureBizType(db);
- EnsurePublishedFlow(db);
- }
- catch (Exception ex)
- {
- Trace.TraceWarning("S5 IQC inspbill flow seed: " + ex);
- }
- }
- private static void EnsureRoles(ISqlSugarClient db)
- {
- EnsureRole(db, IqcInspBillFlowConst.RoleInspectorId, IqcInspBillFlowConst.RoleInspectorCode, "来料检验员", 810);
- EnsureRole(db, IqcInspBillFlowConst.RoleSupervisorId, IqcInspBillFlowConst.RoleSupervisorCode, "来料检验主管", 811);
- EnsureRole(db, IqcInspBillFlowConst.RoleSqeId, IqcInspBillFlowConst.RoleSqeCode, "来料检验SQE", 812);
- }
- private static void EnsureRole(ISqlSugarClient db, long id, string code, string name, int orderNo)
- {
- var exists = db.Queryable<SysRole>().ClearFilter().Any(x => x.Code == code);
- if (exists) return;
- db.Insertable(new SysRole
- {
- Id = id,
- TenantId = SqlSugarConst.DefaultTenantId,
- Name = name,
- Code = code,
- OrderNo = orderNo,
- DataScope = DataScopeEnum.Self,
- Status = StatusEnum.Enable,
- Remark = "S5 来料检验流程角色",
- CreateTime = DateTime.Now,
- }).ExecuteCommand();
- }
- private static void EnsureUatMembers(ISqlSugarClient db)
- {
- var user = db.Queryable<SysUser>().ClearFilter()
- .Where(x => x.Account == IqcInspBillFlowConst.UatAccount)
- .First();
- if (user == null)
- {
- Trace.TraceWarning($"S5 IQC flow seed: UAT 账号 {IqcInspBillFlowConst.UatAccount} 不存在,跳过成员绑定(阶段2 冒烟前须指定成员)");
- return;
- }
- EnsureUserRole(db, user.Id, IqcInspBillFlowConst.RoleInspectorId);
- EnsureUserRole(db, user.Id, IqcInspBillFlowConst.RoleSupervisorId);
- EnsureUserRole(db, user.Id, IqcInspBillFlowConst.RoleSqeId);
- }
- private static void EnsureUserRole(ISqlSugarClient db, long userId, long roleId)
- {
- var exists = db.Queryable<SysUserRole>().ClearFilter().Any(x => x.UserId == userId && x.RoleId == roleId);
- if (exists) return;
- db.Insertable(new SysUserRole
- {
- Id = YitIdHelper.NextId(),
- UserId = userId,
- RoleId = roleId,
- }).ExecuteCommand();
- }
- private static void EnsureBizType(ISqlSugarClient db)
- {
- var exists = db.Queryable<ApprovalBizType>().Any(x => x.Code == IqcInspBillFlowConst.BizType);
- if (exists) return;
- db.Insertable(new ApprovalBizType
- {
- Id = YitIdHelper.NextId(),
- Code = IqcInspBillFlowConst.BizType,
- Name = "来料检验单审批",
- Remark = "S5 来料检验单 检验员→主管 审批流",
- IsEnabled = true,
- CreateTime = DateTime.Now,
- UpdateTime = DateTime.Now,
- }).ExecuteCommand();
- }
- private static void EnsurePublishedFlow(ISqlSugarClient db)
- {
- var orgIds = db.Queryable<SysOrg>()
- .Select(x => x.Id)
- .ToList()
- .Where(x => x > 0)
- .Distinct()
- .ToList();
- if (orgIds.Count == 0) orgIds.Add(0);
- var now = DateTime.Now;
- var flowJson = BuildFlowJson();
- foreach (var orgId in orgIds)
- {
- var existing = db.Queryable<ApprovalFlowEntity>()
- .Where(x => x.BizType == IqcInspBillFlowConst.BizType && x.OrgId == orgId && x.IsPublished && !x.IsDelete)
- .OrderByDescending(x => x.Version)
- .First();
- // v1→v2 幂等升级:已发布定义若已含 N3_SQE(v2)则跳过;若仍为 v1(无 N3)则下架旧版、发布 v2。
- // 历史 Running/Approved 实例使用各自 FlowJsonSnapshot,不受本次 republish 影响。
- if (existing != null)
- {
- var isV2 = (existing.FlowJson ?? "").Contains(IqcInspBillFlowConst.NodeSqe)
- && (existing.FlowJson ?? "").Contains(IqcInspBillFlowConst.GatewayPd);
- if (isV2) continue;
- db.Updateable<ApprovalFlowEntity>()
- .SetColumns(x => x.IsPublished == false)
- .SetColumns(x => x.UpdateTime == now)
- .Where(x => x.Id == existing.Id)
- .ExecuteCommand();
- }
- var nextVersion = (existing?.Version ?? 0) + 1;
- var flow = new ApprovalFlowEntity
- {
- Id = YitIdHelper.NextId(),
- Code = $"S5IQC_{orgId}",
- Name = "来料检验单审批",
- BizType = IqcInspBillFlowConst.BizType,
- FormJson = "{}",
- FlowJson = flowJson,
- Status = 1,
- Remark = "系统默认流程 v2:开始-检验员检验-检验主管审核-网关(pd)-SQE处置-结束",
- Version = nextVersion,
- IsPublished = true,
- OrgId = orgId,
- CreateTime = now,
- UpdateTime = now,
- };
- db.Insertable(flow).ExecuteCommand();
- db.Insertable(new ApprovalFlowVersion
- {
- Id = YitIdHelper.NextId(),
- FlowId = flow.Id,
- Version = flow.Version,
- FlowJson = flow.FlowJson,
- FormJson = flow.FormJson,
- PublishTime = now,
- PublisherName = "系统初始化",
- CreateTime = now,
- UpdateTime = now,
- }).ExecuteCommand();
- }
- }
- private static string BuildFlowJson()
- {
- var item = new ApprovalFlowItem
- {
- Nodes = new List<ApprovalFlowNodeItem>
- {
- new()
- {
- Id = "start",
- Type = "bpmn:startEvent",
- X = 100,
- Y = 120,
- Properties = new FlowProperties { NodeName = "开始" },
- Text = new FlowTextItem { X = 100, Y = 154, Value = "开始" },
- },
- new()
- {
- Id = IqcInspBillFlowConst.NodeInspect,
- Type = "bpmn:userTask",
- X = 300,
- Y = 120,
- Properties = new FlowProperties
- {
- NodeName = "检验员检验",
- ApproverType = nameof(ApproverTypeEnum.Role),
- ApproverIds = IqcInspBillFlowConst.RoleInspectorId.ToString(),
- ApproverNames = "来料检验员",
- MultiApproveMode = "Any",
- },
- Text = new FlowTextItem { X = 300, Y = 154, Value = "检验员检验" },
- },
- new()
- {
- Id = IqcInspBillFlowConst.NodeSupervisor,
- Type = "bpmn:userTask",
- X = 500,
- Y = 120,
- Properties = new FlowProperties
- {
- NodeName = "检验主管审核",
- ApproverType = nameof(ApproverTypeEnum.Role),
- ApproverIds = IqcInspBillFlowConst.RoleSupervisorId.ToString(),
- ApproverNames = "来料检验主管",
- MultiApproveMode = "Any",
- },
- Text = new FlowTextItem { X = 500, Y = 154, Value = "检验主管审核" },
- },
- new()
- {
- Id = IqcInspBillFlowConst.GatewayPd,
- Type = "bpmn:exclusiveGateway",
- X = 660,
- Y = 120,
- Properties = new FlowProperties
- {
- NodeName = "判定分流",
- Conditions = new List<GatewayCondition>
- {
- new()
- {
- Expression = "pd == 1",
- TargetNodeId = IqcInspBillFlowConst.NodeSqe,
- IsDefault = false,
- Label = "不合格转SQE",
- },
- new()
- {
- TargetNodeId = "end",
- IsDefault = true,
- Label = "合格完成",
- },
- },
- },
- Text = new FlowTextItem { X = 660, Y = 154, Value = "判定分流" },
- },
- new()
- {
- Id = IqcInspBillFlowConst.NodeSqe,
- Type = "bpmn:userTask",
- X = 820,
- Y = 120,
- Properties = new FlowProperties
- {
- NodeName = "SQE处置",
- ApproverType = nameof(ApproverTypeEnum.Role),
- ApproverIds = IqcInspBillFlowConst.RoleSqeId.ToString(),
- ApproverNames = "来料检验SQE",
- MultiApproveMode = "Any",
- },
- Text = new FlowTextItem { X = 820, Y = 154, Value = "SQE处置" },
- },
- new()
- {
- Id = "end",
- Type = "bpmn:endEvent",
- X = 980,
- Y = 120,
- Properties = new FlowProperties { NodeName = "结束" },
- Text = new FlowTextItem { X = 980, Y = 154, Value = "结束" },
- },
- },
- Edges = new List<ApprovalFlowEdgeItem>
- {
- BuildEdge("edge-start-n1", "start", IqcInspBillFlowConst.NodeInspect, 140, 120, 260, 120),
- BuildEdge("edge-n1-n2", IqcInspBillFlowConst.NodeInspect, IqcInspBillFlowConst.NodeSupervisor, 340, 120, 460, 120),
- BuildEdge("edge-n2-gw", IqcInspBillFlowConst.NodeSupervisor, IqcInspBillFlowConst.GatewayPd, 540, 120, 640, 120),
- BuildEdge("edge-gw-n3", IqcInspBillFlowConst.GatewayPd, IqcInspBillFlowConst.NodeSqe, 680, 120, 780, 120),
- BuildEdge("edge-gw-end", IqcInspBillFlowConst.GatewayPd, "end", 680, 120, 960, 120),
- BuildEdge("edge-n3-end", IqcInspBillFlowConst.NodeSqe, "end", 860, 120, 960, 120),
- }
- };
- return JsonSerializer.Serialize(item);
- }
- private static ApprovalFlowEdgeItem BuildEdge(string id, string source, string target, float sx, float sy, float ex, float ey)
- {
- return new ApprovalFlowEdgeItem
- {
- Id = id,
- Type = "bpmn:sequenceFlow",
- SourceNodeId = source,
- TargetNodeId = target,
- StartPoint = new FlowEdgePointItem { X = sx, Y = sy },
- EndPoint = new FlowEdgePointItem { X = ex, Y = ey },
- Properties = new FlowProperties(),
- PointsList = new List<FlowEdgePointItem>
- {
- new() { X = sx, Y = sy },
- new() { X = ex, Y = ey },
- },
- };
- }
- }
|