@weitutech/by-components 1.2.31 → 1.2.33

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.
@@ -78979,8 +78979,8 @@ var pair_number_input_component = normalizeComponent(
78979
78979
  )
78980
78980
 
78981
78981
  /* harmony default export */ var pair_number_input = (pair_number_input_component.exports);
78982
- ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/form/comps/custom-date-picker.vue?vue&type=template&id=78d80522
78983
- var custom_date_pickervue_type_template_id_78d80522_render = function render() {
78982
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/form/comps/custom-date-picker.vue?vue&type=template&id=9d8d406a
78983
+ var custom_date_pickervue_type_template_id_9d8d406a_render = function render() {
78984
78984
  var _vm = this,
78985
78985
  _c = _vm._self._c;
78986
78986
  return _c('div', {
@@ -79050,7 +79050,7 @@ var custom_date_pickervue_type_template_id_78d80522_render = function render() {
79050
79050
  }, [_vm._v(" " + _vm._s(char) + " ")]);
79051
79051
  }) : [_vm._v(_vm._s(_vm.activeShortcutLabel))]], 2) : _vm._e()], 1)], 2);
79052
79052
  };
79053
- var custom_date_pickervue_type_template_id_78d80522_staticRenderFns = [];
79053
+ var custom_date_pickervue_type_template_id_9d8d406a_staticRenderFns = [];
79054
79054
 
79055
79055
  // EXTERNAL MODULE: ./node_modules/moment/moment.js
79056
79056
  var moment = __webpack_require__(9618);
@@ -79061,6 +79061,17 @@ var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
79061
79061
 
79062
79062
 
79063
79063
 
79064
+ const DEFAULT_FORMAT_BY_TYPE = {
79065
+ daterange: 'YYYY-MM-DD',
79066
+ datetimerange: 'YYYY-MM-DD HH:mm:ss',
79067
+ monthrange: 'YYYY-MM',
79068
+ date: 'YYYY-MM-DD',
79069
+ datetime: 'YYYY-MM-DD HH:mm:ss',
79070
+ month: 'YYYY-MM',
79071
+ year: 'YYYY',
79072
+ week: 'YYYY-MM-DD'
79073
+ };
79074
+ const FORM_FIELD_TYPE = 'customDatePicker';
79064
79075
  /* harmony default export */ var custom_date_pickervue_type_script_lang_js = ({
79065
79076
  name: 'ByCustomDatePicker',
79066
79077
  props: {
@@ -79088,6 +79099,23 @@ var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
79088
79099
  type: String,
79089
79100
  default: ''
79090
79101
  },
79102
+ /**
79103
+ * 日期选择器类型(透传 el-date-picker 的 type)
79104
+ * 默认 daterange;常见:daterange / datetimerange / monthrange
79105
+ * 注意:Form 配置里字段 type 固定为 customDatePicker,请用本属性或 otherOption.type 指定面板类型
79106
+ */
79107
+ pickerType: {
79108
+ type: String,
79109
+ default: ''
79110
+ },
79111
+ /**
79112
+ * 绑定值格式(moment 格式,也兼容 Element 的 yyyy/dd 写法)
79113
+ * 不传时按 pickerType 自动推断,如 daterange → YYYY-MM-DD
79114
+ */
79115
+ valueFormat: {
79116
+ type: String,
79117
+ default: ''
79118
+ },
79091
79119
  /**
79092
79120
  * 快捷按钮展示方式
79093
79121
  * external: 快捷按钮在输入框右侧(默认,保持原有样式)
@@ -79108,43 +79136,81 @@ var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
79108
79136
  };
79109
79137
  },
79110
79138
  computed: {
79139
+ /** 实际生效的面板类型 */
79140
+ resolvedPickerType() {
79141
+ const fromProp = this.normalizePickerType(this.pickerType);
79142
+ if (fromProp) return fromProp;
79143
+ const fromOther = this.normalizePickerType(this.otherOption && this.otherOption.type);
79144
+ if (fromOther) return fromOther;
79145
+ return 'daterange';
79146
+ },
79147
+ /** 实际生效的输出格式(moment) */
79148
+ resolvedValueFormat() {
79149
+ const raw = this.valueFormat || this.otherOption && this.otherOption.valueFormat || DEFAULT_FORMAT_BY_TYPE[this.resolvedPickerType] || 'YYYY-MM-DD';
79150
+ return this.toMomentDateFormat(raw);
79151
+ },
79152
+ /** 是否包含时分秒(用于快捷项起止时刻) */
79153
+ includesTime() {
79154
+ return /H{1,2}|m{1,2}|s{1,2}/.test(this.resolvedValueFormat);
79155
+ },
79111
79156
  shortcuts() {
79157
+ const fmt = this.resolvedValueFormat;
79158
+ const rangeOfDay = dayMoment => ({
79159
+ start_time: dayMoment.clone().startOf('day').format(fmt),
79160
+ end_time: this.includesTime ? dayMoment.clone().endOf('day').format(fmt) : dayMoment.clone().startOf('day').format(fmt)
79161
+ });
79162
+ const yesterday = rangeOfDay(moment_default()().subtract(1, 'days'));
79163
+ const today = rangeOfDay(moment_default()());
79112
79164
  return [{
79113
79165
  label: '上月',
79114
- start_time: moment_default()().subtract(1, 'months').startOf('month').format('YYYY-MM-DD'),
79115
- end_time: moment_default()().subtract(1, 'months').endOf('month').format('YYYY-MM-DD'),
79166
+ start_time: moment_default()().subtract(1, 'months').startOf('month').format(fmt),
79167
+ end_time: moment_default()().subtract(1, 'months').endOf('month').format(fmt),
79116
79168
  key: 'last_month'
79117
79169
  }, {
79118
79170
  label: '昨天',
79119
- start_time: moment_default()().subtract(1, 'days').format('YYYY-MM-DD'),
79120
- end_time: moment_default()().subtract(1, 'days').format('YYYY-MM-DD'),
79171
+ start_time: yesterday.start_time,
79172
+ end_time: yesterday.end_time,
79121
79173
  key: 'yesterday'
79122
79174
  }, {
79123
79175
  label: '今天',
79124
- start_time: moment_default()().startOf('day').format('YYYY-MM-DD'),
79125
- end_time: moment_default()().startOf('day').format('YYYY-MM-DD'),
79176
+ start_time: today.start_time,
79177
+ end_time: today.end_time,
79126
79178
  key: 'today'
79127
79179
  }, {
79128
79180
  label: '本周',
79129
- start_time: moment_default()().startOf('isoWeek').format('YYYY-MM-DD'),
79130
- end_time: moment_default()().endOf('isoWeek').format('YYYY-MM-DD'),
79181
+ start_time: moment_default()().startOf('isoWeek').format(fmt),
79182
+ end_time: moment_default()().endOf('isoWeek').format(fmt),
79131
79183
  key: 'week'
79132
79184
  }, {
79133
79185
  label: '本月',
79134
- start_time: moment_default()().startOf('month').format('YYYY-MM-DD'),
79135
- end_time: moment_default()().endOf('month').format('YYYY-MM-DD'),
79186
+ start_time: moment_default()().startOf('month').format(fmt),
79187
+ end_time: moment_default()().endOf('month').format(fmt),
79136
79188
  key: 'month'
79137
79189
  }];
79138
79190
  },
79139
79191
  dateOptions() {
79192
+ const {
79193
+ type: _type,
79194
+ valueFormat: _valueFormat,
79195
+ format: userFormat,
79196
+ ...restOther
79197
+ } = this.otherOption || {};
79198
+ const pickerType = this.resolvedPickerType;
79199
+ const elementFormat = this.toElementDateFormat(this.resolvedValueFormat);
79200
+ const needDefaultTime = pickerType === 'datetimerange' || pickerType === 'datetime';
79140
79201
  return {
79141
79202
  startPlaceholder: '开始时间',
79142
79203
  endPlaceholder: '结束时间',
79143
- type: 'daterange',
79144
79204
  rangeSeparator: '至',
79145
79205
  size: 'mini',
79146
79206
  active: '',
79147
- ...this.otherOption
79207
+ format: userFormat || elementFormat,
79208
+ ...(needDefaultTime ? {
79209
+ defaultTime: ['00:00:00', '23:59:59']
79210
+ } : {}),
79211
+ ...restOther,
79212
+ // 最终以解析后的 pickerType 为准,避免 Form 的 type=customDatePicker 或旧配置干扰
79213
+ type: pickerType
79148
79214
  };
79149
79215
  },
79150
79216
  panelDateOptions() {
@@ -79209,10 +79275,25 @@ var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
79209
79275
  this.destroyShortcutTagObserver();
79210
79276
  },
79211
79277
  methods: {
79278
+ normalizePickerType(type) {
79279
+ if (!type || type === FORM_FIELD_TYPE) return '';
79280
+ return type;
79281
+ },
79282
+ /** Element 格式(yyyy/dd) → moment 格式(YYYY/DD) */
79283
+ toMomentDateFormat(fmt) {
79284
+ return String(fmt).replace(/yyyy/g, 'YYYY').replace(/dd/g, 'DD');
79285
+ },
79286
+ /** moment 格式 → Element 展示格式 */
79287
+ toElementDateFormat(fmt) {
79288
+ return String(fmt).replace(/YYYY/g, 'yyyy').replace(/DD/g, 'dd');
79289
+ },
79290
+ formatMomentValue(val) {
79291
+ return moment_default()(val).format(this.resolvedValueFormat);
79292
+ },
79212
79293
  syncActiveFromValue(newValue) {
79213
79294
  if (Array.isArray(newValue) && newValue.length) {
79214
- const start = moment_default()(newValue[0]).format('YYYY-MM-DD');
79215
- const end = moment_default()(newValue[1]).format('YYYY-MM-DD');
79295
+ const start = this.formatMomentValue(newValue[0]);
79296
+ const end = this.formatMomentValue(newValue[1]);
79216
79297
  let matchedKey = '';
79217
79298
  this.shortcuts.forEach(item => {
79218
79299
  if (item.start_time === start && item.end_time === end) {
@@ -79239,12 +79320,13 @@ var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
79239
79320
  });
79240
79321
  }
79241
79322
  } else {
79242
- const formattedDates = e.map(item => moment_default()(item).format('YYYY-MM-DD'));
79323
+ const list = Array.isArray(e) ? e : [e];
79324
+ const formattedDates = list.map(item => this.formatMomentValue(item));
79243
79325
  this.$emit('input', formattedDates);
79244
79326
  if (this.startTimeField && this.endTimeField) {
79245
79327
  this.$emit('range-change', {
79246
- startTime: formattedDates[0],
79247
- endTime: formattedDates[1]
79328
+ startTime: formattedDates[0] || '',
79329
+ endTime: formattedDates[1] || ''
79248
79330
  });
79249
79331
  }
79250
79332
 
@@ -79354,8 +79436,8 @@ var moment_default = /*#__PURE__*/__webpack_require__.n(moment);
79354
79436
  ;
79355
79437
  var custom_date_picker_component = normalizeComponent(
79356
79438
  comps_custom_date_pickervue_type_script_lang_js,
79357
- custom_date_pickervue_type_template_id_78d80522_render,
79358
- custom_date_pickervue_type_template_id_78d80522_staticRenderFns,
79439
+ custom_date_pickervue_type_template_id_9d8d406a_render,
79440
+ custom_date_pickervue_type_template_id_9d8d406a_staticRenderFns,
79359
79441
  false,
79360
79442
  null,
79361
79443
  null,
@@ -94696,8 +94778,8 @@ ByDialogService.install = function (Vue) {
94696
94778
  Vue.prototype.$byDialog = ByDialogService;
94697
94779
  };
94698
94780
  /* harmony default export */ var by_dialog_ByDialogService = (ByDialogService);
94699
- ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel/ByCascaderPanel.vue?vue&type=template&id=727f392c
94700
- var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94781
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel/ByCascaderPanel.vue?vue&type=template&id=3691e51e
94782
+ var ByCascaderPanelvue_type_template_id_3691e51e_render = function render() {
94701
94783
  var _vm = this,
94702
94784
  _c = _vm._self._c;
94703
94785
  return _c('div', {
@@ -94716,7 +94798,10 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94716
94798
  }, [_vm._v("可选(" + _vm._s(_vm.selectedCount) + "/" + _vm._s(_vm.totalCount) + ")")]) : _vm._e(), _c('div', {
94717
94799
  staticClass: "search-section"
94718
94800
  }, [_c('div', {
94719
- staticClass: "search-container"
94801
+ staticClass: "search-container",
94802
+ class: {
94803
+ 'has-dropdown-filter': _vm.showDropdownFilter
94804
+ }
94720
94805
  }, [_c('div', {
94721
94806
  staticClass: "search-input-wrap",
94722
94807
  class: {
@@ -94815,7 +94900,37 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94815
94900
  slot: "reference"
94816
94901
  }, [_c('i', {
94817
94902
  staticClass: "el-icon-edit-outline"
94818
- })])], 1)], 1) : _vm._e()], 1), _vm.showRefreshBtn ? _c('el-tooltip', {
94903
+ })])], 1)], 1) : _vm._e()], 1), _vm.showDropdownFilter ? _c('div', {
94904
+ staticClass: "dropdown-filter-group"
94905
+ }, [_vm.dropdownFilterTitle ? _c('span', {
94906
+ staticClass: "dropdown-filter-title"
94907
+ }, [_vm._v(_vm._s(_vm.dropdownFilterTitle) + ":")]) : _vm._e(), _c('el-select', {
94908
+ staticClass: "dropdown-filter-select",
94909
+ attrs: {
94910
+ "placeholder": _vm.dropdownFilterPlaceholder,
94911
+ "clearable": "",
94912
+ "size": "mini",
94913
+ "disabled": _vm.panelViewMode
94914
+ },
94915
+ on: {
94916
+ "change": _vm.handleDropdownFilterChange
94917
+ },
94918
+ model: {
94919
+ value: _vm.dropdownFilterValue,
94920
+ callback: function ($$v) {
94921
+ _vm.dropdownFilterValue = $$v;
94922
+ },
94923
+ expression: "dropdownFilterValue"
94924
+ }
94925
+ }, _vm._l(_vm.normalizedDropdownFilterOptions, function (opt) {
94926
+ return _c('el-option', {
94927
+ key: 'df-' + opt.value,
94928
+ attrs: {
94929
+ "label": opt.label,
94930
+ "value": opt.value
94931
+ }
94932
+ });
94933
+ }), 1)], 1) : _vm._e(), _vm.showRefreshBtn ? _c('el-tooltip', {
94819
94934
  attrs: {
94820
94935
  "content": _vm.refreshTooltip,
94821
94936
  "placement": "top",
@@ -94857,8 +94972,8 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94857
94972
  directives: [{
94858
94973
  name: "show",
94859
94974
  rawName: "v-show",
94860
- value: _vm.searchInput === '' || !_vm.isShowSearch,
94861
- expression: "searchInput === '' || !isShowSearch"
94975
+ value: !_vm.isFilterView,
94976
+ expression: "!isFilterView"
94862
94977
  }],
94863
94978
  ref: "cascaderPanel",
94864
94979
  staticClass: "cascader-panel-inner",
@@ -94874,6 +94989,17 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94874
94989
  "expand-change": _vm.handleExpandChange,
94875
94990
  "change": _vm.handleValueChange
94876
94991
  },
94992
+ scopedSlots: _vm._u([{
94993
+ key: "default",
94994
+ fn: function ({
94995
+ node,
94996
+ data
94997
+ }) {
94998
+ return [_vm._v(" " + _vm._s(node.label)), _vm.showDropdownFilter && _vm.getNodeFilterFieldText(data) ? _c('span', {
94999
+ staticClass: "node-filter-field"
95000
+ }, [_vm._v(_vm._s(_vm.getNodeFilterFieldText(data)))]) : _vm._e()];
95001
+ }
95002
+ }], null, false, 181072543),
94877
95003
  model: {
94878
95004
  value: _vm.mainPanelValue,
94879
95005
  callback: function ($$v) {
@@ -94881,12 +95007,12 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94881
95007
  },
94882
95008
  expression: "mainPanelValue"
94883
95009
  }
94884
- }) : _vm._e(), _vm.searchOptions.length > 0 ? _c('el-cascader-panel', {
95010
+ }) : _vm._e(), _vm.viewOptions.length > 0 ? _c('el-cascader-panel', {
94885
95011
  directives: [{
94886
95012
  name: "show",
94887
95013
  rawName: "v-show",
94888
- value: _vm.searchInput !== '' && _vm.isShowSearch,
94889
- expression: "searchInput !== '' && isShowSearch"
95014
+ value: _vm.isFilterView,
95015
+ expression: "isFilterView"
94890
95016
  }],
94891
95017
  ref: "searchCascaderPanel",
94892
95018
  staticClass: "cascader-panel-inner",
@@ -94895,13 +95021,24 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94895
95021
  },
94896
95022
  attrs: {
94897
95023
  "append-to-body": false,
94898
- "options": _vm.searchOptions,
95024
+ "options": _vm.viewOptions,
94899
95025
  "props": _vm.cascaderProps
94900
95026
  },
94901
95027
  on: {
94902
95028
  "expand-change": _vm.handleExpandChange,
94903
95029
  "change": _vm.handleSearchValueChange
94904
95030
  },
95031
+ scopedSlots: _vm._u([{
95032
+ key: "default",
95033
+ fn: function ({
95034
+ node,
95035
+ data
95036
+ }) {
95037
+ return [_vm._v(" " + _vm._s(node.label)), _vm.showDropdownFilter && _vm.getNodeFilterFieldText(data) ? _c('span', {
95038
+ staticClass: "node-filter-field"
95039
+ }, [_vm._v(_vm._s(_vm.getNodeFilterFieldText(data)))]) : _vm._e()];
95040
+ }
95041
+ }], null, false, 181072543),
94905
95042
  model: {
94906
95043
  value: _vm.searchPanelValue,
94907
95044
  callback: function ($$v) {
@@ -94909,13 +95046,7 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94909
95046
  },
94910
95047
  expression: "searchPanelValue"
94911
95048
  }
94912
- }) : _vm._e(), _vm.isShowSearch && _vm.searchOptions.length === 0 ? _c('div', {
94913
- directives: [{
94914
- name: "show",
94915
- rawName: "v-show",
94916
- value: _vm.searchInput !== '',
94917
- expression: "searchInput !== ''"
94918
- }],
95049
+ }) : _vm._e(), _vm.isFilterView && _vm.viewOptions.length === 0 ? _c('div', {
94919
95050
  staticClass: "empty-search"
94920
95051
  }, [_c('el-empty', {
94921
95052
  attrs: {
@@ -94997,7 +95128,7 @@ var ByCascaderPanelvue_type_template_id_727f392c_render = function render() {
94997
95128
  staticClass: "empty-state"
94998
95129
  }, [_vm._v("暂无选中项")]) : _vm._e()], 2)])])])]);
94999
95130
  };
95000
- var ByCascaderPanelvue_type_template_id_727f392c_staticRenderFns = [];
95131
+ var ByCascaderPanelvue_type_template_id_3691e51e_staticRenderFns = [];
95001
95132
 
95002
95133
  ;// ./src/utils/cascaderUtils.js
95003
95134
 
@@ -95169,6 +95300,58 @@ class CascaderUtils {
95169
95300
  return result;
95170
95301
  }
95171
95302
 
95303
+ /**
95304
+ * 判断节点指定字段是否匹配下拉筛选值
95305
+ * @param {Object} node
95306
+ * @param {String} field
95307
+ * @param {*} filterValue
95308
+ * @returns {Boolean}
95309
+ */
95310
+ static isFilterFieldMatched(node, field, filterValue) {
95311
+ if (!node || !field || filterValue === null || filterValue === undefined || filterValue === '') {
95312
+ return false;
95313
+ }
95314
+ const raw = node[field];
95315
+ if (raw === null || raw === undefined || raw === '') {
95316
+ return false;
95317
+ }
95318
+ return String(raw).trim() === String(filterValue).trim();
95319
+ }
95320
+
95321
+ /**
95322
+ * 按数据字段过滤树:保留字段匹配的节点及其祖先路径
95323
+ * @param {Array} tree - 树形数据
95324
+ * @param {String} field - 数据中用于筛选的字段名
95325
+ * @param {*} filterValue - 下拉选中值
95326
+ * @param {Object} cascaderProps - 级联配置
95327
+ * @returns {Array} 过滤后的树
95328
+ */
95329
+ static filterTreeByField(tree, field, filterValue, cascaderProps) {
95330
+ if (!Array.isArray(tree) || !field || filterValue === null || filterValue === undefined || filterValue === '') {
95331
+ return tree || [];
95332
+ }
95333
+ const childrenKey = cascaderProps && cascaderProps.children || 'children';
95334
+ const result = [];
95335
+ tree.forEach(node => {
95336
+ const children = node[childrenKey];
95337
+ const hasChildren = Array.isArray(children) && children.length > 0;
95338
+ if (hasChildren) {
95339
+ const matchedChildren = this.filterTreeByField(children, field, filterValue, cascaderProps);
95340
+ if (matchedChildren.length > 0) {
95341
+ result.push({
95342
+ ...node,
95343
+ [childrenKey]: matchedChildren
95344
+ });
95345
+ }
95346
+ } else if (this.isFilterFieldMatched(node, field, filterValue)) {
95347
+ result.push({
95348
+ ...node
95349
+ });
95350
+ }
95351
+ });
95352
+ return result;
95353
+ }
95354
+
95172
95355
  /**
95173
95356
  * 获取叶子节点的值
95174
95357
  * @param {Array} tree - 树形数据
@@ -95620,6 +95803,13 @@ class CascaderUtils {
95620
95803
 
95621
95804
 
95622
95805
 
95806
+
95807
+
95808
+
95809
+
95810
+
95811
+
95812
+
95623
95813
  /* harmony default export */ var ByCascaderPanelvue_type_script_lang_js = ({
95624
95814
  name: 'ByCascaderPanel',
95625
95815
  props: {
@@ -95734,6 +95924,15 @@ class CascaderUtils {
95734
95924
  refreshing: {
95735
95925
  type: Boolean,
95736
95926
  default: false
95927
+ },
95928
+ /**
95929
+ * 下拉筛选配置。外部传入且 enabled 不为 false、并指定 field 时才展示下拉框。
95930
+ * { enabled, title, placeholder, options: [{ label, value }], field }
95931
+ * field 为数据中用于过滤和展示的字段名。
95932
+ */
95933
+ dropdownFilter: {
95934
+ type: Object,
95935
+ default: null
95737
95936
  }
95738
95937
  },
95739
95938
  data() {
@@ -95753,7 +95952,9 @@ class CascaderUtils {
95753
95952
  // 防止循环更新的标志
95754
95953
  batchSearchVisible: false,
95755
95954
  // 批量搜索弹窗显示状态
95756
- batchSearchContent: '' // 批量搜索输入内容
95955
+ batchSearchContent: '',
95956
+ // 批量搜索输入内容
95957
+ dropdownFilterValue: '' // 下拉筛选当前值,未开启时不使用
95757
95958
  };
95758
95959
  },
95759
95960
  computed: {
@@ -95826,6 +96027,61 @@ class CascaderUtils {
95826
96027
  this.searchSelectedValues = value ? [value] : [];
95827
96028
  }
95828
96029
  }
96030
+ },
96031
+ // 是否展示下拉筛选(外部有配置且指定了数据字段才展示)
96032
+ showDropdownFilter() {
96033
+ const cfg = this.dropdownFilter;
96034
+ return !!(cfg && typeof cfg === 'object' && cfg.enabled !== false && cfg.field);
96035
+ },
96036
+ dropdownFilterPlaceholder() {
96037
+ return this.dropdownFilter && this.dropdownFilter.placeholder || '请选择';
96038
+ },
96039
+ dropdownFilterTitle() {
96040
+ const title = this.dropdownFilter && this.dropdownFilter.title;
96041
+ return title != null && String(title).trim() !== '' ? String(title).trim() : '';
96042
+ },
96043
+ dropdownFilterField() {
96044
+ return this.dropdownFilter && this.dropdownFilter.field || '';
96045
+ },
96046
+ normalizedDropdownFilterOptions() {
96047
+ const opts = this.dropdownFilter && this.dropdownFilter.options || [];
96048
+ return opts.map(opt => {
96049
+ if (opt != null && typeof opt === 'object') {
96050
+ return {
96051
+ label: opt.label != null ? opt.label : opt.value,
96052
+ value: opt.value != null ? opt.value : opt.label
96053
+ };
96054
+ }
96055
+ return {
96056
+ label: String(opt),
96057
+ value: opt
96058
+ };
96059
+ });
96060
+ },
96061
+ hasActiveDropdownFilter() {
96062
+ return this.showDropdownFilter && this.dropdownFilterValue !== '' && this.dropdownFilterValue !== null && this.dropdownFilterValue !== undefined;
96063
+ },
96064
+ // 下拉筛选后的展示树;未筛选时等于完整 processed 树,保证原有逻辑不变
96065
+ displayOptions() {
96066
+ if (!this.hasActiveDropdownFilter) {
96067
+ return this.filteredOptions;
96068
+ }
96069
+ return CascaderUtils.filterTreeByField(this.filteredOptions, this.dropdownFilterField, this.dropdownFilterValue, this.cascaderProps);
96070
+ },
96071
+ isFilterView() {
96072
+ if (this.searchInput !== '' && this.isShowSearch) {
96073
+ return true;
96074
+ }
96075
+ return this.hasActiveDropdownFilter;
96076
+ },
96077
+ viewOptions() {
96078
+ if (this.searchInput !== '' && this.isShowSearch) {
96079
+ return this.searchOptions;
96080
+ }
96081
+ if (this.hasActiveDropdownFilter) {
96082
+ return this.displayOptions;
96083
+ }
96084
+ return [];
95829
96085
  }
95830
96086
  },
95831
96087
  watch: {
@@ -95865,6 +96121,9 @@ class CascaderUtils {
95865
96121
  // 普通模式下的全选判断
95866
96122
  this.isAllSelected = this.selectedCount === this.totalCount;
95867
96123
  }
96124
+ if (this.hasActiveDropdownFilter) {
96125
+ this.updateFilterAllSelectedState();
96126
+ }
95868
96127
  } else {
95869
96128
  // 单选模式:最多只能有一个选中项
95870
96129
  if (newVal.length > 1) {
@@ -95881,6 +96140,11 @@ class CascaderUtils {
95881
96140
  if (val) {
95882
96141
  this.batchSearchVisible = false;
95883
96142
  }
96143
+ },
96144
+ showDropdownFilter(val) {
96145
+ if (!val) {
96146
+ this.dropdownFilterValue = '';
96147
+ }
95884
96148
  }
95885
96149
  },
95886
96150
  mounted() {
@@ -95952,6 +96216,11 @@ class CascaderUtils {
95952
96216
  this.filteredOptions = this.processOptions(this.options);
95953
96217
  this.countTotalItems();
95954
96218
  this.updateSelectedItems();
96219
+ if (this.searchInput) {
96220
+ this.handleSearch();
96221
+ } else if (this.hasActiveDropdownFilter) {
96222
+ this.syncFilterViewSelection();
96223
+ }
95955
96224
  },
95956
96225
  // 处理选项数据,添加禁用状态
95957
96226
  processOptions(options) {
@@ -96040,10 +96309,14 @@ class CascaderUtils {
96040
96309
  this.searchInput = this.searchInput.trim();
96041
96310
  if (this.searchInput === '') {
96042
96311
  this.isShowSearch = false;
96312
+ this.searchOptions = [];
96313
+ if (this.hasActiveDropdownFilter) {
96314
+ this.syncFilterViewSelection();
96315
+ }
96043
96316
  return;
96044
96317
  }
96045
96318
  this.isShowSearch = false;
96046
- this.searchOptions = CascaderUtils.searchInTree(this.filteredOptions, this.searchInput, this.cascaderProps);
96319
+ this.searchOptions = CascaderUtils.searchInTree(this.displayOptions, this.searchInput, this.cascaderProps);
96047
96320
 
96048
96321
  // 只设置搜索范围内的选中值
96049
96322
  this.searchSelectedValues = CascaderUtils.getSearchSelectedValues(this.selectedValues, this.searchOptions, this.cascaderProps);
@@ -96080,7 +96353,7 @@ class CascaderUtils {
96080
96353
  handleExpandChange(values = []) {
96081
96354
  if (values.length === 1) {
96082
96355
  this.$nextTick(() => {
96083
- const panel = this.$refs.cascaderPanel || this.$refs.searchCascaderPanel;
96356
+ const panel = this.isFilterView ? this.$refs.searchCascaderPanel || this.$refs.cascaderPanel : this.$refs.cascaderPanel || this.$refs.searchCascaderPanel;
96084
96357
  if (panel) {
96085
96358
  const menus = panel.menus;
96086
96359
  const targetNode = menus[0].find(node => node.value == values[0]);
@@ -96120,15 +96393,15 @@ class CascaderUtils {
96120
96393
  this.$emit('input', emitValue);
96121
96394
  });
96122
96395
  },
96123
- // 搜索模式值变化处理
96396
+ // 搜索 / 下拉筛选视图值变化处理
96124
96397
  handleSearchValueChange(value) {
96125
- // 获取搜索面板中所有可能的叶子节点值
96126
- const searchLeafValues = CascaderUtils.getLeafValues(this.searchOptions, this.cascaderProps);
96398
+ // 获取当前筛选/搜索视图中所有可能的叶子节点值
96399
+ const viewLeafValues = CascaderUtils.getLeafValues(this.viewOptions, this.cascaderProps);
96127
96400
  if (this.isMultiple) {
96128
- // 多选模式:从主选择列表中移除搜索范围内的项,然后添加搜索面板中选中的项
96401
+ // 多选模式:从主选择列表中移除视图范围内的项,然后添加视图中选中的项
96129
96402
  this.selectedValues = this.selectedValues.filter(path => {
96130
96403
  const leafValue = path[path.length - 1];
96131
- return !searchLeafValues.includes(leafValue);
96404
+ return !viewLeafValues.includes(leafValue);
96132
96405
  });
96133
96406
  this.selectedValues = [...this.selectedValues, ...this.searchSelectedValues];
96134
96407
  } else {
@@ -96198,15 +96471,26 @@ class CascaderUtils {
96198
96471
  // 单选模式下不支持全选
96199
96472
  return;
96200
96473
  }
96201
- if (this.isAllSelected) {
96474
+ const config = {
96475
+ disabledField: this.disabledField,
96476
+ disabledValue: this.disabledValue,
96477
+ disabledCheck: this.disabledCheck
96478
+ };
96479
+ if (this.hasActiveDropdownFilter) {
96480
+ const viewPaths = CascaderUtils.getAllLeafPaths(this.displayOptions, config, this.cascaderProps);
96481
+ const viewLeafSet = new Set(viewPaths.map(path => path[path.length - 1]));
96482
+ if (this.isAllSelected) {
96483
+ this.selectedValues = this.selectedValues.filter(path => !viewLeafSet.has(path[path.length - 1]));
96484
+ } else {
96485
+ const preserved = this.selectedValues.filter(path => !viewLeafSet.has(path[path.length - 1]));
96486
+ this.selectedValues = [...preserved, ...viewPaths];
96487
+ }
96488
+ this.searchSelectedValues = CascaderUtils.getSearchSelectedValues(this.selectedValues, this.viewOptions, this.cascaderProps);
96489
+ this.updateSelectedItems();
96490
+ } else if (this.isAllSelected) {
96202
96491
  this.selectedValues = [];
96203
96492
  this.selectedItems = [];
96204
96493
  } else {
96205
- const config = {
96206
- disabledField: this.disabledField,
96207
- disabledValue: this.disabledValue,
96208
- disabledCheck: this.disabledCheck
96209
- };
96210
96494
  // 无论是普通模式还是聚合模式,全选时都选择所有可选的叶子节点
96211
96495
  this.selectedValues = CascaderUtils.getAllLeafPaths(this.filteredOptions, config, this.cascaderProps);
96212
96496
  this.updateSelectedItems();
@@ -96359,6 +96643,54 @@ class CascaderUtils {
96359
96643
  }
96360
96644
  this.$emit('refresh');
96361
96645
  },
96646
+ getNodeFilterFieldText(data) {
96647
+ if (!this.showDropdownFilter || !this.dropdownFilterField || !data) {
96648
+ return '';
96649
+ }
96650
+ const val = data[this.dropdownFilterField];
96651
+ if (val === null || val === undefined || val === '') {
96652
+ return '';
96653
+ }
96654
+ return `(${val})`;
96655
+ },
96656
+ updateFilterAllSelectedState() {
96657
+ if (!this.hasActiveDropdownFilter) {
96658
+ return;
96659
+ }
96660
+ const config = {
96661
+ disabledField: this.disabledField,
96662
+ disabledValue: this.disabledValue,
96663
+ disabledCheck: this.disabledCheck
96664
+ };
96665
+ const viewPaths = CascaderUtils.getAllLeafPaths(this.displayOptions, config, this.cascaderProps);
96666
+ if (viewPaths.length === 0) {
96667
+ this.isAllSelected = false;
96668
+ return;
96669
+ }
96670
+ const selectedLeafSet = new Set(this.selectedValues.map(path => path[path.length - 1]));
96671
+ this.isAllSelected = viewPaths.every(path => selectedLeafSet.has(path[path.length - 1]));
96672
+ },
96673
+ syncFilterViewSelection() {
96674
+ this.searchSelectedValues = CascaderUtils.getSearchSelectedValues(this.selectedValues, this.viewOptions, this.cascaderProps);
96675
+ this.$nextTick(() => {
96676
+ if (this.viewOptions.length > 0) {
96677
+ this.handleSearchExpand();
96678
+ }
96679
+ });
96680
+ },
96681
+ handleDropdownFilterChange() {
96682
+ if (this.searchInput) {
96683
+ this.handleSearch();
96684
+ return;
96685
+ }
96686
+ this.isShowSearch = false;
96687
+ this.searchOptions = [];
96688
+ if (this.hasActiveDropdownFilter) {
96689
+ this.syncFilterViewSelection();
96690
+ } else {
96691
+ this.searchSelectedValues = [];
96692
+ }
96693
+ },
96362
96694
  // 处理批量搜索
96363
96695
  handleBatchSearch() {
96364
96696
  if (!this.batchSearchContent.trim()) {
@@ -96481,8 +96813,8 @@ class CascaderUtils {
96481
96813
  ;
96482
96814
  var ByCascaderPanel_component = normalizeComponent(
96483
96815
  cascader_panel_ByCascaderPanelvue_type_script_lang_js,
96484
- ByCascaderPanelvue_type_template_id_727f392c_render,
96485
- ByCascaderPanelvue_type_template_id_727f392c_staticRenderFns,
96816
+ ByCascaderPanelvue_type_template_id_3691e51e_render,
96817
+ ByCascaderPanelvue_type_template_id_3691e51e_staticRenderFns,
96486
96818
  false,
96487
96819
  null,
96488
96820
  null,
@@ -96491,8 +96823,8 @@ var ByCascaderPanel_component = normalizeComponent(
96491
96823
  )
96492
96824
 
96493
96825
  /* harmony default export */ var ByCascaderPanel = (ByCascaderPanel_component.exports);
96494
- ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel-pro/ByCascaderPanelPro.vue?vue&type=template&id=961f637e
96495
- var ByCascaderPanelProvue_type_template_id_961f637e_render = function render() {
96826
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel-pro/ByCascaderPanelPro.vue?vue&type=template&id=21ca97ff
96827
+ var ByCascaderPanelProvue_type_template_id_21ca97ff_render = function render() {
96496
96828
  var _vm = this,
96497
96829
  _c = _vm._self._c;
96498
96830
  return _c('div', {
@@ -96511,7 +96843,10 @@ var ByCascaderPanelProvue_type_template_id_961f637e_render = function render() {
96511
96843
  }, [_vm._v("可选(" + _vm._s(_vm.selectedCount) + "/" + _vm._s(_vm.totalCount) + ")")]) : _vm._e(), _c('div', {
96512
96844
  staticClass: "search-section"
96513
96845
  }, [_c('div', {
96514
- staticClass: "search-container"
96846
+ staticClass: "search-container",
96847
+ class: {
96848
+ 'has-dropdown-filter': _vm.showDropdownFilter
96849
+ }
96515
96850
  }, [_c('div', {
96516
96851
  staticClass: "search-input-wrap",
96517
96852
  class: {
@@ -96607,7 +96942,37 @@ var ByCascaderPanelProvue_type_template_id_961f637e_render = function render() {
96607
96942
  slot: "reference"
96608
96943
  }, [_c('i', {
96609
96944
  staticClass: "el-icon-edit-outline"
96610
- })])], 1)], 1) : _vm._e()], 1), _vm.showRefreshBtn ? _c('el-tooltip', {
96945
+ })])], 1)], 1) : _vm._e()], 1), _vm.showDropdownFilter ? _c('div', {
96946
+ staticClass: "dropdown-filter-group"
96947
+ }, [_vm.dropdownFilterTitle ? _c('span', {
96948
+ staticClass: "dropdown-filter-title"
96949
+ }, [_vm._v(_vm._s(_vm.dropdownFilterTitle) + ":")]) : _vm._e(), _c('el-select', {
96950
+ staticClass: "dropdown-filter-select",
96951
+ attrs: {
96952
+ "placeholder": _vm.dropdownFilterPlaceholder,
96953
+ "clearable": "",
96954
+ "size": "mini",
96955
+ "disabled": _vm.panelViewMode
96956
+ },
96957
+ on: {
96958
+ "change": _vm.handleDropdownFilterChange
96959
+ },
96960
+ model: {
96961
+ value: _vm.dropdownFilterValue,
96962
+ callback: function ($$v) {
96963
+ _vm.dropdownFilterValue = $$v;
96964
+ },
96965
+ expression: "dropdownFilterValue"
96966
+ }
96967
+ }, _vm._l(_vm.normalizedDropdownFilterOptions, function (opt) {
96968
+ return _c('el-option', {
96969
+ key: 'df-' + opt.value,
96970
+ attrs: {
96971
+ "label": opt.label,
96972
+ "value": opt.value
96973
+ }
96974
+ });
96975
+ }), 1)], 1) : _vm._e(), _vm.showRefreshBtn ? _c('el-tooltip', {
96611
96976
  attrs: {
96612
96977
  "content": _vm.refreshTooltip,
96613
96978
  "placement": "top",
@@ -96648,8 +97013,8 @@ var ByCascaderPanelProvue_type_template_id_961f637e_render = function render() {
96648
97013
  directives: [{
96649
97014
  name: "show",
96650
97015
  rawName: "v-show",
96651
- value: _vm.searchInput === '' || !_vm.isShowSearch,
96652
- expression: "searchInput === '' || !isShowSearch"
97016
+ value: !_vm.isFilterView,
97017
+ expression: "!isFilterView"
96653
97018
  }],
96654
97019
  ref: "cascaderPanel",
96655
97020
  staticClass: "cascader-panel-inner",
@@ -96665,44 +97030,41 @@ var ByCascaderPanelProvue_type_template_id_961f637e_render = function render() {
96665
97030
  "column-min-width": _vm.columnMinWidth,
96666
97031
  "column-max-width": _vm.columnMaxWidth,
96667
97032
  "disabled-config": _vm.disabledConfig,
96668
- "is-view-mode": _vm.panelViewMode
97033
+ "is-view-mode": _vm.panelViewMode,
97034
+ "filter-field": _vm.showDropdownFilter ? _vm.dropdownFilterField : ''
96669
97035
  },
96670
97036
  on: {
96671
97037
  "input": _vm.onMainPanelInput,
96672
97038
  "change": _vm.handleValueChange,
96673
97039
  "store-ready": _vm.schedulePanelSyncFromExternalValue
96674
97040
  }
96675
- }) : _vm._e(), _vm.searchOptions.length > 0 ? _c('VirtualCascaderPanel', {
97041
+ }) : _vm._e(), _vm.viewOptions.length > 0 ? _c('VirtualCascaderPanel', {
96676
97042
  directives: [{
96677
97043
  name: "show",
96678
97044
  rawName: "v-show",
96679
- value: _vm.searchInput !== '' && _vm.isShowSearch,
96680
- expression: "searchInput !== '' && isShowSearch"
97045
+ value: _vm.isFilterView,
97046
+ expression: "isFilterView"
96681
97047
  }],
96682
97048
  ref: "searchCascaderPanel",
96683
97049
  staticClass: "cascader-panel-inner",
96684
97050
  attrs: {
96685
97051
  "value": _vm.compactSearchPanelValue,
96686
97052
  "sync-value-from-parent": false,
96687
- "options": _vm.searchOptions,
97053
+ "options": _vm.viewOptions,
96688
97054
  "props": _vm.cascaderProps,
96689
97055
  "height": _vm.computedPanelHeight - 20,
96690
97056
  "column-min-width": _vm.columnMinWidth,
96691
97057
  "column-max-width": _vm.columnMaxWidth,
96692
97058
  "disabled-config": _vm.disabledConfig,
96693
- "is-view-mode": _vm.panelViewMode
97059
+ "is-view-mode": _vm.panelViewMode,
97060
+ "filter-field": _vm.showDropdownFilter ? _vm.dropdownFilterField : ''
96694
97061
  },
96695
97062
  on: {
96696
97063
  "input": _vm.onSearchPanelInput,
96697
- "change": _vm.handleSearchValueChange
97064
+ "change": _vm.handleSearchValueChange,
97065
+ "store-ready": _vm.syncSearchPanelSelection
96698
97066
  }
96699
- }) : _vm._e(), _vm.isShowSearch && _vm.searchOptions.length === 0 ? _c('div', {
96700
- directives: [{
96701
- name: "show",
96702
- rawName: "v-show",
96703
- value: _vm.searchInput !== '',
96704
- expression: "searchInput !== ''"
96705
- }],
97067
+ }) : _vm._e(), _vm.isFilterView && _vm.viewOptions.length === 0 ? _c('div', {
96706
97068
  staticClass: "empty-search"
96707
97069
  }, [_c('el-empty', {
96708
97070
  attrs: {
@@ -96773,7 +97135,7 @@ var ByCascaderPanelProvue_type_template_id_961f637e_render = function render() {
96773
97135
  staticClass: "empty-state"
96774
97136
  }, [_vm._v("暂无选中项")])], 1)])])])]);
96775
97137
  };
96776
- var ByCascaderPanelProvue_type_template_id_961f637e_staticRenderFns = [];
97138
+ var ByCascaderPanelProvue_type_template_id_21ca97ff_staticRenderFns = [];
96777
97139
 
96778
97140
  ;// ./src/components/cascader-panel-pro/cascaderStorePro.js
96779
97141
 
@@ -97065,14 +97427,22 @@ class CascaderUtilsPro {
97065
97427
  minWidth = 180,
97066
97428
  maxWidth = 420,
97067
97429
  extraPadding = 56,
97068
- hasCheckbox = true
97430
+ hasCheckbox = true,
97431
+ filterField = ''
97069
97432
  } = options;
97070
97433
  if (!nodes || nodes.length === 0) {
97071
97434
  return minWidth;
97072
97435
  }
97073
97436
  let maxLabelWidth = 0;
97074
97437
  nodes.forEach(node => {
97075
- maxLabelWidth = Math.max(maxLabelWidth, this.measureCascaderLabelWidth(node.label));
97438
+ let text = node.label || '';
97439
+ if (filterField) {
97440
+ const extra = node.raw && node.raw[filterField];
97441
+ if (extra !== null && extra !== undefined && extra !== '') {
97442
+ text += ` (${extra})`;
97443
+ }
97444
+ }
97445
+ maxLabelWidth = Math.max(maxLabelWidth, this.measureCascaderLabelWidth(text));
97076
97446
  });
97077
97447
  const checkboxWidth = hasCheckbox ? 28 : 0;
97078
97448
  const arrowWidth = 24;
@@ -97231,6 +97601,58 @@ class CascaderUtilsPro {
97231
97601
  return result;
97232
97602
  }
97233
97603
 
97604
+ /**
97605
+ * 判断节点指定字段是否匹配下拉筛选值
97606
+ * @param {Object} node
97607
+ * @param {String} field
97608
+ * @param {*} filterValue
97609
+ * @returns {Boolean}
97610
+ */
97611
+ static isFilterFieldMatched(node, field, filterValue) {
97612
+ if (!node || !field || filterValue === null || filterValue === undefined || filterValue === '') {
97613
+ return false;
97614
+ }
97615
+ const raw = node[field];
97616
+ if (raw === null || raw === undefined || raw === '') {
97617
+ return false;
97618
+ }
97619
+ return String(raw).trim() === String(filterValue).trim();
97620
+ }
97621
+
97622
+ /**
97623
+ * 按数据字段过滤树:保留字段匹配的节点及其祖先路径
97624
+ * @param {Array} tree - 树形数据
97625
+ * @param {String} field - 数据中用于筛选的字段名
97626
+ * @param {*} filterValue - 下拉选中值
97627
+ * @param {Object} cascaderProps - 级联配置
97628
+ * @returns {Array} 过滤后的树
97629
+ */
97630
+ static filterTreeByField(tree, field, filterValue, cascaderProps) {
97631
+ if (!Array.isArray(tree) || !field || filterValue === null || filterValue === undefined || filterValue === '') {
97632
+ return tree || [];
97633
+ }
97634
+ const childrenKey = cascaderProps && cascaderProps.children || 'children';
97635
+ const result = [];
97636
+ tree.forEach(node => {
97637
+ const children = node[childrenKey];
97638
+ const hasChildren = Array.isArray(children) && children.length > 0;
97639
+ if (hasChildren) {
97640
+ const matchedChildren = this.filterTreeByField(children, field, filterValue, cascaderProps);
97641
+ if (matchedChildren.length > 0) {
97642
+ result.push({
97643
+ ...node,
97644
+ [childrenKey]: matchedChildren
97645
+ });
97646
+ }
97647
+ } else if (this.isFilterFieldMatched(node, field, filterValue)) {
97648
+ result.push({
97649
+ ...node
97650
+ });
97651
+ }
97652
+ });
97653
+ return result;
97654
+ }
97655
+
97234
97656
  /**
97235
97657
  * 基于扁平 store 快速搜索(父节点命中时直接复用 raw 子树,跳过子级遍历)
97236
97658
  */
@@ -97774,8 +98196,8 @@ class CascaderUtilsPro {
97774
98196
  return paths;
97775
98197
  }
97776
98198
  }
97777
- ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel-pro/VirtualCascaderPanel.vue?vue&type=template&id=05f77638
97778
- var VirtualCascaderPanelvue_type_template_id_05f77638_render = function render() {
98199
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel-pro/VirtualCascaderPanel.vue?vue&type=template&id=7d8ff846
98200
+ var VirtualCascaderPanelvue_type_template_id_7d8ff846_render = function render() {
97779
98201
  var _vm = this,
97780
98202
  _c = _vm._self._c;
97781
98203
  return _c('div', {
@@ -97856,7 +98278,9 @@ var VirtualCascaderPanelvue_type_template_id_05f77638_render = function render()
97856
98278
  }
97857
98279
  }, [_c('span')])], 1) : _vm._e(), _c('span', {
97858
98280
  staticClass: "el-cascader-node__label"
97859
- }, [_vm._v(_vm._s(item.label))]), !item.isLeaf ? _c('span', {
98281
+ }, [_vm.filterField ? [_vm._v(" " + _vm._s(item.label)), _vm.getFilterFieldText(item) ? _c('span', {
98282
+ staticClass: "node-filter-field"
98283
+ }, [_vm._v(_vm._s(_vm.getFilterFieldText(item)))]) : _vm._e()] : [_vm._v(_vm._s(item.label))]], 2), !item.isLeaf ? _c('span', {
97860
98284
  staticClass: "el-cascader-node__postfix"
97861
98285
  }, [_c('i', {
97862
98286
  staticClass: "el-icon-arrow-right el-cascader-node__icon-arrow"
@@ -97866,7 +98290,7 @@ var VirtualCascaderPanelvue_type_template_id_05f77638_render = function render()
97866
98290
  })], 1);
97867
98291
  }), 0);
97868
98292
  };
97869
- var VirtualCascaderPanelvue_type_template_id_05f77638_staticRenderFns = [];
98293
+ var VirtualCascaderPanelvue_type_template_id_7d8ff846_staticRenderFns = [];
97870
98294
 
97871
98295
  ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"185687ec-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel-pro/VirtualList.vue?vue&type=template&id=43cb1148
97872
98296
  var VirtualListvue_type_template_id_43cb1148_render = function render() {
@@ -98350,6 +98774,11 @@ class SelectionStatePro {
98350
98774
  syncValueFromParent: {
98351
98775
  type: Boolean,
98352
98776
  default: true
98777
+ },
98778
+ // 下拉筛选字段名:有值时在节点名称后展示该字段内容
98779
+ filterField: {
98780
+ type: String,
98781
+ default: ''
98353
98782
  }
98354
98783
  },
98355
98784
  data() {
@@ -98466,7 +98895,8 @@ class SelectionStatePro {
98466
98895
  const width = CascaderUtilsPro.getCascaderColumnWidth(columnNodes, {
98467
98896
  minWidth: this.columnMinWidth,
98468
98897
  maxWidth: this.columnMaxWidth,
98469
- hasCheckbox: this.multiple || this.checkStrictly
98898
+ hasCheckbox: this.multiple || this.checkStrictly,
98899
+ filterField: this.filterField
98470
98900
  });
98471
98901
  return {
98472
98902
  width: width + 'px',
@@ -98474,6 +98904,17 @@ class SelectionStatePro {
98474
98904
  maxWidth: width + 'px'
98475
98905
  };
98476
98906
  },
98907
+ getFilterFieldText(item) {
98908
+ if (!this.filterField || !item) {
98909
+ return '';
98910
+ }
98911
+ const raw = item.raw || item;
98912
+ const val = raw[this.filterField];
98913
+ if (val === null || val === undefined || val === '') {
98914
+ return '';
98915
+ }
98916
+ return `(${val})`;
98917
+ },
98477
98918
  rebuildStore() {
98478
98919
  this.store = buildCascaderStore(this.options, this.disabledConfig, this.props, CascaderUtilsPro);
98479
98920
  this.selection = new SelectionStatePro(this.store);
@@ -98783,8 +99224,8 @@ class SelectionStatePro {
98783
99224
  ;
98784
99225
  var VirtualCascaderPanel_component = normalizeComponent(
98785
99226
  cascader_panel_pro_VirtualCascaderPanelvue_type_script_lang_js,
98786
- VirtualCascaderPanelvue_type_template_id_05f77638_render,
98787
- VirtualCascaderPanelvue_type_template_id_05f77638_staticRenderFns,
99227
+ VirtualCascaderPanelvue_type_template_id_7d8ff846_render,
99228
+ VirtualCascaderPanelvue_type_template_id_7d8ff846_staticRenderFns,
98788
99229
  false,
98789
99230
  null,
98790
99231
  null,
@@ -98940,6 +99381,15 @@ var VirtualCascaderPanel_component = normalizeComponent(
98940
99381
  columnMaxWidth: {
98941
99382
  type: Number,
98942
99383
  default: 420
99384
+ },
99385
+ /**
99386
+ * 下拉筛选配置。外部传入且 enabled 不为 false、并指定 field 时才展示下拉框。
99387
+ * { enabled, title, placeholder, options: [{ label, value }], field }
99388
+ * field 为数据中用于过滤和展示的字段名。
99389
+ */
99390
+ dropdownFilter: {
99391
+ type: Object,
99392
+ default: null
98943
99393
  }
98944
99394
  },
98945
99395
  data() {
@@ -98967,7 +99417,8 @@ var VirtualCascaderPanel_component = normalizeComponent(
98967
99417
  searchLeafSetCache: null,
98968
99418
  panelSyncTimer: null,
98969
99419
  // 外部 v-model 回显同步中,避免与用户操作冲突
98970
- isExternalSync: false
99420
+ isExternalSync: false,
99421
+ dropdownFilterValue: ''
98971
99422
  };
98972
99423
  },
98973
99424
  computed: {
@@ -99068,6 +99519,59 @@ var VirtualCascaderPanel_component = normalizeComponent(
99068
99519
  this.searchSelectedValues = value ? [value] : [];
99069
99520
  }
99070
99521
  }
99522
+ },
99523
+ showDropdownFilter() {
99524
+ const cfg = this.dropdownFilter;
99525
+ return !!(cfg && typeof cfg === 'object' && cfg.enabled !== false && cfg.field);
99526
+ },
99527
+ dropdownFilterPlaceholder() {
99528
+ return this.dropdownFilter && this.dropdownFilter.placeholder || '请选择';
99529
+ },
99530
+ dropdownFilterTitle() {
99531
+ const title = this.dropdownFilter && this.dropdownFilter.title;
99532
+ return title != null && String(title).trim() !== '' ? String(title).trim() : '';
99533
+ },
99534
+ dropdownFilterField() {
99535
+ return this.dropdownFilter && this.dropdownFilter.field || '';
99536
+ },
99537
+ normalizedDropdownFilterOptions() {
99538
+ const opts = this.dropdownFilter && this.dropdownFilter.options || [];
99539
+ return opts.map(opt => {
99540
+ if (opt != null && typeof opt === 'object') {
99541
+ return {
99542
+ label: opt.label != null ? opt.label : opt.value,
99543
+ value: opt.value != null ? opt.value : opt.label
99544
+ };
99545
+ }
99546
+ return {
99547
+ label: String(opt),
99548
+ value: opt
99549
+ };
99550
+ });
99551
+ },
99552
+ hasActiveDropdownFilter() {
99553
+ return this.showDropdownFilter && this.dropdownFilterValue !== '' && this.dropdownFilterValue !== null && this.dropdownFilterValue !== undefined;
99554
+ },
99555
+ displayOptions() {
99556
+ if (!this.hasActiveDropdownFilter) {
99557
+ return this.filteredOptions;
99558
+ }
99559
+ return CascaderUtilsPro.filterTreeByField(this.filteredOptions, this.dropdownFilterField, this.dropdownFilterValue, this.cascaderProps);
99560
+ },
99561
+ isFilterView() {
99562
+ if (this.searchInput !== '' && this.isShowSearch) {
99563
+ return true;
99564
+ }
99565
+ return this.hasActiveDropdownFilter;
99566
+ },
99567
+ viewOptions() {
99568
+ if (this.searchInput !== '' && this.isShowSearch) {
99569
+ return this.searchOptions;
99570
+ }
99571
+ if (this.hasActiveDropdownFilter) {
99572
+ return this.displayOptions;
99573
+ }
99574
+ return [];
99071
99575
  }
99072
99576
  },
99073
99577
  watch: {
@@ -99093,6 +99597,9 @@ var VirtualCascaderPanel_component = normalizeComponent(
99093
99597
  searchInput(val) {
99094
99598
  if (!val) {
99095
99599
  this.clearSearchState();
99600
+ if (this.hasActiveDropdownFilter) {
99601
+ this.prepareFilterView();
99602
+ }
99096
99603
  return;
99097
99604
  }
99098
99605
  this.scheduleSearch();
@@ -99120,6 +99627,9 @@ var VirtualCascaderPanel_component = normalizeComponent(
99120
99627
  } else if (panel && panel.store && panel.selection && this.aggregationMode) {
99121
99628
  this.isAllSelected = panel.selection.size() === panel.store.totalLeafCount && panel.store.totalLeafCount > 0;
99122
99629
  }
99630
+ if (this.hasActiveDropdownFilter) {
99631
+ this.updateFilterAllSelectedState();
99632
+ }
99123
99633
  } else {
99124
99634
  if (newVal.length > 1) {
99125
99635
  this.selectedItems = [newVal[newVal.length - 1]];
@@ -99134,6 +99644,11 @@ var VirtualCascaderPanel_component = normalizeComponent(
99134
99644
  if (val) {
99135
99645
  this.batchSearchVisible = false;
99136
99646
  }
99647
+ },
99648
+ showDropdownFilter(val) {
99649
+ if (!val) {
99650
+ this.dropdownFilterValue = '';
99651
+ }
99137
99652
  }
99138
99653
  },
99139
99654
  mounted() {
@@ -99187,6 +99702,9 @@ var VirtualCascaderPanel_component = normalizeComponent(
99187
99702
  this.selectedValues = selection.getCheckedPaths();
99188
99703
  }
99189
99704
  panel.bumpSelectionView();
99705
+ if (this.hasActiveDropdownFilter) {
99706
+ this.updateFilterAllSelectedState();
99707
+ }
99190
99708
  return;
99191
99709
  }
99192
99710
  if (selection.isCompactSelection()) {
@@ -99194,11 +99712,17 @@ var VirtualCascaderPanel_component = normalizeComponent(
99194
99712
  this.selectedCount = selection.size();
99195
99713
  this.isAllSelected = selection.size() === store.totalLeafCount;
99196
99714
  panel.bumpSelectionView();
99715
+ if (this.hasActiveDropdownFilter) {
99716
+ this.updateFilterAllSelectedState();
99717
+ }
99197
99718
  return;
99198
99719
  }
99199
99720
  this.selectedValues = selection.getCheckedPaths();
99200
99721
  this.updateSelectedItems();
99201
99722
  panel.bumpSelectionView();
99723
+ if (this.hasActiveDropdownFilter) {
99724
+ this.updateFilterAllSelectedState();
99725
+ }
99202
99726
  },
99203
99727
  /**
99204
99728
  * 用户操作(勾选/全选/清除/删除)统一提交:更新展示 + emit,标记内部更新防回显覆盖
@@ -99452,6 +99976,11 @@ var VirtualCascaderPanel_component = normalizeComponent(
99452
99976
  } else {
99453
99977
  this.updateSelectedItems();
99454
99978
  }
99979
+ if (this.searchInput) {
99980
+ this.scheduleSearch();
99981
+ } else if (this.hasActiveDropdownFilter) {
99982
+ this.prepareFilterView();
99983
+ }
99455
99984
  },
99456
99985
  // 处理选项数据,添加禁用状态(浅拷贝,避免 JSON 深拷贝大数据卡顿)
99457
99986
  processOptions(options) {
@@ -99537,13 +100066,20 @@ var VirtualCascaderPanel_component = normalizeComponent(
99537
100066
  const keyword = this.searchInput.trim();
99538
100067
  if (!keyword) {
99539
100068
  this.clearSearchState();
100069
+ if (this.hasActiveDropdownFilter) {
100070
+ this.prepareFilterView();
100071
+ }
99540
100072
  return;
99541
100073
  }
99542
- const panel = this.$refs.cascaderPanel;
99543
- if (panel && panel.store) {
99544
- this.searchOptions = CascaderUtilsPro.searchFromStore(panel.store, keyword, this.cascaderProps);
100074
+ if (this.hasActiveDropdownFilter) {
100075
+ this.searchOptions = CascaderUtilsPro.searchInTree(this.displayOptions, keyword, this.cascaderProps);
99545
100076
  } else {
99546
- this.searchOptions = CascaderUtilsPro.searchInTree(this.filteredOptions, keyword, this.cascaderProps);
100077
+ const panel = this.$refs.cascaderPanel;
100078
+ if (panel && panel.store) {
100079
+ this.searchOptions = CascaderUtilsPro.searchFromStore(panel.store, keyword, this.cascaderProps);
100080
+ } else {
100081
+ this.searchOptions = CascaderUtilsPro.searchInTree(this.filteredOptions, keyword, this.cascaderProps);
100082
+ }
99547
100083
  }
99548
100084
  this.searchLeafSetCache = new Set(CascaderUtilsPro.getLeafValues(this.searchOptions, this.cascaderProps));
99549
100085
  this.searchSelectedValues = this.getSearchSelectedPathsFromMain(this.searchLeafSetCache);
@@ -99575,7 +100111,7 @@ var VirtualCascaderPanel_component = normalizeComponent(
99575
100111
  if (this.searchLeafSetCache) {
99576
100112
  return this.searchLeafSetCache;
99577
100113
  }
99578
- return new Set(CascaderUtilsPro.getLeafValues(this.searchOptions, this.cascaderProps));
100114
+ return new Set(CascaderUtilsPro.getLeafValues(this.viewOptions, this.cascaderProps));
99579
100115
  },
99580
100116
  syncSearchPanelSelection() {
99581
100117
  const searchPanel = this.$refs.searchCascaderPanel;
@@ -99595,12 +100131,46 @@ var VirtualCascaderPanel_component = normalizeComponent(
99595
100131
  },
99596
100132
  // 搜索模式下的展开处理
99597
100133
  handleSearchExpand() {
99598
- if (this.$refs.searchCascaderPanel && this.searchOptions.length > 0) {
99599
- const firstOption = this.searchOptions[0];
100134
+ if (this.$refs.searchCascaderPanel && this.viewOptions.length > 0) {
100135
+ const firstOption = this.viewOptions[0];
99600
100136
  const valueKey = this.cascaderProps.value || 'value';
99601
100137
  this.$refs.searchCascaderPanel.expandPathValues([firstOption[valueKey]], true);
99602
100138
  }
99603
100139
  },
100140
+ prepareFilterView() {
100141
+ this.searchLeafSetCache = new Set(CascaderUtilsPro.getLeafValues(this.displayOptions, this.cascaderProps));
100142
+ this.$nextTick(() => {
100143
+ this.syncSearchPanelSelection();
100144
+ this.handleSearchExpand();
100145
+ });
100146
+ },
100147
+ handleDropdownFilterChange() {
100148
+ if (this.searchInput) {
100149
+ this.scheduleSearch();
100150
+ return;
100151
+ }
100152
+ this.clearSearchState();
100153
+ if (this.hasActiveDropdownFilter) {
100154
+ this.prepareFilterView();
100155
+ }
100156
+ },
100157
+ updateFilterAllSelectedState() {
100158
+ if (!this.hasActiveDropdownFilter) {
100159
+ return;
100160
+ }
100161
+ const viewPaths = CascaderUtilsPro.getAllLeafPaths(this.displayOptions, this.disabledConfig, this.cascaderProps);
100162
+ if (viewPaths.length === 0) {
100163
+ this.isAllSelected = false;
100164
+ return;
100165
+ }
100166
+ const panel = this.$refs.cascaderPanel;
100167
+ if (panel && panel.selection && panel.selection.selectedLeafSet) {
100168
+ this.isAllSelected = viewPaths.every(path => panel.selection.selectedLeafSet.has(path[path.length - 1]));
100169
+ return;
100170
+ }
100171
+ const selectedLeafSet = new Set(this.selectedValues.map(path => path[path.length - 1]));
100172
+ this.isAllSelected = viewPaths.every(path => selectedLeafSet.has(path[path.length - 1]));
100173
+ },
99604
100174
  // 值变化处理(面板勾选)
99605
100175
  handleValueChange() {
99606
100176
  this.commitUserSelectionChange();
@@ -99692,6 +100262,26 @@ var VirtualCascaderPanel_component = normalizeComponent(
99692
100262
  }
99693
100263
  const panel = this.$refs.cascaderPanel;
99694
100264
  const searchPanel = this.$refs.searchCascaderPanel;
100265
+ if (this.hasActiveDropdownFilter && panel && panel.selection && panel.store) {
100266
+ const viewPaths = CascaderUtilsPro.getAllLeafPaths(this.displayOptions, this.disabledConfig, this.cascaderProps);
100267
+ const viewLeafSet = new Set(viewPaths.map(path => path[path.length - 1]));
100268
+ if (this.isAllSelected) {
100269
+ viewLeafSet.forEach(leaf => {
100270
+ panel.selection.selectedLeafSet.delete(leaf);
100271
+ });
100272
+ } else {
100273
+ viewLeafSet.forEach(leaf => {
100274
+ panel.selection.selectedLeafSet.add(leaf);
100275
+ });
100276
+ }
100277
+ panel.selection._reconcileAllRoots();
100278
+ panel.bumpSelectionView();
100279
+ if (searchPanel && searchPanel.selection) {
100280
+ this.syncSearchPanelSelection();
100281
+ }
100282
+ this.commitUserSelectionChange();
100283
+ return;
100284
+ }
99695
100285
  if (this.isAllSelected) {
99696
100286
  this.clearPanelSelectionState(panel);
99697
100287
  this.clearPanelSelectionState(searchPanel);
@@ -99817,6 +100407,9 @@ var VirtualCascaderPanel_component = normalizeComponent(
99817
100407
  if (this.panelViewMode) return;
99818
100408
  this.searchInput = '';
99819
100409
  this.clearSearchState();
100410
+ if (this.hasActiveDropdownFilter) {
100411
+ this.prepareFilterView();
100412
+ }
99820
100413
  this.$emit('refresh');
99821
100414
  },
99822
100415
  // 处理批量搜索
@@ -99945,8 +100538,8 @@ var VirtualCascaderPanel_component = normalizeComponent(
99945
100538
  ;
99946
100539
  var ByCascaderPanelPro_component = normalizeComponent(
99947
100540
  cascader_panel_pro_ByCascaderPanelProvue_type_script_lang_js,
99948
- ByCascaderPanelProvue_type_template_id_961f637e_render,
99949
- ByCascaderPanelProvue_type_template_id_961f637e_staticRenderFns,
100541
+ ByCascaderPanelProvue_type_template_id_21ca97ff_render,
100542
+ ByCascaderPanelProvue_type_template_id_21ca97ff_staticRenderFns,
99950
100543
  false,
99951
100544
  null,
99952
100545
  null,