feat: MBTI头像与用户规则链路升级,三端页面与接口同步

Made-with: Cursor
This commit is contained in:
卡若
2026-03-24 01:22:50 +08:00
parent fa3da12b16
commit 1d56d0336c
71 changed files with 3848 additions and 1621 deletions

View File

@@ -48,6 +48,8 @@ Page({
wizardMode: false,
wizardStep: 1,
totalWizardSteps: 3,
/** 头像区展示:含 MBTI 默认图 */
avatarPreviewUrl: '',
},
onLoad(options) {
@@ -83,6 +85,9 @@ Page({
app.request({ url: `/api/miniprogram/user/profile?userId=${userId}`, silent: true }),
app.request({ url: `/api/miniprogram/vip/status?userId=${userId}`, silent: true }),
])
try {
if (app.loadMbtiAvatarsMap) await app.loadMbtiAvatarsMap()
} catch (_) {}
this.setData({ isVip: vipRes?.data?.isVip || false })
const res = profileRes
if (res?.success && res.data) {
@@ -110,6 +115,7 @@ Page({
loading: false,
})
this._applyWizardModeFromProfile(d)
this._syncAvatarPreview()
setTimeout(() => this.generateShareCard(), 200)
} else {
this.setData({ loading: false })
@@ -367,7 +373,22 @@ Page({
onMbtiPickerChange(e) {
const i = parseInt(e.detail.value, 10)
this.setData({ mbtiIndex: i, mbti: MBTI_OPTIONS[i] })
this.setData({ mbtiIndex: i, mbti: MBTI_OPTIONS[i] }, () => this._syncAvatarPreview())
},
_syncAvatarPreview() {
try {
const { resolveAvatarWithMbti } = require('../../utils/mbtiAvatar.js')
const url = resolveAvatarWithMbti(
this.data.avatar,
this.data.mbti,
app.globalData.mbtiAvatarsMap || {},
app.globalData.baseUrl || ''
)
this.setData({ avatarPreviewUrl: url || '' })
} catch (_) {
this.setData({ avatarPreviewUrl: (this.data.avatar || '').trim() })
}
},
// 微信原生 chooseAvatar 回调(点击头像直接弹出原生选择器:用微信头像/从相册选择/拍照)
@@ -400,7 +421,7 @@ Page({
if (avatarUrl && !avatarUrl.startsWith('http')) {
avatarUrl = app.globalData.baseUrl + avatarUrl
}
this.setData({ avatar: avatarUrl })
this.setData({ avatar: avatarUrl }, () => this._syncAvatarPreview())
const avatarToSave = toAvatarPath(avatarUrl)
await app.request({
url: '/api/miniprogram/user/profile',

View File

@@ -29,7 +29,7 @@
<button class="avatar-wrap-btn" open-type="chooseAvatar" bindchooseavatar="onChooseAvatar">
<view class="avatar-wrap">
<view class="avatar-inner">
<image wx:if="{{avatar}}" class="avatar-img" src="{{avatar}}" mode="aspectFill"/>
<image wx:if="{{avatarPreviewUrl}}" class="avatar-img" src="{{avatarPreviewUrl}}" mode="aspectFill"/>
<view wx:else class="avatar-placeholder">{{nickname ? nickname[0] : '?'}}</view>
</view>
<view class="avatar-camera"><icon name="camera" size="48" color="#ffffff"></icon></view>
@@ -179,7 +179,7 @@
<button class="avatar-wrap-btn" open-type="chooseAvatar" bindchooseavatar="onChooseAvatar">
<view class="avatar-wrap">
<view class="avatar-inner">
<image wx:if="{{avatar}}" class="avatar-img" src="{{avatar}}" mode="aspectFill"/>
<image wx:if="{{avatarPreviewUrl}}" class="avatar-img" src="{{avatarPreviewUrl}}" mode="aspectFill"/>
<view wx:else class="avatar-placeholder">{{nickname ? nickname[0] : '?'}}</view>
</view>
<view class="avatar-camera"><icon name="camera" size="48" color="#ffffff"></icon></view>