feat: 进度查看界面添加了按照进度排序功能
This commit is contained in:
parent
4406934444
commit
e0995a9132
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -27,6 +27,7 @@ declare module 'vue' {
|
|||||||
WdProgress: typeof import('wot-design-uni/components/wd-progress/wd-progress.vue')['default']
|
WdProgress: typeof import('wot-design-uni/components/wd-progress/wd-progress.vue')['default']
|
||||||
WdRadio: typeof import('wot-design-uni/components/wd-radio/wd-radio.vue')['default']
|
WdRadio: typeof import('wot-design-uni/components/wd-radio/wd-radio.vue')['default']
|
||||||
WdRadioGroup: typeof import('wot-design-uni/components/wd-radio-group/wd-radio-group.vue')['default']
|
WdRadioGroup: typeof import('wot-design-uni/components/wd-radio-group/wd-radio-group.vue')['default']
|
||||||
|
WdSortButton: typeof import('wot-design-uni/components/wd-sort-button/wd-sort-button.vue')['default']
|
||||||
WdStatusTip: typeof import('wot-design-uni/components/wd-status-tip/wd-status-tip.vue')['default']
|
WdStatusTip: typeof import('wot-design-uni/components/wd-status-tip/wd-status-tip.vue')['default']
|
||||||
WdStep: typeof import('wot-design-uni/components/wd-step/wd-step.vue')['default']
|
WdStep: typeof import('wot-design-uni/components/wd-step/wd-step.vue')['default']
|
||||||
WdSteps: typeof import('wot-design-uni/components/wd-steps/wd-steps.vue')['default']
|
WdSteps: typeof import('wot-design-uni/components/wd-steps/wd-steps.vue')['default']
|
||||||
|
@ -54,6 +54,7 @@ const handleBeforeToggle: DropMenuItemBeforeToggle = ({ status, resolve }) => {
|
|||||||
|
|
||||||
const expandedCourse = ref(['lesson'])
|
const expandedCourse = ref(['lesson'])
|
||||||
const groupedLessons = ref<{ [key: string]: LessonTask[] }>({})
|
const groupedLessons = ref<{ [key: string]: LessonTask[] }>({})
|
||||||
|
const refreshKey = ref(0)
|
||||||
|
|
||||||
const openLessonDetail = (courseId: number) => {
|
const openLessonDetail = (courseId: number) => {
|
||||||
router.push({
|
router.push({
|
||||||
@ -97,22 +98,47 @@ const loadLessons = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupData = res.data.content
|
// 先按 id 排序
|
||||||
.sort((a: LessonTask, b: LessonTask) => a.id - b.id)
|
let sortedContent = [...res.data.content].sort((a: LessonTask, b: LessonTask) => a.id - b.id)
|
||||||
.reduce((acc: { [key: string]: LessonTask[] }, cur: LessonTask) => {
|
|
||||||
if (!acc[cur.courseName]) {
|
|
||||||
acc[cur.courseName] = []
|
|
||||||
}
|
|
||||||
acc[cur.courseName].push(cur)
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
|
|
||||||
|
// 分组
|
||||||
|
const groupData = sortedContent.reduce((acc: { [key: string]: LessonTask[] }, cur: LessonTask) => {
|
||||||
|
if (!acc[cur.courseName]) {
|
||||||
|
acc[cur.courseName] = []
|
||||||
|
}
|
||||||
|
acc[cur.courseName].push(cur)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
|
||||||
|
// 如果不是默认排序,对每个组内的课程按进度排序
|
||||||
|
if (value.value !== 0) {
|
||||||
|
Object.keys(groupData).forEach(courseName => {
|
||||||
|
groupData[courseName].sort((a: LessonTask, b: LessonTask) => {
|
||||||
|
const progressA = calcLessonProgress(a)
|
||||||
|
const progressB = calcLessonProgress(b)
|
||||||
|
return value.value === 1
|
||||||
|
? progressB - progressA // 完成度高的优先(降序)
|
||||||
|
: progressA - progressB // 完成度低的优先(升序)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('分组后的课程数据:', JSON.stringify(groupData, null, 2))
|
||||||
groupedLessons.value = groupData
|
groupedLessons.value = groupData
|
||||||
expandedCourse.value = Object.keys(groupData).filter(courseName => {
|
|
||||||
return groupData[courseName].filter((lesson: LessonTask) =>
|
const expandedGroups = Object.keys(groupData).filter(courseName => {
|
||||||
calcLessonProgress(lesson) !== 0 && calcLessonProgress(lesson) !== 100
|
const courses = groupData[courseName]
|
||||||
).length > 0
|
const hasCompleted = courses.some(lesson => calcLessonProgress(lesson) === 100)
|
||||||
|
const hasNotStarted = courses.some(lesson => calcLessonProgress(lesson) === 0)
|
||||||
|
const hasInProgress = courses.some(lesson => {
|
||||||
|
const progress = calcLessonProgress(lesson)
|
||||||
|
return progress > 0 && progress < 100
|
||||||
|
})
|
||||||
|
return (hasCompleted && hasNotStarted) || hasInProgress
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 更新展开的课程组
|
||||||
|
expandedCourse.value = expandedGroups
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
toast.error({ msg: err.message })
|
toast.error({ msg: err.message })
|
||||||
@ -163,19 +189,35 @@ onLoad(() => {
|
|||||||
loadLessons()
|
loadLessons()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const value = ref<number>(0)
|
||||||
|
|
||||||
|
// 处理排序按钮点击
|
||||||
|
const handleChange = ({ value: newValue }: { value: number }) => {
|
||||||
|
console.log('排序值:', newValue)
|
||||||
|
value.value = newValue
|
||||||
|
loadLessons().then(() => {
|
||||||
|
// 强制重新渲染组件
|
||||||
|
refreshKey.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<page-wrapper>
|
<page-wrapper>
|
||||||
<div>
|
<div>
|
||||||
<wd-drop-menu v-if="!user.hasRole('teacher')">
|
<div v-if="!user.hasRole('teacher')" class="flex items-center justify-around gap-4 px-4">
|
||||||
<wd-drop-menu-item v-model="teacherFilterValue" :options="teacherFilterOptions"
|
<wd-drop-menu>
|
||||||
:before-toggle="handleBeforeToggle" />
|
<wd-drop-menu-item v-model="teacherFilterValue" :options="teacherFilterOptions"
|
||||||
</wd-drop-menu>
|
:before-toggle="handleBeforeToggle" />
|
||||||
|
</wd-drop-menu>
|
||||||
|
<view>
|
||||||
|
<wd-sort-button title="进度" allow-reset v-model="value" @change="handleChange" />
|
||||||
|
</view>
|
||||||
|
</div>
|
||||||
<wd-collapse v-model="expandedCourse">
|
<wd-collapse v-model="expandedCourse">
|
||||||
<wd-status-tip v-if="Object.keys(groupedLessons).length === 0" image="content" tip="当前账号没有分配微课" />
|
<wd-status-tip v-if="Object.keys(groupedLessons).length === 0" image="content" tip="当前账号没有分配微课" />
|
||||||
<wd-collapse-item v-else v-for="(courses, courseName) in groupedLessons" :name="`${courseName}`"
|
<wd-collapse-item v-else v-for="(courses, courseName) in groupedLessons" :name="`${courseName}`"
|
||||||
:key="courseName">
|
:key="`${courseName}-${refreshKey}`">
|
||||||
<template #title="{ expanded, disabled, isFirst }">
|
<template #title="{ expanded, disabled, isFirst }">
|
||||||
<div class="w-full flex justify-between items-center">
|
<div class="w-full flex justify-between items-center">
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
@ -184,25 +226,31 @@ onLoad(() => {
|
|||||||
</p>
|
</p>
|
||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
<wd-tag v-if="(() => {
|
<wd-tag v-if="(() => {
|
||||||
|
// 如果有已完成的课程和未开始的课程,就显示进行中
|
||||||
|
const hasCompleted = courses.some(lesson => calcLessonProgress(lesson) === 100)
|
||||||
|
const hasNotStarted = courses.some(lesson => calcLessonProgress(lesson) === 0)
|
||||||
|
if (hasCompleted && hasNotStarted) return true
|
||||||
|
|
||||||
|
// 或者有进度在0-100之间的课程
|
||||||
const hasInProgress = courses.some(lesson => {
|
const hasInProgress = courses.some(lesson => {
|
||||||
const progress = calcLessonProgress(lesson);
|
const progress = calcLessonProgress(lesson)
|
||||||
return progress > 0 && progress < 100;
|
return progress > 0 && progress < 100
|
||||||
});
|
})
|
||||||
return hasInProgress;
|
return hasInProgress
|
||||||
})()" custom-class="w-fit" type="primary">进行中</wd-tag>
|
})()" custom-class="w-fit" type="primary">进行中</wd-tag>
|
||||||
<wd-tag v-if="(() => {
|
<wd-tag v-if="(() => {
|
||||||
const allCompleted = courses.every(lesson => {
|
const allCompleted = courses.every(lesson => {
|
||||||
const progress = calcLessonProgress(lesson);
|
const progress = calcLessonProgress(lesson)
|
||||||
return progress === 100;
|
return progress === 100
|
||||||
});
|
})
|
||||||
return allCompleted;
|
return allCompleted
|
||||||
})()" custom-class="w-fit" type="success">已完成</wd-tag>
|
})()" custom-class="w-fit" type="success">已完成</wd-tag>
|
||||||
<wd-tag v-if="(() => {
|
<wd-tag v-if="(() => {
|
||||||
const allNotStarted = courses.every(lesson => {
|
const allNotStarted = courses.every(lesson => {
|
||||||
const progress = calcLessonProgress(lesson);
|
const progress = calcLessonProgress(lesson)
|
||||||
return progress === 0;
|
return progress === 0
|
||||||
});
|
})
|
||||||
return allNotStarted;
|
return allNotStarted
|
||||||
})()" custom-class="w-fit" type="default">未开始</wd-tag>
|
})()" custom-class="w-fit" type="default">未开始</wd-tag>
|
||||||
<wd-tag custom-class="op-60" plain>
|
<wd-tag custom-class="op-60" plain>
|
||||||
共{{ courses.length }}节微课
|
共{{ courses.length }}节微课
|
||||||
@ -238,7 +286,8 @@ onLoad(() => {
|
|||||||
</template>
|
</template>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<wd-status-tip v-if="courses.length === 0" image="content" tip="没有课程小节" />
|
<wd-status-tip v-if="courses.length === 0" image="content" tip="没有课程小节" />
|
||||||
<div v-else v-for="(lesson, i) in courses" :key="i" @click="openLessonDetail(lesson.id)"
|
<div v-else v-for="(lesson, i) in courses" :key="`${lesson.id}-${refreshKey}`"
|
||||||
|
@click="openLessonDetail(lesson.id)"
|
||||||
class="w-full py-2 gap-12 flex justify-between items-center border-b border-b-solid border-neutral-100 last:border-b-0 first:pt-0 last:pb-0">
|
class="w-full py-2 gap-12 flex justify-between items-center border-b border-b-solid border-neutral-100 last:border-b-0 first:pt-0 last:pb-0">
|
||||||
<div class="flex items-center gap-1 self-center">
|
<div class="flex items-center gap-1 self-center">
|
||||||
<wd-badge is-dot hidden>
|
<wd-badge is-dot hidden>
|
||||||
|
Loading…
Reference in New Issue
Block a user