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