Преглед изворни кода

Merge branch 'dev' of http://110.41.163.243:9980/kd-aiot/kd-aiot-frontend into dev

xieyong пре 1 недеља
родитељ
комит
d1f4623d79
1 измењених фајлова са 144 додато и 17 уклоњено
  1. 144 17
      src/views/system/organization/components/org-user-edit.vue

+ 144 - 17
src/views/system/organization/components/org-user-edit.vue

@@ -48,7 +48,7 @@
           </el-form-item>
           <el-form-item label="所属机构:" prop="groupId">
             <org-select
-              :data="institutionList"
+              :data="institutionOptions"
               placeholder="请选择所属机构"
               v-model="form.groupId"
               :disabled="!!form.loginName"
@@ -59,13 +59,13 @@
           <el-form-item label="隶属部门:">
             <el-cascader
               class="ele-block"
-              :options="organization"
-              placeholder="请选择隶属部门"
+              :options="deptOptions"
+              :placeholder="form.groupId ? '请选择隶属部门' : '请先选择所属机构'"
               :props="defaultProps"
               ref="deptRef"
               :show-all-levels="true"
               @change="handleChange"
-              :disabled="!!form.loginName"
+              :disabled="!!form.loginName || !form.groupId"
               v-model="form.deptIds"
               clearable
             ></el-cascader>
@@ -1271,6 +1271,13 @@
           ],
           status: [
             { required: true, message: '请选择员工状态', trigger: 'blur' }
+          ],
+          joinDate: [
+            {
+              required: true,
+              message: '请选择入职时间',
+              trigger: ['blur', 'change']
+            }
           ]
         },
         // 提交状态
@@ -1415,6 +1422,8 @@
           value: 'id',
           label: 'name'
         },
+        // 上一次所属机构(用于判断用户是否真的换了机构,避免误清隶属部门)
+        lastGroupId: null,
 
         professionList: []
       };
@@ -1424,8 +1433,53 @@
       styleResponsive() {
         return this.$store.state.theme.styleResponsive;
       },
-      organization() {
-        return this.setList(this.organizationList);
+      // 组织架构平铺数据(含父级,用于判断公司机构与部门归属)
+      orgFlatList() {
+        const result = [];
+        const walk = (nodes) => {
+          (nodes || []).forEach((item) => {
+            result.push(item);
+            walk(item.children);
+          });
+        };
+        walk(
+          this.institutionList && this.institutionList.length
+            ? this.institutionList
+            : this.organizationList
+        );
+        return result;
+      },
+      // 组织树全部 id 集合:parentId 不在其中的节点即公司机构
+      orgIdSet() {
+        return new Set(this.orgFlatList.map((item) => String(item.id)));
+      },
+      /*
+       * 所属机构下拉:只允许选择公司机构,非公司节点置灰保留层级;
+       * 已选节点即使不是公司也保留(置灰),避免回显成裸 id
+       */
+      institutionOptions() {
+        return this.buildInstitutionOptions(
+          this.institutionList && this.institutionList.length
+            ? this.institutionList
+            : this.organizationList
+        );
+      },
+      /*
+       * 隶属部门级联:与所属机构联动,只展示所选公司机构下的部门;
+       * 未选机构时为空(提示先选机构),所选机构不在组织树中时兜底展示整棵树
+       */
+      deptOptions() {
+        const groupId = this.form.groupId;
+        if (groupId == null || groupId === '') {
+          return [];
+        }
+        const company = this.orgFlatList.find(
+          (item) => String(item.id) === String(groupId)
+        );
+        if (!company) {
+          return this.copyOrgTree(this.organizationList);
+        }
+        return this.copyOrgTree(company.children || []);
       },
       identityPhotosColumns() {
         return [
@@ -1966,14 +2020,73 @@
 
         this.professionList = res.list || [];
       },
-      setList(list) {
-        return list.map((val) => {
-          val['disabled'] = val.id == this.form.groupId;
-          if (val.children) {
-            val.children = this.setList(val.children);
+      /*
+       * 所属机构下拉数据:公司机构可选,其它节点置灰;
+       * 既不是公司又没有下级公司的纯部门节点直接丢弃,避免下拉被部门撑满
+       */
+      buildInstitutionOptions(list) {
+        const result = [];
+        // 编辑回显的机构(不限公司)保留在选项中,避免历史数据回显成裸 id
+        const selectedId = this.data ? this.data.groupId : null;
+        (list || []).forEach((item) => {
+          const children = this.buildInstitutionOptions(item.children);
+          const isCompany = this.isCompanyOrg(item);
+          const isSelected = String(item.id) === String(selectedId);
+          if (!isCompany && !isSelected && !children.length) {
+            return;
           }
-          return val;
+          const node = { ...item, disabled: !isCompany };
+          if (children.length) {
+            node.children = children;
+          } else {
+            delete node.children;
+          }
+          result.push(node);
         });
+        return result;
+      },
+      /* 组织树浅拷贝,避免直接改动父组件传入的数据 */
+      copyOrgTree(list) {
+        return (list || []).map((item) => {
+          const node = { ...item };
+          if (item.children && item.children.length) {
+            node.children = this.copyOrgTree(item.children);
+          } else {
+            delete node.children;
+          }
+          return node;
+        });
+      },
+      /*
+       * 是否公司机构:上级不在组织树内的节点即顶层机构(公司)。
+       * 组织机构列表已在页面过滤「超级管理员」,故顶层节点就是公司机构
+       */
+      isCompanyOrg(node) {
+        if (!node || node.name === '超级管理员') {
+          return false;
+        }
+        return !this.orgIdSet.has(String(node.parentId));
+      },
+      /* 沿父级上溯取所属公司机构 id(新增时把树里选中的部门换算成公司) */
+      resolveCompanyId(id) {
+        if (id == null || id === '') {
+          return id;
+        }
+        const byId = new Map(
+          this.orgFlatList.map((item) => [String(item.id), item])
+        );
+        let node = byId.get(String(id));
+        const seen = new Set();
+        while (
+          node &&
+          !this.isCompanyOrg(node) &&
+          byId.has(String(node.parentId)) &&
+          !seen.has(String(node.id))
+        ) {
+          seen.add(String(node.id));
+          node = byId.get(String(node.parentId));
+        }
+        return node && this.isCompanyOrg(node) ? node.id : id;
       },
       addIdentityPhotos() {
         this.form.identityPhotos.push({
@@ -2134,15 +2247,24 @@
         this.form.deptIds = this.form.deptIds || [];
       },
       checkedKeys(value) {
+        const groupId = this.form.groupId;
         this.getLabelName(this.institutionList, (i) => {
-          if (i.id == this.form.groupId) {
+          if (String(i.id) === String(groupId)) {
             return (this.form.groupName = i.name);
           }
         });
-        this.form.deptIds = this.form.deptIds.filter(
-          (item) => item != this.form.groupId
+        // 所属机构变化:清空隶属部门(部门选项已按新机构重建)
+        if (
+          this.lastGroupId != null &&
+          String(this.lastGroupId) !== String(groupId)
+        ) {
+          this.form.deptIds = [];
+          this.form.deptName = '';
+        }
+        this.lastGroupId = groupId;
+        this.form.deptIds = (this.form.deptIds || []).filter(
+          (item) => String(item) != String(groupId)
         );
-        console.log(this.form.groupName);
       },
       getLabelName(data, callback) {
         data.some((i) => {
@@ -2163,6 +2285,8 @@
                 res.postId = res.postId.split(',');
               }
               this.form = { ...res };
+              // 记录回显的所属机构,避免后续误判为「换了机构」而清空隶属部门
+              this.lastGroupId = this.form.groupId ?? null;
               if (Array.isArray(this.form.signature)) {
                 this.form.signature = this.form.signature[0];
               }
@@ -2188,11 +2312,14 @@
             // console.log('this.form',this.form)
           } else {
             this.city = null;
-            this.form.groupId = this.organizationId;
+            // 新增时默认带入左侧树选中的机构:若选中的是部门,上溯到所属公司机构
+            this.form.groupId = this.resolveCompanyId(this.organizationId);
+            this.lastGroupId = this.form.groupId ?? null;
             this.isUpdate = false;
           }
         } else {
           this.city = null;
+          this.lastGroupId = null;
           this.$refs.form.clearValidate();
           this.form = { ...this.defaultForm };
         }