AuditFlow.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. import React, { useMemo, useEffect, useState, useRef } from 'react';
  2. import { Steps, Popover, Alert, Button, Spin } from 'antd';
  3. import styles from './Index.less';
  4. import { queryDDProcessesForecast } from '@/services/boom';
  5. import { connect } from 'dva';
  6. const { Step } = Steps;
  7. function AuditFlow(props) {
  8. const {
  9. processCode,
  10. deptId,
  11. userId,
  12. formComponentValues,
  13. // activityId,
  14. direction,
  15. status,
  16. tasks,
  17. userList,
  18. cc_userids = [],
  19. canShowAudit = false,
  20. onApprove,
  21. } = props;
  22. const [flow, setFlow] = useState({ workflowActivityRules: [] });
  23. const [loading, setLoading] = useState(false);
  24. const timerRef = useRef({
  25. id: '',
  26. status: false,
  27. });
  28. const current = useMemo(() => {
  29. if (!tasks || tasks.length == 0) {
  30. return false;
  31. } else {
  32. // 查询最后一个task的activityId
  33. let current = 0;
  34. const activityId = tasks[tasks.length - 1].activity_id;
  35. flow.workflowActivityRules.forEach((item, index) => {
  36. let task = tasks.find(task => task.activity_id == item.activityId);
  37. if (task) {
  38. if (task.task_status == 'COMPLETED') {
  39. // 完成时节点为下一级
  40. current = index + 1;
  41. } else {
  42. // 未完成则为当前节点
  43. current = index;
  44. }
  45. }
  46. });
  47. return current;
  48. }
  49. }, [tasks, flow]);
  50. const showAduit = useMemo(() => {
  51. if (!canShowAudit) return false;
  52. //当前处理中的审批人和登录人是一个人显示审批通过和拒绝
  53. if (!tasks || tasks.length == 0) {
  54. return false;
  55. } else {
  56. // 查询处于RUNNING的task activityId
  57. const runningTask = tasks.filter(item => item.task_status == 'RUNNING');
  58. // const task = tasks.find(task => task.activity_id == activityId);
  59. if (runningTask.length == 0) return false;
  60. // if (task.task_status == 'RUNNING' && task.userid == userId) return true;
  61. return runningTask.find(task => task.userid == userId);
  62. }
  63. }, [tasks, userId]);
  64. const getDesc = item => {
  65. const { activityId } = item;
  66. if (!tasks || tasks.length == 0) return '';
  67. if (item.activityName == '抄送人') {
  68. let names = cc_userids
  69. .map(userId => {
  70. let user = userList.find(u => u.DingUserId == userId);
  71. return user?.CName;
  72. })
  73. .filter(item => item);
  74. return names.join(',');
  75. } else {
  76. const task = tasks.find(task => task.activity_id == activityId);
  77. if (!task) return;
  78. const user = userList.find(user => task.userid == user.DingUserId);
  79. let result = null;
  80. if (task.task_result !== 'NONE') {
  81. result = (
  82. <>
  83. <br />
  84. 审批结果: {TASK_RESULT[task.task_result]}
  85. <br />
  86. </>
  87. );
  88. }
  89. return (
  90. <>
  91. {user?.CName || '未知操作人'}({TASK_STATUS[task.task_status]}){result}
  92. </>
  93. );
  94. }
  95. };
  96. const renderAlert = () => {
  97. // const audit_comment = history.list[0]?.audit_comment;
  98. let item = '';
  99. switch (status) {
  100. case -1:
  101. item = <Alert message="已失效" type="error" />;
  102. break;
  103. case 0:
  104. if (!flow.list || flow.list.FlowNodes?.length == 0) return;
  105. item = <Alert message="审批拒绝" type="error" />;
  106. break;
  107. case 1:
  108. item = <Alert message="等待审核中" type="info" />;
  109. break;
  110. case 2:
  111. item = <Alert message={`审批被拒绝`} type="error" />;
  112. break;
  113. case 3:
  114. item = <Alert message="审批通过" type="success" />;
  115. break;
  116. }
  117. return <div style={{ margin: '20px auto' }}>{item}</div>;
  118. };
  119. const customDot = (dot, { status, index }) => {
  120. let item = flow.workflowActivityRules[index];
  121. return (
  122. <Popover
  123. content={
  124. <div>
  125. 节点类型:{ACTIVITY_TYPE[item.activityType]}
  126. <br />
  127. 操作人类型:{ACTOR_TYPE[item.workflowActor?.actorType]}
  128. <br />
  129. 审批类型:{APPROVAL_TYPE[item.workflowActor?.approvalType]}
  130. <br />
  131. 审批方式:{APPROVAL_METHOD[item.workflowActor?.approvalMethod]}
  132. </div>
  133. }
  134. >
  135. {dot}
  136. </Popover>
  137. );
  138. };
  139. const getDetail = async () => {
  140. if (!deptId || !userId) {
  141. console.log('depId或userId不存在!');
  142. return;
  143. }
  144. if (!timerRef.current.status) {
  145. // 上锁
  146. timerRef.current.status = true;
  147. setLoading(true);
  148. try {
  149. let flow = await queryDDProcessesForecast({
  150. processCode,
  151. deptId,
  152. userId,
  153. formComponentValues,
  154. });
  155. setFlow(flow);
  156. console.log(flow);
  157. } catch (error) {}
  158. setLoading(false);
  159. setTimeout(() => {
  160. // 延时解锁
  161. timerRef.current.status = false;
  162. }, 2000);
  163. } else {
  164. clearTimeout(timerRef.current.id);
  165. // 延迟调用
  166. timerRef.current.id = setTimeout(() => {
  167. getDetail();
  168. }, 2000);
  169. }
  170. };
  171. useEffect(() => {
  172. if (!processCode || !formComponentValues) return;
  173. getDetail();
  174. }, [processCode, formComponentValues]);
  175. return (
  176. <Spin spinning={loading}>
  177. <div className={styles.top}>
  178. <Steps current={current} progressDot={customDot} direction={direction}>
  179. {flow.workflowActivityRules.map(item => (
  180. <Step key={item.activityId} title={item?.activityName} description={getDesc(item)} />
  181. ))}
  182. {/* <Step key={item.activityId} title={item?.activityName} description={renderDesc(item)} /> */}
  183. </Steps>
  184. {showAduit && (
  185. <div className={styles.btns} style={{ marginLeft: 80 }}>
  186. <Button type="primary" onClick={() => onApprove(true, tasks[current].taskid)}>
  187. 审批通过
  188. </Button>
  189. <Button onClick={() => onApprove(false, tasks[current].taskid)} danger>
  190. 审批拒绝
  191. </Button>
  192. </div>
  193. )}
  194. </div>
  195. {status !== undefined && renderAlert()}
  196. </Spin>
  197. );
  198. }
  199. const ACTOR_TYPE = {
  200. approver: '审批人',
  201. notifier: '抄送人',
  202. audit: '办理人',
  203. };
  204. const APPROVAL_TYPE = {
  205. MANUAL: '人工审批',
  206. AUTO_AGREE: '自动通过',
  207. AUTO_REFUSE: '自动拒绝',
  208. };
  209. const APPROVAL_METHOD = {
  210. ONE_BY_ONE: '依次审批',
  211. AND: '会签审批',
  212. OR: '或签审批',
  213. };
  214. const ACTIVITY_TYPE = {
  215. target_select: '自选审批人',
  216. target_approval: '指定审批人',
  217. };
  218. const OPERATION_RESULT = {
  219. AGREE: '同意',
  220. REFUSE: '拒绝',
  221. NONE: '未处理',
  222. };
  223. const OPERATION_TYPE = {
  224. EXECUTE_TASK_NORMAL: '正常执行任务',
  225. EXECUTE_TASK_AGENT: '代理人执行任务',
  226. APPEND_TASK_BEFORE: '前加签任务',
  227. APPEND_TASK_AFTER: '后加签任务',
  228. REDIRECT_TASK: '转交任务',
  229. START_PROCESS_INSTANCE: '发起流程实例',
  230. TERMINATE_PROCESS_INSTANCE: '终止(撤销)流程实例',
  231. FINISH_PROCESS_INSTANCE: '结束流程实例',
  232. ADD_REMARK: '添加评论',
  233. REDIRECT_PROCESS: '审批退回',
  234. PROCESS_CC: '抄送',
  235. };
  236. const TASK_STATUS = {
  237. NEW: '未启动',
  238. RUNNING: '处理中',
  239. PAUSED: '暂停',
  240. CANCELED: '取消',
  241. COMPLETED: '完成',
  242. TERMINATED: '终止',
  243. };
  244. const TASK_RESULT = {
  245. AGREE: '同意',
  246. REFUSE: '拒绝',
  247. REDIRECTED: '转交',
  248. NONE: '未处理',
  249. };
  250. export default connect(({ user }) => ({
  251. userList: user.list,
  252. }))(AuditFlow);