@lambo-design/workflow-approve 1.0.0-beta.85 → 1.0.0-beta.86

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.
package/src/portrait.vue CHANGED
@@ -1,201 +1,128 @@
1
1
  <template>
2
- <LamboPageContainer>
2
+ <LamboPageContainer style="padding: 0">
3
3
  <template slot="page-title">
4
- {{ title }}
4
+ <Tabs v-if="processTraceInTab" value="business" @on-click="changeTab">
5
+ <TabPane :label="title" name="business"></TabPane>
6
+ <TabPane label="流程跟踪" name="processTrace"></TabPane>
7
+ </Tabs>
8
+ <span v-else>{{ title }}</span>
5
9
  </template>
6
10
  <template slot="page-extend">
7
11
  <slot name="return-button"></slot>
8
12
  </template>
9
- <div class="portrait-lambo-indicator-card"
10
- :style="{float: 'left', width: isExpanded && showProcessInfo ? `calc(100% - ${portraitWidth+10}px)` : '99%'}">
11
- <slot name="business-content">
12
- </slot>
13
+
14
+ <!-- 横版 -->
15
+ <div v-if="inHorizontal && currentTab === 'business'" style="display: flex; flex-direction: column; height: 100%">
16
+ <!-- 业务内容区插槽 -->
17
+ <div class="portrait-lambo-indicator-card" :style="{height: `${soltHeight}px`}">
18
+ <slot name="business-content"></slot>
19
+ </div>
20
+
21
+ <!-- 流程信息区 -->
22
+ <div
23
+ v-if="openProcessInfo"
24
+ class="resizable-container"
25
+ :style="{
26
+ height: `${currentHeight}px`,
27
+ maxHeight: `${maxHeight}px`,
28
+ minHeight: `${minHeight}px`,
29
+ }">
30
+ <div
31
+ class="resizer"
32
+ @mousedown="startDrag"
33
+ :class="{ 'resizing': isResizing }">
34
+ <div class="resizer-handle"></div>
35
+ </div>
36
+
37
+ <div class="resizable-content portrait-lambo-indicator-card">
38
+ <div class="process-info-header">
39
+ <span style="flex: 1">流程信息</span>
40
+ <Icon type="md-remove" @click="changeShowHeight('reduce')" class="process-info-header-icon"/>
41
+ <Icon type="md-expand" @click="changeShowHeight('amplify')" class="process-info-header-icon"/>
42
+ <Icon type="md-refresh" @click="changeShowHeight('refresh')" class="process-info-header-icon"/>
43
+ </div>
44
+ <ProcessInfo ref="processInfo" v-show="openProcessInfo"
45
+ v-model="form.auditOpinion"
46
+ :apply-id="applyId"
47
+ :task-node="taskNode"
48
+ :proc-id="procId"
49
+ :task-id="curTaskId"
50
+ :is-detail="isDetail"
51
+ :default-audit-opinion="defaultAuditOpinion"
52
+ :push-button="pushButton"
53
+ :in-horizontal="inHorizontal"
54
+ :handle-name="handleName"
55
+ :handle-buttons="handleButtons"
56
+ :process-history="processHistory"
57
+ :portrait-width="portraitWidth"
58
+ :smart-flow-server-context="smartFlowServerContext"
59
+ @upload-file="uploadFile"/>
60
+ </div>
61
+ </div>
62
+ <div v-else>
63
+ <div class="process-info-hidden-header">
64
+ <span style="flex: 1">流程信息</span>
65
+ <Icon type="md-remove" @click="changeShowHeight('reduce')" class="process-info-header-icon"/>
66
+ <Icon type="md-expand" @click="changeShowHeight('amplify')" class="process-info-header-icon"/>
67
+ <Icon type="md-refresh" @click="changeShowHeight('refresh')" class="process-info-header-icon"/>
68
+ </div>
69
+ </div>
70
+ </div>
71
+
72
+ <div ref="processTraceTab" v-if="inHorizontal && currentTab === 'processTrace'">
73
+ <Workflow_Diagram ref="processTrace" :instanceId="process.instanceId" :applyId="process.applyId" :key="currentTab"
74
+ :procId="process.procId" :table-columns="diagramTableColumns" :scroll-element="scrollElement"
75
+ :tableData="process.tableData" :hisAudit="hisAudit"
76
+ :approve-detail-show-way="approveDetailShowWay"
77
+ :smart-flow-server-context="smartFlowServerContext">
78
+ </Workflow_Diagram>
13
79
  </div>
14
80
 
15
- <a v-if="showProcessInfo" @click="isExpanded = !isExpanded" class="arrow-button-container"
81
+ <!-- 竖版 -->
82
+ <div v-if="!inHorizontal" class="portrait-lambo-indicator-card"
83
+ :style="{float: 'left', width: isExpanded && showProcessInfo ? `calc(100% - ${portraitWidth+10}px)` : '99%'}">
84
+ <!-- 业务内容区插槽 -->
85
+ <slot v-if="currentTab === 'business'" name="business-content"></slot>
86
+ <div ref="processTraceTab" v-if="currentTab === 'processTrace'">
87
+ <Workflow_Diagram ref="processTrace" :instanceId="process.instanceId" :applyId="process.applyId" :key="currentTab"
88
+ :procId="process.procId" :table-columns="diagramTableColumns" :scroll-element="scrollElement"
89
+ :tableData="process.tableData" :hisAudit="hisAudit"
90
+ :approve-detail-show-way="approveDetailShowWay"
91
+ :smart-flow-server-context="smartFlowServerContext">
92
+ </Workflow_Diagram>
93
+ </div>
94
+ </div>
95
+ <!-- 流程信息区 -->
96
+ <a v-if="showProcessInfo && !inHorizontal" @click="isExpanded = !isExpanded" class="arrow-button-container"
16
97
  :style="{right: isExpanded ? portraitWidth+10 + 'px' : '10px'}">
17
98
  <Icon class="icon-class" v-if="isExpanded" type="ios-arrow-forward"/>
18
99
  <Icon class="icon-class" v-if="!isExpanded" type="ios-arrow-back"/>
19
100
  </a>
20
- <transition v-if="showProcessInfo" name="draw" @before-enter="beforeFlowInfoEnter" @enter="flowInfoEnter"
101
+ <transition v-if="showProcessInfo && !inHorizontal" name="draw" @before-enter="beforeFlowInfoEnter" @enter="flowInfoEnter"
21
102
  @before-leave="beforeFlowInfoLeave" @leave="flowInfoLeave">
22
103
  <lamboIndicatorCard v-show="isExpanded" class="portrait-lambo-indicator-card"
23
104
  :style="{width: portraitWidth + 'px', float: 'right'}" :hasExtend="false">
24
105
  <div slot="content-title">流程信息</div>
25
- <a v-if="!isDetail" @click="auditShow = !auditShow">
26
- <Title
27
- v-if="handleButtons && (handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile'))">
28
- <a style="color: #989898">
29
- <Icon v-if="auditShow" type="ios-arrow-down"/>
30
- <Icon v-if="!auditShow" type="ios-arrow-up"/>
31
- {{ handleName }}信息
32
- </a>
33
- </Title>
34
- </a>
35
- <transition v-if="!isDetail" name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave"
36
- @leave="leave">
37
- <div class="box" v-show="auditShow">
38
- <Form ref="auditOpinion" justify="center" :label-width="100" :model="form"
39
- v-if="handleButtons && handleButtons.includes('auditOpinion')"
40
- style="margin: 10px 0 0 10px;" :rules="ruleValidate">
41
- <FormItem :label="auditOpinionTitle" prop="auditOpinion">
42
- <AuditOpinion v-model="form.auditOpinion" :attachment-file="handleButtons.includes('attachmentFile')"
43
- :attachmentdata="fileList" :default-audit-opinion="defaultAuditOpinion"
44
- :smart-flow-server-context="smartFlowServerContext"></AuditOpinion>
45
- </FormItem>
46
- </Form>
47
- <Form ref="auditOpinion" justify="center" :label-width="100"
48
- v-if="handleButtons && !handleButtons.includes('auditOpinion') && handleButtons.includes('attachmentFile')"
49
- style="margin: 10px 0 0 10px;">
50
- <FormItem style="min-height: 70px">
51
- <Tooltip placement="bottom" max-width="200">
52
- <div style="font-size: smaller" slot="content">支持扩展名:.pdf .doc .docx .txt .xls .xlsx .jpg .jpeg
53
- .png .gif
54
- </div>
55
- <UploadFile @upload-result="uploadFile" :multiple="true"
56
- :oss-server-context="smartFlowServerContext"
57
- :oss-file-put-url="ossFilePutUrl"></UploadFile>
58
- </Tooltip>
59
- </FormItem>
60
- </Form>
61
- </div>
62
- </transition>
63
- <a v-if="taskNode && isDetail && hisAuditOpinion[0].auditOpinion" @click="auditShow = !auditShow">
64
- <Title
65
- v-if="handleButtons && (handleButtons.includes('auditOpinion') || handleButtons.includes('attachmentFile'))">
66
- <a style="color: #989898">
67
- <Icon v-if="auditShow" type="ios-arrow-down"/>
68
- <Icon v-if="!auditShow" type="ios-arrow-up"/>
69
- {{ handleName }}信息
70
- </a>
71
- </Title>
72
- </a>
73
- <transition v-if="taskNode && isDetail && hisAuditOpinion[0].auditOpinion" name="draw"
74
- @before-enter="beforeEnter"
75
- @enter="enter" @before-leave="beforeLeave" @leave="leave">
76
- <div class="box" v-show="auditShow">
77
- <Form ref="auditOpinion" justify="center" :model="form"
78
- v-if="handleButtons && handleButtons.includes('auditOpinion')"
79
- style="margin: 10px 0 0 10px;" :rules="ruleValidate">
80
- <FormItem style="margin-left: -60px">
81
- <Card v-for="(item, index) in hisAuditOpinion" :key="index">
82
- <Row style="display: flex">
83
- <Col span="24">
84
- <div style="word-wrap: break-word;">
85
- <span>{{ item.auditOpinion }}</span>
86
- <div style="position: absolute; right: 0;bottom: -18px;color: grey">{{ item.auditTime }}</div>
87
- </div>
88
- </Col>
89
- </Row>
90
- </Card>
91
- </FormItem>
92
- </Form>
93
- </div>
94
- </transition>
95
- <a @click="historyShow = !historyShow">
96
- <Title v-if="handleButtons && handleButtons.includes('auditHistory')">
97
- <a style="color: #989898">
98
- <Icon v-if="historyShow" type="ios-arrow-down"/>
99
- <Icon v-if="!historyShow" type="ios-arrow-up"/>
100
- {{ handleName }}记录
101
- </a>
102
- </Title>
103
- </a>
104
- <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
105
- <div class="box" v-show="historyShow">
106
- <Card class="process-history" :style="processHistoryHeight" dis-hover :bordered="false"
107
- v-if="handleButtons && handleButtons.includes('auditHistory')">
108
- <processHistory :portrait-width="portraitWidth" :list="processHistory" :done-page="isDetail"
109
- :push-button="pushButton"
110
- :smart-flow-server-context="smartFlowServerContext"></processHistory>
111
- </Card>
112
- </div>
113
- </transition>
114
-
115
- <a @click="attachListShow = !attachListShow">
116
- <Title v-if="handleButtons && handleButtons.includes('attachmentFile') && attachmentList.length > 0">
117
- <a style="color: #989898">
118
- <Icon v-if="attachListShow" type="ios-arrow-down"/>
119
- <Icon v-if="!attachListShow" type="ios-arrow-up"/>
120
- 查看附件
121
- </a>
122
- </Title>
123
- </a>
124
- <transition name="draw" @before-enter="beforeEnter" @enter="enter" @before-leave="beforeLeave" @leave="leave">
125
- <div class="box"
126
- v-show="handleButtons && handleButtons.includes('auditHistory') && attachmentList.length > 0 && attachListShow">
127
- <div v-for="(item, index) in attachmentList" :key="index">
128
- <Card dis-hover class="attach-card">
129
- <List item-layout="vertical">
130
- <ListItem style="margin-top: -8px">
131
- <Row style="display: flex; align-items: center;">
132
- <!-- 左边:图片 -->
133
- <Col span="4" style="margin-top: -25px">
134
- <avatar v-if="item.fileType === 'image'" icon="ios-image-outline" class="attach-avatar"
135
- style="background-color: #005aff"
136
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
137
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
138
- <avatar v-else-if="item.fileType === 'doc'" icon="ios-document-outline" class="attach-avatar"
139
- style="background-color: #005aff"
140
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
141
- :size="portraitWidth >= 600 ? 'middle' : 'small'">
142
- </avatar>
143
- <avatar v-else-if="item.fileType === 'xlsx'" icon="ios-document-outline" class="attach-avatar"
144
- style="background-color: #19be6b"
145
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
146
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
147
- <avatar v-else-if="item.fileType === 'pdf'" icon="ios-document-outline" class="attach-avatar"
148
- style="background-color: #ed4014"
149
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
150
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
151
- <avatar v-else icon="ios-document-outline" class="attach-avatar"
152
- :style="portraitWidth >= 600 ? 'margin-left: 10px' : ''"
153
- :size="portraitWidth >= 600 ? 'middle' : 'small'"></avatar>
154
- </Col>
155
- <!-- 右边:附件信息 -->
156
- <Col span="20">
157
- <Row>
158
- <tooltip>
159
- <span class="attach-name-style"> {{ item.attachName }}</span>
160
- <div slot="content" style="white-space: normal"> {{ item.attachName }}</div>
161
- </tooltip>
162
- </Row>
163
- <Row style="margin-top: 3px">
164
- <span style="color: #005aff; font-size: 13px;">{{ item.uploadUserName }}</span>
165
- <Divider style="background-color:#808695;height: 1em;margin: 4px 9px 0 6px;"
166
- type="vertical"/>
167
- <span style="color: #808695;font-size: 13px"
168
- >{{ showTaskNode(item.taskId) }}</span>
169
- </Row>
170
- <Row style="margin-bottom: -10px; margin-top: 10px">
171
- <template>
172
- <Button @click="getAttach(item)" size="small">下载</Button>
173
- <Button v-if="item.showPreview" ghost type="primary" @click="preViewAttach(item)"
174
- style="margin-left: 10px" size="small">预览
175
- </Button>
176
- </template>
177
- </Row>
178
- </Col>
179
- </Row>
180
-
181
- </ListItem>
182
- </List>
183
- </Card>
184
- </div>
185
- </div>
186
- </transition>
187
- <Modal title="查看附件" v-model="modalVisible" fullscreen scrollable :mask="false">
188
- <img :src="imageUrl" v-if="modalVisible" alt="" style="width: 100%">
189
- <div slot="footer">
190
- <Button type="primary" @click="modalVisible = false">关闭</Button>
191
- </div>
192
- </Modal>
193
- <Modal title="查看附件" v-model="modalDocx" fullscreen scrollable :mask="false">
194
- <div ref="file"></div>
195
- </Modal>
106
+ <ProcessInfo ref="processInfo"
107
+ v-model="form.auditOpinion"
108
+ :apply-id="applyId"
109
+ :task-node="taskNode"
110
+ :proc-id="procId"
111
+ :task-id="curTaskId"
112
+ :is-detail="isDetail"
113
+ :default-audit-opinion="defaultAuditOpinion"
114
+ :push-button="pushButton"
115
+ :in-horizontal="inHorizontal"
116
+ :handle-name="handleName"
117
+ :handle-buttons="handleButtons"
118
+ :process-history="processHistory"
119
+ :portrait-width="portraitWidth"
120
+ :smart-flow-server-context="smartFlowServerContext"
121
+ @upload-file="uploadFile"/>
196
122
  </lamboIndicatorCard>
197
123
  </transition>
198
124
 
125
+ <!-- 节点跳转选择弹框 -->
199
126
  <Modal v-model="modal1" title="选择节点"
200
127
  @on-cancel="cancel"
201
128
  @on-ok="doJump">
@@ -212,12 +139,14 @@
212
139
  </RadioGroup>
213
140
  </Card>
214
141
  </Modal>
142
+ <!-- 指定他人处理弹框 -->
215
143
  <assigneeBox ref="assigneeHelpBox" :execution-completed="executionCompleted"
216
144
  @update-selected="handleSelectedUser" @update-next-node-assignee="updateNextNodeAssignee"
217
145
  @add-multitask-instance="addMultitaskInstance" @delegate-task-assignee="delegateTask"
218
146
  :data="assigneeBoxData" :smart-flow-server-context="smartFlowServerContext"
219
147
  :upms-server-context="upmsServerContext"/>
220
- <Modal ref="processTraceModal" v-model="modalBoxShow" width="1000" title="流程跟踪图">
148
+ <!-- 流程跟踪图弹框 -->
149
+ <Modal v-if="!processTraceInTab" ref="processTraceModal" v-model="modalBoxShow" width="1000" title="流程跟踪图">
221
150
  <Workflow_Diagram ref="processTrace" :instanceId="process.instanceId" :applyId="process.applyId"
222
151
  :procId="process.procId" :table-columns="diagramTableColumns" :scroll-element="scrollElement"
223
152
  :tableData="process.tableData" :hisAudit="hisAudit"
@@ -225,6 +154,7 @@
225
154
  :smart-flow-server-context="smartFlowServerContext">
226
155
  </Workflow_Diagram>
227
156
  </Modal>
157
+ <!-- 减签弹框 -->
228
158
  <Modal v-model="reductionMultitaskInstanceModal" title="选择减签人员"
229
159
  @on-cancel="reductionModalCancel"
230
160
  @on-ok="reductionMultitaskInstance">
@@ -234,6 +164,7 @@
234
164
  @on-selection-change="selectAssignee">
235
165
  </Table>
236
166
  </Modal>
167
+ <!-- 下一环节设置弹框 -->
237
168
  <Modal v-model="appointBoxShow" title="下一环节设置"
238
169
  @on-cancel="appointBoxShow = false" width="600"
239
170
  @on-ok="appointOk">
@@ -331,49 +262,23 @@
331
262
  @update-cand-groups="updateCandGroups"
332
263
  :upms-server-context="upmsServerContext"
333
264
  :smart-flow-server-context="smartFlowServerContext"/>
265
+
266
+ <!-- 底部操作按钮区 -->
334
267
  <template slot="page-footer">
335
268
  <div>
336
269
  <slot name="footer-button"></slot>
337
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo70') && !isDetail && !appointTask && !rejectedTask"
338
- :disabled="disable" :loading="loading" @click="audit('70')">{{rejectName}}到原点
339
- </Button>
340
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo40') && !isDetail && !appointTask && !rejectedTask"
341
- :disabled="disable" :loading="loading" @click="audit('40')">{{rejectName}}上一节点
342
- </Button>
343
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo90') && !isDetail && !appointTask && !rejectedTask"
344
- :disabled="disable" :loading="loading" @click="audit('90')">{{rejectName}}指定节点
345
- </Button>
346
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo80') && !isDetail && !appointTask && !rejectedTask"
347
- :disabled="disable" :loading="loading" @click="audit('80')">跳转指定节点
348
- </Button>
349
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo82') && !isDetail && !appointTask && !rejectedTask"
350
- :disabled="disable" :loading="loading" @click="audit('82')">指定他人处理
351
- </Button>
352
- <Button style="margin-left: 10px;"
353
- v-if="curNodeType === 'userTask' && handleButtons && handleButtons.includes('delegateTask') && !isDetail && !appointTask && !rejectedTask"
354
- :disabled="disable" :loading="loading" @click="audit('84')">委派
355
- </Button>
356
- <Button style="margin-left: 10px;"
357
- v-if="curNodeType === 'multiNode' && handleButtons && handleButtons.includes('addMultitaskInstance') && !isDetail && !appointTask && !rejectedTask"
358
- :disabled="disable" :loading="loading" @click="showUpdateMultitaskInstanceModal('81')">加签
359
- </Button>
360
- <Button style="margin-left: 10px;"
361
- v-if="curNodeType === 'multiNode' && handleButtons && handleButtons.includes('reductionMultitaskInstance') && !isDetail && !appointTask && !rejectedTask"
362
- :disabled="disable" :loading="loading" @click="showUpdateMultitaskInstanceModal('83')">减签
363
- </Button>
364
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo50') && !isDetail && !appointTask && !rejectedTask"
365
- :disabled="disable" :loading="loading" @click="audit('50')">直接结束流程
366
- </Button>
367
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('processTrace')"
368
- @click="processPrint">流程跟踪图
369
- </Button>
370
- <Button style="margin-left: 10px;" v-if="handleButtons && handleButtons.includes('auditTo30') && !isDetail && !appointTask"
371
- :disabled="disable" :loading="loading" type="primary" @click="audit('30')">{{passName}}
270
+ <Button
271
+ v-for="button in buttons"
272
+ :key="button.id"
273
+ style="margin-left: 10px;"
274
+ v-if="button.condition"
275
+ :disabled="button.disabled || disable"
276
+ :loading="loading"
277
+ :type="button.type || 'default'"
278
+ @click="button.action"
279
+ >
280
+ {{ button.label }}
372
281
  </Button>
373
- <Button style="margin-left: 10px;" v-if="revokeDelegateTask"
374
- :disabled="!revokeDelegateTask && disable" :loading="loading" @click="audit('62')">撤回委派
375
- </Button>
376
- <Button style="margin-left: 10px;" v-if="appointTask" :disabled="disable" :loading="loading" type="primary" @click="audit('61')">交回</Button>
377
282
  </div>
378
283
  </template>
379
284
  </LamboPageContainer>
@@ -391,14 +296,9 @@ import processHistory from './components/history'
391
296
  import assigneeBox from './components/assignee-box'
392
297
  import CandidateGroupsHelpBox from './components/candidate-groups-box'
393
298
  import CountersingersBox from './components/countersigners-box'
394
- import LamboPagingTable from '@lambo-design/paging-table'
395
- import AuditOpinion from './components/opinion'
396
- import axios from 'axios'
397
- import UploadFile from '@lambo-design/upload-file'
398
299
  import { timestampToTime } from '@lambo-design/shared/utils/date'
399
-
400
- // 引入docx-preview插件
401
- let docx = require('docx-preview')
300
+ import ProcessInfo from './components/process-info'
301
+ import { nodeType } from './utils/const'
402
302
 
403
303
  export default {
404
304
  props: {
@@ -469,10 +369,20 @@ export default {
469
369
  default: () => {
470
370
  }
471
371
  },
372
+ //是否显示竖向布局
373
+ inHorizontal: {
374
+ type: Boolean,
375
+ default: false
376
+ },
472
377
  title: {
473
378
  type: String,
474
379
  default: '流程办理'
475
380
  },
381
+ //流程跟踪图以tab形式展示
382
+ processTraceInTab: {
383
+ type: Boolean,
384
+ default: false
385
+ },
476
386
  smartFlowServerContext: {
477
387
  type: String,
478
388
  default: '/api/smart-flow-server',
@@ -488,24 +398,30 @@ export default {
488
398
  Workflow_Diagram,
489
399
  processHistory,
490
400
  assigneeBox,
491
- LamboPagingTable,
492
- AuditOpinion,
493
401
  LamboIndicatorCard,
494
- UploadFile,
495
402
  CandidateGroupsHelpBox,
496
- CountersingersBox
403
+ CountersingersBox,
404
+ ProcessInfo,
497
405
  },
498
406
  data() {
499
407
  return {
500
408
  isExpanded: true,
501
409
  showProcessInfo: true,
502
410
  portraitWidth: 0,
411
+ openProcessInfo: true,
412
+ currentHeight: 0,
413
+ soltHeight: 0,
414
+ maxHeight: 0,
415
+ isResizing: false,
416
+ startY: 0,
417
+ minHeight: 0,
418
+ maxHeightPercent: 85,
419
+ initialHeightPercent: 30,
503
420
  procType: '',
504
421
  requestSuccessCodes: [200, '200'],
505
422
  auditShow: true,
506
423
  historyShow: true,
507
424
  attachListShow: true,
508
- attachmentList: [],
509
425
  modalVisible: false,
510
426
  modalDocx: false,
511
427
  imageUrl: '',
@@ -551,7 +467,7 @@ export default {
551
467
  appointTask: false,
552
468
  instanceId: '',
553
469
  curTaskId: '',
554
- curNodeType: 'userTask',
470
+ curNodeType: nodeType.userTask,
555
471
  handleButtons: [],
556
472
  handleName: '审批',
557
473
  passName: '通过',
@@ -564,6 +480,7 @@ export default {
564
480
  auditProcess: 'auditProcess',
565
481
  fileList: [],
566
482
  ossFilePutUrl: '/manage/oss/file/put',
483
+ currentTab: 'business',
567
484
  hisAudit: [],
568
485
  hisAuditOpinion: [{
569
486
  auditOpinion: '',
@@ -619,34 +536,122 @@ export default {
619
536
  },
620
537
 
621
538
  mounted() {
539
+ this.calculateDimensions();
540
+ // 监听窗口大小变化
541
+ window.addEventListener('resize', this.handleWindowResize);
542
+
622
543
  this.getWidth()
623
544
  if (this.procId) {
624
545
  this.initData()
625
546
  }
626
- let modalElement = this.$refs.processTraceModal.$el
627
- for (let i = 0; i < modalElement.children.length; i++) {
628
- //找到滚动的目标element
629
- let targetElement = modalElement.children[i]
630
- if (targetElement.classList.toString().includes('-wrap')){
631
- this.scrollElement = targetElement
632
- break
547
+ if (!this.processTraceInTab){
548
+ let modalElement = this.$refs.processTraceModal.$el
549
+ for (let i = 0; i < modalElement.children.length; i++) {
550
+ //找到滚动的目标element
551
+ let targetElement = modalElement.children[i]
552
+ if (targetElement.classList.toString().includes('-wrap')){
553
+ this.scrollElement = targetElement
554
+ break
555
+ }
633
556
  }
634
557
  }
635
558
  },
559
+ beforeDestroy() {
560
+ // 移除事件监听
561
+ window.removeEventListener('resize', this.handleWindowResize);
562
+ },
636
563
  computed: {
637
- processHistoryHeight() {
638
- let str = ''
639
- const hasAuditOpinion = this.taskNode && this.handleButtons && this.handleButtons.includes('auditOpinion')
640
- const hasAttachmentFile = this.handleButtons && this.handleButtons.includes('auditHistory') && this.attachmentList.length > 0
641
- const isDetail = this.isDetail && !this.hisAuditOpinion[0].auditOpinion.length > 0
642
- if (hasAuditOpinion && !hasAttachmentFile && !isDetail) {
643
- str += 'height: 43vh'
644
- } else if (hasAuditOpinion && hasAttachmentFile && !isDetail) {
645
- str += 'height: 40vh'
646
- } else {
647
- str += 'height: 67vh'
648
- }
649
- return str
564
+ buttons() {
565
+ const showButtons = !this.isDetail && !this.appointTask && !this.rejectedTask
566
+ return [
567
+ {
568
+ id: 'auditTo70',
569
+ label: `${this.rejectName}到原点`,
570
+ condition: this.handleButtons?.includes('auditTo70') && showButtons,
571
+ action: () => this.audit('70')
572
+ },
573
+ {
574
+ id: 'auditTo40',
575
+ label: `${this.rejectName}上一节点`,
576
+ condition: this.handleButtons?.includes('auditTo40') && showButtons,
577
+ action: () => this.audit('40')
578
+ },
579
+ {
580
+ id: 'auditTo90',
581
+ label: `${this.rejectName}指定节点`,
582
+ condition: this.handleButtons?.includes('auditTo90') && showButtons,
583
+ action: () => this.audit('90')
584
+ },
585
+ {
586
+ id: 'auditTo80',
587
+ label: '跳转指定节点',
588
+ condition: this.handleButtons?.includes('auditTo80') && showButtons,
589
+ action: () => this.audit('80')
590
+ },
591
+ {
592
+ id: 'auditTo82',
593
+ label: '指定他人处理',
594
+ condition: this.handleButtons?.includes('auditTo82') && showButtons,
595
+ action: () => this.audit('82')
596
+ },
597
+ {
598
+ id: 'delegateTask',
599
+ label: '委派',
600
+ condition: this.curNodeType === nodeType.userTask &&
601
+ this.handleButtons?.includes('delegateTask') &&
602
+ showButtons,
603
+ action: () => this.audit('84')
604
+ },
605
+ {
606
+ id: 'addMultitaskInstance',
607
+ label: '加签',
608
+ condition: this.curNodeType === nodeType.multiNode &&
609
+ this.handleButtons?.includes('addMultitaskInstance') &&
610
+ showButtons,
611
+ action: () => this.showUpdateMultitaskInstanceModal('81')
612
+ },
613
+ {
614
+ id: 'reductionMultitaskInstance',
615
+ label: '减签',
616
+ condition: this.curNodeType === nodeType.multiNode &&
617
+ this.handleButtons?.includes('reductionMultitaskInstance') &&
618
+ showButtons,
619
+ action: () => this.showUpdateMultitaskInstanceModal('83')
620
+ },
621
+ {
622
+ id: 'auditTo50',
623
+ label: '直接结束流程',
624
+ condition: this.handleButtons?.includes('auditTo50') && showButtons,
625
+ action: () => this.audit('50')
626
+ },
627
+ {
628
+ id: 'processTrace',
629
+ label: '流程跟踪图',
630
+ condition: this.handleButtons?.includes('processTrace') && !this.processTraceInTab,
631
+ action: () => this.processPrint()
632
+ },
633
+ {
634
+ id: 'auditTo30',
635
+ label: this.passName,
636
+ condition: this.handleButtons?.includes('auditTo30') && !this.isDetail && !this.appointTask,
637
+ action: () => this.audit('30'),
638
+ type: 'primary'
639
+ },
640
+ {
641
+ id: 'revokeDelegateTask',
642
+ label: '撤回委派',
643
+ condition: this.revokeDelegateTask,
644
+ action: () => this.audit('62'),
645
+ disabled: !this.revokeDelegateTask
646
+ },
647
+ {
648
+ id: 'appointTask',
649
+ label: '交回',
650
+ condition: this.appointTask,
651
+ action: () => this.audit('61'),
652
+ type: 'primary'
653
+ }
654
+ ];
650
655
  },
651
656
  nodeColumn: function () {
652
657
  let column = []
@@ -942,6 +947,75 @@ export default {
942
947
  }
943
948
  },
944
949
  methods: {
950
+ changeShowHeight(option){
951
+ const windowHeight = window.innerHeight - 50;
952
+ switch (option){
953
+ case 'reduce':
954
+ this.openProcessInfo = false
955
+ this.soltHeight = windowHeight - 80;
956
+ break;
957
+ case 'amplify':
958
+ this.openProcessInfo = true
959
+ this.currentHeight = 0.8 * windowHeight;
960
+ this.soltHeight = windowHeight - this.currentHeight - 40;
961
+ break;
962
+ case 'refresh':
963
+ this.openProcessInfo = true
964
+ this.calculateDimensions()
965
+ break;
966
+ }
967
+ },
968
+ calculateDimensions() {
969
+ const windowHeight = window.innerHeight - 50;
970
+ this.maxHeight = (this.maxHeightPercent / 100) * windowHeight;
971
+ this.minHeight = 0.15 * windowHeight;
972
+
973
+ let initialHeight = (this.initialHeightPercent / 100) * windowHeight;
974
+ initialHeight = Math.max(this.minHeight, Math.min(initialHeight, this.maxHeight));
975
+ this.currentHeight = initialHeight;
976
+ this.soltHeight = windowHeight - initialHeight - 40;
977
+ },
978
+
979
+ startDrag(e) {
980
+ e.preventDefault();
981
+ this.isResizing = true;
982
+ this.startY = e.clientY;
983
+
984
+ document.addEventListener('mousemove', this.handleDrag);
985
+ document.addEventListener('mouseup', this.stopDrag);
986
+
987
+ document.body.style.userSelect = 'none';
988
+ },
989
+
990
+ handleDrag(e) {
991
+ if (!this.isResizing) return;
992
+
993
+ const windowHeight = window.innerHeight - 50;
994
+ const deltaY = e.clientY - this.startY;
995
+ let newHeight = this.currentHeight - deltaY;
996
+
997
+ newHeight = Math.max(this.minHeight, Math.min(newHeight, this.maxHeight));
998
+
999
+ this.currentHeight = newHeight;
1000
+ this.soltHeight = windowHeight - newHeight - 40;
1001
+ this.startY = e.clientY;
1002
+ this.$emit('height-change', this.currentHeight);
1003
+ },
1004
+
1005
+ stopDrag() {
1006
+ this.isResizing = false;
1007
+
1008
+ document.removeEventListener('mousemove', this.handleDrag);
1009
+ document.removeEventListener('mouseup', this.stopDrag);
1010
+ document.body.style.userSelect = '';
1011
+
1012
+ this.$emit('resize-end', this.currentHeight);
1013
+ },
1014
+
1015
+ handleWindowResize() {
1016
+ this.calculateDimensions();
1017
+ },
1018
+
945
1019
  getWidth() {
946
1020
  if (this.width && this.width < 400) {
947
1021
  this.portraitWidth = 400
@@ -982,15 +1056,14 @@ export default {
982
1056
  let procType = todoData.procType
983
1057
  self.procType = todoData.procType
984
1058
  ajax.get(self.smartFlowServerContext + '/manage/processType/lists?proType=' + procType)
985
- .then(resp => {
986
- let data = resp.data.data.rows
987
- self.permScope = data[0].permScope
988
- self.defaultOrganTreeType = data[0].organTreeType ? data[0].organTreeType : '00'
989
- self.getNodeOrganTreeType(procType)
990
- }).catch(err => {
1059
+ .then(resp => {
1060
+ let data = resp.data.data.rows
1061
+ self.permScope = data[0].permScope
1062
+ self.defaultOrganTreeType = data[0].organTreeType ? data[0].organTreeType : '00'
1063
+ self.getNodeOrganTreeType(procType)
1064
+ }).catch(err => {
991
1065
  console.log(err)
992
1066
  })
993
- self.getAttachList(self.curTaskId)
994
1067
  self.getHisAudit(self.curTaskId)
995
1068
  self.getProcessHistory(self.curTaskId)
996
1069
  } else {
@@ -1054,7 +1127,6 @@ export default {
1054
1127
  console.log(err)
1055
1128
  })
1056
1129
  }
1057
- self.getAttachList(self.curTaskId)
1058
1130
  self.getHisAudit(self.curTaskId)
1059
1131
  self.getProcessHistory(self.curTaskId)
1060
1132
  } else {
@@ -1074,7 +1146,7 @@ export default {
1074
1146
  if (resp.data.code === '200') {
1075
1147
  self.handleButtons = resp.data.data[0].handleButtons ? resp.data.data[0].handleButtons : ["processTrace","auditHistory","auditOpinion","attachmentFile","auditTo30","auditTo70","auditTo40","auditTo90","auditTo80","auditTo82","auditTo50"];
1076
1148
  if (resp.data.data[0].hasOwnProperty('isSequential')) {
1077
- self.curNodeType = resp.data.data[0].isSequential ? 'sequentialMultiNode' : 'multiNode';
1149
+ self.curNodeType = resp.data.data[0].isSequential ? nodeType.sequentialMultiNode : nodeType.multiNode;
1078
1150
  }
1079
1151
  self.handleName = resp.data.data[0].handleName ? resp.data.data[0].handleName : '审批';
1080
1152
  self.rejectName = resp.data.data[0].rejectName ? resp.data.data[0].rejectName : '驳回';
@@ -1166,29 +1238,6 @@ export default {
1166
1238
  console.log(err)
1167
1239
  })
1168
1240
  },
1169
- getAttachList(taskId) {
1170
- const self = this
1171
- const param = {
1172
- taskId: taskId,
1173
- procId: this.procId,
1174
- applyId: this.applyId
1175
- }
1176
- ajax.get(self.smartFlowServerContext + '/manage/processDone/getAttachmentList', { params: param }).then(function (resp) {
1177
- self.attachmentList = resp.data.data.rows
1178
- self.attachmentList.forEach(item => {
1179
- const index = item.fileName.lastIndexOf('.')
1180
- const fileType = item.fileName.substr(index + 1).toLowerCase()
1181
- const imageList = ['jpg', 'gif', 'png', 'svg']
1182
- const docList = ['doc', 'docx']
1183
- const zipList = ['rar', 'zip']
1184
- const typeList = ['jpg', 'gif', 'png', 'docx']
1185
- item.fileType = imageList.indexOf(fileType) !== -1 ? 'image' : docList.indexOf(fileType) !== -1 ? 'doc' : zipList.indexOf(fileType) !== -1 ? 'zip' : fileType
1186
- item.showPreview = typeList.indexOf(fileType) !== -1
1187
- })
1188
- }).catch(err => {
1189
- console.log(err)
1190
- })
1191
- },
1192
1241
  getHisAudit(taskId) {
1193
1242
  let self = this
1194
1243
  let params = {
@@ -1590,51 +1639,9 @@ export default {
1590
1639
  doSearch() {
1591
1640
  //不需要实现,是子组件assigneeBox要求使用父组件的这个方法
1592
1641
  },
1593
- tabsChange(tab) {
1594
- console.log(tab)
1595
- },
1596
1642
  getAttach(row) {
1597
1643
  window.open(this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId, '_blank')
1598
1644
  },
1599
- preViewAttach(row) {
1600
- let reg = /\.(gif|jpg|jpeg|bmp|png|PNG)$/
1601
- let regs = /\.(pdf)$/
1602
- if (reg.test(row.fileName)) {
1603
- let url = this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId
1604
- this.imgPreview(url)
1605
- } else if (regs.test(row.fileName)) {
1606
- window.open(this.smartFlowServerContext + '/manage/oss/file/getFileStream?fileId=' + row.fileId, '_blank')
1607
- } else {
1608
- this.modalDocx = true
1609
- axios({
1610
- method: 'get',
1611
- responseType: 'blob', // 因为是流文件,所以要指定blob类型
1612
- url: this.smartFlowServerContext + '/manage/oss/file/get/' + row.fileId// 一个word下载文件的接口
1613
- }).then(({ data }) => {
1614
- docx.renderAsync(data, this.$refs.file, null, {
1615
- className: 'docx', //默认和文档样式类的类名/前缀
1616
- inWrapper: true, //启用围绕文档内容呈现包装器
1617
- ignoreWidth: false, //禁用页面的渲染宽度
1618
- ignoreHeight: false, //禁用页面的渲染高度
1619
- ignoreFonts: false, //禁用字体渲染
1620
- breakPages: true, //在分页符上启用分页
1621
- ignoreLastRenderedPageBreak: true, //在lastRenderedPageBreak元素上禁用分页
1622
- experimental: false, //启用实验功能(制表符停止计算)
1623
- trimXmlDeclaration: true, //如果为true,则在解析之前将从xml文档中删除xml声明
1624
- useBase64URL: false, //如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
1625
- useMathMLPolyfill: false, //包括用于铬、边等的MathML多填充。
1626
- showChanges: false, //启用文档更改的实验渲染(插入/删除)
1627
- debug: false, //启用额外的日志记录
1628
- })
1629
- }
1630
- )
1631
- }
1632
- },
1633
- imgPreview(url) {
1634
- this.imageUrl = url
1635
- this.modalVisible = true
1636
- },
1637
-
1638
1645
  //打印流程图信息
1639
1646
  processPrint() {
1640
1647
  let self = this
@@ -1659,17 +1666,6 @@ export default {
1659
1666
  })
1660
1667
  },
1661
1668
 
1662
- showTaskNode(taskId) {
1663
- if (this.processHistory.length > 0) {
1664
- let task = null
1665
- this.processHistory.some(itemList => {
1666
- task = itemList.find(item => item.taskId === taskId)
1667
- return task !== undefined
1668
- })
1669
- return task ? task.taskName : ''
1670
- }
1671
- return ''
1672
- },
1673
1669
  cancel() {
1674
1670
  this.modal = false
1675
1671
  this.auditResult = ''
@@ -1776,15 +1772,8 @@ export default {
1776
1772
  el.style.transform = 'translateX(100%)'
1777
1773
  el.addEventListener('transitionend', done)
1778
1774
  },
1779
- uploadFile(file) {
1780
- const self = this
1781
- self.fileList = []
1782
- file.forEach(item => {
1783
- self.fileList.push({
1784
- fileName: item.fileName,
1785
- fileId: item.fileCode,
1786
- })
1787
- })
1775
+ uploadFile(fileList) {
1776
+ this.fileList = fileList
1788
1777
  },
1789
1778
 
1790
1779
  appointOk() {
@@ -1912,24 +1901,24 @@ export default {
1912
1901
  } else {
1913
1902
  if (self.auditParams.auditResult == '40'){
1914
1903
  self.rejectAttributeList.push(
1915
- {
1916
- type: 'returnToCurrentAuditUser',
1917
- name: '返回我'
1918
- }
1904
+ {
1905
+ type: 'returnToCurrentAuditUser',
1906
+ name: '返回我'
1907
+ }
1919
1908
  )
1920
1909
  } else {
1921
1910
  self.rejectAttributeList.push(
1922
- {
1923
- type: 'returnToCurrentNode',
1924
- name: '返回本节点'
1925
- }
1911
+ {
1912
+ type: 'returnToCurrentNode',
1913
+ name: '返回本节点'
1914
+ }
1926
1915
  )
1927
1916
  if (!resp.data.data.multiNode){
1928
1917
  self.rejectAttributeList.push(
1929
- {
1930
- type: 'returnToCurrentAuditUser',
1931
- name: '返回我'
1932
- }
1918
+ {
1919
+ type: 'returnToCurrentAuditUser',
1920
+ name: '返回我'
1921
+ }
1933
1922
  )
1934
1923
  }
1935
1924
  }
@@ -1954,7 +1943,28 @@ export default {
1954
1943
  return originalString.replace(regex, replaceString)
1955
1944
  }
1956
1945
  return originalString
1957
- }
1946
+ },
1947
+ changeTab(name){
1948
+ if (name === 'processTrace'){
1949
+ this.processPrint()
1950
+ this.$nextTick(() => {
1951
+ setTimeout(() => {
1952
+ if (this.$refs.processTraceTab.$el) {
1953
+ let modalElement = this.$refs.processTraceTab.$el
1954
+ for (let i = 0; i < modalElement.children.length; i++) {
1955
+ //找到滚动的目标element
1956
+ let targetElement = modalElement.children[i]
1957
+ if (targetElement.classList.toString().includes('-wrap')){
1958
+ this.scrollElement = targetElement
1959
+ break
1960
+ }
1961
+ }
1962
+ }
1963
+ }, 1000);
1964
+ })
1965
+ }
1966
+ this.currentTab = name
1967
+ },
1958
1968
  },
1959
1969
  watch: {
1960
1970
  auditOpinionText(label) {
@@ -1990,7 +2000,17 @@ export default {
1990
2000
  padding: 10px;
1991
2001
  }
1992
2002
 
1993
- .page-info /deep/ .page-body {
2003
+ /deep/ .page-body {
1994
2004
  overflow-y: hidden;
2005
+ padding: 0 0 50px 0 !important;
2006
+ }
2007
+
2008
+ /deep/ .ivu-tabs-bar {
2009
+ margin-bottom: 0;
2010
+ }
2011
+
2012
+ /deep/ .ivu-tabs-nav .ivu-tabs-tab {
2013
+ padding: 4px 16px;
1995
2014
  }
2015
+
1996
2016
  </style>