新购到货管理/领料申请-类型规格-优化
This commit is contained in:
		
							parent
							
								
									a0519e57fa
								
							
						
					
					
						commit
						fa474c8a07
					
				| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "printWidth": 120,
 | 
				
			||||||
 | 
					  "tabWidth": 4,
 | 
				
			||||||
 | 
					  "singleQuote": true,
 | 
				
			||||||
 | 
					  "semi": false,
 | 
				
			||||||
 | 
					  "bracketSpacing": true,
 | 
				
			||||||
 | 
					  "jsxBracketSameLine": true,
 | 
				
			||||||
 | 
					  "arrowParens": "avoid",
 | 
				
			||||||
 | 
					  "endOfLine": "lf",
 | 
				
			||||||
 | 
					  "useTabs": false,
 | 
				
			||||||
 | 
					  "trailingComma": "none",
 | 
				
			||||||
 | 
					  "bracketSameLine": false,
 | 
				
			||||||
 | 
					  "htmlWhitespaceSensitivity": "ignore",
 | 
				
			||||||
 | 
					  "vueIndentScriptAndStyle": false,
 | 
				
			||||||
 | 
					  "singleAttributePerLine": false,
 | 
				
			||||||
 | 
					  "importStatement": "none"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -91,20 +91,57 @@
 | 
				
			||||||
      </el-form-item>
 | 
					      </el-form-item>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <el-form-item label="类型规格" prop="deviceType">
 | 
					      <el-form-item label="类型规格" prop="deviceType">
 | 
				
			||||||
        <el-cascader
 | 
					        <el-row :gutter="10">
 | 
				
			||||||
          :key="propsKey"
 | 
					          <el-col :span="15">
 | 
				
			||||||
          v-model="deviceType"
 | 
					            <el-select
 | 
				
			||||||
          :show-all-levels="false"
 | 
					              ref="typeSelect"
 | 
				
			||||||
          :options="equipmentTypeList"
 | 
					              v-model="tempDeviceType"
 | 
				
			||||||
          :props="deviceTypeTreeProps"
 | 
					              multiple
 | 
				
			||||||
          filterable
 | 
					              filterable
 | 
				
			||||||
          collapse-tags
 | 
					              placeholder="请输入类型规格"
 | 
				
			||||||
          style="width: 240px"
 | 
					              style="width: 500px"
 | 
				
			||||||
          placeholder="请选择规格型号"
 | 
					              @change="handleTypeChange"
 | 
				
			||||||
          ref="deviceTypeCascader"
 | 
					              clearable
 | 
				
			||||||
          popper-class="popper-select"
 | 
					              collapse-tags
 | 
				
			||||||
          @change="deviceTypeChange"
 | 
					              :filter-method="handleSearchImpl"
 | 
				
			||||||
        ></el-cascader>
 | 
					              :popper-class="'type-select-dropdown'"
 | 
				
			||||||
 | 
					              :popper-append-to-body="false"
 | 
				
			||||||
 | 
					              @visible-change="handleVisibleChange"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <el-option
 | 
				
			||||||
 | 
					                v-for="item in filteredOptions"
 | 
				
			||||||
 | 
					                :key="item.typeId"
 | 
				
			||||||
 | 
					                :label="item.fullPath"
 | 
				
			||||||
 | 
					                :value="item.typeId"
 | 
				
			||||||
 | 
					                :data-key="item.typeId"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <span v-html="highlightText(item.fullPath, searchKeyword)"></span>
 | 
				
			||||||
 | 
					                <span style="float: right; color: #8492a6; font-size: 13px">
 | 
				
			||||||
 | 
					                  库存:{{ item.storageNum }}
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					              </el-option>
 | 
				
			||||||
 | 
					            </el-select>
 | 
				
			||||||
 | 
					          </el-col>
 | 
				
			||||||
 | 
					          <el-col :span="6">
 | 
				
			||||||
 | 
					            <el-input
 | 
				
			||||||
 | 
					              ref="searchInput"
 | 
				
			||||||
 | 
					              v-model="searchKeyword"
 | 
				
			||||||
 | 
					              placeholder="输入类型规格高亮搜索"
 | 
				
			||||||
 | 
					              prefix-icon="el-icon-search"
 | 
				
			||||||
 | 
					              clearable
 | 
				
			||||||
 | 
					              style="width: 300px"
 | 
				
			||||||
 | 
					              @input="handleHighlightSearch"
 | 
				
			||||||
 | 
					              @focus="handleSearchFocus"
 | 
				
			||||||
 | 
					              @click.native="handleSearchClick"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <template slot="append">
 | 
				
			||||||
 | 
					                <span v-if="matchedOptions.length" style="margin: 0 5px">
 | 
				
			||||||
 | 
					                  {{ currentMatchIndex + 1 }}/{{ matchedOptions.length }}
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					              </template>
 | 
				
			||||||
 | 
					            </el-input>
 | 
				
			||||||
 | 
					          </el-col>
 | 
				
			||||||
 | 
					        </el-row>
 | 
				
			||||||
      </el-form-item>
 | 
					      </el-form-item>
 | 
				
			||||||
      <el-form-item label="备注" prop="remark">
 | 
					      <el-form-item label="备注" prop="remark">
 | 
				
			||||||
          <el-input
 | 
					          <el-input
 | 
				
			||||||
| 
						 | 
					@ -340,9 +377,9 @@ export default {
 | 
				
			||||||
      deviceTypeTreeProps: {
 | 
					      deviceTypeTreeProps: {
 | 
				
			||||||
        children: "children",
 | 
					        children: "children",
 | 
				
			||||||
        label: "typeName",
 | 
					        label: "typeName",
 | 
				
			||||||
        // multiple: false,
 | 
					 | 
				
			||||||
        value: "typeId",
 | 
					        value: "typeId",
 | 
				
			||||||
        multiple: true,
 | 
					        multiple: true,
 | 
				
			||||||
 | 
					        emitPath: true
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      deviceType: [],
 | 
					      deviceType: [],
 | 
				
			||||||
      propsKey: 1000,
 | 
					      propsKey: 1000,
 | 
				
			||||||
| 
						 | 
					@ -350,6 +387,23 @@ export default {
 | 
				
			||||||
      unitTemp: undefined,
 | 
					      unitTemp: undefined,
 | 
				
			||||||
      agreementId: undefined,
 | 
					      agreementId: undefined,
 | 
				
			||||||
      // taxRate:0,
 | 
					      // taxRate:0,
 | 
				
			||||||
 | 
					      flattenOptions: [], // 扁平化后的选项数据
 | 
				
			||||||
 | 
					      typePopoverVisible: false,
 | 
				
			||||||
 | 
					      typeOptions: [], // 类型选项
 | 
				
			||||||
 | 
					      allTypeList: [], // 所有类型数据
 | 
				
			||||||
 | 
					      flattenTypeOptions: [], // 扁平化后的选项数据(缓存所有选项)
 | 
				
			||||||
 | 
					      typeGroups: [], // 分组后的类型选项
 | 
				
			||||||
 | 
					      typeGroupsBackup: [], // 备份原始分组数据,用于搜索
 | 
				
			||||||
 | 
					      typeMap: new Map(), // 用于快速查找类型数据
 | 
				
			||||||
 | 
					      tempDeviceType: [], // 临时选中值
 | 
				
			||||||
 | 
					      filteredOptions: [], // 过滤后的选项(用于显示)
 | 
				
			||||||
 | 
					      maxShowOptions: 100, // 最大显示选项数
 | 
				
			||||||
 | 
					      searchTimer: null, // 用于自定义防抖
 | 
				
			||||||
 | 
					      searchKeyword: '', // 高亮搜索关键字
 | 
				
			||||||
 | 
					      currentMatchIndex: -1, // 当前匹配项索引
 | 
				
			||||||
 | 
					      matchedOptions: [], // 匹配的选项
 | 
				
			||||||
 | 
					      keepSelectOpen: false, // 控制下拉框是否保持打开
 | 
				
			||||||
 | 
					      isSearching: false, // 添加搜索状态标记
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
| 
						 | 
					@ -363,7 +417,6 @@ export default {
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  watch: {},
 | 
					 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
    this.projectInfoList();//单位工程下拉选
 | 
					    this.projectInfoList();//单位工程下拉选
 | 
				
			||||||
    this.equipmentType();//机具类型下拉选
 | 
					    this.equipmentType();//机具类型下拉选
 | 
				
			||||||
| 
						 | 
					@ -452,84 +505,95 @@ export default {
 | 
				
			||||||
    equipmentType() {
 | 
					    equipmentType() {
 | 
				
			||||||
      equipmentTypeTree().then((response) => {
 | 
					      equipmentTypeTree().then((response) => {
 | 
				
			||||||
        this.equipmentTypeList = response.data;
 | 
					        this.equipmentTypeList = response.data;
 | 
				
			||||||
        this.equipmentTypeList.forEach((item, index) => {
 | 
					        // 处理并扁平化所有类型数据
 | 
				
			||||||
          if (item.children && item.children.length > 0) {
 | 
					        this.flattenTypeOptions = this.processTypeData(response.data);
 | 
				
			||||||
            item.children.forEach((item2, index2) => {
 | 
					        // 初始显示所有选项
 | 
				
			||||||
              if (item2.children && item2.children.length > 0) {
 | 
					        this.filteredOptions = [...this.flattenTypeOptions];
 | 
				
			||||||
                item2.children.forEach((item3) => {
 | 
					        
 | 
				
			||||||
                  if (item3.children && item3.children.length > 0) {
 | 
					        // 反显选中数据
 | 
				
			||||||
                    item3.children.forEach((item4) => {
 | 
					        if (this.equipmentList.length > 0) {
 | 
				
			||||||
                      item4.maTypeName = item3.typeName;
 | 
					          this.deviceType = this.equipmentList.map(item => item.typeId);
 | 
				
			||||||
                      item4.specificationType = item4.typeName;
 | 
					        }
 | 
				
			||||||
                      // this.$set(item4, "purchaseTaxPrice", 0);
 | 
					 | 
				
			||||||
                      // this.$set(item4, "purchasePrice", 0);
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        //反显
 | 
					 | 
				
			||||||
        let selectList = [];
 | 
					 | 
				
			||||||
        this.equipmentList.forEach((e) => {
 | 
					 | 
				
			||||||
          selectList.push(
 | 
					 | 
				
			||||||
            this.getParentsById(this.equipmentTypeList, e.typeId)
 | 
					 | 
				
			||||||
          );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        this.deviceType = selectList;
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    //添加机具类型
 | 
					    // 处理类型数据
 | 
				
			||||||
    deviceTypeChange(val) {
 | 
					    processTypeData(data) {
 | 
				
			||||||
      const deviceTypeList = this.$refs.deviceTypeCascader.getCheckedNodes();
 | 
					      const result = [];
 | 
				
			||||||
      let tempList = [];
 | 
					      
 | 
				
			||||||
      if (val.length > 0) {
 | 
					      const traverse = (node, parents = []) => {
 | 
				
			||||||
        const items = val.map((e) => {
 | 
					        const path = [...parents, node.typeName];
 | 
				
			||||||
          return e[3];
 | 
					        
 | 
				
			||||||
        });
 | 
					        if (!node.children || node.children.length === 0) {
 | 
				
			||||||
        for (let i of items) {
 | 
					          result.push({
 | 
				
			||||||
          for (let z of deviceTypeList) {
 | 
					            typeId: node.typeId,
 | 
				
			||||||
            if (z.data.typeId === i) {
 | 
					            typeName: node.typeName,
 | 
				
			||||||
              const obj = JSON.parse(JSON.stringify(z.data));
 | 
					            fullPath: path.join(' / '),
 | 
				
			||||||
              obj.preNum = 0;
 | 
					            searchKey: path.join('').toLowerCase(),
 | 
				
			||||||
              if(obj.storageNum<=0){
 | 
					            storageNum: node.storageNum || 0,
 | 
				
			||||||
                let index = this.deviceType.length;
 | 
					            maTypeName: parents[parents.length - 1] || '',
 | 
				
			||||||
                if(index==1){
 | 
					            specificationType: node.typeName,
 | 
				
			||||||
                  this.$nextTick(() => {
 | 
					            unitName: node.unitName,
 | 
				
			||||||
                    this.deviceType=[]; // 可选,如果你想要重置选中状态
 | 
					            unitValue: node.unitValue
 | 
				
			||||||
                  });
 | 
					 | 
				
			||||||
                }else{
 | 
					 | 
				
			||||||
                  this.deviceType=this.deviceType.splice(0,1)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                this.$modal.msgError("所选物资规格类型暂时无库存,无法申请!");
 | 
					 | 
				
			||||||
              }else{
 | 
					 | 
				
			||||||
                tempList.push(obj);
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        const newDataListNew = [...this.equipmentList, ...tempList];
 | 
					 | 
				
			||||||
        const map = new Map();
 | 
					 | 
				
			||||||
        for (let item of newDataListNew) {
 | 
					 | 
				
			||||||
          if (!map.has(item.typeId)) {
 | 
					 | 
				
			||||||
            map.set(item.typeId, item);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        const newArray = [...map.values()];
 | 
					 | 
				
			||||||
        let newArray_array = [];
 | 
					 | 
				
			||||||
        items.forEach((e) => {
 | 
					 | 
				
			||||||
          newArray.forEach((j) => {
 | 
					 | 
				
			||||||
            if (e == j.typeId) {
 | 
					 | 
				
			||||||
              newArray_array.push(j);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
        });
 | 
					        }
 | 
				
			||||||
        this.equipmentList = newArray_array;
 | 
					        
 | 
				
			||||||
      } else {
 | 
					        if (node.children) {
 | 
				
			||||||
        this.equipmentList = [];
 | 
					          node.children.forEach(child => traverse(child, path));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      data.forEach(node => traverse(node));
 | 
				
			||||||
 | 
					      return result;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 搜索处理函数
 | 
				
			||||||
 | 
					    handleSearchImpl(query) {
 | 
				
			||||||
 | 
					      if (!query) {
 | 
				
			||||||
 | 
					        this.filteredOptions = [...this.flattenTypeOptions];
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      const lowercaseQuery = query.toLowerCase();
 | 
				
			||||||
 | 
					      this.filteredOptions = this.flattenTypeOptions.filter(item => 
 | 
				
			||||||
 | 
					        item.searchKey.includes(lowercaseQuery) || 
 | 
				
			||||||
 | 
					        item.fullPath.toLowerCase().includes(lowercaseQuery)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 选择变化处理
 | 
				
			||||||
 | 
					    handleTypeChange(val) {
 | 
				
			||||||
 | 
					      if (!val || val.length === 0) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 获取新选中的项
 | 
				
			||||||
 | 
					      const lastSelected = val[val.length - 1];
 | 
				
			||||||
 | 
					      const typeData = this.flattenTypeOptions.find(item => item.typeId === lastSelected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (typeData) {
 | 
				
			||||||
 | 
					        if (this.equipmentList.some(item => item.typeId === lastSelected)) {
 | 
				
			||||||
 | 
					          this.$message({
 | 
				
			||||||
 | 
					            message: `${typeData.typeName} 已添加到列表中`,
 | 
				
			||||||
 | 
					            type: 'warning'
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          this.tempDeviceType = this.tempDeviceType.filter(id => id !== lastSelected);
 | 
				
			||||||
 | 
					        } else if (typeData.storageNum <= 0) {
 | 
				
			||||||
 | 
					          this.$message.error("所选物资规格类型暂时无库存,无法申请!");
 | 
				
			||||||
 | 
					          this.tempDeviceType = this.tempDeviceType.filter(id => id !== lastSelected);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          // 将新项添加到数组开头,实现倒序
 | 
				
			||||||
 | 
					          this.equipmentList.unshift({
 | 
				
			||||||
 | 
					            ...typeData,
 | 
				
			||||||
 | 
					            preNum: 0
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          this.deviceType.push(lastSelected);
 | 
				
			||||||
 | 
					          this.$message({
 | 
				
			||||||
 | 
					            message: `已添加 ${typeData.typeName}`,
 | 
				
			||||||
 | 
					            type: 'success'
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 清空临时选中值
 | 
				
			||||||
 | 
					      this.$nextTick(() => {
 | 
				
			||||||
 | 
					        this.tempDeviceType = [];
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    //获取任务详情--- 编辑回显数据
 | 
					    //获取任务详情--- 编辑回显数据
 | 
				
			||||||
    async getTaskInfo() {
 | 
					    async getTaskInfo() {
 | 
				
			||||||
| 
						 | 
					@ -775,42 +839,16 @@ export default {
 | 
				
			||||||
        this.dialogVisible = true;
 | 
					        this.dialogVisible = true;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    //树结构数据获取父
 | 
					 | 
				
			||||||
    getParentsById(list, id) {
 | 
					 | 
				
			||||||
      for (let i in list) {
 | 
					 | 
				
			||||||
        if (list[i].typeId == id) {
 | 
					 | 
				
			||||||
          //查询到就返回该数组对象的value
 | 
					 | 
				
			||||||
          return [list[i].typeId];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (list[i].children) {
 | 
					 | 
				
			||||||
          let node = this.getParentsById(list[i].children, id);
 | 
					 | 
				
			||||||
          if (node !== undefined) {
 | 
					 | 
				
			||||||
            //查询到把父节把父节点加到数组前面
 | 
					 | 
				
			||||||
            node.unshift(list[i].typeId);
 | 
					 | 
				
			||||||
            return node;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    /** 删除按钮操作 */
 | 
					    /** 删除按钮操作 */
 | 
				
			||||||
    handleDelete(row) {
 | 
					    handleDelete(row) {
 | 
				
			||||||
      console.log(row)
 | 
					 | 
				
			||||||
      this.$modal
 | 
					      this.$modal
 | 
				
			||||||
        .confirm("是否确认删除所选择的数据项?")
 | 
					        .confirm("是否确认删除所选择的数据项?")
 | 
				
			||||||
        .then(() => {
 | 
					        .then(() => {
 | 
				
			||||||
          this.deviceType.forEach((e, index) => {
 | 
					          this.equipmentList = this.equipmentList.filter(
 | 
				
			||||||
            console.log("e", e);
 | 
					            item => item.typeId !== row.typeId
 | 
				
			||||||
            if (e[3] === row.typeId) {
 | 
					          );
 | 
				
			||||||
              this.deviceType.splice(index, 1);
 | 
					          // 更新实际存储的选中值
 | 
				
			||||||
              this.propsKey++;
 | 
					          this.deviceType = this.equipmentList.map(item => item.typeId);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
          console.log(this.equipmentList)
 | 
					 | 
				
			||||||
          this.equipmentList.forEach((item, index) => {
 | 
					 | 
				
			||||||
            if (item.typeId == row.typeId) {
 | 
					 | 
				
			||||||
              this.equipmentList.splice(index, 1);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .catch(() => {});
 | 
					        .catch(() => {});
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					@ -822,7 +860,88 @@ export default {
 | 
				
			||||||
        `新购到货详情_${new Date().getTime()}.xlsx`
 | 
					        `新购到货详情_${new Date().getTime()}.xlsx`
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    // 高亮文本
 | 
				
			||||||
 | 
					    highlightText(text, keyword) {
 | 
				
			||||||
 | 
					      if (!keyword) return text;
 | 
				
			||||||
 | 
					      const reg = new RegExp(keyword, 'gi');
 | 
				
			||||||
 | 
					      return text.replace(reg, match => `<span class="highlight-text">${match}</span>`);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 处理下拉框可见性变化
 | 
				
			||||||
 | 
					    handleVisibleChange(visible) {
 | 
				
			||||||
 | 
					      if (!visible && this.keepSelectOpen && !this.isSearching) {
 | 
				
			||||||
 | 
					        // 只有在非搜索状态下才重新打开下拉框
 | 
				
			||||||
 | 
					        this.$nextTick(() => {
 | 
				
			||||||
 | 
					          this.$refs.typeSelect.focus();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 处理搜索框点击
 | 
				
			||||||
 | 
					    handleSearchClick() {
 | 
				
			||||||
 | 
					      this.isSearching = true;
 | 
				
			||||||
 | 
					      this.keepSelectOpen = true;
 | 
				
			||||||
 | 
					      // 确保下拉框打开
 | 
				
			||||||
 | 
					      this.$refs.typeSelect.focus();
 | 
				
			||||||
 | 
					      // 立即将焦点返回给搜索框
 | 
				
			||||||
 | 
					      this.$nextTick(() => {
 | 
				
			||||||
 | 
					        this.$refs.searchInput.focus();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 处理搜索框获得焦点
 | 
				
			||||||
 | 
					    handleSearchFocus() {
 | 
				
			||||||
 | 
					      this.isSearching = true;
 | 
				
			||||||
 | 
					      if (!this.$refs.typeSelect.visible) {
 | 
				
			||||||
 | 
					        this.$refs.typeSelect.focus();
 | 
				
			||||||
 | 
					        this.$nextTick(() => {
 | 
				
			||||||
 | 
					          this.$refs.searchInput.focus();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 高亮搜索处理
 | 
				
			||||||
 | 
					    handleHighlightSearch() {
 | 
				
			||||||
 | 
					      this.isSearching = true;
 | 
				
			||||||
 | 
					      this.keepSelectOpen = true;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      if (!this.searchKeyword) {
 | 
				
			||||||
 | 
					        this.currentMatchIndex = -1;
 | 
				
			||||||
 | 
					        this.matchedOptions = [];
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 找到所有匹配项
 | 
				
			||||||
 | 
					      this.matchedOptions = this.filteredOptions.filter(item => 
 | 
				
			||||||
 | 
					        item.fullPath.toLowerCase().includes(this.searchKeyword.toLowerCase())
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (this.matchedOptions.length > 0) {
 | 
				
			||||||
 | 
					        this.currentMatchIndex = 0;
 | 
				
			||||||
 | 
					        this.$nextTick(() => {
 | 
				
			||||||
 | 
					          this.scrollToMatch();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 滚动到匹配项
 | 
				
			||||||
 | 
					    scrollToMatch() {
 | 
				
			||||||
 | 
					      if (this.currentMatchIndex === -1 || !this.matchedOptions.length) return;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      const option = this.matchedOptions[this.currentMatchIndex];
 | 
				
			||||||
 | 
					      const selectDom = this.$el.querySelector('.el-select-dropdown__wrap');
 | 
				
			||||||
 | 
					      const optionDom = selectDom?.querySelector(`[data-key="${option.typeId}"]`);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      if (optionDom) {
 | 
				
			||||||
 | 
					        optionDom.scrollIntoView({ block: 'center', behavior: 'smooth' });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  // 添加组件销毁时的清理
 | 
				
			||||||
 | 
					  beforeDestroy() {
 | 
				
			||||||
 | 
					    this.keepSelectOpen = false;
 | 
				
			||||||
 | 
					    this.isSearching = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style lang="scss">
 | 
					<style lang="scss">
 | 
				
			||||||
| 
						 | 
					@ -835,4 +954,75 @@ export default {
 | 
				
			||||||
    display: block !important;
 | 
					    display: block !important;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.custom-tree-node {
 | 
				
			||||||
 | 
					  flex: 1;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  justify-content: space-between;
 | 
				
			||||||
 | 
					  font-size: 14px;
 | 
				
			||||||
 | 
					  padding-right: 8px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.el-icon-arrow-down.is-reverse {
 | 
				
			||||||
 | 
					  transform: rotateZ(180deg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.el-tree {
 | 
				
			||||||
 | 
					  max-height: 300px;
 | 
				
			||||||
 | 
					  overflow-y: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.highlight-text {
 | 
				
			||||||
 | 
					  background-color: #ffd04b;
 | 
				
			||||||
 | 
					  color: #000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					::v-deep .el-input-group__append {
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					  .el-button {
 | 
				
			||||||
 | 
					    padding: 0 10px;
 | 
				
			||||||
 | 
					    border: none;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    &:first-child {
 | 
				
			||||||
 | 
					      border-right: 1px solid #dcdfe6;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    &[disabled] {
 | 
				
			||||||
 | 
					      color: #c0c4cc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.type-select-dropdown {
 | 
				
			||||||
 | 
					  .el-select-dropdown__wrap {
 | 
				
			||||||
 | 
					    max-height: 400px !important;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  .el-select-dropdown__item {
 | 
				
			||||||
 | 
					    height: auto;
 | 
				
			||||||
 | 
					    padding: 8px 20px;
 | 
				
			||||||
 | 
					    white-space: normal;
 | 
				
			||||||
 | 
					    word-break: break-all;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.highlight-text {
 | 
				
			||||||
 | 
					  background-color: #ffd04b;
 | 
				
			||||||
 | 
					  color: #000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.el-input-group__append {
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					  .el-button {
 | 
				
			||||||
 | 
					    padding: 0 10px;
 | 
				
			||||||
 | 
					    border: none;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    &:first-child {
 | 
				
			||||||
 | 
					      border-right: 1px solid #dcdfe6;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    &[disabled] {
 | 
				
			||||||
 | 
					      color: #c0c4cc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue