Commit Graph
97 Commits
  • 草稿计划支持选择场次后“批量移除已选场次”,一次最多 100 个。
    批量操作会完整校验:包含不存在、其他计划或已发布计划的场次时整批拒绝,不会部分删除。[ExamsController.cs (line 384)](E:/jiaowu/src/Jiaowu.Api/Controllers/ExamsController.cs:384)
    草稿计划新增“删除草稿”按钮,删除前显示计划名称及场次数量确认。[ExamsView.vue (line 292)](E:/jiaowu/web/src/views/ExamsView.vue:292)
    删除草稿计划会级联清理场次和监考关联;已发布计划不能删除。[ExamsController.cs (line 81)](E:/jiaowu/src/Jiaowu.Api/Controllers/ExamsController.cs:81)
    删除后会自动切换到其他计划;没有剩余计划时正确显示空状态。
    新增草稿、已发布、跨计划混选及级联删除测试。[ExamDeletionControllerTests.cs (line 17)](E:/jiaowu/tests/Jiaowu.Api.Tests/ExamDeletionControllerTests.cs:17)
  • 已修改完成,同时解决了“考生名单都是 0 人”的根因。
    考生范围统一为“行政班关联学生 + 已选课学生”,并自动去重;考场分配、人数显示、冲突检测、学生考试安排均使用同一口径。[TeachingTaskRosterQuery.cs (line 40)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Teaching/TeachingTaskRosterQuery.cs:40)
    新增考场签名单 Excel 导出接口。[ExamsController.cs (line 568)](E:/jiaowu/src/Jiaowu.Api/Controllers/ExamsController.cs:568)
    考试计划页面新增“导出考场签名单”按钮。[ExamsView.vue (line 255)](E:/jiaowu/web/src/views/ExamsView.vue:255)
    工作簿包含“考场汇总”以及每个考试场次独立的 A4 签到表,字段包括座位号、学号、姓名、行政班、考生签名和备注。[ExamSignInWorkbookExporter.cs (line 12)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Exams/ExamSignInWorkbookExporter.cs:12)
    未分配考场或监考教师时,也能导出并显示“待分配”。
  • “教务总览”改成可实际工作的分级工作台:
    校级管理员查看全校数据,学院管理员仅查看本学院数据。
    待办按当前审批阶段统计,涵盖授课资格、成绩、调停课、学籍异动、教室借用等。
    增加学期进度、教学任务发布、课表覆盖、成绩发布状态。
    快捷入口根据管理员角色自动调整。
    完善未配置学期、无待办、加载失败等状态。
    适配桌面和 390px 移动端,无横向溢出。
  • “运维与审计控制台”。
    主要能力:
    SuperAdmin 专用入口:组织与权限 → 运维与审计。
    操作日志分页查询,支持时间、账号、路径、方法和状态码筛选。
    汇总自动排课、课表发布、补考安排三类失败后台任务。
    实时检查数据库、缓存、任务通道及积压状态。
    聚合 5xx、失败/重试任务、健康探针和备份时效告警。
    SQLite 在线备份;MySQL 调用原生客户端备份。
    SHA-256 校验及隔离数据库恢复演练,不覆盖业务库。
    MySQL 强制使用独立运维连接,容器增加持久化备份卷与数据库客户端。
  • 发信改为事务内每 300 人分批写入,避免全校群发一次插入过大;数据库异常现在返回明确的 503,不再只显示模糊 500。
    校级、学院级管理员支持按学院、身份、行政班、教学班、姓名/学号/工号筛选,也可指定最多 500 名收件人。所有结果均由服务端重新校验权限。
    接入 CKEditor 5,支持标题、列表、引用和链接;正文扩展为 MySQL longtext。
    富文本在收件箱、详情弹窗和已发送记录中统一经 DOMPurify 净化后展示。
    页面改用系统现有的冷白、靛蓝、青绿色令牌,新增“选择收件人 → 编辑内容”工作台和移动端适配。
  • 点名、成绩册统一读取“行政班在籍学生 ∪ 已选课学生”,不再错误显示 0 人。
    教师选课名单改为展示全部本人教学班及完整学生名单,支持 Excel 导出。
    调停课改用教师专用教学班接口,并在服务端限制只能操作本人教学班。
  • 第二阶段优化已完成,重点是提高后台任务吞吐并降低 Outbox 数据库开销。
    RabbitMQ 默认从单一回调通道提升为三类任务独立并行,跨类型并发能力由 1 提升到 3;每类还能独立配置 1–16 个消费者。[RabbitMqBackgroundJobs.cs (line 143)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/BackgroundJobs/RabbitMqBackgroundJobs.cs:143)
    InMemory 开发模式同步改为按任务类型隔离队列,避免某类长任务堵塞其他任务。
    租约恢复检查从“每发布一条执行一次”改为默认每 60 秒维护一次。
    启动恢复改为数据库 NOT EXISTS 查询,不再把全部历史 Outbox 加载进内存。[BackgroundJobOutboxPublisher.cs (line 9)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/BackgroundJobs/BackgroundJobOutboxPublisher.cs:9)
    完成消息默认保留 14 天,之后按每批 500 条清理,并增加对应组合索引。
    /health/messaging 现在返回各状态积压量、过期租约和最老任务等待时间。[BackgroundJobMonitoringService.cs (line 16)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/BackgroundJobs/BackgroundJobMonitoringService.cs:16)
    新增 Jiaowu.BackgroundJobs 运行时指标,覆盖发布量、处理量、发布耗时、处理耗时和清理量。[BackgroundJobTelemetry.cs (line 9)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/BackgroundJobs/BackgroundJobTelemetry.cs:9)
    配置、Compose 和调优建议已更新。[README.md (line 257)](E:/jiaowu/README.md:257)
  • 排课计算、课表发布、补考自动编排三类任务统一接入消息系统。
    业务任务与 Outbox 消息同一事务落库,避免“数据库成功但消息没发出去”。
    RabbitMQ 使用持久化消息、发布确认、手动 ACK、Quorum Queue、死信队列。
    增加处理租约、心跳、异常重试、最大重试次数和幂等状态控制。
    保留 InMemory 模式,开发环境无需安装 RabbitMQ。
    支持多实例竞争消费,后续可以横向扩容。
    新增 /health/messaging 消息系统健康检查。
  • 成绩通知:仅在某门课程成绩正式发布后自动发送,按成绩单学生名单通知,不展示具体分数;发布状态与通知同一次提交。
    手动发信:移除“成绩通知”选项,只能发送普通通知,原有角色与范围权限保持不变。
    选课通知:管理员关闭一轮选课时,自动向每位参与学生发送一条汇总通知,包含最终选中课程及候补未成功课程;候补失效、轮次关闭和通知生成保持原子性。
    关闭选课界面会明确提示发送通知,并显示实际通知人数。
  • 学生可在“学籍管理 → 电子成绩单与证明”申请成绩单或学籍证明。
    服务端根据登录账号绑定本人档案,不接受学生 ID,无法代他人申请。
    成绩单仅包含正式发布成绩;无已发布成绩时明确提示。
    同类型、同用途 5 分钟内重复申请复用已有有效凭证。
    申请后即时生成 PDF,可在本人凭证列表下载、二维码验真。
    管理员的下载记录、失效、重签能力保持不变。
  • 已完善个人教学日历订阅。
    主要能力:
    教师、学生可在“我的课表”启用订阅、复制 URL、唤起日历客户端或下载一次性 ICS。
    自动覆盖固定课程、调停课后的最新安排、考试/监考、补考,以及灵活课程提醒。
    采用独立随机订阅标识和 HMAC 签名;重置或停用后旧地址立即失效。
    支持 ETag 条件请求和一小时刷新提示,减少日历客户端重复同步。
    订阅地址按实际前端 API 地址生成,兼容独立部署域名。
    已增加窄屏弹窗最大宽度和纵向操作布局。
  • 将索引缩短为 IX_CE_Offering_Status_WaitlistedAt。
    将候补迁移改为可重入:先检查列和索引是否存在,再执行 DDL。
    附件中已经成功添加 WaitlistedAt、但索引创建失败的数据库可直接重试,不会报重复列。
    运行时和 dotnet ef 连接统一开启 AllowUserVariables;Connector/NET 默认关闭该选项。Connector/NET 官方说明
    增加所有 MySQL 索引名不得超过 64 字符的回归测试。
  • 已把选课的“年级划分”和限制规则补成完整闭环:
    选课批次可指定多个适用年级;留空兼容原有“全部年级”。
    新增可选的“最多课程门数”,与原有学分上限并行。
    年级、门数限制统一作用于学生可见批次、自主选课、候补、管理员代选和自动递补。
    普通候选名单遵守年级及行政班范围;强制选课可绕过业务限制,但仍严格遵守管理员学院权限。
    管理页面会展示“2026 级 · 最多 6 门 · 最多 30 学分”,名单和候补列表也增加年级列。
    新增 MySQL 迁移:[CourseSelectionGradeLimits.cs](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Persistence/Migrations/MySql/20260726180000_CourseSelectionGradeLimits.cs)。
  • 已完成“选课候补与自动递补”完整流程。
    学生端:满员后可加入/取消候补,展示候补顺位和当前候补人数。
    自动递补:退课释放名额后,按候补时间顺序重新校验学籍、范围、学分及时间冲突;不合格者自动失效并继续下一位。
    管理端:教学班显示候补人数,名单抽屉提供候补队列及移出操作。
    状态通知:递补成功、资格失效、批次关闭、管理员移出均会通知学生。
    并发安全:退课和递补放在 Serializable 事务中执行。
    数据库:已补充 SQLite 开发迁移和 MySQL 正式迁移。
  • 仪表盘和 6 类统计摘要接入 HybridCache(内存 + Redis)。
    默认 Redis 缓存 3 分钟、本地缓存 30 秒,可通过环境变量调整。
    缓存键包含数据权限范围、有效学院和全部筛选条件,避免跨学院串数据。
    Excel 导出保持实时查询,不使用摘要缓存。
    无需数据库迁移。
  • 主要变更:
    新增统一缓存封装:[AppCache.cs (line 12)](/E:/jiaowu/src/Jiaowu.Api/Infrastructure/Caching/AppCache.cs:12)
    接入 HybridCache 和可选 Redis:[Program.cs (line 153)](/E:/jiaowu/src/Jiaowu.Api/Program.cs:153)
    缓存学生激活选项、基础数据、公开课表和课表选项。
    个人课表、选课容量、成绩、权限、通知和任务状态保持实时查询。
    基础数据、课程、教师、教学任务、作息、考试和课表发布后自动失效相关缓存。
    新增 /health/cache,Redis 故障不影响 /health/ready。
    Compose 增加 256MB、allkeys-lfu、无持久化的 redis:8.8-alpine 服务;该镜像标签已由 Docker 官方镜像仓库核对。
    更新 [.env.example (line 1)](/E:/jiaowu/.env.example:1) 和 [README.md (line 190)](/E:/jiaowu/README.md:190) 部署说明。
  • 免修、缓考现在包含当前学期课程,以及未归档且课表已发布的实际修读课程。
    实际开发库验证已返回 CS101 程序设计基础。
    课程替代改为“修读中/未通过课程 → 已发布及格课程”的双栏选择。
    新增搜索、教学班号、学期、教师、学分、课表状态和完整空状态说明。
    新增课程替代申请记录。
    提交接口增加服务端资格校验,不能伪造课程 ID 绕过前端。
  • 修复500
    TimeOnly ↔ TimeSpan
  • 学年学期页面新增“设为当前”“归档”“撤销归档”,当前学期不能归档、删除或直接取消;已归档学期需先撤销才能重新设为当前。[BaseDataController.cs (line 286)](/E:/jiaowu/src/Jiaowu.Api/Controllers/BaseDataController.cs:286)
    切换后,其他学期自动变为历史态;已归档学期进一步弱化。所有主要学期选择器统一默认当前,并显示“当前 / 历史 / 已归档”。[academicTerms.ts (line 1)](/E:/jiaowu/web/src/utils/academicTerms.ts:1)
    桌面使用分层表格,390px 手机端改为独立学期卡片,操作不会再挤压表格。[BaseDataView.vue (line 211)](/E:/jiaowu/web/src/views/BaseDataView.vue:211)
    归档定义为“历史显示状态”,不是成绩冻结:补考成绩仍可录入并回写,已发布成绩仍可走成绩更正审批。
    已加入 SQLite 开发迁移、MySQL 正式迁移和切换/归档/撤销测试。[20260726143000_AcademicTermArchiving.cs (line 1)](/E:/jiaowu/src/Jiaowu.Api/Infrastructure/Persistence/Migrations/MySql/20260726143000_AcademicTermArchiving.cs:1)
  • 已完成,学生端考勤记录现在按课程展示。
    每门课程会独立显示:
    课程名称、代码、教学班和任课教师。
    课程总体出勤率。
    出勤、迟到、缺勤、请假、免修次数。
    按日期排列的历次点名记录。
    缺勤或迟到记录仍可单独申诉。
  • ge
    xiufu
  • 新增显式命令:--seed-demo-data --confirm-production-demo-data
    仅允许非 Development 环境运行。
    只允许写入没有业务数据的独立空库。
    演示数据使用单个 InnoDB 事务,失败整体回滚;迁移 DDL 仍单独执行,因为 MySQL 8.4 的 DDL 会隐式提交。MySQL 事务文档、隐式提交说明
    不包含通用测试密码或学生、教师登录账号。
    包含校区、学期、30 间教室、16 个学院、52 个专业、104 个班级、128 名教师、3,640 名学生和148门课程。
  • 新增“课程统计”模式,展示总体出勤率、状态分布、历次趋势和每位学生的出勤明细。
    支持按姓名/学号、行政班及异常情况筛选,默认优先显示低出勤率学生。
    新增课程统计 Excel 导出,包含课程概览、学生出勤明细、历次点名趋势三个工作表。
    统计仅使用已提交点名;出勤和迟到计为到课,免修不计入应到次数。
    修复了枚举兼容问题,已提交点名不会再错误显示为“草稿”,考勤状态中文标签恢复正常。
    统计与导出接口均执行教师/数据范围权限校验。
  • ---
    成绩册 Excel 导入/导出 — 已完成
    
      后端 (GradesController.cs)
    
      GET /api/grades/sheets/{id}/template — 下载成绩导入模板
      - 根据成绩单的动态分项(GradeItems)生成对应的 Excel 列:学号 | 姓名 | 班级 | 平时成绩 | [分项1] | [分项2] | ... | 期末成绩 | 考试状态 | 备注
      - 预填已有学生信息和已有成绩
      - 附带填写说明工作表
    
      POST /api/grades/sheets/{id}/import — 从 Excel 导入成绩
      - 按学号匹配学生,批量更新平时成绩、分项成绩、期末成绩、考试状态、备注
      - 支持留空(不覆盖已有成绩)、0-100 范围校验、考试状态校验(正常/缺考/缓考/免修)
      - 导入后自动重新计算总评成绩和绩点
      - 仅限 Draft/Returned 状态的成绩单,仅限有编辑权限的用户
      - 错误时整批回滚,最多显示 50 条错误详情
    
      前端 (GradesView.vue)
    
      在成绩登记册底部操作栏新增两个按钮(仅在 canEdit 时显示):
      - 下载模板 — 调用 downloadApiFile 下载当前成绩单的 Excel 模板
      - Excel导入 — 通过隐藏 file input 选择 .xlsx 文件,调用 importExcel 上传
    
      工作流程
    
      1. 教师打开成绩单 → 点击「下载模板」
      2. 在 Excel 中填写/修改学生成绩
      3. 点击「Excel导入」选择文件上传
      4. 系统自动校验、合并成绩、重新计算总评 → 提示更新条数
      5. 成绩表刷新显示最新数据
    
    ✻ Crunched for 5m 50s