n20-common-lib 2.16.4 → 2.16.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n20-common-lib",
3
- "version": "2.16.4",
3
+ "version": "2.16.6",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -6,13 +6,12 @@
6
6
  border-right: $--tab-border-line;
7
7
 
8
8
  .cell {
9
-
10
9
  .el-icon-download,
11
10
  .el-icon-view {
12
11
  color: $--color-text-primary;
13
12
 
14
13
  &:hover {
15
- color: $--color-primary
14
+ color: $--color-primary;
16
15
  }
17
16
  }
18
17
  }
@@ -36,4 +35,4 @@
36
35
  .el-message-box__btns {
37
36
  margin-top: 0;
38
37
  }
39
- }
38
+ }
@@ -141,7 +141,9 @@ export default {
141
141
  if (btnt.includes('back')) {
142
142
  btns.push({ emit: 'back', label: $lc('返回'), plain: true })
143
143
  }
144
-
144
+ if (btnt.includes('zsbf')) {
145
+ btns.push({ emit: 'zsbf', label: $lc('证书颁发'), plain: true })
146
+ }
145
147
  return btns
146
148
  }
147
149
  }
@@ -0,0 +1,982 @@
1
+ <template>
2
+ <div class="file-upload-table-v3">
3
+ <!-- <div class="flex-box flex-v flex-lr m-b-s">
4
+ <div>
5
+ <slot name="title">附件上传</slot>
6
+ <span v-if="fileText" v-html="fileText"></span>
7
+ </div>
8
+ <div>
9
+ <slot v-if="!readonly" name="add-btn">
10
+ <el-button type="primary" size="mini" @click="addRow">{{ '新增' | $lc }}</el-button>
11
+ </slot>
12
+ <slot v-if="!readonly && showBatchUpload" name="batch-btn">
13
+ <el-button size="mini" plain @click="handleBathUpload">{{ '批量上传' | $lc }}</el-button>
14
+ </slot>
15
+ <slot v-if="!readonly && showBatchPrint" name="batch-btn">
16
+ <el-button size="mini" plain @click="batchPrint">{{ '批量打印' | $lc }}</el-button>
17
+ </slot>
18
+ <slot name="down-btn">
19
+ <el-button size="mini" plain @click="downRows">{{ '下载' | $lc }}</el-button>
20
+ </slot>
21
+ <slot v-if="!readonly" name="delete-btn">
22
+ <el-button type="danger" plain size="mini" @click="deleteRows">{{ '删除' | $lc }}</el-button>
23
+ </slot>
24
+ </div>
25
+ </div>
26
+ <el-table
27
+ :data="tableData"
28
+ :row-key="keys.rowKey"
29
+ :height="height"
30
+ border
31
+ @selection-change="(selection) => (selectionList = selection)"
32
+ >
33
+ <slot name="selection-column">
34
+ <el-table-column type="selection" width="50" align="center" />
35
+ </slot>
36
+ <template v-if="dataPorp.slotHeader">
37
+ <el-table-column
38
+ v-for="item in dataPorp.slotHeader"
39
+ :key="item.prop"
40
+ :label="item.label"
41
+ :prop="item.prop"
42
+ :align="item.align || 'center'"
43
+ :width="item.width || 'auto'"
44
+ :show-overflow-tooltip="item.showOverflowTooltip || item['show-overflow-tooltip']"
45
+ />
46
+ </template>
47
+ <template v-else>
48
+ <el-table-column :label="'附件类型' | $lc" :prop="keys.type">
49
+ <slot slot="header" slot-scope="scope" name="type-header" :column="scope.column">{{ '附件类型' | $lc }}</slot>
50
+ <slot slot-scope="{ row }" name="type" :row="row">
51
+ <span v-if="readonly">{{ row[keys.type] | typeFiter(typeOptions) }}</span>
52
+ <div v-else class="flex-box flex-v">
53
+ <span v-if="requiredTypes.includes(row[keys.type])" style="color: red" class="m-r-s">*</span>
54
+ <el-select
55
+ v-model="row[keys.type]"
56
+ :disabled="row._typeDisabled"
57
+ :placeholder="'请选择' | $lc"
58
+ style="width: calc(100% - 16px)"
59
+ @change="$emit('typeChange', row[keys.type])"
60
+ >
61
+ <el-option
62
+ v-for="item in typeOptions"
63
+ :key="item.type"
64
+ :disabled="item.disabled"
65
+ :value="item.type"
66
+ :label="item.label"
67
+ />
68
+ </el-select>
69
+ </div>
70
+ </slot>
71
+ </el-table-column>
72
+ <el-table-column :label="'附件名称' | $lc" :prop="keys.name">
73
+ <slot slot="header" slot-scope="scope" name="name-header" :column="scope.column">{{ '附件名称' | $lc }}</slot>
74
+ <slot slot-scope="{ row }" name="name" :row="row">
75
+ <span v-if="readonly">{{ row[keys.name] ? row[keys.name].replace(/\.[A-z0-9]+$/, '') : '' }}</span>
76
+ <el-input
77
+ v-else
78
+ v-title
79
+ :value="row[keys.name] ? row[keys.name].replace(/\.[A-z0-9]+$/, '') : ''"
80
+ disabled
81
+ :placeholder="'请输入' | $lc"
82
+ />
83
+ </slot>
84
+ </el-table-column>
85
+ <el-table-column v-if="readonly" :label="'附件上传' | $lc" :prop="keys.name">
86
+ <slot slot="header" slot-scope="scope" name="upload-header" :column="scope.column"
87
+ >{{ '附件上传' | $lc }}
88
+ </slot>
89
+ <slot slot-scope="{ row }" name="upload" :row="row">
90
+ {{ $options.filters.fileName(row, keys.url) || row[keys.name] }}
91
+ </slot>
92
+ </el-table-column>
93
+ <el-table-column v-if="!readonly" :label="'附件上传' | $lc">
94
+ <slot slot="header" slot-scope="scope" name="upload-header" :column="scope.column"
95
+ >{{ '附件上传' | $lc }}
96
+ </slot>
97
+ <slot slot-scope="{ row, $index }" name="upload" :row="row" :[indexK]="$index">
98
+ <Upload
99
+ :ref="'upload' + $index"
100
+ class="n20-upload-table-up"
101
+ :file-name="row | fileName(keys.url)"
102
+ :data="row['_fileData'] || fileData"
103
+ :msg-type="null"
104
+ :show-clear="false"
105
+ :action="apiPrefix ? apiPrefix + action : action"
106
+ :multiple="multiple"
107
+ :headers="headers"
108
+ :disabled="!row[keys.type] || row._typeDisabled"
109
+ :accept="row[keys.type] | acceptFilter(typeOptions, fileAccept)"
110
+ :size="row[keys.type] | sizeFilter(typeOptions, fileSize)"
111
+ :http-request="uploadHttpRequest ? (options) => uploadHttpRequest(options, row) : undefined"
112
+ :before-upload="(file) => beforeUploadFn(file, row)"
113
+ :on-progress="(event) => onProgressFn(event, row)"
114
+ :on-success="
115
+ (response, file, fileList) =>
116
+ multiple
117
+ ? MultipleSUccessFn(response, file, fileList, row)
118
+ : onSuccessFn(response, file, fileList, row)
119
+ "
120
+ :on-error="(err, file, fileList) => errorFn(err, file, fileList, row, $index)"
121
+ />
122
+ </slot>
123
+ </el-table-column>
124
+ <slot name="slotCol"></slot>
125
+ <el-table-column v-if="!hideTime" :label="'上传时间' | $lc" :prop="keys.time" sortable width="170" align="left">
126
+ <slot slot="header" slot-scope="scope" name="time-header" :column="scope.column">{{ '上传时间' | $lc }}</slot>
127
+ <slot slot-scope="{ row }" name="time" :row="row">{{ row[keys.time] }}</slot>
128
+ </el-table-column>
129
+ <el-table-column v-if="!hideUser" :label="'上传人' | $lc" :prop="keys.user" width="100">
130
+ <slot slot="header" slot-scope="scope" name="user-header" :column="scope.column">{{ '上传人' | $lc }}</slot>
131
+ <slot slot-scope="{ row }" name="user" :row="row">{{ row[keys.user] }}</slot>
132
+ </el-table-column>
133
+ </template>
134
+ <el-table-column v-if="!readonly" :label="'上传进度' | $lc" width="220">
135
+ <template slot="header" slot-scope="scope">
136
+ <slot name="percent-header" :column="scope.column">{{ '上传进度' | $lc }}</slot>
137
+ </template>
138
+ <template slot-scope="{ row, $index }">
139
+ <slot name="percent" :row="row" :[indexK]="$index">
140
+ <div v-if="row['_percent'] >= 0 && !readonly" class="flex-box flex-v">
141
+ <el-progress
142
+ class="n20-upload-table-progress"
143
+ :percentage="row['_percent']"
144
+ :status="row['_status']"
145
+ text-color=""
146
+ style="width: 140px"
147
+ />
148
+ <el-button
149
+ v-if="row['_status'] === 'exception'"
150
+ type="text"
151
+ size="mini"
152
+ style="width: 60px"
153
+ @click="anewSubmitFn(row, $index)"
154
+ >{{ '重新上传' | $lc }}
155
+ </el-button>
156
+ <el-button
157
+ v-else-if="row['_percent'] >= 0 && row['_percent'] < 100"
158
+ type="text"
159
+ size="mini"
160
+ style="width: 60px"
161
+ @click="abortFn(row, $index)"
162
+ >{{ '取消' | $lc }}
163
+ </el-button>
164
+ </div>
165
+ </slot>
166
+ </template>
167
+ </el-table-column>
168
+ <el-table-column :label="'操作' | $lc" align="center" width="90" fixed="right">
169
+ <slot slot="header" slot-scope="scope" name="handle-header" :column="scope.column">{{ '操作' | $lc }}</slot>
170
+ <slot slot-scope="{ row }" name="handle" :row="row">
171
+ <el-button type="text" icon="el-icon-view" :disabled="!row[keys.url]" @click="seeFile(row)" />
172
+ <el-button
173
+ v-if="getOfficeStatus && openAI"
174
+ v-title="'ai识别'"
175
+ type="text"
176
+ icon="n20-icon-query"
177
+ :disabled="!row[keys.url]"
178
+ @click="AiFn(row)"
179
+ />
180
+ <el-button
181
+ v-if="readonly"
182
+ type="text"
183
+ icon="el-icon-download"
184
+ :disabled="!row[keys.url]"
185
+ @click="downFile(row)"
186
+ />
187
+ </slot>
188
+ </el-table-column>
189
+ </el-table> -->
190
+ <div class="flex-box flex-v flex-lr">
191
+ <div class="title">
192
+ 附件上传
193
+ <span>(带 * 为必要上传的附件)</span>
194
+ </div>
195
+ </div>
196
+ <div class="file-list">
197
+ <div v-for="(item, index) in typeOptions" :key="index" class="file-item">
198
+ <div class="type-title">
199
+ <div class="flex-box flex-v">
200
+ <span class="m-r-s">*</span>
201
+ <span>{{ index + 1 }}、</span>
202
+ <span>{{ item.label }}</span>
203
+ <img src="./ysc.svg" width="14px" class="m-l-s" />
204
+ </div>
205
+ <Upload
206
+ :ref="'upload' + index"
207
+ class="n20-upload-table-up"
208
+ :msg-type="null"
209
+ :show-clear="false"
210
+ :action="apiPrefix ? apiPrefix + action : action"
211
+ :multiple="multiple"
212
+ :headers="headers"
213
+ :data="fileData"
214
+ :http-request="uploadHttpRequest ? (options) => uploadHttpRequest(options, row) : undefined"
215
+ :on-success="
216
+ (response, file, fileList) =>
217
+ multiple ? MultipleSUccessFn(response, file, fileList, row) : onSuccessFn(response, file, fileList, row)
218
+ "
219
+ :on-error="(err, file, fileList) => errorFn(err, file, fileList, row, $index)"
220
+ >
221
+ <el-button slot="trigger" type="text" size="small">去上传</el-button>
222
+ </Upload>
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ <Dialog
228
+ v-drag
229
+ class="p-a-0"
230
+ :title="'附件预览' | $lc"
231
+ :visible.sync="visibleP"
232
+ top="2vh"
233
+ width="96%"
234
+ :close-on-click-modal="false"
235
+ @close="closeSee"
236
+ >
237
+ <span class="file-upload-table_preview-pn">
238
+ <el-button round onlyicon plain size="mini" icon="el-icon-back" @click="preSee" />
239
+ <el-button round onlyicon plain size="mini" icon="el-icon-right" @click="nextSee" />
240
+ </span>
241
+
242
+ <div v-if="visiblePv" class="p-a" style="height: 82vh">
243
+ <ViewerImg v-if="imgType.test(previewName)" :options="viewerOptions" style="height: 100%">
244
+ <img :src="previewUrl" :alt="previewName" style="display: none" />
245
+ </ViewerImg>
246
+ <component
247
+ :is="previewSameOrg ? 'object' : 'div'"
248
+ v-else
249
+ :key="previewUrl"
250
+ :data="previewUrl"
251
+ style="width: 100%; height: 100%"
252
+ >
253
+ <div class="flex-column flex-c flex-v" style="height: 100%">
254
+ <i class="el-icon-s-release" style="font-size: 60px; color: #999"></i>
255
+ <span style="margin-top: 16px">
256
+ {{ '不支持在线预览,请' | $lc
257
+ }}<el-link type="primary" class="color-primary" @click="downFile(seeRow)">{{ '下载' | $lc }}</el-link
258
+ >{{ '到本地查看' | $lc }}
259
+ </span>
260
+ </div>
261
+ </component>
262
+ </div>
263
+ </Dialog>
264
+ <Dialog
265
+ v-drag
266
+ :title="'附件批量上传' | $lc"
267
+ :visible.sync="visibleBatch"
268
+ top="5vh"
269
+ width="692px"
270
+ :close-on-click-modal="false"
271
+ :destroy-on-open="true"
272
+ >
273
+ <el-select v-model="bathType" class="m-b-s" clearable @change="handleBathChange">
274
+ <el-option
275
+ v-for="item in typeOptions"
276
+ :key="item.type"
277
+ :disabled="item.disabled"
278
+ :value="item.type"
279
+ :label="item.label"
280
+ />
281
+ </el-select>
282
+ <Upload
283
+ v-if="bathType"
284
+ ref="upload-batch"
285
+ class="n20-upload-drag"
286
+ :msg-type="null"
287
+ :show-clear="false"
288
+ :drag="true"
289
+ :auto-upload="false"
290
+ :multiple="true"
291
+ :show-file-list="true"
292
+ :action="apiPrefix ? apiPrefix + action : action"
293
+ :data="fileData"
294
+ :headers="headers"
295
+ :accept="fileAccept"
296
+ :size="fileSize"
297
+ :http-request="uploadHttpRequestBath"
298
+ :before-upload="(file) => batchBeforeUploadFn(file)"
299
+ :on-remove="batchRemove"
300
+ :on-success="batchSuccess"
301
+ :on-error="batchError"
302
+ >
303
+ <template slot="trigger">
304
+ <i class="drag-icon n20-icon-shangchuan"></i>
305
+ <span class="drag-text">{{ '点击或将文件拖拽到这里上传' | $lc }}</span>
306
+ <span class="drag-tip">{{ fileAcceptTip }}</span>
307
+ </template>
308
+ </Upload>
309
+ <div class="dialog-footer">
310
+ <el-button type="primary" @click="batchUploadFn">{{ '确认' | $lc }}</el-button>
311
+ <el-button plain @click="visibleBatch = false">{{ '取消' | $lc }}</el-button>
312
+ </div>
313
+ </Dialog>
314
+ </div>
315
+ </template>
316
+
317
+ <script>
318
+ import getJsonc from '../../assets/getJsonc.js'
319
+ import _axios from 'axios'
320
+ import dayjs from 'dayjs'
321
+ import XEUtils from 'xe-utils'
322
+
323
+ import 'viewerjs/dist/viewer.css'
324
+ import auth from '../../utils/auth.js'
325
+ import axios from '../../utils/axios.js'
326
+ import { $lc } from '../../utils/i18n/index'
327
+ import importG from '../../utils/importGlobal.js'
328
+ import Dialog from '../Dialog/index.vue'
329
+ import Upload from '../Upload/index.vue'
330
+
331
+ const ViewerImg = async function () {
332
+ let { component } = await importG('v-viewer', () => import(/*webpackChunkName: "v-viewer"*/ 'v-viewer'))
333
+ return component
334
+ }
335
+ const keysDefault = {
336
+ rowKey: 'id',
337
+ type: 'type',
338
+ name: 'name',
339
+ url: 'url',
340
+ time: 'time',
341
+ user: 'user'
342
+ }
343
+ const typeOptionsDefault = [
344
+ { type: '001', label: $lc('信贷合同') },
345
+ { type: '002', label: $lc('贴现合同') },
346
+ { type: '003', label: $lc('其他合同') }
347
+ ]
348
+
349
+ export default {
350
+ name: 'FileUploadTableV3',
351
+ components: {
352
+ Upload,
353
+ Dialog,
354
+ ViewerImg
355
+ },
356
+ filters: {
357
+ typeFiter(type, typeOptions) {
358
+ return typeOptions.find((c) => c.type === type)?.label || type
359
+ },
360
+ acceptFilter(type, typeOptions, fileAccept) {
361
+ return typeOptions.find((c) => c.type === type)?.accept || fileAccept
362
+ },
363
+ sizeFilter(type, typeOptions, fileSize) {
364
+ return typeOptions.find((c) => c.type === type)?.size || fileSize
365
+ },
366
+ fileName(row, urlK) {
367
+ if (row['_name']) {
368
+ return row['_name']
369
+ } else if (row[urlK]) {
370
+ let urlArr = row[urlK].split('/')
371
+ let _n = urlArr[urlArr.length - 1]
372
+ return _n ? decodeURI(_n) : undefined
373
+ }
374
+ return undefined
375
+ }
376
+ },
377
+ props: {
378
+ AIOptions: {
379
+ type: Object,
380
+ default: () => ({})
381
+ },
382
+ openAI: {
383
+ type: Boolean,
384
+ default: false
385
+ },
386
+ readonly: {
387
+ type: Boolean,
388
+ default: false
389
+ },
390
+ action: {
391
+ type: String,
392
+ default: '/bems/1.0/attach'
393
+ },
394
+ batchPrintMethod: {
395
+ type: Function,
396
+ default: undefined
397
+ },
398
+ headers: {
399
+ type: Object,
400
+ default: undefined
401
+ },
402
+ apiPrefix: {
403
+ type: String,
404
+ default: undefined
405
+ },
406
+ seePrefix: {
407
+ type: String,
408
+ default: undefined
409
+ },
410
+ seeTypes: {
411
+ type: RegExp,
412
+ default: () => /\.(jpg|png|gif|svg|pdf)$/i
413
+ },
414
+ height: {
415
+ type: [String, Number],
416
+ default: '300px'
417
+ },
418
+ tableData: {
419
+ type: Array,
420
+ default: () => []
421
+ },
422
+ dataPorp: {
423
+ type: Object,
424
+ default: () => ({})
425
+ },
426
+ showBatchUpload: {
427
+ type: Boolean,
428
+ default: false
429
+ },
430
+ showBatchPrint: {
431
+ type: Boolean,
432
+ default: false
433
+ },
434
+ uploadHttpRequest: {
435
+ type: Function,
436
+ default: undefined
437
+ },
438
+ getFileMethod: {
439
+ type: Function,
440
+ default: undefined
441
+ },
442
+ hideUser: {
443
+ type: Boolean,
444
+ default: false
445
+ },
446
+ hideTime: {
447
+ type: Boolean,
448
+ default: false
449
+ }
450
+ },
451
+ data() {
452
+ this.viewerOptions = {
453
+ debug: true,
454
+ inline: true,
455
+ scalable: false, // 不显示水平(垂直)翻转
456
+ navbar: false,
457
+ button: false,
458
+ title: true,
459
+ toolbar: {
460
+ zoomIn: true,
461
+ zoomOut: true,
462
+ oneToOne: true,
463
+ reset: true,
464
+ rotateLeft: true,
465
+ rotateRight: true,
466
+ flipHorizontal: true,
467
+ flipVertical: true,
468
+ prev: false,
469
+ play: false,
470
+ next: false
471
+ }
472
+ }
473
+
474
+ return {
475
+ // 是否仅平铺必选附件
476
+ fileRequired: true,
477
+ // 必传附件
478
+ requiredTypes: [],
479
+ fileText: '',
480
+ bathType: '',
481
+ indexK: '$index',
482
+ imgType: /\.(jpg|png|gif|svg)$/i,
483
+ selectionList: [],
484
+ currFileList: [],
485
+ visibleP: false,
486
+ visiblePv: false,
487
+ visibleBatch: false,
488
+ previewUrl: undefined,
489
+ previewName: undefined,
490
+ previewSameOrg: false,
491
+ seeRow: {},
492
+ officeStatus: false
493
+ }
494
+ },
495
+ computed: {
496
+ fileAccept() {
497
+ return this.dataPorp.fileAccept || undefined
498
+ },
499
+ fileSize() {
500
+ return this.dataPorp.fileSize || undefined
501
+ },
502
+ fileAcceptTip() {
503
+ return this.dataPorp.fileAcceptTip || $lc('支持扩展名:.rar .zip .doc .docx .pdf .jpg...')
504
+ },
505
+ fileData() {
506
+ return this.dataPorp.fileData || undefined
507
+ },
508
+ typeOptions() {
509
+ return this.dataPorp.typeOptions || typeOptionsDefault
510
+ },
511
+ keys() {
512
+ return this.dataPorp.keys || keysDefault
513
+ },
514
+ multiple() {
515
+ return this.dataPorp.multiple ?? true
516
+ }
517
+ },
518
+ watch: {
519
+ dataPorp: {
520
+ handler() {
521
+ this.requiredTypes = this.dataPorp.typeOptions
522
+ .filter((item) => {
523
+ return item.required === 1
524
+ })
525
+ .map((item) => {
526
+ return item.attno
527
+ })
528
+ if (this.dataPorp.typeOptions.length === 0) {
529
+ return false
530
+ }
531
+ this.setTableData()
532
+ },
533
+ immediate: true,
534
+ deep: true
535
+ }
536
+ },
537
+ mounted() {
538
+ this.getConfiguration()
539
+ },
540
+ methods: {
541
+ // ai识别
542
+ async AiFn(row) {
543
+ if (!this.AIOptions.bussType) {
544
+ this.$message.error('请先配置bussType')
545
+ return false
546
+ }
547
+ const { data, code } = await this.$axios.post(
548
+ this.apiPrefix ? `${this.apiPrefix}neams/eamsbaserecord/aiAttaFile` : `/neams/eamsbaserecord/aiAttaFile`,
549
+ {
550
+ beid: row.beid,
551
+ bussType: this.AIOptions.bussType,
552
+ extendPrompt: ''
553
+ }
554
+ )
555
+ if (code === 200) {
556
+ this.$emit('aiFn', data)
557
+ }
558
+ },
559
+ // 平铺附件
560
+ setTableData() {
561
+ if (this.tableData.length === 0 && !this.readonly) {
562
+ this.dataPorp.typeOptions
563
+ .filter((item) => {
564
+ if (this.fileRequired) {
565
+ return item.required === 1
566
+ } else {
567
+ return item.required === 1 || item.required === 0
568
+ }
569
+ })
570
+ .forEach((item) => {
571
+ let obj
572
+ obj = {
573
+ id: 'n' + Math.random(),
574
+ name: ''
575
+ }
576
+ obj[this.keys.type] = item.attno
577
+ obj[this.keys.time] = ''
578
+ obj[this.keys.user] = JSON.parse(sessionStorage.getItem('userInfo')).uname
579
+
580
+ console.log(obj)
581
+ this.tableData.push(obj)
582
+ })
583
+ }
584
+ },
585
+ getConfiguration() {
586
+ getJsonc('portal/server-config.jsonc', null, true)
587
+ .then(({ loginConf, fileRequired }) => {
588
+ this.fileText = loginConf?.sLogan?.fileText
589
+ this.fileRequired = fileRequired ?? true
590
+ })
591
+ .catch(() => {
592
+ this.fileText = ''
593
+ this.fileRequired = true
594
+ })
595
+ },
596
+ async getOfficeStatus() {
597
+ const { data } = await this.$axios.get(
598
+ this.apiPrefix
599
+ ? `${this.apiPrefix}/neams/eamsBaseFile/getOfficeIsEnable`
600
+ : `/neams/eamsBaseFile/getOfficeIsEnable`
601
+ )
602
+ this.officeStatus = data
603
+ },
604
+ handleBathUpload() {
605
+ this.visibleBatch = true
606
+ },
607
+ async batchPrint() {
608
+ if (!this.selectionList.length) {
609
+ return this.$message({
610
+ message: $lc(`请先勾选要打印的数据!`),
611
+ type: 'warning',
612
+ showClose: true
613
+ })
614
+ }
615
+ if (this.batchPrintMethod) {
616
+ return this.batchPrintMethod(this.selectionList)
617
+ }
618
+ const { code, data } = await axios.post(
619
+ this.apiPrefix
620
+ ? this.apiPrefix + `/neams/eamsbaserecord/mergeDownladPdf`
621
+ : `/neams/eamsbaserecord/mergeDownladPdf`,
622
+ this.selectionList.map((res) => res.beid) || [],
623
+ {
624
+ responseType: 'blob'
625
+ }
626
+ )
627
+ if (code === 200) {
628
+ let aDom = document.createElement('a')
629
+ aDom.href = data
630
+ aDom.download = '批量附件.pdf'
631
+ aDom.click()
632
+
633
+ this.$nextTick(() => {
634
+ aDom = undefined
635
+ data && URL.revokeObjectURL(data)
636
+ })
637
+ }
638
+ },
639
+ batchBeforeUploadFn(file) {
640
+ let bu = this.$listeners['before-upload'] || this.$listeners['beforeUpload']
641
+ if (bu) return bu(file)
642
+ },
643
+ handleBathChange() {
644
+ let dto = JSON.parse(this.dataPorp.fileData.data)
645
+ dto[this.keys.type] = this.bathType
646
+ this.fileData.data = JSON.stringify(dto)
647
+ },
648
+ batchUploadFn() {
649
+ let $uploadwrap = this.$refs['upload-batch']
650
+ let fileList = $uploadwrap.fileList
651
+ if (fileList.length !== 0 && fileList.every((f) => f.status === 'success')) {
652
+ this.visibleBatch = false
653
+ }
654
+ $uploadwrap.submit()
655
+ },
656
+ batchSuccess(response, file, fileList) {
657
+ let row = { ...this.dataPorp.keys }
658
+ this.tableData.splice(0, 0, row)
659
+ this.$nextTick(() => {
660
+ this.onSuccessFn(response, file, fileList, row)
661
+ })
662
+
663
+ if (fileList.every((f) => f.status === 'success')) {
664
+ this.visibleBatch = false
665
+ }
666
+ },
667
+ batchError(err, file, fileList) {
668
+ if (!fileList.some((f) => f.uid === file.uid)) {
669
+ let list = [...fileList]
670
+ file.status = 'ready'
671
+ if (err.msg) {
672
+ file.OrgName || (file.OrgName = file.name)
673
+ file.name = file.OrgName + ` *(${err.msg})`
674
+ }
675
+
676
+ list.push(file)
677
+ let $uploadwrap = this.$refs['upload-batch']
678
+ $uploadwrap.fileList = list
679
+ }
680
+ },
681
+ batchRemove(file, fileList) {
682
+ let list = fileList.filter((f) => f.uid !== file.uid)
683
+
684
+ let $uploadwrap = this.$refs['upload-batch']
685
+ $uploadwrap.fileList = list
686
+
687
+ this.$emit('on-remove', file)
688
+ },
689
+ addRow() {
690
+ this.$emit('add-row')
691
+ },
692
+ downRows() {
693
+ if (!this.selectionList.length) {
694
+ return this.$message({
695
+ message: $lc(`请先勾选要下载的数据!`),
696
+ type: 'warning',
697
+ showClose: true
698
+ })
699
+ }
700
+ this.$emit(
701
+ 'down-rows',
702
+ this.selectionList.filter((item) => item[this.keys.url] || item._name)
703
+ )
704
+ },
705
+ deleteRows() {
706
+ if (!this.selectionList.length) {
707
+ return this.$message({
708
+ message: $lc('请先勾选要删除的数据!'),
709
+ type: 'warning',
710
+ showClose: true
711
+ })
712
+ }
713
+ this.$emit('delete-rows', this.selectionList)
714
+ },
715
+
716
+ async getFileInfo(row, type) {
717
+ if (this.getFileMethod) {
718
+ return this.getFileMethod(row, type)
719
+ }
720
+ let _url = row[this.keys.url]
721
+ this.seePrefix && (_url = this.seePrefix + _url)
722
+ if (_url) {
723
+ if (type === 'preview') {
724
+ // 预览
725
+ return {
726
+ url: `/api/onlinePreview?beid=${row[this.keys.rowKey]}`,
727
+ name: row[this.keys.name] + '.html',
728
+ sameOrg: this.seeTypes.test(row[this.keys.name])
729
+ }
730
+ } else {
731
+ // 下载
732
+ let blob = await axios.get(
733
+ this.apiPrefix
734
+ ? this.apiPrefix + `/neams/eamsbaserecord/download/${row[this.keys.rowKey]}`
735
+ : `/neams/eamsbaserecord/download/${row[this.keys.rowKey]}`,
736
+ null,
737
+ {
738
+ responseType: 'blob'
739
+ }
740
+ )
741
+ let name = row[this.keys.name] || blob.name
742
+ return {
743
+ url: URL.createObjectURL(blob),
744
+ name: name,
745
+ sameOrg: this.seeTypes.test(name)
746
+ }
747
+ }
748
+ } else {
749
+ return {}
750
+ }
751
+ },
752
+ async downFile(row) {
753
+ let { url, name } = await this.getFileInfo(row)
754
+ if (url) {
755
+ let aDom = document.createElement('a')
756
+ aDom.href = url
757
+ aDom.download = name
758
+ aDom.click()
759
+
760
+ this.$nextTick(() => {
761
+ aDom = undefined
762
+ url && URL.revokeObjectURL(url)
763
+ })
764
+ }
765
+ },
766
+ async seeFile(row) {
767
+ let { url, name, sameOrg } = await this.getFileInfo(row, 'preview')
768
+ if (url) {
769
+ this.previewSameOrg = sameOrg
770
+ this.previewUrl = url
771
+ this.previewName = name
772
+ this.visibleP = true
773
+
774
+ clearTimeout(this.visiblePvT)
775
+ this.visiblePv = true
776
+ this.seeRow = row
777
+ }
778
+ },
779
+ preSee() {
780
+ let i = this.tableData.findIndex((row) => row === this.seeRow)
781
+ let row = this.tableData[i - 1] || this.tableData[this.tableData.length - 1]
782
+ this.seeFile(row)
783
+ },
784
+ nextSee() {
785
+ let i = this.tableData.findIndex((row) => row === this.seeRow)
786
+ let row = this.tableData[i + 1] || this.tableData[0]
787
+ this.seeFile(row)
788
+ },
789
+ closeSee() {
790
+ this.previewUrl && URL.revokeObjectURL(this.previewUrl)
791
+ this.previewUrl = undefined
792
+
793
+ this.visiblePvT = setTimeout(() => {
794
+ this.visiblePv = false
795
+ }, 300)
796
+ },
797
+ uploadHttpRequestBath(opt) {
798
+ console.log(opt)
799
+ if (this.uploadHttpRequest) {
800
+ return this.uploadHttpRequest(opt)
801
+ } else {
802
+ let FD = new FormData()
803
+ FD.append(opt.filename, opt.file)
804
+
805
+ let data
806
+ if (window._fileData) {
807
+ data = window._fileData
808
+ delete window._fileData
809
+ } else {
810
+ data = opt.data
811
+ }
812
+
813
+ if (data) {
814
+ let dto = JSON.parse(data.data)
815
+ dto[this.keys.type] = this.bathType
816
+ data.data = JSON.stringify(dto)
817
+ for (let k in data) {
818
+ FD.append(k, data[k])
819
+ }
820
+ }
821
+
822
+ let abort
823
+ let Pro = axios.post(opt.action + '?r=' + Math.random(), FD, {
824
+ headers: Object.assign(auth.setHeaders(this.headers), { 'Content-Type': 'multipart/form-data' }),
825
+ loading: false,
826
+ timeout: 900000,
827
+ onUploadProgress: (arg) => {
828
+ if (opt.onProgress) {
829
+ arg.percent = arg.progress * 100
830
+ opt.onProgress(arg)
831
+ }
832
+ },
833
+ cancelToken: new _axios.CancelToken((cancel) => {
834
+ abort = cancel
835
+ })
836
+ })
837
+ Pro.abort = abort
838
+ return Pro
839
+ }
840
+ },
841
+ beforeUploadFn(file, row) {
842
+ this.$set(row, '_percent', 0)
843
+ this.$set(row, '_status', undefined)
844
+
845
+ let bu = this.$listeners['before-upload'] || this.$listeners['beforeUpload']
846
+ if (bu) return bu(file, row)
847
+ },
848
+ onProgressFn({ percent }, row) {
849
+ this.$set(row, '_percent', percent <= 99 ? Math.round(percent) : 99)
850
+ },
851
+ onSuccessFn(response, file, fileList, row) {
852
+ console.log(response, file, fileList)
853
+ console.log(this.tableData)
854
+ this.$emit('on-success', file, row)
855
+ /* this.$set(row, '_typeDisabled', true)
856
+ this.$set(row, '_name', file.name)
857
+
858
+ this.$set(row, [this.keys.rowKey], response.data)
859
+ this.$set(row, [this.keys.type], row[this.keys.type] || this.bathType)
860
+ row[this.keys.time] = dayjs().format('YYYY-MM-DD HH:mm:ss')
861
+ if (response.code >= 900 || response.code === -1) {
862
+ this.$set(row, '_percent', 99)
863
+ this.$set(row, '_status', 'error')
864
+ } else {
865
+ this.$set(row, '_percent', 100)
866
+ this.$set(row, '_status', 'success')
867
+ }
868
+ row[this.keys.url] = response.data
869
+ row[this.keys.name] = file.name
870
+
871
+ this.$emit('on-success', file, row) */
872
+ },
873
+ MultipleSUccessFn(response, file, fileList, row) {
874
+ if (fileList.length > 1) {
875
+ let deepRow = XEUtils.clone(row, true)
876
+ this.$nextTick(() => {
877
+ if (this.tableData.length && !this.tableData[0][this.keys.url]) {
878
+ this.tableData.shift()
879
+ }
880
+ })
881
+ let _percent = 0
882
+ let _status = undefined
883
+ if (response.code >= 900 || response.code === -1) {
884
+ _percent = 99
885
+ _status = 'error'
886
+ } else {
887
+ _percent = 99
888
+ _status = 'success'
889
+ }
890
+ setTimeout(() => {
891
+ this.tableData.splice(0, 0, {
892
+ _name: file.name,
893
+ _percent,
894
+ [this.keys.time]: dayjs().format('YYYY-MM-DD HH:mm:ss'),
895
+ [this.keys.url]: response.data,
896
+ [this.keys.name]: file.name,
897
+ _status,
898
+ _typeDisabled: true,
899
+ [this.keys.user]: deepRow[this.keys.user],
900
+ [this.keys.type]: deepRow[this.keys.type]
901
+ })
902
+ }, 100)
903
+ } else {
904
+ this.onSuccessFn(response, file, fileList, row)
905
+ }
906
+ },
907
+ errorFn(err, file, fileList, row, $index) {
908
+ this.$set(row, '_status', 'exception')
909
+
910
+ let clUpload = this.$refs['upload' + $index]
911
+ /* 重置文件状态,并加入文件队列 */
912
+ file.status = 'ready'
913
+ clUpload.fileList = [file]
914
+
915
+ this.$emit('on-error', file, row)
916
+ },
917
+ abortFn(row, $index) {
918
+ this.$set(row, '_status', 'exception')
919
+
920
+ let clUpload = this.$refs['upload' + $index]
921
+ let elUpload = clUpload.$refs['upload']
922
+
923
+ // let uploadFiles = elUpload.uploadFiles
924
+ // /* 重置文件状态,并加入文件队列 */
925
+ // let file = uploadFiles[uploadFiles.length - 1]
926
+ // file.status = 'ready'
927
+ // clUpload.fileList = [file]
928
+
929
+ elUpload.abort()
930
+ },
931
+ anewSubmitFn(row, $index) {
932
+ this.$set(row, '_status', undefined)
933
+ this.$refs['upload' + $index]?.$refs['upload']?.submit()
934
+ }
935
+ }
936
+ }
937
+ </script>
938
+ <style lang="scss">
939
+ .file-upload-table-v3 {
940
+ .title {
941
+ font-size: 16px;
942
+ font-style: normal;
943
+ font-weight: 500;
944
+ line-height: normal;
945
+ span {
946
+ color: #666666;
947
+ font-family: 'PingFang SC';
948
+ font-size: 14px;
949
+ font-style: normal;
950
+ font-weight: 400;
951
+ line-height: normal;
952
+ }
953
+ }
954
+ .title::before {
955
+ content: '';
956
+ display: inline-block;
957
+ width: 4px;
958
+ height: 16px;
959
+ background: #4471fe;
960
+ margin-right: 4px;
961
+ position: relative;
962
+ top: 2px;
963
+ }
964
+ .file-list {
965
+ margin-top: 16px;
966
+ .file-item {
967
+ margin-bottom: 16px;
968
+ .type-title {
969
+ display: flex;
970
+ width: calc(100% - 18px);
971
+ height: 28px;
972
+ padding: 9px;
973
+ justify-content: space-between;
974
+ align-items: center;
975
+ flex-shrink: 0;
976
+ border-radius: 4px;
977
+ background: #48d2a029;
978
+ }
979
+ }
980
+ }
981
+ }
982
+ </style>
@@ -0,0 +1,6 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="design-iconfont">
2
+ <path d="M8.24182 3.58716L11.2487 8.99438V6.31665H13.3151V12.9797L11.3785 13.4827L7.3219 6.18677L4.3512 11.3323H8.37366V13.3997H2.56018L1.66565 11.8499L6.44397 3.57349L8.24182 3.58716Z" fill="#007AFF"/>
3
+ <path d="M12.2593 1.66284L12.7877 3.21041L14.3353 3.73888L12.7877 4.26736L12.2593 5.81492L11.7308 4.26736L10.1832 3.73888L11.7308 3.21041L12.2593 1.66284Z" fill="#007AFF"/>
4
+ <path d="M2.32765 3.57349L2.68419 4.61759L3.72829 4.97413L2.68419 5.33068L2.32765 6.37478L1.9711 5.33068L0.927002 4.97413L1.9711 4.61759L2.32765 3.57349Z" fill="#007AFF"/>
5
+ <path d="M9.83558 13.011L10.0044 13.5053L10.4987 13.6741L10.0044 13.8429L9.83558 14.3372L9.66679 13.8429L9.17249 13.6741L9.66679 13.5053L9.83558 13.011Z" fill="#007AFF"/>
6
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="design-iconfont">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M1.33334 7.99998C1.33334 4.31808 4.31811 1.33331 8.00001 1.33331C11.6819 1.33331 14.6667 4.31808 14.6667 7.99998C14.6667 11.6819 11.6819 14.6666 8.00001 14.6666C4.31811 14.6666 1.33334 11.6819 1.33334 7.99998ZM7.33335 10.6095L11.6381 6.30473L10.6953 5.36192L7.33335 8.72385L5.47142 6.86192L4.52862 7.80473L7.33335 10.6095Z" fill="#CCC"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="design-iconfont">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M1.33334 8.00004C1.33334 4.31814 4.31811 1.33337 8.00001 1.33337C11.6819 1.33337 14.6667 4.31814 14.6667 8.00004C14.6667 11.6819 11.6819 14.6667 8.00001 14.6667C4.31811 14.6667 1.33334 11.6819 1.33334 8.00004ZM7.33335 10.6095L11.6381 6.30479L10.6953 5.36198L7.33335 8.72391L5.47142 6.86198L4.52862 7.80479L7.33335 10.6095Z" fill="#48D2A0"/>
3
+ </svg>
@@ -463,8 +463,8 @@ function saveTransform(list, labelKey, isFilter) {
463
463
  list.forEach((c) => {
464
464
  if (c.prop && !c.children && !c.isNew && !c.width & !c.isNew) {
465
465
  listN.push({ _colKey: 'prop', _colVal: c.prop })
466
- } else if (c.slotName) {
467
- listN.push({ _colKey: 'slotName', _colVal: c.slotName })
466
+ } else if (c.type && ['selection', 'index', 'expand'].includes(c.type)) {
467
+ listN.push({ _colKey: 'type', _colVal: c.type })
468
468
  } else {
469
469
  let sFn = false
470
470
  for (let k in c) {
package/src/i18n.json CHANGED
@@ -1,4 +1,9 @@
1
1
  {
2
+ "证书颁发": {
3
+ "en": "Certificate Issuance",
4
+ "th": "การออกใบรับรอง",
5
+ "vi": "Cấp chứng chỉ"
6
+ },
2
7
  "风险指令": {
3
8
  "en": "Risk Instruction",
4
9
  "th": "คำสั่งควบคุมความเสี่ยง",
package/src/index.js CHANGED
@@ -30,6 +30,7 @@ import ExpandablePane from './components/Expandable/main.vue'
30
30
  import FileExportAsync from './components/FileExportAsync/index.vue'
31
31
  import FileImport from './components/FileImport/index.vue'
32
32
  import FileUploadTable from './components/FileUploadTable/index.vue'
33
+ import FileUploadTableV3 from './components/FileUploadTable/FileUploadTableV3.vue'
33
34
  import Filters from './components/Filters/index.vue'
34
35
  import FlowStep from './components/FlowStep/index.vue'
35
36
  import FooterBox from './components/FooterBox/index.vue'
@@ -190,6 +191,7 @@ const components = [
190
191
  DragList,
191
192
  Sifting,
192
193
  FileUploadTable,
194
+ FileUploadTableV3,
193
195
  FooterBox,
194
196
  Filters,
195
197
  Table,
@@ -333,6 +335,7 @@ export {
333
335
  FileExportAsync,
334
336
  FileImport,
335
337
  FileUploadTable,
338
+ FileUploadTableV3,
336
339
  Filters,
337
340
  FlowDialog,
338
341
  FlowStep,