Files
spring-festival-greetings/pages/index/index.vue
2026-02-23 22:36:31 +08:00

620 lines
14 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>
<view class="home-container" :style="{
height: navBarHeight + 'px',
paddingTop: statusBarHeight + 'px',
}">
<!-- 顶部用户信息栏 -->
<view class="header-section">
<view class="user-info">
<image
class="user-avatar"
:src="userInfo.avatarUrl || '/static/default-avatar.png'"
mode="aspectFill"
/>
<view class="user-texts">
<text class="greeting-text">{{ greetingText }}</text>
<text class="user-name">{{ userInfo.nickName || '新春福星' }}</text>
</view>
</view>
</view>
<!-- 红色 Banner 区域 (Hero) -->
<view v-if="!showheroSection" class="hero-section">
<view class="hero-card">
<view class="hero-tag">节日专题</view>
<view class="hero-content">
<text class="hero-title">除夕倒计时 · 团圆家宴</text>
<text class="hero-subtitle">定制您的专属新春祝福寄语</text>
</view>
<image
class="hero-bg-decor"
src="https://file.lihailezzc.com/resource/58c8d19e5f2d9c958a7b8b9f44b8c3e3.png"
mode="aspectFill"
/>
</view>
</view>
<!-- 今日问候 -->
<view class="daily-greeting-bar" @tap="onDailyGreetingTap">
<view class="bar-left">
<view class="icon-box calendar-icon">📅</view>
<text class="bar-text">今日问候 · 传递好心情</text>
</view>
<text class="bar-arrow"></text>
</view>
<!-- 今日运势 -->
<view class="fortune-card">
<view class="fortune-left">
<view class="fortune-icon-box"></view>
<view class="fortune-texts">
<text class="fortune-label">今日运势</text>
<text class="fortune-value">大吉 · 万事如意</text>
</view>
</view>
<view class="fortune-btn" @tap="onFortuneTap">立即抽签</view>
</view>
<!-- 快捷标签 -->
<!-- <view class="quick-tags">
<view
v-for="(tag, index) in quickTags"
:key="index"
class="tag-item"
@tap="onTagTap(tag)"
>
<text class="tag-icon">{{ tag.icon }}</text>
<text class="tag-text">{{ tag.text }}</text>
</view>
</view> -->
<!-- 排行榜 Tab -->
<view class="ranking-section">
<view class="tabs-header">
<view
v-for="(tab, index) in tabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@tap="switchTab(index)"
>
{{ tab.name }}
</view>
</view>
<view class="ranking-list">
<view
v-for="(item, index) in rankingList"
:key="index"
class="ranking-item"
:class="'rank-' + (index + 1)"
@tap="onItemTap(item)"
>
<view class="rank-badge-wrap" v-if="index < 3">
<view class="rank-badge">Top {{ index + 1 }}</view>
</view>
<view class="item-content">
<image class="item-thumb" :src="item.thumb" mode="aspectFill" />
<view class="item-info">
<text class="item-title">{{ item.title }}</text>
<view class="item-usage">
<text class="fire-icon">🔥</text>
<text>{{ item.usageCount }} 人已使用</text>
</view>
</view>
<view class="item-action">
<button class="use-btn" @tap.stop="onUseTap(item)">立即使用</button>
</view>
</view>
</view>
</view>
</view>
<!-- 底部占位防止被 TabBar 遮挡 -->
<view class="bottom-spacer"></view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { getBavBarHeight } from "@/utils/system";
import { onShow, onLoad } from "@dcloudio/uni-app";
import { useUserStore } from "@/stores/user";
import { getTitleBarHeight } from "@/utils/system";
const userStore = useUserStore();
const showheroSection = ref(false);
// 用户信息
const userInfo = ref(userStore?.userInfo || {
avatarUrl: "",
nickName: "哎萌",
});
const greetingText = ref("早上好");
// 快捷标签数据
const quickTags = ref([
{ text: "开心", icon: "😊" },
{ text: "暴富", icon: "🧧" },
{ text: "团圆", icon: "🏠" },
{ text: "好运", icon: "✨" },
]);
// Tab 数据
const tabs = ref([
{ name: "热门头像框", type: "avatar" },
{ name: "热门模板", type: "template" },
{ name: "热门壁纸", type: "wallpaper" },
]);
const currentTab = ref(0);
// 排行榜数据
const rankingList = ref([
{
title: "马到成功金边头像框",
usageCount: "12.5w",
thumb: "https://file.lihailezzc.com/resource/avatar_frame_horse_gold.png",
id: 1,
},
{
title: "龙年大吉祥云框",
usageCount: "8.2w",
thumb: "https://file.lihailezzc.com/resource/avatar_frame_dragon_cloud.png",
id: 2,
},
{
title: "瑞雪兆丰年背景",
usageCount: "5.7w",
thumb: "https://file.lihailezzc.com/resource/wallpaper_snow_red.png",
id: 3,
},
// 更多模拟数据...
]);
const navBarHeight = ref(64);
const statusBarHeight = ref(20);
onMounted(() => {
const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = systemInfo.statusBarHeight || 20;
navBarHeight.value = statusBarHeight.value + getTitleBarHeight();
});
const switchTab = (index) => {
currentTab.value = index;
// TODO: 切换数据逻辑
};
const onDailyGreetingTap = () => {
uni.showToast({ title: "今日问候", icon: "none" });
};
const onFortuneTap = () => {
uni.navigateTo({ url: "/pages/fortune/index" });
};
const onTagTap = (tag) => {
uni.showToast({ title: "点击了 " + tag.text, icon: "none" });
};
const onItemTap = (item) => {
console.log("Item tapped", item);
};
const onUseTap = (item) => {
uni.navigateTo({
url: `/pages/avatar/index?id=${item.id}`,
});
};
onLoad(() => {
// 初始化逻辑
});
</script>
<style lang="scss" scoped>
.home-container {
min-height: 100vh;
background-color: #f5f7fa;
padding-bottom: 20rpx;
box-sizing: border-box;
}
/* 顶部用户信息栏 */
.header-section {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 30rpx;
background-color: #fff;
.user-info {
display: flex;
align-items: center;
.user-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 20rpx;
border: 2rpx solid #f0f0f0;
}
.user-texts {
display: flex;
flex-direction: column;
.greeting-text {
font-size: 24rpx;
color: #666;
margin-bottom: 4rpx;
}
.user-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
}
}
.header-actions {
display: flex;
gap: 24rpx;
.action-btn {
width: 72rpx;
height: 72rpx;
background-color: #f5f7fa;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
.icon {
font-size: 36rpx;
}
}
}
}
/* 红色 Banner 区域 */
.hero-section {
padding: 20rpx 30rpx;
background-color: #fff;
padding-bottom: 40rpx;
border-bottom-left-radius: 40rpx;
border-bottom-right-radius: 40rpx;
.hero-card {
position: relative;
width: 100%;
height: 320rpx;
background: linear-gradient(135deg, #d32f2f 0%, #b71c1c 100%);
border-radius: 32rpx;
overflow: hidden;
box-shadow: 0 10rpx 30rpx rgba(211, 47, 47, 0.3);
padding: 40rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
.hero-bg-decor {
position: absolute;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
opacity: 0.2;
z-index: 1;
}
.hero-tag {
position: absolute;
top: 40rpx;
left: 40rpx;
background-color: #ffca28;
color: #7f0000;
font-size: 22rpx;
font-weight: bold;
padding: 6rpx 16rpx;
border-radius: 8rpx;
z-index: 2;
}
.hero-content {
margin-top: 40rpx;
z-index: 2;
.hero-title {
font-size: 44rpx;
font-weight: bold;
color: #fff;
display: block;
margin-bottom: 12rpx;
text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.1);
}
.hero-subtitle {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
}
}
}
}
/* 今日问候条 */
.daily-greeting-bar {
margin: -30rpx 30rpx 0;
background-color: #fff;
border-radius: 40rpx;
padding: 24rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.03);
position: relative;
z-index: 10;
.bar-left {
display: flex;
align-items: center;
.icon-box {
margin-right: 20rpx;
font-size: 36rpx;
}
.bar-text {
font-size: 30rpx;
font-weight: 600;
color: #333;
}
}
.bar-arrow {
font-size: 36rpx;
color: #ccc;
font-weight: bold;
}
}
/* 今日运势卡片 */
.fortune-card {
margin: 24rpx 30rpx;
background-color: #fff;
border-radius: 32rpx;
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.03);
.fortune-left {
display: flex;
align-items: center;
.fortune-icon-box {
width: 80rpx;
height: 80rpx;
background-color: #ffebee;
color: #d32f2f;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 40rpx;
font-weight: bold;
margin-right: 24rpx;
}
.fortune-texts {
display: flex;
flex-direction: column;
.fortune-label {
font-size: 24rpx;
color: #999;
margin-bottom: 4rpx;
}
.fortune-value {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
}
}
.fortune-btn {
background-color: #d32f2f;
color: #fff;
font-size: 26rpx;
padding: 14rpx 32rpx;
border-radius: 40rpx;
font-weight: 600;
box-shadow: 0 4rpx 10rpx rgba(211, 47, 47, 0.3);
}
}
/* 快捷标签 */
.quick-tags {
display: flex;
justify-content: space-between;
margin: 0 30rpx 40rpx;
.tag-item {
flex: 1;
background-color: #fff;
margin: 0 10rpx;
padding: 20rpx 0;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.02);
&:first-child { margin-left: 0; }
&:last-child { margin-right: 0; }
.tag-icon {
font-size: 32rpx;
margin-right: 12rpx;
}
.tag-text {
font-size: 28rpx;
color: #555;
font-weight: 500;
}
}
}
/* 排行榜 */
.ranking-section {
padding: 0 30rpx;
.tabs-header {
display: flex;
justify-content: space-around;
background-color: #f5f7fa; /* 这里的背景色与页面一致,但可以调整 */
padding-bottom: 30rpx;
.tab-item {
font-size: 30rpx;
color: #888;
padding: 10rpx 0;
position: relative;
font-weight: 500;
transition: all 0.3s;
&.active {
color: #d32f2f;
font-weight: bold;
font-size: 32rpx;
&::after {
content: '';
position: absolute;
bottom: -6rpx;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 6rpx;
background-color: #d32f2f;
border-radius: 6rpx;
}
}
}
}
.ranking-list {
.ranking-item {
background-color: #fff;
border-radius: 24rpx;
margin-bottom: 24rpx;
padding: 24rpx;
position: relative;
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.03);
border: 2rpx solid transparent; /* 默认无边框 */
/* Top 1 金色边框 */
&.rank-1 {
border-color: #ffca28;
.rank-badge-wrap .rank-badge { background-color: #ffca28; color: #7f0000; }
}
/* Top 2 银色边框 */
&.rank-2 {
border-color: #cfd8dc;
.rank-badge-wrap .rank-badge { background-color: #b0bec5; color: #fff; }
}
/* Top 3 铜色边框 */
&.rank-3 {
border-color: #ffcc80; /* 铜色近似 */
.rank-badge-wrap .rank-badge { background-color: #d89647; color: #fff; }
}
.rank-badge-wrap {
position: absolute;
top: -16rpx;
left: 20rpx;
z-index: 10;
.rank-badge {
font-size: 20rpx;
font-weight: bold;
padding: 6rpx 16rpx;
border-radius: 20rpx;
box-shadow: 0 4rpx 8rpx rgba(0,0,0,0.1);
}
}
.item-content {
display: flex;
align-items: center;
.item-thumb {
width: 140rpx;
height: 140rpx;
border-radius: 20rpx;
background-color: #eee;
flex-shrink: 0;
}
.item-info {
flex: 1;
margin-left: 24rpx;
display: flex;
flex-direction: column;
justify-content: center;
.item-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 12rpx;
}
.item-usage {
display: flex;
align-items: center;
font-size: 24rpx;
color: #999;
.fire-icon {
color: #ff5722;
margin-right: 8rpx;
font-size: 26rpx;
}
}
}
.item-action {
.use-btn {
background-color: #d32f2f;
color: #fff;
font-size: 24rpx;
padding: 0 30rpx;
height: 60rpx;
line-height: 60rpx;
border-radius: 30rpx;
font-weight: 600;
margin: 0;
box-shadow: 0 4rpx 10rpx rgba(211, 47, 47, 0.3);
}
}
}
}
}
}
.bottom-spacer {
height: 40rpx;
}
</style>