主要更新:
班级课表支持年级、学院、专业、行政班分级筛选。 管理员课表查询中心支持班级、教师、场地三种课表。 超级管理员、校级教务、学院教务、领导可查询草稿和已发布版本;学院管理员保留学院数据范围。 增加周视图、日视图切换。 支持 Excel 导出和当前视图 PDF 导出。 学生端增加“空闲教室”,支持学期、周次、星期、连续节次、校区、教学楼、容量筛选,并按教学楼分组、分页展示。 空闲教室只依据正式课表计算;未配置节次表时自动提供默认节次。
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
using Jiaowu.Api.Domain.Academic;
|
||||
using Jiaowu.Api.Infrastructure.Timetables;
|
||||
|
||||
namespace Jiaowu.Api.Tests;
|
||||
|
||||
public sealed class FreeClassroomRulesTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(WeekPattern.All, 2, true)]
|
||||
[InlineData(WeekPattern.Odd, 3, true)]
|
||||
[InlineData(WeekPattern.Odd, 4, false)]
|
||||
[InlineData(WeekPattern.Even, 4, true)]
|
||||
[InlineData(WeekPattern.Even, 3, false)]
|
||||
public void MatchesWeek_respects_all_odd_and_even_patterns(
|
||||
WeekPattern pattern,
|
||||
int week,
|
||||
bool expected)
|
||||
{
|
||||
Assert.Equal(expected, FreeClassroomRules.MatchesWeek(pattern, week));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1, 2, 2, 2, true)]
|
||||
[InlineData(3, 1, 2, 1, false)]
|
||||
[InlineData(1, 1, 2, 1, false)]
|
||||
[InlineData(4, 3, 3, 5, true)]
|
||||
public void PeriodsOverlap_uses_half_open_period_ranges(
|
||||
int requestedStart,
|
||||
int requestedCount,
|
||||
int occupiedStart,
|
||||
int occupiedCount,
|
||||
bool expected)
|
||||
{
|
||||
Assert.Equal(expected, FreeClassroomRules.PeriodsOverlap(
|
||||
requestedStart,
|
||||
requestedCount,
|
||||
occupiedStart,
|
||||
occupiedCount));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using ClosedXML.Excel;
|
||||
using Jiaowu.Api.Domain.Academic;
|
||||
using Jiaowu.Api.Infrastructure.Timetables;
|
||||
|
||||
namespace Jiaowu.Api.Tests;
|
||||
|
||||
public sealed class TimetableExcelExporterTests
|
||||
{
|
||||
[Fact]
|
||||
public void Create_builds_week_grid_and_flexible_course_section()
|
||||
{
|
||||
var timetable = new TimetableData(
|
||||
new TimetableTermDto(
|
||||
Guid.NewGuid(),
|
||||
"2026-2027 学年第一学期",
|
||||
"2026-2027",
|
||||
TermSeason.Autumn,
|
||||
new DateOnly(2026, 9, 1),
|
||||
new DateOnly(2027, 1, 15),
|
||||
true),
|
||||
new TimetableSubjectDto(
|
||||
Guid.NewGuid(),
|
||||
"CS2601",
|
||||
"计算机科学 2601 班",
|
||||
TimetableResourceType.Class,
|
||||
2026,
|
||||
Guid.NewGuid(),
|
||||
"计算机科学与技术",
|
||||
Guid.NewGuid(),
|
||||
"计算机学院",
|
||||
null,
|
||||
null,
|
||||
null),
|
||||
null,
|
||||
null,
|
||||
new TimetablePlanDto(
|
||||
Guid.NewGuid(),
|
||||
"正式课表",
|
||||
"V1",
|
||||
SchedulePlanStatus.Published,
|
||||
DateTime.UtcNow,
|
||||
DateTime.UtcNow),
|
||||
[
|
||||
new TimetableSlotDto(
|
||||
1,
|
||||
"第一节",
|
||||
new TimeOnly(8, 0),
|
||||
new TimeOnly(8, 45))
|
||||
],
|
||||
[
|
||||
new TimetableEntryDto(
|
||||
Guid.NewGuid(),
|
||||
Guid.NewGuid(),
|
||||
"TASK-01",
|
||||
"高等数学 01",
|
||||
"MATH101",
|
||||
"高等数学",
|
||||
["张老师"],
|
||||
["计算机科学 2601 班"],
|
||||
"101",
|
||||
"第一教学楼",
|
||||
"主校区",
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
16,
|
||||
WeekPattern.All,
|
||||
null)
|
||||
],
|
||||
[
|
||||
new FlexibleCourseDto(
|
||||
Guid.NewGuid(),
|
||||
"TASK-02",
|
||||
"劳动教育",
|
||||
"LAB101",
|
||||
"劳动教育",
|
||||
1,
|
||||
16,
|
||||
1,
|
||||
16,
|
||||
1,
|
||||
["李老师"],
|
||||
["计算机科学 2601 班"],
|
||||
null)
|
||||
]);
|
||||
|
||||
var bytes = TimetableExcelExporter.Create(timetable);
|
||||
|
||||
using var stream = new MemoryStream(bytes);
|
||||
using var workbook = new XLWorkbook(stream);
|
||||
var sheet = workbook.Worksheet("课表");
|
||||
Assert.Contains("计算机科学 2601 班", sheet.Cell("A1").GetString());
|
||||
Assert.Contains("高等数学", sheet.Cell(5, 2).GetString());
|
||||
Assert.Contains(
|
||||
sheet.CellsUsed(),
|
||||
cell => cell.GetString().Contains("非排时课程"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user