diff --git a/src/Jiaowu.Api/Controllers/CoursesController.cs b/src/Jiaowu.Api/Controllers/CoursesController.cs index c7b58d5..4ee00ab 100644 --- a/src/Jiaowu.Api/Controllers/CoursesController.cs +++ b/src/Jiaowu.Api/Controllers/CoursesController.cs @@ -97,6 +97,46 @@ public sealed class CoursesController( return Ok(new PagedResult(items, total, page, pageSize)); } + [HttpGet("options")] + public async Task> GetOptions( + Guid? collegeId = null, + CourseNature? nature = null, + string? keyword = null, + CancellationToken cancellationToken = default) + { + var source = ScopedCourses().AsNoTracking().Where(x => x.IsEnabled); + if (collegeId.HasValue) + source = source.Where(x => x.CollegeId == collegeId.Value); + if (nature.HasValue) + source = source.Where(x => x.Nature == nature.Value); + if (!string.IsNullOrWhiteSpace(keyword)) + { + keyword = keyword.Trim(); + source = source.Where(x => + x.Code.Contains(keyword) || + x.Name.Contains(keyword) || + (x.EnglishName != null && x.EnglishName.Contains(keyword))); + } + + return Ok(await source + .OrderBy(x => x.SortOrder) + .ThenBy(x => x.Code) + .Select(x => new + { + x.Id, + x.Code, + x.Name, + x.CollegeId, + CollegeName = x.College!.Name, + x.CourseCategoryId, + CategoryName = x.CourseCategory != null ? x.CourseCategory.Name : null, + x.Credits, + x.Nature, + x.AssessmentMethod + }) + .ToListAsync(cancellationToken)); + } + [HttpPost] [Authorize(Roles = WriteRoles)] public async Task Create( diff --git a/src/Jiaowu.Api/Controllers/TeacherCourseApplicationsController.cs b/src/Jiaowu.Api/Controllers/TeacherCourseApplicationsController.cs index 30b141b..4be9a3f 100644 --- a/src/Jiaowu.Api/Controllers/TeacherCourseApplicationsController.cs +++ b/src/Jiaowu.Api/Controllers/TeacherCourseApplicationsController.cs @@ -21,6 +21,27 @@ public sealed class TeacherCourseApplicationsController( SystemRoles.AcademicAdmin + "," + SystemRoles.CollegeAdmin; + [HttpGet("course-options")] + [Authorize(Roles = SystemRoles.Teacher)] + public async Task GetCourseOptions(CancellationToken cancellationToken) + { + return Ok(await db.Courses.AsNoTracking() + .Where(x => x.IsEnabled) + .OrderBy(x => x.SortOrder) + .ThenBy(x => x.Code) + .Select(x => new + { + x.Id, + x.Code, + x.Name, + x.CollegeId, + CollegeName = x.College!.Name, + x.Credits, + x.Nature + }) + .ToListAsync(cancellationToken)); + } + [HttpGet("mine")] [Authorize(Roles = SystemRoles.Teacher)] public async Task GetMine( diff --git a/web/src/views/CurriculumView.vue b/web/src/views/CurriculumView.vue index 027e977..781dbcf 100644 --- a/web/src/views/CurriculumView.vue +++ b/web/src/views/CurriculumView.vue @@ -294,12 +294,12 @@ async function deleteCourse(moduleId: string, item: any) { onMounted(async () => { const [optionRes, courseRes] = await Promise.all([ http.get('/curriculum-plans/filter-options'), - http.get('/courses', { params: { page: 1, pageSize: 100, isEnabled: true } }), + http.get('/courses/options'), ]) colleges.value = optionRes.data.colleges majors.value = optionRes.data.majors grades.value = optionRes.data.grades - courses.value = courseRes.data.items + courses.value = courseRes.data if (isCollegeAdmin.value && auth.user?.collegeId) { query.collegeId = auth.user.collegeId } diff --git a/web/src/views/TeachingPreferencesView.vue b/web/src/views/TeachingPreferencesView.vue index 8d47e63..c19d4a1 100644 --- a/web/src/views/TeachingPreferencesView.vue +++ b/web/src/views/TeachingPreferencesView.vue @@ -111,13 +111,11 @@ async function review() { onMounted(async () => { const requests: Promise[] = [http.get('/base-data/terms')] if (isTeacher.value) { - requests.push(http.get('/courses', { - params: { page: 1, pageSize: 100, isEnabled: true }, - })) + requests.push(http.get('/teacher-course-applications/course-options')) } const [termRes, courseRes] = await Promise.all(requests) terms.value = termRes.data - courses.value = courseRes?.data.items ?? [] + courses.value = courseRes?.data ?? [] filters.academicTermId = terms.value.find((item) => item.isCurrent)?.id await load() }) diff --git a/web/src/views/TeachingTasksView.vue b/web/src/views/TeachingTasksView.vue index 73b447e..2ede0e0 100644 --- a/web/src/views/TeachingTasksView.vue +++ b/web/src/views/TeachingTasksView.vue @@ -300,13 +300,13 @@ async function generatePublicTasks() { onMounted(async () => { const [termRes, courseRes, teacherRes, classRes, majorRes] = await Promise.all([ http.get('/base-data/terms'), - http.get('/courses', { params: { page: 1, pageSize: 100, isEnabled: true } }), + http.get('/courses/options'), http.get('/personnel/teachers', { params: { page: 1, pageSize: 100, teacherStatus: 'Active' } }), http.get('/base-data/classes'), http.get('/base-data/majors'), ]) terms.value = termRes.data - courses.value = courseRes.data.items + courses.value = courseRes.data teachers.value = teacherRes.data.items classes.value = classRes.data majors.value = majorRes.data