提交 | 用户 | 时间
820397 1 <template>
H 2   <ContentWrap>
3     <!-- 搜索工作栏 -->
4     <el-form
5       class="-mb-15px"
6       :model="queryParams"
7       ref="queryFormRef"
8       :inline="true"
9       label-width="68px"
10     >
3e359e 11       <el-form-item label="" prop="name">
820397 12         <el-input
H 13           v-model="queryParams.name"
14           placeholder="请输入流程名称"
15           clearable
16           @keyup.enter="handleQuery"
17           class="!w-240px"
18         />
19       </el-form-item>
3e359e 20
H 21       <el-form-item>
22         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
820397 23       </el-form-item>
3e359e 24
H 25       <!-- TODO @ tuituji:style 可以使用 unocss -->
9259c2 26       <el-form-item label="" prop="category" :style="{ position: 'absolute', right: '300px' }">
H 27         <!-- TODO @tuituji:应该选择好分类,就触发搜索啦。 RE:done & to check-->
820397 28         <el-select
H 29           v-model="queryParams.category"
30           placeholder="请选择流程分类"
31           clearable
3e359e 32           class="!w-155px"
9259c2 33           @change="handleQuery"
820397 34         >
H 35           <el-option
36             v-for="category in categoryList"
37             :key="category.code"
38             :label="category.name"
39             :value="category.code"
40           />
41         </el-select>
42       </el-form-item>
3e359e 43
9259c2 44       <el-form-item label="" prop="status" :style="{ position: 'absolute', right: '130px' }">
H 45         <el-select
46           v-model="queryParams.status"
47           placeholder="请选择流程状态"
48           clearable
49           class="!w-155px"
50           @change="handleQuery"
51         >
52           <el-option
53             v-for="dict in getIntDictOptions(DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS)"
54             :key="dict.value"
55             :label="dict.label"
56             :value="dict.value"
57           />
58         </el-select>
59       </el-form-item>
60
3e359e 61       <!-- 高级筛选 -->
H 62       <!-- TODO @ tuituji:style 可以使用 unocss -->
63       <el-form-item :style="{ position: 'absolute', right: '0px' }">
64         <el-popover
9259c2 65           :visible="showPopover"
3e359e 66           persistent
H 67           :width="400"
68           :show-arrow="false"
69           placement="bottom-end"
70         >
9259c2 71           <template #reference>
H 72             <el-button @click="showPopover = !showPopover">
73               <Icon icon="ep:plus" class="mr-5px" />高级筛选
74             </el-button>
75           </template>
3e359e 76           <el-form-item label="流程发起人" class="bold-label" label-position="top" prop="category">
H 77             <el-select
78               v-model="queryParams.category"
79               placeholder="请选择流程发起人"
80               clearable
81               class="!w-390px"
82             >
83               <el-option
84                 v-for="category in categoryList"
85                 :key="category.code"
86                 :label="category.name"
87                 :value="category.code"
88               />
89             </el-select>
90           </el-form-item>
91           <el-form-item
92             label="所属流程"
93             class="bold-label"
94             label-position="top"
95             prop="processDefinitionKey"
96           >
97             <el-input
98               v-model="queryParams.processDefinitionKey"
99               placeholder="请输入流程定义的标识"
100               clearable
101               @keyup.enter="handleQuery"
102               class="!w-390px"
103             />
104           </el-form-item>
105           <el-form-item label="发起时间" class="bold-label" label-position="top" prop="createTime">
106             <el-date-picker
107               v-model="queryParams.createTime"
108               value-format="YYYY-MM-DD HH:mm:ss"
109               type="daterange"
110               start-placeholder="开始日期"
111               end-placeholder="结束日期"
112               :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
113               class="!w-240px"
114             />
115           </el-form-item>
9259c2 116           <!-- TODO tuituiji:参考钉钉,1)按照清空、取消、确认排序。2)右对齐。3)确认增加 primary -->
H 117           <el-form-item class="bold-label" label-position="top">
118             <el-button @click="handleQuery"> 确认</el-button>
119             <el-button @click="showPopover = false"> 取消</el-button>
120             <el-button @click="resetQuery"> 清空</el-button>
121           </el-form-item>
3e359e 122         </el-popover>
820397 123       </el-form-item>
H 124     </el-form>
125   </ContentWrap>
126
127   <!-- 列表 -->
128   <ContentWrap>
129     <el-table v-loading="loading" :data="list">
130       <el-table-column label="流程名称" align="center" prop="name" min-width="200px" fixed="left" />
131       <el-table-column
132         label="流程分类"
133         align="center"
134         prop="categoryName"
135         min-width="100"
136         fixed="left"
137       />
3e359e 138       <!-- TODO @芋艿:摘要 -->
9259c2 139       <!-- TODO tuituiji:参考钉钉;1)审批中时,展示审批任务;2)非审批中,展示状态 -->
820397 140       <el-table-column label="流程状态" prop="status" width="120">
H 141         <template #default="scope">
142           <dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="scope.row.status" />
143         </template>
144       </el-table-column>
145       <el-table-column
146         label="发起时间"
147         align="center"
148         prop="startTime"
149         width="180"
150         :formatter="dateFormatter"
151       />
152       <el-table-column
153         label="结束时间"
154         align="center"
155         prop="endTime"
156         width="180"
157         :formatter="dateFormatter"
158       />
3e359e 159       <!--<el-table-column align="center" label="耗时" prop="durationInMillis" width="160">
820397 160         <template #default="scope">
H 161           {{ scope.row.durationInMillis > 0 ? formatPast2(scope.row.durationInMillis) : '-' }}
162         </template>
163       </el-table-column>
164       <el-table-column label="当前审批任务" align="center" prop="tasks" min-width="120px">
165         <template #default="scope">
166           <el-button type="primary" v-for="task in scope.row.tasks" :key="task.id" link>
167             <span>{{ task.name }}</span>
168           </el-button>
169         </template>
170       </el-table-column>
3e359e 171       -->
820397 172       <el-table-column label="操作" align="center" fixed="right" width="180">
H 173         <template #default="scope">
174           <el-button
175             link
176             type="primary"
177             v-hasPermi="['bpm:process-instance:cancel']"
178             @click="handleDetail(scope.row)"
179           >
180             详情
181           </el-button>
182           <el-button
183             link
184             type="primary"
185             v-if="scope.row.status === 1"
186             v-hasPermi="['bpm:process-instance:query']"
187             @click="handleCancel(scope.row)"
188           >
189             取消
190           </el-button>
191           <el-button link type="primary" v-else @click="handleCreate(scope.row)">
192             重新发起
193           </el-button>
194         </template>
195       </el-table-column>
196     </el-table>
197     <!-- 分页 -->
198     <Pagination
199       :total="total"
200       v-model:page="queryParams.pageNo"
201       v-model:limit="queryParams.pageSize"
202       @pagination="getList"
203     />
204   </ContentWrap>
205 </template>
206 <script lang="ts" setup>
9259c2 207 // TODO @tuituji:List 改成 <Icon icon="ep:plus" class="mr-5px" /> 类似这种组件哈。 RE:done & to check
820397 208 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
3e359e 209 import { dateFormatter } from '@/utils/formatTime'
820397 210 import { ElMessageBox } from 'element-plus'
H 211 import * as ProcessInstanceApi from '@/api/bpm/processInstance'
3e359e 212 import { CategoryApi, CategoryVO } from '@/api/bpm/category'
820397 213 import { ProcessInstanceVO } from '@/api/bpm/processInstance'
H 214 import * as DefinitionApi from '@/api/bpm/definition'
215
216 defineOptions({ name: 'BpmProcessInstanceMy' })
217
218 const router = useRouter() // 路由
219 const message = useMessage() // 消息弹窗
220 const { t } = useI18n() // 国际化
221
222 const loading = ref(true) // 列表的加载中
223 const total = ref(0) // 列表的总页数
224 const list = ref([]) // 列表的数据
225 const queryParams = reactive({
226   pageNo: 1,
227   pageSize: 10,
228   name: '',
3e359e 229   processDefinitionKey: undefined,
820397 230   category: undefined,
H 231   status: undefined,
232   createTime: []
233 })
234 const queryFormRef = ref() // 搜索的表单
3e359e 235 const categoryList = ref<CategoryVO[]>([]) // 流程分类列表
820397 236
H 237 /** 查询列表 */
238 const getList = async () => {
239   loading.value = true
240   try {
241     const data = await ProcessInstanceApi.getProcessInstanceMyPage(queryParams)
242     list.value = data.list
243     total.value = data.total
244   } finally {
245     loading.value = false
246   }
247 }
248
9259c2 249 const showPopover = ref(false)
H 250
820397 251 /** 搜索按钮操作 */
H 252 const handleQuery = () => {
253   queryParams.pageNo = 1
254   getList()
255 }
256
257 /** 重置按钮操作 */
258 const resetQuery = () => {
259   queryFormRef.value.resetFields()
260   handleQuery()
261 }
262
263 /** 发起流程操作 **/
264 const handleCreate = async (row?: ProcessInstanceVO) => {
265   // 如果是【业务表单】,不支持重新发起
266   if (row?.id) {
267     const processDefinitionDetail = await DefinitionApi.getProcessDefinition(
268       row.processDefinitionId
269     )
270     if (processDefinitionDetail.formType === 20) {
271       message.error('重新发起流程失败,原因:该流程使用业务表单,不支持重新发起')
272       return
273     }
274   }
275   // 跳转发起流程界面
276   await router.push({
277     name: 'BpmProcessInstanceCreate',
278     query: { processInstanceId: row?.id }
279   })
280 }
281
282 /** 查看详情 */
9259c2 283 const handleDetail = (row: ProcessInstanceVO) => {
820397 284   router.push({
H 285     name: 'BpmProcessInstanceDetail',
286     query: {
287       id: row.id
288     }
289   })
290 }
291
292 /** 取消按钮操作 */
9259c2 293 const handleCancel = async (row: ProcessInstanceVO) => {
820397 294   // 二次确认
H 295   const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
296     confirmButtonText: t('common.ok'),
297     cancelButtonText: t('common.cancel'),
298     inputPattern: /^[\s\S]*.*\S[\s\S]*$/, // 判断非空,且非空格
299     inputErrorMessage: '取消原因不能为空'
300   })
301   // 发起取消
302   await ProcessInstanceApi.cancelProcessInstanceByStartUser(row.id, value)
303   message.success('取消成功')
304   // 刷新列表
305   await getList()
3e359e 306 }
H 307
820397 308 /** 激活时 **/
H 309 onActivated(() => {
310   getList()
311 })
312
313 /** 初始化 **/
314 onMounted(async () => {
315   await getList()
316   categoryList.value = await CategoryApi.getCategorySimpleList()
317 })
318 </script>
3e359e 319 <style>
H 320 .bold-label .el-form-item__label {
321   font-weight: bold; /* 将字体加粗 */
322 }
323 </style>