LearningRecordsPage.vue 5.01 KB
<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="没有更多了"
      @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.course.coverImage"
              :alt="record.course.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.course.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>学习时长:{{ formatDuration(record.duration) }}</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>最近学习:{{ formatDate(record.lastStudyTime) }}</span>
            </div>
            <div class="flex items-center">
              <div class="flex-1">
                <van-progress
                  :percentage="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, formatDuration } from '@/utils/tools';

const $route = useRoute();
useTitle($route.meta.title);

const records = ref([]);
const loading = ref(false);
const finished = ref(false);
const page = ref(1);
const pageSize = 10;

// 模拟学习记录数据
const mockRecords = [
  {
    id: 1,
    course: {
      title: '亲子教育必修课:如何培养孩子的学习兴趣',
      coverImage: '/assets/images/course-1.jpg'
    },
    duration: 3600, // 秒
    lastStudyTime: '2024-01-15T10:30:00',
    progress: 75
  },
  {
    id: 2,
    course: {
      title: '儿童心理发展指南:0-6岁关键期教育方法',
      coverImage: '/assets/images/course-2.jpg'
    },
    duration: 7200,
    lastStudyTime: '2024-01-14T15:20:00',
    progress: 45
  }
];

// 加载数据
const onLoad = () => {
  loading.value = true;
  // 模拟异步加载
  setTimeout(() => {
    const start = (page.value - 1) * pageSize;
    const end = start + pageSize;
    const newRecords = mockRecords.slice(start, end);

    records.value.push(...newRecords);
    loading.value = false;

    if (newRecords.length < pageSize) {
      finished.value = true;
    } else {
      page.value += 1;
    }
  }, 1000);
};

// 处理图片加载错误
const handleImageError = (e) => {
  e.target.onerror = null;
  e.target.src = '/assets/images/course-placeholder.jpg';
};
</script>