# subenteng **Repository Path**: enterprise-practice/subenteng ## Basic Information - **Project Name**: subenteng - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-11-06 - **Last Updated**: 2026-11-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 讲座管理系统 《企业项目实战实训》课程项目:讲座发布、学生报名、数字签到码签到/签退、出勤统计,外加一个基于本地大模型的 AI 智能助手。 - 后端:Spring Boot 3.5.16 + MyBatis-Plus 3.5.7 + MySQL 8.0 + JWT(jjwt 0.12.6) - 前端:Vue 3 + Vite 5 + Element Plus + Pinia + Vue Router + Axios - 角色:管理员(PC 后台)、老师(PC 后台)、学生(H5) ## 目录结构 ``` . ├── lecture-server/ 后端工程 │ ├── src/main/java/com/subenteng/lecture/ │ │ ├── auth/ JWT 生成与解析 │ │ ├── common/ Result、BizException、全局异常 │ │ ├── config/ MyBatis-Plus、BCrypt、初始管理员、Jackson │ │ ├── controller/ Hello、Auth、Major、Teacher、Class、Student、Account、Lecture、Enrollment │ │ ├── dto/ 请求/响应对象 │ │ ├── entity/ 实体 │ │ ├── mapper/ MyBatis-Plus Mapper │ │ └── service/ 业务逻辑 │ └── src/main/resources/ │ ├── application.yml 公共配置(端口 8090、JWT、初始管理员) │ ├── application-dev.yml 数据库账号密码(已 gitignore) │ └── application-dev.yml.example 配置模板 ├── lecture-web/ 前端工程 │ └── src/ │ ├── layout/AdminLayout.vue 后台布局(左侧菜单 + 顶栏) │ ├── router/ 路由 + 登录守卫 │ ├── stores/user.js 登录状态(Pinia + localStorage) │ ├── utils/ axios 封装、接口定义 │ └── views/ 登录页、首页、专业/老师/班级/学生/账号/讲座管理、学生 H5 ├── db/schema.sql 11 张表的建表脚本 ├── api-test/ IDEA HTTP Client 接口测试 └── docs/ 需求、设计、AI 协同日志 ``` ## 环境要求 | 软件 | 版本 | |---|---| | JDK | 17 及以上(本机用 21 编译,`release 17`) | | Maven | 3.8+ | | MySQL | 8.0 | | Node.js | 18+ | ## 启动步骤 ### 1. 建库建表 ```bash mysql -u root -p --default-character-set=utf8mb4 < db/schema.sql ``` 脚本会创建 `lecture_subenteng` 库和 11 张表。 ### 2. 配置数据库密码 ```bash cd lecture-server/src/main/resources cp application-dev.yml.example application-dev.yml # 修改 application-dev.yml 里的 password ``` `application-dev.yml` 已加入 `.gitignore`,不会提交到仓库。 ### 3. 启动后端 ```bash cd lecture-server mvn spring-boot:run ``` 启动后访问 ,应返回: ```json {"code":200,"msg":"Hello 讲座管理系统","data":null} ``` 首次启动会自动在 `sys_user` 表创建管理员账号: | 用户名 | 密码 | 角色 | |---|---|---| | admin | admin123 | ADMIN | 密码在数据库里是 `$2a$10$...` 开头的 BCrypt 密文。 > 如果终端里有 `SERVER__PORT` 环境变量,会覆盖 `server.port`,导致端口不是 8090。用 IDEA 启动不受影响。 ### 4. 启动前端 ```bash cd lecture-web npm install npm run dev ``` 打开 ,用 `admin / admin123` 登录。 学生端 H5 入口是 ,用学号 + 初始密码登录;首次登录会被强制要求改密。 手机上访问时,把 `localhost` 换成电脑的局域网 IP(如 `http://192.168.1.10:5173/h5/login`),Vite 默认监听所有网卡。 开发环境下 `/api` 由 Vite 代理到 `http://localhost:8090`,不需要处理跨域。 ## 已实现的功能 - [x] 前后端分离骨架、`/api/hello` 连通 - [x] 11 张表 - [x] 统一返回 `{code, msg, data}` + 全局异常处理 - [x] 专业管理(分页、搜索、新增、编辑、删除、重名校验) - [x] 老师管理(工号唯一、下拉选项、担任班主任时禁止删除) - [x] 班级管理(专业/班主任下拉,列表显示名称,删除保护) - [x] 学生管理(按班级/关键字筛选,重置密码) - [x] Excel 批量导入(学生/老师/班级,逐行校验、部分成功、失败行给出行号和原因) - [x] 管理员登录(BCrypt 校验 + JWT 令牌) - [x] 登录密码 RSA 传输加密(前端 JSEncrypt,后端私钥解密) - [x] 接口鉴权拦截器:无令牌 / 令牌无效返回 401,角色不符返回 403 - [x] `@RequireRole` 声明式角色控制(管理员接口已加) - [x] 前端登录页、Pinia 存令牌、Axios 自动带 `Authorization` - [x] 按角色显示不同菜单 + 路由守卫 - [x] 退出登录(清 Pinia + localStorage) - [x] 老师账号管理(一师一号、启用/停用、重置密码,停用后无法登录) - [x] 学生 H5 登录(学号 + 密码,RSA 加密,手机端自适应页面) - [x] 首次登录强制改密(拦截器 428,只放行改密接口) - [x] 修改密码(原密码校验 + 新密码 ≥8 位且含字母和数字,前后端双校验) - [x] 讲座发布(主题、主讲人、时间、地点、简介、名额、报名起止、签到刷新周期、签到开放时长) - [x] 报名范围(全校 / 指定专业多选 / 指定班级多选,存为 `scope_type` + `scope_ids`) - [x] 时间校验(结束晚于开始、报名截止不晚于讲座开始,不合法直接拦下并提示原因) - [x] 讲座上下线(已发布可下线;有人报名的讲座不可删除,只能下线) - [x] 讲座状态计算(报名中 / 待开始 / 进行中 / 已结束 / 已下线 / 草稿,由发布状态 + 当前时间算出,列表彩色标签区分) - [x] 讲座列表按展示状态、讲座开始日期区间筛选 - [x] 学生 H5 讲座列表(后端按范围过滤,标明可报名 / 已报名 / 已截止 / 已满) - [x] 学生报名 / 取消报名(条件 UPDATE 扣名额 + 唯一索引兜底,报名截止后不可取消) - [x] 学生 H5 讲座详情页(剩余名额、报名起止、简介,点标题进入) - [x] 报名并发控制(名额 1 时两人同时报名只有一人成功,6 轮压测无超卖) - [x] 报名名单(学号、姓名、班级、报名时间、报名方式,按班级筛选、分页) - [x] 报名名单导出 Excel(EasyExcel,导出当前筛选条件,行数与页面一致) - [x] 管理员代报名 / 代取消(按学号,不受报名时间限制、受名额限制,标记「管理员代报」) - [x] 我的报名(H5 tab,按报名时间排序) ## 待实现(后续课次) - 数字签到码、签到签退、出勤统计(出勤状态列现为「待签到」占位) - 出勤记录导出、补签、操作日志 - AI 助手(Ollama + Qdrant + RAG) ## 分支与提交规范 - `master` 保持可运行,日常开发在 `develop`,功能开发用 `feature/功能名` - 提交信息遵循 Conventional Commits:`feat(auth): 实现 JWT 登录接口` - 每次课在 `docs/ai-log/<姓名>/` 追加一篇 AI 协同日志 **一次功能开发的正确顺序**(顺序错了会补不出 MR 记录): ```bash # 1. 从最新 develop 切功能分支 git checkout develop && git pull git checkout -b feature/xxx # 2. 开发、提交、只推功能分支 git add . && git commit -m "feat(xxx): ..." git push origin feature/xxx # 3. 在 Gitee 网页发起 MR(目标 develop),点“审查通过”“测试通过”后合并 # 4. 合并完再回本地同步 git checkout develop && git pull git checkout master && git merge --ff-only develop && git push origin master ``` > 踩过的坑:先在本地把功能分支合进 develop 再推送,develop 就包含了全部提交,Gitee 对比页显示“0 个提交”,MR 根本建不出来。 ## 合并记录 每个 MR 都是在 Gitee 网页上点完「审查通过(所有)」和「测试通过(所有)」之后才合并的,`develop` 里没有直接提交。 | MR | 源分支 → 目标分支 | 内容 | 状态 | |---|---|---|---| | !1 | `feature/auth` → `develop` | BCrypt 密码加密 + JWT 登录接口(第 3 次课) | 已合并 | | !2 | `feature/docs-review` → `develop` | 需求评审记录、需求说明书 v1.2、第 1/2 次课 AI 日志 | 已合并 | | !3 | `feature/auth-guard` → `develop` | 接口鉴权拦截器、`@RequireRole`、RSA 传输加密(第 4 次课) | 已合并 | | !4 | `feature/basic-data` → `develop` | 老师 / 班级 / 学生管理 + Excel 批量导入(第 5、6 次课) | 已合并 | | !5 | `feature/docs-mr-record` → `develop` | 补充本合并记录表 | 已合并 | | !6 | `feature/teacher-class-import` → `develop` | 老师 / 班级页补 Excel 导入入口、设计说明书补签到码与并发报名时序图 | 已合并 | | !7 | `feature/ai-log-supplement` → `develop` | 第 6 次课 AI 日志补「课后补漏」一节 | 已合并 | | !8 | `feature/student-h5` → `develop` | 老师账号管理、学生 H5 登录、首次改密、修改密码(第 7 次课) | 已合并 | | !9 | `feature/lecture-enroll` → `develop` | 讲座发布、报名范围、上下线、状态计算与筛选;学生报名 / 取消(第 8 次课) | 已合并 | | !10 | `develop` → `master` | 第 8 次课成果同步到 `master` | 已合并 | | !11 | `feature/docs-mr-9-10` → `develop` | 合并记录表补 !9、!10 | 已合并 | | !12 | `develop` → `master` | 同步 !11 | 已合并 | | !13 | `feature/enroll-manage` → `develop` | H5 讲座详情、并发报名压测、报名名单 / 导出 / 代报名代取消、开发中审①(第 9、10 次课) | 已合并 | ## 文档索引 | 文件 | 内容 | 对应课次 | |---|---|---| | `docs/需求说明书.md` | 需求说明书 v1.2:调研原话、4 个用户故事、功能优先级、补充业务规则、版本变更记录 | 第 1 次课起草,第 3 次课前修订 | | `docs/评审记录/需求评审.md` | 课堂抽查三问(防代签、老师数据范围、AI 边界)+ 同桌互评意见 | 第 1 次课 | | `docs/设计说明书.md` | 系统架构、11 张表数据模型、接口清单、登录与令牌设计、签到码与并发报名流程、讲座状态机(§5.3)、**报名权限边界(§5.4)与并发压测结果(§5.5)** | 第 5 次课设计评审,第 8 次课补状态机,第 9 次课补压测 | | `docs/ai-log/苏本腾/2026-11-06-第1次课-骨架.md` | 骨架搭建、前后端第一次握手 | 第 1 次课 | | `docs/ai-log/苏本腾/2026-11-06-第2次课-建表与专业管理.md` | 11 张表、统一返回、专业管理全链路 | 第 2 次课 | | `docs/ai-log/苏本腾/2026-11-09-第3次课-登录.md` | BCrypt 密码加密 + JWT 登录 | 第 3 次课 | | `docs/ai-log/苏本腾/2026-11-10-第4次课-鉴权与RSA.md` | 拦截器、@RequireRole、RSA 传输加密、角色菜单 | 第 4 次课 | | `docs/评审记录/设计评审.md` | 设计评审:教师点评 + 同桌互查 6 条意见 | 第 5 次课 | | `docs/ai-log/苏本腾/2026-11-10-第5次课-班级与老师管理.md` | 班级管理、老师管理、删除保护 | 第 5 次课 | | `docs/ai-log/苏本腾/2026-11-10-第6次课-学生与Excel导入.md` | 学生管理、EasyExcel 部分成功导入 | 第 6 次课 | | `docs/ai-log/苏本腾/2026-11-11-第7次课-学生H5与账号管理.md` | 学生 H5 登录、首次改密强制、老师账号管理、移动端适配 | 第 7 次课 | | `docs/ai-log/苏本腾/2026-11-12-第8次课-讲座发布与状态机.md` | 讲座表单与报名范围、上下线、状态计算与筛选、批量补全历史遗漏 | 第 8 次课 | | `docs/ai-log/苏本腾/2026-11-13-第9-10次课-报名并发与报名管理.md` | 并发压测(Barrier 同步)、导出多列问题、428 改密拦截、越权验证 | 第 9、10 次课 | | `docs/评审记录/开发中审①.md` | 中审:提交与 MR 盘点、五步全流程演示、教师四问、4 条整改 | 第 10 次课 | | `db/schema.sql` | 11 张表的建表脚本(含唯一索引) | 第 2 次课 | | `api-test/*.http` | IDEA HTTP Client 用例:`major` / `teacher` / `class` / `student` / `account` / `auth` / `lecture` / `enrollment` | 第 2、3、5、6、7、8、9、10 次课 |