8565 lines
204 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="profile-page">
<!-- 刷新遮罩 -->
<div v-if="isRefreshing" class="refresh-mask">
<div class="refresh-content">
<div class="refresh-spinner"></div>
<p>正在刷新...</p>
</div>
</div>
<!-- 主要内容区域 -->
<div class="profile-content flex-row">
<!-- 左侧侧边栏 -->
<div class="block_14">
<!-- 用户头像和姓名 -->
<SafeAvatar class="image_7" :src="userStore.user?.avatar"
:name="userStore.user?.profile?.realName || userStore.user?.nickname || userStore.user?.username || '用户'"
:size="96" alt="用户头像" />
<span class="text_72">{{ userStore.user?.profile?.realName || userStore.user?.nickname ||
userStore.user?.username || '用户名' }}</span>
<!-- 菜单项容器 -->
<div class="box_22">
<!-- 分割线 -->
<div class="menu-divider"></div>
<!-- 我的课程 -->
<div :class="['image-text_19', { active: activeTab === 'courses' }]" @click="handleMenuSelect('courses')">
<img class="image_8 default-icon" referrerpolicy="no-referrer" src="/images/profile/course.png" />
<img class="image_8 hover-icon" referrerpolicy="no-referrer" src="/images/profile/course-active.png" />
<span class="text-group_19">我的课程</span>
</div>
<!-- 我的作业 -->
<div :class="['image-text_20', { active: activeTab === 'homework' }]" @click="handleMenuSelect('homework')">
<img class="label_4 default-icon" referrerpolicy="no-referrer" src="/images/profile/grade.png" />
<img class="label_4 hover-icon" referrerpolicy="no-referrer" src="/images/profile/grade-active.png" />
<span class="text-group_20">我的作业</span>
</div>
<!-- 我的考试 -->
<div :class="['image-text_21', { active: activeTab === 'exam' }]" @click="handleMenuSelect('exam')">
<img class="label_5 default-icon" referrerpolicy="no-referrer" src="/images/profile/checklist.png" />
<img class="label_5 hover-icon" referrerpolicy="no-referrer" src="/images/profile/checklist-active.png" />
<span class="text-group_21">我的考试</span>
</div>
<!-- 我的练习 -->
<div :class="['image-text_22', { active: activeTab === 'practice' }]" @click="handleMenuSelect('practice')">
<img class="label_6 default-icon" referrerpolicy="no-referrer" src="/images/profile/bookmark.png" />
<img class="label_6 hover-icon" referrerpolicy="no-referrer" src="/images/profile/bookmark-active.png" />
<span class="text-group_22">我的练习</span>
</div>
<!-- 我的活动 -->
<div :class="['image-text_23', { active: activeTab === 'activity' }]" @click="handleMenuSelect('activity')">
<img class="thumbnail_40 default-icon" referrerpolicy="no-referrer" src="/images/profile/gift.png" />
<img class="thumbnail_40 hover-icon" referrerpolicy="no-referrer" src="/images/profile/gift-active.png" />
<span class="text-group_23">我的活动</span>
</div>
<!-- 我的关注 -->
<div :class="['image-text_27', { active: activeTab === 'follows' }]" @click="handleMenuSelect('follows')">
<img class="thumbnail_42 default-icon" referrerpolicy="no-referrer" src="/images/profile/concern.png" />
<img class="thumbnail_42 hover-icon" referrerpolicy="no-referrer"
src="/images/profile/concern-active.png" />
<span class="text-group_27">我的关注</span>
</div>
<!-- 我的消息 -->
<div :class="['image-text_24', { active: activeTab === 'message' }]" @click="handleMenuSelect('message')">
<img class="label_7 default-icon" referrerpolicy="no-referrer" src="/images/profile/message.png" />
<img class="label_7 hover-icon" referrerpolicy="no-referrer" src="/images/profile/message-active.png" />
<span class="text-group_24">我的消息</span>
</div>
<!-- 我的资料 -->
<div :class="['image-text_25', { active: activeTab === 'materials' }]" @click="handleMenuSelect('materials')">
<img class="image_9 default-icon" referrerpolicy="no-referrer" src="/images/profile/profile.png" />
<img class="image_9 hover-icon" referrerpolicy="no-referrer" src="/images/profile/profile-active.png" />
<span class="text-group_25">我的资料</span>
</div>
<!-- 我的下载 -->
<div :class="['image-text_26', { active: activeTab === 'download' }]" @click="handleMenuSelect('download')">
<img class="thumbnail_41 default-icon" referrerpolicy="no-referrer" src="/images/profile/download.png" />
<img class="thumbnail_41 hover-icon" referrerpolicy="no-referrer"
src="/images/profile/download-active.png" />
<span class="text-group_26">我的下载</span>
</div>
</div>
</div>
<!-- 右侧内容区域 -->
<div class="group_5 flex-col">
<!-- 课程内容 -->
<div v-if="isCoursesTab">
<!-- 课程筛选标签 -->
<div class="text-wrapper_1 flex-row">
<span class="text_12" :class="{ active: activeCourseTab === 'all' }"
@click="handleCourseTabChange('all')">全部课程</span>
<span class="text_13" :class="{ active: activeCourseTab === 'learning' }"
@click="handleCourseTabChange('learning')">学习中</span>
<span class="text_14" :class="{ active: activeCourseTab === 'completed' }"
@click="handleCourseTabChange('completed')">已完结</span>
</div>
<!-- 分割线 -->
<div class="course-divider"></div>
<!-- 课程列表 -->
<div class="course-list">
<!-- 学习中的课程 -->
<div v-for="course in filteredCourses" :key="course.id" class="box_2 flex-row justify-between">
<div class="block_4 flex-col">
<div class="box_3 flex-row justify-between">
<div class="status-image-container">
<img class="status-image" referrerpolicy="no-referrer"
:src="course.status === 'learning' ? '/images/icon/learning.png' : '/images/icon/finish.png'"
alt="{{ getStatusText(course.status) }}" />
</div>
<img class="thumbnail_4" referrerpolicy="no-referrer" :src="bannerImage" :alt="bannerAlt" />
<span :class="['status-text', course.status]">{{ getStatusText(course.status) }}</span>
</div>
</div>
<div class="block_5 flex-col">
<div class="group_6 flex-row">
<span class="text_16">{{ course.title }}</span>
<img class="thumbnail_5" referrerpolicy="no-referrer"
src="https://lanhu-oss-2537-2.lanhuapp.com/SketchPnge131c44858bb817d4885b81fdd8ddff8507f62cd51f1025cee826849e6a52c65" />
<span class="text_17">{{ course.rating || 541 }}</span>
</div>
<span class="text_18">讲师{{ course.instructor }}</span>
<span class="text_19">{{ course.description }}</span>
<div class="group_7 flex-row">
<img class="thumbnail_6" referrerpolicy="no-referrer" src="/images/profile/11.png" />
<span class="text_20">{{ course.chapters || 9 }}{{ course.lessons || 54 }}</span>
<img class="thumbnail_7" referrerpolicy="no-referrer" src="/images/profile/22.png" />
<span class="text_21">{{ course.duration || '12小时43分钟' }}</span>
<img class="thumbnail_8" referrerpolicy="no-referrer"
:src="course.status === 'learning' ? '/images/profile/33.png' : '/images/profile/33.png'" />
<span class="text_22">已看{{ course.watchedTime || '10小时20分钟' }}</span>
<div class="text-wrapper_2 flex-col" @click="goToCourse(course.id)">
<span class="text_23">{{ course.status === 'learning' ? '去学习' : '去复习' }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 分页器 -->
<div class="pagination-wrapper" v-if="totalPages > 1">
<div class="pagination">
<span class="pagination-item nav-button" :class="{ disabled: currentPage === 1 }"
@click="goToPage('first')">
首页
</span>
<span class="pagination-item nav-button" :class="{ disabled: currentPage === 1 }"
@click="goToPage('prev')">
上一页
</span>
<span v-for="page in totalPages" :key="page" class="pagination-item page-number"
:class="{ active: page === currentPage }" @click="goToPage(page)">
{{ page }}
</span>
<span class="pagination-item nav-button" :class="{ disabled: currentPage === totalPages }"
@click="goToPage('next')">
下一页
</span>
<span class="pagination-item nav-button" :class="{ disabled: currentPage === totalPages }"
@click="goToPage('last')">
尾页
</span>
</div>
</div>
</div>
<!-- 作业内容 -->
<div v-else-if="isHomeworkTab" class="homework-content">
<!-- 作业筛选标签 -->
<div v-if="!showDraftBoxView" class="text-wrapper_1 flex-row">
<span class="text_12" :class="{ active: activeHomeworkTab === 'all' }"
@click="handleHomeworkTabChange('all')">全部作业</span>
<span class="text_13" :class="{ active: activeHomeworkTab === 'pending' }"
@click="handleHomeworkTabChange('pending')">未完成</span>
<span class="text_14" :class="{ active: activeHomeworkTab === 'completed' }"
@click="handleHomeworkTabChange('completed')">已完成</span>
<span class="draftbox" @click="showDraftBox">
<img src="/images/auth/mti.png" alt="">
<span>草稿箱</span>
</span>
</div>
<!-- 分割线 -->
<div v-if="!showDraftBoxView" class="course-divider"></div>
<!-- 面包屑 -->
<!-- <div class="breadcrumb-wrapper flex-row">
<span class="text_15">全部作业</span>
<span class="text_15">></span>
<span class="text_15 homework">作业名称</span>
</div> -->
<!-- 作业详情视图 -->
<div v-if="showDetailView && detailAssignment">
<!-- <div class="detail-header">
<div class="breadcrumb-nav">
<span class="breadcrumb-item" @click="backToAssignmentList">全部作业</span>
<span class="breadcrumb-separator">></span>
<span class="breadcrumb-current">作业名称</span>
</div>
</div> -->
<div class="group_11">
<!-- 头部信息 -->
<div class="box_5">
<div class="image-text_2">
<div class="avatar-line"></div>
<img :src="detailAssignment.teacherAvatar" alt="教师头像" class="image_22" />
<div class="text-group_3">
<span class="text_30">{{ detailAssignment.teacherName }}</span>
<span class="text_31">{{ detailAssignment.assignTime }}</span>
</div>
</div>
<span class="text_32">
<img v-if="detailAssignment.status === '已提交'" src="/images/profile/55.png" alt="">
<span :style="{
color: detailAssignment.status === '未完成' || detailAssignment.status === '待提交' ? '#FF560C' : '#999999',
fontSize: '14px'
}">
{{ detailAssignment.status === '未完成' || detailAssignment.status === '待提交' ? '未完成' :
(detailAssignment.status === '已完成' ? '已完成' : '541人已完成') }}
</span>
</span>
</div>
<!-- 作业内容 -->
<div class="text-group_4">
<div class="course-divider"></div>
<span class="text_33">{{ detailAssignment.title }}</span>
<div class="description-container">
<span class="text_34 description-full-view">
{{ detailAssignment.description }}
</span>
</div>
</div>
<!-- 作业附件区域 -->
<div class="box_6">
<div class="attachment-images">
<img v-for="(_, index) in detailAssignment.attachments.slice(0, 5)" :key="index"
src="/images/traings/traing1.png" :class="['image_' + (24 + index)]" />
</div>
</div>
<div class="files-container">
<div class="file-items">
<img src="/images/auth/file.png" alt="" class="files-icon">
<span>文件名称.PDF</span>
<img src="/images/auth/download.png" alt="" class="files-icon">
</div>
<div class="file-items">
<img src="/images/auth/file.png" alt="" class="files-icon">
<span>文件名称.PDF</span>
<img src="/images/auth/download.png" alt="" class="files-icon">
</div>
</div>
<div class="course-name">这里是课程名称!!! <span>查看详情></span></div>
<!-- 作业按钮区域 -->
<div class="assignment-buttons">
<template v-if="detailAssignment.status === '未完成' || detailAssignment.status === '待提交'">
<div class="text-wrapper_8 submit-button" @click="showUploadFromDetail">
<span class="">上传作业</span>
</div>
</template>
</div>
</div>
</div>
<!-- 草稿箱视图 -->
<div v-if="showDraftBoxView && draftAssignment">
<div class="detail-header">
<div class="breadcrumb-nav">
<span class="breadcrumb-item" @click="backFromDraftBox">全部作业</span>
<span class="breadcrumb-separator">></span>
<span class="breadcrumb-current">草稿箱</span>
</div>
</div>
<div class="group_11">
<!-- 头部信息 -->
<div class="box_5">
<div class="image-text_2">
<div class="avatar-line"></div>
<img :src="draftAssignment.teacherAvatar" alt="教师头像" class="image_22" />
<div class="text-group_3">
<span class="text_30">{{ draftAssignment.teacherName }}</span>
<span class="text_31">{{ draftAssignment.assignTime }}</span>
</div>
</div>
<span class="text_32">
<img v-if="draftAssignment.status === '已提交'" src="/images/profile/55.png" alt="">
<span :style="{
color: draftAssignment.status === '未完成' || draftAssignment.status === '待提交' ? '#FF560C' : '#999999',
fontSize: '14px'
}">
{{ draftAssignment.status === '未完成' || draftAssignment.status === '待提交' ? '未完成' :
(draftAssignment.status === '已完成' ? '已完成' : '541人已完成') }}
</span>
</span>
</div>
<!-- 作业内容 -->
<div class="text-group_4">
<span class="text_33">{{ draftAssignment.title }}</span>
<div class="description-container">
<span class="text_34 description-full-view">
{{ draftAssignment.description }}
</span>
</div>
</div>
<!-- 作业附件区域 -->
<div class="box_6">
<div class="attachment-images">
<img v-for="(_, index) in draftAssignment.attachments.slice(0, 5)" :key="index"
src="/images/traings/traing1.png" :class="['image_' + (24 + index)]" />
</div>
</div>
<div class="files-container">
<div class="file-items">
<img src="/images/auth/file.png" alt="" class="files-icon">
<span>文件名称.PDF</span>
<img src="/images/auth/download.png" alt="" class="files-icon">
</div>
<div class="file-items">
<img src="/images/auth/file.png" alt="" class="files-icon">
<span>文件名称.PDF</span>
<img src="/images/auth/download.png" alt="" class="files-icon">
</div>
</div>
<div class="course-name">这里是课程名称!!! <span>查看详情></span></div>
<!-- 作业按钮区域 -->
<div class="assignment-buttons">
<div class="text-wrapper_8 submit-button" @click="showUploadModal(draftAssignment)">
<span class="text_36">上传作业</span>
</div>
<div class="text-wrapper_8 anew-button" @click="reEditDraft">
<span class="text_36">重新编辑</span>
</div>
</div>
</div>
</div>
<!-- 作业列表 -->
<div v-else-if="!showDetailView && !showDraftBoxView">
<div v-for="assignment in filteredAssignments" :key="assignment.id" class="group_11">
<!-- 作业头部信息 -->
<div class="box_5">
<div class="image-text_2">
<div class="avatar-line"></div>
<img src="/images/traings/traing1.png" class="image_22" />
<div class="text-group_3">
<span class="text_30">{{ assignment.teacherName }}</span>
<span class="text_31">{{ assignment.assignTime }}</span>
</div>
</div>
<span class="text_32">
<span :style="{
color: assignment.status === '未完成' || assignment.status === '待提交' ? '#FF560C' : '#999999',
fontSize: '14px'
}">
{{ assignment.status === '未完成' || assignment.status === '待提交' ? '未完成' : '已完成' }}
</span>
</span>
</div>
<!-- 作业内容 -->
<div class="text-group_4">
<!-- 分割线 -->
<div class="course-divider"></div>
<span class="text_33">{{ assignment.title }}</span>
<div class="description-container">
<span class="text_34 text-truncated">
{{ assignment.description }}
</span>
</div>
</div>
<!-- 作业附件区域 -->
<div class="box_6">
<!-- 附件图片列表 -->
<div class="attachment-images">
<img v-for="(_, index) in assignment.attachments.slice(0, 5)" :key="index"
src="/images/traings/traing1.png" :class="['image_' + (24 + index)]" />
</div>
<div class="attachment-images attachment-number-container">
<img src="/images/profile/55.png" alt="" class="attachment-number-icon">
<span class="attachment-number-text">541人已完成</span>
</div>
</div>
<!-- 作业按钮区域 -->
<div class="assignment-buttons">
<!-- 未完成状态显示两个按钮 -->
<template v-if="assignment.status === '未完成' || assignment.status === '待提交'">
<div class="text-wrapper_8 view-button" @click="showUploadModal(assignment)">
<span class="text_36 text-view">上传作业</span>
</div>
<!-- 查看详细 -->
<div class="text-wrapper_8 details-button" @click="viewAssignmentDetail(assignment)">
<span class="text_36">查看详情</span>
</div>
</template>
<!-- 已完成状态只显示一个按钮 -->
<template v-else>
<div class="text-wrapper_8 details-button" @click="viewAssignmentDetail(assignment)">
<span class="text_36">查看详情</span>
</div>
</template>
</div>
</div>
</div>
</div>
<!-- 考试内容 -->
<div v-else-if="isExamTab" class="exam-content">
<!-- 考试筛选标签 -->
<div class="text-wrapper_1 flex-row">
<span class="text_12" :class="{ active: activeExamTab === 'all' }"
@click="handleExamTabChange('all')">全部考试</span>
<span class="text_13" :class="{ active: activeExamTab === 'upcoming' }"
@click="handleExamTabChange('upcoming')">未开始</span>
<span class="text_14" :class="{ active: activeExamTab === 'ongoing' }"
@click="handleExamTabChange('ongoing')">进行中</span>
<span class="text_15" :class="{ active: activeExamTab === 'finished' }"
@click="handleExamTabChange('finished')">已结束</span>
</div>
<!-- 分割线 -->
<div class="course-divider"></div>
<!-- 考试列表 -->
<div class="exam-grid">
<div v-for="exam in filteredExams" :key="exam.id" class="exam-card">
<!-- 考试标题 -->
<div class="exam-title">{{ exam.title }}</div>
<!-- 分数显示 -->
<div class="exam-score-badge" v-if="exam.score !== null">
<span class="score-text">{{ exam.score }}<span></span></span>
</div>
<!-- 考试信息 -->
<div class="exam-details">
<div class="exam-meta-item">
<span class="meta-label">考试日期</span>
<span class="meta-value">{{ exam.examDate }}</span>
</div>
<div class="exam-meta-item">
<span class="meta-label">考试时间</span>
<span class="meta-value">{{ exam.duration }}分钟</span>
</div>
<div class="exam-meta-item">
<span class="meta-label">考试题量</span>
<span class="meta-value">{{ exam.questionCount }}</span>
</div>
</div>
<!-- 考试描述 -->
<div class="exam-description">
{{ exam.description }}
</div>
<!-- 底部操作区域 -->
<div class="exam-footer">
<div class="exam-action-right">
<button v-if="exam.status === 'upcoming'" class="action-btn upcoming-btn" @click="startExam(exam.id)">
未开始
</button>
<button v-else-if="exam.status === 'ongoing'" class="action-btn ongoing-btn"
@click="continueExam(exam.id)">
开始考试
</button>
<button v-else-if="exam.status === 'finished'" class="action-btn finished-btn"
@click="viewExamResult(exam.id)">
查看详情
</button>
</div>
<div class="exam-status-left">
<span class="exam-status-text">{{ getExamStatusText(exam.status) }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 练习内容 -->
<div v-else-if="isPracticeTab" class="practice-content">
<!-- 练习筛选标签 -->
<div class="text-wrapper_1 flex-row">
<span class="text_12" :class="{ active: activePracticeTab === 'all' }"
@click="handlePracticeTabChange('all')">全部练习</span>
<span class="text_13" :class="{ active: activePracticeTab === 'ongoing' }"
@click="handlePracticeTabChange('ongoing')">练习中</span>
<span class="text_14" :class="{ active: activePracticeTab === 'finished' }"
@click="handlePracticeTabChange('finished')">已结束</span>
</div>
<!-- 练习分割线 -->
<div class="course-divider"></div>
<!-- 练习网格 -->
<div class="exam-grid">
<div v-for="practice in filteredPractices" :key="practice.id" class="exam-card">
<!-- 考试标题 -->
<div class="exam-title">{{ practice.title }}</div>
<!-- 分数显示 -->
<div v-if="practice.status === 'finished'" class="practice-score-badge">
<span class="score-text">{{ practice.score }}<span></span></span>
</div>
<!-- 考试信息 -->
<div class="exam-details">
<div class="exam-meta-item">
<span class="meta-label">练习日期</span>
<span class="meta-value">{{ practice.practiceDate }}</span>
</div>
<div class="exam-meta-item">
<span class="meta-label">练习时间</span>
<span class="meta-value">{{ practice.duration }}分钟</span>
</div>
<div class="exam-meta-item">
<span class="meta-label">题库数量</span>
<span class="meta-value">{{ practice.questionCount }}</span>
</div>
</div>
<!-- 动态显示内容 -->
<div v-if="practice.status === 'finished'" class="practice-stats">
<div class="stat-row">
<span class="stat-label">答对</span>
<span class="stat-value correct">{{ practice.correctCount || 0 }}<span></span></span>
</div>
<!-- 分割线 -->
<div class="divider"></div>
<div class="stat-row">
<span class="stat-label">答错</span>
<span class="stat-value wrong">{{ practice.wrongCount || 0 }}<span></span></span>
</div>
</div>
<div v-else class="exam-description">
{{ practice.description || '该练习包含' + practice.questionCount + '道题目,涵盖了相关知识点。' }}
</div>
<!-- 底部操作区域 -->
<div class="exam-footer">
<div class="exam-action-right">
<button v-show="practice.status === 'ongoing'" class="action-btn ongoing-btn"
@click="continuePractice(practice.id)">
继续练习
</button>
<button v-show="practice.status === 'finished'" class="action-btn finished-btn"
@click="viewPracticeDetail(practice.id)">
查看详情
</button>
</div>
<div class="exam-status-left">
<span class="exam-status-text">{{ practice.status === 'ongoing' ? '练习中' : '已结束' }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 活动内容 -->
<div v-else-if="isActivityTab" class="activity-content">
<!-- 活动筛选标签 -->
<div class="text-wrapper_1 flex-row">
<span class="text_12" :class="{ active: activeActivityTab === 'all' }"
@click="handleActivityTabChange('all')">全部活动</span>
<span class="text_13" :class="{ active: activeActivityTab === 'ongoing' }"
@click="handleActivityTabChange('ongoing')">进行中</span>
<span class="text_14" :class="{ active: activeActivityTab === 'finished' }"
@click="handleActivityTabChange('finished')">已结束</span>
</div>
<!-- 活动分割线 -->
<div class="course-divider"></div>
<!-- 活动网格 -->
<div class="activity-grid">
<div v-for="activity in filteredActivities" :key="activity.id" class="activity-card">
<!-- 活动卡片顶部图片 -->
<div class="activity-card-image">
<img src="/banners/banner1.png" alt="活动图片" class="activity-image" />
</div>
<!-- 活动标题 -->
<h3 class="activity-title">{{ activity.title }}</h3>
<!-- 活动简介 -->
<div class="activity-intro">
<!-- <div class="intro-title">活动简介</div> -->
<div class="intro-content">
{{ activity.description }}
</div>
</div>
<!-- 活动详情 -->
<div class="activity-details">
<div class="activity-meta-item">
<span class="meta-label">活动时间</span>
<span class="meta-value">{{ activity.activityDate }}</span>
</div>
<div class="activity-meta-item">
<span class="meta-label">活动类型</span>
<span class="meta-value">{{ activity.activityType }}</span>
</div>
<div class="activity-meta-item">
<span class="meta-label">已报名</span>
<span class="meta-value">{{ activity.registeredCount }}</span>
</div>
</div>
<!-- 活动底部 -->
<div class="activity-footer">
<div class="activity-action-right">
<button v-if="activity.status === 'ongoing'" class="action-btn ongoing-btn"
@click="continueActivity(activity.id)">
查看活动
</button>
<button v-else-if="activity.status === 'finished'"
class="action-btn finished-btn activity-finished-btn" @click="viewActivityDetail(activity.id)">
查看详情
</button>
</div>
<div class="activity-status-left">
<span :class="['activity-status-text', activity.status]">{{ activity.status === 'ongoing' ? '进行中' :
'已结束'
}}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 关注内容 -->
<div v-else-if="isFollowsTab" class="follows-content">
<!-- 关注筛选标签 -->
<div class="text-wrapper_1 flex-row">
<span class="text_12" :class="{ active: activeFollowsTab === 'all' }"
@click="handleFollowsTabChange('all')">全部关注</span>
<span class="text_13" :class="{ active: activeFollowsTab === 'recent' }"
@click="handleFollowsTabChange('recent')">最近关注</span>
<span class="text_14" :class="{ active: activeFollowsTab === 'frequent' }"
@click="handleFollowsTabChange('frequent')">最常访问</span>
</div>
<!-- 关注分割线 -->
<div class="course-divider"></div>
<!-- 关注列表 -->
<div class="follows-list">
<div v-for="follow in filteredFollows" :key="follow.id" class="follow-item">
<!-- 用户头像 -->
<div class="follow-avatar">
<img :src="follow.avatar" :alt="follow.name" class="avatar-image" />
</div>
<!-- 右侧信息区域 -->
<div class="follow-right-content">
<!-- 用户信息 -->
<div class="follow-info">
<div class="follow-name">{{ follow.name }}</div>
<div class="follow-description">{{ follow.description }}</div>
</div>
<!-- 关注操作 -->
<div class="follow-actions">
<button class="follow-btn"
:class="{ 'following': follow.isFollowing, 'not-following': !follow.isFollowing }"
@click="toggleFollow(follow.id)">
{{ follow.isFollowing ? '已关注' : '取消关注' }}
</button>
</div>
</div>
</div>
</div>
</div>
<!-- 消息内容 -->
<div v-else-if="isMessageTab" class="message-content">
<!-- 消息筛选标签 -->
<div class="message-header">
<div class="message-tabs">
<span class="message-tab-item" :class="{ active: activeMessageTab === 'instant' }"
@click="handleMessageTabChange('instant')">
即时消息
<span class="message-count">2</span>
</span>
<span class="message-tab-item" :class="{ active: activeMessageTab === 'comment' }"
@click="handleMessageTabChange('comment')">
评论和@
<span class="message-count">3</span>
</span>
<span class="message-tab-item" :class="{ active: activeMessageTab === 'like' }"
@click="handleMessageTabChange('like')">
点赞
<span class="message-count">5</span>
</span>
<span class="message-tab-item" :class="{ active: activeMessageTab === 'system' }"
@click="handleMessageTabChange('system')">
系统消息
</span>
</div>
<div class="message-actions">
<span class="action-link">
<img src="/images/profile/read.png" alt="全部已读" class="action-icon">
全部已读
</span>
<span class="action-link">
<img src="/images/profile/time.png" alt="按时间" class="action-icon">
按时间
</span>
</div>
</div>
<!-- 消息列表 -->
<div class="message-list">
<!-- 即时消息 -->
<div v-if="activeMessageTab === 'instant'" class="instant-message-container">
<InstantMessage />
</div>
<!-- 评论和@消息 -->
<div v-else-if="activeMessageTab === 'comment'" v-for="msg in filteredMessages" :key="msg.id" class="message-item">
<!-- 未读标识 - 移到右上角 -->
<div v-if="!msg.isRead" class="unread-indicator-top-right"></div>
<!-- 消息内容 -->
<div class="message-main">
<!-- 用户头像和信息 -->
<div class="message-user">
<img src="/images/traings/traing1.png" class="image_22" />
<div class="user-info">
<div class="user-content">
<span class="message-text" :class="{ 'mention-highlight': msg.senderName.includes('@') }">{{
msg.senderName }}</span>
<span class="message-text">{{ msg.content }}</span>
</div>
<div class="course-info-container">
<span class="course-label">回复我的课程</span>
<span class="course-name">{{ msg.courseName }}</span>
</div>
</div>
<div class="message-time">{{ msg.date }}</div>
</div>
<!-- 操作按钮 -->
<div class="message-actions-row">
<button class="message-action-btn reply-btn" @click="startReply(msg.id)">
<img src="/images/profile/reply.png" alt="回复" class="action-icon">
回复
</button>
<button class="message-action-btn delete-btn">
<img src="/images/profile/del.png" alt="删除" class="action-icon">
删除
</button>
<button class="message-action-btn report-btn">
<img src="/images/profile/report.png" alt="举报" class="action-icon">
举报
</button>
</div>
<!-- 回复区域 -->
<div v-if="replyingMessageId === msg.id" class="reply-section">
<div class="reply-input-container">
<n-input v-model:value="replyContent" type="textarea" placeholder="回复该评论:" :rows="3"
class="reply-input" />
<div class="reply-actions">
<button class="send-btn" @click="sendReply(msg.id)">发送</button>
</div>
</div>
</div>
<!-- 已有回复显示 -->
<div v-if="msg.hasReply && msg.replyContent" class="existing-reply">
<div class="reply-content">{{ msg.replyContent }}</div>
</div>
</div>
</div>
<!-- 点赞消息 -->
<div v-else-if="activeMessageTab === 'like'" v-for="like in filteredLikeMessages" :key="'like-' + like.id" class="like-message-item">
<!-- 未读标识 -->
<div v-if="!like.isRead" class="unread-indicator-top-right"></div>
<!-- 点赞消息内容 -->
<div class="like-message-main">
<div class="like-message-user">
<img :src="like.userAvatar" class="image_22" />
<div class="like-info">
<div class="like-content">
<span class="message-text">{{ like.userName }}</span>
<span class="message-text">赞了我的{{ like.type === 'comment' ? '评论' : '课程' }}</span>
</div>
<div class="course-info-container" v-if="like.courseName">
<span class="course-label">在课程</span>
<span class="course-name">{{ like.courseName }}</span>
</div>
<div class="like-content-preview" v-if="like.content">
<span class="content-preview">{{ like.content }}</span>
</div>
</div>
<div class="message-time">{{ like.date }}</div>
</div>
</div>
</div>
<!-- 系统消息 -->
<div v-else-if="activeMessageTab === 'system'" v-for="sysMsg in filteredSystemMessages" :key="'sys-' + sysMsg.id" class="system-message-item">
<!-- 未读标识 - 移到右上角 -->
<!-- <div v-if="!sysMsg.isRead" class="unread-indicator-top-right"></div> -->
<!-- 系统消息内容 -->
<div class="system-message-main">
<!-- 系统图标和信息 -->
<div class="system-message-user">
<div class="system-icon"></div>
<div class="system-info">
<div class="system-title">{{ sysMsg.title }}</div>
<div class="system-subtitle-row">
<span class="system-subtitle">{{ sysMsg.subtitle }}</span>
<span class="system-detail-link">查看详情></span>
</div>
</div>
<div class="system-time">{{ sysMsg.date }}</div>
</div>
</div>
</div>
</div>
</div>
<!-- 我的资料页面 -->
<div v-else-if="activeTab === 'materials'" class="materials-content">
<!-- 资料页面标签页 -->
<div class="materials-header">
<div class="materials-tabs">
<span class="materials-tab-item" :class="{ active: activeMaterialsTab === 'basic' }"
@click="handleMaterialsTabChange('basic')">
基础信息
</span>
<span class="materials-tab-item" :class="{ active: activeMaterialsTab === 'password' }"
@click="handleMaterialsTabChange('password')">
密码修改
</span>
</div>
</div>
<!-- 基础信息页面 -->
<div v-if="activeMaterialsTab === 'basic'" class="basic-info-content">
<div class="basic-info-container">
<h3 class="basic-info-title">基础信息</h3>
<!-- 用户头像 -->
<div class="avatar-section">
<div class="avatar-container">
<SafeAvatar :src="userStore.user?.avatar"
:name="userStore.user?.profile?.realName || userStore.user?.nickname || userStore.user?.username || '用户'"
:size="68" alt="用户头像" class="user-avatar-large" />
<div class="avatar-edit-btn">
<img src="/images/auth/revise.png" alt="编辑头像" class="edit-icon" />
</div>
</div>
</div>
<!-- 基础信息表单 -->
<div class="basic-info-form">
<div class="form-row">
<div class="form-group">
<label class="form-label">昵称</label>
<input v-model="userInfo.nickname" type="text" class="form-input" placeholder="张成学" />
</div>
<div class="form-group">
<label class="form-label">性别</label>
<select v-model="userInfo.gender" class="form-select">
<option value="男"></option>
<option value="女"></option>
</select>
</div>
<div class="form-group">
<label class="form-label">所在院校</label>
<input v-model="userInfo.college" type="text" class="form-input" placeholder="北京清华大学" />
</div>
</div>
</div>
</div>
</div>
<!-- 密码修改页面 -->
<div v-else-if="activeMaterialsTab === 'password'" class="password-content">
<div class="password-container">
<h3 class="password-title">密码修改</h3>
<div class="password-form">
<!-- 账号显示 -->
<div class="password-form-group">
<label class="password-form-label">账号</label>
<div class="account-display">{{ userInfo.phone || '18658822666654' }}</div>
</div>
<!-- 原密码 -->
<div class="password-form-group">
<label class="password-form-label">原密码</label>
<input v-model="passwordForm.currentPassword" type="password" class="password-form-input"
placeholder="请输入原密码" />
</div>
<!-- 新密码 -->
<div class="password-form-group">
<label class="password-form-label">新密码</label>
<input v-model="passwordForm.newPassword" type="password" class="password-form-input"
placeholder="请输入新密码" />
</div>
<!-- 确认密码 -->
<div class="password-form-group">
<label class="password-form-label">确认密码</label>
<input v-model="passwordForm.confirmPassword" type="password" class="password-form-input"
placeholder="请输入确认新密码" />
</div>
<!-- 保存按钮 -->
<div class="password-form-actions">
<button class="password-save-btn" @click="savePassword">保存</button>
</div>
</div>
</div>
</div>
</div>
<!-- 我的下载页面 -->
<div v-else-if="activeTab === 'download'" class="download-content"
:class="{ 'in-subdirectory': isInSubDirectory }">
<!-- 下载页面标签页 -->
<div class="download-header">
<div class="download-tabs">
<span class="download-tab-item" :class="{ active: activeDownloadTab === 'courseware' }"
@click="handleDownloadTabChange('courseware')">
课件
</span>
<span class="download-tab-item" :class="{ active: activeDownloadTab === 'certificate' }"
@click="handleDownloadTabChange('certificate')">
证书
</span>
<span class="download-tab-item" :class="{ active: activeDownloadTab === 'resources' }"
@click="handleDownloadTabChange('resources')">
资源库
</span>
<span class="download-tab-item" :class="{ active: activeDownloadTab === 'homework' }"
@click="handleDownloadTabChange('homework')">
作业
</span>
</div>
</div>
<!-- 面包屑导航或筛选和操作区域 -->
<div v-if="isInSubDirectory" class="breadcrumb-controls">
<div class="breadcrumb-nav">
<span class="breadcrumb-text" @click="goBack">{{ currentPath.join(' > ') }} ></span>
<span class="breadcrumb-current">{{ currentPath[currentPath.length - 1] || '文件夹' }}</span>
</div>
</div>
<!-- 筛选和操作区域 -->
<div v-else-if="activeDownloadTab === 'courseware'" class="download-controls">
<div class="download-filters">
<div class="filter-group">
<label class="filter-label">类型:</label>
<select v-model="downloadFilter.type" class="filter-select">
<option value="all">全部</option>
<option value="folder">文件夹</option>
<option value="file">文件</option>
</select>
</div>
<div class="search-group">
<label class="search-label">搜索:</label>
<div class="search-input-container">
<input v-model="downloadFilter.keyword" type="text" class="search-input" placeholder="请输入文件名称" />
<button class="search-btn">
<img src="/images/profile/search.png" alt="搜索图标" class="search-icon" />
</button>
</div>
</div>
</div>
<div class="download-actions">
<span class="file-count">已全部加载共17个文件</span>
<button class="new-folder-btn" @click="createNewFolder">
+ 新建文件夹
</button>
</div>
</div>
<!-- 文件网格 -->
<div class="files-grid"
:class="{ 'subdirectory-grid': isInSubDirectory, 'certificate-grid': activeDownloadTab === 'certificate', 'homework-grid': activeDownloadTab === 'homework' }">
<div v-for="file in filteredDownloadFiles" :key="file.id" class="file-item"
:class="{ 'subdirectory-item': isInSubDirectory }" @dblclick="handleFolderDoubleClick(file)"
@click="handleFileClick(file)">
<div class="file-menu">
<button class="file-menu-btn" @click.stop="toggleFileMenu(file.id)">
<img src="/images/profile/more.png" alt="更多操作" class="more-icon" />
</button>
<div v-if="activeFileMenu === file.id" class="file-menu-dropdown">
<div class="menu-item" @click.stop="renameFile(file.id)">
<img src="/images/profile/edit.png" alt="编辑图标" class="menu-icon" />
<span>编辑</span>
</div>
<div class="menu-item" @click.stop="deleteFile(file.id)">
<img src="/images/profile/del.png" alt="删除图标" class="menu-icon" />
<span>删除</span>
</div>
</div>
</div>
<div class="file-icon">
<img :src="getFileIcon(file.id)" alt="文件图标" class="folder-icon" />
</div>
<div class="file-name">{{ file.name }}</div>
</div>
</div>
</div>
<!-- 其他内容的占位符 -->
<div v-else class="other-content">
<h2>{{ getTabTitle(activeTab) }}</h2>
<p>{{ activeTab }}功能开发中...</p>
</div>
</div>
</div>
</div>
<!-- 上传作业弹窗 -->
<div v-if="showModal" class="custom-modal-overlay" @click="closeUploadModal">
<div class="custom-modal" @click.stop>
<div v-if="currentAssignment" class="modal-content">
<n-form>
<div class="form-item">
<label class="form-label">标题名称 <span class="required">*</span></label>
<input v-model="uploadForm.title" type="text" class="form-input" placeholder="" />
</div>
<n-form-item label="编辑内容" required>
<QuillEditor v-model="uploadForm.content" placeholder="请输入内容" height="400px" />
</n-form-item>
<!-- <n-form-item label="上传文件" required>
<n-upload multiple directory-dnd :custom-request="customRequest" :default-upload="false">
<n-button>选择文件</n-button>
</n-upload>
<div class="file-list" v-if="uploadForm.files.length > 0">
<div v-for="(file, index) in uploadForm.files" :key="index" class="file-item">
<div class="file-icon">
<img src="/images/auth/file.png" alt="文件图标" />
</div>
<div class="file-info">
<div class="file-name">{{ file.name }}</div>
<div class="file-size">{{ (file.size / 1024).toFixed(2) }}KB</div>
</div>
<button class="file-delete" @click="removeFile(index)">🗑️</button>
</div>
</div>
</n-form-item> -->
</n-form>
<div class="modal-footer">
<button type="primary" @click="submitAssignment" style="margin-left: 12px;">确认</button>
<button @click="closeUploadModal" class="cancel">取消</button>
</div>
</div>
</div>
</div>
<!-- 考试详情页面 -->
</template>
<script setup lang="ts">
import { ref, computed, onMounted, onActivated, reactive } from 'vue'
import { useMessage, NInput, NForm, NFormItem } from 'naive-ui'
import { useI18n } from 'vue-i18n'
import { useUserStore } from '@/stores/user'
import SafeAvatar from '@/components/common/SafeAvatar.vue'
import QuillEditor from '@/components/common/QuillEditor.vue'
import InstantMessage from '@/components/InstantMessage.vue'
import { useRouter, useRoute } from 'vue-router'
const { t, locale } = useI18n()
const router = useRouter()
const route = useRoute()
// 轮播图根据语言动态切换
const bannerImage = computed(() => {
return locale.value === 'zh' ? '/banners/banner8.png' : '/banners/banner1-en.png'
})
const bannerAlt = computed(() => {
return t('home.banner.alt')
})
// 定义课程接口
interface Course {
id: number
title: string
instructor: string
description: string
thumbnail: string
status: 'learning' | 'completed'
rating?: number
chapters?: number
lessons?: number
duration?: string
watchedTime?: string
progress?: number
}
// 定义作业接口
interface Assignment {
id: number
teacherName: string
teacherAvatar: string
assignTime: string
status: string
title: string
description: string
attachments: Array<{
icon: string
name: string
}>
mainImage: string
}
// 定义考试接口
interface Exam {
id: number
title: string
examDate: string
duration: number
questionCount: number
description: string
status: 'upcoming' | 'ongoing' | 'finished'
score: number | null
}
// 考试题目选项接口
// interface ExamOption {
// id: string
// text: string
// image?: string
// }
// 考试题目接口
// interface ExamQuestion {
// id: number
// type: 'single' | 'multiple'
// title: string
// content: string
// options: ExamOption[]
// correctAnswers: string[]
// userAnswers: string[]
// isCorrect: boolean
// }
// 考试详情接口
// interface ExamDetail {
// id: number
// title: string
// examDate: string
// duration: number
// totalQuestions: number
// correctCount: number
// wrongCount: number
// score: number
// questions: ExamQuestion[]
// }
// 练习接口
interface Practice {
id: number
title: string
practiceDate: string
duration: number
questionCount: number
description: string
status: 'ongoing' | 'finished'
score: number | null
correctCount: number
wrongCount: number
}
// 练习详情接口(复用考试题目结构)
// interface PracticeDetail {
// id: number
// title: string
// practiceDate: string
// duration: number
// totalQuestions: number
// correctCount: number
// wrongCount: number
// score: number
// questions: ExamQuestion[]
// }
// 活动接口
interface Activity {
id: number
title: string
subtitle: string
courseTitle: string
activityDate: string
duration: number
activityType: string
registeredCount: string
description: string
status: 'ongoing' | 'finished'
score: number | null
}
// 消息接口
interface Message {
id: number
senderName: string
senderAvatar: string
content: string
courseName: string
date: string
isRead: boolean
hasReply: boolean
replyContent?: string
}
// 系统消息接口
interface SystemMessage {
id: number
title: string
subtitle: string
date: string
isRead: boolean
}
// 点赞消息接口
interface LikeMessage {
id: number
userName: string
userAvatar: string
type: 'comment' | 'course'
courseName?: string
content?: string
date: string
isRead: boolean
}
const message = useMessage()
const userStore = useUserStore()
// 定义标签页类型
type TabType = 'courses' | 'homework' | 'exam' | 'practice' | 'activity' | 'follows' | 'message' | 'materials' | 'download'
const activeTab = ref<TabType>('courses')
const activeCourseTab = ref('all')
// 作业筛选状态
const activeHomeworkTab = ref('all')
// 考试筛选状态
const activeExamTab = ref('all')
// 练习筛选状态
const activePracticeTab = ref('all')
// 活动筛选状态
const activeActivityTab = ref('all')
// 关注筛选状态
const activeFollowsTab = ref('all')
// 消息相关状态
const activeMessageTab = ref('instant')
const replyingMessageId = ref<number | null>(null)
const replyContent = ref('')
// 资料相关状态
const activeMaterialsTab = ref('basic')
// 用户信息
const userInfo = reactive({
avatar: '/images/traings/traing1.png',
nickname: '张成学',
gender: '',
college: '北京清华大学',
phone: '18658822666654'
})
// 密码修改表单
const passwordForm = reactive({
currentPassword: '',
newPassword: '',
confirmPassword: ''
})
// 下载相关状态
const activeDownloadTab = ref('courseware')
const activeFileMenu = ref<number | null>(null)
const currentPath = ref<string[]>([]) // 当前路径,用于面包屑
const isInSubDirectory = ref(false) // 是否在子目录中
const isRefreshing = ref(false) // 是否正在刷新
// 下载筛选条件
const downloadFilter = reactive({
type: 'all',
keyword: ''
})
// 下载文件数据
const downloadFiles = reactive([
{ id: 1, name: '图片', type: 'folder', category: 'courseware' },
{ id: 2, name: '文档', type: 'folder', category: 'courseware' },
{ id: 3, name: '视频', type: 'folder', category: 'courseware' },
{ id: 4, name: '样子', type: 'folder', category: 'courseware' },
{ id: 5, name: '音频', type: 'folder', category: 'courseware' },
{ id: 6, name: '文件名称', type: 'folder', category: 'courseware' },
{ id: 7, name: '文件名称', type: 'folder', category: 'courseware' },
{ id: 8, name: '文件名称', type: 'folder', category: 'courseware' },
{ id: 9, name: '文件名称', type: 'folder', category: 'courseware' },
{ id: 10, name: '文件名称', type: 'folder', category: 'courseware' },
{ id: 11, name: '文件名称', type: 'folder', category: 'courseware' },
{ id: 12, name: '文件名称', type: 'folder', category: 'courseware' },
{ id: 13, name: '证书文件1', type: 'folder', category: 'certificate' },
{ id: 14, name: '证书文件2', type: 'folder', category: 'certificate' },
{ id: 16, name: '证书文件2', type: 'folder', category: 'certificate' },
{ id: 17, name: '证书文件2', type: 'folder', category: 'certificate' },
{ id: 18, name: '证书文件2', type: 'folder', category: 'certificate' },
{ id: 15, name: '资源文件1', type: 'folder', category: 'resources' },
{ id: 19, name: '作业文件1', type: 'folder', category: 'homework' },
{ id: 20, name: '作业文件2', type: 'folder', category: 'homework' },
{ id: 21, name: '作业文件3', type: 'folder', category: 'homework' },
{ id: 22, name: '作业文件4', type: 'folder', category: 'homework' },
{ id: 23, name: '作业文件5', type: 'folder', category: 'homework' },
{ id: 24, name: '作业文件6', type: 'folder', category: 'homework' }
])
// 分页相关状态
const currentPage = ref(1)
const pageSize = ref(5) // 每页显示5个课程
// 模拟课程数据基于蓝湖UI设计
const mockCourses: Course[] = [
{
id: 1,
title: '教育心理学的起源',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试"1+X"WPS办公应用职业技能等级证书技能',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngd0745b9ee85d1fd2251cde7df5f13cdc38cfb57ba7f1ca467638a1196af0a4fc',
status: 'learning',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '10小时20分钟',
progress: 75
},
{
id: 2,
title: '现代教育技术应用',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书技能…',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng80fbbc0cab537164b6d85a9a7dcea31848f9becbaceafadb4ea618af4fde9554',
status: 'completed',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '10小时20分钟',
progress: 100
},
{
id: 3,
title: '课程设计与开发',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书技能…',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng80fbbc0cab537164b6d85a9a7dcea31848f9becbaceafadb4ea618af4fde9554',
status: 'completed',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '10小时20分钟',
progress: 100
},
{
id: 4,
title: '现代教育技术应用',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书技能…',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng80fbbc0cab537164b6d85a9a7dcea31848f9becbaceafadb4ea618af4fde9554',
status: 'learning',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '8小时15分钟',
progress: 65
},
{
id: 5,
title: '数字化教学设计',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书技能…',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng80fbbc0cab537164b6d85a9a7dcea31848f9becbaceafadb4ea618af4fde9554',
status: 'learning',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '5小时30分钟',
progress: 45
},
{
id: 6,
title: '在线教育平台运营',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书技能…',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng80fbbc0cab537164b6d85a9a7dcea31848f9becbaceafadb4ea618af4fde9554',
status: 'completed',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '12小时43分钟',
progress: 100
},
{
id: 7,
title: '教学评估与反馈',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书技能…',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng80fbbc0cab537164b6d85a9a7dcea31848f9becbaceafadb4ea618af4fde9554',
status: 'learning',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '3小时20分钟',
progress: 25
},
{
id: 8,
title: '智能教育工具应用',
instructor: '代方枚 史雯',
description: '本课程紧跟风向让每一位教师了解并学习使用DeepSeek结合办公自动化职业岗位标准以实际工作任务为引领强调课程内容的易用性和岗位要求的匹配性课程内容与全国计算机等级考试、"1+X"WPS办公应用职业技能等级证书技能…',
thumbnail: 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPng80fbbc0cab537164b6d85a9a7dcea31848f9becbaceafadb4ea618af4fde9554',
status: 'completed',
rating: 541,
chapters: 9,
lessons: 54,
duration: '12小时43分钟',
watchedTime: '12小时43分钟',
progress: 100
}
]
// 模拟作业数据基于蓝湖UI设计
const mockAssignments: Assignment[] = [
{
id: 1,
teacherName: '张老师',
teacherAvatar: '/images/traings/traing1.png',
assignTime: '2024-01-15',
status: '待提交',
title: '教育心理学课程设计作业',
description: '请根据所学的教育心理学理论,设计一个完整的课程教学方案,包括教学目标、教学内容、教学方法、教学评价等方面。要求理论联系实际,体现现代教育理念。',
attachments: [
{ icon: '/images/traings/traing1.png', name: '作业要求.pdf' },
{ icon: '/images/traings/traing1.png', name: '参考资料.docx' },
{ icon: '/images/traings/traing1.png', name: '模板文件.pptx' },
{ icon: '/images/traings/traing1.png', name: '评分标准.pdf' },
{ icon: '/images/traings/traing1.png', name: '案例分析.xlsx' }
],
mainImage: '/images/traings/traing1.png'
},
{
id: 2,
teacherName: '李老师',
teacherAvatar: '/images/traings/traing1.png',
assignTime: '2024-01-20',
status: '已完成',
title: '现代教育技术应用实践报告',
description: '结合本学期所学的现代教育技术知识,选择一个具体的教学场景,设计并实施一个融合信息技术的教学活动,撰写实践报告。',
attachments: [
{ icon: '/images/traings/traing1.png', name: '实践指导.pdf' },
{ icon: '/images/traings/traing1.png', name: '报告模板.docx' },
{ icon: '/images/traings/traing1.png', name: '技术工具清单.xlsx' },
{ icon: '/images/traings/traing1.png', name: '评价量表.pdf' },
{ icon: '/images/traings/traing1.png', name: '优秀案例.pptx' }
],
mainImage: '/images/traings/traing1.png'
},
{
id: 3,
teacherName: '王老师',
teacherAvatar: '/images/traings/traing1.png',
assignTime: '2024-01-18',
status: '未完成',
title: '数字化教学资源开发',
description: '开发一套完整的数字化教学资源,包括课件制作、视频录制、在线测试设计等,要求体现现代教育技术的应用特点。',
attachments: [
{ icon: '/images/traings/traing1.png', name: '开发指南.pdf' },
{ icon: '/images/traings/traing1.png', name: '技术要求.docx' },
{ icon: '/images/traings/traing1.png', name: '示例资源.zip' }
],
mainImage: '/images/traings/traing1.png'
},
{
id: 4,
teacherName: '刘老师',
teacherAvatar: '/images/traings/traing1.png',
assignTime: '2024-01-10',
status: '已完成',
title: '在线教育平台使用报告',
description: '体验并分析主流在线教育平台的功能特点,撰写详细的使用报告和改进建议。',
attachments: [
{ icon: '/images/traings/traing1.png', name: '平台列表.pdf' },
{ icon: '/images/traings/traing1.png', name: '评价标准.docx' }
],
mainImage: '/images/traings/traing1.png'
}
]
// 模拟考试数据
const mockExams: Exam[] = [
{
id: 1,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'upcoming',
score: null
},
{
id: 2,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'ongoing',
score: null
},
{
id: 3,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'finished',
score: 90
},
{
id: 4,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'upcoming',
score: null
},
{
id: 5,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'ongoing',
score: null
},
{
id: 6,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'finished',
score: 90
},
{
id: 7,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'upcoming',
score: null
},
{
id: 8,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'finished',
score: 90
},
{
id: 9,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '考试涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'ongoing',
score: null
}
]
// 模拟考试详情数据
// const mockExamDetails: { [key: number]: ExamDetail } = {
// 3: {
// id: 3,
// title: 'C++语言程序设计基础考试',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书' },
// { id: 'B', text: 'B.应急处理措施' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[多选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.产品标签' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// },
// 6: {
// id: 6,
// title: 'C++语言程序设计基础考试',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书' },
// { id: 'B', text: 'B.应急处理措施' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[多选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.产品标签' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// },
// 8: {
// id: 8,
// title: 'C++语言程序设计基础考试',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书' },
// { id: 'B', text: 'B.应急处理措施' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[多选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.产品标签' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// },
// 9: {
// id: 9,
// title: 'C++语言程序设计基础考试',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书' },
// { id: 'B', text: 'B.应急处理措施' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[多选题]',
// content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
// options: [
// { id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.安全标签' },
// { id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.产品标签' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// }
// }
// 模拟练习数据
const mockPractices: Practice[] = [
{
id: 1,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '练习涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'ongoing',
score: null,
correctCount: 18,
wrongCount: 15
},
{
id: 2,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-18 10:00',
duration: 88,
questionCount: 100,
description: '练习涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'finished',
score: 90,
correctCount: 18,
wrongCount: 15
},
{
id: 3,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-18 10:00',
duration: 88,
questionCount: 100,
description: '练习涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'finished',
score: 90,
correctCount: 18,
wrongCount: 15
},
{
id: 4,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-18 10:00',
duration: 120,
questionCount: 100,
description: '练习涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'ongoing',
score: null,
correctCount: 18,
wrongCount: 15
},
{
id: 5,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-18 10:00',
duration: 88,
questionCount: 100,
description: '练习涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'finished',
score: 90,
correctCount: 18,
wrongCount: 15
},
{
id: 6,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-18 10:00',
duration: 88,
questionCount: 100,
description: '练习涵盖C++基础语法、面向对象编程、数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力。',
status: 'finished',
score: 90,
correctCount: 18,
wrongCount: 15
}
]
// 模拟活动数据
const mockActivities: Activity[] = [
{
id: 1,
title: '2025计算机二级',
subtitle: 'C语言讲练综合班',
courseTitle: '2025计算机二级C语言讲练综合班',
activityDate: '2025-07-18 10:00',
duration: 120,
activityType: '激励类活动',
registeredCount: '100/200',
description: 'C++语言程序设计基础练习题涵盖C++基础语法、面向对象编程、数据结构等核心内容。',
status: 'ongoing',
score: null
},
{
id: 2,
title: '2025计算机二级',
subtitle: 'C语言讲练综合班',
courseTitle: '2025计算机二级C语言讲练综合班',
activityDate: '2025-07-18 10:00',
duration: 88,
activityType: '激励类活动',
registeredCount: '100/200',
description: 'C++语言程序设计基础练习题涵盖C++基础语法、面向对象编程、数据结构等核心内容。',
status: 'finished',
score: null
},
{
id: 3,
title: '2025计算机二级',
subtitle: 'C语言讲练综合班',
courseTitle: '2025计算机二级C语言讲练综合班',
activityDate: '2025-07-18 10:00',
duration: 88,
activityType: '激励类活动',
registeredCount: '100/200',
description: 'C++语言程序设计基础练习题涵盖C++基础语法、面向对象编程、数据结构等核心内容。',
status: 'finished',
score: null
},
{
id: 4,
title: '2025计算机二级',
subtitle: 'C语言讲练综合班',
courseTitle: '2025计算机二级C语言讲练综合班',
activityDate: '2025-07-18 10:00',
duration: 120,
activityType: '激励类活动',
registeredCount: '100/200',
description: 'C++语言程序设计基础练习题涵盖C++基础语法、面向对象编程、数据结构等核心内容。',
status: 'ongoing',
score: null
},
{
id: 5,
title: '2025计算机二级',
subtitle: 'C语言讲练综合班',
courseTitle: '2025计算机二级C语言讲练综合班',
activityDate: '2025-07-18 10:00',
duration: 88,
activityType: '激励类活动',
registeredCount: '100/200',
description: 'C++语言程序设计基础练习题涵盖C++基础语法、面向对象编程、数据结构等核心内容。',
status: 'finished',
score: null
},
{
id: 6,
title: '2025计算机二级',
subtitle: 'C语言讲练综合班',
courseTitle: '2025计算机二级C语言讲练综合班',
activityDate: '2025-07-18 10:00',
duration: 88,
activityType: '激励类活动',
registeredCount: '100/200',
description: 'C++语言程序设计基础练习题涵盖C++基础语法、面向对象编程、数据结构等核心内容。',
status: 'finished',
score: null
}
]
// 模拟关注数据
const mockFollows = [
{
id: 1,
name: '张教授',
role: '教育心理学教授',
description: '专注于教育心理学研究,发表多篇学术论文',
avatar: '/images/profile/avater.png',
type: 'all',
category: 'recent',
visitCount: 15,
isFollowing: true
},
{
id: 2,
name: '李老师',
role: '数学教师',
description: '拥有10年教学经验擅长数学教学方法创新',
avatar: '/images/profile/avater.png',
type: 'all',
category: 'recent',
visitCount: 8,
isFollowing: false
},
{
id: 3,
name: '王同学',
role: '学习伙伴',
description: '北京理工大学计算机学院教授计算机计算机计算',
avatar: '/images/profile/avater.png',
type: 'all',
category: 'frequent',
visitCount: 25,
isFollowing: true
},
{
id: 4,
name: '刘同学',
role: '学习伙伴',
description: '学习小组组长,组织能力强',
avatar: '/images/profile/avater.png',
type: 'all',
category: 'frequent',
visitCount: 32,
isFollowing: false
},
{
id: 5,
name: '陈博士',
role: '计算机科学教授',
description: '人工智能与机器学习专家发表论文50余篇',
avatar: '/images/profile/avater.png',
type: 'all',
category: 'recent',
visitCount: 12,
isFollowing: true
},
{
id: 6,
name: '赵同学',
role: '学习伙伴',
description: '编程爱好者,经常分享学习心得',
avatar: '/images/profile/avater.png',
type: 'all',
category: 'frequent',
visitCount: 28,
isFollowing: false
}
]
// 模拟消息数据
const mockMessages: Message[] = [
{
id: 1,
senderName: '王建',
senderAvatar: '/images/avatars/teacher1.png',
content: '回复了我:没事多看看课程的起源',
courseName: '教育心理学的起源',
date: '7月20日 12:41',
isRead: false,
hasReply: true,
replyContent: ''
},
{
id: 2,
senderName: '建国学习@了我:',
senderAvatar: '/images/avatars/student1.png',
content: '没事多看看课程的起源',
courseName: '教育心理学的起源',
date: '7月20日 12:41',
isRead: false,
hasReply: true,
replyContent: ''
},
{
id: 3,
senderName: '建国学习',
senderAvatar: '/images/avatars/student2.png',
content: '回复了我:没事多看看课程的起源了',
courseName: '教育心理学的起源',
date: '7月20日 12:41',
isRead: false,
hasReply: true,
replyContent: ''
}
]
// 模拟系统消息数据
const mockSystemMessages: SystemMessage[] = [
{
id: 1,
title: '你的会员日专属福利已更新,快来领取今日小惊喜,仅此一天!',
subtitle: '好消息好消息BilibiliWorld2024将在明天6月29日周六正式开票',
date: '7月20日 12:41',
isRead: false
},
{
id: 2,
title: 'PACS在特殊医疗场景的业务适配与功能创新',
subtitle: '好消息好消息BilibiliWorld2024将在明天6月29日周六正式开票',
date: '7月20日 12:41',
isRead: false
},
{
id: 3,
title: '你的会员日专属福利已更新,快来领取今日小惊喜,仅此一天!',
subtitle: '好消息好消息BilibiliWorld2024将在明天6月29日周六正式开票',
date: '7月20日 12:41',
isRead: false
},
{
id: 4,
title: '你的会员日专属福利已更新,快来领取今日小惊喜,仅此一天!',
subtitle: '好消息好消息BilibiliWorld2024将在明天6月29日周六正式开票',
date: '7月20日 12:41',
isRead: false
}
]
// 模拟点赞消息数据
const mockLikeMessages: LikeMessage[] = [
{
id: 1,
userName: '张同学',
userAvatar: '/images/traings/traing1.png',
type: 'comment',
courseName: 'Python语言基础与应用',
content: '这个课程讲得很好,老师很专业',
date: '7月21日 14:30',
isRead: false
},
{
id: 2,
userName: '李老师',
userAvatar: '/images/traings/traing2.png',
type: 'course',
courseName: 'Java程序设计',
content: '',
date: '7月21日 10:15',
isRead: false
},
{
id: 3,
userName: '王同学',
userAvatar: '/images/traings/traing3.png',
type: 'comment',
courseName: 'C语言程序设计',
content: '感谢老师的耐心解答',
date: '7月20日 16:45',
isRead: true
},
{
id: 4,
userName: '刘同学',
userAvatar: '/images/traings/traing1.png',
type: 'comment',
courseName: 'JavaScript基础',
content: '这个例子很实用',
date: '7月20日 09:20',
isRead: true
},
{
id: 5,
userName: '陈老师',
userAvatar: '/images/traings/traing2.png',
type: 'course',
courseName: 'HTML5与CSS3',
content: '',
date: '7月19日 18:30',
isRead: true
}
]
// 模拟练习详情数据
// const mockPracticeDetails: { [key: number]: PracticeDetail } = {
// 2: {
// id: 2,
// title: 'C++语言程序设计基础练习题',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: 'C++中,下列哪个关键字用于定义类?',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[多选题]',
// content: 'C++中,下列哪些是面向对象编程的特性?',
// options: [
// { id: 'A', text: 'A.封装' },
// { id: 'B', text: 'B.继承' },
// { id: 'C', text: 'C.多态' },
// { id: 'D', text: 'D.递归' },
// { id: 'E', text: 'E.抽象' }
// ],
// correctAnswers: ['A', 'B', 'C', 'E'],
// userAnswers: ['A', 'B', 'C'],
// isCorrect: false
// }
// ]
// },
// 3: {
// id: 3,
// title: 'C++语言程序设计基础练习题',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: 'C++中,下列哪个关键字用于定义类?',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// }
// ]
// },
// 5: {
// id: 5,
// title: 'C++语言程序设计基础练习题',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: 'C++中,下列哪个关键字用于定义类?',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// }
// ]
// },
// 6: {
// id: 6,
// title: 'C++语言程序设计基础练习题',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[单选题]',
// content: 'C++中,下列哪个关键字用于定义类?',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// }
// ]
// }
// }
// 获取筛选后的所有课程
const allFilteredCourses = computed(() => {
if (activeCourseTab.value === 'learning') {
return mockCourses.filter(course => course.status === 'learning')
} else if (activeCourseTab.value === 'completed') {
return mockCourses.filter(course => course.status === 'completed')
}
return mockCourses
})
// 计算总页数
const totalPages = computed(() => {
return Math.ceil(allFilteredCourses.value.length / pageSize.value)
})
// 当前页显示的课程
const filteredCourses = computed(() => {
const start = (currentPage.value - 1) * pageSize.value
const end = start + pageSize.value
return allFilteredCourses.value.slice(start, end)
})
// 获取筛选后的作业
const filteredAssignments = computed(() => {
if (activeHomeworkTab.value === 'pending') {
return mockAssignments.filter(assignment => assignment.status === '待提交' || assignment.status === '未完成')
} else if (activeHomeworkTab.value === 'completed') {
return mockAssignments.filter(assignment => assignment.status === '已完成' || assignment.status === '已完成')
}
return mockAssignments
})
// 获取筛选后的考试
const filteredExams = computed(() => {
if (activeExamTab.value === 'upcoming') {
return mockExams.filter(exam => exam.status === 'upcoming')
} else if (activeExamTab.value === 'ongoing') {
return mockExams.filter(exam => exam.status === 'ongoing')
} else if (activeExamTab.value === 'finished') {
return mockExams.filter(exam => exam.status === 'finished')
}
return mockExams
})
// 获取筛选后的练习
const filteredPractices = computed(() => {
if (activePracticeTab.value === 'ongoing') {
return mockPractices.filter(practice => practice.status === 'ongoing')
} else if (activePracticeTab.value === 'finished') {
return mockPractices.filter(practice => practice.status === 'finished')
}
return mockPractices
})
// 获取筛选后的活动
const filteredActivities = computed(() => {
if (activeActivityTab.value === 'ongoing') {
return mockActivities.filter(activity => activity.status === 'ongoing')
} else if (activeActivityTab.value === 'finished') {
return mockActivities.filter(activity => activity.status === 'finished')
}
return mockActivities
})
// 获取筛选后的关注
const filteredFollows = computed(() => {
if (activeFollowsTab.value === 'recent') {
return mockFollows.filter(follow => follow.category === 'recent')
} else if (activeFollowsTab.value === 'frequent') {
return mockFollows.filter(follow => follow.category === 'frequent')
}
return mockFollows
})
// 计算属性用于模板中的条件判断
const isCoursesTab = computed(() => activeTab.value === 'courses')
const isHomeworkTab = computed(() => activeTab.value === 'homework')
const isExamTab = computed(() => activeTab.value === 'exam')
const isPracticeTab = computed(() => activeTab.value === 'practice')
const isActivityTab = computed(() => activeTab.value === 'activity')
const isFollowsTab = computed(() => activeTab.value === 'follows')
const isMessageTab = computed(() => activeTab.value === 'message')
// 处理菜单选择
const handleMenuSelect = (key: TabType) => {
activeTab.value = key
router.push(`/profile/${key}`)
// message.info(`切换到${getTabTitle(key)}`)
}
// 获取状态文本
const getStatusText = (status: string) => {
switch (status) {
case 'learning':
return '学习中'
case 'completed':
return '已完结'
default:
return '未开始'
}
}
// 跳转到课程
const goToCourse = (courseId: number) => {
message.info(`跳转到课程 ${courseId}`)
}
// 分页器方法
const goToPage = (page: number | string) => {
if (typeof page === 'number') {
if (page >= 1 && page <= totalPages.value) {
currentPage.value = page
}
} else {
switch (page) {
case 'first':
if (currentPage.value > 1) {
currentPage.value = 1
}
break
case 'prev':
if (currentPage.value > 1) {
currentPage.value--
}
break
case 'next':
if (currentPage.value < totalPages.value) {
currentPage.value++
}
break
case 'last':
if (currentPage.value < totalPages.value) {
currentPage.value = totalPages.value
}
break
}
}
}
// 监听筛选变化,重置到第一页
const handleCourseTabChange = (tab: string) => {
activeCourseTab.value = tab
currentPage.value = 1
}
// 处理作业筛选变化
const handleHomeworkTabChange = (tab: string) => {
activeHomeworkTab.value = tab
}
// 处理考试筛选变化
const handleExamTabChange = (tab: string) => {
activeExamTab.value = tab
}
// 处理练习筛选变化
const handlePracticeTabChange = (tab: string) => {
activePracticeTab.value = tab
}
// 处理活动筛选变化
const handleActivityTabChange = (tab: string) => {
activeActivityTab.value = tab
}
// 处理关注筛选变化
const handleFollowsTabChange = (tab: string) => {
activeFollowsTab.value = tab
}
// 获取考试状态文本
const getExamStatusText = (status: string) => {
switch (status) {
case 'upcoming':
return '未开始'
case 'ongoing':
return '进行中'
case 'finished':
return '已结束'
default:
return '未知状态'
}
}
// 开始考试
const startExam = (examId: number) => {
message.info(`开始考试 ${examId}`)
}
// 继续考试
const continueExam = (examId: number) => {
// message.info(`继续考试 ${examId}`)
router.push(`/exam/notice/${examId}`)
}
// 查看考试结果
const viewExamResult = (examId: number) => {
router.push(`/exam-detail/${examId}?source=exam`)
}
// 继续练习
const continuePractice = (practiceId: number) => {
message.info(`继续练习 ${practiceId}`)
}
// 查看练习详情
const viewPracticeDetail = (practiceId: number) => {
router.push(`/exam-detail/${practiceId}?source=practice`)
}
// 继续活动
const continueActivity = (id: number) => {
console.log('继续活动:', id)
message.info(`继续活动 ${id}`)
}
// 查看活动详情
const viewActivityDetail = (id: number) => {
router.push(`/activity/${id}`)
}
// 切换关注状态
const toggleFollow = (id: number) => {
const follow = mockFollows.find(f => f.id === id)
if (follow) {
follow.isFollowing = !follow.isFollowing
const action = follow.isFollowing ? '关注' : '取消关注'
message.info(`${action}用户 ${follow.name}`)
}
}
// 消息相关方法
const handleMessageTabChange = (tab: string) => {
activeMessageTab.value = tab
}
// 资料相关方法
const handleMaterialsTabChange = (tab: string) => {
activeMaterialsTab.value = tab
}
// 保存密码修改
const savePassword = () => {
if (!passwordForm.currentPassword || !passwordForm.newPassword || !passwordForm.confirmPassword) {
message.error('请填写完整的密码信息')
return
}
if (passwordForm.newPassword !== passwordForm.confirmPassword) {
message.error('两次输入的新密码不一致')
return
}
if (passwordForm.newPassword.length < 6) {
message.error('新密码长度不能少于6位')
return
}
// 这里可以添加实际的密码修改逻辑
message.success('密码修改成功')
// 清空表单
passwordForm.currentPassword = ''
passwordForm.newPassword = ''
passwordForm.confirmPassword = ''
}
// 下载相关方法
const handleDownloadTabChange = (tab: string) => {
activeDownloadTab.value = tab
}
// 筛选后的下载文件
const filteredDownloadFiles = computed(() => {
// 如果在子目录中,返回空数组显示空页面
if (isInSubDirectory.value) {
return []
}
let files = downloadFiles.filter(file => file.category === activeDownloadTab.value)
if (downloadFilter.type !== 'all') {
files = files.filter(file => file.type === downloadFilter.type)
}
if (downloadFilter.keyword) {
files = files.filter(file =>
file.name.toLowerCase().includes(downloadFilter.keyword.toLowerCase())
)
}
return files
})
// 文件菜单操作
const toggleFileMenu = (fileId: number) => {
activeFileMenu.value = activeFileMenu.value === fileId ? null : fileId
}
const handleFileClick = (file: any) => {
// 单击文件时的处理逻辑(如选中文件等)
console.log('单击文件:', file.name)
}
const handleFolderDoubleClick = (file: any) => {
if (file.type === 'folder') {
// 双击文件夹,进入子目录(显示空页面)
isInSubDirectory.value = true
currentPath.value = ['课件', file.name]
console.log('进入文件夹:', file.name)
}
}
const goBack = () => {
// 返回上级目录
isInSubDirectory.value = false
currentPath.value = []
}
const getFileIcon = (fileId?: number) => {
if (activeDownloadTab.value === 'certificate') {
// 证书标签页使用证书图标
return '/images/profile/certificate.jpg'
} else if (activeDownloadTab.value === 'homework') {
// 作业标签页使用不同的作业相关图标
const homeworkImages = [
'/images/profile/word.png',
'/images/profile/pdf.png',
'/images/profile/ppt.png',
'/images/profile/xls.png',
'/images/profile/zip.png',
'/images/profile/word.png'
]
const index = (fileId || 0) % homeworkImages.length
return homeworkImages[index]
} else if (isInSubDirectory.value) {
// 子目录使用子目录图标
return 'https://lanhu-oss-2537-2.lanhuapp.com/SketchPngf45333052202c303acc2c06223c26b820d330459ce2d452a21a3132fbbeab442'
} else {
// 默认文件夹图标
return '/images/profile/folder.png'
}
}
const createNewFolder = () => {
message.info('新建文件夹功能开发中...')
}
const renameFile = (fileId: number) => {
message.info(`重命名文件 ${fileId}`)
activeFileMenu.value = null
}
const deleteFile = (fileId: number) => {
message.info(`删除文件 ${fileId}`)
activeFileMenu.value = null
}
// 开始回复消息
const startReply = (messageId: number) => {
replyingMessageId.value = messageId
replyContent.value = ''
}
// 取消回复
const cancelReply = () => {
replyingMessageId.value = null
replyContent.value = ''
}
// 发送回复
const sendReply = (messageId: number) => {
if (!replyContent.value.trim()) {
message.error('请输入回复内容')
return
}
// 这里可以添加实际的发送逻辑
message.success('回复发送成功')
// 更新消息数据中的回复内容
const messageIndex = mockMessages.findIndex(msg => msg.id === messageId)
if (messageIndex !== -1) {
mockMessages[messageIndex].replyContent = replyContent.value
}
cancelReply()
}
// 获取筛选后的消息
const filteredMessages = computed(() => {
if (activeMessageTab.value === 'comment') {
return mockMessages
}
return []
})
// 获取筛选后的系统消息
const filteredSystemMessages = computed(() => {
if (activeMessageTab.value === 'system') {
return mockSystemMessages
}
return []
})
// 获取筛选后的点赞消息
const filteredLikeMessages = computed(() => {
if (activeMessageTab.value === 'like') {
return mockLikeMessages
}
return []
})
// 获取标签标题
const getTabTitle = (tab: TabType) => {
const titles: Record<TabType, string> = {
courses: '我的课程',
homework: '我的作业',
exam: '我的考试',
practice: '我的练习',
activity: '我的活动',
follows: '我的关注',
message: '我的消息',
materials: '我的资料',
download: '我的下载'
}
return titles[tab] || '未知页面'
}
// 上传作业弹窗状态
const showModal = ref(false)
const currentAssignment = ref<Assignment | null>(null)
const uploadForm = reactive({
title: '',
content: '',
files: [] as File[]
})
// 作业详情视图状态
const showDetailView = ref(false)
const detailAssignment = ref<Assignment | null>(null)
// 草稿箱视图状态
const showDraftBoxView = ref(false)
const draftAssignment = ref<Assignment | null>(null)
// 考试详情视图状态
// // 获取答题卡项目的样式类
// const getAnswerItemClass = (index: number) => {
// // 模拟答题状态前10题答对第11-15题答错其余未答
// if (index <= 10) {
// return 'correct'
// } else if (index <= 15) {
// return 'wrong'
// } else {
// return 'unanswered'
// }
// }
// 查看作业详情
const viewAssignmentDetail = (assignment: Assignment) => {
detailAssignment.value = assignment
showDetailView.value = true
showDraftBoxView.value = false
}
// 返回作业列表
// const backToAssignmentList = () => {
// showDetailView.value = false
// detailAssignment.value = null
// }
// 从详情页面跳转到上传作业
const showUploadFromDetail = () => {
showUploadModal(detailAssignment.value!)
}
// 显示草稿箱
const showDraftBox = () => {
// 模拟草稿箱数据,实际应该从后端获取
draftAssignment.value = {
id: 1,
title: '教育心理学课程设计作业',
description: '请根据所学的教育心理学理论,设计一个完整的课程教学方案,包括教学目标、教学内容、教学方法、教学评价等方面。要求理论联系实际,体现现代教育理念。',
teacherName: '张老师',
teacherAvatar: '/images/traings/traing1.png',
assignTime: '2024-01-15',
status: '草稿',
attachments: [
{ icon: '/images/auth/file.png', name: 'file1.pdf' },
{ icon: '/images/auth/file.png', name: 'file2.pdf' }
],
mainImage: '/images/traings/traing1.png'
}
showDraftBoxView.value = true
showDetailView.value = false
}
// 返回作业列表(从草稿箱)
const backFromDraftBox = () => {
showDraftBoxView.value = false
draftAssignment.value = null
}
// 重新编辑草稿
const reEditDraft = () => {
showUploadModal(draftAssignment.value!)
}
// 显示上传作业弹窗
const showUploadModal = (assignment: Assignment) => {
currentAssignment.value = assignment
uploadForm.title = ''
uploadForm.content = ''
uploadForm.files = []
showModal.value = true
}
// 关闭上传作业弹窗
const closeUploadModal = () => {
showModal.value = false
currentAssignment.value = null
}
// 提交作业
const submitAssignment = () => {
if (!uploadForm.title.trim()) {
message.error('请输入标题')
return
}
if (!uploadForm.content.trim()) {
message.error('请输入内容')
return
}
if (uploadForm.files.length === 0) {
message.error('请上传至少一个文件')
return
}
// 这里可以添加实际的提交逻辑
message.success('作业提交成功')
closeUploadModal()
}
onMounted(() => {
// 初始化
// 检查是否需要刷新
const shouldRefresh = sessionStorage.getItem('refreshProfile')
if (shouldRefresh === 'true') {
isRefreshing.value = true
sessionStorage.removeItem('refreshProfile')
// 延迟刷新,给用户一个视觉反馈
setTimeout(() => {
window.location.reload()
}, 100)
}
const tabKey = <TabType>route.params.tabKey || 'courses'
handleMenuSelect(tabKey)
})
onActivated(() => {
// 检查是否需要刷新
const shouldRefresh = sessionStorage.getItem('refreshProfile')
if (shouldRefresh === 'true') {
isRefreshing.value = true
sessionStorage.removeItem('refreshProfile')
// 延迟刷新,给用户一个视觉反馈
setTimeout(() => {
window.location.reload()
}, 100)
}
})
</script>
<style scoped>
/* 刷新遮罩样式 */
.refresh-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.9);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
backdrop-filter: blur(4px);
}
.refresh-content {
text-align: center;
color: #333;
}
.refresh-spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 16px;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 基础布局类 */
.flex-col {
display: flex;
flex-direction: column;
}
.flex-row {
display: flex;
flex-direction: row;
}
.justify-between {
justify-content: space-between;
}
/* 主页面容器 */
.profile-page {
width: 100vw;
min-height: calc(100vh - 6.4vh);
/* 减去顶部导航栏高度 */
background: #f6f6f6;
padding: 0;
display: flex;
justify-content: center;
}
/* 主要内容区域 */
.profile-content {
/* width: 80vw; */
/* 调整为80vw */
min-height: 1415px;
margin: 3vh auto 0 auto;
/* 距离顶部40px转换为vh */
position: relative;
background: #f6f6f6;
}
/* 左侧侧边栏 */
.block_14 {
position: relative;
width: 13.4vw;
height: auto;
background: #ffffff;
/* 改为白色背景 */
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 30px;
/* 内容居中 */
}
/* 用户头像和姓名 */
.image_7 {
width: 5vw !important;
/* 调整头像大小覆盖SafeAvatar的内联样式 */
height: 5vw !important;
border-radius: 50%;
margin: 2.6vh auto 0 auto;
/* 居中显示 */
}
.image_7 img {
object-fit: cover;
display: block;
}
.text_72 {
width: 100%;
height: auto;
font-size: 1.1vw;
/* 调整字体大小 */
color: rgba(0, 0, 0, 1);
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
line-height: 1.6vh;
margin: 0.9vh 0 0 0;
/* 居中显示 */
}
/* 菜单背景 */
.box_22 {
width: 12vw;
/* 调整菜单背景宽度,适应缩小的导航栏 */
height: auto;
/* 自适应高度 */
background: transparent;
/* 去掉背景色 */
border-radius: 0.6vw;
/* 12px转换为vw */
margin: 2.55vh 0;
/* 去掉左右边距,因为父容器已经居中 */
padding: 1.04vh 0;
/* 20px 0转换 */
display: flex;
flex-direction: column;
align-items: center;
/* 菜单项居中 */
}
/* 分割线 */
.menu-divider {
width: 11vw;
/* 与菜单项宽度一致 */
height: 0.05vh;
/* 1px转换为vh */
background: #E6E6E6;
margin: 0;
/* 上下间距 */
}
/* 菜单项 */
.image-text_19,
.image-text_20,
.image-text_21,
.image-text_22,
.image-text_23,
.image-text_24,
.image-text_25,
.image-text_26,
.image-text_27 {
width: 11vw;
/* 进一步缩小菜单项宽度,适应新的导航栏宽度 */
height: auto;
/* 自适应高度 */
min-height: 3vh;
/* 设置最小高度,让盒子更大 */
margin: .5vh;
/* 减小间距从2.34vh减少到1.5vh */
display: flex;
align-items: center;
justify-content: left;
/* 菜单项内容居中 */
cursor: pointer;
padding: 1.5vh 0 1.5vh 1.8vw;
/* 增加上下内边距,让盒子更高 */
border-radius: 0.31vw;
/* 6px转换为vw */
transition: all 0.3s ease;
background: transparent;
/* 默认透明背景 */
}
.image-text_19:hover,
.image-text_20:hover,
.image-text_21:hover,
.image-text_22:hover,
.image-text_23:hover,
.image-text_24:hover,
.image-text_25:hover,
.image-text_26:hover,
.image-text_27:hover {
background: #eff7fc;
/* 悬停时背景色 */
}
/* 激活状态的菜单项 */
.image-text_19.active,
.image-text_20.active,
.image-text_21.active,
.image-text_22.active,
.image-text_23.active,
.image-text_24.active,
.image-text_25.active,
.image-text_26.active,
.image-text_27.active {
background: #eff7fc;
/* 激活时背景色 */
}
/* 菜单图标 */
.image_8,
.label_4,
.label_5,
.label_6,
.thumbnail_40,
.label_7,
.image_9,
.thumbnail_41,
.thumbnail_42 {
width: 1.04vw;
/* 20px转换为vw */
height: 1.04vw;
margin-right: 0.78vw;
/* 15px转换为vw */
}
/* 菜单文字 */
.text-group_19,
.text-group_20,
.text-group_21,
.text-group_22,
.text-group_23,
.text-group_24,
.text-group_25,
.text-group_26,
.text-group_27 {
font-size: 16px;
/* 20px转换为vw */
color: rgba(102, 102, 102, 1);
/* 默认灰色 */
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
line-height: 1.46vh;
/* 28px转换为vh */
transition: color 0.3s ease;
}
/* 激活状态的菜单文字颜色 */
.image-text_19.active .text-group_19,
.image-text_20.active .text-group_20,
.image-text_21.active .text-group_21,
.image-text_22.active .text-group_22,
.image-text_23.active .text-group_23,
.image-text_24.active .text-group_24,
.image-text_25.active .text-group_25,
.image-text_27.active .text-group_27,
.image-text_26.active .text-group_26 {
color: rgba(2, 134, 206, 1);
/* 激活时蓝色 */
}
/* 悬停状态的菜单文字颜色 */
.image-text_19:hover .text-group_19,
.image-text_20:hover .text-group_20,
.image-text_21:hover .text-group_21,
.image-text_22:hover .text-group_22,
.image-text_23:hover .text-group_23,
.image-text_24:hover .text-group_24,
.image-text_25:hover .text-group_25,
.image-text_27:hover .text-group_27,
.image-text_26:hover .text-group_26 {
color: rgba(2, 134, 206, 1);
/* 悬停时蓝色 */
}
/* 菜单项图标悬停效果 */
.image-text_19 .hover-icon,
.image-text_20 .hover-icon,
.image-text_21 .hover-icon,
.image-text_22 .hover-icon,
.image-text_23 .hover-icon,
.image-text_24 .hover-icon,
.image-text_25 .hover-icon,
.image-text_26 .hover-icon,
.image-text_27 .hover-icon {
display: none;
}
.image-text_19:hover .default-icon,
.image-text_20:hover .default-icon,
.image-text_21:hover .default-icon,
.image-text_22:hover .default-icon,
.image-text_23:hover .default-icon,
.image-text_24:hover .default-icon,
.image-text_25:hover .default-icon,
.image-text_26:hover .default-icon,
.image-text_27:hover .default-icon {
display: none;
}
.image-text_19:hover .hover-icon,
.image-text_20:hover .hover-icon,
.image-text_21:hover .hover-icon,
.image-text_22:hover .hover-icon,
.image-text_23:hover .hover-icon,
.image-text_24:hover .hover-icon,
.image-text_25:hover .hover-icon,
.image-text_26:hover .hover-icon,
.image-text_27:hover .hover-icon {
display: block;
}
/* 激活状态的图标显示 */
.image-text_19.active .default-icon,
.image-text_20.active .default-icon,
.image-text_21.active .default-icon,
.image-text_22.active .default-icon,
.image-text_23.active .default-icon,
.image-text_24.active .default-icon,
.image-text_25.active .default-icon,
.image-text_26.active .default-icon,
.image-text_27.active .default-icon {
display: none;
}
.image-text_19.active .hover-icon,
.image-text_20.active .hover-icon,
.image-text_21.active .hover-icon,
.image-text_22.active .hover-icon,
.image-text_23.active .hover-icon,
.image-text_24.active .hover-icon,
.image-text_25.active .hover-icon,
.image-text_26.active .hover-icon,
.image-text_27.active .hover-icon {
display: block;
}
/* 右侧课程列表区域 */
.group_5 {
width: 65vw;
/* 保持60vw宽度 */
min-height: calc(100vh - 6.4vh);
padding: 2.08vh 1.9vw;
/* 40px转换为vh和vw */
background: rgba(255, 255, 255, 1);
overflow-y: auto;
margin-left: 1.56vw;
margin-bottom: 30px;
}
/* 课程筛选标签 */
.text-wrapper_1 {
width: 100%;
height: 2.08vh;
/* 40px转换为vh */
align-items: center;
margin: 20px 0 20px 0;
/* 32px转换为vh */
gap: 2.81vw;
/* 54px转换为vw54/1920*100 = 2.81vw */
}
.text_12,
.text_13,
.text_14,
.text_15 {
font-size: 0.94vw;
/* 18px转换为vw */
color: #000;
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
cursor: pointer;
padding: 0.42vh 0;
/* 去掉左右内边距,只保留上下 */
transition: color 0.3s ease;
/* 只保留颜色过渡 */
background: transparent;
/* 确保背景透明 */
}
.text_12.active,
.text_13.active,
.text_14.active,
.text_15.active {
color: rgba(2, 134, 206, 1);
/* 只改变字体颜色,去掉背景色 */
}
.text_12:hover,
.text_13:hover,
.text_14:hover,
.text_15:hover {
color: rgba(2, 134, 206, 1);
}
/* 课程区域分割线 */
.course-divider {
width: 100%;
/* 与课程卡片宽度一致 */
height: 1.5px;
/* 1px转换为vh */
background: #E6E6E6;
margin-bottom: 1.67vh;
/* 与课程列表的间距 */
}
/* 课程列表 */
.course-list {
display: flex;
flex-direction: column;
gap: 1.25vh;
/* 24px转换为vh */
}
/* 课程卡片 */
.box_2 {
width: 100%;
min-height: 10.42vh;
/* 200px转换为vh */
background: rgba(255, 255, 255, 1);
border: none;
/* 去掉边框 */
border-radius: 0.6vw;
/* 12px转换为vw */
padding: 1.04vh 1.04vw;
/* 20px转换 */
transition: all 0.3s ease;
}
.box_2:hover {
box-shadow: 0 0.21vh 1.04vh rgba(0, 0, 0, 0.1);
/* 0 4px 20px转换 */
transform: translateY(-0.1vh);
/* -2px转换为vh */
}
/* 课程缩略图区域 */
.block_4 {
margin-right: 1.04vw;
}
.box_3 {
width: 202px;
/* 200px转换为vw */
height: 156px;
/* 大幅增加高度到300px转换为vh让图片展示到外部盒子高度 */
position: relative;
border-radius: 5px;
/* 8px转换为vw */
overflow: hidden;
}
.thumbnail_4 {
width: 100%;
height: 156px;
object-fit: cover;
}
/* 状态标签 */
.status-image-container {
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
.status-image {
width: 66px;
height: 22px;
}
.status-text {
position: absolute;
top: 26vh;
/* 12px转换为vh */
right: 0.63vw;
/* 调整到右侧 */
padding: 0.21vh 0.63vw;
/* 4px 12px转换 */
border-radius: 0.21vw;
/* 4px转换为vw */
font-size: 0.63vw;
/* 12px转换为vw */
color: rgba(255, 255, 255, 1);
font-weight: 500;
}
.status-text.learning {
background: rgba(82, 196, 26, 1);
}
.status-text.completed {
background: rgba(24, 144, 255, 1);
}
/* 课程信息区域 */
.block_5 {
flex: 1;
display: flex;
flex-direction: column;
}
/* 课程标题和评分 */
.group_6 {
align-items: center;
margin-bottom: 0.42vh;
/* 8px转换为vh */
gap: 0.63vw;
/* 12px转换为vw */
}
.text_16 {
font-size: 18px;
/* 18px转换为vw */
color: #000000;
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: 600;
flex: 1;
}
.thumbnail_5 {
width: 0.83vw;
/* 16px转换为vw */
height: 0.83vw;
}
.text_17 {
font-size: 0.73vw;
/* 14px转换为vw */
color: #999999;
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
}
/* 讲师信息 */
.text_18 {
font-size: 14px;
/* 14px转换为vw */
color: #999;
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
margin-bottom: 0.42vh;
/* 8px转换为vh */
}
/* 课程描述 */
.text_19 {
font-size: 14px;
/* 14px转换为vw */
color: #999;
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
line-height: 1.5;
margin-top: 5px;
margin-bottom: 22px;
/* 16px转换为vh */
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* 课程统计信息 */
.group_7 {
align-items: center;
gap: 5px;
/* 20px转换为vw */
}
.thumbnail_6,
.thumbnail_7 {
width: 14px;
height: 14px;
}
.thumbnail_8 {
width: 18px;
height: 18px;
}
.text_20,
.text_21,
.text_22 {
font-size: 14px;
/* 14px转换为vw */
color: #999;
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
margin-right: 10px;
}
/* 操作按钮 */
.text-wrapper_2 {
background: #0288D1;
border-radius: 5px;
/* 6px转换为vw */
padding: 6px 22px;
/* 8px 16px转换 */
cursor: pointer;
transition: background-color 0.3s ease;
margin-left: auto;
}
.text-wrapper_2:hover {
background: rgba(2, 134, 206, 0.8);
}
.text_23 {
font-size: 14px;
/* 14px转换为vw */
color: white;
font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
}
/* 分页器样式 */
.pagination-wrapper {
width: 100%;
display: flex;
justify-content: center;
margin-top: 4.17vh;
/* 80px转换为vh增加上方间距 */
padding: 1.04vh 0;
/* 20px转换为vh */
}
.pagination {
display: flex;
align-items: center;
gap: 0.52vw;
/* 10px转换为vw */
}
.pagination-item {
min-width: 38px;
height: 38px;
background: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.73vw;
/* 14px转换为vw */
color: #666666;
font-family: 'Microsoft YaHei', Arial, sans-serif;
cursor: pointer;
border-radius: 0.21vw;
/* 4px转换为vw */
transition: all 0.3s ease;
padding: 0.52vh 0.83vw;
/* 10px 16px转换 */
border: 0.05vw solid rgba(232, 232, 232, 1);
}
.pagination-item:hover {
color: rgba(2, 134, 206, 1);
border-color: rgba(2, 134, 206, 1);
}
.pagination-item.active {
background: #0088D1;
color: rgba(255, 255, 255, 1);
border-color: #0088D1;
}
.pagination-item.disabled {
color: rgba(204, 204, 204, 1);
cursor: not-allowed;
border-color: rgba(232, 232, 232, 1);
}
.pagination-item.disabled:hover {
color: rgba(204, 204, 204, 1);
border-color: rgba(232, 232, 232, 1);
background: rgba(248, 248, 248, 1);
}
.nav-button {
min-width: 3.65vw;
border: none;
}
.page-number {
min-width: 2.08vw;
/* 40px转换为vw页码按钮保持原宽度 */
}
/* 作业部分样式 - 严格按照蓝湖UI */
.homework-content {
width: 100%;
}
/* 作业卡片主容器 */
.group_11 {
padding-top: 15px;
position: relative;
width: 100%;
/* 1033px转换为vw */
min-height: 25vh;
/* 设置最小高度 */
height: auto;
/* 改为自适应高度 */
/* background: url('https://lanhu-oss-2537-2.lanhuapp.com/SketchPng75139e59843c2accc2ef713eac90adeeea2be065395a76d5e5e3d7365677e090') -0.05vw -0.05vh no-repeat; */
background-size: 100% auto;
/* 背景图宽度100%,高度自适应 */
background-color: #fff;
/* 添加背景色,避免内容超出背景图范围时显示问题 */
margin: 0.2vh 0 3vh 0;
/* 减少底部间距,避免卡片挤在一起 */
/* padding-top: 3vh;
padding-bottom: 3vh; */
/* 增加内边距确保内容不会溢出 */
display: flex;
flex-direction: column;
border: 2px solid #ECECEC;
}
/* 头部信息容器 */
.box_5 {
/* width: 51.46vw; */
/* 988px转换为vw */
height: 2.81vh;
/* 54px转换为vh */
margin: 1.15vh 0 0 1.2vw;
/* 22px 0 0 23px转换 */
display: flex;
justify-content: space-between;
align-items: center;
}
/* 教师信息 */
.image-text_2 {
width: 8.07vw;
/* 155px转换为vw */
height: 2.81vh;
/* 54px转换为vh */
display: flex;
align-items: center;
margin-top: 3.3vh;
/* 25px转换为vh (25/1920*100) */
position: relative;
gap: 8px;
}
.avatar-line {
position: absolute;
left: -4px;
top: 53%;
transform: translateY(-50%);
width: 57px;
height: 56px;
border-radius: 50%;
border: 2px solid #0288D1;
}
/* 教师头像 */
.image_22 {
width: 2.71vw;
/* 52px转换为vw */
height: 2.71vw;
/* 改为vw单位保持正圆形 */
border-radius: 50%;
object-fit: cover;
margin-top: 2vh;
/* 头像向下移动 */
}
.image-avatar {
width: 2.71vw;
/* 52px转换为vw */
height: 2.71vw;
border: 2px solid #000;
background-color: pink;
}
/* 教师详细信息容器 */
.text-group_3 {
width: 4.43vw;
/* 85px转换为vw */
height: auto;
/* 改为自适应高度 */
display: flex;
flex-direction: column;
justify-content: space-between;
/* 增加垂直间距 */
margin-left: 0.52vw;
/* 10px转换为vw头像和姓名之间的间距 */
margin-top: -2vh;
/* 25px转换为vh (25/1920*100) */
}
/* 教师姓名 */
.text_30 {
width: 2.81vw;
/* 54px转换为vw */
height: 1.3vh;
/* 25px转换为vh */
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1);
font-size: 0.94vw;
/* 18px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 1.3vh;
/* 恢复原来的行高 */
margin-top: 0.5vh;
/* 调整姓名位置 */
}
/* 作业时间 */
.text_31 {
width: 4.43vw;
/* 85px转换为vw */
height: 1.04vh;
/* 20px转换为vh */
overflow-wrap: break-word;
color: #999999;
font-size: 14px;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 1.04vh;
/* 20px转换为vh */
margin-top: 1.2vh;
margin-top: 15px;
/* 调整时间与姓名的间距 */
}
/* 作业状态 */
.text_32 {
width: auto;
/* 42px转换为vw */
height: 1.04vh;
/* 20px转换为vh */
overflow-wrap: break-word;
color: rgba(153, 153, 153, 1);
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 1.04vh;
/* 20px转换为vh */
margin-top: 0.47vh;
margin-right: 25px;
/* 9px转换为vh */
display: flex;
align-items: center;
}
.text_32 img {
margin-right: 7px;
width: 16px;
height: 16px;
}
/* 作业内容区域 */
.text-group_4 {
/* width: 48.02vw; */
/* 922px转换为vw */
height: auto;
/* 改为自适应高度 */
margin: 4vh 1vw 0 5vw;
/* 减少顶部margin让内容更紧凑 */
flex-grow: 1;
/* 允许内容区域伸展 */
}
/* 作业标题 */
.text_33 {
width: 16.67vw;
/* 320px转换为vw */
min-height: 1.46vh;
/* 最小高度,允许内容增长 */
height: auto;
/* 自适应高度 */
overflow-wrap: break-word;
color: rgba(0, 0, 0, 1);
font-size: 1.04vw;
/* 20px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: normal;
/* 允许文本换行 */
line-height: 1.8vh;
/* 增加行高,提高可读性 */
padding-top: 10px;
padding-bottom: 5px;
margin-bottom: 1vh;
/* 添加底部间距 */
display: block;
/* 确保是块级元素 */
}
/* 作业描述容器 */
.description-container {
/* width: 48.02vw; */
/* 922px转换为vw */
position: relative;
}
/* 作业描述 */
.text_34 {
width: 100%;
min-height: 1.15vh;
/* 最小高度 */
height: auto;
/* 自适应高度 */
overflow-wrap: break-word;
color: rgba(102, 102, 102, 1);
font-size: 0.83vw;
/* 16px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: normal;
/* 允许文本换行 */
line-height: 1.8vh;
/* 增加行高,提高可读性 */
display: block;
/* 确保是块级元素 */
margin-top: 0;
/* 移除顶部间距,因为已经在标题添加了底部间距 */
transition: all 0.3s ease;
/* 添加过渡动画 */
}
/* 文本截断样式 */
.text_34.text-truncated {
/* display: -webkit-box; */
-webkit-line-clamp: 1;
line-height: 1.4;
/* 限制显示1行 */
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
/* 展开/收起按钮 */
.expand-toggle {
color: #1890ff;
cursor: pointer;
font-size: 0.73vw;
/* 14px转换为vw */
margin-left: 0.5vw;
user-select: none;
transition: color 0.3s ease;
}
.expand-toggle:hover {
color: #40a9ff;
text-decoration: underline;
}
/* 作业详情弹窗样式 */
.assignment-detail {
padding: 20px 0;
}
.detail-header {
/* padding-bottom: 20px; */
}
.detail-header h2 {
margin: 0 0 15px 0;
color: #333;
font-size: 24px;
font-weight: 600;
}
.assignment-meta {
display: flex;
flex-direction: column;
gap: 10px;
}
.teacher-info {
display: flex;
align-items: center;
gap: 10px;
}
.teacher-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
}
.teacher-name {
font-weight: 500;
color: #333;
}
.assignment-time {
color: #666;
font-size: 14px;
}
.assignment-status {
font-size: 14px;
font-weight: 500;
}
.assignment-status.未完成,
.assignment-status.待提交 {
color: #ff4d4f;
}
.assignment-status.已完成,
.assignment-status.已完成 {
color: #52c41a;
}
.detail-content h3 {
margin: 20px 0 10px 0;
color: #333;
font-size: 18px;
font-weight: 600;
}
.description-full {
background: #f8f9fa;
padding: 15px;
border-radius: 6px;
line-height: 1.6;
color: #333;
white-space: pre-wrap;
word-wrap: break-word;
}
.attachments-section {
margin-top: 20px;
}
.attachment-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.attachment-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: #f8f9fa;
border-radius: 6px;
border: 1px solid #e9ecef;
}
.attachment-icon {
width: 24px;
height: 24px;
object-fit: cover;
}
.attachment-name {
color: #333;
font-size: 14px;
}
/* 附件区域 */
.box_6 {
/* width: 48.65vw; */
/* 934px转换为vw */
height: auto;
/* 改为自适应高度 */
margin: 0.94vh 0 0 5vw;
/* 18px 0 0 67px转换 */
position: relative;
display: flex;
flex-direction: column;
}
/* 附件小图标 */
.thumbnail_6 {
width: 0.83vw;
/* 16px转换为vw */
height: 0.83vw;
/* 保持宽高比一致 */
}
/* 附件大图标 */
.image_23 {
width: 0.83vw;
/* 16px转换为vw */
height: 2.03vh;
/* 39px转换为vh */
margin: 6.51vh 0 0 0.94vw;
/* 125px 0 0 18px转换 */
}
/* 附件数量文本 */
.text_35 {
width: 4.27vw;
/* 82px转换为vw */
height: 1.04vh;
/* 20px转换为vh */
overflow-wrap: break-word;
color: rgba(153, 153, 153, 1);
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 1.04vh;
/* 20px转换为vh */
margin: 7.76vh 0 0 0.31vw;
/* 149px 0 0 6px转换 */
position: absolute;
}
/* 附件头部区域 */
.attachment-header {
position: relative;
height: 3vh;
margin-bottom: 1vh;
}
/* 附件图片容器 */
.attachment-images {
display: flex;
gap: 0.7vw;
align-items: center;
margin-top: 1vh;
/* margin-left: 2.5vh; */
}
.attachment-number-container {
justify-content: left;
gap: 0;
align-items: center;
}
.attachment-number-icon {
width: 14px;
height: 12px;
}
.attachment-number-text {
margin-left: 5px;
font-size: 14px;
color: #999;
}
/* 附件图片样式 - 使用flex布局避免重叠 */
.image_24,
.image_25,
.image_26,
.image_27,
.image_28 {
width: 6.5vw;
/* 缩小图片尺寸 */
height: 6.5vw;
/* 保持正方形 */
object-fit: cover;
border: 0.05vw solid #e9ecef;
}
/* 作业按钮区域 */
.assignment-buttons {
display: flex;
gap: 1vw;
margin: 2vh 0 2vh 4.95vw;
}
/* 提交按钮容器 */
.text-wrapper_8 {
height: 1.72vh;
/* 33px转换为vh */
width: 5.31vw;
/* 102px转换为vw */
position: relative;
/* 改为相对定位 */
cursor: pointer;
align-self: flex-start;
/* 按钮靠左对齐 */
border-radius: 0.2vw;
display: flex;
align-items: center;
justify-content: center;
background-color: #0288D1;
color: #fff;
}
/* 上传作业按钮 - 未完成状态 */
.submit-button {
width: 102px;
height: 33px;
border: 1px solid #0288D1;
}
.anew-button {
width: 102px;
height: 33px;
background-color: #fff;
color: #0288D1 !important;
border: 1px solid #0288D1;
font-size: 14px;
}
/* 查看情况按钮 - 未完成状态 */
.view-button {
width: 102px;
height: 33px;
background-color: white;
border: 1px solid #0288D1;
color: #0288D1;
font-size: 14px;
}
/* 查看详情按钮 - 已完成状态 */
.details-button {
width: 102px;
height: 33px;
background-color: #0288D1;
color: white !important;
}
/* 提交按钮文字 */
.text_36 {
width: auto;
/* 自适应宽度 */
height: 1.04vh;
/* 20px转换为vh */
overflow-wrap: break-word;
color: #fff;
font-size: 14px;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
text-align: center;
white-space: nowrap;
line-height: 1.04vh;
margin: 0;
}
.text-view {
color: #0288D1;
}
/* 主图样式 */
.image_29 {
position: absolute;
left: 4.95vw;
/* 95px转换为vw */
top: 12vh;
/* 调整位置,避免与附件重叠 */
width: 6.98vw;
/* 134px转换为vw */
height: 6.98vh;
/* 134px转换为vh */
object-fit: cover;
border-radius: 0.3vw;
border: 0.05vw solid #e9ecef;
}
/* 蓝湖UI作业样式完成 */
/* 考试页面样式 - 网格布局 */
.exam-content {
width: 100%;
}
.exam-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin-top: 20px;
}
.exam-card {
background: #ffffff;
border: 1.5px solid #D8D8D8;
padding: 20px;
position: relative;
min-height: 280px;
display: flex;
flex-direction: column;
transition: all 0.3s ease;
}
.exam-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
.exam-title {
font-size: 16px;
color: #333;
margin-bottom: 10px;
line-height: 1.4;
border-bottom: 1.5px solid #E6E6E6;
padding-bottom: 10px;
}
.exam-score-badge {
position: absolute;
top: 11px;
right: 18px;
background: white;
border: 1px solid #FF6F0F;
border-radius: 4px;
padding: 0 11px;
}
.score-text {
font-size: 20px;
font-weight: bold;
color: #FF6F0F;
}
.score-text span {
margin-left: 2px;
font-size: 10px;
}
.exam-details {
margin-bottom: 5px;
}
.exam-meta-item {
display: flex;
margin-bottom: 8px;
font-size: 14px;
}
.meta-label {
color: #999;
min-width: 70px;
}
.meta-value {
color: #999;
font-weight: 500;
}
.exam-description {
padding: 8px 10px;
font-size: 12px;
color: #497087;
margin-bottom: auto;
flex: 1;
overflow: hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
background-color: #F5F8FB;
}
.exam-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto;
padding-top: 16px;
flex-shrink: 0;
}
.exam-status-left {
display: flex;
align-items: center;
}
.exam-status-text {
font-size: 12px;
color: #999;
}
.exam-action-right {
display: flex;
gap: 10px;
}
.action-btn {
padding: 6px 16px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
border: none;
transition: all 0.3s ease;
min-width: 80px;
}
.upcoming-btn {
background: #F5F8FB;
color: #999999;
border: none;
}
.upcoming-btn:hover {
background: #e8e8e8;
}
.ongoing-btn {
background: #0288D1;
color: white;
}
.ongoing-btn:hover {
background: #40a9ff;
}
.finished-btn {
background: #0288D1;
color: white;
}
.finished-btn:hover {
background: #01579B;
}
.files-container {
margin: 15px 20px 0 83px;
/* width: 100%; */
background-color: #F5F9FC;
height: 48px;
display: flex;
align-items: center;
}
.file-items {
display: flex;
align-items: center;
padding: 10px;
cursor: pointer;
gap: 4px;
}
.file-items span {
font-size: 12px;
}
.files-icon {
width: 15px;
height: 15px;
}
.course-name {
margin-left: 0px;
color: #497087;
}
.course-name span {
color: #6AA5CC;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.exam-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.exam-grid {
grid-template-columns: 1fr;
gap: 16px;
}
.exam-card {
padding: 16px;
min-height: 240px;
}
/* 考试标题在小屏幕上给分数留出空间并允许换行 */
.exam-title {
padding-right: 80px; /* 给分数徽章留出空间 */
word-wrap: break-word;
word-break: break-word;
white-space: normal;
}
/* 分数徽章保持在右上角不换行 */
.exam-score-badge {
position: absolute;
top: 16px;
right: 16px;
white-space: nowrap;
}
}
/* 更小屏幕的适配 */
@media (max-width: 480px) {
.exam-card {
padding: 12px;
min-height: 220px;
}
.exam-title {
padding-right: 70px; /* 给分数徽章留出更多空间 */
font-size: 14px;
}
.exam-score-badge {
top: 12px;
right: 12px;
}
.score-text {
font-size: 16px;
}
}
/* 简化的作业卡片样式 */
.assignment-card-simple {
width: 100%;
margin-bottom: 2vh;
}
/* 其他内容样式 */
.other-content {
width: 100%;
padding: 2.08vh 2.08vw;
/* 40px转换 */
text-align: center;
}
.other-content h2 {
font-size: 1.25vw;
/* 24px转换为vw */
color: rgba(51, 51, 51, 1);
margin-bottom: 1.04vh;
/* 20px转换为vh */
}
.other-content p {
font-size: 0.83vw;
/* 16px转换为vw */
color: rgba(153, 153, 153, 1);
}
/* 作业分隔线 */
.assignment-divider {
width: 100%;
height: 1px;
background-color: #E5E5E5;
margin: 0.89vh 0;
/* 17px转换为vh */
}
/* 响应式设计 */
@media (max-width: 1440px) {
.profile-page {
max-width: 100vw;
}
.profile-content {
max-width: 100vw;
}
}
@media (max-width: 1024px) {
.profile-content {
flex-direction: column;
}
.block_14 {
width: 100%;
min-height: auto;
order: 2;
border-right: none;
border-top: 0.05vw solid rgba(232, 232, 232, 1);
}
.group_5 {
width: 100%;
order: 1;
min-height: auto;
margin-left: 0;
/* 移动端取消左边距 */
}
.box_2 {
flex-direction: column;
}
.block_4 {
width: 100%;
margin-right: 0;
margin-bottom: 0.83vh;
/* 16px转换为vh */
}
.box_3 {
width: 100%;
height: 18vh;
/* 平板端大幅增加高度,让图片展示到外部盒子高度 */
}
/* 调整用户信息区域为横向布局 */
.image_7 {
margin: 1.04vh 0 0 1.04vw;
/* 20px转换 */
width: 4.17vw !important;
/* 80px转换为vw覆盖SafeAvatar样式 */
height: 4.17vw !important;
}
.text_72 {
margin: 1.04vh 0 0 1.04vw;
/* 20px转换 */
width: auto;
text-align: left;
}
.box_22 {
margin: 1.04vh 0;
/* 移动端保持居中 */
width: 90%;
/* 移动端调整宽度 */
height: auto;
padding: 1.04vh 0;
/* 移动端调整内边距 */
}
.image-text_19,
.image-text_20,
.image-text_21,
.image-text_22,
.image-text_23,
.image-text_24,
.image-text_25,
.image-text_26 {
width: 80%;
/* 移动端菜单项宽度 */
margin: 1.5vh 0;
/* 保持与桌面端一致的间距 */
padding: 1.2vh 2vw;
/* 保持与桌面端一致的内边距 */
min-height: 3vh;
/* 保持最小高度 */
}
.menu-divider {
width: 80%;
/* 移动端分割线宽度 */
margin: 1.5vh 0;
}
}
@media (max-width: 768px) {
.group_5 {
padding: 1.04vh 1.04vw;
/* 20px转换 */
}
.text-wrapper_1 {
justify-content: flex-start;
/* 改为左对齐 */
gap: 4vw;
/* 手机端调整间距 */
flex-wrap: wrap;
}
.text_12,
.text_13,
.text_14 {
font-size: 2.16px;
/* 手机端调整字体大小 */
padding: 10px 0;
/* 保持无左右内边距 */
}
.course-divider {
width: 100%;
/* 手机端也保持与课程卡片宽度一致 */
}
.pagination-wrapper {
margin-top: 6vh;
/* 手机端增加更多上方间距 */
}
.pagination {
gap: 2vw;
/* 手机端增加间距 */
}
.pagination-item {
min-width: 8vw;
/* 手机端增加按钮宽度 */
height: 4vh;
/* 手机端增加按钮高度 */
font-size: 2.5vw;
/* 手机端调整字体大小 */
padding: 1vh 2vw;
}
.nav-button {
min-width: 12vw;
/* 手机端导航按钮更宽 */
}
.page-number {
min-width: 8vw;
/* 手机端页码按钮宽度 */
}
/* 作业部分响应式 */
.assignment-card {
width: 90vw;
height: auto;
min-height: 30vh;
margin: 2vh 5vw;
background-size: 100% 100%;
}
.assignment-header {
width: 85vw;
height: auto;
margin: 2vh 2.5vw;
flex-direction: column;
align-items: flex-start;
gap: 1vh;
}
.teacher-info {
width: auto;
height: auto;
gap: 2vw;
}
.teacher-avatar {
width: 8vw;
height: 8vw;
}
.teacher-details {
width: auto;
height: auto;
}
.teacher-name {
font-size: 3vw;
width: auto;
height: auto;
}
.assignment-time {
font-size: 2.5vw;
width: auto;
height: auto;
margin-top: 0.5vh;
}
.assignment-status {
font-size: 2.5vw;
width: auto;
height: auto;
margin-top: 0;
}
.assignment-content {
width: 85vw;
height: auto;
margin: 2vh 2.5vw;
}
.assignment-title {
font-size: 3.5vw;
width: auto;
height: auto;
white-space: normal;
line-height: 1.4;
}
.assignment-description {
font-size: 2.8vw;
width: auto;
height: auto;
white-space: normal;
line-height: 1.4;
margin-top: 1vh;
}
.assignment-attachments {
width: 85vw;
height: auto;
margin: 2vh 2.5vw;
flex-direction: column;
align-items: flex-start;
gap: 2vh;
}
.attachment-list {
flex-wrap: wrap;
gap: 2vw;
}
.attachment-item {
width: 15vw;
height: 15vw;
}
.attachment-count {
font-size: 2.5vw;
width: auto;
height: auto;
margin-left: 0;
}
.attachment-actions {
width: auto;
height: auto;
gap: 2vw;
margin-bottom: 0;
}
.action-btn {
width: 20vw;
height: 6vh;
border-radius: 1vw;
}
.download-btn span,
.submit-btn span {
font-size: 2.5vw;
width: auto;
height: auto;
margin: 0;
}
.assignment-main-image {
position: relative;
left: 2.5vw;
top: 0;
width: 20vw;
height: 20vw;
margin-top: 2vh;
}
.other-content {
padding: 4vh 4vw;
}
.other-content h2 {
font-size: 4vw;
margin-bottom: 2vh;
}
.other-content p {
font-size: 3vw;
}
.group_7 {
flex-direction: column;
align-items: flex-start;
gap: 0.42vh;
/* 8px转换为vh */
}
.box_2 {
padding: 0.83vh 0.83vw;
/* 16px转换 */
}
.block_4 {
margin-bottom: 0.63vh;
/* 12px转换为vh */
}
.box_3 {
height: 20vh;
/* 手机端大幅增加高度,让图片展示到外部盒子高度 */
}
}
@media (max-width: 576px) {
.profile-page {
padding: 0;
}
.group_5 {
padding: 0.83vh 0.83vw;
/* 16px转换 */
}
.text-wrapper_1 {
gap: 0.83vw;
/* 16px转换为vw */
}
.text_12,
.text_13,
.text_14 {
font-size: 0.83vw;
/* 16px转换为vw */
padding: 0.31vh 0.63vw;
/* 6px 12px转换 */
}
/* 平板端面包屑样式 */
.breadcrumb-nav {
font-size: 1vw;
/* 平板端调整字体大小 */
}
.breadcrumb-item {
width: 5vw;
/* 平板端调整宽度 */
font-size: 1vw;
/* 平板端调整字体大小 */
line-height: 1.3vh;
/* 平板端调整行高 */
}
.breadcrumb-current {
width: 4.5vw;
/* 平板端调整宽度 */
font-size: 1vw;
/* 平板端调整字体大小 */
line-height: 1.3vh;
/* 平板端调整行高 */
}
.breadcrumb-separator {
margin: 0 0.8vw;
/* 平板端调整间距 */
}
.box_2 {
padding: 0.63vh 0.63vw;
/* 12px转换 */
}
.text_16 {
font-size: 0.83vw;
}
.text_19 {
font-size: 0.68vw;
/* 13px转换为vw */
}
.group_7 {
gap: 0.31vh;
/* 6px转换为vh */
}
.text_20,
.text_21,
.text_22 {
font-size: 0.63vw;
/* 12px转换为vw */
}
/* 手机端面包屑样式 */
.breadcrumb-nav {
font-size: 3.5vw;
/* 手机端调整字体大小 */
margin-bottom: 2vh;
/* 手机端增加底部间距 */
}
.breadcrumb-item {
width: 15vw;
/* 手机端调整宽度 */
font-size: 3.5vw;
/* 手机端调整字体大小 */
line-height: 2vh;
/* 手机端调整行高 */
}
.breadcrumb-current {
width: 13vw;
/* 手机端调整宽度 */
font-size: 3.5vw;
/* 手机端调整字体大小 */
line-height: 2vh;
/* 手机端调整行高 */
}
.breadcrumb-separator {
margin: 0 2vw;
/* 手机端调整间距 */
}
}
/* 上传作业弹窗样式 */
.assignment-info {
margin-bottom: 20px;
padding: 15px;
background-color: #f9f9f9;
border-radius: 8px;
}
.assignment-info h3 {
margin-top: 0;
margin-bottom: 10px;
font-size: 18px;
color: #333;
}
.assignment-info p {
margin: 0;
font-size: 14px;
color: #666;
line-height: 1.5;
}
.file-list {
margin-top: 10px;
max-height: 200px;
overflow-y: auto;
border: 1px solid #eee;
border-radius: 4px;
}
.file-item {
display: flex;
justify-content: space-between;
padding: 8px 12px;
border-bottom: 1px solid #eee;
}
.file-item:last-child {
border-bottom: none;
}
.modal-footer {
width: 100%;
display: flex;
justify-content: flex-start;
margin-top: -30px;
}
.modal-footer button {
width: 100px;
height: 42px;
background: #0088D1;
border: none;
color: white;
border-radius: 5px;
font-size: 16px;
}
.cancel {
background: #E2F5FF !important;
color: #0088D1 !important;
border: 1px solid #0088D1 !important;
}
/* 作业详情视图样式 */
.detail-header {
display: flex;
align-items: center;
/* margin-bottom: 15px; */
}
/* 面包屑导航样式 */
.breadcrumb-nav {
display: flex;
align-items: center;
font-size: 0.73vw;
/* 14px转换为vw */
color: #666;
margin-bottom: 1.04vh;
/* 20px转换为vh */
}
.breadcrumb-item {
width: 3.39vw;
/* 65px转换为vw */
height: 1.04vh;
/* 20px转换为vh */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #333333;
line-height: 1.04vh;
/* 20px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
cursor: pointer;
transition: color 0.3s ease;
}
.breadcrumb-item:hover {
color: #0056b3;
text-decoration: underline;
}
.breadcrumb-separator {
margin: 0 0.52vw;
/* 10px转换为vw */
color: #999;
}
.breadcrumb-current {
width: 2.97vw;
/* 57px转换为vw */
height: 1.04vh;
/* 20px转换为vh */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #999999;
line-height: 1.04vh;
/* 20px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
}
.description-full-view {
white-space: pre-wrap;
line-height: 1.6;
color: #666;
font-size: 14px;
}
/* 考试详情页面样式 */
.exam-detail-overlay {
position: fixed;
top: 60px;
/* 留出导航栏的空间 */
left: 0;
width: 100%;
height: calc(100% - 60px);
/* 减去导航栏的高度 */
background: #f5f5f5;
z-index: 999;
/* 降低z-index确保导航栏可见 */
overflow-y: auto;
}
.exam-detail-container {
margin: 0 auto;
background: #f5f5f5;
min-height: 100vh;
}
.exam-detail-header {
margin: auto;
width: 1420px;
padding: 24px 0;
background: #f5f5f5;
}
.breadcrumb {
font-size: 14px;
color: #666;
white-space: nowrap;
overflow: hidden;
display: flex;
align-items: center;
}
.breadcrumb-link {
height: 20px;
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 14px;
color: #333333;
line-height: 20px;
text-align: left;
font-style: normal;
text-transform: none;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
flex-shrink: 0;
}
.breadcrumb-link:hover {
text-decoration: underline;
}
.breadcrumb-separator {
margin: 0 8px;
color: #999999;
flex-shrink: 0;
}
.breadcrumb-current {
height: 20px;
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 14px;
color: #999999;
line-height: 20px;
text-align: left;
font-style: normal;
text-transform: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
.exam-detail-content {
margin: auto;
max-width: 1420px;
display: flex;
gap: 24px;
padding: 0;
background: #f5f5f5;
}
.exam-questions-section {
flex: 1;
background: white;
padding: 24px;
}
.exam-title-section {
margin-bottom: 24px;
padding-bottom: 16px;
border-bottom: 1px solid #e8e8e8;
}
.exam-main-title {
font-size: 20px;
font-weight: 600;
color: #333;
margin: 0;
}
.questions-container {
margin-bottom: 24px;
}
.question-item {
background: white;
padding: 20px;
margin-bottom: 20px;
}
.question-header {
display: flex;
align-items: center;
margin-bottom: 16px;
}
.question-number {
color: #0088D1;
font-size: 14px;
font-weight: 500;
margin-right: 12px;
}
.question-type {
color: #1890ff;
font-size: 14px;
font-weight: 500;
margin-right: 12px;
}
.question-score {
width: 36px;
height: 20px;
background: #EEF9FF;
color: #1890ff;
font-size: 12px;
font-weight: 500;
margin-left: auto;
display: flex;
align-items: center;
justify-content: center;
border-radius: 25%;
}
.question-content {
font-size: 16px;
color: #333;
line-height: 1.6;
margin-bottom: 20px;
}
.question-options {
margin-bottom: 20px;
}
.option-item {
display: flex;
align-items: center;
width: 1053px;
height: 50px;
background: #F5F8FB;
padding: 0 16px;
margin-bottom: 8px;
transition: all 0.3s ease;
}
.option-item.option-selected {
background: #F5F8FB !important;
}
.option-item.option-correct {
background: #f6ffed;
}
.option-item.option-wrong {
background: #fff2f0;
}
.option-checkbox {
margin-right: 12px;
flex-shrink: 0;
}
.option-checkbox input[type="checkbox"] {
width: 14px;
height: 14px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background: white;
border: 1px solid #d9d9d9;
cursor: pointer;
position: relative;
}
.option-checkbox input[type="checkbox"]:checked {
background: #1890ff;
border-color: #1890ff;
}
.option-checkbox input[type="checkbox"]:checked::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 10px;
font-weight: bold;
}
.option-content {
flex: 1;
display: flex;
align-items: center;
}
.option-text {
font-size: 14px;
color: #333;
line-height: 1.5;
}
.option-image {
margin-top: 8px;
}
.option-image img {
max-width: 200px;
height: auto;
border: 1px solid #e8e8e8;
border-radius: 4px;
}
.question-footer {
display: flex;
align-items: center;
gap: 16px;
padding-top: 16px;
border-top: 1px solid #f0f0f0;
}
.answer-status-box {
width: 100px;
height: 33px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, sans-serif;
font-size: 14px;
color: #FFFFFF;
line-height: 20px;
text-align: center;
font-style: normal;
text-transform: none;
}
.answer-status-box.status-correct {
background: #0288D1;
}
.answer-status-box.status-wrong {
background: #ff4d4f;
}
.question-stats {
display: flex;
gap: 16px;
flex: 1;
}
.correct-answer,
.user-answer {
font-size: 14px;
color: #666;
}
.question-result {
font-size: 20px;
font-weight: bold;
}
.result-correct {
color: #52c41a;
}
.result-wrong {
color: #ff4d4f;
}
.question-analysis {
margin-top: 16px;
padding: 16px;
background: #fafafa;
border-radius: 6px;
}
.analysis-title {
font-size: 14px;
font-weight: 500;
color: #333;
margin-bottom: 8px;
}
.analysis-content {
font-size: 14px;
color: #497087;
line-height: 1.6;
}
.exam-submit-section {
margin-top: 24px;
text-align: left;
margin-left: 16px;
}
.submit-btn {
background: #1890ff;
color: white;
border: none;
border-radius: 6px;
padding: 12px 24px;
font-size: 14px;
cursor: pointer;
display: inline-block;
transition: background-color 0.3s ease;
}
.submit-btn:hover {
background: #40a9ff;
}
.submit-text {
font-weight: 500;
}
.submit-stats {
font-size: 12px;
opacity: 0.8;
}
.submit-score {
font-weight: bold;
}
.exam-info-section {
width: 300px;
flex-shrink: 0;
display: flex;
flex-direction: column;
gap: 16px;
}
.score-circle-container {
background: white;
padding: 24px;
text-align: center;
}
.score-circle {
width: 120px;
height: 120px;
border-radius: 50%;
background: conic-gradient(#1890ff 0deg 352deg, #e8e8e8 352deg 360deg);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 12px;
position: relative;
}
.score-inner {
width: 90px;
height: 90px;
border-radius: 50%;
background: white;
display: flex;
align-items: center;
justify-content: center;
}
.score-number {
font-size: 32px;
font-weight: bold;
color: #333;
}
.score-label {
font-size: 14px;
color: #666;
}
.exam-stats {
background: white;
padding: 24px;
}
.stat-item {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
font-size: 14px;
}
.stat-item:last-child {
margin-bottom: 0;
}
.stat-label {
font-size: 10px;
color: #497087;
}
.stat-value {
margin-left: 20px;
color: #333;
font-weight: 500;
font-size: 18px;
}
.stat-value span {
margin-left: 2px;
font-size: 10px;
}
.stat-value.correct {
color: #3F76ED;
}
.stat-value.wrong {
color: #FE2E2F;
}
.answer-stats {
background: white;
padding: 24px;
}
.stats-row {
display: flex;
gap: 12px;
}
.stat-box {
flex: 1;
text-align: center;
padding: 16px 8px;
border-radius: 6px;
}
.stat-box.correct {
background: #f6ffed;
border: 1px solid #b7eb8f;
}
.stat-box.wrong {
background: #fff2f0;
border: 1px solid #ffb3b3;
}
.stat-box.total {
background: #e6f7ff;
border: 1px solid #91d5ff;
}
.stat-number {
font-size: 24px;
font-weight: bold;
margin-bottom: 4px;
}
.stat-box.correct .stat-number {
color: #52c41a;
}
.stat-box.wrong .stat-number {
color: #ff4d4f;
}
.stat-box.total .stat-number {
color: #1890ff;
}
.stat-text {
font-size: 12px;
color: #666;
}
.answer-card {
background: white;
padding: 24px;
}
.card-title {
font-size: 16px;
font-weight: 500;
color: #333;
margin-bottom: 16px;
}
.card-sections {
margin-bottom: 16px;
}
.card-section {
margin-bottom: 20px;
}
.card-section:last-child {
margin-bottom: 0;
}
.section-title {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.answer-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 8px;
}
.answer-item {
width: 32px;
height: 32px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
}
.answer-item.correct {
background: #1890ff;
color: white;
}
.answer-item.wrong {
background: #ff4d4f;
color: white;
}
.answer-item.unanswered {
background: #f5f5f5;
color: #999;
border: 1px solid #e8e8e8;
}
.answer-item:hover {
transform: scale(1.1);
}
.card-legend {
display: flex;
align-items: center;
gap: 16px;
padding-top: 16px;
border-top: 1px solid #f0f0f0;
}
.legend-item {
display: flex;
align-items: center;
gap: 6px;
}
.legend-color {
width: 12px;
height: 12px;
border-radius: 2px;
}
.legend-color.correct {
background: #1890ff;
}
.legend-color.wrong {
background: #ff4d4f;
}
.legend-text {
font-size: 12px;
color: #666;
}
.legend-checkbox {
margin-left: auto;
display: flex;
align-items: center;
gap: 6px;
}
.legend-checkbox input[type="checkbox"] {
width: 14px;
height: 14px;
}
.legend-checkbox label {
font-size: 12px;
color: #666;
cursor: pointer;
}
/* 响应式设计 */
@media (max-width: 1024px) {
.exam-detail-content {
flex-direction: column;
}
.exam-info-section {
width: 100%;
}
.stats-row {
justify-content: center;
}
.stat-box {
max-width: 120px;
}
}
@media (max-width: 768px) {
.exam-detail-content {
padding: 16px;
}
.question-item {
padding: 16px;
}
.answer-grid {
grid-template-columns: repeat(4, 1fr);
}
.score-circle {
width: 100px;
height: 100px;
}
.score-inner {
width: 75px;
height: 75px;
}
.score-number {
font-size: 24px;
}
}
/* 练习页面样式 - 网格布局 */
.practice-content {
width: 100%;
}
.exam-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin-top: 20px;
}
.practice-card {
background: #ffffff;
border: 1px solid #e8e8e8;
border-radius: 8px;
padding: 20px;
position: relative;
min-height: 280px;
display: flex;
flex-direction: column;
transition: all 0.3s ease;
}
.practice-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
.practice-title {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 16px;
line-height: 1.4;
}
.practice-score-badge {
position: absolute;
top: 11px;
right: 18px;
background: white;
border: 1px solid #FF6F0F;
border-radius: 4px;
padding: 0 11px;
}
.practice-details {
margin-bottom: 10px;
}
.practice-meta-item {
display: flex;
margin-bottom: 8px;
font-size: 14px;
}
.practice-description {
font-size: 13px;
color: #666;
line-height: 1.5;
margin-bottom: 16px;
flex: 1;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.practice-stats {
display: flex;
gap: 16px;
height: 54px;
background: #F5F8FB;
align-items: center;
justify-content: space-evenly;
}
.divider {
width: 1px;
height: 20px;
background: #EBEBEB;
}
.stats-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.stats-item.correct .stats-number {
color: #1890ff;
}
.stats-item.wrong .stats-number {
color: #ff4d4f;
}
.stats-label {
font-size: 12px;
color: #666;
margin-bottom: 4px;
}
.stats-number {
font-size: 14px;
font-weight: 600;
}
.practice-intro {
padding: 12px;
background: #f8f9fa;
border-radius: 6px;
margin-bottom: 16px;
}
.intro-title {
font-size: 14px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
}
.intro-content {
padding-bottom: 10px;
font-size: 14px;
color: #666;
line-height: 1.5;
border-bottom: 1.5px solid #E6E6E6;
}
.practice-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto;
padding-top: 16px;
border-top: 1px solid #f0f0f0;
flex-shrink: 0;
}
.practice-status-left {
display: flex;
align-items: center;
}
.practice-status-text {
font-size: 14px;
color: #666;
}
.practice-action-right {
display: flex;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.practice-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.practice-grid {
grid-template-columns: 1fr;
gap: 16px;
}
.practice-card {
padding: 16px;
min-height: 240px;
}
}
/* 活动页面样式 - 网格布局 */
.activity-content {
width: 100%;
}
.activity-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1.04vw;
/* 20px转换为vw */
margin-top: 1.04vh;
/* 20px转换为vh */
}
.activity-card {
background: #ffffff;
border: 1px solid #e8e8e8;
/* 8px转换为vw */
padding: 0;
/* 移除内边距,让图片可以占满顶部 */
position: relative;
min-height: 14.58vh;
/* 280px转换为vh */
display: flex;
flex-direction: column;
transition: all 0.3s ease;
overflow: hidden;
/* 确保图片不会溢出圆角 */
}
.activity-card:hover {
box-shadow: 0 0.21vw 0.63vw rgba(0, 0, 0, 0.1);
/* 0 4px 12px转换 */
transform: translateY(-0.1vh);
/* -2px转换为vh */
}
/* 活动卡片顶部图片容器 */
.activity-card-image {
width: 100%;
height: 179px;
/* 179px转换为vh (179/1080*100) */
overflow: hidden;
/* 只有顶部圆角 */
}
/* 活动卡片图片 */
.activity-image {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.activity-score-badge {
position: absolute;
top: 0.83vw;
/* 16px转换为vw */
right: 0.83vw;
/* 16px转换为vw */
background: #FF6B35;
color: white;
padding: 0.21vw 0.42vw;
/* 4px 8px转换为vw */
border-radius: 0.21vw;
/* 4px转换为vw */
font-size: 0.63vw;
/* 12px转换为vw */
font-weight: 500;
z-index: 1;
}
.activity-title {
font-size: 16px;
/* 16px转换为vw */
/* font-weight: 600; */
color: #333;
margin: 15px 0 5px 0;
/* 0 0 16px 0转换 */
line-height: 1.4;
padding: 0 1.04vw;
/* 添加左右内边距 */
font-weight: 600;
}
.activity-details {
/* 20px转换为vh */
padding: 0 1.04vw;
/* 添加左右内边距 */
}
.activity-meta-item {
margin-bottom: 10px;
/* 8px转换为vh */
font-size: 14px;
/* 13px转换为vw */
line-height: 1.4;
}
.activity-intro {
flex: 1;
margin-bottom: 1.04vh;
/* 20px转换为vh */
padding: 0 1.04vw;
/* 添加左右内边距 */
}
.intro-title {
font-size: 0.73vw;
/* 14px转换为vw */
font-weight: 600;
color: #333;
margin-bottom: 0.42vh;
/* 8px转换为vh */
}
.intro-content {
font-size: 14px;
/* 13px转换为vw */
color: #666;
line-height: 1.5;
margin-bottom: 10px;
/* 16px转换为vh */
/* display: -webkit-box; */
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.activity-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto;
padding: 5px 15px 15px 15px;
/* 添加内边距 */
}
.activity-status-left {
/* flex: 1; */
}
.activity-status-text {
font-size: 12px;
/* 13px转换为vw */
font-weight: 500;
}
/* 活动状态颜色 - 与练习中保持一致 */
.activity-status-text.ongoing {
color: #FF520F;
/* 进行中 - 橙色 */
}
.activity-status-text.finished {
color: #999999;
/* 已结束 - 灰色 */
}
.activity-action-right {
display: flex;
}
/* 活动已结束按钮样式 - 灰色 */
.activity-finished-btn {
background-color: #999999 !important;
border-color: #999999 !important;
color: #ffffff !important;
}
.activity-finished-btn:hover {
background-color: #808080 !important;
border-color: #808080 !important;
}
/* 活动响应式设计 */
@media (max-width: 1200px) {
.activity-grid {
grid-template-columns: repeat(2, 1fr);
}
.activity-score-badge {
font-size: 1vw;
padding: 0.3vw 0.6vw;
}
.activity-title {
font-size: 1.2vw;
}
.activity-meta-item {
font-size: 1vw;
}
.intro-title {
font-size: 1.1vw;
}
.intro-content {
font-size: 1vw;
}
.activity-status-text {
font-size: 1vw;
}
}
@media (max-width: 768px) {
.activity-grid {
grid-template-columns: 1fr;
gap: 2vw;
}
.activity-card {
padding: 0;
/* 保持无内边距,让图片占满顶部 */
min-height: 30vh;
}
/* 手机端活动卡片图片 */
.activity-card-image {
height: 12vh;
/* 手机端增加图片高度 */
}
/* 手机端活动内容区域添加内边距 */
.activity-title,
.activity-details,
.activity-intro {
padding-left: 3vw;
padding-right: 3vw;
}
.activity-footer {
padding: 0 3vw 3vw;
}
.activity-score-badge {
font-size: 2.5vw;
padding: 1vw 2vw;
top: 2vw;
right: 2vw;
}
.activity-title {
font-size: 3.5vw;
margin-bottom: 2vh;
}
.activity-meta-item {
font-size: 2.8vw;
margin-bottom: 1vh;
}
.intro-title {
font-size: 3vw;
margin-bottom: 1vh;
}
.intro-content {
font-size: 2.8vw;
margin-bottom: 2vh;
}
.activity-status-text {
font-size: 2.8vw;
}
}
/* 消息页面样式 */
.message-content {
width: 100%;
}
.message-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
/* 20px转换为vh */
padding: 10px 0;
border-bottom: 1.5px solid #e6e6e6;
}
.message-tabs {
display: flex;
gap: 2.08vw;
/* 40px转换为vw */
}
.message-tab-item {
font-size: 0.94vw;
/* 18px转换为vw */
color: #666;
cursor: pointer;
padding: 0.52vh 0;
/* 10px转换为vh */
position: relative;
display: flex;
align-items: center;
gap: 0.52vw;
/* 10px转换为vw */
}
.message-tab-item.active {
color: #1890ff;
font-weight: 500;
}
/* 移除蓝色下划线
.message-tab-item.active::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 0.1vh;
background-color: #1890ff;
}
*/
.message-count {
position: absolute;
top: 0;
right: -30%;
background: #ff4d4f;
color: white;
font-size: 0.63vw;
/* 12px转换为vw */
width: 12px;
height: 12px;
line-height: 12px;
/* 2px 6px转换 */
border-radius: 50%;
/* 10px转换为vw */
/* 20px转换为vw */
text-align: center;
line-height: 1;
}
.message-actions {
display: flex;
gap: 1.04vw;
align-items: center;
/* 20px转换为vw */
}
.action-link {
/* width: 2.92vw; */
/* 56px转换为vw */
/* height: 1.04vh; */
/* 20px转换为vh */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #000000;
line-height: 1.04vh;
/* 20px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
cursor: pointer;
text-decoration: none;
display: inline-flex;
align-items: center;
/* 使用flexbox确保垂直居中 */
}
.action-link:hover {
color: #000000;
/* 悬停时保持黑色 */
text-decoration: none;
/* 移除下划线 */
}
/* 操作图标样式 */
.action-icon {
width: 0.94vw;
/* 18px转换为vw */
height: 0.94vw;
/* 18px转换为vw */
margin-right: 0.26vw;
/* 5px转换为vw */
vertical-align: middle;
display: inline-block;
position: relative;
top: -0.05vw;
/* 微调垂直位置 */
}
.message-list {
display: flex;
flex-direction: column;
gap: 1.04vh;
/* 20px转换为vh消息项之间的间距 */
}
.message-item {
position: relative;
background: white;
border: 1px solid #D8D8D8;
/* 8px转换为vw */
transition: border-color 0.3s ease;
}
.message-item:hover {
border-color: #1890ff;
}
/* 右上角未读标识 */
.unread-indicator-top-right {
position: absolute;
top: 0.52vh;
/* 10px转换为vh */
right: 0.52vw;
/* 10px转换为vw */
width: 0.42vw;
/* 8px转换为vw */
height: 0.42vw;
/* 8px转换为vw */
background: #ff4d4f;
border-radius: 50%;
}
.message-main {
padding: 1.04vh 1.04vw;
/* 20px转换 */
/* margin-left: 1.04vw; */
/* 为未读标识留出空间 */
}
.message-user {
display: flex;
align-items: flex-start;
gap: 0.73vw;
/* 14px转换为vw */
margin-bottom: 0.73vh;
/* 14px转换为vh */
width: 100%;
/* 确保占满宽度 */
position: relative;
}
/* 消息头像样式 */
.image_22 {
width: 49px;
/* 42px转换为vw */
height: 49px;
/* 42px转换为vw */
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
margin-top: 0.1vh;
/* 2px转换为vh微调位置 */
}
.user-info {
flex: 1;
min-width: 0;
overflow: hidden;
/* 确保内容不会溢出 */
}
.user-content {
margin-bottom: 0.31vh;
/* 6px转换为vh */
overflow: hidden;
/* 隐藏溢出内容 */
}
.user-name {
font-size: 0.83vw;
/* 16px转换为vw */
font-weight: 500;
color: #1890ff;
}
.message-text {
width: auto;
/* 自适应宽度 */
height: auto;
/* 自适应高度 */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #0388D1;
line-height: 1.04vh;
/* 20px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
display: inline;
/* 改为inline让文字在一行显示 */
white-space: nowrap;
/* 不换行 */
overflow: hidden;
/* 隐藏溢出 */
text-overflow: ellipsis;
/* 超出显示省略号 */
max-width: 100%;
/* 最大宽度为容器宽度 */
}
/* 课程信息容器 */
.course-info-container {
width: 100%;
/* 942px转换为vw */
/* height: 5.21vh; */
padding: 0.52vh 0.57vw;
/* 100px转换为vh进一步增加高度 */
background: #F5F8FB;
background-size: 100% 100%;
margin-top: 0.26vh;
/* 5px转换为vh */
position: relative;
display: flex;
align-items: center;
/* 垂直居中 */
justify-content: flex-start;
/* 水平左对齐 */
padding: 1.04vh 0.57vw;
/* 20px 11px转换为vh/vw增加上下内边距 */
}
.course-label {
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: #999999;
line-height: 1.04vh;
/* 20px转换为vh */
}
.course-name {
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
/* color: #497087; */
line-height: 1.04vh;
/* 20px转换为vh */
}
.message-time {
position: absolute;
right: 0;
top: 0.57vw;
/* 90px转换为vw */
height: 1.04vh;
/* 20px转换为vh */
font-size: 0.63vw;
/* 12px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: rgba(153, 153, 153, 1);
text-align: left;
white-space: nowrap;
line-height: 1.04vh;
/* 20px转换为vh */
margin-left: auto;
flex-shrink: 0;
align-self: flex-start;
margin-top: 0.05vh;
/* 1px转换为vh微调位置 */
/* 30px转换为vh让时间下移 */
}
.message-actions-row {
display: flex;
align-items: center;
justify-content: flex-start;
margin-top: 1.56vh;
/* 30px转换为vh增加距离上方的距离 */
margin-bottom: 1.09vh;
/* 21px转换为vh */
margin-left: 0.36vw;
/* 7px转换为vw */
position: relative;
width: 100%;
}
.message-action-btn {
display: flex;
align-items: center;
justify-content: center;
/* 确保内容水平居中 */
gap: 0;
/* 移除图标和文字间距,让它们紧贴 */
padding: 0;
border: none;
background: none;
width: auto;
/* 自适应宽度 */
height: 1.04vh;
/* 20px转换为vh */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #999999;
line-height: 1.04vh;
/* 20px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
/* 防止文字换行 */
}
/* 回复按钮位置 */
.reply-btn {
margin-left: 2.92vw;
/* 56px转换为vw */
}
/* 删除按钮位置 */
.delete-btn {
margin-left: 0.78vw;
/* 15px转换为vw减小与回复按钮的间距 */
}
/* 举报按钮位置 - 在最右边 */
.report-btn {
position: absolute;
right: 7px;
}
/* 消息操作按钮中的图标样式 */
.message-action-btn .action-icon {
width: 0.73vw;
/* 14px转换为vw */
height: 0.73vw;
/* 14px转换为vw */
margin-right: 0.26vw;
/* 5px转换为vw */
vertical-align: middle;
display: inline-block;
position: relative;
top: -0.03vw;
/* 微调垂直位置 */
}
/* 点赞消息样式 */
.like-message-item {
position: relative;
background: white;
border: 1px solid #D8D8D8;
transition: border-color 0.3s ease;
}
.like-message-item:hover {
border-color: #1890ff;
}
.like-message-main {
padding: 1.04vh 1.04vw;
}
.like-message-user {
display: flex;
align-items: flex-start;
gap: 0.73vw;
margin-bottom: 0.73vh;
}
.like-info {
flex: 1;
min-width: 0;
}
.like-content {
display: flex;
align-items: center;
gap: 0.26vw;
margin-bottom: 0.52vh;
}
.like-content-preview {
margin-top: 0.52vh;
padding: 0.52vh 0.73vw;
background-color: #f5f5f5;
border-radius: 4px;
border-left: 3px solid #1890ff;
}
.content-preview {
font-size: 0.73vw;
color: #666;
font-style: italic;
}
/* 系统消息样式 */
.system-message-item {
position: relative;
background: white;
border: 1.5px solid #D8D8D8;
border-radius: 0;
transition: border-color 0.3s ease;
height: auto;
min-height: 90px;
/* 132px转换为vh */
margin-bottom: 1.04vh;
display: flex;
align-items: center;
/* 20px转换为vh */
}
.system-message-item:hover {
border-color: #1890ff;
}
.system-message-main {
padding: 10px 0;
/* 24px 20px转换 */
margin-left: 15px;
/* 30px转换为vw */
width: 100%;
}
.system-message-user {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 0.73vw;
/* 14px转换为vw */
margin-bottom: 0.73vh;
/* 14px转换为vh */
width: 100%;
position: relative;
/* 为绝对定位的时间提供参考 */
}
.system-icon {
width: 45px;
/* 42px转换为vw */
height: 45px;
/* 42px转换为vw */
background: rgba(3, 136, 209, 1);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 0.1vh;
background-image: url('/images/profile/root.png');
background-size: 100% 100%;
}
.system-info {
flex: 1;
min-width: 0;
overflow: hidden;
}
.system-title {
font-size: 16px;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: #333;
line-height: 1.5;
/* 使用相对行高,确保文字不错位 */
text-align: left;
font-style: normal;
text-transform: none;
margin-bottom: 0.52vh;
/* 10px转换为vh */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.system-subtitle-row {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
}
.system-subtitle {
font-size: 14px;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: #999;
line-height: 1.5;
/* 使用相对行高,确保文字不错位 */
text-align: left;
font-style: normal;
text-transform: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* flex: 1; */
/* 20px转换为vw与查看详情保持间距 */
}
.system-detail-link {
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: rgba(3, 136, 209, 1);
line-height: 1.5;
/* 使用相对行高,确保文字不错位 */
text-align: left;
font-style: normal;
text-transform: none;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
flex-shrink: 0;
}
.system-detail-link:hover {
text-decoration: underline;
}
.system-time {
width: 90px;
/* 90px转换为vw */
font-size: 12px;
/* 12px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: rgba(153, 153, 153, 1);
text-align: left;
white-space: nowrap;
line-height: 1.5;
/* 使用相对行高,确保文字不错位 */
margin-left: auto;
/* 推到右边 */
flex-shrink: 0;
align-self: flex-start;
}
.message-action-btn:hover {
/* 移除背景色,只保持透明 */
background: none;
color: #999999;
/* 保持原色不变 */
}
.message-action-btn.reply-btn:hover {
background: none;
color: #999999;
/* 保持原色不变 */
}
.message-action-btn.delete-btn:hover {
background: none;
color: #999999;
/* 保持原色不变 */
}
.message-action-btn.report-btn:hover {
background: none;
color: #999999;
/* 保持原色不变 */
}
.reply-section {
margin-top: 0.73vh;
}
.reply-input-container {
padding: 0 0 0 3vw;
}
.reply-textarea {
width: 100%;
min-height: 3.91vh;
/* 75px转换为vh */
border: 1.5px solid #D8D8D8;
/* 6px转换为vw */
padding: 0.52vh 0.52vw;
/* 10px转换 */
font-size: 0.73vw;
/* 14px转换为vw */
line-height: 1.5;
resize: vertical;
font-family: inherit;
}
.reply-textarea:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 0.1vw rgba(24, 144, 255, 0.2);
}
.reply-actions {
display: flex;
justify-content: flex-end;
gap: 0.52vw;
/* 10px转换为vw */
margin-top: 0.52vh;
/* 10px转换为vh */
}
.cancel-btn,
.send-btn {
padding: 0.31vh 0.83vw;
/* 6px 16px转换 */
border: 1px solid #d9d9d9;
border-radius: 0.31vw;
/* 6px转换为vw */
font-size: 0.73vw;
/* 14px转换为vw */
cursor: pointer;
transition: all 0.3s ease;
}
.cancel-btn {
background: white;
color: #666;
}
.cancel-btn:hover {
border-color: #40a9ff;
color: #40a9ff;
}
.send-btn {
width: 80px;
height: 28px;
background: #0288D1;
color: white;
border-color: #1890ff;
border-radius: 0;
margin-top: 5px;
}
.send-btn:hover {
background: #40a9ff;
border-color: #40a9ff;
}
.draftbox {
margin-left: auto;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
.draftbox img {
width: 16px;
height: 16px;
margin-right: 8px;
}
.draftbox span {
font-size: 16px;
color: #000;
}
.draftbox:hover {
color: #40a9ff;
}
.breadcrumb-wrapper {
padding: 5px 0;
}
.breadcrumb-wrapper .text_15 {
font-size: 13px;
}
.homework {
color: #A2A2A2;
}
/* 消息页面响应式设计 */
@media (max-width: 1200px) {
.message-header {
flex-direction: column;
align-items: flex-start;
gap: 1vh;
}
.message-tabs {
gap: 3vw;
}
.message-tab-item {
font-size: 1.2vw;
}
}
/* 消息页面响应式设计 */
@media (max-width: 1200px) {
.message-header {
flex-direction: column;
align-items: flex-start;
gap: 1vh;
}
.message-tabs {
gap: 3vw;
}
.message-tab-item {
font-size: 1.2vw;
}
.user-avatar {
width: 3vw;
height: 3vw;
}
.user-name {
font-size: 1.1vw;
}
.message-text {
font-size: 1.1vw;
width: auto;
/* 响应式下自适应宽度 */
height: auto;
/* 响应式下自适应高度 */
line-height: 1.5;
/* 响应式下调整行高 */
white-space: nowrap;
/* 保持不换行 */
overflow: hidden;
/* 隐藏溢出 */
text-overflow: ellipsis;
/* 超出显示省略号 */
}
.course-label,
.course-name,
.message-time {
font-size: 1vw;
}
}
@media (max-width: 768px) {
.message-header {
padding: 0 3vw;
}
.message-tabs {
gap: 5vw;
}
.message-tab-item {
font-size: 3vw;
}
.message-count {
font-size: 2.5vw;
padding: 0.5vh 1.5vw;
}
.action-link {
font-size: 2.8vw;
}
.message-main {
padding: 3vh 3vw;
margin-left: 2vw;
}
.user-avatar {
width: 8vw;
height: 8vw;
}
.user-name {
font-size: 3.2vw;
}
.message-text {
font-size: 3.2vw;
width: auto;
/* 手机端自适应宽度 */
height: auto;
/* 手机端自适应高度 */
line-height: 1.5;
/* 手机端调整行高 */
white-space: nowrap;
/* 保持不换行 */
overflow: hidden;
/* 隐藏溢出 */
text-overflow: ellipsis;
/* 超出显示省略号 */
}
.course-label,
.course-name,
.message-time {
font-size: 2.8vw;
}
/* 手机端课程信息容器调整 */
.course-info-container {
width: 90vw;
height: auto;
padding: 1vh 3vw;
}
/* 手机端系统消息调整 */
.system-message-item {
min-height: 15vh;
}
.system-message-main {
padding: 3vh 3vw;
margin-left: 2vw;
}
.system-icon {
width: 8vw;
height: 8vw;
}
.system-title,
.system-subtitle,
.system-detail-link,
.system-time {
font-size: 2.8vw;
}
.action-btn {
font-size: 2.8vw;
padding: 1vh 2vw;
}
.reply-textarea {
font-size: 3vw;
padding: 2vh 2vw;
}
.cancel-btn,
.send-btn {
font-size: 2.8vw;
padding: 1.5vh 3vw;
}
}
/* 我的资料页面样式 */
.materials-content {
background: white;
border-radius: 0.42vw;
/* 8px转换为vw */
padding: 0;
margin: 1.04vh 0;
/* 20px转换为vh */
}
.materials-header {
padding-bottom: 1vh;
/* 30px 40px转换 */
border-bottom: 1.5px solid #E6E6E6;
}
.materials-tabs {
display: flex;
gap: 2.08vw;
/* 40px转换为vw */
}
.materials-tab-item {
font-size: 0.83vw;
/* 16px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: #666;
cursor: pointer;
padding: 0.52vh 0;
/* 10px转换为vh */
border-bottom: 2px solid transparent;
transition: all 0.3s ease;
}
.materials-tab-item.active {
color: #0288D1;
font-weight: 500;
/* 移除蓝色下划线 */
}
.materials-tab-item:hover {
color: #0288D1;
}
/* 基础信息页面样式 */
.basic-info-content {
padding: 1.04vh 0;
/* 20px转换减少内边距因为容器已有边距 */
}
.basic-info-container {
height: 310px;
margin: 10px auto;
border: 1.5px solid #D8D8D8;
/* 8px转换为vw */
padding: 2.08vh 2.08vw;
/* 40px转换 */
background: white;
}
.basic-info-title {
font-size: 16px;
/* 18px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: 500;
color: #333;
margin-bottom: 2.08vh;
/* 40px转换为vh */
padding-bottom: 1.04vh;
/* 20px转换为vh */
border-bottom: 1.5px solid #E6E6E6;
}
/* 头像部分样式 */
.avatar-section {
display: flex;
justify-content: center;
margin-bottom: 3.13vh;
/* 60px转换为vh */
}
.avatar-container {
position: relative;
display: inline-block;
width: 78px !important;
height: 78px !important;
border: 1.5px solid #0292D5;
border-radius: 50%;
}
.user-avatar-large {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 68px !important;
/* 68px转换为vw覆盖SafeAvatar样式 */
height: 68px !important;
/* 68px转换为vw覆盖SafeAvatar样式 */
border-radius: 50%;
}
.user-avatar-large img {
object-fit: cover;
}
.avatar-edit-btn {
position: absolute;
bottom: 0;
right: 0;
width: 25px;
/* 25px转换为vw */
height: 25px;
/* 25px转换为vw */
background: #0288D1;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
}
.avatar-edit-btn:hover {
background: #0277BD;
/* 稍微深一点的蓝色作为悬停效果 */
}
.avatar-edit-btn .edit-icon {
width: 11px;
/* 11px转换为vw */
height: 11px;
/* 11px转换为vw */
object-fit: contain;
}
/* 表单样式 */
.basic-info-form {
width: 100%;
}
.form-row {
display: flex;
flex-direction: row;
/* 改为水平展示 */
gap: 2.08vw;
/* 40px转换为vw */
justify-content: space-between;
}
.form-group {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1.56vh;
/* 30px转换为vh增加标签和输入框之间的距离 */
}
.form-label {
width: auto;
/* 改为自适应宽度,避免换行 */
min-width: 4.17vw;
/* 80px转换为vw确保最小宽度 */
height: 1.04vh;
/* 20px转换为vh */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #999999;
line-height: 1.04vh;
/* 20px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
white-space: nowrap;
/* 防止换行 */
flex-shrink: 0;
}
.form-input,
.form-select {
width: 276px;
height: 41px;
/* 80px转换为vh与密码修改页面保持一致 */
padding: 1.04vh 0.73vw;
/* 20px 14px转换增加上下内边距 */
background: #F5F8FB;
border: 1px solid #D8D8D8;
/* 4px转换为vw */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #333333;
line-height: normal;
/* 改为normal让浏览器自动计算合适的行高 */
text-align: left;
font-style: normal;
text-transform: none;
transition: border-color 0.3s ease;
box-sizing: border-box;
/* 确保padding包含在总高度内 */
}
/* 专门为select元素优化 */
.form-select {
display: flex;
align-items: center;
/* 垂直居中对齐 */
padding-top: 0.78vh;
/* 15px转换为vh调整顶部内边距 */
padding-bottom: 0.78vh;
/* 15px转换为vh调整底部内边距 */
}
.form-input:focus,
.form-select:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.form-input::placeholder {
color: #bfbfbf;
}
/* 密码修改页面样式 */
.password-content {
margin-top: 15px;
/* 20px转换减少内边距因为容器已有边距 */
}
.password-container {
/* 1000px转换为vw */
margin: 0 auto;
border: 1.5px solid #D8D8D8;
/* 8px转换为vw */
padding: 10px 15px;
/* 40px转换 */
background: white;
}
.password-title {
font-size: 16px;
/* 18px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: 500;
color: #333;
margin-bottom: 10px;
/* 40px转换为vh */
padding-bottom: 10px;
/* 20px转换为vh */
border-bottom: 1.5px solid #E6E6E6;
}
.password-form {
width: 100%;
}
.password-form-group {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1.56vh;
/* 30px转换为vh */
margin-bottom: 2.08vh;
/* 40px转换为vh */
}
.password-form-label {
margin-top: 15px;
margin-bottom: 5px;
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 14px;
/* 14px转换为vw */
color: #999999;
line-height: 1.04vh;
/* 20px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
white-space: nowrap;
flex-shrink: 0;
}
.account-display {
padding-left: 15px;
width: 100%;
height: 41px;
background: #F5F8FB;
border: 1.5px solid #D8D8D8;
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #333333;
line-height: normal;
text-align: left;
font-style: normal;
text-transform: none;
box-sizing: border-box;
display: flex;
align-items: center;
}
.password-form-input {
width: 100%;
height: 41px;
padding: 10px 15px;
background: #F5F8FB;
border: 1.5px solid #D8D8D8;
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 0.73vw;
/* 14px转换为vw */
color: #333333;
line-height: normal;
text-align: left;
font-style: normal;
text-transform: none;
transition: border-color 0.3s ease;
box-sizing: border-box;
}
.password-form-input:focus {
outline: none;
border-color: #1890ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.password-form-input::placeholder {
color: #bfbfbf;
}
.password-form-actions {
display: flex;
justify-content: flex-start;
margin-top: 15px;
margin-bottom: 10px;
/* 40px转换为vh */
}
.password-save-btn {
width: 100px;
height: 33px;
background: #0288D1;
color: white;
border: none;
/* 4px转换为vw */
font-size: 14px;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
}
.password-save-btn:hover {
background: #40a9ff;
}
.password-save-btn:active {
background: #096dd9;
}
/* 我的下载页面样式 */
.download-content {
background: white;
border-radius: 0.42vw;
/* 8px转换为vw */
padding: 0 0 1.04vh 0;
/* 底部添加20px内边距确保内容不被截断 */
margin: 1.04vh 0;
/* 20px转换为vh */
overflow: visible;
/* 确保内容完全可见 */
}
/* 面包屑控制区域样式 */
.breadcrumb-controls {
display: flex;
justify-content: flex-start;
align-items: center;
padding-top: 1.56vh;
/* 30px 40px转换 */
}
/* 面包屑导航样式 */
.breadcrumb-nav {
display: flex;
align-items: center;
}
.breadcrumb-text {
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
color: #666;
cursor: pointer;
transition: color 0.3s ease;
}
.breadcrumb-text:hover {
color: #1890ff;
}
.breadcrumb-current {
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
color: #333;
font-weight: 500;
}
/* 子目录中的文件项样式调整 */
.download-content.in-subdirectory .file-item .file-icon {
margin-left: 0 !important;
/* 子目录中移除左边距 */
}
.download-content.in-subdirectory .file-item .file-name {
margin-top: 1.56vh !important;
/* 子目录中文件名下移30px */
}
/* 子目录特有样式 */
.subdirectory-item .file-icon {
margin-left: 0 !important;
/* 移除左边距 */
}
.subdirectory-item .file-name {
margin-top: 2.04vh !important;
/* 20px转换为vh下移文件名 */
}
/* 证书网格特有样式 - 一行显示3个 */
.certificate-grid {
grid-template-columns: repeat(3, 1fr) !important;
/* 固定3列 */
gap: 1.5vw !important;
/* 减少间距,给证书更多空间 */
justify-content: center;
width: 100% !important;
/* 确保占满容器宽度 */
}
.certificate-grid .file-item {
width: 100% !important;
/* 占满网格单元格宽度 */
height: auto !important;
/* 高度自适应内容 */
min-height: 15vh !important;
/* 增加最小高度给证书更多空间 */
background: white !important;
/* 证书背景色改为白色 */
padding: 2.6vh 2.6vw !important;
/* 50px转换为vw/vh上下左右50px间距 */
display: flex !important;
/* 使用flex布局 */
flex-direction: column !important;
/* 垂直排列 */
align-items: center !important;
/* 水平居中 */
justify-content: center !important;
/* 垂直居中 */
}
.certificate-grid .file-item .file-icon {
width: 100% !important;
/* 占满容器宽度 */
height: auto !important;
/* 高度自适应 */
max-width: 20vw !important;
/* 增大最大宽度限制 */
margin: 0 auto 2.6vh auto !important;
/* 居中显示底部留50px间距(2.6vh) */
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.certificate-grid .file-item .folder-icon {
width: 100% !important;
/* 图片占满图标容器 */
height: auto !important;
/* 高度自适应保持比例 */
max-width: 100% !important;
/* 最大宽度不超过容器 */
min-height: 8vh !important;
/* 设置最小高度确保图片足够大 */
object-fit: contain !important;
/* 保持图片比例,完整显示 */
}
.certificate-grid .file-item .file-name {
margin-top: 0.5vh !important;
/* 证书名字与图片间距约25px */
text-align: center !important;
/* 文字居中 */
padding: 0 1.3vw !important;
/* 左右内边距约25px */
}
/* 作业网格特有样式 - 一行显示6个参考图片布局 */
.homework-grid {
grid-template-columns: repeat(6, 1fr) !important;
/* 固定6列 */
gap: 1vw !important;
/* 减少间距 */
justify-content: center;
width: 100% !important;
/* 确保占满容器宽度 */
}
.homework-grid .file-item {
width: 100% !important;
/* 占满网格单元格宽度 */
height: auto !important;
/* 高度自适应内容 */
min-height: 201px !important;
/* 设置最小高度 */
background: white !important;
/* 白色背景 */
padding: 1.5vh 1vw !important;
/* 适当的内边距 */
display: flex !important;
/* 使用flex布局 */
flex-direction: column !important;
/* 垂直排列 */
align-items: center !important;
/* 水平居中 */
justify-content: center !important;
/* 垂直居中 */
border: 1.5px solid #D8D8D8 !important;
/* 添加边框 */
}
.homework-grid .file-item .file-icon {
/* 高度自适应 */
width: 64px;
height: 64px;
/* 限制最大宽度 */
margin: 0 auto 1vh auto !important;
/* 居中显示,底部留间距 */
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
.homework-grid .file-item .folder-icon {
width: 100% !important;
/* 图片占满图标容器 */
height: auto !important;
/* 高度自适应保持比例 */
max-width: 100% !important;
/* 最大宽度不超过容器 */
min-height: 4vh !important;
/* 设置最小高度 */
object-fit: contain !important;
/* 保持图片比例,完整显示 */
}
.homework-grid .file-item .file-name {
margin-top: 20px !important;
/* 文件名与图片间距 */
text-align: center !important;
/* 文字居中 */
padding: 0 0.5vw !important;
/* 左右内边距 */
font-size: 14px !important;
/* 较小的字体 */
color: #333 !important;
/* 文字颜色 */
}
.download-header {
padding: 0 0 1vh 0;
/* 30px 40px转换 */
border-bottom: 1px solid #f0f0f0;
}
.download-tabs {
display: flex;
gap: 2.08vw;
/* 40px转换为vw */
}
.download-tab-item {
font-size: 0.83vw;
/* 16px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal;
color: #666;
cursor: pointer;
padding: 0.52vh 0;
/* 10px转换为vh */
border-bottom: 2px solid transparent;
transition: all 0.3s ease;
}
.download-tab-item.active {
color: #1890ff;
font-weight: 500;
/* 移除蓝色下划线 */
}
.download-tab-item:hover {
color: #1890ff;
}
/* 筛选和操作区域 */
.download-controls {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 30px;
margin-bottom: 10px;
/* padding: 1.56vh 2.08vw; */
/* 30px 40px转换 */
/* 移除下方边框线条 */
}
.download-filters {
display: flex;
align-items: center;
gap: 2.08vw;
/* 40px转换为vw */
}
.filter-group,
.search-group {
display: flex;
align-items: center;
gap: 0.52vw;
/* 10px转换为vw */
}
.filter-label,
.search-label {
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
color: #333;
white-space: nowrap;
}
.filter-select {
width: 9.21vw;
/* 100px转换为vw */
height: 32px;
/* 80px转换为vh增加一倍高度 */
padding: 0.52vh 0.52vw;
/* 10px转换增加内边距 */
border: 1px solid #d9d9d9;
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
color: #333;
background: white;
}
.search-input-container {
display: flex;
align-items: center;
position: relative;
}
.search-input {
width: 10.42vw;
/* 200px转换为vw */
height: 32px;
/* 80px转换为vh增加一倍高度 */
padding: 0.26vh 2.08vw 0.26vh 0.52vw;
/* 5px 40px 5px 10px转换右侧留空给按钮 */
border: 1px solid #d9d9d9;
border-radius: 0;
/* 移除圆角,变成直角 */
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
color: #333;
background: white;
}
.search-btn {
position: absolute;
right: 20px;
/* 5px转换为vw */
top: 50%;
transform: translateY(-50%);
width: 16px;
/* 30px转换为vw */
height: 16px;
/* 30px转换为vh */
border: none;
background: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.search-icon {
width: 100%;
height: 100%;
object-fit: contain;
}
.download-actions {
display: flex;
align-items: center;
gap: 1.04vw;
/* 20px转换为vw */
}
.file-count {
/* width: 5.83vw; */
/* 112px转换为vw */
/* height: 0.73vh; */
/* 14px转换为vh */
font-family: AppleSystemUIFont, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 10px;
/* 10px转换为vw */
color: #999999;
line-height: 0.73vh;
/* 14px转换为vh */
text-align: left;
font-style: normal;
text-transform: none;
}
.new-folder-btn {
width: 109px;
height: 31px;
background: #0288D1;
/* 10px 20px转换 */
color: white;
border: none;
/* 4px转换为vw */
font-size: 14px;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
cursor: pointer;
transition: all 0.3s ease;
}
.new-folder-btn:hover {
background: #40a9ff;
}
/* 文件网格样式 */
.files-grid {
display: grid;
grid-template-columns: repeat(auto-fit, 9.17vw);
/* 自适应列数每列157px */
gap: 20px;
/* 30px转换为vw增加间距 */
/* padding: 2.08vh 2.08vw 3.13vh 2.08vw; 上40px 左右40px 下60px确保底部边框可见 */
padding: 20px 0;
justify-content: start;
overflow: visible;
/* 确保内容不被截断 */
}
.file-item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 157px;
height: 201px;
/* 157px转换为vw */
min-height: 10.47vh;
/* 最小高度201px允许自适应增长 */
padding: 1.04vh 0.52vw;
/* 上下20px 左右10px */
border: 1px solid #D8D8D8 !important;
/* 强制显示边框 */
border-radius: 0;
/* 移除圆角,变成直角 */
background: white;
transition: all 0.3s ease;
cursor: pointer;
box-sizing: border-box;
margin-bottom: 0.26vh;
/* 2px转换为vh确保底部边框可见 */
}
.file-item:hover {
background: #f5f5f5;
border-color: #bfbfbf;
}
.file-menu {
position: absolute;
top: 0.52vh;
/* 10px转换为vh */
right: 0.52vw;
/* 10px转换为vw */
z-index: 10;
}
.file-menu-btn {
margin-top: 10px;
width: 13px;
height: 13px;
/* 24px转换为vh */
border: none;
background: none;
/* 移除背景 */
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.83vw;
/* 16px转换为vw */
color: #666;
transition: all 0.3s ease;
}
.file-menu-btn:hover {
background: none;
/* 移除悬停背景 */
}
.more-icon {
width: 100%;
height: 100%;
object-fit: contain;
}
.file-menu-dropdown {
position: absolute;
top: 100%;
right: 0;
background: white;
border: 1px solid #d9d9d9;
border-radius: 0.21vw;
/* 4px转换为vw */
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
z-index: 20;
min-width: 4.17vw;
/* 80px转换为vw */
}
.menu-item {
display: flex;
align-items: center;
gap: 0.21vw;
/* 4px转换为vw减小图标和文字间距 */
padding: 0.52vh 0.73vw;
/* 10px 14px转换 */
font-size: 14px;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
color: #000;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
/* 确保文字水平展示,不换行 */
}
.menu-icon {
width: 18px;
/* 84px转换为vw增加一倍 */
height: 18px;
/* 24px转换为vh增加一倍 */
object-fit: contain;
flex-shrink: 0;
}
.menu-item:hover {
background: #f5f5f5;
}
.menu-item:first-child {
border-radius: 0.21vw 0.21vw 0 0;
/* 4px转换为vw */
}
.menu-item:last-child {
border-radius: 0 0 0.21vw 0.21vw;
/* 4px转换为vw */
}
.file-icon {
width: 131px;
/* 100px转换为vw */
height: 131px;
/* 100px转换为vw */
margin-left: 0.5vw;
margin-top: 1.5vh;
/* 30px转换为vh增加顶部间距图片下移 */
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.folder-icon {
width: 100%;
height: 100%;
object-fit: contain;
max-width: 100%;
max-height: 100%;
}
.folder-icon-css {
font-size: 2.5vw;
/* 48px转换为vw */
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.file-name {
font-size: 0.73vw;
/* 14px转换为vw */
font-family: Helvetica, 'Microsoft YaHei', Arial, sans-serif;
color: #333;
text-align: center;
word-break: break-all;
line-height: 1.2;
margin-top: -0.26vh;
/* 5px转换为vh减小与图标的间距文件名上移 */
margin-bottom: 0.52vh;
/* 10px转换为vh底部间距确保不贴边框 */
padding: 0 0.26vw;
/* 左右5px内边距 */
width: 100%;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.download-tabs {
gap: 3vw;
}
.download-tab-item {
font-size: 1vw;
}
.download-controls {
flex-direction: column;
gap: 2vh;
align-items: flex-start;
}
.download-filters {
gap: 3vw;
}
.filter-select {
width: 8vw;
font-size: 1vw;
}
.search-input {
width: 15vw;
font-size: 1vw;
}
.files-grid {
grid-template-columns: repeat(auto-fit, 12vw);
/* 平板端调整文件项宽度 */
gap: 2vw;
}
.file-item {
width: 12vw;
height: 18vh;
/* 增加平板端高度 */
}
.file-icon {
width: 8vw;
height: 8vw;
}
.file-name {
font-size: 1vw;
}
}
@media (max-width: 1200px) {
.materials-tabs {
gap: 3vw;
}
.materials-tab-item {
font-size: 1vw;
}
.user-avatar-large {
width: 6vw !important;
height: 6vw !important;
}
.avatar-edit-btn {
width: 2.6vw;
/* 平板端按比例调整25px * 1.3 ≈ 32px */
height: 2.6vw;
}
.avatar-edit-btn .edit-icon {
width: 1.14vw;
/* 平板端按比例调整11px * 1.3 ≈ 14px */
height: 1.14vw;
}
.form-row {
flex-direction: column;
gap: 3vh;
}
.form-label {
width: auto;
font-size: 1vw;
}
.form-input,
.form-select {
width: 30vw;
font-size: 1vw;
}
.basic-info-title,
.password-title {
font-size: 1.2vw;
}
.save-btn {
font-size: 1vw;
padding: 1vh 3vw;
}
}
@media (max-width: 576px) {
.download-content,
.materials-content {
margin: 2vh 1vw;
border-radius: 1vw;
}
.download-header {
padding: 3vh 4vw;
}
.download-tabs {
gap: 6vw;
}
.download-tab-item {
font-size: 3vw;
}
.download-controls {
padding: 3vh 4vw;
flex-direction: column;
gap: 3vh;
}
.download-filters {
flex-direction: column;
gap: 2vh;
width: 100%;
}
.filter-group,
.search-group {
width: 100%;
justify-content: space-between;
}
.filter-select {
width: 20vw;
font-size: 3.5vw;
height: 6vh;
}
.search-input {
width: 50vw;
font-size: 3.5vw;
height: 6vh;
padding: 2vh 8vw 2vh 3vw;
}
.search-btn {
width: 6vw;
height: 6vh;
}
.download-actions {
width: 100%;
justify-content: space-between;
}
.file-count {
font-size: 3vw;
}
.new-folder-btn {
font-size: 3vw;
padding: 2vh 4vw;
}
.files-grid {
grid-template-columns: repeat(auto-fit, 40vw);
/* 手机端文件项宽度 */
gap: 4vw;
padding: 4vh 4vw;
justify-content: center;
}
.file-item {
width: 40vw;
height: 30vh;
/* 增加手机端高度 */
}
.file-icon {
width: 20vw;
height: 20vw;
}
.file-name {
font-size: 3vw;
}
.file-menu-btn {
width: 6vw;
height: 6vh;
font-size: 4vw;
}
.menu-item {
font-size: 3.5vw;
padding: 2vh 3vw;
}
.materials-header {
padding: 3vh 4vw;
}
.materials-tabs {
gap: 6vw;
}
.materials-tab-item {
font-size: 3vw;
}
.basic-info-content,
.password-content {
padding: 4vh 4vw;
}
.user-avatar-large {
width: 15vw !important;
height: 15vw !important;
}
.avatar-edit-btn {
width: 6.5vw;
/* 手机端按比例调整25px * 2.6 ≈ 65px */
height: 6.5vw;
}
.avatar-edit-btn .edit-icon {
width: 2.86vw;
/* 手机端按比例调整11px * 2.6 ≈ 29px */
height: 2.86vw;
}
.form-row {
flex-direction: column;
gap: 4vh;
}
.form-group {
flex-direction: column;
align-items: flex-start;
gap: 1vh;
}
.form-label {
width: auto;
font-size: 3.5vw;
text-align: left;
}
.form-input,
.form-select {
width: 100%;
font-size: 3.5vw;
height: 6vh;
padding: 2vh 3vw;
}
.basic-info-title,
.password-title {
font-size: 4vw;
}
.save-btn {
font-size: 3.5vw;
padding: 2vh 6vw;
}
}
/* 包含@的消息高亮样式 */
.mention-highlight {
color: #E02424 !important;
}
/* 关注页面样式 */
.follows-content {
width: 100%;
}
.follows-list {
margin-top: 20px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.56vh 1.04vw;
}
.follow-item {
display: flex;
flex-direction: row;
align-items: center;
padding: 2.08vh 0;
background: white;
transition: all 0.3s ease;
text-align: left;
}
.follow-avatar {
margin-right: 1.04vw;
flex-shrink: 0;
}
.avatar-image {
width: 75px;
height: 75px;
border-radius: 50%;
object-fit: cover;
border: 2px solid #f0f0f0;
}
.follow-right-content {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.78vh;
}
.follow-info {
display: flex;
flex-direction: column;
gap: 0.26vh;
}
.follow-name {
font-size: 14px;
font-weight: 500;
color: #333;
margin-bottom: 0.26vh;
}
.follow-role {
font-size: 12px;
color: #707070;
margin-bottom: 0.26vh;
}
.follow-description {
font-size: 0.73vw;
color: #999;
line-height: 1.4;
margin-bottom: 0.26vh;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.follow-visits {
font-size: 0.68vw;
color: #1890ff;
margin-bottom: 0.52vh;
}
.follow-actions {
display: flex;
justify-content: flex-start;
}
.follow-btn {
width: 80px;
height: 23px;
border: none;
font-size: 10px;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
border-radius: 0;
}
/* 取消关注状态 */
.follow-btn.not-following {
background: #0288D1;
color: white;
}
.follow-btn.not-following:hover {
background: #0277BD;
}
/* 已关注状态 */
.follow-btn.following {
background: #F5F8FB;
color: #999999;
}
.follow-btn.following:hover {
background: #E8F4FD;
color: #666666;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.follows-list {
grid-template-columns: repeat(2, 1fr);
}
/* 作业网格响应式 */
.homework-grid {
grid-template-columns: repeat(4, 1fr) !important;
gap: 1.5vw !important;
}
}
@media (max-width: 768px) {
.follows-list {
grid-template-columns: 1fr;
padding: 0 3vw;
gap: 3vh 0;
}
.follow-item {
padding: 4vh 3vw;
border-radius: 1vh;
}
.avatar-image {
width: 15vw;
height: 15vw;
}
.follow-name {
font-size: 4vw;
}
.follow-role {
font-size: 3.5vw;
}
.follow-description {
font-size: 3vw;
}
.follow-visits {
font-size: 3vw;
}
.follow-btn {
padding: 2vh 4vw;
font-size: 3.5vw;
border-radius: 1vh;
}
/* 作业网格移动端响应式 */
.homework-grid {
grid-template-columns: repeat(3, 1fr) !important;
gap: 2vw !important;
}
.homework-grid .file-item {
min-height: 15vh !important;
padding: 2vh 1.5vw !important;
}
.homework-grid .file-item .file-icon {
max-width: 20vw !important;
}
.homework-grid .file-item .file-name {
font-size: 3vw !important;
padding: 0 1vw !important;
}
}
/* 文件列表样式 */
.file-list {
margin-top: 12px;
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.file-list-section .file-item {
display: flex;
align-items: center;
background: #f8f9fa;
border: 1px solid #e0e0e0;
border-radius: 6px;
padding: 8px 12px;
min-width: 200px;
position: relative;
}
.file-list-section .file-icon {
margin-right: 8px;
}
.file-list-section .file-icon img {
width: 24px;
height: 24px;
}
.file-list-section .file-info {
flex: 1;
min-width: 0;
}
.file-list-section .file-name {
font-size: 12px;
color: #333;
font-weight: 500;
margin-bottom: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.file-list-section .file-size {
font-size: 11px;
color: #666;
}
.file-list-section .file-delete {
background: none;
border: none;
cursor: pointer;
padding: 2px;
font-size: 14px;
color: #999;
transition: color 0.2s;
}
.file-delete:hover {
color: #d03050;
}
/* 自定义弹窗样式 */
.custom-modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.custom-modal {
background: #F7F7F7;
width: 799px;
max-width: 90vw;
max-height: 758px;
overflow-y: auto;
}
.modal-content {
padding: 22px;
width: 100%;
background: #F7F7F7;
}
/* 弹窗表单标签样式 */
.n-form-item-label {
font-size: 18px !important;
color: #333 !important;
font-weight: 500;
}
/* 弹窗表单项目间距 */
.n-form-item {
margin-bottom: 24px !important;
}
/* 弹窗表单项目内部间距 */
.n-form-item-blank {
margin-top: 8px !important;
}
/* 弹窗底部按钮区域 */
.modal-footer {
display: flex;
gap: 12px;
}
/* 自定义表单样式 */
.form-item {
margin-bottom: 10px;
}
.form-label {
display: block;
font-size: 14px;
color: #333;
font-weight: 500;
margin-bottom: 15px;
}
.required {
color: #d03050;
}
.form-input {
width: 100%;
min-height: 50px;
padding: 12px 16px;
border: 1px solid #e0e0e0;
font-size: 14px;
color: #333;
background: white;
transition: border-color 0.2s;
}
.form-input:focus {
outline: none;
border-color: #18a058;
}
.form-input::placeholder {
color: #999;
}
</style>