refactor: 一点优化
This commit is contained in:
parent
65e2d19089
commit
a57ed52643
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"setting": {
|
||||||
|
"es6": true,
|
||||||
|
"postcss": true,
|
||||||
|
"minified": true,
|
||||||
|
"uglifyFileName": false,
|
||||||
|
"enhance": true,
|
||||||
|
"packNpmRelationList": [],
|
||||||
|
"babelSetting": {
|
||||||
|
"ignore": [],
|
||||||
|
"disablePlugins": [],
|
||||||
|
"outputPath": ""
|
||||||
|
},
|
||||||
|
"useCompilerPlugins": false,
|
||||||
|
"minifyWXML": true
|
||||||
|
},
|
||||||
|
"compileType": "miniprogram",
|
||||||
|
"simulatorPluginLibVersion": {},
|
||||||
|
"packOptions": {
|
||||||
|
"ignore": [],
|
||||||
|
"include": []
|
||||||
|
},
|
||||||
|
"appid": "wxc5e2d4198a20dfdf",
|
||||||
|
"editorSetting": {}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"libVersion": "3.11.2",
|
||||||
|
"projectname": "xlx_teacher_app",
|
||||||
|
"setting": {
|
||||||
|
"urlCheck": true,
|
||||||
|
"coverView": true,
|
||||||
|
"lazyloadPlaceholderEnable": false,
|
||||||
|
"skylineRenderEnable": false,
|
||||||
|
"preloadBackgroundData": false,
|
||||||
|
"autoAudits": false,
|
||||||
|
"showShadowRootInWxmlPanel": true,
|
||||||
|
"compileHotReLoad": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -62,13 +62,6 @@ const compareClassName = computed(() => {
|
||||||
return cls?.label || '选择对比班级'
|
return cls?.label || '选择对比班级'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取对比班级的 grade_key
|
|
||||||
const compareClassGradeKey = computed(() => {
|
|
||||||
if (!compareClassId.value)
|
|
||||||
return null
|
|
||||||
return homeStore.classGradeMap.get(compareClassId.value) || null
|
|
||||||
})
|
|
||||||
|
|
||||||
// 使用 TanStack Query 获取走势数据(包含本班和对比班级)
|
// 使用 TanStack Query 获取走势数据(包含本班和对比班级)
|
||||||
const {
|
const {
|
||||||
data: trendData,
|
data: trendData,
|
||||||
|
|
@ -81,7 +74,6 @@ const {
|
||||||
homeStore.selectedClassId,
|
homeStore.selectedClassId,
|
||||||
homeStore.selectedGradeKey,
|
homeStore.selectedGradeKey,
|
||||||
compareClassId,
|
compareClassId,
|
||||||
compareClassGradeKey,
|
|
||||||
props.selectedSubjectId,
|
props.selectedSubjectId,
|
||||||
topN,
|
topN,
|
||||||
],
|
],
|
||||||
|
|
@ -101,8 +93,7 @@ const {
|
||||||
enabled: computed(() =>
|
enabled: computed(() =>
|
||||||
!!homeStore.selectedClassId
|
!!homeStore.selectedClassId
|
||||||
&& !!homeStore.selectedGradeKey
|
&& !!homeStore.selectedGradeKey
|
||||||
&& !!compareClassId.value
|
&& !!compareClassId.value,
|
||||||
&& !!compareClassGradeKey.value,
|
|
||||||
),
|
),
|
||||||
staleTime: 30000, // 30秒内不重新请求
|
staleTime: 30000, // 30秒内不重新请求
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,6 @@ function navigateToQuality(subjectId: number) {
|
||||||
<view class="mb-4">
|
<view class="mb-4">
|
||||||
<view class="mb-2 flex items-center justify-between">
|
<view class="mb-2 flex items-center justify-between">
|
||||||
<text class="text-lg font-semibold">{{ task.exam_name }}</text>
|
<text class="text-lg font-semibold">{{ task.exam_name }}</text>
|
||||||
<view class="flex items-center">
|
|
||||||
<view class="i-mingcute:calendar-line mr-1 text-xs text-slate-500" />
|
|
||||||
<text class="text-xs text-gray-500">{{ formatDate(task.exam_date) }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 第二行:类型 + ID -->
|
<!-- 第二行:类型 + ID -->
|
||||||
|
|
@ -100,6 +96,10 @@ function navigateToQuality(subjectId: number) {
|
||||||
<text class="text-xs text-blue-600"> {{ task.exam_type }}</text>
|
<text class="text-xs text-blue-600"> {{ task.exam_type }}</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-xs text-green-600">考试ID: {{ task.exam_id }}</text>
|
<text class="text-xs text-green-600">考试ID: {{ task.exam_id }}</text>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="i-mingcute:calendar-line mr-1 text-xs text-slate-500" />
|
||||||
|
<text class="text-xs text-gray-500">{{ formatDate(task.exam_date) }}</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ function handleExamChange() {
|
||||||
uni.showActionSheet({
|
uni.showActionSheet({
|
||||||
itemList: examNames,
|
itemList: examNames,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
const selectedOption = homeStore.examOptions[res.tapIndex]
|
const selectedOption = homeStore.examOptions[res.tapIndex].filter(item => item.)
|
||||||
homeStore.selectedExamId = selectedOption.value as number
|
homeStore.selectedExamId = selectedOption.value as number
|
||||||
// 选择考试后重新获取统计数据
|
// 选择考试后重新获取统计数据
|
||||||
fetchExamStats()
|
fetchExamStats()
|
||||||
|
|
@ -449,7 +449,7 @@ onMounted(async () => {
|
||||||
<view class="i-mingcute:group-line mr-1 text-base text-blue-500" />
|
<view class="i-mingcute:group-line mr-1 text-base text-blue-500" />
|
||||||
<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.classCount }}/{{ statsData.totalCount }}</text>
|
<text class="center text-lg text-slate-800 font-bold">{{ statsData.classCount }}/{{ statsData.totalCount }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 均分排名 -->
|
<!-- 均分排名 -->
|
||||||
|
|
@ -458,7 +458,7 @@ onMounted(async () => {
|
||||||
<view class="i-mingcute:chart-bar-line mr-1 text-base text-blue-600" />
|
<view class="i-mingcute:chart-bar-line mr-1 text-base text-blue-600" />
|
||||||
<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.ranking }}/{{ statsData.totalRanking }}</text>
|
<text class="center text-lg text-slate-800 font-bold">{{ statsData.ranking }}/{{ statsData.totalRanking }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 年级前50名 -->
|
<!-- 年级前50名 -->
|
||||||
|
|
@ -467,7 +467,7 @@ onMounted(async () => {
|
||||||
<view class="i-mingcute:trophy-line mr-1 text-base text-cyan-500" />
|
<view class="i-mingcute:trophy-line mr-1 text-base text-cyan-500" />
|
||||||
<text class="text-xs text-slate-600">年级前50名</text>
|
<text class="text-xs text-slate-600">年级前50名</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData.top50Count }}/{{ statsData.top50Total }}</text>
|
<text class="center text-lg text-slate-800 font-bold">{{ statsData.top50Count }}/{{ statsData.top50Total }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 最高分/最低分 -->
|
<!-- 最高分/最低分 -->
|
||||||
|
|
@ -476,9 +476,12 @@ onMounted(async () => {
|
||||||
<view class="i-carbon:chart-line mr-1 text-base text-cyan-600" />
|
<view class="i-carbon:chart-line mr-1 text-base text-cyan-600" />
|
||||||
<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 }}/{{ statsData.lowestScore }}</text>
|
<text class="center text-lg text-slate-800 font-bold">{{ statsData.highestScore }}/{{ statsData.lowestScore }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 统计数据卡片 -->
|
||||||
|
<view class="grid grid-cols-3 mb-2 gap-2">
|
||||||
<!-- 优秀率 -->
|
<!-- 优秀率 -->
|
||||||
<view class="border border-sky-100 rounded-xl from-white to-sky-50 bg-gradient-to-br p-4 shadow-sky-50 shadow-sm">
|
<view class="border border-sky-100 rounded-xl from-white to-sky-50 bg-gradient-to-br p-4 shadow-sky-50 shadow-sm">
|
||||||
<view class="mb-1 flex items-center">
|
<view class="mb-1 flex items-center">
|
||||||
|
|
@ -496,15 +499,15 @@ onMounted(async () => {
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData.goodRate }}%</text>
|
<text class="text-lg text-slate-800 font-bold">{{ statsData.goodRate }}%</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 及格率 -->
|
<!-- 及格率 -->
|
||||||
<view class="mb-4 border border-blue-100 rounded-xl from-white to-blue-50 bg-gradient-to-br p-4 shadow-blue-50 shadow-sm">
|
<view class="border border-blue-100 rounded-xl from-white to-blue-50 bg-gradient-to-br p-4 shadow-blue-50 shadow-sm">
|
||||||
<view class="mb-1 flex items-center">
|
<view class="mb-1 flex items-center">
|
||||||
<view class="i-carbon:checkmark mr-1 text-base text-blue-500" />
|
<view class="i-carbon:checkmark mr-1 text-base text-blue-500" />
|
||||||
<text class="text-xs text-slate-600">及格率</text>
|
<text class="text-xs text-slate-600">及格率</text>
|
||||||
|
</view>
|
||||||
|
<text class="text-lg text-slate-800 font-bold">{{ statsData.passRate }}%</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="text-lg text-slate-800 font-bold">{{ statsData.passRate }}%</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 底部操作按钮 -->
|
<!-- 底部操作按钮 -->
|
||||||
|
|
@ -623,11 +626,11 @@ onMounted(async () => {
|
||||||
v-for="classItem in homeStore.classOptions"
|
v-for="classItem in homeStore.classOptions"
|
||||||
:key="classItem.value"
|
:key="classItem.value"
|
||||||
class="flex items-center justify-between rounded-xl bg-gray-50 p-3 active:bg-blue-50"
|
class="flex items-center justify-between rounded-xl bg-gray-50 p-3 active:bg-blue-50"
|
||||||
@tap="homeStore.selectedClassId = classItem.value"
|
@tap="homeStore.selectedClassId = classItem.value; homeStore.selectedGradeKey = classItem.gradeKey"
|
||||||
>
|
>
|
||||||
<text class="text-base">{{ classItem.label }}</text>
|
<text class="text-base">{{ classItem.label }}</text>
|
||||||
<view
|
<view
|
||||||
v-if="homeStore.selectedClassId === classItem.value"
|
v-if="homeStore.selectedClassId === classItem.value && homeStore.selectedGradeKey === classItem.gradeKey"
|
||||||
class="i-mingcute:check-line text-lg text-blue-500"
|
class="i-mingcute:check-line text-lg text-blue-500"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ function getIconColorClass(index: number) {
|
||||||
|
|
||||||
<!-- 角色信息 -->
|
<!-- 角色信息 -->
|
||||||
<view class="rounded-full bg-white/20 px-3 py-1 backdrop-blur-sm">
|
<view class="rounded-full bg-white/20 px-3 py-1 backdrop-blur-sm">
|
||||||
<text class="text-sm text-white/90">角色:{{ getRoleText }}</text>
|
<text class="text-sm text-white/90">账号信息:{{ userInfo.phone || "17622222222" }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -174,28 +174,15 @@ function getIconColorClass(index: number) {
|
||||||
<!-- 主要内容区域 -->
|
<!-- 主要内容区域 -->
|
||||||
<view class="relative z-10 mx-2 min-h-[calc(100vh-200px)] rounded-t-3xl bg-white px-2 pt-4">
|
<view class="relative z-10 mx-2 min-h-[calc(100vh-200px)] rounded-t-3xl bg-white px-2 pt-4">
|
||||||
<!-- 账号和学校信息卡片 -->
|
<!-- 账号和学校信息卡片 -->
|
||||||
<view class="grid grid-cols-2 mx-2 mb-4 gap-3">
|
<!-- 所属学校 -->
|
||||||
<!-- 账号信息 -->
|
<view class="mx-2 mb-4 border border-cyan-100 rounded-xl from-white to-cyan-50 bg-gradient-to-br p-4 shadow-cyan-50 shadow-sm">
|
||||||
<view class="border border-blue-100 rounded-xl from-white to-blue-50 bg-gradient-to-br p-4 shadow-blue-50 shadow-sm">
|
<view class="mb-1 flex items-center">
|
||||||
<view class="mb-1 flex items-center">
|
<view class="i-mingcute:school-line mr-1 text-base text-cyan-500" />
|
||||||
<view class="i-mingcute:user-line mr-1 text-base text-blue-500" />
|
<text class="text-xs text-slate-600">所属学校</text>
|
||||||
<text class="text-xs text-slate-600">账号信息</text>
|
|
||||||
</view>
|
|
||||||
<text class="text-base text-slate-800 font-bold">
|
|
||||||
{{ userInfo.phone || "17622222222" }}
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 所属学校 -->
|
|
||||||
<view class="border border-cyan-100 rounded-xl from-white to-cyan-50 bg-gradient-to-br p-4 shadow-cyan-50 shadow-sm">
|
|
||||||
<view class="mb-1 flex items-center">
|
|
||||||
<view class="i-mingcute:school-line mr-1 text-base text-cyan-500" />
|
|
||||||
<text class="text-xs text-slate-600">所属学校</text>
|
|
||||||
</view>
|
|
||||||
<text class="text-base text-slate-800 font-bold">
|
|
||||||
{{ userInfo.schools?.[0]?.name || "光谷四小" }}
|
|
||||||
</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
<text class="text-base text-slate-800 font-bold">
|
||||||
|
{{ userInfo.schools?.[0]?.name || "光谷四小" }}
|
||||||
|
</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 功能菜单标题 -->
|
<!-- 功能菜单标题 -->
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ export interface SelectOption {
|
||||||
value: number
|
value: number
|
||||||
examSubjectId?: number
|
examSubjectId?: number
|
||||||
subjectId?: number
|
subjectId?: number
|
||||||
|
gradeKey?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
// 班级信息类型
|
// 班级信息类型
|
||||||
|
|
@ -29,14 +30,13 @@ export const useHomeStore = defineStore(
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const examDataMap = ref<Map<number, ModelTeacherAnalysisExamInfo>>(new Map())
|
const examDataMap = ref<Map<number, ModelTeacherAnalysisExamInfo>>(new Map())
|
||||||
const classList = ref<ClassItem[]>([])
|
const classList = ref<ClassItem[]>([])
|
||||||
const classGradeMap = ref<Map<number, number>>(new Map())
|
|
||||||
|
|
||||||
// 已选择的数据(使用 useUserStorage 实现基于用户的持久化)
|
// 已选择的数据(使用 useUserStorage 实现基于用户的持久化)
|
||||||
const selectedClassId = useUserStorage<number>('home_selectedClassId', 0)
|
const selectedClassId = useUserStorage<number>('home_selectedClassId', 0)
|
||||||
const selectedExamId = useUserStorage<number>('home_selectedExamId', 0)
|
const selectedExamId = useUserStorage<number>('home_selectedExamId', 0)
|
||||||
const selectedSubjectId = useUserStorage<number>('home_selectedSubjectId', 0)
|
const selectedSubjectId = useUserStorage<number>('home_selectedSubjectId', 0)
|
||||||
const selectedExamSubjectId = useUserStorage<number>('home_selectedExamSubjectId', 0)
|
const selectedExamSubjectId = useUserStorage<number>('home_selectedExamSubjectId', 0)
|
||||||
const selectedGradeKey = computed(() => classGradeMap.value.get(selectedClassId.value || 0) || null)
|
const selectedGradeKey = useUserStorage<number>('home_selectedGradeKey', 0)
|
||||||
|
|
||||||
// 计算属性:考试选项
|
// 计算属性:考试选项
|
||||||
const examOptions = computed((): SelectOption[] => {
|
const examOptions = computed((): SelectOption[] => {
|
||||||
|
|
@ -51,6 +51,7 @@ export const useHomeStore = defineStore(
|
||||||
return classList.value.map(item => ({
|
return classList.value.map(item => ({
|
||||||
label: item.label,
|
label: item.label,
|
||||||
value: item.value,
|
value: item.value,
|
||||||
|
gradeKey: item.gradeKey,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -82,18 +83,18 @@ export const useHomeStore = defineStore(
|
||||||
if (response) {
|
if (response) {
|
||||||
// 处理班级数据并建立班级到年级的映射
|
// 处理班级数据并建立班级到年级的映射
|
||||||
classList.value = (response.class_list || []).map((item: ModelTeacherAnalysisClassInfo) => {
|
classList.value = (response.class_list || []).map((item: ModelTeacherAnalysisClassInfo) => {
|
||||||
const classKey = item.class_key || 0
|
if (!item.class_key || !item.grade_key) {
|
||||||
const gradeKey = item.grade_key || 0
|
return null
|
||||||
|
}
|
||||||
// 建立班级到年级的映射
|
const classKey = item.class_key
|
||||||
classGradeMap.value.set(classKey, gradeKey)
|
const gradeKey = item.grade_key
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: `${item.grade || ''} ${item.class || ''}`.trim(),
|
label: `${item.grade || ''} ${item.class || ''}`.trim(),
|
||||||
value: classKey,
|
value: classKey,
|
||||||
gradeKey,
|
gradeKey,
|
||||||
}
|
}
|
||||||
})
|
}).filter(item => item !== null) as ClassItem[]
|
||||||
|
|
||||||
// 处理考试数据,存储到 map 中
|
// 处理考试数据,存储到 map 中
|
||||||
examDataMap.value.clear()
|
examDataMap.value.clear()
|
||||||
|
|
@ -150,7 +151,6 @@ export const useHomeStore = defineStore(
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
classList.value = []
|
classList.value = []
|
||||||
examDataMap.value.clear()
|
examDataMap.value.clear()
|
||||||
classGradeMap.value.clear()
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
clearSelections()
|
clearSelections()
|
||||||
}
|
}
|
||||||
|
|
@ -195,9 +195,6 @@ export const useHomeStore = defineStore(
|
||||||
selectedExamSubjectId,
|
selectedExamSubjectId,
|
||||||
selectedGradeKey,
|
selectedGradeKey,
|
||||||
|
|
||||||
// 内部数据映射
|
|
||||||
classGradeMap,
|
|
||||||
|
|
||||||
// 方法
|
// 方法
|
||||||
fetchOptions,
|
fetchOptions,
|
||||||
onExamChange,
|
onExamChange,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue