Sfoglia il codice sorgente

岗位晋升改样式

lihaiting 1 settimana fa
parent
commit
f087f311e8

+ 1 - 1
src/api/hr/index.js

@@ -486,7 +486,7 @@ function buildLevelConfig(level = {}, positionList = [], positionSequence = "")
     .map((item, index) =>
       compact({
         skillId: item.skillId || undefined,
-        skillCode: item.code || item.skillCode || `SKILL-${index + 1}`,
+        // skillCode: item.code || item.skillCode || `SKILL-${index + 1}`,
         skillName: item.name,
         skillLevel: item.level || item.skillLevel || "",
         // 文档:1-必备、0-非必备、2-加分

+ 21 - 75
src/styles/views/positionManagement/index.scss

@@ -742,7 +742,7 @@
   display: block;
   margin-top: 2px;
   color: #8b98aa;
-  font-size: 13px;
+  font-size: 14px;
   font-weight: 400;
 }
 .ladder-board {
@@ -753,12 +753,11 @@
 }
 .ladder-row {
   display: flex;
-  align-items: flex-start;
+  align-items: stretch;
   gap: 14px;
 }
 .ladder-rail {
   flex: 0 0 132px;
-  align-self: stretch;
   padding: 10px 12px;
   display: flex;
   flex-direction: column;
@@ -770,57 +769,41 @@
 }
 .ladder-rail strong {
   color: #203047;
-  font-size: 14px;
+  font-size: 15px;
   font-weight: 600;
   line-height: 1.35;
 }
 .ladder-rail span {
   color: #8b98aa;
-  font-size: 12px;
+  font-size: 14px;
 }
-/* 一行 = 一个序列;列内纵向堆岗位,列间箭头连接 */
+/* 一行 = 一个序列,层级横向排列;放不下时横向滚动,不换行不挤压 */
 .ladder-chips {
   flex: 1;
   min-width: 0;
   display: flex;
   flex-wrap: nowrap;
-  align-items: flex-start;
-  gap: 4px;
-  overflow-x: auto;
-  padding-bottom: 6px;
-}
-.ladder-arrow {
-  flex: 0 0 34px;
-  height: 40px;
-  display: flex;
   align-items: center;
-  justify-content: center;
-  color: #b6c6da;
-  font-size: 18px;
+  gap: 10px;
+  overflow-x: auto;
+  padding-bottom: 4px;
 }
-.ladder-col {
+.ladder-chip {
   flex: 0 0 auto;
-  width: 176px;
-  display: flex;
-  flex-direction: column;
-  gap: 6px;
-}
-.ladder-col-head {
-  height: 40px;
-  padding: 6px 10px;
-  display: flex;
+  min-width: 110px;
+  max-width: 220px;
+  min-height: 52px;
+  padding: 7px 12px;
+  display: inline-flex;
   align-items: center;
-  gap: 7px;
+  gap: 8px;
   border: 1px solid #dfe7f2;
   border-radius: 9px;
   background: #f4f7fb;
   color: #31445d;
-  transition: box-shadow .16s ease, border-color .16s ease;
-}
-.ladder-col-head:hover {
-  box-shadow: 0 6px 14px rgba(40, 67, 106, 0.12);
+  text-align: left;
 }
-.ladder-col-head em {
+.ladder-chip em {
   flex: 0 0 20px;
   width: 20px;
   height: 20px;
@@ -829,58 +812,21 @@
   justify-content: center;
   border: 1px solid currentColor;
   border-radius: 50%;
-  font-size: 11px;
+  font-size: 14px;
   font-style: normal;
   font-weight: 600;
   line-height: 1;
 }
-.ladder-col-head .chip-label {
-  min-width: 0;
-  font-size: 13px;
+.ladder-chip .chip-label {
+  font-size: 15px;
   font-weight: 600;
   line-height: 1.2;
   white-space: nowrap;
-  overflow: hidden;
-  text-overflow: ellipsis;
-}
-.ladder-col-head small {
-  margin-left: auto;
-  flex: 0 0 auto;
-  font-size: 11px;
-  opacity: 0.72;
-  white-space: nowrap;
-}
-.ladder-col-list {
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-  border: 1px solid #e5ecf6;
-  border-radius: 8px;
-  background: #fff;
-}
-.ladder-pos {
-  padding: 7px 10px;
-  border-left: 3px solid var(--seq-color, #1890ff);
-  color: #31445d;
-  font-size: 13px;
-  line-height: 1.35;
-  word-break: break-all;
-}
-.ladder-pos + .ladder-pos {
-  border-top: 1px solid #eef3f9;
-}
-.ladder-pos.is-empty {
-  border-left-color: #dde5ef;
-  border-left-style: dashed;
-  color: #a8b4c4;
-  text-align: center;
-  font-size: 12px;
 }
-/* 窄屏:序列名一行;层级列横向滚动 */
+/* 窄屏:序列名一行;chips 已是 nowrap + 横向滚动,无需额外处理 */
 @media (max-width: 900px) {
   .ladder-row { flex-direction: column; gap: 8px; }
   .ladder-rail { flex: none; flex-direction: row; align-items: baseline; gap: 8px; }
-  .ladder-col { width: 150px; }
 }
 
 .matrix-table {

+ 2 - 21
src/views/position/positionApplication/index.vue

@@ -124,9 +124,6 @@
               <div>
                 <span>所属机构</span><strong>{{ orgName(form.organizationId) }}</strong>
               </div>
-              <div>
-                <span>所属部门</span><strong>{{ form.deptName || "-" }}</strong>
-              </div>
               <div>
                 <span>岗位层级</span><strong>{{ levelText(form.positionLevel) || "-" }}</strong>
               </div>
@@ -230,11 +227,8 @@
               <el-form-item label="岗位名称" prop="positionName"><el-input v-model.trim="form.positionName" maxlength="40"
                   show-word-limit placeholder="如:数控车床操作工" /></el-form-item>
               <el-form-item label="机构归属" prop="organizationId"><el-select v-model="form.organizationId" filterable
-                  placeholder="请选择所属机构" @change="handleOrganizationChange"><el-option v-for="item in legalEntities"
+                  placeholder="请选择所属机构"><el-option v-for="item in legalEntities"
                     :key="item.id" :label="item.name" :value="item.id" /></el-select></el-form-item>
-              <el-form-item label="所属部门" prop="deptId"><el-select v-model="form.deptId" filterable
-                  placeholder="请选择所属部门"><el-option v-for="item in departmentOptions" :key="item.id" :label="item.name"
-                    :value="item.id" /></el-select></el-form-item>
               <el-form-item label="岗位性质" prop="type"><el-select v-model="form.type" clearable
                   placeholder="请选择岗位性质"><el-option v-for="item in typeOptions" :key="String(item.value)"
                     :label="item.label" :value="item.value" /></el-select></el-form-item>
@@ -411,7 +405,6 @@ const emptyForm = () => ({
   code: "",
   positionName: "",
   organizationId: null,
-  deptId: null,
   deptName: "",
   positionLevel: null,
   positionSequence: "",
@@ -479,9 +472,6 @@ export default {
         organizationId: [
           { required: true, message: "请选择所属机构", trigger: "change" },
         ],
-        deptId: [
-          { required: true, message: "请选择所属部门", trigger: "change" },
-        ],
         type: [{ required: true, message: "请选择岗位性质", trigger: "change" }],
         headcount: [
           { required: true, message: "请输入申请招聘人数", trigger: "change" },
@@ -626,11 +616,6 @@ export default {
         },
       ];
     },
-    departmentOptions() {
-      return this.departments.filter(
-        (item) => String(item.legalId) === String(this.form.organizationId),
-      );
-    },
     salaryText() {
       const min = Number(this.form.salaryMin || 0);
       const mid = Number(this.form.salaryMid || 0);
@@ -812,10 +797,9 @@ export default {
     openCreate() {
       this.mode = "create";
       this.form = emptyForm();
-      // 默认带出当前登录用户所属机构,并联动默认部门
+      // 默认带出当前登录用户所属机构
       this.form.organizationId =
         getCurrentOrgId() ?? this.legalEntities[0]?.id ?? null;
-      this.form.deptId = this.departmentOptions[0]?.id || null;
       this.syncLevelOptions(this.form.positionSequence);
       this.drawerVisible = true;
       this.$nextTick(() => this.$refs.applicationForm?.clearValidate());
@@ -866,9 +850,6 @@ export default {
         dutiesText: (row.duties || []).join("\n"),
       };
     },
-    handleOrganizationChange() {
-      this.form.deptId = null;
-    },
     // 岗位序列变化时联动岗位层级选项,并清空已选层级
     handleSequenceChange() {
       this.form.positionLevel = null;

+ 7 - 35
src/views/position/positionManagement/index.vue

@@ -148,7 +148,7 @@
           <div class="panel-heading">
             <div>
               <h2>纵向晋升通道</h2>
-              <span class="panel-hint">横向为岗位序列,纵向为层级:同一层级下的岗位同列展示,箭头方向即自左向右按级别逐级晋升</span>
+              <span class="panel-hint">左侧为岗位序列,右侧为该序列下的启用层级,自左向右按层级级别逐级晋升</span>
             </div>
             <div class="canvas-tools">
               <el-button icon="el-icon-download" @click="exportChannels">导出通道</el-button>
@@ -162,24 +162,10 @@
                 <span>{{ lane.code }} 序列</span>
               </div>
               <div class="ladder-chips">
-                <!-- Vue 2 编译器不允许 key 落在 <template v-for> 的子元素上,也不允许落在
-                     <template> 自身,因此循环根节点用真实 div,箭头与列由 type 区分 -->
-                <div v-for="cell in lane.cells" :key="cell.key"
-                  :class="cell.type === 'arrow' ? 'ladder-arrow' : 'ladder-col'">
-                  <template v-if="cell.type === 'col'">
-                    <div class="ladder-col-head" :style="ladderChipStyle(lane, cell.index)">
-                      <em>{{ cell.level.badge }}</em>
-                      <span class="chip-label">{{ cell.level.label }}</span>
-                      <small>{{ cell.level.count }} 个岗位</small>
-                    </div>
-                    <div class="ladder-col-list">
-                      <div v-for="pos in cell.level.positions" :key="pos.id" class="ladder-pos">
-                        {{ pos.name || "-" }}
-                      </div>
-                      <div v-if="!cell.level.positions.length" class="ladder-pos is-empty">暂无岗位</div>
-                    </div>
-                  </template>
-                  <i v-else class="el-icon-right"></i>
+                <div v-for="(lv, lvIndex) in lane.levels" :key="lv.key" class="ladder-chip"
+                  :style="ladderChipStyle(lane, lvIndex)">
+                  <em>{{ lv.badge }}</em>
+                  <span class="chip-label">{{ lv.label }}</span>
                 </div>
               </div>
             </div>
@@ -398,10 +384,8 @@ export default {
     },
     /**
      * 纵向晋升通道:数据来源就是左侧的岗位序列树——
-     * 每行一个序列,行内按 levelGrade(层级级别,越大越高)自左向右排成若干列,列即层级。
-     * 同一层级的岗位在列内纵向排列(不再横向铺开,避免同级岗位一前一后难以区分);
-     * 列之间用箭头连接,形成自左向右逐级晋升的链路。
-     * 同名层级(同一序列下重复的层级名)合并为一列,避免重复列。
+     * 每行一个序列,行内按 levelGrade(层级级别,越大越高)自左向右排层级 chip。
+     * 同名层级(同一序列下重复的层级名)合并为一个 chip,避免重复展示。
      * 不再依赖晋升通道接口的岗位间路由(那是岗位维度的路由图,与"按层级晋升"的展示口径不一致)。
      */
     promoteLadders() {
@@ -436,17 +420,6 @@ export default {
             positions,
           });
         });
-        /*
-         * 把「列 + 列前的箭头」摊平成单元素序列:
-         * Vue 2 编译器既不允许把 key 写在 <template v-for> 的子元素上,
-         * 也不允许 key 写在 <template> 自身,因此循环根节点必须是真实元素。
-         * 摊平后 DOM 顺序仍为 列、箭头、列、箭头……与原结构一致。
-         */
-        const cells = [];
-        columns.forEach((lv, lvIndex) => {
-          if (lvIndex > 0) cells.push({ key: `${lv.key}-arrow`, type: "arrow" });
-          cells.push({ key: lv.key, type: "col", index: lvIndex, level: lv });
-        });
         return {
           id: seq.key || seq.id || `seq-${index}`,
           key: seq.key,
@@ -454,7 +427,6 @@ export default {
           code: this.sequenceShortName(seq.id),
           color: seq.color,
           levels: columns,
-          cells,
         };
       });
     },