n20-common-lib 3.0.35 → 3.0.36

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.35",
3
+ "version": "3.0.36",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -68,7 +68,7 @@
68
68
  "vue-jsonp": "2.0.0",
69
69
  "vuedraggable": "*",
70
70
  "webpack-duplicate-relano-plugin": "^0.1.0",
71
- "xe-utils": "^4.0.2",
71
+ "xe-utils": "4.0.2",
72
72
  "ngraph.events": "1.2.2"
73
73
  },
74
74
  "devDependencies": {
@@ -7,10 +7,47 @@
7
7
  max-height: 300px;
8
8
  overflow-y: auto;
9
9
  }
10
+
11
+ .el-popover.pro-filter-view-popover {
12
+ padding: 8px;
13
+ margin-top: 4px;
14
+ max-width: 256px;
15
+ // .popper__arrow::after {
16
+ // border-width: 0;
17
+ // }
18
+
19
+ .filter-view-wrapper {
20
+ max-height: 300px;
21
+ overflow-y: auto;
22
+ }
23
+ /* more 图标默认隐藏,hover 列表项时显示 */
24
+ .proFilterView-list-item .proFilterView-list-item__more {
25
+ visibility: hidden;
26
+ }
27
+ .proFilterView-list-item:hover .proFilterView-list-item__more {
28
+ visibility: visible;
29
+ }
30
+ /* 视图名称单行溢出省略 */
31
+ .proFilterView-list-item__name {
32
+ flex: 1;
33
+ width: 180px;
34
+ overflow: hidden;
35
+ white-space: nowrap;
36
+ text-overflow: ellipsis;
37
+ cursor: pointer;
38
+ }
39
+ }
40
+ // .pro-filter-view-popover[x-placement^='bottom'] .popper__arrow {
41
+ // top: 0;
42
+ // left: 0;
43
+ // border-bottom-color: transparent;
44
+ // }
45
+
10
46
  // 高级筛选
11
47
  .ProFilterView {
12
48
  width: 100%;
13
49
  font-size: 14px;
50
+
14
51
  .top {
15
52
  padding: 12px 0px;
16
53
  border-bottom: 1px solid #e5e6eb !important;
@@ -20,7 +57,7 @@
20
57
  border-bottom: 1px solid #e5e6eb !important;
21
58
  }
22
59
  .flex-item {
23
- border-bottom: 1px solid var(--button-disabled-background-color);
60
+ // border-bottom: 1px solid var(--button-disabled-background-color);
24
61
  padding: 0 8px;
25
62
  margin-top: 8px;
26
63
  }
@@ -30,6 +67,14 @@
30
67
  border-radius: 4px;
31
68
  background: var(--fill-2, #f2f3f5);
32
69
  border: none;
70
+ .popover-title {
71
+ display: inline-block;
72
+ max-width: 120px;
73
+ overflow: hidden;
74
+ white-space: nowrap;
75
+ text-overflow: ellipsis;
76
+ cursor: pointer;
77
+ }
33
78
  }
34
79
  .activiti {
35
80
  background: var(--color-primary-light-9);
@@ -41,16 +86,26 @@
41
86
  margin-left: 0;
42
87
  }
43
88
  }
89
+ .ProFilterView_divider {
90
+ width: 100%;
91
+ height: 1px;
92
+ background-color: #e5e5e5;
93
+ margin-top: 8px;
94
+ }
95
+
44
96
  .ProFilterView-add {
45
97
  cursor: pointer;
46
98
  margin-top: 8px;
99
+
47
100
  img {
48
101
  margin-right: 12px;
49
102
  }
50
103
  padding: 8px;
51
104
  height: 20px;
52
105
  line-height: 20px;
106
+ position: relative;
53
107
  }
108
+
54
109
  .ProFilterView-add:hover {
55
110
  border-radius: 2px;
56
111
  background: var(--fill-1, #f7f8fa);
@@ -54,7 +54,7 @@
54
54
  <div v-for="(row, rowIndex) in group.rows" :key="`${group.typeValue}-${rowIndex}`" class="file-card">
55
55
  <div class="file-info">
56
56
  <img v-if="matchFileExtension(row[keys.name], ['word', 'doc', 'docx'])" src="./46.svg" class="m-r-s" />
57
- <img v-if="matchFileExtension(row[keys.name], ['xlsx', 'xls'])" src="./60.svg" class="m-r-s" />
57
+ <img v-if="matchFileExtension(row[keys.name], ['xlsx', 'xls', 'csv'])" src="./60.svg" class="m-r-s" />
58
58
  <img v-if="matchFileExtension(row[keys.name], ['pdf'])" src="./37.svg" class="m-r-s" />
59
59
  <div>
60
60
  <div class="file-name" :title="row[keys.name]">{{ row[keys.name] }}</div>
@@ -669,4 +669,4 @@ export default {
669
669
  }
670
670
  }
671
671
  }
672
- </script>
672
+ </script>
@@ -177,7 +177,7 @@
177
177
  <el-button v-if="value.length > 0" type="text" class="add-condition-btn" @click.stop="addCondition(0)">
178
178
  <i class="v3-icon-add-fill"></i> 添加条件
179
179
  </el-button>
180
- <el-button type="text" class="add-group-btn" @click.stop="addConditionGroup(groupIndex)">
180
+ <el-button type="text" class="add-group-btn" @click.stop="addConditionGroup()">
181
181
  <i class="v3-icon-add-fill"></i> 添加条件组
182
182
  </el-button>
183
183
  </div>
@@ -2,43 +2,48 @@
2
2
  <div class="ProFilterView">
3
3
  <div class="flex-box flex-lr flex-v top">
4
4
  <div class="flex-box flex-v">
5
- <el-popover v-model="stVisible" placement="bottom" trigger="click" class="m-r">
5
+ <el-popover
6
+ v-model="stVisible"
7
+ popper-class="pro-filter-view-popover"
8
+ placement="bottom-start"
9
+ trigger="click"
10
+ class="m-r"
11
+ >
6
12
  <el-button slot="reference" class="botton" :class="{ activiti: selectedItem !== '所有的' }">
7
13
  <div class="flex-box flex-v m-r">
8
14
  <i class="v3-icon-inbox"></i>
9
- <div style="margin: 0 8px">{{ selectedItem }}</div>
15
+ <div class="popover-title" style="margin: 0 8px" :title="selectedItem">{{ selectedItem }}</div>
10
16
  <i class="n20-icon-xiala-moren"></i>
11
17
  </div>
12
18
  </el-button>
13
19
  <div class="p-s">
14
- <cl-input-search v-model="val" class="input-w" placeholder="请输入" />
15
- <div style="color: var(--color-text-secondary); margin-top: 8px">{{ $lc('自定义视图') }}</div>
16
- <cl-drag-list class="flex-item" :list="filteredList" :hide-delete="true" @change="fn">
17
- <template v-slot="{ item }">
18
- <div
19
- class="proFilterView-list-item"
20
- :class="{ 'is-selected': selectedItem === item.viewName }"
21
- @click="handleSelect(item)"
22
- >
23
- <span>{{ item.viewName }}</span>
24
- <i v-if="selectedItem === item.viewName" class="el-icon-check selected-icon"></i>
25
- <el-button
26
- v-if="selectedItem !== item.viewName && item.viewName !== '所有的'"
27
- type="text"
28
- size="mini"
29
- @click.stop="edit(item)"
30
- >{{ $lc('编辑') }}</el-button
31
- >
32
- <el-button
33
- v-if="selectedItem !== item.viewName && item.viewName !== '所有的'"
34
- type="text"
35
- size="mini"
36
- @click.stop="deleteOne(item)"
37
- >{{ $lc('删除') }}</el-button
38
- >
39
- </div>
40
- </template>
41
- </cl-drag-list>
20
+ <cl-input-search v-model="val" class="w-100p" placeholder="请输入关键字" />
21
+ <div style="color: var(--color-text-secondary); margin: 12px 0 8px 0">{{ $lc('自定义视图') }}</div>
22
+ <div class="filter-view-wrapper">
23
+ <cl-drag-list class="flex-item" :list="filteredList" :hide-delete="true" @change="fn">
24
+ <template v-slot="{ item }">
25
+ <div class="proFilterView-list-item" :class="{ 'is-selected': selectedItem === item.viewName }">
26
+ <span class="proFilterView-list-item__name" :title="item.viewName" @click="handleSelect(item)">{{
27
+ item.viewName
28
+ }}</span>
29
+ <i v-if="selectedItem === item.viewName" class="el-icon-check selected-icon"></i>
30
+ <el-dropdown
31
+ v-if="selectedItem !== item.viewName && item.viewName !== '所有的'"
32
+ trigger="click"
33
+ class="proFilterView-list-item__more"
34
+ @command="(command) => handleCommand(command, item)"
35
+ >
36
+ <i class="v3-icon-more"></i>
37
+ <el-dropdown-menu slot="dropdown">
38
+ <el-dropdown-item command="edit">{{ $lc('编辑') }}</el-dropdown-item>
39
+ <el-dropdown-item command="delete">{{ $lc('删除') }}</el-dropdown-item>
40
+ </el-dropdown-menu>
41
+ </el-dropdown>
42
+ </div>
43
+ </template>
44
+ </cl-drag-list>
45
+ </div>
46
+ <div class="ProFilterView_divider"></div>
42
47
  <div class="flex-box flex-v flex-l ProFilterView-add">
43
48
  <img src="./plus.svg" alt="" />
44
49
  <div @click="add">{{ $lc('新建视图') }}</div>
@@ -104,7 +109,7 @@
104
109
  prop="viewName"
105
110
  :rules="[{ required: true, message: '请输入', trigger: 'blur' }]"
106
111
  >
107
- <el-input maxlength="30" show-word-limit v-model="form.viewName" />
112
+ <el-input v-model="form.viewName" maxlength="30" show-word-limit />
108
113
  </el-form-item>
109
114
  <div class="flex-box flex-lr flex-v">
110
115
  <div>{{ $lc('数据范围') }}</div>
@@ -225,11 +230,16 @@ export default {
225
230
  }
226
231
  },
227
232
  computed: {
233
+ /**
234
+ * 本地搜索过滤视图列表
235
+ * @returns {Array} 根据 val 关键字过滤后的视图列表;val 为空时返回完整列表
236
+ */
228
237
  filteredList() {
229
238
  if (!this.val) {
230
239
  return this.list
231
240
  }
232
- return this.list.filter((item) => item.toLowerCase().includes(this.val.toLowerCase()))
241
+ const keyword = this.val.toLowerCase()
242
+ return this.list.filter((item) => item.viewName && item.viewName.toLowerCase().includes(keyword))
233
243
  },
234
244
  getInitialSearchValue() {
235
245
  const obj = {}
@@ -262,6 +272,13 @@ export default {
262
272
  this.searchValue = { ...this.getInitialSearchValue }
263
273
  },
264
274
  methods: {
275
+ handleCommand(command, item) {
276
+ const commandMap = {
277
+ edit: () => this.edit(item),
278
+ delete: () => this.deleteOne(item)
279
+ }
280
+ commandMap[command]()
281
+ },
265
282
  setOptions(id, opts) {
266
283
  this.$refs.filter.setOptions(id, opts)
267
284
  this.filterList.forEach((item) => {
@@ -342,6 +359,8 @@ export default {
342
359
  this.searchForm = {
343
360
  ...this.getInitialSearchValue
344
361
  }
362
+ // 新建时重置切换缓存
363
+ this._savedViewConfigs = {}
345
364
  },
346
365
  // 修改
347
366
  edit(item, isRefresh = false) {
@@ -354,10 +373,16 @@ export default {
354
373
  // 赋值操作
355
374
  this.form = item
356
375
  this.viewId = item.viewId
376
+ // 初始化两种类型的已保存数据缓存,供 typeChange 切换时恢复使用
377
+ this._savedViewConfigs = {}
357
378
  if (item.viewType === '0') {
358
- this.searchForm = { ...this.getInitialSearchValue, ...JSON.parse(item.viewConfig) }
379
+ const parsed = JSON.parse(item.viewConfig || '{}')
380
+ this.searchForm = { ...this.getInitialSearchValue, ...parsed }
381
+ this._savedViewConfigs['0'] = { ...parsed }
359
382
  } else {
360
- this.conditionGroups = JSON.parse(item.viewConfig)?.conditionGroups || []
383
+ const parsed = JSON.parse(item.viewConfig || '{}')
384
+ this.conditionGroups = parsed.conditionGroups || []
385
+ this._savedViewConfigs['1'] = { conditionGroups: this.conditionGroups }
361
386
  }
362
387
  },
363
388
  // 保存筛选条件
@@ -441,12 +466,34 @@ export default {
441
466
  fn(list) {
442
467
  console.log('当前list:', list)
443
468
  },
444
- // 查询切换
469
+ /**
470
+ * 查询类型切换(基础查询 <-> 高级查询)
471
+ * 切换时优先从已保存的 viewConfig 中恢复对应类型的数据,
472
+ * 若无已保存数据则重置为初始值
473
+ */
445
474
  typeChange() {
446
475
  this.form.viewType = this.form.viewType === '0' ? '1' : '0'
476
+ // 切换到基础查询(viewType === '0')
447
477
  if (this.form.viewType === '0') {
448
478
  this.conditionGroups = []
479
+ // 若已有保存的 viewConfig 且原始类型也是基础查询,则恢复已保存的搜索条件
480
+ const savedConfig = this._savedViewConfigs && this._savedViewConfigs['0']
481
+ if (savedConfig) {
482
+ this.searchForm = { ...this.getInitialSearchValue, ...savedConfig }
483
+ } else {
484
+ this.searchForm = { ...this.getInitialSearchValue }
485
+ }
449
486
  } else {
487
+ // 切换到高级查询(viewType === '1'),先保存当前基础查询数据
488
+ if (!this._savedViewConfigs) this._savedViewConfigs = {}
489
+ this._savedViewConfigs['0'] = { ...this.searchForm }
490
+ // 恢复已保存的高级查询数据,若无则重置
491
+ const savedConfig = this._savedViewConfigs['1']
492
+ if (savedConfig) {
493
+ this.conditionGroups = savedConfig.conditionGroups || []
494
+ } else {
495
+ this.conditionGroups = []
496
+ }
450
497
  this.searchForm = { ...this.getInitialSearchValue }
451
498
  }
452
499
  }