Files
spring-festival-greetings/pages/fortune/detail.vue
2026-02-01 00:14:19 +08:00

354 lines
8.2 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="fortune-detail-page">
<NavBar title="2026 灵马贺岁" :transparent="true"/>
<!-- 顶部提示条 -->
<!-- <view class="top-banner" v-if="inviterName">
<image
class="avatar-icon"
v-if="inviterAvatar"
:src="inviterAvatar"
mode="aspectFill"
/>
<text class="banner-text"
>你的好友 {{ inviterName }} 正在测试2026新年运势</text
>
</view>
<view class="top-banner" v-else>
<text class="banner-icon"></text>
<text class="banner-text">2026 灵马贺岁 · 开启你的新年好运</text>
</view> -->
<!-- 页面标题 -->
<view class="page-header">
<view class="main-title">2026 灵马贺岁</view>
<view class="sub-title">SPIRIT HORSE · LUNAR NEW YEAR FORTUNE</view>
</view>
<!-- 运势卡片 -->
<view class="fortune-card">
<view class="card-image-wrapper">
<image
class="card-image"
:src="fortuneData.imageUrl || defaultImage"
mode="widthFix"
/>
</view>
<view class="card-content">
<view class="content-header">
<text class="content-sub">2026 灵马贺岁 · 运势卡片</text>
</view>
<view class="content-title">{{
fortuneData.title || "锦鲤附身 · 万事顺遂"
}}</view>
<view class="content-desc">
{{
fortuneData.desc ||
"灵马奔腾瑞气盈门。此签预示您在2026年如同千里骏马不仅拥有敏锐的洞察力更有贵人暗中相助。事业将如破竹之势学业更有意外惊喜心之所向皆能圆满。"
}}
</view>
<view class="lucky-score">
<text class="score-label">幸运指数</text>
<view class="stars">
<text v-for="i in 5" :key="i" class="star"></text>
</view>
</view>
</view>
</view>
<!-- 底部按钮区 -->
<view class="action-area">
<button class="primary-btn" @click="goTest">
我也要测运势 <text class="arrow"></text>
</button>
<button class="secondary-btn" @click="saveCard">
<text class="download-icon">📥</text> 保存好运卡片
</button>
</view>
<!-- 底部信息 -->
<view class="footer-info">
<view class="qr-box">
<!-- 这里放二维码图片实际项目中可以用 canvas 生成或后端返回 -->
<view class="qr-placeholder"></view>
</view>
<view class="footer-text">2026 灵马贺岁 · 测出你的新年锦鲤关键词</view>
<view class="footer-sub"
>LONG-PRESS TO SAVE OR SCAN TO JOIN THE RITUAL</view
>
</view>
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { getPageDetail } from "@/api/system.js";
import { saveViewRequest } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue";
const inviterName = ref("");
const inviterAvatar = ref("");
const fortuneData = ref({
imageUrl: "",
title: "",
desc: "",
});
const defaultImage =
"https://file.lihailezzc.com/resource/2a30c7983af2646058a386fcc36d2ab8.png"; // 占位图,实际需替换
onLoad((options) => {
if (options.shareToken) {
loadPageDetail(options.shareToken);
} else {
// 仅作演示如果没传数据使用默认mock数据
// 在实际场景中,可能需要根据 fortuneId 去后端拉取详情
if (options.id) {
// fetchFortuneDetail(options.id)
}
}
});
const loadPageDetail = async (shareToken) => {
const data = await getPageDetail(shareToken);
fortuneData.value = data;
inviterName.value = data?.from?.nickname || "";
inviterAvatar.value = data?.from?.avatar || "";
saveViewRequest(shareToken, "fortune_draw", data.fortuneId);
};
const goHome = () => {
uni.switchTab({ url: "/pages/index/index" });
};
const goTest = () => {
// 如果是 tabbar 页面用 switchTab否则用 navigateTo
// 假设 /pages/fortune/index 不是 tabbar 页面
uni.reLaunch({ url: "/pages/fortune/index" });
};
const saveCard = () => {
// 这里应该是保存图片逻辑
// 由于这是一个网页展示页,如果需要保存整张卡片,通常需要 canvas 绘图
// 或者如果 imageUrl 本身就是合成好的海报,直接保存 imageUrl
// 简单起见,这里先保存 imageUrl
const url = fortuneData.value.imageUrl || defaultImage;
uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.showToast({ title: "保存成功", icon: "success" });
},
fail: () => {
uni.showToast({ title: "保存失败", icon: "none" });
},
});
}
},
fail: () => {
uni.showToast({ title: "下载失败", icon: "none" });
},
});
};
</script>
<style scoped>
.fortune-detail-page {
min-height: 100vh;
background-color: #2c1e1c;
padding: 44px 20px 40px;
display: flex;
flex-direction: column;
align-items: center;
font-family: sans-serif;
}
.top-banner {
background: rgba(255, 215, 0, 0.1);
border: 1px solid rgba(255, 215, 0, 0.2);
border-radius: 20px;
padding: 6px 16px;
display: flex;
align-items: center;
margin-bottom: 20px;
margin-top: 10px;
}
.banner-icon {
margin-right: 6px;
font-size: 14px;
}
.avatar-icon {
width: 32px;
height: 32px;
border-radius: 50%;
margin-right: 6px;
}
.banner-text {
font-size: 12px;
color: #ffd700;
}
.page-header {
text-align: center;
margin-bottom: 20px;
}
.main-title {
font-size: 28px;
color: #fff;
font-weight: bold;
letter-spacing: 2px;
margin-bottom: 4px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}
.sub-title {
font-size: 10px;
color: #d4af37;
letter-spacing: 1px;
opacity: 0.8;
}
.fortune-card {
width: 100%;
background: #3a2a28;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
margin-bottom: 30px;
border: 1px solid #4a3a38;
}
.card-image-wrapper {
position: relative;
width: 100%;
/* 保持图片区域有一定高度,防止加载时塌陷 */
min-height: 200px;
}
.card-image {
width: 100%;
display: block;
}
.card-content {
padding: 24px;
}
.content-header {
margin-bottom: 12px;
}
.content-sub {
font-size: 12px;
color: #d4af37;
opacity: 0.8;
}
.content-title {
font-size: 24px;
color: #fff;
font-weight: bold;
margin-bottom: 16px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.content-desc {
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
line-height: 1.8;
margin-bottom: 20px;
text-align: justify;
}
.lucky-score {
display: flex;
align-items: center;
}
.score-label {
font-size: 12px;
color: #ffd700;
margin-right: 8px;
}
.stars {
display: flex;
}
.star {
color: #ffd700;
font-size: 14px;
margin-right: 2px;
}
.action-area {
width: 100%;
margin-bottom: 30px;
}
.primary-btn {
background: linear-gradient(90deg, #ffd700 0%, #ffa500 100%);
color: #333;
font-weight: bold;
font-size: 16px;
height: 50px;
line-height: 50px;
border-radius: 25px;
margin-bottom: 16px;
box-shadow: 0 4px 12px rgba(255, 165, 0, 0.3);
display: flex;
justify-content: center;
align-items: center;
border: none;
}
.arrow {
margin-left: 6px;
font-size: 18px;
}
.secondary-btn {
background: rgba(255, 255, 255, 0.1);
color: #fff;
font-size: 14px;
height: 46px;
line-height: 46px;
border-radius: 23px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.download-icon {
margin-right: 6px;
font-size: 16px;
}
.footer-info {
display: flex;
flex-direction: column;
align-items: center;
}
.qr-box {
width: 60px;
height: 60px;
background: #fff;
padding: 4px;
border-radius: 8px;
margin-bottom: 12px;
}
.qr-placeholder {
width: 100%;
height: 100%;
background-color: #eee;
background-image: url("https://file.lihailezzc.com/resource/qr-placeholder.png");
background-size: cover;
border-radius: 4px;
}
.footer-text {
font-size: 12px;
color: rgba(255, 255, 255, 0.6);
margin-bottom: 4px;
}
.footer-sub {
font-size: 10px;
color: rgba(255, 255, 255, 0.3);
transform: scale(0.9);
}
</style>