n20-common-lib 3.3.0 → 3.3.2
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/package.json +2 -2
- package/src/assets/css/_coreLib.scss +1 -0
- package/src/assets/css/v3/approval-card.scss +513 -0
- package/src/components/ApprovalButtons/getApprovalConfig.js +87 -0
- package/src/components/ApprovalButtons/index.vue +14 -17
- package/src/components/ApprovalRecord/index.vue +8 -4
- package/src/components/FileUploadTable/index.vue +84 -24
- package/src/components/v3/ApprovalCard/index.vue +634 -0
- package/src/i18n.json +7 -0
- package/src/index.js +3 -0
- package/style/index.css +1 -1
- package/theme/blue.css +1 -1
- package/theme/cctcRed.css +1 -1
- package/theme/green.css +1 -1
- package/theme/lightBlue.css +1 -1
- package/theme/orange.css +1 -1
- package/theme/purple.css +1 -1
- package/theme/red.css +1 -1
- package/theme/yellow.css +1 -1
- package/theme/fonts/iconfont.1871f864.ttf +0 -0
- package/theme/fonts/iconfont.7ddd3bd8.woff +0 -0
- package/theme/fonts/iconfont.ca8ecaf4.woff2 +0 -0
|
@@ -0,0 +1,634 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="v3-approval-card">
|
|
3
|
+
<div class="v3-approval-card__timeline">
|
|
4
|
+
<section
|
|
5
|
+
v-for="(item, index) in displayApprovalData"
|
|
6
|
+
:key="getItemKey(item, index)"
|
|
7
|
+
class="v3-approval-card__item"
|
|
8
|
+
:class="statusClass(item)"
|
|
9
|
+
>
|
|
10
|
+
<span v-if="index < displayApprovalData.length - 1" class="v3-approval-card__track"></span>
|
|
11
|
+
<span class="v3-approval-card__dot"></span>
|
|
12
|
+
|
|
13
|
+
<header class="v3-approval-card__node-header">
|
|
14
|
+
<div class="v3-approval-card__title-row">
|
|
15
|
+
<span class="v3-approval-card__title">{{ resultTitle(item) }}</span>
|
|
16
|
+
<span v-if="isWaiting(item) && getPendingUsers(item).length" class="v3-approval-card__count">
|
|
17
|
+
· {{ getPendingUsers(item).length }} {{ $lc('人') }}
|
|
18
|
+
</span>
|
|
19
|
+
</div>
|
|
20
|
+
<div v-if="showNodeMeta(item)" class="v3-approval-card__meta">
|
|
21
|
+
<span v-if="item.endTime">{{ item.endTime }}</span>
|
|
22
|
+
<span v-if="item.endTime && item.approvalCost" class="v3-approval-card__meta-divider"></span>
|
|
23
|
+
<span v-if="item.approvalCost" class="v3-approval-card__cost">
|
|
24
|
+
<i class="el-icon-time"></i>
|
|
25
|
+
{{ $lc('本节点用时') }} {{ item.approvalCost }}
|
|
26
|
+
</span>
|
|
27
|
+
</div>
|
|
28
|
+
</header>
|
|
29
|
+
|
|
30
|
+
<div v-if="isWaiting(item)" class="v3-approval-card__panel v3-approval-card__pending-panel">
|
|
31
|
+
<div class="v3-approval-card__panel-title">{{ $lc('待审批人') }}</div>
|
|
32
|
+
<div class="v3-approval-card__pending-users">
|
|
33
|
+
<div
|
|
34
|
+
v-for="(user, userIndex) in getPendingUsers(item)"
|
|
35
|
+
:key="`${getUserName(user)}-${userIndex}`"
|
|
36
|
+
class="v3-approval-card__pending-user"
|
|
37
|
+
>
|
|
38
|
+
<span class="v3-approval-card__avatar">
|
|
39
|
+
<img v-if="getUserAvatar(user)" :src="getUserAvatar(user)" :alt="getUserName(user)" />
|
|
40
|
+
<i v-else class="n20-icon-user"></i>
|
|
41
|
+
</span>
|
|
42
|
+
<span>{{ getUserName(user) }}</span>
|
|
43
|
+
<span v-if="userIndex < getPendingUsers(item).length - 1" class="v3-approval-card__separator">、</span>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<template v-else-if="!isEnd(item)">
|
|
49
|
+
<div v-if="item.addTaskName" class="v3-approval-card__add-task">
|
|
50
|
+
<span>{{ $lc('加签审批人:') }}</span>
|
|
51
|
+
<span class="v3-approval-card__avatar v3-approval-card__avatar--small">
|
|
52
|
+
<i class="n20-icon-user"></i>
|
|
53
|
+
</span>
|
|
54
|
+
<span>{{ item.addTaskName }}</span>
|
|
55
|
+
<span v-if="item.addTaskTag" class="v3-approval-card__add-task-tag">
|
|
56
|
+
{{ item.addTaskTag | remarkF(remarkOpt) }}
|
|
57
|
+
</span>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="v3-approval-card__panel v3-approval-card__person-panel">
|
|
61
|
+
<div
|
|
62
|
+
v-if="getOrganizationText(item) || item.showConnect === '1'"
|
|
63
|
+
class="v3-approval-card__organization-row"
|
|
64
|
+
>
|
|
65
|
+
<span v-title="getOrganizationText(item)" class="v3-approval-card__organization">
|
|
66
|
+
{{ getOrganizationText(item) }}
|
|
67
|
+
</span>
|
|
68
|
+
<button
|
|
69
|
+
v-if="item.showConnect === '1'"
|
|
70
|
+
type="button"
|
|
71
|
+
class="v3-approval-card__link-button"
|
|
72
|
+
@click="seeDetail(item)"
|
|
73
|
+
>
|
|
74
|
+
{{ $lc('查看详情') }}
|
|
75
|
+
</button>
|
|
76
|
+
</div>
|
|
77
|
+
<div v-if="item.assignee" class="v3-approval-card__assignee-pill">
|
|
78
|
+
<span class="v3-approval-card__avatar">
|
|
79
|
+
<img v-if="getUserAvatar(item)" :src="getUserAvatar(item)" :alt="item.assignee" />
|
|
80
|
+
<i v-else class="n20-icon-user"></i>
|
|
81
|
+
</span>
|
|
82
|
+
<span class="v3-approval-card__assignee-name">{{ item.assignee }}</span>
|
|
83
|
+
<span v-if="getTerminalLabel(item)" class="v3-approval-card__terminal"
|
|
84
|
+
>· {{ getTerminalLabel(item) }}</span
|
|
85
|
+
>
|
|
86
|
+
</div>
|
|
87
|
+
<div v-if="item.ccUserName" class="v3-approval-card__secondary-line">
|
|
88
|
+
{{ $lc('抄送人:') }}{{ item.ccUserName }}
|
|
89
|
+
</div>
|
|
90
|
+
<div
|
|
91
|
+
v-if="showSuggestionContent(item) && item.suggestion && !item.subProcInitId"
|
|
92
|
+
class="v3-approval-card__opinion"
|
|
93
|
+
>
|
|
94
|
+
<span v-if="item.result !== status.waiting">{{ $lc('审批意见:') }}</span>
|
|
95
|
+
<span>{{ item.suggestion }}</span>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<div
|
|
100
|
+
v-if="showSuggestionContent(item) && item.subProcInitId"
|
|
101
|
+
class="v3-approval-card__panel v3-approval-card__sub-process"
|
|
102
|
+
>
|
|
103
|
+
<button
|
|
104
|
+
type="button"
|
|
105
|
+
class="v3-approval-card__sub-process-trigger"
|
|
106
|
+
@click="seeApproveChild(item.subProcInitId)"
|
|
107
|
+
>
|
|
108
|
+
<span>{{ item.suggestion || $lc('查看子流程') }}</span>
|
|
109
|
+
<i :class="showChildTimeline ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
|
|
110
|
+
</button>
|
|
111
|
+
<div v-if="showChildTimeline" class="v3-approval-card__child-list">
|
|
112
|
+
<div
|
|
113
|
+
v-for="(row, childIndex) in displayApprovalChildrenData"
|
|
114
|
+
:key="getItemKey(row, childIndex)"
|
|
115
|
+
class="v3-approval-card__child-item"
|
|
116
|
+
>
|
|
117
|
+
<div class="v3-approval-card__child-title-row">
|
|
118
|
+
<span :class="['v3-approval-card__child-title', statusClass(row)]">{{ resultTitle(row) }}</span>
|
|
119
|
+
<span v-if="row.endTime" class="v3-approval-card__child-time">{{ row.endTime }}</span>
|
|
120
|
+
</div>
|
|
121
|
+
<div v-if="getOrganizationText(row)" class="v3-approval-card__organization">
|
|
122
|
+
{{ getOrganizationText(row) }}
|
|
123
|
+
</div>
|
|
124
|
+
<div v-if="row.assignee" class="v3-approval-card__assignee-pill">
|
|
125
|
+
<span class="v3-approval-card__avatar v3-approval-card__avatar--small">
|
|
126
|
+
<i class="n20-icon-user"></i>
|
|
127
|
+
</span>
|
|
128
|
+
<span>{{ row.assignee }}</span>
|
|
129
|
+
</div>
|
|
130
|
+
<div v-if="row.ccUserName" class="v3-approval-card__secondary-line">
|
|
131
|
+
{{ $lc('抄送人:') }}{{ row.ccUserName }}
|
|
132
|
+
</div>
|
|
133
|
+
<div v-if="row.addTaskName" class="v3-approval-card__secondary-line">
|
|
134
|
+
{{ $lc('加签审批人:') }}{{ row.addTaskName }}
|
|
135
|
+
</div>
|
|
136
|
+
<div v-if="showSuggestionContent(row) && row.suggestion" class="v3-approval-card__opinion">
|
|
137
|
+
<span v-if="row.result !== status.waiting">{{ $lc('审批意见:') }}</span>
|
|
138
|
+
<span>{{ row.suggestion }}</span>
|
|
139
|
+
</div>
|
|
140
|
+
<div
|
|
141
|
+
v-if="showSuggestionContent(row) && row.flowHistoryCfgs && row.flowHistoryCfgs.length"
|
|
142
|
+
class="v3-approval-card__child-review"
|
|
143
|
+
>
|
|
144
|
+
<div class="v3-approval-card__review-header">
|
|
145
|
+
<span>{{ $lc('审查意见') }}</span>
|
|
146
|
+
<button
|
|
147
|
+
type="button"
|
|
148
|
+
class="v3-approval-card__link-button v3-approval-card__collapse-button"
|
|
149
|
+
@click="showFlowHistoryChild = !showFlowHistoryChild"
|
|
150
|
+
>
|
|
151
|
+
<i :class="showFlowHistoryChild ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
|
|
152
|
+
{{ showFlowHistoryChild ? $lc('收起') : $lc('展开') }}
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
<div v-show="showFlowHistoryChild" class="v3-approval-card__review-content">
|
|
156
|
+
<div
|
|
157
|
+
v-for="(history, historyIndex) in row.flowHistoryCfgs"
|
|
158
|
+
:key="historyIndex"
|
|
159
|
+
class="v3-approval-card__review-row"
|
|
160
|
+
:class="{ 'is-stacked': align !== 'left-right' }"
|
|
161
|
+
>
|
|
162
|
+
<span>{{ history.cfgName }}:{{ history.cfgText || history.cfgVal }}</span>
|
|
163
|
+
<span v-if="history.cfgRemark">{{ history.cfgRemark }}</span>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
<div v-if="row.flowHisFileList && row.flowHisFileList.length" class="v3-approval-card__child-files">
|
|
168
|
+
<button
|
|
169
|
+
v-for="(file, fileIndex) in row.flowHisFileList"
|
|
170
|
+
:key="`${file.beid || file.fileName}-${fileIndex}`"
|
|
171
|
+
type="button"
|
|
172
|
+
class="v3-approval-card__child-file"
|
|
173
|
+
@click="preview(file)"
|
|
174
|
+
>
|
|
175
|
+
{{ file.fileName }}
|
|
176
|
+
</button>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
|
|
182
|
+
<div
|
|
183
|
+
v-if="showSuggestionContent(item) && item.flowHistoryCfgs && item.flowHistoryCfgs.length"
|
|
184
|
+
class="v3-approval-card__panel v3-approval-card__review-panel"
|
|
185
|
+
>
|
|
186
|
+
<div class="v3-approval-card__review-header">
|
|
187
|
+
<span>{{ $lc('审查意见') }}</span>
|
|
188
|
+
<button
|
|
189
|
+
type="button"
|
|
190
|
+
class="v3-approval-card__link-button v3-approval-card__collapse-button"
|
|
191
|
+
@click="showFlowHistory = !showFlowHistory"
|
|
192
|
+
>
|
|
193
|
+
<i :class="showFlowHistory ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
|
|
194
|
+
{{ showFlowHistory ? $lc('收起') : $lc('展开') }}
|
|
195
|
+
</button>
|
|
196
|
+
</div>
|
|
197
|
+
<div v-show="showFlowHistory" class="v3-approval-card__review-content">
|
|
198
|
+
<div
|
|
199
|
+
v-for="(history, historyIndex) in item.flowHistoryCfgs"
|
|
200
|
+
:key="historyIndex"
|
|
201
|
+
class="v3-approval-card__review-row"
|
|
202
|
+
:class="{ 'is-stacked': align !== 'left-right' }"
|
|
203
|
+
>
|
|
204
|
+
<span>{{ history.cfgName }}:{{ history.cfgText || history.cfgVal }}</span>
|
|
205
|
+
<span v-if="history.cfgRemark">{{ history.cfgRemark }}</span>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div
|
|
211
|
+
v-if="item.flowHisFileList && item.flowHisFileList.length"
|
|
212
|
+
class="v3-approval-card__panel v3-approval-card__file-panel"
|
|
213
|
+
>
|
|
214
|
+
<div class="v3-approval-card__panel-title">{{ $lc('附件') }}</div>
|
|
215
|
+
<div class="v3-approval-card__file-list">
|
|
216
|
+
<div
|
|
217
|
+
v-for="(file, fileIndex) in item.flowHisFileList"
|
|
218
|
+
:key="`${file.beid || file.fileName}-${fileIndex}`"
|
|
219
|
+
class="v3-approval-card__file-item"
|
|
220
|
+
>
|
|
221
|
+
<div class="v3-approval-card__file-main">
|
|
222
|
+
<img class="v3-approval-card__file-icon" :src="getFileIcon(file.fileName)" alt="" />
|
|
223
|
+
<span v-title="file.fileName" class="v3-approval-card__file-name">{{ file.fileName }}</span>
|
|
224
|
+
</div>
|
|
225
|
+
<div class="v3-approval-card__file-actions">
|
|
226
|
+
<span class="v3-approval-card__file-divider"></span>
|
|
227
|
+
<button type="button" :title="$lc('预览')" @click="preview(file)">
|
|
228
|
+
<i class="el-icon-view"></i>
|
|
229
|
+
</button>
|
|
230
|
+
<button type="button" :title="$lc('下载')" @click="downFile(file)">
|
|
231
|
+
<i class="el-icon-download"></i>
|
|
232
|
+
</button>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</template>
|
|
238
|
+
</section>
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
<el-drawer
|
|
242
|
+
class="v3-approval-card__preview-drawer"
|
|
243
|
+
custom-class="v3-approval-card__drawer"
|
|
244
|
+
:visible.sync="visibleP"
|
|
245
|
+
direction="rtl"
|
|
246
|
+
size="60%"
|
|
247
|
+
:append-to-body="true"
|
|
248
|
+
:wrapper-closable="true"
|
|
249
|
+
@close="closeSee"
|
|
250
|
+
>
|
|
251
|
+
<div slot="title" class="v3-approval-card__drawer-header">
|
|
252
|
+
<span class="v3-approval-card__drawer-title">{{ $lc('附件预览') }}</span>
|
|
253
|
+
<el-button v-if="seeRow && seeRow.beid" plain size="mini" @click.stop="downFile(seeRow)">
|
|
254
|
+
{{ $lc('下载') }}
|
|
255
|
+
</el-button>
|
|
256
|
+
</div>
|
|
257
|
+
<div v-if="visibleP" class="v3-approval-card__drawer-body">
|
|
258
|
+
<component
|
|
259
|
+
:is="previewSameOrg ? 'object' : 'div'"
|
|
260
|
+
:key="previewUrl"
|
|
261
|
+
:data="previewUrl"
|
|
262
|
+
class="v3-approval-card__preview-content"
|
|
263
|
+
>
|
|
264
|
+
<div class="v3-approval-card__preview-fallback">
|
|
265
|
+
<i class="el-icon-s-release"></i>
|
|
266
|
+
<span>
|
|
267
|
+
{{ $lc('不支持在线预览,请') }}
|
|
268
|
+
<el-link type="primary" @click="downFile(seeRow)">{{ $lc('下载') }}</el-link>
|
|
269
|
+
{{ $lc('到本地查看') }}
|
|
270
|
+
</span>
|
|
271
|
+
</div>
|
|
272
|
+
</component>
|
|
273
|
+
</div>
|
|
274
|
+
</el-drawer>
|
|
275
|
+
</div>
|
|
276
|
+
</template>
|
|
277
|
+
|
|
278
|
+
<script>
|
|
279
|
+
import getJsonc from '../../../assets/getJsonc.js'
|
|
280
|
+
import axios from '../../../utils/axios'
|
|
281
|
+
import { $lc } from '../../../utils/i18n/index'
|
|
282
|
+
import { linkPush } from '../../../utils/urlToGo.js'
|
|
283
|
+
import pdfIcon from '../UploadList/assets/37.svg'
|
|
284
|
+
import wordIcon from '../UploadList/assets/46.svg'
|
|
285
|
+
import excelIcon from '../UploadList/assets/60.svg'
|
|
286
|
+
import defaultFileIcon from '../UploadList/assets/not.svg'
|
|
287
|
+
import pngIcon from '../UploadList/assets/Png.svg'
|
|
288
|
+
import txtIcon from '../UploadList/assets/Txt.svg'
|
|
289
|
+
import zipIcon from '../UploadList/assets/Zip.svg'
|
|
290
|
+
|
|
291
|
+
function getApprovalExtend() {
|
|
292
|
+
if (typeof window === 'undefined') return {}
|
|
293
|
+
if (!window._approvalExtend) window._approvalExtend = {}
|
|
294
|
+
return window._approvalExtend
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export default {
|
|
298
|
+
name: 'ApprovalCardV3',
|
|
299
|
+
filters: {
|
|
300
|
+
remarkF(value, list) {
|
|
301
|
+
const option = (list || []).find((item) => item.code === value)
|
|
302
|
+
return option ? option.name : value
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
props: {
|
|
306
|
+
apiPrefix: {
|
|
307
|
+
type: String,
|
|
308
|
+
default: undefined
|
|
309
|
+
},
|
|
310
|
+
close: {
|
|
311
|
+
type: Boolean,
|
|
312
|
+
default: false
|
|
313
|
+
},
|
|
314
|
+
status: {
|
|
315
|
+
type: Object,
|
|
316
|
+
default: () => ({
|
|
317
|
+
waiting: 0,
|
|
318
|
+
submit: 1,
|
|
319
|
+
approval: 2,
|
|
320
|
+
reject: 3,
|
|
321
|
+
invalid: 4,
|
|
322
|
+
end: 5,
|
|
323
|
+
revocation: 6
|
|
324
|
+
})
|
|
325
|
+
},
|
|
326
|
+
approvalData: {
|
|
327
|
+
type: Array,
|
|
328
|
+
default: () => []
|
|
329
|
+
},
|
|
330
|
+
procInstId: {
|
|
331
|
+
type: String,
|
|
332
|
+
default: undefined
|
|
333
|
+
},
|
|
334
|
+
hideLoading: {
|
|
335
|
+
type: Boolean,
|
|
336
|
+
default: false
|
|
337
|
+
},
|
|
338
|
+
align: {
|
|
339
|
+
type: String,
|
|
340
|
+
default: 'left-right'
|
|
341
|
+
},
|
|
342
|
+
seeTypes: {
|
|
343
|
+
type: RegExp,
|
|
344
|
+
default: () => /\.(jpg|png|gif|svg|pdf|swf|xlsx|xls|docx|doc|txt)$/i
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
data() {
|
|
348
|
+
this.approvalRequestId = 0
|
|
349
|
+
this.remarkRequest = null
|
|
350
|
+
return {
|
|
351
|
+
remoteApprovalData: [],
|
|
352
|
+
remarkOpt: [],
|
|
353
|
+
showChildTimeline: false,
|
|
354
|
+
approvalChildrenData: [],
|
|
355
|
+
showCtdMsg: getApprovalExtend()['card.countermand.suggestion'] === true,
|
|
356
|
+
visibleP: false,
|
|
357
|
+
previewUrl: '',
|
|
358
|
+
previewSameOrg: false,
|
|
359
|
+
seeRow: {},
|
|
360
|
+
showFlowHistory: true,
|
|
361
|
+
showFlowHistoryChild: true
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
computed: {
|
|
365
|
+
resolvedApprovalData() {
|
|
366
|
+
return [...(this.approvalData || []), ...this.remoteApprovalData]
|
|
367
|
+
},
|
|
368
|
+
displayApprovalData() {
|
|
369
|
+
// 保持旧版 el-timeline reverse 的展示顺序,但不再修改调用方传入的数组。
|
|
370
|
+
return [...this.resolvedApprovalData].reverse()
|
|
371
|
+
},
|
|
372
|
+
displayApprovalChildrenData() {
|
|
373
|
+
return [...(this.approvalChildrenData || [])].reverse()
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
watch: {
|
|
377
|
+
procInstId: {
|
|
378
|
+
immediate: true,
|
|
379
|
+
handler(value) {
|
|
380
|
+
this.loadApprovalData(value)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
beforeDestroy() {
|
|
385
|
+
this.approvalRequestId += 1
|
|
386
|
+
this.closeSee()
|
|
387
|
+
},
|
|
388
|
+
methods: {
|
|
389
|
+
async loadApprovalData(procInstId) {
|
|
390
|
+
const requestId = ++this.approvalRequestId
|
|
391
|
+
if (!procInstId) {
|
|
392
|
+
this.remoteApprovalData = []
|
|
393
|
+
return
|
|
394
|
+
}
|
|
395
|
+
// 切换流程实例时先清空旧记录,避免新请求完成前短暂展示上一条流程的数据。
|
|
396
|
+
this.remoteApprovalData = []
|
|
397
|
+
try {
|
|
398
|
+
const data = await this.getProcInstData(procInstId)
|
|
399
|
+
// 只接收最后一次请求,避免快速切换流程实例时出现旧数据回写。
|
|
400
|
+
if (requestId === this.approvalRequestId) {
|
|
401
|
+
this.remoteApprovalData = data
|
|
402
|
+
}
|
|
403
|
+
} catch (error) {
|
|
404
|
+
if (requestId === this.approvalRequestId) {
|
|
405
|
+
this.remoteApprovalData = []
|
|
406
|
+
}
|
|
407
|
+
return error
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
async seeDetail(item) {
|
|
411
|
+
const details = (item && item._details) || {}
|
|
412
|
+
if (!details.appNo) {
|
|
413
|
+
this.$message.error($lc('未配置审批详情链接'))
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
const { appUrl = {} } = await getJsonc('activiti/server-config.jsonc', null, true)
|
|
417
|
+
if (!appUrl[details.appNo]) {
|
|
418
|
+
this.$message.error($lc('未配置审批详情链接'))
|
|
419
|
+
return
|
|
420
|
+
}
|
|
421
|
+
linkPush(`${appUrl[details.appNo]}/${details.typeCode}`, {
|
|
422
|
+
taskId: details.taskId,
|
|
423
|
+
typeCode: details.typeCode,
|
|
424
|
+
processInstanceId: details.procInstId,
|
|
425
|
+
appNo: details.appNo,
|
|
426
|
+
businessId: details.businessId
|
|
427
|
+
})
|
|
428
|
+
},
|
|
429
|
+
async seeApproveChild(id) {
|
|
430
|
+
this.showChildTimeline = !this.showChildTimeline
|
|
431
|
+
if (!this.showChildTimeline) {
|
|
432
|
+
this.approvalChildrenData = []
|
|
433
|
+
return
|
|
434
|
+
}
|
|
435
|
+
try {
|
|
436
|
+
this.approvalChildrenData = await this.getProcInstData(id)
|
|
437
|
+
} catch (error) {
|
|
438
|
+
this.approvalChildrenData = []
|
|
439
|
+
return error
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
async getProcInstData(procInstId) {
|
|
443
|
+
const { data } = await axios.get(
|
|
444
|
+
`/bems/activiti/sample/Q003?r=${Math.random()}`,
|
|
445
|
+
{ procInstId },
|
|
446
|
+
{ loading: !this.hideLoading }
|
|
447
|
+
)
|
|
448
|
+
return (Array.isArray(data) ? data : [])
|
|
449
|
+
.map((item) => this.normalizeApprovalItem(item))
|
|
450
|
+
.filter((item) => item.isShow !== '0')
|
|
451
|
+
},
|
|
452
|
+
normalizeApprovalItem(item) {
|
|
453
|
+
const resultNames = String(item.optResult || '').split('-')
|
|
454
|
+
const rawResultName = resultNames[resultNames.length - 1]
|
|
455
|
+
const normalizedResultName = rawResultName === $lc('推进') ? $lc('批准') : rawResultName
|
|
456
|
+
const approvalItem = {
|
|
457
|
+
approvalCost: item.approvalCost,
|
|
458
|
+
job: item.job || '',
|
|
459
|
+
isShow: item.isShow,
|
|
460
|
+
endTime: item.endTime || '',
|
|
461
|
+
assignee: item.assignee,
|
|
462
|
+
assigneeList: item.assigneeList,
|
|
463
|
+
approvers: item.approvers,
|
|
464
|
+
suggestion: item.suggestion,
|
|
465
|
+
roleName: item.roleName,
|
|
466
|
+
flowHisFileList: item.flowHisFileList || null,
|
|
467
|
+
ccUserName: item.ccUserName,
|
|
468
|
+
addTaskName: item.addTaskName,
|
|
469
|
+
memberName: item.memberName,
|
|
470
|
+
subProcInitId: item.subProcInitId,
|
|
471
|
+
appOrPc: item.appOrPc,
|
|
472
|
+
outTitle: item.outTitle,
|
|
473
|
+
showConnect: item.showConnect,
|
|
474
|
+
deptName: item.deptName,
|
|
475
|
+
addTaskTag: item.addTaskTag,
|
|
476
|
+
flowHistoryCfgs: item.flowHistoryCfgs,
|
|
477
|
+
avatar: item.avatar,
|
|
478
|
+
avatarUrl: item.avatarUrl,
|
|
479
|
+
photoUrl: item.photoUrl,
|
|
480
|
+
headImg: item.headImg,
|
|
481
|
+
resultName: item.optName || normalizedResultName,
|
|
482
|
+
resultNameA: normalizedResultName,
|
|
483
|
+
_details: item
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (approvalItem.addTaskTag && this.remarkOpt.length === 0) {
|
|
487
|
+
this.getMdmDataDoc()
|
|
488
|
+
}
|
|
489
|
+
if (item.taskName === $lc('开始')) {
|
|
490
|
+
approvalItem.result = this.status.submit
|
|
491
|
+
} else if (approvalItem.resultNameA === $lc('加签推进')) {
|
|
492
|
+
approvalItem.result = this.status.approval
|
|
493
|
+
} else if (approvalItem.resultNameA === $lc('作废')) {
|
|
494
|
+
approvalItem.result = this.status.invalid
|
|
495
|
+
} else if (item.taskName === $lc('结束')) {
|
|
496
|
+
approvalItem.result = this.status.end
|
|
497
|
+
} else if (Object.prototype.hasOwnProperty.call(item, 'approvalState')) {
|
|
498
|
+
approvalItem.result = item.approvalState
|
|
499
|
+
} else if (!item.endTime) {
|
|
500
|
+
approvalItem.result = this.status.waiting
|
|
501
|
+
} else if (item.rejectFlag === 1) {
|
|
502
|
+
approvalItem.result = this.status.reject
|
|
503
|
+
} else {
|
|
504
|
+
approvalItem.result = this.status.approval
|
|
505
|
+
}
|
|
506
|
+
return approvalItem
|
|
507
|
+
},
|
|
508
|
+
async getMdmDataDoc() {
|
|
509
|
+
if (this.remarkRequest) return this.remarkRequest
|
|
510
|
+
this.remarkRequest = axios.get(`/bems/1.0/mdmDataDoc?t=${Math.random()}`, { typeCode: 'ADD_TASK_TAG' })
|
|
511
|
+
try {
|
|
512
|
+
const { code, data } = await this.remarkRequest
|
|
513
|
+
if (code === 200) {
|
|
514
|
+
this.remarkOpt = data || []
|
|
515
|
+
}
|
|
516
|
+
} catch (error) {
|
|
517
|
+
// 字典仅用于展示加签标签,请求失败不应阻断审批记录渲染。
|
|
518
|
+
return error
|
|
519
|
+
} finally {
|
|
520
|
+
this.remarkRequest = null
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
preview(row = {}) {
|
|
524
|
+
const fileName = row.fileName || ''
|
|
525
|
+
this.visibleP = true
|
|
526
|
+
this.seeRow = row
|
|
527
|
+
this.previewUrl = row.beid ? `/api/onlinePreview?beid=${row.beid}` : ''
|
|
528
|
+
// 全局正则的 lastIndex 会影响连续预览结果,每次判断前后均复位。
|
|
529
|
+
this.seeTypes.lastIndex = 0
|
|
530
|
+
this.previewSameOrg = this.seeTypes.test(fileName)
|
|
531
|
+
this.seeTypes.lastIndex = 0
|
|
532
|
+
},
|
|
533
|
+
closeSee() {
|
|
534
|
+
if (this.previewUrl && this.previewUrl.indexOf('blob:') === 0 && typeof URL !== 'undefined') {
|
|
535
|
+
URL.revokeObjectURL(this.previewUrl)
|
|
536
|
+
}
|
|
537
|
+
this.previewUrl = ''
|
|
538
|
+
this.previewSameOrg = false
|
|
539
|
+
this.seeRow = {}
|
|
540
|
+
this.visibleP = false
|
|
541
|
+
},
|
|
542
|
+
async downFile(row = {}) {
|
|
543
|
+
if (!row.beid) {
|
|
544
|
+
this.$message.error($lc('缺少文件标识'))
|
|
545
|
+
return
|
|
546
|
+
}
|
|
547
|
+
const url = this.apiPrefix
|
|
548
|
+
? `${this.apiPrefix}/neams/eamsbaserecord/download/${row.beid}`
|
|
549
|
+
: `/neams/eamsbaserecord/download/${row.beid}`
|
|
550
|
+
const blob = await axios.get(url, null, {
|
|
551
|
+
responseType: 'blob',
|
|
552
|
+
loading: false
|
|
553
|
+
})
|
|
554
|
+
this.$downloadBlob(blob, blob.name || row.fileName)
|
|
555
|
+
},
|
|
556
|
+
getItemKey(item = {}, index) {
|
|
557
|
+
return `${item.subProcInitId || item.endTime || item.resultName || 'approval'}-${item.result}-${index}`
|
|
558
|
+
},
|
|
559
|
+
isWaiting(item = {}) {
|
|
560
|
+
return item.result === this.status.waiting
|
|
561
|
+
},
|
|
562
|
+
isEnd(item = {}) {
|
|
563
|
+
return item.result === this.status.end
|
|
564
|
+
},
|
|
565
|
+
showSuggestionContent(item = {}) {
|
|
566
|
+
return item.resultName !== this.$lc('撤回') || this.showCtdMsg
|
|
567
|
+
},
|
|
568
|
+
showNodeMeta(item = {}) {
|
|
569
|
+
return !this.isWaiting(item) && !this.isEnd(item) && Boolean(item.endTime || item.approvalCost)
|
|
570
|
+
},
|
|
571
|
+
resultTitle(item = {}) {
|
|
572
|
+
if (item.resultName) return this.$lc(item.resultName)
|
|
573
|
+
if (this.isWaiting(item)) return this.$lc('待审批')
|
|
574
|
+
if (this.isEnd(item)) return this.$lc('结束')
|
|
575
|
+
if (item.result === this.status.submit) return this.$lc('提交')
|
|
576
|
+
if (item.result === this.status.approval) return this.$lc('批准')
|
|
577
|
+
if (item.result === this.status.reject) return this.$lc('驳回')
|
|
578
|
+
if (item.result === this.status.invalid) return this.$lc('作废')
|
|
579
|
+
if (item.result === this.status.revocation) return this.$lc('撤回')
|
|
580
|
+
return ''
|
|
581
|
+
},
|
|
582
|
+
statusClass(item = {}) {
|
|
583
|
+
if (this.isWaiting(item)) return 'is-waiting'
|
|
584
|
+
if (item.result === this.status.approval) return 'is-approval'
|
|
585
|
+
if (item.result === this.status.reject || item.result === this.status.invalid) return 'is-reject'
|
|
586
|
+
if (item.result === this.status.revocation) return 'is-revocation'
|
|
587
|
+
return 'is-primary'
|
|
588
|
+
},
|
|
589
|
+
getPendingUsers(item = {}) {
|
|
590
|
+
const details = item._details || {}
|
|
591
|
+
// 兼容外部直传的审批人列表,以及接口映射后保留在 _details 中的原始列表。
|
|
592
|
+
const users = item.assigneeList || item.approvers || details.assigneeList || details.approvers
|
|
593
|
+
if (Array.isArray(users)) return users.filter(Boolean)
|
|
594
|
+
return String(item.assignee || '')
|
|
595
|
+
.split(/[、,,;;]+/)
|
|
596
|
+
.map((name) => name.trim())
|
|
597
|
+
.filter(Boolean)
|
|
598
|
+
},
|
|
599
|
+
getUserName(user) {
|
|
600
|
+
if (!user) return ''
|
|
601
|
+
if (typeof user === 'string') return user
|
|
602
|
+
return user.name || user.assignee || user.userName || user.memberName || user.label || ''
|
|
603
|
+
},
|
|
604
|
+
getUserAvatar(user) {
|
|
605
|
+
if (!user || typeof user === 'string') return ''
|
|
606
|
+
const source = user._details || user
|
|
607
|
+
return source.avatar || source.avatarUrl || source.photoUrl || source.headImg || ''
|
|
608
|
+
},
|
|
609
|
+
getOrganizationText(item = {}) {
|
|
610
|
+
return [item.memberName, item.deptName, item.job, item.roleName].filter(Boolean).join('|')
|
|
611
|
+
},
|
|
612
|
+
getTerminalLabel(item = {}) {
|
|
613
|
+
if (item.outTitle) return item.outTitle
|
|
614
|
+
if (item.appOrPc === '1' || item.appOrPc === 1) return 'PC'
|
|
615
|
+
if (item.appOrPc === '2' || item.appOrPc === 2) return this.$lc('外部系统')
|
|
616
|
+
if (item.appOrPc === null || item.appOrPc === '' || item.appOrPc === undefined) return ''
|
|
617
|
+
return 'APP'
|
|
618
|
+
},
|
|
619
|
+
getFileIcon(fileName = '') {
|
|
620
|
+
const suffix = String(fileName || '')
|
|
621
|
+
.split('.')
|
|
622
|
+
.pop()
|
|
623
|
+
.toLowerCase()
|
|
624
|
+
if (suffix === 'pdf' || suffix === 'ppt' || suffix === 'pptx') return pdfIcon
|
|
625
|
+
if (suffix === 'doc' || suffix === 'docx') return wordIcon
|
|
626
|
+
if (suffix === 'xls' || suffix === 'xlsx') return excelIcon
|
|
627
|
+
if (['png', 'jpg', 'jpeg', 'gif', 'svg'].includes(suffix)) return pngIcon
|
|
628
|
+
if (suffix === 'txt') return txtIcon
|
|
629
|
+
if (['zip', 'rar', '7z'].includes(suffix)) return zipIcon
|
|
630
|
+
return defaultFileIcon
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
</script>
|
package/src/i18n.json
CHANGED
|
@@ -12654,5 +12654,12 @@
|
|
|
12654
12654
|
"vi": "Vui lòng cấu hình danh mục tệp đính kèm",
|
|
12655
12655
|
"ja": "添付ファイルのカテゴリを設定してください",
|
|
12656
12656
|
"zh-hk": "請配置附件分類"
|
|
12657
|
+
},
|
|
12658
|
+
"上传结果为空,请稍后重试": {
|
|
12659
|
+
"en": "Upload result is empty, please try again later",
|
|
12660
|
+
"th": "ผลการอัปโหลดว่างเปล่า โปรดลองอีกครั้งในภายหลัง",
|
|
12661
|
+
"vi": "Kết quả tải lên trống, vui lòng thử lại sau",
|
|
12662
|
+
"ja": "アップロード結果が空です。後でもう一度お試しください",
|
|
12663
|
+
"zh-hk": "上傳結果為空,請稍後重試"
|
|
12657
12664
|
}
|
|
12658
12665
|
}
|
package/src/index.js
CHANGED
|
@@ -127,6 +127,7 @@ import Tree from './components/Tree/index.vue'
|
|
|
127
127
|
import Upload from './components/Upload/index.vue'
|
|
128
128
|
import UploadMsg from './components/Upload/uploadMsg.vue'
|
|
129
129
|
import AnchorV3 from './components/v3/Anchor/index.vue'
|
|
130
|
+
import ApprovalCardV3 from './components/v3/ApprovalCard/index.vue'
|
|
130
131
|
import Collapse from './components/v3/Collapse/index.vue'
|
|
131
132
|
import CollapseLink from './components/v3/CollapseLink/index.vue'
|
|
132
133
|
import Footer from './components/v3/Footer/index.vue'
|
|
@@ -293,6 +294,7 @@ const components = [
|
|
|
293
294
|
operatingStatus,
|
|
294
295
|
/* v3组件*/
|
|
295
296
|
tableProV3,
|
|
297
|
+
ApprovalCardV3,
|
|
296
298
|
SecondaryTabV3,
|
|
297
299
|
Header,
|
|
298
300
|
Footer,
|
|
@@ -447,6 +449,7 @@ export {
|
|
|
447
449
|
WornPagination,
|
|
448
450
|
/* v3组件*/
|
|
449
451
|
tableProV3,
|
|
452
|
+
ApprovalCardV3,
|
|
450
453
|
SecondaryTabV3,
|
|
451
454
|
Header,
|
|
452
455
|
Footer,
|