fix(前端): 修复 ID 类型和分页 total 类型不匹配问题
- 将 Props 中 ID 字段从 number 改为 number | string,兼容后端 Long 序列化为 String - 修复分页组件 total 字段类型,使用 Number() 转换避免 Vue warn - 影响组件: PrepareNavigation, LessonCard, SelectLessonsModal 等 - 影响视图: StudentListView, TeacherListView, ParentListView 等
This commit is contained in:
parent
5c9be63347
commit
55343ead0b
@ -4,7 +4,8 @@
|
|||||||
"Bash(mvn compile:*)",
|
"Bash(mvn compile:*)",
|
||||||
"Bash(sed:*)",
|
"Bash(sed:*)",
|
||||||
"Bash(grep:*)",
|
"Bash(grep:*)",
|
||||||
"Bash(export:*)"
|
"Bash(export:*)",
|
||||||
|
"Bash(git:*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,7 +133,7 @@ import type { Theme } from '@/api/theme';
|
|||||||
|
|
||||||
interface BasicInfoData {
|
interface BasicInfoData {
|
||||||
name: string;
|
name: string;
|
||||||
themeId: number | undefined;
|
themeId: number | string | undefined;
|
||||||
grades: string[];
|
grades: string[];
|
||||||
pictureBookName: string;
|
pictureBookName: string;
|
||||||
coreContent: string;
|
coreContent: string;
|
||||||
|
|||||||
@ -63,7 +63,7 @@ import { getLessonByType, createLesson, updateLesson, deleteLesson as deleteLess
|
|||||||
import { parseAssessmentDataForDisplay } from '@/utils/assessmentData';
|
import { parseAssessmentDataForDisplay } from '@/utils/assessmentData';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
courseId: number;
|
courseId: number | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
|
|||||||
@ -63,7 +63,7 @@ import { getLessonByType, createLesson as createLessonApi, updateLesson, deleteL
|
|||||||
import { parseAssessmentDataForDisplay } from '@/utils/assessmentData';
|
import { parseAssessmentDataForDisplay } from '@/utils/assessmentData';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
courseId: number;
|
courseId: number | string;
|
||||||
courseName: string;
|
courseName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -106,7 +106,7 @@ interface DomainConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
courseId: number;
|
courseId: number | string;
|
||||||
courseName: string;
|
courseName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -200,7 +200,7 @@ import LessonStepsEditor from './LessonStepsEditor.vue';
|
|||||||
import type { StepData } from './LessonStepsEditor.vue';
|
import type { StepData } from './LessonStepsEditor.vue';
|
||||||
|
|
||||||
export interface LessonData {
|
export interface LessonData {
|
||||||
id?: number;
|
id?: number | string;
|
||||||
tempId?: string;
|
tempId?: string;
|
||||||
lessonType: string;
|
lessonType: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@ -95,7 +95,7 @@ import {
|
|||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
|
|
||||||
export interface StepData {
|
export interface StepData {
|
||||||
id?: number;
|
id?: number | string;
|
||||||
tempId?: string;
|
tempId?: string;
|
||||||
name: string;
|
name: string;
|
||||||
content: string;
|
content: string;
|
||||||
|
|||||||
@ -163,7 +163,7 @@ const fetchData = async () => {
|
|||||||
...(filters.status ? { status: filters.status } : {}),
|
...(filters.status ? { status: filters.status } : {}),
|
||||||
});
|
});
|
||||||
dataSource.value = data.items;
|
dataSource.value = data.items;
|
||||||
pagination.total = data.total;
|
pagination.total = Number(data.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取套餐列表失败', error);
|
console.error('获取套餐列表失败', error);
|
||||||
message.error('获取套餐列表失败');
|
message.error('获取套餐列表失败');
|
||||||
|
|||||||
@ -267,7 +267,7 @@ const fetchCourses = async () => {
|
|||||||
|
|
||||||
// API 已统一返回 { items, total, page, pageSize }
|
// API 已统一返回 { items, total, page, pageSize }
|
||||||
courses.value = (data as any).items || [];
|
courses.value = (data as any).items || [];
|
||||||
pagination.total = (data as any).total || 0;
|
pagination.total = Number((data as any).total) || 0;
|
||||||
console.log('📊 课程列表数据:', courses.value, '总数:', pagination.total);
|
console.log('📊 课程列表数据:', courses.value, '总数:', pagination.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取课程包列表失败:', error);
|
console.error('获取课程包列表失败:', error);
|
||||||
|
|||||||
@ -250,7 +250,7 @@ const fetchCourses = async () => {
|
|||||||
// 已驳回的课程不显示「通过」,待审核的默认通过(能提交的已过基本验证)
|
// 已驳回的课程不显示「通过」,待审核的默认通过(能提交的已过基本验证)
|
||||||
validationPassed: item.status !== 'REJECTED',
|
validationPassed: item.status !== 'REJECTED',
|
||||||
}));
|
}));
|
||||||
pagination.total = data.total || 0;
|
pagination.total = Number(data.total) || 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取审核列表失败:', error);
|
console.error('获取审核列表失败:', error);
|
||||||
message.error('获取审核列表失败');
|
message.error('获取审核列表失败');
|
||||||
|
|||||||
@ -130,7 +130,7 @@ import type { Theme } from '@/api/theme';
|
|||||||
|
|
||||||
interface BasicInfoData {
|
interface BasicInfoData {
|
||||||
name: string;
|
name: string;
|
||||||
themeId: number | undefined;
|
themeId: number | string | undefined;
|
||||||
grades: string[];
|
grades: string[];
|
||||||
pictureBookName: string;
|
pictureBookName: string;
|
||||||
coreContent: string;
|
coreContent: string;
|
||||||
|
|||||||
@ -58,7 +58,7 @@ import type { LessonData } from '@/components/course/LessonConfigPanel.vue';
|
|||||||
import { getLessonByType, createLesson, updateLesson, deleteLesson as deleteLessonApi } from '@/api/lesson';
|
import { getLessonByType, createLesson, updateLesson, deleteLesson as deleteLessonApi } from '@/api/lesson';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
courseId: number;
|
courseId: number | string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
|
|||||||
@ -58,7 +58,7 @@ import type { LessonData } from '@/components/course/LessonConfigPanel.vue';
|
|||||||
import { getLessonByType, createLesson as createLessonApi, updateLesson, deleteLesson as deleteLessonApi } from '@/api/lesson';
|
import { getLessonByType, createLesson as createLessonApi, updateLesson, deleteLesson as deleteLessonApi } from '@/api/lesson';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
courseId: number;
|
courseId: number | string;
|
||||||
courseName: string;
|
courseName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,7 +101,7 @@ interface DomainConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
courseId: number;
|
courseId: number | string;
|
||||||
courseName: string;
|
courseName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -218,7 +218,7 @@ const fetchPackages = async () => {
|
|||||||
pageSize: pagination.pageSize,
|
pageSize: pagination.pageSize,
|
||||||
}) as any;
|
}) as any;
|
||||||
packages.value = res.list || [];
|
packages.value = res.list || [];
|
||||||
pagination.total = res.total || 0;
|
pagination.total = Number(res.total) || 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取套餐列表失败:', error);
|
console.error('获取套餐列表失败:', error);
|
||||||
message.error('获取套餐列表失败');
|
message.error('获取套餐列表失败');
|
||||||
|
|||||||
@ -511,7 +511,7 @@ const fetchItems = async () => {
|
|||||||
...filters,
|
...filters,
|
||||||
});
|
});
|
||||||
items.value = result?.list ?? [];
|
items.value = result?.list ?? [];
|
||||||
pagination.total = result?.total ?? 0;
|
pagination.total = Number(result?.total) ?? 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('获取资源列表失败');
|
message.error('获取资源列表失败');
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -483,7 +483,7 @@ const loadData = async () => {
|
|||||||
collectionId: searchForm.collectionId,
|
collectionId: searchForm.collectionId,
|
||||||
});
|
});
|
||||||
tenants.value = res.list;
|
tenants.value = res.list;
|
||||||
pagination.total = res.total;
|
pagination.total = Number(res.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载租户列表失败', error);
|
console.error('加载租户列表失败', error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -569,7 +569,7 @@ const loadClassStudents = async (classId: number) => {
|
|||||||
pageSize: studentsPagination.pageSize,
|
pageSize: studentsPagination.pageSize,
|
||||||
});
|
});
|
||||||
classStudents.value = result.list;
|
classStudents.value = result.list;
|
||||||
studentsPagination.total = result.total;
|
studentsPagination.total = Number(result.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load class students:', error);
|
console.error('Failed to load class students:', error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -246,7 +246,7 @@ const loading = ref(false);
|
|||||||
const authLoading = ref(false);
|
const authLoading = ref(false);
|
||||||
const authModalVisible = ref(false);
|
const authModalVisible = ref(false);
|
||||||
const searchKeyword = ref('');
|
const searchKeyword = ref('');
|
||||||
const selectedCourseIds = ref<number[]>([]);
|
const selectedCourseIds = ref<(number | string)[]>([]);
|
||||||
|
|
||||||
// 筛选条件(参考教师端)
|
// 筛选条件(参考教师端)
|
||||||
const filters = reactive({
|
const filters = reactive({
|
||||||
@ -401,7 +401,7 @@ const searchCourses = () => {
|
|||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleCourseSelection = (id: number) => {
|
const toggleCourseSelection = (id: number | string) => {
|
||||||
const index = selectedCourseIds.value.indexOf(id);
|
const index = selectedCourseIds.value.indexOf(id);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
selectedCourseIds.value.splice(index, 1);
|
selectedCourseIds.value.splice(index, 1);
|
||||||
|
|||||||
@ -330,7 +330,7 @@ const fetchFeedbacks = async () => {
|
|||||||
teacherId: filters.teacherId,
|
teacherId: filters.teacherId,
|
||||||
});
|
});
|
||||||
feedbacks.value = result.list;
|
feedbacks.value = result.list;
|
||||||
pagination.total = result.total;
|
pagination.total = Number(result.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('获取反馈列表失败');
|
message.error('获取反馈列表失败');
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -449,7 +449,7 @@ const loadParents = async () => {
|
|||||||
keyword: searchKeyword.value || undefined,
|
keyword: searchKeyword.value || undefined,
|
||||||
});
|
});
|
||||||
parents.value = result.list;
|
parents.value = result.list;
|
||||||
pagination.total = result.total;
|
pagination.total = Number(result.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load parents:', error);
|
console.error('Failed to load parents:', error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -684,7 +684,7 @@ const loadStudentsForSelect = async () => {
|
|||||||
classId: studentClassFilter.value || undefined,
|
classId: studentClassFilter.value || undefined,
|
||||||
});
|
});
|
||||||
studentTableData.value = result.list;
|
studentTableData.value = result.list;
|
||||||
studentPagination.total = result.total;
|
studentPagination.total = Number(result.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load students:', error);
|
console.error('Failed to load students:', error);
|
||||||
studentTableData.value = [];
|
studentTableData.value = [];
|
||||||
|
|||||||
@ -219,7 +219,7 @@ const loadLogs = async () => {
|
|||||||
...filters,
|
...filters,
|
||||||
});
|
});
|
||||||
logs.value = res.list;
|
logs.value = res.list;
|
||||||
pagination.total = res.total;
|
pagination.total = Number(res.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('加载日志失败');
|
message.error('加载日志失败');
|
||||||
} finally {
|
} finally {
|
||||||
@ -241,7 +241,7 @@ const loadModules = async () => {
|
|||||||
const loadStats = async () => {
|
const loadStats = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await getOperationLogStats(filters.startDate, filters.endDate);
|
const res = await getOperationLogStats(filters.startDate, filters.endDate);
|
||||||
stats.total = res.total;
|
stats.total = Number(res.total);
|
||||||
stats.modules = res.modules || [];
|
stats.modules = res.modules || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载统计失败', error);
|
console.error('加载统计失败', error);
|
||||||
|
|||||||
@ -444,7 +444,7 @@ const loadStudents = async () => {
|
|||||||
keyword: searchKeyword.value || undefined,
|
keyword: searchKeyword.value || undefined,
|
||||||
});
|
});
|
||||||
students.value = result.list;
|
students.value = result.list;
|
||||||
pagination.total = result.total;
|
pagination.total = Number(result.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load students:', error);
|
console.error('Failed to load students:', error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -329,7 +329,7 @@ const loadTeachers = async () => {
|
|||||||
keyword: searchKeyword.value || undefined,
|
keyword: searchKeyword.value || undefined,
|
||||||
});
|
});
|
||||||
teachers.value = result.list;
|
teachers.value = result.list;
|
||||||
pagination.total = result.total;
|
pagination.total = Number(result.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load teachers:', error);
|
console.error('Failed to load teachers:', error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -322,7 +322,7 @@ const loadCourses = async () => {
|
|||||||
pictureUrl: item.coverImagePath ?? item.pictureUrl,
|
pictureUrl: item.coverImagePath ?? item.pictureUrl,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
pagination.total = data.total || 0;
|
pagination.total = Number(data.total) || 0;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error.message || '获取课程列表失败');
|
message.error(error.message || '获取课程列表失败');
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -109,7 +109,7 @@ const loading = ref(false);
|
|||||||
|
|
||||||
// 导航状态
|
// 导航状态
|
||||||
const selectedSection = ref<'overview' | 'lesson'>('overview');
|
const selectedSection = ref<'overview' | 'lesson'>('overview');
|
||||||
const selectedLessonId = ref<number | null>(null);
|
const selectedLessonId = ref<number | string | null>(null);
|
||||||
const selectedItem = ref<string>('basic');
|
const selectedItem = ref<string>('basic');
|
||||||
const selectedStep = ref<any>(null);
|
const selectedStep = ref<any>(null);
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,7 @@ import {
|
|||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
lesson: any;
|
lesson: any;
|
||||||
courseId: number;
|
courseId: number | string;
|
||||||
lessonType: string;
|
lessonType: string;
|
||||||
index: number;
|
index: number;
|
||||||
}>();
|
}>();
|
||||||
|
|||||||
@ -278,7 +278,7 @@ const props = defineProps<{
|
|||||||
course: any;
|
course: any;
|
||||||
lessons: any[];
|
lessons: any[];
|
||||||
selectedSection: 'overview' | 'lesson';
|
selectedSection: 'overview' | 'lesson';
|
||||||
selectedLessonId: number | null;
|
selectedLessonId: number | string | null;
|
||||||
selectedItem: string;
|
selectedItem: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|||||||
@ -117,7 +117,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
'update:open': [value: boolean];
|
'update:open': [value: boolean];
|
||||||
'confirm': [lessonIds: number[], mode: string];
|
'confirm': [lessonIds: (number | string)[], mode: string];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const visible = computed({
|
const visible = computed({
|
||||||
@ -126,7 +126,7 @@ const visible = computed({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const selectionMode = ref<'all' | 'custom'>('all');
|
const selectionMode = ref<'all' | 'custom'>('all');
|
||||||
const selectedLessonIds = ref<number[]>([]);
|
const selectedLessonIds = ref<(number | string)[]>([]);
|
||||||
|
|
||||||
// 按类型分组课程
|
// 按类型分组课程
|
||||||
const introductionLesson = computed(() =>
|
const introductionLesson = computed(() =>
|
||||||
|
|||||||
@ -308,7 +308,7 @@ const fetchFeedbacks = async () => {
|
|||||||
pageSize: pagination.pageSize,
|
pageSize: pagination.pageSize,
|
||||||
});
|
});
|
||||||
feedbacks.value = result.items;
|
feedbacks.value = result.items;
|
||||||
pagination.total = result.total;
|
pagination.total = Number(result.total);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('获取反馈列表失败');
|
message.error('获取反馈列表失败');
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -335,7 +335,7 @@ const loadRecords = async () => {
|
|||||||
keyword: filters.keyword || undefined,
|
keyword: filters.keyword || undefined,
|
||||||
});
|
});
|
||||||
records.value = res.list || [];
|
records.value = res.list || [];
|
||||||
pagination.total = res.total || 0;
|
pagination.total = Number(res.total) || 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('加载档案失败');
|
message.error('加载档案失败');
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
import Step4IntroLessonAdmin from '@/components/course-edit/Step4IntroLesson.vue';
|
import Step4IntroLessonAdmin from '@/components/course-edit/Step4IntroLesson.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
schoolCourseId: number;
|
schoolCourseId: number | string;
|
||||||
lessonData?: any;
|
lessonData?: any;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
import Step5CollectiveLessonAdmin from '@/components/course-edit/Step5CollectiveLesson.vue';
|
import Step5CollectiveLessonAdmin from '@/components/course-edit/Step5CollectiveLesson.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
schoolCourseId: number;
|
schoolCourseId: number | string;
|
||||||
lessonData?: any;
|
lessonData?: any;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
import Step6DomainLessonsAdmin from '@/components/course-edit/Step6DomainLessons.vue';
|
import Step6DomainLessonsAdmin from '@/components/course-edit/Step6DomainLessons.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
schoolCourseId: number;
|
schoolCourseId: number | string;
|
||||||
domainLessons?: {
|
domainLessons?: {
|
||||||
LANGUAGE?: any;
|
LANGUAGE?: any;
|
||||||
HEALTH?: any;
|
HEALTH?: any;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user