deepseek
前台 — 路由 (router/index.ts) - my-timetable 路由的角色从 ['Student'] 扩展为 ['Student', 'Teacher'] - 新增 teacher-timetable/:teacherId 路由,用于查看指定教师的课表 前台 — 课表视图 (TimetableView.vue) - 新增 isTeacherView 和 isTeacher 计算属性,区分教师个人课表和查看他人课表 - 教师个人课表:标题显示"我的授课课表",描述改为"展示本人本学期所有授课安排" - 查看他人课表:标题显示"教师课表" - 两种模式均隐藏资源筛选面板,只保留学期选择 - 加载逻辑适配教师模式 API 前台 — 教师档案页 (PersonnelView.vue) - 教师行操作列新增 "课表" 按钮(带日历图标),仅在职教师可点击 - 点击后跳转到该教师的授课课表页面 前台 — 侧边导航 (AdminLayout.vue) - 教师角色可见"我的授课课表"菜单项,与学生的"我的课表"并列
This commit is contained in:
@@ -91,6 +91,45 @@ public sealed class TimetablesController(
|
||||
CancellationToken cancellationToken) =>
|
||||
BuildTimetableAsync(classId, academicTermId, null, cancellationToken);
|
||||
|
||||
[HttpGet("teachers/{teacherId:guid}")]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult> GetTeacherTimetable(
|
||||
Guid teacherId,
|
||||
Guid? academicTermId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await timetableDataService.BuildAsync(
|
||||
TimetableResourceType.Teacher,
|
||||
teacherId,
|
||||
academicTermId,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
cancellationToken);
|
||||
return result is null ? NotFound() : Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("teachers/{teacherId:guid}/export.xlsx")]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult> ExportTeacherTimetable(
|
||||
Guid teacherId,
|
||||
Guid? academicTermId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await timetableDataService.BuildAsync(
|
||||
TimetableResourceType.Teacher,
|
||||
teacherId,
|
||||
academicTermId,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
cancellationToken);
|
||||
if (result is null) return NotFound();
|
||||
return ExcelFile(result);
|
||||
}
|
||||
|
||||
[HttpGet("classes/{classId:guid}/export.xlsx")]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult> ExportClassTimetable(
|
||||
@@ -112,13 +151,14 @@ public sealed class TimetablesController(
|
||||
}
|
||||
|
||||
[HttpGet("mine")]
|
||||
[Authorize(Roles = SystemRoles.Student)]
|
||||
[Authorize(Roles = SystemRoles.Student + "," + SystemRoles.Teacher)]
|
||||
public async Task<ActionResult> GetMyTimetable(
|
||||
Guid? academicTermId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!Guid.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier), out var userId))
|
||||
return Unauthorized();
|
||||
|
||||
var student = await db.Students.AsNoTracking()
|
||||
.Where(x => x.UserId == userId)
|
||||
.Select(x => new
|
||||
@@ -129,30 +169,51 @@ public sealed class TimetablesController(
|
||||
x.Name
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
if (student is null)
|
||||
return Conflict(new ProblemDetails
|
||||
{
|
||||
Title = "学生档案未关联",
|
||||
Detail = "当前登录账号没有关联学生档案,请联系教务管理员。",
|
||||
Status = StatusCodes.Status409Conflict
|
||||
});
|
||||
if (student is not null)
|
||||
{
|
||||
return await BuildTimetableAsync(
|
||||
student.AdministrativeClassId,
|
||||
academicTermId,
|
||||
student.Id,
|
||||
cancellationToken,
|
||||
new TimetableStudentDto(student.StudentNumber, student.Name));
|
||||
}
|
||||
|
||||
return await BuildTimetableAsync(
|
||||
student.AdministrativeClassId,
|
||||
academicTermId,
|
||||
student.Id,
|
||||
cancellationToken,
|
||||
new TimetableStudentDto(student.StudentNumber, student.Name));
|
||||
var teacher = await db.Teachers.AsNoTracking()
|
||||
.Where(x => x.UserId == userId && x.Status == TeacherStatus.Active)
|
||||
.Select(x => new { x.Id })
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
if (teacher is not null)
|
||||
{
|
||||
var result = await timetableDataService.BuildAsync(
|
||||
TimetableResourceType.Teacher,
|
||||
teacher.Id,
|
||||
academicTermId,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
cancellationToken);
|
||||
return result is null ? NotFound() : Ok(result);
|
||||
}
|
||||
|
||||
return Conflict(new ProblemDetails
|
||||
{
|
||||
Title = "档案未关联",
|
||||
Detail = "当前登录账号没有关联教师或学生档案,请联系教务管理员。",
|
||||
Status = StatusCodes.Status409Conflict
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("mine/export.xlsx")]
|
||||
[Authorize(Roles = SystemRoles.Student)]
|
||||
[Authorize(Roles = SystemRoles.Student + "," + SystemRoles.Teacher)]
|
||||
public async Task<ActionResult> ExportMyTimetable(
|
||||
Guid? academicTermId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!Guid.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier), out var userId))
|
||||
return Unauthorized();
|
||||
|
||||
var student = await db.Students.AsNoTracking()
|
||||
.Where(x => x.UserId == userId)
|
||||
.Select(x => new
|
||||
@@ -163,18 +224,41 @@ public sealed class TimetablesController(
|
||||
x.Name
|
||||
})
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
if (student is null) return NotFound();
|
||||
var result = await timetableDataService.BuildAsync(
|
||||
TimetableResourceType.Class,
|
||||
student.AdministrativeClassId,
|
||||
academicTermId,
|
||||
null,
|
||||
false,
|
||||
student.Id,
|
||||
new TimetableStudentDto(student.StudentNumber, student.Name),
|
||||
cancellationToken);
|
||||
if (result is null) return NotFound();
|
||||
return ExcelFile(result);
|
||||
if (student is not null)
|
||||
{
|
||||
var result = await timetableDataService.BuildAsync(
|
||||
TimetableResourceType.Class,
|
||||
student.AdministrativeClassId,
|
||||
academicTermId,
|
||||
null,
|
||||
false,
|
||||
student.Id,
|
||||
new TimetableStudentDto(student.StudentNumber, student.Name),
|
||||
cancellationToken);
|
||||
if (result is null) return NotFound();
|
||||
return ExcelFile(result);
|
||||
}
|
||||
|
||||
var teacher = await db.Teachers.AsNoTracking()
|
||||
.Where(x => x.UserId == userId && x.Status == TeacherStatus.Active)
|
||||
.Select(x => new { x.Id })
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
if (teacher is not null)
|
||||
{
|
||||
var result = await timetableDataService.BuildAsync(
|
||||
TimetableResourceType.Teacher,
|
||||
teacher.Id,
|
||||
academicTermId,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
cancellationToken);
|
||||
if (result is null) return NotFound();
|
||||
return ExcelFile(result);
|
||||
}
|
||||
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
private async Task<ActionResult> BuildTimetableAsync(
|
||||
|
||||
Reference in New Issue
Block a user