fix: daily page

This commit is contained in:
zzc
2026-03-01 22:35:20 +08:00
parent a7cc9babac
commit 8110e209c7
3 changed files with 615 additions and 0 deletions

603
pages/greeting/daily.vue Normal file
View File

@@ -0,0 +1,603 @@
<template>
<view class="daily-page">
<NavBar title="每日精选" :transparent="true" color="#333" />
<!-- Header -->
<view class="page-header" :style="{ paddingTop: navBarHeight + 'px' }">
<view class="header-left">
<uni-icons type="sun-filled" size="24" color="#ff9800" />
<text class="header-title">{{ greetingTitle }}</text>
</view>
<view class="streak-badge">
<text>已连续问候</text>
<text class="streak-count">{{ streakDays }}</text>
<text></text>
<text class="fire-icon">🔥</text>
</view>
</view>
<view class="sub-header">
<text>{{ dateStr }} 灵马送福 · 每日精选</text>
</view>
<!-- Main Card -->
<view class="main-card-container">
<view class="quote-card">
<view class="quote-icon"></view>
<view class="quote-content">
<text class="quote-text">{{ currentQuote.text }}</text>
<text class="quote-highlight" v-if="currentQuote.highlight">{{
currentQuote.highlight
}}</text>
</view>
<view class="quote-divider"></view>
<view class="quote-author">
<text> {{ currentQuote.author }} 的专属问候</text>
</view>
<view class="card-actions">
<view class="refresh-btn" @tap="refreshQuote">
<uni-icons type="loop" size="16" color="#666" />
<text>换一句</text>
</view>
<!-- Placeholder for layout balance -->
<view style="width: 160rpx"></view>
</view>
</view>
</view>
<!-- Categories -->
<view class="category-section">
<view class="category-grid">
<view
v-for="(cat, index) in categories"
:key="index"
class="category-item"
@tap="selectCategory(cat.id)"
>
<view
class="cat-icon-box"
:class="{ active: currentCategory === cat.id }"
:style="{ background: cat.bg }"
>
<text class="cat-emoji">{{ cat.emoji }}</text>
</view>
<text
class="cat-name"
:class="{ active: currentCategory === cat.id }"
>{{ cat.name }}</text
>
</view>
</view>
</view>
<!-- Hot List -->
<view class="hot-list-section">
<view class="section-title-row">
<view class="title-bar"></view>
<text class="section-title">今日最热榜单</text>
<text class="section-subtitle">REAL-TIME DATA</text>
</view>
<view class="hot-list">
<view
v-for="(item, index) in hotList"
:key="index"
class="hot-item"
@tap="useHotItem(item)"
>
<view class="rank-icon">
<uni-icons
v-if="index === 0"
type="vip-filled"
size="24"
color="#ffbc00"
/>
<uni-icons
v-else-if="index === 1"
type="vip-filled"
size="24"
color="#b0bec5"
/>
<uni-icons
v-else
type="vip-filled"
size="24"
color="#cd7f32"
/>
</view>
<view class="hot-content">
<text class="hot-text">{{ item.text }}</text>
<view class="hot-meta">
<text class="fire">🔥</text>
<text class="hot-count">{{ item.count }}w 人正在使用</text>
</view>
</view>
<uni-icons type="right" size="16" color="#ccc" />
</view>
</view>
</view>
<!-- Bottom Actions -->
<view class="bottom-actions safe-area-bottom">
<button class="action-btn secondary" @tap="drawLucky">
<uni-icons type="gift-filled" size="18" color="#fff" />
<text>抽一句今日好运</text>
<view class="badge-tag">LUCKY</view>
</button>
<button class="action-btn primary" @tap="sendGreeting">
<uni-icons type="paperplane-filled" size="18" color="#fff" />
<text>立即发送今日问候</text>
</button>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
import { getBavBarHeight } from "@/utils/system";
import NavBar from "@/components/NavBar/NavBar.vue";
const navBarHeight = getBavBarHeight();
const streakDays = ref(5);
const dateStr = computed(() => {
const date = new Date();
return `${date.getFullYear()} 灵马送福 · 每日精选`;
});
const greetingTitle = computed(() => {
const hour = new Date().getHours();
if (hour < 9) return "早安,今天也要好运";
if (hour < 12) return "上午好,元气满满";
if (hour < 14) return "午安,记得休息";
if (hour < 18) return "下午好,继续加油";
return "晚安,好梦相伴";
});
const categories = [
{ id: "vitality", name: "元气", emoji: "😊", bg: "#fff8e1" },
{ id: "luck", name: "好运", emoji: "🍀", bg: "#e8f5e9" },
{ id: "gentle", name: "温柔", emoji: "❤️", bg: "#ffebee" },
{ id: "work", name: "工作", emoji: "💼", bg: "#e3f2fd" },
{ id: "funny", name: "搞笑", emoji: "😂", bg: "#fff3e0" },
];
const currentCategory = ref("vitality");
const quotes = {
vitality: [
{
text: "愿你眼中有星辰\n心中有山海\n每一步都走在",
highlight: "开满鲜花的路上",
author: "陈小明",
},
{
text: "生活原本沉闷\n但跑起来就有风",
highlight: "做自己的小太阳",
author: "李华",
},
],
luck: [
{
text: "好运正在派送中\n请保持心情舒畅",
highlight: "万事顺遂",
author: "锦鲤",
},
],
gentle: [
{
text: "温柔是宝藏\n你也是",
highlight: "岁月静好",
author: "微风",
},
],
work: [
{
text: "打工人的意志\n是钢铁铸成的",
highlight: "搞钱要紧",
author: "打工人",
},
],
funny: [
{
text: "间歇性踌躇满志\n持续性混吃等死",
highlight: "这就是人生",
author: "咸鱼",
},
],
};
const currentQuote = ref(quotes.vitality[0]);
const hotList = ref([
{ text: "新的一年,愿灵马带走烦恼...", count: "2.4" },
{ text: "事事顺意,岁岁平安。", count: "1.8" },
]);
const selectCategory = (id) => {
currentCategory.value = id;
refreshQuote();
};
const refreshQuote = () => {
const list = quotes[currentCategory.value] || quotes.vitality;
const randomIndex = Math.floor(Math.random() * list.length);
currentQuote.value = list[randomIndex];
};
const useHotItem = (item) => {
currentQuote.value = {
text: item.text,
highlight: "",
author: "热榜推荐",
};
};
const drawLucky = () => {
uni.showToast({ title: "好运 +1", icon: "none" });
};
const sendGreeting = () => {
uni.navigateTo({
url: `/pages/make/index?scene=daily&content=${encodeURIComponent(currentQuote.value.text)}`,
});
};
</script>
<style lang="scss" scoped>
.daily-page {
min-height: 100vh;
background: #fbfbf9;
padding-bottom: 200rpx;
}
.page-header {
padding: 0 32rpx;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8rpx;
}
.header-left {
display: flex;
align-items: center;
gap: 12rpx;
}
.header-title {
font-size: 36rpx;
font-weight: 800;
color: #333;
}
.streak-badge {
display: flex;
align-items: center;
background: #fff;
padding: 6rpx 20rpx;
border-radius: 30rpx;
font-size: 22rpx;
color: #666;
border: 1rpx solid #eee;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
.streak-count {
font-size: 28rpx;
font-weight: bold;
color: #ff3b30;
margin: 0 4rpx;
}
.fire-icon {
margin-left: 4rpx;
font-size: 24rpx;
}
}
.sub-header {
padding: 0 32rpx;
font-size: 24rpx;
color: #999;
margin-bottom: 40rpx;
}
/* Main Card */
.main-card-container {
padding: 0 40rpx;
margin-bottom: 60rpx;
}
.quote-card {
background: #fff;
border-radius: 40rpx;
padding: 60rpx 40rpx 40rpx;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.08);
border: 4rpx solid #f5e6d3; /* Gold-ish border */
position: relative;
min-height: 600rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* Inner Border Effect */
&::after {
content: "";
position: absolute;
inset: 12rpx;
border: 2rpx solid #f9f3e8;
border-radius: 32rpx;
pointer-events: none;
}
}
.quote-icon {
font-size: 80rpx;
color: #f5e6d3;
margin-bottom: 40rpx;
line-height: 1;
}
.quote-content {
text-align: center;
margin-bottom: 60rpx;
}
.quote-text {
font-size: 40rpx;
color: #333;
font-weight: bold;
line-height: 1.6;
font-family: "Songti SC", serif;
display: block;
white-space: pre-wrap;
}
.quote-highlight {
display: block;
font-size: 44rpx;
color: #d81e06;
font-weight: 800;
margin-top: 20rpx;
font-family: "Songti SC", serif;
}
.quote-divider {
width: 80rpx;
height: 2rpx;
background: #eee;
margin-bottom: 30rpx;
}
.quote-author {
font-size: 24rpx;
color: #999;
margin-bottom: 60rpx;
font-style: italic;
}
.card-actions {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 2;
}
.refresh-btn {
display: flex;
align-items: center;
gap: 12rpx;
padding: 16rpx 32rpx;
background: #fff;
border: 1rpx solid #eee;
border-radius: 40rpx;
font-size: 26rpx;
color: #666;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
&:active {
background: #f5f5f5;
}
}
/* Categories */
.category-section {
padding: 0 32rpx;
margin-bottom: 60rpx;
}
.category-grid {
display: flex;
justify-content: space-between;
}
.category-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 16rpx;
}
.cat-icon-box {
width: 100rpx;
height: 100rpx;
border-radius: 30rpx;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
border: 2rpx solid transparent;
&.active {
transform: translateY(-4rpx);
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.08);
border-color: rgba(0, 0, 0, 0.05);
}
}
.cat-emoji {
font-size: 48rpx;
}
.cat-name {
font-size: 24rpx;
color: #666;
font-weight: 500;
&.active {
color: #333;
font-weight: bold;
}
}
/* Hot List */
.hot-list-section {
padding: 0 32rpx;
margin-bottom: 40rpx;
}
.section-title-row {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.title-bar {
width: 8rpx;
height: 32rpx;
background: #d4a017;
border-radius: 4rpx;
margin-right: 16rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-right: 16rpx;
}
.section-subtitle {
font-size: 20rpx;
color: #ccc;
font-weight: 500;
}
.hot-list {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.hot-item {
background: #fff;
border-radius: 24rpx;
padding: 24rpx 32rpx;
display: flex;
align-items: center;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.02);
&:active {
background: #f9f9f9;
}
}
.rank-icon {
margin-right: 24rpx;
display: flex;
align-items: center;
}
.hot-content {
flex: 1;
}
.hot-text {
font-size: 28rpx;
color: #333;
margin-bottom: 8rpx;
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 450rpx;
}
.hot-meta {
display: flex;
align-items: center;
font-size: 22rpx;
color: #999;
}
.fire {
color: #ff3b30;
margin-right: 4rpx;
font-size: 20rpx;
}
/* Bottom Actions */
.bottom-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: #fff; /* Glass effect if supported */
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20rpx);
padding: 20rpx 32rpx;
display: flex;
flex-direction: column;
gap: 24rpx;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
z-index: 100;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
}
.action-btn {
width: 100%;
height: 96rpx;
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 16rpx;
font-size: 30rpx;
font-weight: bold;
border: none;
position: relative;
&.secondary {
background: #c62828; /* Dark Red */
color: #fff;
background: linear-gradient(135deg, #d32f2f 0%, #b71c1c 100%);
box-shadow: 0 8rpx 20rpx rgba(211, 47, 47, 0.3);
}
&.primary {
background: #8e0000; /* Deep Red/Brown */
color: #fff;
background: linear-gradient(135deg, #8e0000 0%, #600000 100%);
box-shadow: 0 8rpx 20rpx rgba(142, 0, 0, 0.3);
}
&:active {
transform: scale(0.99);
}
}
.badge-tag {
position: absolute;
top: -12rpx;
right: 40rpx;
background: #ffbc00;
color: #333;
font-size: 18rpx;
padding: 2rpx 10rpx;
border-radius: 12rpx;
font-weight: 800;
border: 2rpx solid #fff;
}
</style>

View File

@@ -504,6 +504,10 @@ const navTo = (url) => {
};
const navToMake = (item) => {
if (item.scene === "daily") {
uni.navigateTo({ url: "/pages/greeting/daily" });
return;
}
uni.navigateTo({ url: `/pages/make/index?scene=${item.scene}` });
};