n20-common-lib 3.0.97 → 3.0.98

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": "3.0.97",
3
+ "version": "3.0.98",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -7,7 +7,7 @@
7
7
  :key="getOnlyKey(item)"
8
8
  :class="[prefixCls + '-item', activeClass(item)]"
9
9
  :label="item.label"
10
- :required="item.required !== undefined || item.required !== null ? item.required : false"
10
+ :required="!!item.required"
11
11
  :disabled="item.props && item.props.disabled"
12
12
  >
13
13
  <div :class="prefixCls + '-content'">
@@ -5,7 +5,7 @@
5
5
  <div class="flex-box flex-v">
6
6
  <el-popover
7
7
  v-if="bussId"
8
- v-model="stVisible"
8
+ v-model="viewPopoverVisible"
9
9
  popper-class="pro-filter-view-popover"
10
10
  placement="bottom-start"
11
11
  trigger="click"
@@ -19,10 +19,10 @@
19
19
  </div>
20
20
  </el-button>
21
21
  <div class="p-s">
22
- <cl-input-search v-model="val" class="w-100p" placeholder="请输入关键字" />
22
+ <cl-input-search v-model="searchKeyword" class="w-100p" placeholder="请输入关键字" />
23
23
  <div style="color: var(--color-text-secondary); margin: 12px 0 8px 0">{{ $lc('自定义视图') }}</div>
24
24
  <div class="filter-view-wrapper">
25
- <cl-drag-list class="flex-item" :list="filteredList" :hide-delete="true" @change="fn">
25
+ <cl-drag-list class="flex-item" :list="filteredList" :hide-delete="true" @change="handleDragSort">
26
26
  <template v-slot="{ item }">
27
27
  <div class="proFilterView-list-item" :class="{ 'is-selected': selectedItem === item.viewName }">
28
28
  <span class="proFilterView-list-item__name" :title="item.viewName" @click="handleSelect(item)">{{
@@ -67,7 +67,7 @@
67
67
  </div>
68
68
  </el-button>
69
69
  <div class="flex-box flex-v">
70
- <el-button icon="v3-icon-filter" class="m-r-s botton" @click="multiple = !multiple">{{
70
+ <el-button icon="v3-icon-filter" class="m-r-s botton" @click="filterExpanded = !filterExpanded">{{
71
71
  '筛选' | $lc
72
72
  }}</el-button>
73
73
  <slot name="rightContent"></slot>
@@ -77,8 +77,8 @@
77
77
  <cl-advanced-filter
78
78
  ref="filter"
79
79
  class="filter"
80
- :class="{ 'is-hidden': !multiple }"
81
- :visible.sync="multiple"
80
+ :class="{ 'is-hidden': !filterExpanded }"
81
+ :visible.sync="filterExpanded"
82
82
  :filter-id="filterId"
83
83
  :buss-id="bussId"
84
84
  :model="searchValue"
@@ -95,9 +95,8 @@
95
95
  <div slot="prefix">
96
96
  <slot name="prefix"></slot>
97
97
  </div>
98
- <!-- 使用作用域插槽传递 searchValue -->
99
98
  <template
100
- v-for="filter in filterList.filter((item) => item.type === 'slot' && $scopedSlots[item.slotName])"
99
+ v-for="filter in slotFilters"
101
100
  #[filter.slotName]="{ model }"
102
101
  >
103
102
  <slot
@@ -131,25 +130,24 @@
131
130
  <div>{{ $lc('数据范围') }}</div>
132
131
  <div style="color: var(--color-primary); cursor: pointer" @click="typeChange">
133
132
  <i class="v3-icon-switch"></i>
134
- <span v-if="form.viewType === '0'"> {{ $lc('高级查询') }}</span>
133
+ <span v-if="form.viewType === VIEW_TYPE.ADVANCED"> {{ $lc('高级查询') }}</span>
135
134
  <span v-else> {{ $lc('基础查询') }}</span>
136
135
  </div>
137
136
  </div>
138
137
  <cl-advanced-filter
139
- v-if="form.viewType === '0'"
138
+ v-if="form.viewType === VIEW_TYPE.ADVANCED"
140
139
  ref="filter"
141
- :key="key"
140
+ :key="dialogFilterKey"
142
141
  class="filter"
143
- :visible.sync="multiple"
142
+ :visible="visible"
144
143
  :model="searchForm"
145
144
  only-key="id"
146
145
  :filter-list="filterList"
147
146
  :check-ids="form.keyIds"
148
147
  @saveCheckData="saveCheckData"
149
148
  >
150
- <!-- 使用作用域插槽传递 searchValue -->
151
149
  <template
152
- v-for="filter in filterList.filter((item) => item.type === 'slot' && $scopedSlots[item.slotName])"
150
+ v-for="filter in slotFilters"
153
151
  #[filter.slotName]="{ model }"
154
152
  >
155
153
  <slot
@@ -168,9 +166,8 @@
168
166
  :filter-id="filterId"
169
167
  :buss-id="bussId"
170
168
  >
171
- <!-- 使用作用域插槽传递 slot 类型的过滤器 -->
172
169
  <template
173
- v-for="filter in filterList.filter((item) => item.type === 'slot' && $scopedSlots[item.slotName])"
170
+ v-for="filter in slotFilters"
174
171
  #[filter.slotName]="{ model, value, input, disabled }"
175
172
  >
176
173
  <slot
@@ -199,6 +196,8 @@ import ClDragList from '../DragList/index.vue'
199
196
  import ClDialog from '../Dialog/index.vue'
200
197
  import axios from '../../utils/axios.js'
201
198
 
199
+ const VIEW_TYPE = { ADVANCED: '0', BASIC: '1' }
200
+
202
201
  export default {
203
202
  name: 'ProFilterView',
204
203
  components: {
@@ -234,19 +233,17 @@ export default {
234
233
  },
235
234
  data() {
236
235
  return {
237
- val: '',
236
+ VIEW_TYPE,
237
+ searchKeyword: '',
238
238
  list: ['无视图'],
239
239
  selectedItem: '无视图', // 默认选中第一项
240
- stVisible: false,
240
+ viewPopoverVisible: false,
241
241
  visible: false,
242
242
  isAdd: false,
243
243
  form: { userNo: sessionStorage.getItem('userNo'), pageNo: this.filterId },
244
244
 
245
- multiple: this.defaultExpanded,
246
- // 保存的筛选字段
247
- checkData: [],
248
- key: 0,
249
- keyIds: [],
245
+ filterExpanded: this.defaultExpanded,
246
+ dialogFilterKey: 0,
250
247
  selectItem: '',
251
248
  // 高级视图筛选
252
249
  conditionGroups: [],
@@ -255,21 +252,29 @@ export default {
255
252
  // 普通筛选值
256
253
  searchValue: {},
257
254
  viewId: undefined,
258
- isRefresh: false
255
+ isRefresh: false,
256
+ // 视图类型切换时缓存对方数据
257
+ savedViewConfigs: {}
259
258
  }
260
259
  },
261
260
  computed: {
262
261
  /**
263
262
  * 本地搜索过滤视图列表
264
- * @returns {Array} 根据 val 关键字过滤后的视图列表;val 为空时返回完整列表
263
+ * @returns {Array} 根据 searchKeyword 过滤后的视图列表;searchKeyword 为空时返回完整列表
265
264
  */
266
265
  filteredList() {
267
- if (!this.val) {
266
+ if (!this.searchKeyword) {
268
267
  return this.list
269
268
  }
270
- const keyword = this.val.toLowerCase()
269
+ const keyword = this.searchKeyword.toLowerCase()
271
270
  return this.list.filter((item) => item.viewName && item.viewName.toLowerCase().includes(keyword))
272
271
  },
272
+ // 筛选出类型为 slot 且在父组件提供了对应作用域插槽的筛选项
273
+ slotFilters() {
274
+ return this.filterList.filter(
275
+ (item) => item.type === 'slot' && this.$scopedSlots[item.slotName]
276
+ )
277
+ },
273
278
  getInitialSearchValue() {
274
279
  const obj = {}
275
280
  // 遍历 filterList,为每个 type 为 slot 的项初始化值
@@ -381,8 +386,36 @@ export default {
381
386
  this.$emit('filter', this.filterObj, 'clean')
382
387
  },
383
388
  handleClear() {
384
- this.searchValue = { ...this.getInitialSearchValue }
385
- this.$emit('filter', this.filterObj, 'clear')
389
+ // 收集 required 项的当前值,清空时保留
390
+ const preserved = {}
391
+ this.filterList.forEach((item) => {
392
+ if (!item.required) return
393
+ if (item.type === 'daterange' || item.type === 'datetimerange' || item.type === 'monthrange') {
394
+ if (item.startDate && this.searchValue[item.startDate] !== undefined) {
395
+ preserved[item.startDate] = this.searchValue[item.startDate]
396
+ }
397
+ if (item.endDate && this.searchValue[item.endDate] !== undefined) {
398
+ preserved[item.endDate] = this.searchValue[item.endDate]
399
+ }
400
+ } else if (item.type === 'numberrange') {
401
+ if (item.startValue && this.searchValue[item.startValue] !== undefined) {
402
+ preserved[item.startValue] = this.searchValue[item.startValue]
403
+ }
404
+ if (item.endValue && this.searchValue[item.endValue] !== undefined) {
405
+ preserved[item.endValue] = this.searchValue[item.endValue]
406
+ }
407
+ } else if (item.value && this.searchValue[item.value] !== undefined) {
408
+ preserved[item.value] = this.searchValue[item.value]
409
+ }
410
+ })
411
+ this.searchValue = { ...this.getInitialSearchValue, ...preserved }
412
+ // 直接构建 payload,绕过 filterObj 避免 initialValue 重新注入
413
+ this.$emit('filter', {
414
+ conditionGroups: this.conditionGroups,
415
+ searchValue: { ...this.searchValue },
416
+ viewId: this.selectItem ? this.selectItem.viewId : null,
417
+ viewType: this.selectItem ? this.selectItem.viewType : null
418
+ }, 'clear')
386
419
  },
387
420
  isEnter() {
388
421
  this.$rulesValidateForm('ruleValidate', (valid) => {
@@ -406,7 +439,7 @@ export default {
406
439
  .get(`/bems/query/viewColumn/getViewInfo`, { bussId: this.bussId })
407
440
  .then((res) => {
408
441
  list = res.data.map((item) => {
409
- item.keyIds = item.keyIds ? JSON.parse(item.keyIds) : []
442
+ item.keyIds = this.safeParse(item.keyIds, [])
410
443
  return item
411
444
  })
412
445
  this.list = [
@@ -434,13 +467,13 @@ export default {
434
467
  // 新增
435
468
  add() {
436
469
  this.isRefresh = false
437
- this.stVisible = false
470
+ this.viewPopoverVisible = false
438
471
  this.visible = true
439
472
  this.isAdd = true
440
473
  this.form = {
441
474
  userNo: sessionStorage.getItem('userNo'),
442
475
  pageNo: this.filterId,
443
- viewType: '0' // 明确设置 type 为 1
476
+ viewType: VIEW_TYPE.ADVANCED
444
477
  }
445
478
  this.viewId = undefined
446
479
  this.form.keyIds = []
@@ -449,30 +482,37 @@ export default {
449
482
  ...this.getInitialSearchValue
450
483
  }
451
484
  // 新建时重置切换缓存
452
- this._savedViewConfigs = {}
485
+ this.savedViewConfigs = {}
453
486
  },
454
487
  // 修改
455
488
  edit(item, isRefresh = false) {
456
489
  this.isRefresh = isRefresh
457
490
  console.log(item)
458
- this.stVisible = false
491
+ this.viewPopoverVisible = false
459
492
  this.visible = true
460
493
  this.isAdd = false
461
- this.key++
494
+ this.dialogFilterKey++
462
495
  // 赋值操作
463
496
  this.form = item
464
497
  this.viewId = item.viewId
465
498
  // 初始化两种类型的已保存数据缓存,供 typeChange 切换时恢复使用
466
- this._savedViewConfigs = {}
467
- if (item.viewType === '0') {
468
- const parsed = JSON.parse(item.viewConfig || '{}')
499
+ this.savedViewConfigs = {}
500
+ if (item.viewType === VIEW_TYPE.ADVANCED) {
501
+ const parsed = this.safeParse(item.viewConfig)
469
502
  this.searchForm = { ...this.getInitialSearchValue, ...parsed }
470
- this._savedViewConfigs['0'] = { ...parsed }
503
+ this.savedViewConfigs[VIEW_TYPE.ADVANCED] = { ...parsed }
471
504
  } else {
472
- const parsed = JSON.parse(item.viewConfig || '{}')
505
+ const parsed = this.safeParse(item.viewConfig)
473
506
  this.conditionGroups = parsed.conditionGroups || []
474
507
 
475
- this._savedViewConfigs['1'] = { conditionGroups: this.conditionGroups }
508
+ this.savedViewConfigs[VIEW_TYPE.BASIC] = { conditionGroups: this.conditionGroups }
509
+ }
510
+ },
511
+ safeParse(str, fallback = {}) {
512
+ try {
513
+ return JSON.parse(str || '{}')
514
+ } catch {
515
+ return fallback
476
516
  }
477
517
  },
478
518
  // 保存筛选条件
@@ -481,29 +521,31 @@ export default {
481
521
  return item.id
482
522
  })
483
523
  },
484
- // 保存视图
485
- saveSt() {
486
- // 如果没有 bussId,不保存视图
487
- if (!this.bussId) {
488
- this.$message.warning('缺少业务ID,无法保存视图')
489
- return
490
- }
491
-
524
+ // 构建视图保存请求体
525
+ buildViewPayload() {
492
526
  let viewConfig
493
527
  let keyIds
494
- if (this.form.viewType === '0') {
528
+ if (this.form.viewType === VIEW_TYPE.ADVANCED) {
495
529
  viewConfig = JSON.stringify(this.searchForm)
496
530
  keyIds = this.form.keyIds
497
531
  } else {
498
532
  viewConfig = JSON.stringify({ conditionGroups: this.conditionGroups })
499
533
  keyIds = []
500
534
  }
501
- console.log(this.conditionGroups)
502
535
  this.form.viewConfig = viewConfig
503
-
504
- const hasEmptyValue = this.conditionGroups.some((group) =>
536
+ return {
537
+ viewName: this.form.viewName,
538
+ viewType: this.form.viewType,
539
+ bussId: this.bussId,
540
+ viewConfig,
541
+ keyIds: JSON.stringify(keyIds),
542
+ viewId: this.viewId
543
+ }
544
+ },
545
+ // 检查基础查询条件是否有空值
546
+ hasEmptyCondition() {
547
+ return this.conditionGroups.some((group) =>
505
548
  group.conditions.some((condition) => {
506
- // operator 5(为空) 和 6(不为空) 不需要填写 value
507
549
  if (condition.operator === 5 || condition.operator === 6) {
508
550
  return false
509
551
  }
@@ -511,35 +553,34 @@ export default {
511
553
  return val === null || val === undefined || val === '' || (Array.isArray(val) && val.length === 0)
512
554
  })
513
555
  )
556
+ },
557
+ // 保存视图
558
+ saveSt() {
559
+ if (!this.bussId) {
560
+ this.$message.warning('缺少业务ID,无法保存视图')
561
+ return
562
+ }
563
+
564
+ const payload = this.buildViewPayload()
565
+ const hasEmptyValue = this.hasEmptyCondition()
514
566
 
515
567
  this.$refs.form.validate(async (valid) => {
516
568
  if (!valid) {
517
569
  this.$message.error('请输入视图名称')
518
570
  return
519
571
  }
520
-
521
- if (this.form.viewType === '0' && !keyIds.length) {
572
+ if (this.form.viewType === VIEW_TYPE.ADVANCED && !this.form.keyIds.length) {
522
573
  this.$message.warning('至少添加一个条件')
523
574
  return
524
575
  }
525
- if (this.form.viewType === '1') {
576
+ if (this.form.viewType === VIEW_TYPE.BASIC) {
526
577
  if (!this.conditionGroups.length || hasEmptyValue) {
527
578
  this.$message.warning('至少添加一个条件')
528
579
  return
529
580
  }
530
581
  }
531
582
 
532
- // 保存筛选视图
533
- const obj = {
534
- viewName: this.form.viewName,
535
- viewType: this.form.viewType,
536
- bussId: this.bussId,
537
- viewConfig: this.form.viewConfig,
538
- keyIds: JSON.stringify(keyIds),
539
- viewId: this.viewId
540
- }
541
-
542
- axios.post('/bems/query/viewColumn/saveOrUpdateViewInfo', obj).then((res) => {
583
+ axios.post('/bems/query/viewColumn/saveOrUpdateViewInfo', payload).then((res) => {
543
584
  if (res.code !== 200) {
544
585
  return false
545
586
  }
@@ -567,7 +608,7 @@ export default {
567
608
  // 选中视图
568
609
  handleSelect(item) {
569
610
  console.log(item)
570
- this.stVisible = false
611
+ this.viewPopoverVisible = false
571
612
  this.selectItem = item
572
613
  this.selectedItem = item.viewName
573
614
  if (item.viewName === '无视图') {
@@ -575,17 +616,18 @@ export default {
575
616
  this.searchValue = {}
576
617
  this.conditionGroups = []
577
618
  }
578
- if (item.viewType === '0') {
579
- this.searchForm = JSON.parse(item.viewConfig)
580
- this.searchValue = JSON.parse(item.viewConfig)
581
- } else if (item.viewType === '1') {
582
- this.conditionGroups = JSON.parse(item.viewConfig)?.conditionGroups || []
619
+ if (item.viewType === VIEW_TYPE.ADVANCED) {
620
+ const config = this.safeParse(item.viewConfig)
621
+ this.searchForm = config
622
+ this.searchValue = config
623
+ } else if (item.viewType === VIEW_TYPE.BASIC) {
624
+ this.conditionGroups = this.safeParse(item.viewConfig).conditionGroups || []
583
625
  this.searchValue = { ...this.getInitialSearchValue }
584
626
  }
585
627
  this.$emit('filter', this.filterObj, 'filter')
586
628
  },
587
629
  // 拖动保存视图列表
588
- fn(list) {
630
+ handleDragSort(list) {
589
631
  console.log('当前list:', list)
590
632
  },
591
633
  /**
@@ -594,23 +636,22 @@ export default {
594
636
  * 若无已保存数据则重置为初始值
595
637
  */
596
638
  typeChange() {
597
- this.form.viewType = this.form.viewType === '0' ? '1' : '0'
598
- // 切换到基础查询(viewType === '0')
599
- if (this.form.viewType === '0') {
639
+ this.form.viewType = this.form.viewType === VIEW_TYPE.ADVANCED ? VIEW_TYPE.BASIC : VIEW_TYPE.ADVANCED
640
+ // 切换到高级查询
641
+ if (this.form.viewType === VIEW_TYPE.ADVANCED) {
600
642
  this.conditionGroups = []
601
643
  // 若已有保存的 viewConfig 且原始类型也是基础查询,则恢复已保存的搜索条件
602
- const savedConfig = this._savedViewConfigs && this._savedViewConfigs['0']
644
+ const savedConfig = this.savedViewConfigs[VIEW_TYPE.ADVANCED]
603
645
  if (savedConfig) {
604
646
  this.searchForm = { ...this.getInitialSearchValue, ...savedConfig }
605
647
  } else {
606
648
  this.searchForm = { ...this.getInitialSearchValue }
607
649
  }
608
650
  } else {
609
- // 切换到高级查询(viewType === '1'),先保存当前基础查询数据
610
- if (!this._savedViewConfigs) this._savedViewConfigs = {}
611
- this._savedViewConfigs['0'] = { ...this.searchForm }
651
+ // 切换到基础查询,保存当前高级查询数据
652
+ this.savedViewConfigs[VIEW_TYPE.ADVANCED] = { ...this.searchForm }
612
653
  // 恢复已保存的高级查询数据,若无则重置
613
- const savedConfig = this._savedViewConfigs['1']
654
+ const savedConfig = this.savedViewConfigs[VIEW_TYPE.BASIC]
614
655
  if (savedConfig) {
615
656
  this.conditionGroups = savedConfig.conditionGroups || []
616
657
  } else {
@@ -624,17 +665,15 @@ export default {
624
665
  * 供下游调用以恢复组件初始状态
625
666
  */
626
667
  resetState() {
627
- this.val = ''
668
+ this.searchKeyword = ''
628
669
  this.selectedItem = '无视图'
629
670
  this.selectItem = ''
630
671
  this.searchValue = { ...this.getInitialSearchValue, ...this.initialValue }
631
672
  this.searchForm = { ...this.getInitialSearchValue }
632
673
  this.conditionGroups = []
633
- this.multiple = this.defaultExpanded
634
- this.checkData = []
635
- this.keyIds = []
674
+ this.filterExpanded = this.defaultExpanded
636
675
  this.viewId = undefined
637
- this._savedViewConfigs = {}
676
+ this.savedViewConfigs = {}
638
677
  }
639
678
  }
640
679
  }