| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705 |
- <template>
- <view class="zodiac-page">
- <!-- 自定义导航栏 -->
- <view class="custom-nav">
- <view class="nav-left" @click="goBack">
- <text class="back-icon">←</text>
- </view>
- <view class="nav-title">生肖配对</view>
- <view class="nav-right"></view>
- </view>
- <!-- 生肖配对选择区域 -->
- <view class="zodiac-selection-section" v-if="!hasResult">
- <view class="selection-card">
- <view class="card-title">💕 生肖配对测试</view>
- <view class="card-subtitle">看看你们的缘分指数有多高</view>
-
- <!-- 我的生肖选择 -->
- <view class="zodiac-picker-wrapper">
- <view class="picker-label">我的生肖</view>
- <picker mode="selector" :range="zodiacNames" :value="myZodiacIndex" @change="onMyZodiacChange">
- <view class="zodiac-display">
- <text class="zodiac-emoji">{{ myZodiacEmoji }}</text>
- <text class="zodiac-text">{{ myZodiac || '请选择' }}</text>
- </view>
- </picker>
- </view>
- <!-- 对方生肖选择 -->
- <view class="zodiac-picker-wrapper">
- <view class="picker-label">TA的生肖</view>
- <picker mode="selector" :range="zodiacNames" :value="targetZodiacIndex" @change="onTargetZodiacChange">
- <view class="zodiac-display">
- <text class="zodiac-emoji">{{ targetZodiacEmoji }}</text>
- <text class="zodiac-text">{{ targetZodiac || '请选择' }}</text>
- </view>
- </picker>
- </view>
- <button class="submit-btn" @click="handleSubmit" :disabled="!myZodiac || !targetZodiac">
- 开始配对
- </button>
- </view>
- <!-- 装饰性生肖图标 -->
- <view class="zodiac-icons">
- <text class="zodiac-icon" v-for="(zodiac, index) in allZodiacs" :key="index">
- {{ zodiac.emoji }}
- </text>
- </view>
- </view>
- <!-- 配对结果 -->
- <view class="result-section" v-if="hasResult">
- <!-- 配对标题卡片 -->
- <view class="match-title-card">
- <view class="match-header">
- <view class="zodiac-pair">
- <text class="zodiac-emoji-large">{{ myZodiacEmoji }}</text>
- <text class="vs-text">💕</text>
- <text class="zodiac-emoji-large">{{ targetZodiacEmoji }}</text>
- </view>
- <view class="match-title">{{ myZodiac }} 💕 {{ targetZodiac }}</view>
- <view class="match-subtitle">{{ matchResult.title || '配对分析' }}</view>
- </view>
- </view>
- <!-- 配对分析 -->
- <view class="match-analysis-section" v-if="matchResult">
- <view class="section-title">💝 配对分析</view>
- <view class="analysis-card">
- <!-- 男性视角 -->
- <view class="perspective-item" v-if="matchResult.malePerspective">
- <view class="perspective-header">
- <text class="perspective-icon">👨</text>
- <text class="perspective-title">男生视角</text>
- </view>
- <text class="perspective-content">{{ matchResult.malePerspective }}</text>
- </view>
-
- <!-- 女性视角 -->
- <view class="perspective-item" v-if="matchResult.femalePerspective">
- <view class="perspective-header">
- <text class="perspective-icon">👩</text>
- <text class="perspective-title">女生视角</text>
- </view>
- <text class="perspective-content">{{ matchResult.femalePerspective }}</text>
- </view>
-
- <!-- 补充分析 -->
- <view class="perspective-item" v-if="matchResult.malePerspective2">
- <view class="perspective-header">
- <text class="perspective-icon">💭</text>
- <text class="perspective-title">深度分析</text>
- </view>
- <text class="perspective-content">{{ matchResult.malePerspective2 }}</text>
- </view>
-
- <view class="perspective-item" v-if="matchResult.femalePerspective2">
- <view class="perspective-header">
- <text class="perspective-icon">💖</text>
- <text class="perspective-title">感情建议</text>
- </view>
- <text class="perspective-content">{{ matchResult.femalePerspective2 }}</text>
- </view>
- </view>
- </view>
- <!-- 重新配对 -->
- <view class="retest-btn" @click="handleRetest">
- 重新配对
- </view>
- <!-- 数据来源说明 -->
- <view class="data-source" :class="{'api-source': isAPIData}">
- <text class="source-icon">{{ isAPIData ? '✓' : 'ℹ️' }}</text>
- <view class="source-content">
- <text class="source-text">数据来源:{{ dataSourceText }}</text>
- <text class="source-time">更新时间:{{ updateTime }}</text>
- </view>
- </view>
- <!-- 免责声明 -->
- <view class="disclaimer">
- <view class="disclaimer-title">⚠️ 免责声明</view>
- <view class="disclaimer-text">
- 本配对结果基于传统文化和民俗理论,仅供娱乐参考,不作为感情决策依据。
- 每个人的性格和缘分是多方面因素综合作用的结果,建议理性对待配对内容。
- 真正的幸福需要双方共同努力和经营。
- </view>
- </view>
- </view>
- <!-- 底部占位 -->
- <view class="bottom-placeholder"></view>
- </view>
- </template>
- <script>
- import zodiacUtil from '@/utils/zodiac.js'
- import zodiacEnhanced from '@/utils/zodiac-enhanced.js'
- export default {
- data() {
- return {
- // 生肖配对相关数据
- myZodiac: uni.getStorageSync("userInfo").animal,
- targetZodiac: '',
- myZodiacIndex: -1,
- targetZodiacIndex: -1,
- hasResult: false,
- matchResult: null,
- allZodiacs: [],
- updateTime: '',
-
- // 生肖名称列表
- zodiacNames: ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪']
- }
- },
- computed: {
- // 我的生肖emoji
- myZodiacEmoji() {
- return this.myZodiac ? zodiacUtil.getZodiacEmoji(this.myZodiac) : '🔮'
- },
-
- // 对方生肖emoji
- targetZodiacEmoji() {
- return this.targetZodiac ? zodiacUtil.getZodiacEmoji(this.targetZodiac) : '🔮'
- },
-
- // 是否使用API数据
- isAPIData() {
- return this.matchResult?.source === 'tianapi'
- },
-
- // 数据来源文本
- dataSourceText() {
- if (this.isAPIData) {
- return '天行数据专业API'
- }
- return '传统生肖配对理论'
- }
- },
- onLoad() {
- this.initData()
- },
- methods: {
- initData() {
- // 设置更新时间
- const date = new Date()
- const year = date.getFullYear()
- const month = parseInt(date.getMonth() + 1)
- const day = parseInt(date.getDate())
- this.updateTime = `${year}年${month}月${day}日`
- // 加载所有生肖
- this.allZodiacs = zodiacUtil.ZODIACS.map(name => ({
- name,
- emoji: zodiacUtil.getZodiacEmoji(name)
- }))
- },
- // 我的生肖选择
- onMyZodiacChange(e) {
- const index = e.detail.value
- this.myZodiacIndex = index
- this.myZodiac = this.zodiacNames[index]
-
- },
-
- // 对方生肖选择
- onTargetZodiacChange(e) {
- const index = e.detail.value
- this.targetZodiacIndex = index
- this.targetZodiac = this.zodiacNames[index]
-
- },
- // 提交配对
- async handleSubmit() {
- if (!this.myZodiac || !this.targetZodiac) {
- uni.showToast({
- title: '请选择双方生肖',
- icon: 'none'
- })
- return
- }
- // 显示加载中
- uni.showLoading({
- title: '配对分析中...',
- mask: true
- })
- try {
-
- // 调用天行数据配对API
- this.matchResult = await zodiacEnhanced.getZodiacMatch(this.myZodiac, this.targetZodiac)
-
- // 检查API结果并降级处理
- if (!this.matchResult) {
-
- this.matchResult = this.getLocalMatchResult()
-
- // 显示友好提示
- uni.showToast({
- title: '使用本地配对数据',
- icon: 'none',
- duration: 1500
- })
- }
-
- this.hasResult = true
-
- // 保存到本地存储
- uni.setStorageSync('zodiacMatch', {
- myZodiac: this.myZodiac,
- targetZodiac: this.targetZodiac,
- result: this.matchResult,
- lastUpdate: new Date().getTime()
- })
- } catch (error) {
-
-
- // 兜底降级到本地数据
- this.matchResult = this.getLocalMatchResult()
- this.hasResult = true
-
- uni.showToast({
- title: '配对分析异常,使用本地数据',
- icon: 'none',
- duration: 2000
- })
- } finally {
- uni.hideLoading()
- }
- },
-
- // 本地配对结果(当API失败时使用)
- getLocalMatchResult() {
- const myInfo = zodiacUtil.getZodiacInfo(this.myZodiac)
- const targetInfo = zodiacUtil.getZodiacInfo(this.targetZodiac)
-
- // 简单的配对逻辑
- const isBestMatch = myInfo.compatibility.best.includes(this.targetZodiac)
- const isGoodMatch = myInfo.compatibility.good.includes(this.targetZodiac)
-
- let analysisText = ''
- if (isBestMatch) {
- analysisText = `${this.myZodiac}和${this.targetZodiac}是非常般配的一对!你们在性格上互补,能够互相理解和支持。`
- } else if (isGoodMatch) {
- analysisText = `${this.myZodiac}和${this.targetZodiac}是比较和谐的组合,虽然偶有小摩擦,但总体来说相处愉快。`
- } else {
- analysisText = `${this.myZodiac}和${this.targetZodiac}需要更多的理解和包容,通过沟通和努力可以建立美好关系。`
- }
-
- return {
- title: `${this.myZodiac}💕${this.targetZodiac}`,
- malePerspective: analysisText,
- femalePerspective: '感情需要双方共同经营,真诚和理解是最重要的。',
- malePerspective2: `${this.myZodiac}的特点是${myInfo.personality},建议在交往中发挥这些优势。`,
- femalePerspective2: `${this.targetZodiac}的特点是${targetInfo.personality},了解对方的性格有助于更好相处。`,
- source: 'local',
- dataFrom: '传统生肖配对理论',
- updateTime: new Date().toLocaleString('zh-CN')
- }
- },
- // 获取生肖emoji
- getZodiacEmoji(zodiacName) {
- return zodiacUtil.getZodiacEmoji(zodiacName)
- },
- // 重新配对
- handleRetest() {
- this.hasResult = false
- this.myZodiac = ''
- this.targetZodiac = ''
- this.myZodiacIndex = -1
- this.targetZodiacIndex = -1
- this.matchResult = null
- },
- // 返回
- goBack() {
- uni.navigateBack({
- delta: 1
- })
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .zodiac-page {
- min-height: 100vh;
- background: linear-gradient(180deg, #FFF9F9 0%, #FFFFFF 50%);
- padding-bottom: 40rpx;
- }
- /* 自定义导航栏 */
- .custom-nav {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: space-between;
- height: 88rpx;
- padding: 0 30rpx;
- background-color: #FFFFFF;
- border-bottom: 1rpx solid #F0F0F0;
- .nav-left {
- width: 80rpx;
- .back-icon {
- font-size: 40rpx;
- color: #333333;
- }
- }
- .nav-title {
- position: absolute;
- left: 50%;
- transform: translateX(-50%);
- font-size: 34rpx;
- font-weight: 600;
- color: #333333;
- }
- .nav-right {
- width: 80rpx;
- }
- }
- /* 生肖选择区域 */
- .zodiac-selection-section {
- padding: 60rpx 30rpx;
- display: flex;
- flex-direction: column;
- align-items: center;
- .selection-card {
- width: 100%;
- background-color: #FFFFFF;
- border-radius: 30rpx;
- padding: 60rpx 40rpx;
- box-shadow: 0 8rpx 30rpx rgba(233, 30, 99, 0.1);
- text-align: center;
- .card-title {
- font-size: 40rpx;
- font-weight: bold;
- color: #333333;
- margin-bottom: 15rpx;
- }
- .card-subtitle {
- font-size: 26rpx;
- color: #999999;
- margin-bottom: 50rpx;
- }
- .zodiac-picker-wrapper {
- margin-bottom: 30rpx;
- text-align: left;
-
- .picker-label {
- font-size: 28rpx;
- color: #666666;
- margin-bottom: 15rpx;
- }
- .zodiac-display {
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: #F8F8F8;
- border-radius: 20rpx;
- padding: 25rpx 30rpx;
- border: 2rpx solid #E91E63;
- transition: all 0.3s;
- .zodiac-emoji {
- font-size: 40rpx;
- margin-right: 15rpx;
- }
- .zodiac-text {
- font-size: 32rpx;
- color: #333333;
- font-weight: 500;
- }
- }
-
- &:active .zodiac-display {
- background-color: #FFE5EE;
- transform: scale(0.98);
- }
- }
- .submit-btn {
- width: 100%;
- height: 90rpx;
- background: linear-gradient(135deg, #E91E63 0%, #FF6B9D 100%);
- color: #FFFFFF;
- font-size: 32rpx;
- font-weight: 600;
- border-radius: 45rpx;
- border: none;
- box-shadow: 0 8rpx 20rpx rgba(233, 30, 99, 0.3);
- &:disabled {
- opacity: 0.5;
- }
- &:active:not(:disabled) {
- opacity: 0.9;
- }
- }
- }
- .zodiac-icons {
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- gap: 20rpx;
- margin-top: 50rpx;
- opacity: 0.3;
- .zodiac-icon {
- font-size: 48rpx;
- animation: float 3s ease-in-out infinite;
- &:nth-child(2n) {
- animation-delay: 0.5s;
- }
- &:nth-child(3n) {
- animation-delay: 1s;
- }
- }
- }
- }
- @keyframes float {
- 0%, 100% {
- transform: translateY(0);
- }
- 50% {
- transform: translateY(-10rpx);
- }
- }
- /* 结果区域 */
- .result-section {
- padding: 30rpx 25rpx 40rpx 25rpx;
- }
- /* 配对标题卡片 */
- .match-title-card {
- background: linear-gradient(135deg, #FF6B9D 0%, #FFA5C6 100%);
- border-radius: 32rpx;
- padding: 60rpx 40rpx;
- text-align: center;
- box-shadow: 0 12rpx 40rpx rgba(233, 30, 99, 0.25);
- margin-bottom: 40rpx;
- .match-header {
- text-align: center;
-
- .zodiac-pair {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 30rpx;
-
- .zodiac-emoji-large {
- font-size: 120rpx;
- }
-
- .vs-text {
- font-size: 70rpx;
- margin: 0 30rpx;
- }
- }
- .match-title {
- font-size: 42rpx;
- font-weight: bold;
- color: #FFFFFF;
- margin-bottom: 15rpx;
- letter-spacing: 2rpx;
- }
- .match-subtitle {
- font-size: 28rpx;
- color: rgba(255, 255, 255, 0.9);
- }
- }
- }
- /* 通用标题 */
- .section-title {
- font-size: 36rpx;
- font-weight: 600;
- color: #333333;
- margin-bottom: 25rpx;
- padding: 0 10rpx;
- display: flex;
- align-items: center;
- justify-content: flex-start;
- }
- /* 配对分析 */
- .match-analysis-section {
- margin-bottom: 40rpx;
-
- .analysis-card {
- background-color: #FFFFFF;
- border-radius: 24rpx;
- padding: 0;
- box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08);
- overflow: hidden;
-
- .perspective-item {
- margin-bottom: 0;
- border-bottom: 1rpx solid #F5F5F5;
-
- &:last-child {
- border-bottom: none;
- }
-
- .perspective-header {
- display: flex;
- align-items: center;
- padding: 25rpx 30rpx 15rpx 30rpx;
- background: linear-gradient(135deg, #FFF9F9 0%, #FFFBFC 100%);
-
- .perspective-icon {
- font-size: 32rpx;
- margin-right: 15rpx;
- }
-
- .perspective-title {
- font-size: 30rpx;
- color: #E91E63;
- font-weight: 600;
- }
- }
-
- .perspective-content {
- font-size: 30rpx;
- color: #333333;
- line-height: 1.8;
- padding: 20rpx 30rpx 30rpx 30rpx;
- text-align: justify;
- background-color: #FFFFFF;
- }
- }
- }
- }
- /* 重新配对 */
- .retest-btn {
- text-align: center;
- padding: 30rpx 40rpx;
- font-size: 30rpx;
- color: #666666;
- background-color: #F8F8F8;
- border-radius: 25rpx;
- margin: 20rpx 20rpx 30rpx 20rpx;
- border: 2rpx solid #E0E0E0;
- &:active {
- color: #E91E63;
- background-color: #FFF0F5;
- border-color: #E91E63;
- }
- }
- /* 数据来源说明 */
- .data-source {
- display: flex;
- align-items: center;
- background-color: #E3F2FD;
- border-radius: 20rpx;
- padding: 25rpx 30rpx;
- margin-bottom: 30rpx;
- transition: all 0.3s;
- .source-icon {
- font-size: 32rpx;
- margin-right: 15rpx;
- }
- .source-content {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 8rpx;
- .source-text {
- font-size: 28rpx;
- color: #1976D2;
- font-weight: 500;
- }
- .source-time {
- font-size: 24rpx;
- color: #64B5F6;
- }
- }
- // API数据特殊样式
- &.api-source {
- background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
- border-left: 6rpx solid #4CAF50;
- .source-icon {
- color: #4CAF50;
- }
- .source-text {
- color: #2E7D32;
- }
- .source-time {
- color: #66BB6A;
- }
- }
- }
- /* 免责声明 */
- .disclaimer {
- background-color: #FFF3E0;
- border-radius: 20rpx;
- padding: 30rpx;
- border-left: 6rpx solid #FF9800;
- margin: 0 10rpx;
- .disclaimer-title {
- font-size: 30rpx;
- font-weight: 600;
- color: #F57C00;
- margin-bottom: 20rpx;
- }
- .disclaimer-text {
- font-size: 26rpx;
- color: #666666;
- line-height: 2.0;
- text-align: justify;
- }
- }
- /* 底部占位 */
- .bottom-placeholder {
- height: 60rpx;
- }
- </style>
|