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
});
}
}