11 KiB
11 KiB
AcaSyllabu 课程表改造计划
创建日期:2026-10-11 执行状态(2026-10-11):全部完成。
- 后端:包名已改
com.yunhai.acasyllabu,宿舍通知业务已删(保留日志/附件/基建),新增 Timetable/TimetableSlot 实体 + TimetableController(Get/Save/SavePhoto/RemovePhoto/Subjects)+ ClassService 学科接口;mvn clean compileBUILD 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,电子课程表(节次×星期编排)+ 照片课程表(图片上传),前后端真实联调。
一、业务需求
课程表分两种形式,均以「班级」为维度维护:
- 电子课程表(参考 timetable-site/index.html):
- 顶部选择班级;「电子版 / 照片版」两个页签。
- 编辑表格:
节次 | 星期一~星期日 | 开始时间 | 结束时间 | 操作(删除)。 - 节次默认 10 节(可新增/删除/恢复默认);每个单元格下拉选择学科。
- 按开始时间自动判定时段:上午 < 12:30;下午 12:30–18:30;晚自习 ≥ 18:30,分组行展示。
- 支持预览课表(时段分栏课表 + 打印)。
- 照片课程表:按班级上传一张课表照片(预览/替换/移除)。
二、现状调研摘要
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。
- 已知隐患:
BaseApiControllerimport 了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:前端改造
- 新增
src/types/syllabus.ts(TimetableVo/SlotVo/SubjectVo/SaveRequest)。 - 新增
src/api/module/syllabus.ts(syllabusApi:Get/Save/SavePhoto/RemovePhoto/Subjects;复用 baseApi.GetClassTree/GetUserInfo —— baseApi 移入本模块或新建base.ts)。 - 新增
src/views/syllabus/TimetableEdit.vue:移植 timetable-site 交互(页签、班级选择、编辑表格、时段分组、新增/删除/恢复节次、预览 Modal+打印、照片 dropzone 上传/替换/移除);保存到后端(保存按钮 + 未保存标记,替代原 localStorage)。 - routes.ts:删 dorm 路由,新增
/timetable(meta.title 课程表编排、modId 占位);/默认进课程表。 - layout.vue
getMenuIcon、menuRoute.ts 别名、App.vue 应用名、index.html/vite.config 标题 → 「课程表」。 - 删除
views/dorm/、api/module/dorm.ts、types/dorm.ts;死组件(GradeClassSel/BschSubjectSelect/UploadImg/TreeNode 等)不再被引用,随构建树摇出产物,暂不物理删除。
任务 7:bug 审查与优化(账号 lijing / a123123)
已知待修(本计划内执行):
- BaseApiController 错误 import activity.ClassTreeNodeVo(任务 2 前置)。
- 切面切点/排除名单硬编码包名(任务 1 一并替换)。
- 生产 context-path/库名/sms module-id 残留 dormnotice(任务 1.5)。
- Dockerfile EXPOSE(10002) 与实际端口(8070) 不一致。
- dorm.ts
ReceiptFormTemplate未导入的类型瑕疵(随 dorm 删除消解)。 - 前端
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 审查修复 + 联调准备 | 清单全过;文档勾选执行状态 |
六、风险与说明
- lijing/a123123 为基础平台(CAS/用户中心)账号,代码中不落库不校验密码;联调依赖平台与班级服务在线。
- 学科 oapi 若因权限/网络不可用, Subjects 返回空列表并前端提示,不阻断电子课表编辑(学科名仍可显示已存数据)。
- 平台菜单(GetUserMod)未配「课程表」模块时,前端
/兜底直接进/timetable,菜单缺失不影响直访。 - 旧 dorm 数据表(activity 等)保留在库中不删,仅代码层不再引用。