浏览代码

机构数选择框

zhangjie 2 年之前
父节点
当前提交
206a89c961

+ 184 - 0
src/components/base/OrgSelect.vue

@@ -0,0 +1,184 @@
+<template>
+  <div class="org-select el-select major-select el-select--small">
+    <div v-if="multiple" class="el-select__tags">
+      <el-tag v-for="item in selectedList" :key="item.id">{{
+        item.name
+      }}</el-tag>
+    </div>
+    <div
+      :class="[
+        'el-input el-input--small el-input--suffix',
+        { 'is-focus': isFocus }
+      ]"
+    >
+      <input
+        ref="inputRef"
+        type="text"
+        autocomplete="off"
+        :placeholder="placeholder"
+        class="el-input__inner"
+        :value="selectedOrg.name"
+        readonly
+        @focus="handleFocus"
+        @blur="handleBlur"
+      />
+      <span class="el-input__suffix">
+        <span class="el-input__suffix-inner">
+          <i
+            :class="[
+              'el-select__caret',
+              'el-input__icon',
+              'el-icon-arrow-up',
+              { 'is-reverse': visible }
+            ]"
+          ></i>
+        </span>
+      </span>
+    </div>
+
+    <el-popover
+      popper-class="org-popover"
+      placement="bottom-start"
+      trigger="manual"
+      v-model="visible"
+    >
+      <div ref="popoverRef" slot="reference"></div>
+      <el-tree
+        ref="OrgTree"
+        :data="orgs"
+        default-expand-all
+        node-key="id"
+        :props="defaultProps"
+        check-on-click-node
+        :expand-on-click-node="false"
+        @node-click="nodeClick"
+      >
+        <span
+          :class="['custom-tree-node', { 'is-select': checkSelected(data) }]"
+          slot-scope="{ node, data }"
+        >
+          <span>{{ node.label }}</span>
+          <span>
+            <i class="el-icon-check"></i>
+          </span>
+        </span>
+      </el-tree>
+    </el-popover>
+  </div>
+</template>
+
+<script>
+import { organizationList } from "../../modules/base/api";
+
+export default {
+  name: "org-select",
+  props: {
+    value: {
+      type: [Array, String]
+    },
+    placeholder: { type: String, default: "请选择" },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      selectedOrg: {},
+      selectedOrgList: [],
+      selectedOrgIds: [],
+      visible: false,
+      isFocus: false,
+      orgs: [],
+      defaultProps: {
+        label: "name"
+      }
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    async getList() {
+      const orgs = await organizationList();
+      this.orgs = orgs || [];
+
+      if (this.orgs.length) {
+        this.orgs[0].children.sort((a, b) => {
+          if (a.type === "PRINTING_HOUSE") return 1;
+          if (b.type === "PRINTING_HOUSE") return -1;
+
+          return 0;
+        });
+      }
+    },
+    handleFocus() {
+      this.visible = true;
+      this.isFocus = true;
+    },
+    handleBlur() {
+      this.visible = false;
+      this.isFocus = false;
+    },
+    nodeClick(data) {
+      if (this.selectedOrgIds.includes(data.id)) {
+        this.selectedOrgList = this.selectedOrgList.filter(
+          item => item.id !== data.id
+        );
+        if (!this.multiple) this.selectedOrg = {};
+      } else {
+        if (!this.multiple) {
+          this.selectedOrgList = [];
+          this.selectedOrg = { ...data };
+        }
+        this.selectedOrgList.push({ ...data });
+      }
+      this.updateSelectOrgIds();
+      if (!this.multiple) this.visible = false;
+      this.emitChange();
+    },
+    updateSelectOrgIds() {
+      this.selectedOrgIds = this.selectedOrgList.map(item => item.id);
+    },
+    checkSelected(data) {
+      return this.selectedOrgIds.includes(data.id);
+    },
+    emitChange() {
+      this.$emit(
+        "input",
+        this.multiple ? this.selectedOrgIds : this.selectedOrgIds[0]
+      );
+      this.$emit(
+        "change",
+        this.multiple ? this.selectedOrgList : this.selectedOrgList[0]
+      );
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.org-select {
+  width: 220px;
+}
+.org-popover {
+  width: 300px;
+
+  .custom-tree-node {
+    .el-icon-check {
+      display: none;
+    }
+
+    &.is-select {
+      color: #3a5ae5;
+      .el-icon-check {
+        display: block;
+      }
+    }
+  }
+}
+</style>

+ 10 - 0
src/components/base/lin.html

@@ -0,0 +1,10 @@
+<div class="el-select major-select el-select--small">
+  <div class="el-input el-input--small el-input--suffix is-focus">
+    <input type="text" autocomplete="off" placeholder="专业" class="el-input__inner">
+    <span class="el-input__suffix">
+      <span class="el-input__suffix-inner">
+        <i class="el-select__caret el-input__icon el-icon-arrow-up is-reverse"></i>
+      </span>
+    </span>
+  </div>
+</div>

+ 3 - 2
src/modules/base/views/StudentManage.vue

@@ -11,10 +11,11 @@
           ></el-input>
         </el-form-item>
         <el-form-item label="机构:">
-          <college-select
+          <!-- <college-select
             v-model="filter.collegeId"
             placeholder="机构"
-          ></college-select>
+          ></college-select> -->
+          <org-select v-model="filter.collegeId"></org-select>
         </el-form-item>
         <el-form-item label="专业:">
           <major-select

+ 3 - 1
src/plugins/globalVuePlugins.js

@@ -24,6 +24,7 @@ import ClazzSelect from "../components/base/ClazzSelect.vue";
 import MajorSelect from "../components/base/MajorSelect.vue";
 import ClassSelect from "../components/base/ClassSelect.vue";
 import ExamSelect from "../components/base/ExamSelect.vue";
+import OrgSelect from "../components/base/OrgSelect.vue";
 
 const components = {
   ViewFooter,
@@ -46,7 +47,8 @@ const components = {
   ClazzSelect,
   MajorSelect,
   ClassSelect,
-  ExamSelect
+  ExamSelect,
+  OrgSelect
 };
 
 export default {