FlowTaskService.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. namespace Admin.NET.Plugin.ApprovalFlow.Service;
  2. /// <summary>
  3. /// 审批任务服务
  4. /// </summary>
  5. [ApiDescriptionSettings(ApprovalFlowConst.GroupName, Order = 90)]
  6. public class FlowTaskService : IDynamicApiController, ITransient
  7. {
  8. private readonly FlowEngineService _engine;
  9. private readonly SqlSugarRepository<ApprovalFlowTask> _taskRep;
  10. private readonly SqlSugarRepository<ApprovalFlowInstance> _instanceRep;
  11. private readonly UserManager _userManager;
  12. public FlowTaskService(
  13. FlowEngineService engine,
  14. SqlSugarRepository<ApprovalFlowTask> taskRep,
  15. SqlSugarRepository<ApprovalFlowInstance> instanceRep,
  16. UserManager userManager)
  17. {
  18. _engine = engine;
  19. _taskRep = taskRep;
  20. _instanceRep = instanceRep;
  21. _userManager = userManager;
  22. }
  23. // ── 查询 ──
  24. /// <summary>
  25. /// 我的待办(分页)
  26. /// </summary>
  27. [HttpPost]
  28. [ApiDescriptionSettings(Name = "MyPendingPage")]
  29. [DisplayName("我的待办")]
  30. public async Task<SqlSugarPagedList<TaskPageOutput>> MyPendingPage(TaskPageInput input)
  31. {
  32. var userId = _userManager.UserId;
  33. return await _taskRep.AsQueryable()
  34. .InnerJoin<ApprovalFlowInstance>((t, i) => t.InstanceId == i.Id)
  35. .Where((t, i) => t.AssigneeId == userId && t.Status == FlowTaskStatusEnum.Pending)
  36. .WhereIF(!string.IsNullOrWhiteSpace(input.BizType), (t, i) => i.BizType == input.BizType)
  37. .OrderByDescending((t, i) => t.CreateTime)
  38. .Select((t, i) => new TaskPageOutput
  39. {
  40. Id = t.Id,
  41. InstanceId = t.InstanceId,
  42. NodeId = t.NodeId,
  43. NodeName = t.NodeName,
  44. Status = t.Status,
  45. Title = i.Title,
  46. BizType = i.BizType,
  47. BizId = i.BizId,
  48. BizNo = i.BizNo,
  49. InitiatorName = i.InitiatorName,
  50. StartTime = i.StartTime,
  51. CreateTime = t.CreateTime,
  52. })
  53. .ToPagedListAsync(input.Page, input.PageSize);
  54. }
  55. /// <summary>
  56. /// 我的已办(分页)
  57. /// </summary>
  58. [HttpPost]
  59. [ApiDescriptionSettings(Name = "MyDonePage")]
  60. [DisplayName("我的已办")]
  61. public async Task<SqlSugarPagedList<TaskPageOutput>> MyDonePage(TaskPageInput input)
  62. {
  63. var userId = _userManager.UserId;
  64. return await _taskRep.AsQueryable()
  65. .InnerJoin<ApprovalFlowInstance>((t, i) => t.InstanceId == i.Id)
  66. .Where((t, i) => t.AssigneeId == userId && t.Status != FlowTaskStatusEnum.Pending)
  67. .WhereIF(!string.IsNullOrWhiteSpace(input.BizType), (t, i) => i.BizType == input.BizType)
  68. .OrderByDescending((t, i) => t.ActionTime)
  69. .Select((t, i) => new TaskPageOutput
  70. {
  71. Id = t.Id,
  72. InstanceId = t.InstanceId,
  73. NodeId = t.NodeId,
  74. NodeName = t.NodeName,
  75. Status = t.Status,
  76. Comment = t.Comment,
  77. ActionTime = t.ActionTime,
  78. Title = i.Title,
  79. BizType = i.BizType,
  80. BizId = i.BizId,
  81. BizNo = i.BizNo,
  82. InitiatorName = i.InitiatorName,
  83. StartTime = i.StartTime,
  84. CreateTime = t.CreateTime,
  85. })
  86. .ToPagedListAsync(input.Page, input.PageSize);
  87. }
  88. /// <summary>
  89. /// 我发起的(分页)
  90. /// </summary>
  91. [HttpPost]
  92. [ApiDescriptionSettings(Name = "MyInitiatedPage")]
  93. [DisplayName("我发起的")]
  94. public async Task<SqlSugarPagedList<InstancePageOutput>> MyInitiatedPage(InstancePageInput input)
  95. {
  96. var userId = _userManager.UserId;
  97. var page = await _instanceRep.AsQueryable()
  98. .Where(i => i.InitiatorId == userId)
  99. .WhereIF(!string.IsNullOrWhiteSpace(input.BizType), i => i.BizType == input.BizType)
  100. .WhereIF(input.Status.HasValue, i => i.Status == input.Status!.Value)
  101. .OrderByDescending(i => i.CreateTime)
  102. .Select(i => new InstancePageOutput
  103. {
  104. Id = i.Id,
  105. BizType = i.BizType,
  106. BizId = i.BizId,
  107. BizNo = i.BizNo,
  108. Title = i.Title,
  109. Status = i.Status,
  110. CurrentNodeId = i.CurrentNodeId,
  111. StartTime = i.StartTime,
  112. EndTime = i.EndTime,
  113. InitiatorName = i.InitiatorName,
  114. })
  115. .ToPagedListAsync(input.Page, input.PageSize);
  116. var runningIds = page.Items.Where(x => x.Status == FlowInstanceStatusEnum.Running).Select(x => x.Id).ToList();
  117. if (runningIds.Count > 0)
  118. {
  119. var pendingAssignees = await _taskRep.AsQueryable()
  120. .Where(t => runningIds.Contains(t.InstanceId) && t.Status == FlowTaskStatusEnum.Pending)
  121. .Select(t => new { t.InstanceId, t.AssigneeName })
  122. .ToListAsync();
  123. var grouped = pendingAssignees.GroupBy(x => x.InstanceId)
  124. .ToDictionary(g => g.Key, g => string.Join(", ", g.Select(x => x.AssigneeName).Distinct()));
  125. foreach (var item in page.Items)
  126. {
  127. if (grouped.TryGetValue(item.Id, out var names))
  128. item.CurrentAssigneeName = names;
  129. }
  130. }
  131. return page;
  132. }
  133. /// <summary>
  134. /// 待办数量
  135. /// </summary>
  136. [HttpGet]
  137. [ApiDescriptionSettings(Name = "MyPendingCount")]
  138. [DisplayName("待办数量")]
  139. public async Task<int> MyPendingCount()
  140. {
  141. var userId = _userManager.UserId;
  142. return await _taskRep.AsQueryable()
  143. .Where(t => t.AssigneeId == userId && t.Status == FlowTaskStatusEnum.Pending)
  144. .CountAsync();
  145. }
  146. // ── 操作 ──
  147. /// <summary>
  148. /// 同意
  149. /// </summary>
  150. [HttpPost]
  151. [ApiDescriptionSettings(Name = "Approve")]
  152. [DisplayName("同意")]
  153. public async Task Approve(TaskActionInput input)
  154. {
  155. await _engine.Approve(input.TaskId, input.Comment);
  156. }
  157. /// <summary>
  158. /// 拒绝
  159. /// </summary>
  160. [HttpPost]
  161. [ApiDescriptionSettings(Name = "Reject")]
  162. [DisplayName("拒绝")]
  163. public async Task Reject(TaskActionInput input)
  164. {
  165. await _engine.Reject(input.TaskId, input.Comment);
  166. }
  167. /// <summary>
  168. /// 转办
  169. /// </summary>
  170. [HttpPost]
  171. [ApiDescriptionSettings(Name = "Transfer")]
  172. [DisplayName("转办")]
  173. public async Task Transfer(TaskTransferInput input)
  174. {
  175. await _engine.Transfer(input.TaskId, input.TargetUserId, input.Comment);
  176. }
  177. /// <summary>
  178. /// 撤回
  179. /// </summary>
  180. [HttpPost]
  181. [ApiDescriptionSettings(Name = "Withdraw")]
  182. [DisplayName("撤回")]
  183. public async Task Withdraw(TaskWithdrawInput input)
  184. {
  185. await _engine.Withdraw(input.InstanceId);
  186. }
  187. /// <summary>
  188. /// 退回上一步
  189. /// </summary>
  190. [HttpPost]
  191. [ApiDescriptionSettings(Name = "ReturnToPrev")]
  192. [DisplayName("退回上一步")]
  193. public async Task ReturnToPrev(TaskActionInput input)
  194. {
  195. await _engine.ReturnToPrev(input.TaskId, input.Comment);
  196. }
  197. /// <summary>
  198. /// 加签
  199. /// </summary>
  200. [HttpPost]
  201. [ApiDescriptionSettings(Name = "AddSign")]
  202. [DisplayName("加签")]
  203. public async Task AddSign(TaskAddSignInput input)
  204. {
  205. await _engine.AddSign(input.TaskId, input.TargetUserId, input.Comment);
  206. }
  207. /// <summary>
  208. /// 催办
  209. /// </summary>
  210. [HttpPost]
  211. [ApiDescriptionSettings(Name = "Urge")]
  212. [DisplayName("催办")]
  213. public async Task Urge(TaskUrgeInput input)
  214. {
  215. await _engine.Urge(input.InstanceId);
  216. }
  217. }