xiangqinxiaochengxu/miniprogram/pages/profile/profile.js

111 lines
3.2 KiB
JavaScript
Raw Normal View History

2026-04-17 10:49:14 +08:00
const request = require('../../utils/request')
2026-05-18 14:24:55 +08:00
const { resolveImageUrl, resolveImageList } = require('../../utils/media')
2026-04-17 10:49:14 +08:00
2026-04-17 19:26:32 +08:00
function addCacheVersion(url, version) {
if (!url) {
return ''
}
const joiner = url.includes('?') ? '&' : '?'
return `${url}${joiner}v=${encodeURIComponent(version)}`
}
2026-04-17 21:28:56 +08:00
function normalizeAvatarState(userInfo) {
2026-05-18 14:24:55 +08:00
const profileImages = resolveImageList(userInfo.profile_images)
2026-04-17 21:28:56 +08:00
return {
...userInfo,
avatar_url: resolveImageUrl(userInfo.avatar_url || ''),
更新功能修改完版本提交: 功能需求:活动分享与嘉宾匹配系统 1. 活动分享入口 每个活动配置独立的分享链接和二维码,支持扫码或点击链接进入小程序。 2. 用户绑定流程 用户通过分享链接/二维码打开小程序,填写个人信息并绑定至对应活动。 若用户曾参与过历史活动,系统自动复用其历史信息并完成绑定,无需重复填写。 绑定成功后,在活动正式开始前,用户无法查看其他参与者的信息。 3. 信息可见性规则 活动开始前:仅允许查看自己的信息,其他用户信息不可见。 活动开始后:开放本活动内异性嘉宾资料查看与匹配,其他活动的用户信息完全隔离,不可见。 资料展示:男嘉宾、女嘉宾资料分开展示,用户仅可浏览异性嘉宾信息。 4. 嘉宾选择规则 每位用户最多可选择 3 位心仪嘉宾。 确认提交后不可再新增选择,但支持修改或撤销已选嘉宾。 管理员可设置匹配截止时间,到达截止时间后系统自动锁定,禁止任何修改。 5. 匹配判定规则 双向互选:若双方恰好互选,则判定为匹配成功,双方均可查看匹配结果。 多向匹配:用户同时与多位嘉宾匹配成功,全部同时展示。 单向选择:A选择B但B未选择A,A可在"谁选了我"页面看到B。 6. 用户页面说明 异性嘉宾列表:展示所有异性嘉宾资料,支持选择/取消选择。 我的选择:展示当前已选的3位嘉宾,支持修改/撤销(截止前)。 谁选了我:展示所有选择了自己的嘉宾(无论自己是否选择了对方)。 匹配成功:展示所有双向互选的匹配对象,支持查看对方完整资料。
2026-05-17 10:23:02 +08:00
avatar_blur_url: resolveImageUrl(userInfo.avatar_blur_url || ''),
profile_images: profileImages
2026-04-17 21:28:56 +08:00
}
}
2026-04-17 10:49:14 +08:00
Page({
data: {
loading: false,
userInfo: null,
auditTextMap: {
0: '未提交',
1: '待审核',
2: '已通过',
3: '已驳回'
}
},
onShow() {
2026-04-17 19:26:32 +08:00
this.refreshFromCache()
this.loadProfile(true)
2026-04-17 10:49:14 +08:00
},
2026-04-17 19:26:32 +08:00
async loadProfile(silent = false) {
if (!silent) {
this.setData({ loading: true })
}
2026-04-17 10:49:14 +08:00
try {
const userInfo = await request({ url: '/users/me' })
2026-06-18 23:06:40 +08:00
// 保护缓存中的头像:如果服务端返回空 avatar_url保留缓存中的值
const cached = wx.getStorageSync('profile_page_cache') || {}
if (!userInfo.avatar_url && cached.avatar_url) {
userInfo.avatar_url = cached.avatar_url
}
if (!userInfo.avatar_blur_url && cached.avatar_blur_url) {
userInfo.avatar_blur_url = cached.avatar_blur_url
}
if ((!userInfo.profile_images || !userInfo.profile_images.length) && cached.profile_images && cached.profile_images.length) {
userInfo.profile_images = cached.profile_images
}
2026-04-17 19:26:32 +08:00
this.applyUserInfo(userInfo)
2026-04-17 21:28:56 +08:00
wx.setStorageSync('profile_page_cache', normalizeAvatarState(userInfo))
2026-04-17 10:49:14 +08:00
} catch (err) {
console.error('Load profile failed:', err)
2026-04-17 19:26:32 +08:00
if (!this.data.userInfo) {
this.setData({ userInfo: null })
}
2026-04-17 10:49:14 +08:00
} finally {
2026-04-17 19:26:32 +08:00
if (!silent) {
this.setData({ loading: false })
}
}
},
applyUserInfo(userInfo) {
const avatarVersion = Date.now().toString()
2026-04-17 21:28:56 +08:00
const normalized = normalizeAvatarState(userInfo)
2026-06-18 23:06:40 +08:00
// 优先使用 avatar_url其次使用 profile_images[0]
const previewImage = normalized.avatar_url
|| (normalized.profile_images && normalized.profile_images.length ? normalized.profile_images[0] : '')
2026-04-17 19:26:32 +08:00
this.setData({
userInfo: {
2026-04-17 21:28:56 +08:00
...normalized,
avatar_url: addCacheVersion(normalized.avatar_url, avatarVersion),
avatar_blur_url: addCacheVersion(normalized.avatar_blur_url, avatarVersion),
2026-06-18 23:06:40 +08:00
previewImage: addCacheVersion(previewImage, avatarVersion),
2026-04-17 21:28:56 +08:00
nicknameText: normalized.nickname || '未设置昵称',
auditStatusText: this.data.auditTextMap[normalized.audit_status] || '未知'
2026-04-17 19:26:32 +08:00
}
})
},
refreshFromCache() {
const cached = wx.getStorageSync('profile_page_cache')
if (cached) {
this.applyUserInfo(cached)
2026-04-17 10:49:14 +08:00
}
},
goEdit() {
wx.navigateTo({ url: '/pages/profile-edit/profile-edit' })
},
goAudit() {
wx.navigateTo({ url: '/pages/audit-status/audit-status' })
},
goMyActivities() {
wx.navigateTo({ url: '/pages/my-activities/my-activities' })
},
goMyMatches() {
wx.navigateTo({ url: '/pages/my-matches/my-matches' })
}
})