StartUserNode.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <template>
  2. <div class="node-wrapper">
  3. <div class="node-container">
  4. <div
  5. class="node-box"
  6. :class="[
  7. { 'node-config-error': !currentNode.showText },
  8. `${useTaskStatusClass(currentNode?.activityStatus)}`
  9. ]"
  10. >
  11. <div class="node-title-container">
  12. <div class="node-title-icon start-user"
  13. ><span class="iconfont icon-start-user"></span
  14. ></div>
  15. <input
  16. v-if="!readonly && showInput"
  17. type="text"
  18. class="editable-title-input"
  19. @blur="blurEvent()"
  20. v-mountedFocus
  21. v-model="currentNode.name"
  22. :placeholder="currentNode.name"
  23. />
  24. <div v-else class="node-title" @click="clickTitle">
  25. {{ currentNode.name }}
  26. </div>
  27. </div>
  28. <div class="node-content" @click="nodeClick">
  29. <div class="node-text" :title="currentNode.showText" v-if="currentNode.showText">
  30. {{ currentNode.showText }}
  31. </div>
  32. <div class="node-text" v-else>
  33. {{ NODE_DEFAULT_TEXT.get(NodeType.START_USER_NODE) }}
  34. </div>
  35. <Icon icon="ep:arrow-right-bold" v-if="!readonly" />
  36. </div>
  37. </div>
  38. <!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
  39. <NodeHandler
  40. v-if="currentNode"
  41. v-model:child-node="currentNode.childNode"
  42. :current-node="currentNode"
  43. />
  44. </div>
  45. </div>
  46. <StartUserNodeConfig v-if="!readonly && currentNode" ref="nodeSetting" :flow-node="currentNode" />
  47. <!-- 审批记录 -->
  48. <el-dialog
  49. :title="dialogTitle || '审批记录'"
  50. v-model="dialogVisible"
  51. width="1000px"
  52. append-to-body
  53. >
  54. <el-row>
  55. <el-table :data="selectTasks" size="small" border header-cell-class-name="table-header-gray">
  56. <el-table-column
  57. label="序号"
  58. header-align="center"
  59. align="center"
  60. type="index"
  61. width="50"
  62. />
  63. <el-table-column label="审批人" min-width="100" align="center">
  64. <template #default="scope">
  65. {{ scope.row.assigneeUser?.nickname || scope.row.ownerUser?.nickname }}
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="部门" min-width="100" align="center">
  69. <template #default="scope">
  70. {{ scope.row.assigneeUser?.deptName || scope.row.ownerUser?.deptName }}
  71. </template>
  72. </el-table-column>
  73. <el-table-column
  74. :formatter="dateFormatter"
  75. align="center"
  76. label="开始时间"
  77. prop="createTime"
  78. min-width="140"
  79. />
  80. <el-table-column
  81. :formatter="dateFormatter"
  82. align="center"
  83. label="结束时间"
  84. prop="endTime"
  85. min-width="140"
  86. />
  87. <el-table-column align="center" label="审批状态" prop="status" min-width="90">
  88. <template #default="scope">
  89. <dict-tag :type="DICT_TYPE.BPM_TASK_STATUS" :value="scope.row.status" />
  90. </template>
  91. </el-table-column>
  92. <el-table-column align="center" label="审批建议" prop="reason" min-width="120" />
  93. <el-table-column align="center" label="耗时" prop="durationInMillis" width="100">
  94. <template #default="scope">
  95. {{ formatPast2(scope.row.durationInMillis) }}
  96. </template>
  97. </el-table-column>
  98. </el-table>
  99. </el-row>
  100. </el-dialog>
  101. </template>
  102. <script setup lang="ts">
  103. import NodeHandler from '../NodeHandler.vue'
  104. import { useWatchNode, useNodeName2, useTaskStatusClass } from '../node'
  105. import { SimpleFlowNode, NODE_DEFAULT_TEXT, NodeType } from '../consts'
  106. import StartUserNodeConfig from '../nodes-config/StartUserNodeConfig.vue'
  107. import { dateFormatter, formatPast2 } from '@/utils/formatTime'
  108. import { DICT_TYPE } from '@/utils/dict'
  109. defineOptions({
  110. name: 'StartEventNode'
  111. })
  112. const props = defineProps({
  113. flowNode: {
  114. type: Object as () => SimpleFlowNode,
  115. default: () => null
  116. }
  117. })
  118. const readonly = inject<Boolean>('readonly') // 是否只读
  119. const tasks = inject<Ref<any[]>>('tasks', ref([]))
  120. // 定义事件,更新父组件。
  121. const emits = defineEmits<{
  122. 'update:modelValue': [node: SimpleFlowNode | undefined]
  123. }>()
  124. // 监控节点变化
  125. const currentNode = useWatchNode(props)
  126. // 节点名称编辑
  127. const { showInput, blurEvent, clickTitle } = useNodeName2(currentNode, NodeType.START_USER_NODE)
  128. const nodeSetting = ref()
  129. //
  130. const nodeClick = () => {
  131. if (readonly) {
  132. // 只读模式,弹窗显示任务信息
  133. if (tasks && tasks.value) {
  134. dialogTitle.value = currentNode.value.name
  135. selectTasks.value = tasks.value.filter(
  136. (item: any) => item?.taskDefinitionKey === currentNode.value.id
  137. )
  138. dialogVisible.value = true
  139. }
  140. } else {
  141. // 编辑模式,打开节点配置、把当前节点传递给配置组件
  142. nodeSetting.value.showStartUserNodeConfig(currentNode.value)
  143. nodeSetting.value.openDrawer()
  144. }
  145. }
  146. // 任务的弹窗显示,用于只读模式
  147. const dialogVisible = ref(false) // 弹窗可见性
  148. const dialogTitle = ref<string | undefined>(undefined) // 弹窗标题
  149. const selectTasks = ref<any[] | undefined>([]) // 选中的任务数组
  150. </script>
  151. <style lang="scss" scoped></style>