521 lines
10 KiB
Vue
521 lines
10 KiB
Vue
<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> |