Files
coursehomework-front/classwork-frontend-m5-plan.md
T

40 KiB
Raw Blame History

课堂作业前端 M5 切换计划 —— 对齐后端 V2 接口完成页面

项 内容
项目 前端 E:\YHXT\view\CourseHomework(Vue3 + Vite + TS + view-ui-plus + alova)
依据 后端 E:\YHXT\java\ClassHomeWork 已实现接口(M1~M4 完成,V3.2 运行验证通过)+ classwork-homework-plan-v3.md §11 前端适配计划 / §15.5 遗留待办第 1 条
目标 前端 9 个核心页面全部切换到 V2 接口面,打通「发布→统计→批阅→学生提交→结果」全链路联调
后端地址 本地 http://localhost:8102(vite proxy 已配置,无需改动)
文档版本 V1.0(2026-09-15)

1. 背景与现状差距

1.1 后端权威接口面(已实现,本计划的对齐目标)

后端按 PRD §18 完成了 V2 接口(28 个新端点),同时保留 V1 冻结接口(17 个)。统一响应 {code,msg,data},分页 BasePageResult,时间格式全局 yyyy-MM-dd HH:mm:ss(无 "T" 分隔符)。

教师端 /api/teacher/homeworks(19 端点,PRD 页 1~6):

方法 路径 用途
POST `` 创建作业(一律落草稿 DRAFT_UNPUBLISHED)
PUT /{id} 编辑作业(仅草稿两态)
DELETE /{id} 删除作业(仅草稿两态)
POST /{id}/publish 立即发布
POST /{id}/schedule 定时发布 / 取消定时({scheduledAt} 或 {cancel:true})
GET /drafts 草稿箱分页(subject/hwStatus/keyword 筛选)
GET /published 已发布列表分页(含应交/已读/已交/未读未交聚合)
POST /{id}/remind 提醒未读/未交({type: NOT_READ|NOT_SUBMITTED, studentIds?},返回 {reminded})
POST /{id}/extend 延长截止({deadlineAt} 须晚于当前值)
POST /{id}/copy 复制为新草稿,返回新 id
POST /{id}/archive 归档(只读,屏蔽提醒)
GET /{id}/export 导出学生矩阵 Excel(文件流)
GET /{id} 作业详情
GET /{id}/stats 汇总统计卡片(总进度 + 分班进度)
GET /{id}/students 学生矩阵分页(classId/submitStatus/reviewStatus/pendingGrade 筛选)
POST /{id}/submissions/{studentId}/review 保存批阅({score?, comment?, markedImages?},score/comment 至少一项)
POST /{id}/submissions/{studentId}/return 打回({comment} 必填)
GET /{id}/submissions/{studentId}/versions 历史提交版本列表
GET /classes 年级→班级树(叶子 id=classId,含 studentCount)
POST /classes/sync 手动触发名册同步

学生端 /api/student/homeworks(6 端点,PRD 学生页 1~3):

方法 路径 用途
GET `` 我的作业列表(tab=all/todo/done/closed + 分页/keyword)
GET /{id} 作业详情(含 description/attachments/myAttachments/myText)
POST /{id}/read 阅读上报(前端停留 ≥3 秒后调用,幂等)
POST /{id}/submissions 提交作业({text?, attachments[]}),返回 {submissionId}
PUT /{id}/submissions/{submissionId} 撤回/打回重交({action: withdraw|resubmit, text?, attachments?})
GET /{id}/result 批阅结果(当前版本 + 历史版本含各版评语)

通知 /api/notifications(3 端点):GET 分页(含未读数)、POST /{id}/read、POST /read-all。

辅助域(已存在,继续沿用):文件 /api/file/Upload|UploadImage|Down|Preview|Delete|List|Bind;字典 /api/dict/List|ManageList|Add|Update|Delete|Sort|Sync;联系组 /api/contacts/*;/api/base/GetUserInfo|GetUserMod|GetSchoolAll|GetGroupUser|FileUpload|Logout。

V1 冻结接口 /api/homework/*(17 个):继续服务未切换页面(如「已收到」收件箱、「全部作业」管理端、「作业统计」),M5 完成后评估退役。

1.2 前端现状盘点与技术债

页面与数据源核对结果(homeworkApi.* 实际调用 vs 后端真伪):

页面 路由 现状数据源 判定
NewHomework.vue /list/new 旧 Create/Edit/GetDetail 真实接口,需切 V2
HomeworkList.vue /list、/homeworklist 旧 SendList + remind(伪) 部分伪接口
HomeworkDetails.vue /list/detail 旧 Detail/GetNextPrev/ReadDetail 真实接口,需切 V2
Submissions.vue /submissions Submissions/SubmissionDetail/grade(伪) 全部伪接口
Grade.vue /grade sendList + Submissions/SubmissionDetail/grade(伪) 部分伪接口
StudentHomeworks.vue /stu/today、/stu/redo、/par/kids MyHomeworks/parentNudge(伪) 全部伪接口
HomeworkAccept.vue /accept 旧 List/Detail(v1 收件箱) 真实接口,需改造为学生详情页
HomeworkStats.vue /stats 旧 Statis 真实接口,保留
HomeworkSetting.vue /setting dict/contacts 真实接口,保留
ApprovalList.vue /approval approvalList/approve/reject(伪) 后端无审批域
ApprovalSetting.vue /approval-setting approvers 系(伪) 后端无审批域

「伪接口」清单(后端不存在,真实环境必 404,仅 mock 模式可跑):/api/homework/ 下的 Submissions、SubmissionDetail、Grade、Remind、MyHomeworks、MySubmission、Submit、ParentNudge、ApprovalList、ApprovalCount、Approve、Reject;/api/dict/ 下的 ApproverPool、Approvers、AddApprover、UpdateApprover、DelApprover;/api/base/SetRole。

类型契约差距:types/homework.ts 为 V1 契约(hwStatus 四态 draft/collecting/closed/done、submitStatus 小写五值);V2 要求 hwStatus 五态 DRAFT_UNPUBLISHED/DRAFT_SCHEDULED/PUBLISHED/CLOSED/ARCHIVED、submitStatus 五态 NOT_SUBMITTED/SUBMITTED/LATE_SUBMITTED/RETURNED/REVIEWED、reviewStatus 三态 PENDING/REVIEWED/RETURNED。

工作区未提交改动:Grade/StudentHomeworks/Submissions 三页的图片预览/上传优化 + mock/env 配置微调(与本次切换方向一致,保留并在其上继续)。

2. 总体方案

三层推进:契约层(类型+API 客户端)→ 教师端页面 → 学生端页面,最后清理菜单路由与 mock。旧 V1 页面(已收到/全部作业/统计/设置)不动,继续走冻结接口。

2.1 契约层(P0)

新增 src/types/homeworkV2.ts(V2 契约独立成文件,不污染 V1 类型;与后端 model/v2/*.java 一一对齐):

/** 作业五态(PRD §17) */
export type HwStatusV2 = "DRAFT_UNPUBLISHED" | "DRAFT_SCHEDULED" | "PUBLISHED" | "CLOSED" | "ARCHIVED";
/** 提交五态 */
export type SubmitStatusV2 = "NOT_SUBMITTED" | "SUBMITTED" | "LATE_SUBMITTED" | "RETURNED" | "REVIEWED";
/** 批阅三态 */
export type ReviewStatus = "PENDING" | "REVIEWED" | "RETURNED";

export interface AttachmentItem { fileId?: number; fileUrl: string; fileType?: "image" | "file"; fileName?: string; sort?: number; }
export interface ClassItem { classId: string; className: string; }
export interface ProgressVo { should: number; read: number; submitted: number; graded: number; pendingGrade: number; unsubmitted: number; unread: number; unreadUndone: number; readRate: number; submitRate: number; gradeRate: number; }
export interface HomeworkV2Vo { id; title; subject; description; hwStatus: HwStatusV2; hwStatusDesc; scheduledAt; publishedAt; deadlineAt; archivedAt; submitType: string[]; allowLate; remind1d; remind1h; classes: ClassItem[]; attachments: AttachmentItem[]; publisherId; publisherName; createTime; updateTime; progress?: ProgressVo | null; }
export interface HomeworkV2Request { title: string; subject?; description?; classIds: string[]; attachments?: AttachmentItem[]; deadlineAt?; submitType: string[]; allowLate?; remind1d?; remind1h?; }
export interface TeacherHomeworkQuery { pageIndex?; pageSize?; keyword?; subject?; hwStatus?; }
export interface StudentMatrixVo / StudentMatrixQuery / HomeworkStatsVo / ClassTreeNodeV2(id: string)/ SubmissionVersionVo / StudentHomeworkV2Vo(含 MySubmission)/ StudentHomeworkDetailV2Vo / StudentSubmitRequest / StudentResultVo / NotificationVo …

新增 3 个 API 客户端(风格沿 api/module/homework.ts 的 get/postJSON 封装):

  • src/api/module/teacherHomework.ts → teacherApi:19 端点全覆盖 + exportUrl(id)(Excel 直链,浏览器跳转下载)
  • src/api/module/studentHomework.ts → studentApi:6 端点
  • src/api/module/notification.ts → notificationApi:3 端点

修正 api/module/homework.ts:baseApi.setRole 标注仅 mock 可用(后端无此端点,真实环境学生身份由 CAS 登录账号 ↔ class_student 映射,联调用种子账号 stu01~stu06);baseApi.getClassTree 的调用方改走 teacherApi.classTree()。

2.2 页面改造映射(P1~P3)

PRD 页面 前端页面 目标接口 关键改造点
页 1 发布作业 NewHomework.vue POST/PUT + /classes + publish/schedule + file/Upload ① 表单重构:classIds(年级→班级树多选,数据源换 /teacher/homeworks/classes)② 新增:截止时间(精确到分钟,空=仅查阅型)、submitType(图片/文件/两者/文本)、allowLate、remind1d/remind1h、定时发布时间 ③ 保存语义拆分:「存草稿」(POST/PUT)与「立即发布」(POST 后调 publish)/「定时发布」(POST 后调 schedule)④ 附件走 file/Upload,组装 AttachmentItem[] ⑤ 编辑回显改 GET /teacher/homeworks/{id}(旧 GetDetail 保留给转发场景)
页 2 草稿箱 HomeworkList.vue(/list 增加「草稿箱」段) GET /drafts 草稿两态(未发布/定时待发)标签展示;操作:编辑、发布、取消定时(schedule cancel)、删除
页 3 已发布列表 HomeworkList.vue(/list 主段) GET /published + remind/extend/copy/archive/export ① 统计列:应交/已读/已交/未读未交高亮 + 阅读率/提交率(progress)② 状态筛选 PUBLISHED/CLOSED/ARCHIVED ③ 操作组:提醒(NOT_READ/NOT_SUBMITTED,返回 reminded 提示)、延长截止(日期选择,须晚于当前)、复制为新草稿、归档、导出 Excel(直链)④ 行点击进详情
页 4 详情/统计 HomeworkDetails.vue GET /{id} + GET /{id}/stats 作业信息卡(五态标签、学科、截止、提交方式、班级、附件下载)+ 统计卡片(总进度 + 分班进度:阅读率/提交率/批阅率、待批阅数)
页 5 学生矩阵 Submissions.vue GET /{id}/students ① 列:学生/班级/阅读状态(含首末阅读时间)/提交状态(含逾期角标)/提交时间/评分/批阅状态/附件缩略图 ② 筛选:classId、submitStatus、reviewStatus、只看待批阅(pendingGrade)③ 未交学生占位行(submissionId=0)④ 行操作:批阅、打回、提醒单个学生(remind 定向)
页 6 批阅/打回/版本 Grade.vue(批改中心) /published(pendingGrade 作业列表) + versions + review/return ① 待批作业列表改 GET /published(按 progress.pendingGrade 排序/展示)② 选中学生(矩阵 pendingGrade=true)→ 右侧工作台 ③ 版本切换(GET versions,默认最新)④ 批阅保存(score+comment 至少一项)⑤ 打回(comment 必填,二次确认)⑥ 提交内容展示:text + 附件/图片(复用已有缩略图放大预览)
学生页 1 列表 StudentHomeworks.vue GET /student/homeworks?tab= ① tab 改 all/todo/done/closed(对齐 meta.initTab=redo→todo 语义调整)② 倒计时(deadlineAt)③ my 提交状态徽标(五态 + 逾期角标)④ 分页 + keyword
学生页 2 详情/结果 HomeworkAccept.vue(改造为学生详情页,挂 /stu/detail?serid=) GET /{id} + read + result ① 作业说明富文本 + 附件预览/下载 ② 进入页 3 秒定时器调 read(onUnmounted 清理) ③ 我的提交区(当前版本 text/附件/评分/评语)④ 历史版本 + 各版评语(GET result)⑤ 提交/撤回/重交入口
学生页 3 提交 HomeworkAccept.vue 内提交区(+列表页快捷弹窗保留) POST submissions + PUT withdraw/resubmit ① 按 submitType 动态渲染:文本框 / 图片上传(file/UploadImage 产物→AttachmentItem)/文件上传 ② 截止校验:截止后 allowLate=0 禁交 ③ 撤回(截止前)→ 重新填写重交 ④ 打回(RETURNED)→ 显示订正原因 + 重交

不动页面:HomeworkStats(旧 Statis)、HomeworkSetting(dict/contacts)、/accept 的 v1 收件箱语义由 HomeworkAccept 改造承接(路由 /accept 重定向到 /stu/today)。

2.3 路由与菜单调整(P3)

项 处置 理由
新增 /stu/detail(HomeworkAccept 改造后) meta { role: "student", title: "作业详情", modId: 33 } PRD 学生页 2/3 载体
/accept 重定向 /stu/today v1 收件箱语义被学生列表替代
/approval、/approval-setting + 菜单 modId 5/6 路由与菜单摘除(页面文件保留不引) 后端无审批域(plan-v3 §4.6 顺延),伪接口联调必挂
/par/kids 家长端 保留路由但隐藏入口 后端无家长接口(plan-v3 §4.6 顺延),parentNudge 为伪接口;页面内调用加守卫
/homeworklist 全部作业、/stats 统计、/setting 设置 保留走 V1 冻结接口 冻结接口可用,M5 后评估退役
通知中心(可选) 视排期加 /notify 轻量页(notificationApi 3 端点,未读角标) PRD §18 未列页面,plan-v3 §7.3 补充接口;列为可选项

2.4 mock 同步(P4)

src/assets/mock/homeworkapi.ts 增补 V2 端点 mock(teacher 19 + student 6 + notifications 3),数据模型对齐 types/homeworkV2.ts,保证 npm run dev:mock 全页面可演示;同时清理伪接口 mock(Submissions/Grade/MyHomeworks/审批系),避免继续误导联调。

3. 实施顺序与验收

阶段 内容 验收标准
P0 契约层 types/homeworkV2.ts + teacherHomework/studentHomework/notification 三客户端 + homework.ts 修正 vue-tsc 通过;接口路径/参数与本文 §1.1 表逐项一致
P1 教师端发布链路 NewHomework + HomeworkList(草稿箱+已发布) 真实后端(8102):建作业→存草稿→草稿箱可见→立即发布/定时发布→已发布列表出统计聚合
P2 教师端批阅链路 HomeworkDetails(stats)+ Submissions(矩阵)+ Grade(批阅/打回/版本) 矩阵筛选/缩略图/占位行正确;批阅→学生端可见结果;打回→重交→版本递增
P3 学生端闭环 StudentHomeworks + HomeworkAccept + 路由菜单调整 用种子账号(stu01~stu06):列表 tab→详情 3 秒已读→提交→倒计时/逾期分流→撤回留版本→打回重交→查结果
P4 清理与全量走查 mock 更新、审批/家长端摘除、全页面回归 dev(dev) + dev:mock 双模式走查;PRD §18 九页面映射逐格核对

每阶段一组语义化 commit;P1 起需要后端 8102 运行 + sql/v3_seed.sql 名册种子(库名 class_homework,utf8mb4)。

4. 风险与开放问题

# 事项 影响 处置建议
1 学生身份联调:后端无 SetRole,学生接口按 CAS 登录账号 ↔ class_student 映射 高(P3 阻塞) 与后端确认本地登录方案(种子账号 stu01~stu06 走 CAS 或本地放行);mock 模式保留 SetRole 演示用
2 审批域下线需产品确认 中 本计划先摘菜单/路由不删代码;产品若要保留需后端补接口
3 提交附件契约:v2 只收 file/Upload 产物(fileId/fileUrl),拒绝 dataURL 中 HomeworkUpload 组件改造为真实上传后再组装 AttachmentItem;改造前 dataURL 直交必被后端拒
4 学生端入口与菜单结构(/stu/* 不在现有静态菜单) 低 沿用现有约定,学生视角由平台角色决定入口;具体待 GetUserMod 对接方案
5 Excel 导出/export 直链需带登录态 cookie 低 同源代理下 location.href 直跳即可(与 AllFileDown 同模式)
6 V1 页面(已收到/全部作业/统计)与新数据并存的两套状态口径 低 双轨期 hwStatus 派生映射(后端已做),前端不做转换;M5 后评估 V1 退役
7 tab=redo(待订正)语义:V2 无独立 redo 桶,RETURNED 归入 todo 低 /stu/redo 路由 initTab 改 todo 并在页内强化 RETURNED 过滤,或改路由为 /stu/todo

5. 交付物清单

  1. src/types/homeworkV2.ts —— V2 全量类型契约
  2. src/api/module/teacherHomework.ts / studentHomework.ts / notification.ts —— 28 端点客户端
  3. 改造后 7 个页面:NewHomework / HomeworkList / HomeworkDetails / Submissions / Grade / StudentHomeworks / HomeworkAccept
  4. src/router/routes.ts + src/assets/config/menu.ts 调整
  5. src/assets/mock/homeworkapi.ts V2 增补与伪接口清理

6. 审核(审批)功能下线(2026-09-15)

6.1 裁决变化

§2.3 与 §4 风险 2 原口径为「摘菜单/路由、页面文件保留不引,等产品确认」。本次确认彻底删除审批(审核)功能:产品定位为任课教师直接布置,不存在送审环节;后端 ClassHomeWork 从未实现审批域(无 approval_* 列、无 ApprovalList/Approve/Reject、无审批人池接口),而前端两页调用的 homeworkApi.approvalList/approve/reject 与整个 approvalSettingApi 在 API 层根本不存在,属编译期即悬空的死代码。

注意边界:本节只删「审批/审核」(approval),不动「批改/批阅」(grade/review)——Grade.vue、Submissions.vue、ReviewModal.vue 是作业核心链路。

6.2 牵连面盘点(grep approval|审核|审批|approver|canApprove|vote|flow 全仓)

# 文件 现状 处置
1 src/views/homework/ApprovalList.vue 审批列表页,未挂路由,调用不存在的 homeworkApi.approvalList/approve/reject 删除(git 跟踪,可 git checkout 恢复)
2 src/views/homework/ApprovalSetting.vue 审批人池设置页,未挂路由,调用不存在的 approvalSettingApi 删除(同上)
3 src/components/ApprovalFlowEditor.vue 工作区已处于删除态(git status 显示 D) 保持删除,不恢复
4 src/types/homework.ts HomeworkVo 81-95、ApprovalStatus 103、HomeworkDetailVo 146-174(含 approvalFlow/canApprove)、HomeworkRequest 393-398(approvers/vote/flow)、ApprovalQuery 489、ApprovalAction 500、ApproverVo 509、分节标题 476 全部删除;分节标题改「班级」
5 src/api/module/homework.ts 23-24 import { ApprovalQuery, ApproverVo }(导入后零使用) 删两行导入
6 src/assets/config/menu.ts 12-13 静态菜单 id/modId 5 审批列表 /approval、6 审核设置 /approval-setting(指向不存在的路由) 删两行
7 src/utils/menuRoute.ts 无审批别名;但 resolveMenuPage 对无法识别的模块只 console.warn 并返回 path:"",而 layout.vue:192 直接渲染 modList(不过滤空 path)→ 平台 GetUserMod 若仍下发 modId 5/6,侧栏会出现点了没反应的死菜单 新增 DROPPED_MOD_IDS={5,6} + dropDroppedModules(list)(顶层 + children,按 modId ?? id,不改入参),App.vue 赋值 layoutData.modList 前调用
8 src/assets/mock/homeworkapi.ts 审批引擎与数据:头注释 7/15-16、审批人池 41-52、buildFlowFromInput 62-72、pendingApprovers 75-79、canAct 81-84、flowProgressText 86-92、种子 approval* 字段 155-313(7 处)、seedFlows 318-343、复位循环 345-353、isPublished 639-641、APPROVAL_DESC 648、列表映射 682-689、详情映射 728-753、Create 1026-1032、Edit 1059-1092 全删;isPublished 简化为「非草稿即可见」;种子行不再带 approval* 键
9 其余 src/views、src/components、src/router、App.vue grep 零命中 无需改动

后端 E:\YHXT\java\ClassHomeWork:审批域从未落地,无可删代码;仅需把 classwork-homework-plan-v4.md 的 §0 排除说明与 Q-08 由「待确认」改为「已裁决下线」。

6.3 执行步骤与验收

  1. 备份:types/homework.ts、api/module/homework.ts、assets/mock/homeworkapi.ts、assets/config/menu.ts、utils/menuRoute.ts、App.vue 快照到 .backup/20260915-drop-approval/(这些文件工作区相对 HEAD 已有 M5 未提交改动,git restore 会连带丢改动,故单独快照)。
  2. 删 2 个页面文件(git rm 语义,历史可查)。
  3. 按 6.2 顺序改 types → api → menu → menuRoute+App → mock(自底向上,先断引用再清数据)。
  4. 验收(实测见 §6.4):① grep -rniE "approval|approver|canApprove" src 命中数为 0;② npm run build 成功;③ dev:mock 下逐端点冒烟正常、审批端点 404、侧栏无审批入口。

    原定的 npx vue-tsc --noEmit 门禁在本工程跑不起来:vue-tsc@1.8.27 与 typescript@5.9.3 不兼容会直接崩溃,且工程 tsc 基线本就有 65 条存量报错。故类型侧只作「不得新增引用已删符号的报错」的对照检查,见 §6.4 第 4 条。

  5. 结果回填 §6.4。

6.4 执行结果回填(2026-09-15 完成)

改动清单

文件 动作
src/views/homework/ApprovalList.vue、ApprovalSetting.vue git rm(索引内 D,历史可查)
src/components/ApprovalFlowEditor.vue 保持工作区已删除状态,未恢复
src/types/homework.ts 删 HomeworkVo 8 个 approval 字段、ApprovalStatus、HomeworkDetailVo 9 个 approval 字段(含 approvalFlow/canApprove)、HomeworkRequest 的 approvers/vote/flow、ApprovalQuery/ApprovalAction/ApproverVo;分节标题「班级 / 审批」→「班级」
src/api/module/homework.ts 删 ApprovalQuery、ApproverVo 两个死导入
src/assets/config/menu.ts 删 modId 5「审批列表」/6「审核设置」两项,头注释记录「平台若仍下发则由 DROPPED_MOD_IDS 剔除」
src/utils/menuRoute.ts 新增 DROPPED_MOD_IDS={5,6}、DROPPED_NAMES(审批/审核 7 个叫法)、dropDroppedModules()(顶层+children,按 modId ?? id 或名称命中,返回新数组不改入参)
src/App.vue GetUserMod 结果入壳层前经 dropDroppedModules 过滤(侧栏渲染、默认跳转、console.table 共用同一份)
src/assets/mock/homeworkapi.ts 删审批引擎(审批人池 approvers/approverSeq/approverName/approverPoolAccounts、FlowLevel、buildFlowFromInput、pendingApprovers、canAct、flowProgressText、APPROVAL_DESC)、seedFlows() 与其后的复位 forEach、种子 8 处 approval 属性、toVo/详情两处 8 行映射与 approvalFlow 块、Create 新对象的 7 行 approval 初始化、Edit 的 flow 重建整段(35 行);isPublished() 由「审批通过或免审」改为 hwStatus !== "draft";头注释与存储注释同步改写

验收实测

  1. 残留归零:grep -rniE "approval|approver|canapprove|flowprogress|buildflow" src → 0 命中(中文「审批/审核」仅存于注释与 DROPPED_NAMES 名单,属有意保留)。
  2. 构建通过:npm run build(vite build --mode base)EXIT=0,18.82s。
  3. mock 冒烟(npm run dev:mock @8077,node fetch 逐端点,全部 code==0):
    • List 5/7 条、SendList?scope=user 3/3 条、Detail?serid=1&type=0 出参键仍为 serid/Contents/DeptID/...ChaoSend/tlist 且不再含任何 approval 键、ReadDetail 按班级分组(account=1301/teaname=初一(1)班(45人))、MyHomeworks buckets {todo:3,submitted:1,graded:2,redo:0,all:7}、Statis 11 字段齐全、GetClassTree 年级→班级带 studentCount。
    • 审批端点确认消失:/api/homework/ApprovalList、/api/dict/ApproverPool 均 HTTP 404。
    • 临时服务已按 PID 校验(命令行确为本工程 vite.js --mode mock)后 taskkill,8077 已释放。
  4. 类型检查工具链本身不可用(既有问题,非本次引入):vue-tsc@1.8.27 在 typescript@5.9.3 下直接崩溃(Search string not found: "/supportedTSExtensions = .*(?=;)/",vue-tsc 1.x 的 monkey-patch 与 TS 5.5+ 不兼容)。退化用 npx tsc --noEmit 得 65 个报错,全部为存量:alova 泛型 TS2344 Type 'T' does not satisfy the constraint 'AlovaGenerics'(连未改动的 notification.ts/teacherHomework.ts/studentHomework.ts 同样报)、mock 种子数组属性推断 TS2339、menu.ts 的 IModule 未从 @/store 导出、teacherNames 未使用等;其中无一条引用被删除的审批符号(已 grep 验证)。→ 建议后续单列一项:升级 vue-tsc 到 2.x 或锁 typescript<=5.4,否则类型门禁形同虚设。

行为变化(预期内):原先 pending/rejected 的演示种子不再被门控,收件箱从 6 条变 7 条、Statis.publishedCount 7/8;这符合「无送审环节,发布即可见」的产品口径。

回退方式:git checkout HEAD -- src/views/homework/ApprovalList.vue src/views/homework/ApprovalSetting.vue 可复原页面;types/api/menu/menuRoute/App/mock 六个文件的改动前快照在 .backup/20260915-drop-approval/(因工作区相对 HEAD 另有未提交的 M5 改动,直接 git restore 会连带丢 M5,故用快照)。


7. 应用设置功能下线(2026-09-15)

7.1 裁决

「应用设置」(路由 /setting,modId 21)承载两块能力:发文部门字典(dict/ManageList·Add·Update·Delete·Sort)与自定义联系组(contacts/GetGroup·AddGroup·EditGroup·DelGroup·GetContactsTea·SetContactsTea·GetGroupTree),任课教师布置作业不依赖它们。裁决:

  • 只删前端:后端 DictController/ContactsController 及其 sys_dict/contacts_group/contacts_group_user 表保留不动(HomeworkService.resolveDeptName 仍要查 sys_dict;端点无人调用不影响运行)。
  • 仅该页使用的组件与死 API 一并清掉(与 §6 同一口径)。

7.2 牵连面盘点

文件 现状 处置
src/views/homework/HomeworkSetting.vue 应用设置页(部门拖拽排序 + 联系组及组员维护) 删除(git 跟踪)
src/components/TypeSetBox.vue 仅被 HomeworkSetting 引用(全仓 grep 零其他消费者) 删除
src/components/UserCheckInput.vue 零消费者(其 loader 用 baseApi.getSchoolAll + settingApi.getGroupTree) 删除
src/router/routes.ts /setting 路由(86-91)+ 旧路径重定向 /homework/setting(121)+ 头注释 21=应用设置 删两处路由与注释项
src/assets/config/menu.ts { id: 21, modId: 21, name: "应用设置", page: "/setting" } 删除
src/api/module/homework.ts class SettingApi(12 个方法)+ export const settingApi;BaseApi.getSchoolAll;HomeworkApi.getSysDic(dict/List)、getSchModuleIsSms(dict/Sync) 自 §6 后零调用 全部删除
src/types/homework.ts DeptManageItem、DictOption、ContactGroupPage、ContactUserPage、ContactGroupItem、ContactUser 删除
src/assets/mock/homeworkapi.ts /api/base/GetSchoolAll(682)、/api/dict/*(692-741)、/api/contacts/*(1173-1250) 三组桩;种子 groups/groupSeq(412-418)、idNames(420)、teacherNames(425,本就是死码)、schoolTree(431)、deptSeq(31) 全部删除;头注释端点清单同步改写

7.3 明确保留项(勿顺手删)

保留 理由
mock 的 deptDict(21-30) Create(830)/Edit(867) 仍用 deptDict.find(d => d.CodeID === b.deptId) 解析部门名,是作业域数据来源,不是设置页专属
src/components/UserCheckModal.vue、ClassCheckInput.vue 发作业选班级仍在用
src/components/MyConfirm HomeworkList / TeacherHomeworks 仍在用
类型 SchoolTreeNode BaseApi.getUserInfo 的返回类型仍引用它
vuedraggable 依赖 删除后成未用依赖,但改 package.json/lock 属额外风险,本次不动(后续清依赖时一并处理)
后端 dict/*、contacts/* 端点与三张表 按 7.1 裁决保留

7.4 对后端 V4 方案的连带影响(需同步改 classwork-homework-plan-v4.md)

  1. E-01 修法调整:原计划「deptId 为空时回填字典默认发文部门」失去维护入口,改为从当前教师主组/BoaUser.getCurrentRole() 推导 deptId/deptName,sys_dict 仅作为已有数据的名称解析(resolveDeptName 保持)。
  2. E-05 面收窄但过滤器仍必需:postForm 的 14 处调用点里,dict 4 处 + contacts 6 处随本功能下线归零,剩余 Remind(N-04 新门面)、ReceiveUsers、UserPull、SetTopmost、Expedite、InitializeRed(无参) —— SingleValueParameterFilter 照旧要做,只是回归面变小。

7.5 执行步骤与验收

  1. 快照受影响文件到 .backup/20260915-drop-app-setting/。
  2. git rm 三个文件 → 删路由/菜单 → 删 SettingApi 与死方法 → 删 types → 清 mock(端点 + 专属种子)。
  3. 验收:① grep -rniE "settingApi|DeptManageItem|ContactGroup|ContactUser|DictOption|getSchoolAll|getGroupTree|TypeSetBox|UserCheckInput|homework_setting" src 命中 0;② npm run build EXIT=0;③ dev:mock 冒烟:List/SendList/Detail/ReadDetail/MyHomeworks/Statis/GetClassTree 仍全 code=0,/api/dict/*、/api/contacts/*、/api/base/GetSchoolAll 均 404,Create 仍能解析 deptName(回归 §7.3 第一条);④ 侧栏无「应用设置」。
  4. 结果回填 §7.6。

7.6 执行结果回填(2026-09-15 完成)

改动清单

文件 动作
src/views/homework/HomeworkSetting.vue、src/components/TypeSetBox.vue、src/components/UserCheckInput.vue git rm
src/router/routes.ts 删 /setting 路由 + /homework/setting 重定向(目标已不存在,留着会把用户导向未知路由);头注释 modId 对照去掉 21=应用设置
src/assets/config/menu.ts 删 { id: 21, modId: 21, 应用设置 },头注释改为「不做审批、不开放应用设置」
src/utils/menuRoute.ts DROPPED_MOD_IDS 扩为 {5, 6, 21},DROPPED_NAMES 增「应用设置 / 作业设置」——平台 GetUserMod 若仍下发 modId 21,侧栏不会出现死菜单
src/api/module/homework.ts 删 class SettingApi(12 方法)与 settingApi 导出、BaseApi.getSchoolAll、HomeworkApi.getSysDic/getSchModuleIsSms、DICT/CONTACTS 前缀常量、4 个类型导入;头注释第 3 条改写
src/types/homework.ts 删 DictOption、DeptManageItem、ContactGroupItem、ContactGroupPage、ContactUser、ContactUserPage;分节改名为「基础平台」(保留 SchoolTreeNode)
src/assets/mock/homeworkapi.ts 删 dict 6 桩 + contacts 7 桩 + GetSchoolAll 桩;删种子 groups/groupSeq、idNames、teacherNames(本就是死码)、schoolTree、deptSeq;头注释与 deptDict 注释同步改写。deptDict 按 §7.3 保留

验收实测

  1. 残留归零:手写代码中 settingApi|DeptManageItem|ContactGroup|ContactUser|DictOption|getSchoolAll|getGroupTree|TypeSetBox|UserCheckInput|homework_setting|deptSeq 0 命中。另有 12 处 grep 命中经逐条核对均非残留:src/api/apiDefinitions.ts 与 globals.d.ts 是 npm run api:gen 生成的 swagger 快照(镜像后端现状,后端端点仍在,属正确内容);其余为 SchoolTreeNode 被大小写不敏感的 schoolTree 模式误命中。
  2. 构建通过:npm run build EXIT=0,16.79s。
  3. mock 冒烟(dev:mock @8077):保留面 9 个端点全 code=0(List 5/7、SendList 3/3、Detail、ReadDetail 3 组、MyHomeworks buckets {todo:3,submitted:1,graded:2,redo:0,all:7}、Statis、GetClassTree、GetUserInfo、GetUserMod);§7.3 保留项回归:Create(deptId:"D002") → GetDetail 仍解析出 DeptName="数学教研组"、DeptID="D002",说明 deptDict 未误删;已删端点 6/6 全部 404(dict/List、dict/ManageList、dict/Sync、contacts/GetGroup、contacts/GetGroupTree、base/GetSchoolAll)。临时服务按 PID 命令行确认归属后 taskkill,8077 已释放。
  4. 类型侧:沿用 §6.4 第 4 条结论(vue-tsc@1.8.27 与 typescript@5.9.3 不兼容、工程 tsc 基线 65 条存量错),本次只核对「无引用已删符号的新报错」。

遗留(有意不动):vuedraggable 依赖失去唯一使用者,留待统一清依赖时处理;apiDefinitions.ts/globals.d.ts 待下次 npm run api:gen 自然刷新;后端 dict/*、contacts/* 与三张表按裁决保留。

回退方式:git checkout HEAD -- src/views/homework/HomeworkSetting.vue src/components/TypeSetBox.vue src/components/UserCheckInput.vue 复原三文件;routes/menu/menuRoute/api/types/mock 六个文件的改动前快照在 .backup/20260915-drop-app-setting/。


8. M5 主体执行结果回填(2026-09-16 完成)

8.1 提交序列(每阶段一组语义化 commit)

commit 阶段 内容
e6639f7 基线(前会话成果入库) P0 契约层(types/homeworkV2.ts + 28 端点三客户端)+ §6/§7 下线 + 新增 TeacherHomeworks/ReviewModal/AttachmentUpload 组件(未挂路由)
39824fb P1 教师端发布链路 /list 挂 TeacherHomeworks(已发布+草稿箱);NewHomework 切 V2(班级树/create→publish·schedule 三段式/AttachmentUpload/仅查阅互斥;转发保留 V1 GetDetail);HomeworkList 摘伪接口 remind;路由:/accept→/stu/today、新增 /stu/detail、/stu/redo initTab=todo
23d6716 P2 教师端批阅链路 ReviewWorkbench 从 ReviewModal 抽出(版本切换/批阅/打回共用);Submissions 切 V2 矩阵(stats 汇总卡+classId/submitStatus/pendingGrade 筛选+未交占位行定向提醒);Grade 切 V2 批改中心(pendingGrade 排序+队列+内嵌工作台批完前移);HomeworkDetails 双模式(/list/detail 走 V2 详情+统计+分班进度表,/homeworklist/detail 保留 V1——V2 详情有 requireOwned 校验看不了他人作业)
6258ebb P3 学生端闭环 StudentHomeworks 切 V2(四 tab 服务端分页+五态徽标+逾期角标+倒计时变色+todo 桶 RETURNED 置顶强化+快捷提交弹窗);HomeworkAccept 改造为学生详情页(3 秒阅读上报 onUnmounted 清理/我的提交/批阅结果/历史版本各版评语/submitType 动态表单/修改提交生成新版本/截止前撤回/打回重交);菜单与别名列齐 V2
44ace7c P4 清理+mock+走查 见 §8.3

8.2 关键实现口径(与计划的差异说明)

  1. 页 2/3 载体:原计划「HomeworkList.vue 增加 草稿箱 段」,实际采用前会话已建好的独立页 TeacherHomeworks.vue 挂 /list(已发布/草稿箱双 Tab),HomeworkList.vue 仅保留给 /homeworklist(全部作业 V1 冻结)。功能映射不变,页面文件归属有变。
  2. HomeworkDetails 双模式(计划外新增):后端 V2 detail() 有 requireOwned 归属校验,而 /homeworklist 管理页要看他人作业 → 同一组件按路由分支:/list/detail 走 V2(详情+stats),/homeworklist/detail 走 V1 冻结 Detail。
  3. 学生端 redo 桶(§4 风险 7 落地):采用「initTab 改 todo + 页内 RETURNED 红色强化置顶(当前页内重排)」;未做服务端 redo 过滤(V2 无此桶)。
  4. 修改提交语义:后端 doSubmit 对「已交未批」无拦截,POST 直接生成新版本——修改提交无需先撤回;撤回(withdraw)是独立动作(截止前,生成 NOT_SUBMITTED 空行后重新 POST)。
  5. 已截止且 allowLate=0 的 RETURNED:前端在列表与详情均禁重交入口(后端 doSubmit 必拒,前后端口径一致)。
  6. vite 代理:发现工作区实际指向远程测试环境,按计划改回 http://localhost:8102(远程地址保留注释可切回)。

8.3 P4 清理与 mock

  • V1 客户端收敛(api/module/homework.ts):仅保留仍被消费的 9 方法(sendList/modify/getHomeworkDetails/getNextPrevHomework/orgizeModify/deleteHomework/statistics/fileDownUrl/allFileDownUrl);删除伪接口方法(Submissions/SubmissionDetail/Grade/Remind/MyHomeworks/MySubmission/Submit)与孤儿方法(list/initializeRed/create/editHomework/receiveUsers/userPull/setTopmost/expedite + baseApi.getClassTree + postForm 辅助)。
  • types/homework.ts:收敛为 V1 冻结契约,删 11 个孤儿类型(HomeworkPageResult/InitializeRedVo/HomeworkRequest/SubmitStatus/SubmissionBrief/SubmissionGroup/SubmissionsResultVo/GradeResult/SubmissionDetailVo/GradeRequest/ClassTreeNode/v2 学生端 6 类型等)。
  • 删除被切换孤儿化的组件:HomeworkUpload(消费者全部改 AttachmentUpload)、ClassCheckInput、UserCheckModal(ClassCheckInput 唯一消费者)。模板遗留死组件(BschImport/MyTree/TablePage 系等 M5 前已死)未动,留待统一清理。
  • mock 整体重写(.backup/20260916-m5-v2-mock/ 有改动前快照):「V2 单一存储 + V1 适配层」——V2 端点 28 个直连存储(教师 19/学生 6/通知 3),V1 冻结 7 端点(SendList/Detail/GetDetail/GetNextPrev/ReadDetail/Delete/Statis)由同一存储派生(hwStatus 派生映射),与后端「同一张 homework 表」一致;提交内核对齐后端 doSubmit(版本翻转、逾期 LATE_SUBMITTED 分流、image/attach 必附附件、dataURL 拒绝、仅查阅拒绝、归档拒交),submit/action 返回 {submissionId}(走查中发现裸 id 契约偏差后修正,教师 create/copy 为裸 Integer 与后端一致);种子 12 份作业覆盖五态(含 DRAFT_SCHEDULED/ARCHIVED),演示学生定制七种提交态(含 hw12 双版本)。

8.4 验收实测

  1. dev:mock 冒烟(node fetch 逐端点,.backup/20260916-m5-v2-mock/smoke.mjs):58/58 PASS——教师 23(创建→编辑→定时→取消→发布→详情→统计→矩阵→筛选→提醒(含定向)→延长→复制→删除→批阅→版本→打回→导出占位)、学生 16(四 tab/详情/read/纯文本与带附件提交/withdraw/resubmit/版本递增/仅查阅拒绝/打回态)、通知 4(含 read-all 后 unreadCount=0)、V1 冻结 7、已删伪接口 7 端点全部 404。
  2. 构建:npm run build EXIT=0(约 40s)。npx tsc --noEmit 47 条全部为存量(基线 65 条 alova 泛型等,见 §6.4-4;vue-tsc 工具链不可用为既有问题),零条引用已删符号。
  3. 浏览器走查(dev:mock @8077,IAB):9 页面渲染与数据流全过——/list(14 列统计聚合+草稿箱+定时标签)、/list/new(V2 表单)、/list/detail(统计卡+分班表)、/submissions(矩阵+筛选+未交占位)、/grade(队列 31 份+内嵌工作台)、/homeworklist 与其 detail、/stats(V1 face 由 V2 存储派生)、/stu/today(五态徽标+倒计时+身份自动切换)、/stu/detail(提交表单/双版本历史/打回原因)。交互闭环:批阅弹窗填 95 分+评语→保存→toast→矩阵行变「已批阅 95」;/stu/detail 停留 >3 秒→教师矩阵 isRead 0→1(firstReadAt=当前时间)。
  4. 走查发现并修复 3 个缺陷(均在 44ace7c):
    • TeacherHomeworks 操作列 Dropdown 在 render 函数下插槽失效(view-ui-plus 需模板插槽),菜单项内联常显 → 改 column.slot + template #action;
    • ReviewModal 残留 Vue2 写法 :value/@input(view-ui-plus Modal 是 modelValue),弹窗打不开 → 修正后批阅闭环通过;
    • StudentHomeworks「重新提交」按钮缺 canSubmit 门控(已截止且不允许补交时后端必拒)→ 补门控。
  5. 真实后端(8102)E2E 未执行:本地后端未启动(MySQL/v3_seed 名册环境未就绪),风险 1 的种子账号联调(stu01~stu06)留待后端联调时进行;vite 代理已指向 8102,冒烟与走查均在 mock 模式完成。

8.5 遗留与后续

  • 真实后端全链路联调(P1~P3 验收的 8102 实测部分):启动 ClassHomeWork + v3_seed.sql 后按 §3 表逐项补测。
  • 通知中心页面(/notify 轻量页)为可选项未实施;notificationApi 3 端点已就绪并 mock 覆盖。
  • 模板遗留死组件与 vuedraggable 依赖统一清理(§7.6 遗留合并处理)。
  • 工作区新增用户文档 bug检测与修复.md(并行检测计划,44ace7c 随快照入库);.gitignore 增补 .backup/ 忽略。