topfans/frontend/pages/components/JianmianContent.vue
2026-04-07 23:08:49 +08:00

314 lines
5.9 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>
<scroll-view class="jianmian-scroll" scroll-y>
<view class="jianmian-container">
<!-- 大卡片票务海报 -->
<view class="big-card">
<view class="big-card-surface">
<image class="card-bg" src="/static/starcity/jianmian/ticket-poster.png" mode="aspectFill"></image>
<view class="card-gradient-mask"></view>
<view class="big-card-content">
<text class="hero-title">首场内场门票</text>
<view class="hero-bottom-row">
<text class="hero-subtitle">盲盒开启中</text>
<text class="hero-price">100星钻/</text>
</view>
</view>
</view>
<image class="new-badge" src="/static/icon/new-badge.png" mode="aspectFit"></image>
</view>
<!-- 热门推荐组件 -->
<view class="recommend-card">
<view class="recommend-surface">
<view class="rec-tab-bar">
<view
v-for="(tab, index) in recTabs"
:key="index"
class="rec-tab-item"
:class="{ active: activeRecTab === index }"
@click="activeRecTab = index"
>
<text class="rec-tab-text">{{ tab }}</text>
<view v-if="activeRecTab === index" class="rec-tab-indicator"></view>
</view>
</view>
<view class="activity-row">
<image
class="activity-cover"
src="/static/starcity/jianmian/ticket-card.png"
mode="aspectFill"
></image>
<view class="activity-info">
<text class="activity-title">肖战「最好的地方」巡回演唱会</text>
<text class="activity-sub">2个城市巡演中</text>
</view>
</view>
</view>
</view>
<!-- ③ 他的资讯组件 -->
<view class="news-card">
<view class="news-surface">
<text class="news-title">他的资讯</text>
<view class="news-grid">
<view
v-for="(item, index) in newsItems"
:key="index"
class="news-item"
>
<view class="news-item-surface">
<image class="news-cover" :src="item.image" mode="aspectFill"></image>
</view>
<image class="new-badge-small" src="/static/icon/new-badge.png" mode="aspectFit"></image>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</template>
<script setup>
import { ref } from 'vue';
const recTabs = ['热门推荐', '周边', '资讯'];
const activeRecTab = ref(0);
const newsItems = [
{ image: '/static/starcity/jianmian/ticket-card2.png' },
{ image: '/static/starcity/jianmian/ticket-card3.png' }
];
</script>
<style scoped>
.jianmian-scroll {
width: 100%;
height: 100%;
background: transparent;
}
.jianmian-container {
padding: 24rpx 24rpx 200rpx;
box-sizing: border-box;
}
/* ===== 大卡片 ===== */
.big-card {
position: relative;
width: 100%;
overflow: visible;
margin-bottom: 20rpx;
}
.big-card-surface {
position: relative;
min-height: 380rpx;
border-radius: 24rpx;
overflow: hidden;
}
.card-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.card-gradient-mask {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 60%;
background: linear-gradient(to top, rgba(0, 0, 0, 0.72) 0%, transparent 100%);
z-index: 1;
}
.big-card-content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
padding: 24rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.hero-title {
font-size: 52rpx;
font-weight: 900;
color: #fff;
line-height: 1.2;
text-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.6);
}
.hero-bottom-row {
display: flex;
flex-direction: row;
align-items: flex-end;
justify-content: space-between;
margin-top: 4rpx;
}
.hero-subtitle {
font-size: 48rpx;
font-weight: 900;
color: #fff;
line-height: 1.2;
text-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.6);
}
.hero-price {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.85);
border: 1rpx solid rgba(255, 255, 255, 0.5);
border-radius: 24rpx;
padding: 6rpx 18rpx;
margin-bottom: 4rpx;
flex-shrink: 0;
}
.new-badge {
position: absolute;
top: -40rpx;
right: -24rpx;
width: 29%;
height: 29%;
z-index: 20;
}
/* ===== 热门推荐组件 ===== */
.recommend-card {
margin-bottom: 20rpx;
}
.recommend-surface {
border-radius: 20rpx;
background: rgba(0, 0, 0, 0.55);
overflow: hidden;
}
.rec-tab-bar {
display: flex;
flex-direction: row;
padding: 20rpx 24rpx 0;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.12);
}
.rec-tab-item {
padding: 10rpx 16rpx 16rpx;
position: relative;
}
.rec-tab-indicator {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 36rpx;
height: 4rpx;
background: #fff;
border-radius: 2rpx;
}
.rec-tab-text {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.5);
transition: all 0.2s ease;
}
.rec-tab-item.active .rec-tab-text {
color: #fff;
font-weight: bold;
font-size: 28rpx;
}
.activity-row {
display: flex;
flex-direction: row;
align-items: center;
padding: 20rpx 24rpx;
border-top: 1rpx solid rgba(255, 255, 255, 0.1);
}
.activity-cover {
width: 120rpx;
height: 160rpx;
border-radius: 10rpx;
flex-shrink: 0;
}
.activity-info {
flex: 1;
margin-left: 20rpx;
display: flex;
flex-direction: column;
}
.activity-title {
font-size: 28rpx;
color: #fff;
font-weight: 600;
line-height: 1.4;
}
.activity-sub {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.6);
margin-top: 12rpx;
}
/* ===== 他的资讯组件 ===== */
.news-surface {
border-radius: 20rpx;
background: rgba(0, 0, 0, 0.55);
padding: 24rpx;
box-sizing: border-box;
}
.news-title {
display: block;
font-size: 30rpx;
color: #fff;
font-weight: bold;
margin-bottom: 20rpx;
}
.news-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16rpx;
}
.news-item {
position: relative;
overflow: visible;
}
.news-item-surface {
border-radius: 16rpx;
overflow: hidden;
aspect-ratio: 3 / 4;
}
.news-cover {
width: 100%;
height: 100%;
}
.new-badge-small {
position: absolute;
top: -18rpx;
right: -18rpx;
width: 34%;
height: 34%;
z-index: 20;
}
</style>