ExceptionEscalationBizHandler.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. using Admin.NET.Plugin.ApprovalFlow;
  2. using Admin.NET.Plugin.ApprovalFlow.Service;
  3. using Admin.NET.Plugin.AiDOP.Entity.S0.Warehouse;
  4. using Admin.NET.Plugin.AiDOP.Entity.S8;
  5. namespace Admin.NET.Plugin.AiDOP.Service.S8;
  6. /// <summary>
  7. /// 异常升级审批业务回调
  8. /// BizType = "EXCEPTION_ESCALATION"
  9. /// </summary>
  10. public class ExceptionEscalationBizHandler : IFlowBizHandler, ITransient
  11. {
  12. public string BizType => "EXCEPTION_ESCALATION";
  13. private readonly SqlSugarRepository<AdoS8Exception> _rep;
  14. private readonly SqlSugarRepository<AdoS8ExceptionTimeline> _timelineRep;
  15. private readonly SqlSugarRepository<AdoS0EmployeeMaster> _employeeRep;
  16. public ExceptionEscalationBizHandler(
  17. SqlSugarRepository<AdoS8Exception> rep,
  18. SqlSugarRepository<AdoS8ExceptionTimeline> timelineRep,
  19. SqlSugarRepository<AdoS0EmployeeMaster> employeeRep)
  20. {
  21. _rep = rep;
  22. _timelineRep = timelineRep;
  23. _employeeRep = employeeRep;
  24. }
  25. public async Task OnFlowStarted(long bizId, long instanceId)
  26. {
  27. var e = await _rep.GetByIdAsync(bizId) ?? throw new S8BizException("异常不存在");
  28. e.Status = "ESCALATED";
  29. e.ActiveFlowInstanceId = instanceId;
  30. e.ActiveFlowBizType = BizType;
  31. e.UpdatedAt = DateTime.Now;
  32. await _rep.UpdateAsync(e);
  33. await InsertTimelineAsync(e.Id, "ESCALATE_START", "发起升级", null, "ESCALATED", instanceId, null);
  34. }
  35. public async Task OnFlowCompleted(long bizId, long instanceId, FlowInstanceStatusEnum finalStatus, long? lastApproverId)
  36. {
  37. var e = await _rep.GetByIdAsync(bizId) ?? throw new S8BizException("异常不存在");
  38. e.ActiveFlowInstanceId = null;
  39. e.ActiveFlowBizType = null;
  40. e.UpdatedAt = DateTime.Now;
  41. if (finalStatus == FlowInstanceStatusEnum.Approved)
  42. {
  43. e.Status = "ASSIGNED";
  44. // S8-ESCALATION-IDSPACE-1:lastApproverId 是 sysUser.Id 语义;e.AssigneeId 是 employee.RecID 语义。
  45. // 通过 EmployeeMaster.SysUserId 反查映射:命中唯一员工 → 写 employee.RecID;
  46. // 找不到绑定员工 → 保留原 AssigneeId 不变(不静默写 sysUserId 污染业务字段),并通过 timeline 备注暴露。
  47. string? assigneeNote = null;
  48. if (lastApproverId.HasValue)
  49. {
  50. var emp = await _employeeRep.GetFirstAsync(x => x.SysUserId == lastApproverId.Value);
  51. if (emp != null)
  52. {
  53. e.AssigneeId = emp.Id;
  54. }
  55. else
  56. {
  57. assigneeNote = $"审批人 sysUserId={lastApproverId.Value} 未绑定员工主数据,AssigneeId 保持原值";
  58. }
  59. }
  60. else
  61. {
  62. assigneeNote = "未提供审批人信息,AssigneeId 保持原值";
  63. }
  64. await _rep.UpdateAsync(e);
  65. await InsertTimelineAsync(e.Id, "ESCALATE_APPROVED",
  66. assigneeNote == null ? "升级已确认" : $"升级已确认({assigneeNote})",
  67. "ESCALATED", "ASSIGNED",
  68. instanceId, lastApproverId);
  69. }
  70. else if (finalStatus == FlowInstanceStatusEnum.Cancelled)
  71. {
  72. e.Status = "IN_PROGRESS";
  73. await _rep.UpdateAsync(e);
  74. await InsertTimelineAsync(e.Id, "ESCALATE_CANCELLED", "发起人撤回升级申请", "ESCALATED", "IN_PROGRESS",
  75. instanceId, lastApproverId);
  76. }
  77. else
  78. {
  79. e.Status = "IN_PROGRESS";
  80. await _rep.UpdateAsync(e);
  81. await InsertTimelineAsync(e.Id, "ESCALATE_REJECTED", "升级被驳回", "ESCALATED", "IN_PROGRESS",
  82. instanceId, lastApproverId);
  83. }
  84. }
  85. public async Task<Dictionary<string, object>> GetBizData(long bizId)
  86. {
  87. var e = await _rep.GetByIdAsync(bizId);
  88. if (e == null) return new Dictionary<string, object>();
  89. return new Dictionary<string, object>
  90. {
  91. ["severity"] = e.Severity ?? string.Empty,
  92. ["sceneCode"] = e.SceneCode ?? string.Empty,
  93. ["priorityLevel"] = e.PriorityLevel ?? string.Empty,
  94. ["factoryCode"] = e.FactoryId.ToString(),
  95. };
  96. }
  97. private async Task InsertTimelineAsync(long exceptionId, string code, string label,
  98. string? from, string? to, long? instanceId, long? approverId)
  99. {
  100. string? remark = null;
  101. if (instanceId.HasValue && approverId.HasValue)
  102. remark = $"审批实例ID: {instanceId},审批人: {approverId}";
  103. else if (instanceId.HasValue)
  104. remark = $"审批实例ID: {instanceId}";
  105. else if (approverId.HasValue)
  106. remark = $"审批人: {approverId}";
  107. await _timelineRep.InsertAsync(new AdoS8ExceptionTimeline
  108. {
  109. ExceptionId = exceptionId,
  110. ActionCode = code,
  111. ActionLabel = label,
  112. FromStatus = from,
  113. ToStatus = to,
  114. OperatorId = approverId,
  115. ActionRemark = remark,
  116. CreatedAt = DateTime.Now
  117. });
  118. }
  119. }