소스 검색

合并dev分支到test

xieyong 1 주 전
부모
커밋
1682497d50

+ 71 - 12
src/views/enterpriseModel/dept/components/org-edit.vue

@@ -515,6 +515,11 @@
   import { basicAreaPageAPI } from '@/api/regionalManage';
   import { cityDataLabel } from 'ele-admin/packages/utils/regions';
 
+  // 岗位序列属配置类数据,会话级缓存:
+  // 只要本页成功拉到过一次非空数据,后续再次打开弹窗就直接复用,
+  // 避免二次请求返回空数据时把已经拿到的选项冲掉
+  let positionSequenceCache = [];
+
   export default {
     components: {
       OrgSelect,
@@ -764,23 +769,55 @@
         }
         this._ensurePositionPromise = (async () => {
           try {
+            // 各数据源独立容错:一个接口失败不能导致其它下拉也没数据
             if (!this.positionList.length) {
-              const res = await getHrPositionPage({
-                pageNum: 1,
-                size: 9999,
-                status: 1
-              });
-              this.positionList = (res && res.list) || [];
+              try {
+                const res = await getHrPositionPage({
+                  pageNum: 1,
+                  size: 9999,
+                  status: 1
+                });
+                // 同理:接口返回空时不覆盖已有岗位选项
+                const list = (res && res.list) || [];
+                if (list.length || !this.positionList.length) {
+                  this.positionList = list;
+                }
+              } catch (e) {
+                console.error('获取岗位列表失败', e);
+              }
+            }
+            // 先用会话缓存兜底,避免再次打开弹窗时因请求返回异常导致下拉为空
+            if (!this.positionSequenceList.length && positionSequenceCache.length) {
+              this.positionSequenceList = positionSequenceCache;
             }
             if (!this.positionSequenceList.length) {
               try {
                 const res = await getPositionSequenceList();
-                this.positionSequenceList = (Array.isArray(res)
+                // 兼容数组 / {list:[...]} / {records:[...]} 三种返回结构
+                const list = Array.isArray(res)
                   ? res
-                  : []
-                ).filter((item) => Number(item.status) === 1);
+                  : (res && (res.list || res.records)) || [];
+                // status 字段缺失时不过滤,只有明确为停用状态才剔除
+                const enabledList = list.filter(
+                  (item) =>
+                    item.status === undefined ||
+                    item.status === null ||
+                    Number(item.status) === 1
+                );
+                if (enabledList.length) {
+                  positionSequenceCache = enabledList;
+                  this.positionSequenceList = enabledList;
+                } else {
+                  // 接口没返回可用数据时保留已有选项,并打印原始响应便于排查
+                  console.error(
+                    '岗位序列接口未返回可用数据,原始响应:',
+                    res
+                  );
+                  this.positionSequenceList = positionSequenceCache;
+                }
               } catch (e) {
-                this.positionSequenceList = [];
+                console.error('获取岗位序列列表失败', e);
+                this.positionSequenceList = positionSequenceCache;
               }
             }
             // 加载岗位性质字典(无静态兜底)
@@ -789,7 +826,7 @@
                 const res = await getPositionNatureDict();
                 this.positionNatureOptions = Array.isArray(res) ? res : [];
               } catch (e) {
-                this.positionNatureOptions = [];
+                console.error('获取岗位性质字典失败', e);
               }
             }
           } finally {
@@ -944,6 +981,22 @@
                 levelOptions: []
               })
             );
+            // 兜底:岗位序列接口没拿到数据时,用该部门已保存的岗位序列补全下拉选项
+            if (!this.positionSequenceList.length) {
+              const seqMap = new Map();
+              this.departmentPositionList.forEach((row) => {
+                if (row.positionSequenceId && row.positionSequence) {
+                  seqMap.set(String(row.positionSequenceId), {
+                    id: row.positionSequenceId,
+                    sequence: row.positionSequence,
+                    status: 1
+                  });
+                }
+              });
+              if (seqMap.size) {
+                this.positionSequenceList = Array.from(seqMap.values());
+              }
+            }
           } finally {
             this._loadDeptPromise = null;
           }
@@ -955,6 +1008,10 @@
         this.positionList = [];
         this.positionSequenceList = [];
         this.positionNatureOptions = [];
+        // 清理并发防重状态,避免上一次弹窗遗留的 Promise 影响下一次打开
+        this._ensurePositionPromise = null;
+        this._loadDeptPromise = null;
+        this._loadDeptId = null;
       },
       formValidate() {
         return new Promise((resolve, reject) => {
@@ -1068,7 +1125,9 @@
             this.isUpdate = false;
           }
         } else {
-          this.$refs.form.clearValidate();
+          // 关闭弹窗时必须确保下面的重置逻辑一定执行,
+          // 否则上一次的岗位下拉数据/防重 Promise 会被带到下一次打开
+          this.$refs.form && this.$refs.form.clearValidate();
           this.$refs.enterpriseForm &&
             this.$refs.enterpriseForm.clearValidate();
           this.form = { ...this.defaultForm };

+ 173 - 8
src/views/material/BOMmanage/components/detailedList.vue

@@ -9,7 +9,7 @@
       :pagination="pagination"
       :datasource="datasource"
       :page-size="20"
-      cache-key="routed_detailed_list"
+      :cache-key="useNewColumns ? 'routed_detailed_list_v2' : 'routed_detailed_list'"
       class="dict-table"
       tool-class="ele-toolbar-actions"
       :height="tableHeight"
@@ -76,7 +76,10 @@
         </el-input>
       </template>
 
-      <template v-slot:versions="{ row }"> V{{ row.versions }}.0 </template>
+      <template v-slot:versions="{ row }"> 
+        <template v-if="row.versions">V{{ row.versions }}.0</template>
+        <template v-else>无</template>
+      </template>
 
       <template v-slot:rootCategoryLevelId="{ row }"
         >{{ rootCategoryLevelIdText(row.rootCategoryLevelId) }}
@@ -277,7 +280,7 @@
 
   import clientDialog from './clientDialog.vue';
 
-  import { getByCode } from '@/api/system/dictionary-data';
+  import { getByCode, parameterGetByCode } from '@/api/system/dictionary-data';
 
   import bomTreeDialog from './bomTreeDialog.vue';
   import { produceTypeList } from '@/enum/dict.js';
@@ -291,11 +294,13 @@
       return {
         produceTypeList,
         clientEnvironmentId: this.$store.state.user.info.clientEnvironmentId,
+        // 是否启用新 columns 方案(true=新方案,false=老方案)
+        useNewColumns: false,
         pagination: {
           tableTotal: 0
         },
-        // 表格列配置
-        columns: [
+        // 老 columns 方案(保持原有 28 列可见)
+        oldColumnsConfig: [
           {
             label: '序号',
             columnKey: 'index',
@@ -329,11 +334,12 @@
 
           {
             prop: 'brandNum',
-            label: '牌号'
+            label: '牌号/材质',
+            width: 100
           },
           {
             prop: 'imgCode',
-            label: '图号'
+            label: '图号/件号'
           },
 
           {
@@ -442,7 +448,7 @@
           },
 
           {
-            prop: 'status ',
+            prop: 'status',
             label: '状态',
             formatter: (row) => {
               return this.statusOpt[+row.status];
@@ -459,6 +465,11 @@
             label: '创建日期',
             width: 160
           },
+          {
+            prop: 'updateTime',
+            label: '修改时间',
+            width: 160
+          },
           {
             action: 'action',
             slot: 'action',
@@ -467,6 +478,107 @@
             width: 120
           }
         ],
+        // 新 columns 方案:默认展示这 14 列,老方案里独有列由 computed 拼到末尾且 show:false
+        newColumnsConfig: [
+          {
+            prop: 'level',
+            label: '零部件层级',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'sn',
+            label: '明细表序号',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'categoryCode',
+            label: '物料编码',
+            showOverflowTooltip: true,
+            width: 120
+          },
+          {
+            prop: 'imgCode',
+            label: '零部件图号(规格型号)',
+            showOverflowTooltip: true,
+            width: 150
+          },
+          {
+            prop: 'versions',
+            slot: 'versions',
+            label: '图纸版本',
+            showOverflowTooltip: true,
+            align: 'center',
+            width: 90
+          },
+          {
+            prop: 'updateTime',
+            label: '修改时间',
+            width: 160,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'name',
+            label: '零件名称',
+            showOverflowTooltip: true,
+            width: 150
+          },
+          {
+            prop: 'dosage',
+            slot: 'dosage',
+            label: '单台用量',
+            width: 100,
+            headerSlot: 'dosageHead'
+          },
+          {
+            prop: 'measuringUnit',
+            label: '计量单位',
+            showOverflowTooltip: true,
+            align: 'center',
+            width: 90
+          },
+          {
+            prop: 'brandNum',
+            label: '材质',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'netWeight',
+            label: '单重',
+            showOverflowTooltip: true,
+            align: 'right',
+            width: 100
+          },
+          {
+            prop: 'totalWeight',
+            label: '总重',
+            showOverflowTooltip: true,
+            align: 'right',
+            width: 100
+          },
+          {
+            prop: 'remark',
+            label: '备注',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'createName',
+            label: '创建人',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'createTime',
+            label: '创建日期',
+            width: 160,
+            showOverflowTooltip: true
+          }
+        ],
         statusOpt: {
           '': '全部',
           0: '草稿',
@@ -606,6 +718,7 @@
       // this.getDictList('productionType');
       // this.getZeroPartPros('zeroPartPros');
       this.getContactList();
+      this.getRuntianConfig();
     },
 
     props: {
@@ -668,6 +781,43 @@
     //     });
     //   }
     // },
+    computed: {
+      // 操作列:固定右侧,不参与新老的合并
+      actionColumn() {
+        return {
+          action: 'action',
+          slot: 'action',
+          fixed: 'right',
+          label: '操作',
+          width: 120
+        };
+      },
+      // 新方案默认展示的 prop 集合(自动从 newColumnsConfig 推导,避免漏配导致老列覆盖新列)
+      newPropSet() {
+        const set = new Set();
+        this.newColumnsConfig.forEach((c) => {
+          if (c.prop) set.add(c.prop);
+        });
+        return set;
+      },
+      // 表格列:按 useNewColumns 决定输出老方案还是新方案
+      columns() {
+        if (this.useNewColumns) {
+          // 老方案里独有、且不在新方案里的列 → 追加到末尾,默认隐藏,用户可手动显示
+          const extras = this.oldColumnsConfig
+            .filter((c) => {
+              if (c.action === 'action') return false; // 操作列单独追加
+              if (c.type === 'index' || c.columnKey === 'index') return false;
+              if (c.prop && this.newPropSet.has(c.prop)) return false;
+              return true;
+            })
+            .map((c) => ({ ...c, show: false }));
+          return [...this.newColumnsConfig, ...extras, this.actionColumn];
+        }
+        // 老方案:保持原有顺序
+        return [...this.oldColumnsConfig];
+      }
+    },
 
     methods: {
       attributeTypeText(v) {
@@ -688,6 +838,21 @@
         });
       },
 
+      // 根据系统参数 is_runtian 判断是否启用新 columns 方案
+      // 兼容常见返回:'1' / 1 / { value: 1 } / { paramValue: '1' } / true
+      async getRuntianConfig() {
+        try {
+          const data = await parameterGetByCode({ code: 'is_runtian' });
+          const val =
+            typeof data === 'object' && data !== null
+              ? data.value ?? data.paramValue ?? data.val
+              : data;
+          this.useNewColumns = val === '1' || val === 1 || val === true;
+        } catch (e) {
+          this.useNewColumns = false;
+        }
+      },
+
       rootCategoryLevelIdText(v) {
         console.log(v, '111111');
         console.log(

+ 170 - 6
src/views/material/BOMmanage/index.vue

@@ -45,7 +45,10 @@
             >
           </template>
 
-          <template v-slot:versions="{ row }"> V{{ row.versions }}.0 </template>
+          <template v-slot:versions="{ row }">
+            <template v-if="row.versions">V{{ row.versions }}.0</template>
+            <template v-else>无</template>
+          </template>
           <template v-slot:isTemp="{ row }">
             <el-tag size="mini" v-if="row.isTemp == 1">主数据</el-tag>
           </template>
@@ -181,7 +184,7 @@
     withdrawBom
   } from '@/api/material/BOM';
   import LCdetail from './components/LCdetail.vue';
-  import { getByCode } from '@/api/system/dictionary-data';
+  import { getByCode, parameterGetByCode } from '@/api/system/dictionary-data';
   import BomDetailsPop from '../BOMmanage/detailsPop.vue';
   import { mapGetters } from 'vuex';
 
@@ -193,8 +196,8 @@
       return {
         produceTypeList,
         processSubmitDialogFlag: false,
-        // 表格列配置
-        columns: [
+        // 老 columns 方案(默认 20 列全部可见)
+        oldColumnsConfig: [
           {
             label: '序号',
             columnKey: 'index',
@@ -279,7 +282,7 @@
             minWidth: 180
           },
           {
-            prop: 'status ',
+            prop: 'status',
             label: '状态',
             formatter: (row) => {
               return this.statusOpt[+row.status];
@@ -326,6 +329,110 @@
             align: 'center'
           }
         ],
+        // 新 columns 方案(PBOM + is_runtian===1 时使用),内容与 detailedList.vue 的 newColumnsConfig 保持一致
+        newColumnsConfig: [
+          {
+            prop: 'level',
+            label: '零部件层级',
+            align: 'center',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'sn',
+            label: '明细表序号',
+            align: 'center',
+            width: 120,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'code',
+            label: '物料编码',
+            slot: 'code',
+            showOverflowTooltip: true,
+            width: 120
+          },
+          {
+            prop: 'imgCode',
+            label: '零部件图号(规格型号)',
+            showOverflowTooltip: true,
+            width: 150
+          },
+          {
+            prop: 'versions',
+            slot: 'versions',
+            label: '图纸版本',
+            showOverflowTooltip: true,
+            align: 'center',
+            width: 90
+          },
+          {
+            prop: 'updateTime',
+            label: '修改时间',
+            width: 160,
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'name',
+            label: '零件名称',
+            showOverflowTooltip: true,
+            width: 150
+          },
+          {
+            prop: 'dosage',
+            slot: 'dosage',
+            label: '单台用量',
+            width: 100,
+            headerSlot: 'dosageHead'
+          },
+          {
+            prop: 'measuringUnit',
+            label: '计量单位',
+            showOverflowTooltip: true,
+            align: 'center',
+            width: 90
+          },
+          {
+            prop: 'brandNum',
+            label: '材质',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'netWeight',
+            label: '单重',
+            showOverflowTooltip: true,
+            align: 'right',
+            width: 100
+          },
+          {
+            prop: 'totalWeight',
+            label: '总重',
+            showOverflowTooltip: true,
+            align: 'right',
+            width: 100
+          },
+          {
+            prop: 'remark',
+            label: '备注',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'createName',
+            label: '创建人',
+            showOverflowTooltip: true,
+            width: 100
+          },
+          {
+            prop: 'createTime',
+            label: '创建日期',
+            width: 160,
+            showOverflowTooltip: true
+          }
+        ],
+        // 系统参数 is_runtian 原始值(false=未加载/失败,其他=接口返回值)
+        isRuntianValue: false,
         sxtList: [
           {
             label: '自制件',
@@ -454,12 +561,55 @@
       clientEnvironmentId() {
         return this.$store.state.user.info.clientEnvironmentId;
       },
-      ...mapGetters(['user'])
+      ...mapGetters(['user']),
+      // 是否启用新 columns 方案:activeName 为 PBOM (1/'1') 且 is_runtian === 1
+      useNewColumns() {
+        const isPBOM = this.activeName == 1 || this.activeName === '1';
+        const val = this.isRuntianValue;
+        const isRuntianOk = val === '1' || val === 1 || val === true;
+        return isPBOM && isRuntianOk;
+      },
+      // 新方案默认展示的 prop 集合(自动从 newColumnsConfig 推导,避免漏配导致老列覆盖新列)
+      newPropSet() {
+        const set = new Set();
+        this.newColumnsConfig.forEach((c) => {
+          if (c.prop) set.add(c.prop);
+        });
+        return set;
+      },
+      // 操作列:固定右侧,不参与新老的合并
+      actionColumn() {
+        return {
+          columnKey: 'action',
+          slot: 'action',
+          label: '操作',
+          width: 170,
+          align: 'center'
+        };
+      },
+      // 表格列:按 useNewColumns 决定输出老方案还是新方案
+      columns() {
+        if (this.useNewColumns) {
+          // 老方案里独有、且不在新方案里的列 → 追加到末尾,默认隐藏,用户可手动显示
+          const extras = this.oldColumnsConfig
+            .filter((c) => {
+              if (c.columnKey === 'action') return false; // 操作列单独追加
+              if (c.type === 'index' || c.columnKey === 'index') return false;
+              if (c.prop && this.newPropSet.has(c.prop)) return false;
+              return true;
+            })
+            .map((c) => ({ ...c, show: false }));
+          return [...this.newColumnsConfig, ...extras, this.actionColumn];
+        }
+        // 老方案:保持原有顺序
+        return [...this.oldColumnsConfig];
+      }
     },
 
     created() {
       this.getDictList('productionType');
       this.getAttriButeList('inventory_type');
+      this.getRuntianConfig();
     },
     methods: {
       attributeTypeText(v) {
@@ -496,6 +646,20 @@
           };
         });
       },
+
+      // 取系统参数 is_runtian 的原始值(由 computed useNewColumns 配合 activeName 共同判断)
+      // 兼容常见返回:'1' / 1 / { value: 1 } / { paramValue: '1' } / true
+      async getRuntianConfig() {
+        try {
+          const data = await parameterGetByCode({ code: 'is_runtian' });
+          this.isRuntianValue =
+            typeof data === 'object' && data !== null
+              ? data.value ?? data.paramValue ?? data.val
+              : data;
+        } catch (e) {
+          this.isRuntianValue = false;
+        }
+      },
       // 撤回
       handWithdraw(row) {
         const params = {

+ 6 - 0
src/views/material/product/components/index-data.vue

@@ -578,6 +578,12 @@
             align: 'center',
             showOverflowTooltip: true
           },
+          {
+            prop: 'imgCode',
+            label: '图号/件号',
+            align: 'center',
+            showOverflowTooltip: true
+          },
           {
             prop: 'level',
             label: '级别',

+ 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 };
         }

+ 8 - 9
src/views/technology/route/components/user-search.vue

@@ -89,17 +89,16 @@
   import { getFactoryarea } from '@/api/factoryModel';
   export default {
     data() {
-      // 默认表单数据
-      const defaultWhere = {
-        code: '',
-        name: '',
-        status: 1,
-        produceVersionId: '',
-        factoriesId: ''
-      };
       return {
+        defaultWhere: {
+          code: '',
+          name: '',
+          status: '',
+          produceVersionId: '',
+          factoriesId: ''
+        },
         // 表单数据
-        where: { ...defaultWhere },
+        where: { ...this.defaultWhere },
         statusList: [
           { label: '草稿', value: -1 },
           { label: '失效', value: 0 },

+ 13 - 8
src/views/technology/route/index.vue

@@ -2,7 +2,7 @@
   <div class="ele-body">
     <el-card shadow="never">
       <!-- 搜索表单 -->
-      <user-search @search="reload" />
+      <user-search ref="userSearchRef" @search="reload" />
       <!-- 数据表格 -->
       <ele-pro-table
         ref="table"
@@ -289,11 +289,11 @@
             slot: 'status',
             showOverflowTooltip: true,
             minWidth: 110,
-            filters: [
-              { text: '草稿', value: -1 },
-              { text: '失效', value: 0 },
-              { text: '生效', value: 1 }
-            ],
+            // filters: [
+            //   { text: '草稿', value: -1 },
+            //   { text: '失效', value: 0 },
+            //   { text: '生效', value: 1 }
+            // ],
             filterMultiple: false,
             columnKey: 'status'
           },
@@ -375,7 +375,8 @@
           ...where,
           ...order,
           pageNum: page,
-          size: limit
+          size: limit,
+          latestApprovedOnly: true
         };
         const res = await route.list({ ...this.params });
         return res;
@@ -402,6 +403,10 @@
 
       /* 刷新表格 */
       reload(where) {
+        // where 是字符串(或其他非对象)时,从搜索组件取最新的搜索条件
+        if (typeof where !== 'object' || where === null) {
+          where = this.$refs.userSearchRef?.where || {};
+        }
         this.$refs.table.reload({ page: 1, where: where });
       },
       /* 打开编辑弹窗 */
@@ -448,7 +453,7 @@
           .taskinstanceChange(param)
           .then((msg) => {
             // loading.close();
-            this.$message.success('变更' + msg);
+            msg && this.$message.success('变更' + msg);
             this.reload();
           })
           .catch((e) => {