LearningRecordsPage.vue 5.01 KB
<template>
<AppLayout :has-title="false">
  <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" @click="handleClick(record)">
          <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 ? 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>
</AppLayout>
</template>

<script setup>
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useTitle } from '@vueuse/core';
import FrostedGlass from '@/components/ui/FrostedGlass.vue';
import AppLayout from '@/components/layout/AppLayout.vue';
import { formatDate } from '@/utils/tools';

// 导入接口
import { getStudyRecordListAPI } from "@/api/record";

const $route = useRoute();
const $router = useRouter();

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';
};

// 跳转到课程详情页
const handleClick = (record) => {
  $router.push(`/profile/studyCourse/${record.id}`);
};
</script>