@weitutech/by-components 1.1.96 → 1.1.98

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.
@@ -60513,6 +60513,7 @@ __webpack_require__.r(__webpack_exports__);
60513
60513
  // EXPORTS
60514
60514
  __webpack_require__.d(__webpack_exports__, {
60515
60515
  ByBatchQuerySelector: function() { return /* reexport */ BatchQuerySelector; },
60516
+ ByCascaderPanel: function() { return /* reexport */ ByCascaderPanel; },
60516
60517
  ByCommonSelector: function() { return /* reexport */ ByCommonSelector; },
60517
60518
  ByCustomDatePicker: function() { return /* reexport */ custom_date_picker; },
60518
60519
  ByDatePickerRange: function() { return /* reexport */ date_picker_range; },
@@ -76942,8 +76943,8 @@ var ByTreeSearch_component = normalizeComponent(
76942
76943
  )
76943
76944
 
76944
76945
  /* harmony default export */ var ByTreeSearch = (ByTreeSearch_component.exports);
76945
- ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"ffbc40de-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/by-dialog/ByDialog.vue?vue&type=template&id=7a5fdd30
76946
- var ByDialogvue_type_template_id_7a5fdd30_render = function render() {
76946
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"ffbc40de-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/by-dialog/ByDialog.vue?vue&type=template&id=75a24552
76947
+ var ByDialogvue_type_template_id_75a24552_render = function render() {
76947
76948
  var _vm = this,
76948
76949
  _c = _vm._self._c;
76949
76950
  return _c('el-dialog', _vm._g(_vm._b({
@@ -76960,11 +76961,9 @@ var ByDialogvue_type_template_id_7a5fdd30_render = function render() {
76960
76961
  }
76961
76962
  }, 'el-dialog', _vm.dialogAttrs, false), _vm.$listeners), [_c('div', {
76962
76963
  staticClass: "by-dialog__body"
76963
- }, [_vm._t("default", function () {
76964
- return [_vm.content ? _c('div', {
76965
- staticClass: "by-dialog__content"
76966
- }, [_vm._v(_vm._s(_vm.content))]) : _vm._e()];
76967
- })], 2), _vm.showFooter ? _c('div', {
76964
+ }, [_vm.content ? _c('div', {
76965
+ staticClass: "by-dialog__content"
76966
+ }, [_vm._v(_vm._s(_vm.content))]) : _vm._e(), _vm._t("default")], 2), _vm.showFooter ? _c('div', {
76968
76967
  staticClass: "by-dialog__footer"
76969
76968
  }, [_c('div', {
76970
76969
  staticClass: "by-dialog__buttons"
@@ -76975,7 +76974,7 @@ var ByDialogvue_type_template_id_7a5fdd30_render = function render() {
76975
76974
  style: button.style,
76976
76975
  attrs: {
76977
76976
  "type": button.type || 'default',
76978
- "size": button.size || 'medium',
76977
+ "size": button.size || 'mini',
76979
76978
  "loading": button.loading,
76980
76979
  "disabled": button.disabled,
76981
76980
  "icon": button.icon
@@ -76988,7 +76987,7 @@ var ByDialogvue_type_template_id_7a5fdd30_render = function render() {
76988
76987
  }, [_vm._v(" " + _vm._s(button.text) + " ")])];
76989
76988
  })], 2), _vm._t("footer")], 2) : _vm._e()]);
76990
76989
  };
76991
- var ByDialogvue_type_template_id_7a5fdd30_staticRenderFns = [];
76990
+ var ByDialogvue_type_template_id_75a24552_staticRenderFns = [];
76992
76991
 
76993
76992
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.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/by-dialog/ByDialog.vue?vue&type=script&lang=js
76994
76993
  /* harmony default export */ var ByDialogvue_type_script_lang_js = ({
@@ -77127,8 +77126,8 @@ var ByDialogvue_type_template_id_7a5fdd30_staticRenderFns = [];
77127
77126
  ;
77128
77127
  var ByDialog_component = normalizeComponent(
77129
77128
  by_dialog_ByDialogvue_type_script_lang_js,
77130
- ByDialogvue_type_template_id_7a5fdd30_render,
77131
- ByDialogvue_type_template_id_7a5fdd30_staticRenderFns,
77129
+ ByDialogvue_type_template_id_75a24552_render,
77130
+ ByDialogvue_type_template_id_75a24552_staticRenderFns,
77132
77131
  false,
77133
77132
  null,
77134
77133
  null,
@@ -77528,6 +77527,1478 @@ ByDialogService.install = function (Vue) {
77528
77527
  Vue.prototype.$byDialog = ByDialogService;
77529
77528
  };
77530
77529
  /* harmony default export */ var by_dialog_ByDialogService = (ByDialogService);
77530
+ ;// ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"ffbc40de-vue-loader-template"}!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/cache-loader/dist/cjs.js??ruleSet[0].use[0]!./node_modules/@vue/cli-service/node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/cascader-panel/ByCascaderPanel.vue?vue&type=template&id=d3dd0512
77531
+ var ByCascaderPanelvue_type_template_id_d3dd0512_render = function render() {
77532
+ var _vm = this,
77533
+ _c = _vm._self._c;
77534
+ return _c('div', {
77535
+ staticClass: "by-cascader-panel"
77536
+ }, [_c('div', {
77537
+ staticClass: "cascade-box row"
77538
+ }, [_c('div', {
77539
+ staticClass: "cascade-container left-panel"
77540
+ }, [_c('div', {
77541
+ staticClass: "cascade-title row column-c"
77542
+ }, [!_vm.aggregationMode ? _c('div', {
77543
+ staticClass: "txt"
77544
+ }, [_vm._v("可选(" + _vm._s(_vm.selectedCount) + "/" + _vm._s(_vm.totalCount) + ")")]) : _vm._e(), _c('div', {
77545
+ staticClass: "cell",
77546
+ staticStyle: {
77547
+ "padding-left": "20px"
77548
+ }
77549
+ }, [_c('el-input', {
77550
+ staticClass: "search-input",
77551
+ attrs: {
77552
+ "placeholder": _vm.searchPlaceholder,
77553
+ "clearable": ""
77554
+ },
77555
+ on: {
77556
+ "input": _vm.handleSearch
77557
+ },
77558
+ model: {
77559
+ value: _vm.searchInput,
77560
+ callback: function ($$v) {
77561
+ _vm.searchInput = $$v;
77562
+ },
77563
+ expression: "searchInput"
77564
+ }
77565
+ })], 1), _c('div', {
77566
+ staticClass: "menu"
77567
+ }, [_vm.searchInput === '' && _vm.isMultiple && _vm.showSelectAll ? _c('div', {
77568
+ staticClass: "all-select",
77569
+ on: {
77570
+ "click": _vm.handleSelectAll
77571
+ }
77572
+ }, [_vm._v(" " + _vm._s(_vm.isAllSelected ? '取消全选' : '全选') + " ")]) : _vm._e()])]), _c('div', {
77573
+ staticClass: "cascade-content",
77574
+ staticStyle: {
77575
+ "border": "1px solid #dcdfe6",
77576
+ "overflow-x": "scroll",
77577
+ "padding": "20px 20px 20px 20px"
77578
+ },
77579
+ style: {
77580
+ height: _vm.computedPanelHeight + 'px'
77581
+ }
77582
+ }, [_c('div', [_vm.isShow && _vm.filteredOptions.length > 0 ? _c('el-cascader-panel', {
77583
+ directives: [{
77584
+ name: "show",
77585
+ rawName: "v-show",
77586
+ value: _vm.searchInput === '' || !_vm.isShowSearch,
77587
+ expression: "searchInput === '' || !isShowSearch"
77588
+ }],
77589
+ ref: "cascaderPanel",
77590
+ staticClass: "singleCascader",
77591
+ style: {
77592
+ height: _vm.computedPanelHeight - 50 + 'px'
77593
+ },
77594
+ attrs: {
77595
+ "append-to-body": false,
77596
+ "options": _vm.filteredOptions,
77597
+ "props": _vm.cascaderProps
77598
+ },
77599
+ on: {
77600
+ "expand-change": _vm.handleExpandChange,
77601
+ "change": _vm.handleValueChange
77602
+ },
77603
+ model: {
77604
+ value: _vm.mainPanelValue,
77605
+ callback: function ($$v) {
77606
+ _vm.mainPanelValue = $$v;
77607
+ },
77608
+ expression: "mainPanelValue"
77609
+ }
77610
+ }) : _vm._e(), _vm.searchOptions.length > 0 ? _c('el-cascader-panel', {
77611
+ directives: [{
77612
+ name: "show",
77613
+ rawName: "v-show",
77614
+ value: _vm.searchInput !== '' && _vm.isShowSearch,
77615
+ expression: "searchInput !== '' && isShowSearch"
77616
+ }],
77617
+ ref: "searchCascaderPanel",
77618
+ staticClass: "singleCascader",
77619
+ style: {
77620
+ height: _vm.computedPanelHeight - 50 + 'px'
77621
+ },
77622
+ attrs: {
77623
+ "append-to-body": false,
77624
+ "options": _vm.searchOptions,
77625
+ "props": _vm.cascaderProps
77626
+ },
77627
+ on: {
77628
+ "expand-change": _vm.handleExpandChange,
77629
+ "change": _vm.handleSearchValueChange
77630
+ },
77631
+ model: {
77632
+ value: _vm.searchPanelValue,
77633
+ callback: function ($$v) {
77634
+ _vm.searchPanelValue = $$v;
77635
+ },
77636
+ expression: "searchPanelValue"
77637
+ }
77638
+ }) : _vm._e()], 1), _vm.isShowSearch && _vm.searchOptions.length === 0 ? _c('div', {
77639
+ directives: [{
77640
+ name: "show",
77641
+ rawName: "v-show",
77642
+ value: _vm.searchInput !== '',
77643
+ expression: "searchInput !== ''"
77644
+ }],
77645
+ staticClass: "row column-c row-c",
77646
+ staticStyle: {
77647
+ "width": "100%",
77648
+ "height": "100%"
77649
+ }
77650
+ }, [_c('el-empty', {
77651
+ attrs: {
77652
+ "image-size": 100
77653
+ }
77654
+ })], 1) : _vm._e()])]), _c('div', {
77655
+ staticClass: "cascade-container bb right-panel"
77656
+ }, [_c('div', {
77657
+ staticClass: "cascade-title row column-c"
77658
+ }, [_c('div', {
77659
+ staticClass: "txt"
77660
+ }, [_vm._v("已选(" + _vm._s(_vm.selectedItems.length) + ")")]), _c('div', {
77661
+ staticClass: "menu"
77662
+ }, [_vm.selectedItems.length > 0 ? _c('div', {
77663
+ staticClass: "clear-btn",
77664
+ on: {
77665
+ "click": _vm.clearSelection
77666
+ }
77667
+ }, [_vm._v("清除")]) : _vm._e()])]), _c('div', {
77668
+ staticClass: "cascade-content",
77669
+ style: {
77670
+ height: _vm.computedPanelHeight - 5 + 'px'
77671
+ }
77672
+ }, [_c('div', {
77673
+ staticClass: "item",
77674
+ staticStyle: {
77675
+ "overflow-y": "auto",
77676
+ "height": "100%",
77677
+ "max-height": "100%"
77678
+ }
77679
+ }, _vm._l(_vm.selectedItems, function (item, index) {
77680
+ return _c('div', {
77681
+ key: item.value,
77682
+ staticClass: "check-box row column-c",
77683
+ staticStyle: {
77684
+ "height": "36px",
77685
+ "flex-shrink": "0"
77686
+ }
77687
+ }, [_c('div', {
77688
+ staticClass: "cell",
77689
+ staticStyle: {
77690
+ "white-space": "nowrap",
77691
+ "overflow": "hidden",
77692
+ "text-overflow": "ellipsis"
77693
+ }
77694
+ }, [_vm._v(" " + _vm._s(item.label || '') + " ")]), _c('div', {
77695
+ staticClass: "icon",
77696
+ staticStyle: {
77697
+ "cursor": "pointer"
77698
+ },
77699
+ on: {
77700
+ "click": function ($event) {
77701
+ return _vm.removeItem(item, index);
77702
+ }
77703
+ }
77704
+ }, [_c('i', {
77705
+ staticClass: "el-icon-close"
77706
+ })])]);
77707
+ }), 0)])])])]);
77708
+ };
77709
+ var ByCascaderPanelvue_type_template_id_d3dd0512_staticRenderFns = [];
77710
+
77711
+ ;// ./src/utils/cascaderUtils.js
77712
+
77713
+
77714
+
77715
+
77716
+
77717
+
77718
+
77719
+
77720
+
77721
+
77722
+
77723
+
77724
+
77725
+
77726
+
77727
+ /**
77728
+ * 级联选择器工具类
77729
+ */
77730
+ class CascaderUtils {
77731
+ /**
77732
+ * 判断项目是否禁用
77733
+ * @param {Object} item - 项目数据
77734
+ * @param {Object} config - 禁用配置
77735
+ * @param {String} config.disabledField - 禁用字段名
77736
+ * @param {*} config.disabledValue - 禁用值
77737
+ * @param {Function} config.disabledCheck - 自定义禁用判断函数
77738
+ * @returns {Boolean} 是否禁用
77739
+ */
77740
+ static isItemDisabled(item, config) {
77741
+ const {
77742
+ disabledField,
77743
+ disabledValue,
77744
+ disabledCheck
77745
+ } = config;
77746
+
77747
+ // 优先使用自定义禁用判断函数
77748
+ if (disabledCheck && typeof disabledCheck === 'function') {
77749
+ return disabledCheck(item);
77750
+ }
77751
+
77752
+ // 检查直接的 disabled 属性
77753
+ if (item.disabled === true) {
77754
+ return true;
77755
+ }
77756
+
77757
+ // 使用字段判断
77758
+ const fieldValue = item[disabledField];
77759
+ if (fieldValue !== undefined) {
77760
+ return fieldValue === disabledValue;
77761
+ }
77762
+ return false;
77763
+ }
77764
+
77765
+ /**
77766
+ * 检查路径上是否存在禁选项
77767
+ * @param {Array} tree - 树形数据
77768
+ * @param {Array} path - 路径数组
77769
+ * @param {Object} config - 禁用配置
77770
+ * @param {Object} cascaderProps - 级联配置
77771
+ * @returns {Boolean} 路径上是否存在禁选项
77772
+ */
77773
+ static isPathDisabled(tree, path, config, cascaderProps) {
77774
+ if (!path || path.length === 0) return false;
77775
+ const findPathInTree = (nodes, targetPath, currentIndex = 0) => {
77776
+ if (currentIndex >= targetPath.length) return false;
77777
+ for (const node of nodes) {
77778
+ if (node[cascaderProps.value] === targetPath[currentIndex]) {
77779
+ // 检查当前节点是否禁用
77780
+ if (this.isItemDisabled(node, config)) {
77781
+ return true;
77782
+ }
77783
+
77784
+ // 如果还有下一级,继续检查
77785
+ if (currentIndex < targetPath.length - 1 && node[cascaderProps.children]) {
77786
+ return findPathInTree(node[cascaderProps.children], targetPath, currentIndex + 1);
77787
+ }
77788
+
77789
+ // 如果已经到达路径末尾,返回false(路径上没有禁选项)
77790
+ return false;
77791
+ }
77792
+ }
77793
+ return false;
77794
+ };
77795
+ return findPathInTree(tree, path);
77796
+ }
77797
+
77798
+ /**
77799
+ * 设置禁用项
77800
+ * @param {Array} options - 选项数据
77801
+ * @param {Object} config - 禁用配置
77802
+ * @param {Object} cascaderProps - 级联配置
77803
+ */
77804
+ static setDisabledItems(options, config, cascaderProps) {
77805
+ const processItems = items => {
77806
+ items.forEach(item => {
77807
+ // 判断是否禁用
77808
+ if (this.isItemDisabled(item, config)) {
77809
+ item.disabled = true;
77810
+ }
77811
+ // 递归处理子项
77812
+ if (item[cascaderProps.children]) {
77813
+ processItems(item[cascaderProps.children]);
77814
+ }
77815
+ });
77816
+ };
77817
+ processItems(options);
77818
+ }
77819
+
77820
+ /**
77821
+ * 统计总项目数(排除禁用项和路径上有禁选项的项)
77822
+ * @param {Array} options - 选项数据
77823
+ * @param {Object} config - 禁用配置
77824
+ * @param {Object} cascaderProps - 级联配置
77825
+ * @returns {Number} 总项目数
77826
+ */
77827
+ static countTotalItems(options, config, cascaderProps) {
77828
+ let totalCount = 0;
77829
+ const countItems = (items, currentPath = []) => {
77830
+ items.forEach(item => {
77831
+ const newPath = [...currentPath, item[cascaderProps.value]];
77832
+
77833
+ // 检查当前节点是否禁用
77834
+ const isCurrentDisabled = this.isItemDisabled(item, config);
77835
+ if (!item[cascaderProps.children]) {
77836
+ // 只统计非禁用项且路径上没有禁选项的叶子节点
77837
+ if (!isCurrentDisabled && !this.isPathDisabled(options, newPath, config, cascaderProps)) {
77838
+ totalCount++;
77839
+ }
77840
+ } else {
77841
+ // 如果当前节点禁用,则其所有子节点都不可选
77842
+ if (!isCurrentDisabled) {
77843
+ countItems(item[cascaderProps.children], newPath);
77844
+ }
77845
+ }
77846
+ });
77847
+ };
77848
+ countItems(options);
77849
+ return totalCount;
77850
+ }
77851
+
77852
+ /**
77853
+ * 在树形数据中搜索
77854
+ * @param {Array} tree - 树形数据
77855
+ * @param {String} keyword - 搜索关键词
77856
+ * @param {Object} cascaderProps - 级联配置
77857
+ * @returns {Array} 搜索结果
77858
+ */
77859
+ static searchInTree(tree, keyword, cascaderProps) {
77860
+ const result = [];
77861
+ tree.forEach(node => {
77862
+ if (node[cascaderProps.label].includes(keyword)) {
77863
+ const matchedNode = {
77864
+ ...node
77865
+ };
77866
+ result.push(matchedNode);
77867
+ } else if (node[cascaderProps.children]) {
77868
+ const matchedChildren = this.searchInTree(node[cascaderProps.children], keyword, cascaderProps);
77869
+ if (matchedChildren.length > 0) {
77870
+ const matchedNode = {
77871
+ ...node,
77872
+ [cascaderProps.children]: matchedChildren
77873
+ };
77874
+ result.push(matchedNode);
77875
+ }
77876
+ }
77877
+ });
77878
+ return result;
77879
+ }
77880
+
77881
+ /**
77882
+ * 获取叶子节点的值
77883
+ * @param {Array} tree - 树形数据
77884
+ * @param {Object} cascaderProps - 级联配置
77885
+ * @returns {Array} 叶子节点值数组
77886
+ */
77887
+ static getLeafValues(tree, cascaderProps) {
77888
+ const leafValues = [];
77889
+ const traverse = nodes => {
77890
+ nodes.forEach(node => {
77891
+ if (!node[cascaderProps.children]) {
77892
+ leafValues.push(node[cascaderProps.value]);
77893
+ } else {
77894
+ traverse(node[cascaderProps.children]);
77895
+ }
77896
+ });
77897
+ };
77898
+ traverse(tree);
77899
+ return leafValues;
77900
+ }
77901
+
77902
+ /**
77903
+ * 获取所有叶子节点的路径(排除禁用项和路径上有禁选项的项)
77904
+ * @param {Array} tree - 树形数据
77905
+ * @param {Object} config - 禁用配置
77906
+ * @param {Object} cascaderProps - 级联配置
77907
+ * @returns {Array} 路径数组
77908
+ */
77909
+ static getAllLeafPaths(tree, config, cascaderProps) {
77910
+ const paths = [];
77911
+ const traverse = (nodes, currentPath = []) => {
77912
+ nodes.forEach(node => {
77913
+ const newPath = [...currentPath, node[cascaderProps.value]];
77914
+
77915
+ // 检查当前节点是否禁用
77916
+ const isCurrentDisabled = this.isItemDisabled(node, config);
77917
+ if (!node[cascaderProps.children]) {
77918
+ // 只包含非禁用项且路径上没有禁选项的叶子节点
77919
+ if (!isCurrentDisabled && !this.isPathDisabled(tree, newPath, config, cascaderProps)) {
77920
+ paths.push(newPath);
77921
+ }
77922
+ } else {
77923
+ // 如果当前节点禁用,则其所有子节点都不可选
77924
+ if (!isCurrentDisabled) {
77925
+ traverse(node[cascaderProps.children], newPath);
77926
+ }
77927
+ }
77928
+ });
77929
+ };
77930
+ traverse(tree);
77931
+ return paths;
77932
+ }
77933
+
77934
+ /**
77935
+ * 根据路径查找节点
77936
+ * @param {Array} tree - 树形数据
77937
+ * @param {Array} path - 路径数组
77938
+ * @param {Object} cascaderProps - 级联配置
77939
+ * @returns {Object|null} 找到的节点
77940
+ */
77941
+ static findNodeByPath(tree, path, cascaderProps) {
77942
+ if (!path || path.length === 0) return null;
77943
+ const findInTree = (nodes, targetPath) => {
77944
+ for (const node of nodes) {
77945
+ if (node[cascaderProps.value] == targetPath[0]) {
77946
+ if (targetPath.length === 1) {
77947
+ return node;
77948
+ } else if (node[cascaderProps.children]) {
77949
+ return findInTree(node[cascaderProps.children], targetPath.slice(1));
77950
+ }
77951
+ }
77952
+ }
77953
+ return null;
77954
+ };
77955
+ return findInTree(tree, path);
77956
+ }
77957
+
77958
+ /**
77959
+ * 基于 selectedValues 构建已选项列表
77960
+ * @param {Array} selectedValues - 已选值数组
77961
+ * @param {Array} options - 选项数据
77962
+ * @param {Object} cascaderProps - 级联配置
77963
+ * @returns {Array} 已选项列表
77964
+ */
77965
+ static buildSelectedItemsFromValues(selectedValues, options, cascaderProps) {
77966
+ const items = [];
77967
+ selectedValues.forEach(path => {
77968
+ if (path.length > 0) {
77969
+ const leafValue = path[path.length - 1];
77970
+ // 从原始数据中查找对应的节点信息
77971
+ const node = this.findNodeByPath(options, path, cascaderProps);
77972
+ if (node) {
77973
+ items.push({
77974
+ value: leafValue,
77975
+ label: node[cascaderProps.label],
77976
+ path: path
77977
+ });
77978
+ }
77979
+ }
77980
+ });
77981
+ return items;
77982
+ }
77983
+
77984
+ /**
77985
+ * 获取搜索范围内的选中值
77986
+ * @param {Array} selectedValues - 已选值数组
77987
+ * @param {Array} searchOptions - 搜索结果
77988
+ * @param {Object} cascaderProps - 级联配置
77989
+ * @returns {Array} 搜索范围内的选中值
77990
+ */
77991
+ static getSearchSelectedValues(selectedValues, searchOptions, cascaderProps) {
77992
+ const searchLeafValues = this.getLeafValues(searchOptions, cascaderProps);
77993
+ return selectedValues.filter(path => {
77994
+ const leafValue = path[path.length - 1];
77995
+ return searchLeafValues.includes(leafValue);
77996
+ });
77997
+ }
77998
+
77999
+ /**
78000
+ * 检查父项的所有子项是否都被选中
78001
+ * @param {Object} parentNode - 父节点
78002
+ * @param {Array} selectedValues - 已选值数组
78003
+ * @param {Object} cascaderProps - 级联配置
78004
+ * @returns {Boolean} 是否所有子项都被选中
78005
+ */
78006
+ static isParentFullySelected(parentNode, selectedValues, cascaderProps) {
78007
+ if (!parentNode[cascaderProps.children]) {
78008
+ return false;
78009
+ }
78010
+
78011
+ // 获取父项的所有叶子节点
78012
+ const allLeafValues = this.getLeafValues([parentNode], cascaderProps);
78013
+
78014
+ // 检查所有叶子节点是否都在选中值中
78015
+ return allLeafValues.every(leafValue => {
78016
+ return selectedValues.some(path => {
78017
+ const pathLeafValue = path[path.length - 1];
78018
+ return pathLeafValue === leafValue;
78019
+ });
78020
+ });
78021
+ }
78022
+
78023
+ /**
78024
+ * 根据路径获取对应的标签数组
78025
+ * @param {Array} path - 节点路径
78026
+ * @param {Array} options - 选项数据
78027
+ * @param {Object} cascaderProps - 级联配置
78028
+ * @returns {Array} 标签数组
78029
+ */
78030
+ static getPathLabels(path, options, cascaderProps) {
78031
+ const labels = [];
78032
+ let currentNodes = options;
78033
+ for (let i = 0; i < path.length; i++) {
78034
+ const targetValue = path[i];
78035
+ const foundNode = currentNodes.find(node => node[cascaderProps.value] === targetValue);
78036
+ if (foundNode) {
78037
+ labels.push(foundNode[cascaderProps.label]);
78038
+ if (foundNode[cascaderProps.children] && i < path.length - 1) {
78039
+ currentNodes = foundNode[cascaderProps.children];
78040
+ }
78041
+ } else {
78042
+ labels.push(targetValue); // 如果找不到对应的节点,使用原始值
78043
+ }
78044
+ }
78045
+ return labels;
78046
+ }
78047
+
78048
+ /**
78049
+ * 构建完整的节点信息对象
78050
+ * @param {Object} node - 原始节点数据
78051
+ * @param {Array} path - 节点路径
78052
+ * @param {Object} cascaderProps - 级联配置
78053
+ * @param {Array} options - 选项数据
78054
+ * @param {Boolean} isAggregated - 是否为聚合项
78055
+ * @returns {Object} 完整的节点信息对象
78056
+ */
78057
+ static buildCompleteNodeInfo(node, path, cascaderProps, options, isAggregated = false) {
78058
+ const hasChildren = !!node[cascaderProps.children];
78059
+ const level = path.length - 1;
78060
+ return {
78061
+ // 基本属性
78062
+ value: node[cascaderProps.value],
78063
+ label: node[cascaderProps.label],
78064
+ path: path,
78065
+ isAggregated: isAggregated,
78066
+ // 节点结构信息
78067
+ hasChildren: hasChildren,
78068
+ level: level,
78069
+ children: hasChildren ? node[cascaderProps.children] : undefined,
78070
+ // 级联面板相关属性
78071
+ checked: true,
78072
+ indeterminate: false,
78073
+ loaded: true,
78074
+ loading: false,
78075
+ // 原始数据
78076
+ data: node,
78077
+ // 路径相关
78078
+ pathLabels: this.getPathLabels(path, options, cascaderProps),
78079
+ // 其他可能需要的属性
78080
+ config: cascaderProps,
78081
+ parent: null,
78082
+ // 在级联面板中会动态设置
78083
+ pathNodes: null // 在级联面板中会动态设置
78084
+ };
78085
+ }
78086
+
78087
+ /**
78088
+ * 获取聚合模式下的选中项(如果父项完全选中,则只返回父项)
78089
+ * @param {Array} selectedValues - 已选值数组
78090
+ * @param {Array} options - 选项数据
78091
+ * @param {Object} cascaderProps - 级联配置
78092
+ * @returns {Array} 聚合后的选中项列表
78093
+ */
78094
+ static getAggregatedSelectedItems(selectedValues, options, cascaderProps) {
78095
+ const items = [];
78096
+ const processedPaths = new Set();
78097
+
78098
+ // 递归检查每个节点
78099
+ const checkNode = (nodes, currentPath = []) => {
78100
+ nodes.forEach(node => {
78101
+ const newPath = [...currentPath, node[cascaderProps.value]];
78102
+ const pathKey = newPath.join(',');
78103
+
78104
+ // 如果这个路径已经被处理过,跳过
78105
+ if (processedPaths.has(pathKey)) {
78106
+ return;
78107
+ }
78108
+
78109
+ // 检查当前节点是否完全选中
78110
+ if (this.isParentFullySelected(node, selectedValues, cascaderProps)) {
78111
+ // 父项完全选中,添加父项
78112
+ items.push(this.buildCompleteNodeInfo(node, newPath, cascaderProps, options, true));
78113
+
78114
+ // 标记所有子路径为已处理
78115
+ const allLeafValues = this.getLeafValues([node], cascaderProps);
78116
+ selectedValues.forEach(path => {
78117
+ const pathLeafValue = path[path.length - 1];
78118
+ if (allLeafValues.includes(pathLeafValue)) {
78119
+ processedPaths.add(path.join(','));
78120
+ }
78121
+ });
78122
+ } else if (!node[cascaderProps.children]) {
78123
+ // 叶子节点,检查是否在选中值中且未被父项覆盖
78124
+ const leafValue = node[cascaderProps.value];
78125
+ const isSelected = selectedValues.some(path => {
78126
+ const pathLeafValue = path[path.length - 1];
78127
+ return pathLeafValue === leafValue;
78128
+ });
78129
+ if (isSelected && !processedPaths.has(pathKey)) {
78130
+ items.push(this.buildCompleteNodeInfo(node, newPath, cascaderProps, options, false));
78131
+ processedPaths.add(pathKey);
78132
+ }
78133
+ } else {
78134
+ // 继续检查子节点
78135
+ checkNode(node[cascaderProps.children], newPath);
78136
+ }
78137
+ });
78138
+ };
78139
+ checkNode(options);
78140
+ return items;
78141
+ }
78142
+
78143
+ /**
78144
+ * 获取聚合模式下的选中值(只返回最终选中的值,不包含被聚合的子项)
78145
+ * @param {Array} selectedValues - 已选值数组
78146
+ * @param {Array} options - 选项数据
78147
+ * @param {Object} cascaderProps - 级联配置
78148
+ * @param {String} prefix - 前缀标识
78149
+ * @returns {Array} 聚合后的选中值
78150
+ */
78151
+ static getAggregatedSelectedValues(selectedValues, options, cascaderProps, prefix = '__parent__') {
78152
+ const aggregatedItems = this.getAggregatedSelectedItems(selectedValues, options, cascaderProps);
78153
+ return aggregatedItems.map(item => {
78154
+ // 如果是聚合项(非叶子节点),添加前缀标识
78155
+ if (item.isAggregated) {
78156
+ return this.addParentNodePrefix(item.value, prefix);
78157
+ }
78158
+ return item.value;
78159
+ });
78160
+ }
78161
+
78162
+ /**
78163
+ * 获取聚合模式下的路径数组(只返回最终选中的路径,不包含被聚合的子项路径)
78164
+ * @param {Array} selectedValues - 已选值数组
78165
+ * @param {Array} options - 选项数据
78166
+ * @param {Object} cascaderProps - 级联配置
78167
+ * @returns {Array} 聚合后的路径数组
78168
+ */
78169
+ static getAggregatedSelectedPaths(selectedValues, options, cascaderProps) {
78170
+ const aggregatedItems = this.getAggregatedSelectedItems(selectedValues, options, cascaderProps);
78171
+ return aggregatedItems.map(item => item.path);
78172
+ }
78173
+
78174
+ /**
78175
+ * 检查聚合模式下是否全选(所有可选的叶子节点都被选中)
78176
+ * @param {Array} selectedValues - 已选值数组
78177
+ * @param {Array} options - 选项数据
78178
+ * @param {Object} config - 禁用配置
78179
+ * @param {Object} cascaderProps - 级联配置
78180
+ * @returns {Boolean} 是否全选
78181
+ */
78182
+ static isAggregatedAllSelected(selectedValues, options, config, cascaderProps) {
78183
+ // 获取所有可选的叶子节点
78184
+ const allSelectableLeafValues = this.getAllLeafPaths(options, config, cascaderProps).map(path => path[path.length - 1]); // 获取叶子节点的值
78185
+
78186
+ // 获取当前选中的叶子节点值
78187
+ const selectedLeafValues = selectedValues.map(path => path[path.length - 1]);
78188
+
78189
+ // 检查所有可选的叶子节点是否都被选中
78190
+ return allSelectableLeafValues.every(leafValue => selectedLeafValues.includes(leafValue));
78191
+ }
78192
+
78193
+ /**
78194
+ * 检查值是否为非叶子节点标识
78195
+ * @param {*} value - 要检查的值
78196
+ * @param {String} prefix - 前缀标识
78197
+ * @returns {Boolean} 是否为非叶子节点标识
78198
+ */
78199
+ static isParentNodeValue(value, prefix = '__parent__') {
78200
+ return typeof value === 'string' && value.startsWith(prefix);
78201
+ }
78202
+
78203
+ /**
78204
+ * 从非叶子节点标识中提取实际值
78205
+ * @param {String} parentValue - 非叶子节点标识值
78206
+ * @param {String} prefix - 前缀标识
78207
+ * @returns {String} 实际值
78208
+ */
78209
+ static extractParentNodeValue(parentValue, prefix = '__parent__') {
78210
+ if (this.isParentNodeValue(parentValue, prefix)) {
78211
+ return parentValue.substring(prefix.length);
78212
+ }
78213
+ return parentValue;
78214
+ }
78215
+
78216
+ /**
78217
+ * 为非叶子节点值添加前缀标识
78218
+ * @param {String} value - 原始值
78219
+ * @param {String} prefix - 前缀标识
78220
+ * @returns {String} 带前缀的值
78221
+ */
78222
+ static addParentNodePrefix(value, prefix = '__parent__') {
78223
+ return prefix + value;
78224
+ }
78225
+
78226
+ /**
78227
+ * 根据非叶子节点值获取其所有叶子节点的路径
78228
+ * @param {String} parentValue - 非叶子节点值
78229
+ * @param {Array} options - 选项数据
78230
+ * @param {Object} cascaderProps - 级联配置
78231
+ * @returns {Array} 叶子节点路径数组
78232
+ */
78233
+ static getLeafPathsByParentValue(parentValue, options, cascaderProps) {
78234
+ const paths = [];
78235
+
78236
+ // 查找非叶子节点
78237
+ const findParentNode = (nodes, currentPath = []) => {
78238
+ for (const node of nodes) {
78239
+ const newPath = [...currentPath, node[cascaderProps.value]];
78240
+ if (node[cascaderProps.value] == parentValue) {
78241
+ // 找到目标非叶子节点,获取其所有叶子节点路径
78242
+ this.getAllLeafPaths([node], {}, cascaderProps).forEach(leafPath => {
78243
+ // 将叶子节点路径与当前路径合并
78244
+ const fullPath = [...currentPath, ...leafPath];
78245
+ paths.push(fullPath);
78246
+ });
78247
+ return true;
78248
+ }
78249
+
78250
+ // 递归查找子节点
78251
+ if (node[cascaderProps.children] && node[cascaderProps.children].length > 0) {
78252
+ if (findParentNode(node[cascaderProps.children], newPath)) {
78253
+ return true;
78254
+ }
78255
+ }
78256
+ }
78257
+ return false;
78258
+ };
78259
+ findParentNode(options);
78260
+ return paths;
78261
+ }
78262
+
78263
+ /**
78264
+ * 处理包含非叶子节点的值数组,将非叶子节点转换为对应的叶子节点路径
78265
+ * @param {Array} values - 值数组(可能包含非叶子节点标识)
78266
+ * @param {Array} options - 选项数据
78267
+ * @param {Object} cascaderProps - 级联配置
78268
+ * @param {String} prefix - 前缀标识
78269
+ * @returns {Array} 处理后的路径数组
78270
+ */
78271
+ static processValuesWithParentNodes(values, options, cascaderProps, prefix = '__parent__') {
78272
+ const paths = [];
78273
+ for (const value of values) {
78274
+ if (this.isParentNodeValue(value, prefix)) {
78275
+ // 非叶子节点,获取其所有叶子节点路径
78276
+ const actualValue = this.extractParentNodeValue(value, prefix);
78277
+ const leafPaths = this.getLeafPathsByParentValue(actualValue, options, cascaderProps);
78278
+ paths.push(...leafPaths);
78279
+ } else {
78280
+ // 普通值,查找对应的路径
78281
+ const valuePaths = this.findPathsByValues([value], options, cascaderProps);
78282
+ paths.push(...valuePaths);
78283
+ }
78284
+ }
78285
+ return paths;
78286
+ }
78287
+
78288
+ /**
78289
+ * 根据values找到对应的路径(支持非叶子节点)
78290
+ * @param {Array} values - 值数组
78291
+ * @param {Array} options - 选项数据
78292
+ * @param {Object} cascaderProps - 级联配置
78293
+ * @returns {Array} 路径数组
78294
+ */
78295
+ static findPathsByValues(values, options, cascaderProps) {
78296
+ const paths = [];
78297
+ const findPath = (nodes, targetValues, currentPath = []) => {
78298
+ for (const option of nodes) {
78299
+ const newPath = [...currentPath, option[cascaderProps.value]];
78300
+ if (targetValues.includes(option[cascaderProps.value])) {
78301
+ // 如果是叶子节点(没有children属性),添加到路径中
78302
+ if (!option[cascaderProps.children]) {
78303
+ paths.push(newPath);
78304
+ }
78305
+ }
78306
+
78307
+ // 递归查找子节点
78308
+ if (option[cascaderProps.children] && option[cascaderProps.children].length > 0) {
78309
+ findPath(option[cascaderProps.children], targetValues, newPath);
78310
+ }
78311
+ }
78312
+ };
78313
+ findPath(options, values);
78314
+ return paths;
78315
+ }
78316
+ }
78317
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.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/ByCascaderPanel.vue?vue&type=script&lang=js
78318
+
78319
+
78320
+
78321
+
78322
+
78323
+
78324
+ /* harmony default export */ var ByCascaderPanelvue_type_script_lang_js = ({
78325
+ name: 'ByCascaderPanel',
78326
+ props: {
78327
+ // 级联数据源
78328
+ options: {
78329
+ type: Array,
78330
+ default: () => []
78331
+ },
78332
+ // 已选值
78333
+ value: {
78334
+ type: [Array, Number, String],
78335
+ default: () => []
78336
+ },
78337
+ // 级联面板配置
78338
+ cascaderProps: {
78339
+ type: Object,
78340
+ default: () => ({
78341
+ multiple: true,
78342
+ label: 'label',
78343
+ value: 'value',
78344
+ children: 'children'
78345
+ })
78346
+ },
78347
+ // 面板高度
78348
+ panelHeight: {
78349
+ type: [String, Number],
78350
+ default: 300,
78351
+ validator: value => {
78352
+ const numValue = Number(value);
78353
+ if (isNaN(numValue)) {
78354
+ console.warn(`[ByCascaderPanel] panelHeight 必须是数字,当前值: ${value}`);
78355
+ return false;
78356
+ }
78357
+ if (numValue < 200) {
78358
+ console.warn(`[ByCascaderPanel] panelHeight 不能小于 200px,当前值: ${value}px`);
78359
+ return false;
78360
+ }
78361
+ if (numValue > 800) {
78362
+ console.warn(`[ByCascaderPanel] panelHeight 不能大于 800px,当前值: ${value}px`);
78363
+ return false;
78364
+ }
78365
+ return true;
78366
+ }
78367
+ },
78368
+ // 搜索占位符
78369
+ searchPlaceholder: {
78370
+ type: String,
78371
+ default: '请输入名称搜索'
78372
+ },
78373
+ // 禁用字段名(只针对叶子节点,非叶子节点为disabled)
78374
+ disabledField: {
78375
+ type: String,
78376
+ default: 'disabled'
78377
+ },
78378
+ // 禁用值(只针对叶子节点,非叶子节点为disabled)
78379
+ disabledValue: {
78380
+ type: [String, Number, Boolean],
78381
+ default: true
78382
+ },
78383
+ // 自定义禁用判断函数
78384
+ disabledCheck: {
78385
+ type: Function,
78386
+ default: null
78387
+ },
78388
+ // 是否显示全选按钮
78389
+ showSelectAll: {
78390
+ type: Boolean,
78391
+ default: true
78392
+ },
78393
+ // 是否聚合模式 (聚合模式下如果子项全部选中,会直接返回父ID)
78394
+ aggregationMode: {
78395
+ type: Boolean,
78396
+ default: false
78397
+ },
78398
+ /**
78399
+ * 非叶子节点前缀标识 (聚合模式下用于标识非叶子节点)
78400
+ * 注意:聚合模式下,由于叶子节点和非叶子节点可能存在相同id,所以绑定数据中务必给非叶子节点加上parentNodePrefix前缀作为标识
78401
+ */
78402
+ parentNodePrefix: {
78403
+ type: String,
78404
+ default: '__parent__'
78405
+ }
78406
+ },
78407
+ data() {
78408
+ return {
78409
+ selectedValues: [],
78410
+ searchSelectedValues: [],
78411
+ filteredOptions: [],
78412
+ searchOptions: [],
78413
+ selectedItems: [],
78414
+ searchInput: '',
78415
+ isShow: true,
78416
+ isShowSearch: false,
78417
+ totalCount: 0,
78418
+ selectedCount: 0,
78419
+ isAllSelected: false,
78420
+ isInternalUpdate: false // 防止循环更新的标志
78421
+ };
78422
+ },
78423
+ computed: {
78424
+ // 处理后的面板高度,确保在有效范围内
78425
+ computedPanelHeight() {
78426
+ const height = Number(this.panelHeight);
78427
+ if (isNaN(height)) {
78428
+ return 300; // 默认值
78429
+ }
78430
+ // 限制在 200px 到 800px 之间
78431
+ return Math.max(200, Math.min(800, height));
78432
+ },
78433
+ // 是否为多选模式
78434
+ isMultiple() {
78435
+ return this.cascaderProps.multiple !== false;
78436
+ },
78437
+ // 当前选中的值(单选时返回单个值,多选时返回数组)
78438
+ currentValue() {
78439
+ if (this.isMultiple) {
78440
+ return this.selectedItems.map(item => item.value);
78441
+ } else {
78442
+ return this.selectedItems.length > 0 ? this.selectedItems[0].value : null;
78443
+ }
78444
+ },
78445
+ // 主面板的值(单选时返回单个路径,多选时返回路径数组)
78446
+ mainPanelValue: {
78447
+ get() {
78448
+ if (this.isMultiple) {
78449
+ return this.selectedValues;
78450
+ } else {
78451
+ return this.selectedValues.length > 0 ? this.selectedValues[0] : [];
78452
+ }
78453
+ },
78454
+ set(value) {
78455
+ if (this.isMultiple) {
78456
+ this.selectedValues = value || [];
78457
+ } else {
78458
+ this.selectedValues = value ? [value] : [];
78459
+ }
78460
+ }
78461
+ },
78462
+ // 搜索面板的值(单选时返回单个路径,多选时返回路径数组)
78463
+ searchPanelValue: {
78464
+ get() {
78465
+ if (this.isMultiple) {
78466
+ return this.searchSelectedValues;
78467
+ } else {
78468
+ return this.searchSelectedValues.length > 0 ? this.searchSelectedValues[0] : [];
78469
+ }
78470
+ },
78471
+ set(value) {
78472
+ if (this.isMultiple) {
78473
+ this.searchSelectedValues = value || [];
78474
+ } else {
78475
+ this.searchSelectedValues = value ? [value] : [];
78476
+ }
78477
+ }
78478
+ }
78479
+ },
78480
+ watch: {
78481
+ options: {
78482
+ handler(newVal) {
78483
+ this.initOptions();
78484
+ },
78485
+ deep: true,
78486
+ immediate: true
78487
+ },
78488
+ value: {
78489
+ handler(newVal) {
78490
+ // 如果是内部更新触发的,跳过处理
78491
+ if (this.isInternalUpdate) {
78492
+ this.isInternalUpdate = false;
78493
+ return;
78494
+ }
78495
+ this.processValue();
78496
+ },
78497
+ deep: true,
78498
+ immediate: true
78499
+ },
78500
+ selectedItems: {
78501
+ handler(newVal) {
78502
+ if (this.isMultiple) {
78503
+ this.selectedCount = newVal.length;
78504
+
78505
+ // 聚合模式下的全选判断
78506
+ if (this.aggregationMode) {
78507
+ const config = {
78508
+ disabledField: this.disabledField,
78509
+ disabledValue: this.disabledValue,
78510
+ disabledCheck: this.disabledCheck
78511
+ };
78512
+ this.isAllSelected = CascaderUtils.isAggregatedAllSelected(this.selectedValues, this.filteredOptions, config, this.cascaderProps);
78513
+ } else {
78514
+ // 普通模式下的全选判断
78515
+ this.isAllSelected = this.selectedCount === this.totalCount;
78516
+ }
78517
+ } else {
78518
+ // 单选模式:最多只能有一个选中项
78519
+ if (newVal.length > 1) {
78520
+ this.selectedItems = [newVal[newVal.length - 1]];
78521
+ }
78522
+ this.selectedCount = this.selectedItems.length;
78523
+ }
78524
+ this.$emit('change', this.getSelectedData());
78525
+ },
78526
+ deep: true
78527
+ }
78528
+ },
78529
+ mounted() {
78530
+ this.initOptions();
78531
+ // 确保在 mounted 后处理默认值
78532
+ this.$nextTick(() => {
78533
+ this.processValue();
78534
+ });
78535
+ },
78536
+ methods: {
78537
+ // 处理 value 值
78538
+ processValue() {
78539
+ if (this.isMultiple) {
78540
+ // 多选模式:支持直接传入value值或路径数组
78541
+ if (Array.isArray(this.value) && this.value.length > 0) {
78542
+ if (typeof this.value[0] === 'string' || typeof this.value[0] === 'number') {
78543
+ // 传入的是value值数组,需要转换为路径
78544
+ if (this.aggregationMode) {
78545
+ // 聚合模式下,支持非叶子节点标识
78546
+ this.selectedValues = CascaderUtils.processValuesWithParentNodes(this.value, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78547
+ } else {
78548
+ // 普通模式下,只处理叶子节点
78549
+ this.selectedValues = this.findPathsByValues(this.value);
78550
+ }
78551
+ } else {
78552
+ // 传入的是路径数组
78553
+ this.selectedValues = [...this.value];
78554
+ }
78555
+ } else {
78556
+ this.selectedValues = [];
78557
+ }
78558
+ } else {
78559
+ // 单选模式:支持单个值或路径数组
78560
+ if (this.value !== null && this.value !== undefined && this.value !== '') {
78561
+ if (Array.isArray(this.value)) {
78562
+ // 传入的是路径数组
78563
+ this.selectedValues = [...this.value];
78564
+ } else {
78565
+ // 传入的是单个值,需要转换为路径
78566
+ if (this.aggregationMode) {
78567
+ // 聚合模式下,支持非叶子节点标识
78568
+ this.selectedValues = CascaderUtils.processValuesWithParentNodes([this.value], this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78569
+ } else {
78570
+ // 普通模式下,只处理叶子节点
78571
+ this.selectedValues = this.findPathsByValues([this.value]);
78572
+ }
78573
+ }
78574
+ } else {
78575
+ this.selectedValues = [];
78576
+ }
78577
+ }
78578
+ this.updateSelectedItems();
78579
+
78580
+ // 单选模式下,确保级联面板正确显示选中状态
78581
+ if (!this.isMultiple && this.selectedValues.length > 0) {
78582
+ this.$nextTick(() => {
78583
+ const panel = this.$refs.cascaderPanel;
78584
+ if (panel) {
78585
+ // 强制更新级联面板的选中状态
78586
+ panel.$forceUpdate();
78587
+ // 再次更新已选项列表,确保右侧面板显示正确
78588
+ this.updateSelectedItems();
78589
+ }
78590
+ });
78591
+ }
78592
+ },
78593
+ // 初始化选项数据
78594
+ initOptions() {
78595
+ this.filteredOptions = this.processOptions(this.options);
78596
+ this.countTotalItems();
78597
+ this.updateSelectedItems();
78598
+ },
78599
+ // 处理选项数据,添加禁用状态
78600
+ processOptions(options) {
78601
+ const processedOptions = JSON.parse(JSON.stringify(options));
78602
+ const config = {
78603
+ disabledField: this.disabledField,
78604
+ disabledValue: this.disabledValue,
78605
+ disabledCheck: this.disabledCheck
78606
+ };
78607
+ CascaderUtils.setDisabledItems(processedOptions, config, this.cascaderProps);
78608
+ return processedOptions;
78609
+ },
78610
+ // 判断项目是否禁用
78611
+ isItemDisabled(item) {
78612
+ const config = {
78613
+ disabledField: this.disabledField,
78614
+ disabledValue: this.disabledValue,
78615
+ disabledCheck: this.disabledCheck
78616
+ };
78617
+ return CascaderUtils.isItemDisabled(item, config);
78618
+ },
78619
+ // 统计总项目数
78620
+ countTotalItems() {
78621
+ const config = {
78622
+ disabledField: this.disabledField,
78623
+ disabledValue: this.disabledValue,
78624
+ disabledCheck: this.disabledCheck
78625
+ };
78626
+ this.totalCount = CascaderUtils.countTotalItems(this.filteredOptions, config, this.cascaderProps);
78627
+ },
78628
+ // 更新已选项列表
78629
+ updateSelectedItems() {
78630
+ this.$nextTick(() => {
78631
+ if (this.isShowSearch) {
78632
+ // 搜索模式下,基于 selectedValues 构建已选项列表
78633
+ if (this.aggregationMode) {
78634
+ // 聚合模式:使用聚合逻辑处理选中项
78635
+ this.selectedItems = CascaderUtils.getAggregatedSelectedItems(this.selectedValues, this.filteredOptions, this.cascaderProps);
78636
+ } else {
78637
+ this.selectedItems = this.buildSelectedItemsFromValues();
78638
+ }
78639
+ } else {
78640
+ // 正常模式下,优先从面板获取选中项,如果面板没有选中项则基于 selectedValues 构建
78641
+ const panel = this.$refs.cascaderPanel;
78642
+ if (panel) {
78643
+ const checkedNodes = panel.getCheckedNodes();
78644
+ if (this.aggregationMode) {
78645
+ // 聚合模式:使用聚合逻辑处理选中项
78646
+ this.selectedItems = CascaderUtils.getAggregatedSelectedItems(this.selectedValues, this.filteredOptions, this.cascaderProps);
78647
+ } else {
78648
+ // 普通模式:只显示叶子节点(最后一级),过滤掉父节点
78649
+ const panelSelectedItems = checkedNodes.filter(node => {
78650
+ // 如果是叶子节点(没有children属性),则显示
78651
+ return node && !node[this.cascaderProps.children];
78652
+ });
78653
+
78654
+ // 如果面板有选中项,使用面板的选中项;否则使用 selectedValues 构建
78655
+ if (panelSelectedItems.length > 0) {
78656
+ this.selectedItems = panelSelectedItems;
78657
+ } else {
78658
+ this.selectedItems = this.buildSelectedItemsFromValues();
78659
+ }
78660
+ }
78661
+ } else {
78662
+ // 面板不存在时,基于 selectedValues 构建
78663
+ if (this.aggregationMode) {
78664
+ // 聚合模式:使用聚合逻辑处理选中项
78665
+ this.selectedItems = CascaderUtils.getAggregatedSelectedItems(this.selectedValues, this.filteredOptions, this.cascaderProps);
78666
+ } else {
78667
+ this.selectedItems = this.buildSelectedItemsFromValues();
78668
+ }
78669
+ }
78670
+ }
78671
+ });
78672
+ },
78673
+ // 基于 selectedValues 构建已选项列表
78674
+ buildSelectedItemsFromValues() {
78675
+ return CascaderUtils.buildSelectedItemsFromValues(this.selectedValues, this.filteredOptions, this.cascaderProps);
78676
+ },
78677
+ // 搜索处理
78678
+ handleSearch() {
78679
+ this.searchInput = this.searchInput.trim();
78680
+ if (this.searchInput === '') {
78681
+ this.isShowSearch = false;
78682
+ return;
78683
+ }
78684
+ this.isShowSearch = false;
78685
+ this.searchOptions = CascaderUtils.searchInTree(this.filteredOptions, this.searchInput, this.cascaderProps);
78686
+
78687
+ // 只设置搜索范围内的选中值
78688
+ this.searchSelectedValues = CascaderUtils.getSearchSelectedValues(this.selectedValues, this.searchOptions, this.cascaderProps);
78689
+ this.$nextTick(() => {
78690
+ this.isShowSearch = true;
78691
+ if (this.searchOptions.length > 0) {
78692
+ // 等待搜索面板渲染完成后再展开
78693
+ this.$nextTick(() => {
78694
+ this.handleSearchExpand();
78695
+ });
78696
+ }
78697
+ });
78698
+ },
78699
+ // 搜索模式下的展开处理
78700
+ handleSearchExpand() {
78701
+ if (this.$refs.searchCascaderPanel && this.searchOptions.length > 0) {
78702
+ const panel = this.$refs.searchCascaderPanel;
78703
+ const firstOption = this.searchOptions[0];
78704
+
78705
+ // 确保面板已经渲染
78706
+ if (panel.menus && panel.menus[0]) {
78707
+ // 找到第一个选项的节点
78708
+ const targetNode = panel.menus[0].find(node => node.value == firstOption[this.cascaderProps.value]);
78709
+ if (targetNode) {
78710
+ // 展开第一个选项
78711
+ panel.handleExpand(targetNode, true);
78712
+ // 递归展开所有子节点
78713
+ this.expandAllChildren(targetNode, panel);
78714
+ }
78715
+ }
78716
+ }
78717
+ },
78718
+ // 展开变化处理
78719
+ handleExpandChange(values = []) {
78720
+ if (values.length === 1) {
78721
+ this.$nextTick(() => {
78722
+ const panel = this.$refs.cascaderPanel || this.$refs.searchCascaderPanel;
78723
+ if (panel) {
78724
+ const menus = panel.menus;
78725
+ const targetNode = menus[0].find(node => node.value == values[0]);
78726
+ if (targetNode) {
78727
+ panel.handleExpand(targetNode, true);
78728
+ this.expandAllChildren(targetNode, panel);
78729
+ }
78730
+ }
78731
+ });
78732
+ }
78733
+ },
78734
+ // 展开所有子节点
78735
+ expandAllChildren(node, panel) {
78736
+ if (node[this.cascaderProps.children] && node[this.cascaderProps.children].length > 0) {
78737
+ const firstChild = node[this.cascaderProps.children][0];
78738
+ panel.handleExpand(firstChild, true);
78739
+ this.expandAllChildren(firstChild, panel);
78740
+ }
78741
+ },
78742
+ // 值变化处理
78743
+ handleValueChange() {
78744
+ this.searchSelectedValues = [...this.selectedValues];
78745
+ this.updateSelectedItems();
78746
+
78747
+ // 等待updateSelectedItems完成后再发出事件
78748
+ this.$nextTick(() => {
78749
+ this.isInternalUpdate = true; // 标记为内部更新
78750
+ let emitValue = this.currentValue;
78751
+
78752
+ // 聚合模式下,发出聚合后的值
78753
+ if (this.aggregationMode) {
78754
+ emitValue = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78755
+ if (!this.isMultiple && emitValue.length > 0) {
78756
+ emitValue = emitValue[0]; // 单选模式下返回单个值
78757
+ }
78758
+ }
78759
+ this.$emit('input', emitValue);
78760
+ });
78761
+ },
78762
+ // 搜索模式值变化处理
78763
+ handleSearchValueChange(value) {
78764
+ // 获取搜索面板中所有可能的叶子节点值
78765
+ const searchLeafValues = CascaderUtils.getLeafValues(this.searchOptions, this.cascaderProps);
78766
+ if (this.isMultiple) {
78767
+ // 多选模式:从主选择列表中移除搜索范围内的项,然后添加搜索面板中选中的项
78768
+ this.selectedValues = this.selectedValues.filter(path => {
78769
+ const leafValue = path[path.length - 1];
78770
+ return !searchLeafValues.includes(leafValue);
78771
+ });
78772
+ this.selectedValues = [...this.selectedValues, ...this.searchSelectedValues];
78773
+ } else {
78774
+ // 单选模式:直接替换为搜索面板中选中的项
78775
+ if (value && value.length > 0) {
78776
+ this.selectedValues = [value];
78777
+ } else {
78778
+ this.selectedValues = [];
78779
+ }
78780
+ }
78781
+ this.isShow = false;
78782
+ this.$nextTick(() => {
78783
+ this.isShow = true;
78784
+ });
78785
+ this.updateSelectedItems();
78786
+
78787
+ // 等待updateSelectedItems完成后再发出事件
78788
+ this.$nextTick(() => {
78789
+ this.isInternalUpdate = true; // 标记为内部更新
78790
+ let emitValue = this.currentValue;
78791
+
78792
+ // 聚合模式下,发出聚合后的值
78793
+ if (this.aggregationMode) {
78794
+ emitValue = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78795
+ if (!this.isMultiple && emitValue.length > 0) {
78796
+ emitValue = emitValue[0]; // 单选模式下返回单个值
78797
+ }
78798
+ }
78799
+ this.$emit('input', emitValue);
78800
+ });
78801
+ },
78802
+ // 移除已选项
78803
+ removeItem(item, index) {
78804
+ const valueToRemove = item.value;
78805
+
78806
+ // 从选择值中移除
78807
+ this.selectedValues = this.selectedValues.filter(path => {
78808
+ return !path.includes(valueToRemove);
78809
+ });
78810
+
78811
+ // 从搜索选择值中移除
78812
+ this.searchSelectedValues = this.searchSelectedValues.filter(path => {
78813
+ return !path.includes(valueToRemove);
78814
+ });
78815
+
78816
+ // 从已选项列表中移除
78817
+ this.selectedItems.splice(index, 1);
78818
+
78819
+ // 等待updateSelectedItems完成后再发出事件
78820
+ this.$nextTick(() => {
78821
+ this.isInternalUpdate = true; // 标记为内部更新
78822
+ let emitValue = this.currentValue;
78823
+
78824
+ // 聚合模式下,发出聚合后的值
78825
+ if (this.aggregationMode) {
78826
+ emitValue = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78827
+ if (!this.isMultiple && emitValue.length > 0) {
78828
+ emitValue = emitValue[0]; // 单选模式下返回单个值
78829
+ }
78830
+ }
78831
+ this.$emit('input', emitValue);
78832
+ });
78833
+ },
78834
+ // 全选/取消全选
78835
+ handleSelectAll() {
78836
+ if (!this.isMultiple) {
78837
+ // 单选模式下不支持全选
78838
+ return;
78839
+ }
78840
+ if (this.isAllSelected) {
78841
+ this.selectedValues = [];
78842
+ this.selectedItems = [];
78843
+ } else {
78844
+ const config = {
78845
+ disabledField: this.disabledField,
78846
+ disabledValue: this.disabledValue,
78847
+ disabledCheck: this.disabledCheck
78848
+ };
78849
+ // 无论是普通模式还是聚合模式,全选时都选择所有可选的叶子节点
78850
+ this.selectedValues = CascaderUtils.getAllLeafPaths(this.filteredOptions, config, this.cascaderProps);
78851
+ this.updateSelectedItems();
78852
+ }
78853
+ // 等待updateSelectedItems完成后再发出事件
78854
+ this.$nextTick(() => {
78855
+ this.isInternalUpdate = true; // 标记为内部更新
78856
+ let emitValue = this.currentValue;
78857
+
78858
+ // 聚合模式下,发出聚合后的值
78859
+ if (this.aggregationMode) {
78860
+ emitValue = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78861
+ if (!this.isMultiple && emitValue.length > 0) {
78862
+ emitValue = emitValue[0]; // 单选模式下返回单个值
78863
+ }
78864
+ }
78865
+ this.$emit('input', emitValue);
78866
+ });
78867
+ },
78868
+ // 获取选中的数据
78869
+ getSelectedData() {
78870
+ let values = this.currentValue;
78871
+ let valuesPath = this.selectedValues;
78872
+
78873
+ // 聚合模式下,返回聚合后的值和路径
78874
+ if (this.aggregationMode) {
78875
+ values = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78876
+ valuesPath = CascaderUtils.getAggregatedSelectedPaths(this.selectedValues, this.filteredOptions, this.cascaderProps);
78877
+ if (!this.isMultiple && values.length > 0) {
78878
+ values = values[0]; // 单选模式下返回单个值
78879
+ }
78880
+ }
78881
+ return {
78882
+ valuesPath: valuesPath,
78883
+ // 路径数组(聚合模式下已聚合)
78884
+ values: values,
78885
+ // 外部value(单选时返回单个值,多选时返回数组)
78886
+ items: this.selectedItems,
78887
+ count: this.selectedItems.length
78888
+ };
78889
+ },
78890
+ // 清空选择
78891
+ clearSelection() {
78892
+ this.selectedValues = [];
78893
+ this.selectedItems = [];
78894
+ this.searchSelectedValues = [];
78895
+ // 等待updateSelectedItems完成后再发出事件
78896
+ this.$nextTick(() => {
78897
+ this.isInternalUpdate = true; // 标记为内部更新
78898
+ let emitValue = this.currentValue;
78899
+
78900
+ // 聚合模式下,发出聚合后的值
78901
+ if (this.aggregationMode) {
78902
+ emitValue = CascaderUtils.getAggregatedSelectedValues(this.selectedValues, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78903
+ if (!this.isMultiple && emitValue.length > 0) {
78904
+ emitValue = emitValue[0]; // 单选模式下返回单个值
78905
+ }
78906
+ }
78907
+ this.$emit('input', emitValue);
78908
+ });
78909
+ },
78910
+ // 设置选择值
78911
+ setValue(values) {
78912
+ if (this.isMultiple) {
78913
+ // 多选模式:支持直接传入value值或路径数组
78914
+ if (Array.isArray(values) && values.length > 0) {
78915
+ if (typeof values[0] === 'string' || typeof values[0] === 'number') {
78916
+ // 传入的是value值数组,需要转换为路径
78917
+ if (this.aggregationMode) {
78918
+ // 聚合模式下,支持非叶子节点标识
78919
+ this.selectedValues = CascaderUtils.processValuesWithParentNodes(values, this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78920
+ } else {
78921
+ // 普通模式下,只处理叶子节点
78922
+ this.selectedValues = this.findPathsByValues(values);
78923
+ }
78924
+ } else {
78925
+ // 传入的是路径数组
78926
+ this.selectedValues = [...values];
78927
+ }
78928
+ } else {
78929
+ this.selectedValues = [];
78930
+ }
78931
+ } else {
78932
+ // 单选模式:支持单个值或路径数组
78933
+ if (values !== null && values !== undefined && values !== '') {
78934
+ if (Array.isArray(values)) {
78935
+ // 传入的是路径数组
78936
+ this.selectedValues = [...values];
78937
+ } else {
78938
+ // 传入的是单个值,需要转换为路径
78939
+ if (this.aggregationMode) {
78940
+ // 聚合模式下,支持非叶子节点标识
78941
+ this.selectedValues = CascaderUtils.processValuesWithParentNodes([values], this.filteredOptions, this.cascaderProps, this.parentNodePrefix);
78942
+ } else {
78943
+ // 普通模式下,只处理叶子节点
78944
+ this.selectedValues = this.findPathsByValues([values]);
78945
+ }
78946
+ }
78947
+ } else {
78948
+ this.selectedValues = [];
78949
+ }
78950
+ }
78951
+ this.updateSelectedItems();
78952
+ },
78953
+ // 根据values找到对应的路径
78954
+ findPathsByValues(values) {
78955
+ const paths = [];
78956
+ const findPath = (options, targetValues, currentPath = []) => {
78957
+ for (const option of options) {
78958
+ const newPath = [...currentPath, option[this.cascaderProps.value]];
78959
+ if (targetValues.includes(option[this.cascaderProps.value])) {
78960
+ // 如果是叶子节点(没有children属性),添加到路径中
78961
+ if (!option[this.cascaderProps.children]) {
78962
+ paths.push(newPath);
78963
+ }
78964
+ }
78965
+
78966
+ // 递归查找子节点
78967
+ if (option[this.cascaderProps.children] && option[this.cascaderProps.children].length > 0) {
78968
+ findPath(option[this.cascaderProps.children], targetValues, newPath);
78969
+ }
78970
+ }
78971
+ };
78972
+
78973
+ // 使用 filteredOptions 如果存在,否则使用原始 options
78974
+ const optionsToSearch = this.filteredOptions.length > 0 ? this.filteredOptions : this.options;
78975
+ findPath(optionsToSearch, values);
78976
+ return paths;
78977
+ }
78978
+ }
78979
+ });
78980
+ ;// ./src/components/cascader-panel/ByCascaderPanel.vue?vue&type=script&lang=js
78981
+ /* harmony default export */ var cascader_panel_ByCascaderPanelvue_type_script_lang_js = (ByCascaderPanelvue_type_script_lang_js);
78982
+ ;// ./src/components/cascader-panel/ByCascaderPanel.vue
78983
+
78984
+
78985
+
78986
+
78987
+
78988
+ /* normalize component */
78989
+ ;
78990
+ var ByCascaderPanel_component = normalizeComponent(
78991
+ cascader_panel_ByCascaderPanelvue_type_script_lang_js,
78992
+ ByCascaderPanelvue_type_template_id_d3dd0512_render,
78993
+ ByCascaderPanelvue_type_template_id_d3dd0512_staticRenderFns,
78994
+ false,
78995
+ null,
78996
+ null,
78997
+ null
78998
+
78999
+ )
79000
+
79001
+ /* harmony default export */ var ByCascaderPanel = (ByCascaderPanel_component.exports);
77531
79002
  ;// ./src/index.js
77532
79003
 
77533
79004
 
@@ -77547,6 +79018,7 @@ ByDialogService.install = function (Vue) {
77547
79018
 
77548
79019
 
77549
79020
 
79021
+
77550
79022
  const components = {
77551
79023
  ByPager: pager,
77552
79024
  ByTable: table,
@@ -77560,7 +79032,8 @@ const components = {
77560
79032
  ByCommonSelector: ByCommonSelector,
77561
79033
  ByBatchQuerySelector: BatchQuerySelector,
77562
79034
  ByTreeSearch: ByTreeSearch,
77563
- ByDialog: ByDialog
79035
+ ByDialog: ByDialog,
79036
+ ByCascaderPanel: ByCascaderPanel
77564
79037
  };
77565
79038
 
77566
79039
  // 设置当前 z-index 起始值