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