constellation-match.vue 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523
  1. <template>
  2. <view class="constellation-match-page">
  3. <!-- 自定义导航栏 -->
  4. <view class="custom-nav">
  5. <view class="nav-left" @click="goBack">
  6. <text class="back-icon">←</text>
  7. </view>
  8. <view class="nav-title">星座配对</view>
  9. <view class="nav-right"></view>
  10. </view>
  11. <!-- 星座选择区域 -->
  12. <view class="constellation-selection-section" v-if="!hasResult">
  13. <view class="selection-card">
  14. <view class="card-title">💕 星座配对测试</view>
  15. <view class="card-subtitle">看看你们的星座匹配度有多高</view>
  16. <!-- 我的星座选择 -->
  17. <view class="constellation-picker-wrapper">
  18. <view class="picker-label">我的星座</view>
  19. <picker mode="selector" :range="constellationNames" :value="myConstellationIndex" @change="onMyConstellationChange">
  20. <view class="constellation-display">
  21. <text class="constellation-emoji">{{ myConstellationEmoji }}</text>
  22. <text class="constellation-text">{{ myConstellation || '请选择' }}</text>
  23. </view>
  24. </picker>
  25. </view>
  26. <!-- 对方星座选择 -->
  27. <view class="constellation-picker-wrapper">
  28. <view class="picker-label">TA的星座</view>
  29. <picker mode="selector" :range="constellationNames" :value="targetConstellationIndex" @change="onTargetConstellationChange">
  30. <view class="constellation-display">
  31. <text class="constellation-emoji">{{ targetConstellationEmoji }}</text>
  32. <text class="constellation-text">{{ targetConstellation || '请选择' }}</text>
  33. </view>
  34. </picker>
  35. </view>
  36. <button class="submit-btn" @click="handleSubmit" :disabled="!myConstellation || !targetConstellation">
  37. 开始配对
  38. </button>
  39. </view>
  40. <!-- 装饰性星座图标 -->
  41. <view class="constellation-icons">
  42. <text class="constellation-icon" v-for="(constellation, index) in allConstellations" :key="index">
  43. {{ constellation.emoji }}
  44. </text>
  45. </view>
  46. </view>
  47. <!-- 配对结果 -->
  48. <view class="result-section" v-if="hasResult">
  49. <!-- 配对标题卡片 -->
  50. <view class="match-title-card">
  51. <view class="match-header">
  52. <view class="constellation-pair">
  53. <text class="constellation-emoji-large">{{ myConstellationEmoji }}</text>
  54. <text class="vs-text">💕</text>
  55. <text class="constellation-emoji-large">{{ targetConstellationEmoji }}</text>
  56. </view>
  57. <view class="match-title">{{ myConstellation }} 💕 {{ targetConstellation }}</view>
  58. <view class="match-subtitle">{{ matchResult.title || '配对分析' }}</view>
  59. </view>
  60. </view>
  61. <!-- 配对分数 -->
  62. <view class="score-section">
  63. <view class="section-title">💯 配对分数</view>
  64. <view class="score-card">
  65. <view class="score-main">
  66. <view class="score-circle" :style="{background: matchResult.scoreColor}">
  67. <text class="score-number">{{ matchResult.totalScore }}</text>
  68. <text class="score-unit">分</text>
  69. </view>
  70. <view class="score-level" :style="{background: matchResult.levelColor}">
  71. {{ matchResult.level }}
  72. </view>
  73. </view>
  74. <view class="score-breakdown">
  75. <view class="score-item" v-for="(item, index) in matchResult.scoreDetails" :key="index">
  76. <view class="score-item-header">
  77. <text class="score-item-icon">{{ item.icon }}</text>
  78. <text class="score-item-label">{{ item.label }}</text>
  79. </view>
  80. <view class="score-progress">
  81. <view class="progress-bar">
  82. <view class="progress-fill" :style="{width: item.score + '%', background: item.color}"></view>
  83. </view>
  84. <text class="progress-text">{{ item.score }}%</text>
  85. </view>
  86. </view>
  87. </view>
  88. </view>
  89. </view>
  90. <!-- API专业分析 -->
  91. <view class="api-analysis-section" v-if="matchResult.apiGrade || matchResult.apiContent">
  92. <view class="section-title">🎯 专业分析</view>
  93. <view class="api-analysis-card">
  94. <!-- API评级 -->
  95. <view class="api-grade-item" v-if="matchResult.apiGrade">
  96. <view class="grade-header">
  97. <text class="grade-icon">⭐</text>
  98. <text class="grade-title">专业评级</text>
  99. </view>
  100. <text class="grade-content">{{ matchResult.apiGrade }}</text>
  101. </view>
  102. <!-- API详细内容 -->
  103. <view class="api-content-item" v-if="matchResult.apiContent">
  104. <view class="content-header">
  105. <text class="content-icon">📝</text>
  106. <text class="content-title">详细分析</text>
  107. </view>
  108. <text class="content-text">{{ matchResult.apiContent }}</text>
  109. </view>
  110. </view>
  111. </view>
  112. <!-- 配对分析 -->
  113. <view class="match-analysis-section">
  114. <view class="section-title">💝 深度解析</view>
  115. <view class="analysis-card">
  116. <!-- 优势分析 -->
  117. <view class="analysis-item" v-if="matchResult.advantages">
  118. <view class="analysis-header">
  119. <text class="analysis-icon">✨</text>
  120. <text class="analysis-title">配对优势</text>
  121. </view>
  122. <text class="analysis-content">{{ matchResult.advantages }}</text>
  123. </view>
  124. <!-- 挑战分析 -->
  125. <view class="analysis-item" v-if="matchResult.challenges">
  126. <view class="analysis-header">
  127. <text class="analysis-icon">⚠️</text>
  128. <text class="analysis-title">潜在挑战</text>
  129. </view>
  130. <text class="analysis-content">{{ matchResult.challenges }}</text>
  131. </view>
  132. <!-- 建议 -->
  133. <view class="analysis-item" v-if="matchResult.suggestions">
  134. <view class="analysis-header">
  135. <text class="analysis-icon">💡</text>
  136. <text class="analysis-title">相处建议</text>
  137. </view>
  138. <text class="analysis-content">{{ matchResult.suggestions }}</text>
  139. </view>
  140. <!-- 总结 -->
  141. <view class="analysis-item" v-if="matchResult.summary">
  142. <view class="analysis-header">
  143. <text class="analysis-icon">💖</text>
  144. <text class="analysis-title">配对总结</text>
  145. </view>
  146. <text class="analysis-content">{{ matchResult.summary }}</text>
  147. </view>
  148. </view>
  149. </view>
  150. <!-- 元素分析 -->
  151. <view class="element-analysis-section">
  152. <view class="section-title">🔥 元素分析</view>
  153. <view class="element-card">
  154. <view class="element-pair">
  155. <view class="element-item">
  156. <text class="element-name">{{ myConstellationInfo.element }}</text>
  157. <text class="element-desc">{{ getElementDescription(myConstellationInfo.element) }}</text>
  158. </view>
  159. <text class="element-vs">VS</text>
  160. <view class="element-item">
  161. <text class="element-name">{{ targetConstellationInfo.element }}</text>
  162. <text class="element-desc">{{ getElementDescription(targetConstellationInfo.element) }}</text>
  163. </view>
  164. </view>
  165. <view class="element-compatibility">
  166. <text class="compatibility-label">元素相容性</text>
  167. <text class="compatibility-result">{{ matchResult.elementCompatibility }}</text>
  168. </view>
  169. </view>
  170. </view>
  171. <!-- 星座特质对比 -->
  172. <view class="traits-comparison-section">
  173. <view class="section-title">🌟 特质对比</view>
  174. <view class="traits-card">
  175. <view class="traits-comparison">
  176. <view class="traits-column">
  177. <view class="traits-header">
  178. <text class="traits-emoji">{{ myConstellationEmoji }}</text>
  179. <text class="traits-name">{{ myConstellation }}</text>
  180. </view>
  181. <view class="trait-tag" v-for="(trait, index) in myConstellationInfo.traits" :key="index">
  182. {{ trait }}
  183. </view>
  184. </view>
  185. <view class="traits-column">
  186. <view class="traits-header">
  187. <text class="traits-emoji">{{ targetConstellationEmoji }}</text>
  188. <text class="traits-name">{{ targetConstellation }}</text>
  189. </view>
  190. <view class="trait-tag" v-for="(trait, index) in targetConstellationInfo.traits" :key="index">
  191. {{ trait }}
  192. </view>
  193. </view>
  194. </view>
  195. </view>
  196. </view>
  197. <!-- 爱情指数预测 -->
  198. <view class="love-prediction-section">
  199. <view class="section-title">💕 爱情指数预测</view>
  200. <view class="prediction-grid">
  201. <view class="prediction-item" v-for="(item, index) in matchResult.lovePrediction" :key="index">
  202. <view class="prediction-icon-wrapper" :style="{background: item.bgColor}">
  203. <text class="prediction-icon">{{ item.icon }}</text>
  204. </view>
  205. <text class="prediction-label">{{ item.label }}</text>
  206. <text class="prediction-value">{{ item.value }}</text>
  207. </view>
  208. </view>
  209. </view>
  210. <!-- 重新配对 -->
  211. <view class="retest-btn" @click="handleRetest">
  212. 重新配对
  213. </view>
  214. <!-- 数据来源说明 -->
  215. <view class="data-source" :class="{'api-source': matchResult.source === 'tianapi'}">
  216. <text class="source-icon">{{ matchResult.source === 'tianapi' ? '✓' : 'ℹ️' }}</text>
  217. <view class="source-content">
  218. <text class="source-text">数据来源:{{ matchResult.dataFrom || '星座占星学理论' }}</text>
  219. <text class="source-time">更新时间:{{ updateTime }}</text>
  220. </view>
  221. </view>
  222. <!-- 免责声明 -->
  223. <view class="disclaimer">
  224. <view class="disclaimer-title">⚠️ 免责声明</view>
  225. <view class="disclaimer-text">
  226. 本星座配对结果基于传统占星学理论,仅供娱乐参考,不作为感情决策依据。
  227. 真正的爱情需要双方的理解、包容和努力经营。
  228. 每个人都是独特的个体,不要被星座标签所限制。
  229. </view>
  230. </view>
  231. </view>
  232. <!-- 底部占位 -->
  233. <view class="bottom-placeholder"></view>
  234. </view>
  235. </template>
  236. <script>
  237. import constellationUtil from '@/utils/constellation.js'
  238. export default {
  239. data() {
  240. return {
  241. // 星座配对相关数据
  242. myConstellation: '',
  243. targetConstellation: '',
  244. myConstellationIndex: -1,
  245. targetConstellationIndex: -1,
  246. hasResult: false,
  247. matchResult: null,
  248. updateTime: '',
  249. // 星座信息
  250. myConstellationInfo: null,
  251. targetConstellationInfo: null,
  252. // 所有星座数据
  253. allConstellations: constellationUtil.getAllConstellations(),
  254. // 星座名称列表
  255. constellationNames: constellationUtil.getAllConstellations().map(c => c.name)
  256. }
  257. },
  258. computed: {
  259. // 我的星座emoji
  260. myConstellationEmoji() {
  261. return this.myConstellation ? constellationUtil.getConstellationEmoji(this.myConstellation) : '🔮'
  262. },
  263. // 对方星座emoji
  264. targetConstellationEmoji() {
  265. return this.targetConstellation ? constellationUtil.getConstellationEmoji(this.targetConstellation) : '🔮'
  266. }
  267. },
  268. onLoad() {
  269. this.initData()
  270. },
  271. methods: {
  272. initData() {
  273. // 设置更新时间
  274. const date = new Date()
  275. const year = date.getFullYear()
  276. const month = parseInt(date.getMonth() + 1)
  277. const day = parseInt(date.getDate())
  278. this.updateTime = `${year}年${month}月${day}日`
  279. },
  280. // 我的星座选择
  281. onMyConstellationChange(e) {
  282. const index = e.detail.value
  283. this.myConstellationIndex = index
  284. this.myConstellation = this.constellationNames[index]
  285. this.myConstellationInfo = constellationUtil.getConstellationInfo(this.myConstellation)
  286. console.log('选择我的星座:', this.myConstellation)
  287. },
  288. // 对方星座选择
  289. onTargetConstellationChange(e) {
  290. const index = e.detail.value
  291. this.targetConstellationIndex = index
  292. this.targetConstellation = this.constellationNames[index]
  293. this.targetConstellationInfo = constellationUtil.getConstellationInfo(this.targetConstellation)
  294. console.log('选择对方星座:', this.targetConstellation)
  295. },
  296. // 提交配对
  297. async handleSubmit() {
  298. if (!this.myConstellation || !this.targetConstellation) {
  299. uni.showToast({
  300. title: '请选择双方星座',
  301. icon: 'none'
  302. })
  303. return
  304. }
  305. // 显示加载中
  306. uni.showLoading({
  307. title: '配对分析中...',
  308. mask: true
  309. })
  310. try {
  311. console.log('🔍 开始星座配对分析')
  312. console.log('我的星座:', this.myConstellation, '对方星座:', this.targetConstellation)
  313. // 生成配对结果
  314. this.matchResult = await this.generateMatchResult()
  315. this.hasResult = true
  316. console.log('✅ 配对分析完成')
  317. // 保存到本地存储
  318. uni.setStorageSync('constellationMatch', {
  319. myConstellation: this.myConstellation,
  320. targetConstellation: this.targetConstellation,
  321. result: this.matchResult,
  322. lastUpdate: new Date().getTime()
  323. })
  324. } catch (error) {
  325. console.error('❌ 配对分析过程异常:', error)
  326. uni.showToast({
  327. title: '分析异常,请重试',
  328. icon: 'none',
  329. duration: 2000
  330. })
  331. } finally {
  332. uni.hideLoading()
  333. }
  334. },
  335. // 生成配对结果
  336. async generateMatchResult() {
  337. try {
  338. // 调用星座配对API(优先API,失败时使用本地数据)
  339. const matchData = await constellationUtil.getDetailedConstellationMatch(
  340. this.myConstellation,
  341. this.targetConstellation
  342. )
  343. if (!matchData) {
  344. throw new Error('获取配对数据失败')
  345. }
  346. // 生成评分详情
  347. const scoreDetails = this.generateScoreDetails(matchData.totalScore)
  348. // 生成总结
  349. const summary = this.generateMatchSummary(matchData)
  350. return {
  351. title: matchData.title || `${this.myConstellation} × ${this.targetConstellation}`,
  352. totalScore: matchData.totalScore,
  353. level: matchData.level,
  354. levelColor: matchData.levelColor,
  355. scoreColor: matchData.scoreColor,
  356. scoreDetails: scoreDetails,
  357. advantages: matchData.advantages,
  358. challenges: matchData.challenges,
  359. suggestions: matchData.suggestions,
  360. summary: summary,
  361. elementCompatibility: matchData.elementCompatibility,
  362. lovePrediction: matchData.lovePrediction,
  363. // API特有数据
  364. apiGrade: matchData.apiGrade || '',
  365. apiContent: matchData.apiContent || '',
  366. source: matchData.source,
  367. dataFrom: matchData.dataFrom
  368. }
  369. } catch (error) {
  370. console.error('生成配对结果异常:', error)
  371. // 异常时使用本地算法
  372. return this.generateLocalMatchResult()
  373. }
  374. },
  375. // 生成本地配对结果(备用方案)
  376. generateLocalMatchResult() {
  377. const myInfo = this.myConstellationInfo
  378. const targetInfo = this.targetConstellationInfo
  379. // 计算基础匹配度
  380. const baseScore = this.calculateBaseScore(myInfo, targetInfo)
  381. // 生成详细分析
  382. const analysis = this.generateDetailedAnalysis(myInfo, targetInfo, baseScore)
  383. return {
  384. title: `${this.myConstellation} × ${this.targetConstellation}`,
  385. totalScore: baseScore.total,
  386. level: baseScore.level,
  387. levelColor: baseScore.levelColor,
  388. scoreColor: baseScore.scoreColor,
  389. scoreDetails: baseScore.details,
  390. advantages: analysis.advantages,
  391. challenges: analysis.challenges,
  392. suggestions: analysis.suggestions,
  393. summary: analysis.summary,
  394. elementCompatibility: analysis.elementCompatibility,
  395. lovePrediction: analysis.lovePrediction,
  396. apiGrade: '',
  397. apiContent: '',
  398. source: 'local',
  399. dataFrom: '星座占星学理论'
  400. }
  401. },
  402. // 生成评分详情
  403. generateScoreDetails(totalScore) {
  404. return [
  405. {
  406. label: '情感默契',
  407. icon: '💕',
  408. score: Math.min(totalScore + Math.floor(Math.random() * 10) - 5, 100),
  409. color: 'linear-gradient(135deg, #E91E63 0%, #FF6B9D 100%)'
  410. },
  411. {
  412. label: '性格互补',
  413. icon: '🤝',
  414. score: Math.min(totalScore + Math.floor(Math.random() * 8) - 4, 100),
  415. color: 'linear-gradient(135deg, #2196F3 0%, #64B5F6 100%)'
  416. },
  417. {
  418. label: '沟通理解',
  419. icon: '💬',
  420. score: Math.min(totalScore + Math.floor(Math.random() * 12) - 6, 100),
  421. color: 'linear-gradient(135deg, #4CAF50 0%, #81C784 100%)'
  422. },
  423. {
  424. label: '长期发展',
  425. icon: '🌱',
  426. score: Math.min(totalScore + Math.floor(Math.random() * 6) - 3, 100),
  427. color: 'linear-gradient(135deg, #9C27B0 0%, #CE93D8 100%)'
  428. }
  429. ]
  430. },
  431. // 生成配对总结
  432. generateMatchSummary(matchData) {
  433. const totalScore = matchData.totalScore
  434. const constellation1 = this.myConstellation
  435. const constellation2 = this.targetConstellation
  436. // 如果有API内容,优先使用
  437. if (matchData.apiContent) {
  438. return matchData.apiContent
  439. }
  440. // 否则使用本地生成的总结
  441. if (totalScore >= 90) {
  442. return `${constellation1}与${constellation2}的组合堪称天作之合,你们在各个方面都有着很好的默契,是令人羡慕的一对。只要继续保持这份美好,未来充满无限可能。`
  443. } else if (totalScore >= 80) {
  444. return `${constellation1}与${constellation2}是非常匹配的组合,你们能够互相理解和支持。虽然偶尔会有小摩擦,但总体来说是和谐美好的一对。`
  445. } else if (totalScore >= 70) {
  446. return `${constellation1}与${constellation2}的组合比较合适,需要双方多一些耐心和理解。通过磨合和沟通,你们能够建立稳定的关系。`
  447. } else if (totalScore >= 60) {
  448. return `${constellation1}与${constellation2}的组合需要更多努力,但这并不意味着不可能。只要双方都愿意为这份感情付出,就能克服困难。`
  449. } else {
  450. return `${constellation1}与${constellation2}的组合面临较大挑战,需要极大的包容和理解。不过,真爱面前没有不可能,关键在于是否愿意为对方改变。`
  451. }
  452. },
  453. // 计算基础匹配分数
  454. calculateBaseScore(myInfo, targetInfo) {
  455. // 元素相容性得分
  456. const elementScore = this.getElementCompatibilityScore(myInfo.element, targetInfo.element)
  457. // 性格互补性得分
  458. const personalityScore = this.getPersonalityCompatibilityScore(myInfo, targetInfo)
  459. // 传统匹配度得分
  460. const traditionalScore = this.getTraditionalCompatibilityScore(myInfo.name, targetInfo.name)
  461. // 综合计算
  462. const total = Math.round((elementScore * 0.3 + personalityScore * 0.4 + traditionalScore * 0.3))
  463. // 确定等级和颜色
  464. let level, levelColor, scoreColor
  465. if (total >= 90) {
  466. level = '天作之合'
  467. levelColor = 'linear-gradient(135deg, #FF6B9D 0%, #FFA5C6 100%)'
  468. scoreColor = 'linear-gradient(135deg, #FF6B9D 0%, #FFA5C6 100%)'
  469. } else if (total >= 80) {
  470. level = '非常匹配'
  471. levelColor = 'linear-gradient(135deg, #4CAF50 0%, #81C784 100%)'
  472. scoreColor = 'linear-gradient(135deg, #4CAF50 0%, #81C784 100%)'
  473. } else if (total >= 70) {
  474. level = '比较合适'
  475. levelColor = 'linear-gradient(135deg, #2196F3 0%, #64B5F6 100%)'
  476. scoreColor = 'linear-gradient(135deg, #2196F3 0%, #64B5F6 100%)'
  477. } else if (total >= 60) {
  478. level = '需要努力'
  479. levelColor = 'linear-gradient(135deg, #FF9800 0%, #FFB74D 100%)'
  480. scoreColor = 'linear-gradient(135deg, #FF9800 0%, #FFB74D 100%)'
  481. } else {
  482. level = '挑战较大'
  483. levelColor = 'linear-gradient(135deg, #9E9E9E 0%, #BDBDBD 100%)'
  484. scoreColor = 'linear-gradient(135deg, #9E9E9E 0%, #BDBDBD 100%)'
  485. }
  486. return {
  487. total: total,
  488. level: level,
  489. levelColor: levelColor,
  490. scoreColor: scoreColor,
  491. details: [
  492. {
  493. label: '情感默契',
  494. icon: '💕',
  495. score: Math.min(elementScore + 10, 100),
  496. color: 'linear-gradient(135deg, #E91E63 0%, #FF6B9D 100%)'
  497. },
  498. {
  499. label: '性格互补',
  500. icon: '🤝',
  501. score: personalityScore,
  502. color: 'linear-gradient(135deg, #2196F3 0%, #64B5F6 100%)'
  503. },
  504. {
  505. label: '沟通理解',
  506. icon: '💬',
  507. score: Math.min(traditionalScore + 5, 100),
  508. color: 'linear-gradient(135deg, #4CAF50 0%, #81C784 100%)'
  509. },
  510. {
  511. label: '长期发展',
  512. icon: '🌱',
  513. score: Math.min(total - 5, 100),
  514. color: 'linear-gradient(135deg, #9C27B0 0%, #CE93D8 100%)'
  515. }
  516. ]
  517. }
  518. },
  519. // 获取元素相容性得分
  520. getElementCompatibilityScore(element1, element2) {
  521. const compatibilityMatrix = {
  522. '火象': { '火象': 85, '土象': 65, '风象': 90, '水象': 45 },
  523. '土象': { '火象': 65, '土象': 80, '风象': 55, '水象': 95 },
  524. '风象': { '火象': 90, '土象': 55, '风象': 75, '水象': 70 },
  525. '水象': { '火象': 45, '土象': 95, '风象': 70, '水象': 85 }
  526. }
  527. return compatibilityMatrix[element1]?.[element2] || 70
  528. },
  529. // 获取性格相容性得分
  530. getPersonalityCompatibilityScore(myInfo, targetInfo) {
  531. // 基于传统星座配对理论的得分
  532. const isInBestList = myInfo.compatibility.best.includes(targetInfo.name)
  533. const isInGoodList = myInfo.compatibility.good.includes(targetInfo.name)
  534. const isInAvoidList = myInfo.compatibility.avoid.includes(targetInfo.name)
  535. if (isInBestList) return 95
  536. if (isInGoodList) return 80
  537. if (isInAvoidList) return 50
  538. return 70 // 中性匹配
  539. },
  540. // 获取传统配对得分
  541. getTraditionalCompatibilityScore(constellation1, constellation2) {
  542. // 反向查找,确保双向匹配
  543. const info1 = constellationUtil.getConstellationInfo(constellation1)
  544. const info2 = constellationUtil.getConstellationInfo(constellation2)
  545. let score1 = 70, score2 = 70
  546. if (info1.compatibility.best.includes(constellation2)) score1 = 95
  547. else if (info1.compatibility.good.includes(constellation2)) score1 = 80
  548. else if (info1.compatibility.avoid.includes(constellation2)) score1 = 50
  549. if (info2.compatibility.best.includes(constellation1)) score2 = 95
  550. else if (info2.compatibility.good.includes(constellation1)) score2 = 80
  551. else if (info2.compatibility.avoid.includes(constellation1)) score2 = 50
  552. return Math.round((score1 + score2) / 2)
  553. },
  554. // 生成详细分析
  555. generateDetailedAnalysis(myInfo, targetInfo, baseScore) {
  556. const myElement = myInfo.element
  557. const targetElement = targetInfo.element
  558. const totalScore = baseScore.total
  559. // 生成优势分析
  560. const advantages = this.generateAdvantages(myInfo, targetInfo, myElement, targetElement)
  561. // 生成挑战分析
  562. const challenges = this.generateChallenges(myInfo, targetInfo, myElement, targetElement)
  563. // 生成建议
  564. const suggestions = this.generateSuggestions(myInfo, targetInfo, totalScore)
  565. // 生成总结
  566. const summary = this.generateSummary(myInfo, targetInfo, totalScore)
  567. // 元素相容性描述
  568. const elementCompatibility = this.getElementCompatibilityDescription(myElement, targetElement)
  569. // 爱情指数预测
  570. const lovePrediction = this.generateLovePrediction(myInfo, targetInfo, totalScore)
  571. return {
  572. advantages,
  573. challenges,
  574. suggestions,
  575. summary,
  576. elementCompatibility,
  577. lovePrediction
  578. }
  579. },
  580. // 生成优势分析
  581. generateAdvantages(myInfo, targetInfo, myElement, targetElement) {
  582. const advantages = []
  583. // 基于元素的优势
  584. if (myElement === targetElement) {
  585. advantages.push('你们属于同一元素,有着相似的价值观和生活节奏')
  586. } else if (
  587. (myElement === '火象' && targetElement === '风象') ||
  588. (myElement === '风象' && targetElement === '火象')
  589. ) {
  590. advantages.push('火象与风象的组合充满激情与创意,能够互相激发潜能')
  591. } else if (
  592. (myElement === '土象' && targetElement === '水象') ||
  593. (myElement === '水象' && targetElement === '土象')
  594. ) {
  595. advantages.push('土象与水象的结合稳定而温馨,能够建立深厚的情感基础')
  596. }
  597. // 基于性格特质的优势
  598. const commonTraits = myInfo.traits.filter(trait => targetInfo.traits.includes(trait))
  599. if (commonTraits.length > 0) {
  600. advantages.push(`你们都具有${commonTraits.join('、')}的特质,容易产生共鸣`)
  601. }
  602. // 基于星座特性的优势
  603. if (myInfo.compatibility.best.includes(targetInfo.name)) {
  604. advantages.push('从传统占星学角度来看,你们是非常理想的配对组合')
  605. }
  606. return advantages.join(';') || '你们的组合有着独特的魅力,能够在相处中发现彼此的闪光点。'
  607. },
  608. // 生成挑战分析
  609. generateChallenges(myInfo, targetInfo, myElement, targetElement) {
  610. const challenges = []
  611. // 基于元素的挑战
  612. if (
  613. (myElement === '火象' && targetElement === '水象') ||
  614. (myElement === '水象' && targetElement === '火象')
  615. ) {
  616. challenges.push('火象与水象的组合可能在表达方式上存在差异,需要更多理解')
  617. } else if (
  618. (myElement === '土象' && targetElement === '风象') ||
  619. (myElement === '风象' && targetElement === '土象')
  620. ) {
  621. challenges.push('土象的稳重与风象的多变可能产生摩擦,需要找到平衡点')
  622. }
  623. // 基于避免列表的挑战
  624. if (myInfo.compatibility.avoid.includes(targetInfo.name)) {
  625. challenges.push('你们的性格差异较大,需要更多的耐心和包容来磨合')
  626. }
  627. // 通用挑战
  628. challenges.push('任何关系都需要双方的努力和妥协,保持开放的沟通很重要')
  629. return challenges.join(';')
  630. },
  631. // 生成建议
  632. generateSuggestions(myInfo, targetInfo, totalScore) {
  633. const suggestions = []
  634. if (totalScore >= 80) {
  635. suggestions.push('你们的匹配度很高,要珍惜这份缘分,在相处中保持真诚和理解')
  636. } else if (totalScore >= 60) {
  637. suggestions.push('通过增进了解和有效沟通,你们的关系会更加稳固')
  638. } else {
  639. suggestions.push('虽然挑战较大,但只要双方都愿意努力,任何困难都可以克服')
  640. }
  641. // 基于星座特性的建议
  642. suggestions.push(`理解${myInfo.name}的${myInfo.personality}和${targetInfo.name}的${targetInfo.personality},互相欣赏对方的独特之处`)
  643. suggestions.push('记住,星座只是参考,真正的爱情需要用心经营')
  644. return suggestions.join(';')
  645. },
  646. // 生成总结
  647. generateSummary(myInfo, targetInfo, totalScore) {
  648. if (totalScore >= 90) {
  649. return `${myInfo.name}与${targetInfo.name}的组合堪称天作之合,你们在各个方面都有着很好的默契,是令人羡慕的一对。只要继续保持这份美好,未来充满无限可能。`
  650. } else if (totalScore >= 80) {
  651. return `${myInfo.name}与${targetInfo.name}是非常匹配的组合,你们能够互相理解和支持。虽然偶尔会有小摩擦,但总体来说是和谐美好的一对。`
  652. } else if (totalScore >= 70) {
  653. return `${myInfo.name}与${targetInfo.name}的组合比较合适,需要双方多一些耐心和理解。通过磨合和沟通,你们能够建立稳定的关系。`
  654. } else if (totalScore >= 60) {
  655. return `${myInfo.name}与${targetInfo.name}的组合需要更多努力,但这并不意味着不可能。只要双方都愿意为这份感情付出,就能克服困难。`
  656. } else {
  657. return `${myInfo.name}与${targetInfo.name}的组合面临较大挑战,需要极大的包容和理解。不过,真爱面前没有不可能,关键在于是否愿意为对方改变。`
  658. }
  659. },
  660. // 获取元素相容性描述
  661. getElementCompatibilityDescription(element1, element2) {
  662. const descriptions = {
  663. '火象火象': '同为火象星座,你们都充满激情和活力,能够互相理解对方的冲动和热情',
  664. '火象土象': '火象的激情与土象的稳重形成互补,但需要找到节奏的平衡点',
  665. '火象风象': '火象与风象的结合如同火遇风,能够互相激发,创造出更大的能量',
  666. '火象水象': '火象与水象的组合对比强烈,需要更多的理解和包容',
  667. '土象土象': '同为土象星座,你们都追求稳定和安全感,能够建立坚实的关系基础',
  668. '土象风象': '土象的踏实与风象的灵活可能产生分歧,需要相互学习和适应',
  669. '土象水象': '土象与水象的组合非常和谐,既有稳定性又有情感深度',
  670. '风象风象': '同为风象星座,你们都重视精神交流,思维活跃,有很多共同话题',
  671. '风象水象': '风象的理性与水象的感性形成有趣的对比,能够互相学习',
  672. '水象水象': '同为水象星座,你们情感丰富,能够深度理解彼此的内心世界'
  673. }
  674. const key = element1 + element2
  675. return descriptions[key] || descriptions[element2 + element1] || '你们的元素组合有着独特的化学反应'
  676. },
  677. // 生成爱情指数预测
  678. generateLovePrediction(myInfo, targetInfo, totalScore) {
  679. const baseScore = totalScore
  680. return [
  681. {
  682. label: '初见印象',
  683. icon: '👀',
  684. value: Math.min(baseScore + Math.floor(Math.random() * 10) - 5, 100) + '%',
  685. bgColor: 'linear-gradient(135deg, #FFB6C1 0%, #FFE4E1 100%)'
  686. },
  687. {
  688. label: '恋爱甜蜜度',
  689. icon: '🍯',
  690. value: Math.min(baseScore + Math.floor(Math.random() * 15) - 7, 100) + '%',
  691. bgColor: 'linear-gradient(135deg, #FF6B9D 0%, #FFA5C6 100%)'
  692. },
  693. {
  694. label: '长期稳定性',
  695. icon: '🏠',
  696. value: Math.min(baseScore + Math.floor(Math.random() * 8) - 4, 100) + '%',
  697. bgColor: 'linear-gradient(135deg, #4CAF50 0%, #81C784 100%)'
  698. },
  699. {
  700. label: '婚姻契合度',
  701. icon: '💍',
  702. value: Math.min(baseScore + Math.floor(Math.random() * 12) - 6, 100) + '%',
  703. bgColor: 'linear-gradient(135deg, #9C27B0 0%, #CE93D8 100%)'
  704. }
  705. ]
  706. },
  707. // 获取元素描述
  708. getElementDescription(element) {
  709. const descriptions = {
  710. '火象': '热情、积极、冲动',
  711. '土象': '稳重、务实、踏实',
  712. '风象': '理智、灵活、善变',
  713. '水象': '感性、直觉、温柔'
  714. }
  715. return descriptions[element] || element
  716. },
  717. // 重新配对
  718. handleRetest() {
  719. this.hasResult = false
  720. this.myConstellation = ''
  721. this.targetConstellation = ''
  722. this.myConstellationIndex = -1
  723. this.targetConstellationIndex = -1
  724. this.matchResult = null
  725. this.myConstellationInfo = null
  726. this.targetConstellationInfo = null
  727. },
  728. // 返回
  729. goBack() {
  730. uni.navigateBack({
  731. delta: 1
  732. })
  733. }
  734. }
  735. }
  736. </script>
  737. <style lang="scss" scoped>
  738. .constellation-match-page {
  739. min-height: 100vh;
  740. background: linear-gradient(180deg, #FFF9F9 0%, #FFFFFF 50%);
  741. padding-bottom: 40rpx;
  742. }
  743. /* 自定义导航栏 */
  744. .custom-nav {
  745. position: relative;
  746. display: flex;
  747. align-items: center;
  748. justify-content: space-between;
  749. height: 88rpx;
  750. padding: 0 30rpx;
  751. background-color: #FFFFFF;
  752. border-bottom: 1rpx solid #F0F0F0;
  753. .nav-left {
  754. width: 80rpx;
  755. .back-icon {
  756. font-size: 40rpx;
  757. color: #333333;
  758. }
  759. }
  760. .nav-title {
  761. position: absolute;
  762. left: 50%;
  763. transform: translateX(-50%);
  764. font-size: 34rpx;
  765. font-weight: 600;
  766. color: #333333;
  767. }
  768. .nav-right {
  769. width: 80rpx;
  770. }
  771. }
  772. /* 星座选择区域 */
  773. .constellation-selection-section {
  774. padding: 60rpx 30rpx;
  775. display: flex;
  776. flex-direction: column;
  777. align-items: center;
  778. .selection-card {
  779. width: 100%;
  780. background-color: #FFFFFF;
  781. border-radius: 30rpx;
  782. padding: 60rpx 40rpx;
  783. box-shadow: 0 8rpx 30rpx rgba(233, 30, 99, 0.1);
  784. text-align: center;
  785. .card-title {
  786. font-size: 40rpx;
  787. font-weight: bold;
  788. color: #333333;
  789. margin-bottom: 15rpx;
  790. }
  791. .card-subtitle {
  792. font-size: 26rpx;
  793. color: #999999;
  794. margin-bottom: 50rpx;
  795. }
  796. .constellation-picker-wrapper {
  797. margin-bottom: 30rpx;
  798. text-align: left;
  799. .picker-label {
  800. font-size: 28rpx;
  801. color: #666666;
  802. margin-bottom: 15rpx;
  803. }
  804. .constellation-display {
  805. display: flex;
  806. align-items: center;
  807. justify-content: center;
  808. background-color: #F8F8F8;
  809. border-radius: 20rpx;
  810. padding: 25rpx 30rpx;
  811. border: 2rpx solid #E91E63;
  812. transition: all 0.3s;
  813. .constellation-emoji {
  814. font-size: 40rpx;
  815. margin-right: 15rpx;
  816. }
  817. .constellation-text {
  818. font-size: 32rpx;
  819. color: #333333;
  820. font-weight: 500;
  821. }
  822. }
  823. &:active .constellation-display {
  824. background-color: #FFE5EE;
  825. transform: scale(0.98);
  826. }
  827. }
  828. .submit-btn {
  829. width: 100%;
  830. height: 90rpx;
  831. background: linear-gradient(135deg, #E91E63 0%, #FF6B9D 100%);
  832. color: #FFFFFF;
  833. font-size: 32rpx;
  834. font-weight: 600;
  835. border-radius: 45rpx;
  836. border: none;
  837. box-shadow: 0 8rpx 20rpx rgba(233, 30, 99, 0.3);
  838. &:disabled {
  839. opacity: 0.5;
  840. }
  841. &:active:not(:disabled) {
  842. opacity: 0.9;
  843. }
  844. }
  845. }
  846. .constellation-icons {
  847. display: flex;
  848. flex-wrap: wrap;
  849. justify-content: center;
  850. gap: 20rpx;
  851. margin-top: 50rpx;
  852. opacity: 0.3;
  853. .constellation-icon {
  854. font-size: 48rpx;
  855. animation: float 3s ease-in-out infinite;
  856. &:nth-child(2n) {
  857. animation-delay: 0.5s;
  858. }
  859. &:nth-child(3n) {
  860. animation-delay: 1s;
  861. }
  862. }
  863. }
  864. }
  865. @keyframes float {
  866. 0%, 100% {
  867. transform: translateY(0);
  868. }
  869. 50% {
  870. transform: translateY(-10rpx);
  871. }
  872. }
  873. /* 结果区域 */
  874. .result-section {
  875. padding: 30rpx 25rpx 40rpx 25rpx;
  876. }
  877. /* 配对标题卡片 */
  878. .match-title-card {
  879. background: linear-gradient(135deg, #FF6B9D 0%, #FFA5C6 100%);
  880. border-radius: 32rpx;
  881. padding: 60rpx 40rpx;
  882. text-align: center;
  883. box-shadow: 0 12rpx 40rpx rgba(233, 30, 99, 0.25);
  884. margin-bottom: 40rpx;
  885. .match-header {
  886. text-align: center;
  887. .constellation-pair {
  888. display: flex;
  889. align-items: center;
  890. justify-content: center;
  891. margin-bottom: 30rpx;
  892. .constellation-emoji-large {
  893. font-size: 120rpx;
  894. }
  895. .vs-text {
  896. font-size: 70rpx;
  897. margin: 0 30rpx;
  898. }
  899. }
  900. .match-title {
  901. font-size: 42rpx;
  902. font-weight: bold;
  903. color: #FFFFFF;
  904. margin-bottom: 15rpx;
  905. letter-spacing: 2rpx;
  906. }
  907. .match-subtitle {
  908. font-size: 28rpx;
  909. color: rgba(255, 255, 255, 0.9);
  910. }
  911. }
  912. }
  913. /* 通用标题 */
  914. .section-title {
  915. font-size: 36rpx;
  916. font-weight: 600;
  917. color: #333333;
  918. margin-bottom: 25rpx;
  919. padding: 0 10rpx;
  920. display: flex;
  921. align-items: center;
  922. justify-content: flex-start;
  923. }
  924. /* 配对分数 */
  925. .score-section {
  926. margin-bottom: 40rpx;
  927. .score-card {
  928. background-color: #FFFFFF;
  929. border-radius: 24rpx;
  930. padding: 40rpx 30rpx;
  931. box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08);
  932. .score-main {
  933. display: flex;
  934. justify-content: space-between;
  935. align-items: center;
  936. margin-bottom: 40rpx;
  937. padding-bottom: 30rpx;
  938. border-bottom: 1rpx solid #F0F0F0;
  939. .score-circle {
  940. width: 150rpx;
  941. height: 150rpx;
  942. border-radius: 50%;
  943. display: flex;
  944. flex-direction: column;
  945. align-items: center;
  946. justify-content: center;
  947. color: #FFFFFF;
  948. .score-number {
  949. font-size: 48rpx;
  950. font-weight: bold;
  951. line-height: 1;
  952. }
  953. .score-unit {
  954. font-size: 24rpx;
  955. margin-top: 5rpx;
  956. }
  957. }
  958. .score-level {
  959. padding: 15rpx 40rpx;
  960. border-radius: 30rpx;
  961. font-size: 32rpx;
  962. color: #FFFFFF;
  963. font-weight: 600;
  964. }
  965. }
  966. .score-breakdown {
  967. .score-item {
  968. margin-bottom: 25rpx;
  969. &:last-child {
  970. margin-bottom: 0;
  971. }
  972. .score-item-header {
  973. display: flex;
  974. align-items: center;
  975. margin-bottom: 12rpx;
  976. .score-item-icon {
  977. font-size: 28rpx;
  978. margin-right: 12rpx;
  979. }
  980. .score-item-label {
  981. font-size: 28rpx;
  982. color: #333333;
  983. font-weight: 500;
  984. }
  985. }
  986. .score-progress {
  987. display: flex;
  988. align-items: center;
  989. .progress-bar {
  990. flex: 1;
  991. height: 12rpx;
  992. background-color: #F0F0F0;
  993. border-radius: 6rpx;
  994. overflow: hidden;
  995. margin-right: 15rpx;
  996. .progress-fill {
  997. height: 100%;
  998. border-radius: 6rpx;
  999. transition: width 0.6s ease;
  1000. }
  1001. }
  1002. .progress-text {
  1003. font-size: 24rpx;
  1004. color: #E91E63;
  1005. font-weight: 600;
  1006. min-width: 60rpx;
  1007. text-align: right;
  1008. }
  1009. }
  1010. }
  1011. }
  1012. }
  1013. }
  1014. /* API专业分析 */
  1015. .api-analysis-section {
  1016. margin-bottom: 40rpx;
  1017. .api-analysis-card {
  1018. background: linear-gradient(135deg, #E8F5E9 0%, #F1F8E9 100%);
  1019. border-radius: 24rpx;
  1020. padding: 0;
  1021. box-shadow: 0 6rpx 24rpx rgba(76, 175, 80, 0.15);
  1022. overflow: hidden;
  1023. border-left: 6rpx solid #4CAF50;
  1024. .api-grade-item, .api-content-item {
  1025. padding: 30rpx;
  1026. border-bottom: 1rpx solid rgba(76, 175, 80, 0.1);
  1027. &:last-child {
  1028. border-bottom: none;
  1029. }
  1030. .grade-header, .content-header {
  1031. display: flex;
  1032. align-items: center;
  1033. margin-bottom: 15rpx;
  1034. .grade-icon, .content-icon {
  1035. font-size: 32rpx;
  1036. margin-right: 15rpx;
  1037. }
  1038. .grade-title, .content-title {
  1039. font-size: 30rpx;
  1040. color: #2E7D32;
  1041. font-weight: 600;
  1042. }
  1043. }
  1044. .grade-content, .content-text {
  1045. font-size: 28rpx;
  1046. color: #333333;
  1047. line-height: 1.8;
  1048. text-align: justify;
  1049. margin-left: 47rpx;
  1050. }
  1051. .grade-content {
  1052. color: #4CAF50;
  1053. font-weight: 500;
  1054. }
  1055. }
  1056. }
  1057. }
  1058. /* 配对分析 */
  1059. .match-analysis-section {
  1060. margin-bottom: 40rpx;
  1061. .analysis-card {
  1062. background-color: #FFFFFF;
  1063. border-radius: 24rpx;
  1064. padding: 0;
  1065. box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08);
  1066. overflow: hidden;
  1067. .analysis-item {
  1068. padding: 30rpx;
  1069. border-bottom: 1rpx solid #F5F5F5;
  1070. &:last-child {
  1071. border-bottom: none;
  1072. }
  1073. .analysis-header {
  1074. display: flex;
  1075. align-items: center;
  1076. margin-bottom: 15rpx;
  1077. .analysis-icon {
  1078. font-size: 32rpx;
  1079. margin-right: 15rpx;
  1080. }
  1081. .analysis-title {
  1082. font-size: 30rpx;
  1083. color: #E91E63;
  1084. font-weight: 600;
  1085. }
  1086. }
  1087. .analysis-content {
  1088. font-size: 28rpx;
  1089. color: #333333;
  1090. line-height: 1.8;
  1091. text-align: justify;
  1092. margin-left: 47rpx;
  1093. }
  1094. }
  1095. }
  1096. }
  1097. /* 元素分析 */
  1098. .element-analysis-section {
  1099. margin-bottom: 40rpx;
  1100. .element-card {
  1101. background-color: #FFFFFF;
  1102. border-radius: 24rpx;
  1103. padding: 40rpx 30rpx;
  1104. box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08);
  1105. .element-pair {
  1106. display: flex;
  1107. align-items: center;
  1108. justify-content: space-between;
  1109. margin-bottom: 30rpx;
  1110. .element-item {
  1111. flex: 1;
  1112. text-align: center;
  1113. .element-name {
  1114. display: block;
  1115. font-size: 32rpx;
  1116. color: #E91E63;
  1117. font-weight: 600;
  1118. margin-bottom: 10rpx;
  1119. }
  1120. .element-desc {
  1121. font-size: 24rpx;
  1122. color: #666666;
  1123. }
  1124. }
  1125. .element-vs {
  1126. font-size: 28rpx;
  1127. color: #999999;
  1128. font-weight: 600;
  1129. margin: 0 20rpx;
  1130. }
  1131. }
  1132. .element-compatibility {
  1133. background: linear-gradient(135deg, #F3E5F5 0%, #FFEEF5 100%);
  1134. border-radius: 15rpx;
  1135. padding: 25rpx;
  1136. text-align: center;
  1137. .compatibility-label {
  1138. display: block;
  1139. font-size: 24rpx;
  1140. color: #9C27B0;
  1141. margin-bottom: 10rpx;
  1142. }
  1143. .compatibility-result {
  1144. font-size: 28rpx;
  1145. color: #333333;
  1146. line-height: 1.6;
  1147. }
  1148. }
  1149. }
  1150. }
  1151. /* 特质对比 */
  1152. .traits-comparison-section {
  1153. margin-bottom: 40rpx;
  1154. .traits-card {
  1155. background-color: #FFFFFF;
  1156. border-radius: 24rpx;
  1157. padding: 40rpx 30rpx;
  1158. box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.08);
  1159. .traits-comparison {
  1160. display: flex;
  1161. gap: 30rpx;
  1162. .traits-column {
  1163. flex: 1;
  1164. .traits-header {
  1165. display: flex;
  1166. align-items: center;
  1167. justify-content: center;
  1168. margin-bottom: 20rpx;
  1169. .traits-emoji {
  1170. font-size: 40rpx;
  1171. margin-right: 10rpx;
  1172. }
  1173. .traits-name {
  1174. font-size: 28rpx;
  1175. color: #333333;
  1176. font-weight: 600;
  1177. }
  1178. }
  1179. .trait-tag {
  1180. display: inline-block;
  1181. background: linear-gradient(135deg, #E3F2FD 0%, #F0F8FF 100%);
  1182. color: #2196F3;
  1183. font-size: 22rpx;
  1184. padding: 8rpx 16rpx;
  1185. border-radius: 20rpx;
  1186. margin: 5rpx;
  1187. border: 1rpx solid #2196F3;
  1188. }
  1189. }
  1190. }
  1191. }
  1192. }
  1193. /* 爱情指数预测 */
  1194. .love-prediction-section {
  1195. margin-bottom: 40rpx;
  1196. .prediction-grid {
  1197. display: grid;
  1198. grid-template-columns: repeat(2, 1fr);
  1199. gap: 20rpx;
  1200. .prediction-item {
  1201. display: flex;
  1202. flex-direction: column;
  1203. align-items: center;
  1204. background-color: #FFFFFF;
  1205. border-radius: 15rpx;
  1206. padding: 30rpx 20rpx;
  1207. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.06);
  1208. .prediction-icon-wrapper {
  1209. width: 80rpx;
  1210. height: 80rpx;
  1211. border-radius: 50%;
  1212. display: flex;
  1213. align-items: center;
  1214. justify-content: center;
  1215. margin-bottom: 15rpx;
  1216. .prediction-icon {
  1217. font-size: 40rpx;
  1218. }
  1219. }
  1220. .prediction-label {
  1221. font-size: 24rpx;
  1222. color: #999999;
  1223. margin-bottom: 8rpx;
  1224. }
  1225. .prediction-value {
  1226. font-size: 28rpx;
  1227. color: #333333;
  1228. font-weight: 600;
  1229. }
  1230. }
  1231. }
  1232. }
  1233. /* 重新配对 */
  1234. .retest-btn {
  1235. text-align: center;
  1236. padding: 30rpx 40rpx;
  1237. font-size: 30rpx;
  1238. color: #666666;
  1239. background-color: #F8F8F8;
  1240. border-radius: 25rpx;
  1241. margin: 20rpx 20rpx 30rpx 20rpx;
  1242. border: 2rpx solid #E0E0E0;
  1243. &:active {
  1244. color: #E91E63;
  1245. background-color: #FFF0F5;
  1246. border-color: #E91E63;
  1247. }
  1248. }
  1249. /* 数据来源说明 */
  1250. .data-source {
  1251. display: flex;
  1252. align-items: center;
  1253. background-color: #E3F2FD;
  1254. border-radius: 20rpx;
  1255. padding: 25rpx 30rpx;
  1256. margin-bottom: 30rpx;
  1257. transition: all 0.3s;
  1258. .source-icon {
  1259. font-size: 32rpx;
  1260. margin-right: 15rpx;
  1261. }
  1262. .source-content {
  1263. flex: 1;
  1264. display: flex;
  1265. flex-direction: column;
  1266. gap: 8rpx;
  1267. .source-text {
  1268. font-size: 28rpx;
  1269. color: #1976D2;
  1270. font-weight: 500;
  1271. }
  1272. .source-time {
  1273. font-size: 24rpx;
  1274. color: #64B5F6;
  1275. }
  1276. }
  1277. // API数据特殊样式
  1278. &.api-source {
  1279. background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
  1280. border-left: 6rpx solid #4CAF50;
  1281. .source-icon {
  1282. color: #4CAF50;
  1283. }
  1284. .source-text {
  1285. color: #2E7D32;
  1286. }
  1287. .source-time {
  1288. color: #66BB6A;
  1289. }
  1290. }
  1291. }
  1292. /* 免责声明 */
  1293. .disclaimer {
  1294. background-color: #FFF3E0;
  1295. border-radius: 20rpx;
  1296. padding: 30rpx;
  1297. border-left: 6rpx solid #FF9800;
  1298. margin: 0 10rpx;
  1299. .disclaimer-title {
  1300. font-size: 30rpx;
  1301. font-weight: 600;
  1302. color: #F57C00;
  1303. margin-bottom: 20rpx;
  1304. }
  1305. .disclaimer-text {
  1306. font-size: 26rpx;
  1307. color: #666666;
  1308. line-height: 2.0;
  1309. text-align: justify;
  1310. }
  1311. }
  1312. /* 底部占位 */
  1313. .bottom-placeholder {
  1314. height: 60rpx;
  1315. }
  1316. </style>