LearningRecordsPage.vue
4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<template>
<div class="bg-gradient-to-b from-green-50/70 to-white/90 min-h-screen pb-20">
<!-- Course List -->
<van-list
v-model:loading="loading"
:finished="finished"
:finished-text="finishText"
@load="onLoad"
class="px-4 py-3 space-y-4"
>
<FrostedGlass
v-for="record in records"
:key="record.id"
class="p-4 rounded-xl"
>
<div class="flex items-start">
<div
class="w-20 h-20 rounded-lg overflow-hidden flex-shrink-0 mr-3"
>
<van-image
:src="record.cover"
:alt="record.title"
class="w-full h-full"
fit="cover"
error-icon="photo-fail"
loading-icon="photo"
:error-icon-size="32"
:loading-icon-size="32"
/>
</div>
<div class="flex-1">
<h3 class="text-base font-medium mb-2 line-clamp-1">
{{ record.title }}
</h3>
<div class="flex items-center text-sm text-gray-500 mb-2">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-4 w-4 mr-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<span>学习时长:{{ record.study_duration_desc }}</span>
</div>
<div class="flex items-center text-sm text-gray-500 mb-3">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-4 w-4 mr-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
/>
</svg>
<span>最近学习:{{ record.recent_study_time }}</span>
</div>
<div class="flex items-center">
<div class="flex-1">
<van-progress
:percentage="record.record_progress"
:stroke-width="4"
color="#10B981"
/>
</div>
<!-- <span class="ml-3 text-sm text-green-600">{{ record.progress }}%</span> -->
</div>
</div>
</div>
</FrostedGlass>
</van-list>
<!-- 无数据提示 -->
<div
v-if="!loading && records.length === 0"
class="flex flex-col items-center justify-center py-12"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-16 w-16 text-gray-300"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
/>
</svg>
<p class="mt-4 text-gray-500">暂无学习记录</p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRoute } from 'vue-router';
import { useTitle } from '@vueuse/core';
import FrostedGlass from '@/components/ui/FrostedGlass.vue';
import { formatDate } from '@/utils/tools';
// 导入接口
import { getStudyRecordListAPI } from "@/api/record";
const $route = useRoute();
useTitle($route.meta.title);
const records = ref([]);
const loading = ref(false);
const finished = ref(false);
const page = ref(0);
const limit = ref(10);
const finishText = ref('没有更多了');
// 加载数据
const onLoad = async () => {
loading.value = true;
// 模拟异步加载
const nextPage = page.value;
const { code, data } = await getStudyRecordListAPI({
limit: limit.value,
page: nextPage,
});
if (code) {
data.forEach((item) => {
item.record_progress = Math.floor((item?.study_count/item?.count)*100);
});
records.value.push(...data);
finished.value = data.length < limit.value;
page.value = nextPage + 1;
loading.value = false;
} else {
finished.value = true;
finishText.value = '';
loading.value = false;
}
};
// 处理图片加载错误
const handleImageError = (e) => {
e.target.onerror = null;
e.target.src = '/assets/images/course-placeholder.jpg';
};
</script>