部分个人中心

This commit is contained in:
Wxp 2025-08-12 18:22:50 +08:00
parent 7e5809afde
commit d4db394b58
4 changed files with 4026 additions and 323 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

File diff suppressed because it is too large Load Diff

View File

@ -111,6 +111,11 @@
<div v-for="course in filteredCourses" :key="course.id" class="box_2 flex-row justify-between"> <div v-for="course in filteredCourses" :key="course.id" class="box_2 flex-row justify-between">
<div class="block_4 flex-col"> <div class="block_4 flex-col">
<div class="box_3 flex-row justify-between"> <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" /> <img class="thumbnail_4" referrerpolicy="no-referrer" :src="bannerImage" :alt="bannerAlt" />
<span :class="['status-text', course.status]">{{ getStatusText(course.status) }}</span> <span :class="['status-text', course.status]">{{ getStatusText(course.status) }}</span>
</div> </div>
@ -359,7 +364,7 @@
<!-- 分数显示 --> <!-- 分数显示 -->
<div class="exam-score-badge" v-if="exam.score !== null"> <div class="exam-score-badge" v-if="exam.score !== null">
<span class="score-text">{{ exam.score }}</span> <span class="score-text">{{ exam.score }}<span></span></span>
</div> </div>
<!-- 考试信息 --> <!-- 考试信息 -->
@ -385,9 +390,6 @@
<!-- 底部操作区域 --> <!-- 底部操作区域 -->
<div class="exam-footer"> <div class="exam-footer">
<div class="exam-status-left">
<span class="exam-status-text">{{ getExamStatusText(exam.status) }}</span>
</div>
<div class="exam-action-right"> <div class="exam-action-right">
<button v-if="exam.status === 'upcoming'" class="action-btn upcoming-btn" @click="startExam(exam.id)"> <button v-if="exam.status === 'upcoming'" class="action-btn upcoming-btn" @click="startExam(exam.id)">
未开始 未开始
@ -401,6 +403,9 @@
查看详情 查看详情
</button> </button>
</div> </div>
<div class="exam-status-left">
<span class="exam-status-text">{{ getExamStatusText(exam.status) }}</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -422,69 +427,64 @@
<div class="course-divider"></div> <div class="course-divider"></div>
<!-- 练习网格 --> <!-- 练习网格 -->
<div class="practice-grid"> <div class="exam-grid">
<div v-for="practice in filteredPractices" :key="practice.id" class="practice-card"> <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"> <div v-if="practice.status === 'finished'" class="practice-score-badge">
<span class="score-text">{{ practice.score }}</span> <span class="score-text">{{ practice.score }} <span></span></span>
</div> </div>
<!-- 练习标题 --> <!-- 考试信息 -->
<h3 class="practice-title">{{ practice.title }}</h3> <div class="exam-details">
<div class="exam-meta-item">
<!-- 练习详情 -->
<div class="practice-details">
<div class="practice-meta-item">
<span class="meta-label">练习日期</span> <span class="meta-label">练习日期</span>
<span class="meta-value">{{ practice.practiceDate }}</span> <span class="meta-value">{{ practice.practiceDate }}</span>
</div> </div>
<div class="practice-meta-item"> <div class="exam-meta-item">
<span class="meta-label">练习时间</span> <span class="meta-label">练习时间</span>
<span class="meta-value">{{ practice.duration }}分钟</span> <span class="meta-value">{{ practice.duration }}分钟</span>
</div> </div>
<div class="practice-meta-item"> <div class="exam-meta-item">
<span class="meta-label">题库数量</span> <span class="meta-label">题库数量</span>
<span class="meta-value">{{ practice.questionCount }}</span> <span class="meta-value">{{ practice.questionCount }}</span>
</div> </div>
</div> </div>
<!-- 动态显示内容 -->
<!-- 练习统计/简介 -->
<div v-if="practice.status === 'finished'" class="practice-stats"> <div v-if="practice.status === 'finished'" class="practice-stats">
<div class="stats-item correct"> <div class="stat-row">
<span class="stats-label">答对</span> <span class="stat-label">答对</span>
<span class="stats-number">{{ practice.correctCount }}</span> <span class="stat-value correct">{{ practice.correctCount || 0 }}<span></span></span>
</div> </div>
<div class="stats-item wrong"> <!-- 分割线 -->
<span class="stats-label">答错</span> <div class="divider"></div>
<span class="stats-number">{{ practice.wrongCount }}</span> <div class="stat-row">
<span class="stat-label">答错</span>
<span class="stat-value wrong">{{ practice.wrongCount || 0 }}<span></span></span>
</div> </div>
</div> </div>
<div v-else class="exam-description">
<!-- 练习简介练习中状态 --> {{ practice.description || '该练习包含' + practice.questionCount + '道题目,涵盖了相关知识点。' }}
<div v-else class="practice-intro">
<div class="intro-title">练习简介</div>
<div class="intro-content">
练习涵盖C++基础语法面向对象编程数据结构等核心内容旨在全面评估学生对C++编程语言的掌握程度和实际应用能力
</div>
</div> </div>
<!-- 练习底部 --> <!-- 底部操作区域 -->
<div class="practice-footer"> <div class="exam-footer">
<div class="practice-status-left"> <div class="exam-action-right">
<span class="practice-status-text">{{ practice.status === 'ongoing' ? '练习中' : '已结束' }}</span> <button v-show="practice.status === 'ongoing'" class="action-btn ongoing-btn"
</div>
<div class="practice-action-right">
<button v-if="practice.status === 'ongoing'" class="action-btn ongoing-btn"
@click="continuePractice(practice.id)"> @click="continuePractice(practice.id)">
继续练习 继续练习
</button> </button>
<button v-else-if="practice.status === 'finished'" class="action-btn finished-btn" <button v-show="practice.status === 'finished'" class="action-btn finished-btn"
@click="viewPracticeDetail(practice.id)"> @click="viewPracticeDetail(practice.id)">
查看详情 查看详情
</button> </button>
</div> </div>
<div class="exam-status-left">
<span class="exam-status-text">{{ practice.status === 'ongoing' ? '练习中' : '已结束' }}</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -909,184 +909,8 @@
</n-modal> </n-modal>
<!-- 考试详情页面 --> <!-- 考试详情页面 -->
<div v-if="showExamDetail && currentExamDetail" class="exam-detail-overlay"> <ExamDetail v-if="showExamDetail && currentExamDetail" :currentExamDetail="currentExamDetail"
<div class="exam-detail-container"> :currentDetailType="currentDetailType" @close="closeExamDetail" />
<!-- 头部导航 -->
<div class="exam-detail-header">
<div class="breadcrumb">
<span @click="closeExamDetail" class="breadcrumb-link">用户中心</span>
<span class="breadcrumb-separator">></span>
<span @click="closeExamDetail" class="breadcrumb-link">{{ currentDetailType === 'exam' ? '我的考试' : '我的练习'
}}</span>
<span class="breadcrumb-separator">></span>
<span class="breadcrumb-current">{{ currentExamDetail.title }}</span>
</div>
</div>
<!-- 考试内容区域 -->
<div class="exam-detail-content">
<!-- 左侧题目区域 -->
<div class="exam-questions-section">
<div class="exam-title-section">
<h1 class="exam-main-title">{{ currentExamDetail.title }}</h1>
</div>
<!-- 题目列表 -->
<div class="questions-container">
<div v-for="(question, index) in currentExamDetail.questions" :key="question.id" class="question-item">
<!-- 题目标题 -->
<div class="question-header">
<span class="question-number">{{ String(index + 1).padStart(2, '0') }}</span>
<span class="question-type">{{ question.title }}</span>
<span class="question-score">+59</span>
</div>
<!-- 题目内容 -->
<div class="question-content">
{{ question.content }}
</div>
<!-- 选项列表 -->
<div class="question-options">
<div v-for="option in question.options" :key="option.id" class="option-item" :class="{
'option-selected': question.userAnswers.includes(option.id),
'option-correct': question.correctAnswers.includes(option.id),
'option-wrong': question.userAnswers.includes(option.id) && !question.correctAnswers.includes(option.id)
}">
<div class="option-checkbox">
<input type="checkbox" :checked="question.userAnswers.includes(option.id)" disabled />
</div>
<div class="option-content">
<span class="option-text">{{ option.text }}</span>
<div v-if="option.image" class="option-image">
<img :src="option.image" :alt="option.text" />
</div>
</div>
</div>
</div>
<!-- 题目底部信息 -->
<div class="question-footer">
<div class="answer-status-box" :class="question.isCorrect ? 'status-correct' : 'status-wrong'">
{{ question.isCorrect ? '回答正确' : '回答错误' }}
</div>
<div class="question-stats">
<span class="correct-answer">正确答案{{ question.correctAnswers.join(', ') }}</span>
<span class="user-answer">你的答案{{ question.userAnswers.join(', ') || '未作答' }}</span>
</div>
</div>
<!-- 题目解析 -->
<div class="question-analysis">
<div class="analysis-title">答案解析</div>
<div class="analysis-content">
这道题考查的是危险化学品安全管理的相关知识点根据相关法规要求危险化学品生产企业应当提供完整的安全技术说明书和应急处理措施
</div>
</div>
</div>
</div>
<!-- 底部提交按钮 -->
<div class="exam-submit-section">
<button class="submit-btn">
重新练习
</button>
</div>
</div>
<!-- 右侧信息区域 -->
<div class="exam-info-section">
<!-- 分数圆环 -->
<div class="score-circle-container">
<div class="score-circle">
<div class="score-inner">
<div class="score-number">{{ currentExamDetail.score }}</div>
</div>
</div>
<div class="score-label">得分</div>
</div>
<!-- 考试统计 -->
<div class="exam-stats">
<div class="stat-item">
<span class="stat-label">{{ currentDetailType === 'exam' ? '交卷时间:' : '练习时间:' }}</span>
<span class="stat-value">{{ currentDetailType === 'exam' ? (currentExamDetail as any).examDate :
(currentExamDetail as any).practiceDate }}</span>
</div>
<div class="stat-item">
<span class="stat-label">{{ currentDetailType === 'exam' ? '考试时长:' : '练习时长:' }}</span>
<span class="stat-value">{{ currentExamDetail.duration }}分钟</span>
</div>
<div class="stat-item">
<span class="stat-label">{{ currentDetailType === 'exam' ? '考试题量:' : '练习题量:' }}</span>
<span class="stat-value">{{ currentExamDetail.totalQuestions }}</span>
</div>
</div>
<!-- 答题统计 -->
<div class="answer-stats">
<div class="stats-row">
<div class="stat-box correct">
<div class="stat-number">{{ currentExamDetail.correctCount }}</div>
<div class="stat-text">答对题数</div>
</div>
<div class="stat-box wrong">
<div class="stat-number">{{ currentExamDetail.wrongCount }}</div>
<div class="stat-text">答错题数</div>
</div>
<div class="stat-box total">
<div class="stat-number">{{ currentExamDetail.totalQuestions - currentExamDetail.correctCount -
currentExamDetail.wrongCount }}</div>
<div class="stat-text">答对题数</div>
</div>
</div>
</div>
<!-- 答题卡 -->
<div class="answer-card">
<div class="card-title">答题卡</div>
<div class="card-sections">
<!-- 单选题部分 -->
<div class="card-section">
<div class="section-title">单选 (10)</div>
<div class="answer-grid">
<div v-for="i in 15" :key="i" class="answer-item" :class="getAnswerItemClass(i)">
{{ String(i).padStart(2, '0') }}
</div>
</div>
</div>
<!-- 多选题部分 -->
<div class="card-section">
<div class="section-title">多选 (10)</div>
<div class="answer-grid">
<div v-for="i in 15" :key="i + 15" class="answer-item" :class="getAnswerItemClass(i + 15)">
{{ String(i).padStart(2, '0') }}
</div>
</div>
</div>
</div>
<!-- 答题卡图例 -->
<div class="card-legend">
<div class="legend-item">
<span class="legend-color correct"></span>
<span class="legend-text">答对</span>
</div>
<div class="legend-item">
<span class="legend-color wrong"></span>
<span class="legend-text">答错</span>
</div>
<div class="legend-checkbox">
<input type="checkbox" id="showOnlyWrong" />
<label for="showOnlyWrong">只看错题</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template> </template>
@ -1097,6 +921,7 @@ import { useMessage, NModal, NUpload, NInput, NForm, NFormItem, NButton } from '
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import SafeAvatar from '@/components/common/SafeAvatar.vue' import SafeAvatar from '@/components/common/SafeAvatar.vue'
import ExamDetail from '../components/ExamDetail.vue';
const { t, locale } = useI18n() const { t, locale } = useI18n()
@ -2438,7 +2263,9 @@ const getFileIcon = () => {
} }
} }
// 使使 const createNewFolder = () => {
message.info('新建文件夹功能开发中...')
}
const renameFile = (fileId: number) => { const renameFile = (fileId: number) => {
message.info(`重命名文件 ${fileId}`) message.info(`重命名文件 ${fileId}`)
@ -2664,10 +2491,10 @@ onMounted(() => {
/* 主要内容区域 */ /* 主要内容区域 */
.profile-content { .profile-content {
width: 80vw; /* width: 80vw; */
/* 调整为80vw */ /* 调整为80vw */
min-height: calc(100vh - 6.4vh); min-height: 1415px;
margin: 2.08vh auto 0 auto; margin: 3vh auto 0 auto;
/* 距离顶部40px转换为vh */ /* 距离顶部40px转换为vh */
position: relative; position: relative;
background: #f6f6f6; background: #f6f6f6;
@ -2677,15 +2504,14 @@ onMounted(() => {
.block_14 { .block_14 {
position: relative; position: relative;
width: 13.4vw; width: 13.4vw;
/* 20vw缩小33% = 20vw * 0.67 = 13.4vw */ height: auto;
min-height: calc(100vh - 6.4vh);
background: #ffffff; background: #ffffff;
/* 改为白色背景 */ /* 改为白色背景 */
border-right: 0.05vw solid rgba(232, 232, 232, 1);
flex-shrink: 0; flex-shrink: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
margin-bottom: 30px;
/* 内容居中 */ /* 内容居中 */
} }
@ -2740,12 +2566,12 @@ onMounted(() => {
/* 分割线 */ /* 分割线 */
.menu-divider { .menu-divider {
width: 10vw; width: 11vw;
/* 与菜单项宽度一致 */ /* 与菜单项宽度一致 */
height: 0.05vh; height: 0.05vh;
/* 1px转换为vh */ /* 1px转换为vh */
background: #E6E6E6; background: #E6E6E6;
margin: 1.5vh 0; margin: 0;
/* 上下间距 */ /* 上下间距 */
} }
@ -2758,20 +2584,20 @@ onMounted(() => {
.image-text_24, .image-text_24,
.image-text_25, .image-text_25,
.image-text_26 { .image-text_26 {
width: 10vw; width: 11vw;
/* 进一步缩小菜单项宽度,适应新的导航栏宽度 */ /* 进一步缩小菜单项宽度,适应新的导航栏宽度 */
height: auto; height: auto;
/* 自适应高度 */ /* 自适应高度 */
min-height: 3vh; min-height: 3vh;
/* 设置最小高度,让盒子更大 */ /* 设置最小高度,让盒子更大 */
margin: 1.5vh 0; margin: 1.5vh;
/* 减小间距从2.34vh减少到1.5vh */ /* 减小间距从2.34vh减少到1.5vh */
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: left;
/* 菜单项内容居中 */ /* 菜单项内容居中 */
cursor: pointer; cursor: pointer;
padding: 1.2vh 0.5vw; padding: 1.5vh 0 1.5vh 1.8vw;
/* 增加上下内边距,让盒子更高 */ /* 增加上下内边距,让盒子更高 */
border-radius: 0.31vw; border-radius: 0.31vw;
/* 6px转换为vw */ /* 6px转换为vw */
@ -2830,7 +2656,7 @@ onMounted(() => {
.text-group_24, .text-group_24,
.text-group_25, .text-group_25,
.text-group_26 { .text-group_26 {
font-size: 1.04vw; font-size: 16px;
/* 20px转换为vw */ /* 20px转换为vw */
color: rgba(102, 102, 102, 1); color: rgba(102, 102, 102, 1);
/* 默认灰色 */ /* 默认灰色 */
@ -2869,15 +2695,15 @@ onMounted(() => {
/* 右侧课程列表区域 */ /* 右侧课程列表区域 */
.group_5 { .group_5 {
width: 60vw; width: 65vw;
/* 保持60vw宽度 */ /* 保持60vw宽度 */
min-height: calc(100vh - 6.4vh); min-height: calc(100vh - 6.4vh);
padding: 2.08vh 2.08vw; padding: 2.08vh 1.9vw;
/* 40px转换为vh和vw */ /* 40px转换为vh和vw */
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
overflow-y: auto; overflow-y: auto;
margin-left: 1.56vw; margin-left: 1.56vw;
/* 30px转换为vw30/1920*100 = 1.56vw */ margin-bottom: 30px;
} }
/* 课程筛选标签 */ /* 课程筛选标签 */
@ -2886,7 +2712,7 @@ onMounted(() => {
height: 2.08vh; height: 2.08vh;
/* 40px转换为vh */ /* 40px转换为vh */
align-items: center; align-items: center;
margin-bottom: 1.67vh; margin: 10px 0 20px 0;
/* 32px转换为vh */ /* 32px转换为vh */
gap: 2.81vw; gap: 2.81vw;
/* 54px转换为vw54/1920*100 = 2.81vw */ /* 54px转换为vw54/1920*100 = 2.81vw */
@ -2968,36 +2794,45 @@ onMounted(() => {
/* 课程缩略图区域 */ /* 课程缩略图区域 */
.block_4 { .block_4 {
width: 10.42vw;
/* 200px转换为vw */
margin-right: 1.04vw; margin-right: 1.04vw;
/* 20px转换为vw */
} }
.box_3 { .box_3 {
width: 10.42vw; width: 202px;
/* 200px转换为vw */ /* 200px转换为vw */
height: 15.63vh; height: 156px;
/* 大幅增加高度到300px转换为vh让图片展示到外部盒子高度 */ /* 大幅增加高度到300px转换为vh让图片展示到外部盒子高度 */
position: relative; position: relative;
border-radius: 0.42vw; border-radius: 5px;
/* 8px转换为vw */ /* 8px转换为vw */
overflow: hidden; overflow: hidden;
} }
.thumbnail_4 { .thumbnail_4 {
width: 100%; width: 100%;
height: 100%; height: 156px;
object-fit: cover; object-fit: cover;
} }
/* 状态标签 */ /* 状态标签 */
.status-image-container {
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
.status-image {
width: 66px;
height: 22px;
}
.status-text { .status-text {
position: absolute; position: absolute;
top: 26vh; top: 26vh;
/* 12px转换为vh */ /* 12px转换为vh */
left: 0.63vw; right: 0.63vw;
/* 12px转换为vw */ /* 调整到右侧 */
padding: 0.21vh 0.63vw; padding: 0.21vh 0.63vw;
/* 4px 12px转换 */ /* 4px 12px转换 */
border-radius: 0.21vw; border-radius: 0.21vw;
@ -3033,11 +2868,11 @@ onMounted(() => {
} }
.text_16 { .text_16 {
font-size: 0.94vw; font-size: 18px;
/* 18px转换为vw */ /* 18px转换为vw */
color: rgba(51, 51, 51, 1); color: #000000;
font-family: 'Microsoft YaHei', Arial, sans-serif; font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: 500; font-weight: 600;
flex: 1; flex: 1;
} }
@ -3050,16 +2885,16 @@ onMounted(() => {
.text_17 { .text_17 {
font-size: 0.73vw; font-size: 0.73vw;
/* 14px转换为vw */ /* 14px转换为vw */
color: rgba(250, 173, 20, 1); color: #999999;
font-family: 'Microsoft YaHei', Arial, sans-serif; font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal; font-weight: normal;
} }
/* 讲师信息 */ /* 讲师信息 */
.text_18 { .text_18 {
font-size: 0.73vw; font-size: 14px;
/* 14px转换为vw */ /* 14px转换为vw */
color: rgba(102, 102, 102, 1); color: #999;
font-family: 'Microsoft YaHei', Arial, sans-serif; font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal; font-weight: normal;
margin-bottom: 0.42vh; margin-bottom: 0.42vh;
@ -3068,13 +2903,14 @@ onMounted(() => {
/* 课程描述 */ /* 课程描述 */
.text_19 { .text_19 {
font-size: 0.73vw; font-size: 14px;
/* 14px转换为vw */ /* 14px转换为vw */
color: rgba(102, 102, 102, 1); color: #999;
font-family: 'Microsoft YaHei', Arial, sans-serif; font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal; font-weight: normal;
line-height: 1.5; line-height: 1.5;
margin-bottom: 0.83vh; margin-top: 5px;
margin-bottom: 22px;
/* 16px转换为vh */ /* 16px转换为vh */
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
@ -3085,7 +2921,7 @@ onMounted(() => {
/* 课程统计信息 */ /* 课程统计信息 */
.group_7 { .group_7 {
align-items: center; align-items: center;
gap: 1.04vw; gap: 5px;
/* 20px转换为vw */ /* 20px转换为vw */
} }
@ -3100,19 +2936,20 @@ onMounted(() => {
.text_20, .text_20,
.text_21, .text_21,
.text_22 { .text_22 {
font-size: 0.73vw; font-size: 14px;
/* 14px转换为vw */ /* 14px转换为vw */
color: rgba(102, 102, 102, 1); color: #999;
font-family: 'Microsoft YaHei', Arial, sans-serif; font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal; font-weight: normal;
margin-right: 10px;
} }
/* 操作按钮 */ /* 操作按钮 */
.text-wrapper_2 { .text-wrapper_2 {
background: rgba(2, 134, 206, 1); background: #0288D1;
border-radius: 0.31vw; border-radius: 5px;
/* 6px转换为vw */ /* 6px转换为vw */
padding: 0.42vh 0.83vw; padding: 6px 22px;
/* 8px 16px转换 */ /* 8px 16px转换 */
cursor: pointer; cursor: pointer;
transition: background-color 0.3s ease; transition: background-color 0.3s ease;
@ -3124,9 +2961,9 @@ onMounted(() => {
} }
.text_23 { .text_23 {
font-size: 0.73vw; font-size: 14px;
/* 14px转换为vw */ /* 14px转换为vw */
color: rgba(255, 255, 255, 1); color: white;
font-family: 'Microsoft YaHei', Arial, sans-serif; font-family: 'Microsoft YaHei', Arial, sans-serif;
font-weight: normal; font-weight: normal;
text-align: center; text-align: center;
@ -3151,16 +2988,15 @@ onMounted(() => {
} }
.pagination-item { .pagination-item {
min-width: 2.08vw; min-width: 38px;
/* 40px转换为vw */ height: 38px;
height: 2.08vh; background: white;
/* 40px转换为vh */
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.73vw; font-size: 0.73vw;
/* 14px转换为vw */ /* 14px转换为vw */
color: rgba(102, 102, 102, 1); color: #666666;
font-family: 'Microsoft YaHei', Arial, sans-serif; font-family: 'Microsoft YaHei', Arial, sans-serif;
cursor: pointer; cursor: pointer;
border-radius: 0.21vw; border-radius: 0.21vw;
@ -3168,7 +3004,6 @@ onMounted(() => {
transition: all 0.3s ease; transition: all 0.3s ease;
padding: 0.52vh 0.83vw; padding: 0.52vh 0.83vw;
/* 10px 16px转换 */ /* 10px 16px转换 */
background: rgba(255, 255, 255, 1);
border: 0.05vw solid rgba(232, 232, 232, 1); border: 0.05vw solid rgba(232, 232, 232, 1);
} }
@ -3178,16 +3013,15 @@ onMounted(() => {
} }
.pagination-item.active { .pagination-item.active {
background: rgba(2, 134, 206, 1); background: #0088D1;
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
border-color: rgba(2, 134, 206, 1); border-color: #0088D1;
} }
.pagination-item.disabled { .pagination-item.disabled {
color: rgba(204, 204, 204, 1); color: rgba(204, 204, 204, 1);
cursor: not-allowed; cursor: not-allowed;
border-color: rgba(232, 232, 232, 1); border-color: rgba(232, 232, 232, 1);
background: rgba(248, 248, 248, 1);
} }
.pagination-item.disabled:hover { .pagination-item.disabled:hover {
@ -3198,7 +3032,7 @@ onMounted(() => {
.nav-button { .nav-button {
min-width: 3.65vw; min-width: 3.65vw;
/* 70px转换为vw导航按钮稍宽一些 */ border: none;
} }
.page-number { .page-number {
@ -3751,8 +3585,7 @@ onMounted(() => {
.exam-card { .exam-card {
background: #ffffff; background: #ffffff;
border: 1px solid #e8e8e8; border: 1.5px solid #D8D8D8;
border-radius: 8px;
padding: 20px; padding: 20px;
position: relative; position: relative;
min-height: 280px; min-height: 280px;
@ -3768,30 +3601,36 @@ onMounted(() => {
.exam-title { .exam-title {
font-size: 16px; font-size: 16px;
font-weight: 600;
color: #333; color: #333;
margin-bottom: 16px; margin-bottom: 10px;
line-height: 1.4; line-height: 1.4;
border-bottom: 1.5px solid #E6E6E6;
padding-bottom: 10px;
} }
.exam-score-badge { .exam-score-badge {
position: absolute; position: absolute;
top: 15px; top: 11px;
right: 15px; right: 18px;
background: #fff2e8; background: white;
border: 1px solid #ffb366; border: 1px solid #FF6F0F;
border-radius: 4px; border-radius: 4px;
padding: 4px 8px; padding: 0 11px;
} }
.score-text { .score-text {
font-size: 14px; font-size: 20px;
font-weight: bold; font-weight: bold;
color: #ff8c00; color: #FF6F0F;
}
.score-text span {
margin-left: 2px;
font-size: 10px;
} }
.exam-details { .exam-details {
margin-bottom: 16px; margin-bottom: 5px;
} }
.exam-meta-item { .exam-meta-item {
@ -3801,25 +3640,25 @@ onMounted(() => {
} }
.meta-label { .meta-label {
color: #666; color: #999;
min-width: 70px; min-width: 70px;
} }
.meta-value { .meta-value {
color: #333; color: #999;
font-weight: 500; font-weight: 500;
} }
.exam-description { .exam-description {
font-size: 13px; padding: 8px 10px;
color: #666; font-size: 12px;
line-height: 1.5; color: #497087;
margin-bottom: auto; margin-bottom: auto;
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
background-color: #F5F8FB;
} }
.exam-footer { .exam-footer {
@ -3828,7 +3667,6 @@ onMounted(() => {
align-items: center; align-items: center;
margin-top: auto; margin-top: auto;
padding-top: 16px; padding-top: 16px;
border-top: 1px solid #f0f0f0;
flex-shrink: 0; flex-shrink: 0;
} }
@ -3838,17 +3676,17 @@ onMounted(() => {
} }
.exam-status-text { .exam-status-text {
font-size: 14px; font-size: 12px;
color: #666; color: #999;
} }
.exam-action-right { .exam-action-right {
display: flex; display: flex;
gap: 10px;
} }
.action-btn { .action-btn {
padding: 6px 16px; padding: 6px 16px;
border-radius: 4px;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
cursor: pointer; cursor: pointer;
@ -3858,9 +3696,9 @@ onMounted(() => {
} }
.upcoming-btn { .upcoming-btn {
background: #f5f5f5; background: #F5F8FB;
color: #999; color: #999999;
border: 1px solid #e8e8e8; border: none;
} }
.upcoming-btn:hover { .upcoming-btn:hover {
@ -3868,7 +3706,7 @@ onMounted(() => {
} }
.ongoing-btn { .ongoing-btn {
background: #1890ff; background: #0288D1;
color: white; color: white;
} }
@ -3877,12 +3715,12 @@ onMounted(() => {
} }
.finished-btn { .finished-btn {
background: #52c41a; background: #0288D1;
color: white; color: white;
} }
.finished-btn:hover { .finished-btn:hover {
background: #73d13d; background: #01579B;
} }
.files-container { .files-container {
@ -3907,8 +3745,8 @@ onMounted(() => {
} }
.files-icon { .files-icon {
width: 15px; width: 15px;
height: 15px; height: 15px;
} }
.course-name { .course-name {
@ -4095,9 +3933,9 @@ onMounted(() => {
.text_12, .text_12,
.text_13, .text_13,
.text_14 { .text_14 {
font-size: 2.5vw; font-size: 2.16px;
/* 手机端调整字体大小 */ /* 手机端调整字体大小 */
padding: 0.8vh 0; padding: 10px 0;
/* 保持无左右内边距 */ /* 保持无左右内边距 */
} }
@ -4365,7 +4203,7 @@ onMounted(() => {
.text_16 { .text_16 {
font-size: 0.83vw; font-size: 0.83vw;
/* 16px转换为vw */
} }
.text_19 { .text_19 {
@ -4537,24 +4375,28 @@ onMounted(() => {
/* 考试详情页面样式 */ /* 考试详情页面样式 */
.exam-detail-overlay { .exam-detail-overlay {
position: fixed; position: fixed;
top: 0; top: 60px;
/* 留出导航栏的空间 */
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: calc(100% - 60px);
/* 减去导航栏的高度 */
background: #f5f5f5; background: #f5f5f5;
z-index: 1000; z-index: 999;
/* 降低z-index确保导航栏可见 */
overflow-y: auto; overflow-y: auto;
} }
.exam-detail-container { .exam-detail-container {
max-width: 1200px;
margin: 0 auto; margin: 0 auto;
background: #f5f5f5; background: #f5f5f5;
min-height: 100vh; min-height: 100vh;
} }
.exam-detail-header { .exam-detail-header {
padding: 16px 24px; margin: auto;
width: 1420px;
padding: 24px 0;
background: #f5f5f5; background: #f5f5f5;
} }
@ -4609,9 +4451,11 @@ onMounted(() => {
} }
.exam-detail-content { .exam-detail-content {
margin: auto;
max-width: 1420px;
display: flex; display: flex;
gap: 24px; gap: 24px;
padding: 24px; padding: 0;
background: #f5f5f5; background: #f5f5f5;
} }
@ -4944,12 +4788,28 @@ onMounted(() => {
} }
.stat-label { .stat-label {
color: #666; font-size: 10px;
color: #497087;
} }
.stat-value { .stat-value {
margin-left: 20px;
color: #333; color: #333;
font-weight: 500; 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 { .answer-stats {
@ -5179,7 +5039,7 @@ onMounted(() => {
width: 100%; width: 100%;
} }
.practice-grid { .exam-grid {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
gap: 20px; gap: 20px;
@ -5213,16 +5073,16 @@ onMounted(() => {
.practice-score-badge { .practice-score-badge {
position: absolute; position: absolute;
top: 15px; top: 11px;
right: 15px; right: 18px;
background: #fff2e8; background: white;
border: 1px solid #ffb366; border: 1px solid #FF6F0F;
border-radius: 4px; border-radius: 4px;
padding: 4px 8px; padding: 0 11px;
} }
.practice-details { .practice-details {
margin-bottom: 16px; margin-bottom: 10px;
} }
.practice-meta-item { .practice-meta-item {
@ -5246,12 +5106,19 @@ onMounted(() => {
.practice-stats { .practice-stats {
display: flex; display: flex;
gap: 16px; gap: 16px;
margin-bottom: 16px; height: 54px;
padding: 12px; background: #F5F8FB;
background: #f8f9fa; align-items: center;
border-radius: 6px; justify-content: space-evenly;
} }
.divider {
width: 1px;
height: 20px;
background: #EBEBEB;
}
.stats-item { .stats-item {
display: flex; display: flex;
flex-direction: column; flex-direction: column;