更新个人资料页和文章类型需求分析,增加增值版与普通版的计价逻辑及相关字段展示。优化小程序页面,确保用户在选择导师顾问时的跳转逻辑一致性,提升用户体验。调整文档以反映最新开发进展,增强功能可用性与团队协作效率。

This commit is contained in:
Alex-larget
2026-03-03 16:11:12 +08:00
parent 3097d796e0
commit 7064f82126
24 changed files with 1083 additions and 642 deletions

View File

@@ -201,12 +201,7 @@ Page({
async handleMatchClick() {
const currentType = MATCH_TYPES.find(t => t.id === this.data.selectedType)
// stitch_soul导师顾问 → 跳转选择导师页
if (currentType && currentType.id === 'mentor') {
wx.navigateTo({ url: '/pages/mentors/mentors' })
return
}
// 导师顾问:先播匹配动画,动画完成后再跳转(不在此处直接跳)
// 找伙伴/资源对接:需先完善联系方式
if (this.data.isLoggedIn && currentType?.matchFromDB) {
await this.ensureContactInfo(() => this._handleMatchClickInner(currentType))
@@ -346,7 +341,7 @@ Page({
this.startMatch()
},
// 匹配动画后弹出加入确认
// 匹配动画后弹出加入确认(导师顾问:动画完成后直接跳转导师页)
startMatchingAnimation(currentType) {
// 显示匹配中状态
this.setData({
@@ -360,19 +355,23 @@ Page({
this.setData({ matchAttempts: this.data.matchAttempts + 1 })
}, 500)
// 1-3秒随机延迟后显示弹窗
const delay = Math.random() * 2000 + 1000
// 1.5-3秒后:导师顾问→跳转;其他类型→弹窗
const delay = Math.random() * 1500 + 1500
setTimeout(() => {
clearInterval(timer)
this.setData({
isMatching: false,
showJoinModal: true,
joinType: currentType.id,
joinTypeLabel: currentType.matchLabel || currentType.label,
joinSuccess: false,
joinError: '',
needBindFirst: false
})
this.setData({ isMatching: false })
if (currentType && currentType.id === 'mentor') {
wx.navigateTo({ url: '/pages/mentors/mentors' })
} else {
this.setData({
showJoinModal: true,
joinType: currentType.id,
joinTypeLabel: currentType.matchLabel || currentType.label,
joinSuccess: false,
joinError: '',
needBindFirst: false
})
}
}, delay)
},

View File

@@ -1,10 +1,10 @@
const app = getApp()
const MOCK_ENRICHMENT = [
{ mbti: 'ENTJ', region: '深圳', skills: '电商运营、供应链管理、团队搭建', contactRaw: '13800138001', bestMonth: '做跨境电商独立站单月GMV突破200万净利润35万', achievement: '从0到1搭建了30人的电商团队年营收破3000万', turningPoint: '2019年从传统外贸转型跨境电商放弃稳定薪资All in创业', canHelp: '电商选品、供应链对接、团队管理SOP', needHelp: '寻找品牌合作方和内容营销人才', project: '跨境电商独立站+亚马逊多店铺运营,主营家居类目' },
{ mbti: 'INFP', region: '杭州', skills: '短视频制作、IP打造、私域运营', contactRaw: '13900139002', bestMonth: '旅游账号30天涨粉10万带货佣金收入12万', achievement: '帮助3个素人打造个人IP每个月稳定变现5万+', turningPoint: '辞去互联网大厂工作开始做自媒体,第三个月就超过原薪资', canHelp: '短视频脚本、账号冷启动、私域转化设计', needHelp: '寻找供应链资源和线下活动合作', project: '旅游+生活方式自媒体矩阵全网粉丝50万+' },
{ mbti: 'INTP', region: '厦门', skills: 'AI开发、小程序开发、系统架构', contactRaw: '13700137003', bestMonth: 'AI客服系统外包项目单月收入18万', achievement: '独立开发的SaaS产品获得天使轮200万融资', turningPoint: '从程序员转型技术创业者,学会用技术解决商业问题', canHelp: '技术方案设计、AI应用落地、小程序开发', needHelp: '需要商业化运营和市场推广合伙人', project: 'AI+私域运营工具SaaS平台' },
{ mbti: 'ESTP', region: '成都', skills: '资源对接、商务BD、活动策划', contactRaw: '13600136004', bestMonth: '撮合景区合作居间费收入25万', achievement: '组建覆盖全国50+城市创业者社群活跃成员3000+', turningPoint: '在Soul派对房认识第一个合伙人打开了社交创业的大门', canHelp: '各行业资源对接、活动策划、社群引荐', needHelp: '寻找技术合伙人和内容创作者', project: '创业者资源对接平台+线下创业者沙龙' }
{ mbti: 'ENTJ', region: '深圳', industry: '跨境电商', position: '创始人', businessScale: '年GMV 3000万+', skills: '电商运营、供应链管理、团队搭建', contactRaw: '13800138001', wechatRaw: 'wxid_entj001', bestMonth: '做跨境电商独立站单月GMV突破200万净利润35万', achievement: '从0到1搭建了30人的电商团队年营收破3000万', turningPoint: '2019年从传统外贸转型跨境电商放弃稳定薪资All in创业', canHelp: '电商选品、供应链对接、团队管理SOP', needHelp: '寻找品牌合作方和内容营销人才', project: '跨境电商独立站+亚马逊多店铺运营,主营家居类目' },
{ mbti: 'INFP', region: '杭州', industry: '新媒体/电商', position: '创始人', businessScale: '年GMV 5000万+', skills: '短视频制作、IP打造、私域运营', contactRaw: '13900139002', wechatRaw: 'wxid_****abc', bestMonth: '旅游账号30天涨粉10万带货佣金收入12万', achievement: '帮助3个素人打造个人IP每个月稳定变现5万+', turningPoint: '辞去互联网大厂工作开始做自媒体,第三个月就超过原薪资', canHelp: '短视频脚本、账号冷启动、私域转化设计', needHelp: '寻找供应链资源和线下活动合作', project: '旅游+生活方式自媒体矩阵全网粉丝50万+' },
{ mbti: 'INTP', region: '厦门', industry: 'SaaS/技术', position: '技术合伙人', businessScale: '天使轮200万', skills: 'AI开发、小程序开发、系统架构', contactRaw: '13700137003', wechatRaw: 'wxid_intp003', bestMonth: 'AI客服系统外包项目单月收入18万', achievement: '独立开发的SaaS产品获得天使轮200万融资', turningPoint: '从程序员转型技术创业者,学会用技术解决商业问题', canHelp: '技术方案设计、AI应用落地、小程序开发', needHelp: '需要商业化运营和市场推广合伙人', project: 'AI+私域运营工具SaaS平台' },
{ mbti: 'ESTP', region: '成都', industry: '资源对接', position: '联合创始人', businessScale: '50+城市', skills: '资源对接、商务BD、活动策划', contactRaw: '13600136004', wechatRaw: 'wxid_estp004', bestMonth: '撮合景区合作居间费收入25万', achievement: '组建覆盖全国50+城市创业者社群活跃成员3000+', turningPoint: '在Soul派对房认识第一个合伙人打开了社交创业的大门', canHelp: '各行业资源对接、活动策划、社群引荐', needHelp: '寻找技术合伙人和内容创作者', project: '创业者资源对接平台+线下创业者沙龙' }
]
Page({
@@ -33,8 +33,16 @@ Page({
this.setData({ member: this.enrichAndFormat({
id: u.id, name: u.vipName || u.vip_name || u.nickname || '创业者',
avatar: u.vipAvatar || u.vip_avatar || u.avatar || '', isVip: u.is_vip === 1,
contactRaw: u.vipContact || u.vip_contact || u.phone || '', project: u.vipProject || u.vip_project || '',
bio: u.vipBio || u.vip_bio || '', mbti: '', region: '', skills: '',
contactRaw: u.vipContact || u.vip_contact || u.phone || '',
wechatId: u.wechatId || u.wechat_id,
project: u.vipProject || u.vip_project || u.projectIntro || u.project_intro || '',
industry: u.industry, position: u.position, businessScale: u.businessScale || u.business_scale,
skills: u.skills, mbti: u.mbti, region: u.region,
storyBestMonth: u.storyBestMonth || u.story_best_month,
storyAchievement: u.storyAchievement || u.story_achievement,
storyTurning: u.storyTurning || u.story_turning,
helpOffer: u.helpOffer || u.help_offer,
helpNeed: u.helpNeed || u.help_need,
}), loading: false })
return
}
@@ -54,21 +62,29 @@ Page({
isVip: raw.isVip || raw.is_vip === 1,
mbti: raw.mbti || mock.mbti,
region: raw.region || mock.region,
industry: raw.industry || mock.industry,
position: raw.position || mock.position,
businessScale: raw.businessScale || raw.business_scale || mock.businessScale,
skills: raw.skills || mock.skills,
contactRaw: raw.contactRaw || raw.vipContact || raw.vip_contact || mock.contactRaw,
bestMonth: raw.bestMonth || mock.bestMonth,
achievement: raw.achievement || mock.achievement,
turningPoint: raw.turningPoint || mock.turningPoint,
canHelp: raw.canHelp || mock.canHelp,
needHelp: raw.needHelp || mock.needHelp,
project: raw.project || raw.vipProject || raw.vip_project || mock.project
contactRaw: raw.contactRaw || raw.vipContact || raw.vip_contact || raw.phone || mock.contactRaw,
wechatRaw: raw.wechatRaw || raw.wechatId || raw.wechat_id || mock.wechatRaw,
bestMonth: raw.bestMonth || raw.storyBestMonth || raw.story_best_month || mock.bestMonth,
achievement: raw.achievement || raw.storyAchievement || raw.story_achievement || mock.achievement,
turningPoint: raw.turningPoint || raw.storyTurning || raw.story_turning || mock.turningPoint,
canHelp: raw.canHelp || raw.helpOffer || raw.help_offer || mock.canHelp,
needHelp: raw.needHelp || raw.helpNeed || raw.help_need || mock.needHelp,
project: raw.project || raw.vipProject || raw.vip_project || raw.projectIntro || raw.project_intro || mock.project
}
const contact = merged.contactRaw || ''
const wechat = merged.wechatRaw || ''
const isMatched = (app.globalData.matchedUsers || []).includes(merged.id)
merged.contactDisplay = contact ? (contact.slice(0, 3) + '****' + (contact.length > 7 ? contact.slice(-2) : '')) : ''
merged.contactUnlocked = isMatched
merged.contactFull = contact
merged.wechatDisplay = wechat ? (wechat.slice(0, 4) + '****' + (wechat.length > 8 ? wechat.slice(-3) : '')) : ''
merged.wechatUnlocked = isMatched
merged.wechatFull = wechat
return merged
},
@@ -86,6 +102,12 @@ Page({
wx.setClipboardData({ data: c, success: () => wx.showToast({ title: '已复制', icon: 'success' }) })
},
copyWechat() {
const w = this.data.member?.wechatFull
if (!w) return
wx.setClipboardData({ data: w, success: () => wx.showToast({ title: '已复制', icon: 'success' }) })
},
goToMatch() { wx.switchTab({ url: '/pages/match/match' }) },
goToVip() { wx.navigateTo({ url: '/pages/vip/vip' }) },
goBack() { wx.navigateBack() },

View File

@@ -1,101 +1,147 @@
<!-- Soul创业派对 - 超级个体详情(按 enhanced_professional_profile 1:1 还原) -->
<view class="page">
<!-- 导航栏 -->
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
<view class="nav-back" bindtap="goBack"><text class="back-arrow"></text></view>
<text class="nav-title">超级个体</text>
<view class="nav-ph"></view>
<view class="nav-back" bindtap="goBack">
<text class="nav-icon"></text>
</view>
<text class="nav-title">个人资料</text>
<view class="nav-right">
<view class="nav-icon-wrap"><text class="nav-icon">⋯</text></view>
<view class="nav-icon-wrap"><text class="nav-icon-dot">●</text></view>
</view>
</view>
<view style="height: {{statusBarHeight + 44}}px;"></view>
<scroll-view scroll-y class="scroll-wrap" wx:if="{{member}}">
<!-- ===== 顶部名片 ===== -->
<view class="card-hero">
<view class="hero-deco"></view>
<view class="hero-deco2"></view>
<view class="hero-body">
<view class="avatar-ring {{member.isVip ? 'vip-ring' : ''}}">
<!-- 顶部 profile 卡片 -->
<view class="card-profile">
<view class="profile-deco"></view>
<view class="profile-body">
<view class="avatar-wrap {{member.isVip ? 'vip-ring' : ''}}">
<image class="avatar-img" wx:if="{{member.avatar}}" src="{{member.avatar}}" mode="aspectFill"/>
<view class="avatar-ph" wx:else><text>{{member.name[0] || '创'}}</text></view>
<view class="vip-tag" wx:if="{{member.isVip}}">VIP</view>
</view>
<text class="hero-name">{{member.name}}</text>
<view class="hero-tags">
<text class="tag-item tag-mbti" wx:if="{{member.mbti}}">{{member.mbti}}</text>
<text class="tag-item tag-region" wx:if="{{member.region}}">📍{{member.region}}</text>
<text class="profile-name">{{member.name}}</text>
<view class="profile-tags">
<text class="tag tag-mbti" wx:if="{{member.mbti}}">{{member.mbti}}</text>
<text class="tag tag-region" wx:if="{{member.region}}"><text class="pin-icon">📍</text>{{member.region}}</text>
</view>
</view>
</view>
<!-- ===== 基本信息 ===== -->
<!-- 基本信息 -->
<view class="card">
<view class="card-head"><text class="card-icon">👤</text><text class="card-label">基本信息</text></view>
<view class="field" wx:if="{{member.skills}}">
<text class="f-key">我擅长</text>
<text class="f-val">{{member.skills}}</text>
<view class="card-head">
<text class="card-icon">👤</text>
<text class="card-label">基本信息</text>
</view>
<view class="field" wx:if="{{member.contactDisplay}}">
<text class="f-key">联系方式</text>
<view class="f-contact">
<text class="f-val masked">{{member.contactDisplay}}</text>
<view class="lock-chip" wx:if="{{!member.contactUnlocked}}" bindtap="unlockContact">
<text class="lock-icon">🔒</text><text>匹配解锁</text>
<view class="card-body">
<view class="field" wx:if="{{member.industry}}">
<text class="f-key">行业</text>
<text class="f-val">{{member.industry}}</text>
</view>
<view class="field" wx:if="{{member.position}}">
<text class="f-key">职位</text>
<text class="f-val">{{member.position}}</text>
</view>
<view class="field" wx:if="{{member.businessScale}}">
<text class="f-key">业务体量</text>
<text class="f-val">{{member.businessScale}}</text>
</view>
<view class="divider" wx:if="{{member.industry || member.position || member.businessScale}}"></view>
<view class="field" wx:if="{{member.skills}}">
<text class="f-key">我擅长</text>
<text class="f-val">{{member.skills}}</text>
</view>
<view class="field" wx:if="{{member.contactDisplay || member.contactRaw}}">
<text class="f-key">联系方式</text>
<view class="f-row">
<text class="f-val mono">{{member.contactDisplay || '未填写'}}</text>
<view class="icon-copy" wx:if="{{!member.contactUnlocked}}" bindtap="unlockContact">🔒</view>
<view class="icon-copy" wx:else bindtap="copyContact">📋</view>
</view>
</view>
<view class="field" wx:if="{{member.wechatDisplay || member.wechatRaw}}">
<text class="f-key">微信号</text>
<view class="f-row">
<text class="f-val mono">{{member.wechatDisplay || '未填写'}}</text>
<view class="icon-copy" wx:if="{{!member.wechatUnlocked}}" bindtap="unlockContact">🔒</view>
<view class="icon-copy" wx:else bindtap="copyWechat">📋</view>
</view>
<view class="copy-chip" wx:if="{{member.contactUnlocked}}" bindtap="copyContact">复制</view>
</view>
</view>
</view>
<!-- ===== 个人故事 ===== -->
<!-- 个人故事 -->
<view class="card" wx:if="{{member.bestMonth || member.achievement || member.turningPoint}}">
<view class="card-head"><text class="card-icon">💡</text><text class="card-label">个人故事</text></view>
<view class="story" wx:if="{{member.bestMonth}}">
<text class="story-q">🏆 最赚钱的一个月做的是什么</text>
<text class="story-a">{{member.bestMonth}}</text>
<view class="card-head">
<text class="card-icon bulb">💡</text>
<text class="card-label">个人故事</text>
</view>
<view class="divider"></view>
<view class="story" wx:if="{{member.achievement}}">
<text class="story-q">⭐ 最有成就感的一件事</text>
<text class="story-a">{{member.achievement}}</text>
</view>
<view class="divider"></view>
<view class="story" wx:if="{{member.turningPoint}}">
<text class="story-q">🔄 人生的转折点</text>
<text class="story-a">{{member.turningPoint}}</text>
<view class="card-body">
<view class="story" wx:if="{{member.bestMonth}}">
<view class="story-head"><text class="story-icon">🏆</text><text class="story-q">最赚钱的一个月做的是什么</text></view>
<text class="story-a">{{member.bestMonth}}</text>
</view>
<view class="divider" wx:if="{{member.bestMonth && (member.achievement || member.turningPoint)}}"></view>
<view class="story" wx:if="{{member.achievement}}">
<view class="story-head"><text class="story-icon">⭐</text><text class="story-q">最有成就感的一件事</text></view>
<text class="story-a">{{member.achievement}}</text>
</view>
<view class="divider" wx:if="{{member.achievement && member.turningPoint}}"></view>
<view class="story" wx:if="{{member.turningPoint}}">
<view class="story-head"><text class="story-icon turn">🔄</text><text class="story-q">人生的转折点</text></view>
<text class="story-a">{{member.turningPoint}}</text>
</view>
</view>
</view>
<!-- ===== 互助需求 ===== -->
<!-- 互助需求 -->
<view class="card" wx:if="{{member.canHelp || member.needHelp}}">
<view class="card-head"><text class="card-icon">🤝</text><text class="card-label">互助需求</text></view>
<view class="help-box help-give" wx:if="{{member.canHelp}}">
<text class="help-tag">我能帮到你</text>
<text class="help-txt">{{member.canHelp}}</text>
<view class="card-head">
<text class="card-icon">🤝</text>
<text class="card-label">互助需求</text>
</view>
<view class="help-box help-need" wx:if="{{member.needHelp}}">
<text class="help-tag need">我需要帮助</text>
<text class="help-txt">{{member.needHelp}}</text>
<view class="card-body">
<view class="help-box help-give" wx:if="{{member.canHelp}}">
<text class="help-tag">我能帮你</text>
<text class="help-txt">{{member.canHelp}}</text>
</view>
<view class="help-box help-need" wx:if="{{member.needHelp}}">
<text class="help-tag need">我需要帮助</text>
<text class="help-txt">{{member.needHelp}}</text>
</view>
</view>
</view>
<!-- ===== 项目介绍 ===== -->
<!-- 项目介绍 -->
<view class="card" wx:if="{{member.project}}">
<view class="card-head"><text class="card-icon">🚀</text><text class="card-label">项目介绍</text></view>
<view class="card-head">
<text class="card-icon rocket">🚀</text>
<text class="card-label">项目介绍</text>
</view>
<text class="proj-txt">{{member.project}}</text>
</view>
<!-- ===== 底部操作 ===== -->
<view class="bottom-actions">
<view class="btn-match" bindtap="goToMatch">开始匹配 · 解锁联系方式</view>
<view class="btn-vip" bindtap="goToVip" wx:if="{{!member.isVip}}">成为超级个体 →</view>
<!-- 底部按钮 -->
<view class="bottom-wrap">
<view class="btn-super" bindtap="goToVip">
<text>成为超级个体</text>
<text class="btn-arrow">→</text>
</view>
</view>
<view style="height:120rpx;"></view>
<view style="height:160rpx;"></view>
</scroll-view>
<!-- 加载和空状态 -->
<view class="state-wrap" wx:if="{{loading}}">
<view class="loading-dot"></view><text class="state-txt">加载中...</text>
<view class="loading-dot"></view>
<text class="state-txt">加载中...</text>
</view>
<view class="state-wrap" wx:if="{{!loading && !member}}">
<text class="state-emoji">👤</text><text class="state-txt">暂无该超级个体信息</text>
<text class="state-emoji">👤</text>
<text class="state-txt">暂无该超级个体信息</text>
</view>
</view>

View File

@@ -1,75 +1,164 @@
.page { background: #050a10; min-height: 100vh; color: #fff; }
/* Soul创业派对 - 个人资料页enhanced_professional_profile 1:1 还原) */
.page { background: #050B14; min-height: 100vh; color: #fff; }
/* 导航 */
.nav-bar { position: fixed; top: 0; left: 0; right: 0; z-index: 999; display: flex; align-items: center; justify-content: space-between; padding: 0 24rpx; height: 44px; background: rgba(5,10,16,.92); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); border-bottom: 1rpx solid rgba(56,189,172,.08); }
.back-arrow { font-size: 48rpx; color: #38bdac; font-weight: 300; }
.nav-title { font-size: 32rpx; font-weight: 600; letter-spacing: 2rpx; }
.nav-ph { width: 48rpx; }
.nav-back { width: 48rpx; height: 48rpx; display: flex; align-items: center; justify-content: center; }
/* 导航 */
.nav-bar {
position: fixed; top: 0; left: 0; right: 0; z-index: 999;
display: flex; align-items: center; justify-content: space-between;
padding: 0 32rpx; height: 44px;
background: rgba(5, 11, 20, 0.9);
backdrop-filter: blur(24rpx);
-webkit-backdrop-filter: blur(24rpx);
border-bottom: 1rpx solid rgba(255, 255, 255, 0.05);
}
.nav-back { width: 80rpx; height: 80rpx; display: flex; align-items: center; justify-content: flex-start; }
.nav-icon { font-size: 44rpx; color: #5EEAD4; font-weight: 300; }
.nav-title { font-size: 34rpx; font-weight: 700; color: #fff; letter-spacing: 2rpx; }
.nav-right { display: flex; align-items: center; gap: 16rpx; }
.nav-icon-wrap { padding: 8rpx; }
.nav-icon-dot { font-size: 28rpx; color: rgba(255,255,255,0.8); }
.scroll-wrap { height: calc(100vh - 88px); }
/* ===== 顶部片 ===== */
.card-hero { position: relative; margin: 24rpx 24rpx 0; padding: 56rpx 0 40rpx; border-radius: 28rpx; overflow: hidden; background: linear-gradient(160deg, #0d1f2d 0%, #0a1620 40%, #101828 100%); border: 1rpx solid rgba(56,189,172,.15); }
.hero-deco { position: absolute; top: -60rpx; right: -60rpx; width: 240rpx; height: 240rpx; border-radius: 50%; background: radial-gradient(circle, rgba(56,189,172,.12) 0%, transparent 70%); }
.hero-deco2 { position: absolute; bottom: -40rpx; left: -40rpx; width: 180rpx; height: 180rpx; border-radius: 50%; background: radial-gradient(circle, rgba(245,166,35,.06) 0%, transparent 70%); }
.hero-body { position: relative; display: flex; flex-direction: column; align-items: center; z-index: 1; }
.avatar-ring { position: relative; width: 168rpx; height: 168rpx; border-radius: 50%; padding: 6rpx; background: linear-gradient(135deg, #1a3a3a, #0d1f2d); margin-bottom: 20rpx; }
.avatar-ring.vip-ring { background: linear-gradient(135deg, #f5a623, #38bdac, #f5a623); background-size: 300% 300%; animation: vipGlow 4s ease infinite; }
@keyframes vipGlow { 0%,100%{background-position:0% 50%} 50%{background-position:100% 50%} }
.avatar-img { width: 100%; height: 100%; border-radius: 50%; border: 4rpx solid #0a1620; }
.avatar-ph { width: 100%; height: 100%; border-radius: 50%; border: 4rpx solid #0a1620; background: #152030; display: flex; align-items: center; justify-content: center; font-size: 52rpx; color: #38bdac; font-weight: 700; }
.vip-tag { position: absolute; bottom: 4rpx; right: 4rpx; background: linear-gradient(135deg, #f5a623, #e8920d); color: #000; font-size: 18rpx; font-weight: 800; padding: 4rpx 14rpx; border-radius: 16rpx; letter-spacing: 1rpx; box-shadow: 0 4rpx 12rpx rgba(245,166,35,.4); }
.hero-name { font-size: 38rpx; font-weight: 700; letter-spacing: 2rpx; margin-bottom: 12rpx; text-shadow: 0 2rpx 8rpx rgba(0,0,0,.5); }
.hero-tags { display: flex; gap: 12rpx; flex-wrap: wrap; justify-content: center; }
.tag-item { font-size: 22rpx; padding: 6rpx 18rpx; border-radius: 24rpx; }
.tag-mbti { color: #38bdac; background: rgba(56,189,172,.12); border: 1rpx solid rgba(56,189,172,.2); }
.tag-region { color: #ccc; background: rgba(255,255,255,.06); border: 1rpx solid rgba(255,255,255,.08); }
/* ===== 顶部 Profile 卡片 ===== */
.card-profile {
position: relative; margin: 32rpx 32rpx 0;
padding: 64rpx 40rpx 48rpx;
border-radius: 32rpx;
background: #0F1720;
border: 1rpx solid rgba(255, 255, 255, 0.08);
overflow: hidden;
}
.profile-deco {
position: absolute; top: 0; left: 0; right: 0; height: 128rpx;
background: linear-gradient(180deg, rgba(30, 58, 69, 0.3) 0%, transparent 100%);
pointer-events: none;
}
.profile-body { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; }
.avatar-wrap {
position: relative;
width: 176rpx; height: 176rpx;
border-radius: 50%;
overflow: hidden;
margin-bottom: 32rpx;
border: 2rpx solid rgba(255, 255, 255, 0.1);
box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.4);
}
.avatar-wrap.vip-ring {
border: 4rpx solid transparent;
background: linear-gradient(135deg, #F59E0B, #5EEAD4, #F59E0B);
background-size: 200% 200%;
animation: vipGlow 4s ease infinite;
}
@keyframes vipGlow {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
.avatar-img { width: 100%; height: 100%; object-fit: cover; }
.avatar-ph {
width: 100%; height: 100%;
background: #17212F;
display: flex; align-items: center; justify-content: center;
font-size: 56rpx; color: #5EEAD4; font-weight: 700;
}
.vip-tag {
position: absolute; bottom: 4rpx; right: 4rpx;
background: linear-gradient(135deg, #F59E0B, #e8920d);
color: #000; font-size: 20rpx; font-weight: 800;
padding: 6rpx 16rpx; border-radius: 20rpx;
}
.profile-name { font-size: 40rpx; font-weight: 700; color: #fff; margin-bottom: 24rpx; letter-spacing: 2rpx; }
.profile-tags { display: flex; align-items: center; justify-content: center; gap: 24rpx; flex-wrap: wrap; }
.tag { font-size: 24rpx; font-weight: 500; padding: 8rpx 24rpx; border-radius: 999rpx; }
.tag-mbti { background: #134E4A; color: #5EEAD4; border: 1rpx solid rgba(94, 234, 212, 0.2); }
.tag-region { background: #1F2937; color: #D1D5DB; border: 1rpx solid rgba(255, 255, 255, 0.1); display: flex; align-items: center; gap: 8rpx; }
.pin-icon { color: #EF4444; font-size: 22rpx; }
/* ===== 通用卡片 ===== */
.card { margin: 20rpx 24rpx; padding: 28rpx 28rpx; border-radius: 24rpx; background: rgba(15,25,40,.8); border: 1rpx solid rgba(255,255,255,.06); backdrop-filter: blur(10px); }
.card-head { display: flex; align-items: center; gap: 10rpx; margin-bottom: 24rpx; }
.card-icon { font-size: 28rpx; }
.card-label { font-size: 28rpx; font-weight: 600; color: #fff; letter-spacing: 1rpx; }
.card {
margin: 32rpx;
padding: 40rpx 40rpx;
border-radius: 32rpx;
background: #0F1720;
border: 1rpx solid rgba(255, 255, 255, 0.08);
}
.card-head { display: flex; align-items: center; gap: 20rpx; margin-bottom: 40rpx; }
.card-icon { font-size: 40rpx; }
.card-icon.bulb { filter: sepia(1) saturate(3) hue-rotate(15deg); }
.card-icon.rocket { opacity: 0.9; }
.card-label { font-size: 30rpx; font-weight: 700; color: #fff; letter-spacing: 1rpx; }
.field { margin-bottom: 20rpx; }
.card-body { }
.field { margin-bottom: 32rpx; }
.field:last-child { margin-bottom: 0; }
.f-key { display: block; font-size: 22rpx; color: #6b7b8e; margin-bottom: 8rpx; text-transform: uppercase; letter-spacing: 2rpx; }
.f-val { font-size: 28rpx; color: #e0e8f0; line-height: 1.7; }
.f-contact { display: flex; align-items: center; gap: 16rpx; }
.masked { letter-spacing: 3rpx; font-family: 'Courier New', monospace; }
.lock-chip { display: flex; align-items: center; gap: 6rpx; font-size: 20rpx; color: #f5a623; background: rgba(245,166,35,.1); border: 1rpx solid rgba(245,166,35,.2); padding: 6rpx 16rpx; border-radius: 20rpx; white-space: nowrap; }
.lock-icon { font-size: 18rpx; }
.copy-chip { font-size: 20rpx; color: #38bdac; background: rgba(56,189,172,.1); border: 1rpx solid rgba(56,189,172,.2); padding: 6rpx 16rpx; border-radius: 20rpx; white-space: nowrap; }
.f-key { display: block; font-size: 26rpx; color: #94A3B8; margin-bottom: 12rpx; }
.f-val { font-size: 30rpx; font-weight: 500; color: #fff; line-height: 1.6; }
.f-val.mono { font-family: ui-monospace, monospace; letter-spacing: 2rpx; }
.f-row { display: flex; align-items: center; gap: 16rpx; }
.icon-copy { font-size: 36rpx; color: #94A3B8; opacity: 0.6; padding: 8rpx; }
/* ===== 故事 ===== */
.story { padding: 4rpx 0; }
.story-q { display: block; font-size: 24rpx; color: #7a8fa3; margin-bottom: 10rpx; }
.story-a { display: block; font-size: 28rpx; color: #e0e8f0; line-height: 1.8; }
.divider { height: 1rpx; background: rgba(255,255,255,.04); margin: 20rpx 0; }
.divider { height: 1rpx; background: rgba(255, 255, 255, 0.05); margin: 32rpx 0; }
/* ===== 互助 ===== */
.help-box { padding: 20rpx; border-radius: 16rpx; margin-bottom: 16rpx; }
/* ===== 个人故事 ===== */
.story { margin-bottom: 32rpx; }
.story:last-child { margin-bottom: 0; }
.story-head { display: flex; align-items: center; gap: 12rpx; margin-bottom: 12rpx; }
.story-icon { font-size: 32rpx; }
.story-icon.turn { opacity: 0.9; }
.story-q { font-size: 26rpx; font-weight: 500; color: #94A3B8; }
.story-a { display: block; font-size: 28rpx; color: #E5E7EB; line-height: 1.7; }
/* ===== 互助需求 ===== */
.help-box {
padding: 32rpx;
border-radius: 24rpx;
margin-bottom: 24rpx;
background: #17212F;
border: 1rpx solid rgba(255, 255, 255, 0.05);
}
.help-box:last-child { margin-bottom: 0; }
.help-give { background: rgba(56,189,172,.06); border: 1rpx solid rgba(56,189,172,.1); }
.help-need { background: rgba(245,166,35,.06); border: 1rpx solid rgba(245,166,35,.1); }
.help-tag { display: inline-block; font-size: 22rpx; font-weight: 600; color: #38bdac; margin-bottom: 10rpx; padding: 4rpx 14rpx; border-radius: 12rpx; background: rgba(56,189,172,.12); }
.help-tag.need { color: #f5a623; background: rgba(245,166,35,.12); }
.help-txt { display: block; font-size: 26rpx; color: #ccd4de; line-height: 1.7; }
.help-tag {
display: inline-block;
font-size: 22rpx; font-weight: 600;
padding: 6rpx 16rpx; border-radius: 12rpx;
margin-bottom: 16rpx;
}
.help-give .help-tag { color: #5EEAD4; background: #112D2A; }
.help-need .help-tag { color: #F59E0B; background: #2D1F0D; }
.help-txt { display: block; font-size: 26rpx; color: #fff; line-height: 1.6; letter-spacing: 1rpx; }
/* ===== 项目 ===== */
.proj-txt { font-size: 26rpx; color: #ccd4de; line-height: 1.8; }
/* ===== 项目介绍 ===== */
.proj-txt { font-size: 28rpx; color: #E5E7EB; line-height: 1.7; }
/* ===== 底部按钮 ===== */
.bottom-actions { padding: 32rpx 24rpx 0; display: flex; flex-direction: column; gap: 16rpx; }
.btn-match { text-align: center; padding: 26rpx 0; border-radius: 48rpx; font-size: 30rpx; font-weight: 700; letter-spacing: 2rpx; background: linear-gradient(135deg, #38bdac 0%, #2ca898 50%, #249e8c 100%); color: #fff; box-shadow: 0 8rpx 24rpx rgba(56,189,172,.3); }
.btn-vip { text-align: center; padding: 22rpx 0; border-radius: 48rpx; font-size: 26rpx; color: #f5a623; background: transparent; border: 1rpx solid rgba(245,166,35,.3); }
.bottom-wrap {
padding: 48rpx 32rpx 0;
}
.btn-super {
display: flex;
align-items: center;
justify-content: center;
gap: 12rpx;
width: 100%;
padding: 32rpx 0;
border-radius: 999rpx;
background: transparent;
border: 1rpx solid rgba(245, 158, 11, 0.3);
color: #F59E0B;
font-size: 30rpx; font-weight: 500;
letter-spacing: 2rpx;
}
.btn-arrow { font-size: 36rpx; font-weight: 300; }
/* ===== 状态 ===== */
.state-wrap { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 60vh; gap: 16rpx; }
.state-txt { font-size: 28rpx; color: #4a5a6e; }
.state-emoji { font-size: 80rpx; }
.loading-dot { width: 48rpx; height: 48rpx; border-radius: 50%; border: 4rpx solid rgba(56,189,172,.2); border-top-color: #38bdac; animation: spin 1s linear infinite; }
.state-wrap { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 60vh; gap: 24rpx; }
.state-txt { font-size: 28rpx; color: #64748B; }
.state-emoji { font-size: 96rpx; }
.loading-dot {
width: 56rpx; height: 56rpx;
border-radius: 50%;
border: 4rpx solid rgba(94, 234, 212, 0.2);
border-top-color: #5EEAD4;
animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }