using Admin.NET.Plugin.ApprovalFlow; using Admin.NET.Plugin.ApprovalFlow.Service; using Admin.NET.Plugin.AiDOP.Entity.S0.Warehouse; using Admin.NET.Plugin.AiDOP.Entity.S8; namespace Admin.NET.Plugin.AiDOP.Service.S8; /// /// 异常升级审批业务回调 /// BizType = "EXCEPTION_ESCALATION" /// public class ExceptionEscalationBizHandler : IFlowBizHandler, ITransient { public string BizType => "EXCEPTION_ESCALATION"; private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _timelineRep; private readonly SqlSugarRepository _employeeRep; public ExceptionEscalationBizHandler( SqlSugarRepository rep, SqlSugarRepository timelineRep, SqlSugarRepository employeeRep) { _rep = rep; _timelineRep = timelineRep; _employeeRep = employeeRep; } public async Task OnFlowStarted(long bizId, long instanceId) { var e = await _rep.GetByIdAsync(bizId) ?? throw new S8BizException("异常不存在"); e.Status = "ESCALATED"; e.ActiveFlowInstanceId = instanceId; e.ActiveFlowBizType = BizType; e.UpdatedAt = DateTime.Now; await _rep.UpdateAsync(e); await InsertTimelineAsync(e.Id, "ESCALATE_START", "发起升级", null, "ESCALATED", instanceId, null); } public async Task OnFlowCompleted(long bizId, long instanceId, FlowInstanceStatusEnum finalStatus, long? lastApproverId) { var e = await _rep.GetByIdAsync(bizId) ?? throw new S8BizException("异常不存在"); e.ActiveFlowInstanceId = null; e.ActiveFlowBizType = null; e.UpdatedAt = DateTime.Now; if (finalStatus == FlowInstanceStatusEnum.Approved) { e.Status = "ASSIGNED"; // S8-ESCALATION-IDSPACE-1:lastApproverId 是 sysUser.Id 语义;e.AssigneeId 是 employee.RecID 语义。 // 通过 EmployeeMaster.SysUserId 反查映射:命中唯一员工 → 写 employee.RecID; // 找不到绑定员工 → 保留原 AssigneeId 不变(不静默写 sysUserId 污染业务字段),并通过 timeline 备注暴露。 string? assigneeNote = null; if (lastApproverId.HasValue) { var emp = await _employeeRep.GetFirstAsync(x => x.SysUserId == lastApproverId.Value); if (emp != null) { e.AssigneeId = emp.Id; } else { assigneeNote = $"审批人 sysUserId={lastApproverId.Value} 未绑定员工主数据,AssigneeId 保持原值"; } } else { assigneeNote = "未提供审批人信息,AssigneeId 保持原值"; } await _rep.UpdateAsync(e); await InsertTimelineAsync(e.Id, "ESCALATE_APPROVED", assigneeNote == null ? "升级已确认" : $"升级已确认({assigneeNote})", "ESCALATED", "ASSIGNED", instanceId, lastApproverId); } else if (finalStatus == FlowInstanceStatusEnum.Cancelled) { e.Status = "IN_PROGRESS"; await _rep.UpdateAsync(e); await InsertTimelineAsync(e.Id, "ESCALATE_CANCELLED", "发起人撤回升级申请", "ESCALATED", "IN_PROGRESS", instanceId, lastApproverId); } else { e.Status = "IN_PROGRESS"; await _rep.UpdateAsync(e); await InsertTimelineAsync(e.Id, "ESCALATE_REJECTED", "升级被驳回", "ESCALATED", "IN_PROGRESS", instanceId, lastApproverId); } } public async Task> GetBizData(long bizId) { var e = await _rep.GetByIdAsync(bizId); if (e == null) return new Dictionary(); return new Dictionary { ["severity"] = e.Severity ?? string.Empty, ["sceneCode"] = e.SceneCode ?? string.Empty, ["priorityLevel"] = e.PriorityLevel ?? string.Empty, ["factoryCode"] = e.FactoryId.ToString(), }; } private async Task InsertTimelineAsync(long exceptionId, string code, string label, string? from, string? to, long? instanceId, long? approverId) { string? remark = null; if (instanceId.HasValue && approverId.HasValue) remark = $"审批实例ID: {instanceId},审批人: {approverId}"; else if (instanceId.HasValue) remark = $"审批实例ID: {instanceId}"; else if (approverId.HasValue) remark = $"审批人: {approverId}"; await _timelineRep.InsertAsync(new AdoS8ExceptionTimeline { ExceptionId = exceptionId, ActionCode = code, ActionLabel = label, FromStatus = from, ToStatus = to, OperatorId = approverId, ActionRemark = remark, CreatedAt = DateTime.Now }); } }