hookehuyr

refactor(StudyPage, CourseList): 优化布局和样式,提升用户体验

- 在StudyPage.vue中,将学习统计部分的布局从列表形式改为网格形式,使其更直观
- 在CourseList.vue中,重新设计课程列表的布局,增加缩略图样式和进度条显示,提升可读性
...@@ -6,18 +6,29 @@ ...@@ -6,18 +6,29 @@
6 <div class="course-list"> 6 <div class="course-list">
7 <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad"> 7 <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
8 <div v-for="course in courses" :key="course.id" 8 <div v-for="course in courses" :key="course.id"
9 - class="course-item bg-white mb-3 rounded-lg overflow-hidden"> 9 + class="course-item bg-white p-3 rounded-lg overflow-hidden flex">
10 - <van-cell :title="course.title" :label="course.type" class="pb-2"> 10 + <div class="relative w-[120px] h-full flex-shrink-0">
11 - <template #icon> 11 + <van-image :src="course.thumbnail" width="120" height="100%" fit="cover" class="item-cover">
12 - <van-image :src="course.thumbnail" width="120" height="68" fit="cover" class="mr-3 rounded" /> 12 + <div class="absolute bg-white/80 px-2 py-0.5 text-xs rounded"
13 - </template> 13 + style="right: 0.25rem; bottom: 0.5rem">
14 - </van-cell> 14 + {{ course.type }}
15 - <div class="px-4 pb-4"> 15 + </div>
16 - <div class="flex justify-between items-center text-sm text-gray-600 mb-2"> 16 + </van-image>
17 - <span>已学习 {{ formatDuration(course.studyTime) }}</span> 17 + </div>
18 - <span>{{ course.progress }}%</span> 18 + <div class="flex-1 p-3 flex flex-col" style="padding-top: 0; padding-right: 0">
19 + <div class="text-sm font-medium mb-2 mt-0">{{ course.title }}</div>
20 + <div class="mt-auto">
21 + <div class="flex items-center w-full">
22 + <span class="text-sm text-gray-400 shrink-0" style="font-size: 0.75rem; width: 5rem">已学习 {{
23 + formatDuration(course.studyTime) }}</span>
24 + <div class="flex-1 mx-4">
25 + <van-progress :percentage="course.progress" :stroke-width="4" color="#4080ff"
26 + :show-pivot="false" />
27 + </div>
28 + <span class="text-sm text-gray-400 shrink-0 text-center"
29 + style="font-size: 0.75rem; width: 2rem; text-align: right">{{ course.progress }}%</span>
30 + </div>
19 </div> 31 </div>
20 - <van-progress :percentage="course.progress" :stroke-width="4" color="#4080ff" />
21 </div> 32 </div>
22 </div> 33 </div>
23 </van-list> 34 </van-list>
...@@ -25,42 +36,46 @@ ...@@ -25,42 +36,46 @@
25 </template> 36 </template>
26 37
27 <script setup> 38 <script setup>
28 -import { ref } from 'vue' 39 +import { ref } from "vue";
29 40
30 // 接收课程列表数据 41 // 接收课程列表数据
31 const props = defineProps({ 42 const props = defineProps({
32 courses: { 43 courses: {
33 type: Array, 44 type: Array,
34 - default: () => [] 45 + default: () => [],
35 - } 46 + },
36 -}) 47 +});
37 48
38 // 列表加载状态 49 // 列表加载状态
39 -const loading = ref(false) 50 +const loading = ref(false);
40 -const finished = ref(true) // 由于使用的是传入的静态数据,所以直接设置为完成状态 51 +const finished = ref(true); // 由于使用的是传入的静态数据,所以直接设置为完成状态
41 52
42 // 加载更多 53 // 加载更多
43 const onLoad = () => { 54 const onLoad = () => {
44 - loading.value = false 55 + loading.value = false;
45 -} 56 +};
46 57
47 // 格式化时长显示 58 // 格式化时长显示
48 const formatDuration = (seconds) => { 59 const formatDuration = (seconds) => {
49 - const hours = Math.floor(seconds / 3600) 60 + const hours = Math.floor(seconds / 3600);
50 - const minutes = Math.floor((seconds % 3600) / 60) 61 + const minutes = Math.floor((seconds % 3600) / 60);
51 if (hours > 0) { 62 if (hours > 0) {
52 - return `${hours}小时${minutes}分钟` 63 + return `${hours}小时${minutes}分钟`;
53 } 64 }
54 - return `${minutes}分钟` 65 + return `${minutes}分钟`;
55 -} 66 +};
56 </script> 67 </script>
57 68
58 <style scoped> 69 <style scoped>
59 .course-list { 70 .course-list {
60 - padding: 0.5rem; 71 + padding: 0rem;
61 } 72 }
62 73
63 .course-item { 74 .course-item {
64 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); 75 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
65 } 76 }
77 +
78 +:deep(.van-image__img) {
79 + border-radius: 0.5rem;
80 +}
66 </style> 81 </style>
......
...@@ -31,18 +31,14 @@ ...@@ -31,18 +31,14 @@
31 <van-tab title="学习记录" name="record"> 31 <van-tab title="学习记录" name="record">
32 <div class="p-4"> 32 <div class="p-4">
33 <div class="flex space-x-4 mb-4"> 33 <div class="flex space-x-4 mb-4">
34 - <button 34 + <button class="rounded-full px-6 py-2 text-sm transition-colors"
35 - class="rounded-full px-6 py-2 text-sm transition-colors"
36 :class="courseType === 'column' ? 'bg-green-500 text-white' : 'bg-gray-100 text-gray-600'" 35 :class="courseType === 'column' ? 'bg-green-500 text-white' : 'bg-gray-100 text-gray-600'"
37 - @click="courseType = 'column'" 36 + @click="courseType = 'column'">
38 - >
39 专栏 37 专栏
40 </button> 38 </button>
41 - <button 39 + <button class="rounded-full px-6 py-2 text-sm transition-colors"
42 - class="rounded-full px-6 py-2 text-sm transition-colors"
43 :class="courseType === 'single' ? 'bg-green-500 text-white' : 'bg-gray-100 text-gray-600'" 40 :class="courseType === 'single' ? 'bg-green-500 text-white' : 'bg-gray-100 text-gray-600'"
44 - @click="courseType = 'single'" 41 + @click="courseType = 'single'">
45 - >
46 单课 42 单课
47 </button> 43 </button>
48 </div> 44 </div>
...@@ -54,12 +50,24 @@ ...@@ -54,12 +50,24 @@
54 <!-- 学习统计标签 --> 50 <!-- 学习统计标签 -->
55 <van-tab title="学习统计" name="stats"> 51 <van-tab title="学习统计" name="stats">
56 <div class="p-4"> 52 <div class="p-4">
57 - <van-cell-group inset> 53 + <div class="grid grid-cols-2 gap-4">
58 - <van-cell title="总学习时长" :value="formatDuration(stats.totalDuration)" /> 54 + <div class="bg-white rounded-lg p-4 shadow-sm">
59 - <van-cell title="已完成课程" :value="`${stats.completedCourses}门`" /> 55 + <div class="text-gray-500 text-sm mb-1">总学习时长</div>
60 - <van-cell title="学习天数" :value="`${stats.studyDays}天`" /> 56 + <div class="text-black font-medium">{{ formatDuration(stats.totalDuration) }}</div>
61 - <van-cell title="平均每日学习" :value="formatDuration(stats.avgDailyDuration)" /> 57 + </div>
62 - </van-cell-group> 58 + <div class="bg-white rounded-lg p-4 shadow-sm">
59 + <div class="text-gray-500 text-sm mb-1">已完成课程</div>
60 + <div class="text-black font-medium">{{ stats.completedCourses }}门</div>
61 + </div>
62 + <div class="bg-white rounded-lg p-4 shadow-sm">
63 + <div class="text-gray-500 text-sm mb-1">学习天数</div>
64 + <div class="text-black font-medium">{{ stats.studyDays }}天</div>
65 + </div>
66 + <div class="bg-white rounded-lg p-4 shadow-sm">
67 + <div class="text-gray-500 text-sm mb-1">平均每日学习</div>
68 + <div class="text-black font-medium">{{ formatDuration(stats.avgDailyDuration) }}</div>
69 + </div>
70 + </div>
63 </div> 71 </div>
64 </van-tab> 72 </van-tab>
65 </van-tabs> 73 </van-tabs>
......