接口同步

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";
const { http } = require("./index");
import type {
ResultListCourseLesson,
CourseLesson as ApiCourseLesson,
@ -68,13 +69,8 @@ export interface CreateStepData {
// ==================== 超管端 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) {
return readingApi
@ -100,7 +96,6 @@ export function updateLesson(
data: Partial<CreateLessonData>,
) {
// Orval 接口需要同时提供 courseId 和 lessonId这里仅有 lessonId 时保留旧实现
const { http } = require("./index");
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[]) {
const { http } = require("./index");
return http.put(`/api/v1/admin/courses/${courseId}/lessons/reorder`, {
lessonIds,
});
@ -121,7 +115,6 @@ export function reorderLessons(courseId: number, lessonIds: number[]) {
// 获取环节列表
export function getStepList(courseId: number, lessonId: number) {
const { http } = require("./index");
return http.get(
`/api/v1/admin/courses/${courseId}/lessons/${lessonId}/steps`,
);
@ -133,7 +126,6 @@ export function createStep(
lessonId: number,
data: CreateStepData,
) {
const { http } = require("./index");
return http.post(
`/api/v1/admin/courses/${courseId}/lessons/${lessonId}/steps`,
data,
@ -142,13 +134,11 @@ export function createStep(
// 更新环节
export function updateStep(stepId: number, data: Partial<CreateStepData>) {
const { http } = require("./index");
return http.put(`/api/v1/admin/courses/0/lessons/steps/${stepId}`, data);
}
// 删除环节
export function deleteStep(courseId: number, lessonId: number, stepId: number) {
const { http } = require("./index");
return http.delete(
`/api/v1/admin/courses/${courseId}/lessons/steps/${stepId}`,
);
@ -160,7 +150,6 @@ export function reorderSteps(
lessonId: number,
stepIds: number[],
) {
const { http } = require("./index");
return http.put(
`/admin/courses/${courseId}/lessons/${lessonId}/steps/reorder`,
{ stepIds },

View File

@ -1,5 +1,10 @@
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[];
}
type AdminPackageResult = UnwrapResult<ApiResultOf<"getPackage1">>
type AdminPackageListResult = GetPackages1Result
type AdminPackageResult = UnwrapResult<ApiResultOf<"getPackage1">>;
// 获取套餐列表(管理员端)
export function getPackageList(
params?: PackageListParams,
): Promise<AdminPackageListResult> {
return readingApi.getPackages1(params as any).then((res) => res.data as any);
}
export const getPackageList = readingApi.getPackages1;
// 获取套餐详情(管理员端)
export function getPackageDetail(id: number): Promise<AdminPackageResult> {
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) => {
const list = (res.data as any as ResourceLibrary[]) || [];
const page = params?.page ?? 1;
const pageSize = params?.pageSize ?? list.length || 10;
const pageSize = params?.pageSize ?? (list.length || 10);
return {
items: list,
total: list.length,

View File

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

View File

@ -158,41 +158,43 @@ export interface PackageUsage {
export const getTeachers = (params: TeacherQueryParams) =>
http.get<{ items: Teacher[]; total: number; page: number; pageSize: number }>(
"/school/teachers",
"/api/v1/school/teachers",
{ params },
);
export const getTeacher = (id: number) =>
http.get<Teacher>(`/school/teachers/${id}`);
http.get<Teacher>(`/api/v1/school/teachers/${id}`);
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>) =>
http.put<Teacher>(`/school/teachers/${id}`, data);
http.put<Teacher>(`/api/v1/school/teachers/${id}`, data);
export const deleteTeacher = (id: number) =>
http.delete(`/api/v1/school/teachers/${id}`);
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) =>
http.get<{ items: Student[]; total: number; page: number; pageSize: number }>(
"/school/students",
"/api/v1/school/students",
{ params },
);
export const getStudent = (id: number) =>
http.get<Student>(`/school/students/${id}`);
http.get<Student>(`/api/v1/school/students/${id}`);
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>) =>
http.put<Student>(`/school/students/${id}`, data);
http.put<Student>(`/api/v1/school/students/${id}`, data);
export const deleteStudent = (id: number) =>
http.delete(`/api/v1/school/students/${id}`);
@ -212,7 +214,7 @@ export interface ImportTemplate {
}
export const getStudentImportTemplate = () =>
http.get<ImportTemplate>("/school/students/import/template");
http.get<ImportTemplate>("/api/v1/school/students/import/template");
export const importStudents = (
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) =>
http.get<ClassInfo>(`/school/classes/${id}`);
http.get<ClassInfo>(`/api/v1/school/classes/${id}`);
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>) =>
http.put<ClassInfo>(`/school/classes/${id}`, data);
http.put<ClassInfo>(`/api/v1/school/classes/${id}`, data);
export const deleteClass = (id: number) =>
http.delete(`/api/v1/school/classes/${id}`);
@ -256,35 +258,37 @@ export const getClassStudents = (
page: number;
pageSize: number;
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) =>
http.get<Array<{ id: number; name: string; lessonCount: number }>>(
"/school/stats/teachers",
"/api/v1/school/stats/teachers",
{ params: { limit } },
);
export const getCourseUsageStats = () =>
http.get<Array<{ courseId: number; courseName: string; usageCount: number }>>(
"/school/stats/courses",
"/api/v1/school/stats/courses",
);
export const getRecentActivities = (limit?: number) =>
http.get<Array<{ id: number; type: string; title: string; time: string }>>(
"/school/stats/activities",
"/api/v1/school/stats/activities",
{ params: { limit } },
);
// ==================== 套餐信息旧API保留兼容 ====================
export const getPackageInfo = () => http.get<PackageInfo>("/school/package");
export const getPackageInfo = () =>
http.get<PackageInfo>("/api/v1/school/package");
export const getPackageUsage = () =>
http.get<PackageUsage>("/school/package/usage");
http.get<PackageUsage>("/api/v1/school/package/usage");
// ==================== 套餐管理新API ====================
@ -326,10 +330,10 @@ export interface RenewPackageDto {
}
export const getTenantPackages = () =>
http.get<TenantPackage[]>("/school/packages");
http.get<TenantPackage[]>("/api/v1/school/packages");
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;
}
export const getSettings = () => http.get<SystemSettings>("/school/settings");
export const getSettings = () =>
http.get<SystemSettings>("/api/v1/school/settings");
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) =>
http.get<any>(`/school/courses/${id}`);
http.get<any>(`/api/v1/school/courses/${id}`);
// ==================== 班级教师管理 ====================
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) =>
http.post<ClassTeacher>(`/school/classes/${classId}/teachers`, data);
http.post<ClassTeacher>(`/api/v1/school/classes/${classId}/teachers`, data);
export const updateClassTeacher = (
classId: number,
@ -381,25 +386,27 @@ export const updateClassTeacher = (
data: UpdateClassTeacherDto,
) =>
http.put<ClassTeacher>(
`/school/classes/${classId}/teachers/${teacherId}`,
`/api/v1/school/classes/${classId}/teachers/${teacherId}`,
data,
);
export const removeClassTeacher = (classId: number, teacherId: number) =>
http.delete<{ message: string }>(
`/school/classes/${classId}/teachers/${teacherId}`,
`/api/v1/school/classes/${classId}/teachers/${teacherId}`,
);
// ==================== 学生调班 ====================
export const transferStudent = (studentId: number, data: TransferStudentDto) =>
http.post<{ message: string }>(
`/school/students/${studentId}/transfer`,
`/api/v1/school/students/${studentId}/transfer`,
data,
);
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;
page: number;
pageSize: number;
}>("/school/schedules", { params });
}>("/api/v1/school/schedules", { params });
export const getSchedule = (id: number) =>
http.get<SchedulePlan>(`/school/schedules/${id}`);
http.get<SchedulePlan>(`/api/v1/school/schedules/${id}`);
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) =>
http.put<SchedulePlan>(`/school/schedules/${id}`, data);
http.put<SchedulePlan>(`/api/v1/school/schedules/${id}`, data);
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) =>
http.get<TimetableItem[]>("/school/schedules/timetable", { params });
http.get<TimetableItem[]>("/api/v1/school/schedules/timetable", { params });
export interface BatchScheduleItem {
classId: number;
@ -513,7 +520,7 @@ export interface BatchCreateResult {
}
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) =>
http.get<LessonTrendItem[]>("/school/stats/lesson-trend", {
http.get<LessonTrendItem[]>("/api/v1/school/stats/lesson-trend", {
params: { months },
});
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?: {
classId?: number;
courseId?: number;
}) => http.get<ScheduleTemplate[]>("/school/schedule-templates", { params });
}) =>
http.get<ScheduleTemplate[]>("/api/v1/school/schedule-templates", { params });
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) =>
http.post<ScheduleTemplate>("/school/schedule-templates", data);
http.post<ScheduleTemplate>("/api/v1/school/schedule-templates", data);
export const updateScheduleTemplate = (
id: number,
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) =>
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) =>
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;
page: number;
pageSize: number;
}>("/school/operation-logs", { params });
}>("/api/v1/school/operation-logs", { params });
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 },
});
export const getOperationLogById = (id: number) =>
http.get<OperationLog>(`/school/operation-logs/${id}`);
http.get<OperationLog>(`/api/v1/school/operation-logs/${id}`);
// ==================== 任务模板 API ====================
@ -784,22 +798,24 @@ export const getTaskTemplates = (params?: {
total: number;
page: number;
pageSize: number;
}>("/school/task-templates", { params });
}>("/api/v1/school/task-templates", { params });
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) =>
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) =>
http.post<TaskTemplate>("/school/task-templates", data);
http.post<TaskTemplate>("/api/v1/school/task-templates", data);
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) =>
http.delete<{ message: string }>(`/school/task-templates/${id}`);
http.delete<{ message: string }>(`/api/v1/school/task-templates/${id}`);
// ==================== 任务统计 API ====================
@ -838,16 +854,17 @@ export interface MonthlyTaskStats {
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 = () =>
http.get<TaskStatsByType>("/school/tasks/stats/by-type");
http.get<TaskStatsByType>("/api/v1/school/tasks/stats/by-type");
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) =>
http.get<MonthlyTaskStats[]>("/school/tasks/stats/monthly", {
http.get<MonthlyTaskStats[]>("/api/v1/school/tasks/stats/monthly", {
params: { months },
});
@ -920,24 +937,25 @@ export const getSchoolTasks = (params?: {
total: number;
page: number;
pageSize: number;
}>("/school/tasks", { params });
}>("/api/v1/school/tasks", { params });
export const getSchoolTask = (id: number) =>
http.get<SchoolTask>(`/school/tasks/${id}`);
http.get<SchoolTask>(`/api/v1/school/tasks/${id}`);
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) =>
http.put<SchoolTask>(`/school/tasks/${id}`, data);
http.put<SchoolTask>(`/api/v1/school/tasks/${id}`, data);
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) =>
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 ====================
@ -976,16 +994,16 @@ export interface StudentReport {
}
export const getReportOverview = () =>
http.get<ReportOverview>("/school/reports/overview");
http.get<ReportOverview>("/api/v1/school/reports/overview");
export const getTeacherReports = () =>
http.get<TeacherReport[]>("/school/reports/teachers");
http.get<TeacherReport[]>("/api/v1/school/reports/teachers");
export const getCourseReports = () =>
http.get<CourseReport[]>("/school/reports/courses");
http.get<CourseReport[]>("/api/v1/school/reports/courses");
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) =>
http.get<{ items: Parent[]; total: number; page: number; pageSize: number }>(
"/school/parents",
"/api/v1/school/parents",
{ params },
);
export const getParent = (id: number) =>
http.get<Parent>(`/school/parents/${id}`);
http.get<Parent>(`/api/v1/school/parents/${id}`);
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) =>
http.put<Parent>(`/school/parents/${id}`, data);
http.put<Parent>(`/api/v1/school/parents/${id}`, data);
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) =>
http.post<{ tempPassword: string }>(`/school/parents/${id}/reset-password`);
http.post<{ tempPassword: string }>(
`/api/v1/school/parents/${id}/reset-password`,
);
export const getParentChildren = async (
parentId: number,
): Promise<ParentChild[]> => {
const parent = await http.get<Parent & { children: ParentChild[] }>(
`/school/parents/${parentId}`,
`/api/v1/school/parents/${parentId}`,
);
return parent.children || [];
};
export const addChildToParent = (parentId: number, data: AddChildDto) =>
http.post<ParentChild>(
`/school/parents/${parentId}/children/${data.studentId}`,
`/api/v1/school/parents/${parentId}/children/${data.studentId}`,
{ relationship: data.relationship },
);
export const removeChildFromParent = (parentId: number, studentId: number) =>
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;
}) =>
http.get<{ items: Task[]; total: number; page: number; pageSize: number }>(
"/school/tasks",
"/api/v1/school/tasks",
{ 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 = (
taskId: number,
@ -111,13 +112,13 @@ export const getTaskCompletions = (
total: number;
page: number;
pageSize: number;
}>(`/school/tasks/${taskId}/completions`, { params });
}>(`/api/v1/school/tasks/${taskId}/completions`, { params });
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) =>
http.put<Task>(`/school/tasks/${id}`, data);
http.put<Task>(`/api/v1/school/tasks/${id}`, data);
export const deleteTask = (id: number) =>
http.delete(`/api/v1/school/tasks/${id}`);
@ -128,7 +129,7 @@ export const updateTaskCompletion = (
data: UpdateCompletionDto,
) =>
http.put<TaskCompletion>(
`/school/tasks/${taskId}/completions/${studentId}`,
`/api/v1/school/tasks/${taskId}/completions/${studentId}`,
data,
);
@ -145,12 +146,12 @@ export const getTeacherTasks = (params?: {
keyword?: string;
}) =>
http.get<{ items: Task[]; total: number; page: number; pageSize: number }>(
"/teacher/tasks",
"/api/v1/teacher/tasks",
{ params },
);
export const getTeacherTask = (id: number) =>
http.get<Task>(`/teacher/tasks/${id}`);
http.get<Task>(`/api/v1/teacher/tasks/${id}`);
export const getTeacherTaskCompletions = (
taskId: number,
@ -165,13 +166,13 @@ export const getTeacherTaskCompletions = (
total: number;
page: number;
pageSize: number;
}>(`/teacher/tasks/${taskId}/completions`, { params });
}>(`/api/v1/teacher/tasks/${taskId}/completions`, { params });
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) =>
http.put<Task>(`/teacher/tasks/${id}`, data);
http.put<Task>(`/api/v1/teacher/tasks/${id}`, data);
export const deleteTeacherTask = (id: number) =>
http.delete(`/api/v1/teacher/tasks/${id}`);
@ -182,7 +183,7 @@ export const updateTeacherTaskCompletion = (
data: UpdateCompletionDto,
) =>
http.put<TaskCompletion>(
`/teacher/tasks/${taskId}/completions/${studentId}`,
`/api/v1/teacher/tasks/${taskId}/completions/${studentId}`,
data,
);

View File

@ -87,7 +87,7 @@ export function getTeacherCourse(id: number): Promise<unknown> {
// 获取教师的班级列表
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;
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;
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> {
return http.post("/teacher/lessons", data);
return http.post("/api/v1/teacher/lessons", data);
}
// 开始上课
@ -319,16 +319,18 @@ export interface DashboardData {
}
export const getTeacherDashboard = () =>
http.get<DashboardData>("/teacher/dashboard");
http.get<DashboardData>("/api/v1/teacher/dashboard");
export const getTodayLessons = () =>
http.get<DashboardData["todayLessons"]>("/teacher/dashboard/today");
http.get<DashboardData["todayLessons"]>("/api/v1/teacher/dashboard/today");
export const getRecommendedCourses = () =>
http.get<DashboardData["recommendedCourses"]>("/teacher/dashboard/recommend");
http.get<DashboardData["recommendedCourses"]>(
"/api/v1/teacher/dashboard/recommend",
);
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) =>
http.get<TeacherLessonTrendItem[]>("/teacher/dashboard/lesson-trend", {
http.get<TeacherLessonTrendItem[]>("/api/v1/teacher/dashboard/lesson-trend", {
params: { months },
});
export const getTeacherCourseUsage = () =>
http.get<TeacherCourseUsageItem[]>("/teacher/dashboard/course-usage");
http.get<TeacherCourseUsageItem[]>("/api/v1/teacher/dashboard/course-usage");
// ==================== 课程反馈 API ====================
@ -432,12 +434,12 @@ export function getSchoolFeedbacks(params: FeedbackQueryParams): Promise<{
page: number;
pageSize: number;
}> {
return http.get("/school/feedbacks", { params });
return http.get("/api/v1/school/feedbacks", { params });
}
// 获取反馈统计
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;
pageSize: number;
}> {
return http.get("/teacher/feedbacks", { params });
return http.get("/api/v1/teacher/feedbacks", { params });
}
// 获取教师自己的反馈统计
export function getTeacherFeedbackStats(): Promise<FeedbackStats> {
return http.get("/teacher/feedbacks/stats");
return http.get("/api/v1/teacher/feedbacks/stats");
}
// ==================== 排课管理 API ====================
@ -516,26 +518,28 @@ export const getTeacherSchedules = (params?: {
total: number;
page: number;
pageSize: number;
}>("/teacher/schedules", { params });
}>("/api/v1/teacher/schedules", { params });
export const getTeacherTimetable = (params: {
startDate: string;
endDate: string;
}) =>
http.get<TeacherTimetableItem[]>("/teacher/schedules/timetable", { params });
http.get<TeacherTimetableItem[]>("/api/v1/teacher/schedules/timetable", {
params,
});
export const getTodayTeacherSchedules = () =>
http.get<TeacherSchedule[]>("/teacher/schedules/today");
http.get<TeacherSchedule[]>("/api/v1/teacher/schedules/today");
export const createTeacherSchedule = (data: CreateTeacherScheduleDto) =>
http.post<TeacherSchedule>("/teacher/schedules", data);
http.post<TeacherSchedule>("/api/v1/teacher/schedules", data);
export const updateTeacherSchedule = (
id: number,
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) =>
http.delete<{ message: string }>(`/teacher/schedules/${id}`);
http.delete<{ message: string }>(`/api/v1/teacher/schedules/${id}`);
// ==================== 阅读任务 API ====================
@ -609,10 +613,10 @@ export const getTeacherTasks = (params?: {
total: number;
page: number;
pageSize: number;
}>("/teacher/tasks", { params });
}>("/api/v1/teacher/tasks", { params });
export const getTeacherTask = (id: number) =>
http.get<TeacherTask>(`/teacher/tasks/${id}`);
http.get<TeacherTask>(`/api/v1/teacher/tasks/${id}`);
export const getTeacherTaskCompletions = (
taskId: number,
@ -627,18 +631,18 @@ export const getTeacherTaskCompletions = (
total: number;
page: number;
pageSize: number;
}>(`/teacher/tasks/${taskId}/completions`, { params });
}>(`/api/v1/teacher/tasks/${taskId}/completions`, { params });
export const createTeacherTask = (data: CreateTeacherTaskDto) =>
http.post<TeacherTask>("/teacher/tasks", data);
http.post<TeacherTask>("/api/v1/teacher/tasks", data);
export const updateTeacherTask = (
id: number,
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) =>
http.delete<{ message: string }>(`/teacher/tasks/${id}`);
http.delete<{ message: string }>(`/api/v1/teacher/tasks/${id}`);
export const updateTaskCompletion = (
taskId: number,
@ -646,12 +650,12 @@ export const updateTaskCompletion = (
data: UpdateTaskCompletionDto,
) =>
http.put<TaskCompletion>(
`/teacher/tasks/${taskId}/completions/${studentId}`,
`/api/v1/teacher/tasks/${taskId}/completions/${studentId}`,
data,
);
export const sendTaskReminder = (taskId: number) =>
http.post<{ message: string }>(`/teacher/tasks/${taskId}/remind`);
http.post<{ message: string }>(`/api/v1/teacher/tasks/${taskId}/remind`);
// ==================== 任务模板 API ====================
@ -702,16 +706,18 @@ export const getTaskTemplates = (params?: {
total: number;
page: number;
pageSize: number;
}>("/teacher/task-templates", { params });
}>("/api/v1/teacher/task-templates", { params });
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) =>
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) =>
http.post<TeacherTask>("/teacher/tasks/from-template", data);
http.post<TeacherTask>("/api/v1/teacher/tasks/from-template", data);
// ==================== 任务统计 API ====================
@ -750,15 +756,16 @@ export interface MonthlyTaskStats {
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 = () =>
http.get<TaskStatsByType>("/teacher/tasks/stats/by-type");
http.get<TaskStatsByType>("/api/v1/teacher/tasks/stats/by-type");
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) =>
http.get<MonthlyTaskStats[]>("/teacher/tasks/stats/monthly", {
http.get<MonthlyTaskStats[]>("/api/v1/teacher/tasks/stats/monthly", {
params: { months },
});

View File

@ -7,22 +7,59 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
AAvatar: typeof import('ant-design-vue/es')['Avatar']
ABadge: typeof import('ant-design-vue/es')['Badge']
AButton: typeof import('ant-design-vue/es')['Button']
ACard: typeof import('ant-design-vue/es')['Card']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
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']
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']
ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader']
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']
AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider']
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']
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']
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']
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']
FileUploader: typeof import('./components/course/FileUploader.vue')['default']
LessonConfigPanel: typeof import('./components/course/LessonConfigPanel.vue')['default']

View File

@ -33,13 +33,8 @@
<a-spin :spinning="loading">
<div class="class-grid" v-if="classes.length > 0">
<!-- 班级卡片 -->
<div
v-for="cls in classes"
:key="cls.id"
class="class-card"
:class="'grade-' + getGradeKey(cls.grade)"
@click="viewClassDetail(cls)"
>
<div v-for="cls in classes" :key="cls.id" class="class-card" :class="'grade-' + getGradeKey(cls.grade)"
@click="viewClassDetail(cls)">
<!-- 年级标签 -->
<div class="grade-badge" :class="'badge-' + getGradeKey(cls.grade)">
<span class="badge-icon">
@ -89,13 +84,10 @@
<div class="class-progress">
<div class="progress-label">本月授课进度</div>
<div class="progress-bar">
<div
class="progress-fill"
:style="{
<div class="progress-fill" :style="{
width: Math.min((cls.lessonCount / 20) * 100, 100) + '%',
background: getGradeGradient(cls.grade)
}"
></div>
}"></div>
</div>
<div class="progress-text">{{ Math.min(Math.round((cls.lessonCount / 20) * 100), 100) }}%</div>
</div>
@ -195,7 +187,7 @@ onMounted(() => {
});
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) => {

View File

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