mooho-base-admin-plus 2.3.7 → 2.3.8

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,7 +1,7 @@
1
1
  {
2
2
  "name": "mooho-base-admin-plus",
3
3
  "description": "MOOHO basic framework for admin by Vue3",
4
- "version": "2.3.7",
4
+ "version": "2.3.8",
5
5
  "author": "jinyifan <jinyifan@mooho.com.cn>",
6
6
  "license": "MIT",
7
7
  "private": false,
package/public/setting.js CHANGED
@@ -82,7 +82,7 @@ window.setting = {
82
82
  // 筛选标题栏宽度
83
83
  filterWidth: 125,
84
84
  // 每页默认数量
85
- pageSize: 20
85
+ pageSize: 10
86
86
  },
87
87
  /**
88
88
  * 多语言配置
@@ -71,6 +71,7 @@
71
71
  data.controlType == 'SelectWithOther' ||
72
72
  data.controlType == 'ComboSelect' ||
73
73
  data.controlType == 'MultiSelect' ||
74
+ data.controlType == 'MultiComboSelect' ||
74
75
  data.controlType == 'Radio' ||
75
76
  data.controlType == 'CheckGroup'
76
77
  "
@@ -95,6 +96,7 @@
95
96
  data.controlType == 'SelectWithOther' ||
96
97
  data.controlType == 'ComboSelect' ||
97
98
  data.controlType == 'MultiSelect' ||
99
+ data.controlType == 'MultiComboSelect' ||
98
100
  data.controlType == 'Radio' ||
99
101
  data.controlType == 'CheckGroup') &&
100
102
  !data.isStaticItem
@@ -123,6 +125,7 @@
123
125
  data.controlType == 'SelectWithOther' ||
124
126
  data.controlType == 'ComboSelect' ||
125
127
  data.controlType == 'MultiSelect' ||
128
+ data.controlType == 'MultiComboSelect' ||
126
129
  data.controlType == 'Radio' ||
127
130
  data.controlType == 'CheckGroup')
128
131
  "
@@ -676,6 +679,7 @@
676
679
  this.data.controlType === 'MultiTreeSelect' ||
677
680
  this.data.controlType === 'SelectWithOther' ||
678
681
  this.data.controlType === 'ComboSelect' ||
682
+ this.data.controlType === 'MultiComboSelect' ||
679
683
  this.data.controlType === 'Radio' ||
680
684
  this.data.controlType === 'CheckGroup') &&
681
685
  !this.data.isStaticItem &&
@@ -63,6 +63,7 @@
63
63
  data.controlType == 'MultiSelect' ||
64
64
  data.controlType == 'SelectWithOther' ||
65
65
  data.controlType == 'ComboSelect' ||
66
+ data.controlType == 'MultiComboSelect' ||
66
67
  data.controlType == 'Radio' ||
67
68
  data.controlType == 'CheckGroup'
68
69
  "
@@ -84,8 +85,9 @@
84
85
  v-if="
85
86
  (data.controlType == 'Select' ||
86
87
  data.controlType == 'SelectWithOther' ||
87
- data.controlType == 'ComboSelect' ||
88
88
  data.controlType == 'MultiSelect' ||
89
+ data.controlType == 'ComboSelect' ||
90
+ data.controlType == 'MultiComboSelect' ||
89
91
  data.controlType == 'Radio' ||
90
92
  data.controlType == 'CheckGroup') &&
91
93
  !data.isStaticItem
@@ -114,6 +116,7 @@
114
116
  data.controlType == 'MultiSelect' ||
115
117
  data.controlType == 'SelectWithOther' ||
116
118
  data.controlType == 'ComboSelect' ||
119
+ data.controlType == 'MultiComboSelect' ||
117
120
  data.controlType == 'Radio' ||
118
121
  data.controlType == 'CheckGroup')
119
122
  "
@@ -452,6 +455,7 @@
452
455
  this.data.controlType === 'MultiTreeSelect' ||
453
456
  this.data.controlType === 'SelectWithOther' ||
454
457
  this.data.controlType === 'ComboSelect' ||
458
+ this.data.controlType === 'MultiComboSelect' ||
455
459
  this.data.controlType === 'Radio' ||
456
460
  this.data.controlType === 'CheckGroup') &&
457
461
  !this.data.isStaticItem &&
@@ -174,6 +174,7 @@
174
174
  item.id == 'SelectWithOther' ||
175
175
  item.id == 'MultiSelect' ||
176
176
  item.id == 'ComboSelect' ||
177
+ item.id == 'MultiComboSelect' ||
177
178
  item.id == 'DialogSelect' ||
178
179
  item.id == 'MultiDialogSelect' ||
179
180
  item.id == 'TreeSelect' ||
@@ -120,18 +120,39 @@
120
120
  @update:model-value="$event => setFilterData(data, column, $event)"
121
121
  :style="{ width: column.controlWidth == null ? '40%' : column.controlWidth + 'px' }"
122
122
  style="margin-left: 4px"
123
- :maxlength="column.maxLength"
124
123
  :placeholder="column.description"
125
124
  @on-change="onDataChange(column)"
126
125
  />
127
126
  </template>
128
127
  <template v-else-if="column.controlType === 'ComboSelect'">
129
128
  <Select
129
+ :ref="'control_' + column.code"
130
130
  size="small"
131
- :model-value="parseFilterData(data, column)"
131
+ :model-value="parseComboData(data, column)"
132
132
  @update:model-value="$event => setFilterData(data, column, $event)"
133
- clearable
133
+ :clearable="true"
134
+ filterable
135
+ remote
136
+ :remote-method="search => loadOption(data, column, search)"
137
+ :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
138
+ :placeholder="column.description"
139
+ :transfer="true"
140
+ @on-change="selected => onSelectDataChange(column, selected)"
141
+ >
142
+ <Option v-for="item in getDataSource(data, column)" :key="item.id" :value="item.id">{{ item.name }}</Option>
143
+ </Select>
144
+ </template>
145
+ <template v-else-if="column.controlType === 'MultiComboSelect'">
146
+ <Select
147
+ :ref="'control_' + column.code"
148
+ size="small"
149
+ :model-value="parseMultiComboData(data, column)"
150
+ @update:model-value="$event => setArrayFilterData(data, column, $event)"
151
+ :clearable="true"
152
+ :multiple="true"
134
153
  filterable
154
+ remote
155
+ :remote-method="search => loadOption(data, column, search)"
135
156
  :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
136
157
  :placeholder="column.description"
137
158
  :transfer="true"
@@ -140,6 +161,7 @@
140
161
  <Option v-for="item in getDataSource(data, column)" :key="item.id" :value="item.id">{{ item.name }}</Option>
141
162
  </Select>
142
163
  </template>
164
+
143
165
  <template v-else-if="column.controlType === 'DialogSelect'">
144
166
  <dialog-select
145
167
  size="small"
@@ -221,6 +243,16 @@
221
243
  </Radio>
222
244
  </RadioGroup>
223
245
  </template>
246
+ <template v-else-if="column.controlType === 'TextArea'">
247
+ <Input
248
+ type="textarea"
249
+ :model-value="parseFilterData(data, column.code)"
250
+ @update:model-value="$event => setFilterData(data, column.code, $event)"
251
+ :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
252
+ :rows="column.controlHeight / 20"
253
+ :placeholder="column.description"
254
+ />
255
+ </template>
224
256
  <template v-else>{{ $t('Front_Label_Control_Type_Not_Supported') }} {{ column.controlType }}</template>
225
257
  </FormItem>
226
258
  </template>
@@ -407,18 +439,31 @@
407
439
  },
408
440
  // 填充数据源
409
441
  async fillDataSource(data, column, param) {
442
+ let value;
443
+ if (column.controlType === 'TreeSelect' || column.controlType === 'MultiTreeSelect') {
444
+ // 树选择框重新加载数据源时,需要先清空数据源,否则无法直接点击清空按钮清除数据。
445
+ value = this.parseTreeFilterData(data, column);
446
+ column.dataSource = null;
447
+ }
448
+
449
+ if (column.controlType === 'ComboSelect' || column.controlType === 'MultiComboSelect') {
450
+ param.per = 20;
451
+ }
452
+
410
453
  // 参数完整,查询数据
454
+ this.disableLoader();
411
455
  let res;
412
456
  if (column.isSourceCustom) {
413
457
  res = await customModelApi.query(column.source, param);
414
458
  } else {
415
459
  res = await modelApi.query(column.source, param);
416
460
  }
461
+ this.enableLoader();
417
462
 
418
463
  column.rawData = res.data;
419
464
 
420
465
  if (column.controlType === 'TreeSelect' || column.controlType === 'MultiTreeSelect') {
421
- let data = res.data.map(item => {
466
+ let treeData = res.data.map(item => {
422
467
  return {
423
468
  id: !(column.sourceDataCode || '').trim() ? item.id : this.parseData(item, column.sourceDataCode),
424
469
  name: this.parseData(item, column.sourceDisplayCode),
@@ -426,7 +471,8 @@
426
471
  };
427
472
  });
428
473
 
429
- column.dataSource = this.getTreeDataSource(data, column, null);
474
+ column.dataSource = this.getTreeDataSource(treeData, column, null);
475
+ this.setFilterData(data, column, value);
430
476
  } else {
431
477
  column.dataSource = res.data.map(item => {
432
478
  return {
@@ -439,17 +485,43 @@
439
485
  if (data) {
440
486
  if (this.parseFilterData(data, column) == null && column.isDefaultFirst && res.length > 0) {
441
487
  this.setData(data, column.code, this.parseData(res[0], column.sourceDataCode));
488
+ /**
489
+ * 数据变化事件
490
+ * @property {object} sender 触发的列对象
491
+ * @property {object} oldValue 原数据
492
+ * @property {object} newValue 新数据
493
+ * @property {object} selected 选中对象(弹出选择框等有效)
494
+ */
495
+ this.$emit('on-change', column, null, column.rawData[0], null);
496
+
497
+ if (column.sourceDataCode == 'id' && column.code.length > 2) {
498
+ let code = column.code.substr(0, column.code.length - 2);
499
+ let model = column.rawData.find(item => {
500
+ return item.id == this.parseData(data, column.code);
501
+ });
502
+
503
+ this.setData(data, code, model);
504
+ }
442
505
  }
443
506
  }
444
507
  }
445
508
 
446
- //this.$forceUpdate();
447
-
448
- // 更新data触发刷新
449
- // this.data = { ...this.data };
509
+ // 级联更新时清空数据
510
+ if (column.controlType == 'Select' || column.controlType == 'Radio') {
511
+ if (
512
+ !column.dataSource.some(item => {
513
+ return item.id == this.parseData(data, column.code);
514
+ })
515
+ ) {
516
+ // 数据不存在于此数据源,清空数据
517
+ this.setData(data, column.code, null);
450
518
 
451
- // 触发
452
- this.onDataChange(column);
519
+ // 触发
520
+ column.triggers.forEach(item => {
521
+ item.needClear = true;
522
+ });
523
+ }
524
+ }
453
525
  },
454
526
  // 获取树结构数据源
455
527
  getTreeDataSource(data, column, parentID) {
@@ -477,7 +549,7 @@
477
549
  },
478
550
  // 获取数据源
479
551
  getDataSource(data, column) {
480
- if (!column.isStaticItem && column.dataType.indexOf('Enum:') === 0) {
552
+ if (!column.isStaticItem && column.dataType.startsWith('Enum:')) {
481
553
  // 枚举
482
554
  return this.getEnumList(column.dataType.split(':')[1]);
483
555
  } else {
@@ -597,6 +669,7 @@
597
669
  column.controlType === 'MultiTreeSelect' ||
598
670
  column.controlType === 'SelectWithOther' ||
599
671
  column.controlType === 'ComboSelect' ||
672
+ column.controlType === 'MultiComboSelect' ||
600
673
  column.controlType === 'Radio'
601
674
  ) {
602
675
  // 选择框、单选框组
@@ -636,8 +709,8 @@
636
709
  parseArrayFilterData(model, column) {
637
710
  let data = [];
638
711
  let value = this.parseFilterData(model, column);
639
- if (value != null && value !== '') {
640
- data = value.split(',');
712
+ if (this.isJSON(value)) {
713
+ data = JSON.parse(value);
641
714
  }
642
715
 
643
716
  return data;
@@ -646,7 +719,7 @@
646
719
  setArrayFilterData(model, column, value) {
647
720
  let data = '';
648
721
  if (value != null) {
649
- data = value.join(',');
722
+ data = JSON.stringify(value);
650
723
  }
651
724
 
652
725
  this.setFilterData(model, column, data);
@@ -753,6 +826,111 @@
753
826
  } else {
754
827
  return column.name;
755
828
  }
829
+ },
830
+ // 可筛选下拉框加载数据
831
+ async loadOption(data, column, keyword) {
832
+ if (column.isStaticItem || (column.dataType && column.dataType.startsWith('Enum:'))) {
833
+ return;
834
+ }
835
+
836
+ let param = this.getParam(data, column);
837
+
838
+ if (param != null) {
839
+ param[column.sourceDisplayCode + '_c'] = keyword;
840
+ this.fillDataSource(data, column, param);
841
+ } else {
842
+ // 参数不完整,清空数据
843
+ column.rawData = [];
844
+ column.dataSource = [];
845
+ this.setData(data, column.code, null);
846
+ // column.displayValue = null;
847
+
848
+ // 触发
849
+ column.triggers.forEach(item => {
850
+ item.needClear = true;
851
+ });
852
+ }
853
+ },
854
+ // 根据表达式取值(可筛选选择框)
855
+ parseComboData(model, column) {
856
+ let value = this.parseFilterData(model, column);
857
+
858
+ this.loadComboDataLabel(model, column, value);
859
+
860
+ return value;
861
+ },
862
+ // 根据表达式取值(可筛选多选选择框)
863
+ parseMultiComboData(model, column) {
864
+ let data = [];
865
+ let value = this.parseFilterData(model, column);
866
+
867
+ if (this.isJSON(value)) {
868
+ data = JSON.parse(value);
869
+ }
870
+
871
+ this.loadComboDataLabel(model, column, data);
872
+
873
+ return data;
874
+ },
875
+ // 加载可筛选选择框显示内容
876
+ async loadComboDataLabel(model, column, data) {
877
+ if (column.isStaticItem || (column.dataType && column.dataType.startsWith('Enum:'))) {
878
+ return;
879
+ }
880
+
881
+ if (this.$refs['control_' + column.code]) {
882
+ let values = this.$refs['control_' + column.code][0].$data.values;
883
+
884
+ let pendings = [];
885
+ if (column.controlType == 'MultiComboSelect') {
886
+ data.forEach(value => {
887
+ if (!values.some(v => v.value == value)) {
888
+ // 不在选中项中
889
+ let newValue = { value, label: null, disabled: false };
890
+ values.push(newValue);
891
+ pendings.push(newValue);
892
+ }
893
+ });
894
+ } else {
895
+ if (!values.some(v => v.value == data)) {
896
+ // 不在选中项中
897
+ let newValue = { value: data, label: null, disabled: false };
898
+ values.push(newValue);
899
+ pendings.push(newValue);
900
+ }
901
+ }
902
+
903
+ // 读取显示内容
904
+ if (pendings.length > 0) {
905
+ let param = this.getParam(model, column);
906
+ param[column.sourceDataCode] = pendings.map(item => item.value).join(',');
907
+ let res;
908
+
909
+ if (column.isSourceCustom) {
910
+ res = await customModelApi.query(column.source, param);
911
+ } else {
912
+ res = await modelApi.query(column.source, param);
913
+ }
914
+
915
+ res.data.forEach(item => {
916
+ let v = this.parseData(item, column.sourceDataCode);
917
+ let label = this.parseData(item, column.sourceDisplayCode);
918
+
919
+ if (column.controlType == 'ComboSelect') {
920
+ // 添加筛选内容
921
+ this.$refs['control_' + column.code][0].$data.query = label;
922
+ }
923
+
924
+ let newValue = pendings.find(i => i.value == v);
925
+
926
+ if (newValue) {
927
+ newValue.label = label;
928
+ }
929
+ });
930
+
931
+ this.$forceUpdate();
932
+ }
933
+ }
756
934
  }
757
935
  }
758
936
  };
@@ -250,7 +250,7 @@
250
250
  };
251
251
 
252
252
  // 预先加载枚举值
253
- if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.indexOf('Enum:') === 0) {
253
+ if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.startsWith('Enum:')) {
254
254
  await this.loadEnum(this.setting.chartGroupCodeType.replace('Enum:', ''));
255
255
  }
256
256
 
@@ -279,7 +279,7 @@
279
279
  this.data.map(item => {
280
280
  let value = this.parseData(item, this.setting.chartGroupCode);
281
281
 
282
- if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.indexOf('Enum:') === 0) {
282
+ if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.startsWith('Enum:')) {
283
283
  value = this.getEnum(this.setting.chartGroupCodeType.replace('Enum:', ''), value);
284
284
  }
285
285
 
@@ -297,7 +297,7 @@
297
297
  .filter(data => {
298
298
  let value = this.parseData(data, this.setting.chartGroupCode);
299
299
 
300
- if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.indexOf('Enum:') === 0) {
300
+ if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.startsWith('Enum:')) {
301
301
  value = this.getEnum(this.setting.chartGroupCodeType.replace('Enum:', ''), value);
302
302
  }
303
303
 
@@ -334,7 +334,7 @@
334
334
  this.data.map(item => {
335
335
  let value = this.parseData(item, this.setting.chartGroupCode);
336
336
 
337
- if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.indexOf('Enum:') === 0) {
337
+ if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.startsWith('Enum:')) {
338
338
  value = this.getEnum(this.setting.chartGroupCodeType.replace('Enum:', ''), value);
339
339
  }
340
340
 
@@ -352,7 +352,7 @@
352
352
  .filter(data => {
353
353
  let value = this.parseData(data, this.setting.chartGroupCode);
354
354
 
355
- if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.indexOf('Enum:') === 0) {
355
+ if (this.setting.chartGroupCodeType && this.setting.chartGroupCodeType.startsWith('Enum:')) {
356
356
  value = this.getEnum(this.setting.chartGroupCodeType.replace('Enum:', ''), value);
357
357
  }
358
358