620 lines
14 KiB
Vue
620 lines
14 KiB
Vue
<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>
|