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.
@@ -188,15 +188,36 @@
188
188
  </template> -->
189
189
  <template v-else-if="column.controlType === 'ComboSelect'">
190
190
  <Select
191
- :model-value="parseData(data, column.code)"
191
+ :ref="'control_' + column.code"
192
+ :model-value="parseComboData(data, column)"
192
193
  @update:model-value="$event => setData(data, column.code, $event)"
193
194
  :disabled="column.isReadonly"
194
- clearable
195
+ :clearable="true"
195
196
  filterable
197
+ remote
198
+ :remote-method="search => loadOption(data, column, search)"
196
199
  :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
197
200
  :placeholder="column.description"
198
201
  :transfer="true"
199
- @on-change="onDataChange(column)"
202
+ @on-change="selected => onSelectDataChange(column, selected)"
203
+ >
204
+ <Option v-for="item in getDataSource(data, column)" :key="item.id" :value="item.id">{{ item.name }}</Option>
205
+ </Select>
206
+ </template>
207
+ <template v-else-if="column.controlType === 'MultiComboSelect'">
208
+ <Select
209
+ :ref="'control_' + column.code"
210
+ :model-value="parseMultiComboData(data, column)"
211
+ @update:model-value="$event => setArrayData(data, column.code, $event)"
212
+ :clearable="true"
213
+ :multiple="true"
214
+ filterable
215
+ remote
216
+ :remote-method="search => loadOption(data, column, search)"
217
+ :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
218
+ :placeholder="column.description"
219
+ :transfer="true"
220
+ @on-change="selected => onSelectDataChange(column, selected)"
200
221
  >
201
222
  <Option v-for="item in getDataSource(data, column)" :key="item.id" :value="item.id">{{ item.name }}</Option>
202
223
  </Select>
@@ -486,7 +507,7 @@
486
507
  if (!(column.dataType || '').trim()) {
487
508
  return null;
488
509
  }
489
- if (column.dataType.indexOf('Enum:') === 0) {
510
+ if (column.dataType.startsWith('Enum:')) {
490
511
  return 'string';
491
512
  }
492
513
 
@@ -627,18 +648,31 @@
627
648
  },
628
649
  // 填充数据源
629
650
  async fillDataSource(data, column, param) {
651
+ let value;
652
+ if (column.controlType === 'TreeSelect' || column.controlType === 'MultiTreeSelect') {
653
+ // 树选择框重新加载数据源时,需要先清空数据源,否则无法直接点击清空按钮清除数据。
654
+ value = this.parseTreeData(data, column.code);
655
+ column.dataSource = null;
656
+ }
657
+
658
+ if (column.controlType === 'ComboSelect' || column.controlType === 'MultiComboSelect') {
659
+ param.per = 20;
660
+ }
661
+
630
662
  // 参数完整,查询数据
663
+ this.disableLoader();
631
664
  let res;
632
665
  if (column.isSourceCustom) {
633
666
  res = await customModelApi.query(column.source, param);
634
667
  } else {
635
668
  res = await modelApi.query(column.source, param);
636
669
  }
670
+ this.enableLoader();
637
671
 
638
672
  column.rawData = res.data;
639
673
 
640
674
  if (column.controlType === 'TreeSelect' || column.controlType === 'MultiTreeSelect') {
641
- let data = res.data.map(item => {
675
+ let treeData = res.data.map(item => {
642
676
  return {
643
677
  id: !(column.sourceDataCode || '').trim() ? item.id : this.parseData(item, column.sourceDataCode),
644
678
  name: this.parseData(item, column.sourceDisplayCode),
@@ -646,7 +680,8 @@
646
680
  };
647
681
  });
648
682
 
649
- column.dataSource = this.getTreeDataSource(data, column, null);
683
+ column.dataSource = this.getTreeDataSource(treeData, column, null);
684
+ this.setData(data, column.code, value);
650
685
  } else {
651
686
  column.dataSource = res.data.map(item => {
652
687
  return {
@@ -659,6 +694,14 @@
659
694
  if (data) {
660
695
  if (this.parseData(data, column.code) == null && column.isDefaultFirst && res.data.length > 0) {
661
696
  this.setData(data, column.code, this.parseData(res.data[0], column.sourceDataCode));
697
+ /**
698
+ * 数据变化事件
699
+ * @property {object} sender 触发的列对象
700
+ * @property {object} oldValue 原数据
701
+ * @property {object} newValue 新数据
702
+ * @property {object} selected 选中对象(弹出选择框等有效)
703
+ */
704
+ this.$emit('on-change', column, null, column.rawData[0], null);
662
705
 
663
706
  if (column.sourceDataCode == 'id' && column.code.length > 2) {
664
707
  let code = column.code.substr(0, column.code.length - 2);
@@ -672,10 +715,8 @@
672
715
  }
673
716
  }
674
717
 
675
- //this.$forceUpdate();
676
-
677
718
  // 级联更新时清空数据
678
- if (column.controlType == 'Select' || column.controlType == 'ComboSelect' || column.controlType == 'Radio') {
719
+ if (column.controlType == 'Select' || column.controlType == 'Radio') {
679
720
  if (
680
721
  !column.dataSource.some(item => {
681
722
  return item.id == this.parseData(data, column.code);
@@ -717,38 +758,13 @@
717
758
  },
718
759
  // 获取数据源
719
760
  getDataSource(data, column) {
720
- if (!column.isStaticItem && column.dataType && column.dataType.indexOf('Enum:') === 0) {
761
+ if (!column.isStaticItem && column.dataType && column.dataType.startsWith('Enum:')) {
721
762
  // 枚举
722
763
  return this.getEnumList(column.dataType.split(':')[1]);
723
764
  } else {
724
765
  return column.dataSource == null ? [] : column.dataSource;
725
766
  }
726
767
  },
727
- // // 可筛选下拉框加载数据
728
- // loadOption(data, column, keyword) {
729
- // let param = this.getParam(data, column);
730
-
731
- // if (param != null) {
732
- // if (!(keyword || '').trim() && this.parseData(data, column.code) != null && column.controlType !== 'AutoComplete') {
733
- // param[column.sourceDataCode] = this.parseData(data, column.code);
734
- // } else {
735
- // param.keyword = keyword;
736
- // }
737
- // param.per = 20;
738
-
739
- // this.fillDataSource(data, column, param);
740
- // } else {
741
- // // 参数不完整,清空数据
742
- // column.dataSource = [];
743
- // this.setData(data, column.code, null);
744
- // // column.displayValue = null;
745
-
746
- // // 触发
747
- // column.triggers.forEach(item => {
748
- // item.needRefresh = true;
749
- // });
750
- // }
751
- // },
752
768
  // 数据变化事件
753
769
  async onDataChange(sender) {
754
770
  // 计算需要刷新的字段
@@ -795,6 +811,7 @@
795
811
  column.controlType === 'MultiTreeSelect' ||
796
812
  column.controlType === 'SelectWithOther' ||
797
813
  column.controlType === 'ComboSelect' ||
814
+ column.controlType === 'MultiComboSelect' ||
798
815
  column.controlType === 'Radio' ||
799
816
  column.controlType === 'CheckGroup'
800
817
  // column.controlType === 'AutoComplete'
@@ -1024,6 +1041,111 @@
1024
1041
  col.parentNode.insertBefore(line, col);
1025
1042
  }
1026
1043
  });
1044
+ },
1045
+ // 可筛选下拉框加载数据
1046
+ async loadOption(data, column, keyword) {
1047
+ if (column.isStaticItem || (column.dataType && column.dataType.startsWith('Enum:'))) {
1048
+ return;
1049
+ }
1050
+
1051
+ let param = this.getParam(data, column);
1052
+
1053
+ if (param != null) {
1054
+ param[column.sourceDisplayCode + '_c'] = keyword;
1055
+ this.fillDataSource(data, column, param);
1056
+ } else {
1057
+ // 参数不完整,清空数据
1058
+ column.rawData = [];
1059
+ column.dataSource = [];
1060
+ this.setData(data, column.code, null);
1061
+ // column.displayValue = null;
1062
+
1063
+ // 触发
1064
+ column.triggers.forEach(item => {
1065
+ item.needClear = true;
1066
+ });
1067
+ }
1068
+ },
1069
+ // 根据表达式取值(可筛选选择框)
1070
+ parseComboData(model, column) {
1071
+ let value = this.parseData(model, column.code);
1072
+
1073
+ this.loadComboDataLabel(model, column, value);
1074
+
1075
+ return value;
1076
+ },
1077
+ // 根据表达式取值(可筛选多选选择框)
1078
+ parseMultiComboData(model, column) {
1079
+ let data = [];
1080
+ let value = this.parseData(model, column.code);
1081
+
1082
+ if (this.isJSON(value)) {
1083
+ data = JSON.parse(value);
1084
+ }
1085
+
1086
+ this.loadComboDataLabel(model, column, data);
1087
+
1088
+ return data;
1089
+ },
1090
+ // 加载可筛选选择框显示内容
1091
+ async loadComboDataLabel(model, column, data) {
1092
+ if (column.isStaticItem || (column.dataType && column.dataType.startsWith('Enum:'))) {
1093
+ return;
1094
+ }
1095
+
1096
+ if (this.$refs['control_' + column.code]) {
1097
+ let values = this.$refs['control_' + column.code][0].$data.values;
1098
+
1099
+ let pendings = [];
1100
+ if (column.controlType == 'MultiComboSelect') {
1101
+ data.forEach(value => {
1102
+ if (!values.some(v => v.value == value)) {
1103
+ // 不在选中项中
1104
+ let newValue = { value, label: null, disabled: false };
1105
+ values.push(newValue);
1106
+ pendings.push(newValue);
1107
+ }
1108
+ });
1109
+ } else {
1110
+ if (!values.some(v => v.value == data)) {
1111
+ // 不在选中项中
1112
+ let newValue = { value: data, label: null, disabled: false };
1113
+ values.push(newValue);
1114
+ pendings.push(newValue);
1115
+ }
1116
+ }
1117
+
1118
+ // 读取显示内容
1119
+ if (pendings.length > 0) {
1120
+ let param = this.getParam(model, column);
1121
+ param[column.sourceDataCode] = pendings.map(item => item.value).join(',');
1122
+ let res;
1123
+
1124
+ if (column.isSourceCustom) {
1125
+ res = await customModelApi.query(column.source, param);
1126
+ } else {
1127
+ res = await modelApi.query(column.source, param);
1128
+ }
1129
+
1130
+ res.data.forEach(item => {
1131
+ let v = this.parseData(item, column.sourceDataCode);
1132
+ let label = this.parseData(item, column.sourceDisplayCode);
1133
+
1134
+ if (column.controlType == 'ComboSelect') {
1135
+ // 添加筛选内容
1136
+ this.$refs['control_' + column.code][0].$data.query = label;
1137
+ }
1138
+
1139
+ let newValue = pendings.find(i => i.value == v);
1140
+
1141
+ if (newValue) {
1142
+ newValue.label = label;
1143
+ }
1144
+ });
1145
+
1146
+ this.$forceUpdate();
1147
+ }
1148
+ }
1027
1149
  }
1028
1150
  }
1029
1151
  };
@@ -207,11 +207,33 @@
207
207
  </template> -->
208
208
  <template v-else-if="column.controlType === 'ComboSelect'">
209
209
  <Select
210
- :model-value="parseData(data, column.code)"
210
+ :ref="'control_' + column.code"
211
+ :model-value="parseComboData(data, column)"
211
212
  @update:model-value="$event => setData(data, column.code, $event)"
212
213
  :disabled="readonly || column.isReadonly"
213
214
  :clearable="true"
214
215
  filterable
216
+ remote
217
+ :remote-method="search => loadOption(data, column, search)"
218
+ :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
219
+ :placeholder="column.description"
220
+ :transfer="true"
221
+ @on-change="selected => onSelectDataChange(column, selected)"
222
+ >
223
+ <Option v-for="item in getDataSource(data, column)" :key="item.id" :value="item.id">{{ item.name }}</Option>
224
+ </Select>
225
+ </template>
226
+ <template v-else-if="column.controlType === 'MultiComboSelect'">
227
+ <Select
228
+ :ref="'control_' + column.code"
229
+ :model-value="parseMultiComboData(data, column)"
230
+ @update:model-value="$event => setArrayData(data, column.code, $event)"
231
+ :disabled="readonly || column.isReadonly"
232
+ :clearable="true"
233
+ :multiple="true"
234
+ filterable
235
+ remote
236
+ :remote-method="search => loadOption(data, column, search)"
215
237
  :style="{ width: column.controlWidth == null ? null : column.controlWidth + 'px' }"
216
238
  :placeholder="column.description"
217
239
  :transfer="true"
@@ -464,7 +486,7 @@
464
486
  <script>
465
487
  import mixinPage from '../../mixins/page';
466
488
  import mixin from './mixin';
467
- import { mapActions } from 'vuex';
489
+ import { mapActions, mapMutations } from 'vuex';
468
490
  import modelApi from '../../api/model';
469
491
  import customModelApi from '../../api/customModel';
470
492
  import richEditor from '../richEditor/index.vue';
@@ -1054,13 +1076,19 @@
1054
1076
  column.dataSource = null;
1055
1077
  }
1056
1078
 
1079
+ if (column.controlType === 'ComboSelect' || column.controlType === 'MultiComboSelect') {
1080
+ param.per = 20;
1081
+ }
1082
+
1057
1083
  // 参数完整,查询数据
1084
+ this.disableLoader();
1058
1085
  let res;
1059
1086
  if (column.isSourceCustom) {
1060
1087
  res = await customModelApi.query(column.source, param);
1061
1088
  } else {
1062
1089
  res = await modelApi.query(column.source, param);
1063
1090
  }
1091
+ this.enableLoader();
1064
1092
 
1065
1093
  column.rawData = res.data;
1066
1094
 
@@ -1087,7 +1115,14 @@
1087
1115
  if (data) {
1088
1116
  if (this.parseData(data, column.code) == null && column.isDefaultFirst && res.data.length > 0) {
1089
1117
  this.setData(data, column.code, this.parseData(res.data[0], column.sourceDataCode));
1090
- this.$emit('on-change', column, null, value, null);
1118
+ /**
1119
+ * 数据变化事件
1120
+ * @property {object} sender 触发的列对象
1121
+ * @property {object} oldValue 原数据
1122
+ * @property {object} newValue 新数据
1123
+ * @property {object} selected 选中对象(弹出选择框等有效)
1124
+ */
1125
+ this.$emit('on-change', column, null, column.rawData[0], null);
1091
1126
 
1092
1127
  if (column.sourceDataCode == 'id' && column.code.length > 2) {
1093
1128
  let code = column.code.substr(0, column.code.length - 2);
@@ -1101,10 +1136,8 @@
1101
1136
  }
1102
1137
  }
1103
1138
 
1104
- //this.$forceUpdate();
1105
-
1106
1139
  // 级联更新时清空数据
1107
- if (column.controlType == 'Select' || column.controlType == 'ComboSelect' || column.controlType == 'Radio') {
1140
+ if (column.controlType == 'Select' || column.controlType == 'Radio') {
1108
1141
  if (
1109
1142
  !column.dataSource.some(item => {
1110
1143
  return item.id == this.parseData(data, column.code);
@@ -1146,38 +1179,13 @@
1146
1179
  },
1147
1180
  // 获取数据源
1148
1181
  getDataSource(data, column) {
1149
- if (!column.isStaticItem && column.dataType.indexOf('Enum:') === 0) {
1182
+ if (!column.isStaticItem && column.dataType.startsWith('Enum:')) {
1150
1183
  // 枚举
1151
1184
  return this.getEnumList(column.dataType.split(':')[1]);
1152
1185
  } else {
1153
1186
  return column.dataSource == null ? [] : column.dataSource;
1154
1187
  }
1155
1188
  },
1156
- // // 可筛选下拉框加载数据
1157
- // loadOption(data, column, keyword) {
1158
- // let param = this.getParam(data, column);
1159
-
1160
- // if (param != null) {
1161
- // if (!(keyword || '').trim() && this.parseData(data, column.code) != null && column.controlType !== 'AutoComplete') {
1162
- // param[column.sourceDataCode] = this.parseData(data, column.code);
1163
- // } else {
1164
- // param.keyword = keyword;
1165
- // }
1166
- // param.per = 20;
1167
-
1168
- // this.fillDataSource(data, column, param);
1169
- // } else {
1170
- // // 参数不完整,清空数据
1171
- // column.dataSource = [];
1172
- // this.setData(data, column.code, null);
1173
- // // column.displayValue = null;
1174
-
1175
- // // 触发
1176
- // column.triggers.forEach(item => {
1177
- // item.needClear = true;
1178
- // });
1179
- // }
1180
- // },
1181
1189
  // 选项变化事件
1182
1190
  onSelectDataChange(sender, selected) {
1183
1191
  let code;
@@ -1283,7 +1291,6 @@
1283
1291
  * @property {object} oldValue 原数据
1284
1292
  * @property {object} newValue 新数据
1285
1293
  * @property {object} selected 选中对象(弹出选择框等有效)
1286
- * @property {boolean} loading 加载数据时触发
1287
1294
  */
1288
1295
  this.$emit('on-change', sender, null, null, this.$refs['table_' + sender.code][0].data);
1289
1296
  } else if (sender != null) {
@@ -1376,6 +1383,7 @@
1376
1383
  column.controlType === 'MultiTreeSelect' ||
1377
1384
  column.controlType === 'SelectWithOther' ||
1378
1385
  column.controlType === 'ComboSelect' ||
1386
+ column.controlType === 'MultiComboSelect' ||
1379
1387
  column.controlType === 'Radio' ||
1380
1388
  column.controlType === 'CheckGroup'
1381
1389
  // column.controlType === 'AutoComplete'
@@ -1459,7 +1467,7 @@
1459
1467
  if (!(column.dataType || '').trim()) {
1460
1468
  return null;
1461
1469
  }
1462
- if (column.dataType.indexOf('Enum:') === 0) {
1470
+ if (column.dataType.startsWith('Enum:')) {
1463
1471
  return 'string';
1464
1472
  }
1465
1473
 
@@ -1591,6 +1599,111 @@
1591
1599
  } else {
1592
1600
  return column.name;
1593
1601
  }
1602
+ },
1603
+ // 可筛选下拉框加载数据
1604
+ async loadOption(data, column, keyword) {
1605
+ if (column.isStaticItem || (column.dataType && column.dataType.startsWith('Enum:'))) {
1606
+ return;
1607
+ }
1608
+
1609
+ let param = this.getParam(data, column);
1610
+
1611
+ if (param != null) {
1612
+ param[column.sourceDisplayCode + '_c'] = keyword;
1613
+ this.fillDataSource(data, column, param);
1614
+ } else {
1615
+ // 参数不完整,清空数据
1616
+ column.rawData = [];
1617
+ column.dataSource = [];
1618
+ this.setData(data, column.code, null);
1619
+ // column.displayValue = null;
1620
+
1621
+ // 触发
1622
+ column.triggers.forEach(item => {
1623
+ item.needClear = true;
1624
+ });
1625
+ }
1626
+ },
1627
+ // 根据表达式取值(可筛选选择框)
1628
+ parseComboData(model, column) {
1629
+ let value = this.parseData(model, column.code);
1630
+
1631
+ this.loadComboDataLabel(model, column, value);
1632
+
1633
+ return value;
1634
+ },
1635
+ // 根据表达式取值(可筛选多选选择框)
1636
+ parseMultiComboData(model, column) {
1637
+ let data = [];
1638
+ let value = this.parseData(model, column.code);
1639
+
1640
+ if (this.isJSON(value)) {
1641
+ data = JSON.parse(value);
1642
+ }
1643
+
1644
+ this.loadComboDataLabel(model, column, data);
1645
+
1646
+ return data;
1647
+ },
1648
+ // 加载可筛选选择框显示内容
1649
+ async loadComboDataLabel(model, column, data) {
1650
+ if (column.isStaticItem || (column.dataType && column.dataType.startsWith('Enum:'))) {
1651
+ return;
1652
+ }
1653
+
1654
+ if (this.$refs['control_' + column.code]) {
1655
+ let values = this.$refs['control_' + column.code][0].$data.values;
1656
+
1657
+ let pendings = [];
1658
+ if (column.controlType == 'MultiComboSelect') {
1659
+ data.forEach(value => {
1660
+ if (!values.some(v => v.value == value)) {
1661
+ // 不在选中项中
1662
+ let newValue = { value, label: null, disabled: false };
1663
+ values.push(newValue);
1664
+ pendings.push(newValue);
1665
+ }
1666
+ });
1667
+ } else {
1668
+ if (!values.some(v => v.value == data)) {
1669
+ // 不在选中项中
1670
+ let newValue = { value: data, label: null, disabled: false };
1671
+ values.push(newValue);
1672
+ pendings.push(newValue);
1673
+ }
1674
+ }
1675
+
1676
+ // 读取显示内容
1677
+ if (pendings.length > 0) {
1678
+ let param = this.getParam(model, column);
1679
+ param[column.sourceDataCode] = pendings.map(item => item.value).join(',');
1680
+ let res;
1681
+
1682
+ if (column.isSourceCustom) {
1683
+ res = await customModelApi.query(column.source, param);
1684
+ } else {
1685
+ res = await modelApi.query(column.source, param);
1686
+ }
1687
+
1688
+ res.data.forEach(item => {
1689
+ let v = this.parseData(item, column.sourceDataCode);
1690
+ let label = this.parseData(item, column.sourceDisplayCode);
1691
+
1692
+ if (column.controlType == 'ComboSelect') {
1693
+ // 添加筛选内容
1694
+ this.$refs['control_' + column.code][0].$data.query = label;
1695
+ }
1696
+
1697
+ let newValue = pendings.find(i => i.value == v);
1698
+
1699
+ if (newValue) {
1700
+ newValue.label = label;
1701
+ }
1702
+ });
1703
+
1704
+ this.$forceUpdate();
1705
+ }
1706
+ }
1594
1707
  }
1595
1708
  }
1596
1709
  };