选课批次:时间窗口、退课截止、学分上限、开放/关闭。

教学班投放:容量、班级范围、全校开放。
学生选退课:容量、重复课程、学分上限、课表冲突校验。
教学班实时名单。
校级、学院级、学生角色分级操作。
SQLite 本地增量升级及演示数据。
MySQL 正式 EF Core 迁移。
Vue 已编译进 wwwroot,单服务运行无需 npm run dev。
学生端和管理端均完成桌面、手机响应式检查。
This commit is contained in:
2026-07-24 15:17:26 +08:00 Unverified
parent bcc4d33bd5
commit 151a22554f
19 changed files with 3972 additions and 6 deletions
+64
View File
@@ -91,6 +91,24 @@ try {
-Uri "http://localhost:5255/api/schedules/plans/$($schedulePlans[0].id)" `
-Headers $headers
}
$selectionRounds = Invoke-RestMethod `
-Uri 'http://localhost:5255/api/course-selections/rounds' `
-Headers $headers
if (@($selectionRounds).Count -lt 1) {
throw 'Development course-selection round was not seeded.'
}
$activeSelectionRound = @($selectionRounds) |
Where-Object { $_.isAvailableNow } |
Select-Object -First 1
if ($null -eq $activeSelectionRound) {
throw 'No course-selection round is open for the smoke test.'
}
$selectionOfferings = Invoke-RestMethod `
-Uri "http://localhost:5255/api/course-selections/rounds/$($activeSelectionRound.id)/offerings" `
-Headers $headers
if (@($selectionOfferings).Count -lt 1) {
throw 'Development course-selection offering was not seeded.'
}
$managedUsers = Invoke-RestMethod -Uri 'http://localhost:5255/api/users' -Headers $headers
$teacherAccount = @($managedUsers) |
Where-Object { $_.userName -eq 'teacher' } |
@@ -162,6 +180,48 @@ try {
"$($scenario.UserName):$($scenario.Scope)"
}
$studentLoginBody = @{
userName = 'student'
password = 'Student@123456'
} | ConvertTo-Json
$studentLogin = Invoke-RestMethod `
-Method Post `
-Uri 'http://localhost:5255/api/auth/login' `
-ContentType 'application/json' `
-Body $studentLoginBody
$studentHeaders = @{ Authorization = "Bearer $($studentLogin.token)" }
$studentOptions = Invoke-RestMethod `
-Uri "http://localhost:5255/api/course-selections/student/options?roundId=$($activeSelectionRound.id)" `
-Headers $studentHeaders
$studentOffering = @($studentOptions.offerings) | Select-Object -First 1
if ($null -eq $studentOffering) {
throw 'Student has no eligible course-selection offering.'
}
if ($studentOffering.enrollmentStatus -ne 'Enrolled') {
$enrollmentBody = @{ offeringId = $studentOffering.id } | ConvertTo-Json
Invoke-RestMethod `
-Method Post `
-Uri 'http://localhost:5255/api/course-selections/student/enrollments' `
-Headers $studentHeaders `
-ContentType 'application/json' `
-Body $enrollmentBody |
Out-Null
}
$studentEnrollments = Invoke-RestMethod `
-Uri "http://localhost:5255/api/course-selections/student/enrollments?academicTermId=$($activeSelectionRound.academicTermId)" `
-Headers $studentHeaders
$activeEnrollments = @($studentEnrollments) |
Where-Object { $_.status -eq 'Enrolled' }
if ($activeEnrollments.Count -lt 1) {
throw 'Student course enrollment was not persisted.'
}
$selectionRoster = Invoke-RestMethod `
-Uri "http://localhost:5255/api/course-selections/offerings/$($studentOffering.id)/roster" `
-Headers $headers
if ($selectionRoster.enrolledCount -lt 1) {
throw 'Course-selection roster did not include the selected student.'
}
$frontend = Invoke-WebRequest -Uri 'http://localhost:5255/' -TimeoutSec 5
$spaFallback = Invoke-WebRequest -Uri 'http://localhost:5255/base-data' -TimeoutSec 5
$unknownApiParameters = @{
@@ -186,6 +246,10 @@ try {
TeachingTasks = $teachingTasks.total
Schedules = @($schedulePlans).Count
ScheduleEntries = if ($null -ne $scheduleDetail) { @($scheduleDetail.entries).Count } else { 0 }
SelectionRounds = @($selectionRounds).Count
SelectionOfferings = @($selectionOfferings).Count
StudentEnrollments = $activeEnrollments.Count
RosterStudents = $selectionRoster.enrolledCount
AccessUpdate = $true
ScopeChecks = $scopeChecks -join ', '
StaticIndex = $frontend.Content.Contains('明序教务管理系统')