Files
aca-syllabu-service/课程表改造计划.md
2026-10-14 16:15:16 +08:00

11 KiB
Raw Permalink Blame History

AcaSyllabu 课程表改造计划

创建日期:2026-10-11 执行状态(2026-10-11):全部完成。

  • 后端:包名已改 com.yunhai.acasyllabu,宿舍通知业务已删(保留日志/附件/基建),新增 Timetable/TimetableSlot 实体 + TimetableController(Get/Save/SavePhoto/RemovePhoto/Subjects)+ ClassService 学科接口;mvn clean compile BUILD SUCCESS;本地启动冒烟通过(/actuator/health 200,未登录访问 /api/* 正确 302 跳 SSO)。
  • 前端:新增 views/syllabus/TimetableEdit.vue(参考页整体移植)+ api/module/syllabus.ts + types/syllabus.ts,路由/菜单/标题全部切换为课程表,dorm 业务已删;npm run build 通过。
  • 待联调:账号 lijing/a123123 为 CAS 平台账号,需平台与班级服务在线后做登录态全流程验证(见任务 7)。 后端项目:E:\YHXT\java\AcaSyllabu(原包 com.yunhai.dormnotice,宿舍通知/家校活动遗留) 前端项目:E:\YHXT\view\AcaSyllabu(Vue3 + alova + view-ui-plus,原为宿舍通知页面) 参考项目:E:\YHXT\java\UserclassService(UserContext / SysOperationLogAspect / 学科 oapi 出处) 参考 UI:E:\YHXT\view\AcaSyllabu\timetable-site\index.html(qoder 站点本地副本,本次改造的界面蓝本) 目标:改造为课程表服务——包名 com.yunhai.acasyllabu,电子课程表(节次×星期编排)+ 照片课程表(图片上传),前后端真实联调。

一、业务需求

课程表分两种形式,均以「班级」为维度维护:

  1. 电子课程表(参考 timetable-site/index.html):
    • 顶部选择班级;「电子版 / 照片版」两个页签。
    • 编辑表格:节次 | 星期一~星期日 | 开始时间 | 结束时间 | 操作(删除)。
    • 节次默认 10 节(可新增/删除/恢复默认);每个单元格下拉选择学科。
    • 按开始时间自动判定时段:上午 < 12:30;下午 12:30–18:30;晚自习 ≥ 18:30,分组行展示。
    • 支持预览课表(时段分栏课表 + 打印)。
  2. 照片课程表:按班级上传一张课表照片(预览/替换/移除)。

二、现状调研摘要

2.1 后端(com.yunhai.dormnotice)

  • Spring Boot 2.7.18 + Java 8 + JPA/Hibernate + MySQL;端口 8105;本地库已是 aca_syllabu;生产 context-path /dormnotice、库 bsch_dormnotice(未改)。
  • 上一轮重构已移植:UserContext、ControllerUserContextAspect、SysOperationLogAspect(异步落库)、SysOperationLog、UpFile 附件体系、ClassService(班级树/学生树,5 分钟缓存,直连 {yh.open.bschclass}/oapi)。
  • 无学科接口——ClassService 只有教师/学生树,需补 getSchSubjectList。
  • 宿舍通知业务待删:Activity/ActivityRead/ActivitySignup/ContactGroup/ContactGroupUser 实体 + Contacts/Dict 控制器 + model/activity 15 个 VO。
  • 已知隐患:BaseApiController import 了 model.activity.ClassTreeNodeVo(与 bsch 包同名类重复),删 activity 包前必须改为 model.bsch.ClassTreeNodeVo;两个切面的切点/排除名单硬编码 com.yunhai.dormnotice。

2.2 前端(view/AcaSyllabu)

  • dev 端口 8078,代理 /api → http://localhost:8105(与后端一致,无需改)。
  • 路由静态注册(routes.ts + meta.modId),菜单由后端 GetUserMod 下发经 menuRoute.ts 映射;dorm 7 页面 + api/module/dorm.ts + types/dorm.ts 为待删业务。
  • alova 封装(get/postJSON/postForm)+ {code,msg,data} 解包 + 302 跳 SSO 均为可复用基建。
  • GradeClassSel/BschSubjectSelect/UploadImg 是其它项目拷来的死组件(依赖的 store 字段不存在),不可直接用。
  • timetable-site/index.html:完整交互蓝本(时段色板、学科色板、预览 sheet、照片 dropzone、打印样式俱全),整体迁入 Vue 页面。

2.3 构建环境

  • 后端:D:\Program Files\Java\jdk-1.8 + D:\Program Files\Java\maven\apache-maven-3.6.1(需 JAVA_HOME);平台依赖已在本地 ~/.m2 缓存。
  • 前端:Node 24 + npm,node_modules 缺失需先 npm install。

三、数据库设计(ddl-auto=update 自动建表,SQL 脚本同步留存)

表 字段 说明
timetable id、sch_id、class_id、class_name、grade_name、teacher_id、photo_file_id、create/update 审计 每班一条,(sch_id, class_id) 唯一;teacher_id 为平台用户/教师 id,不存账号;photo_file_id 关联 up_file
timetable_slot id、timetable_id、sort_order、start_time、end_time、day_1..day_7 每节次一行;start/end 存 HH:mm;day_N 存学科名(空=未排)
sys_operation_log (沿用) 操作日志,切面异步落库
up_file (沿用) 附件表,topic_type=timetable

派生数据(时段分组、统计)不落库,前后端按开始时间实时计算。

2026-10-12 变更:时段判断已移除。所属时段改为显式维护在模板行上(timetable_template_row.band = es/am/noon/pm/ev), 保存后不随开始时间变化;节次与空白行都落在时段里,启用哪些时段就要维护哪些时段的行——每个启用时段至少保留一行(节次或空白行), 只剩一行时该行不允许删除、也不允许移出该时段;课表编排页按生效模板行的 band 分组展示。上文「按开始时间自动判定时段」为改造初期的原始设计,仅作历史记录。

四、任务分解

任务 1:后端框架改名 com.yunhai.dormnotice → com.yunhai.acasyllabu

# 改动点
1.1 源码目录 java/com/yunhai/dormnotice/ → acasyllabu/,全部 package/import 替换(含两切面切点表达式与 LogController 排除名单)
1.2 主类 DormNoticeApplication → AcaSyllabuApplication(scanBasePackages 同步)
1.3 pom.xml:artifactId/name/finalName/mainClass → acasyllabu;ci profile 输出目录同步
1.4 bootstrap.yml:spring.application.name: acasyllabu,Nacos dataId acasyllabu.yaml
1.5 application.yml:sms.module-id 改名;docker/application-prod.yml:context-path /acasyllabu、库 bsch_acasyllabu;Dockerfile EXPOSE 对齐
1.6 logback-spring.xml / SwaggerConfig 标题 / notice.iml 及 .idea 辅助文件同步

任务 2:删除宿舍通知业务,保留日志/附件/基建

  • 删除:Activity、ActivityRead、ActivitySignup、ContactGroup、ContactGroupUser、SysDict 实体 + 对应 Repository/Service/Controller(ActivityController、ContactsController、DictController)+ model/activity/ 全部 + sql/dormnotice_schema.sql。
  • 保留:BaseEntity、SysOperationLog、UpFile、BaseAuditListener、ValidationGroups、PageUtils、BasePageQuery/Result、UserContext/UserSysRole/UserType、两切面、BaseApiController、FileController、LogController、ClassService、UserCenterService、FileService、SysOperationLogService。
  • 前置修复:BaseApiController 的 ClassTreeNodeVo import 改指 model.bsch。

任务 3:新实体与业务(不存账号,存教师 id)

  • entity/Timetable、entity/TimetableSlot(见第三节表设计)。
  • service/ITimetableService + impl:
    • get(classId):按 UserContext.schId + classId 取课表,组装 slots(无数据返回空骨架由前端补默认 10 节)。
    • save(request):校验(班级属于本校 via ClassService、时间格式与先后、学科 ∈ 本校学科表、day 列数=7)→ 全量替换 slots,teacher_id=UserContext.userId,冗余 class_name/grade_name。
    • savePhoto(classId, fileId):绑定照片(up_file topic_type=timetable),替换时清理旧文件。
    • removePhoto(classId):解绑并删文件。

任务 4:ClassService 扩展学科接口

  • IClassService.getSubjectList(schId):GET {bschclass}/oapi/sch/getSchSubjectList?schId=,5 分钟缓存(与学生树同款),返回 [{id, code, name}]。失败降级返回空列表并 log.warn。

任务 5:TimetableController(/{platform}/timetable/,PascalCase 惯例)

接口 方法 说明
/Get GET ?classId= 返回课表 VO(slots + photoFileId/photoUrl)
/Save POST @RequestBody 整表保存(电子版)
/SavePhoto POST ?classId=&fileId= 绑定照片
/RemovePhoto POST ?classId= 移除照片
/Subjects GET 本校学科列表
  • FileController 上传沿用:前端先 /api/file/Upload 拿 fileid,再 SavePhoto 绑定;Preview 展示。

任务 6:前端改造

  1. 新增 src/types/syllabus.ts(TimetableVo/SlotVo/SubjectVo/SaveRequest)。
  2. 新增 src/api/module/syllabus.ts(syllabusApi:Get/Save/SavePhoto/RemovePhoto/Subjects;复用 baseApi.GetClassTree/GetUserInfo —— baseApi 移入本模块或新建 base.ts)。
  3. 新增 src/views/syllabus/TimetableEdit.vue:移植 timetable-site 交互(页签、班级选择、编辑表格、时段分组、新增/删除/恢复节次、预览 Modal+打印、照片 dropzone 上传/替换/移除);保存到后端(保存按钮 + 未保存标记,替代原 localStorage)。
  4. routes.ts:删 dorm 路由,新增 /timetable(meta.title 课程表编排、modId 占位);/ 默认进课程表。
  5. layout.vue getMenuIcon、menuRoute.ts 别名、App.vue 应用名、index.html/vite.config 标题 → 「课程表」。
  6. 删除 views/dorm/、api/module/dorm.ts、types/dorm.ts;死组件(GradeClassSel/BschSubjectSelect/UploadImg/TreeNode 等)不再被引用,随构建树摇出产物,暂不物理删除。

任务 7:bug 审查与优化(账号 lijing / a123123)

已知待修(本计划内执行):

  1. BaseApiController 错误 import activity.ClassTreeNodeVo(任务 2 前置)。
  2. 切面切点/排除名单硬编码包名(任务 1 一并替换)。
  3. 生产 context-path/库名/sms module-id 残留 dormnotice(任务 1.5)。
  4. Dockerfile EXPOSE(10002) 与实际端口(8070) 不一致。
  5. dorm.ts ReceiptFormTemplate 未导入的类型瑕疵(随 dorm 删除消解)。
  6. 前端 postForm 双发导致 Spring 参数合并 "x,x" 的历史坑——新 syllabus.ts postForm 仅在 isMock 时拼 query,沿用防御。 联调项(需平台在线,代码层先保证):
  • CAS 登录 → GetUserInfo/GetUserMod → currentRole → UserContext 填充 → schId 隔离;
  • lijing 建课表/换班/预览/打印/照片全流程;操作日志落库抽查。

五、实施顺序与验收

阶段 内容 验收
一 任务 1+2:改名、删业务、前置修复 mvn compile 通过;全局 grep dormnotice 仅剩历史文档
二 任务 3+4+5:实体/服务/接口 mvn compile 通过;Swagger 自查接口形状
三 任务 6:前端页面/路由/API npm run build 通过
四 任务 7:bug 审查修复 + 联调准备 清单全过;文档勾选执行状态

六、风险与说明

  1. lijing/a123123 为基础平台(CAS/用户中心)账号,代码中不落库不校验密码;联调依赖平台与班级服务在线。
  2. 学科 oapi 若因权限/网络不可用, Subjects 返回空列表并前端提示,不阻断电子课表编辑(学科名仍可显示已存数据)。
  3. 平台菜单(GetUserMod)未配「课程表」模块时,前端 / 兜底直接进 /timetable,菜单缺失不影响直访。
  4. 旧 dorm 数据表(activity 等)保留在库中不删,仅代码层不再引用。