Files
spring-festival-greetings/pages/index/index.vue
2026-01-22 22:19:41 +08:00

462 lines
11 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="spring-page" :style="{ paddingTop: getBavBarHeight() + 'px' }">
<!-- 顶部 Banner -->
<view class="hero">
<view class="hero-badge">
<text class="badge-dot"></text>
<text class="badge-text">{{ countdownText }}</text>
</view>
<view class="hero-title">
<text class="year">2026</text>
<text class="main">新春祝福</text>
</view>
<text class="hero-sub">新年快乐万事如意!</text>
<!-- <image class="hero-decor" src="https://file.lihailezzc.com/resource/58c8d19e5f2d9c958a7b8b9f44b8c3e3.png" mode="aspectFill" /> -->
</view>
<!-- 功能入口宫格 -->
<view class="feature-grid">
<view
v-for="(item, idx) in features"
:key="idx"
class="feature-item"
@tap="onFeatureTap(item)"
>
<image
class="feature-icon"
:src="item.icon"
mode="aspectFill"
:style="{
backgroundColor: idx < 2 ? '#FEF2F2' : '#FFFBEC',
}"
/>
<view class="feature-texts">
<text class="feature-title">{{ item.title }}</text>
<text class="feature-sub">{{ item.subtitle }}</text>
</view>
</view>
</view>
<!-- 大家都在用竖向列表左图右文 -->
<view class="section">
<view class="section-header">
<view class="section-bar"></view>
<text class="section-title">大家都在用</text>
<text class="section-more" @tap="onMore('use')">查看更多 ></text>
</view>
<view class="use-list">
<view
v-for="(card, i) in popularCards"
:key="i"
class="use-row"
@tap="previewCard(card)"
>
<view class="thumb-wrap">
<image :src="card.cover" class="thumb" mode="aspectFill" />
<view v-if="card.type === 'video'" class="thumb-play"></view>
</view>
<view class="use-right">
<view class="title-line">
<text class="use-title">{{ card.title }}</text>
<text
v-if="card.tag"
class="tag"
:class="`tag--${card.tagType || 'default'}`"
>{{ card.tag }}</text
>
</view>
<text class="use-desc">{{ card.desc }}</text>
<text class="use-cta" @tap.stop="onCta(card)"
>{{ card.cta }} ></text
>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { onPullDownRefresh, onShareAppMessage } from "@dcloudio/uni-app";
import { getBavBarHeight } from "@/utils/system";
const countdownText = ref("");
const updateCountdown = () => {
const now = new Date();
const springFestival = new Date("2026-02-17T00:00:00"); // 2026春节
// 只比较日期,忽略时分秒
now.setHours(0, 0, 0, 0);
springFestival.setHours(0, 0, 0, 0);
const diffTime = now.getTime() - springFestival.getTime();
const days = Math.floor(diffTime / (1000 * 60 * 60 * 24));
if (days < 0) {
countdownText.value = `距春节还有 ${Math.abs(days)}`;
} else if (days === 0) {
countdownText.value = "大年初一";
} else {
const cnNums = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"];
if (days < 10) {
countdownText.value = `大年初${cnNums[days]}`;
} else if (days < 15) {
const sub = days + 1 - 10;
const subCn = ["一", "二", "三", "四", "五"][sub - 1];
countdownText.value = `正月十${subCn}`;
} else if (days === 14) {
// days=14是第15天
countdownText.value = "元宵节";
} else {
countdownText.value = "蛇年大吉";
}
}
};
onMounted(() => {
updateCountdown();
});
const features = ref([
{
title: "新春祝福卡片",
subtitle: "定制专属贺卡",
icon: "/static/icon/celebrate.png",
type: "card",
},
{
title: "红包封面",
subtitle: "获取新年红包封面",
icon: "/static/icon/hongbao.png",
type: "video",
},
{
title: "新春头像",
subtitle: "焕上节日新饰",
icon: "/static/icon/guashi.png",
type: "avatar_decor",
},
{
title: "新年运势",
subtitle: "抽取新年关键词",
icon: "/static/icon/yunshi.png",
type: "fortune",
},
]);
const popularCards = ref([
{
title: "招财进宝金框",
tag: "热门",
tagType: "hot",
desc: "2026马年限定汉字金框金光闪烁财运亨通。适合送亲友的新春祝福。",
cta: "立即制作",
cover:
"https://file.lihailezzc.com/9a929a32-439f-453b-b603-fda7b04cbe08.png",
},
{
title: "大吉大利卡片",
tag: "精选",
tagType: "featured",
desc: "经典红色大拜年卡片,适合送长辈、老师、同学,传递满满的新春喜气。",
cta: "去写祝福",
cover:
"https://file.lihailezzc.com/b5fe8ffb-5901-48d2-94fb-48191e36cbf5.png",
},
{
title: "合家团圆模板",
tag: "爆款",
tagType: "hot2",
desc: "一键生成合家福贺图,支持换装、特效装饰、朋友圈海报等。",
cta: "开始创作",
cover:
"https://file.lihailezzc.com/91cd1611-bb87-442b-a338-24e9d79e4ee9.png",
type: "video",
},
]);
const onFeatureTap = (item) => {
if (item.type === "avatar_decor" || item.type === "avatar_frame") {
uni.navigateTo({ url: "/pages/avatar/index" });
return;
}
if (item.type === "fortune") {
uni.navigateTo({ url: "/pages/fortune/index" });
return;
}
if (item.type === "card") {
uni.navigateTo({ url: "/pages/make/index" });
return;
}
uni.showToast({ title: `进入:${item.title}`, icon: "none" });
};
const previewCard = (card) => {
uni.previewImage({ urls: [card.cover] });
};
const onMore = () => {
uni.showToast({ title: "更多模板即将上线~", icon: "none" });
};
const onCta = (card) => {
uni.showToast({ title: `${card.cta} · ${card.title}`, icon: "none" });
};
onPullDownRefresh(() => {
setTimeout(() => {
uni.stopPullDownRefresh();
uni.showToast({ title: "已为你更新内容", icon: "success" });
}, 600);
});
onShareAppMessage(() => {
return {
title: "新春祝福",
path: "/pages/detail/index",
imageUrl: "/static/images/bg.jpg",
success: function (res) {
uni.showToast({ title: "分享成功", icon: "success" });
},
fail: function (res) {
uni.showToast({ title: "分享失败", icon: "none" });
},
};
});
</script>
<style lang="scss" scoped>
.spring-page {
min-height: 100vh;
box-sizing: border-box;
background: #f8f6f6;
}
/* 顶部 Banner */
.hero {
position: relative;
margin: 24rpx auto;
padding: 32rpx;
height: 324rpx;
width: 92vw;
border-radius: 24rpx;
color: #fff;
background: url("http://file.lihailezzc.com/77ea2597-569c-4f13-b5af-22606742adcfssss.jpg");
background-size: cover;
overflow: hidden;
.hero-badge {
display: inline-flex;
align-items: center;
background: rgba(255, 255, 255, 0.2);
border-radius: 999rpx;
padding: 8rpx 16rpx;
font-size: 22rpx;
.badge-dot {
margin-right: 8rpx;
}
}
.hero-title {
margin-top: 24rpx;
display: flex;
align-items: baseline;
.year {
font-size: 44rpx;
font-weight: 700;
margin-right: 12rpx;
}
.main {
font-size: 44rpx;
font-weight: 700;
}
}
.hero-sub {
margin-top: 8rpx;
font-size: 24rpx;
opacity: 0.9;
}
.hero-decor {
position: absolute;
right: 12rpx;
bottom: 12rpx;
width: 160rpx;
height: 160rpx;
opacity: 0.3;
border-radius: 16rpx;
}
}
/* 功能入口宫格 - 2x2 */
.feature-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 20rpx;
padding: 0 24rpx;
margin-top: 8rpx;
.feature-item {
position: relative;
display: flex;
align-items: left;
flex-direction: column;
padding: 20rpx;
border-radius: 18rpx;
background: #fff;
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.04);
}
.feature-item::after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 60rpx;
height: 60rpx;
border-bottom-left-radius: 80rpx;
z-index: 1;
}
.feature-item:nth-child(1)::after,
.feature-item:nth-child(2)::after {
background: #fef2f2; /* 可换成你的主题粉 */
}
.feature-item:nth-child(3)::after,
.feature-item:nth-child(4)::after {
background: #fffbec; /* 温柔一点的黄 */
}
.feature-icon {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
padding: 5rpx;
}
.feature-texts {
margin-top: 20rpx;
display: flex;
flex-direction: column;
.feature-title {
font-size: 28rpx;
color: #222;
font-weight: 600;
}
.feature-sub {
font-size: 22rpx;
color: #888;
margin-top: 4rpx;
}
}
}
/* 通用区块标题 */
.section {
margin-top: 28rpx;
}
.section-header {
display: flex;
align-items: center;
padding: 0 24rpx;
.section-bar {
width: 10rpx;
height: 30rpx;
border-radius: 6rpx;
background: #ff3b30;
margin-right: 12rpx;
}
.section-title {
font-size: 28rpx;
color: #222;
flex: 1;
font-weight: 600;
}
.section-more {
font-size: 24rpx;
color: #ff3b30;
}
}
/* 大家都在用 - 竖向列表 */
.use-list {
padding: 0 24rpx;
margin-top: 16rpx;
}
.use-row {
display: flex;
align-items: center;
background: #fff;
border-radius: 18rpx;
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.06);
padding: 16rpx;
margin-bottom: 18rpx;
}
.thumb-wrap {
position: relative;
width: 120rpx;
height: 120rpx;
border-radius: 16rpx;
overflow: hidden;
margin-right: 16rpx;
}
.thumb {
width: 100%;
height: 100%;
}
.thumb-play {
position: absolute;
right: 8rpx;
bottom: 8rpx;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background: rgba(0, 0, 0, 0.55);
color: #fff;
font-size: 22rpx;
display: flex;
align-items: center;
justify-content: center;
}
.use-right {
flex: 1;
display: flex;
flex-direction: column;
}
.title-line {
display: flex;
align-items: center;
}
.use-title {
font-size: 28rpx;
color: #222;
font-weight: 600;
margin-right: 12rpx;
}
.tag {
font-size: 22rpx;
border-radius: 999rpx;
padding: 4rpx 10rpx;
margin-left: 4rpx;
&.tag--hot {
color: #ff6a00;
background: #fff4eb;
}
&.tag--featured {
color: #ff4d6d;
background: #fff0f3;
}
&.tag--hot2 {
color: #7c4dff;
background: #f3efff;
}
}
.use-desc {
margin-top: 6rpx;
font-size: 24rpx;
color: #777;
line-height: 1.5;
}
.use-cta {
margin-top: 10rpx;
font-size: 24rpx;
color: #ff3b30;
}
</style>