feat: 使用微信原生chooseAvatar获取头像

改用 button open-type="chooseAvatar" 替代上传方案,用户只能选择
微信头像,确保头像来源安全可控。头像URL直接存储到数据库。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
richarjiang
2026-04-05 11:03:46 +08:00
parent 64b319ea19
commit 9c5dd4a911
2 changed files with 43 additions and 11 deletions

View File

@@ -2,6 +2,7 @@
<view class="info-page">
<!-- Avatar section -->
<view class="avatar-section">
<button class="avatar-btn" open-type="chooseAvatar" @chooseavatar="handleChooseAvatar">
<view class="avatar-wrap">
<image
v-if="avatarUrl"
@@ -13,6 +14,7 @@
<text class="avatar-placeholder-text">{{ nicknameInitial }}</text>
</view>
</view>
</button>
<text class="avatar-name">{{ form.nickname || '未设置昵称' }}</text>
<text class="avatar-hint">微信头像</text>
</view>
@@ -91,6 +93,7 @@ const form = ref({
})
const originalNickname = ref('')
const saving = ref(false)
const uploadingAvatar = ref(false)
// ─── Computed ─────────────────────────────────────────────
const isDirty = computed(() => form.value.nickname.trim() !== originalNickname.value)
@@ -122,6 +125,24 @@ const activeMembershipCount = computed(
() => userStore.user?.activeMembershipCount ?? userStore.activeMemberships.length,
)
// ─── Avatar upload ────────────────────────────────────────
async function handleChooseAvatar(e: { detail: { avatarUrl: string } }) {
const { avatarUrl } = e.detail
if (!avatarUrl) return
uploadingAvatar.value = true
try {
await userStore.updateProfile({ avatarUrl })
await userStore.fetchProfile()
uni.showToast({ title: '头像更新成功', icon: 'success' })
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : '更新失败,请重试'
uni.showToast({ title: msg, icon: 'none' })
} finally {
uploadingAvatar.value = false
}
}
// ─── Phone binding ────────────────────────────────────────
async function handleGetPhone(e: {
detail: { encryptedData: string; iv: string; errMsg: string }
@@ -204,6 +225,17 @@ onMounted(async () => {
border-bottom: 1rpx solid #f0ece8;
}
.avatar-btn {
background: transparent;
border: none;
padding: 0;
margin: 0;
&::after {
border: none;
}
}
.avatar-wrap {
position: relative;
width: 160rpx;

File diff suppressed because one or more lines are too long