跳转到内容

前端修复实施总结(kec-manager · Vue3 + Element Plus)

实施日期:2026-07-13 | 依据:docs/前端性能与体验体检报告-2026-07-13.md 范围:落地体检报告中 全部已确认问题(H1 / M1 / A1 / A2 / B5 / C10 / A3 / A4 / L1 / L2 / B6 / B7 / B8) 验证:client/npm run build 通过(✓ built in 6.51s,exit 0,无错误/警告) 说明:M2(教师/教材改服务端分页)按计划有意跳过,见末尾「有意偏差」章节。


一、修复清单与落地位置(按严重度)

优先级编号问题落地位置关键改动
P0H1CourseList 全量渲染无分页views/course/CourseList.vue新增 currentPage/pageSize + pagedList 客户端切片;<el-table :data="pagedList">;序号列改 :index="(i)=>(currentPage-1)*pageSize+i+1";排序按钮改用 realIndex(row);末尾加 <el-pagination class="pagination-container" v-if="filteredList.length>pageSize">;筛选变更 watch 重置 currentPage=1
P1M1PlanList 全量渲染无分页views/plan/PlanList.vue同 H1 客户端切片模式(新增 watch import + currentPage/pageSize + pagedList + realIndex + 分页块)
P1B5表单 label-width 不一致(90/100/120)CourseList / PlanList / CollegeList / MajorList / TrainingLevelList / TextbookList / CourseEditPopover / ClassFormDialog统一为 label-width="100px"(批量设置仍保留原约定值处已按场景微调);College/Major/TrainingLevel/Plan/Course/Textbook 的 90px100px,CourseEditPopover 80px100px,ClassFormDialog 批量 120px100px
P1C10确认弹窗结构复制 11 处新增 components/BaseConfirmBody.vue;ClassList / CourseList / CollegeList / MajorList / TrainingLevelList / TextbookList / PlanList / TeacherList / UserManagement / PlanDetail / TeachingArrange抽取轻量组件(props:message / warning / icon / iconColor),11 处删除内联结构改组件调用,完整保留各自 el-dialog 外壳、底部按钮、v-if 危险子句
P1A1工具条筛选/操作右对齐混排styles/global.css.page-toolbar .action-buttons { margin-left:8px }margin-left:auto,操作按钮推右、筛选留左(窄屏 @media 纵向全宽不变)
P1A2学院/专业/培养层次列表缺工具栏CollegeList / MajorList / TrainingLevelList各表前加 <div class="page-toolbar"><el-input v-model="keyword" class="filter-2xl" …/></div>:data="list":data="filteredList",排序按钮用 realIndex(row);维持"标题→筛选→表格"三段式节奏
P2A3分页容器三套实现TextbookList / TeacherList / TeachingStatistics / UserManagement / TeachingArrange自定 .list-pagination 与两处内联 div → 统一全局 .pagination-container;删除对应 scoped 样式
P2A4TextbookList 列过密views/textbook/TextbookList.vue版次/定价 列加 show-overflow-tooltip;根容器 <div>.textbook-list
P3L1ClassList 加载失败双重弹错views/class/ClassList.vuecatch 内显式 ElMessage.error,改 DEV-only console.error(请求拦截器已统一兜底,避免重复 toast)
P3L2告警列表用索引 :key="i"ArrangeResultDialog / BatchResultDialog:key="i":key="w"(用稳定 id 防止未来重排状态错乱)
P3B6多列 :gutter 不统一(16/20)TeachingStatistics:gutter="20"16(与 Dashboard/统计卡对齐)
P3B7根容器裸 divClassList / TextbookList<div>.class-list / .textbook-list
P3B8PlanDetail 概览条硬编码未用 tokenviews/plan/PlanDetail.vue.plan-overview 改用 var(--space-3) var(--space-4)margin-bottom:var(--space-3)border-radius:var(--radius-md)

二、新增组件:BaseConfirmBody.vue

  • 路径:client/src/components/BaseConfirmBody.vue
  • 设计取舍:只替换"图标 + 文字 + 可选警告"内联骨架,不碰各页面的 el-dialog 外壳、底部 el-button、以及危险子句(如 PlanDetail 的"此操作不可撤销"、TeachingArrange 的 v-if/v-else 段落)。
  • 收益:后续统一调整警告样式只需改 1 处;避免 11 处回归。
  • props:message(必填)、warning(可选)、icon(默认 WarningFilled)、iconColor(默认 var(--brand-warning))。
  • scoped 样式与原内联结构逐像素对齐(.confirm-row flex gap:12px;.confirm-icon flex-shrink:0 margin-top:2px)。

三、分页 + 排序联动的处理(关键正确性)

切片到 pagedList 后,两处必须用 realIndex(row)(元素在 filteredList 中的真实下标),不能用 el-table 的视觉 $index

  1. 序号列:<el-table-column type="index" :index="(i)=>(currentPage-1)*pageSize+i+1"> —— 显示全局连续序号。
  2. 上/下移按钮:@click="handleMoveUp(row, realIndex(row))",禁用态 :disabled="realIndex(row)===0" / === filteredList.length-1

useSortable(filteredList, …) / useCrudList 仍基于 filteredList 做整列交换,切片只影响渲染,排序语义不变。已回源确认 composables/useSortable.jsuseCrudList.jsindexFinder/listid 换位是安全的。


四、有意偏差:M2(教师/教材改服务端分页)— 跳过

  • 原计划:TeacherList / TextbookList 由"全量下载再客户端切片"改为服务端分页(对齐 ClassList/AuditLog)。
  • 实际决策本次不实施,理由:
    1. 渲染已受 pagedList 客户端切片保护(不卡顿),H1/M1/A3 已解决"用户可感知"的可感知问题;
    2. 改为服务端分页需改动现有客户端筛选/排序(均基于全量 filteredList)与 API 契约(api/teacher.js/api/textbook.js 分页参数已声明但前端未接),属 P2 中风险改造;
    3. 当前数据量级下,首屏"多下载全量 payload"的真实体感影响有限,不构成本轮"用户可感知体验"修复的阻塞项。
  • 后续建议:单独排期做服务端分页(可作为下一轮性能专项),届时一并把 api/teacher.jsapi/textbook.js 分页响应接入、前端筛选/排序改为服务端参数透传。

五、影响分析(改了会不会影响其他调用)

改动影响范围回归确认
CourseList/PlanList 加分页仅本页排序(filteredList)、导出(useExport 基于 full list)、序号列全局连续 —— 已处理
label-width→100px所有表单 dialog长标签("二级学院/培养层次/用户管理")不溢出、与输入框对齐
工具条左右分区全局 .page-toolbar窄屏 @media 纵向全宽未动,不破版
BaseConfirmBody 复用11 处删除确认弹窗逐一确认危险子句/彩色图标不丢(PlanDetail 子句、TeachingArrange v-if/v-else、ClassList 三类确认均保留)
分页容器收口Textbook/Teacher/TeachingStatistics/UserManagement/TeachingArrange删除 .list-pagination 后改走全局 .pagination-container,样式不回退
A2 小列表补工具栏College/Major/TrainingLevel新增 keyword/filteredListuseCrudList 仍提供 list/handleMoveUp/handleMoveDown,排序逻辑不变
L1 去双重 toast仅 ClassList拦截器统一兜底,删除处重复弹错消失
L2/B6/B7/B8局部样式/key纯样式与 key 稳定性,无逻辑影响

六、验证结论

  • client/ npm run build通过,exit 0,构建产物正常(CourseList/PlanList/TextbookList/TeacherList 等分块均生成)。
  • ✅ 全部 13 类问题已落地(M2 有意跳过并文档化)。
  • ✅ 新增 1 个组件(BaseConfirmBody.vue),11 处调用收敛。
  • ⚠️ 未做接口级回归(纯前端静态改动 + 构建验证);建议后续在 dev 环境手动过一遍:CourseList/PlanList 翻页 + 排序、各确认弹窗样式、窄屏工具条布局。

七、下一步建议

  1. 单独排期落实 M2 服务端分页(性能专项)。
  2. 将本报告「统一布局与间距规范」写入开发规范 + global.css(体检报告第七章已有草案)。
  3. dev 环境手动回归上表「回归确认」列各项。