接口同步

This commit is contained in:
zhonghua 2026-03-11 16:27:37 +08:00
parent 271e02032c
commit 128b89241e
10 changed files with 310 additions and 258 deletions

View File

@ -1,4 +1,5 @@
import { readingApi } from "./client"; import { readingApi } from "./client";
const { http } = require("./index");
import type { import type {
ResultListCourseLesson, ResultListCourseLesson,
CourseLesson as ApiCourseLesson, CourseLesson as ApiCourseLesson,
@ -68,13 +69,8 @@ export interface CreateStepData {
// ==================== 超管端 API ==================== // ==================== 超管端 API ====================
// 获取课程列表(系统课程课时) // 获取课程列表(系统课程课时)
export function getLessonList(courseId: number) {
return readingApi.getLessons1(courseId).then((res) => {
const wrapped = res as ResultListCourseLesson;
return wrapped.data?.items ?? [];
});
}
export const getLessonList = readingApi.getLessons1;
// 获取课程详情 // 获取课程详情
export function getLessonDetail(courseId: number, lessonId: number) { export function getLessonDetail(courseId: number, lessonId: number) {
return readingApi return readingApi
@ -100,7 +96,6 @@ export function updateLesson(
data: Partial<CreateLessonData>, data: Partial<CreateLessonData>,
) { ) {
// Orval 接口需要同时提供 courseId 和 lessonId这里仅有 lessonId 时保留旧实现 // Orval 接口需要同时提供 courseId 和 lessonId这里仅有 lessonId 时保留旧实现
const { http } = require("./index");
return http.put(`/api/v1/admin/courses/0/lessons/${lessonId}`, data); return http.put(`/api/v1/admin/courses/0/lessons/${lessonId}`, data);
} }
@ -111,7 +106,6 @@ export function deleteLesson(courseId: number, lessonId: number) {
// 重新排序课程 // 重新排序课程
export function reorderLessons(courseId: number, lessonIds: number[]) { export function reorderLessons(courseId: number, lessonIds: number[]) {
const { http } = require("./index");
return http.put(`/api/v1/admin/courses/${courseId}/lessons/reorder`, { return http.put(`/api/v1/admin/courses/${courseId}/lessons/reorder`, {
lessonIds, lessonIds,
}); });
@ -121,7 +115,6 @@ export function reorderLessons(courseId: number, lessonIds: number[]) {
// 获取环节列表 // 获取环节列表
export function getStepList(courseId: number, lessonId: number) { export function getStepList(courseId: number, lessonId: number) {
const { http } = require("./index");
return http.get( return http.get(
`/api/v1/admin/courses/${courseId}/lessons/${lessonId}/steps`, `/api/v1/admin/courses/${courseId}/lessons/${lessonId}/steps`,
); );
@ -133,7 +126,6 @@ export function createStep(
lessonId: number, lessonId: number,
data: CreateStepData, data: CreateStepData,
) { ) {
const { http } = require("./index");
return http.post( return http.post(
`/api/v1/admin/courses/${courseId}/lessons/${lessonId}/steps`, `/api/v1/admin/courses/${courseId}/lessons/${lessonId}/steps`,
data, data,
@ -142,13 +134,11 @@ export function createStep(
// 更新环节 // 更新环节
export function updateStep(stepId: number, data: Partial<CreateStepData>) { export function updateStep(stepId: number, data: Partial<CreateStepData>) {
const { http } = require("./index");
return http.put(`/api/v1/admin/courses/0/lessons/steps/${stepId}`, data); return http.put(`/api/v1/admin/courses/0/lessons/steps/${stepId}`, data);
} }
// 删除环节 // 删除环节
export function deleteStep(courseId: number, lessonId: number, stepId: number) { export function deleteStep(courseId: number, lessonId: number, stepId: number) {
const { http } = require("./index");
return http.delete( return http.delete(
`/api/v1/admin/courses/${courseId}/lessons/steps/${stepId}`, `/api/v1/admin/courses/${courseId}/lessons/steps/${stepId}`,
); );
@ -160,7 +150,6 @@ export function reorderSteps(
lessonId: number, lessonId: number,
stepIds: number[], stepIds: number[],
) { ) {
const { http } = require("./index");
return http.put( return http.put(
`/admin/courses/${courseId}/lessons/${lessonId}/steps/reorder`, `/admin/courses/${courseId}/lessons/${lessonId}/steps/reorder`,
{ stepIds }, { stepIds },

View File

@ -1,5 +1,10 @@
import { http } from "./index"; import { http } from "./index";
import { readingApi, UnwrapResult, ApiResultOf, GetPackages1Result } from "./client"; import {
readingApi,
UnwrapResult,
ApiResultOf,
GetPackages1Result,
} from "./client";
// ==================== 套餐管理 ==================== // ==================== 套餐管理 ====================
@ -48,16 +53,10 @@ export interface CreatePackageData {
gradeLevels: string[]; gradeLevels: string[];
} }
type AdminPackageResult = UnwrapResult<ApiResultOf<"getPackage1">> type AdminPackageResult = UnwrapResult<ApiResultOf<"getPackage1">>;
type AdminPackageListResult = GetPackages1Result
// 获取套餐列表(管理员端) // 获取套餐列表(管理员端)
export function getPackageList( export const getPackageList = readingApi.getPackages1;
params?: PackageListParams,
): Promise<AdminPackageListResult> {
return readingApi.getPackages1(params as any).then((res) => res.data as any);
}
// 获取套餐详情(管理员端) // 获取套餐详情(管理员端)
export function getPackageDetail(id: number): Promise<AdminPackageResult> { export function getPackageDetail(id: number): Promise<AdminPackageResult> {
return readingApi.getPackage1(id).then((res) => res.data as any); return readingApi.getPackage1(id).then((res) => res.data as any);

View File

@ -87,7 +87,7 @@ export const getLibraries = (params?: {
readingApi.getLibraries(params as any).then((res) => { readingApi.getLibraries(params as any).then((res) => {
const list = (res.data as any as ResourceLibrary[]) || []; const list = (res.data as any as ResourceLibrary[]) || [];
const page = params?.page ?? 1; const page = params?.page ?? 1;
const pageSize = params?.pageSize ?? list.length || 10; const pageSize = params?.pageSize ?? (list.length || 10);
return { return {
items: list, items: list,
total: list.length, total: list.length,

View File

@ -114,7 +114,7 @@ export function updateSchoolCourseLesson(
data: Partial<SchoolCourseLesson>, data: Partial<SchoolCourseLesson>,
) { ) {
return http.put( return http.put(
`/school/school-courses/${schoolCourseId}/lessons/${lessonId}`, `/api/v1/school/school-courses/${schoolCourseId}/lessons/${lessonId}`,
data, data,
); );
} }
@ -191,7 +191,7 @@ export function updateTeacherSchoolCourseLesson(
data: Partial<SchoolCourseLesson>, data: Partial<SchoolCourseLesson>,
) { ) {
return http.put( return http.put(
`/teacher/school-courses/${schoolCourseId}/lessons/${lessonId}`, `/api/v1/teacher/school-courses/${schoolCourseId}/lessons/${lessonId}`,
data, data,
); );
} }

View File

@ -158,41 +158,43 @@ export interface PackageUsage {
export const getTeachers = (params: TeacherQueryParams) => export const getTeachers = (params: TeacherQueryParams) =>
http.get<{ items: Teacher[]; total: number; page: number; pageSize: number }>( http.get<{ items: Teacher[]; total: number; page: number; pageSize: number }>(
"/school/teachers", "/api/v1/school/teachers",
{ params }, { params },
); );
export const getTeacher = (id: number) => export const getTeacher = (id: number) =>
http.get<Teacher>(`/school/teachers/${id}`); http.get<Teacher>(`/api/v1/school/teachers/${id}`);
export const createTeacher = (data: CreateTeacherDto) => export const createTeacher = (data: CreateTeacherDto) =>
http.post<Teacher>("/school/teachers", data); http.post<Teacher>("/api/v1/school/teachers", data);
export const updateTeacher = (id: number, data: Partial<CreateTeacherDto>) => export const updateTeacher = (id: number, data: Partial<CreateTeacherDto>) =>
http.put<Teacher>(`/school/teachers/${id}`, data); http.put<Teacher>(`/api/v1/school/teachers/${id}`, data);
export const deleteTeacher = (id: number) => export const deleteTeacher = (id: number) =>
http.delete(`/api/v1/school/teachers/${id}`); http.delete(`/api/v1/school/teachers/${id}`);
export const resetTeacherPassword = (id: number) => export const resetTeacherPassword = (id: number) =>
http.post<{ tempPassword: string }>(`/school/teachers/${id}/reset-password`); http.post<{ tempPassword: string }>(
`/api/v1/school/teachers/${id}/reset-password`,
);
// ==================== 学生管理 ==================== // ==================== 学生管理 ====================
export const getStudents = (params: StudentQueryParams) => export const getStudents = (params: StudentQueryParams) =>
http.get<{ items: Student[]; total: number; page: number; pageSize: number }>( http.get<{ items: Student[]; total: number; page: number; pageSize: number }>(
"/school/students", "/api/v1/school/students",
{ params }, { params },
); );
export const getStudent = (id: number) => export const getStudent = (id: number) =>
http.get<Student>(`/school/students/${id}`); http.get<Student>(`/api/v1/school/students/${id}`);
export const createStudent = (data: CreateStudentDto) => export const createStudent = (data: CreateStudentDto) =>
http.post<Student>("/school/students", data); http.post<Student>("/api/v1/school/students", data);
export const updateStudent = (id: number, data: Partial<CreateStudentDto>) => export const updateStudent = (id: number, data: Partial<CreateStudentDto>) =>
http.put<Student>(`/school/students/${id}`, data); http.put<Student>(`/api/v1/school/students/${id}`, data);
export const deleteStudent = (id: number) => export const deleteStudent = (id: number) =>
http.delete(`/api/v1/school/students/${id}`); http.delete(`/api/v1/school/students/${id}`);
@ -212,7 +214,7 @@ export interface ImportTemplate {
} }
export const getStudentImportTemplate = () => export const getStudentImportTemplate = () =>
http.get<ImportTemplate>("/school/students/import/template"); http.get<ImportTemplate>("/api/v1/school/students/import/template");
export const importStudents = ( export const importStudents = (
file: File, file: File,
@ -232,16 +234,16 @@ export const importStudents = (
// ==================== 班级管理 ==================== // ==================== 班级管理 ====================
export const getClasses = () => http.get<ClassInfo[]>("/school/classes"); export const getClasses = () => http.get<ClassInfo[]>("/api/v1/school/classes");
export const getClass = (id: number) => export const getClass = (id: number) =>
http.get<ClassInfo>(`/school/classes/${id}`); http.get<ClassInfo>(`/api/v1/school/classes/${id}`);
export const createClass = (data: CreateClassDto) => export const createClass = (data: CreateClassDto) =>
http.post<ClassInfo>("/school/classes", data); http.post<ClassInfo>("/api/v1/school/classes", data);
export const updateClass = (id: number, data: Partial<CreateClassDto>) => export const updateClass = (id: number, data: Partial<CreateClassDto>) =>
http.put<ClassInfo>(`/school/classes/${id}`, data); http.put<ClassInfo>(`/api/v1/school/classes/${id}`, data);
export const deleteClass = (id: number) => export const deleteClass = (id: number) =>
http.delete(`/api/v1/school/classes/${id}`); http.delete(`/api/v1/school/classes/${id}`);
@ -256,35 +258,37 @@ export const getClassStudents = (
page: number; page: number;
pageSize: number; pageSize: number;
class?: ClassInfo; class?: ClassInfo;
}>(`/school/classes/${classId}/students`, { params }); }>(`/api/v1/school/classes/${classId}/students`, { params });
// ==================== 统计数据 ==================== // ==================== 统计数据 ====================
export const getSchoolStats = () => http.get<SchoolStats>("/school/stats"); export const getSchoolStats = () =>
http.get<SchoolStats>("/api/v1/school/stats");
export const getActiveTeachers = (limit?: number) => export const getActiveTeachers = (limit?: number) =>
http.get<Array<{ id: number; name: string; lessonCount: number }>>( http.get<Array<{ id: number; name: string; lessonCount: number }>>(
"/school/stats/teachers", "/api/v1/school/stats/teachers",
{ params: { limit } }, { params: { limit } },
); );
export const getCourseUsageStats = () => export const getCourseUsageStats = () =>
http.get<Array<{ courseId: number; courseName: string; usageCount: number }>>( http.get<Array<{ courseId: number; courseName: string; usageCount: number }>>(
"/school/stats/courses", "/api/v1/school/stats/courses",
); );
export const getRecentActivities = (limit?: number) => export const getRecentActivities = (limit?: number) =>
http.get<Array<{ id: number; type: string; title: string; time: string }>>( http.get<Array<{ id: number; type: string; title: string; time: string }>>(
"/school/stats/activities", "/api/v1/school/stats/activities",
{ params: { limit } }, { params: { limit } },
); );
// ==================== 套餐信息旧API保留兼容 ==================== // ==================== 套餐信息旧API保留兼容 ====================
export const getPackageInfo = () => http.get<PackageInfo>("/school/package"); export const getPackageInfo = () =>
http.get<PackageInfo>("/api/v1/school/package");
export const getPackageUsage = () => export const getPackageUsage = () =>
http.get<PackageUsage>("/school/package/usage"); http.get<PackageUsage>("/api/v1/school/package/usage");
// ==================== 套餐管理新API ==================== // ==================== 套餐管理新API ====================
@ -326,10 +330,10 @@ export interface RenewPackageDto {
} }
export const getTenantPackages = () => export const getTenantPackages = () =>
http.get<TenantPackage[]>("/school/packages"); http.get<TenantPackage[]>("/api/v1/school/packages");
export const renewPackage = (packageId: number, data: RenewPackageDto) => export const renewPackage = (packageId: number, data: RenewPackageDto) =>
http.post<TenantPackage>(`/school/packages/${packageId}/renew`, data); http.post<TenantPackage>(`/api/v1/school/packages/${packageId}/renew`, data);
// ==================== 系统设置 ==================== // ==================== 系统设置 ====================
@ -355,25 +359,26 @@ export interface UpdateSettingsDto {
notifyOnGrowth?: boolean; notifyOnGrowth?: boolean;
} }
export const getSettings = () => http.get<SystemSettings>("/school/settings"); export const getSettings = () =>
http.get<SystemSettings>("/api/v1/school/settings");
export const updateSettings = (data: UpdateSettingsDto) => export const updateSettings = (data: UpdateSettingsDto) =>
http.put<SystemSettings>("/school/settings", data); http.put<SystemSettings>("/api/v1/school/settings", data);
// ==================== 课程管理 ==================== // ==================== 课程管理 ====================
export const getSchoolCourses = () => http.get<any[]>("/school/courses"); export const getSchoolCourses = () => http.get<any[]>("/api/v1/school/courses");
export const getSchoolCourse = (id: number) => export const getSchoolCourse = (id: number) =>
http.get<any>(`/school/courses/${id}`); http.get<any>(`/api/v1/school/courses/${id}`);
// ==================== 班级教师管理 ==================== // ==================== 班级教师管理 ====================
export const getClassTeachers = (classId: number) => export const getClassTeachers = (classId: number) =>
http.get<ClassTeacher[]>(`/school/classes/${classId}/teachers`); http.get<ClassTeacher[]>(`/api/v1/school/classes/${classId}/teachers`);
export const addClassTeacher = (classId: number, data: AddClassTeacherDto) => export const addClassTeacher = (classId: number, data: AddClassTeacherDto) =>
http.post<ClassTeacher>(`/school/classes/${classId}/teachers`, data); http.post<ClassTeacher>(`/api/v1/school/classes/${classId}/teachers`, data);
export const updateClassTeacher = ( export const updateClassTeacher = (
classId: number, classId: number,
@ -381,25 +386,27 @@ export const updateClassTeacher = (
data: UpdateClassTeacherDto, data: UpdateClassTeacherDto,
) => ) =>
http.put<ClassTeacher>( http.put<ClassTeacher>(
`/school/classes/${classId}/teachers/${teacherId}`, `/api/v1/school/classes/${classId}/teachers/${teacherId}`,
data, data,
); );
export const removeClassTeacher = (classId: number, teacherId: number) => export const removeClassTeacher = (classId: number, teacherId: number) =>
http.delete<{ message: string }>( http.delete<{ message: string }>(
`/school/classes/${classId}/teachers/${teacherId}`, `/api/v1/school/classes/${classId}/teachers/${teacherId}`,
); );
// ==================== 学生调班 ==================== // ==================== 学生调班 ====================
export const transferStudent = (studentId: number, data: TransferStudentDto) => export const transferStudent = (studentId: number, data: TransferStudentDto) =>
http.post<{ message: string }>( http.post<{ message: string }>(
`/school/students/${studentId}/transfer`, `/api/v1/school/students/${studentId}/transfer`,
data, data,
); );
export const getStudentClassHistory = (studentId: number) => export const getStudentClassHistory = (studentId: number) =>
http.get<StudentClassHistory[]>(`/school/students/${studentId}/history`); http.get<StudentClassHistory[]>(
`/api/v1/school/students/${studentId}/history`,
);
// ==================== 排课管理 ==================== // ==================== 排课管理 ====================
@ -479,22 +486,22 @@ export const getSchedules = (params?: ScheduleQueryParams) =>
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>("/school/schedules", { params }); }>("/api/v1/school/schedules", { params });
export const getSchedule = (id: number) => export const getSchedule = (id: number) =>
http.get<SchedulePlan>(`/school/schedules/${id}`); http.get<SchedulePlan>(`/api/v1/school/schedules/${id}`);
export const createSchedule = (data: CreateScheduleDto) => export const createSchedule = (data: CreateScheduleDto) =>
http.post<SchedulePlan>("/school/schedules", data); http.post<SchedulePlan>("/api/v1/school/schedules", data);
export const updateSchedule = (id: number, data: UpdateScheduleDto) => export const updateSchedule = (id: number, data: UpdateScheduleDto) =>
http.put<SchedulePlan>(`/school/schedules/${id}`, data); http.put<SchedulePlan>(`/api/v1/school/schedules/${id}`, data);
export const cancelSchedule = (id: number) => export const cancelSchedule = (id: number) =>
http.delete<{ message: string }>(`/school/schedules/${id}`); http.delete<{ message: string }>(`/api/v1/school/schedules/${id}`);
export const getTimetable = (params: TimetableQueryParams) => export const getTimetable = (params: TimetableQueryParams) =>
http.get<TimetableItem[]>("/school/schedules/timetable", { params }); http.get<TimetableItem[]>("/api/v1/school/schedules/timetable", { params });
export interface BatchScheduleItem { export interface BatchScheduleItem {
classId: number; classId: number;
@ -513,7 +520,7 @@ export interface BatchCreateResult {
} }
export const batchCreateSchedules = (schedules: BatchScheduleItem[]) => export const batchCreateSchedules = (schedules: BatchScheduleItem[]) =>
http.post<BatchCreateResult>("/school/schedules/batch", { schedules }); http.post<BatchCreateResult>("/api/v1/school/schedules/batch", { schedules });
// ==================== 趋势与分布统计 ==================== // ==================== 趋势与分布统计 ====================
@ -529,12 +536,14 @@ export interface CourseDistributionItem {
} }
export const getLessonTrend = (months?: number) => export const getLessonTrend = (months?: number) =>
http.get<LessonTrendItem[]>("/school/stats/lesson-trend", { http.get<LessonTrendItem[]>("/api/v1/school/stats/lesson-trend", {
params: { months }, params: { months },
}); });
export const getCourseDistribution = () => export const getCourseDistribution = () =>
http.get<CourseDistributionItem[]>("/school/stats/course-distribution"); http.get<CourseDistributionItem[]>(
"/api/v1/school/stats/course-distribution",
);
// ==================== 数据导出 ==================== // ==================== 数据导出 ====================
@ -668,24 +677,29 @@ export interface ApplyTemplateDto {
export const getScheduleTemplates = (params?: { export const getScheduleTemplates = (params?: {
classId?: number; classId?: number;
courseId?: number; courseId?: number;
}) => http.get<ScheduleTemplate[]>("/school/schedule-templates", { params }); }) =>
http.get<ScheduleTemplate[]>("/api/v1/school/schedule-templates", { params });
export const getScheduleTemplate = (id: number) => export const getScheduleTemplate = (id: number) =>
http.get<ScheduleTemplate>(`/school/schedule-templates/${id}`); http.get<ScheduleTemplate>(`/api/v1/school/schedule-templates/${id}`);
export const createScheduleTemplate = (data: CreateScheduleTemplateDto) => export const createScheduleTemplate = (data: CreateScheduleTemplateDto) =>
http.post<ScheduleTemplate>("/school/schedule-templates", data); http.post<ScheduleTemplate>("/api/v1/school/schedule-templates", data);
export const updateScheduleTemplate = ( export const updateScheduleTemplate = (
id: number, id: number,
data: UpdateScheduleTemplateDto, data: UpdateScheduleTemplateDto,
) => http.put<ScheduleTemplate>(`/school/schedule-templates/${id}`, data); ) =>
http.put<ScheduleTemplate>(`/api/v1/school/schedule-templates/${id}`, data);
export const deleteScheduleTemplate = (id: number) => export const deleteScheduleTemplate = (id: number) =>
http.delete<{ message: string }>(`/school/schedule-templates/${id}`); http.delete<{ message: string }>(`/api/v1/school/schedule-templates/${id}`);
export const applyScheduleTemplate = (id: number, data: ApplyTemplateDto) => export const applyScheduleTemplate = (id: number, data: ApplyTemplateDto) =>
http.post<SchedulePlan>(`/school/schedule-templates/${id}/apply`, data); http.post<SchedulePlan>(
`/api/v1/school/schedule-templates/${id}/apply`,
data,
);
// ==================== 操作日志 ==================== // ==================== 操作日志 ====================
@ -723,15 +737,15 @@ export const getOperationLogs = (params?: {
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>("/school/operation-logs", { params }); }>("/api/v1/school/operation-logs", { params });
export const getOperationLogStats = (startDate?: string, endDate?: string) => export const getOperationLogStats = (startDate?: string, endDate?: string) =>
http.get<OperationLogStats>("/school/operation-logs/stats", { http.get<OperationLogStats>("/api/v1/school/operation-logs/stats", {
params: { startDate, endDate }, params: { startDate, endDate },
}); });
export const getOperationLogById = (id: number) => export const getOperationLogById = (id: number) =>
http.get<OperationLog>(`/school/operation-logs/${id}`); http.get<OperationLog>(`/api/v1/school/operation-logs/${id}`);
// ==================== 任务模板 API ==================== // ==================== 任务模板 API ====================
@ -784,22 +798,24 @@ export const getTaskTemplates = (params?: {
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>("/school/task-templates", { params }); }>("/api/v1/school/task-templates", { params });
export const getTaskTemplate = (id: number) => export const getTaskTemplate = (id: number) =>
http.get<TaskTemplate>(`/school/task-templates/${id}`); http.get<TaskTemplate>(`/api/v1/school/task-templates/${id}`);
export const getDefaultTaskTemplate = (taskType: string) => export const getDefaultTaskTemplate = (taskType: string) =>
http.get<TaskTemplate | null>(`/school/task-templates/default/${taskType}`); http.get<TaskTemplate | null>(
`/api/v1/school/task-templates/default/${taskType}`,
);
export const createTaskTemplate = (data: CreateTaskTemplateDto) => export const createTaskTemplate = (data: CreateTaskTemplateDto) =>
http.post<TaskTemplate>("/school/task-templates", data); http.post<TaskTemplate>("/api/v1/school/task-templates", data);
export const updateTaskTemplate = (id: number, data: UpdateTaskTemplateDto) => export const updateTaskTemplate = (id: number, data: UpdateTaskTemplateDto) =>
http.put<TaskTemplate>(`/school/task-templates/${id}`, data); http.put<TaskTemplate>(`/api/v1/school/task-templates/${id}`, data);
export const deleteTaskTemplate = (id: number) => export const deleteTaskTemplate = (id: number) =>
http.delete<{ message: string }>(`/school/task-templates/${id}`); http.delete<{ message: string }>(`/api/v1/school/task-templates/${id}`);
// ==================== 任务统计 API ==================== // ==================== 任务统计 API ====================
@ -838,16 +854,17 @@ export interface MonthlyTaskStats {
rate: number; rate: number;
} }
export const getTaskStats = () => http.get<TaskStats>("/school/tasks/stats"); export const getTaskStats = () =>
http.get<TaskStats>("/api/v1/school/tasks/stats");
export const getTaskStatsByType = () => export const getTaskStatsByType = () =>
http.get<TaskStatsByType>("/school/tasks/stats/by-type"); http.get<TaskStatsByType>("/api/v1/school/tasks/stats/by-type");
export const getTaskStatsByClass = () => export const getTaskStatsByClass = () =>
http.get<TaskStatsByClass[]>("/school/tasks/stats/by-class"); http.get<TaskStatsByClass[]>("/api/v1/school/tasks/stats/by-class");
export const getMonthlyTaskStats = (months?: number) => export const getMonthlyTaskStats = (months?: number) =>
http.get<MonthlyTaskStats[]>("/school/tasks/stats/monthly", { http.get<MonthlyTaskStats[]>("/api/v1/school/tasks/stats/monthly", {
params: { months }, params: { months },
}); });
@ -920,24 +937,25 @@ export const getSchoolTasks = (params?: {
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>("/school/tasks", { params }); }>("/api/v1/school/tasks", { params });
export const getSchoolTask = (id: number) => export const getSchoolTask = (id: number) =>
http.get<SchoolTask>(`/school/tasks/${id}`); http.get<SchoolTask>(`/api/v1/school/tasks/${id}`);
export const createSchoolTask = (data: CreateSchoolTaskDto) => export const createSchoolTask = (data: CreateSchoolTaskDto) =>
http.post<SchoolTask>("/school/tasks", data); http.post<SchoolTask>("/api/v1/school/tasks", data);
export const updateSchoolTask = (id: number, data: UpdateSchoolTaskDto) => export const updateSchoolTask = (id: number, data: UpdateSchoolTaskDto) =>
http.put<SchoolTask>(`/school/tasks/${id}`, data); http.put<SchoolTask>(`/api/v1/school/tasks/${id}`, data);
export const deleteSchoolTask = (id: number) => export const deleteSchoolTask = (id: number) =>
http.delete<{ message: string }>(`/school/tasks/${id}`); http.delete<{ message: string }>(`/api/v1/school/tasks/${id}`);
export const getSchoolTaskCompletions = (taskId: number) => export const getSchoolTaskCompletions = (taskId: number) =>
http.get<TaskCompletion[]>(`/school/tasks/${taskId}/completions`); http.get<TaskCompletion[]>(`/api/v1/school/tasks/${taskId}/completions`);
export const getSchoolClasses = () => http.get<ClassInfo[]>("/school/classes"); export const getSchoolClasses = () =>
http.get<ClassInfo[]>("/api/v1/school/classes");
// ==================== 数据报告 API ==================== // ==================== 数据报告 API ====================
@ -976,16 +994,16 @@ export interface StudentReport {
} }
export const getReportOverview = () => export const getReportOverview = () =>
http.get<ReportOverview>("/school/reports/overview"); http.get<ReportOverview>("/api/v1/school/reports/overview");
export const getTeacherReports = () => export const getTeacherReports = () =>
http.get<TeacherReport[]>("/school/reports/teachers"); http.get<TeacherReport[]>("/api/v1/school/reports/teachers");
export const getCourseReports = () => export const getCourseReports = () =>
http.get<CourseReport[]>("/school/reports/courses"); http.get<CourseReport[]>("/api/v1/school/reports/courses");
export const getStudentReports = () => export const getStudentReports = () =>
http.get<StudentReport[]>("/school/reports/students"); http.get<StudentReport[]>("/api/v1/school/reports/students");
// ==================== 家长管理 ==================== // ==================== 家长管理 ====================
@ -1040,41 +1058,43 @@ export interface AddChildDto {
export const getParents = (params?: ParentQueryParams) => export const getParents = (params?: ParentQueryParams) =>
http.get<{ items: Parent[]; total: number; page: number; pageSize: number }>( http.get<{ items: Parent[]; total: number; page: number; pageSize: number }>(
"/school/parents", "/api/v1/school/parents",
{ params }, { params },
); );
export const getParent = (id: number) => export const getParent = (id: number) =>
http.get<Parent>(`/school/parents/${id}`); http.get<Parent>(`/api/v1/school/parents/${id}`);
export const createParent = (data: CreateParentDto) => export const createParent = (data: CreateParentDto) =>
http.post<Parent>("/school/parents", data); http.post<Parent>("/api/v1/school/parents", data);
export const updateParent = (id: number, data: UpdateParentDto) => export const updateParent = (id: number, data: UpdateParentDto) =>
http.put<Parent>(`/school/parents/${id}`, data); http.put<Parent>(`/api/v1/school/parents/${id}`, data);
export const deleteParent = (id: number) => export const deleteParent = (id: number) =>
http.delete<{ message: string }>(`/school/parents/${id}`); http.delete<{ message: string }>(`/api/v1/school/parents/${id}`);
export const resetParentPassword = (id: number) => export const resetParentPassword = (id: number) =>
http.post<{ tempPassword: string }>(`/school/parents/${id}/reset-password`); http.post<{ tempPassword: string }>(
`/api/v1/school/parents/${id}/reset-password`,
);
export const getParentChildren = async ( export const getParentChildren = async (
parentId: number, parentId: number,
): Promise<ParentChild[]> => { ): Promise<ParentChild[]> => {
const parent = await http.get<Parent & { children: ParentChild[] }>( const parent = await http.get<Parent & { children: ParentChild[] }>(
`/school/parents/${parentId}`, `/api/v1/school/parents/${parentId}`,
); );
return parent.children || []; return parent.children || [];
}; };
export const addChildToParent = (parentId: number, data: AddChildDto) => export const addChildToParent = (parentId: number, data: AddChildDto) =>
http.post<ParentChild>( http.post<ParentChild>(
`/school/parents/${parentId}/children/${data.studentId}`, `/api/v1/school/parents/${parentId}/children/${data.studentId}`,
{ relationship: data.relationship }, { relationship: data.relationship },
); );
export const removeChildFromParent = (parentId: number, studentId: number) => export const removeChildFromParent = (parentId: number, studentId: number) =>
http.delete<{ message: string }>( http.delete<{ message: string }>(
`/school/parents/${parentId}/children/${studentId}`, `/api/v1/school/parents/${parentId}/children/${studentId}`,
); );

View File

@ -92,11 +92,12 @@ export const getTasks = (params?: {
keyword?: string; keyword?: string;
}) => }) =>
http.get<{ items: Task[]; total: number; page: number; pageSize: number }>( http.get<{ items: Task[]; total: number; page: number; pageSize: number }>(
"/school/tasks", "/api/v1/school/tasks",
{ params }, { params },
); );
export const getTask = (id: number) => http.get<Task>(`/school/tasks/${id}`); export const getTask = (id: number) =>
http.get<Task>(`/api/v1/school/tasks/${id}`);
export const getTaskCompletions = ( export const getTaskCompletions = (
taskId: number, taskId: number,
@ -111,13 +112,13 @@ export const getTaskCompletions = (
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>(`/school/tasks/${taskId}/completions`, { params }); }>(`/api/v1/school/tasks/${taskId}/completions`, { params });
export const createTask = (data: CreateTaskDto) => export const createTask = (data: CreateTaskDto) =>
http.post<Task>("/school/tasks", data); http.post<Task>("/api/v1/school/tasks", data);
export const updateTask = (id: number, data: UpdateTaskDto) => export const updateTask = (id: number, data: UpdateTaskDto) =>
http.put<Task>(`/school/tasks/${id}`, data); http.put<Task>(`/api/v1/school/tasks/${id}`, data);
export const deleteTask = (id: number) => export const deleteTask = (id: number) =>
http.delete(`/api/v1/school/tasks/${id}`); http.delete(`/api/v1/school/tasks/${id}`);
@ -128,7 +129,7 @@ export const updateTaskCompletion = (
data: UpdateCompletionDto, data: UpdateCompletionDto,
) => ) =>
http.put<TaskCompletion>( http.put<TaskCompletion>(
`/school/tasks/${taskId}/completions/${studentId}`, `/api/v1/school/tasks/${taskId}/completions/${studentId}`,
data, data,
); );
@ -145,12 +146,12 @@ export const getTeacherTasks = (params?: {
keyword?: string; keyword?: string;
}) => }) =>
http.get<{ items: Task[]; total: number; page: number; pageSize: number }>( http.get<{ items: Task[]; total: number; page: number; pageSize: number }>(
"/teacher/tasks", "/api/v1/teacher/tasks",
{ params }, { params },
); );
export const getTeacherTask = (id: number) => export const getTeacherTask = (id: number) =>
http.get<Task>(`/teacher/tasks/${id}`); http.get<Task>(`/api/v1/teacher/tasks/${id}`);
export const getTeacherTaskCompletions = ( export const getTeacherTaskCompletions = (
taskId: number, taskId: number,
@ -165,13 +166,13 @@ export const getTeacherTaskCompletions = (
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>(`/teacher/tasks/${taskId}/completions`, { params }); }>(`/api/v1/teacher/tasks/${taskId}/completions`, { params });
export const createTeacherTask = (data: CreateTaskDto) => export const createTeacherTask = (data: CreateTaskDto) =>
http.post<Task>("/teacher/tasks", data); http.post<Task>("/api/v1/teacher/tasks", data);
export const updateTeacherTask = (id: number, data: UpdateTaskDto) => export const updateTeacherTask = (id: number, data: UpdateTaskDto) =>
http.put<Task>(`/teacher/tasks/${id}`, data); http.put<Task>(`/api/v1/teacher/tasks/${id}`, data);
export const deleteTeacherTask = (id: number) => export const deleteTeacherTask = (id: number) =>
http.delete(`/api/v1/teacher/tasks/${id}`); http.delete(`/api/v1/teacher/tasks/${id}`);
@ -182,7 +183,7 @@ export const updateTeacherTaskCompletion = (
data: UpdateCompletionDto, data: UpdateCompletionDto,
) => ) =>
http.put<TaskCompletion>( http.put<TaskCompletion>(
`/teacher/tasks/${taskId}/completions/${studentId}`, `/api/v1/teacher/tasks/${taskId}/completions/${studentId}`,
data, data,
); );

View File

@ -87,7 +87,7 @@ export function getTeacherCourse(id: number): Promise<unknown> {
// 获取教师的班级列表 // 获取教师的班级列表
export function getTeacherClasses(): Promise<TeacherClass[]> { export function getTeacherClasses(): Promise<TeacherClass[]> {
return http.get("/teacher/courses/classes"); return http.get("/api/v1/teacher/courses/classes");
} }
// 获取教师所有学生列表(跨班级) // 获取教师所有学生列表(跨班级)
@ -115,7 +115,7 @@ export function getTeacherStudents(params?: {
page: number; page: number;
pageSize: number; pageSize: number;
}> { }> {
return http.get("/teacher/students", { params }); return http.get("/api/v1/teacher/students", { params });
} }
// 获取班级学生列表 // 获取班级学生列表
@ -190,7 +190,7 @@ export function getLessons(params?: {
page: number; page: number;
pageSize: number; pageSize: number;
}> { }> {
return http.get("/teacher/lessons", { params }); return http.get("/api/v1/teacher/lessons", { params });
} }
// 获取单个授课记录详情 // 获取单个授课记录详情
@ -200,7 +200,7 @@ export function getLesson(id: number): Promise<unknown> {
// 创建授课记录(备课) // 创建授课记录(备课)
export function createLesson(data: CreateLessonDto): Promise<unknown> { export function createLesson(data: CreateLessonDto): Promise<unknown> {
return http.post("/teacher/lessons", data); return http.post("/api/v1/teacher/lessons", data);
} }
// 开始上课 // 开始上课
@ -319,16 +319,18 @@ export interface DashboardData {
} }
export const getTeacherDashboard = () => export const getTeacherDashboard = () =>
http.get<DashboardData>("/teacher/dashboard"); http.get<DashboardData>("/api/v1/teacher/dashboard");
export const getTodayLessons = () => export const getTodayLessons = () =>
http.get<DashboardData["todayLessons"]>("/teacher/dashboard/today"); http.get<DashboardData["todayLessons"]>("/api/v1/teacher/dashboard/today");
export const getRecommendedCourses = () => export const getRecommendedCourses = () =>
http.get<DashboardData["recommendedCourses"]>("/teacher/dashboard/recommend"); http.get<DashboardData["recommendedCourses"]>(
"/api/v1/teacher/dashboard/recommend",
);
export const getWeeklyStats = () => export const getWeeklyStats = () =>
http.get<DashboardData["weeklyStats"]>("/teacher/dashboard/weekly"); http.get<DashboardData["weeklyStats"]>("/api/v1/teacher/dashboard/weekly");
// ==================== 教师统计趋势 ==================== // ==================== 教师统计趋势 ====================
@ -344,12 +346,12 @@ export interface TeacherCourseUsageItem {
} }
export const getTeacherLessonTrend = (months?: number) => export const getTeacherLessonTrend = (months?: number) =>
http.get<TeacherLessonTrendItem[]>("/teacher/dashboard/lesson-trend", { http.get<TeacherLessonTrendItem[]>("/api/v1/teacher/dashboard/lesson-trend", {
params: { months }, params: { months },
}); });
export const getTeacherCourseUsage = () => export const getTeacherCourseUsage = () =>
http.get<TeacherCourseUsageItem[]>("/teacher/dashboard/course-usage"); http.get<TeacherCourseUsageItem[]>("/api/v1/teacher/dashboard/course-usage");
// ==================== 课程反馈 API ==================== // ==================== 课程反馈 API ====================
@ -432,12 +434,12 @@ export function getSchoolFeedbacks(params: FeedbackQueryParams): Promise<{
page: number; page: number;
pageSize: number; pageSize: number;
}> { }> {
return http.get("/school/feedbacks", { params }); return http.get("/api/v1/school/feedbacks", { params });
} }
// 获取反馈统计 // 获取反馈统计
export function getFeedbackStats(): Promise<FeedbackStats> { export function getFeedbackStats(): Promise<FeedbackStats> {
return http.get("/school/feedbacks/stats"); return http.get("/api/v1/school/feedbacks/stats");
} }
// 获取教师自己的反馈列表 // 获取教师自己的反馈列表
@ -447,12 +449,12 @@ export function getTeacherFeedbacks(params: FeedbackQueryParams): Promise<{
page: number; page: number;
pageSize: number; pageSize: number;
}> { }> {
return http.get("/teacher/feedbacks", { params }); return http.get("/api/v1/teacher/feedbacks", { params });
} }
// 获取教师自己的反馈统计 // 获取教师自己的反馈统计
export function getTeacherFeedbackStats(): Promise<FeedbackStats> { export function getTeacherFeedbackStats(): Promise<FeedbackStats> {
return http.get("/teacher/feedbacks/stats"); return http.get("/api/v1/teacher/feedbacks/stats");
} }
// ==================== 排课管理 API ==================== // ==================== 排课管理 API ====================
@ -516,26 +518,28 @@ export const getTeacherSchedules = (params?: {
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>("/teacher/schedules", { params }); }>("/api/v1/teacher/schedules", { params });
export const getTeacherTimetable = (params: { export const getTeacherTimetable = (params: {
startDate: string; startDate: string;
endDate: string; endDate: string;
}) => }) =>
http.get<TeacherTimetableItem[]>("/teacher/schedules/timetable", { params }); http.get<TeacherTimetableItem[]>("/api/v1/teacher/schedules/timetable", {
params,
});
export const getTodayTeacherSchedules = () => export const getTodayTeacherSchedules = () =>
http.get<TeacherSchedule[]>("/teacher/schedules/today"); http.get<TeacherSchedule[]>("/api/v1/teacher/schedules/today");
export const createTeacherSchedule = (data: CreateTeacherScheduleDto) => export const createTeacherSchedule = (data: CreateTeacherScheduleDto) =>
http.post<TeacherSchedule>("/teacher/schedules", data); http.post<TeacherSchedule>("/api/v1/teacher/schedules", data);
export const updateTeacherSchedule = ( export const updateTeacherSchedule = (
id: number, id: number,
data: Partial<CreateTeacherScheduleDto> & { status?: string }, data: Partial<CreateTeacherScheduleDto> & { status?: string },
) => http.put<TeacherSchedule>(`/teacher/schedules/${id}`, data); ) => http.put<TeacherSchedule>(`/api/v1/teacher/schedules/${id}`, data);
export const cancelTeacherSchedule = (id: number) => export const cancelTeacherSchedule = (id: number) =>
http.delete<{ message: string }>(`/teacher/schedules/${id}`); http.delete<{ message: string }>(`/api/v1/teacher/schedules/${id}`);
// ==================== 阅读任务 API ==================== // ==================== 阅读任务 API ====================
@ -609,10 +613,10 @@ export const getTeacherTasks = (params?: {
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>("/teacher/tasks", { params }); }>("/api/v1/teacher/tasks", { params });
export const getTeacherTask = (id: number) => export const getTeacherTask = (id: number) =>
http.get<TeacherTask>(`/teacher/tasks/${id}`); http.get<TeacherTask>(`/api/v1/teacher/tasks/${id}`);
export const getTeacherTaskCompletions = ( export const getTeacherTaskCompletions = (
taskId: number, taskId: number,
@ -627,18 +631,18 @@ export const getTeacherTaskCompletions = (
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>(`/teacher/tasks/${taskId}/completions`, { params }); }>(`/api/v1/teacher/tasks/${taskId}/completions`, { params });
export const createTeacherTask = (data: CreateTeacherTaskDto) => export const createTeacherTask = (data: CreateTeacherTaskDto) =>
http.post<TeacherTask>("/teacher/tasks", data); http.post<TeacherTask>("/api/v1/teacher/tasks", data);
export const updateTeacherTask = ( export const updateTeacherTask = (
id: number, id: number,
data: Partial<CreateTeacherTaskDto> & { status?: string }, data: Partial<CreateTeacherTaskDto> & { status?: string },
) => http.put<TeacherTask>(`/teacher/tasks/${id}`, data); ) => http.put<TeacherTask>(`/api/v1/teacher/tasks/${id}`, data);
export const deleteTeacherTask = (id: number) => export const deleteTeacherTask = (id: number) =>
http.delete<{ message: string }>(`/teacher/tasks/${id}`); http.delete<{ message: string }>(`/api/v1/teacher/tasks/${id}`);
export const updateTaskCompletion = ( export const updateTaskCompletion = (
taskId: number, taskId: number,
@ -646,12 +650,12 @@ export const updateTaskCompletion = (
data: UpdateTaskCompletionDto, data: UpdateTaskCompletionDto,
) => ) =>
http.put<TaskCompletion>( http.put<TaskCompletion>(
`/teacher/tasks/${taskId}/completions/${studentId}`, `/api/v1/teacher/tasks/${taskId}/completions/${studentId}`,
data, data,
); );
export const sendTaskReminder = (taskId: number) => export const sendTaskReminder = (taskId: number) =>
http.post<{ message: string }>(`/teacher/tasks/${taskId}/remind`); http.post<{ message: string }>(`/api/v1/teacher/tasks/${taskId}/remind`);
// ==================== 任务模板 API ==================== // ==================== 任务模板 API ====================
@ -702,16 +706,18 @@ export const getTaskTemplates = (params?: {
total: number; total: number;
page: number; page: number;
pageSize: number; pageSize: number;
}>("/teacher/task-templates", { params }); }>("/api/v1/teacher/task-templates", { params });
export const getTaskTemplate = (id: number) => export const getTaskTemplate = (id: number) =>
http.get<TaskTemplate>(`/teacher/task-templates/${id}`); http.get<TaskTemplate>(`/api/v1/teacher/task-templates/${id}`);
export const getDefaultTaskTemplate = (taskType: string) => export const getDefaultTaskTemplate = (taskType: string) =>
http.get<TaskTemplate | null>(`/teacher/task-templates/default/${taskType}`); http.get<TaskTemplate | null>(
`/api/v1/teacher/task-templates/default/${taskType}`,
);
export const createTaskFromTemplate = (data: CreateTaskFromTemplateDto) => export const createTaskFromTemplate = (data: CreateTaskFromTemplateDto) =>
http.post<TeacherTask>("/teacher/tasks/from-template", data); http.post<TeacherTask>("/api/v1/teacher/tasks/from-template", data);
// ==================== 任务统计 API ==================== // ==================== 任务统计 API ====================
@ -750,15 +756,16 @@ export interface MonthlyTaskStats {
rate: number; rate: number;
} }
export const getTaskStats = () => http.get<TaskStats>("/teacher/tasks/stats"); export const getTaskStats = () =>
http.get<TaskStats>("/api/v1/teacher/tasks/stats");
export const getTaskStatsByType = () => export const getTaskStatsByType = () =>
http.get<TaskStatsByType>("/teacher/tasks/stats/by-type"); http.get<TaskStatsByType>("/api/v1/teacher/tasks/stats/by-type");
export const getTaskStatsByClass = () => export const getTaskStatsByClass = () =>
http.get<TaskStatsByClass[]>("/teacher/tasks/stats/by-class"); http.get<TaskStatsByClass[]>("/api/v1/teacher/tasks/stats/by-class");
export const getMonthlyTaskStats = (months?: number) => export const getMonthlyTaskStats = (months?: number) =>
http.get<MonthlyTaskStats[]>("/teacher/tasks/stats/monthly", { http.get<MonthlyTaskStats[]>("/api/v1/teacher/tasks/stats/monthly", {
params: { months }, params: { months },
}); });

View File

@ -7,22 +7,59 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
AAvatar: typeof import('ant-design-vue/es')['Avatar'] AAvatar: typeof import('ant-design-vue/es')['Avatar']
ABadge: typeof import('ant-design-vue/es')['Badge'] ABadge: typeof import('ant-design-vue/es')['Badge']
AButton: typeof import('ant-design-vue/es')['Button']
ACard: typeof import('ant-design-vue/es')['Card'] ACard: typeof import('ant-design-vue/es')['Card']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ACol: typeof import('ant-design-vue/es')['Col'] ACol: typeof import('ant-design-vue/es')['Col']
ADescriptions: typeof import('ant-design-vue/es')['Descriptions']
ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem']
ADivider: typeof import('ant-design-vue/es')['Divider']
ADrawer: typeof import('ant-design-vue/es')['Drawer']
ADropdown: typeof import('ant-design-vue/es')['Dropdown'] ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AEmpty: typeof import('ant-design-vue/es')['Empty'] AEmpty: typeof import('ant-design-vue/es')['Empty']
AForm: typeof import('ant-design-vue/es')['Form']
AFormItem: typeof import('ant-design-vue/es')['FormItem']
AInput: typeof import('ant-design-vue/es')['Input']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
ALayout: typeof import('ant-design-vue/es')['Layout'] ALayout: typeof import('ant-design-vue/es')['Layout']
ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader'] ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader']
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider'] ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
AList: typeof import('ant-design-vue/es')['List']
AListItem: typeof import('ant-design-vue/es')['ListItem']
AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta']
AMenu: typeof import('ant-design-vue/es')['Menu'] AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider'] AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
APageHeader: typeof import('ant-design-vue/es')['PageHeader']
APagination: typeof import('ant-design-vue/es')['Pagination']
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ARow: typeof import('ant-design-vue/es')['Row'] ARow: typeof import('ant-design-vue/es')['Row']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
ASpace: typeof import('ant-design-vue/es')['Space'] ASpace: typeof import('ant-design-vue/es')['Space']
ASpin: typeof import('ant-design-vue/es')['Spin']
AStatistic: typeof import('ant-design-vue/es')['Statistic']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATag: typeof import('ant-design-vue/es')['Tag'] ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
AUpload: typeof import('ant-design-vue/es')['Upload']
FilePreviewModal: typeof import('./components/FilePreviewModal.vue')['default'] FilePreviewModal: typeof import('./components/FilePreviewModal.vue')['default']
FileUploader: typeof import('./components/course/FileUploader.vue')['default'] FileUploader: typeof import('./components/course/FileUploader.vue')['default']
LessonConfigPanel: typeof import('./components/course/LessonConfigPanel.vue')['default'] LessonConfigPanel: typeof import('./components/course/LessonConfigPanel.vue')['default']

View File

@ -33,99 +33,91 @@
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<div class="class-grid" v-if="classes.length > 0"> <div class="class-grid" v-if="classes.length > 0">
<!-- 班级卡片 --> <!-- 班级卡片 -->
<div <div v-for="cls in classes" :key="cls.id" class="class-card" :class="'grade-' + getGradeKey(cls.grade)"
v-for="cls in classes" @click="viewClassDetail(cls)">
:key="cls.id" <!-- 年级标签 -->
class="class-card" <div class="grade-badge" :class="'badge-' + getGradeKey(cls.grade)">
:class="'grade-' + getGradeKey(cls.grade)" <span class="badge-icon">
@click="viewClassDetail(cls)" <TagsOutlined />
> </span>
<!-- 年级标签 --> <span class="badge-text">{{ cls.grade }}</span>
<div class="grade-badge" :class="'badge-' + getGradeKey(cls.grade)">
<span class="badge-icon">
<TagsOutlined />
</span>
<span class="badge-text">{{ cls.grade }}</span>
</div>
<!-- 角色标签 -->
<div class="role-badge" :class="'role-' + cls.myRole?.toLowerCase()">
{{ getRoleLabel(cls.myRole) }}
<span v-if="cls.isPrimary" class="primary-mark">班主任</span>
</div>
<!-- 班级信息 -->
<div class="class-header">
<div class="class-avatar" :style="{ background: getGradeGradient(cls.grade) }">
<span class="avatar-text">{{ getGradeInitial(cls.grade) }}</span>
</div> </div>
<div class="class-name">{{ cls.name }}</div>
</div>
<!-- 统计信息 --> <!-- 角色标签 -->
<div class="class-stats"> <div class="role-badge" :class="'role-' + cls.myRole?.toLowerCase()">
<div class="stat-item"> {{ getRoleLabel(cls.myRole) }}
<div class="stat-icon-wrapper pink"> <span v-if="cls.isPrimary" class="primary-mark">班主任</span>
<TeamOutlined /> </div>
<!-- 班级信息 -->
<div class="class-header">
<div class="class-avatar" :style="{ background: getGradeGradient(cls.grade) }">
<span class="avatar-text">{{ getGradeInitial(cls.grade) }}</span>
</div> </div>
<div class="stat-content"> <div class="class-name">{{ cls.name }}</div>
<div class="stat-number">{{ cls.studentCount }}</div> </div>
<div class="stat-label">名学生</div>
<!-- 统计信息 -->
<div class="class-stats">
<div class="stat-item">
<div class="stat-icon-wrapper pink">
<TeamOutlined />
</div>
<div class="stat-content">
<div class="stat-number">{{ cls.studentCount }}</div>
<div class="stat-label">名学生</div>
</div>
</div>
<div class="stat-divider"></div>
<div class="stat-item">
<div class="stat-icon-wrapper blue">
<ReadOutlined />
</div>
<div class="stat-content">
<div class="stat-number">{{ cls.lessonCount }}</div>
<div class="stat-label">授课次数</div>
</div>
</div> </div>
</div> </div>
<div class="stat-divider"></div>
<div class="stat-item">
<div class="stat-icon-wrapper blue">
<ReadOutlined />
</div>
<div class="stat-content">
<div class="stat-number">{{ cls.lessonCount }}</div>
<div class="stat-label">授课次数</div>
</div>
</div>
</div>
<!-- 进度条 --> <!-- 进度条 -->
<div class="class-progress"> <div class="class-progress">
<div class="progress-label">本月授课进度</div> <div class="progress-label">本月授课进度</div>
<div class="progress-bar"> <div class="progress-bar">
<div <div class="progress-fill" :style="{
class="progress-fill"
:style="{
width: Math.min((cls.lessonCount / 20) * 100, 100) + '%', width: Math.min((cls.lessonCount / 20) * 100, 100) + '%',
background: getGradeGradient(cls.grade) background: getGradeGradient(cls.grade)
}" }"></div>
></div> </div>
<div class="progress-text">{{ Math.min(Math.round((cls.lessonCount / 20) * 100), 100) }}%</div>
</div> </div>
<div class="progress-text">{{ Math.min(Math.round((cls.lessonCount / 20) * 100), 100) }}%</div>
</div>
<!-- 操作按钮 --> <!-- 操作按钮 -->
<div class="class-actions"> <div class="class-actions">
<button class="action-btn primary" @click.stop="prepareLesson(cls)"> <button class="action-btn primary" @click.stop="prepareLesson(cls)">
<EditOutlined /> <EditOutlined />
备课 备课
</button> </button>
<button class="action-btn" @click.stop="viewStudents(cls)"> <button class="action-btn" @click.stop="viewStudents(cls)">
<UsergroupAddOutlined /> <UsergroupAddOutlined />
学生 学生
</button> </button>
<button class="action-btn" @click.stop="viewHistory(cls)"> <button class="action-btn" @click.stop="viewHistory(cls)">
<BarChartOutlined /> <BarChartOutlined />
记录 记录
</button> </button>
</div>
</div> </div>
</div> </div>
</div>
<!-- 空状态 --> <!-- 空状态 -->
<div v-if="!loading && classes.length === 0" class="empty-state"> <div v-if="!loading && classes.length === 0" class="empty-state">
<div class="empty-icon-wrapper"> <div class="empty-icon-wrapper">
<HomeOutlined /> <HomeOutlined />
</div>
<h3 class="empty-title">暂无分配班级</h3>
<p class="empty-desc">请联系学校管理员为您分配班级</p>
</div> </div>
<h3 class="empty-title">暂无分配班级</h3>
<p class="empty-desc">请联系学校管理员为您分配班级</p>
</div>
</a-spin> </a-spin>
</div> </div>
</template> </template>
@ -195,7 +187,7 @@ onMounted(() => {
}); });
const totalStudents = computed(() => { const totalStudents = computed(() => {
return classes.value.reduce((sum, cls) => sum + cls.studentCount, 0); return classes.value?.reduce((sum, cls) => sum + cls.studentCount, 0) || 0;
}); });
const getGradeKey = (grade: string) => { const getGradeKey = (grade: string) => {

View File

@ -1,24 +1,24 @@
import { defineConfig } from 'vite'; import { defineConfig } from "vite";
import vue from '@vitejs/plugin-vue'; import vue from "@vitejs/plugin-vue";
import { resolve } from 'path'; import { resolve } from "path";
import AutoImport from 'unplugin-auto-import/vite'; import AutoImport from "unplugin-auto-import/vite";
import Components from 'unplugin-vue-components/vite'; import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'; import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
import viteCompression from 'vite-plugin-compression'; import viteCompression from "vite-plugin-compression";
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
vue(), vue(),
AutoImport({ AutoImport({
imports: [ imports: [
'vue', "vue",
'vue-router', "vue-router",
'pinia', "pinia",
{ {
'ant-design-vue': ['message', 'notification', 'Modal'], "ant-design-vue": ["message", "notification", "Modal"],
}, },
], ],
dts: 'src/auto-imports.d.ts', dts: "src/auto-imports.d.ts",
}), }),
Components({ Components({
resolvers: [ resolvers: [
@ -26,31 +26,32 @@ export default defineConfig({
importStyle: false, importStyle: false,
}), }),
], ],
dts: 'src/components.d.ts', dts: "src/components.d.ts",
}), }),
viteCompression({ viteCompression({
verbose: true, verbose: true,
disable: false, disable: false,
threshold: 10240, threshold: 10240,
algorithm: 'gzip', algorithm: "gzip",
ext: '.gz', ext: ".gz",
}), }),
], ],
resolve: { resolve: {
alias: { alias: {
'@': resolve(__dirname, 'src'), "@": resolve(__dirname, "src"),
}, },
}, },
server: { server: {
port: 5173, port: 5173,
host: true, host: true,
proxy: { proxy: {
'/api': { "/api": {
target: 'http://localhost:8080', // target: 'http://localhost:8080',
target: "http://192.168.1.110:8080",
changeOrigin: true, changeOrigin: true,
}, },
'/uploads': { "/uploads": {
target: 'http://localhost:8080', target: "http://192.168.1.110:8080",
changeOrigin: true, changeOrigin: true,
}, },
}, },
@ -59,10 +60,16 @@ export default defineConfig({
rollupOptions: { rollupOptions: {
output: { output: {
manualChunks: { manualChunks: {
'ant-design-vue': ['ant-design-vue', '@ant-design/icons-vue'], "ant-design-vue": ["ant-design-vue", "@ant-design/icons-vue"],
'echarts': ['echarts'], echarts: ["echarts"],
'fullcalendar': ['@fullcalendar/vue3', '@fullcalendar/core', '@fullcalendar/daygrid', '@fullcalendar/timegrid', '@fullcalendar/interaction'], fullcalendar: [
'dayjs': ['dayjs'], "@fullcalendar/vue3",
"@fullcalendar/core",
"@fullcalendar/daygrid",
"@fullcalendar/timegrid",
"@fullcalendar/interaction",
],
dayjs: ["dayjs"],
}, },
}, },
}, },