mbti-profile.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <template>
  2. <view class="mbp-page">
  3. <view class="mbp-header">
  4. <text class="mbp-title">MBTI 16 型人格百科</text>
  5. <text class="mbp-subtitle">点击卡片查看完整画像与五维建议</text>
  6. </view>
  7. <view class="mbp-grid">
  8. <view
  9. class="mbp-card"
  10. :class="{ 'mbp-card-active': selectedType === type.code }"
  11. v-for="type in types" :key="type.code"
  12. @click="selectType(type)"
  13. >
  14. <text class="mbp-card-code">{{ type.code }}</text>
  15. <text class="mbp-card-name">{{ type.name }}</text>
  16. <text class="mbp-card-tag" :style="{ background: tagColorMap[type.tag] }">{{ type.tag }}</text>
  17. </view>
  18. </view>
  19. <view class="mbp-drawer" v-if="selectedProfile" @click.self="closeDrawer">
  20. <view class="mbp-drawer-content" @click.stop>
  21. <view class="mbp-drawer-header">
  22. <text class="mbp-drawer-code">{{ selectedProfile.typeCode }}</text>
  23. <text class="mbp-drawer-name">{{ selectedProfile.name }}</text>
  24. </view>
  25. <scroll-view class="mbp-drawer-body" scroll-y>
  26. <view class="mbp-drawer-section" v-for="(val, key) in drawerFields" :key="key" v-if="selectedProfile[key]">
  27. <text class="mbp-drawer-label">{{ val.label }}</text>
  28. <text class="mbp-drawer-value">{{ selectedProfile[key] }}</text>
  29. </view>
  30. <view class="mbp-drawer-section" v-if="selectedProfile.energySuggestion">
  31. <text class="mbp-drawer-label">五维联动建议</text>
  32. <view class="mbp-energy-mini" v-for="(sug, dim) in selectedProfile.energySuggestion" :key="dim">
  33. <text class="mbp-energy-dim" :style="{ color: dimColors[dim] }">{{ dimLabels[dim] }}: </text>
  34. <text class="mbp-energy-sug">{{ sug }}</text>
  35. </view>
  36. </view>
  37. </scroll-view>
  38. <button class="mbp-drawer-close" @click="closeDrawer">关闭</button>
  39. </view>
  40. </view>
  41. </view>
  42. </template>
  43. <script>
  44. import { getMbtiProfile } from '@/utils/api'
  45. export default {
  46. data() {
  47. return {
  48. types: [
  49. { code: 'INTJ', name: '战略家', tag: 'NT' },
  50. { code: 'INTP', name: '逻辑学家', tag: 'NT' },
  51. { code: 'ENTJ', name: '指挥官', tag: 'NT' },
  52. { code: 'ENTP', name: '辩论家', tag: 'NT' },
  53. { code: 'INFJ', name: '提倡者', tag: 'NF' },
  54. { code: 'INFP', name: '调停者', tag: 'NF' },
  55. { code: 'ENFJ', name: '主人公', tag: 'NF' },
  56. { code: 'ENFP', name: '竞选者', tag: 'NF' },
  57. { code: 'ISTJ', name: '物流师', tag: 'SJ' },
  58. { code: 'ISFJ', name: '守卫者', tag: 'SJ' },
  59. { code: 'ESTJ', name: '总经理', tag: 'SJ' },
  60. { code: 'ESFJ', name: '执政官', tag: 'SJ' },
  61. { code: 'ISTP', name: '鉴赏家', tag: 'SP' },
  62. { code: 'ISFP', name: '探险家', tag: 'SP' },
  63. { code: 'ESTP', name: '企业家', tag: 'SP' },
  64. { code: 'ESFP', name: '表演者', tag: 'SP' }
  65. ],
  66. selectedType: null,
  67. selectedProfile: null,
  68. drawerFields: {
  69. description: { label: '核心特质' },
  70. strengths: { label: '优势' },
  71. weaknesses: { label: '挑战' },
  72. career_tendency: { label: '职业倾向' },
  73. family_style: { label: '家庭风格' },
  74. pairing_notes: { label: '搭配建议' }
  75. },
  76. dimLabels: { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' },
  77. dimColors: { body: '#FF8C42', mind: '#FF6B9D', wisdom: '#6366F1', action: '#10B981', wealth: '#F59E0B' },
  78. tagColorMap: { NT: '#6366F1', NF: '#FF6B9D', SJ: '#10B981', SP: '#F59E0B' }
  79. }
  80. },
  81. methods: {
  82. selectType(type) {
  83. var self = this
  84. if (this.selectedType === type.code && this.selectedProfile) return
  85. this.selectedType = type.code
  86. getMbtiProfile({ typeCode: type.code }).then(function(res) {
  87. if (res.code === 200 && res.data) self.selectedProfile = res.data
  88. else { uni.showToast({ title: '加载失败', icon: 'none' }) }
  89. })
  90. },
  91. closeDrawer() { this.selectedType = null; this.selectedProfile = null }
  92. }
  93. }
  94. </script>
  95. <style scoped>
  96. .mbp-page { min-height: 100vh; background: #F5FAFE; padding: 24rpx 30rpx 120rpx; box-sizing: border-box }
  97. .mbp-header { text-align: center; padding: 20rpx 0 10rpx }
  98. .mbp-title { font-size: 32rpx; font-weight: 600; color: #333; display: block }
  99. .mbp-subtitle { font-size: 22rpx; color: #999; display: block; margin-top: 4rpx }
  100. .mbp-grid { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 16rpx }
  101. .mbp-card { width: 48%; background: #fff; border-radius: 20rpx; padding: 20rpx 10rpx; display: flex; flex-direction: column; align-items: center; border: 2rpx solid transparent; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.05); transition: border-color .2s }
  102. .mbp-card:active { transform: scale(0.98) }
  103. .mbp-card-active { border-color: #6366F1 }
  104. .mbp-card-code { font-size: 30rpx; font-weight: 700; color: #6366F1; margin-bottom: 4rpx }
  105. .mbp-card-name { font-size: 24rpx; color: #333; margin-bottom: 8rpx }
  106. .mbp-card-tag { font-size: 20rpx; color: #fff; padding: 2rpx 10rpx; border-radius: 10rpx }
  107. .mbp-drawer { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.4); z-index: 100; display: flex; align-items: flex-end }
  108. .mbp-drawer-content { width: 100%; max-height: 80vh; background: #fff; border-radius: 24rpx 24rpx 0 0; display: flex; flex-direction: column }
  109. .mbp-drawer-header { padding: 30rpx 20rpx; background: linear-gradient(135deg, #6366F1, #818CF8); color: #fff; display: flex; flex-direction: column; align-items: center }
  110. .mbp-drawer-code { font-size: 60rpx; font-weight: 700; letter-spacing: 8rpx }
  111. .mbp-drawer-name { font-size: 28rpx; opacity: 0.9; margin-top: 4rpx }
  112. .mbp-drawer-body { flex: 1; overflow-y: auto; padding: 20rpx }
  113. .mbp-drawer-section { margin-bottom: 24rpx }
  114. .mbp-drawer-label { display: block; font-size: 22rpx; color: #999; font-weight: 600; margin-bottom: 8rpx }
  115. .mbp-drawer-value { font-size: 24rpx; color: #333; line-height: 1.6 }
  116. .mbp-energy-mini { display: flex; flex-direction: column; gap: 8rpx; margin-top: 8rpx; padding: 16rpx; background: #F5FAFE; border-radius: 12rpx }
  117. .mbp-energy-dim { font-size: 24rpx; font-weight: 600 }
  118. .mbp-energy-sug { font-size: 24rpx; color: #555; line-height: 1.5 }
  119. .mbp-drawer-close { margin: 20rpx; height: 88rpx; line-height: 88rpx; font-size: 30rpx; border-radius: 44rpx; background: linear-gradient(135deg, #6366F1, #818CF8); color: #fff; font-weight: 600; border: none; text-align: center }
  120. </style>