Files
----/前端源码/uni-app/components/screens/AffinityResult.vue

1176 lines
31 KiB
Vue
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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="affinity-result">
<!-- 状态栏占位 -->
<view class="status-bar-placeholder"></view>
<!-- Header -->
<view class="result-header">
<view class="result-back-btn" @click="$emit('back')">
<text class="result-back-icon"></text>
</view>
<text class="result-header-title">{{ relationshipLabel }}合盘报告</text>
<view class="result-share-btn">
<text class="result-share-icon"></text>
</view>
</view>
<!-- Content -->
<scroll-view scroll-y class="result-content">
<view class="result-container">
<!-- 1. 分数卡片 -->
<view class="score-card">
<view class="score-main">
<text class="score-number">{{ score }}</text>
<view class="score-badge">
<text class="score-badge-text">{{ data?.scoreBadge || '上上婚' }}</text>
</view>
</view>
<text class="score-label">默契指数</text>
<view class="persons-row">
<view class="person-item">
<view class="person-avatar">
<text class="person-avatar-text">{{ data?.person1?.name?.[0] || '甲' }}</text>
</view>
<text class="person-name">{{ data?.person1?.name || '甲方' }}</text>
</view>
<view class="persons-line"></view>
<view class="person-item">
<view class="person-avatar">
<text class="person-avatar-text">{{ data?.person2?.name?.[0] || '乙' }}</text>
</view>
<text class="person-name">{{ data?.person2?.name || '乙方' }}</text>
</view>
</view>
</view>
<!-- 2. 六维雷达图 -->
<view class="radar-card">
<text class="radar-title">六维契合度</text>
<view class="radar-chart">
<canvas id="radarCanvas" class="radar-canvas" />
</view>
<text class="radar-desc">{{ data?.radarDesc || '双方在信任与情感维度表现卓越,虽在沟通方式上略有差异,但互补性极强。' }}</text>
</view>
<!-- 3. 分析卡片 -->
<view class="analysis-cards">
<view v-for="card in analysisCards" :key="card.id" class="analysis-card"
:class="{ expanded: expandedCard === card.id }" @click="toggleCard(card.id)">
<view class="analysis-card-header">
<view class="analysis-card-left">
<view class="analysis-icon" :style="{ background: card.iconBg }">
<text class="analysis-icon-text">{{ card.icon }}</text>
</view>
<text class="analysis-title">{{ card.title }}</text>
</view>
<view class="analysis-card-right">
<text class="analysis-score">{{ card.score }}</text>
<text class="analysis-arrow">{{ expandedCard === card.id ? '▲' : '▼' }}</text>
</view>
</view>
<text v-if="expandedCard !== card.id" class="analysis-summary">{{ card.summary }}</text>
<view v-else class="analysis-content">
<text class="analysis-content-text">{{ card.content }}</text>
</view>
</view>
</view>
<!-- 深度内容免费开放 -->
<view class="unlocked-content">
<!-- 前世羁绊 -->
<view class="deep-card">
<view class="deep-card-header">
<text class="deep-card-icon"></text>
<text class="deep-card-title">前世羁绊 · 三世书</text>
</view>
<text class="deep-card-text">{{ data?.unlocked?.pastLife?.description ||
'根据三世书推演,你们二人前世曾是同门师兄妹。彼时情深缘浅,因世俗礼教未能终成眷属,留下了深刻的遗憾。这份未了的情缘穿越轮回,在今生化作了你们初见时的"一见如故"。'
}}</text>
<view class="deep-card-grid">
<view class="deep-grid-item">
<text class="deep-grid-label">缘分深浅</text>
<text class="deep-grid-value gold">{{ data?.unlocked?.pastLife?.depth || '三生石上旧精魂'
}}</text>
</view>
<view class="deep-grid-item">
<text class="deep-grid-label">还债关系</text>
<text class="deep-grid-value">{{ data?.unlocked?.pastLife?.relationship || '互不相欠 · 共同成长'
}}</text>
</view>
</view>
</view>
<!-- 正缘验证 -->
<view class="deep-card">
<view class="deep-card-header">
<text class="deep-card-icon">👤</text>
<text class="deep-card-title">正缘特征验证</text>
</view>
<text class="deep-card-desc">系统根据您的八字推算的"命中注定"与当前对象{{ data?.person2?.name || '对方'
}}的匹配度</text>
<view class="match-list">
<view v-for="item in matchItems" :key="item.label" class="match-item">
<view class="match-header">
<text class="match-label">{{ item.label }}</text>
<text class="match-percent">契合度 {{ item.match }}%</text>
</view>
<view class="match-bar">
<view class="match-bar-fill" :style="{ width: item.match + '%' }"></view>
</view>
<text class="match-desc">{{ item.desc }}</text>
</view>
</view>
</view>
<!-- 潜意识指南 -->
<view class="deep-card">
<view class="deep-card-header">
<text class="deep-card-icon">🔐</text>
<text class="deep-card-title">潜意识与相处指南</text>
</view>
<view class="guide-section">
<view class="guide-header">
<view class="guide-bar pink"></view>
<text class="guide-title">TA的真实需求</text>
</view>
<text class="guide-text">{{ data?.unlocked?.guide?.realNeeds ||
'表面上TA看起来很独立、无所谓其实内心极度渴望被坚定地选择。TA最怕的不是争吵而是冷暴力和被忽略。' }}</text>
</view>
<view class="guide-section">
<view class="guide-header">
<view class="guide-bar red"></view>
<text class="guide-title">绝对雷区</text>
</view>
<text class="guide-text">{{ data?.unlocked?.guide?.redZone ||
'千万不要在公开场合质疑TA的决定或者拿TA与前任/别人做比较。这会瞬间触犯TA的自尊底线。' }}</text>
</view>
<view class="guide-section">
<view class="guide-header">
<view class="guide-bar gold"></view>
<text class="guide-title">如何拿捏TA</text>
</view>
<view class="guide-list">
<text
v-for="(tip, idx) in (data?.unlocked?.guide?.tips || ['适当示弱TA有很强的保护欲你的偶尔依赖会让TA成就感爆棚。', '制造反差在平淡生活中突然制造一个小惊喜能让TA记很久。'])"
:key="idx" class="guide-list-item"> {{ tip }}</text>
</view>
</view>
</view>
<!-- 12月运势 -->
<view class="deep-card">
<view class="deep-card-header">
<text class="deep-card-icon">📅</text>
<text class="deep-card-title">未来12个月 · 感情运势</text>
</view>
<view class="month-grid">
<view v-for="(heat, idx) in monthHeats" :key="idx" class="month-item"
:class="'heat-' + String(heat)">
<text class="month-num">{{ Number(idx) + 1 }}</text>
<text class="month-label">{{ heatLabels[heat] }}</text>
</view>
</view>
<text class="month-tip">
<text class="highlight-gold">高光时刻</text> {{ data?.unlocked?.monthlyFortune?.highlights ||
'3月、4月、10月是感情升温的最佳窗口期。' }}
</text>
<text class="month-tip gray">
<text class="highlight-gray">预警时刻</text> {{ data?.unlocked?.monthlyFortune?.warnings ||
'7月需防范外界诱惑或误会。' }}
</text>
</view>
<!-- 十年大运 -->
<view class="deep-card">
<view class="deep-card-header">
<text class="deep-card-icon"></text>
<text class="deep-card-title">未来十年 · 关键节点</text>
</view>
<view class="timeline">
<view v-for="item in timelineItems" :key="item.year" class="timeline-item">
<view class="timeline-dot" :class="{ highlight: item.highlight }"></view>
<view class="timeline-content">
<view class="timeline-header">
<text class="timeline-year" :class="{ highlight: item.highlight }">{{ item.year
}}</text>
<text class="timeline-tag">{{ item.title }}</text>
</view>
<text class="timeline-desc">{{ item.desc }}</text>
</view>
</view>
</view>
</view>
<!-- 大师寄语 -->
<view class="deep-card master-card">
<view class="deep-card-header">
<text class="deep-card-icon">🛡</text>
<text class="deep-card-title master-title">大师寄语 · 化解之道</text>
</view>
<text class="master-text">{{ data?.unlocked?.masterAdvice?.message ||
'虽然你们是上上婚配,但仍需注意农历五月和十一月,这两个月份情绪易波动。' }}</text>
<view class="master-tips">
<text class="master-tips-title">开运建议</text>
<text
v-for="(tip, idx) in (data?.unlocked?.masterAdvice?.tips || ['家中东南方摆放一对木质鸳鸯摆件,可增进感情。', '多佩戴红色或紫色饰品,以火生土,旺运旺财。'])"
:key="idx" class="master-tip-item"> {{ tip }}</text>
</view>
</view>
</view>
<!-- 底部占位 -->
<view class="bottom-spacer"></view>
</view>
</scroll-view>
</view>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, nextTick } from 'vue';
import type { AffinityCalculateResponse } from '../../api';
const props = defineProps<{
data: AffinityCalculateResponse | null;
}>();
const relationshipLabel = computed(() => {
return props.data?.relationshipLabel || '缘分';
});
const score = computed(() => props.data?.score || 88);
const expandedCard = ref<string | null>(null);
const analysisCards = computed(() => props.data?.analysisCards || []);
const matchItems = computed(() => props.data?.unlocked?.matchItems || []);
const monthHeats = computed(() => props.data?.unlocked?.monthlyFortune?.heats || [1, 2, 3, 3, 2, 1, 0, 1, 2, 3, 3, 2]);
const heatLabels = computed(() => props.data?.unlocked?.monthlyFortune?.heatLabels || ['平', '吉', '大吉', '如意']);
const timelineItems = computed(() => props.data?.unlocked?.timeline || []);
const toggleCard = (id: string) => {
expandedCard.value = expandedCard.value === id ? null : id;
};
// 绘制雷达图
const drawRadarChart = () => {
const sixDimension = props.data?.sixDimension;
if (!sixDimension) return;
// 在Web环境下使用原生Canvas API
const canvas = document.getElementById('radarCanvas') as HTMLCanvasElement;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
// 设置画布实际尺寸(考虑设备像素比)
const dpr = window.devicePixelRatio || 1;
const rect = canvas.getBoundingClientRect();
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
ctx.scale(dpr, dpr);
const canvasSize = rect.width;
const centerX = canvasSize / 2;
const centerY = canvasSize / 2;
const maxRadius = canvasSize * 0.35; // 最大半径为画布的35%
// 六个维度的数据和标签(按照接口返回的字段名)
const dimensions = [
{ key: 'personality', label: '性格', value: sixDimension.personality || 0 },
{ key: 'career', label: '事业', value: sixDimension.career || 0 },
{ key: 'wealth', label: '财运', value: sixDimension.wealth || 0 },
{ key: 'health', label: '健康', value: sixDimension.health || 0 },
{ key: 'emotion', label: '情感', value: sixDimension.emotion || 0 },
{ key: 'family', label: '家庭', value: sixDimension.family || 0 },
];
// 计算每个点的坐标
const points = dimensions.map((dim, index) => {
const angle = (Math.PI * 2 * index) / 6 - Math.PI / 2; // 从顶部开始
const radius = (dim.value / 100) * maxRadius;
return {
x: centerX + radius * Math.cos(angle),
y: centerY + radius * Math.sin(angle),
};
});
// 绘制背景网格4层
ctx.lineWidth = 0.5;
ctx.strokeStyle = 'rgba(234, 221, 207, 0.2)';
for (let i = 1; i <= 4; i++) {
const radius = (maxRadius * i) / 4;
ctx.beginPath();
for (let j = 0; j <= 6; j++) {
const angle = (Math.PI * 2 * j) / 6 - Math.PI / 2;
const x = centerX + radius * Math.cos(angle);
const y = centerY + radius * Math.sin(angle);
if (j === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.closePath();
ctx.stroke();
}
// 绘制从中心到各顶点的线
ctx.lineWidth = 0.5;
ctx.strokeStyle = 'rgba(234, 221, 207, 0.2)';
for (let i = 0; i < 6; i++) {
const angle = (Math.PI * 2 * i) / 6 - Math.PI / 2;
const x = centerX + maxRadius * Math.cos(angle);
const y = centerY + maxRadius * Math.sin(angle);
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.lineTo(x, y);
ctx.stroke();
}
// 绘制数据区域(填充)
ctx.beginPath();
points.forEach((point, index) => {
if (index === 0) {
ctx.moveTo(point.x, point.y);
} else {
ctx.lineTo(point.x, point.y);
}
});
ctx.closePath();
ctx.fillStyle = 'rgba(236, 72, 153, 0.3)';
ctx.fill();
// 绘制数据区域(边框)
ctx.beginPath();
points.forEach((point, index) => {
if (index === 0) {
ctx.moveTo(point.x, point.y);
} else {
ctx.lineTo(point.x, point.y);
}
});
ctx.closePath();
ctx.lineWidth = 2;
ctx.strokeStyle = '#ec4899';
ctx.stroke();
// 绘制数据点
points.forEach(point => {
ctx.beginPath();
ctx.arc(point.x, point.y, 3, 0, Math.PI * 2);
ctx.fillStyle = '#ec4899';
ctx.fill();
});
// 绘制标签
ctx.font = '12px SimSun, "Songti SC", serif';
ctx.fillStyle = '#a0a0a0';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
dimensions.forEach((dim, index) => {
const angle = (Math.PI * 2 * index) / 6 - Math.PI / 2;
const labelRadius = maxRadius + 20;
const x = centerX + labelRadius * Math.cos(angle);
const y = centerY + labelRadius * Math.sin(angle);
ctx.fillText(dim.label, x, y);
});
};
onMounted(() => {
nextTick(() => {
setTimeout(() => {
drawRadarChart();
}, 300);
});
});
</script>
<style scoped>
.affinity-result {
height: 100%;
display: flex;
flex-direction: column;
background: #050508;
position: relative;
}
.status-bar-placeholder {
height: var(--status-bar-height, 0);
width: 100%;
flex-shrink: 0;
}
.result-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
background: rgba(5, 5, 8, 0.8);
backdrop-filter: blur(20rpx);
border-bottom: 2rpx solid rgba(255, 255, 255, 0.1);
position: relative;
z-index: 10;
}
.result-back-btn,
.result-share-btn {
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.result-back-icon {
font-size: 48rpx;
color: #d4af37;
font-weight: bold;
}
.result-share-icon {
font-size: 36rpx;
color: #d4af37;
}
.result-header-title {
font-size: 32rpx;
font-weight: bold;
color: #d4af37;
letter-spacing: 0.3em;
font-family: SimSun, "Songti SC", serif;
}
.result-content {
flex: 1;
height: 0;
}
.result-container {
padding: 48rpx;
}
/* 分数卡片 */
.score-card {
text-align: center;
margin-bottom: 48rpx;
}
.score-main {
position: relative;
display: inline-block;
}
.score-number {
font-size: 160rpx;
font-weight: bold;
font-family: SimSun, "Songti SC", serif;
background: linear-gradient(to bottom, #d4af37, #8b6d30);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
line-height: 1;
}
.score-badge {
position: absolute;
right: -80rpx;
top: 0;
background: #8b2323;
padding: 8rpx 16rpx;
border-radius: 0 16rpx 0 16rpx;
}
.score-badge-text {
font-size: 20rpx;
color: #fff;
}
.score-label {
font-size: 24rpx;
color: #a0a0a0;
letter-spacing: 1em;
display: block;
margin-top: 16rpx;
}
.persons-row {
display: flex;
align-items: center;
justify-content: center;
margin-top: 48rpx;
gap: 64rpx;
}
.person-item {
text-align: center;
}
.person-avatar {
width: 96rpx;
height: 96rpx;
border-radius: 50%;
border: 2rpx solid rgba(255, 255, 255, 0.2);
background: rgba(255, 255, 255, 0.05);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 16rpx;
}
.person-avatar-text {
font-size: 36rpx;
color: #e2e2e2;
font-family: SimSun, "Songti SC", serif;
}
.person-name {
font-size: 24rpx;
color: #8a8a8a;
}
.persons-line {
width: 96rpx;
height: 2rpx;
background: linear-gradient(to right, transparent, #ec4899, transparent);
opacity: 0.5;
}
/* 雷达图卡片 */
.radar-card {
background: rgba(255, 255, 255, 0.05);
border-radius: 24rpx;
border: 2rpx solid rgba(255, 255, 255, 0.1);
padding: 32rpx;
margin-bottom: 48rpx;
}
.radar-title {
text-align: center;
font-size: 28rpx;
color: #d4af37;
font-family: SimSun, "Songti SC", serif;
letter-spacing: 0.3em;
display: block;
margin-bottom: 24rpx;
}
.radar-chart {
width: 400rpx;
height: 400rpx;
margin: 0 auto 24rpx;
position: relative;
}
.radar-bg {
width: 100%;
height: 100%;
}
.radar-canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.radar-desc {
font-size: 24rpx;
color: #8a8a8a;
text-align: center;
line-height: 1.6;
display: block;
padding: 0 16rpx;
}
.radar-desc .highlight {
color: #d4af37;
}
/* 分析卡片 */
.analysis-cards {
margin-bottom: 48rpx;
}
.analysis-card {
background: rgba(255, 255, 255, 0.05);
border-radius: 16rpx;
border: 2rpx solid rgba(255, 255, 255, 0.05);
padding: 32rpx;
margin-bottom: 24rpx;
transition: all 0.3s;
}
.analysis-card.expanded {
border-color: rgba(212, 175, 55, 0.5);
background: rgba(255, 255, 255, 0.1);
}
.analysis-card-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16rpx;
}
.analysis-card-left {
display: flex;
align-items: center;
gap: 16rpx;
}
.analysis-icon {
width: 56rpx;
height: 56rpx;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
}
.analysis-icon-text {
font-size: 28rpx;
}
.analysis-title {
font-size: 28rpx;
font-weight: bold;
color: #e2e2e2;
}
.analysis-card-right {
display: flex;
align-items: center;
gap: 24rpx;
}
.analysis-score {
font-size: 36rpx;
font-weight: bold;
color: #d4af37;
font-family: SimSun, "Songti SC", serif;
font-style: italic;
}
.analysis-arrow {
font-size: 20rpx;
color: #a0a0a0;
}
.analysis-summary {
font-size: 24rpx;
color: #a0a0a0;
line-height: 1.6;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.analysis-content {
margin-top: 24rpx;
padding-top: 24rpx;
border-top: 2rpx solid rgba(255, 255, 255, 0.1);
}
.analysis-content-text {
font-size: 28rpx;
color: #e2e2e2;
line-height: 2;
white-space: pre-wrap;
}
/* 解锁区域 */
.unlock-section {
background: rgba(255, 255, 255, 0.05);
border-radius: 24rpx;
border: 2rpx solid rgba(212, 175, 55, 0.3);
overflow: hidden;
margin-bottom: 48rpx;
}
.unlock-content {
padding: 64rpx 48rpx;
text-align: center;
background: rgba(5, 5, 8, 0.8);
}
.unlock-icon {
font-size: 96rpx;
display: block;
margin-bottom: 32rpx;
}
.unlock-title {
font-size: 40rpx;
font-weight: bold;
color: #d4af37;
font-family: SimSun, "Songti SC", serif;
letter-spacing: 0.3em;
display: block;
margin-bottom: 24rpx;
}
.unlock-desc {
font-size: 28rpx;
color: #a0a0a0;
line-height: 1.8;
display: block;
margin-bottom: 48rpx;
}
.unlock-highlight {
color: #d4af37;
font-weight: bold;
}
.unlock-btn {
width: 80%;
height: 96rpx;
background: linear-gradient(to right, #d4af37, #b39030);
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
border: none;
box-shadow: 0 8rpx 24rpx rgba(212, 175, 55, 0.3);
margin: 0 auto 24rpx;
}
.unlock-btn-text {
font-size: 32rpx;
font-weight: bold;
color: #1a1a2e;
font-family: SimSun, "Songti SC", serif;
letter-spacing: 0.2em;
}
.unlock-stats {
font-size: 24rpx;
color: #666;
display: block;
}
.unlock-preview {
padding: 48rpx;
opacity: 0.3;
filter: blur(8rpx);
pointer-events: none;
background: rgba(0, 0, 0, 0.2);
}
.unlock-preview-title {
font-size: 32rpx;
font-weight: bold;
color: #e2e2e2;
display: block;
margin-bottom: 16rpx;
}
.unlock-preview-text {
font-size: 24rpx;
color: #a0a0a0;
line-height: 1.6;
display: block;
margin-bottom: 32rpx;
}
/* 解锁后内容 */
.unlocked-content {
margin-bottom: 48rpx;
}
.deep-card {
background: rgba(255, 253, 249, 0.05);
border: 2rpx solid rgba(212, 175, 55, 0.2);
border-radius: 24rpx;
padding: 48rpx;
margin-bottom: 32rpx;
position: relative;
overflow: hidden;
}
.deep-card-header {
display: flex;
align-items: center;
gap: 16rpx;
margin-bottom: 32rpx;
}
.deep-card-icon {
font-size: 32rpx;
}
.deep-card-title {
font-size: 36rpx;
font-weight: bold;
color: #d4af37;
font-family: SimSun, "Songti SC", serif;
letter-spacing: 0.3em;
}
.deep-card-text {
font-size: 28rpx;
color: #e2e2e2;
line-height: 1.8;
text-align: justify;
display: block;
margin-bottom: 32rpx;
}
.highlight-gold {
color: #d4af37;
font-weight: bold;
}
.highlight-white {
color: #e2e2e2;
font-weight: bold;
}
.highlight-gray {
color: #888;
font-weight: bold;
}
.deep-card-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24rpx;
}
.deep-grid-item {
background: rgba(0, 0, 0, 0.2);
padding: 24rpx;
border-radius: 16rpx;
text-align: center;
}
.deep-grid-label {
font-size: 20rpx;
color: #a0a0a0;
display: block;
margin-bottom: 8rpx;
}
.deep-grid-value {
font-size: 24rpx;
color: #e2e2e2;
font-family: SimSun, "Songti SC", serif;
font-weight: bold;
}
.deep-grid-value.gold {
color: #d4af37;
}
.deep-card-desc {
font-size: 24rpx;
color: #a0a0a0;
display: block;
margin-bottom: 24rpx;
}
/* 匹配列表 */
.match-list {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.match-item {
background: rgba(255, 255, 255, 0.05);
border-radius: 16rpx;
padding: 24rpx;
}
.match-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.match-label {
font-size: 28rpx;
color: #e2e2e2;
font-weight: bold;
}
.match-percent {
font-size: 24rpx;
color: #d4af37;
font-weight: bold;
}
.match-bar {
width: 100%;
height: 12rpx;
background: rgba(0, 0, 0, 0.3);
border-radius: 6rpx;
overflow: hidden;
margin-bottom: 16rpx;
}
.match-bar-fill {
height: 100%;
background: linear-gradient(to right, #d4af37, #fcd34d);
border-radius: 6rpx;
transition: width 1s ease;
}
.match-desc {
font-size: 20rpx;
color: #a0a0a0;
line-height: 1.6;
}
/* 指南部分 */
.guide-section {
margin-bottom: 32rpx;
}
.guide-section:last-child {
margin-bottom: 0;
}
.guide-header {
display: flex;
align-items: center;
gap: 16rpx;
margin-bottom: 16rpx;
}
.guide-bar {
width: 6rpx;
height: 32rpx;
border-radius: 3rpx;
}
.guide-bar.pink {
background: #ec4899;
}
.guide-bar.red {
background: #8b2323;
}
.guide-bar.gold {
background: #d4af37;
}
.guide-title {
font-size: 28rpx;
color: #e2e2e2;
font-weight: bold;
}
.guide-text {
font-size: 24rpx;
color: #a0a0a0;
line-height: 1.8;
background: rgba(0, 0, 0, 0.2);
padding: 24rpx;
border-radius: 16rpx;
text-align: justify;
}
.guide-list {
background: rgba(0, 0, 0, 0.2);
padding: 24rpx;
border-radius: 16rpx;
}
.guide-list-item {
font-size: 24rpx;
color: #a0a0a0;
line-height: 1.8;
display: block;
margin-bottom: 8rpx;
}
.guide-list-item:last-child {
margin-bottom: 0;
}
/* 月度运势 */
.month-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16rpx;
margin-bottom: 24rpx;
}
.month-item {
aspect-ratio: 1;
border-radius: 12rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.month-item.heat-0 {
background: #374151;
}
.month-item.heat-1 {
background: rgba(212, 175, 55, 0.3);
}
.month-item.heat-2 {
background: rgba(212, 175, 55, 0.6);
}
.month-item.heat-3 {
background: #d4af37;
}
.month-num {
font-size: 20rpx;
font-weight: bold;
color: #fff;
}
.month-label {
font-size: 16rpx;
color: rgba(255, 255, 255, 0.8);
transform: scale(0.9);
}
.month-tip {
font-size: 20rpx;
color: #a0a0a0;
display: block;
margin-bottom: 8rpx;
}
.month-tip.gray {
color: #888;
}
/* 时间线 */
.timeline {
position: relative;
padding-left: 32rpx;
border-left: 2rpx solid rgba(212, 175, 55, 0.3);
margin-left: 16rpx;
}
.timeline-item {
position: relative;
margin-bottom: 48rpx;
}
.timeline-item:last-child {
margin-bottom: 0;
}
.timeline-dot {
position: absolute;
left: -41rpx;
top: 8rpx;
width: 24rpx;
height: 24rpx;
border-radius: 50%;
background: #1a1a2e;
border: 4rpx solid #a0a0a0;
}
.timeline-dot.highlight {
background: #d4af37;
border-color: #d4af37;
box-shadow: 0 0 20rpx #d4af37;
}
.timeline-content {
padding-left: 16rpx;
}
.timeline-header {
display: flex;
align-items: baseline;
justify-content: space-between;
margin-bottom: 8rpx;
}
.timeline-year {
font-size: 36rpx;
font-weight: bold;
color: #e2e2e2;
font-family: SimSun, "Songti SC", serif;
}
.timeline-year.highlight {
color: #d4af37;
}
.timeline-tag {
font-size: 24rpx;
font-weight: bold;
color: #a0a0a0;
background: rgba(255, 255, 255, 0.05);
padding: 8rpx 16rpx;
border-radius: 8rpx;
}
.timeline-desc {
font-size: 24rpx;
color: #a0a0a0;
line-height: 1.6;
}
/* 大师寄语 */
.master-card {
background: linear-gradient(135deg, rgba(139, 35, 35, 0.2), rgba(90, 26, 26, 0.2));
border-color: rgba(139, 35, 35, 0.3);
}
.master-title {
color: #ff8a8a;
}
.master-text {
font-size: 28rpx;
color: #e2e2e2;
line-height: 1.8;
text-align: justify;
display: block;
margin-bottom: 24rpx;
}
.master-tips {
background: rgba(0, 0, 0, 0.2);
border-radius: 16rpx;
padding: 24rpx;
}
.master-tips-title {
font-size: 24rpx;
color: #ff8a8a;
font-weight: bold;
display: block;
margin-bottom: 16rpx;
}
.master-tip-item {
font-size: 24rpx;
color: #a0a0a0;
line-height: 1.8;
display: block;
margin-bottom: 8rpx;
}
.master-tip-item:last-child {
margin-bottom: 0;
}
.bottom-spacer {
height: 64rpx;
}
</style>