n20-common-lib 3.1.6 → 3.1.7

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.1.6",
3
+ "version": "3.1.7",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -50,7 +50,9 @@
50
50
  @import './page.scss';
51
51
  @import './view-toggle.scss';
52
52
  @import './pivot.scss';
53
+ @import './dynamic-table.scss';
53
54
  @import './v3/table.scss';
54
55
  @import './v3/secondary-tab.scss';
56
+
55
57
  //临时引入
56
58
  @import '../../components/ChildRange/style.scss';
@@ -0,0 +1,6 @@
1
+ .dynamic-table-pro {
2
+ .el-form-item,
3
+ .el-form-item--small.el-form-item {
4
+ margin-bottom: 0;
5
+ }
6
+ }
@@ -8,7 +8,7 @@ import inputNumber from '../InputNumber/index.vue'
8
8
  import InputNumberRange from '../InputNumber/numberRange.vue'
9
9
  import selectTree from '../SelectTree/index.vue'
10
10
  import selectTreePro from '../SelectTree/pro.vue'
11
- import { setOptionsMap } from './utils.js'
11
+
12
12
  const canvas = document.createElement('canvas')
13
13
  const context = canvas.getContext('2d')
14
14
  context.font = '14px Ping Fang SC'
@@ -83,7 +83,6 @@ export default {
83
83
  resKeys.forEach((key) => {
84
84
  list = list[key]
85
85
  })
86
- setOptionsMap(this.item.id, list)
87
86
  this.$set(this.item, 'options', list)
88
87
  // 同步更新 filterList 中的 options,确保两者一致,
89
88
  // 防止 AdvancedFilter 的 filterList watcher 用旧数据覆盖 reqOptions 结果
@@ -5,7 +5,7 @@
5
5
  <el-form-item
6
6
  v-for="item in GroupData"
7
7
  :key="getOnlyKey(item)"
8
- :class="[prefixCls + '-item', activeClass(item)]"
8
+ :class="[prefixCls + '-item', activeClassMap[item.value || item[onlyKey]] || '']"
9
9
  :label="item.label"
10
10
  :required="!!item.required"
11
11
  :disabled="item.props && item.props.disabled"
@@ -107,17 +107,17 @@
107
107
  </template>
108
108
 
109
109
  <script>
110
- // import formItemInput from './form-item-input.vue'
111
110
  import XEUtils from 'xe-utils'
112
111
 
113
112
  import filterItem from './filterItem.vue'
114
113
  import formItemRender from './formItemRender.vue'
115
- import { getOnlyKey } from './utils'
116
114
 
117
115
  import axios from '../../utils/axios.js'
118
116
  import ClDialog from '../Dialog/index.vue'
119
117
  import InputSearch from '../InputSearch/index.vue'
120
118
 
119
+ const getOnlyKeys = (key, data) => (key ? data[key] : Date.now().toString(36) + Math.random().toString(36).slice(2, 7))
120
+
121
121
  const prefixCls = 'n20-advanced-filter'
122
122
  export default {
123
123
  name: 'AdvancedFilter',
@@ -221,6 +221,48 @@ export default {
221
221
 
222
222
  const nonFixedItemIds = nonFixedItems.map((item) => item[this.onlyKey])
223
223
  return nonFixedItemIds.every((id) => this.checkList.includes(id))
224
+ },
225
+ // 通过深度遍历 model 所有属性触发 getter,建立完整响应式依赖
226
+ // 同时收集对象级 __ob__.dep,确保 $set 新增属性时也能触发重算
227
+ _modelValues() {
228
+ const model = this.model
229
+ // 遍历所有自有属性触发 getter(收集属性级 dep)
230
+ // Object.keys 在 Vue 2 内部会触发对象级 dep 收集
231
+ const keys = Object.keys(model)
232
+ const values = []
233
+ for (let i = 0; i < keys.length; i++) {
234
+ values.push(model[keys[i]])
235
+ }
236
+ return values
237
+ },
238
+ activeClassMap() {
239
+ // 访问 _modelValues 建立深度依赖,确保 model 任何值变化都能触发重算
240
+ void this._modelValues
241
+
242
+ const model = this.model
243
+ const hasValue = (val) => {
244
+ if (Array.isArray(val)) return val.length > 0
245
+ return val !== null && val !== undefined && val !== ''
246
+ }
247
+ const hasRange = (start, end) => hasValue(model[start]) && hasValue(model[end])
248
+ const rangeTypes = ['daterange', 'datetimerange', 'monthrange']
249
+
250
+ const map = {}
251
+ this.GroupData.forEach((item) => {
252
+ const key = item.value || item[this.onlyKey]
253
+ let isActive = false
254
+ if (item.type === 'numberrange') {
255
+ isActive = hasRange(item.startValue, item.endValue)
256
+ } else if (rangeTypes.includes(item.type)) {
257
+ isActive = hasRange(item.startDate, item.endDate)
258
+ } else if (item.slotFields && item.slotFields.length > 0) {
259
+ isActive = item.slotFields.some((field) => hasValue(model[field]))
260
+ } else {
261
+ isActive = hasValue(model[item.value])
262
+ }
263
+ map[key] = isActive ? this.prefixCls + '-active' : ''
264
+ })
265
+ return map
224
266
  }
225
267
  },
226
268
  watch: {
@@ -298,7 +340,7 @@ export default {
298
340
  this.defineCheckList = XEUtils.clone(_checkList, true)
299
341
  },
300
342
  getOnlyKey(data) {
301
- return getOnlyKey(this.onlyKey, data)
343
+ return getOnlyKeys(this.onlyKey, data)
302
344
  },
303
345
  setOptions(id, opts) {
304
346
  this.optionsMap[id] = opts
@@ -318,29 +360,7 @@ export default {
318
360
  filter() {
319
361
  return this.model
320
362
  },
321
- activeClass(item) {
322
- // 判断值是否有效(非空)
323
- const hasValue = (val) => {
324
- if (Array.isArray(val)) return val.length > 0
325
- return val !== null && val !== undefined && val !== ''
326
- }
327
-
328
- // 判断范围类型是否有效(起止值都存在)
329
- const hasRange = (start, end) => hasValue(this.model[start]) && hasValue(this.model[end])
330
363
 
331
- const rangeTypes = ['daterange', 'datetimerange', 'monthrange']
332
-
333
- if (item.type === 'numberrange') {
334
- return hasRange(item.startValue, item.endValue) ? this.prefixCls + '-active' : ''
335
- }
336
- if (rangeTypes.includes(item.type)) {
337
- return hasRange(item.startDate, item.endDate) ? this.prefixCls + '-active' : ''
338
- }
339
- if (item.slotFields && item.slotFields.length > 0) {
340
- return item.slotFields.some((field) => hasValue(this.model[field])) ? this.prefixCls + '-active' : ''
341
- }
342
- return hasValue(this.model[item.value]) ? this.prefixCls + '-active' : ''
343
- },
344
364
  handleClose(item) {
345
365
  const key = item[this.onlyKey] || item.value
346
366
  if (this.optionsMap[key]) {
@@ -437,7 +457,7 @@ export default {
437
457
  if (Object.hasOwnProperty.call(this.model, key)) {
438
458
  // 仅当该字段在 filterList 中定义且未被选中时才清除
439
459
  if (allDefinedFields.has(key) && !selectedFields.has(key)) {
440
- delete this.model[key]
460
+ this.$delete(this.model, key)
441
461
  }
442
462
  }
443
463
  }
@@ -418,48 +418,49 @@ export default {
418
418
  this.$emit('filter', this.filterObj, 'clean')
419
419
  },
420
420
  handleClear() {
421
- // 收集 required 项的当前值,清空时保留
421
+ // 收集不需要清空的字段 key(required / isNotClose / initialValue 中的额外 key)
422
+ const noClearKeys = new Set()
423
+ const allFilterKeys = new Set()
424
+
425
+ this.filterList.forEach((item) => {
426
+ const keys =
427
+ item.type === 'daterange'
428
+ ? [item.startDate, item.endDate]
429
+ : item.type === 'numberrange'
430
+ ? [item.startValue, item.endValue]
431
+ : item.slotFields?.length
432
+ ? item.slotFields
433
+ : [item.value]
434
+
435
+ keys.forEach((k) => allFilterKeys.add(k))
436
+ if (item.required) {
437
+ keys.forEach((k) => noClearKeys.add(k))
438
+ }
439
+ })
440
+
441
+ // initialValue 中不在 filterList 里的 key 也需要保留
442
+ Object.keys(this.initialValue).forEach((key) => {
443
+ if (!allFilterKeys.has(key)) {
444
+ noClearKeys.add(key)
445
+ }
446
+ })
447
+
448
+ // 仅保留 noClearKeys 中的值,其余清空
422
449
  const preserved = {}
423
- this.filterList
424
- .filter((item) => item.required)
425
- .forEach((item) => {
426
- // 日期范围类型
427
- if (item.startDate && this.searchValue[item.startDate] !== undefined) {
428
- preserved[item.startDate] = this.searchValue[item.startDate]
429
- }
430
- if (item.endDate && this.searchValue[item.endDate] !== undefined) {
431
- preserved[item.endDate] = this.searchValue[item.endDate]
432
- }
433
- // 数字范围类型
434
- if (item.startValue && this.searchValue[item.startValue] !== undefined) {
435
- preserved[item.startValue] = this.searchValue[item.startValue]
436
- }
437
- if (item.endValue && this.searchValue[item.endValue] !== undefined) {
438
- preserved[item.endValue] = this.searchValue[item.endValue]
439
- }
440
- // 普通单值
441
- if (item.value && this.searchValue[item.value] !== undefined) {
442
- preserved[item.value] = this.searchValue[item.value]
443
- }
444
- // slot 多值绑定
445
- if (item.slotFields?.length) {
446
- item.slotFields.forEach((field) => {
447
- if (this.searchValue[field] !== undefined) {
448
- preserved[field] = this.searchValue[field]
449
- }
450
- })
451
- }
452
- })
450
+ for (const key in this.searchValue) {
451
+ if (noClearKeys.has(key)) {
452
+ preserved[key] = this.searchValue[key]
453
+ }
454
+ }
453
455
 
454
- this.searchValue = { ...this.initialValue, ...this.getInitialSearchValue, ...preserved }
455
- // 直接构建 payload,绕过 filterObj 避免 initialValue 重新注入
456
+ this.searchValue = preserved
456
457
  this.$emit(
457
458
  'filter',
458
459
  {
459
460
  conditionGroups: this.conditionGroups,
460
461
  searchValue: { ...this.searchValue },
461
- viewId: this.selectItem ? this.selectItem.viewId : null,
462
- viewType: this.selectItem ? this.selectItem.viewType : null
462
+ viewId: this.selectItem?.viewId ?? null,
463
+ viewType: this.selectItem?.viewType ?? null
463
464
  },
464
465
  'clear'
465
466
  )