cloud-web-corejs 1.1.0-dev.58 → 1.1.0-dev.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1734 +1,1734 @@
1
- <template>
2
- <div>
3
- <h5-card-pane label="流程信息">
4
- <template #default>
5
- <div class="flowPath-box">
6
- <!-- 这一行的值是 wfInfo.name(流程主题),标签原先误写成「任务情况」——
7
- 与下面第三行「查看任务情况」重名。PC content.vue 同一个值的标签就是
8
- 「流程主题」(components.wf.theme)。 -->
9
- <div class="t"><span>{{ $t2('流程主题', 'components.wf.theme') }}</span></div>
10
- <div class="c">
11
- <div class="name">
12
- {{ (wfInfo.createDate ? wfInfo.createDate.substring(0, 10) : '') + wfInfo.name }}
13
- <el-tag :type="getWfStatusType()" size="mini">{{ getWfStatusLabel() }}</el-tag>
14
- </div>
15
- </div>
16
- <div class="m2">
17
- <div class="t"><span>{{ $t2('流程图', 'components.wf.wfImage') }}</span></div>
18
- <div class="c">
19
- <el-button icon="" class="btn" @click="showPreviewDialog=true" icon="el-icon-view">查看流程图</el-button>
20
- </div>
21
- </div>
22
- <div class="m2">
23
- <div class="t"><span>{{ $t2('任务情况', 'components.wf.taskInfo') }}</span></div>
24
- <div class="c">
25
- <el-button icon="" class="btn" @click="showRenwuDialog=true" icon="iconfont icon-preview">查看任务情况
26
- </el-button>
27
- </div>
28
- </div>
29
-
30
- </div>
31
- <!-- hideActions:宿主已经把审批动作提到别处(如 xform H5 的底部动作栏)时,
32
- 这一排整条藏掉,避免一个动作出现两份。与 PC content.vue 的
33
- headerActionsMounted 同意图,这里做成 prop 是为了没有时序问题。 -->
34
- <div class="flowPath-btns" v-show="!hideActions">
35
- <el-button type="success" plain class="btn" @click="openAgreeDialog" v-show="wfInfo.toSubmit"
36
- icon="iconfont icon-tongguo">{{ $t2('通过', 'components.wf.agree') }}
37
- </el-button>
38
- <el-button type="warning" plain class="btn" @click="openManualDialog" v-show="wfInfo.toInterrupt"
39
- icon="iconfont icon-caozuozhongduan">{{ $t2('中断', 'components.wf.manual') }}
40
- </el-button>
41
- <el-button type="danger" plain class="btn" @click="rejectWfTask" v-show="wfInfo.toReject"
42
- icon="iconfont icon-a-bohui1">{{ $t2('驳回', 'components.wf.reject') }}
43
- </el-button>
44
- <el-button type="primary" plain class="btn" @click="openChangeWfForm"
45
- v-show="transferEnabled && ((wfInfo.toTransfer===null || wfInfo.toTransfer===undefined) ? wfInfo.toSubmit: wfInfo.toTransfer)"
46
- icon="iconfont icon-zhuanban">{{ $t2('转办', 'components.wf.transfer') }}
47
- </el-button>
48
- <el-button type="primary" plain class="btn" @click="openUrgingDialog" v-show="wfInfo.toInterrupt"
49
- icon="iconfont icon-cuiban">{{ $t2('催办', 'components.wf.urging') }}
50
- </el-button>
51
- <el-button type="primary" plain class="btn" @click="openAddIncreaseSign" v-show="wfInfo.toAddIncreaseSign"
52
- icon="el-icon-plus">{{ $t2('加签', 'components.wf.addIncreaseSign') }}
53
- </el-button>
54
- <el-button type="primary" plain class="btn" @click="openDeleteTaskUserDialog"
55
- v-show="wfInfo.toDeleteIncreaseSign"
56
- icon="el-icon-delete">{{ $t2('减签', 'components.wf.deleteIncreaseSign') }}
57
- </el-button>
58
- <el-button type="primary" plain class="btn" @click="openTalkDialog()"
59
- icon="el-icon-chat-dot-square" v-if="toTalk && wfInfo.toLinkup">
60
- {{ $t2('沟通', 'components.wf.talk') }}
61
- </el-button>
62
- <el-button type="primary" plain class="btn" @click="openSetCandidateDialog(null)"
63
- v-show="wfInfo.toSetCandidate"
64
- icon="el-icon-user">{{ $t2('修改候选人', 'components.wf.setCandidate') }}
65
- </el-button>
66
- <el-button type="danger" plain class="btn" @click="openRevokeDialog(null)"
67
- v-show="wfInfo.toRevoke"
68
- icon="el-icon-document-delete">{{ $t2('撤回', 'components.wf.revoke') }}
69
- </el-button>
70
- </div>
71
- </template>
72
- </h5-card-pane>
73
-
74
- <!-- 流程相关的弹框必须放在卡片外面。h5CardPane 折叠时会给 .cont 加
75
- display:none,放在插槽里的弹框会被一起隐藏 —— 表现为「流程信息收起后,
76
- 通过/驳回/转办这些弹框点了没反应」(祖先 display:none 无法被后代覆盖)。 -->
77
- <el-dialog
78
- title="流程图预览"
79
- :modal-append-to-body="false"
80
- :close-on-click-modal="false"
81
- :visible.sync="showPreviewDialog"
82
- :modal="false"
83
- custom-class="dialog-style h5view-dialog"
84
- width="100%"
85
- top="0px"
86
- v-el-drag-dialog
87
- v-el-dialog-center
88
- :append-to-body ="true"
89
- :destroy-on-close="true"
90
- >
91
- <div class="flex">
92
- <el-form label-position="top" class="form-box">
93
- <div class="tit"><span>{{
94
- (wfInfo.createDate ? wfInfo.createDate.substring(0, 10) : '') + wfInfo.name
95
- }}</span></div>
96
- <iframe
97
- ref="wfPreviewFrame"
98
- style="width: 100%;flex:1"
99
- :src="wfImage"
100
- @load="fitWorkflowPreview"
101
- ></iframe>
102
- </el-form>
103
- </div>
104
- <span slot="footer" class="dialog-footer">
105
- <el-button
106
- type="primary"
107
- plain
108
- class="button-sty"
109
- icon="el-icon-close"
110
- @click="showPreviewDialog = false"
111
- >{{$t2('关 闭', 'system.button.close2')}}</el-button
112
- >
113
- </span>
114
- </el-dialog>
115
-
116
- <el-dialog
117
- title="任务情况预览"
118
- :modal-append-to-body="false"
119
- :close-on-click-modal="false"
120
- :visible.sync="showRenwuDialog"
121
- :modal="false"
122
- custom-class="dialog-style h5view-dialog"
123
- width="100%"
124
- top="0px"
125
- v-el-drag-dialog
126
- v-el-dialog-center
127
- :append-to-body ="true"
128
- :destroy-on-close="true"
129
- >
130
- <div class="flex">
131
- <div class="h5-process-info">
132
- <div class="item" v-for="wftaskLineData in wftaskData" :key="wftaskLineData.id">
133
- <div class="time">
134
- {{ wftaskLineData.approveTime ? wftaskLineData.approveTime.substring(0, 10) : '' }}
135
- <br/>
136
- {{ wftaskLineData.approveTime ? wftaskLineData.approveTime.substring(11) : '' }}
137
- </div>
138
- <div class="status"
139
- :class="taskStatuses[wftaskLineData.type]?taskStatuses[wftaskLineData.type].class:''">
140
- {{ taskStatuses[wftaskLineData.type] ? taskStatuses[wftaskLineData.type].value : null }}
141
- </div>
142
- <i class="circle"></i>
143
- <div class="info">
144
- <p>
145
- <span class="name">{{ wftaskLineData.taskName }}</span>
146
- <span>{{ $t2('执行人', 'components.wf.approverName') }}:{{ wftaskLineData.approverName }}</span>
147
- <span>
148
- {{ $t2('候选人', 'components.wf.candidateName') }}:
149
- <span class="">{{ wftaskLineData.candidateNames }}</span>
150
- </span>
151
- </p>
152
- <p class="t"><span class="t1">{{ $t2('备注/意见', 'components.wf.opinion') }}:</span><span>{{
153
- wftaskLineData.opinion
154
- }}</span></p>
155
- </div>
156
- </div>
157
- </div>
158
- </div>
159
- <!-- 同上:只读预览,合成一个「关 闭」 -->
160
- <span slot="footer" class="dialog-footer">
161
- <el-button
162
- type="primary"
163
- plain
164
- class="button-sty"
165
- icon="el-icon-close"
166
- @click="showRenwuDialog = false"
167
- >{{$t2('关 闭', 'system.button.close2')}}</el-button
168
- >
169
- </span>
170
- </el-dialog>
171
- <!-- 下面 5 个确认框(中断 / 驳回 / 通过 / 转办 / 加签)都走 v-append-to-body:
172
- 节点搬到 document.body 下,不再靠 position:fixed 在宿主子树里侥幸生效。
173
- 它们保持 .pop-tipsBox 的原造型,没有改成 el-dialog——那个圆角卡片 + 顶部
174
- 溢出圆形图标的样子要用 el-dialog 复刻,得把 header/body/footer 三段默认
175
- 样式全推翻,样式量不减反增。
176
-
177
- 三条约束,改动前先看 directive/append-to-body/index.js 的说明:
178
- 1. 必须是 v-show,不能换回 v-if(Vue 的 insert() 会静默跳过以被搬走的
179
- 节点为参照物的插入,兄弟顺序会错乱);
180
- 2. 内联 style="display: block;" 不能删(v-show 的 originalDisplay 取自
181
- 它,删了「显示」态会退回各应用 h5.scss 里 .pop-tipsBox{display:none});
182
- 3. 多挂的 h5-pop-tips 类是样式作用域锚点——搬到 body 后 .xform-h5 前缀
183
- 全部失配,样式改挂在 .pop-tipsBox.h5-pop-tips 上,既保住原有优先级,
184
- 又不会误伤同样用 .pop-tipsBox 的 confirmDialog / baseAlert / errorMsg。 -->
185
- <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="showWfManualDialog"
186
- v-append-to-body>
187
- <div>
188
- <i class="icon"></i>
189
- <div class="cont">
190
- <p class="name">
191
- {{ $t2('流程中断', 'components.wf.wfManual') }}<span>—</span><b
192
- class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
193
- wfInfo.taskName
194
- }}</b>
195
- </p>
196
- <p class="txt">{{ $t2('您确定要中断流程吗?', 'components.wf.manualTip') }}</p>
197
- </div>
198
- <div class="btns">
199
- <el-button type="primary" class="btn" plain icon="el-icon-close" @click="showWfManualDialog = false">{{
200
- $t2('取 消', 'system.button.cancel2')
201
- }}
202
- </el-button>
203
- <el-button type="primary" class="btn" icon="el-icon-check" @click="manualEndWf()">{{
204
- $t2('确 定', 'system.button.confirm2')
205
- }}
206
- </el-button>
207
- </div>
208
- </div>
209
- </div>
210
- <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="rejectDialogVisible"
211
- v-append-to-body>
212
- <div>
213
- <i class="icon"></i>
214
- <div class="cont">
215
- <p class="name">{{ $t2('流程驳回', 'components.wf.wfReject') }}<span
216
- >—</span><b
217
- class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
218
- wfInfo.taskName
219
- }}</b></p>
220
- <el-form label-position="top" class="form-box">
221
- <el-form-item label="驳回节点" field="nodeId">
222
- <el-select v-model="rejectForm.nodeId"
223
- :placeholder="$t2('请选择驳回节点', 'components.wf.rejectNodePlaceholder')">
224
- <el-option v-for="(rejectNode,index) in rejectNodes" :label="rejectNode.nodeName"
225
- :value="rejectNode.nodeId" :key="index"></el-option>
226
- </el-select>
227
- </el-form-item>
228
- <el-form-item label="驳回意见" field="opinion">
229
- <el-input type="textarea" :rows="5"
230
- :placeholder="$t2('请输入内容', 'components.wf.rejectOpinionPlaceholder')"
231
- v-model="rejectForm.opinion" class="txt"></el-input>
232
- </el-form-item>
233
- </el-form>
234
- </div>
235
- <div class="btns">
236
- <el-button type="primary" class="btn" plain icon="el-icon-close" @click="rejectDialogVisible = false">{{
237
- $t2('取 消', 'system.button.cancel2')
238
- }}
239
- </el-button>
240
- <el-button type="primary" class="btn" icon="el-icon-check" @click="subRejectForm()">{{
241
- $t2('确 定', 'system.button.confirm2')
242
- }}
243
- </el-button>
244
- </div>
245
- </div>
246
- </div>
247
- <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="agreeDialogVisible"
248
- v-append-to-body>
249
- <div>
250
- <i class="icon"></i>
251
- <div class="cont">
252
- <p class="name">{{ $t2('流程通过', 'components.wf.wfAgree') }}<span
253
- >—</span><b
254
- class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
255
- wfInfo.taskName
256
- }}</b></p>
257
- <el-form label-position="top" class="form-box">
258
- <!-- 只有分支网关这类多出口节点,getNextOutgoingNodes 才会返回候选节点;
259
- 单出口节点返回空数组,这一项必须整条不渲染,否则会露出一个没有任何
260
- 选项的空下拉(提交时 nodeId 本就传 null,不需要选)。
261
- 与 PC content.vue 的 <tr v-if="agreeNodes.length > 0"> 同口径。 -->
262
- <el-form-item v-if="agreeNodes.length > 0"
263
- :label="$t2('通过节点', 'components.wf.agreeNode')" field="nodeId">
264
- <el-select v-model="agreeForm.nodeId"
265
- :placeholder="$t2('请选择通过节点', 'components.wf.agreeNodePlaceholder')">
266
- <el-option v-for="(node,index) in agreeNodes" :label="node.nodeName"
267
- :value="node.nodeId" :key="index"></el-option>
268
- </el-select>
269
- </el-form-item>
270
- <el-form-item :label="$t2('通过意见', 'components.wf.agreeOpinion')" field="opinion">
271
- <el-input type="textarea" :rows="8" :placeholder="$t2(`请填写您的意见~
272
- 注:
273
- 通过默认意见为“同意”
274
- `, 'components.wf.agreeOpinionPlaceholder')" v-model="agreeForm.opinion"></el-input>
275
- </el-form-item>
276
- </el-form>
277
- </div>
278
- <div class="btns">
279
- <el-button type="primary" class="btn" plain icon="el-icon-close" @click="agreeDialogVisible = false">{{
280
- $t2('取 消', 'system.button.cancel2')
281
- }}
282
- </el-button>
283
- <el-button type="primary" class="btn" icon="el-icon-check" @click="subAgreeForm()">{{
284
- $t2('确 定', 'system.button.confirm2')
285
- }}
286
- </el-button>
287
- </div>
288
- </div>
289
- </div>
290
- <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="changeWfDialogVisible"
291
- v-append-to-body>
292
- <div>
293
- <i class="icon"></i>
294
- <div class="cont">
295
- <p class="name">{{ $t2('流程转办', 'components.wf.wfTransfer') }}<span>—</span><b
296
- class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
297
- wfInfo.taskName
298
- }}</b></p>
299
- <el-form label-position="top" class="form-box">
300
- <el-form-item label="转办人" field="nodeId">
301
- <el-input
302
- class="search-input"
303
- max="200"
304
- v-model="changeWfForm.userNickNames"
305
- @clear="
306
- changeWfForm.userIds = '';
307
- changeUserRows = [];
308
- $forceUpdate();
309
- "
310
- v-el-readonly
311
- clearable
312
- >
313
- <i slot="suffix" class="el-input__icon el-icon-search" @click="showUserDialog = true"></i>
314
- </el-input>
315
- </el-form-item>
316
- <el-form-item label="转办意见" field="opinion">
317
- <el-input type="textarea" :rows="8"
318
- :placeholder="$t2('请输入内容', 'components.wf.transferOpinionPlaceholder')"
319
- v-model="changeWfForm.opinion"></el-input>
320
- </el-form-item>
321
- </el-form>
322
- </div>
323
- <div class="btns">
324
- <el-button type="primary" class="btn" plain @click="changeWfDialogVisible = false">{{
325
- $t2('取 消', 'system.button.cancel2')
326
- }}
327
- </el-button>
328
- <el-button type="primary" class="btn" @click="subChangeWfForm()">
329
- {{ $t2('确认转办', 'components.wf.confirmTransfer') }}
330
- </el-button>
331
- </div>
332
- </div>
333
- </div>
334
- <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="showAddIncreaseSignDialog"
335
- v-append-to-body>
336
- <div>
337
- <i class="icon"></i>
338
- <div class="cont">
339
- <p class="name">
340
- {{ $t2('流程加签', 'components.wf.wfAddIncreaseSign') }}<span>—</span><b
341
- class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
342
- wfInfo.taskName
343
- }}</b>
344
- </p>
345
- <el-form label-position="top" class="form-box">
346
- <el-form-item label="候选人">
347
- <el-input
348
- class="search-input"
349
- max="200"
350
- v-model="addIncreaseSignForm.userNickNames"
351
- @clear="
352
- addIncreaseSignUsers = [];
353
- $forceUpdate();
354
- "
355
- :placeholder="$t2('候选人', 'components.wf.addIncreaseSignUser')"
356
- v-el-readonly
357
- clearable
358
- >
359
- <i slot="suffix" class="el-input__icon el-icon-search"
360
- @click="showAddTaskUserDialog = true"></i>
361
- </el-input>
362
- </el-form-item>
363
- <el-form-item label="加签意见" field="opinion">
364
- <el-input type="textarea" :rows="8"
365
- :placeholder="$t2('请输入内容', 'components.wf.addIncreaseSignOpinionPlaceholder')"
366
- v-model="addIncreaseSignForm.opinion"></el-input>
367
- </el-form-item>
368
- </el-form>
369
- </div>
370
- <div class="btns">
371
- <el-button type="primary" class="btn" plain @click="showAddIncreaseSignDialog = false">{{
372
- $t2('取 消', 'system.button.cancel2')
373
- }}
374
- </el-button>
375
- <el-button type="primary" class="btn" @click="submitAddTaskUserForm(0)">
376
- {{ $t2('确认加签', 'components.wf.confirmAddIncreaseSign') }}
377
- </el-button>
378
- </div>
379
- </div>
380
- </div>
381
-
382
- <user-dialog v-if="showUserDialog" :visiable.sync="showUserDialog" @close="showUserDialog = false"
383
- @confirm="userConfirm" multi="true" :param.sync="wfUserParamForTransfer"
384
- :rows="changeUserRows"></user-dialog>
385
- <urgingDialog v-if="urgingDialogVisible" :visiable.sync="urgingDialogVisible" :wfInfo="wfInfo"
386
- :current_prefix="current_prefix"
387
- @confirm="reloadContent" multi="true"></urgingDialog>
388
- <deleteTaskUserDialog v-if="showDeleteTaskUserDialog" :visiable.sync="showDeleteTaskUserDialog" :wfInfo="wfInfo"
389
- :current_prefix="current_prefix"
390
- @confirm="reloadContent" multi="true"></deleteTaskUserDialog>
391
-
392
- <addTaskUserdialog v-if="showAddTaskUserDialog" :visiable.sync="showAddTaskUserDialog" :wfInfo="wfInfo"
393
- :current_prefix="current_prefix" :rows.sync="addIncreaseSignUsers"
394
- @confirm="confirmAddTaskUser" multi="true"
395
- :param.sync="wfUserParamForAddSign"></addTaskUserdialog>
396
- <user-dialog v-if="showTalkUserDialog" :visiable.sync="showTalkUserDialog" @close="showTalkUserDialog = false"
397
- @confirm="confirmTalkUserDialog" multi="false" :param.sync="wfUserParamForTalk"></user-dialog>
398
- <setCandidateDialog v-if="showSetCandidateDialog" :visiable.sync="showSetCandidateDialog"
399
- @close="closeSetCandidateDialog"
400
- :wfInfo="wfInfo"
401
- :current_prefix="current_prefix"></setCandidateDialog>
402
- </div>
403
- </template>
404
- <script>
405
- import Vue from "vue";
406
-
407
- import settingConfig from "@/settings";
408
- import commonMixin from "../../../mixins/mobile/common/index";
409
- import {getToken} from "../../../utils/auth";
410
- import {isWfTransferEnabled, loadWfTransferEnabled} from "../../wf/wfTransferEnabled";
411
-
412
- let configUtil = {
413
- baseUrl: process.env.VUE_APP_BASE_API,
414
- getToken,
415
- settingConfig,
416
- Vue,
417
- };
418
-
419
- function appendPrevChildDom(parentDom, newDom) {
420
- if (parentDom.hasChildNodes()) {
421
- let currentDom = parentDom.children[0];
422
- parentDom.insertBefore(newDom, currentDom);
423
- } else {
424
- parentDom.append(newDom);
425
- }
426
- }
427
-
428
- function getTarget(t) {
429
- return t.parentVue;
430
- }
431
-
432
- export default {
433
- mixins: [commonMixin],
434
- props: {
435
- _wfInfo: Object,
436
- _taskParam: Object,
437
- wfOption: Object,
438
- defaultShowWfContent: Boolean,
439
- // 见模板里 .flowPath-btns 的注释:宿主接管审批动作时藏掉面板内那一排
440
- hideActions: Boolean,
441
- },
442
- components: {
443
- /* 本组件根节点就是 <h5-card-pane>,但此前没在这里注册——手写移动页是靠
444
- mixins/mobile/common 在**宿主**上局部注册才碰巧能渲染。Vue 2 解析组件只查
445
- 自身 components 与全局注册、不查父组件的局部注册,所以被别处(如 xform 的
446
- detail-h5-item)引用时会渲染不出来。补上自己的依赖声明。 */
447
- h5CardPane: () => import('../h5Card/h5CardPane.vue'),
448
- /* 选用户弹层用包内的 selectUserDialog(el-dialog + append-to-body 版)。
449
- 原来引的 views/mobile/user/user/dialog.vue 仍是 .pop-box 就地渲染版,
450
- 且 src/views 不随包发布(被包内组件引用属隐式依赖),保持原样不动。 */
451
- UserDialog: () => import('./selectUserDialog.vue'),
452
- urgingDialog: () => import('./urgingDialog'),
453
- deleteTaskUserDialog: () => import('./deleteTaskUserDialog'),
454
- addTaskUserdialog: () => import('./addTaskUserdialog'),
455
- setCandidateDialog: () => import('./setCandidateDialog')
456
- },
457
- computed: {
458
- current_prefix() {
459
- return this.serviceId ? "/" + this.serviceId : "";
460
- },
461
- viewTarget() {
462
- return getTarget(this);
463
- },
464
- isHideWf() {
465
- let that = this.viewTarget;
466
- let _hideWf = that._hideWf || that.$attrs._hideWf;
467
- return _hideWf === true || _hideWf === 'true';
468
- },
469
- transferEnabled() {
470
- return isWfTransferEnabled();
471
- }
472
- },
473
- data() {
474
- let showWfFold =
475
- settingConfig.showWfFold != null && settingConfig.showWfFold != undefined
476
- ? settingConfig.showWfFold
477
- : false;
478
- let showWfContent =
479
- showWfFold &&
480
- settingConfig.defaultShowWfContent != null &&
481
- settingConfig.defaultShowWfContent != undefined
482
- ? settingConfig.defaultShowWfContent
483
- : true;
484
- if (
485
- this.defaultShowWfContent != null &&
486
- this.defaultShowWfContent != undefined
487
- ) {
488
- showWfContent = this.defaultShowWfContent;
489
- }
490
-
491
- return {
492
- showRenwuDialog: false,
493
- showDomContent: false,
494
- showPreviewDialog: false,
495
- objId: null,
496
- wfCode: null,
497
- serviceId: null,
498
- parentVue: null,
499
- wfConfig: null,
500
-
501
- fileInfos: [],
502
- showUserDialog: false,
503
- showContent: true,
504
- objTypeCode: "",
505
- // objId: '',
506
- wfInfo: {},
507
- // currentTask: {},
508
- taskParam: {},
509
- wfImage: "",
510
- wfStartBtn: false,
511
- wfManualendBtn: false,
512
- wfSubmitBtn: false,
513
- wfRejectBtn: false,
514
- changeHandlerBtn: false,
515
- wftaskData: [],
516
- allWfTaskOpinions: [],
517
- vxeOption: {},
518
- rejectNodes: [],
519
- rejectDialogVisible: false,
520
- rejectForm: {
521
- rejectSubmitModel: null,
522
- nodeId: null,
523
- opinion: null,
524
- },
525
- formLabelWidth: "120px",
526
- agreeDialogVisible: false,
527
- agreeForm: {
528
- opinion: this.$t2('同意', 'components.wf.defaultAgreeOption'),
529
- nodeId: null,
530
- },
531
- changeWfDialogVisible: false,
532
- changeWfForm: {},
533
- changeUserRows: [],
534
- taskStatuses: {
535
- start: {
536
- class: "blue",
537
- value: this.$t2('开始', 'components.wf.startStatus'),
538
- },
539
- approve: {
540
- class: "orgn",
541
- value: this.$t2('待审批', 'components.wf.approveStatus'),
542
- },
543
- submit: {
544
- class: "green",
545
- value: this.$t2('同意', 'components.wf.submitStatus'),
546
- },
547
- reject: {
548
- class: "red",
549
- value: this.$t2('驳回', 'components.wf.rejectStatus'),
550
- },
551
- transfer: {
552
- class: "green",
553
- value: this.$t2('转办', 'components.wf.transferStatus'),
554
- },
555
- addIncreaseSign: {
556
- class: "green",
557
- value: this.$t2('加签', 'components.wf.addIncreaseSignStatus'),
558
- },
559
- revoke: {
560
- class: "red",
561
- value: this.$t2('撤回', 'components.wf.revokeStatus'),
562
- },
563
- end: {
564
- class: "gray",
565
- value: this.$t2('结束', 'components.wf.endStatus'),
566
- },
567
- },
568
- opinion: "",
569
- showWfFold: showWfFold,
570
- showWfContent: showWfContent,
571
-
572
- urgingForm: {},
573
- urgingDialogVisible: false,
574
- urgingUserIds: [],
575
- urgingUsers: [],
576
- agreeNodes: [],
577
- showWfManualDialog: false,
578
-
579
- showDeleteTaskUserDialog: false,
580
- showAddTaskUserDialog: false,
581
- wfUserParam: {},
582
- wfUserParamForTransfer: {},//转办
583
- wfUserParamForAddSign: {},//加签
584
- wfUserParamForTalk: {},//沟通
585
- tabIndex: "1",
586
- linkupOption: {},
587
- talkForm: {
588
- receiverName: null,
589
- content: null,
590
- attachmentDTOs: [],
591
- replyId: null
592
- },
593
- showTalkUserDialog: false,
594
- showTalkDialog: false,
595
- showFlowImg: true,
596
- operateType: null,
597
- addIncreaseSignUsers: [],
598
- addIncreaseSignForm: {
599
- userNickNames: null,
600
- opinion: null
601
- },
602
- showAddIncreaseSignDialog: false,
603
- showOpeaImg: true,
604
- showSetCandidateDialog: false,
605
- toTalk: false,
606
- showAllWfOpinon: false,
607
-
608
- revokeDialogVisible: false,
609
- revokeForm: {opinion: null},
610
- wfStatusMap: {
611
- 1: {label: "审核中", type: "warning"},
612
- 3: {label: "已驳回", type: "danger"},
613
- 2: {label: "已完成", type: "success"}
614
- }
615
- };
616
- },
617
- provide() {
618
- return {
619
- getParentVue: () => {
620
- return this.parentVue;
621
- }
622
- };
623
- },
624
- created() {
625
- // this.wfInfo = this._wfInfo;
626
- this.showFlowImg = settingConfig.expandWfImage === false ? false : true;
627
- this.showAllWfOpinon = settingConfig.showAllWfOpinon === true;
628
- },
629
- mounted() {
630
- this.init();
631
- },
632
- methods: {
633
- fitWorkflowPreview() {
634
- /* warm-flow-ui 是独立 iframe,窄屏下默认画布宽于视口,左右节点会被
635
- 它自己的 overflow:hidden 裁掉。复用其「自适应」能力,在数据逐步
636
- 渲染的几个时点重新 fit;跨域部署时访问 document 会抛错,静默跳过。 */
637
- [0, 300, 800, 1500].forEach((delay) => {
638
- window.setTimeout(() => {
639
- try {
640
- const frame = this.$refs.wfPreviewFrame;
641
- const buttons = frame?.contentDocument?.querySelectorAll("button") || [];
642
- const fitButton = Array.from(buttons).find(
643
- (button) => button.textContent.trim() === "自适应"
644
- );
645
- fitButton?.click();
646
- } catch (e) {
647
- // 跨域 iframe 无法读取内部 DOM,保留 warm-flow-ui 原有交互。
648
- }
649
- }, delay);
650
- });
651
- },
652
- getWfStatusLabel() {
653
- return this.wfStatusMap[this.wfInfo.stat]?.label;
654
- },
655
- getWfStatusType() {
656
- return this.wfStatusMap[this.wfInfo.stat]?.type;
657
- },
658
- init() {
659
- let opt = this.wfOption;
660
- this.objId = opt.objId;
661
- this.wfCode = opt.wfCode;
662
- this.serviceId = opt.serviceId;
663
- this.parentVue = opt.parentVue;
664
- this.wfConfig = this.wfOption;
665
-
666
- let wfConfig = this.wfOption;
667
- let that = getTarget(this);
668
- let hasWf = false;
669
- let wfInfo, currentTask, taskParam;
670
- let option = {
671
- objId: this.objId,
672
- wfCode: this.wfCode
673
- }
674
- let current_prefix = this.current_prefix;
675
-
676
- let initButton = () => {
677
- /*return
678
- this.$nextTick(() => {
679
- that.$refs.wfButtonGroup.init({
680
- taskParam,
681
- wfInfo,
682
- hasWf,
683
- current_prefix,
684
- wfConfig
685
- });
686
- });*/
687
- }
688
-
689
- this.initWfInfo(option, {
690
- success: res => {
691
- if (res.objx && res.objx.procInstId) {
692
- hasWf = true;
693
- wfInfo = res.objx;
694
- this.wfInfo = wfInfo;
695
- // this.showDomContent = true;
696
-
697
- if (wfInfo.taskId) {
698
- this.getTaskParams(wfInfo.taskId, {
699
- success: res2 => {
700
- taskParam = res2.objx || {};
701
- taskParam.objId = option.objId;
702
- this.taskParam = taskParam;
703
-
704
- initButton();
705
- }
706
- });
707
- } else {
708
- initButton();
709
- }
710
- this.initOperateType();
711
- this.initForAll();
712
- } else {
713
- initButton();
714
- }
715
- }
716
- });
717
- },
718
- initWfInfo(option, httpConfig) {
719
-
720
- let that = getTarget(this);
721
- let id = option.objId;
722
- let code = option.wfCode;
723
- return that.$http({
724
- url: this.current_prefix + '/wf/getWfInfo',
725
- method: `post`,
726
- data: {
727
- objTypeCode: code,
728
- objId: id
729
- },
730
- isLoading: true,
731
- modalStrictly: true,
732
- ...httpConfig
733
- });
734
- },
735
- getTaskParams(taskId, httpConfig) {
736
- let that = getTarget(this);
737
- return that.$http({
738
- url: this.current_prefix + '/wf/getTaskVariables',
739
- method: `post`,
740
- data: {
741
- stringOne: taskId
742
- },
743
- isLoading: true,
744
- modalStrictly: true,
745
- ...httpConfig
746
- });
747
- },
748
-
749
-
750
- initOperateType() {
751
- if (this.operateType) {
752
- let wfInfo = this.wfInfo;
753
- if (wfInfo.toSubmit) {
754
- this.openAgreeDialog('submit');
755
- } else if (wfInfo.toReject) {
756
- this.rejectWfTask('reject');
757
- } else if (wfInfo.toAddIncreaseSign) {
758
- this.openAddIncreaseSign('addIncreaseSign')
759
- } else if (wfInfo.toRevoke) {
760
- this.openRevokeDialog('revoke')
761
- } else if (wfInfo.toLinkup) {
762
- this.openTalkDialog(null, null, 'talk');
763
- } else {
764
- this.operateType = null;
765
- }
766
- }
767
- },
768
- initForAll() {
769
- let that = getTarget(this);
770
- loadWfTransferEnabled(that);
771
- this.initWf(() => {
772
- if (this.wfInfo.procInstId) {
773
- this.initCurrentTask(this.wfInfo.procInstId, () => {
774
- this.initWftask(this.wfInfo.procInstId);
775
- this.getAllWfTaskOpinions();
776
- });
777
- this.initWfUserParam();
778
- this.initTabIndex();
779
- }
780
- });
781
- },
782
- initTabIndex() {
783
- let that = getTarget(this);
784
- that.$http({
785
- url: USER_PREFIX + "/wf_diy_attribute/getValue",
786
- method: `post`,
787
- data: {attributeKey: "param7"},
788
- isLoading: true,
789
- success: (res) => {
790
- let val = res !== null ? res.objx === true : false;
791
- this.toTalk = val;
792
- let flag = false;
793
- if (val) {
794
- let flag1 = that.$attrs._isNotifyMessage == true || that.$attrs._isNotifyMessage == "true";
795
- if (flag1) {
796
- this.tabIndex = "2";
797
- }
798
- if (settingConfig.autoOpenWfLinkup) {
799
- flag = true;
800
- let flag2 = that.$attrs._wfNotifyType == "wfLinkup";
801
- let flag3 = flag1 && flag2;
802
- if (flag3) {
803
- this.$nextTick(() => {
804
- let wfTabPane = this.$refs.wfTabPane;
805
- if (!wfTabPane.showContent) {
806
- wfTabPane.handleFold();
807
- }
808
- });
809
- }
810
- }
811
- }
812
- this.initLinkup(flag);
813
- }
814
- });
815
-
816
- },
817
- initWf(done) {
818
- var data = this.wfInfo;
819
- if (data && data.procInstId) {
820
- /** 流程状态:0未启动,1审核中,2已完成,3驳回,4中断 */
821
- var statuses = {
822
- 1: '<span class="tag">' + this.$t2('审核中', 'components.wf.wfStatus1') + '</span>',
823
- 3: '<span class="tag red">' + this.$t2('已驳回', 'components.wf.wfStatus2') + '</span>',
824
- 2: '<span class="tag green">' + this.$t2('已完成', 'components.wf.wfStatus3') + '</span>',
825
- };
826
- var statusStr = "";
827
- if (data.stat != null) {
828
- statusStr = statuses[data.stat] || "";
829
- }
830
- data.statusStr = statusStr;
831
- this.wfInfo = data;
832
-
833
- this.wfStartBtn = false;
834
- if (data.status != 2 && data.starterId) {
835
- this.wfManualendBtn = true;
836
- }
837
- this.wfSubmitBtn = false;
838
- this.wfRejectBtn = false;
839
-
840
- var url =
841
- this.current_prefix +
842
- "/wf/flowImage?procInstId=" +
843
- data.procInstId +
844
- "&_r=" +
845
- Math.random() +
846
- "&access_token=" +
847
- configUtil.getToken();
848
- this.wfImage = configUtil.baseUrl + url;
849
- done();
850
- }
851
- },
852
- initCurrentTask(procInstId, done) {
853
- if (this.wfInfo.taskId) {
854
- this.wfSubmitBtn = true;
855
- this.wfRejectBtn = true;
856
- this.changeHandlerBtn = true;
857
- }
858
- done();
859
- },
860
- initWftask(procInstId) {
861
- let that = getTarget(this);
862
- that.$http({
863
- url: this.current_prefix + "/wf/getWfTaskOpinionMerge",
864
- data: {
865
- stringOne: procInstId,
866
- },
867
- method: "post",
868
- isLoading: true,
869
- modalStrictly: true,
870
- success: (resultmsg) => {
871
- var datas = resultmsg.objx || [];
872
- this.wftaskData = datas;
873
- },
874
- });
875
- },
876
- getAllWfTaskOpinions() {
877
- if (!this.showAllWfOpinon) {
878
- return;
879
- }
880
- let that = getTarget(this);
881
- let wfInfo = this.wfInfo;
882
- that.$http({
883
- url: this.current_prefix + "/wf/getAllWfTaskOpinions",
884
- data: {
885
- objId: wfInfo.objId,
886
- objTypeCode: wfInfo.objTypeCode
887
- },
888
- method: "post",
889
- isLoading: true,
890
- modalStrictly: true,
891
- success: (resultmsg) => {
892
- var datas = resultmsg.objx || [];
893
- this.allWfTaskOpinions = datas;
894
- },
895
- });
896
- },
897
- openManualDialog(operateType) {
898
- this.operateType = operateType;
899
- this.showWfManualDialog = true;
900
- },
901
- manualEndWf() {
902
- this.showWfManualDialog = false;
903
- let that = getTarget(this);
904
- var procInstId = this.wfInfo.procInstId;
905
- var taskId = this.wfInfo.taskId ? this.wfInfo.taskId : "";
906
- var data = JSON.stringify({
907
- uuid: this.wfInfo.uuid,
908
- });
909
- that.$http({
910
- url: this.current_prefix + "/wf/interrupt",
911
- data: data,
912
- method: "post",
913
- headers: {
914
- "Content-Type": "application/json;charset=utf-8",
915
- },
916
- isLoading: true,
917
- success: (resultMsg) => {
918
- that.$message({
919
- message: resultMsg.content,
920
- type: "success",
921
- duration: 500,
922
- onClose: (t) => {
923
- this.reloadContent();
924
- this.closeWinOnCheck(3);
925
- },
926
- });
927
- },
928
- });
929
- },
930
- async rejectWfTask(operateType) {
931
- // 与 PC wf.js 的 rejectWfTask 同结构:驳回也要先过一遍「驳回提醒」
932
- this.handleReminderContent("rejectReminder", async () => {
933
- let that = getTarget(this);
934
- var procInstId = this.wfInfo.procInstId;
935
- var taskId = this.wfInfo.taskId;
936
- var destinations = [];
937
-
938
- await that.$http({
939
- url: this.current_prefix + "/wf/getPreIncomeNodes",
940
- data: {
941
- stringOne: taskId,
942
- },
943
- method: "post",
944
- //contentType: 'application/json;charset=utf-8',
945
- isLoading: true,
946
- success: (resultMsg) => {
947
- destinations = (resultMsg.objx || []).reverse();
948
- },
949
- });
950
-
951
- if (destinations == null) {
952
- return false;
953
- }
954
- if (destinations.length == 0) {
955
- that.$message({
956
- message: this.$t2('无法驳回,没有目标节点', 'components.wf.rejectWarnMsg1'),
957
- type: "error",
958
- duration: 2 * 1000,
959
- });
960
- return false;
961
- }
962
- this.operateType = operateType;
963
-
964
- /* 驳回后提交模式,取自流程对象配置(wf_obj_config「驳回后提交模式」三选一):
965
- toNextNode === 1 → 顺延下一步提交 → 1
966
- toRejectNode false → 直接提交到驳回节点 → 2
967
- toRejectNode true → 由提交人确定节点提交 → null(提交时自己选)
968
- 三个分支不能省成两个:选了「顺延下一步」时后台把 toRejectNode 置为 null,
969
- 而 null == false 在 JS 里是 false,会落到 null 分支上,配置被静默丢掉。
970
- 与 PC wf.js 的 rejectWfTask 同口径。 */
971
- let rejectSubmitModel = null;
972
- if (this.wfInfo.toNextNode === 1) {
973
- rejectSubmitModel = this.wfInfo.toNextNode
974
- } else {
975
- rejectSubmitModel = this.wfInfo.toRejectNode == false ? 2 : null
976
- }
977
- this.rejectForm.rejectSubmitModel = rejectSubmitModel;
978
- this.rejectForm.nodeId = destinations[0].nodeId;
979
- this.rejectForm.opinion = "";
980
- this.rejectNodes = destinations;
981
- this.rejectDialogVisible = true;
982
- })
983
- },
984
- subRejectForm() {
985
- let that = getTarget(this);
986
- var procInstId = this.wfInfo.procInstId;
987
- var taskId = this.wfInfo.taskId;
988
-
989
- if (!this.rejectForm.nodeId) {
990
- that.$message({
991
- message: this.$t2('请选择驳回节点', 'components.wf.rejectWarnMsg2'),
992
- type: "error",
993
- duration: 2 * 1000,
994
- });
995
- return false;
996
- }
997
-
998
- if (!this.rejectForm.opinion) {
999
- that.$message({
1000
- message: this.$t2('请输入驳回意见', 'components.wf.rejectWarnMsg3'),
1001
- type: "error",
1002
- duration: 2 * 1000,
1003
- });
1004
- return false;
1005
- }
1006
-
1007
- var data = JSON.stringify({
1008
- taskId: taskId,
1009
- uuid: this.wfInfo.uuid,
1010
- nodeId: this.rejectForm.nodeId,
1011
- suggestion: this.rejectForm.opinion,
1012
- rejectSubmitModel: this.rejectForm.rejectSubmitModel
1013
- });
1014
- this.rejectDialogVisible = false;
1015
- that.$http({
1016
- url: this.current_prefix + "/wf/reject",
1017
- data: data,
1018
- method: "post",
1019
- headers: {
1020
- "Content-Type": "application/json;charset=utf-8",
1021
- },
1022
- isLoading: true,
1023
- success: (resultMsg) => {
1024
- that.$message({
1025
- message: resultMsg.content,
1026
- type: "success",
1027
- duration: 500,
1028
- onClose: (t) => {
1029
- this.reloadContent();
1030
- this.closeWinOnCheck(2);
1031
- },
1032
- });
1033
- },
1034
- });
1035
- },
1036
- /**
1037
- * 提交/驳回前的「提醒内容」:后台按 scriptType 跑脚本,返回文案就先弹确认框,
1038
- * 用户点确定才继续;没有文案(或接口 404,即后端未部署该能力)直接放行。
1039
- * 与 PC wf.js 的同名方法保持一致。
1040
- *
1041
- * 提醒只是主流程前面的一道增强,不能让它把主流程带崩或卡死,所以:
1042
- * - 放行只允许一次(go 自带闸门),成功/异常各分支共用一个出口;
1043
- * - 确认框点取消 = 放弃本次操作,什么都不做,但 MessageBox 的 reject 必须吃掉,
1044
- * 否则是一条 unhandled rejection;
1045
- * - error 分支绝不能抛异常。request.js 是先调 config.error(e) 再 removeModel(config)
1046
- * (见 utils/request.js 的响应错误拦截),这里一抛,isLoading 的全屏遮罩就永远
1047
- * 关不掉、整页被锁死。而网络失败/超时时 e.response 本就是 undefined,
1048
- * 老写法 e.response.status 必崩 —— 故 status 取值全程判空。
1049
- */
1050
- handleReminderContent(scriptType, callback) {
1051
- let that = getTarget(this);
1052
- let called = false;
1053
- const go = () => {
1054
- if (called) return
1055
- called = true;
1056
- callback && callback();
1057
- };
1058
- that.$http({
1059
- url: this.current_prefix + "/wf/getReminderContent",
1060
- data: {
1061
- scriptType,
1062
- taskId: this.wfInfo.taskId,
1063
- uuid: this.wfInfo.uuid,
1064
- },
1065
- method: "post",
1066
- isLoading: true,
1067
- errorMsg: false,
1068
- success: (res) => {
1069
- if (res && res.objx) {
1070
- that.$baseConfirm(res.objx).then(go).catch(() => {});
1071
- } else {
1072
- go();
1073
- }
1074
- },
1075
- error: (e) => {
1076
- let status = e && e.response ? e.response.status : null;
1077
- if (status === 404) {
1078
- // 后端没部署这个接口,等同于「没有提醒」,静默放行
1079
- go();
1080
- return
1081
- }
1082
- /* 其余错误只提示不放行:提醒内容可能是必须让人看到的业务警告,
1083
- 接口挂了就悄悄跳过等于把它吞掉。用户重试即可。 */
1084
- that.$errorMsg({
1085
- content: (e && e.message) || this.$t2('获取提醒内容失败', 'components.wf.reminderError'),
1086
- type: 'error',
1087
- }).catch(() => {});
1088
- },
1089
- });
1090
- },
1091
- openAgreeDialog(operateType) {
1092
- const done = () => {
1093
- this.handleReminderContent("submitReminder", () => {
1094
- this.operateType = operateType;
1095
- let that = getTarget(this);
1096
- this.agreeForm = {
1097
- opinion: this.$t2('同意', 'components.wf.defaultAgreeOption'),
1098
- nodeId: null,
1099
- };
1100
- this.agreeNodes = [];
1101
- that.$http({
1102
- url: this.current_prefix + "/wf/getNextOutgoingNodes",
1103
- data: {
1104
- stringOne: this.wfInfo.taskId,
1105
- },
1106
- method: "post",
1107
- isLoading: true,
1108
- success: (res) => {
1109
- let nodes = res.objx || [];
1110
- /*if (tq == true) {
1111
- nodes.reverse();
1112
- }*/
1113
- if (nodes.length) {
1114
- this.agreeForm.nodeId = nodes[0].nodeId;
1115
- }
1116
- this.agreeNodes = nodes;
1117
- this.agreeDialogVisible = true;
1118
- },
1119
- });
1120
- })
1121
- }
1122
- // wfConfig 在 init() 里才赋值(初值 null),这里兜一层空对象
1123
- let wfConfig = this.wfConfig || {};
1124
- if (wfConfig.onClickAgree) {
1125
- wfConfig.onClickAgree(done)
1126
- } else {
1127
- done();
1128
- }
1129
- },
1130
- subAgreeForm() {
1131
- let wfConfig = this.wfConfig;
1132
- let done = () => {
1133
- this.subAgreeHandle();
1134
- }
1135
- if (wfConfig.onBeforeAgree) {
1136
- wfConfig.onBeforeAgree(done)
1137
- } else {
1138
- done();
1139
- }
1140
- },
1141
- subAgreeHandle() {
1142
- let that = getTarget(this);
1143
- let nodeId = null;
1144
- if (this.agreeNodes.length) {
1145
- if (!this.agreeForm.nodeId) {
1146
- that.$message({
1147
- message: this.$t2('请选择节点', 'components.wf.agreeWarnMsg1'),
1148
- type: "error",
1149
- duration: 2 * 1000,
1150
- });
1151
- return;
1152
- }
1153
- nodeId = this.agreeForm.nodeId;
1154
- }
1155
-
1156
- var procInstId = this.wfInfo.procInstId;
1157
- var taskId = this.wfInfo.taskId;
1158
- var memo = this.agreeForm.opinion || this.$t2('同意', 'components.wf.defaultAgreeOption');
1159
- var data = JSON.stringify({
1160
- taskId: taskId,
1161
- uuid: this.wfInfo.uuid,
1162
- suggestion: memo,
1163
- nodeId: nodeId,
1164
- });
1165
- this.agreeDialogVisible = false;
1166
- that.$http({
1167
- url: this.current_prefix + "/wf/submit",
1168
- data: data,
1169
- method: "post",
1170
- headers: {
1171
- "Content-Type": "application/json;charset=utf-8",
1172
- },
1173
- isLoading: true,
1174
- success: (resultMsg) => {
1175
- if (resultMsg.objx && resultMsg.objx.code == "999999") {
1176
- this.errorSubmit({
1177
- taskId: taskId,
1178
- uuid: this.wfInfo.uuid,
1179
- suggestion: memo,
1180
- errorMsg: resultMsg.objx.errorMsg
1181
- });
1182
- } else {
1183
- that.$message({
1184
- message: resultMsg.content,
1185
- type: "success",
1186
- duration: 500,
1187
- onClose: (t) => {
1188
- this.reloadContent();
1189
- this.closeWinOnCheck(1);
1190
- },
1191
- });
1192
- }
1193
- },
1194
- });
1195
- },
1196
- errorSubmit(data) {
1197
- let that = getTarget(this);
1198
- that.$http({
1199
- url: this.current_prefix + "/wf/errorSubmit",
1200
- data: data,
1201
- method: "post",
1202
- isLoading: true,
1203
- success: (resultMsg) => {
1204
- that.$message({
1205
- message: resultMsg.content,
1206
- type: "success",
1207
- duration: 500,
1208
- onClose: (t) => {
1209
- this.reloadContent();
1210
- this.closeWinOnCheck(1);
1211
- },
1212
- });
1213
- },
1214
- });
1215
- },
1216
- openChangeWfForm(operateType) {
1217
- this.operateType = operateType;
1218
- this.changeWfDialogVisible = true;
1219
- this.changeUserRows = [];
1220
- this.changeWfForm = {
1221
- userIds: [],
1222
- userNickNames: null,
1223
- opinion: null,
1224
- };
1225
- },
1226
- subChangeWfForm() {
1227
- let that = getTarget(this);
1228
- var procInstId = this.wfInfo.procInstId;
1229
- var taskId = this.wfInfo.taskId;
1230
-
1231
- var userIds = this.changeWfForm.userIds || [];
1232
- var opinion = this.changeWfForm.opinion || null;
1233
-
1234
- if (!userIds.length) {
1235
- that.$message({
1236
- message: this.$t2('请选择转办人', 'components.wf.transferWarnMsg1'),
1237
- type: "error",
1238
- duration: 2000,
1239
- onClose: (t) => {
1240
- },
1241
- });
1242
- return false;
1243
- }
1244
-
1245
- var data = JSON.stringify({
1246
- taskId: taskId,
1247
- uuid: this.wfInfo.uuid,
1248
- transferTo: userIds,
1249
- suggestion: opinion,
1250
- });
1251
- this.changeWfDialogVisible = false;
1252
- that.$http({
1253
- url: this.current_prefix + "/wf/transfer",
1254
- data: data,
1255
- method: "post",
1256
- headers: {
1257
- "Content-Type": "application/json;charset=utf-8",
1258
- },
1259
- isLoading: true,
1260
- success: (resultMsg) => {
1261
- that.$message({
1262
- message: resultMsg.content,
1263
- type: "success",
1264
- duration: 500,
1265
- onClose: (t) => {
1266
- this.reloadContent();
1267
- this.closeWinOnCheck(4);
1268
- },
1269
- });
1270
- },
1271
- });
1272
- },
1273
- userConfirm(rows) {
1274
- if (rows.length > 0) {
1275
- let changeUserRows = this.changeUserRows;
1276
- let ids = changeUserRows.map((changeUserRow) => changeUserRow.id);
1277
- let addRows = rows.filter((row) => !ids.includes(row.id));
1278
- changeUserRows.push(...addRows);
1279
-
1280
- let row = rows[0];
1281
- this.changeWfForm.userIds = changeUserRows.map(
1282
- (changeUserRow) => changeUserRow.id
1283
- );
1284
- this.changeWfForm.userNickNames = changeUserRows
1285
- .map((changeUserRow) => changeUserRow.nickName)
1286
- .join(",");
1287
- }
1288
- },
1289
- reloadContent() {
1290
- let that = getTarget(this);
1291
- that.$baseReload();
1292
- },
1293
- closeWinOnCheck(flag) {
1294
- //_closeWindowOnCheck=true, 1提交,2驳回,3中断,4转办时,5沟通 关闭窗口
1295
- let that = getTarget(this);
1296
- let _closeWindowOnCheck = that.$attrs._closeWindowOnCheck || that._closeWindowOnCheck;
1297
- if (_closeWindowOnCheck === true || _closeWindowOnCheck === "true") {
1298
- window.close && window.close();
1299
- }
1300
- let _handleCallback = that.$attrs._handleCallback || that._handleCallback;
1301
- _handleCallback && _handleCallback(flag);
1302
- },
1303
- manualCallback() {
1304
- this.$emit("manualCallback");
1305
- },
1306
- openUrgingDialog(operateType) {
1307
- this.operateType = operateType;
1308
- this.urgingDialogVisible = true;
1309
- },
1310
- openDeleteTaskUserDialog(operateType) {
1311
- this.operateType = operateType;
1312
- this.showDeleteTaskUserDialog = true;
1313
- },
1314
- openAddTaskUserDialog(operateType) {
1315
- this.operateType = operateType;
1316
- this.showAddTaskUserDialog = true;
1317
- },
1318
- openAddIncreaseSign(operateType) {
1319
- this.operateType = operateType;
1320
- this.addIncreaseSignUsers = [];
1321
- this.addIncreaseSignForm = {userNickNames: null};
1322
- this.showAddIncreaseSignDialog = true;
1323
- },
1324
- initWfUserParam(callback) {
1325
- this.initTransferUserParam();//转办
1326
- this.initAddSignUserParam();//加签
1327
- this.initTalkUserParam();//沟通
1328
- },
1329
- //
1330
- initTransferUserParam(callback) {
1331
- //初始化转办用户参数
1332
- let that = getTarget(this);
1333
- return that.$http({
1334
- url: USER_PREFIX + "/wf_diy_attribute/getValue",
1335
- method: `post`,
1336
- data: {attributeKey: "param1"},
1337
- isLoading: true,
1338
- modalStrictly: true,
1339
- success: (res) => {
1340
- this.wfUserParamForTransfer = res.objx || {};
1341
- callback && callback();
1342
- },
1343
- });
1344
- },
1345
- initAddSignUserParam(callback) {
1346
- //初始化加签用户参数
1347
- let that = getTarget(this);
1348
- return that.$http({
1349
- url: USER_PREFIX + "/wf_diy_attribute/getValue",
1350
- method: `post`,
1351
- data: {attributeKey: "param2"},
1352
- isLoading: true,
1353
- modalStrictly: true,
1354
- success: (res) => {
1355
- this.wfUserParamForAddSign = res.objx || {};
1356
- callback && callback();
1357
- },
1358
- });
1359
- },
1360
- initTalkUserParam(callback) {
1361
- //初始化沟通用户参数
1362
- let that = getTarget(this);
1363
- return that.$http({
1364
- url: USER_PREFIX + "/wf_diy_attribute/getValue",
1365
- method: `post`,
1366
- data: {attributeKey: "param3"},
1367
- isLoading: true,
1368
- modalStrictly: true,
1369
- success: (res) => {
1370
- this.wfUserParamForTalk = res.objx || {};
1371
- callback && callback();
1372
- },
1373
- });
1374
- },
1375
- //
1376
- resetLinkup() {
1377
- this.formData = {};
1378
- this.$refs["table-linkup"].commitProxy("reload");
1379
- },
1380
- searchLinkup() {
1381
- this.$refs["table-linkup"].commitProxy("reload");
1382
- },
1383
- initLinkup(flag) {
1384
- return
1385
- let h = this.$createElement;
1386
- let statusMap = {
1387
- 0: this.$t2('未完成', 'components.wf.talkStatus0'),
1388
- 1: this.$t2('已完成', 'components.wf.talkStatus1'),
1389
- 2: this.$t2('已取消', 'components.wf.talkStatus2')
1390
- };
1391
- let tableOption = {
1392
- vue: this,
1393
- tableRef: "table-linkup",
1394
- tableName: "wf_table-linkup",
1395
- path: this.current_prefix + "/wf_linkup/listPage",
1396
- param: () => {
1397
- return {
1398
- uuid: this.wfInfo.uuid,
1399
- };
1400
- },
1401
- config: {
1402
- height: 350
1403
- },
1404
- columns: [
1405
- {type: "checkbox", width: 48, resizable: false, fixed: "left"},
1406
- {
1407
- title: this.$t2('任务名称', 'components.wf.taskName'),
1408
- field: "taskName",
1409
- width: 150,
1410
- fixed: "left",
1411
- },
1412
- {
1413
- title: this.$t2('发送人', 'components.wf.senderName'),
1414
- field: "senderName",
1415
- width: 150,
1416
- slots: {
1417
- default: "sender",
1418
- },
1419
- },
1420
- {
1421
- title: this.$t2('接收人', 'components.wf.receiverName'),
1422
- field: "receiverName",
1423
- width: 150,
1424
- slots: {
1425
- default: "receiver",
1426
- },
1427
- },
1428
- {
1429
- title: this.$t2('沟通内容', 'components.wf.talkContent'),
1430
- field: "content",
1431
- width: 250,
1432
- showOverflow: false,
1433
- slots: {
1434
- default: ({row, rowIndex}) => {
1435
- return row.replyId ? ("[" + this.$t2('回复', 'components.wf.reply') + "]" + row.content) : row.content;
1436
- },
1437
- },
1438
- },
1439
- {
1440
- width: 150,
1441
- title: this.$t2('沟通资料', 'components.wf.talkAttachment'),
1442
- field: "attachmentImage",
1443
- sortable: false,
1444
- slots: {
1445
- default: ({row, rowIndex}) => {
1446
- let option = {
1447
- title: this.$t2('沟通资料', 'components.wf.talkAttachment'),
1448
- edit: false,
1449
- rows: (done) => {
1450
- done(row.attachmentDTOs);
1451
- },
1452
- };
1453
- return [
1454
- h("base-attachment", {
1455
- props: {
1456
- option: option,
1457
- },
1458
- }),
1459
- ];
1460
- },
1461
- },
1462
- },
1463
-
1464
- {
1465
- title: this.$t2('状态', 'components.wf.status'),
1466
- field: "status",
1467
- width: 150,
1468
- slots: {
1469
- default: ({row, rowIndex}) => {
1470
- return statusMap[row.status] || "";
1471
- },
1472
- },
1473
- },
1474
- {
1475
- title: this.$t2('创建时间', 'system.label.createDate'),
1476
- field: "createDate",
1477
- width: 150,
1478
- },
1479
- {
1480
- width: 80,
1481
- fixed: "right",
1482
- title: "",
1483
- sortable: false,
1484
- slots: {
1485
- default: "operate"
1486
- }
1487
- },
1488
- ],
1489
- callback: (rows) => {
1490
- if (rows.length && flag) {
1491
- let row = rows[0];
1492
- if (row.replyToSender) {
1493
- this.$nextTick(() => {
1494
- this.tabIndex = "2";
1495
- this.openTalkDialog(row.sender, row.senderName, 'talk', 1, row.id)
1496
- });
1497
- }
1498
- }
1499
- }
1500
- };
1501
- this.$vxeTableUtil.initVxeTable(tableOption).then((opts) => {
1502
- this.linkupOption = opts;
1503
- });
1504
- },
1505
- cancelTalk(row) {
1506
- let that = getTarget(this);
1507
- that.$baseConfirm(this.$t2('您确定要取消沟通记录吗?', 'components.wf.cancelTalkTip')).then(() => {
1508
- that.$http({
1509
- url: this.current_prefix + "/wf_linkup/cancel",
1510
- data: {id: row.id},
1511
- method: "post",
1512
- loadingTarget: document.body,
1513
- isLoading: true,
1514
- success: (resultMsg) => {
1515
- that.$message({
1516
- message: resultMsg.content,
1517
- type: "success",
1518
- duration: 500,
1519
- onClose: (t) => {
1520
- this.reloadContent();
1521
- },
1522
- });
1523
- },
1524
- });
1525
- });
1526
- },
1527
- openTalkDialog(receiver, receiverName, operateType, flag, replyId) {
1528
- this.operateType = operateType;
1529
- /*this.talkForm.receiver = receiver || null;
1530
- this.talkForm.receiverName = receiverName || null;
1531
- this.talkForm.replyId = replyId || null;
1532
- this.talkForm.content = null;
1533
- this.talkForm.attachmentDTOs = [];*/
1534
- this.initTalkForm(receiver, receiverName, replyId)
1535
- this.showTalkDialog = true;
1536
- if (flag == 1) {
1537
- let opeaBtnDom = this.$refs.opeaBtn;
1538
- opeaBtnDom && opeaBtnDom.scrollIntoView();
1539
- }
1540
- },
1541
- initTalkForm(receiver, receiverName, replyId) {
1542
- this.talkForm.receiver = receiver || null;
1543
- this.talkForm.receiverName = receiverName || null;
1544
- this.talkForm.replyId = replyId || null;
1545
- this.talkForm.content = null;
1546
- this.talkForm.attachmentDTOs = [];
1547
- },
1548
- submitTalkForm() {
1549
- let that = getTarget(this);
1550
- var procInstId = this.wfInfo.procInstId;
1551
- var taskId = this.wfInfo.taskId;
1552
-
1553
- if (!this.talkForm.receiver) {
1554
- that.$message({
1555
- message: this.$t2('请选择接收人', 'components.wf.talkWarnMsg1'),
1556
- type: "error",
1557
- duration: 2 * 1000,
1558
- });
1559
- return false;
1560
- }
1561
- if (!this.talkForm.content) {
1562
- that.$message({
1563
- message: this.$t2('请输入沟通内容', 'components.wf.talkWarnMsg2'),
1564
- type: "error",
1565
- duration: 2 * 1000,
1566
- });
1567
- return false;
1568
- }
1569
-
1570
- var data = {
1571
- taskId: taskId,
1572
- uuid: this.wfInfo.uuid,
1573
- receiver: this.talkForm.receiver,
1574
- receiverName: this.talkForm.receiverName,
1575
- replyId: this.talkForm.replyId,
1576
- content: this.talkForm.content,
1577
- attachmentDTOs: this.talkForm.attachmentDTOs,
1578
- notifyType: "wfLinkup",
1579
- };
1580
- this.showTalkDialog = false;
1581
- that.$http({
1582
- url: this.current_prefix + "/wf_linkup/save",
1583
- data: data,
1584
- method: "post",
1585
- isLoading: true,
1586
- success: (resultMsg) => {
1587
- that.$message({
1588
- message: resultMsg.content,
1589
- type: "success",
1590
- duration: 500,
1591
- onClose: (t) => {
1592
- this.reloadContent();
1593
- this.closeWinOnCheck(5);
1594
- },
1595
- });
1596
- },
1597
- });
1598
- },
1599
- openTalkUserDialog() {
1600
- this.showTalkUserDialog = true;
1601
- },
1602
- confirmTalkUserDialog(rows) {
1603
- if (rows.length > 0) {
1604
- let row = rows[0];
1605
- if (this.talkForm.receiver != row.id) {
1606
- this.talkForm.replyId = null;
1607
- }
1608
- this.talkForm.receiver = row.id;
1609
- this.talkForm.receiverName = row.nickName;
1610
- }
1611
- },
1612
- confirmUrging() {
1613
- this.reloadContent();
1614
- },
1615
- confirmDeleteTaskUser() {
1616
- this.reloadContent();
1617
- },
1618
- confirmAddTaskUser(rows) {
1619
- this.addIncreaseSignUsers = rows;
1620
- this.addIncreaseSignForm.userNickNames = rows.map(row => row.nickName).join(',');
1621
- // this.reloadContent();
1622
- },
1623
- submitAddTaskUserForm(flag) {
1624
- let that = getTarget(this);
1625
- let userIds = this.addIncreaseSignUsers.map((checkRow) => checkRow.id);
1626
- if (userIds.length == 0) {
1627
- that.$message({
1628
- message: this.$t2('请选择候选人', 'components.wf.addIncreaseSignWarnMsg1'),
1629
- type: "error",
1630
- duration: 2000,
1631
- onClose: (t) => {
1632
- },
1633
- });
1634
- return false;
1635
- }
1636
- let toDo = () => {
1637
- var data = JSON.stringify({
1638
- uuid: this.wfInfo.uuid,
1639
- taskId: this.wfInfo.taskId,
1640
- userIds: userIds,
1641
- suggestion: this.addIncreaseSignForm.opinion
1642
-
1643
- });
1644
- this.agreeDialogVisible = false;
1645
- that.$http({
1646
- url: this.current_prefix + "/wf/addIncreaseSign",
1647
- data: data,
1648
- method: "post",
1649
- loadingTarget: document.body,
1650
- headers: {
1651
- "Content-Type": "application/json;charset=utf-8",
1652
- },
1653
- isLoading: true,
1654
- success: (resultMsg) => {
1655
- that.$message({
1656
- message: resultMsg.content,
1657
- type: "success",
1658
- duration: 500,
1659
- onClose: (t) => {
1660
- this.reloadContent();
1661
- },
1662
- });
1663
- },
1664
- });
1665
- }
1666
- if (flag === 0) {
1667
- toDo();
1668
- } else {
1669
- that.$baseConfirm(this.$t2('您确定要加签吗?', 'components.wf.addIncreaseSignConfirmTip')).then(() => {
1670
- toDo();
1671
- });
1672
- }
1673
- },
1674
- openSetCandidateDialog(operateType) {
1675
- this.operateType = operateType;
1676
- this.showSetCandidateDialog = true;
1677
- },
1678
- closeSetCandidateDialog() {
1679
- this.showSetCandidateDialog = false;
1680
- this.reloadContent();
1681
- },
1682
- openRevokeDialog(operateType) {
1683
- this.operateType = operateType;
1684
- this.revokeForm = {opinion: null}
1685
- this.revokeDialogVisible = true;
1686
- },
1687
- subRevokeForm(flag) {
1688
- //撤回
1689
- let that = getTarget(this);
1690
- let toDo = () => {
1691
- var data = JSON.stringify({
1692
- uuid: this.wfInfo.uuid,
1693
- taskId: this.wfInfo.taskId,
1694
- suggestion: this.revokeForm.opinion,
1695
- });
1696
- this.revokeDialogVisible = false;
1697
- that.$http({
1698
- url: this.current_prefix + "/wf/revoke",
1699
- data: data,
1700
- method: "post",
1701
- loadingTarget: document.body,
1702
- headers: {
1703
- "Content-Type": "application/json;charset=utf-8",
1704
- },
1705
- isLoading: true,
1706
- success: (resultMsg) => {
1707
- that.$message({
1708
- message: resultMsg.content,
1709
- type: "success",
1710
- duration: 500,
1711
- onClose: (t) => {
1712
- this.reloadContent();
1713
- },
1714
- });
1715
- },
1716
- });
1717
- }
1718
- if (flag === 0) {
1719
- toDo();
1720
- } else {
1721
- that.$baseConfirm(this.$t2('您确定要撤回吗?', 'components.wf.revokeConfirmTip')).then(() => {
1722
- toDo();
1723
- });
1724
- }
1725
- }
1726
- }
1727
- }
1728
- </script>
1729
-
1730
- <style scoped>
1731
- ::v-deep .form-box.el-form .el-form-item .el-form-item__label {
1732
- width: 70px
1733
- }
1734
- </style>
1
+ <template>
2
+ <div>
3
+ <h5-card-pane label="流程信息">
4
+ <template #default>
5
+ <div class="flowPath-box">
6
+ <!-- 这一行的值是 wfInfo.name(流程主题),标签原先误写成「任务情况」——
7
+ 与下面第三行「查看任务情况」重名。PC content.vue 同一个值的标签就是
8
+ 「流程主题」(components.wf.theme)。 -->
9
+ <div class="t"><span>{{ $t2('流程主题', 'components.wf.theme') }}</span></div>
10
+ <div class="c">
11
+ <div class="name">
12
+ {{ (wfInfo.createDate ? wfInfo.createDate.substring(0, 10) : '') + wfInfo.name }}
13
+ <el-tag :type="getWfStatusType()" size="mini">{{ getWfStatusLabel() }}</el-tag>
14
+ </div>
15
+ </div>
16
+ <div class="m2">
17
+ <div class="t"><span>{{ $t2('流程图', 'components.wf.wfImage') }}</span></div>
18
+ <div class="c">
19
+ <el-button class="btn" @click="showPreviewDialog=true" icon="el-icon-view">查看流程图</el-button>
20
+ </div>
21
+ </div>
22
+ <div class="m2">
23
+ <div class="t"><span>{{ $t2('任务情况', 'components.wf.taskInfo') }}</span></div>
24
+ <div class="c">
25
+ <el-button class="btn" @click="showRenwuDialog=true" icon="iconfont icon-preview">查看任务情况
26
+ </el-button>
27
+ </div>
28
+ </div>
29
+
30
+ </div>
31
+ <!-- hideActions:宿主已经把审批动作提到别处(如 xform H5 的底部动作栏)时,
32
+ 这一排整条藏掉,避免一个动作出现两份。与 PC content.vue 的
33
+ headerActionsMounted 同意图,这里做成 prop 是为了没有时序问题。 -->
34
+ <div class="flowPath-btns" v-show="!hideActions">
35
+ <el-button type="success" plain class="btn" @click="openAgreeDialog" v-show="wfInfo.toSubmit"
36
+ icon="iconfont icon-tongguo">{{ $t2('通过', 'components.wf.agree') }}
37
+ </el-button>
38
+ <el-button type="warning" plain class="btn" @click="openManualDialog" v-show="wfInfo.toInterrupt"
39
+ icon="iconfont icon-caozuozhongduan">{{ $t2('中断', 'components.wf.manual') }}
40
+ </el-button>
41
+ <el-button type="danger" plain class="btn" @click="rejectWfTask" v-show="wfInfo.toReject"
42
+ icon="iconfont icon-a-bohui1">{{ $t2('驳回', 'components.wf.reject') }}
43
+ </el-button>
44
+ <el-button type="primary" plain class="btn" @click="openChangeWfForm"
45
+ v-show="transferEnabled && ((wfInfo.toTransfer===null || wfInfo.toTransfer===undefined) ? wfInfo.toSubmit: wfInfo.toTransfer)"
46
+ icon="iconfont icon-zhuanban">{{ $t2('转办', 'components.wf.transfer') }}
47
+ </el-button>
48
+ <el-button type="primary" plain class="btn" @click="openUrgingDialog" v-show="wfInfo.toInterrupt"
49
+ icon="iconfont icon-cuiban">{{ $t2('催办', 'components.wf.urging') }}
50
+ </el-button>
51
+ <el-button type="primary" plain class="btn" @click="openAddIncreaseSign" v-show="wfInfo.toAddIncreaseSign"
52
+ icon="el-icon-plus">{{ $t2('加签', 'components.wf.addIncreaseSign') }}
53
+ </el-button>
54
+ <el-button type="primary" plain class="btn" @click="openDeleteTaskUserDialog"
55
+ v-show="wfInfo.toDeleteIncreaseSign"
56
+ icon="el-icon-delete">{{ $t2('减签', 'components.wf.deleteIncreaseSign') }}
57
+ </el-button>
58
+ <el-button type="primary" plain class="btn" @click="openTalkDialog()"
59
+ icon="el-icon-chat-dot-square" v-if="toTalk && wfInfo.toLinkup">
60
+ {{ $t2('沟通', 'components.wf.talk') }}
61
+ </el-button>
62
+ <el-button type="primary" plain class="btn" @click="openSetCandidateDialog(null)"
63
+ v-show="wfInfo.toSetCandidate"
64
+ icon="el-icon-user">{{ $t2('修改候选人', 'components.wf.setCandidate') }}
65
+ </el-button>
66
+ <el-button type="danger" plain class="btn" @click="openRevokeDialog(null)"
67
+ v-show="wfInfo.toRevoke"
68
+ icon="el-icon-document-delete">{{ $t2('撤回', 'components.wf.revoke') }}
69
+ </el-button>
70
+ </div>
71
+ </template>
72
+ </h5-card-pane>
73
+
74
+ <!-- 流程相关的弹框必须放在卡片外面。h5CardPane 折叠时会给 .cont 加
75
+ display:none,放在插槽里的弹框会被一起隐藏 —— 表现为「流程信息收起后,
76
+ 通过/驳回/转办这些弹框点了没反应」(祖先 display:none 无法被后代覆盖)。 -->
77
+ <el-dialog
78
+ title="流程图预览"
79
+ :modal-append-to-body="false"
80
+ :close-on-click-modal="false"
81
+ :visible.sync="showPreviewDialog"
82
+ :modal="false"
83
+ custom-class="dialog-style h5view-dialog"
84
+ width="100%"
85
+ top="0px"
86
+ v-el-drag-dialog
87
+ v-el-dialog-center
88
+ :append-to-body ="true"
89
+ :destroy-on-close="true"
90
+ >
91
+ <div class="flex">
92
+ <el-form label-position="top" class="form-box">
93
+ <div class="tit"><span>{{
94
+ (wfInfo.createDate ? wfInfo.createDate.substring(0, 10) : '') + wfInfo.name
95
+ }}</span></div>
96
+ <iframe
97
+ ref="wfPreviewFrame"
98
+ style="width: 100%;flex:1"
99
+ :src="wfImage"
100
+ @load="fitWorkflowPreview"
101
+ ></iframe>
102
+ </el-form>
103
+ </div>
104
+ <span slot="footer" class="dialog-footer">
105
+ <el-button
106
+ type="primary"
107
+ plain
108
+ class="button-sty"
109
+ icon="el-icon-close"
110
+ @click="showPreviewDialog = false"
111
+ >{{$t2('关 闭', 'system.button.close2')}}</el-button
112
+ >
113
+ </span>
114
+ </el-dialog>
115
+
116
+ <el-dialog
117
+ title="任务情况预览"
118
+ :modal-append-to-body="false"
119
+ :close-on-click-modal="false"
120
+ :visible.sync="showRenwuDialog"
121
+ :modal="false"
122
+ custom-class="dialog-style h5view-dialog"
123
+ width="100%"
124
+ top="0px"
125
+ v-el-drag-dialog
126
+ v-el-dialog-center
127
+ :append-to-body ="true"
128
+ :destroy-on-close="true"
129
+ >
130
+ <div class="flex">
131
+ <div class="h5-process-info">
132
+ <div class="item" v-for="wftaskLineData in wftaskData" :key="wftaskLineData.id">
133
+ <div class="time">
134
+ {{ wftaskLineData.approveTime ? wftaskLineData.approveTime.substring(0, 10) : '' }}
135
+ <br/>
136
+ {{ wftaskLineData.approveTime ? wftaskLineData.approveTime.substring(11) : '' }}
137
+ </div>
138
+ <div class="status"
139
+ :class="taskStatuses[wftaskLineData.type]?taskStatuses[wftaskLineData.type].class:''">
140
+ {{ taskStatuses[wftaskLineData.type] ? taskStatuses[wftaskLineData.type].value : null }}
141
+ </div>
142
+ <i class="circle"></i>
143
+ <div class="info">
144
+ <p>
145
+ <span class="name">{{ wftaskLineData.taskName }}</span>
146
+ <span>{{ $t2('执行人', 'components.wf.approverName') }}:{{ wftaskLineData.approverName }}</span>
147
+ <span>
148
+ {{ $t2('候选人', 'components.wf.candidateName') }}:
149
+ <span class="">{{ wftaskLineData.candidateNames }}</span>
150
+ </span>
151
+ </p>
152
+ <p class="t"><span class="t1">{{ $t2('备注/意见', 'components.wf.opinion') }}:</span><span>{{
153
+ wftaskLineData.opinion
154
+ }}</span></p>
155
+ </div>
156
+ </div>
157
+ </div>
158
+ </div>
159
+ <!-- 同上:只读预览,合成一个「关 闭」 -->
160
+ <span slot="footer" class="dialog-footer">
161
+ <el-button
162
+ type="primary"
163
+ plain
164
+ class="button-sty"
165
+ icon="el-icon-close"
166
+ @click="showRenwuDialog = false"
167
+ >{{$t2('关 闭', 'system.button.close2')}}</el-button
168
+ >
169
+ </span>
170
+ </el-dialog>
171
+ <!-- 下面 5 个确认框(中断 / 驳回 / 通过 / 转办 / 加签)都走 v-append-to-body:
172
+ 节点搬到 document.body 下,不再靠 position:fixed 在宿主子树里侥幸生效。
173
+ 它们保持 .pop-tipsBox 的原造型,没有改成 el-dialog——那个圆角卡片 + 顶部
174
+ 溢出圆形图标的样子要用 el-dialog 复刻,得把 header/body/footer 三段默认
175
+ 样式全推翻,样式量不减反增。
176
+
177
+ 三条约束,改动前先看 directive/append-to-body/index.js 的说明:
178
+ 1. 必须是 v-show,不能换回 v-if(Vue 的 insert() 会静默跳过以被搬走的
179
+ 节点为参照物的插入,兄弟顺序会错乱);
180
+ 2. 内联 style="display: block;" 不能删(v-show 的 originalDisplay 取自
181
+ 它,删了「显示」态会退回各应用 h5.scss 里 .pop-tipsBox{display:none});
182
+ 3. 多挂的 h5-pop-tips 类是样式作用域锚点——搬到 body 后 .xform-h5 前缀
183
+ 全部失配,样式改挂在 .pop-tipsBox.h5-pop-tips 上,既保住原有优先级,
184
+ 又不会误伤同样用 .pop-tipsBox 的 confirmDialog / baseAlert / errorMsg。 -->
185
+ <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="showWfManualDialog"
186
+ v-append-to-body>
187
+ <div>
188
+ <i class="icon"></i>
189
+ <div class="cont">
190
+ <p class="name">
191
+ {{ $t2('流程中断', 'components.wf.wfManual') }}<span>—</span><b
192
+ class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
193
+ wfInfo.taskName
194
+ }}</b>
195
+ </p>
196
+ <p class="txt">{{ $t2('您确定要中断流程吗?', 'components.wf.manualTip') }}</p>
197
+ </div>
198
+ <div class="btns">
199
+ <el-button type="primary" class="btn" plain icon="el-icon-close" @click="showWfManualDialog = false">{{
200
+ $t2('取 消', 'system.button.cancel2')
201
+ }}
202
+ </el-button>
203
+ <el-button type="primary" class="btn" icon="el-icon-check" @click="manualEndWf()">{{
204
+ $t2('确 定', 'system.button.confirm2')
205
+ }}
206
+ </el-button>
207
+ </div>
208
+ </div>
209
+ </div>
210
+ <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="rejectDialogVisible"
211
+ v-append-to-body>
212
+ <div>
213
+ <i class="icon"></i>
214
+ <div class="cont">
215
+ <p class="name">{{ $t2('流程驳回', 'components.wf.wfReject') }}<span
216
+ >—</span><b
217
+ class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
218
+ wfInfo.taskName
219
+ }}</b></p>
220
+ <el-form label-position="top" class="form-box">
221
+ <el-form-item label="驳回节点" field="nodeId">
222
+ <el-select v-model="rejectForm.nodeId"
223
+ :placeholder="$t2('请选择驳回节点', 'components.wf.rejectNodePlaceholder')">
224
+ <el-option v-for="(rejectNode,index) in rejectNodes" :label="rejectNode.nodeName"
225
+ :value="rejectNode.nodeId" :key="index"></el-option>
226
+ </el-select>
227
+ </el-form-item>
228
+ <el-form-item label="驳回意见" field="opinion">
229
+ <el-input type="textarea" :rows="5"
230
+ :placeholder="$t2('请输入内容', 'components.wf.rejectOpinionPlaceholder')"
231
+ v-model="rejectForm.opinion" class="txt"></el-input>
232
+ </el-form-item>
233
+ </el-form>
234
+ </div>
235
+ <div class="btns">
236
+ <el-button type="primary" class="btn" plain icon="el-icon-close" @click="rejectDialogVisible = false">{{
237
+ $t2('取 消', 'system.button.cancel2')
238
+ }}
239
+ </el-button>
240
+ <el-button type="primary" class="btn" icon="el-icon-check" @click="subRejectForm()">{{
241
+ $t2('确 定', 'system.button.confirm2')
242
+ }}
243
+ </el-button>
244
+ </div>
245
+ </div>
246
+ </div>
247
+ <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="agreeDialogVisible"
248
+ v-append-to-body>
249
+ <div>
250
+ <i class="icon"></i>
251
+ <div class="cont">
252
+ <p class="name">{{ $t2('流程通过', 'components.wf.wfAgree') }}<span
253
+ >—</span><b
254
+ class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
255
+ wfInfo.taskName
256
+ }}</b></p>
257
+ <el-form label-position="top" class="form-box">
258
+ <!-- 只有分支网关这类多出口节点,getNextOutgoingNodes 才会返回候选节点;
259
+ 单出口节点返回空数组,这一项必须整条不渲染,否则会露出一个没有任何
260
+ 选项的空下拉(提交时 nodeId 本就传 null,不需要选)。
261
+ 与 PC content.vue 的 <tr v-if="agreeNodes.length > 0"> 同口径。 -->
262
+ <el-form-item v-if="agreeNodes.length > 0"
263
+ :label="$t2('通过节点', 'components.wf.agreeNode')" field="nodeId">
264
+ <el-select v-model="agreeForm.nodeId"
265
+ :placeholder="$t2('请选择通过节点', 'components.wf.agreeNodePlaceholder')">
266
+ <el-option v-for="(node,index) in agreeNodes" :label="node.nodeName"
267
+ :value="node.nodeId" :key="index"></el-option>
268
+ </el-select>
269
+ </el-form-item>
270
+ <el-form-item :label="$t2('通过意见', 'components.wf.agreeOpinion')" field="opinion">
271
+ <el-input type="textarea" :rows="8" :placeholder="$t2(`请填写您的意见~
272
+ 注:
273
+ 通过默认意见为“同意”
274
+ `, 'components.wf.agreeOpinionPlaceholder')" v-model="agreeForm.opinion"></el-input>
275
+ </el-form-item>
276
+ </el-form>
277
+ </div>
278
+ <div class="btns">
279
+ <el-button type="primary" class="btn" plain icon="el-icon-close" @click="agreeDialogVisible = false">{{
280
+ $t2('取 消', 'system.button.cancel2')
281
+ }}
282
+ </el-button>
283
+ <el-button type="primary" class="btn" icon="el-icon-check" @click="subAgreeForm()">{{
284
+ $t2('确 定', 'system.button.confirm2')
285
+ }}
286
+ </el-button>
287
+ </div>
288
+ </div>
289
+ </div>
290
+ <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="changeWfDialogVisible"
291
+ v-append-to-body>
292
+ <div>
293
+ <i class="icon"></i>
294
+ <div class="cont">
295
+ <p class="name">{{ $t2('流程转办', 'components.wf.wfTransfer') }}<span>—</span><b
296
+ class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
297
+ wfInfo.taskName
298
+ }}</b></p>
299
+ <el-form label-position="top" class="form-box">
300
+ <el-form-item label="转办人" field="nodeId">
301
+ <el-input
302
+ class="search-input"
303
+ max="200"
304
+ v-model="changeWfForm.userNickNames"
305
+ @clear="
306
+ changeWfForm.userIds = '';
307
+ changeUserRows = [];
308
+ $forceUpdate();
309
+ "
310
+ v-el-readonly
311
+ clearable
312
+ >
313
+ <i slot="suffix" class="el-input__icon el-icon-search" @click="showUserDialog = true"></i>
314
+ </el-input>
315
+ </el-form-item>
316
+ <el-form-item label="转办意见" field="opinion">
317
+ <el-input type="textarea" :rows="8"
318
+ :placeholder="$t2('请输入内容', 'components.wf.transferOpinionPlaceholder')"
319
+ v-model="changeWfForm.opinion"></el-input>
320
+ </el-form-item>
321
+ </el-form>
322
+ </div>
323
+ <div class="btns">
324
+ <el-button type="primary" class="btn" plain @click="changeWfDialogVisible = false">{{
325
+ $t2('取 消', 'system.button.cancel2')
326
+ }}
327
+ </el-button>
328
+ <el-button type="primary" class="btn" @click="subChangeWfForm()">
329
+ {{ $t2('确认转办', 'components.wf.confirmTransfer') }}
330
+ </el-button>
331
+ </div>
332
+ </div>
333
+ </div>
334
+ <div class="pop-tipsBox h5-pop-tips" style="display: block;" v-show="showAddIncreaseSignDialog"
335
+ v-append-to-body>
336
+ <div>
337
+ <i class="icon"></i>
338
+ <div class="cont">
339
+ <p class="name">
340
+ {{ $t2('流程加签', 'components.wf.wfAddIncreaseSign') }}<span>—</span><b
341
+ class="f-red">{{ $t2('节点', 'components.wf.node') }}:{{
342
+ wfInfo.taskName
343
+ }}</b>
344
+ </p>
345
+ <el-form label-position="top" class="form-box">
346
+ <el-form-item label="候选人">
347
+ <el-input
348
+ class="search-input"
349
+ max="200"
350
+ v-model="addIncreaseSignForm.userNickNames"
351
+ @clear="
352
+ addIncreaseSignUsers = [];
353
+ $forceUpdate();
354
+ "
355
+ :placeholder="$t2('候选人', 'components.wf.addIncreaseSignUser')"
356
+ v-el-readonly
357
+ clearable
358
+ >
359
+ <i slot="suffix" class="el-input__icon el-icon-search"
360
+ @click="showAddTaskUserDialog = true"></i>
361
+ </el-input>
362
+ </el-form-item>
363
+ <el-form-item label="加签意见" field="opinion">
364
+ <el-input type="textarea" :rows="8"
365
+ :placeholder="$t2('请输入内容', 'components.wf.addIncreaseSignOpinionPlaceholder')"
366
+ v-model="addIncreaseSignForm.opinion"></el-input>
367
+ </el-form-item>
368
+ </el-form>
369
+ </div>
370
+ <div class="btns">
371
+ <el-button type="primary" class="btn" plain @click="showAddIncreaseSignDialog = false">{{
372
+ $t2('取 消', 'system.button.cancel2')
373
+ }}
374
+ </el-button>
375
+ <el-button type="primary" class="btn" @click="submitAddTaskUserForm(0)">
376
+ {{ $t2('确认加签', 'components.wf.confirmAddIncreaseSign') }}
377
+ </el-button>
378
+ </div>
379
+ </div>
380
+ </div>
381
+
382
+ <user-dialog v-if="showUserDialog" :visiable.sync="showUserDialog" @close="showUserDialog = false"
383
+ @confirm="userConfirm" multi="true" :param.sync="wfUserParamForTransfer"
384
+ :rows="changeUserRows"></user-dialog>
385
+ <urgingDialog v-if="urgingDialogVisible" :visiable.sync="urgingDialogVisible" :wfInfo="wfInfo"
386
+ :current_prefix="current_prefix"
387
+ @confirm="reloadContent" multi="true"></urgingDialog>
388
+ <deleteTaskUserDialog v-if="showDeleteTaskUserDialog" :visiable.sync="showDeleteTaskUserDialog" :wfInfo="wfInfo"
389
+ :current_prefix="current_prefix"
390
+ @confirm="reloadContent" multi="true"></deleteTaskUserDialog>
391
+
392
+ <addTaskUserdialog v-if="showAddTaskUserDialog" :visiable.sync="showAddTaskUserDialog" :wfInfo="wfInfo"
393
+ :current_prefix="current_prefix" :rows.sync="addIncreaseSignUsers"
394
+ @confirm="confirmAddTaskUser" multi="true"
395
+ :param.sync="wfUserParamForAddSign"></addTaskUserdialog>
396
+ <user-dialog v-if="showTalkUserDialog" :visiable.sync="showTalkUserDialog" @close="showTalkUserDialog = false"
397
+ @confirm="confirmTalkUserDialog" multi="false" :param.sync="wfUserParamForTalk"></user-dialog>
398
+ <setCandidateDialog v-if="showSetCandidateDialog" :visiable.sync="showSetCandidateDialog"
399
+ @close="closeSetCandidateDialog"
400
+ :wfInfo="wfInfo"
401
+ :current_prefix="current_prefix"></setCandidateDialog>
402
+ </div>
403
+ </template>
404
+ <script>
405
+ import Vue from "vue";
406
+
407
+ import settingConfig from "@/settings";
408
+ import commonMixin from "../../../mixins/mobile/common/index";
409
+ import {getToken} from "../../../utils/auth";
410
+ import {isWfTransferEnabled, loadWfTransferEnabled} from "../../wf/wfTransferEnabled";
411
+
412
+ let configUtil = {
413
+ baseUrl: process.env.VUE_APP_BASE_API,
414
+ getToken,
415
+ settingConfig,
416
+ Vue,
417
+ };
418
+
419
+ function appendPrevChildDom(parentDom, newDom) {
420
+ if (parentDom.hasChildNodes()) {
421
+ let currentDom = parentDom.children[0];
422
+ parentDom.insertBefore(newDom, currentDom);
423
+ } else {
424
+ parentDom.append(newDom);
425
+ }
426
+ }
427
+
428
+ function getTarget(t) {
429
+ return t.parentVue;
430
+ }
431
+
432
+ export default {
433
+ mixins: [commonMixin],
434
+ props: {
435
+ _wfInfo: Object,
436
+ _taskParam: Object,
437
+ wfOption: Object,
438
+ defaultShowWfContent: Boolean,
439
+ // 见模板里 .flowPath-btns 的注释:宿主接管审批动作时藏掉面板内那一排
440
+ hideActions: Boolean,
441
+ },
442
+ components: {
443
+ /* 本组件根节点就是 <h5-card-pane>,但此前没在这里注册——手写移动页是靠
444
+ mixins/mobile/common 在**宿主**上局部注册才碰巧能渲染。Vue 2 解析组件只查
445
+ 自身 components 与全局注册、不查父组件的局部注册,所以被别处(如 xform 的
446
+ detail-h5-item)引用时会渲染不出来。补上自己的依赖声明。 */
447
+ h5CardPane: () => import('../h5Card/h5CardPane.vue'),
448
+ /* 选用户弹层用包内的 selectUserDialog(el-dialog + append-to-body 版)。
449
+ 原来引的 views/mobile/user/user/dialog.vue 仍是 .pop-box 就地渲染版,
450
+ 且 src/views 不随包发布(被包内组件引用属隐式依赖),保持原样不动。 */
451
+ UserDialog: () => import('./selectUserDialog.vue'),
452
+ urgingDialog: () => import('./urgingDialog'),
453
+ deleteTaskUserDialog: () => import('./deleteTaskUserDialog'),
454
+ addTaskUserdialog: () => import('./addTaskUserdialog'),
455
+ setCandidateDialog: () => import('./setCandidateDialog')
456
+ },
457
+ computed: {
458
+ current_prefix() {
459
+ return this.serviceId ? "/" + this.serviceId : "";
460
+ },
461
+ viewTarget() {
462
+ return getTarget(this);
463
+ },
464
+ isHideWf() {
465
+ let that = this.viewTarget;
466
+ let _hideWf = that._hideWf || that.$attrs._hideWf;
467
+ return _hideWf === true || _hideWf === 'true';
468
+ },
469
+ transferEnabled() {
470
+ return isWfTransferEnabled();
471
+ }
472
+ },
473
+ data() {
474
+ let showWfFold =
475
+ settingConfig.showWfFold != null && settingConfig.showWfFold != undefined
476
+ ? settingConfig.showWfFold
477
+ : false;
478
+ let showWfContent =
479
+ showWfFold &&
480
+ settingConfig.defaultShowWfContent != null &&
481
+ settingConfig.defaultShowWfContent != undefined
482
+ ? settingConfig.defaultShowWfContent
483
+ : true;
484
+ if (
485
+ this.defaultShowWfContent != null &&
486
+ this.defaultShowWfContent != undefined
487
+ ) {
488
+ showWfContent = this.defaultShowWfContent;
489
+ }
490
+
491
+ return {
492
+ showRenwuDialog: false,
493
+ showDomContent: false,
494
+ showPreviewDialog: false,
495
+ objId: null,
496
+ wfCode: null,
497
+ serviceId: null,
498
+ parentVue: null,
499
+ wfConfig: null,
500
+
501
+ fileInfos: [],
502
+ showUserDialog: false,
503
+ showContent: true,
504
+ objTypeCode: "",
505
+ // objId: '',
506
+ wfInfo: {},
507
+ // currentTask: {},
508
+ taskParam: {},
509
+ wfImage: "",
510
+ wfStartBtn: false,
511
+ wfManualendBtn: false,
512
+ wfSubmitBtn: false,
513
+ wfRejectBtn: false,
514
+ changeHandlerBtn: false,
515
+ wftaskData: [],
516
+ allWfTaskOpinions: [],
517
+ vxeOption: {},
518
+ rejectNodes: [],
519
+ rejectDialogVisible: false,
520
+ rejectForm: {
521
+ rejectSubmitModel: null,
522
+ nodeId: null,
523
+ opinion: null,
524
+ },
525
+ formLabelWidth: "120px",
526
+ agreeDialogVisible: false,
527
+ agreeForm: {
528
+ opinion: this.$t2('同意', 'components.wf.defaultAgreeOption'),
529
+ nodeId: null,
530
+ },
531
+ changeWfDialogVisible: false,
532
+ changeWfForm: {},
533
+ changeUserRows: [],
534
+ taskStatuses: {
535
+ start: {
536
+ class: "blue",
537
+ value: this.$t2('开始', 'components.wf.startStatus'),
538
+ },
539
+ approve: {
540
+ class: "orgn",
541
+ value: this.$t2('待审批', 'components.wf.approveStatus'),
542
+ },
543
+ submit: {
544
+ class: "green",
545
+ value: this.$t2('同意', 'components.wf.submitStatus'),
546
+ },
547
+ reject: {
548
+ class: "red",
549
+ value: this.$t2('驳回', 'components.wf.rejectStatus'),
550
+ },
551
+ transfer: {
552
+ class: "green",
553
+ value: this.$t2('转办', 'components.wf.transferStatus'),
554
+ },
555
+ addIncreaseSign: {
556
+ class: "green",
557
+ value: this.$t2('加签', 'components.wf.addIncreaseSignStatus'),
558
+ },
559
+ revoke: {
560
+ class: "red",
561
+ value: this.$t2('撤回', 'components.wf.revokeStatus'),
562
+ },
563
+ end: {
564
+ class: "gray",
565
+ value: this.$t2('结束', 'components.wf.endStatus'),
566
+ },
567
+ },
568
+ opinion: "",
569
+ showWfFold: showWfFold,
570
+ showWfContent: showWfContent,
571
+
572
+ urgingForm: {},
573
+ urgingDialogVisible: false,
574
+ urgingUserIds: [],
575
+ urgingUsers: [],
576
+ agreeNodes: [],
577
+ showWfManualDialog: false,
578
+
579
+ showDeleteTaskUserDialog: false,
580
+ showAddTaskUserDialog: false,
581
+ wfUserParam: {},
582
+ wfUserParamForTransfer: {},//转办
583
+ wfUserParamForAddSign: {},//加签
584
+ wfUserParamForTalk: {},//沟通
585
+ tabIndex: "1",
586
+ linkupOption: {},
587
+ talkForm: {
588
+ receiverName: null,
589
+ content: null,
590
+ attachmentDTOs: [],
591
+ replyId: null
592
+ },
593
+ showTalkUserDialog: false,
594
+ showTalkDialog: false,
595
+ showFlowImg: true,
596
+ operateType: null,
597
+ addIncreaseSignUsers: [],
598
+ addIncreaseSignForm: {
599
+ userNickNames: null,
600
+ opinion: null
601
+ },
602
+ showAddIncreaseSignDialog: false,
603
+ showOpeaImg: true,
604
+ showSetCandidateDialog: false,
605
+ toTalk: false,
606
+ showAllWfOpinon: false,
607
+
608
+ revokeDialogVisible: false,
609
+ revokeForm: {opinion: null},
610
+ wfStatusMap: {
611
+ 1: {label: "审核中", type: "warning"},
612
+ 3: {label: "已驳回", type: "danger"},
613
+ 2: {label: "已完成", type: "success"}
614
+ }
615
+ };
616
+ },
617
+ provide() {
618
+ return {
619
+ getParentVue: () => {
620
+ return this.parentVue;
621
+ }
622
+ };
623
+ },
624
+ created() {
625
+ // this.wfInfo = this._wfInfo;
626
+ this.showFlowImg = settingConfig.expandWfImage === false ? false : true;
627
+ this.showAllWfOpinon = settingConfig.showAllWfOpinon === true;
628
+ },
629
+ mounted() {
630
+ this.init();
631
+ },
632
+ methods: {
633
+ fitWorkflowPreview() {
634
+ /* warm-flow-ui 是独立 iframe,窄屏下默认画布宽于视口,左右节点会被
635
+ 它自己的 overflow:hidden 裁掉。复用其「自适应」能力,在数据逐步
636
+ 渲染的几个时点重新 fit;跨域部署时访问 document 会抛错,静默跳过。 */
637
+ [0, 300, 800, 1500].forEach((delay) => {
638
+ window.setTimeout(() => {
639
+ try {
640
+ const frame = this.$refs.wfPreviewFrame;
641
+ const buttons = frame?.contentDocument?.querySelectorAll("button") || [];
642
+ const fitButton = Array.from(buttons).find(
643
+ (button) => button.textContent.trim() === "自适应"
644
+ );
645
+ fitButton?.click();
646
+ } catch (e) {
647
+ // 跨域 iframe 无法读取内部 DOM,保留 warm-flow-ui 原有交互。
648
+ }
649
+ }, delay);
650
+ });
651
+ },
652
+ getWfStatusLabel() {
653
+ return this.wfStatusMap[this.wfInfo.stat]?.label;
654
+ },
655
+ getWfStatusType() {
656
+ return this.wfStatusMap[this.wfInfo.stat]?.type;
657
+ },
658
+ init() {
659
+ let opt = this.wfOption;
660
+ this.objId = opt.objId;
661
+ this.wfCode = opt.wfCode;
662
+ this.serviceId = opt.serviceId;
663
+ this.parentVue = opt.parentVue;
664
+ this.wfConfig = this.wfOption;
665
+
666
+ let wfConfig = this.wfOption;
667
+ let that = getTarget(this);
668
+ let hasWf = false;
669
+ let wfInfo, currentTask, taskParam;
670
+ let option = {
671
+ objId: this.objId,
672
+ wfCode: this.wfCode
673
+ }
674
+ let current_prefix = this.current_prefix;
675
+
676
+ let initButton = () => {
677
+ /*return
678
+ this.$nextTick(() => {
679
+ that.$refs.wfButtonGroup.init({
680
+ taskParam,
681
+ wfInfo,
682
+ hasWf,
683
+ current_prefix,
684
+ wfConfig
685
+ });
686
+ });*/
687
+ }
688
+
689
+ this.initWfInfo(option, {
690
+ success: res => {
691
+ if (res.objx && res.objx.procInstId) {
692
+ hasWf = true;
693
+ wfInfo = res.objx;
694
+ this.wfInfo = wfInfo;
695
+ // this.showDomContent = true;
696
+
697
+ if (wfInfo.taskId) {
698
+ this.getTaskParams(wfInfo.taskId, {
699
+ success: res2 => {
700
+ taskParam = res2.objx || {};
701
+ taskParam.objId = option.objId;
702
+ this.taskParam = taskParam;
703
+
704
+ initButton();
705
+ }
706
+ });
707
+ } else {
708
+ initButton();
709
+ }
710
+ this.initOperateType();
711
+ this.initForAll();
712
+ } else {
713
+ initButton();
714
+ }
715
+ }
716
+ });
717
+ },
718
+ initWfInfo(option, httpConfig) {
719
+
720
+ let that = getTarget(this);
721
+ let id = option.objId;
722
+ let code = option.wfCode;
723
+ return that.$http({
724
+ url: this.current_prefix + '/wf/getWfInfo',
725
+ method: `post`,
726
+ data: {
727
+ objTypeCode: code,
728
+ objId: id
729
+ },
730
+ isLoading: true,
731
+ modalStrictly: true,
732
+ ...httpConfig
733
+ });
734
+ },
735
+ getTaskParams(taskId, httpConfig) {
736
+ let that = getTarget(this);
737
+ return that.$http({
738
+ url: this.current_prefix + '/wf/getTaskVariables',
739
+ method: `post`,
740
+ data: {
741
+ stringOne: taskId
742
+ },
743
+ isLoading: true,
744
+ modalStrictly: true,
745
+ ...httpConfig
746
+ });
747
+ },
748
+
749
+
750
+ initOperateType() {
751
+ if (this.operateType) {
752
+ let wfInfo = this.wfInfo;
753
+ if (wfInfo.toSubmit) {
754
+ this.openAgreeDialog('submit');
755
+ } else if (wfInfo.toReject) {
756
+ this.rejectWfTask('reject');
757
+ } else if (wfInfo.toAddIncreaseSign) {
758
+ this.openAddIncreaseSign('addIncreaseSign')
759
+ } else if (wfInfo.toRevoke) {
760
+ this.openRevokeDialog('revoke')
761
+ } else if (wfInfo.toLinkup) {
762
+ this.openTalkDialog(null, null, 'talk');
763
+ } else {
764
+ this.operateType = null;
765
+ }
766
+ }
767
+ },
768
+ initForAll() {
769
+ let that = getTarget(this);
770
+ loadWfTransferEnabled(that);
771
+ this.initWf(() => {
772
+ if (this.wfInfo.procInstId) {
773
+ this.initCurrentTask(this.wfInfo.procInstId, () => {
774
+ this.initWftask(this.wfInfo.procInstId);
775
+ this.getAllWfTaskOpinions();
776
+ });
777
+ this.initWfUserParam();
778
+ this.initTabIndex();
779
+ }
780
+ });
781
+ },
782
+ initTabIndex() {
783
+ let that = getTarget(this);
784
+ that.$http({
785
+ url: USER_PREFIX + "/wf_diy_attribute/getValue",
786
+ method: `post`,
787
+ data: {attributeKey: "param7"},
788
+ isLoading: true,
789
+ success: (res) => {
790
+ let val = res !== null ? res.objx === true : false;
791
+ this.toTalk = val;
792
+ let flag = false;
793
+ if (val) {
794
+ let flag1 = that.$attrs._isNotifyMessage == true || that.$attrs._isNotifyMessage == "true";
795
+ if (flag1) {
796
+ this.tabIndex = "2";
797
+ }
798
+ if (settingConfig.autoOpenWfLinkup) {
799
+ flag = true;
800
+ let flag2 = that.$attrs._wfNotifyType == "wfLinkup";
801
+ let flag3 = flag1 && flag2;
802
+ if (flag3) {
803
+ this.$nextTick(() => {
804
+ let wfTabPane = this.$refs.wfTabPane;
805
+ if (!wfTabPane.showContent) {
806
+ wfTabPane.handleFold();
807
+ }
808
+ });
809
+ }
810
+ }
811
+ }
812
+ this.initLinkup(flag);
813
+ }
814
+ });
815
+
816
+ },
817
+ initWf(done) {
818
+ var data = this.wfInfo;
819
+ if (data && data.procInstId) {
820
+ /** 流程状态:0未启动,1审核中,2已完成,3驳回,4中断 */
821
+ var statuses = {
822
+ 1: '<span class="tag">' + this.$t2('审核中', 'components.wf.wfStatus1') + '</span>',
823
+ 3: '<span class="tag red">' + this.$t2('已驳回', 'components.wf.wfStatus2') + '</span>',
824
+ 2: '<span class="tag green">' + this.$t2('已完成', 'components.wf.wfStatus3') + '</span>',
825
+ };
826
+ var statusStr = "";
827
+ if (data.stat != null) {
828
+ statusStr = statuses[data.stat] || "";
829
+ }
830
+ data.statusStr = statusStr;
831
+ this.wfInfo = data;
832
+
833
+ this.wfStartBtn = false;
834
+ if (data.status != 2 && data.starterId) {
835
+ this.wfManualendBtn = true;
836
+ }
837
+ this.wfSubmitBtn = false;
838
+ this.wfRejectBtn = false;
839
+
840
+ var url =
841
+ this.current_prefix +
842
+ "/wf/flowImage?procInstId=" +
843
+ data.procInstId +
844
+ "&_r=" +
845
+ Math.random() +
846
+ "&access_token=" +
847
+ configUtil.getToken();
848
+ this.wfImage = configUtil.baseUrl + url;
849
+ done();
850
+ }
851
+ },
852
+ initCurrentTask(procInstId, done) {
853
+ if (this.wfInfo.taskId) {
854
+ this.wfSubmitBtn = true;
855
+ this.wfRejectBtn = true;
856
+ this.changeHandlerBtn = true;
857
+ }
858
+ done();
859
+ },
860
+ initWftask(procInstId) {
861
+ let that = getTarget(this);
862
+ that.$http({
863
+ url: this.current_prefix + "/wf/getWfTaskOpinionMerge",
864
+ data: {
865
+ stringOne: procInstId,
866
+ },
867
+ method: "post",
868
+ isLoading: true,
869
+ modalStrictly: true,
870
+ success: (resultmsg) => {
871
+ var datas = resultmsg.objx || [];
872
+ this.wftaskData = datas;
873
+ },
874
+ });
875
+ },
876
+ getAllWfTaskOpinions() {
877
+ if (!this.showAllWfOpinon) {
878
+ return;
879
+ }
880
+ let that = getTarget(this);
881
+ let wfInfo = this.wfInfo;
882
+ that.$http({
883
+ url: this.current_prefix + "/wf/getAllWfTaskOpinions",
884
+ data: {
885
+ objId: wfInfo.objId,
886
+ objTypeCode: wfInfo.objTypeCode
887
+ },
888
+ method: "post",
889
+ isLoading: true,
890
+ modalStrictly: true,
891
+ success: (resultmsg) => {
892
+ var datas = resultmsg.objx || [];
893
+ this.allWfTaskOpinions = datas;
894
+ },
895
+ });
896
+ },
897
+ openManualDialog(operateType) {
898
+ this.operateType = operateType;
899
+ this.showWfManualDialog = true;
900
+ },
901
+ manualEndWf() {
902
+ this.showWfManualDialog = false;
903
+ let that = getTarget(this);
904
+ var procInstId = this.wfInfo.procInstId;
905
+ var taskId = this.wfInfo.taskId ? this.wfInfo.taskId : "";
906
+ var data = JSON.stringify({
907
+ uuid: this.wfInfo.uuid,
908
+ });
909
+ that.$http({
910
+ url: this.current_prefix + "/wf/interrupt",
911
+ data: data,
912
+ method: "post",
913
+ headers: {
914
+ "Content-Type": "application/json;charset=utf-8",
915
+ },
916
+ isLoading: true,
917
+ success: (resultMsg) => {
918
+ that.$message({
919
+ message: resultMsg.content,
920
+ type: "success",
921
+ duration: 500,
922
+ onClose: (t) => {
923
+ this.reloadContent();
924
+ this.closeWinOnCheck(3);
925
+ },
926
+ });
927
+ },
928
+ });
929
+ },
930
+ async rejectWfTask(operateType) {
931
+ // 与 PC wf.js 的 rejectWfTask 同结构:驳回也要先过一遍「驳回提醒」
932
+ this.handleReminderContent("rejectReminder", async () => {
933
+ let that = getTarget(this);
934
+ var procInstId = this.wfInfo.procInstId;
935
+ var taskId = this.wfInfo.taskId;
936
+ var destinations = [];
937
+
938
+ await that.$http({
939
+ url: this.current_prefix + "/wf/getPreIncomeNodes",
940
+ data: {
941
+ stringOne: taskId,
942
+ },
943
+ method: "post",
944
+ //contentType: 'application/json;charset=utf-8',
945
+ isLoading: true,
946
+ success: (resultMsg) => {
947
+ destinations = (resultMsg.objx || []).reverse();
948
+ },
949
+ });
950
+
951
+ if (destinations == null) {
952
+ return false;
953
+ }
954
+ if (destinations.length == 0) {
955
+ that.$message({
956
+ message: this.$t2('无法驳回,没有目标节点', 'components.wf.rejectWarnMsg1'),
957
+ type: "error",
958
+ duration: 2 * 1000,
959
+ });
960
+ return false;
961
+ }
962
+ this.operateType = operateType;
963
+
964
+ /* 驳回后提交模式,取自流程对象配置(wf_obj_config「驳回后提交模式」三选一):
965
+ toNextNode === 1 → 顺延下一步提交 → 1
966
+ toRejectNode false → 直接提交到驳回节点 → 2
967
+ toRejectNode true → 由提交人确定节点提交 → null(提交时自己选)
968
+ 三个分支不能省成两个:选了「顺延下一步」时后台把 toRejectNode 置为 null,
969
+ 而 null == false 在 JS 里是 false,会落到 null 分支上,配置被静默丢掉。
970
+ 与 PC wf.js 的 rejectWfTask 同口径。 */
971
+ let rejectSubmitModel = null;
972
+ if (this.wfInfo.toNextNode === 1) {
973
+ rejectSubmitModel = this.wfInfo.toNextNode
974
+ } else {
975
+ rejectSubmitModel = this.wfInfo.toRejectNode == false ? 2 : null
976
+ }
977
+ this.rejectForm.rejectSubmitModel = rejectSubmitModel;
978
+ this.rejectForm.nodeId = destinations[0].nodeId;
979
+ this.rejectForm.opinion = "";
980
+ this.rejectNodes = destinations;
981
+ this.rejectDialogVisible = true;
982
+ })
983
+ },
984
+ subRejectForm() {
985
+ let that = getTarget(this);
986
+ var procInstId = this.wfInfo.procInstId;
987
+ var taskId = this.wfInfo.taskId;
988
+
989
+ if (!this.rejectForm.nodeId) {
990
+ that.$message({
991
+ message: this.$t2('请选择驳回节点', 'components.wf.rejectWarnMsg2'),
992
+ type: "error",
993
+ duration: 2 * 1000,
994
+ });
995
+ return false;
996
+ }
997
+
998
+ if (!this.rejectForm.opinion) {
999
+ that.$message({
1000
+ message: this.$t2('请输入驳回意见', 'components.wf.rejectWarnMsg3'),
1001
+ type: "error",
1002
+ duration: 2 * 1000,
1003
+ });
1004
+ return false;
1005
+ }
1006
+
1007
+ var data = JSON.stringify({
1008
+ taskId: taskId,
1009
+ uuid: this.wfInfo.uuid,
1010
+ nodeId: this.rejectForm.nodeId,
1011
+ suggestion: this.rejectForm.opinion,
1012
+ rejectSubmitModel: this.rejectForm.rejectSubmitModel
1013
+ });
1014
+ this.rejectDialogVisible = false;
1015
+ that.$http({
1016
+ url: this.current_prefix + "/wf/reject",
1017
+ data: data,
1018
+ method: "post",
1019
+ headers: {
1020
+ "Content-Type": "application/json;charset=utf-8",
1021
+ },
1022
+ isLoading: true,
1023
+ success: (resultMsg) => {
1024
+ that.$message({
1025
+ message: resultMsg.content,
1026
+ type: "success",
1027
+ duration: 500,
1028
+ onClose: (t) => {
1029
+ this.reloadContent();
1030
+ this.closeWinOnCheck(2);
1031
+ },
1032
+ });
1033
+ },
1034
+ });
1035
+ },
1036
+ /**
1037
+ * 提交/驳回前的「提醒内容」:后台按 scriptType 跑脚本,返回文案就先弹确认框,
1038
+ * 用户点确定才继续;没有文案(或接口 404,即后端未部署该能力)直接放行。
1039
+ * 与 PC wf.js 的同名方法保持一致。
1040
+ *
1041
+ * 提醒只是主流程前面的一道增强,不能让它把主流程带崩或卡死,所以:
1042
+ * - 放行只允许一次(go 自带闸门),成功/异常各分支共用一个出口;
1043
+ * - 确认框点取消 = 放弃本次操作,什么都不做,但 MessageBox 的 reject 必须吃掉,
1044
+ * 否则是一条 unhandled rejection;
1045
+ * - error 分支绝不能抛异常。request.js 是先调 config.error(e) 再 removeModel(config)
1046
+ * (见 utils/request.js 的响应错误拦截),这里一抛,isLoading 的全屏遮罩就永远
1047
+ * 关不掉、整页被锁死。而网络失败/超时时 e.response 本就是 undefined,
1048
+ * 老写法 e.response.status 必崩 —— 故 status 取值全程判空。
1049
+ */
1050
+ handleReminderContent(scriptType, callback) {
1051
+ let that = getTarget(this);
1052
+ let called = false;
1053
+ const go = () => {
1054
+ if (called) return
1055
+ called = true;
1056
+ callback && callback();
1057
+ };
1058
+ that.$http({
1059
+ url: this.current_prefix + "/wf/getReminderContent",
1060
+ data: {
1061
+ scriptType,
1062
+ taskId: this.wfInfo.taskId,
1063
+ uuid: this.wfInfo.uuid,
1064
+ },
1065
+ method: "post",
1066
+ isLoading: true,
1067
+ errorMsg: false,
1068
+ success: (res) => {
1069
+ if (res && res.objx) {
1070
+ that.$baseConfirm(res.objx).then(go).catch(() => {});
1071
+ } else {
1072
+ go();
1073
+ }
1074
+ },
1075
+ error: (e) => {
1076
+ let status = e && e.response ? e.response.status : null;
1077
+ if (status === 404) {
1078
+ // 后端没部署这个接口,等同于「没有提醒」,静默放行
1079
+ go();
1080
+ return
1081
+ }
1082
+ /* 其余错误只提示不放行:提醒内容可能是必须让人看到的业务警告,
1083
+ 接口挂了就悄悄跳过等于把它吞掉。用户重试即可。 */
1084
+ that.$errorMsg({
1085
+ content: (e && e.message) || this.$t2('获取提醒内容失败', 'components.wf.reminderError'),
1086
+ type: 'error',
1087
+ }).catch(() => {});
1088
+ },
1089
+ });
1090
+ },
1091
+ openAgreeDialog(operateType) {
1092
+ const done = () => {
1093
+ this.handleReminderContent("submitReminder", () => {
1094
+ this.operateType = operateType;
1095
+ let that = getTarget(this);
1096
+ this.agreeForm = {
1097
+ opinion: this.$t2('同意', 'components.wf.defaultAgreeOption'),
1098
+ nodeId: null,
1099
+ };
1100
+ this.agreeNodes = [];
1101
+ that.$http({
1102
+ url: this.current_prefix + "/wf/getNextOutgoingNodes",
1103
+ data: {
1104
+ stringOne: this.wfInfo.taskId,
1105
+ },
1106
+ method: "post",
1107
+ isLoading: true,
1108
+ success: (res) => {
1109
+ let nodes = res.objx || [];
1110
+ /*if (tq == true) {
1111
+ nodes.reverse();
1112
+ }*/
1113
+ if (nodes.length) {
1114
+ this.agreeForm.nodeId = nodes[0].nodeId;
1115
+ }
1116
+ this.agreeNodes = nodes;
1117
+ this.agreeDialogVisible = true;
1118
+ },
1119
+ });
1120
+ })
1121
+ }
1122
+ // wfConfig 在 init() 里才赋值(初值 null),这里兜一层空对象
1123
+ let wfConfig = this.wfConfig || {};
1124
+ if (wfConfig.onClickAgree) {
1125
+ wfConfig.onClickAgree(done)
1126
+ } else {
1127
+ done();
1128
+ }
1129
+ },
1130
+ subAgreeForm() {
1131
+ let wfConfig = this.wfConfig;
1132
+ let done = () => {
1133
+ this.subAgreeHandle();
1134
+ }
1135
+ if (wfConfig.onBeforeAgree) {
1136
+ wfConfig.onBeforeAgree(done)
1137
+ } else {
1138
+ done();
1139
+ }
1140
+ },
1141
+ subAgreeHandle() {
1142
+ let that = getTarget(this);
1143
+ let nodeId = null;
1144
+ if (this.agreeNodes.length) {
1145
+ if (!this.agreeForm.nodeId) {
1146
+ that.$message({
1147
+ message: this.$t2('请选择节点', 'components.wf.agreeWarnMsg1'),
1148
+ type: "error",
1149
+ duration: 2 * 1000,
1150
+ });
1151
+ return;
1152
+ }
1153
+ nodeId = this.agreeForm.nodeId;
1154
+ }
1155
+
1156
+ var procInstId = this.wfInfo.procInstId;
1157
+ var taskId = this.wfInfo.taskId;
1158
+ var memo = this.agreeForm.opinion || this.$t2('同意', 'components.wf.defaultAgreeOption');
1159
+ var data = JSON.stringify({
1160
+ taskId: taskId,
1161
+ uuid: this.wfInfo.uuid,
1162
+ suggestion: memo,
1163
+ nodeId: nodeId,
1164
+ });
1165
+ this.agreeDialogVisible = false;
1166
+ that.$http({
1167
+ url: this.current_prefix + "/wf/submit",
1168
+ data: data,
1169
+ method: "post",
1170
+ headers: {
1171
+ "Content-Type": "application/json;charset=utf-8",
1172
+ },
1173
+ isLoading: true,
1174
+ success: (resultMsg) => {
1175
+ if (resultMsg.objx && resultMsg.objx.code == "999999") {
1176
+ this.errorSubmit({
1177
+ taskId: taskId,
1178
+ uuid: this.wfInfo.uuid,
1179
+ suggestion: memo,
1180
+ errorMsg: resultMsg.objx.errorMsg
1181
+ });
1182
+ } else {
1183
+ that.$message({
1184
+ message: resultMsg.content,
1185
+ type: "success",
1186
+ duration: 500,
1187
+ onClose: (t) => {
1188
+ this.reloadContent();
1189
+ this.closeWinOnCheck(1);
1190
+ },
1191
+ });
1192
+ }
1193
+ },
1194
+ });
1195
+ },
1196
+ errorSubmit(data) {
1197
+ let that = getTarget(this);
1198
+ that.$http({
1199
+ url: this.current_prefix + "/wf/errorSubmit",
1200
+ data: data,
1201
+ method: "post",
1202
+ isLoading: true,
1203
+ success: (resultMsg) => {
1204
+ that.$message({
1205
+ message: resultMsg.content,
1206
+ type: "success",
1207
+ duration: 500,
1208
+ onClose: (t) => {
1209
+ this.reloadContent();
1210
+ this.closeWinOnCheck(1);
1211
+ },
1212
+ });
1213
+ },
1214
+ });
1215
+ },
1216
+ openChangeWfForm(operateType) {
1217
+ this.operateType = operateType;
1218
+ this.changeWfDialogVisible = true;
1219
+ this.changeUserRows = [];
1220
+ this.changeWfForm = {
1221
+ userIds: [],
1222
+ userNickNames: null,
1223
+ opinion: null,
1224
+ };
1225
+ },
1226
+ subChangeWfForm() {
1227
+ let that = getTarget(this);
1228
+ var procInstId = this.wfInfo.procInstId;
1229
+ var taskId = this.wfInfo.taskId;
1230
+
1231
+ var userIds = this.changeWfForm.userIds || [];
1232
+ var opinion = this.changeWfForm.opinion || null;
1233
+
1234
+ if (!userIds.length) {
1235
+ that.$message({
1236
+ message: this.$t2('请选择转办人', 'components.wf.transferWarnMsg1'),
1237
+ type: "error",
1238
+ duration: 2000,
1239
+ onClose: (t) => {
1240
+ },
1241
+ });
1242
+ return false;
1243
+ }
1244
+
1245
+ var data = JSON.stringify({
1246
+ taskId: taskId,
1247
+ uuid: this.wfInfo.uuid,
1248
+ transferTo: userIds,
1249
+ suggestion: opinion,
1250
+ });
1251
+ this.changeWfDialogVisible = false;
1252
+ that.$http({
1253
+ url: this.current_prefix + "/wf/transfer",
1254
+ data: data,
1255
+ method: "post",
1256
+ headers: {
1257
+ "Content-Type": "application/json;charset=utf-8",
1258
+ },
1259
+ isLoading: true,
1260
+ success: (resultMsg) => {
1261
+ that.$message({
1262
+ message: resultMsg.content,
1263
+ type: "success",
1264
+ duration: 500,
1265
+ onClose: (t) => {
1266
+ this.reloadContent();
1267
+ this.closeWinOnCheck(4);
1268
+ },
1269
+ });
1270
+ },
1271
+ });
1272
+ },
1273
+ userConfirm(rows) {
1274
+ if (rows.length > 0) {
1275
+ let changeUserRows = this.changeUserRows;
1276
+ let ids = changeUserRows.map((changeUserRow) => changeUserRow.id);
1277
+ let addRows = rows.filter((row) => !ids.includes(row.id));
1278
+ changeUserRows.push(...addRows);
1279
+
1280
+ let row = rows[0];
1281
+ this.changeWfForm.userIds = changeUserRows.map(
1282
+ (changeUserRow) => changeUserRow.id
1283
+ );
1284
+ this.changeWfForm.userNickNames = changeUserRows
1285
+ .map((changeUserRow) => changeUserRow.nickName)
1286
+ .join(",");
1287
+ }
1288
+ },
1289
+ reloadContent() {
1290
+ let that = getTarget(this);
1291
+ that.$baseReload();
1292
+ },
1293
+ closeWinOnCheck(flag) {
1294
+ //_closeWindowOnCheck=true, 1提交,2驳回,3中断,4转办时,5沟通 关闭窗口
1295
+ let that = getTarget(this);
1296
+ let _closeWindowOnCheck = that.$attrs._closeWindowOnCheck || that._closeWindowOnCheck;
1297
+ if (_closeWindowOnCheck === true || _closeWindowOnCheck === "true") {
1298
+ window.close && window.close();
1299
+ }
1300
+ let _handleCallback = that.$attrs._handleCallback || that._handleCallback;
1301
+ _handleCallback && _handleCallback(flag);
1302
+ },
1303
+ manualCallback() {
1304
+ this.$emit("manualCallback");
1305
+ },
1306
+ openUrgingDialog(operateType) {
1307
+ this.operateType = operateType;
1308
+ this.urgingDialogVisible = true;
1309
+ },
1310
+ openDeleteTaskUserDialog(operateType) {
1311
+ this.operateType = operateType;
1312
+ this.showDeleteTaskUserDialog = true;
1313
+ },
1314
+ openAddTaskUserDialog(operateType) {
1315
+ this.operateType = operateType;
1316
+ this.showAddTaskUserDialog = true;
1317
+ },
1318
+ openAddIncreaseSign(operateType) {
1319
+ this.operateType = operateType;
1320
+ this.addIncreaseSignUsers = [];
1321
+ this.addIncreaseSignForm = {userNickNames: null};
1322
+ this.showAddIncreaseSignDialog = true;
1323
+ },
1324
+ initWfUserParam(callback) {
1325
+ this.initTransferUserParam();//转办
1326
+ this.initAddSignUserParam();//加签
1327
+ this.initTalkUserParam();//沟通
1328
+ },
1329
+ //
1330
+ initTransferUserParam(callback) {
1331
+ //初始化转办用户参数
1332
+ let that = getTarget(this);
1333
+ return that.$http({
1334
+ url: USER_PREFIX + "/wf_diy_attribute/getValue",
1335
+ method: `post`,
1336
+ data: {attributeKey: "param1"},
1337
+ isLoading: true,
1338
+ modalStrictly: true,
1339
+ success: (res) => {
1340
+ this.wfUserParamForTransfer = res.objx || {};
1341
+ callback && callback();
1342
+ },
1343
+ });
1344
+ },
1345
+ initAddSignUserParam(callback) {
1346
+ //初始化加签用户参数
1347
+ let that = getTarget(this);
1348
+ return that.$http({
1349
+ url: USER_PREFIX + "/wf_diy_attribute/getValue",
1350
+ method: `post`,
1351
+ data: {attributeKey: "param2"},
1352
+ isLoading: true,
1353
+ modalStrictly: true,
1354
+ success: (res) => {
1355
+ this.wfUserParamForAddSign = res.objx || {};
1356
+ callback && callback();
1357
+ },
1358
+ });
1359
+ },
1360
+ initTalkUserParam(callback) {
1361
+ //初始化沟通用户参数
1362
+ let that = getTarget(this);
1363
+ return that.$http({
1364
+ url: USER_PREFIX + "/wf_diy_attribute/getValue",
1365
+ method: `post`,
1366
+ data: {attributeKey: "param3"},
1367
+ isLoading: true,
1368
+ modalStrictly: true,
1369
+ success: (res) => {
1370
+ this.wfUserParamForTalk = res.objx || {};
1371
+ callback && callback();
1372
+ },
1373
+ });
1374
+ },
1375
+ //
1376
+ resetLinkup() {
1377
+ this.formData = {};
1378
+ this.$refs["table-linkup"].commitProxy("reload");
1379
+ },
1380
+ searchLinkup() {
1381
+ this.$refs["table-linkup"].commitProxy("reload");
1382
+ },
1383
+ initLinkup(flag) {
1384
+ return
1385
+ let h = this.$createElement;
1386
+ let statusMap = {
1387
+ 0: this.$t2('未完成', 'components.wf.talkStatus0'),
1388
+ 1: this.$t2('已完成', 'components.wf.talkStatus1'),
1389
+ 2: this.$t2('已取消', 'components.wf.talkStatus2')
1390
+ };
1391
+ let tableOption = {
1392
+ vue: this,
1393
+ tableRef: "table-linkup",
1394
+ tableName: "wf_table-linkup",
1395
+ path: this.current_prefix + "/wf_linkup/listPage",
1396
+ param: () => {
1397
+ return {
1398
+ uuid: this.wfInfo.uuid,
1399
+ };
1400
+ },
1401
+ config: {
1402
+ height: 350
1403
+ },
1404
+ columns: [
1405
+ {type: "checkbox", width: 48, resizable: false, fixed: "left"},
1406
+ {
1407
+ title: this.$t2('任务名称', 'components.wf.taskName'),
1408
+ field: "taskName",
1409
+ width: 150,
1410
+ fixed: "left",
1411
+ },
1412
+ {
1413
+ title: this.$t2('发送人', 'components.wf.senderName'),
1414
+ field: "senderName",
1415
+ width: 150,
1416
+ slots: {
1417
+ default: "sender",
1418
+ },
1419
+ },
1420
+ {
1421
+ title: this.$t2('接收人', 'components.wf.receiverName'),
1422
+ field: "receiverName",
1423
+ width: 150,
1424
+ slots: {
1425
+ default: "receiver",
1426
+ },
1427
+ },
1428
+ {
1429
+ title: this.$t2('沟通内容', 'components.wf.talkContent'),
1430
+ field: "content",
1431
+ width: 250,
1432
+ showOverflow: false,
1433
+ slots: {
1434
+ default: ({row, rowIndex}) => {
1435
+ return row.replyId ? ("[" + this.$t2('回复', 'components.wf.reply') + "]" + row.content) : row.content;
1436
+ },
1437
+ },
1438
+ },
1439
+ {
1440
+ width: 150,
1441
+ title: this.$t2('沟通资料', 'components.wf.talkAttachment'),
1442
+ field: "attachmentImage",
1443
+ sortable: false,
1444
+ slots: {
1445
+ default: ({row, rowIndex}) => {
1446
+ let option = {
1447
+ title: this.$t2('沟通资料', 'components.wf.talkAttachment'),
1448
+ edit: false,
1449
+ rows: (done) => {
1450
+ done(row.attachmentDTOs);
1451
+ },
1452
+ };
1453
+ return [
1454
+ h("base-attachment", {
1455
+ props: {
1456
+ option: option,
1457
+ },
1458
+ }),
1459
+ ];
1460
+ },
1461
+ },
1462
+ },
1463
+
1464
+ {
1465
+ title: this.$t2('状态', 'components.wf.status'),
1466
+ field: "status",
1467
+ width: 150,
1468
+ slots: {
1469
+ default: ({row, rowIndex}) => {
1470
+ return statusMap[row.status] || "";
1471
+ },
1472
+ },
1473
+ },
1474
+ {
1475
+ title: this.$t2('创建时间', 'system.label.createDate'),
1476
+ field: "createDate",
1477
+ width: 150,
1478
+ },
1479
+ {
1480
+ width: 80,
1481
+ fixed: "right",
1482
+ title: "",
1483
+ sortable: false,
1484
+ slots: {
1485
+ default: "operate"
1486
+ }
1487
+ },
1488
+ ],
1489
+ callback: (rows) => {
1490
+ if (rows.length && flag) {
1491
+ let row = rows[0];
1492
+ if (row.replyToSender) {
1493
+ this.$nextTick(() => {
1494
+ this.tabIndex = "2";
1495
+ this.openTalkDialog(row.sender, row.senderName, 'talk', 1, row.id)
1496
+ });
1497
+ }
1498
+ }
1499
+ }
1500
+ };
1501
+ this.$vxeTableUtil.initVxeTable(tableOption).then((opts) => {
1502
+ this.linkupOption = opts;
1503
+ });
1504
+ },
1505
+ cancelTalk(row) {
1506
+ let that = getTarget(this);
1507
+ that.$baseConfirm(this.$t2('您确定要取消沟通记录吗?', 'components.wf.cancelTalkTip')).then(() => {
1508
+ that.$http({
1509
+ url: this.current_prefix + "/wf_linkup/cancel",
1510
+ data: {id: row.id},
1511
+ method: "post",
1512
+ loadingTarget: document.body,
1513
+ isLoading: true,
1514
+ success: (resultMsg) => {
1515
+ that.$message({
1516
+ message: resultMsg.content,
1517
+ type: "success",
1518
+ duration: 500,
1519
+ onClose: (t) => {
1520
+ this.reloadContent();
1521
+ },
1522
+ });
1523
+ },
1524
+ });
1525
+ });
1526
+ },
1527
+ openTalkDialog(receiver, receiverName, operateType, flag, replyId) {
1528
+ this.operateType = operateType;
1529
+ /*this.talkForm.receiver = receiver || null;
1530
+ this.talkForm.receiverName = receiverName || null;
1531
+ this.talkForm.replyId = replyId || null;
1532
+ this.talkForm.content = null;
1533
+ this.talkForm.attachmentDTOs = [];*/
1534
+ this.initTalkForm(receiver, receiverName, replyId)
1535
+ this.showTalkDialog = true;
1536
+ if (flag == 1) {
1537
+ let opeaBtnDom = this.$refs.opeaBtn;
1538
+ opeaBtnDom && opeaBtnDom.scrollIntoView();
1539
+ }
1540
+ },
1541
+ initTalkForm(receiver, receiverName, replyId) {
1542
+ this.talkForm.receiver = receiver || null;
1543
+ this.talkForm.receiverName = receiverName || null;
1544
+ this.talkForm.replyId = replyId || null;
1545
+ this.talkForm.content = null;
1546
+ this.talkForm.attachmentDTOs = [];
1547
+ },
1548
+ submitTalkForm() {
1549
+ let that = getTarget(this);
1550
+ var procInstId = this.wfInfo.procInstId;
1551
+ var taskId = this.wfInfo.taskId;
1552
+
1553
+ if (!this.talkForm.receiver) {
1554
+ that.$message({
1555
+ message: this.$t2('请选择接收人', 'components.wf.talkWarnMsg1'),
1556
+ type: "error",
1557
+ duration: 2 * 1000,
1558
+ });
1559
+ return false;
1560
+ }
1561
+ if (!this.talkForm.content) {
1562
+ that.$message({
1563
+ message: this.$t2('请输入沟通内容', 'components.wf.talkWarnMsg2'),
1564
+ type: "error",
1565
+ duration: 2 * 1000,
1566
+ });
1567
+ return false;
1568
+ }
1569
+
1570
+ var data = {
1571
+ taskId: taskId,
1572
+ uuid: this.wfInfo.uuid,
1573
+ receiver: this.talkForm.receiver,
1574
+ receiverName: this.talkForm.receiverName,
1575
+ replyId: this.talkForm.replyId,
1576
+ content: this.talkForm.content,
1577
+ attachmentDTOs: this.talkForm.attachmentDTOs,
1578
+ notifyType: "wfLinkup",
1579
+ };
1580
+ this.showTalkDialog = false;
1581
+ that.$http({
1582
+ url: this.current_prefix + "/wf_linkup/save",
1583
+ data: data,
1584
+ method: "post",
1585
+ isLoading: true,
1586
+ success: (resultMsg) => {
1587
+ that.$message({
1588
+ message: resultMsg.content,
1589
+ type: "success",
1590
+ duration: 500,
1591
+ onClose: (t) => {
1592
+ this.reloadContent();
1593
+ this.closeWinOnCheck(5);
1594
+ },
1595
+ });
1596
+ },
1597
+ });
1598
+ },
1599
+ openTalkUserDialog() {
1600
+ this.showTalkUserDialog = true;
1601
+ },
1602
+ confirmTalkUserDialog(rows) {
1603
+ if (rows.length > 0) {
1604
+ let row = rows[0];
1605
+ if (this.talkForm.receiver != row.id) {
1606
+ this.talkForm.replyId = null;
1607
+ }
1608
+ this.talkForm.receiver = row.id;
1609
+ this.talkForm.receiverName = row.nickName;
1610
+ }
1611
+ },
1612
+ confirmUrging() {
1613
+ this.reloadContent();
1614
+ },
1615
+ confirmDeleteTaskUser() {
1616
+ this.reloadContent();
1617
+ },
1618
+ confirmAddTaskUser(rows) {
1619
+ this.addIncreaseSignUsers = rows;
1620
+ this.addIncreaseSignForm.userNickNames = rows.map(row => row.nickName).join(',');
1621
+ // this.reloadContent();
1622
+ },
1623
+ submitAddTaskUserForm(flag) {
1624
+ let that = getTarget(this);
1625
+ let userIds = this.addIncreaseSignUsers.map((checkRow) => checkRow.id);
1626
+ if (userIds.length == 0) {
1627
+ that.$message({
1628
+ message: this.$t2('请选择候选人', 'components.wf.addIncreaseSignWarnMsg1'),
1629
+ type: "error",
1630
+ duration: 2000,
1631
+ onClose: (t) => {
1632
+ },
1633
+ });
1634
+ return false;
1635
+ }
1636
+ let toDo = () => {
1637
+ var data = JSON.stringify({
1638
+ uuid: this.wfInfo.uuid,
1639
+ taskId: this.wfInfo.taskId,
1640
+ userIds: userIds,
1641
+ suggestion: this.addIncreaseSignForm.opinion
1642
+
1643
+ });
1644
+ this.agreeDialogVisible = false;
1645
+ that.$http({
1646
+ url: this.current_prefix + "/wf/addIncreaseSign",
1647
+ data: data,
1648
+ method: "post",
1649
+ loadingTarget: document.body,
1650
+ headers: {
1651
+ "Content-Type": "application/json;charset=utf-8",
1652
+ },
1653
+ isLoading: true,
1654
+ success: (resultMsg) => {
1655
+ that.$message({
1656
+ message: resultMsg.content,
1657
+ type: "success",
1658
+ duration: 500,
1659
+ onClose: (t) => {
1660
+ this.reloadContent();
1661
+ },
1662
+ });
1663
+ },
1664
+ });
1665
+ }
1666
+ if (flag === 0) {
1667
+ toDo();
1668
+ } else {
1669
+ that.$baseConfirm(this.$t2('您确定要加签吗?', 'components.wf.addIncreaseSignConfirmTip')).then(() => {
1670
+ toDo();
1671
+ });
1672
+ }
1673
+ },
1674
+ openSetCandidateDialog(operateType) {
1675
+ this.operateType = operateType;
1676
+ this.showSetCandidateDialog = true;
1677
+ },
1678
+ closeSetCandidateDialog() {
1679
+ this.showSetCandidateDialog = false;
1680
+ this.reloadContent();
1681
+ },
1682
+ openRevokeDialog(operateType) {
1683
+ this.operateType = operateType;
1684
+ this.revokeForm = {opinion: null}
1685
+ this.revokeDialogVisible = true;
1686
+ },
1687
+ subRevokeForm(flag) {
1688
+ //撤回
1689
+ let that = getTarget(this);
1690
+ let toDo = () => {
1691
+ var data = JSON.stringify({
1692
+ uuid: this.wfInfo.uuid,
1693
+ taskId: this.wfInfo.taskId,
1694
+ suggestion: this.revokeForm.opinion,
1695
+ });
1696
+ this.revokeDialogVisible = false;
1697
+ that.$http({
1698
+ url: this.current_prefix + "/wf/revoke",
1699
+ data: data,
1700
+ method: "post",
1701
+ loadingTarget: document.body,
1702
+ headers: {
1703
+ "Content-Type": "application/json;charset=utf-8",
1704
+ },
1705
+ isLoading: true,
1706
+ success: (resultMsg) => {
1707
+ that.$message({
1708
+ message: resultMsg.content,
1709
+ type: "success",
1710
+ duration: 500,
1711
+ onClose: (t) => {
1712
+ this.reloadContent();
1713
+ },
1714
+ });
1715
+ },
1716
+ });
1717
+ }
1718
+ if (flag === 0) {
1719
+ toDo();
1720
+ } else {
1721
+ that.$baseConfirm(this.$t2('您确定要撤回吗?', 'components.wf.revokeConfirmTip')).then(() => {
1722
+ toDo();
1723
+ });
1724
+ }
1725
+ }
1726
+ }
1727
+ }
1728
+ </script>
1729
+
1730
+ <style scoped>
1731
+ ::v-deep .form-box.el-form .el-form-item .el-form-item__label {
1732
+ width: 70px
1733
+ }
1734
+ </style>