FlowService.Nodes.cs 19 KB

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