WXL
4 天以前 ead85633109bcb3cc8d8b3c6804c280dd6ee1e5d
src/views/project/components/orgselect/index.vue
@@ -1,5 +1,5 @@
<template>
  <div>
  <div class="selectclass">
    <el-select
      v-model="myValue"
      :loading="isLoading"
@@ -14,16 +14,17 @@
      @focus="focusEvents.func"
      @change="change"
      @blur="changeBlur"
      @visible-change="handleVisibleChange"
      value-key="organizationid"
      allow-create
      reserve-keyword
      :placeholder="placeholder ? placeholder : '请输入机构名称'"
      :placeholder="placeholder ? placeholder : '请选择'"
      class="full-block"
      ref="selecter"
    >
      <el-option
        v-for="(spec, index) in dataList"
        :key="index"
        v-for="(spec, index) in displayList"
        :key="spec.organizationid"
        :label="spec.organizationname"
        :value="spec.organizationid"
      >
@@ -33,7 +34,7 @@
</template>
<script>
import { listOrganization,listReportname } from "@/api/project/organization";
import { listOrganization, listReportname } from "@/api/project/organization";
export default {
  name: "OrgSelecter",
@@ -41,66 +42,75 @@
  props: {
    //Select基础属性
    value: {
      type: [String, Array],
      type: [String, Array]
    },
    //获取列表
    dataList: {
      type: Array,
      default: function() {
        return [];
      }
    },
    disabled: {
      type: Boolean,
      default: false,
      default: false
    },
    clearable: {
      type: Boolean,
      default: false,
      default: false
    },
    filterable: {
      type: Boolean,
      default: true,
      default: true
    },
    multiple: {
      type: Boolean,
      default: false,
      default: false
    },
    multipleLimit: {
      type: Number,
      default: 0,
      default: 0
    },
    defaultFirstOption: {
      type: Boolean,
      default: true,
      default: true
    },
    size: {
      type: String,
      default: "small",
      default: "small"
    },
    placeholder: {
      type: String,
      default: "",
      default: ""
    },
    //业务属性
    lazyLoad: {
      type: Boolean,
      default: false,
      default: false
    },
    isAll: {
      type: Boolean,
      default: false,
      default: false
    },
    //机构类型
    orgType: {
      type: String,
      default: "",
    },
      default: ""
    }
  },
  data() {
    return {
      pageData: { pageNum:1,pageSize:100 },
      pageData: { pageNum: 1, pageSize: 100 },
      isLoading: false,
      dataList: [],
      tempList: [],
      // 三个独立的数据源,避免相互污染
      originalList: [], // 完整的原始数据源
      tempList: [],     // 中间缓存数据
      displayList: [],  // 用于渲染显示的列表
      myValue: this.multiple ? [] : "",
      focusEvents: {
        func: () => {},
        loaded: false,
      },
        loaded: false
      }
    };
  },
  mounted() {
@@ -120,79 +130,100 @@
    }
  },
  methods: {
    renderSelecter() {
      this.pageData.PageSize = 100;
      this.dataList = [];
      this.myValue = this.value;
      this.getdataList();
    },
    //获取数据
    getdataList() {
      this.isLoading = true;
      let searchData={
          organizationtype:this.orgType,//传入的类型
          pageNum:1,
          pageSize:100000
      };//搜索条件
      let searchData = {
        organizationtype: this.orgType, //传入的类型
        pageNum: 1,
        pageSize: 100000
      }; //搜索条件
      let userType={"userType":"1"};
      let userType = { userType: "1" };
      if (this.orgType == 4) {
        let arr = this.$store.state.user.organization;
        this.originalList.push(...arr);
        if (this.isAll) {
          let all = {
            organizationid: "",
            organizationname: "全部"
          };
          this.originalList.unshift(all);
        }
        // 初始化三个列表为相同数据
        this.tempList = [...this.originalList];
        this.displayList = [...this.originalList];
        this.focusEvents.loaded = true;
        this.isLoading = false;
        return;
      }
      listOrganization(searchData)
        .then((response) => {
          this.dataList.push(...response.rows);
        .then(response => {
          this.originalList.push(...response.rows);
          if (this.isAll) {
            let all = {
              organizationid: "",
              organizationname: "全部",
              organizationname: "全部"
            };
            this.dataList.unshift(all);
            this.originalList.unshift(all);
          }
          this.tempList = this.dataList.map(item=>item);
          // 初始化三个列表为相同数据
          this.tempList = [...this.originalList];
          this.displayList = [...this.originalList];
          this.focusEvents.loaded = true;
        })
        .catch((error) => {
          // 暂无处理
        .catch(error => {
          console.error("获取机构列表失败:", error);
        })
        .finally(() => {
          this.isLoading = false;
        });
    },
    getOptionByValue(key) {
      let outValue = null;
      this.dataList.forEach((e) => {
          if (e.organizationid == key) {
            outValue = e;
          }
      });
      return outValue;
    },
    /**
     * 自定义筛选方法 - 修复搜索无效问题
     * @param {string} val - 搜索关键词
     */
    filterMethod(val) {
      this.myValue = val;
      if (val) {
        this.dataList = this.tempList.filter((item) => {
          if (
            (item.PYM &&
              !!~item.PYM.toUpperCase().indexOf(val.toUpperCase())) ||
            (item.WBM &&
              !!~item.WBM.toUpperCase().indexOf(val.toUpperCase())) ||
        // 对临时列表进行筛选,不修改原始数据
        this.displayList = this.tempList.filter(item => {
          return (
            (item.PYM && item.PYM.toUpperCase().includes(val.toUpperCase())) ||
            (item.WBM && item.WBM.toUpperCase().includes(val.toUpperCase())) ||
            (item.organizationname &&
              !!~item.organizationname.toUpperCase().indexOf(val.toUpperCase()))
          ) {
            return true;
          } else {
            return false;
          }
             item.organizationname.toUpperCase().includes(val.toUpperCase()))
          );
        });
      } else {
        this.dataList = this.tempList.map(item=>item);
        // 搜索词为空时显示完整列表
        this.displayList = [...this.tempList];
      }
    },
    /**
     * 处理下拉框显示/隐藏事件 - 修复数据恢复问题
     * @param {boolean} visible - 是否可见
     */
    handleVisibleChange(visible) {
      if (!visible) {
        // 下拉框关闭时重置显示列表为完整数据
        this.displayList = [...this.originalList];
        this.tempList = [...this.originalList];
      }
    },
    getOptionByValue(key) {
      return this.originalList.find(item => item.organizationid == key) || null;
    },
    focus() {
      this.$refs.selecter.focus();
    },
@@ -208,23 +239,25 @@
        this.$emit("change", data);
      });
    },
    defaultInit(defaultItem, defaultItemName) {
      if (defaultItem && defaultItemName) {
        let list = this.dataList.filter(
          (r) =>
        let list = this.originalList.filter(
          r =>
            r.organizationid == defaultItem &&
            r.organizationname == defaultItemName
        );
        if (list.length == 0) {
          let data = {
            organizationname: defaultItemName,
            organizationid: defaultItem,
            organizationid: defaultItem
          };
          this.dataList.push(data);
          this.originalList.push(data);
          this.tempList = [...this.originalList];
          this.displayList = [...this.originalList];
        }
      }
      this.tempList = this.dataList.map(item=>item);
    },
    }
  },
  computed: {},
  watch: {
@@ -236,8 +269,36 @@
      this.$emit("input", newVal);
      this.$emit("change", newVal);
    },
  },
    // 监听props中的dataList变化
    dataList: {
      handler(newList) {
        if (newList && newList.length > 0) {
          this.originalList = [...newList];
          this.tempList = [...newList];
          this.displayList = [...newList];
        }
      },
      immediate: true,
      deep: true
    }
  }
};
</script>
<style></style>
<style lang="scss" scoped>
::v-deep.selectclass .el-select {
  display: inline-block;
  position: relative;
  width: 90%;
}
// 优化搜索框样式
::v-deep.selectclass .el-select__input {
  min-width: 80px;
}
// 确保选项列表正常显示
::v-deep.selectclass .el-select-dropdown {
  z-index: 9999 !important;
}
</style>