ProcessInstanceSimpleViewer.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <template>
  2. <div v-loading="loading" class="process-viewer-container">
  3. <SimpleProcessViewer
  4. :flow-node="simpleModel"
  5. :tasks="tasks"
  6. :process-instance="processInstance"
  7. class="process-viewer"
  8. />
  9. </div>
  10. </template>
  11. <script lang="ts" setup>
  12. import { propTypes } from '@/utils/propTypes'
  13. import { TaskStatusEnum } from '@/api/bpm/task'
  14. import { SimpleFlowNode, NodeType } from '@/components/SimpleProcessDesignerV2/src/consts'
  15. import { SimpleProcessViewer } from '@/components/SimpleProcessDesignerV2/src/'
  16. defineOptions({ name: 'BpmProcessInstanceSimpleViewer' })
  17. const props = defineProps({
  18. loading: propTypes.bool.def(false), // 是否加载中
  19. modelView: propTypes.object,
  20. simpleJson: propTypes.string // Simple 模型结构数据 (json 格式)
  21. })
  22. const simpleModel = ref()
  23. // 用户任务
  24. const tasks = ref([])
  25. // 流程实例
  26. const processInstance = ref()
  27. /** 监控模型视图 包括任务列表、进行中的活动节点编号等 */
  28. watch(
  29. () => props.modelView,
  30. async (newModelView) => {
  31. if (newModelView) {
  32. tasks.value = newModelView.tasks
  33. processInstance.value = newModelView.processInstance
  34. // 已经拒绝的活动节点编号集合,只包括 UserTask
  35. const rejectedTaskActivityIds: string[] = newModelView.rejectedTaskActivityIds
  36. // 进行中的活动节点编号集合, 只包括 UserTask
  37. const unfinishedTaskActivityIds: string[] = newModelView.unfinishedTaskActivityIds
  38. // 已经完成的活动节点编号集合, 包括 UserTask、Gateway 等
  39. const finishedActivityIds: string[] = newModelView.finishedTaskActivityIds
  40. // 已经完成的连线节点编号集合,只包括 SequenceFlow
  41. const finishedSequenceFlowActivityIds: string[] = newModelView.finishedSequenceFlowActivityIds
  42. setSimpleModelNodeTaskStatus(
  43. newModelView.simpleModel,
  44. newModelView.processInstance.status,
  45. rejectedTaskActivityIds,
  46. unfinishedTaskActivityIds,
  47. finishedActivityIds,
  48. finishedSequenceFlowActivityIds
  49. )
  50. simpleModel.value = newModelView.simpleModel
  51. }
  52. }
  53. )
  54. /** 监控模型结构数据 */
  55. watch(
  56. () => props.simpleJson,
  57. async (value) => {
  58. if (value) {
  59. simpleModel.value = JSON.parse(value)
  60. }
  61. }
  62. )
  63. const setSimpleModelNodeTaskStatus = (
  64. simpleModel: SimpleFlowNode | undefined,
  65. processStatus: number,
  66. rejectedTaskActivityIds: string[],
  67. unfinishedTaskActivityIds: string[],
  68. finishedActivityIds: string[],
  69. finishedSequenceFlowActivityIds: string[]
  70. ) => {
  71. if (!simpleModel) {
  72. return
  73. }
  74. // 结束节点
  75. if (simpleModel.type === NodeType.END_EVENT_NODE) {
  76. if (finishedActivityIds.includes(simpleModel.id)) {
  77. simpleModel.activityStatus = processStatus
  78. } else {
  79. simpleModel.activityStatus = TaskStatusEnum.NOT_START
  80. }
  81. return
  82. }
  83. // 审批节点
  84. if (
  85. simpleModel.type === NodeType.START_USER_NODE ||
  86. simpleModel.type === NodeType.USER_TASK_NODE
  87. ) {
  88. simpleModel.activityStatus = TaskStatusEnum.NOT_START
  89. if (rejectedTaskActivityIds.includes(simpleModel.id)) {
  90. simpleModel.activityStatus = TaskStatusEnum.REJECT
  91. } else if (unfinishedTaskActivityIds.includes(simpleModel.id)) {
  92. simpleModel.activityStatus = TaskStatusEnum.RUNNING
  93. } else if (finishedActivityIds.includes(simpleModel.id)) {
  94. simpleModel.activityStatus = TaskStatusEnum.APPROVE
  95. }
  96. // TODO 是不是还缺一个 cancel 的状态
  97. }
  98. // 抄送节点
  99. if (simpleModel.type === NodeType.COPY_TASK_NODE) {
  100. // 抄送节点,只有通过和未执行状态
  101. if (finishedActivityIds.includes(simpleModel.id)) {
  102. simpleModel.activityStatus = TaskStatusEnum.APPROVE
  103. } else {
  104. simpleModel.activityStatus = TaskStatusEnum.NOT_START
  105. }
  106. }
  107. // 延迟器节点
  108. if (simpleModel.type === NodeType.DELAY_TIMER_NODE) {
  109. // 延迟器节点,只有通过和未执行状态
  110. if (finishedActivityIds.includes(simpleModel.id)) {
  111. simpleModel.activityStatus = TaskStatusEnum.APPROVE
  112. } else {
  113. simpleModel.activityStatus = TaskStatusEnum.NOT_START
  114. }
  115. }
  116. // 条件节点对应 SequenceFlow
  117. if (simpleModel.type === NodeType.CONDITION_NODE) {
  118. // 条件节点,只有通过和未执行状态
  119. if (finishedSequenceFlowActivityIds.includes(simpleModel.id)) {
  120. simpleModel.activityStatus = TaskStatusEnum.APPROVE
  121. } else {
  122. simpleModel.activityStatus = TaskStatusEnum.NOT_START
  123. }
  124. }
  125. // 网关节点
  126. if (
  127. simpleModel.type === NodeType.CONDITION_BRANCH_NODE ||
  128. simpleModel.type === NodeType.PARALLEL_BRANCH_NODE ||
  129. simpleModel.type === NodeType.INCLUSIVE_BRANCH_NODE ||
  130. simpleModel.type === NodeType.ROUTE_BRANCH_NODE
  131. ) {
  132. // 网关节点。只有通过和未执行状态
  133. if (finishedActivityIds.includes(simpleModel.id)) {
  134. simpleModel.activityStatus = TaskStatusEnum.APPROVE
  135. } else {
  136. simpleModel.activityStatus = TaskStatusEnum.NOT_START
  137. }
  138. simpleModel.conditionNodes?.forEach((node) => {
  139. setSimpleModelNodeTaskStatus(
  140. node,
  141. processStatus,
  142. rejectedTaskActivityIds,
  143. unfinishedTaskActivityIds,
  144. finishedActivityIds,
  145. finishedSequenceFlowActivityIds
  146. )
  147. })
  148. }
  149. setSimpleModelNodeTaskStatus(
  150. simpleModel.childNode,
  151. processStatus,
  152. rejectedTaskActivityIds,
  153. unfinishedTaskActivityIds,
  154. finishedActivityIds,
  155. finishedSequenceFlowActivityIds
  156. )
  157. }
  158. </script>
  159. <style lang="scss" scoped>
  160. .process-viewer-container {
  161. width: 100%;
  162. height: 100%;
  163. :deep(.process-viewer) {
  164. width: 100%;
  165. height: 100% !important;
  166. min-height: 100%;
  167. overflow: auto;
  168. }
  169. }
  170. </style>