namespace Admin.NET.Plugin.ApprovalFlow.Service; /// /// 流程实例服务 /// [ApiDescriptionSettings(ApprovalFlowConst.GroupName, Order = 95)] public class FlowInstanceService : IDynamicApiController, ITransient { private readonly FlowEngineService _engine; private readonly SqlSugarRepository _instanceRep; private readonly SqlSugarRepository _taskRep; private readonly SqlSugarRepository _logRep; private readonly SqlSugarRepository _completedNodeRep; public FlowInstanceService( FlowEngineService engine, SqlSugarRepository instanceRep, SqlSugarRepository taskRep, SqlSugarRepository logRep, SqlSugarRepository completedNodeRep) { _engine = engine; _instanceRep = instanceRep; _taskRep = taskRep; _logRep = logRep; _completedNodeRep = completedNodeRep; } /// /// 发起流程 /// [HttpPost] [ApiDescriptionSettings(Name = "Start")] [DisplayName("发起流程")] public async Task Start(StartFlowInput input) { return await _engine.StartFlow(input); } /// /// 查询实例详情 /// [HttpGet] [ApiDescriptionSettings(Name = "Detail")] [DisplayName("流程实例详情")] public async Task GetDetail([FromQuery] long id) { var instance = await _instanceRep.GetByIdAsync(id); if (instance == null) return null; var tasks = await _taskRep.AsQueryable() .Where(t => t.InstanceId == id) .OrderBy(t => t.CreateTime) .ToListAsync(); var completedNodeIds = await _completedNodeRep.AsQueryable() .Where(c => c.InstanceId == id) .Select(c => c.NodeId) .ToListAsync(); var currentNodeIds = tasks .Where(t => t.Status == FlowTaskStatusEnum.Pending) .Select(t => t.NodeId) .Distinct() .ToList(); return new FlowInstanceDetailOutput { Id = instance.Id, FlowId = instance.FlowId, BizType = instance.BizType, BizId = instance.BizId, BizNo = instance.BizNo, Title = instance.Title, InitiatorId = instance.InitiatorId, InitiatorName = instance.InitiatorName, Status = instance.Status, CurrentNodeId = instance.CurrentNodeId, StartTime = instance.StartTime, EndTime = instance.EndTime, FlowJsonSnapshot = instance.FlowJsonSnapshot, Tasks = tasks.Select(t => new FlowTaskOutput { Id = t.Id, NodeId = t.NodeId, NodeName = t.NodeName, AssigneeId = t.AssigneeId, AssigneeName = t.AssigneeName, Status = t.Status, Comment = t.Comment, ActionTime = t.ActionTime, IsDelegate = t.IsDelegate, DelegateForUserId = t.DelegateForUserId, DelegateForUserName = t.DelegateForUserName, }).ToList(), CompletedNodeIds = completedNodeIds, CurrentNodeIds = currentNodeIds, }; } /// /// 根据业务单据查询流程实例 /// [HttpGet] [ApiDescriptionSettings(Name = "GetByBiz")] [DisplayName("按业务查流程")] public async Task GetByBiz([FromQuery] string bizType, [FromQuery] long bizId) { var instance = await _instanceRep.AsQueryable() .Where(i => i.BizType == bizType && i.BizId == bizId) .OrderByDescending(i => i.CreateTime) .FirstAsync(); if (instance == null) return null; return await GetDetail(instance.Id); } /// /// 审批时间线 /// [HttpGet] [ApiDescriptionSettings(Name = "Timeline")] [DisplayName("审批时间线")] public async Task> GetTimeline([FromQuery] long instanceId) { return await _logRep.AsQueryable() .LeftJoin((l, t) => l.TaskId == t.Id) .Where((l, t) => l.InstanceId == instanceId) .OrderBy((l, t) => l.CreateTime) .Select((l, t) => new FlowTimelineItem { Id = l.Id, NodeId = l.NodeId, NodeName = t.NodeName, Action = l.Action, OperatorId = l.OperatorId, OperatorName = l.OperatorName, Comment = l.Comment, CreateTime = l.CreateTime, }) .ToListAsync(); } }