n20-common-lib 2.22.55 → 2.22.57

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.22.55",
3
+ "version": "2.22.57",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -68,7 +68,6 @@
68
68
  "v-viewer": "1.6.4",
69
69
  "vue-jsonp": "2.0.0",
70
70
  "vuedraggable": "*",
71
- "worker-loader": "^3.0.8",
72
71
  "webpack-duplicate-relano-plugin": "^0.1.0",
73
72
  "xe-utils": "^3.5.11",
74
73
  "ngraph.events": "1.2.2"
@@ -17,6 +17,7 @@
17
17
 
18
18
  <script>
19
19
  import importGlobal from '../../utils/importGlobal.js'
20
+ import { $lc } from '../../utils/i18n/index.js'
20
21
  export default {
21
22
  name: 'FilterItem',
22
23
  components: {
@@ -8,6 +8,7 @@
8
8
 
9
9
  <script>
10
10
  import axios from '../../utils/axios'
11
+ import { $lc } from '../../utils/i18n/index.js'
11
12
  import flowImg from './approvalImgPro/index.vue'
12
13
  let hasQ004_1 = true
13
14
 
@@ -47,7 +48,7 @@ export default {
47
48
  )
48
49
  .then(({ data }) => {
49
50
  if (data) {
50
- let file = new File([data], $lc("流程图.svg"), {
51
+ let file = new File([data], $lc('流程图.svg'), {
51
52
  type: 'image/svg+xml'
52
53
  })
53
54
  this.blobUrl = URL.createObjectURL(file)
@@ -57,10 +57,10 @@
57
57
  <span v-if="requiredTypes.includes(row[keys.type])" style="color: red" class="m-r-s">*</span>
58
58
  <el-select
59
59
  v-model="row[keys.type]"
60
- :disabled="row._typeDisabled"
60
+ :disabled="row._typeDisabled || row._typeUpdating"
61
61
  :placeholder="'请选择' | $lc"
62
62
  style="width: calc(100% - 16px)"
63
- @change="$emit('typeChange', row[keys.type])"
63
+ @change="handleTypeChange(row)"
64
64
  >
65
65
  <el-option
66
66
  v-for="item in typeOptions"
@@ -268,7 +268,13 @@
268
268
  :close-on-click-modal="false"
269
269
  :destroy-on-open="true"
270
270
  >
271
- <el-select v-model="bathType" class="m-b-s w-100p" clearable @change="handleBathChange">
271
+ <el-select
272
+ v-if="!autoMatchBatchFileType"
273
+ v-model="bathType"
274
+ class="m-b-s w-100p"
275
+ clearable
276
+ @change="handleBathChange"
277
+ >
272
278
  <el-option
273
279
  v-for="item in typeOptions"
274
280
  :key="item.type"
@@ -278,7 +284,7 @@
278
284
  />
279
285
  </el-select>
280
286
  <Upload
281
- v-if="bathType"
287
+ v-if="autoMatchBatchFileType || bathType"
282
288
  ref="upload-batch"
283
289
  class="n20-upload-drag"
284
290
  :msg-type="null"
@@ -305,7 +311,7 @@
305
311
  </template>
306
312
  </Upload>
307
313
  <div class="dialog-footer">
308
- <el-button type="primary" @click="batchUploadFn">{{ '确认' | $lc }}</el-button>
314
+ <el-button type="primary" :loading="batchUploading" @click="batchUploadFn">{{ '确认' | $lc }}</el-button>
309
315
  <el-button plain @click="visibleBatch = false">{{ '取消' | $lc }}</el-button>
310
316
  </div>
311
317
  </Dialog>
@@ -435,6 +441,10 @@ export default {
435
441
  type: Boolean,
436
442
  default: false
437
443
  },
444
+ autoMatchBatchFileType: {
445
+ type: Boolean,
446
+ default: false
447
+ },
438
448
  showBatchPrint: {
439
449
  type: Boolean,
440
450
  default: false
@@ -503,6 +513,7 @@ export default {
503
513
  previewSameOrg: false,
504
514
  seeRow: {},
505
515
  officeStatus: false,
516
+ batchUploading: false,
506
517
  // 批量上传使用的文件数据(避免直接修改计算属性)
507
518
  _batchFileData: null
508
519
  }
@@ -757,11 +768,157 @@ export default {
757
768
  data: JSON.stringify(dto)
758
769
  }
759
770
  },
760
- batchUploadFn() {
771
+ async batchUploadFn() {
772
+ if (this.autoMatchBatchFileType) {
773
+ await this.autoMatchBatchUpload()
774
+ return
775
+ }
761
776
  let $uploadwrap = this.$refs['upload-batch']
762
777
  // 直接提交上传,关闭对话框的逻辑在 batchSuccess 回调中处理
763
778
  $uploadwrap.submit()
764
779
  },
780
+ async autoMatchBatchUpload() {
781
+ let $uploadwrap = this.$refs['upload-batch']
782
+ let uploadFiles = $uploadwrap?.$refs?.upload?.uploadFiles || []
783
+ let files = uploadFiles.filter((item) => item.status === 'ready' && item.raw)
784
+ if (!files.length) {
785
+ this.$message.warning($lc('请先选择上传文件'))
786
+ return
787
+ }
788
+
789
+ try {
790
+ for (let item of files) {
791
+ let result = await $uploadwrap.beforeUploadFn(item.raw)
792
+ if (result === false) {
793
+ return
794
+ }
795
+ }
796
+
797
+ let FD = new FormData()
798
+ files.forEach((item) => {
799
+ FD.append('file', item.raw)
800
+ })
801
+
802
+ let remoteFileUpload = JSON.parse(this.fileData?.data || '{}')
803
+ remoteFileUpload.bussValues = this.typeOptions.map((item) => item.type)
804
+ FD.append('remoteFileUpload', JSON.stringify(remoteFileUpload))
805
+
806
+ this.batchUploading = true
807
+ let { data } = await axios.post(
808
+ this.apiPrefix
809
+ ? `${this.apiPrefix}/neams/eamsbaserecord/batchSaveFile`
810
+ : '/neams/eamsbaserecord/batchSaveFile',
811
+ FD,
812
+ {
813
+ headers: Object.assign(auth.setHeaders(this.headers), { 'Content-Type': 'multipart/form-data' }),
814
+ loading: false,
815
+ noMsg: true,
816
+ timeout: 900000
817
+ }
818
+ )
819
+
820
+ let responseList = Array.isArray(data) ? data : []
821
+ let rows = responseList.map((item) => this.buildAutoMatchBatchRow(item))
822
+ this.tableData.splice(0, 0, ...rows)
823
+ let pendingFiles = [...files]
824
+ rows.forEach((row) => {
825
+ let fileIndex = pendingFiles.findIndex((item) => item.raw.name === row[this.keys.name])
826
+ let sourceFile = pendingFiles.splice(fileIndex > -1 ? fileIndex : 0, 1)[0]
827
+ this.$emit('on-success', sourceFile?.raw, row)
828
+ })
829
+
830
+ $uploadwrap.clearFiles()
831
+ $uploadwrap.fileList = []
832
+ this.visibleBatch = false
833
+ } catch (err) {
834
+ this.$message.error(err?.msg || $lc('上传失败'))
835
+ } finally {
836
+ this.batchUploading = false
837
+ }
838
+ },
839
+ buildAutoMatchBatchRow(item) {
840
+ let userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}')
841
+ let row = {
842
+ ...item,
843
+ _name: item.fileName,
844
+ _percent: 100,
845
+ _status: 'success',
846
+ _typeDisabled: false,
847
+ _typeUpdating: false,
848
+ _shouldUpdateFileType: !item.attno,
849
+ _lastFileType: item.attno,
850
+ _lastFileTypeName: item.attname,
851
+ _lastBussValue: item.bussValue
852
+ }
853
+ row[this.keys.rowKey] = item.beid
854
+ row[this.keys.type] = item.attno
855
+ row[this.keys.name] = item.fileName
856
+ row[this.keys.url] = this.keys.url === this.keys.rowKey ? item.beid : item.filePath || item.beid
857
+ row[this.keys.time] = row[this.keys.time] || dayjs().format('YYYY-MM-DD HH:mm:ss')
858
+ row[this.keys.user] = row[this.keys.user] || userInfo.uname
859
+ return row
860
+ },
861
+ handleTypeChange(row) {
862
+ let type = row[this.keys.type]
863
+ this.$emit('typeChange', type)
864
+ if (!row._shouldUpdateFileType || !type) {
865
+ return
866
+ }
867
+ this.updateFileBuss(row, type)
868
+ },
869
+ async updateFileBuss(row, type) {
870
+ let previousType = row._lastFileType
871
+ let previousTypeName = row._lastFileTypeName
872
+ let previousBussValue = row._lastBussValue
873
+ let typeOption = this.typeOptions.find((item) => item.type === type)
874
+ let typeName = typeOption?.attname || typeOption?.label || ''
875
+ let bussValue = typeOption?.bussValue
876
+
877
+ this.$set(row, 'attno', type)
878
+ this.$set(row, 'attname', typeName)
879
+ if (bussValue !== undefined) {
880
+ this.$set(row, 'bussValue', bussValue)
881
+ }
882
+ this.$set(row, '_typeUpdating', true)
883
+
884
+ try {
885
+ await axios.post(
886
+ this.apiPrefix
887
+ ? `${this.apiPrefix}/neams/eamsbaserecord/updateFlieBuss`
888
+ : '/neams/eamsbaserecord/updateFlieBuss',
889
+ [
890
+ {
891
+ beid: row.beid,
892
+ reid: row.reid,
893
+ appno: row.appno,
894
+ syscode: row.syscode,
895
+ bussValue: row.bussValue,
896
+ bussId: row.bussId,
897
+ bussName: row.bussName,
898
+ attno: row.attno,
899
+ attname: row.attname,
900
+ filePath: row.filePath,
901
+ fileName: row.fileName,
902
+ fmid: row.fmid
903
+ }
904
+ ],
905
+ {
906
+ noMsg: true
907
+ }
908
+ )
909
+ this.$set(row, '_lastFileType', type)
910
+ this.$set(row, '_lastFileTypeName', typeName)
911
+ this.$set(row, '_lastBussValue', row.bussValue)
912
+ } catch (err) {
913
+ this.$set(row, this.keys.type, previousType)
914
+ this.$set(row, 'attno', previousType)
915
+ this.$set(row, 'attname', previousTypeName)
916
+ this.$set(row, 'bussValue', previousBussValue)
917
+ this.$message.error(err?.msg || $lc('附件类型更新失败'))
918
+ } finally {
919
+ this.$set(row, '_typeUpdating', false)
920
+ }
921
+ },
765
922
  batchSuccess(response, file, fileList) {
766
923
  // 创建完整的行对象,初始化状态字段
767
924
  let row = {
@@ -71,7 +71,9 @@
71
71
  prop="LOGIN_BG_TYPE"
72
72
  :rules="{ required: true, message: $lc('背景模式不能为空'), trigger: 'change' }"
73
73
  >
74
- <label class="m-r"><span class="m-r-ss" style="color: var(--color-danger)">*</span>{{ $lc('背景模式') }}</label>
74
+ <label class="m-r"
75
+ ><span class="m-r-ss" style="color: var(--color-danger)">*</span>{{ $lc('背景模式') }}</label
76
+ >
75
77
  <el-radio-group v-model="form.LOGIN_BG_TYPE">
76
78
  <el-radio label="dark">{{ $lc('深色背景') }}</el-radio>
77
79
  <el-radio label="light">{{ $lc('浅色背景') }}</el-radio>
@@ -179,7 +181,7 @@
179
181
  >
180
182
  <span slot="label"
181
183
  ><span>{{ '登录方式设置' | $lc }}</span
182
- ><span class="color-danger m-l-s f-s-s">({{ $lc('至少选择一种登录方式') | $lc }})</span></span
184
+ ><span class="color-danger m-l-s f-s-s">({{ $lc('至少选择一种登录方式') }})</span></span
183
185
  >
184
186
  <el-checkbox-group v-model="systemItem.LOGIN_MODE">
185
187
  <el-checkbox v-for="item in plainOptions" :key="item.value" :label="item.value">{{
@@ -239,56 +241,56 @@ export default {
239
241
  SYSTEM_LIST: [
240
242
  {
241
243
  NO: 'CSZHYW',
242
- NAME: $lc("财司综合业务系统"),
244
+ NAME: $lc('财司综合业务系统'),
243
245
  ICON: '',
244
246
  LOGIN_MODE: [],
245
247
  OPEN: true
246
248
  },
247
249
  {
248
250
  NO: 'CSYWGL',
249
- NAME: $lc("财司业务管理系统"),
251
+ NAME: $lc('财司业务管理系统'),
250
252
  ICON: '',
251
253
  LOGIN_MODE: [],
252
254
  OPEN: false
253
255
  },
254
256
  {
255
257
  NO: 'CSFZJC',
256
- NAME: $lc("财司辅助决策系统"),
258
+ NAME: $lc('财司辅助决策系统'),
257
259
  ICON: '',
258
260
  LOGIN_MODE: [],
259
261
  OPEN: false
260
262
  },
261
263
  {
262
264
  NO: 'CSWY',
263
- NAME: $lc("财司网银系统"),
265
+ NAME: $lc('财司网银系统'),
264
266
  ICON: '',
265
267
  LOGIN_MODE: [],
266
268
  OPEN: false
267
269
  },
268
270
  {
269
271
  NO: 'JTZL',
270
- NAME: $lc("财司直连平台系统"),
272
+ NAME: $lc('财司直连平台系统'),
271
273
  ICON: '',
272
274
  LOGIN_MODE: [],
273
275
  OPEN: false
274
276
  },
275
277
  {
276
278
  NO: 'JRWG',
277
- NAME: $lc("金融网关系统"),
279
+ NAME: $lc('金融网关系统'),
278
280
  ICON: '',
279
281
  LOGIN_MODE: [],
280
282
  OPEN: false
281
283
  },
282
284
  {
283
285
  NO: 'JTSKYWGK',
284
- NAME: $lc("集团司库业务管控系统"),
286
+ NAME: $lc('集团司库业务管控系统'),
285
287
  ICON: '',
286
288
  LOGIN_MODE: [],
287
289
  OPEN: false
288
290
  },
289
291
  {
290
292
  NO: 'JTSKSJFX',
291
- NAME: $lc("集团数据分析系统"),
293
+ NAME: $lc('集团数据分析系统'),
292
294
  ICON: '',
293
295
  LOGIN_MODE: [],
294
296
  OPEN: false
@@ -296,10 +298,10 @@ export default {
296
298
  ]
297
299
  },
298
300
  plainOptions: [
299
- { label: $lc("账户密码登录"), value: 'account' },
300
- { label: $lc("手机验证码登录"), value: 'pthon' },
301
- { label: $lc("二维码扫码登录"), value: 'qrcode' },
302
- { label: $lc("账户密码验证码登录"), value: 'accountPthon' }
301
+ { label: $lc('账户密码登录'), value: 'account' },
302
+ { label: $lc('手机验证码登录'), value: 'pthon' },
303
+ { label: $lc('二维码扫码登录'), value: 'qrcode' },
304
+ { label: $lc('账户密码验证码登录'), value: 'accountPthon' }
303
305
  ],
304
306
  systemItem: undefined,
305
307
  key_1: 0,
@@ -332,7 +334,7 @@ export default {
332
334
  try {
333
335
  this.form[k] = k === 'LOGIN_URL' ? obj.pmValue : JSON.parse(obj.pmValue)
334
336
  } catch (error) {
335
- console.error(k + $lc("解析错误"))
337
+ console.error(k + $lc('解析错误'))
336
338
  }
337
339
  }
338
340
  } else {
@@ -343,7 +345,7 @@ export default {
343
345
  try {
344
346
  this.$set(this.form.SYSTEM_LIST, i, JSON.parse(obj.pmValue))
345
347
  } catch (error) {
346
- console.error('SYSTEM_LIST[' + item.NO + $lc("]解析错误"))
348
+ console.error('SYSTEM_LIST[' + item.NO + $lc(']解析错误'))
347
349
  }
348
350
  }
349
351
  })
@@ -361,7 +363,7 @@ export default {
361
363
  async save() {
362
364
  let vPro = this.$refs['form'].validate()
363
365
  vPro.catch(() => {
364
- this.$message.error($lc("必填项不能为空"))
366
+ this.$message.error($lc('必填项不能为空'))
365
367
  })
366
368
  await vPro
367
369
  let data = []
@@ -400,7 +402,7 @@ export default {
400
402
  let secondsToGo = 5
401
403
  this.$message({
402
404
  type: 'success',
403
- message: `${$lc("设置成功,系统将在")} ${secondsToGo} ${$lc("秒后退出到登录页面.")}`
405
+ message: `${$lc('设置成功,系统将在')} ${secondsToGo} ${$lc('秒后退出到登录页面.')}`
404
406
  })
405
407
  const interval = setInterval(() => {
406
408
  secondsToGo -= 1
@@ -462,20 +462,14 @@ function saveTransform(list, labelKey, isFilter) {
462
462
  let listN = []
463
463
  if (!isFilter) {
464
464
  list.forEach((c) => {
465
- if (c.prop && !c.children && !c.isNew && !c.width & !c.isNew) {
466
- listN.push({ _colKey: 'prop', _colVal: c.prop })
467
- } else if (c.type && ['selection', 'index', 'expand'].includes(c.type)) {
468
- listN.push({ _colKey: 'type', _colVal: c.type })
469
- } else {
470
- let sFn = false
471
- for (let k in c) {
472
- if (typeof c[k] === 'function') sFn = true
473
- }
474
- if (sFn && c[labelKey]) {
475
- listN.push({ _colKey: labelKey, _colVal: c[labelKey] })
476
- } else {
477
- listN.push(c)
478
- }
465
+ const colKey = getColumnKey(c, labelKey)
466
+ // 已有列只保存稳定标识和用户设置,label 始终从当前 columns 中获取
467
+ if (colKey && !c.isNew && !c.remote) {
468
+ listN.push(createColumnReference(c, colKey))
469
+ }
470
+ // 用户新增列、远程列等没有本地定义可供回填,需要保留完整配置
471
+ else {
472
+ listN.push(c)
479
473
  }
480
474
  })
481
475
  } else {
@@ -494,6 +488,44 @@ function saveTransform(list, labelKey, isFilter) {
494
488
  return listN
495
489
  }
496
490
 
491
+ const COLUMN_KEY_PRIORITY = ['columnKey', 'prop', 'slotName', 'field', 'type']
492
+ const COLUMN_SETTING_KEYS = ['fixed', 'width', 'wrap', 'bold', 'align']
493
+
494
+ function getColumnKey(column, labelKey = 'label') {
495
+ return COLUMN_KEY_PRIORITY.find(
496
+ (key) => key !== labelKey && column[key] !== undefined && column[key] !== null && column[key] !== ''
497
+ )
498
+ }
499
+
500
+ function createColumnReference(column, colKey) {
501
+ const entry = { _colKey: colKey, _colVal: column[colKey] }
502
+ COLUMN_SETTING_KEYS.forEach((key) => {
503
+ if (column[key] !== undefined) entry[key] = column[key]
504
+ })
505
+ return entry
506
+ }
507
+
508
+ function findCurrentColumn(savedColumn, columnsT, labelKey) {
509
+ if (savedColumn._colKey) {
510
+ const column = columnsT.find((c) => c[savedColumn._colKey] === savedColumn._colVal)
511
+ if (column) return column
512
+ }
513
+
514
+ // 兼容历史完整对象,以及曾使用翻译后 label 作为 _colKey 的数据
515
+ const colKey = getColumnKey(savedColumn, labelKey)
516
+ if (colKey) {
517
+ return columnsT.find((c) => c[colKey] === savedColumn[colKey])
518
+ }
519
+ }
520
+
521
+ function mergeColumnSettings(column, savedColumn) {
522
+ const settings = {}
523
+ COLUMN_SETTING_KEYS.forEach((key) => {
524
+ if (savedColumn[key] !== undefined) settings[key] = savedColumn[key]
525
+ })
526
+ return Object.keys(settings).length ? { ...column, ...settings } : column
527
+ }
528
+
497
529
  function getTransform(list, columnsT, labelKey = 'label') {
498
530
  let columns = []
499
531
  list.forEach((d) => {
@@ -505,16 +537,15 @@ function getTransform(list, columnsT, labelKey = 'label') {
505
537
  column && columns.push(column)
506
538
  // 如果list中的每一项是对象
507
539
  } else if (typeof d === 'object') {
508
- // 如果d中有_colKey属性
509
- if (d._colKey) {
510
- // 从columnsT中找到d._colKey等于d._colVal的项
511
- let column = columnsT.find((c) => c[d._colKey] === d._colVal)
512
- // 如果找到,则将其添加到columns中
513
- column && columns.push(column)
514
- // 如果d中没有_colKey属性
515
- } else {
516
- // 将d添加到columns中
540
+ const column = findCurrentColumn(d, columnsT, labelKey)
541
+ if (column) {
542
+ // 使用当前 columns 的完整定义(包括当前语言 label),仅合并用户设置
543
+ columns.push(mergeColumnSettings(column, d))
544
+ } else if (!d._colKey) {
545
+ // 用户新增列、远程列等没有本地定义,保持原有数据形态
517
546
  columns.push(d)
547
+ } else {
548
+ // _colKey 数据未匹配到当前列时沿用原行为:忽略已不存在的列
518
549
  }
519
550
  }
520
551
  })