FlowService.Nodes.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4. using GxPress.Common.Tools;
  5. using GxPress.Entity.WorkFlow;
  6. using GxPress.Entity.WorkFlowDto;
  7. using GxPress.Entity.WorkProcessDto;
  8. using GxPress.EnumConst;
  9. namespace GxPress.Service.Implement
  10. {
  11. public partial class FlowService
  12. {
  13. public async Task<List<ProcessNodeDto>> GetNodesAsync(FlowDto flow, List<ProcessNodeDto> nodes)
  14. {
  15. var nodeList = new List<ProcessNodeDto>();
  16. //var nodes = await _processService.GetNodesAsync(flow.ProcessId, 0);
  17. //var fields = await _processFieldRepository.GetListAsync(flow.ProcessId);
  18. foreach (var processNodeDto in nodes)
  19. {
  20. if (processNodeDto.Type == nameof(ProcessNodeTypeConst.Switch))
  21. {
  22. var theCase = GetCase(processNodeDto.Children, flow);
  23. nodeList.AddRange(await GetNodesAsync(flow, theCase.Children));
  24. }
  25. else if (processNodeDto.Type == nameof(ProcessNodeTypeConst.Start) ||
  26. processNodeDto.Type == nameof(ProcessNodeTypeConst.Approver) ||
  27. processNodeDto.Type == nameof(ProcessNodeTypeConst.End))
  28. {
  29. nodeList.Add(processNodeDto);
  30. }
  31. }
  32. return nodeList;
  33. }
  34. private ProcessNodeDto GetCase(List<ProcessNodeDto> cases, FlowDto flow)
  35. {
  36. cases = cases.OrderBy(x => x.CaseLevel).ToList();
  37. var rightNode = cases.LastOrDefault();
  38. foreach (var caseNode in cases)
  39. {
  40. var isSuccess = false;
  41. foreach (var condition in caseNode.Conditions)
  42. {
  43. var field = flow.Fields?.FirstOrDefault(x => x.Id == condition.FieldId);
  44. if (field != null)
  45. {
  46. if (field.Type == nameof(FieldTypeConst.Number) ||
  47. field.Type == nameof(FieldTypeConst.Currency))
  48. {
  49. var value = StringUtils.ToInt(field.Value);
  50. if (condition.Operator == nameof(OperatorConst.Equals))
  51. {
  52. if (value == condition.IntValue)
  53. {
  54. isSuccess = true;
  55. break;
  56. }
  57. }
  58. else if (condition.Operator == nameof(OperatorConst.NotEquals))
  59. {
  60. if (value != condition.IntValue)
  61. {
  62. isSuccess = true;
  63. break;
  64. }
  65. }
  66. else if (condition.Operator == nameof(OperatorConst.GreatThan))
  67. {
  68. if (value > condition.IntValue)
  69. {
  70. isSuccess = true;
  71. break;
  72. }
  73. }
  74. else if (condition.Operator == nameof(OperatorConst.LessThan))
  75. {
  76. if (value < condition.IntValue)
  77. {
  78. isSuccess = true;
  79. break;
  80. }
  81. }
  82. }
  83. else if (field.Type == nameof(FieldTypeConst.Radio))
  84. {
  85. var value = field.Value;
  86. if (condition.Operator == nameof(OperatorConst.In))
  87. {
  88. if (condition.StringValues.Contains(value))
  89. {
  90. isSuccess = true;
  91. break;
  92. }
  93. }
  94. else if (condition.Operator == nameof(OperatorConst.NotIn))
  95. {
  96. if (!condition.StringValues.Contains(value))
  97. {
  98. isSuccess = true;
  99. break;
  100. }
  101. }
  102. }
  103. else if (field.Type == nameof(FieldTypeConst.Text))
  104. {
  105. var value = field.Value;
  106. if (condition.Operator == nameof(OperatorConst.Equals))
  107. {
  108. if (condition.StringValue == value)
  109. {
  110. isSuccess = true;
  111. break;
  112. }
  113. }
  114. else if (condition.Operator == nameof(OperatorConst.NotEquals))
  115. {
  116. if (condition.StringValue != value)
  117. {
  118. isSuccess = true;
  119. break;
  120. }
  121. }
  122. }
  123. }
  124. }
  125. if (isSuccess)
  126. {
  127. rightNode = caseNode;
  128. break;
  129. }
  130. }
  131. return rightNode;
  132. }
  133. /// <summary>
  134. /// 获取用户ID
  135. /// </summary>
  136. /// <param name="node"></param>
  137. /// <returns></returns>
  138. public async Task<List<int>> GetListUserAsync(ProcessNodeDto node)
  139. {
  140. if (node.Type == nameof(ProcessNodeTypeConst.Start) || node.Type == nameof(ProcessNodeTypeConst.End))
  141. {
  142. var ccList = await _ruleCarbonCopyRepository.GetListAsync(node.Id);
  143. var userIdList = new List<int>();
  144. foreach (var ruleCarbonCopy in ccList)
  145. {
  146. userIdList.AddRange(await GetUserIdListAsync(ruleCarbonCopy));
  147. }
  148. return userIdList;
  149. }
  150. else if (node.Type == nameof(ProcessNodeTypeConst.Approver))
  151. {
  152. var acList = await _ruleApproverCheckRepository.GetListAsync(node.Id);
  153. var userIdList = new List<int>();
  154. foreach (var ruleApproverCheck in acList)
  155. {
  156. userIdList.AddRange(await GetUserIdListAsync(ruleApproverCheck));
  157. }
  158. return userIdList;
  159. }
  160. return new List<int>();
  161. }
  162. /// <summary>
  163. /// 工作流程条件判断
  164. /// </summary>
  165. /// <param name="flow"></param>
  166. /// <returns></returns>
  167. public async Task NodeExecuteSwitchAsync(FlowDto flow, ProcessNodeDto processNode)
  168. {
  169. //查询是否有条件 Switch
  170. var processNodes = await _processNodeRepository.GetAllAsync(flow.ProcessId);
  171. //查询Case
  172. var caseList = processNodes.Where(n => n.ParentId == processNode.Id).ToList();
  173. var success = false;
  174. foreach (var caseValue in caseList)
  175. {
  176. if (success)
  177. break;
  178. //查询Approver
  179. var approvers = processNodes.Where(n => n.ParentId == caseValue.Id);
  180. foreach (var node in approvers)
  181. {
  182. //查询是否有条件
  183. if (node.ParentId > 0)
  184. {
  185. var ruleConditions = await _ruleConditionRepository.GetListAsync(node.ParentId);
  186. if (ruleConditions.Count() > 0)
  187. success = false;
  188. else
  189. success = true;
  190. foreach (var item in ruleConditions)
  191. {
  192. //判断是否等于
  193. if (item.Operator.Equals("Equals"))
  194. {
  195. foreach (var field in flow.Fields)
  196. {
  197. if (field.Id == item.FieldId)
  198. if (field.Value.Equals(item.IntValue))
  199. success = true;
  200. }
  201. }
  202. if (item.Operator.Equals("In"))
  203. {
  204. foreach (var field in flow.Fields)
  205. {
  206. if (field.Id == item.FieldId)
  207. if (field.Value.Equals(item.StringValue))
  208. success = true;
  209. }
  210. }
  211. if (item.Operator.Equals("NotIn"))
  212. {
  213. foreach (var field in flow.Fields)
  214. {
  215. if (field.Id == item.FieldId)
  216. if (field.Value.Equals(item.StringValue))
  217. {
  218. success = true;
  219. break;
  220. }
  221. else
  222. break;
  223. }
  224. }
  225. }
  226. }
  227. if (!success)
  228. break;
  229. }
  230. //
  231. if (success)
  232. {
  233. approvers = processNodes.Where(n => n.ParentId == caseValue.Id);
  234. foreach (var node in approvers)
  235. {
  236. //获取抄送人
  237. var ccList = await _ruleCarbonCopyRepository.GetListAsync(node.Id);
  238. var userIdList = new List<int>();
  239. foreach (var ruleCarbonCopy in ccList)
  240. {
  241. userIdList.AddRange(await GetUserIdListAsync(ruleCarbonCopy));
  242. }
  243. await TaskCarbonCopyAsync(userIdList.Distinct(), flow);
  244. var acList = await _ruleApproverCheckRepository.GetListAsync(node.Id);
  245. //获取审核人 是否是或签
  246. if (node.ApprovalType == "Or")
  247. {
  248. flow.IsCaseOr = true;
  249. flow.ParentId = node.Id;
  250. }
  251. //审核人
  252. acList = await _ruleApproverCheckRepository.GetListAsync(node.Id);
  253. userIdList = new List<int>();
  254. foreach (var ruleApproverCheck in acList)
  255. {
  256. userIdList.AddRange(await GetUserIdListAsync(ruleApproverCheck));
  257. }
  258. await TaskApproverCheckAsync(userIdList.Distinct(), flow);
  259. }
  260. break;
  261. }
  262. }
  263. }
  264. public async Task NodeExecuteAsync(FlowDto flow, ProcessNodeDto node)
  265. {
  266. //_ruleCarbonCopyRepository = ruleCarbonCopyRepository;
  267. //_ruleApproverCheckRepository = ruleApproverCheckRepository;
  268. //_ruleConditionRepository = ruleConditionRepository;
  269. if (node.Type == nameof(ProcessNodeTypeConst.Start) || node.Type == nameof(ProcessNodeTypeConst.End))
  270. {
  271. var ccList = await _ruleCarbonCopyRepository.GetListAsync(node.Id);
  272. var userIdList = new List<int>();
  273. foreach (var ruleCarbonCopy in ccList)
  274. {
  275. userIdList.AddRange(await GetUserIdListAsync(ruleCarbonCopy));
  276. }
  277. await TaskCarbonCopyAsync(userIdList.Distinct(), flow);
  278. }
  279. else if (node.Type == nameof(ProcessNodeTypeConst.Approver))
  280. {
  281. var acList = await _ruleApproverCheckRepository.GetListAsync(node.Id);
  282. //获取审核人 是否是或签
  283. if (node.ApprovalType == "Or")
  284. {
  285. flow.IsCaseOr = true;
  286. flow.ParentId = node.Id;
  287. }
  288. else
  289. {
  290. flow.IsCaseOr = false;
  291. flow.ParentId = 0;
  292. }
  293. var userIdList = new List<int>();
  294. foreach (var ruleApproverCheck in acList)
  295. {
  296. userIdList.AddRange(await GetUserIdListAsync(ruleApproverCheck));
  297. }
  298. await TaskApproverCheckAsync(userIdList.Distinct(), flow);
  299. }
  300. }
  301. /// <summary>
  302. /// 抄送人
  303. /// </summary>
  304. /// <param name="userIdList"></param>
  305. /// <param name="flow"></param>
  306. /// <returns></returns>
  307. private async Task TaskCarbonCopyAsync(IEnumerable<int> userIdList, FlowDto flow)
  308. {
  309. foreach (var userId in userIdList)
  310. {
  311. var todo = new FlowTodo
  312. {
  313. ProcessId = flow.ProcessId,
  314. FlowId = flow.Id,
  315. UserId = userId,
  316. Type = nameof(TodoTypeConst.CarbonCopy),
  317. IsDone = false,
  318. IsOperate = false,
  319. };
  320. await _flowTodoRepository.InsertAsync(todo);
  321. }
  322. }
  323. /// <summary>
  324. /// 审核人
  325. /// </summary>
  326. /// <param name="userIdList"></param>
  327. /// <param name="flow"></param>
  328. /// <returns></returns>
  329. private async Task TaskApproverCheckAsync(IEnumerable<int> userIdList, FlowDto flow)
  330. {
  331. foreach (var userId in userIdList)
  332. {
  333. var todo = new FlowTodo
  334. {
  335. ProcessId = flow.ProcessId,
  336. FlowId = flow.Id,
  337. UserId = userId,
  338. Type = nameof(TodoTypeConst.ApproverCheck),
  339. IsDone = false,
  340. IsOperate = false,
  341. IsCaseOr = flow.IsCaseOr,
  342. ParentId = flow.ParentId
  343. };
  344. await _flowTodoRepository.InsertAsync(todo);
  345. }
  346. }
  347. private async Task<List<int>> GetUserIdListAsync(List<ApproverCheck> approverChecks)
  348. {
  349. var allUserIdList = new List<int>();
  350. foreach (var multipleUser in approverChecks)
  351. {
  352. var userIdList = await GetUserIdListAsync(multipleUser);
  353. foreach (var userId in userIdList)
  354. {
  355. if (!allUserIdList.Contains(userId))
  356. {
  357. allUserIdList.Add(userId);
  358. }
  359. }
  360. }
  361. return allUserIdList;
  362. }
  363. private async Task<List<int>> GetUserIdListAsync(IMultipleUser multipleUser)
  364. {
  365. if (multipleUser != null)
  366. {
  367. if (multipleUser.UserId > 0)
  368. {
  369. return new List<int> { multipleUser.UserId };
  370. }
  371. if (multipleUser.RoleId > 0)
  372. {
  373. return (await _userRepository.GetUserIdListByRoleIdAsync(multipleUser.RoleId)).ToList();
  374. }
  375. if (multipleUser.DepartmentId > 0)
  376. {
  377. return (await _userRepository.GetUserIdListByDepartmentIdAsync(multipleUser.DepartmentId)).ToList();
  378. }
  379. }
  380. return new List<int>();
  381. }
  382. }
  383. }