namespace Admin.NET.Plugin.ApprovalFlow.Service; /// /// 审批任务服务 /// [ApiDescriptionSettings(ApprovalFlowConst.GroupName, Order = 90)] public class FlowTaskService : IDynamicApiController, ITransient { private readonly FlowEngineService _engine; private readonly SqlSugarRepository _taskRep; private readonly SqlSugarRepository _instanceRep; private readonly UserManager _userManager; public FlowTaskService( FlowEngineService engine, SqlSugarRepository taskRep, SqlSugarRepository instanceRep, UserManager userManager) { _engine = engine; _taskRep = taskRep; _instanceRep = instanceRep; _userManager = userManager; } // ── 查询 ── /// /// 我的待办(分页) /// [HttpPost] [ApiDescriptionSettings(Name = "MyPendingPage")] [DisplayName("我的待办")] public async Task> MyPendingPage(TaskPageInput input) { var userId = _userManager.UserId; return await _taskRep.AsQueryable() .InnerJoin((t, i) => t.InstanceId == i.Id) .Where((t, i) => t.AssigneeId == userId && t.Status == FlowTaskStatusEnum.Pending) .WhereIF(!string.IsNullOrWhiteSpace(input.BizType), (t, i) => i.BizType == input.BizType) .OrderByDescending((t, i) => t.CreateTime) .Select((t, i) => new TaskPageOutput { Id = t.Id, InstanceId = t.InstanceId, NodeId = t.NodeId, NodeName = t.NodeName, Status = t.Status, Title = i.Title, BizType = i.BizType, BizId = i.BizId, BizNo = i.BizNo, InitiatorName = i.InitiatorName, StartTime = i.StartTime, CreateTime = t.CreateTime, }) .ToPagedListAsync(input.Page, input.PageSize); } /// /// 我的已办(分页) /// [HttpPost] [ApiDescriptionSettings(Name = "MyDonePage")] [DisplayName("我的已办")] public async Task> MyDonePage(TaskPageInput input) { var userId = _userManager.UserId; return await _taskRep.AsQueryable() .InnerJoin((t, i) => t.InstanceId == i.Id) .Where((t, i) => t.AssigneeId == userId && t.Status != FlowTaskStatusEnum.Pending) .WhereIF(!string.IsNullOrWhiteSpace(input.BizType), (t, i) => i.BizType == input.BizType) .OrderByDescending((t, i) => t.ActionTime) .Select((t, i) => new TaskPageOutput { Id = t.Id, InstanceId = t.InstanceId, NodeId = t.NodeId, NodeName = t.NodeName, Status = t.Status, Comment = t.Comment, ActionTime = t.ActionTime, Title = i.Title, BizType = i.BizType, BizId = i.BizId, BizNo = i.BizNo, InitiatorName = i.InitiatorName, StartTime = i.StartTime, CreateTime = t.CreateTime, }) .ToPagedListAsync(input.Page, input.PageSize); } /// /// 我发起的(分页) /// [HttpPost] [ApiDescriptionSettings(Name = "MyInitiatedPage")] [DisplayName("我发起的")] public async Task> MyInitiatedPage(InstancePageInput input) { var userId = _userManager.UserId; var page = await _instanceRep.AsQueryable() .Where(i => i.InitiatorId == userId) .WhereIF(!string.IsNullOrWhiteSpace(input.BizType), i => i.BizType == input.BizType) .WhereIF(input.Status.HasValue, i => i.Status == input.Status!.Value) .OrderByDescending(i => i.CreateTime) .Select(i => new InstancePageOutput { Id = i.Id, BizType = i.BizType, BizId = i.BizId, BizNo = i.BizNo, Title = i.Title, Status = i.Status, CurrentNodeId = i.CurrentNodeId, StartTime = i.StartTime, EndTime = i.EndTime, InitiatorName = i.InitiatorName, }) .ToPagedListAsync(input.Page, input.PageSize); var runningIds = page.Items.Where(x => x.Status == FlowInstanceStatusEnum.Running).Select(x => x.Id).ToList(); if (runningIds.Count > 0) { var pendingAssignees = await _taskRep.AsQueryable() .Where(t => runningIds.Contains(t.InstanceId) && t.Status == FlowTaskStatusEnum.Pending) .Select(t => new { t.InstanceId, t.AssigneeName }) .ToListAsync(); var grouped = pendingAssignees.GroupBy(x => x.InstanceId) .ToDictionary(g => g.Key, g => string.Join(", ", g.Select(x => x.AssigneeName).Distinct())); foreach (var item in page.Items) { if (grouped.TryGetValue(item.Id, out var names)) item.CurrentAssigneeName = names; } } return page; } /// /// 待办数量 /// [HttpGet] [ApiDescriptionSettings(Name = "MyPendingCount")] [DisplayName("待办数量")] public async Task MyPendingCount() { var userId = _userManager.UserId; return await _taskRep.AsQueryable() .Where(t => t.AssigneeId == userId && t.Status == FlowTaskStatusEnum.Pending) .CountAsync(); } // ── 操作 ── /// /// 同意 /// [HttpPost] [ApiDescriptionSettings(Name = "Approve")] [DisplayName("同意")] public async Task Approve(TaskActionInput input) { await _engine.Approve(input.TaskId, input.Comment); } /// /// 拒绝 /// [HttpPost] [ApiDescriptionSettings(Name = "Reject")] [DisplayName("拒绝")] public async Task Reject(TaskActionInput input) { await _engine.Reject(input.TaskId, input.Comment); } /// /// 转办 /// [HttpPost] [ApiDescriptionSettings(Name = "Transfer")] [DisplayName("转办")] public async Task Transfer(TaskTransferInput input) { await _engine.Transfer(input.TaskId, input.TargetUserId, input.Comment); } /// /// 撤回 /// [HttpPost] [ApiDescriptionSettings(Name = "Withdraw")] [DisplayName("撤回")] public async Task Withdraw(TaskWithdrawInput input) { await _engine.Withdraw(input.InstanceId); } /// /// 退回上一步 /// [HttpPost] [ApiDescriptionSettings(Name = "ReturnToPrev")] [DisplayName("退回上一步")] public async Task ReturnToPrev(TaskActionInput input) { await _engine.ReturnToPrev(input.TaskId, input.Comment); } /// /// 加签 /// [HttpPost] [ApiDescriptionSettings(Name = "AddSign")] [DisplayName("加签")] public async Task AddSign(TaskAddSignInput input) { await _engine.AddSign(input.TaskId, input.TargetUserId, input.Comment); } /// /// 催办 /// [HttpPost] [ApiDescriptionSettings(Name = "Urge")] [DisplayName("催办")] public async Task Urge(TaskUrgeInput input) { await _engine.Urge(input.InstanceId); } }