Files
spring-festival-greetings/pages/index/index.vue

620 lines
14 KiB
Vue
Raw Normal View History

2026-01-09 11:24:40 +08:00
<template>
2026-02-23 22:36:31 +08:00
<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>
2026-02-08 19:07:06 +08:00
</view>
</view>
2026-02-23 22:36:31 +08:00
<!-- 红色 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>
2026-01-15 08:43:10 +08:00
<image
2026-02-23 22:36:31 +08:00
class="hero-bg-decor"
src="https://file.lihailezzc.com/resource/58c8d19e5f2d9c958a7b8b9f44b8c3e3.png"
2026-01-15 08:43:10 +08:00
mode="aspectFill"
/>
2026-01-09 11:24:40 +08:00
</view>
</view>
2026-02-23 22:36:31 +08:00
<!-- 今日问候 -->
<view class="daily-greeting-bar" @tap="onDailyGreetingTap">
<view class="bar-left">
<view class="icon-box calendar-icon">📅</view>
<text class="bar-text">今日问候 · 传递好心情</text>
2026-01-22 23:54:56 +08:00
</view>
2026-02-23 22:36:31 +08:00
<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>
2026-01-22 23:54:56 +08:00
</view>
</view>
2026-02-23 22:36:31 +08:00
<view class="fortune-btn" @tap="onFortuneTap">立即抽签</view>
2026-01-22 23:54:56 +08:00
</view>
2026-02-23 22:36:31 +08:00
<!-- 快捷标签 -->
<!-- <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>
2026-01-09 11:24:40 +08:00
</view>
2026-02-23 22:36:31 +08:00
</view> -->
<!-- 排行榜 Tab -->
<view class="ranking-section">
<view class="tabs-header">
2026-01-09 11:24:40 +08:00
<view
2026-02-23 22:36:31 +08:00
v-for="(tab, index) in tabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@tap="switchTab(index)"
2026-01-09 11:24:40 +08:00
>
2026-02-23 22:36:31 +08:00
{{ 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>
2026-01-09 11:24:40 +08:00
</view>
2026-02-23 22:36:31 +08:00
<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>
2026-01-23 00:01:31 +08:00
</view>
2026-01-09 11:24:40 +08:00
</view>
2026-02-23 22:36:31 +08:00
<view class="item-action">
<button class="use-btn" @tap.stop="onUseTap(item)">立即使用</button>
</view>
2026-01-09 11:24:40 +08:00
</view>
</view>
</view>
</view>
2026-02-23 22:36:31 +08:00
<!-- 底部占位防止被 TabBar 遮挡 -->
<view class="bottom-spacer"></view>
2026-01-09 11:24:40 +08:00
</view>
</template>
<script setup>
2026-02-23 22:36:31 +08:00
import { ref, onMounted } from "vue";
2026-01-15 08:43:10 +08:00
import { getBavBarHeight } from "@/utils/system";
2026-02-23 22:36:31 +08:00
import { onShow, onLoad } from "@dcloudio/uni-app";
import { useUserStore } from "@/stores/user";
import { getTitleBarHeight } from "@/utils/system";
2026-01-09 11:24:40 +08:00
2026-02-23 22:36:31 +08:00
const userStore = useUserStore();
2026-01-22 22:19:41 +08:00
2026-02-23 22:36:31 +08:00
const showheroSection = ref(false);
2026-01-22 22:19:41 +08:00
2026-02-23 22:36:31 +08:00
// 用户信息
const userInfo = ref(userStore?.userInfo || {
avatarUrl: "",
nickName: "哎萌",
2026-01-22 22:19:41 +08:00
});
2026-02-23 22:36:31 +08:00
const greetingText = ref("早上好");
// 快捷标签数据
const quickTags = ref([
{ text: "开心", icon: "😊" },
{ text: "暴富", icon: "🧧" },
{ text: "团圆", icon: "🏠" },
{ text: "好运", icon: "✨" },
]);
2026-01-22 22:19:41 +08:00
2026-02-23 22:36:31 +08:00
// Tab 数据
const tabs = ref([
{ name: "热门头像框", type: "avatar" },
{ name: "热门模板", type: "template" },
{ name: "热门壁纸", type: "wallpaper" },
]);
const currentTab = ref(0);
2026-02-08 19:07:06 +08:00
2026-02-23 22:36:31 +08:00
// 排行榜数据
const rankingList = ref([
2026-01-15 08:43:10 +08:00
{
2026-02-23 22:36:31 +08:00
title: "马到成功金边头像框",
usageCount: "12.5w",
thumb: "https://file.lihailezzc.com/resource/avatar_frame_horse_gold.png",
id: 1,
2026-01-15 08:43:10 +08:00
},
{
2026-02-23 22:36:31 +08:00
title: "龙年大吉祥云框",
usageCount: "8.2w",
thumb: "https://file.lihailezzc.com/resource/avatar_frame_dragon_cloud.png",
id: 2,
2026-01-15 08:43:10 +08:00
},
{
2026-02-23 22:36:31 +08:00
title: "瑞雪兆丰年背景",
usageCount: "5.7w",
thumb: "https://file.lihailezzc.com/resource/wallpaper_snow_red.png",
id: 3,
2026-01-15 08:43:10 +08:00
},
2026-02-23 22:36:31 +08:00
// 更多模拟数据...
2026-01-15 08:43:10 +08:00
]);
2026-01-09 11:24:40 +08:00
2026-02-23 22:36:31 +08:00
const navBarHeight = ref(64);
const statusBarHeight = ref(20);
2026-01-28 15:44:30 +08:00
2026-02-23 22:36:31 +08:00
onMounted(() => {
const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = systemInfo.statusBarHeight || 20;
navBarHeight.value = statusBarHeight.value + getTitleBarHeight();
});
2026-01-28 15:44:30 +08:00
2026-02-23 22:36:31 +08:00
const switchTab = (index) => {
currentTab.value = index;
// TODO: 切换数据逻辑
2026-01-28 15:44:30 +08:00
};
2026-02-23 22:36:31 +08:00
const onDailyGreetingTap = () => {
uni.showToast({ title: "今日问候", icon: "none" });
2026-01-28 15:44:30 +08:00
};
2026-02-23 22:36:31 +08:00
const onFortuneTap = () => {
uni.navigateTo({ url: "/pages/fortune/index" });
2026-01-28 15:44:30 +08:00
};
2026-02-23 22:36:31 +08:00
const onTagTap = (tag) => {
uni.showToast({ title: "点击了 " + tag.text, icon: "none" });
};
2026-01-28 15:55:26 +08:00
2026-02-23 22:36:31 +08:00
const onItemTap = (item) => {
console.log("Item tapped", item);
2026-01-28 15:44:30 +08:00
};
2026-01-09 11:24:40 +08:00
2026-02-23 22:36:31 +08:00
const onUseTap = (item) => {
uni.navigateTo({
url: `/pages/avatar/index?id=${item.id}`,
2026-02-12 17:22:47 +08:00
});
2026-01-15 08:43:10 +08:00
};
2026-01-09 11:24:40 +08:00
2026-02-23 22:36:31 +08:00
onLoad(() => {
// 初始化逻辑
2026-01-15 08:43:10 +08:00
});
2026-01-09 11:24:40 +08:00
</script>
<style lang="scss" scoped>
2026-02-23 22:36:31 +08:00
.home-container {
2026-01-09 11:24:40 +08:00
min-height: 100vh;
2026-02-23 22:36:31 +08:00
background-color: #f5f7fa;
padding-bottom: 20rpx;
2026-01-09 11:24:40 +08:00
box-sizing: border-box;
}
2026-02-23 22:36:31 +08:00
/* 顶部用户信息栏 */
.header-section {
2026-02-08 19:07:06 +08:00
display: flex;
justify-content: space-between;
2026-02-23 22:36:31 +08:00
align-items: center;
padding: 20rpx 30rpx;
background-color: #fff;
.user-info {
2026-02-08 19:07:06 +08:00
display: flex;
align-items: center;
2026-02-23 22:36:31 +08:00
.user-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 20rpx;
border: 2rpx solid #f0f0f0;
2026-02-08 19:13:02 +08:00
}
2026-02-23 22:36:31 +08:00
.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;
2026-02-08 19:13:02 +08:00
}
2026-02-08 19:07:06 +08:00
}
}
2026-02-23 22:36:31 +08:00
.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;
}
}
2026-02-08 19:07:06 +08:00
}
}
2026-02-23 22:36:31 +08:00
/* 红色 Banner 区域 */
.hero-section {
padding: 20rpx 30rpx;
background-color: #fff;
padding-bottom: 40rpx;
border-bottom-left-radius: 40rpx;
border-bottom-right-radius: 40rpx;
.hero-card {
2026-01-15 08:43:10 +08:00
position: relative;
2026-02-23 22:36:31 +08:00
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;
2026-01-15 08:43:10 +08:00
display: flex;
2026-01-09 11:24:40 +08:00
flex-direction: column;
2026-02-23 22:36:31 +08:00
justify-content: center;
.hero-bg-decor {
position: absolute;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
opacity: 0.2;
z-index: 1;
2026-01-15 08:43:10 +08:00
}
2026-02-23 22:36:31 +08:00
.hero-tag {
position: absolute;
top: 40rpx;
left: 40rpx;
background-color: #ffca28;
color: #7f0000;
2026-01-15 08:43:10 +08:00
font-size: 22rpx;
2026-02-23 22:36:31 +08:00
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);
}
2026-01-15 08:43:10 +08:00
}
2026-01-09 11:24:40 +08:00
}
}
2026-02-23 22:36:31 +08:00
/* 今日问候条 */
.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 {
2026-01-22 23:54:56 +08:00
display: flex;
align-items: center;
2026-02-23 22:36:31 +08:00
.icon-box {
margin-right: 20rpx;
font-size: 36rpx;
2026-01-22 23:54:56 +08:00
}
2026-02-23 22:36:31 +08:00
.bar-text {
2026-01-22 23:54:56 +08:00
font-size: 30rpx;
2026-02-23 22:36:31 +08:00
font-weight: 600;
color: #333;
2026-01-22 23:54:56 +08:00
}
}
2026-02-23 22:36:31 +08:00
.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 {
2026-01-22 23:54:56 +08:00
display: flex;
2026-02-23 22:36:31 +08:00
align-items: center;
.fortune-icon-box {
width: 80rpx;
height: 80rpx;
background-color: #ffebee;
color: #d32f2f;
border-radius: 20rpx;
2026-01-22 23:54:56 +08:00
display: flex;
align-items: center;
2026-02-23 22:36:31 +08:00
justify-content: center;
font-size: 40rpx;
font-weight: bold;
margin-right: 24rpx;
2026-01-22 23:54:56 +08:00
}
2026-02-23 22:36:31 +08:00
.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;
}
2026-01-22 23:54:56 +08:00
}
}
2026-02-23 22:36:31 +08:00
.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);
}
2026-01-22 23:54:56 +08:00
}
2026-02-23 22:36:31 +08:00
/* 快捷标签 */
.quick-tags {
2026-01-15 08:43:10 +08:00
display: flex;
2026-02-23 22:36:31 +08:00
justify-content: space-between;
margin: 0 30rpx 40rpx;
.tag-item {
2026-01-15 08:43:10 +08:00
flex: 1;
2026-02-23 22:36:31 +08:00
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;
}
2026-01-15 08:43:10 +08:00
}
2026-01-09 11:24:40 +08:00
}
2026-02-23 22:36:31 +08:00
/* 排行榜 */
.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;
}
}
}
2026-01-23 00:01:31 +08:00
}
2026-02-23 22:36:31 +08:00
.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);
}
}
}
}
2026-01-23 00:01:31 +08:00
}
2026-01-15 08:43:10 +08:00
}
2026-01-28 15:44:30 +08:00
2026-02-23 22:36:31 +08:00
.bottom-spacer {
height: 40rpx;
2026-01-28 15:44:30 +08:00
}
2026-01-15 08:43:10 +08:00
</style>