Преглед на файлове

fix: 部门岗位编制岗位性质改为只读自动带出,编制人数增加非空及大于0校验

lihaiting преди 1 седмица
родител
ревизия
7d259c6f98
променени са 1 файла, в които са добавени 119 реда и са изтрити 75 реда
  1. 119 75
      src/views/enterpriseModel/dept/components/org-edit.vue

+ 119 - 75
src/views/enterpriseModel/dept/components/org-edit.vue

@@ -308,23 +308,7 @@
       </el-table-column>
       <el-table-column label="岗位性质" min-width="140" align="center">
         <template slot-scope="{ row }">
-          <el-select
-            v-if="!row.id"
-            v-model="row.positionType"
-            filterable
-            clearable
-            placeholder="请选择"
-            style="width: 100%"
-            @change="onDeptPositionTypeChange(row)"
-          >
-            <el-option
-              v-for="item in positionNatureOptions"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            />
-          </el-select>
-          <span v-else>{{ row.positionTypeName }}</span>
+          <span>{{ row.positionTypeName || '-' }}</span>
         </template>
       </el-table-column>
       <el-table-column label="编制人数" min-width="120" align="center">
@@ -335,6 +319,7 @@
             :precision="0"
             controls-position="right"
             style="width: 100%"
+            @change="onDeptEstablishmentCountChange(row)"
           />
         </template>
       </el-table-column>
@@ -678,34 +663,30 @@
         };
       },
       buildDepartmentPositionPayload() {
-        if (!this.form.id) {
-          return [];
-        }
         const rows = [];
         for (const row of this.departmentPositionList) {
           const isNew = !row.id;
-          const emptyNew =
-            isNew &&
-            !row.positionId &&
-            !row.positionLevelId &&
-            (row.establishmentCount === undefined ||
-              row.establishmentCount === null ||
-              row.establishmentCount === '');
-          if (emptyNew) {
-            continue;
-          }
+          const rowNo = this.departmentPositionList.indexOf(row) + 1;
           if (isNew) {
-            if (
-              !row.positionId ||
-              !row.positionName ||
-              !row.positionLevelId ||
-              row.establishmentCount === undefined ||
-              row.establishmentCount === null ||
-              row.establishmentCount === ''
-            ) {
-              this.$message.warning('请完善部门岗位信息');
+            const emptyNew =
+              !row.positionId &&
+              !row.positionLevelId &&
+              this.isEmptyEstablishmentCount(row.establishmentCount);
+            if (emptyNew) {
+              continue;
+            }
+            if (!this.isDeptPositionFilled(row)) {
+              this.$message.warning(this.getDeptPositionMissingTip(row, rowNo));
               return false;
             }
+          } else if (!this.isValidEstablishmentCount(row.establishmentCount)) {
+            // 已保存的岗位编制也允许调整人数,同样不允许 0 或空
+            this.$message.warning(this.getEstablishmentCountTip(row, rowNo));
+            return false;
+          }
+          if (!this.form.id) {
+            // 新增部门时还没有部门 id,岗位编制需在部门保存后再维护
+            continue;
           }
           rows.push({
             ...(row.id ? { id: row.id } : {}),
@@ -727,17 +708,59 @@
         return (
           !!row.positionId &&
           !!row.positionLevelId &&
-          row.establishmentCount !== undefined &&
-          row.establishmentCount !== null &&
-          row.establishmentCount !== ''
+          this.isValidEstablishmentCount(row.establishmentCount)
         );
       },
+      // 编制人数是否未填
+      isEmptyEstablishmentCount(value) {
+        return value === undefined || value === null || value === '';
+      },
+      // 编制人数填 0 时即时提示(输入完成后触发)
+      onDeptEstablishmentCountChange(row) {
+        if (
+          !this.isEmptyEstablishmentCount(row.establishmentCount) &&
+          !this.isValidEstablishmentCount(row.establishmentCount)
+        ) {
+          this.$message.warning('编制人数必须大于 0');
+        }
+      },
+      // 编制人数必须是大于 0 的整数(0 不允许)
+      isValidEstablishmentCount(value) {
+        return !this.isEmptyEstablishmentCount(value) && Number(value) > 0;
+      },
+      // 编制人数的提示文案
+      getEstablishmentCountTip(row, rowNo) {
+        const no = rowNo ? `第 ${rowNo} 行` : '当前行';
+        return this.isEmptyEstablishmentCount(row.establishmentCount)
+          ? `${no}请填写编制人数`
+          : `${no}的编制人数必须大于 0`;
+      },
+      // 新增行未填完时按「缺什么提示什么」给出提示
+      getDeptPositionMissingTip(row, rowNo) {
+        const no = rowNo ? `第 ${rowNo} 行` : '当前行';
+        if (!row.positionSequenceId) {
+          return `${no}请选择岗位序列`;
+        }
+        if (!row.positionId) {
+          return `${no}请选择岗位名称`;
+        }
+        if (!row.positionLevelId) {
+          return `${no}请选择岗位层级`;
+        }
+        if (!this.isValidEstablishmentCount(row.establishmentCount)) {
+          return this.getEstablishmentCountTip(row, rowNo);
+        }
+        return '';
+      },
       addDeptPosition() {
-        const hasEmptyNew = this.departmentPositionList
+        const emptyRow = this.departmentPositionList
           .filter((item) => !item.id)
-          .some((item) => !this.isDeptPositionFilled(item));
-        if (hasEmptyNew) {
-          this.$message.warning('请先填写岗位名称、岗位层级和编制人数');
+          .find((item) => !this.isDeptPositionFilled(item));
+        if (emptyRow) {
+          const rowNo = this.departmentPositionList.indexOf(emptyRow) + 1;
+          this.$message.warning(
+            this.getDeptPositionMissingTip(emptyRow, rowNo)
+          );
           return;
         }
         this.ensurePositionOptions();
@@ -867,7 +890,15 @@
           )
           .map((item) => ({
             positionLevelId: item.positionLevelId ?? item.id,
-            positionLevel: item.positionLevel || item.level || ''
+            positionLevel: item.positionLevel || item.level || '',
+            // 层级若携带岗位性质,选中层级时用于自动带出(不可手动选择)
+            positionType:
+              item.positionType ??
+              item.positionTypeId ??
+              item.positionNature ??
+              '',
+            positionTypeName:
+              item.positionTypeName || item.positionNatureName || ''
           }));
         // 详情接口的岗位序列覆盖列表值
         if (detail && (detail.positionSequenceId || detail.sequenceId)) {
@@ -875,29 +906,18 @@
           row.positionSequence =
             detail.positionSequence || detail.sequenceName || '';
         }
-        // 详情/列表的岗位性质可能是 id 或名称,通过字典反查统一为 id+名称
-        const typeRaw =
+        // 岗位性质不可手动选择:先按岗位(详情优先、列表兜底)自动带出
+        const type = await this.resolveDeptPositionType(
           (detail && detail.positionType) ||
-          (position && position.positionType) ||
-          '';
-        if (typeRaw) {
-          if (!this.positionNatureOptions.length) {
-            await this.ensurePositionOptions();
-          }
-          const matched = this.positionNatureOptions.find(
-            (item) =>
-              String(item.id) === String(typeRaw) || item.name === typeRaw
-          );
-          if (matched) {
-            row.positionType = matched.id;
-            row.positionTypeName = matched.name;
-          } else {
-            row.positionType = typeRaw;
-            row.positionTypeName =
-              (detail && detail.positionTypeName) ||
-              (position && position.positionTypeName) ||
-              '';
-          }
+            (position && position.positionType) ||
+            '',
+          (detail && detail.positionTypeName) ||
+            (position && position.positionTypeName) ||
+            ''
+        );
+        if (type) {
+          row.positionType = type.id;
+          row.positionTypeName = type.name;
         }
       },
       onDeptPositionSequenceChange(row) {
@@ -915,12 +935,25 @@
         row.positionTypeName = '';
         row.levelOptions = [];
       },
-      onDeptPositionTypeChange(row) {
-        // 选中岗位性质时同步名称
-        const type = this.positionNatureOptions.find(
-          (item) => item.id === row.positionType
+      // 岗位性质不允许手动选择:把层级/岗位带出的原始值(字典 id 或文案)统一成 id+名称
+      async resolveDeptPositionType(raw, fallbackName) {
+        const value =
+          raw === null || raw === undefined ? '' : String(raw).trim();
+        const name = String(fallbackName || '').trim();
+        if (!value && !name) {
+          return null;
+        }
+        if (!this.positionNatureOptions.length) {
+          await this.ensurePositionOptions();
+        }
+        const matched = this.positionNatureOptions.find(
+          (item) =>
+            String(item.id) === value || String(item.name) === value
         );
-        row.positionTypeName = type ? type.name : '';
+        if (matched) {
+          return { id: matched.id, name: matched.name };
+        }
+        return { id: value || name, name };
       },
       // 按岗位序列过滤岗位名称选项(未选序列时返回全部)
       getPositionsBySequence(sequenceId) {
@@ -947,11 +980,22 @@
           ? `${item.positionName}(${type})`
           : item.positionName;
       },
-      onDeptPositionLevelChange(row) {
+      async onDeptPositionLevelChange(row) {
         const level = (row.levelOptions || []).find(
           (item) => item.positionLevelId === row.positionLevelId
         );
         row.positionLevel = level ? level.positionLevel : '';
+        // 岗位性质不可选:层级若带出性质则按层级刷新,否则保留已带出的性质
+        if (level && (level.positionType || level.positionTypeName)) {
+          const type = await this.resolveDeptPositionType(
+            level.positionType,
+            level.positionTypeName
+          );
+          if (type) {
+            row.positionType = type.id;
+            row.positionTypeName = type.name;
+          }
+        }
       },
       async loadDepartmentPositions() {
         if (!this.form.id || !this.isDeptType) {