@weitutech/by-components 1.1.221 → 1.2.1

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.
@@ -74276,6 +74276,7 @@ __webpack_require__.d(__webpack_exports__, {
74276
74276
  ByCardSelector: function() { return /* reexport */ ByCardSelector; },
74277
74277
  ByCardView: function() { return /* reexport */ ByCardView; },
74278
74278
  ByCascaderPanel: function() { return /* reexport */ ByCascaderPanel; },
74279
+ ByCascaderPanelPro: function() { return /* reexport */ ByCascaderPanelPro; },
74279
74280
  ByCommonInput: function() { return /* reexport */ ByCommonInput; },
74280
74281
  ByCommonSelector: function() { return /* reexport */ ByCommonSelector; },
74281
74282
  ByCustomDatePicker: function() { return /* reexport */ custom_date_picker; },
@@ -74293,7 +74294,6 @@ __webpack_require__.d(__webpack_exports__, {
74293
74294
  ByTable: function() { return /* reexport */ table; },
74294
74295
  ByTag: function() { return /* reexport */ ByTag; },
74295
74296
  ByToolBar: function() { return /* reexport */ ByToolBar; },
74296
- ByTreePanel: function() { return /* reexport */ ByTreePanel; },
74297
74297
  ByTreeSearch: function() { return /* reexport */ ByTreeSearch; },
74298
74298
  GridItem: function() { return /* reexport */ vue_grid_layout_common.GridItem; },
74299
74299
  ToolBarItemType: function() { return /* reexport */ ToolBarItemType; },
@@ -96015,12 +96015,12 @@ var ByCascaderPanel_component = normalizeComponent(
96015
96015
  )
96016
96016
 
96017
96017
  /* harmony default export */ var ByCascaderPanel = (ByCascaderPanel_component.exports);
96018
- ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"8cd600e8-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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/tree-panel/ByTreePanel.vue?vue&type=template&id=af06ba0a
96019
- var ByTreePanelvue_type_template_id_af06ba0a_render = function render() {
96018
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"8cd600e8-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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=804df886
96019
+ var ByCascaderPanelProvue_type_template_id_804df886_render = function render() {
96020
96020
  var _vm = this,
96021
96021
  _c = _vm._self._c;
96022
96022
  return _c('div', {
96023
- staticClass: "tree-panel"
96023
+ staticClass: "cascader-panel-pro"
96024
96024
  }, [_c('div', {
96025
96025
  staticClass: "panel-container"
96026
96026
  }, [_c('div', {
@@ -96041,9 +96041,6 @@ var ByTreePanelvue_type_template_id_af06ba0a_render = function render() {
96041
96041
  "size": "mini",
96042
96042
  "disabled": _vm.isViewMode
96043
96043
  },
96044
- on: {
96045
- "input": _vm.handleSearch
96046
- },
96047
96044
  model: {
96048
96045
  value: _vm.searchInput,
96049
96046
  callback: function ($$v) {
@@ -96056,7 +96053,7 @@ var ByTreePanelvue_type_template_id_af06ba0a_render = function render() {
96056
96053
  "placement": "bottom-start",
96057
96054
  "width": 300,
96058
96055
  "trigger": "click",
96059
- "popper-class": "batch-search-popover"
96056
+ "popper-class": "batch-search-popover-pro"
96060
96057
  },
96061
96058
  on: {
96062
96059
  "show": _vm.handleBatchSearchShow
@@ -96128,26 +96125,69 @@ var ByTreePanelvue_type_template_id_af06ba0a_render = function render() {
96128
96125
  height: _vm.computedPanelHeight + 'px'
96129
96126
  }
96130
96127
  }, [_c('div', {
96131
- staticClass: "tree-content-wrapper"
96132
- }, [_vm.displayOptions.length > 0 ? _c('el-tree', {
96133
- ref: "tree",
96134
- staticClass: "tree-panel-inner",
96128
+ staticClass: "cascader-content-wrapper",
96129
+ style: {
96130
+ height: '100%'
96131
+ }
96132
+ }, [_vm.isShow && _vm.filteredOptions.length > 0 ? _c('VirtualCascaderPanel', {
96133
+ directives: [{
96134
+ name: "show",
96135
+ rawName: "v-show",
96136
+ value: _vm.searchInput === '' || !_vm.isShowSearch,
96137
+ expression: "searchInput === '' || !isShowSearch"
96138
+ }],
96139
+ ref: "cascaderPanel",
96140
+ staticClass: "cascader-panel-inner",
96141
+ style: {
96142
+ height: _vm.computedPanelHeight - 20 + 'px'
96143
+ },
96135
96144
  attrs: {
96136
- "data": _vm.displayOptions,
96137
- "props": _vm.treeFieldProps,
96138
- "node-key": _vm.nodeKey,
96139
- "show-checkbox": _vm.isMultiple && !_vm.isViewMode,
96140
- "check-strictly": false,
96141
- "highlight-current": !_vm.isMultiple,
96142
- "expand-on-click-node": !_vm.isMultiple,
96143
- "default-expand-all": false,
96144
- "filter-node-method": _vm.filterNodeMethod
96145
+ "value": _vm.panelPresentationValue,
96146
+ "sync-value-from-parent": !_vm.useCompactSelection,
96147
+ "options": _vm.filteredOptions,
96148
+ "props": _vm.cascaderProps,
96149
+ "height": _vm.computedPanelHeight - 20,
96150
+ "column-min-width": _vm.columnMinWidth,
96151
+ "column-max-width": _vm.columnMaxWidth,
96152
+ "disabled-config": _vm.disabledConfig,
96153
+ "is-view-mode": _vm.isViewMode
96154
+ },
96155
+ on: {
96156
+ "input": _vm.onMainPanelInput,
96157
+ "change": _vm.handleValueChange,
96158
+ "store-ready": _vm.schedulePanelSyncFromExternalValue
96159
+ }
96160
+ }) : _vm._e(), _vm.searchOptions.length > 0 ? _c('VirtualCascaderPanel', {
96161
+ directives: [{
96162
+ name: "show",
96163
+ rawName: "v-show",
96164
+ value: _vm.searchInput !== '' && _vm.isShowSearch,
96165
+ expression: "searchInput !== '' && isShowSearch"
96166
+ }],
96167
+ ref: "searchCascaderPanel",
96168
+ staticClass: "cascader-panel-inner",
96169
+ attrs: {
96170
+ "value": _vm.compactSearchPanelValue,
96171
+ "sync-value-from-parent": false,
96172
+ "options": _vm.searchOptions,
96173
+ "props": _vm.cascaderProps,
96174
+ "height": _vm.computedPanelHeight - 20,
96175
+ "column-min-width": _vm.columnMinWidth,
96176
+ "column-max-width": _vm.columnMaxWidth,
96177
+ "disabled-config": _vm.disabledConfig,
96178
+ "is-view-mode": _vm.isViewMode
96145
96179
  },
96146
96180
  on: {
96147
- "check": _vm.handleTreeCheck,
96148
- "node-click": _vm.handleNodeClick
96181
+ "input": _vm.onSearchPanelInput,
96182
+ "change": _vm.handleSearchValueChange
96149
96183
  }
96150
- }) : _vm.searchInput ? _c('div', {
96184
+ }) : _vm._e(), _vm.isShowSearch && _vm.searchOptions.length === 0 ? _c('div', {
96185
+ directives: [{
96186
+ name: "show",
96187
+ rawName: "v-show",
96188
+ value: _vm.searchInput !== '',
96189
+ expression: "searchInput !== ''"
96190
+ }],
96151
96191
  staticClass: "empty-search"
96152
96192
  }, [_c('el-empty', {
96153
96193
  attrs: {
@@ -96173,33 +96213,54 @@ var ByTreePanelvue_type_template_id_af06ba0a_render = function render() {
96173
96213
  }
96174
96214
  }, [_c('div', {
96175
96215
  staticClass: "selected-list"
96176
- }, [_vm._l(_vm.selectedItems, function (item, index) {
96177
- return _c('div', {
96178
- key: _vm.getSelectedItemKey(item, index),
96179
- staticClass: "selected-item"
96180
- }, [_c('div', {
96181
- staticClass: "item-content"
96182
- }, [_c('div', {
96183
- staticClass: "item-label"
96184
- }, [_vm._v(_vm._s(item.label || ''))]), _vm.showSubtitle && _vm.subtitleField && item[_vm.subtitleField] ? _c('div', {
96185
- staticClass: "item-subtitle"
96186
- }, [_vm._v(" " + _vm._s(item[_vm.subtitleField]) + " ")]) : _vm._e()]), !_vm.isViewMode ? _c('div', {
96187
- staticClass: "remove-btn",
96188
- on: {
96189
- "click": function ($event) {
96190
- return _vm.removeItem(item, index);
96191
- }
96216
+ }, [_vm.selectedItems.length > 0 ? _c('VcpVirtualList', {
96217
+ staticClass: "selected-virtual-list",
96218
+ style: {
96219
+ height: _vm.selectedListHeight + 'px'
96220
+ },
96221
+ attrs: {
96222
+ "items": _vm.selectedItems,
96223
+ "item-height": _vm.selectedItemHeight,
96224
+ "height": _vm.selectedListHeight,
96225
+ "list-padding": 0,
96226
+ "overscan": 10
96227
+ },
96228
+ scopedSlots: _vm._u([{
96229
+ key: "default",
96230
+ fn: function ({
96231
+ item,
96232
+ index
96233
+ }) {
96234
+ return [_c('div', {
96235
+ key: 'selected-' + item.value + '-' + index,
96236
+ staticClass: "selected-item-row"
96237
+ }, [_c('div', {
96238
+ staticClass: "selected-item"
96239
+ }, [_c('div', {
96240
+ staticClass: "item-content"
96241
+ }, [_c('div', {
96242
+ staticClass: "item-label"
96243
+ }, [_vm._v(_vm._s(item.label || ''))]), _vm.showSubtitle && _vm.subtitleField && item[_vm.subtitleField] ? _c('div', {
96244
+ staticClass: "item-subtitle"
96245
+ }, [_vm._v(" " + _vm._s(item[_vm.subtitleField]) + " ")]) : _vm._e()]), !_vm.isViewMode ? _c('div', {
96246
+ staticClass: "remove-btn",
96247
+ on: {
96248
+ "click": function ($event) {
96249
+ return _vm.removeItem(item, index);
96250
+ }
96251
+ }
96252
+ }, [_c('i', {
96253
+ staticClass: "el-icon-close"
96254
+ })]) : _vm._e()])])];
96192
96255
  }
96193
- }, [_c('i', {
96194
- staticClass: "el-icon-close"
96195
- })]) : _vm._e()]);
96196
- }), _vm.selectedItems.length === 0 ? _c('div', {
96256
+ }], null, false, 2638469921)
96257
+ }) : _c('div', {
96197
96258
  staticClass: "empty-state"
96198
- }, [_vm._v("暂无选中项")]) : _vm._e()], 2)])])])]);
96259
+ }, [_vm._v("暂无选中项")])], 1)])])])]);
96199
96260
  };
96200
- var ByTreePanelvue_type_template_id_af06ba0a_staticRenderFns = [];
96261
+ var ByCascaderPanelProvue_type_template_id_804df886_staticRenderFns = [];
96201
96262
 
96202
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./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/tree-panel/ByTreePanel.vue?vue&type=script&lang=js
96263
+ ;// ./src/components/cascader-panel-pro/cascaderUtilsPro.js
96203
96264
 
96204
96265
 
96205
96266
 
@@ -96208,374 +96269,2753 @@ var ByTreePanelvue_type_template_id_af06ba0a_staticRenderFns = [];
96208
96269
 
96209
96270
 
96210
96271
 
96211
- /* harmony default export */ var ByTreePanelvue_type_script_lang_js = ({
96212
- name: 'ByTreePanel',
96213
- props: {
96214
- options: {
96215
- type: Array,
96216
- default: () => []
96217
- },
96218
- value: {
96219
- type: [Array, Number, String],
96220
- default: () => []
96221
- },
96222
- cascaderProps: {
96223
- type: Object,
96224
- default: () => ({
96225
- multiple: true,
96226
- label: 'label',
96227
- value: 'value',
96228
- children: 'children'
96229
- })
96230
- },
96231
- panelHeight: {
96232
- type: [String, Number],
96233
- default: 300
96234
- },
96235
- searchPlaceholder: {
96236
- type: String,
96237
- default: '请输入名称搜索'
96238
- },
96239
- disabledField: {
96240
- type: String,
96241
- default: 'disabled'
96242
- },
96243
- disabledValue: {
96244
- type: [String, Number, Boolean],
96245
- default: true
96246
- },
96247
- disabledCheck: {
96248
- type: Function,
96249
- default: null
96250
- },
96251
- showSelectAll: {
96252
- type: Boolean,
96253
- default: true
96254
- },
96255
- aggregationMode: {
96256
- type: Boolean,
96257
- default: false
96258
- },
96259
- parentNodePrefix: {
96260
- type: String,
96261
- default: '__parent__'
96262
- },
96263
- isViewMode: {
96264
- type: Boolean,
96265
- default: false
96266
- },
96267
- showSubtitle: {
96268
- type: Boolean,
96269
- default: false
96270
- },
96271
- subtitleField: {
96272
- type: String,
96273
- default: ''
96274
- }
96275
- },
96276
- data() {
96277
- return {
96278
- selectedValues: [],
96279
- filteredOptions: [],
96280
- displayOptions: [],
96281
- selectedItems: [],
96282
- searchInput: '',
96283
- totalCount: 0,
96284
- selectedCount: 0,
96285
- isAllSelected: false,
96286
- isInternalUpdate: false,
96287
- batchSearchVisible: false,
96288
- batchSearchContent: '',
96289
- searchDebounceTimer: null,
96290
- isSyncingTree: false
96291
- };
96292
- },
96293
- computed: {
96294
- computedPanelHeight() {
96295
- const height = Number(this.panelHeight);
96296
- if (isNaN(height)) return 300;
96297
- return Math.max(200, Math.min(800, height));
96298
- },
96299
- isMultiple() {
96300
- return this.cascaderProps.multiple !== false;
96301
- },
96302
- valueKey() {
96303
- return this.cascaderProps.value || 'value';
96304
- },
96305
- labelKey() {
96306
- return this.cascaderProps.label || 'label';
96307
- },
96308
- childrenKey() {
96309
- return this.cascaderProps.children || 'children';
96310
- },
96311
- nodeKey() {
96312
- return this.valueKey;
96313
- },
96314
- treeFieldProps() {
96315
- return {
96316
- label: this.labelKey,
96317
- children: this.childrenKey,
96318
- disabled: 'disabled'
96319
- };
96320
- },
96321
- disabledConfig() {
96322
- return {
96323
- disabledField: this.disabledField,
96324
- disabledValue: this.disabledValue,
96325
- disabledCheck: this.disabledCheck
96326
- };
96327
- },
96328
- currentValue() {
96329
- if (this.isMultiple) {
96330
- return this.selectedItems.map(item => item.value);
96331
- }
96332
- return this.selectedItems.length > 0 ? this.selectedItems[0].value : null;
96272
+
96273
+
96274
+
96275
+
96276
+
96277
+
96278
+
96279
+ /**
96280
+ * 级联选择器工具类(Pro 版,独立于 CascaderUtils)
96281
+ */
96282
+ class CascaderUtilsPro {
96283
+ /**
96284
+ * 估算级联节点标签文本宽度(px)
96285
+ */
96286
+ static measureCascaderLabelWidth(label, fontSize = 14) {
96287
+ if (!label) {
96288
+ return 0;
96333
96289
  }
96334
- },
96335
- watch: {
96336
- options: {
96337
- handler() {
96338
- this.initOptions();
96339
- },
96340
- immediate: true
96341
- },
96342
- value: {
96343
- handler() {
96344
- if (this.isInternalUpdate) {
96345
- this.isInternalUpdate = false;
96346
- return;
96347
- }
96348
- if (!this.filteredOptions.length) return;
96349
- this.processValue();
96350
- },
96351
- deep: true
96352
- },
96353
- selectedValues: {
96354
- handler() {
96355
- this.updateSelectAllState();
96356
- },
96357
- deep: true
96290
+ const str = String(label);
96291
+ let width = 0;
96292
+ for (let i = 0; i < str.length; i++) {
96293
+ const code = str.charCodeAt(i);
96294
+ width += code > 255 ? fontSize : Math.ceil(fontSize * 0.55);
96358
96295
  }
96359
- },
96360
- mounted() {
96361
- this.$nextTick(() => {
96362
- this.updateSelectedItems();
96363
- this.syncTreeCheckedState();
96296
+ return width;
96297
+ }
96298
+
96299
+ /**
96300
+ * 根据列内最长标签计算列宽
96301
+ */
96302
+ static getCascaderColumnWidth(nodes, options = {}) {
96303
+ const {
96304
+ minWidth = 180,
96305
+ maxWidth = 420,
96306
+ extraPadding = 56,
96307
+ hasCheckbox = true
96308
+ } = options;
96309
+ if (!nodes || nodes.length === 0) {
96310
+ return minWidth;
96311
+ }
96312
+ let maxLabelWidth = 0;
96313
+ nodes.forEach(node => {
96314
+ maxLabelWidth = Math.max(maxLabelWidth, this.measureCascaderLabelWidth(node.label));
96364
96315
  });
96365
- },
96366
- beforeDestroy() {
96367
- if (this.searchDebounceTimer) {
96368
- clearTimeout(this.searchDebounceTimer);
96316
+ const checkboxWidth = hasCheckbox ? 28 : 0;
96317
+ const arrowWidth = 24;
96318
+ const contentWidth = maxLabelWidth + extraPadding + checkboxWidth + arrowWidth;
96319
+ return Math.min(maxWidth, Math.max(minWidth, Math.ceil(contentWidth)));
96320
+ }
96321
+
96322
+ /**
96323
+ * 判断项目是否禁用
96324
+ * @param {Object} item - 项目数据
96325
+ * @param {Object} config - 禁用配置
96326
+ * @param {String} config.disabledField - 禁用字段名
96327
+ * @param {*} config.disabledValue - 禁用值
96328
+ * @param {Function} config.disabledCheck - 自定义禁用判断函数
96329
+ * @returns {Boolean} 是否禁用
96330
+ */
96331
+ static isItemDisabled(item, config) {
96332
+ const {
96333
+ disabledField,
96334
+ disabledValue,
96335
+ disabledCheck
96336
+ } = config;
96337
+
96338
+ // 优先使用自定义禁用判断函数
96339
+ if (disabledCheck && typeof disabledCheck === 'function') {
96340
+ return disabledCheck(item);
96369
96341
  }
96370
- },
96371
- methods: {
96372
- initOptions() {
96373
- this.filteredOptions = this.processOptions(this.options);
96374
- this.displayOptions = this.filteredOptions;
96375
- this.countTotalItems();
96376
- this.processValue();
96377
- },
96378
- processOptions(options) {
96379
- const processedOptions = this.cloneTree(options);
96380
- if (this.isViewMode) {
96381
- const disabledKey = this.cascaderProps && this.cascaderProps.disabled || 'disabled';
96382
- const dfs = items => {
96383
- items.forEach(item => {
96384
- item[disabledKey] = true;
96385
- if (item[this.childrenKey] && item[this.childrenKey].length > 0) {
96386
- dfs(item[this.childrenKey]);
96342
+
96343
+ // 检查直接的 disabled 属性
96344
+ if (item.disabled === true) {
96345
+ return true;
96346
+ }
96347
+
96348
+ // 使用字段判断
96349
+ const fieldValue = item[disabledField];
96350
+ if (fieldValue !== undefined) {
96351
+ return fieldValue === disabledValue;
96352
+ }
96353
+ return false;
96354
+ }
96355
+
96356
+ /**
96357
+ * 检查路径上是否存在禁选项
96358
+ * @param {Array} tree - 树形数据
96359
+ * @param {Array} path - 路径数组
96360
+ * @param {Object} config - 禁用配置
96361
+ * @param {Object} cascaderProps - 级联配置
96362
+ * @returns {Boolean} 路径上是否存在禁选项
96363
+ */
96364
+ static isPathDisabled(tree, path, config, cascaderProps) {
96365
+ if (!path || path.length === 0) return false;
96366
+ const findPathInTree = (nodes, targetPath, currentIndex = 0) => {
96367
+ if (currentIndex >= targetPath.length) return false;
96368
+ for (const node of nodes) {
96369
+ if (node[cascaderProps.value] === targetPath[currentIndex]) {
96370
+ // 检查当前节点是否禁用
96371
+ if (this.isItemDisabled(node, config)) {
96372
+ return true;
96373
+ }
96374
+
96375
+ // 如果还有下一级,继续检查
96376
+ if (currentIndex < targetPath.length - 1 && node[cascaderProps.children]) {
96377
+ return findPathInTree(node[cascaderProps.children], targetPath, currentIndex + 1);
96378
+ }
96379
+
96380
+ // 如果已经到达路径末尾,返回false(路径上没有禁选项)
96381
+ return false;
96382
+ }
96383
+ }
96384
+ return false;
96385
+ };
96386
+ return findPathInTree(tree, path);
96387
+ }
96388
+
96389
+ /**
96390
+ * 设置禁用项
96391
+ * @param {Array} options - 选项数据
96392
+ * @param {Object} config - 禁用配置
96393
+ * @param {Object} cascaderProps - 级联配置
96394
+ */
96395
+ static setDisabledItems(options, config, cascaderProps) {
96396
+ const processItems = items => {
96397
+ items.forEach(item => {
96398
+ // 判断是否禁用
96399
+ if (this.isItemDisabled(item, config)) {
96400
+ item.disabled = true;
96401
+ }
96402
+ // 递归处理子项
96403
+ if (item[cascaderProps.children]) {
96404
+ processItems(item[cascaderProps.children]);
96405
+ }
96406
+ });
96407
+ };
96408
+ processItems(options);
96409
+ }
96410
+
96411
+ /**
96412
+ * 统计总项目数(排除禁用项和路径上有禁选项的项)
96413
+ * @param {Array} options - 选项数据
96414
+ * @param {Object} config - 禁用配置
96415
+ * @param {Object} cascaderProps - 级联配置
96416
+ * @returns {Number} 总项目数
96417
+ */
96418
+ static countTotalItems(options, config, cascaderProps) {
96419
+ let totalCount = 0;
96420
+ const countItems = (items, currentPath = []) => {
96421
+ items.forEach(item => {
96422
+ const newPath = [...currentPath, item[cascaderProps.value]];
96423
+
96424
+ // 检查当前节点是否禁用
96425
+ const isCurrentDisabled = this.isItemDisabled(item, config);
96426
+ if (!item[cascaderProps.children]) {
96427
+ // 只统计非禁用项且路径上没有禁选项的叶子节点
96428
+ if (!isCurrentDisabled && !this.isPathDisabled(options, newPath, config, cascaderProps)) {
96429
+ totalCount++;
96430
+ }
96431
+ } else {
96432
+ // 如果当前节点禁用,则其所有子节点都不可选
96433
+ if (!isCurrentDisabled) {
96434
+ countItems(item[cascaderProps.children], newPath);
96435
+ }
96436
+ }
96437
+ });
96438
+ };
96439
+ countItems(options);
96440
+ return totalCount;
96441
+ }
96442
+
96443
+ /**
96444
+ * 在树形数据中搜索
96445
+ * @param {Array} tree - 树形数据
96446
+ * @param {String} keyword - 搜索关键词
96447
+ * @param {Object} cascaderProps - 级联配置
96448
+ * @returns {Array} 搜索结果
96449
+ */
96450
+ static searchInTree(tree, keyword, cascaderProps) {
96451
+ const result = [];
96452
+ const labelKey = cascaderProps.label || 'label';
96453
+ const childrenKey = cascaderProps.children || 'children';
96454
+ tree.forEach(node => {
96455
+ const label = node[labelKey];
96456
+ if (label && label.includes(keyword)) {
96457
+ result.push({
96458
+ ...node
96459
+ });
96460
+ } else if (node[childrenKey]) {
96461
+ const matchedChildren = this.searchInTree(node[childrenKey], keyword, cascaderProps);
96462
+ if (matchedChildren.length > 0) {
96463
+ result.push({
96464
+ ...node,
96465
+ [childrenKey]: matchedChildren
96466
+ });
96467
+ }
96468
+ }
96469
+ });
96470
+ return result;
96471
+ }
96472
+
96473
+ /**
96474
+ * 基于扁平 store 快速搜索(父节点命中时直接复用 raw 子树,跳过子级遍历)
96475
+ */
96476
+ static searchFromStore(store, keyword, cascaderProps) {
96477
+ if (!store || !keyword) {
96478
+ return [];
96479
+ }
96480
+ const childrenKey = cascaderProps.children || 'children';
96481
+ const walk = parentId => {
96482
+ const childIds = parentId == null ? store.rootIds : store.childrenByParentId.get(parentId) || [];
96483
+ const result = [];
96484
+ for (let i = 0; i < childIds.length; i++) {
96485
+ const node = store.nodeById.get(childIds[i]);
96486
+ if (!node) {
96487
+ continue;
96488
+ }
96489
+ const label = node.label || '';
96490
+ if (label.includes(keyword)) {
96491
+ result.push({
96492
+ ...node.raw
96493
+ });
96494
+ } else if (!node.isLeaf) {
96495
+ const matchedChildren = walk(node.id);
96496
+ if (matchedChildren.length > 0) {
96497
+ result.push({
96498
+ ...node.raw,
96499
+ [childrenKey]: matchedChildren
96500
+ });
96501
+ }
96502
+ }
96503
+ }
96504
+ return result;
96505
+ };
96506
+ return walk(null);
96507
+ }
96508
+
96509
+ /**
96510
+ * 获取叶子节点的值
96511
+ * @param {Array} tree - 树形数据
96512
+ * @param {Object} cascaderProps - 级联配置
96513
+ * @returns {Array} 叶子节点值数组
96514
+ */
96515
+ static getLeafValues(tree, cascaderProps) {
96516
+ const leafValues = [];
96517
+ const traverse = nodes => {
96518
+ nodes.forEach(node => {
96519
+ if (!node[cascaderProps.children]) {
96520
+ leafValues.push(node[cascaderProps.value]);
96521
+ } else {
96522
+ traverse(node[cascaderProps.children]);
96523
+ }
96524
+ });
96525
+ };
96526
+ traverse(tree);
96527
+ return leafValues;
96528
+ }
96529
+
96530
+ /**
96531
+ * 获取所有叶子节点的路径(排除禁用项和路径上有禁选项的项)
96532
+ * @param {Array} tree - 树形数据
96533
+ * @param {Object} config - 禁用配置
96534
+ * @param {Object} cascaderProps - 级联配置
96535
+ * @returns {Array} 路径数组
96536
+ */
96537
+ static getAllLeafPaths(tree, config, cascaderProps) {
96538
+ const paths = [];
96539
+ const traverse = (nodes, currentPath = []) => {
96540
+ nodes.forEach(node => {
96541
+ const newPath = [...currentPath, node[cascaderProps.value]];
96542
+
96543
+ // 检查当前节点是否禁用
96544
+ const isCurrentDisabled = this.isItemDisabled(node, config);
96545
+ if (!node[cascaderProps.children]) {
96546
+ // 只包含非禁用项且路径上没有禁选项的叶子节点
96547
+ if (!isCurrentDisabled && !this.isPathDisabled(tree, newPath, config, cascaderProps)) {
96548
+ paths.push(newPath);
96549
+ }
96550
+ } else {
96551
+ // 如果当前节点禁用,则其所有子节点都不可选
96552
+ if (!isCurrentDisabled) {
96553
+ traverse(node[cascaderProps.children], newPath);
96554
+ }
96555
+ }
96556
+ });
96557
+ };
96558
+ traverse(tree);
96559
+ return paths;
96560
+ }
96561
+
96562
+ /**
96563
+ * 根据路径查找节点
96564
+ * @param {Array} tree - 树形数据
96565
+ * @param {Array} path - 路径数组
96566
+ * @param {Object} cascaderProps - 级联配置
96567
+ * @returns {Object|null} 找到的节点
96568
+ */
96569
+ static findNodeByPath(tree, path, cascaderProps) {
96570
+ if (!path || path.length === 0) return null;
96571
+ const findInTree = (nodes, targetPath) => {
96572
+ for (const node of nodes) {
96573
+ if (node[cascaderProps.value] == targetPath[0]) {
96574
+ if (targetPath.length === 1) {
96575
+ return node;
96576
+ } else if (node[cascaderProps.children]) {
96577
+ return findInTree(node[cascaderProps.children], targetPath.slice(1));
96578
+ }
96579
+ }
96580
+ }
96581
+ return null;
96582
+ };
96583
+ return findInTree(tree, path);
96584
+ }
96585
+
96586
+ /**
96587
+ * 基于 selectedValues 构建已选项列表
96588
+ * @param {Array} selectedValues - 已选值数组
96589
+ * @param {Array} options - 选项数据
96590
+ * @param {Object} cascaderProps - 级联配置
96591
+ * @returns {Array} 已选项列表
96592
+ */
96593
+ static buildSelectedItemsFromValues(selectedValues, options, cascaderProps) {
96594
+ const items = [];
96595
+ selectedValues.forEach(path => {
96596
+ if (path.length > 0) {
96597
+ const leafValue = path[path.length - 1];
96598
+ // 从原始数据中查找对应的节点信息
96599
+ const node = this.findNodeByPath(options, path, cascaderProps);
96600
+ if (node) {
96601
+ // 包含完整的节点数据,以便访问额外的字段(如子标题字段)
96602
+ items.push({
96603
+ ...node,
96604
+ // 展开所有原始节点数据
96605
+ value: leafValue,
96606
+ label: node[cascaderProps.label],
96607
+ path: path
96608
+ });
96609
+ }
96610
+ }
96611
+ });
96612
+ return items;
96613
+ }
96614
+
96615
+ /**
96616
+ * 从自研面板 selection 直接构建已选项(紧凑模式,避免生成万级路径数组)
96617
+ */
96618
+ static buildSelectedItemsFromSelection(store, selection, options, cascaderProps) {
96619
+ if (!store || !selection) {
96620
+ return [];
96621
+ }
96622
+ const items = [];
96623
+ selection.selectedLeafSet.forEach(leafValue => {
96624
+ const path = store.pathByLeafValue.get(leafValue);
96625
+ const node = store.nodeByValue.get(leafValue);
96626
+ if (!path || !node) {
96627
+ return;
96628
+ }
96629
+ items.push({
96630
+ ...node.raw,
96631
+ value: leafValue,
96632
+ label: node.label,
96633
+ path
96634
+ });
96635
+ });
96636
+ return items;
96637
+ }
96638
+
96639
+ /**
96640
+ * 获取搜索范围内的选中值
96641
+ * @param {Array} selectedValues - 已选值数组
96642
+ * @param {Array} searchOptions - 搜索结果
96643
+ * @param {Object} cascaderProps - 级联配置
96644
+ * @returns {Array} 搜索范围内的选中值
96645
+ */
96646
+ static getSearchSelectedValues(selectedValues, searchOptions, cascaderProps) {
96647
+ const searchLeafValues = this.getLeafValues(searchOptions, cascaderProps);
96648
+ return selectedValues.filter(path => {
96649
+ const leafValue = path[path.length - 1];
96650
+ return searchLeafValues.includes(leafValue);
96651
+ });
96652
+ }
96653
+
96654
+ /**
96655
+ * 检查父项的所有子项是否都被选中
96656
+ * @param {Object} parentNode - 父节点
96657
+ * @param {Array} selectedValues - 已选值数组
96658
+ * @param {Object} cascaderProps - 级联配置
96659
+ * @returns {Boolean} 是否所有子项都被选中
96660
+ */
96661
+ static isParentFullySelected(parentNode, selectedValues, cascaderProps) {
96662
+ if (!parentNode[cascaderProps.children]) {
96663
+ return false;
96664
+ }
96665
+
96666
+ // 获取父项的所有叶子节点
96667
+ const allLeafValues = this.getLeafValues([parentNode], cascaderProps);
96668
+
96669
+ // 检查所有叶子节点是否都在选中值中
96670
+ return allLeafValues.every(leafValue => {
96671
+ return selectedValues.some(path => {
96672
+ const pathLeafValue = path[path.length - 1];
96673
+ return pathLeafValue === leafValue;
96674
+ });
96675
+ });
96676
+ }
96677
+
96678
+ /**
96679
+ * 根据路径获取对应的标签数组
96680
+ * @param {Array} path - 节点路径
96681
+ * @param {Array} options - 选项数据
96682
+ * @param {Object} cascaderProps - 级联配置
96683
+ * @returns {Array} 标签数组
96684
+ */
96685
+ static getPathLabels(path, options, cascaderProps) {
96686
+ const labels = [];
96687
+ let currentNodes = options;
96688
+ for (let i = 0; i < path.length; i++) {
96689
+ const targetValue = path[i];
96690
+ const foundNode = currentNodes.find(node => node[cascaderProps.value] === targetValue);
96691
+ if (foundNode) {
96692
+ labels.push(foundNode[cascaderProps.label]);
96693
+ if (foundNode[cascaderProps.children] && i < path.length - 1) {
96694
+ currentNodes = foundNode[cascaderProps.children];
96695
+ }
96696
+ } else {
96697
+ labels.push(targetValue); // 如果找不到对应的节点,使用原始值
96698
+ }
96699
+ }
96700
+ return labels;
96701
+ }
96702
+
96703
+ /**
96704
+ * 构建完整的节点信息对象
96705
+ * @param {Object} node - 原始节点数据
96706
+ * @param {Array} path - 节点路径
96707
+ * @param {Object} cascaderProps - 级联配置
96708
+ * @param {Array} options - 选项数据
96709
+ * @param {Boolean} isAggregated - 是否为聚合项
96710
+ * @returns {Object} 完整的节点信息对象
96711
+ */
96712
+ static buildCompleteNodeInfo(node, path, cascaderProps, options, isAggregated = false) {
96713
+ const hasChildren = !!node[cascaderProps.children];
96714
+ const level = path.length - 1;
96715
+ return {
96716
+ // 展开原始节点的所有属性,以便访问额外的字段(如子标题字段)
96717
+ ...node,
96718
+ // 基本属性(覆盖原始节点中的同名属性)
96719
+ value: node[cascaderProps.value],
96720
+ label: node[cascaderProps.label],
96721
+ path: path,
96722
+ isAggregated: isAggregated,
96723
+ // 节点结构信息
96724
+ hasChildren: hasChildren,
96725
+ level: level,
96726
+ children: hasChildren ? node[cascaderProps.children] : undefined,
96727
+ // 级联面板相关属性
96728
+ checked: true,
96729
+ indeterminate: false,
96730
+ loaded: true,
96731
+ loading: false,
96732
+ // 原始数据
96733
+ data: node,
96734
+ // 路径相关
96735
+ pathLabels: this.getPathLabels(path, options, cascaderProps),
96736
+ // 其他可能需要的属性
96737
+ config: cascaderProps,
96738
+ parent: null,
96739
+ // 在级联面板中会动态设置
96740
+ pathNodes: null // 在级联面板中会动态设置
96741
+ };
96742
+ }
96743
+
96744
+ /**
96745
+ * 从自研面板的选中状态递归构建聚合列表(与 getAggregatedSelectedItems 逻辑一致)
96746
+ * 父节点全选时只返回父项;半选时向下展开到具体子项
96747
+ */
96748
+ static getAggregatedItemsFromSelection(store, selection, options, cascaderProps) {
96749
+ if (!store || !selection) {
96750
+ return [];
96751
+ }
96752
+ const items = [];
96753
+ const walk = nodeId => {
96754
+ const node = store.nodeById.get(nodeId);
96755
+ if (!node || node.disabled) {
96756
+ return;
96757
+ }
96758
+ const state = selection.getCheckState(nodeId);
96759
+ if (state === 'unchecked' || state === 'disabled') {
96760
+ return;
96761
+ }
96762
+ if (!node.isLeaf && state === 'checked') {
96763
+ items.push(this.buildCompleteNodeInfo(node.raw, node.path, cascaderProps, options, true));
96764
+ return;
96765
+ }
96766
+ if (node.isLeaf && state === 'checked') {
96767
+ items.push(this.buildCompleteNodeInfo(node.raw, node.path, cascaderProps, options, false));
96768
+ return;
96769
+ }
96770
+ const childIds = node.childIds || [];
96771
+ childIds.forEach(childId => walk(childId));
96772
+ };
96773
+ store.rootIds.forEach(rootId => walk(rootId));
96774
+ return items;
96775
+ }
96776
+
96777
+ /** @deprecated 使用 getAggregatedItemsFromSelection */
96778
+ static getAggregatedItemsFromRootSelection(store, selection, options, cascaderProps) {
96779
+ return this.getAggregatedItemsFromSelection(store, selection, options, cascaderProps);
96780
+ }
96781
+ static getAggregatedEmitValues(items, prefix = '__parent__') {
96782
+ return items.map(item => {
96783
+ if (item.isAggregated) {
96784
+ return this.addParentNodePrefix(item.value, prefix);
96785
+ }
96786
+ return item.value;
96787
+ });
96788
+ }
96789
+
96790
+ /**
96791
+ * 获取聚合模式下的选中项(如果父项完全选中,则只返回父项)
96792
+ * @param {Array} selectedValues - 已选值数组
96793
+ * @param {Array} options - 选项数据
96794
+ * @param {Object} cascaderProps - 级联配置
96795
+ * @returns {Array} 聚合后的选中项列表
96796
+ */
96797
+ static getAggregatedSelectedItems(selectedValues, options, cascaderProps) {
96798
+ const items = [];
96799
+ const processedPaths = new Set();
96800
+
96801
+ // 递归检查每个节点
96802
+ const checkNode = (nodes, currentPath = []) => {
96803
+ nodes.forEach(node => {
96804
+ const newPath = [...currentPath, node[cascaderProps.value]];
96805
+ const pathKey = newPath.join(',');
96806
+
96807
+ // 如果这个路径已经被处理过,跳过
96808
+ if (processedPaths.has(pathKey)) {
96809
+ return;
96810
+ }
96811
+
96812
+ // 检查当前节点是否完全选中
96813
+ if (this.isParentFullySelected(node, selectedValues, cascaderProps)) {
96814
+ // 父项完全选中,添加父项
96815
+ items.push(this.buildCompleteNodeInfo(node, newPath, cascaderProps, options, true));
96816
+
96817
+ // 标记所有子路径为已处理
96818
+ const allLeafValues = this.getLeafValues([node], cascaderProps);
96819
+ selectedValues.forEach(path => {
96820
+ const pathLeafValue = path[path.length - 1];
96821
+ if (allLeafValues.includes(pathLeafValue)) {
96822
+ processedPaths.add(path.join(','));
96823
+ }
96824
+ });
96825
+ } else if (!node[cascaderProps.children]) {
96826
+ // 叶子节点,检查是否在选中值中且未被父项覆盖
96827
+ const leafValue = node[cascaderProps.value];
96828
+ const isSelected = selectedValues.some(path => {
96829
+ const pathLeafValue = path[path.length - 1];
96830
+ return pathLeafValue === leafValue;
96831
+ });
96832
+ if (isSelected && !processedPaths.has(pathKey)) {
96833
+ items.push(this.buildCompleteNodeInfo(node, newPath, cascaderProps, options, false));
96834
+ processedPaths.add(pathKey);
96835
+ }
96836
+ } else {
96837
+ // 继续检查子节点
96838
+ checkNode(node[cascaderProps.children], newPath);
96839
+ }
96840
+ });
96841
+ };
96842
+ checkNode(options);
96843
+ return items;
96844
+ }
96845
+
96846
+ /**
96847
+ * 获取聚合模式下的选中值(只返回最终选中的值,不包含被聚合的子项)
96848
+ * @param {Array} selectedValues - 已选值数组
96849
+ * @param {Array} options - 选项数据
96850
+ * @param {Object} cascaderProps - 级联配置
96851
+ * @param {String} prefix - 前缀标识
96852
+ * @returns {Array} 聚合后的选中值
96853
+ */
96854
+ static getAggregatedSelectedValues(selectedValues, options, cascaderProps, prefix = '__parent__') {
96855
+ const aggregatedItems = this.getAggregatedSelectedItems(selectedValues, options, cascaderProps);
96856
+ return aggregatedItems.map(item => {
96857
+ // 如果是聚合项(非叶子节点),添加前缀标识
96858
+ if (item.isAggregated) {
96859
+ return this.addParentNodePrefix(item.value, prefix);
96860
+ }
96861
+ return item.value;
96862
+ });
96863
+ }
96864
+
96865
+ /**
96866
+ * 获取聚合模式下的路径数组(只返回最终选中的路径,不包含被聚合的子项路径)
96867
+ * @param {Array} selectedValues - 已选值数组
96868
+ * @param {Array} options - 选项数据
96869
+ * @param {Object} cascaderProps - 级联配置
96870
+ * @returns {Array} 聚合后的路径数组
96871
+ */
96872
+ static getAggregatedSelectedPaths(selectedValues, options, cascaderProps) {
96873
+ const aggregatedItems = this.getAggregatedSelectedItems(selectedValues, options, cascaderProps);
96874
+ return aggregatedItems.map(item => item.path);
96875
+ }
96876
+
96877
+ /**
96878
+ * 检查聚合模式下是否全选(所有可选的叶子节点都被选中)
96879
+ * @param {Array} selectedValues - 已选值数组
96880
+ * @param {Array} options - 选项数据
96881
+ * @param {Object} config - 禁用配置
96882
+ * @param {Object} cascaderProps - 级联配置
96883
+ * @returns {Boolean} 是否全选
96884
+ */
96885
+ static isAggregatedAllSelected(selectedValues, options, config, cascaderProps) {
96886
+ // 获取所有可选的叶子节点
96887
+ const allSelectableLeafValues = this.getAllLeafPaths(options, config, cascaderProps).map(path => path[path.length - 1]); // 获取叶子节点的值
96888
+
96889
+ // 获取当前选中的叶子节点值
96890
+ const selectedLeafValues = selectedValues.map(path => path[path.length - 1]);
96891
+
96892
+ // 检查所有可选的叶子节点是否都被选中
96893
+ return allSelectableLeafValues.every(leafValue => selectedLeafValues.includes(leafValue));
96894
+ }
96895
+
96896
+ /**
96897
+ * 检查值是否为非叶子节点标识
96898
+ * @param {*} value - 要检查的值
96899
+ * @param {String} prefix - 前缀标识
96900
+ * @returns {Boolean} 是否为非叶子节点标识
96901
+ */
96902
+ static isParentNodeValue(value, prefix = '__parent__') {
96903
+ return typeof value === 'string' && value.startsWith(prefix);
96904
+ }
96905
+
96906
+ /**
96907
+ * 从非叶子节点标识中提取实际值
96908
+ * @param {String} parentValue - 非叶子节点标识值
96909
+ * @param {String} prefix - 前缀标识
96910
+ * @returns {String} 实际值
96911
+ */
96912
+ static extractParentNodeValue(parentValue, prefix = '__parent__') {
96913
+ if (this.isParentNodeValue(parentValue, prefix)) {
96914
+ return parentValue.substring(prefix.length);
96915
+ }
96916
+ return parentValue;
96917
+ }
96918
+
96919
+ /**
96920
+ * 为非叶子节点值添加前缀标识
96921
+ * @param {String} value - 原始值
96922
+ * @param {String} prefix - 前缀标识
96923
+ * @returns {String} 带前缀的值
96924
+ */
96925
+ static addParentNodePrefix(value, prefix = '__parent__') {
96926
+ return prefix + value;
96927
+ }
96928
+
96929
+ /**
96930
+ * 根据非叶子节点值获取其所有叶子节点的路径
96931
+ * @param {String} parentValue - 非叶子节点值
96932
+ * @param {Array} options - 选项数据
96933
+ * @param {Object} cascaderProps - 级联配置
96934
+ * @returns {Array} 叶子节点路径数组
96935
+ */
96936
+ static getLeafPathsByParentValue(parentValue, options, cascaderProps) {
96937
+ const paths = [];
96938
+
96939
+ // 查找非叶子节点
96940
+ const findParentNode = (nodes, currentPath = []) => {
96941
+ for (const node of nodes) {
96942
+ const newPath = [...currentPath, node[cascaderProps.value]];
96943
+ if (node[cascaderProps.value] == parentValue) {
96944
+ // 找到目标非叶子节点,获取其所有叶子节点路径
96945
+ this.getAllLeafPaths([node], {}, cascaderProps).forEach(leafPath => {
96946
+ // 将叶子节点路径与当前路径合并
96947
+ const fullPath = [...currentPath, ...leafPath];
96948
+ paths.push(fullPath);
96949
+ });
96950
+ return true;
96951
+ }
96952
+
96953
+ // 递归查找子节点
96954
+ if (node[cascaderProps.children] && node[cascaderProps.children].length > 0) {
96955
+ if (findParentNode(node[cascaderProps.children], newPath)) {
96956
+ return true;
96957
+ }
96958
+ }
96959
+ }
96960
+ return false;
96961
+ };
96962
+ findParentNode(options);
96963
+ return paths;
96964
+ }
96965
+
96966
+ /**
96967
+ * 处理包含非叶子节点的值数组,将非叶子节点转换为对应的叶子节点路径
96968
+ * @param {Array} values - 值数组(可能包含非叶子节点标识)
96969
+ * @param {Array} options - 选项数据
96970
+ * @param {Object} cascaderProps - 级联配置
96971
+ * @param {String} prefix - 前缀标识
96972
+ * @returns {Array} 处理后的路径数组
96973
+ */
96974
+ static processValuesWithParentNodes(values, options, cascaderProps, prefix = '__parent__') {
96975
+ const paths = [];
96976
+ for (const value of values) {
96977
+ if (this.isParentNodeValue(value, prefix)) {
96978
+ // 非叶子节点,获取其所有叶子节点路径
96979
+ const actualValue = this.extractParentNodeValue(value, prefix);
96980
+ const leafPaths = this.getLeafPathsByParentValue(actualValue, options, cascaderProps);
96981
+ paths.push(...leafPaths);
96982
+ } else {
96983
+ // 普通值,查找对应的路径
96984
+ const valuePaths = this.findPathsByValues([value], options, cascaderProps);
96985
+ paths.push(...valuePaths);
96986
+ }
96987
+ }
96988
+ return paths;
96989
+ }
96990
+
96991
+ /**
96992
+ * 根据values找到对应的路径(支持非叶子节点)
96993
+ * @param {Array} values - 值数组
96994
+ * @param {Array} options - 选项数据
96995
+ * @param {Object} cascaderProps - 级联配置
96996
+ * @returns {Array} 路径数组
96997
+ */
96998
+ static findPathsByValues(values, options, cascaderProps) {
96999
+ const paths = [];
97000
+ const findPath = (nodes, targetValues, currentPath = []) => {
97001
+ for (const option of nodes) {
97002
+ const newPath = [...currentPath, option[cascaderProps.value]];
97003
+ if (targetValues.includes(option[cascaderProps.value])) {
97004
+ // 如果是叶子节点(没有children属性),添加到路径中
97005
+ if (!option[cascaderProps.children]) {
97006
+ paths.push(newPath);
97007
+ }
97008
+ }
97009
+
97010
+ // 递归查找子节点
97011
+ if (option[cascaderProps.children] && option[cascaderProps.children].length > 0) {
97012
+ findPath(option[cascaderProps.children], targetValues, newPath);
97013
+ }
97014
+ }
97015
+ };
97016
+ findPath(options, values);
97017
+ return paths;
97018
+ }
97019
+ }
97020
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"8cd600e8-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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
97021
+ var VirtualCascaderPanelvue_type_template_id_05f77638_render = function render() {
97022
+ var _vm = this,
97023
+ _c = _vm._self._c;
97024
+ return _c('div', {
97025
+ staticClass: "el-cascader-panel vcp-panel is-bordered",
97026
+ style: {
97027
+ height: _vm.height + 'px'
97028
+ }
97029
+ }, _vm._l(_vm.columns, function (columnNodes, colIndex) {
97030
+ return _c('div', {
97031
+ key: 'col-' + colIndex,
97032
+ staticClass: "el-cascader-menu vcp-menu",
97033
+ class: {
97034
+ 'is-last': colIndex === _vm.columns.length - 1
97035
+ },
97036
+ style: _vm.getColumnStyle(colIndex, columnNodes)
97037
+ }, [_c('VcpVirtualList', {
97038
+ attrs: {
97039
+ "items": columnNodes,
97040
+ "item-height": _vm.itemHeight,
97041
+ "height": _vm.height
97042
+ },
97043
+ scopedSlots: _vm._u([{
97044
+ key: "default",
97045
+ fn: function ({
97046
+ item
97047
+ }) {
97048
+ return [_c('li', {
97049
+ key: 'vcp-node-' + item.id,
97050
+ staticClass: "el-cascader-node",
97051
+ class: _vm.getNodeClass(item, colIndex),
97052
+ attrs: {
97053
+ "role": "menuitem",
97054
+ "id": 'vcp-node-' + item.id,
97055
+ "aria-expanded": !item.isLeaf && _vm.isExpanded(item, colIndex),
97056
+ "tabindex": _vm.isActive(item, colIndex) ? 0 : -1
97057
+ },
97058
+ on: {
97059
+ "click": function ($event) {
97060
+ return _vm.onNodeClick(item, colIndex);
97061
+ }
97062
+ }
97063
+ }, [_vm.multiple ? _c('span', {
97064
+ staticClass: "el-cascader-node__prefix"
97065
+ }, [_c('el-checkbox', {
97066
+ attrs: {
97067
+ "value": _vm.isChecked(item),
97068
+ "indeterminate": _vm.isIndeterminate(item),
97069
+ "disabled": item.disabled || _vm.isViewMode
97070
+ },
97071
+ on: {
97072
+ "change": function ($event) {
97073
+ return _vm.onCheckClick(item, $event);
97074
+ }
97075
+ },
97076
+ nativeOn: {
97077
+ "click": function ($event) {
97078
+ $event.stopPropagation();
97079
+ }
97080
+ }
97081
+ })], 1) : _vm.checkStrictly ? _c('span', {
97082
+ staticClass: "el-cascader-node__prefix",
97083
+ on: {
97084
+ "click": function ($event) {
97085
+ $event.stopPropagation();
97086
+ return _vm.onRadioClick(item);
97087
+ }
97088
+ }
97089
+ }, [_c('el-radio', {
97090
+ attrs: {
97091
+ "value": _vm.singleCheckedValue,
97092
+ "label": item.value,
97093
+ "disabled": item.disabled || _vm.isViewMode
97094
+ },
97095
+ on: {
97096
+ "input": function ($event) {
97097
+ return _vm.onRadioClick(item);
97098
+ }
97099
+ }
97100
+ }, [_c('span')])], 1) : _vm._e(), _c('span', {
97101
+ staticClass: "el-cascader-node__label"
97102
+ }, [_vm._v(_vm._s(item.label))]), !item.isLeaf ? _c('span', {
97103
+ staticClass: "el-cascader-node__postfix"
97104
+ }, [_c('i', {
97105
+ staticClass: "el-icon-arrow-right el-cascader-node__icon-arrow"
97106
+ })]) : _vm._e()])];
97107
+ }
97108
+ }], null, true)
97109
+ })], 1);
97110
+ }), 0);
97111
+ };
97112
+ var VirtualCascaderPanelvue_type_template_id_05f77638_staticRenderFns = [];
97113
+
97114
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"8cd600e8-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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
97115
+ var VirtualListvue_type_template_id_43cb1148_render = function render() {
97116
+ var _vm = this,
97117
+ _c = _vm._self._c;
97118
+ return _c('div', {
97119
+ ref: "scroller",
97120
+ staticClass: "vcp-virtual-scroller el-scrollbar__wrap",
97121
+ on: {
97122
+ "scroll": _vm.onScroll
97123
+ }
97124
+ }, [!_vm.enableVirtual ? _c('ul', {
97125
+ staticClass: "el-cascader-menu__list vcp-native-list"
97126
+ }, [_vm._l(_vm.items, function (item, index) {
97127
+ return [_vm._t("default", null, {
97128
+ "item": item,
97129
+ "index": index
97130
+ })];
97131
+ })], 2) : [_c('div', {
97132
+ staticClass: "vcp-virtual-phantom",
97133
+ style: {
97134
+ height: _vm.totalHeight + 'px'
97135
+ }
97136
+ }), _c('ul', {
97137
+ staticClass: "el-cascader-menu__list vcp-virtual-list",
97138
+ style: {
97139
+ transform: 'translateY(' + _vm.offsetY + 'px)'
97140
+ }
97141
+ }, [_vm._l(_vm.visibleItems, function (item, index) {
97142
+ return [_vm._t("default", null, {
97143
+ "item": item,
97144
+ "index": _vm.startIndex + index
97145
+ })];
97146
+ })], 2)]], 2);
97147
+ };
97148
+ var VirtualListvue_type_template_id_43cb1148_staticRenderFns = [];
97149
+
97150
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./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=script&lang=js
97151
+ /* harmony default export */ var VirtualListvue_type_script_lang_js = ({
97152
+ name: 'VcpVirtualList',
97153
+ props: {
97154
+ items: {
97155
+ type: Array,
97156
+ default: () => []
97157
+ },
97158
+ itemHeight: {
97159
+ type: Number,
97160
+ default: 34
97161
+ },
97162
+ height: {
97163
+ type: Number,
97164
+ default: 200
97165
+ },
97166
+ overscan: {
97167
+ type: Number,
97168
+ default: 8
97169
+ },
97170
+ listPadding: {
97171
+ type: Number,
97172
+ default: 12
97173
+ }
97174
+ },
97175
+ data() {
97176
+ return {
97177
+ scrollTop: 0
97178
+ };
97179
+ },
97180
+ computed: {
97181
+ totalHeight() {
97182
+ return this.items.length * this.itemHeight + this.listPadding;
97183
+ },
97184
+ enableVirtual() {
97185
+ return this.totalHeight > this.height;
97186
+ },
97187
+ startIndex() {
97188
+ const index = Math.floor(this.scrollTop / this.itemHeight) - this.overscan;
97189
+ return Math.max(0, index);
97190
+ },
97191
+ endIndex() {
97192
+ const visibleCount = Math.ceil(this.height / this.itemHeight) + this.overscan * 2;
97193
+ return Math.min(this.items.length, this.startIndex + visibleCount);
97194
+ },
97195
+ offsetY() {
97196
+ return this.startIndex * this.itemHeight;
97197
+ },
97198
+ visibleItems() {
97199
+ return this.items.slice(this.startIndex, this.endIndex);
97200
+ }
97201
+ },
97202
+ watch: {
97203
+ items(newItems, oldItems) {
97204
+ if (!this.isSameItemList(newItems, oldItems)) {
97205
+ this.resetScroll();
97206
+ }
97207
+ },
97208
+ enableVirtual(newVal, oldVal) {
97209
+ if (newVal !== oldVal) {
97210
+ this.resetScroll();
97211
+ }
97212
+ }
97213
+ },
97214
+ methods: {
97215
+ isSameItemList(nextItems, prevItems) {
97216
+ if (!nextItems || !prevItems) {
97217
+ return false;
97218
+ }
97219
+ if (nextItems.length !== prevItems.length) {
97220
+ return false;
97221
+ }
97222
+ for (let i = 0; i < nextItems.length; i++) {
97223
+ if (this.getItemKey(nextItems[i]) !== this.getItemKey(prevItems[i])) {
97224
+ return false;
97225
+ }
97226
+ }
97227
+ return true;
97228
+ },
97229
+ getItemKey(item) {
97230
+ if (!item) {
97231
+ return '';
97232
+ }
97233
+ return item.id != null ? item.id : item.value;
97234
+ },
97235
+ onScroll(event) {
97236
+ this.scrollTop = event.target.scrollTop;
97237
+ },
97238
+ resetScroll() {
97239
+ this.scrollTop = 0;
97240
+ if (this.$refs.scroller) {
97241
+ this.$refs.scroller.scrollTop = 0;
97242
+ }
97243
+ }
97244
+ }
97245
+ });
97246
+ ;// ./src/components/cascader-panel-pro/VirtualList.vue?vue&type=script&lang=js
97247
+ /* harmony default export */ var cascader_panel_pro_VirtualListvue_type_script_lang_js = (VirtualListvue_type_script_lang_js);
97248
+ ;// ./src/components/cascader-panel-pro/VirtualList.vue
97249
+
97250
+
97251
+
97252
+
97253
+
97254
+ /* normalize component */
97255
+ ;
97256
+ var VirtualList_component = normalizeComponent(
97257
+ cascader_panel_pro_VirtualListvue_type_script_lang_js,
97258
+ VirtualListvue_type_template_id_43cb1148_render,
97259
+ VirtualListvue_type_template_id_43cb1148_staticRenderFns,
97260
+ false,
97261
+ null,
97262
+ null,
97263
+ null
97264
+
97265
+ )
97266
+
97267
+ /* harmony default export */ var VirtualList = (VirtualList_component.exports);
97268
+ ;// ./src/components/cascader-panel-pro/cascaderStorePro.js
97269
+
97270
+
97271
+
97272
+
97273
+
97274
+
97275
+ /**
97276
+ * 级联树扁平化存储,初始化时预计算子树叶子元数据,供 O(1) 级勾选/聚合
97277
+ */
97278
+
97279
+ let nodeIdSeed = 0;
97280
+ function nextId() {
97281
+ nodeIdSeed += 1;
97282
+ return nodeIdSeed;
97283
+ }
97284
+ function resetCascaderStoreIdSeed() {
97285
+ nodeIdSeed = 0;
97286
+ }
97287
+
97288
+ /**
97289
+ * @param {Array} options
97290
+ * @param {Object} config - disabledField/disabledValue/disabledCheck
97291
+ * @param {Object} cascaderProps
97292
+ * @param {Object} utils - CascaderUtilsPro
97293
+ */
97294
+ function buildCascaderStore(options, config, cascaderProps, utils) {
97295
+ resetCascaderStoreIdSeed();
97296
+ const valueKey = cascaderProps.value || 'value';
97297
+ const labelKey = cascaderProps.label || 'label';
97298
+ const childrenKey = cascaderProps.children || 'children';
97299
+ const disabledKey = cascaderProps.disabled || 'disabled';
97300
+ const nodes = [];
97301
+ const nodeById = new Map();
97302
+ const nodeByValue = new Map();
97303
+ const childrenByParentId = new Map();
97304
+ const rootIds = [];
97305
+ const pathByLeafValue = new Map();
97306
+ const allLeafValues = [];
97307
+ const allLeafPaths = [];
97308
+ const createNode = (raw, parentPath, level, parentId) => {
97309
+ const value = raw[valueKey];
97310
+ const children = raw[childrenKey];
97311
+ const hasChildren = Array.isArray(children) && children.length > 0;
97312
+ const id = nextId();
97313
+ const nodePath = parentId == null ? [value] : parentPath.concat(value);
97314
+ const node = {
97315
+ id,
97316
+ value,
97317
+ label: raw[labelKey],
97318
+ path: nodePath,
97319
+ level,
97320
+ parentId,
97321
+ childIds: [],
97322
+ isLeaf: !hasChildren,
97323
+ disabled: !!raw[disabledKey],
97324
+ raw,
97325
+ descendantLeafValues: [],
97326
+ descendantLeafCount: 0,
97327
+ descendantPaths: []
97328
+ };
97329
+ nodes.push(node);
97330
+ nodeById.set(id, node);
97331
+ if (!nodeByValue.has(value)) {
97332
+ nodeByValue.set(value, node);
97333
+ }
97334
+ if (parentId == null) {
97335
+ rootIds.push(id);
97336
+ } else {
97337
+ const siblings = childrenByParentId.get(parentId) || [];
97338
+ siblings.push(id);
97339
+ childrenByParentId.set(parentId, siblings);
97340
+ const parent = nodeById.get(parentId);
97341
+ if (parent) {
97342
+ parent.childIds.push(id);
97343
+ }
97344
+ }
97345
+ if (hasChildren) {
97346
+ children.forEach(child => {
97347
+ createNode(child, nodePath, level + 1, id);
97348
+ });
97349
+ } else if (!node.disabled) {
97350
+ pathByLeafValue.set(value, nodePath);
97351
+ allLeafValues.push(value);
97352
+ allLeafPaths.push(nodePath);
97353
+ }
97354
+ return node;
97355
+ };
97356
+ const walkRoots = (items, ancestorDisabled = false) => {
97357
+ items.forEach(item => {
97358
+ const isDisabled = ancestorDisabled || utils.isItemDisabled(item, config);
97359
+ const cloned = {
97360
+ ...item
97361
+ };
97362
+ if (isDisabled) {
97363
+ cloned[disabledKey] = true;
97364
+ }
97365
+ createNode(cloned, [], 0, null);
97366
+ });
97367
+ };
97368
+ walkRoots(options || []);
97369
+
97370
+ // 自底向上汇总子树叶子
97371
+ const sorted = nodes.slice().sort((a, b) => b.level - a.level);
97372
+ sorted.forEach(node => {
97373
+ if (node.isLeaf) {
97374
+ if (!node.disabled) {
97375
+ node.descendantLeafValues = [node.value];
97376
+ node.descendantLeafCount = 1;
97377
+ node.descendantPaths = [node.path];
97378
+ }
97379
+ return;
97380
+ }
97381
+ const leafValues = [];
97382
+ const leafPaths = [];
97383
+ node.childIds.forEach(childId => {
97384
+ const child = nodeById.get(childId);
97385
+ if (!child || child.descendantLeafCount === 0) {
97386
+ return;
97387
+ }
97388
+ leafValues.push(...child.descendantLeafValues);
97389
+ leafPaths.push(...child.descendantPaths);
97390
+ });
97391
+ node.descendantLeafValues = leafValues;
97392
+ node.descendantLeafCount = leafValues.length;
97393
+ node.descendantPaths = leafPaths;
97394
+ });
97395
+ return {
97396
+ nodes,
97397
+ nodeById,
97398
+ nodeByValue,
97399
+ childrenByParentId,
97400
+ rootIds,
97401
+ pathByLeafValue,
97402
+ allLeafValues,
97403
+ allLeafPaths,
97404
+ totalLeafCount: allLeafPaths.length
97405
+ };
97406
+ }
97407
+ function getStoreChildren(store, parentId) {
97408
+ if (parentId == null) {
97409
+ return store.rootIds.map(id => store.nodeById.get(id)).filter(Boolean);
97410
+ }
97411
+ const childIds = store.childrenByParentId.get(parentId) || [];
97412
+ return childIds.map(id => store.nodeById.get(id)).filter(Boolean);
97413
+ }
97414
+ function findStoreNodeByPath(store, pathValues) {
97415
+ if (!pathValues || pathValues.length === 0) {
97416
+ return null;
97417
+ }
97418
+ let node = store.nodeByValue.get(pathValues[0]);
97419
+ if (!node || pathValues.length === 1) {
97420
+ return node;
97421
+ }
97422
+ for (let i = 1; i < pathValues.length; i++) {
97423
+ const target = pathValues[i];
97424
+ const children = getStoreChildren(store, node.id);
97425
+ node = children.find(child => child.value == target) || null;
97426
+ if (!node) {
97427
+ return null;
97428
+ }
97429
+ }
97430
+ return node;
97431
+ }
97432
+ ;// ./src/components/cascader-panel-pro/selectionStatePro.js
97433
+
97434
+
97435
+
97436
+
97437
+
97438
+
97439
+
97440
+
97441
+
97442
+
97443
+ const COMPACT_EMIT_THRESHOLD = 300;
97444
+
97445
+ class SelectionStatePro {
97446
+ constructor(store) {
97447
+ this.store = store;
97448
+ this.selectedLeafSet = new Set();
97449
+ this.subtreeSelectedCount = new Map();
97450
+ }
97451
+ clear() {
97452
+ this.selectedLeafSet.clear();
97453
+ this.subtreeSelectedCount.clear();
97454
+ }
97455
+ isEmpty() {
97456
+ return this.selectedLeafSet.size === 0;
97457
+ }
97458
+ size() {
97459
+ return this.selectedLeafSet.size;
97460
+ }
97461
+ _incAncestors(nodeId, delta) {
97462
+ let current = this.store.nodeById.get(nodeId);
97463
+ while (current) {
97464
+ const prev = this.subtreeSelectedCount.get(current.id) || 0;
97465
+ const next = prev + delta;
97466
+ if (next <= 0) {
97467
+ this.subtreeSelectedCount.delete(current.id);
97468
+ } else {
97469
+ this.subtreeSelectedCount.set(current.id, next);
97470
+ }
97471
+ if (current.parentId == null) {
97472
+ break;
97473
+ }
97474
+ current = this.store.nodeById.get(current.parentId);
97475
+ }
97476
+ }
97477
+
97478
+ /**
97479
+ * 自底向上重算 nodeId 子树内各层选中数
97480
+ */
97481
+ _reconcileSubtreeCounts(nodeId) {
97482
+ const node = this.store.nodeById.get(nodeId);
97483
+ if (!node) {
97484
+ return 0;
97485
+ }
97486
+ if (node.isLeaf) {
97487
+ return this.selectedLeafSet.has(node.value) ? 1 : 0;
97488
+ }
97489
+ let selected = 0;
97490
+ node.childIds.forEach(childId => {
97491
+ selected += this._reconcileSubtreeCounts(childId);
97492
+ });
97493
+ if (selected > 0) {
97494
+ this.subtreeSelectedCount.set(nodeId, selected);
97495
+ } else {
97496
+ this.subtreeSelectedCount.delete(nodeId);
97497
+ }
97498
+ return selected;
97499
+ }
97500
+
97501
+ /**
97502
+ * 从当前节点向上汇总祖先的选中数(勾选子节点后父级需半选/全选)
97503
+ */
97504
+ _reconcileAncestors(nodeId) {
97505
+ var _this$store$nodeById$;
97506
+ let parentId = (_this$store$nodeById$ = this.store.nodeById.get(nodeId)) === null || _this$store$nodeById$ === void 0 ? void 0 : _this$store$nodeById$.parentId;
97507
+ while (parentId != null) {
97508
+ const parent = this.store.nodeById.get(parentId);
97509
+ if (!parent) {
97510
+ break;
97511
+ }
97512
+ let selected = 0;
97513
+ parent.childIds.forEach(childId => {
97514
+ const child = this.store.nodeById.get(childId);
97515
+ if (!child) {
97516
+ return;
97517
+ }
97518
+ if (child.isLeaf) {
97519
+ if (this.selectedLeafSet.has(child.value)) {
97520
+ selected++;
97521
+ }
97522
+ } else {
97523
+ selected += this.subtreeSelectedCount.get(childId) || 0;
97524
+ }
97525
+ });
97526
+ if (selected > 0) {
97527
+ this.subtreeSelectedCount.set(parentId, selected);
97528
+ } else {
97529
+ this.subtreeSelectedCount.delete(parentId);
97530
+ }
97531
+ parentId = parent.parentId;
97532
+ }
97533
+ }
97534
+ _reconcileAllRoots() {
97535
+ this.subtreeSelectedCount.clear();
97536
+ this.store.rootIds.forEach(rootId => {
97537
+ this._reconcileSubtreeCounts(rootId);
97538
+ });
97539
+ }
97540
+ _applyLeaf(value, checked) {
97541
+ const has = this.selectedLeafSet.has(value);
97542
+ if (checked && !has) {
97543
+ this.selectedLeafSet.add(value);
97544
+ const node = this.store.nodeByValue.get(value);
97545
+ if (node) {
97546
+ this._incAncestors(node.id, 1);
97547
+ }
97548
+ } else if (!checked && has) {
97549
+ this.selectedLeafSet.delete(value);
97550
+ const node = this.store.nodeByValue.get(value);
97551
+ if (node) {
97552
+ this._incAncestors(node.id, -1);
97553
+ }
97554
+ }
97555
+ }
97556
+ toggleNode(nodeId, checked) {
97557
+ const node = this.store.nodeById.get(nodeId);
97558
+ if (!node || node.disabled) {
97559
+ return;
97560
+ }
97561
+ if (node.isLeaf) {
97562
+ const had = this.selectedLeafSet.has(node.value);
97563
+ this._applyLeaf(node.value, checked);
97564
+ if (had !== this.selectedLeafSet.has(node.value)) {
97565
+ this._reconcileAncestors(node.id);
97566
+ }
97567
+ return;
97568
+ }
97569
+ const leaves = node.descendantLeafValues;
97570
+ if (leaves.length === 0) {
97571
+ return;
97572
+ }
97573
+ let changedCount = 0;
97574
+ leaves.forEach(v => {
97575
+ const has = this.selectedLeafSet.has(v);
97576
+ if (checked) {
97577
+ if (!has) {
97578
+ this.selectedLeafSet.add(v);
97579
+ changedCount++;
97580
+ }
97581
+ } else if (has) {
97582
+ this.selectedLeafSet.delete(v);
97583
+ changedCount++;
97584
+ }
97585
+ });
97586
+ if (changedCount > 0) {
97587
+ this._reconcileSubtreeCounts(nodeId);
97588
+ this._reconcileAncestors(nodeId);
97589
+ }
97590
+ }
97591
+ selectAll() {
97592
+ this.clear();
97593
+ const leaves = this.store.allLeafValues;
97594
+ leaves.forEach(v => this.selectedLeafSet.add(v));
97595
+ this._reconcileAllRoots();
97596
+ }
97597
+ syncFromPaths(paths) {
97598
+ this.clear();
97599
+ if (!Array.isArray(paths) || paths.length === 0) {
97600
+ return;
97601
+ }
97602
+ paths.forEach(path => {
97603
+ if (!Array.isArray(path) || path.length === 0) {
97604
+ return;
97605
+ }
97606
+ const leafValue = path[path.length - 1];
97607
+ if (this.store.pathByLeafValue.has(leafValue)) {
97608
+ this.selectedLeafSet.add(leafValue);
97609
+ }
97610
+ });
97611
+ this._reconcileAllRoots();
97612
+ }
97613
+ getCheckState(nodeId) {
97614
+ const node = this.store.nodeById.get(nodeId);
97615
+ if (!node || node.disabled) {
97616
+ return 'disabled';
97617
+ }
97618
+ if (node.isLeaf) {
97619
+ return this.selectedLeafSet.has(node.value) ? 'checked' : 'unchecked';
97620
+ }
97621
+ const total = node.descendantLeafCount;
97622
+ if (total === 0) {
97623
+ return 'unchecked';
97624
+ }
97625
+ const selected = this.subtreeSelectedCount.get(node.id) || 0;
97626
+ if (selected === 0) {
97627
+ return 'unchecked';
97628
+ }
97629
+ if (selected >= total) {
97630
+ return 'checked';
97631
+ }
97632
+ return 'indeterminate';
97633
+ }
97634
+ isChecked(nodeId) {
97635
+ return this.getCheckState(nodeId) === 'checked';
97636
+ }
97637
+ isIndeterminate(nodeId) {
97638
+ return this.getCheckState(nodeId) === 'indeterminate';
97639
+ }
97640
+ isPathInCheckedValues(path) {
97641
+ if (!path || path.length === 0) {
97642
+ return false;
97643
+ }
97644
+ const leafValue = path[path.length - 1];
97645
+ return this.selectedLeafSet.has(leafValue);
97646
+ }
97647
+ isNodeInCheckedPath(node) {
97648
+ if (!node) {
97649
+ return false;
97650
+ }
97651
+ return this.isPathInCheckedValues(node.path);
97652
+ }
97653
+ getCheckedPaths() {
97654
+ const paths = [];
97655
+ this.selectedLeafSet.forEach(leafValue => {
97656
+ const path = this.store.pathByLeafValue.get(leafValue);
97657
+ if (path) {
97658
+ paths.push(path);
97659
+ }
97660
+ });
97661
+ return paths;
97662
+ }
97663
+ isCompactSelection() {
97664
+ return this.selectedLeafSet.size >= COMPACT_EMIT_THRESHOLD;
97665
+ }
97666
+
97667
+ /** 从聚合父节点值快速同步(如 __parent__province_0) */
97668
+ syncFromParentValues(parentValues, prefix = '__parent__') {
97669
+ this.clear();
97670
+ if (!Array.isArray(parentValues) || parentValues.length === 0) {
97671
+ return;
97672
+ }
97673
+ parentValues.forEach(val => {
97674
+ let rootValue = val;
97675
+ if (typeof val === 'string' && val.startsWith(prefix)) {
97676
+ rootValue = val.substring(prefix.length);
97677
+ }
97678
+ const node = this.store.nodeByValue.get(rootValue);
97679
+ if (node && !node.isLeaf && !node.disabled) {
97680
+ node.descendantLeafValues.forEach(v => this.selectedLeafSet.add(v));
97681
+ }
97682
+ });
97683
+ this._reconcileAllRoots();
97684
+ }
97685
+ }
97686
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./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=script&lang=js
97687
+
97688
+
97689
+
97690
+
97691
+
97692
+
97693
+
97694
+
97695
+ /* harmony default export */ var VirtualCascaderPanelvue_type_script_lang_js = ({
97696
+ name: 'VirtualCascaderPanel',
97697
+ components: {
97698
+ VcpVirtualList: VirtualList
97699
+ },
97700
+ props: {
97701
+ value: {
97702
+ type: [Array, String, Number],
97703
+ default: () => []
97704
+ },
97705
+ options: {
97706
+ type: Array,
97707
+ default: () => []
97708
+ },
97709
+ props: {
97710
+ type: Object,
97711
+ default: () => ({
97712
+ multiple: true,
97713
+ label: 'label',
97714
+ value: 'value',
97715
+ children: 'children',
97716
+ checkStrictly: false
97717
+ })
97718
+ },
97719
+ height: {
97720
+ type: Number,
97721
+ default: 280
97722
+ },
97723
+ columnMinWidth: {
97724
+ type: Number,
97725
+ default: 180
97726
+ },
97727
+ columnMaxWidth: {
97728
+ type: Number,
97729
+ default: 420
97730
+ },
97731
+ disabledConfig: {
97732
+ type: Object,
97733
+ default: () => ({})
97734
+ },
97735
+ isViewMode: {
97736
+ type: Boolean,
97737
+ default: false
97738
+ },
97739
+ autoExpandDeep: {
97740
+ type: Boolean,
97741
+ default: true
97742
+ },
97743
+ // 是否从 value prop 同步选中(紧凑模式下由面板内部维护选中状态)
97744
+ syncValueFromParent: {
97745
+ type: Boolean,
97746
+ default: true
97747
+ }
97748
+ },
97749
+ data() {
97750
+ return {
97751
+ store: null,
97752
+ selection: null,
97753
+ activePath: [],
97754
+ itemHeight: 34,
97755
+ syncingValue: false,
97756
+ suppressValueSync: false,
97757
+ selectionTick: 0
97758
+ };
97759
+ },
97760
+ computed: {
97761
+ multiple() {
97762
+ return this.props.multiple !== false;
97763
+ },
97764
+ checkStrictly() {
97765
+ return !!this.props.checkStrictly;
97766
+ },
97767
+ columns() {
97768
+ if (!this.store) {
97769
+ return [];
97770
+ }
97771
+ const cols = [getStoreChildren(this.store, null)];
97772
+ this.activePath.forEach(nodeId => {
97773
+ const node = this.store.nodeById.get(nodeId);
97774
+ if (!node || node.isLeaf) {
97775
+ return;
97776
+ }
97777
+ const children = getStoreChildren(this.store, nodeId);
97778
+ if (children.length > 0) {
97779
+ cols.push(children);
97780
+ }
97781
+ });
97782
+ return cols;
97783
+ },
97784
+ singleCheckedValue() {
97785
+ if (this.multiple || !Array.isArray(this.value) || this.value.length === 0) {
97786
+ return null;
97787
+ }
97788
+ const path = Array.isArray(this.value[0]) ? this.value[0] : this.value;
97789
+ return path[path.length - 1];
97790
+ }
97791
+ },
97792
+ watch: {
97793
+ options: {
97794
+ handler() {
97795
+ this.rebuildStore();
97796
+ }
97797
+ },
97798
+ value: {
97799
+ handler() {
97800
+ if (this.suppressValueSync || !this.syncValueFromParent) {
97801
+ return;
97802
+ }
97803
+ this.syncFromValue();
97804
+ },
97805
+ deep: false
97806
+ },
97807
+ activePath: {
97808
+ handler() {
97809
+ this.$nextTick(() => {
97810
+ this.syncHorizontalOverflow();
97811
+ });
97812
+ },
97813
+ deep: true
97814
+ }
97815
+ },
97816
+ created() {
97817
+ this.rebuildStore();
97818
+ },
97819
+ mounted() {
97820
+ this._onWindowResize = () => {
97821
+ this.syncHorizontalOverflow();
97822
+ };
97823
+ window.addEventListener('resize', this._onWindowResize, {
97824
+ passive: true
97825
+ });
97826
+ this.syncHorizontalOverflow();
97827
+ },
97828
+ beforeDestroy() {
97829
+ if (this._onWindowResize) {
97830
+ window.removeEventListener('resize', this._onWindowResize);
97831
+ this._onWindowResize = null;
97832
+ }
97833
+ if (this._hScrollRaf) {
97834
+ cancelAnimationFrame(this._hScrollRaf);
97835
+ this._hScrollRaf = null;
97836
+ }
97837
+ },
97838
+ methods: {
97839
+ syncHorizontalOverflow() {
97840
+ if (this._hScrollRaf) {
97841
+ cancelAnimationFrame(this._hScrollRaf);
97842
+ }
97843
+ this._hScrollRaf = requestAnimationFrame(() => {
97844
+ this._hScrollRaf = null;
97845
+ const panel = this.$el;
97846
+ const wrapper = panel && panel.closest('.cascader-content-wrapper');
97847
+ if (!panel || !wrapper) {
97848
+ return;
97849
+ }
97850
+ const overflow = panel.scrollWidth - wrapper.clientWidth;
97851
+ const hadScroll = wrapper.classList.contains('is-horizontal-scroll');
97852
+ // 滞回区间,避免边界宽度下 overflow 来回切换
97853
+ const needsScroll = hadScroll ? overflow > -4 : overflow > 1;
97854
+ if (needsScroll !== hadScroll) {
97855
+ wrapper.classList.toggle('is-horizontal-scroll', needsScroll);
97856
+ }
97857
+ });
97858
+ },
97859
+ getColumnStyle(colIndex, columnNodes) {
97860
+ const width = CascaderUtilsPro.getCascaderColumnWidth(columnNodes, {
97861
+ minWidth: this.columnMinWidth,
97862
+ maxWidth: this.columnMaxWidth,
97863
+ hasCheckbox: this.multiple || this.checkStrictly
97864
+ });
97865
+ return {
97866
+ width: width + 'px',
97867
+ minWidth: width + 'px',
97868
+ maxWidth: width + 'px'
97869
+ };
97870
+ },
97871
+ rebuildStore() {
97872
+ this.store = buildCascaderStore(this.options, this.disabledConfig, this.props, CascaderUtilsPro);
97873
+ this.selection = new SelectionStatePro(this.store);
97874
+ this.activePath = [];
97875
+ if (this.syncValueFromParent) {
97876
+ this.syncFromValue();
97877
+ }
97878
+ this.$nextTick(() => {
97879
+ this.syncHorizontalOverflow();
97880
+ if (!this.syncValueFromParent) {
97881
+ this.$emit('store-ready');
97882
+ }
97883
+ });
97884
+ },
97885
+ syncFromValue() {
97886
+ if (!this.selection) {
97887
+ return;
97888
+ }
97889
+ this.syncingValue = true;
97890
+ if (this.multiple) {
97891
+ const paths = Array.isArray(this.value) ? this.value : [];
97892
+ this.selection.syncFromPaths(paths);
97893
+ } else {
97894
+ const path = this.normalizeSinglePath(this.value);
97895
+ this.selection.syncFromPaths(path ? [path] : []);
97896
+ if (path && path.length > 1) {
97897
+ this.expandPathValues(path.slice(0, -1), false);
97898
+ }
97899
+ }
97900
+ this.syncingValue = false;
97901
+ },
97902
+ normalizeSinglePath(val) {
97903
+ if (val == null || val === '') {
97904
+ return null;
97905
+ }
97906
+ if (Array.isArray(val)) {
97907
+ if (val.length === 0) {
97908
+ return null;
97909
+ }
97910
+ if (Array.isArray(val[0])) {
97911
+ return val[0];
97912
+ }
97913
+ return val;
97914
+ }
97915
+ const node = this.store && this.store.nodeByValue.get(val);
97916
+ if (node) {
97917
+ return node.path;
97918
+ }
97919
+ return [val];
97920
+ },
97921
+ emitValue() {
97922
+ if (this.syncingValue || !this.selection) {
97923
+ return;
97924
+ }
97925
+ if (this.selection.isCompactSelection()) {
97926
+ this.$emit('change', {
97927
+ compact: true,
97928
+ count: this.selection.size()
97929
+ });
97930
+ return;
97931
+ }
97932
+ let emitVal;
97933
+ if (this.multiple) {
97934
+ emitVal = this.selection.getCheckedPaths();
97935
+ } else {
97936
+ const paths = this.selection.getCheckedPaths();
97937
+ emitVal = paths.length > 0 ? paths[0] : [];
97938
+ }
97939
+ this.$emit('input', emitVal);
97940
+ this.$emit('change', emitVal);
97941
+ },
97942
+ isActive(node, colIndex) {
97943
+ return colIndex < this.activePath.length && this.activePath[colIndex] === node.id;
97944
+ },
97945
+ isExpanded(node, colIndex) {
97946
+ return this.activePath[colIndex] === node.id;
97947
+ },
97948
+ isInActivePath(node) {
97949
+ return this.activePath.includes(node.id);
97950
+ },
97951
+ getNodeClass(node, colIndex) {
97952
+ return {
97953
+ 'is-selectable': this.checkStrictly,
97954
+ 'is-disabled': node.disabled || this.isViewMode,
97955
+ 'in-active-path': this.isInActivePath(node),
97956
+ 'in-checked-path': this.checkStrictly && this.isInCheckedPath(node),
97957
+ 'is-active': this.isNodeActive(node)
97958
+ };
97959
+ },
97960
+ isInCheckedPath(node) {
97961
+ void this.selectionTick;
97962
+ if (!this.selection || !this.checkStrictly) {
97963
+ return false;
97964
+ }
97965
+ return this.selection.isNodeInCheckedPath(node);
97966
+ },
97967
+ isNodeActive(node) {
97968
+ void this.selectionTick;
97969
+ if (!this.selection) {
97970
+ return false;
97971
+ }
97972
+ if (this.multiple) {
97973
+ if (this.checkStrictly) {
97974
+ return this.selection.isNodeInCheckedPath(node);
97975
+ }
97976
+ return node.isLeaf && this.selection.selectedLeafSet.has(node.value);
97977
+ }
97978
+ const paths = this.selection.getCheckedPaths();
97979
+ if (paths.length === 0) {
97980
+ return false;
97981
+ }
97982
+ const activePath = paths[0];
97983
+ return activePath[activePath.length - 1] === node.value;
97984
+ },
97985
+ isChecked(node) {
97986
+ void this.selectionTick;
97987
+ return this.selection ? this.selection.isChecked(node.id) : false;
97988
+ },
97989
+ isIndeterminate(node) {
97990
+ void this.selectionTick;
97991
+ return this.selection ? this.selection.isIndeterminate(node.id) : false;
97992
+ },
97993
+ bumpSelectionView() {
97994
+ this.selectionTick += 1;
97995
+ },
97996
+ // activePath 只保留非叶子,避免多出一列空菜单(空列仍有 min-width 会撑出横向滚动)
97997
+ sanitizeActivePath(pathIds) {
97998
+ if (!this.store || !Array.isArray(pathIds)) {
97999
+ return [];
98000
+ }
98001
+ return pathIds.filter(id => {
98002
+ const node = this.store.nodeById.get(id);
98003
+ return node && !node.isLeaf;
98004
+ });
98005
+ },
98006
+ expandNode(node, silent = false) {
98007
+ if (node.isLeaf) {
98008
+ return;
98009
+ }
98010
+ const pathIds = [];
98011
+ let current = node;
98012
+ while (current) {
98013
+ pathIds.unshift(current.id);
98014
+ if (current.parentId == null) {
98015
+ break;
98016
+ }
98017
+ current = this.store.nodeById.get(current.parentId);
98018
+ }
98019
+ this.activePath = this.sanitizeActivePath(pathIds);
98020
+ if (!silent) {
98021
+ const pathValues = pathIds.map(id => this.store.nodeById.get(id).value);
98022
+ this.$emit('expand-change', pathValues);
98023
+ if (this.autoExpandDeep) {
98024
+ this.$nextTick(() => {
98025
+ this.expandDeepFromNode(node);
98026
+ });
98027
+ }
98028
+ }
98029
+ },
98030
+ expandDeepFromNode(node) {
98031
+ if (!node || node.isLeaf) {
98032
+ return;
98033
+ }
98034
+ const children = getStoreChildren(this.store, node.id);
98035
+ if (children.length === 0) {
98036
+ return;
98037
+ }
98038
+ const firstChild = children[0];
98039
+ const pathIds = [];
98040
+ let cursor = firstChild;
98041
+ while (cursor) {
98042
+ pathIds.push(cursor.id);
98043
+ if (cursor.isLeaf) {
98044
+ break;
98045
+ }
98046
+ const kids = getStoreChildren(this.store, cursor.id);
98047
+ if (kids.length === 0) {
98048
+ break;
98049
+ }
98050
+ cursor = kids[0];
98051
+ }
98052
+ const basePath = [];
98053
+ let parent = node;
98054
+ while (parent) {
98055
+ basePath.unshift(parent.id);
98056
+ if (parent.parentId == null) {
98057
+ break;
98058
+ }
98059
+ parent = this.store.nodeById.get(parent.parentId);
98060
+ }
98061
+ this.activePath = this.sanitizeActivePath(basePath.concat(pathIds));
98062
+ },
98063
+ expandPathValues(pathValues, deep = true) {
98064
+ if (!pathValues || pathValues.length === 0 || !this.store) {
98065
+ return;
98066
+ }
98067
+ const node = findStoreNodeByPath(this.store, pathValues);
98068
+ if (!node) {
98069
+ return;
98070
+ }
98071
+ const pathIds = [];
98072
+ let current = node;
98073
+ while (current) {
98074
+ pathIds.unshift(current.id);
98075
+ if (current.parentId == null) {
98076
+ break;
98077
+ }
98078
+ current = this.store.nodeById.get(current.parentId);
98079
+ }
98080
+ this.activePath = this.sanitizeActivePath(pathIds);
98081
+ if (deep && this.autoExpandDeep) {
98082
+ this.$nextTick(() => {
98083
+ this.expandDeepFromNode(node);
98084
+ });
98085
+ }
98086
+ },
98087
+ onNodeClick(node, colIndex) {
98088
+ if (node.disabled || this.isViewMode) {
98089
+ return;
98090
+ }
98091
+ if (!this.multiple && !this.checkStrictly) {
98092
+ if (node.isLeaf) {
98093
+ this.selection.clear();
98094
+ this.selection.toggleNode(node.id, true);
98095
+ this.emitValue();
98096
+ } else {
98097
+ this.expandNode(node);
98098
+ }
98099
+ return;
98100
+ }
98101
+ this.expandNode(node);
98102
+ },
98103
+ onCheckClick(node, checked) {
98104
+ if (!this.multiple || node.disabled || this.isViewMode) {
98105
+ return;
98106
+ }
98107
+ const nextChecked = typeof checked === 'boolean' ? checked : !this.isChecked(node);
98108
+ this.selection.toggleNode(node.id, nextChecked);
98109
+ this.bumpSelectionView();
98110
+ this.emitValue();
98111
+
98112
+ // 与 el-cascader-panel 一致:非 checkStrictly 时勾选会同步展开当前节点
98113
+ if (!this.checkStrictly && !node.isLeaf) {
98114
+ this.expandNode(node);
98115
+ }
98116
+ },
98117
+ onRadioClick(node) {
98118
+ if (this.multiple || node.disabled || this.isViewMode) {
98119
+ return;
98120
+ }
98121
+ this.selection.clear();
98122
+ this.selection.toggleNode(node.id, true);
98123
+ this.emitValue();
98124
+ if (!node.isLeaf) {
98125
+ this.expandNode(node);
98126
+ }
98127
+ },
98128
+ clearCheckedNodes() {
98129
+ if (this.selection) {
98130
+ this.selection.clear();
98131
+ this.bumpSelectionView();
98132
+ this.$emit('input', this.multiple ? [] : []);
98133
+ this.$emit('change', this.multiple ? [] : []);
98134
+ }
98135
+ },
98136
+ selectAllLeaves() {
98137
+ if (this.selection) {
98138
+ this.selection.selectAll();
98139
+ this.bumpSelectionView();
98140
+ this.emitValue();
98141
+ }
98142
+ },
98143
+ syncCheckedValue() {
98144
+ this.syncFromValue();
98145
+ },
98146
+ syncFromParentValues(values, prefix) {
98147
+ if (!this.selection) {
98148
+ return;
98149
+ }
98150
+ this.suppressValueSync = true;
98151
+ this.selection.syncFromParentValues(values, prefix);
98152
+ this.bumpSelectionView();
98153
+ this.suppressValueSync = false;
98154
+ },
98155
+ getSelectionSnapshot() {
98156
+ if (!this.selection || !this.store) {
98157
+ return null;
98158
+ }
98159
+ return {
98160
+ store: this.store,
98161
+ selection: this.selection,
98162
+ isCompact: this.selection.isCompactSelection(),
98163
+ count: this.selection.size()
98164
+ };
98165
+ }
98166
+ }
98167
+ });
98168
+ ;// ./src/components/cascader-panel-pro/VirtualCascaderPanel.vue?vue&type=script&lang=js
98169
+ /* harmony default export */ var cascader_panel_pro_VirtualCascaderPanelvue_type_script_lang_js = (VirtualCascaderPanelvue_type_script_lang_js);
98170
+ ;// ./src/components/cascader-panel-pro/VirtualCascaderPanel.vue
98171
+
98172
+
98173
+
98174
+
98175
+
98176
+ /* normalize component */
98177
+ ;
98178
+ var VirtualCascaderPanel_component = normalizeComponent(
98179
+ cascader_panel_pro_VirtualCascaderPanelvue_type_script_lang_js,
98180
+ VirtualCascaderPanelvue_type_template_id_05f77638_render,
98181
+ VirtualCascaderPanelvue_type_template_id_05f77638_staticRenderFns,
98182
+ false,
98183
+ null,
98184
+ null,
98185
+ null
98186
+
98187
+ )
98188
+
98189
+ /* harmony default export */ var VirtualCascaderPanel = (VirtualCascaderPanel_component.exports);
98190
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./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=script&lang=js
98191
+
98192
+
98193
+
98194
+
98195
+
98196
+
98197
+
98198
+
98199
+
98200
+
98201
+
98202
+
98203
+
98204
+
98205
+
98206
+
98207
+
98208
+ /* harmony default export */ var ByCascaderPanelProvue_type_script_lang_js = ({
98209
+ name: 'ByCascaderPanelPro',
98210
+ components: {
98211
+ VirtualCascaderPanel: VirtualCascaderPanel,
98212
+ VcpVirtualList: VirtualList
98213
+ },
98214
+ props: {
98215
+ // 级联数据源
98216
+ options: {
98217
+ type: Array,
98218
+ default: () => []
98219
+ },
98220
+ // 已选值
98221
+ value: {
98222
+ type: [Array, Number, String],
98223
+ default: () => []
98224
+ },
98225
+ // 级联面板配置
98226
+ cascaderProps: {
98227
+ type: Object,
98228
+ default: () => ({
98229
+ multiple: true,
98230
+ label: 'label',
98231
+ value: 'value',
98232
+ children: 'children'
98233
+ })
98234
+ },
98235
+ // 面板高度
98236
+ panelHeight: {
98237
+ type: [String, Number],
98238
+ default: 300,
98239
+ validator: value => {
98240
+ const numValue = Number(value);
98241
+ if (isNaN(numValue)) {
98242
+ console.warn(`[ByCascaderPanelPro] panelHeight 必须是数字,当前值: ${value}`);
98243
+ return false;
98244
+ }
98245
+ if (numValue < 200) {
98246
+ console.warn(`[ByCascaderPanelPro] panelHeight 不能小于 200px,当前值: ${value}px`);
98247
+ return false;
98248
+ }
98249
+ if (numValue > 800) {
98250
+ console.warn(`[ByCascaderPanelPro] panelHeight 不能大于 800px,当前值: ${value}px`);
98251
+ return false;
98252
+ }
98253
+ return true;
98254
+ }
98255
+ },
98256
+ // 搜索占位符
98257
+ searchPlaceholder: {
98258
+ type: String,
98259
+ default: '请输入名称搜索'
98260
+ },
98261
+ // 禁用字段名(只针对叶子节点,非叶子节点为disabled)
98262
+ disabledField: {
98263
+ type: String,
98264
+ default: 'disabled'
98265
+ },
98266
+ // 禁用值(只针对叶子节点,非叶子节点为disabled)
98267
+ disabledValue: {
98268
+ type: [String, Number, Boolean],
98269
+ default: true
98270
+ },
98271
+ // 自定义禁用判断函数
98272
+ disabledCheck: {
98273
+ type: Function,
98274
+ default: null
98275
+ },
98276
+ // 是否显示全选按钮
98277
+ showSelectAll: {
98278
+ type: Boolean,
98279
+ default: true
98280
+ },
98281
+ // 是否聚合模式 (聚合模式下如果子项全部选中,会直接返回父ID)
98282
+ aggregationMode: {
98283
+ type: Boolean,
98284
+ default: false
98285
+ },
98286
+ /**
98287
+ * 非叶子节点前缀标识 (聚合模式下用于标识非叶子节点)
98288
+ * 注意:聚合模式下,由于叶子节点和非叶子节点可能存在相同id,所以绑定数据中务必给非叶子节点加上parentNodePrefix前缀作为标识
98289
+ */
98290
+ parentNodePrefix: {
98291
+ type: String,
98292
+ default: '__parent__'
98293
+ },
98294
+ // 是否为查看模式 (如果是查看模式,则组件中的操作交互将全部禁用,仅用于回显查看)
98295
+ isViewMode: {
98296
+ type: Boolean,
98297
+ default: false
98298
+ },
98299
+ // 是否显示子标题
98300
+ showSubtitle: {
98301
+ type: Boolean,
98302
+ default: false
98303
+ },
98304
+ // 子标题字段名
98305
+ subtitleField: {
98306
+ type: String,
98307
+ default: ''
98308
+ },
98309
+ // 级联列最小宽度(px)
98310
+ columnMinWidth: {
98311
+ type: Number,
98312
+ default: 180
98313
+ },
98314
+ // 级联列最大宽度(px),超出后显示省略号
98315
+ columnMaxWidth: {
98316
+ type: Number,
98317
+ default: 420
98318
+ }
98319
+ },
98320
+ data() {
98321
+ return {
98322
+ selectedValues: [],
98323
+ searchSelectedValues: [],
98324
+ filteredOptions: [],
98325
+ searchOptions: [],
98326
+ selectedItems: [],
98327
+ searchInput: '',
98328
+ isShow: true,
98329
+ isShowSearch: false,
98330
+ totalCount: 0,
98331
+ selectedCount: 0,
98332
+ isAllSelected: false,
98333
+ isInternalUpdate: false,
98334
+ // 防止循环更新的标志
98335
+ batchSearchVisible: false,
98336
+ // 批量搜索弹窗显示状态
98337
+ batchSearchContent: '',
98338
+ // 批量搜索输入内容
98339
+ compactPanelValue: [],
98340
+ // 紧凑模式下稳定的空 value 引用,避免 watch 误触发清空
98341
+ searchDebounceTimer: null,
98342
+ searchLeafSetCache: null,
98343
+ panelSyncTimer: null
98344
+ };
98345
+ },
98346
+ computed: {
98347
+ disabledConfig() {
98348
+ return {
98349
+ disabledField: this.disabledField,
98350
+ disabledValue: this.disabledValue,
98351
+ disabledCheck: this.disabledCheck
98352
+ };
98353
+ },
98354
+ // 处理后的面板高度,确保在有效范围内
98355
+ computedPanelHeight() {
98356
+ const height = Number(this.panelHeight);
98357
+ if (isNaN(height)) {
98358
+ return 300; // 默认值
98359
+ }
98360
+ // 限制在 200px 到 800px 之间
98361
+ return Math.max(200, Math.min(800, height));
98362
+ },
98363
+ // 是否为多选模式
98364
+ isMultiple() {
98365
+ return this.cascaderProps.multiple !== false;
98366
+ },
98367
+ useCompactSelection() {
98368
+ return this.isMultiple && this.totalCount >= 300;
98369
+ },
98370
+ panelPresentationValue() {
98371
+ if (this.useCompactSelection) {
98372
+ return this.compactPanelValue;
98373
+ }
98374
+ if (this.isMultiple) {
98375
+ return this.selectedValues;
98376
+ }
98377
+ return this.selectedValues.length > 0 ? this.selectedValues[0] : [];
98378
+ },
98379
+ compactSearchPanelValue() {
98380
+ return this.compactPanelValue;
98381
+ },
98382
+ selectedItemHeight() {
98383
+ return 40;
98384
+ },
98385
+ selectedListHeight() {
98386
+ return Math.max(120, this.computedPanelHeight - 25);
98387
+ },
98388
+ // 当前选中的值(单选时返回单个值,多选时返回数组)
98389
+ currentValue() {
98390
+ if (this.isMultiple) {
98391
+ return this.selectedItems.map(item => item.value);
98392
+ } else {
98393
+ return this.selectedItems.length > 0 ? this.selectedItems[0].value : null;
98394
+ }
98395
+ },
98396
+ // 主面板的值(单选时返回单个路径,多选时返回路径数组)
98397
+ mainPanelValue: {
98398
+ get() {
98399
+ if (this.isMultiple) {
98400
+ return this.selectedValues;
98401
+ } else {
98402
+ return this.selectedValues.length > 0 ? this.selectedValues[0] : [];
98403
+ }
98404
+ },
98405
+ set(value) {
98406
+ if (this.isMultiple) {
98407
+ this.selectedValues = value || [];
98408
+ } else {
98409
+ this.selectedValues = value ? [value] : [];
98410
+ }
98411
+ }
98412
+ },
98413
+ // 搜索面板的值(单选时返回单个路径,多选时返回路径数组)
98414
+ searchPanelValue: {
98415
+ get() {
98416
+ if (this.isMultiple) {
98417
+ return this.searchSelectedValues;
98418
+ } else {
98419
+ return this.searchSelectedValues.length > 0 ? this.searchSelectedValues[0] : [];
98420
+ }
98421
+ },
98422
+ set(value) {
98423
+ if (this.isMultiple) {
98424
+ this.searchSelectedValues = value || [];
98425
+ } else {
98426
+ this.searchSelectedValues = value ? [value] : [];
98427
+ }
98428
+ }
98429
+ }
98430
+ },
98431
+ watch: {
98432
+ options: {
98433
+ handler(newVal) {
98434
+ this.initOptions();
98435
+ },
98436
+ deep: true,
98437
+ immediate: true
98438
+ },
98439
+ value: {
98440
+ handler(newVal) {
98441
+ // 如果是内部更新触发的,跳过处理
98442
+ if (this.isInternalUpdate) {
98443
+ this.isInternalUpdate = false;
98444
+ return;
98445
+ }
98446
+ this.processValue();
98447
+ },
98448
+ deep: true,
98449
+ immediate: true
98450
+ },
98451
+ searchInput(val) {
98452
+ if (!val) {
98453
+ this.clearSearchState();
98454
+ return;
98455
+ }
98456
+ this.scheduleSearch();
98457
+ },
98458
+ selectedItems: {
98459
+ handler(newVal) {
98460
+ if (this.isMultiple) {
98461
+ const panel = this.$refs.cascaderPanel;
98462
+ if (this.useCompactSelection && !this.aggregationMode && panel && panel.selection && panel.selection.isCompactSelection()) {
98463
+ this.selectedCount = panel.selection.size();
98464
+ } else {
98465
+ this.selectedCount = newVal.length;
98466
+ }
98467
+ if (!this.useCompactSelection) {
98468
+ if (this.aggregationMode) {
98469
+ const config = {
98470
+ disabledField: this.disabledField,
98471
+ disabledValue: this.disabledValue,
98472
+ disabledCheck: this.disabledCheck
98473
+ };
98474
+ this.isAllSelected = CascaderUtilsPro.isAggregatedAllSelected(this.selectedValues, this.filteredOptions, config, this.cascaderProps);
98475
+ } else {
98476
+ this.isAllSelected = this.selectedCount === this.totalCount;
96387
98477
  }
96388
- });
96389
- };
96390
- dfs(processedOptions);
96391
- return processedOptions;
98478
+ }
98479
+ } else {
98480
+ if (newVal.length > 1) {
98481
+ this.selectedItems = [newVal[newVal.length - 1]];
98482
+ }
98483
+ this.selectedCount = this.selectedItems.length;
98484
+ }
98485
+ },
98486
+ deep: false
98487
+ }
98488
+ },
98489
+ mounted() {
98490
+ this.initOptions();
98491
+ // 确保在 mounted 后处理默认值
98492
+ this.$nextTick(() => {
98493
+ this.processValue();
98494
+ });
98495
+ // 组件挂载后强制调整样式
98496
+ this.forceVerticalCenter();
98497
+ },
98498
+ beforeDestroy() {
98499
+ if (this.searchDebounceTimer) {
98500
+ clearTimeout(this.searchDebounceTimer);
98501
+ this.searchDebounceTimer = null;
98502
+ }
98503
+ this.clearPanelSyncTimer();
98504
+ },
98505
+ methods: {
98506
+ onMainPanelInput(value) {
98507
+ if (this.useCompactSelection && Array.isArray(value) && value.length >= 300) {
98508
+ return;
98509
+ }
98510
+ if (this.isMultiple) {
98511
+ this.selectedValues = Array.isArray(value) ? value : [];
98512
+ } else {
98513
+ this.selectedValues = value && value.length ? [value] : [];
96392
98514
  }
96393
- CascaderUtils.setDisabledItems(processedOptions, this.disabledConfig, this.cascaderProps);
96394
- return processedOptions;
96395
98515
  },
96396
- cloneTree(options) {
96397
- if (!Array.isArray(options)) return [];
96398
- return options.map(item => {
96399
- const cloned = {
96400
- ...item
96401
- };
96402
- if (item[this.childrenKey] && item[this.childrenKey].length > 0) {
96403
- cloned[this.childrenKey] = this.cloneTree(item[this.childrenKey]);
98516
+ applyPanelSelectionChange() {
98517
+ const panel = this.$refs.cascaderPanel;
98518
+ if (!panel || !panel.store || !panel.selection) {
98519
+ return;
98520
+ }
98521
+ const {
98522
+ store,
98523
+ selection
98524
+ } = panel;
98525
+ if (this.aggregationMode) {
98526
+ const items = CascaderUtilsPro.getAggregatedItemsFromSelection(store, selection, this.filteredOptions, this.cascaderProps);
98527
+ this.selectedItems = items;
98528
+ this.selectedCount = items.length;
98529
+ this.isAllSelected = selection.size() === store.totalLeafCount && store.totalLeafCount > 0;
98530
+ if (!selection.isCompactSelection()) {
98531
+ this.selectedValues = selection.getCheckedPaths();
98532
+ }
98533
+ this.isInternalUpdate = true;
98534
+ let emitValue = CascaderUtilsPro.getAggregatedEmitValues(items, this.parentNodePrefix);
98535
+ if (!this.isMultiple && emitValue.length > 0) {
98536
+ emitValue = emitValue[0];
98537
+ }
98538
+ this.$emit('input', emitValue);
98539
+ this.$emit('change', this.getSelectedData());
98540
+ panel.bumpSelectionView();
98541
+ return;
98542
+ }
98543
+ if (selection.isCompactSelection()) {
98544
+ this.selectedItems = this.buildSelectedItemsFromValuesLazy(panel);
98545
+ this.selectedCount = this.aggregationMode ? this.selectedItems.length : selection.size();
98546
+ this.isAllSelected = selection.size() === store.totalLeafCount;
98547
+ this.isInternalUpdate = true;
98548
+ this.$emit('input', this.currentValue);
98549
+ this.$emit('change', this.getSelectedData());
98550
+ panel.bumpSelectionView();
98551
+ return;
98552
+ }
98553
+ this.selectedValues = selection.getCheckedPaths();
98554
+ this.updateSelectedItems();
98555
+ panel.bumpSelectionView();
98556
+ this.$nextTick(() => {
98557
+ this.isInternalUpdate = true;
98558
+ let emitValue = this.currentValue;
98559
+ if (this.aggregationMode) {
98560
+ emitValue = CascaderUtilsPro.getAggregatedEmitValues(this.selectedItems, this.parentNodePrefix);
98561
+ if (!this.isMultiple && emitValue.length > 0) {
98562
+ emitValue = emitValue[0];
98563
+ }
96404
98564
  }
96405
- return cloned;
98565
+ this.$emit('input', emitValue);
98566
+ this.$emit('change', this.getSelectedData());
96406
98567
  });
96407
98568
  },
96408
- countTotalItems() {
96409
- this.totalCount = CascaderUtils.countTotalItems(this.filteredOptions, this.disabledConfig, this.cascaderProps);
98569
+ buildSelectedItemsFromValuesLazy(panel) {
98570
+ if (!panel || !panel.selection) {
98571
+ return [];
98572
+ }
98573
+ if (!panel.selection.isCompactSelection()) {
98574
+ return this.buildSelectedItemsFromValues();
98575
+ }
98576
+ return CascaderUtilsPro.buildSelectedItemsFromSelection(panel.store, panel.selection, this.filteredOptions, this.cascaderProps);
98577
+ },
98578
+ syncPanelFromExternalValue() {
98579
+ const panel = this.$refs.cascaderPanel;
98580
+ if (!panel || !panel.selection || !panel.store) {
98581
+ return false;
98582
+ }
98583
+ if (!this.hasExternalValue()) {
98584
+ panel.clearCheckedNodes();
98585
+ this.selectedItems = [];
98586
+ this.selectedValues = [];
98587
+ return true;
98588
+ }
98589
+ panel.selection.clear();
98590
+ this.applyExternalValueToPanelSelection(panel);
98591
+ panel.selection._reconcileAllRoots();
98592
+ panel.bumpSelectionView();
98593
+ this.applyPanelSelectionChange();
98594
+ this.expandPanelToExternalValue(panel);
98595
+ return true;
98596
+ },
98597
+ hasExternalValue() {
98598
+ const val = this.value;
98599
+ if (val == null || val === '') {
98600
+ return false;
98601
+ }
98602
+ if (Array.isArray(val)) {
98603
+ return val.length > 0;
98604
+ }
98605
+ return true;
98606
+ },
98607
+ applyExternalValueToPanelSelection(panel) {
98608
+ const {
98609
+ store,
98610
+ selection
98611
+ } = panel;
98612
+ const paths = this.resolveExternalValueToPaths();
98613
+ paths.forEach(path => {
98614
+ const leafValue = path[path.length - 1];
98615
+ if (store.pathByLeafValue.has(leafValue)) {
98616
+ selection.selectedLeafSet.add(leafValue);
98617
+ }
98618
+ });
98619
+
98620
+ // 直接按外部 value 再补一遍,避免 paths 解析遗漏(聚合父节点、异步 options 等)
98621
+ this.getExternalValueList().forEach(val => {
98622
+ if (this.aggregationMode && CascaderUtilsPro.isParentNodeValue(val, this.parentNodePrefix)) {
98623
+ const actualValue = CascaderUtilsPro.extractParentNodeValue(val, this.parentNodePrefix);
98624
+ const node = store.nodeByValue.get(actualValue);
98625
+ if (node && !node.isLeaf && !node.disabled) {
98626
+ node.descendantLeafValues.forEach(leaf => selection.selectedLeafSet.add(leaf));
98627
+ }
98628
+ return;
98629
+ }
98630
+ if (store.pathByLeafValue.has(val)) {
98631
+ selection.selectedLeafSet.add(val);
98632
+ return;
98633
+ }
98634
+ const node = store.nodeByValue.get(val);
98635
+ if (node && node.isLeaf && !node.disabled) {
98636
+ selection.selectedLeafSet.add(val);
98637
+ } else if (node && !node.isLeaf && !node.disabled) {
98638
+ node.descendantLeafValues.forEach(leaf => selection.selectedLeafSet.add(leaf));
98639
+ }
98640
+ });
98641
+ },
98642
+ getExternalValueList() {
98643
+ const val = this.value;
98644
+ if (val == null || val === '') {
98645
+ return [];
98646
+ }
98647
+ if (Array.isArray(val)) {
98648
+ if (val.length === 0) {
98649
+ return [];
98650
+ }
98651
+ if (Array.isArray(val[0])) {
98652
+ return val.map(path => path[path.length - 1]);
98653
+ }
98654
+ return val;
98655
+ }
98656
+ return [val];
98657
+ },
98658
+ clearPanelSyncTimer() {
98659
+ if (this.panelSyncTimer) {
98660
+ clearTimeout(this.panelSyncTimer);
98661
+ this.panelSyncTimer = null;
98662
+ }
98663
+ },
98664
+ schedulePanelSyncFromExternalValue(retry = 0) {
98665
+ this.clearPanelSyncTimer();
98666
+ this.$nextTick(() => {
98667
+ if (!this.hasExternalValue()) {
98668
+ const panel = this.$refs.cascaderPanel;
98669
+ if (panel && panel.selection) {
98670
+ panel.clearCheckedNodes();
98671
+ }
98672
+ this.selectedItems = [];
98673
+ this.selectedValues = [];
98674
+ return;
98675
+ }
98676
+ const synced = this.syncPanelFromExternalValue();
98677
+ if (!synced && retry < 20) {
98678
+ this.panelSyncTimer = setTimeout(() => {
98679
+ this.schedulePanelSyncFromExternalValue(retry + 1);
98680
+ }, 50);
98681
+ }
98682
+ });
98683
+ },
98684
+ resolveExternalValueToPaths() {
98685
+ const val = this.value;
98686
+ if (val == null || val === '') {
98687
+ return [];
98688
+ }
98689
+ if (Array.isArray(val) && val.length > 0 && Array.isArray(val[0])) {
98690
+ return [...val];
98691
+ }
98692
+ const values = Array.isArray(val) ? val : [val];
98693
+ if (typeof values[0] === 'string' || typeof values[0] === 'number') {
98694
+ if (this.aggregationMode) {
98695
+ return CascaderUtilsPro.processValuesWithParentNodes(values, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
98696
+ }
98697
+ return this.findPathsByValues(values);
98698
+ }
98699
+ return Array.isArray(val) ? [...val] : [];
98700
+ },
98701
+ expandPanelToExternalValue(panel) {
98702
+ if (!panel || !panel.store || !this.hasExternalValue()) {
98703
+ return;
98704
+ }
98705
+ const values = this.getExternalValueList();
98706
+ const firstValue = values[0];
98707
+ let pathValues = [];
98708
+ if (this.aggregationMode && CascaderUtilsPro.isParentNodeValue(firstValue, this.parentNodePrefix)) {
98709
+ const actualValue = CascaderUtilsPro.extractParentNodeValue(firstValue, this.parentNodePrefix);
98710
+ const node = panel.store.nodeByValue.get(actualValue);
98711
+ pathValues = node ? [...node.path] : [];
98712
+ } else if (panel.store.pathByLeafValue.has(firstValue)) {
98713
+ const path = panel.store.pathByLeafValue.get(firstValue);
98714
+ pathValues = path ? path.slice(0, -1) : [];
98715
+ } else {
98716
+ const node = panel.store.nodeByValue.get(firstValue);
98717
+ if (node) {
98718
+ pathValues = node.isLeaf ? node.path.slice(0, -1) : [...node.path];
98719
+ }
98720
+ }
98721
+ if (pathValues.length > 0) {
98722
+ this.$nextTick(() => {
98723
+ panel.expandPathValues(pathValues, true);
98724
+ });
98725
+ }
96410
98726
  },
98727
+ onSearchPanelInput(value) {
98728
+ if (this.useCompactSelection && Array.isArray(value) && value.length >= 300) {
98729
+ return;
98730
+ }
98731
+ if (this.isMultiple) {
98732
+ this.searchSelectedValues = Array.isArray(value) ? value : [];
98733
+ } else {
98734
+ this.searchSelectedValues = value && value.length ? [value] : [];
98735
+ }
98736
+ },
98737
+ // 处理 value 值
96411
98738
  processValue() {
96412
- if (!this.filteredOptions.length) return;
98739
+ if (!this.hasExternalValue()) {
98740
+ this.selectedValues = [];
98741
+ this.selectedItems = [];
98742
+ this.schedulePanelSyncFromExternalValue();
98743
+ return;
98744
+ }
98745
+ if (this.useCompactSelection && this.isMultiple) {
98746
+ this.selectedValues = [];
98747
+ this.schedulePanelSyncFromExternalValue();
98748
+ return;
98749
+ }
96413
98750
  if (this.isMultiple) {
98751
+ // 多选模式:支持直接传入value值或路径数组
96414
98752
  if (Array.isArray(this.value) && this.value.length > 0) {
96415
98753
  if (typeof this.value[0] === 'string' || typeof this.value[0] === 'number') {
98754
+ // 传入的是value值数组,需要转换为路径
96416
98755
  if (this.aggregationMode) {
96417
- this.selectedValues = CascaderUtils.processValuesWithParentNodes(this.value, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
98756
+ // 聚合模式下,支持非叶子节点标识
98757
+ this.selectedValues = CascaderUtilsPro.processValuesWithParentNodes(this.value, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
98758
+ } else {
98759
+ // 普通模式下,只处理叶子节点
98760
+ this.selectedValues = this.findPathsByValues(this.value);
98761
+ }
98762
+ } else {
98763
+ // 传入的是路径数组
98764
+ this.selectedValues = [...this.value];
98765
+ }
98766
+ } else {
98767
+ this.selectedValues = [];
98768
+ }
98769
+ } else {
98770
+ // 单选模式:支持单个值或路径数组
98771
+ if (this.value !== null && this.value !== undefined && this.value !== '') {
98772
+ if (Array.isArray(this.value)) {
98773
+ // 传入的是路径数组
98774
+ this.selectedValues = [...this.value];
98775
+ } else {
98776
+ // 传入的是单个值,需要转换为路径
98777
+ if (this.aggregationMode) {
98778
+ // 聚合模式下,支持非叶子节点标识
98779
+ this.selectedValues = CascaderUtilsPro.processValuesWithParentNodes([this.value], this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
96418
98780
  } else {
96419
- this.selectedValues = CascaderUtils.findPathsByValues(this.value, this.filteredOptions, this.cascaderProps);
98781
+ // 普通模式下,只处理叶子节点
98782
+ this.selectedValues = this.findPathsByValues([this.value]);
96420
98783
  }
98784
+ }
98785
+ } else {
98786
+ this.selectedValues = [];
98787
+ }
98788
+ }
98789
+ this.schedulePanelSyncFromExternalValue();
98790
+ },
98791
+ // 初始化选项数据
98792
+ initOptions() {
98793
+ this.filteredOptions = this.processOptions(this.options);
98794
+ this.countTotalItems();
98795
+ if (this.hasExternalValue()) {
98796
+ this.schedulePanelSyncFromExternalValue();
98797
+ } else {
98798
+ this.updateSelectedItems();
98799
+ }
98800
+ },
98801
+ // 处理选项数据,添加禁用状态(浅拷贝,避免 JSON 深拷贝大数据卡顿)
98802
+ processOptions(options) {
98803
+ const childrenKey = this.cascaderProps && this.cascaderProps.children || 'children';
98804
+ const disabledKey = this.cascaderProps && this.cascaderProps.disabled || 'disabled';
98805
+ const config = this.disabledConfig;
98806
+ const cloneItems = (items, ancestorDisabled = false) => {
98807
+ return items.map(item => {
98808
+ const isDisabled = ancestorDisabled || CascaderUtilsPro.isItemDisabled(item, config);
98809
+ const children = item[childrenKey];
98810
+ const cloned = {
98811
+ ...item
98812
+ };
98813
+ if (this.isViewMode || isDisabled) {
98814
+ cloned[disabledKey] = true;
98815
+ }
98816
+ if (children && children.length > 0) {
98817
+ cloned[childrenKey] = cloneItems(children, isDisabled || this.isViewMode);
98818
+ }
98819
+ return cloned;
98820
+ });
98821
+ };
98822
+ return cloneItems(options || []);
98823
+ },
98824
+ // 判断项目是否禁用
98825
+ isItemDisabled(item) {
98826
+ const config = {
98827
+ disabledField: this.disabledField,
98828
+ disabledValue: this.disabledValue,
98829
+ disabledCheck: this.disabledCheck
98830
+ };
98831
+ return CascaderUtilsPro.isItemDisabled(item, config);
98832
+ },
98833
+ // 统计总项目数
98834
+ countTotalItems() {
98835
+ const config = {
98836
+ disabledField: this.disabledField,
98837
+ disabledValue: this.disabledValue,
98838
+ disabledCheck: this.disabledCheck
98839
+ };
98840
+ this.totalCount = CascaderUtilsPro.countTotalItems(this.filteredOptions, config, this.cascaderProps);
98841
+ },
98842
+ // 更新已选项列表
98843
+ updateSelectedItems() {
98844
+ this.$nextTick(() => {
98845
+ const panel = this.$refs.cascaderPanel;
98846
+ if (this.aggregationMode) {
98847
+ if (panel && panel.store && panel.selection) {
98848
+ this.selectedItems = CascaderUtilsPro.getAggregatedItemsFromSelection(panel.store, panel.selection, this.filteredOptions, this.cascaderProps);
96421
98849
  } else {
96422
- this.selectedValues = [...this.value];
98850
+ this.selectedItems = CascaderUtilsPro.getAggregatedSelectedItems(this.selectedValues, this.filteredOptions, this.cascaderProps);
96423
98851
  }
96424
98852
  } else {
96425
- this.selectedValues = [];
96426
- }
96427
- } else if (this.value !== null && this.value !== undefined && this.value !== '') {
96428
- if (Array.isArray(this.value)) {
96429
- this.selectedValues = [...this.value];
96430
- } else if (this.aggregationMode) {
96431
- this.selectedValues = CascaderUtils.processValuesWithParentNodes([this.value], this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
96432
- } else {
96433
- this.selectedValues = CascaderUtils.findPathsByValues([this.value], this.filteredOptions, this.cascaderProps);
98853
+ this.selectedItems = this.buildSelectedItemsFromValues();
96434
98854
  }
96435
- } else {
96436
- this.selectedValues = [];
96437
- }
96438
- this.updateSelectedItems();
96439
- this.syncTreeCheckedState();
98855
+ });
96440
98856
  },
96441
- updateSelectedItems() {
96442
- if (this.aggregationMode) {
96443
- this.selectedItems = CascaderUtils.getAggregatedSelectedItems(this.selectedValues, this.filteredOptions, this.cascaderProps);
96444
- } else {
96445
- this.selectedItems = CascaderUtils.buildSelectedItemsFromValues(this.selectedValues, this.filteredOptions, this.cascaderProps);
98857
+ // 基于 selectedValues 构建已选项列表
98858
+ buildSelectedItemsFromValues() {
98859
+ return CascaderUtilsPro.buildSelectedItemsFromValues(this.selectedValues, this.filteredOptions, this.cascaderProps);
98860
+ },
98861
+ // 搜索处理(防抖,避免每次按键遍历整棵树)
98862
+ scheduleSearch() {
98863
+ if (this.searchDebounceTimer) {
98864
+ clearTimeout(this.searchDebounceTimer);
96446
98865
  }
96447
- this.selectedCount = this.selectedItems.length;
96448
- this.$emit('change', this.getSelectedData());
98866
+ this.searchDebounceTimer = setTimeout(() => {
98867
+ this.searchDebounceTimer = null;
98868
+ this.runSearch();
98869
+ }, 100);
96449
98870
  },
96450
- updateSelectAllState() {
96451
- if (!this.isMultiple) return;
96452
- if (this.aggregationMode) {
96453
- this.isAllSelected = CascaderUtils.isAggregatedAllSelected(this.selectedValues, this.filteredOptions, this.disabledConfig, this.cascaderProps);
96454
- } else {
96455
- this.isAllSelected = this.selectedCount === this.totalCount && this.totalCount > 0;
98871
+ clearSearchState() {
98872
+ if (this.searchDebounceTimer) {
98873
+ clearTimeout(this.searchDebounceTimer);
98874
+ this.searchDebounceTimer = null;
96456
98875
  }
98876
+ this.isShowSearch = false;
98877
+ this.searchOptions = [];
98878
+ this.searchLeafSetCache = null;
98879
+ this.searchSelectedValues = [];
96457
98880
  },
96458
- getNodePath(node) {
96459
- const tree = this.$refs.tree;
96460
- let treeNode = node;
96461
-
96462
- // getCheckedNodes 返回的是 data 对象,需转为内部 Node 才能取路径
96463
- if (tree && treeNode && typeof treeNode.level !== 'number') {
96464
- treeNode = tree.getNode(treeNode);
98881
+ runSearch() {
98882
+ const keyword = this.searchInput.trim();
98883
+ if (!keyword) {
98884
+ this.clearSearchState();
98885
+ return;
96465
98886
  }
96466
- const path = [];
96467
- let current = treeNode;
96468
- while (current && current.level > 0) {
96469
- path.unshift(current.data[this.valueKey]);
96470
- current = current.parent;
98887
+ const panel = this.$refs.cascaderPanel;
98888
+ if (panel && panel.store) {
98889
+ this.searchOptions = CascaderUtilsPro.searchFromStore(panel.store, keyword, this.cascaderProps);
98890
+ } else {
98891
+ this.searchOptions = CascaderUtilsPro.searchInTree(this.filteredOptions, keyword, this.cascaderProps);
96471
98892
  }
96472
- return path;
96473
- },
96474
- syncTreeCheckedState() {
98893
+ this.searchLeafSetCache = new Set(CascaderUtilsPro.getLeafValues(this.searchOptions, this.cascaderProps));
98894
+ this.searchSelectedValues = this.getSearchSelectedPathsFromMain(this.searchLeafSetCache);
98895
+ this.isShowSearch = true;
96475
98896
  this.$nextTick(() => {
96476
- const tree = this.$refs.tree;
96477
- if (!tree) return;
96478
- this.isSyncingTree = true;
96479
- if (this.isMultiple) {
96480
- const leafKeys = this.selectedValues.map(path => path[path.length - 1]);
96481
- tree.setCheckedKeys(leafKeys);
96482
- } else if (this.selectedValues.length > 0) {
96483
- const leafKey = this.selectedValues[0][this.selectedValues[0].length - 1];
96484
- tree.setCurrentKey(leafKey);
96485
- } else {
96486
- tree.setCurrentKey(null);
98897
+ if (this.searchOptions.length > 0) {
98898
+ this.syncSearchPanelSelection();
98899
+ this.handleSearchExpand();
96487
98900
  }
96488
- this.$nextTick(() => {
96489
- this.isSyncingTree = false;
96490
- });
96491
98901
  });
96492
98902
  },
96493
- handleTreeCheck() {
96494
- if (this.isSyncingTree) return;
96495
- const tree = this.$refs.tree;
96496
- if (!tree) return;
96497
- const leafKeys = tree.getCheckedKeys(true);
96498
- this.selectedValues = CascaderUtils.findPathsByValues(leafKeys, this.filteredOptions, this.cascaderProps);
96499
- this.updateSelectedItems();
96500
- this.emitInput();
96501
- },
96502
- handleNodeClick(data, node) {
96503
- if (this.isMultiple || this.isViewMode) return;
96504
- const hasChildren = data[this.childrenKey] && data[this.childrenKey].length > 0;
96505
- if (hasChildren) return;
96506
- if (CascaderUtils.isItemDisabled(data, this.disabledConfig)) return;
96507
- this.selectedValues = [this.getNodePath(node)];
96508
- this.updateSelectedItems();
96509
- this.emitInput();
98903
+ getSearchSelectedPathsFromMain(searchLeafSet) {
98904
+ const panel = this.$refs.cascaderPanel;
98905
+ if (panel && panel.selection && panel.store) {
98906
+ const paths = [];
98907
+ panel.selection.selectedLeafSet.forEach(leaf => {
98908
+ if (searchLeafSet.has(leaf)) {
98909
+ const path = panel.store.pathByLeafValue.get(leaf);
98910
+ if (path) {
98911
+ paths.push(path);
98912
+ }
98913
+ }
98914
+ });
98915
+ return paths;
98916
+ }
98917
+ return CascaderUtilsPro.getSearchSelectedValues(this.selectedValues, this.searchOptions, this.cascaderProps);
96510
98918
  },
96511
- handleSearch() {
96512
- if (this.searchDebounceTimer) {
96513
- clearTimeout(this.searchDebounceTimer);
98919
+ getSearchLeafSet() {
98920
+ if (this.searchLeafSetCache) {
98921
+ return this.searchLeafSetCache;
96514
98922
  }
96515
- this.searchDebounceTimer = setTimeout(() => {
96516
- const keyword = this.searchInput.trim();
96517
- if (!keyword) {
96518
- this.displayOptions = this.filteredOptions;
96519
- this.$nextTick(() => this.syncTreeCheckedState());
96520
- return;
96521
- }
96522
- this.displayOptions = CascaderUtils.searchInTree(this.filteredOptions, keyword, this.cascaderProps);
96523
- this.$nextTick(() => {
96524
- this.syncTreeCheckedState();
96525
- this.expandAllNodes();
96526
- });
96527
- }, 300);
98923
+ return new Set(CascaderUtilsPro.getLeafValues(this.searchOptions, this.cascaderProps));
96528
98924
  },
96529
- expandAllNodes() {
96530
- const tree = this.$refs.tree;
96531
- if (!tree || !tree.store) return;
96532
- const expandNode = node => {
96533
- node.expanded = true;
96534
- if (node.childNodes) {
96535
- node.childNodes.forEach(expandNode);
98925
+ syncSearchPanelSelection() {
98926
+ const searchPanel = this.$refs.searchCascaderPanel;
98927
+ const mainPanel = this.$refs.cascaderPanel;
98928
+ if (!searchPanel || !mainPanel || !searchPanel.selection || !mainPanel.selection) {
98929
+ return;
98930
+ }
98931
+ const searchLeafSet = this.getSearchLeafSet();
98932
+ searchPanel.selection.clear();
98933
+ mainPanel.selection.selectedLeafSet.forEach(leaf => {
98934
+ if (searchLeafSet.has(leaf)) {
98935
+ searchPanel.selection.selectedLeafSet.add(leaf);
96536
98936
  }
96537
- };
96538
- tree.store.root.childNodes.forEach(expandNode);
98937
+ });
98938
+ searchPanel.selection._reconcileAllRoots();
98939
+ searchPanel.bumpSelectionView();
96539
98940
  },
96540
- filterNodeMethod() {
96541
- return true;
98941
+ // 搜索模式下的展开处理
98942
+ handleSearchExpand() {
98943
+ if (this.$refs.searchCascaderPanel && this.searchOptions.length > 0) {
98944
+ const firstOption = this.searchOptions[0];
98945
+ const valueKey = this.cascaderProps.value || 'value';
98946
+ this.$refs.searchCascaderPanel.expandPathValues([firstOption[valueKey]], true);
98947
+ }
96542
98948
  },
96543
- handleSelectAll() {
96544
- if (!this.isMultiple) return;
96545
- if (this.isAllSelected) {
96546
- this.selectedValues = [];
96547
- } else {
96548
- this.selectedValues = CascaderUtils.getAllLeafPaths(this.filteredOptions, this.disabledConfig, this.cascaderProps);
98949
+ // 值变化处理
98950
+ handleValueChange() {
98951
+ this.applyPanelSelectionChange();
98952
+ },
98953
+ // 搜索模式值变化处理
98954
+ handleSearchValueChange() {
98955
+ const searchPanel = this.$refs.searchCascaderPanel;
98956
+ const mainPanel = this.$refs.cascaderPanel;
98957
+ if (!searchPanel || !mainPanel || !searchPanel.selection || !mainPanel.selection) {
98958
+ return;
96549
98959
  }
96550
- this.updateSelectedItems();
96551
- this.syncTreeCheckedState();
96552
- this.emitInput();
98960
+ const searchLeafSet = this.getSearchLeafSet();
98961
+ searchLeafSet.forEach(leaf => {
98962
+ const shouldSelect = searchPanel.selection.selectedLeafSet.has(leaf);
98963
+ const isSelected = mainPanel.selection.selectedLeafSet.has(leaf);
98964
+ if (shouldSelect && !isSelected) {
98965
+ mainPanel.selection.selectedLeafSet.add(leaf);
98966
+ } else if (!shouldSelect && isSelected) {
98967
+ mainPanel.selection.selectedLeafSet.delete(leaf);
98968
+ }
98969
+ });
98970
+ mainPanel.selection._reconcileAllRoots();
98971
+ mainPanel.bumpSelectionView();
98972
+ this.applyPanelSelectionChange();
96553
98973
  },
96554
- removeItem(item) {
96555
- const valueToRemove = item.value;
96556
- this.selectedValues = this.selectedValues.filter(path => path[path.length - 1] !== valueToRemove);
96557
- const tree = this.$refs.tree;
96558
- if (tree) {
96559
- tree.setChecked(valueToRemove, false, true);
96560
- if (!this.isMultiple) {
96561
- tree.setCurrentKey(null);
98974
+ // 移除已选项
98975
+ removeItem(item, index) {
98976
+ const panel = this.$refs.cascaderPanel;
98977
+ if (panel && panel.selection) {
98978
+ if (item.isAggregated) {
98979
+ const node = panel.store.nodeByValue.get(item.value);
98980
+ if (node) {
98981
+ panel.selection.toggleNode(node.id, false);
98982
+ }
98983
+ } else if (item.path && item.path.length > 0) {
98984
+ const leafValue = item.path[item.path.length - 1];
98985
+ const leafNode = panel.store.nodeByValue.get(leafValue);
98986
+ if (leafNode) {
98987
+ panel.selection.toggleNode(leafNode.id, false);
98988
+ } else {
98989
+ const node = panel.store.nodeByValue.get(item.value);
98990
+ if (node) {
98991
+ panel.selection.toggleNode(node.id, false);
98992
+ }
98993
+ }
98994
+ } else {
98995
+ const node = panel.store.nodeByValue.get(item.value);
98996
+ if (node) {
98997
+ panel.selection.toggleNode(node.id, false);
98998
+ }
98999
+ }
99000
+ this.applyPanelSelectionChange();
99001
+ if (this.isShowSearch) {
99002
+ this.syncSearchPanelSelection();
96562
99003
  }
99004
+ return;
96563
99005
  }
96564
- this.updateSelectedItems();
96565
- this.emitInput();
96566
- },
96567
- clearSelection() {
96568
- this.selectedValues = [];
96569
- this.updateSelectedItems();
96570
- this.syncTreeCheckedState();
96571
- this.emitInput();
96572
- },
96573
- emitInput() {
99006
+ const valueToRemove = item.value;
99007
+ this.selectedValues = this.selectedValues.filter(path => {
99008
+ return !path.includes(valueToRemove);
99009
+ });
99010
+ this.searchSelectedValues = this.searchSelectedValues.filter(path => {
99011
+ return !path.includes(valueToRemove);
99012
+ });
99013
+ this.selectedItems.splice(index, 1);
96574
99014
  this.$nextTick(() => {
96575
99015
  this.isInternalUpdate = true;
96576
99016
  let emitValue = this.currentValue;
96577
99017
  if (this.aggregationMode) {
96578
- emitValue = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
99018
+ emitValue = CascaderUtilsPro.getAggregatedEmitValues(this.selectedItems, this.parentNodePrefix);
96579
99019
  if (!this.isMultiple && emitValue.length > 0) {
96580
99020
  emitValue = emitValue[0];
96581
99021
  }
@@ -96583,12 +99023,43 @@ var ByTreePanelvue_type_template_id_af06ba0a_staticRenderFns = [];
96583
99023
  this.$emit('input', emitValue);
96584
99024
  });
96585
99025
  },
99026
+ // 全选/取消全选
99027
+ handleSelectAll() {
99028
+ if (!this.isMultiple) {
99029
+ // 单选模式下不支持全选
99030
+ return;
99031
+ }
99032
+ if (this.isAllSelected) {
99033
+ const panel = this.$refs.cascaderPanel;
99034
+ if (panel) {
99035
+ panel.clearCheckedNodes();
99036
+ } else {
99037
+ this.selectedValues = [];
99038
+ this.selectedItems = [];
99039
+ this.searchSelectedValues = [];
99040
+ this.applyPanelSelectionChange();
99041
+ }
99042
+ } else {
99043
+ const panel = this.$refs.cascaderPanel;
99044
+ if (panel) {
99045
+ panel.selectAllLeaves();
99046
+ } else {
99047
+ this.selectedValues = CascaderUtilsPro.getAllLeafPaths(this.filteredOptions, this.disabledConfig, this.cascaderProps);
99048
+ this.updateSelectedItems();
99049
+ this.applyPanelSelectionChange();
99050
+ }
99051
+ }
99052
+ },
99053
+ // 获取选中的数据
96586
99054
  getSelectedData() {
96587
99055
  let values = this.currentValue;
96588
99056
  let valuesPath = this.selectedValues;
99057
+ if (!this.aggregationMode && this.selectedItems.length > 0 && valuesPath.length === 0) {
99058
+ valuesPath = this.selectedItems.map(item => item.path);
99059
+ }
96589
99060
  if (this.aggregationMode) {
96590
- values = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
96591
- valuesPath = CascaderUtils.getAggregatedSelectedPaths(this.selectedValues, this.filteredOptions, this.cascaderProps);
99061
+ values = CascaderUtilsPro.getAggregatedEmitValues(this.selectedItems, this.parentNodePrefix);
99062
+ valuesPath = this.selectedItems.map(item => item.path);
96592
99063
  if (!this.isMultiple && values.length > 0) {
96593
99064
  values = values[0];
96594
99065
  }
@@ -96600,102 +99071,208 @@ var ByTreePanelvue_type_template_id_af06ba0a_staticRenderFns = [];
96600
99071
  count: this.selectedItems.length
96601
99072
  };
96602
99073
  },
99074
+ // 清空选择
99075
+ clearSelection() {
99076
+ const panel = this.$refs.cascaderPanel;
99077
+ if (panel) {
99078
+ panel.clearCheckedNodes();
99079
+ } else {
99080
+ this.selectedValues = [];
99081
+ this.selectedItems = [];
99082
+ this.searchSelectedValues = [];
99083
+ this.applyPanelSelectionChange();
99084
+ }
99085
+ },
99086
+ // 设置选择值
96603
99087
  setValue(values) {
96604
99088
  if (this.isMultiple) {
99089
+ // 多选模式:支持直接传入value值或路径数组
96605
99090
  if (Array.isArray(values) && values.length > 0) {
96606
99091
  if (typeof values[0] === 'string' || typeof values[0] === 'number') {
99092
+ // 传入的是value值数组,需要转换为路径
96607
99093
  if (this.aggregationMode) {
96608
- this.selectedValues = CascaderUtils.processValuesWithParentNodes(values, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
99094
+ // 聚合模式下,支持非叶子节点标识
99095
+ this.selectedValues = CascaderUtilsPro.processValuesWithParentNodes(values, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
96609
99096
  } else {
96610
- this.selectedValues = CascaderUtils.findPathsByValues(values, this.filteredOptions, this.cascaderProps);
99097
+ // 普通模式下,只处理叶子节点
99098
+ this.selectedValues = this.findPathsByValues(values);
96611
99099
  }
96612
99100
  } else {
99101
+ // 传入的是路径数组
96613
99102
  this.selectedValues = [...values];
96614
99103
  }
96615
99104
  } else {
96616
99105
  this.selectedValues = [];
96617
99106
  }
96618
- } else if (values !== null && values !== undefined && values !== '') {
96619
- if (Array.isArray(values)) {
96620
- this.selectedValues = [...values];
96621
- } else if (this.aggregationMode) {
96622
- this.selectedValues = CascaderUtils.processValuesWithParentNodes([values], this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
99107
+ } else {
99108
+ // 单选模式:支持单个值或路径数组
99109
+ if (values !== null && values !== undefined && values !== '') {
99110
+ if (Array.isArray(values)) {
99111
+ // 传入的是路径数组
99112
+ this.selectedValues = [...values];
99113
+ } else {
99114
+ // 传入的是单个值,需要转换为路径
99115
+ if (this.aggregationMode) {
99116
+ // 聚合模式下,支持非叶子节点标识
99117
+ this.selectedValues = CascaderUtilsPro.processValuesWithParentNodes([values], this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
99118
+ } else {
99119
+ // 普通模式下,只处理叶子节点
99120
+ this.selectedValues = this.findPathsByValues([values]);
99121
+ }
99122
+ }
96623
99123
  } else {
96624
- this.selectedValues = CascaderUtils.findPathsByValues([values], this.filteredOptions, this.cascaderProps);
99124
+ this.selectedValues = [];
96625
99125
  }
96626
- } else {
96627
- this.selectedValues = [];
96628
99126
  }
96629
- this.syncTreeCheckedState();
96630
- this.updateSelectedItems();
99127
+ this.schedulePanelSyncFromExternalValue();
99128
+ },
99129
+ // 根据values找到对应的路径
99130
+ findPathsByValues(values) {
99131
+ const paths = [];
99132
+ const findPath = (options, targetValues, currentPath = []) => {
99133
+ for (const option of options) {
99134
+ const newPath = [...currentPath, option[this.cascaderProps.value]];
99135
+ if (targetValues.includes(option[this.cascaderProps.value])) {
99136
+ // 如果是叶子节点(没有children属性),添加到路径中
99137
+ if (!option[this.cascaderProps.children]) {
99138
+ paths.push(newPath);
99139
+ }
99140
+ }
99141
+
99142
+ // 递归查找子节点
99143
+ if (option[this.cascaderProps.children] && option[this.cascaderProps.children].length > 0) {
99144
+ findPath(option[this.cascaderProps.children], targetValues, newPath);
99145
+ }
99146
+ }
99147
+ };
99148
+
99149
+ // 使用 filteredOptions 如果存在,否则使用原始 options
99150
+ const optionsToSearch = this.filteredOptions.length > 0 ? this.filteredOptions : this.options;
99151
+ findPath(optionsToSearch, values);
99152
+ return paths;
96631
99153
  },
99154
+ // 处理批量搜索弹窗显示
96632
99155
  handleBatchSearchShow() {
96633
99156
  if (this.searchInput) {
96634
99157
  this.searchInput = '';
96635
- this.displayOptions = this.filteredOptions;
96636
99158
  }
96637
99159
  },
99160
+ // 处理批量搜索
96638
99161
  handleBatchSearch() {
96639
99162
  if (!this.batchSearchContent.trim()) {
96640
99163
  this.batchSearchVisible = false;
96641
99164
  return;
96642
99165
  }
99166
+
99167
+ // 分割输入内容(支持换行、逗号、分号等分隔符)
96643
99168
  const inputNames = this.batchSearchContent.split(/[\n,;,;\s]+/).filter(item => item.trim()).map(item => item.trim());
96644
99169
  if (inputNames.length === 0) {
96645
99170
  this.batchSearchVisible = false;
96646
99171
  return;
96647
99172
  }
96648
- const matchedPaths = this.searchNamesInTree(inputNames);
99173
+
99174
+ // 在级联数据中搜索匹配的名称
99175
+ const matchedPaths = this.searchNamesInCascader(inputNames);
96649
99176
  if (matchedPaths.length > 0) {
96650
- const newSelectedValues = [...this.selectedValues];
96651
- matchedPaths.forEach(path => {
96652
- const exists = newSelectedValues.some(existingPath => existingPath.length === path.length && existingPath.every((value, index) => value === path[index]));
96653
- if (!exists) {
96654
- newSelectedValues.push(path);
96655
- }
96656
- });
96657
- this.selectedValues = newSelectedValues;
96658
- this.updateSelectedItems();
96659
- this.syncTreeCheckedState();
96660
- this.emitInput();
99177
+ const panel = this.$refs.cascaderPanel;
99178
+ if (panel && panel.selection && panel.store) {
99179
+ matchedPaths.forEach(path => {
99180
+ const leafValue = path[path.length - 1];
99181
+ if (panel.store.pathByLeafValue.has(leafValue)) {
99182
+ panel.selection.selectedLeafSet.add(leafValue);
99183
+ }
99184
+ });
99185
+ panel.selection._reconcileAllRoots();
99186
+ panel.bumpSelectionView();
99187
+ this.applyPanelSelectionChange();
99188
+ } else {
99189
+ const newSelectedValues = [...this.selectedValues];
99190
+ matchedPaths.forEach(path => {
99191
+ const exists = newSelectedValues.some(existingPath => existingPath.length === path.length && existingPath.every((value, index) => value === path[index]));
99192
+ if (!exists) {
99193
+ newSelectedValues.push(path);
99194
+ }
99195
+ });
99196
+ this.selectedValues = newSelectedValues;
99197
+ this.updateSelectedItems();
99198
+ this.$nextTick(() => {
99199
+ this.isInternalUpdate = true;
99200
+ let emitValue = this.currentValue;
99201
+ if (this.aggregationMode) {
99202
+ emitValue = CascaderUtilsPro.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
99203
+ if (!this.isMultiple && emitValue.length > 0) {
99204
+ emitValue = emitValue[0];
99205
+ }
99206
+ }
99207
+ this.$emit('input', emitValue);
99208
+ });
99209
+ }
96661
99210
  }
99211
+
99212
+ // 关闭弹窗并清空内容
96662
99213
  this.batchSearchVisible = false;
96663
99214
  this.batchSearchContent = '';
96664
99215
  },
96665
- searchNamesInTree(names) {
99216
+ // 在级联数据中搜索匹配的名称(全匹配,忽略空格,排除禁用项)
99217
+ searchNamesInCascader(names) {
96666
99218
  const matchedPaths = [];
99219
+ const labelKey = this.cascaderProps.label || 'label';
96667
99220
  const searchInOptions = (options, currentPath = []) => {
96668
99221
  for (const option of options) {
96669
- const newPath = [...currentPath, option[this.valueKey]];
96670
- const optionLabel = String(option[this.labelKey] || '').replace(/\s+/g, '');
99222
+ const newPath = [...currentPath, option[this.cascaderProps.value]];
99223
+ const optionLabel = String(option[labelKey] || '').replace(/\s+/g, ''); // 去掉所有空格
99224
+
99225
+ // 检查是否全匹配任何输入的名称(去掉空格后比较)
96671
99226
  const isMatched = names.some(name => {
96672
- const cleanName = name.replace(/\s+/g, '');
99227
+ const cleanName = name.replace(/\s+/g, ''); // 去掉输入名称中的空格
96673
99228
  return optionLabel.toLowerCase() === cleanName.toLowerCase();
96674
99229
  });
96675
- const isLeafNode = !option[this.childrenKey] || option[this.childrenKey].length === 0;
96676
- const isNotDisabled = !CascaderUtils.isItemDisabled(option, this.disabledConfig);
99230
+
99231
+ // 检查是否为叶子节点且匹配且未禁用
99232
+ const isLeafNode = !option[this.cascaderProps.children];
99233
+ const isNotDisabled = !this.isItemDisabled(option);
96677
99234
  if (isMatched && isLeafNode && isNotDisabled) {
99235
+ // 如果是叶子节点、匹配且未禁用,添加到结果中
96678
99236
  matchedPaths.push(newPath);
96679
99237
  }
96680
- if (option[this.childrenKey] && option[this.childrenKey].length > 0) {
96681
- searchInOptions(option[this.childrenKey], newPath);
99238
+
99239
+ // 递归搜索子节点
99240
+ if (option[this.cascaderProps.children] && option[this.cascaderProps.children].length > 0) {
99241
+ searchInOptions(option[this.cascaderProps.children], newPath);
96682
99242
  }
96683
99243
  }
96684
99244
  };
96685
99245
  searchInOptions(this.filteredOptions);
96686
99246
  return matchedPaths;
96687
99247
  },
96688
- getSelectedItemKey(item, index) {
96689
- if (item.path && item.path.length) {
96690
- return item.path.join('__');
96691
- }
96692
- return `${item.value}_${index}`;
99248
+ // 强制调整已选项的垂直居中样式
99249
+ forceVerticalCenter() {
99250
+ this.$nextTick(() => {
99251
+ const itemLabels = this.$el.querySelectorAll('.item-label');
99252
+ itemLabels.forEach(label => {
99253
+ if (label) {
99254
+ // 使用JavaScript强制设置样式
99255
+ label.style.setProperty('display', 'flex', 'important');
99256
+ label.style.setProperty('align-items', 'center', 'important');
99257
+ label.style.setProperty('height', '36px', 'important');
99258
+ label.style.setProperty('line-height', '36px', 'important');
99259
+ label.style.setProperty('margin', '0', 'important');
99260
+ label.style.setProperty('padding', '0', 'important');
99261
+ label.style.setProperty('vertical-align', 'middle', 'important');
99262
+ label.style.setProperty('font-size', '14px', 'important');
99263
+ }
99264
+ });
99265
+ });
96693
99266
  }
99267
+ },
99268
+ updated() {
99269
+ // 组件更新后强制调整样式
99270
+ this.forceVerticalCenter();
96694
99271
  }
96695
99272
  });
96696
- ;// ./src/components/tree-panel/ByTreePanel.vue?vue&type=script&lang=js
96697
- /* harmony default export */ var tree_panel_ByTreePanelvue_type_script_lang_js = (ByTreePanelvue_type_script_lang_js);
96698
- ;// ./src/components/tree-panel/ByTreePanel.vue
99273
+ ;// ./src/components/cascader-panel-pro/ByCascaderPanelPro.vue?vue&type=script&lang=js
99274
+ /* harmony default export */ var cascader_panel_pro_ByCascaderPanelProvue_type_script_lang_js = (ByCascaderPanelProvue_type_script_lang_js);
99275
+ ;// ./src/components/cascader-panel-pro/ByCascaderPanelPro.vue
96699
99276
 
96700
99277
 
96701
99278
 
@@ -96703,10 +99280,10 @@ var ByTreePanelvue_type_template_id_af06ba0a_staticRenderFns = [];
96703
99280
 
96704
99281
  /* normalize component */
96705
99282
  ;
96706
- var ByTreePanel_component = normalizeComponent(
96707
- tree_panel_ByTreePanelvue_type_script_lang_js,
96708
- ByTreePanelvue_type_template_id_af06ba0a_render,
96709
- ByTreePanelvue_type_template_id_af06ba0a_staticRenderFns,
99283
+ var ByCascaderPanelPro_component = normalizeComponent(
99284
+ cascader_panel_pro_ByCascaderPanelProvue_type_script_lang_js,
99285
+ ByCascaderPanelProvue_type_template_id_804df886_render,
99286
+ ByCascaderPanelProvue_type_template_id_804df886_staticRenderFns,
96710
99287
  false,
96711
99288
  null,
96712
99289
  null,
@@ -96714,7 +99291,7 @@ var ByTreePanel_component = normalizeComponent(
96714
99291
 
96715
99292
  )
96716
99293
 
96717
- /* harmony default export */ var ByTreePanel = (ByTreePanel_component.exports);
99294
+ /* harmony default export */ var ByCascaderPanelPro = (ByCascaderPanelPro_component.exports);
96718
99295
  ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"8cd600e8-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.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/floating-menu/ByFloatingMenu.vue?vue&type=template&id=04723f13
96719
99296
  var ByFloatingMenuvue_type_template_id_04723f13_render = function render() {
96720
99297
  var _vm = this,
@@ -99428,7 +102005,7 @@ const components = {
99428
102005
  ByTreeSearch: ByTreeSearch,
99429
102006
  ByDialog: ByDialog,
99430
102007
  ByCascaderPanel: ByCascaderPanel,
99431
- ByTreePanel: ByTreePanel,
102008
+ ByCascaderPanelPro: ByCascaderPanelPro,
99432
102009
  ByFloatingMenu: ByFloatingMenu,
99433
102010
  ByPopoverSelector: ByPopoverSelector,
99434
102011
  ByGridLayout: ByGridLayout,