diff --git a/reading-platform-frontend/src/api/school.ts b/reading-platform-frontend/src/api/school.ts
index d5f1b0b..dcff2c8 100644
--- a/reading-platform-frontend/src/api/school.ts
+++ b/reading-platform-frontend/src/api/school.ts
@@ -265,14 +265,22 @@ export const getPackageUsage = () =>
// ==================== 套餐管理(两层结构) ====================
-// 课程包项(对应后端 CourseCollectionResponse.CoursePackageItem)
+// 课程包项(对应后端 CourseCollectionResponse.CoursePackageItem / CoursePackageResponse)
export interface CoursePackageItem {
id: number | string;
name: string;
description?: string;
- gradeLevels: string[];
+ gradeLevels: string[] | string;
courseCount: number;
sortOrder?: number;
+ /** getPackagesByCollection 返回的课程包包含课程列表 */
+ courses?: Array<{
+ id: number;
+ name: string;
+ gradeLevel?: string;
+ sortOrder?: number;
+ scheduleRefData?: string;
+ }>;
}
// 课程套餐(最上层,对应后端 CourseCollectionResponse)
diff --git a/reading-platform-frontend/src/api/teacher.ts b/reading-platform-frontend/src/api/teacher.ts
index 5e91ac7..2b3e61b 100644
--- a/reading-platform-frontend/src/api/teacher.ts
+++ b/reading-platform-frontend/src/api/teacher.ts
@@ -577,8 +577,11 @@ export interface TeacherSchedule {
}
export interface CreateTeacherScheduleDto {
+ name: string; // 计划名称,与学校端 SchedulePlanCreateRequest 一致
classId: number;
courseId: number;
+ coursePackageId?: number; // 课程包 ID
+ lessonType?: string; // 课程类型 (INTRODUCTION/COLLECTIVE/LANGUAGE 等)
scheduledDate?: string;
scheduledTime?: string;
weekDay?: number;
diff --git a/reading-platform-frontend/src/views/teacher/courses/PrepareModeView.vue b/reading-platform-frontend/src/views/teacher/courses/PrepareModeView.vue
index 8f26d2c..1ab5ad9 100644
--- a/reading-platform-frontend/src/views/teacher/courses/PrepareModeView.vue
+++ b/reading-platform-frontend/src/views/teacher/courses/PrepareModeView.vue
@@ -87,36 +87,8 @@
:file-name="previewFileName"
/>
-
-
-
-
- {{ selectedClassInfo?.name || '未选择' }}
-
-
-
-
-
-
-
+
+
@@ -137,6 +109,7 @@ import { translateGradeTags } from '@/utils/tagMaps';
import FilePreviewModal from '@/components/FilePreviewModal.vue';
import PrepareNavigation from './components/PrepareNavigation.vue';
import PreparePreview from './components/PreparePreview.vue';
+import TeacherCreateScheduleModal from '@/views/teacher/schedule/components/TeacherCreateScheduleModal.vue';
const router = useRouter();
const route = useRoute();
@@ -161,9 +134,7 @@ const classes = ref([]);
const selectedClassId = ref();
// 预约上课相关
-const scheduleModalVisible = ref(false);
-const scheduleLoading = ref(false);
-const scheduleDate = ref(undefined);
+const scheduleModalRef = ref>();
// 解析标签(后端可能返回 JSON 字符串或数组)
const parseTags = (val: any): string[] => {
@@ -416,41 +387,26 @@ const showScheduleModal = () => {
message.warning('请先选择班级');
return;
}
- scheduleDate.value = undefined;
- scheduleModalVisible.value = true;
-};
-
-const confirmSchedule = async () => {
- if (!scheduleDate.value) {
- message.warning('请选择计划上课时间');
+ const firstLesson = lessons.value[0];
+ if (!firstLesson) {
+ message.warning('课程数据异常,暂无课程');
return;
}
-
- scheduleLoading.value = true;
- try {
- const teacherId = userStore.user?.id;
- if (!teacherId) {
- message.error('未获取到教师信息,请重新登录');
- scheduleLoading.value = false;
- return;
- }
- const dt = scheduleDate.value!;
- await teacherApi.createLesson({
- courseId: courseId.value,
- classId: selectedClassId.value!,
- teacherId,
- title: course.value.name || '授课',
- lessonDate: dt.format('YYYY-MM-DD'),
- startTime: dt.format('HH:mm'),
- });
-
- message.success('预约成功,可在"上课记录"中查看');
- scheduleModalVisible.value = false;
- } catch (error: any) {
- message.error(error.message || '预约失败');
- } finally {
- scheduleLoading.value = false;
+ const pkgId = parseInt(courseId.value, 10);
+ if (isNaN(pkgId)) {
+ message.warning('课程 ID 无效');
+ return;
}
+ scheduleModalRef.value?.openWithPreset({
+ packageId: pkgId,
+ courseId: firstLesson.id,
+ lessonType: firstLesson.lessonType || 'INTRODUCTION',
+ classId: selectedClassId.value,
+ });
+};
+
+const onScheduleSuccess = () => {
+ message.success('预约成功,可在"我的课表"中查看');
};
const handleExit = () => {
diff --git a/reading-platform-frontend/src/views/teacher/schedule/ScheduleView.vue b/reading-platform-frontend/src/views/teacher/schedule/ScheduleView.vue
index 741147d..5dc95cb 100644
--- a/reading-platform-frontend/src/views/teacher/schedule/ScheduleView.vue
+++ b/reading-platform-frontend/src/views/teacher/schedule/ScheduleView.vue
@@ -129,66 +129,8 @@
-
-
-
-
-
-
- {{ cls.name }}
-
-
-
-
-
-
- {{ course.name }}
-
-
-
-
-
-
-
-
-
-
-
- 单次
- 每周重复
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolPackageController.java b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolPackageController.java
index cfd13ae..0dc71b9 100644
--- a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolPackageController.java
+++ b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolPackageController.java
@@ -37,7 +37,7 @@ public class SchoolPackageController {
@GetMapping
@Operation(summary = "查询租户课程套餐(两层结构-最上层)")
- @RequireRole(UserRole.SCHOOL)
+ @RequireRole({UserRole.SCHOOL, UserRole.TEACHER})
public Result> findTenantCollections() {
Long tenantId = SecurityUtils.getCurrentTenantId();
return Result.success(collectionService.findTenantCollections(tenantId));
@@ -45,7 +45,7 @@ public class SchoolPackageController {
@GetMapping("/{collectionId}/packages")
@Operation(summary = "获取课程套餐下的课程包列表")
- @RequireRole(UserRole.SCHOOL)
+ @RequireRole({UserRole.SCHOOL, UserRole.TEACHER})
public Result> getPackagesByCollection(@PathVariable Long collectionId) {
return Result.success(collectionService.getPackagesByCollection(collectionId));
}
diff --git a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolScheduleController.java b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolScheduleController.java
index c74c445..8d8420b 100644
--- a/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolScheduleController.java
+++ b/reading-platform-java/src/main/java/com/reading/platform/controller/school/SchoolScheduleController.java
@@ -139,6 +139,7 @@ public class SchoolScheduleController {
@GetMapping("/course-packages/{id}/lesson-types")
@Operation(summary = "获取课程包的课程类型列表")
+ @RequireRole({UserRole.SCHOOL, UserRole.TEACHER})
public Result> getCoursePackageLessonTypes(@PathVariable Long id) {
Long tenantId = SecurityUtils.getCurrentTenantId();
return Result.success(schoolScheduleService.getCoursePackageLessonTypes(tenantId, id));
diff --git a/reading-platform-java/src/main/java/com/reading/platform/service/impl/TeacherScheduleServiceImpl.java b/reading-platform-java/src/main/java/com/reading/platform/service/impl/TeacherScheduleServiceImpl.java
index 94bff5f..07168bf 100644
--- a/reading-platform-java/src/main/java/com/reading/platform/service/impl/TeacherScheduleServiceImpl.java
+++ b/reading-platform-java/src/main/java/com/reading/platform/service/impl/TeacherScheduleServiceImpl.java
@@ -120,6 +120,8 @@ public class TeacherScheduleServiceImpl extends ServiceImpl