2025-10-09 14:49:41 +08:00

521 lines
10 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="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="activity.banner || activity.imgs || '/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" v-html="activity.introduction">
</div>
</div>
<!-- 活动详情 -->
<div class="activity-details">
<div class="activity-meta-item">
<span class="meta-label">开始时间</span>
<span class="meta-value">{{ activity.startTime }}</span>
</div>
<div class="activity-meta-item">
<span class="meta-label">结束时间</span>
<span class="meta-value">{{ activity.endTime }}</span>
</div>
<div class="activity-meta-item">
<span class="meta-label">最大人数</span>
<span class="meta-value">{{ activity.maxNum }}</span>
</div>
</div>
<!-- 活动底部 -->
<div class="activity-footer">
<div class="activity-action-right">
<!-- <button v-if="activity.status === '1'" class="action-btn ongoing-btn"
@click="continueActivity(activity.id)">
查看活动
</button> -->
<button
class="action-btn ongoing-btn" @click="viewActivityDetail(activity.id)">
查看详情
</button>
</div>
<div class="activity-status-left">
<span :class="['activity-status-text', activity.status === '1' ? 'ongoing' : 'finished']">
{{ activity.status_dictText }}
</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useMessage } from 'naive-ui'
import { useRouter } from 'vue-router'
import { ActivityListApi } from '@/api/modules/userCenter'
const message = useMessage()
const router = useRouter()
// 活动接口
interface Activity {
id: string
title: string
introduction: string
imgs: string
banner: string
video: string | null
maxNum: number
startTime: string
endTime: string
extra: string | null
attachment: string
status: string
createBy: string
createTime: string
updateBy: string
updateTime: string
status_dictText: string
}
// 活动筛选状态
const activeActivityTab = ref('all')
// 活动列表数据
const activities = ref<Activity[]>([])
// 获取筛选后的活动
const filteredActivities = computed(() => {
if (activeActivityTab.value === 'ongoing') {
return activities.value.filter(activity => activity.status === '1')
} else if (activeActivityTab.value === 'finished') {
return activities.value.filter(activity => activity.status !== '1')
}
return activities.value
})
// 处理活动筛选变化
const handleActivityTabChange = (tab: string) => {
activeActivityTab.value = tab
}
// 继续活动
// const continueActivity = (id: string) => {
// console.log('继续活动:', id)
// message.info(`继续活动 ${id}`)
// }
// 查看活动详情
const viewActivityDetail = (id: string) => {
router.push(`/activity/${id}`)
}
onMounted(async () => {
try {
const response = await ActivityListApi.getActivityList()
console.log('活动列表:', response.data.result)
activities.value = response.data.result.records || []
} catch (error) {
message.error('请求活动列表时发生错误')
console.error(error)
}
})
</script>
<style scoped>
/* 活动页面样式 - 网格布局 */
.activity-content {
width: 100%;
}
/* 课程筛选标签 */
.text-wrapper_1 {
width: 100%;
height: 2.08vh;
align-items: center;
margin: 20px 0 20px 0;
gap: 2.81vw;
}
.text_12,
.text_13,
.text_14 {
font-size: 0.94vw;
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 {
color: rgba(2, 134, 206, 1);
}
.text_12:hover,
.text_13:hover,
.text_14:hover {
color: rgba(2, 134, 206, 1);
}
/* 课程区域分割线 */
.course-divider {
width: 100%;
height: 1.5px;
background: #E6E6E6;
margin-bottom: 1.67vh;
}
.activity-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1.04vw;
margin-top: 1.04vh;
}
.activity-card {
background: #ffffff;
border: 1px solid #e8e8e8;
padding: 0;
position: relative;
min-height: 14.58vh;
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);
transform: translateY(-0.1vh);
}
/* 活动卡片顶部图片容器 */
.activity-card-image {
width: 100%;
height: 179px;
overflow: hidden;
}
/* 活动卡片图片 */
.activity-image {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.activity-score-badge {
position: absolute;
top: 0.83vw;
right: 0.83vw;
background: #FF6B35;
color: white;
padding: 0.21vw 0.42vw;
border-radius: 0.21vw;
font-size: 0.63vw;
font-weight: 500;
z-index: 1;
}
.activity-title {
font-size: 16px;
color: #333;
margin: 15px 0 5px 0;
line-height: 1.4;
padding: 0 1.04vw;
font-weight: 600;
}
.activity-details {
padding: 0 1.04vw;
}
.activity-meta-item {
margin-bottom: 10px;
font-size: 14px;
line-height: 1.4;
display: flex;
}
.meta-label {
color: #999;
min-width: 70px;
}
.meta-value {
color: #333;
font-weight: 500;
}
.activity-intro {
flex: 1;
margin-bottom: 1.04vh;
padding: 0 1.04vw;
}
.intro-title {
font-size: 0.73vw;
font-weight: 600;
color: #333;
margin-bottom: 0.42vh;
}
.intro-content {
font-size: 14px;
color: #666;
line-height: 1.5;
margin-bottom: 10px;
-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;
flex-shrink: 0;
}
.activity-status-left {
display: flex;
align-items: center;
}
.activity-status-text {
font-size: 12px;
font-weight: 500;
}
/* 活动状态颜色 - 与练习中保持一致 */
.activity-status-text.ongoing {
color: #FF520F;
}
.activity-status-text.finished {
color: #999999;
}
.activity-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;
}
.ongoing-btn {
background: #0288D1;
color: white;
}
.ongoing-btn:hover {
background: #40a9ff;
}
.finished-btn {
background: #0288D1;
color: white;
}
.finished-btn:hover {
background: #01579B;
}
/* 活动已结束按钮样式 - 灰色 */
.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;
}
/* 通用样式 */
.flex-row {
display: flex;
flex-direction: row;
align-items: center;
}
/* 活动响应式设计 */
@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;
}
.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%;
}
}
/* 更小屏幕的适配 */
@media (max-width: 480px) {
.activity-card {
padding: 0;
min-height: 220px;
}
.activity-title {
font-size: 14px;
}
.activity-score-badge {
top: 12px;
right: 12px;
}
}
@media (max-width: 576px) {
.text-wrapper_1 {
gap: 0.83vw;
}
.text_12,
.text_13,
.text_14 {
font-size: 0.83vw;
padding: 0.31vh 0.63vw;
}
}
</style>