| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- <template>
- <view class="mbp-page">
- <view class="mbp-header">
- <text class="mbp-title">MBTI 16 型人格百科</text>
- <text class="mbp-subtitle">点击卡片查看完整画像与五维建议</text>
- </view>
- <view class="mbp-grid">
- <view
- class="mbp-card"
- :class="{ 'mbp-card-active': selectedType === type.code }"
- v-for="type in types" :key="type.code"
- @click="selectType(type)"
- >
- <text class="mbp-card-code">{{ type.code }}</text>
- <text class="mbp-card-name">{{ type.name }}</text>
- <text class="mbp-card-tag" :style="{ background: tagColorMap[type.tag] }">{{ type.tag }}</text>
- </view>
- </view>
- <view class="mbp-drawer" v-if="selectedProfile" @click.self="closeDrawer">
- <view class="mbp-drawer-content" @click.stop>
- <view class="mbp-drawer-header">
- <text class="mbp-drawer-code">{{ selectedProfile.typeCode }}</text>
- <text class="mbp-drawer-name">{{ selectedProfile.name }}</text>
- </view>
- <scroll-view class="mbp-drawer-body" scroll-y>
- <view class="mbp-drawer-section" v-for="(val, key) in drawerFields" :key="key" v-if="selectedProfile[key]">
- <text class="mbp-drawer-label">{{ val.label }}</text>
- <text class="mbp-drawer-value">{{ selectedProfile[key] }}</text>
- </view>
- <view class="mbp-drawer-section" v-if="selectedProfile.energySuggestion">
- <text class="mbp-drawer-label">五维联动建议</text>
- <view class="mbp-energy-mini" v-for="(sug, dim) in selectedProfile.energySuggestion" :key="dim">
- <text class="mbp-energy-dim" :style="{ color: dimColors[dim] }">{{ dimLabels[dim] }}: </text>
- <text class="mbp-energy-sug">{{ sug }}</text>
- </view>
- </view>
- </scroll-view>
- <button class="mbp-drawer-close" @click="closeDrawer">关闭</button>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { getMbtiProfile } from '@/utils/api'
- export default {
- data() {
- return {
- types: [
- { code: 'INTJ', name: '战略家', tag: 'NT' },
- { code: 'INTP', name: '逻辑学家', tag: 'NT' },
- { code: 'ENTJ', name: '指挥官', tag: 'NT' },
- { code: 'ENTP', name: '辩论家', tag: 'NT' },
- { code: 'INFJ', name: '提倡者', tag: 'NF' },
- { code: 'INFP', name: '调停者', tag: 'NF' },
- { code: 'ENFJ', name: '主人公', tag: 'NF' },
- { code: 'ENFP', name: '竞选者', tag: 'NF' },
- { code: 'ISTJ', name: '物流师', tag: 'SJ' },
- { code: 'ISFJ', name: '守卫者', tag: 'SJ' },
- { code: 'ESTJ', name: '总经理', tag: 'SJ' },
- { code: 'ESFJ', name: '执政官', tag: 'SJ' },
- { code: 'ISTP', name: '鉴赏家', tag: 'SP' },
- { code: 'ISFP', name: '探险家', tag: 'SP' },
- { code: 'ESTP', name: '企业家', tag: 'SP' },
- { code: 'ESFP', name: '表演者', tag: 'SP' }
- ],
- selectedType: null,
- selectedProfile: null,
- drawerFields: {
- description: { label: '核心特质' },
- strengths: { label: '优势' },
- weaknesses: { label: '挑战' },
- career_tendency: { label: '职业倾向' },
- family_style: { label: '家庭风格' },
- pairing_notes: { label: '搭配建议' }
- },
- dimLabels: { body: '身', mind: '心', wisdom: '智', action: '行', wealth: '富' },
- dimColors: { body: '#FF8C42', mind: '#FF6B9D', wisdom: '#6366F1', action: '#10B981', wealth: '#F59E0B' },
- tagColorMap: { NT: '#6366F1', NF: '#FF6B9D', SJ: '#10B981', SP: '#F59E0B' }
- }
- },
- methods: {
- selectType(type) {
- var self = this
- if (this.selectedType === type.code && this.selectedProfile) return
- this.selectedType = type.code
- getMbtiProfile({ typeCode: type.code }).then(function(res) {
- if (res.code === 200 && res.data) self.selectedProfile = res.data
- else { uni.showToast({ title: '加载失败', icon: 'none' }) }
- })
- },
- closeDrawer() { this.selectedType = null; this.selectedProfile = null }
- }
- }
- </script>
- <style scoped>
- .mbp-page { min-height: 100vh; background: #F5FAFE; padding: 24rpx 30rpx 120rpx; box-sizing: border-box }
- .mbp-header { text-align: center; padding: 20rpx 0 10rpx }
- .mbp-title { font-size: 32rpx; font-weight: 600; color: #333; display: block }
- .mbp-subtitle { font-size: 22rpx; color: #999; display: block; margin-top: 4rpx }
- .mbp-grid { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 16rpx }
- .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 }
- .mbp-card:active { transform: scale(0.98) }
- .mbp-card-active { border-color: #6366F1 }
- .mbp-card-code { font-size: 30rpx; font-weight: 700; color: #6366F1; margin-bottom: 4rpx }
- .mbp-card-name { font-size: 24rpx; color: #333; margin-bottom: 8rpx }
- .mbp-card-tag { font-size: 20rpx; color: #fff; padding: 2rpx 10rpx; border-radius: 10rpx }
- .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 }
- .mbp-drawer-content { width: 100%; max-height: 80vh; background: #fff; border-radius: 24rpx 24rpx 0 0; display: flex; flex-direction: column }
- .mbp-drawer-header { padding: 30rpx 20rpx; background: linear-gradient(135deg, #6366F1, #818CF8); color: #fff; display: flex; flex-direction: column; align-items: center }
- .mbp-drawer-code { font-size: 60rpx; font-weight: 700; letter-spacing: 8rpx }
- .mbp-drawer-name { font-size: 28rpx; opacity: 0.9; margin-top: 4rpx }
- .mbp-drawer-body { flex: 1; overflow-y: auto; padding: 20rpx }
- .mbp-drawer-section { margin-bottom: 24rpx }
- .mbp-drawer-label { display: block; font-size: 22rpx; color: #999; font-weight: 600; margin-bottom: 8rpx }
- .mbp-drawer-value { font-size: 24rpx; color: #333; line-height: 1.6 }
- .mbp-energy-mini { display: flex; flex-direction: column; gap: 8rpx; margin-top: 8rpx; padding: 16rpx; background: #F5FAFE; border-radius: 12rpx }
- .mbp-energy-dim { font-size: 24rpx; font-weight: 600 }
- .mbp-energy-sug { font-size: 24rpx; color: #555; line-height: 1.5 }
- .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 }
- </style>
|