Bläddra i källkod

feat(new-baseInfo): 添加公司范围过滤功能到部门选择下拉框

xieyong 4 dagar sedan
förälder
incheckning
19b95e3995

+ 78 - 1
src/components/CommomSelect/dept-select.vue

@@ -20,6 +20,7 @@
 
 <script>
   import { listOrganizations } from '@/api/system/organization';
+  import { getCurrentUser } from '@/utils/token-util';
   export default {
     props: {
       // 选中的数据(v-model)
@@ -34,6 +35,11 @@
         type: Boolean,
         default: false
       },
+      // 是否只显示当前登录用户所属公司的机构
+      companyScope: {
+        type: Boolean,
+        default: false
+      },
       // 自定义搜索过滤方法(关键字, 节点数据),不传则默认按部门名称/部门编码匹配
       filterMethod: {
         type: Function,
@@ -68,12 +74,83 @@
       },
       async getData(parmas = {}) {
         const data = await listOrganizations(parmas);
+        const list = this.companyScope
+          ? this.filterByCurrentCompany(data || [])
+          : data || [];
         this.treeData = this.$util.toTreeData({
-          data: data || [],
+          data: list,
           idField: 'id',
           parentIdField: 'parentId'
         });
       },
+      /* 当前登录用户所属机构id(优先取顶栏切换后的当前机构) */
+      getCurrentGroupId() {
+        let currentGroupId = null;
+        try {
+          currentGroupId = getCurrentUser()?.currentGroupId;
+        } catch (e) {
+          currentGroupId = null;
+        }
+        const userInfo = this.$store?.state?.user?.info || {};
+        return currentGroupId || userInfo.groupId || null;
+      },
+      /* 只保留当前登录用户所属公司(顶级机构)下的机构 */
+      filterByCurrentCompany(list) {
+        const groupId = this.getCurrentGroupId();
+        if (groupId == null || groupId === '') {
+          return list;
+        }
+        const nodeMap = new Map();
+        list.forEach((item) => nodeMap.set(String(item.id), item));
+        if (!nodeMap.has(String(groupId))) {
+          // 找不到当前用户所属机构时不做过滤, 避免下拉框被清空
+          return list;
+        }
+        const companyCache = new Map();
+        /* 沿 parentId 上溯, 取所属顶级机构(公司) */
+        const getCompanyId = (id) => {
+          const key = String(id);
+          if (companyCache.has(key)) {
+            return companyCache.get(key);
+          }
+          let node = nodeMap.get(key);
+          let companyId = key;
+          const visited = new Set();
+          while (node) {
+            companyId = String(node.id);
+            const parentKey =
+              node.parentId == null || node.parentId === ''
+                ? ''
+                : String(node.parentId);
+            if (
+              !parentKey ||
+              !nodeMap.has(parentKey) ||
+              visited.has(companyId)
+            ) {
+              break;
+            }
+            visited.add(companyId);
+            node = nodeMap.get(parentKey);
+          }
+          companyCache.set(key, companyId);
+          return companyId;
+        };
+        const companyId = getCompanyId(groupId);
+        const selectedKey =
+          this.value == null || this.value === '' ? '' : String(this.value);
+        const selectedCompanyId =
+          selectedKey && nodeMap.has(selectedKey)
+            ? getCompanyId(selectedKey)
+            : '';
+        return list.filter((item) => {
+          const itemCompanyId = getCompanyId(item.id);
+          if (itemCompanyId === companyId) {
+            return true;
+          }
+          // 已选机构属于其他公司时一并保留, 保证编辑/详情能正常回显名称
+          return !!selectedCompanyId && itemCompanyId === selectedCompanyId;
+        });
+      },
       /* 更新选中数据 */
       updateValue(value) {
         this.$emit('input', value);

+ 1 - 0
src/views/inspectionPlan/components/new-baseInfo.vue

@@ -144,6 +144,7 @@
             :disabled="btnType == 'detail'"
             v-model="form.groupId"
             filterable
+            company-scope
             @changeGroup="searchDeptNodeClick"
           />
         </el-form-item>