AuditFlow.js 7.4 KB

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