fix: 除了没接口的部分,其他大体完成
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
95e05b37d6
commit
dece1db47c
|
|
@ -191,8 +191,9 @@ onMounted(async () => {
|
||||||
<!-- 班次/校次列 -->
|
<!-- 班次/校次列 -->
|
||||||
<wd-table-col prop="rank" label="班次/校次" :width="`${40}%`">
|
<wd-table-col prop="rank" label="班次/校次" :width="`${40}%`">
|
||||||
<template #value="{ row }">
|
<template #value="{ row }">
|
||||||
<view class="text-xs">
|
<view class="flex gap-2 text-xs">
|
||||||
<view>{{ row.class_rank || '--' }}</view>
|
<view>{{ row.class_rank || '--' }}</view>
|
||||||
|
/
|
||||||
<view class="text-gray-500">
|
<view class="text-gray-500">
|
||||||
{{ row.grade_rank || '--' }}
|
{{ row.grade_rank || '--' }}
|
||||||
</view>
|
</view>
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ import {
|
||||||
import { useHomeStore } from '@/store/home'
|
import { useHomeStore } from '@/store/home'
|
||||||
|
|
||||||
// 类型别名
|
// 类型别名
|
||||||
type ExamComparisonItem = API.ExamComparisonItem
|
|
||||||
type RankStatisticsItem = API.RankStatisticsItem
|
|
||||||
type KeyStudentInfo = API.KeyStudentInfo
|
type KeyStudentInfo = API.KeyStudentInfo
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
|
|
@ -161,7 +159,7 @@ const {
|
||||||
scoreSettings.value.top_n,
|
scoreSettings.value.top_n,
|
||||||
]),
|
]),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const response = await teacherAnalysisRecentExamStatsUsingPost({
|
return await teacherAnalysisRecentExamStatsUsingPost({
|
||||||
body: {
|
body: {
|
||||||
class_key: homeStore.selectedClassId,
|
class_key: homeStore.selectedClassId,
|
||||||
exam_id: homeStore.selectedExamId,
|
exam_id: homeStore.selectedExamId,
|
||||||
|
|
@ -172,38 +170,14 @@ const {
|
||||||
pass_scoring_rate: scoreSettings.value.pass_scoring_rate,
|
pass_scoring_rate: scoreSettings.value.pass_scoring_rate,
|
||||||
top_n: scoreSettings.value.top_n,
|
top_n: scoreSettings.value.top_n,
|
||||||
},
|
},
|
||||||
}) as any
|
})
|
||||||
|
|
||||||
if (response?.data) {
|
|
||||||
const data = response.data
|
|
||||||
return {
|
|
||||||
examCount: data.class_total_count || 0,
|
|
||||||
averageScore: Math.round(data.class_average_score || 0),
|
|
||||||
totalScore: data.full_score || 100,
|
|
||||||
highestScore: data.class_highest_score || 0,
|
|
||||||
lowestScore: data.class_lowest_score || 0,
|
|
||||||
excellentRate: Math.round((data.excellent_class_scoring_rate || 0) * 100),
|
|
||||||
goodRate: Math.round((data.good_class_scoring_rate || 0) * 100),
|
|
||||||
passRate: Math.round((data.pass_class_scoring_rate || 0) * 100),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
examCount: 0,
|
|
||||||
averageScore: 0,
|
|
||||||
totalScore: 100,
|
|
||||||
highestScore: 0,
|
|
||||||
lowestScore: 0,
|
|
||||||
excellentRate: 0,
|
|
||||||
goodRate: 0,
|
|
||||||
passRate: 0,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
enabled: isQueryEnabled,
|
enabled: isQueryEnabled,
|
||||||
staleTime: 30000, // 30秒内不重新请求
|
staleTime: 30000, // 30秒内不重新请求
|
||||||
})
|
})
|
||||||
|
|
||||||
// 使用 TanStack Query 获取对比数据
|
type ExamComparisonItem = API.ExamComparisonItem & API.ExamComparisonItemH
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: comparisonData,
|
data: comparisonData,
|
||||||
isLoading: isLoadingComparison,
|
isLoading: isLoadingComparison,
|
||||||
|
|
@ -218,26 +192,23 @@ const {
|
||||||
]),
|
]),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (comparisonMode.value === 'horizontal') {
|
if (comparisonMode.value === 'horizontal') {
|
||||||
const response = await teacherAnalysisClassExamComparisonHorizontalUsingPost({
|
return (await teacherAnalysisClassExamComparisonHorizontalUsingPost({
|
||||||
body: {
|
body: {
|
||||||
exam_id: homeStore.selectedExamId,
|
exam_id: homeStore.selectedExamId,
|
||||||
class_key: homeStore.selectedClassId,
|
class_key: homeStore.selectedClassId,
|
||||||
grade_key: homeStore.selectedGradeKey,
|
grade_key: homeStore.selectedGradeKey,
|
||||||
subject_id: selectedSubjectId.value || undefined,
|
subject_id: selectedSubjectId.value || undefined,
|
||||||
},
|
},
|
||||||
})
|
})).exam_list as ExamComparisonItem[] || []
|
||||||
return []
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const response = await teacherAnalysisClassExamComparisonUsingPost({
|
return (await teacherAnalysisClassExamComparisonUsingPost({
|
||||||
body: {
|
body: {
|
||||||
class_key: homeStore.selectedClassId,
|
class_key: homeStore.selectedClassId,
|
||||||
grade_key: homeStore.selectedGradeKey,
|
grade_key: homeStore.selectedGradeKey,
|
||||||
subject_id: selectedSubjectId.value || undefined,
|
subject_id: selectedSubjectId.value || undefined,
|
||||||
},
|
},
|
||||||
}) as any
|
})).exam_list as ExamComparisonItem[] || []
|
||||||
|
|
||||||
return response?.exam_list || []
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled: computed(() => !!homeStore.selectedClassId && !!homeStore.selectedGradeKey),
|
enabled: computed(() => !!homeStore.selectedClassId && !!homeStore.selectedGradeKey),
|
||||||
|
|
@ -255,25 +226,33 @@ const {
|
||||||
homeStore.selectedClassId,
|
homeStore.selectedClassId,
|
||||||
homeStore.selectedExamId,
|
homeStore.selectedExamId,
|
||||||
selectedSubjectId.value,
|
selectedSubjectId.value,
|
||||||
|
scoreSettings.value.rank_top_1,
|
||||||
|
scoreSettings.value.rank_top_2,
|
||||||
|
scoreSettings.value.rank_top_3,
|
||||||
]),
|
]),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const classIds = selectedClassIds.value.length > 0
|
const classIds = selectedClassIds.value.length > 0
|
||||||
? selectedClassIds.value.map(id => Number.parseInt(id))
|
? selectedClassIds.value
|
||||||
: (homeStore.selectedClassId ? [homeStore.selectedClassId] : [])
|
: (homeStore.selectedClassId ? [homeStore.selectedClassId.toString()] : [])
|
||||||
|
|
||||||
if (classIds.length === 0) {
|
if (classIds.length === 0) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await teacherAnalysisRankStatisticsUsingPost({
|
return (await teacherAnalysisRankStatisticsUsingPost({
|
||||||
body: {
|
body: {
|
||||||
class_id: classIds[0],
|
class_ids: classIds,
|
||||||
exam_id: homeStore.selectedExamId,
|
exam_id: homeStore.selectedExamId,
|
||||||
subject_id: selectedSubjectId.value || undefined,
|
subject_id: selectedSubjectId.value || 0,
|
||||||
|
query_mode: 'class',
|
||||||
|
statistics_mode: 'cumulative',
|
||||||
|
rank_ranges: [
|
||||||
|
{ name: `前${scoreSettings.value.rank_top_1}名`, start: 1, end: scoreSettings.value.rank_top_1 },
|
||||||
|
{ name: `前${scoreSettings.value.rank_top_2}名`, start: 1, end: scoreSettings.value.rank_top_2 },
|
||||||
|
{ name: `前${scoreSettings.value.rank_top_3}名`, start: 1, end: scoreSettings.value.rank_top_3 },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
}) as any
|
})).data as any || []
|
||||||
|
|
||||||
return response?.data || []
|
|
||||||
},
|
},
|
||||||
enabled: computed(() => !!homeStore.selectedExamId),
|
enabled: computed(() => !!homeStore.selectedExamId),
|
||||||
staleTime: 30000,
|
staleTime: 30000,
|
||||||
|
|
@ -503,7 +482,7 @@ const loading = computed(() =>
|
||||||
<view class="mb-2 flex items-center">
|
<view class="mb-2 flex items-center">
|
||||||
<text class="text-xs text-slate-600">考试人数</text>
|
<text class="text-xs text-slate-600">考试人数</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData?.examCount || 0 }}</text>
|
<text class="text-lg text-slate-800 font-bold">{{ statsData?.class_total_count || 0 }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 平均分/满分 -->
|
<!-- 平均分/满分 -->
|
||||||
|
|
@ -511,7 +490,7 @@ const loading = computed(() =>
|
||||||
<view class="mb-2 flex items-center">
|
<view class="mb-2 flex items-center">
|
||||||
<text class="text-xs text-slate-600">平均分/满分</text>
|
<text class="text-xs text-slate-600">平均分/满分</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData?.averageScore || 0 }}/{{ statsData?.totalScore || 100 }}</text>
|
<text class="text-lg text-slate-800 font-bold">{{ Math.round(statsData?.class_average_score || 0) }}/{{ statsData?.full_score || 100 }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 最高分/最低分 -->
|
<!-- 最高分/最低分 -->
|
||||||
|
|
@ -519,7 +498,7 @@ const loading = computed(() =>
|
||||||
<view class="mb-2 flex items-center">
|
<view class="mb-2 flex items-center">
|
||||||
<text class="text-xs text-slate-600">最高分/最低分</text>
|
<text class="text-xs text-slate-600">最高分/最低分</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData?.highestScore || 0 }}/{{ statsData?.lowestScore || 0 }}</text>
|
<text class="text-lg text-slate-800 font-bold">{{ statsData?.class_highest_score || 0 }}/{{ statsData?.class_lowest_score || 0 }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 优秀率 -->
|
<!-- 优秀率 -->
|
||||||
|
|
@ -527,7 +506,7 @@ const loading = computed(() =>
|
||||||
<view class="mb-2 flex items-center">
|
<view class="mb-2 flex items-center">
|
||||||
<text class="text-xs text-slate-600">优秀率</text>
|
<text class="text-xs text-slate-600">优秀率</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData?.excellentRate || 0 }}%</text>
|
<text class="text-lg text-slate-800 font-bold">{{ Math.round((statsData?.excellent_class_scoring_rate || 0) * 100) }}%</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 良好率 -->
|
<!-- 良好率 -->
|
||||||
|
|
@ -535,7 +514,7 @@ const loading = computed(() =>
|
||||||
<view class="mb-2 flex items-center">
|
<view class="mb-2 flex items-center">
|
||||||
<text class="text-xs text-slate-600">良好率</text>
|
<text class="text-xs text-slate-600">良好率</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData?.goodRate || 0 }}%</text>
|
<text class="text-lg text-slate-800 font-bold">{{ Math.round((statsData?.good_class_scoring_rate || 0) * 100) }}%</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 及格率 -->
|
<!-- 及格率 -->
|
||||||
|
|
@ -543,7 +522,7 @@ const loading = computed(() =>
|
||||||
<view class="mb-2 flex items-center">
|
<view class="mb-2 flex items-center">
|
||||||
<text class="text-xs text-slate-600">及格率</text>
|
<text class="text-xs text-slate-600">及格率</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData?.passRate || 0 }}%</text>
|
<text class="text-lg text-slate-800 font-bold">{{ Math.round((statsData?.pass_class_scoring_rate || 0) * 100) }}%</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
@ -589,29 +568,28 @@ const loading = computed(() =>
|
||||||
{{ comparisonMode === 'horizontal' ? '学科' : '考试' }}
|
{{ comparisonMode === 'horizontal' ? '学科' : '考试' }}
|
||||||
</text>
|
</text>
|
||||||
<text class="text-sm text-gray-600 font-medium">班级平均分</text>
|
<text class="text-sm text-gray-600 font-medium">班级平均分</text>
|
||||||
<text class="text-sm text-gray-600 font-medium">年级平均分</text>
|
<text class="text-sm text-gray-600 font-medium">{{ comparisonMode === 'horizontal' ? '年级平均分' : '平均分排名' }}</text>
|
||||||
<text class="text-sm text-gray-600 font-medium">班级排名</text>
|
<text class="text-sm text-gray-600 font-medium">{{ comparisonMode === 'horizontal' ? '班级排名' : '班级标准分' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<!-- 对比数据列表 -->
|
||||||
|
<!-- 暂无数据提示 -->
|
||||||
|
<view v-if="comparisonData.length === 0" class="py-8 text-center">
|
||||||
|
<text class="text-sm text-gray-500">暂无对比数据</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 对比数据列表 -->
|
<view v-else class="space-y-2">
|
||||||
<view class="space-y-2">
|
|
||||||
<view
|
<view
|
||||||
v-for="(item, index) in comparisonData"
|
v-for="(item, index) in comparisonData"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="grid grid-cols-4 gap-2 border-b border-gray-100 py-2 text-center last:border-b-0"
|
class="grid grid-cols-4 gap-2 border-b border-gray-100 py-2 text-center last:border-b-0"
|
||||||
>
|
>
|
||||||
<text class="text-sm text-gray-800">{{ item.exam_name || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-800">{{ comparisonMode === 'horizontal' ? item.subject_name : item.exam_name || '-' }}</text>
|
||||||
<text class="text-sm text-gray-800 font-medium">{{ item.class_average || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-800 font-medium">{{ item.class_average || '-' }}</text>
|
||||||
<text class="text-sm text-gray-600">{{ item.class_standard || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-600">{{ comparisonMode === 'horizontal' ? item.grade_average || '-' : item.average_rank || '-' }}</text>
|
||||||
<text class="text-sm text-gray-600">{{ item.average_rank || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-600">{{ comparisonMode === 'horizontal' ? item.class_rank || '-' : item.class_standard || '-' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 暂无数据提示 -->
|
|
||||||
<view v-if="!comparisonData || comparisonData.length === 0" class="py-8 text-center">
|
|
||||||
<text class="text-sm text-gray-500">暂无对比数据</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 名次分析卡片 -->
|
<!-- 名次分析卡片 -->
|
||||||
|
|
@ -646,14 +624,14 @@ const loading = computed(() =>
|
||||||
:key="index"
|
:key="index"
|
||||||
class="grid grid-cols-4 gap-2 border-b border-gray-100 py-2 text-center last:border-b-0"
|
class="grid grid-cols-4 gap-2 border-b border-gray-100 py-2 text-center last:border-b-0"
|
||||||
>
|
>
|
||||||
<text class="text-sm text-gray-800 font-medium">{{ item.name || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-800 font-medium">{{ item.name || '-' }}</text>
|
||||||
<text class="text-sm text-gray-800">
|
<text class="text-ellipsis text-sm text-gray-800">
|
||||||
{{ item.rank_stats?.find(r => r.end === scoreSettings.rank_top_1)?.count || 0 }}
|
{{ item.rank_stats?.find(r => r.end === scoreSettings.rank_top_1)?.count || 0 }}
|
||||||
</text>
|
</text>
|
||||||
<text class="text-sm text-gray-800">
|
<text class="text-ellipsis text-sm text-gray-800">
|
||||||
{{ item.rank_stats?.find(r => r.end === scoreSettings.rank_top_2)?.count || 0 }}
|
{{ item.rank_stats?.find(r => r.end === scoreSettings.rank_top_2)?.count || 0 }}
|
||||||
</text>
|
</text>
|
||||||
<text class="text-sm text-gray-800">
|
<text class="text-ellipsis text-sm text-gray-800">
|
||||||
{{ item.rank_stats?.find(r => r.end === scoreSettings.rank_top_3)?.count || 0 }}
|
{{ item.rank_stats?.find(r => r.end === scoreSettings.rank_top_3)?.count || 0 }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -717,10 +695,10 @@ const loading = computed(() =>
|
||||||
:key="index"
|
:key="index"
|
||||||
class="grid grid-cols-3 gap-2 border-b border-gray-100 py-2 text-center last:border-b-0"
|
class="grid grid-cols-3 gap-2 border-b border-gray-100 py-2 text-center last:border-b-0"
|
||||||
>
|
>
|
||||||
<text class="text-sm text-gray-800 font-medium">{{ student.student_name || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-800 font-medium">{{ student.student_name || '-' }}</text>
|
||||||
<text class="text-sm text-gray-800">{{ student.class_rank || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-800">{{ student.class_rank || '-' }}</text>
|
||||||
<text
|
<text
|
||||||
class="text-sm font-medium"
|
class="text-ellipsis text-sm font-medium"
|
||||||
:class="keyStudentType === 'up' ? 'text-green-600' : 'text-red-600'"
|
:class="keyStudentType === 'up' ? 'text-green-600' : 'text-red-600'"
|
||||||
>
|
>
|
||||||
{{ keyStudentType === 'up' ? '+' : '-' }}{{ student.class_diff_rank || 0 }}
|
{{ keyStudentType === 'up' ? '+' : '-' }}{{ student.class_diff_rank || 0 }}
|
||||||
|
|
@ -791,10 +769,10 @@ const loading = computed(() =>
|
||||||
:key="index"
|
:key="index"
|
||||||
class="grid grid-cols-3 gap-2 p-4 text-center"
|
class="grid grid-cols-3 gap-2 p-4 text-center"
|
||||||
>
|
>
|
||||||
<text class="text-sm text-gray-800 font-medium">{{ student.student_name || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-800 font-medium">{{ student.student_name || '-' }}</text>
|
||||||
<text class="text-sm text-gray-800">{{ student.class_rank || '-' }}</text>
|
<text class="text-ellipsis text-sm text-gray-800">{{ student.class_rank || '-' }}</text>
|
||||||
<text
|
<text
|
||||||
class="text-sm font-medium"
|
class="text-ellipsis text-sm font-medium"
|
||||||
:class="keyStudentType === 'up' ? 'text-green-600' : 'text-red-600'"
|
:class="keyStudentType === 'up' ? 'text-green-600' : 'text-red-600'"
|
||||||
>
|
>
|
||||||
{{ keyStudentType === 'up' ? '+' : '-' }}{{ student.class_diff_rank || 0 }}
|
{{ keyStudentType === 'up' ? '+' : '-' }}{{ student.class_diff_rank || 0 }}
|
||||||
|
|
@ -839,4 +817,11 @@ const loading = computed(() =>
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防溢出通用类
|
||||||
|
.text-ellipsis {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue