Files
2026-03-07 22:58:43 +08:00

223 lines
8.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Soul创业派对 - 资料编辑完整版comprehensive_profile_editor_v1_1
* 温馨提示、头像、基本信息、核心联系方式、个人故事、互助需求、项目介绍
*
* 接口约定(/api/miniprogram/user/profile
* - GET ?userId= 返回 data: { avatar, nickname, mbti, region, industry, businessScale, position, skills, phone, wechatId, ... },空值统一为 ""
* - POST body普通用户提交基础字段VIP 提交全部字段(含 skills、个人故事、互助需求、项目介绍
*
* 表单展示:普通用户仅展示 温馨提示、头像、昵称、MBTI、地区、行业、业务体量、职位、核心联系方式VIP 展示全部
*/
const app = getApp()
const MBTI_OPTIONS = ['INTJ', 'INFP', 'INTP', 'ENTP', 'ENFP', 'ENTJ', 'ENFJ', 'INFJ', 'ISTJ', 'ISFJ', 'ESTJ', 'ESFJ', 'ISTP', 'ISFP', 'ESTP', 'ESFP']
Page({
data: {
statusBarHeight: 44,
isVip: false,
avatar: '',
nickname: '',
mbti: '',
mbtiIndex: 0,
region: '',
industry: '',
businessScale: '',
position: '',
skills: '',
phone: '',
wechatId: '',
storyBestMonth: '',
storyAchievement: '',
storyTurning: '',
helpOffer: '',
helpNeed: '',
projectIntro: '',
mbtiOptions: MBTI_OPTIONS,
showMbtiPicker: false,
saving: false,
loading: true,
},
onLoad() {
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 44 })
this.loadProfile()
},
async loadProfile() {
const userInfo = app.globalData.userInfo
if (!app.globalData.isLoggedIn || !userInfo?.id) {
this.setData({ loading: false })
wx.showToast({ title: '请先登录', icon: 'none' })
setTimeout(() => getApp().goBackOrToHome(), 1500)
return
}
try {
const userId = userInfo.id
const [profileRes, vipRes] = await Promise.all([
app.request({ url: `/api/miniprogram/user/profile?userId=${userId}`, silent: true }),
app.request({ url: `/api/miniprogram/vip/status?userId=${userId}`, silent: true }),
])
this.setData({ isVip: vipRes?.data?.isVip || false })
const res = profileRes
if (res?.success && res.data) {
const d = res.data
const v = (k) => (d[k] != null && d[k] !== '') ? String(d[k]) : ''
const mbtiIndex = MBTI_OPTIONS.indexOf(v('mbti')) >= 0 ? MBTI_OPTIONS.indexOf(v('mbti')) : 0
this.setData({
avatar: v('avatar'),
nickname: v('nickname'),
mbti: v('mbti'),
mbtiIndex,
region: v('region'),
industry: v('industry'),
businessScale: v('businessScale'),
position: v('position'),
skills: v('skills'),
phone: v('phone'),
wechatId: v('wechatId') || wx.getStorageSync('user_wechat') || '',
storyBestMonth: v('storyBestMonth'),
storyAchievement: v('storyAchievement'),
storyTurning: v('storyTurning'),
helpOffer: v('helpOffer'),
helpNeed: v('helpNeed'),
projectIntro: v('projectIntro'),
loading: false,
})
} else {
this.setData({ loading: false })
}
} catch (e) {
this.setData({ loading: false })
}
},
goBack() { getApp().goBackOrToHome() },
onNicknameInput(e) { this.setData({ nickname: e.detail.value }) },
onRegionInput(e) { this.setData({ region: e.detail.value }) },
onIndustryInput(e) { this.setData({ industry: e.detail.value }) },
onBusinessScaleInput(e) { this.setData({ businessScale: e.detail.value }) },
onPositionInput(e) { this.setData({ position: e.detail.value }) },
onSkillsInput(e) { this.setData({ skills: e.detail.value }) },
onPhoneInput(e) { this.setData({ phone: e.detail.value }) },
onWechatInput(e) { this.setData({ wechatId: e.detail.value }) },
onStoryBestMonthInput(e) { this.setData({ storyBestMonth: e.detail.value }) },
onStoryAchievementInput(e) { this.setData({ storyAchievement: e.detail.value }) },
onStoryTurningInput(e) { this.setData({ storyTurning: e.detail.value }) },
onHelpOfferInput(e) { this.setData({ helpOffer: e.detail.value }) },
onHelpNeedInput(e) { this.setData({ helpNeed: e.detail.value }) },
onProjectIntroInput(e) { this.setData({ projectIntro: e.detail.value }) },
onMbtiPickerChange(e) {
const i = parseInt(e.detail.value, 10)
this.setData({ mbtiIndex: i, mbti: MBTI_OPTIONS[i] })
},
chooseAvatar() {
wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
success: async (res) => {
const tempPath = res.tempFiles[0].tempFilePath
wx.showLoading({ title: '上传中...', mask: true })
try {
const uploadRes = await new Promise((resolve, reject) => {
wx.uploadFile({
url: app.globalData.baseUrl + '/api/miniprogram/upload',
filePath: tempPath,
name: 'file',
formData: { folder: 'avatars' },
success: (r) => {
try {
const data = JSON.parse(r.data)
if (data.success) resolve(data)
else reject(new Error(data.error || '上传失败'))
} catch { reject(new Error('解析失败')) }
},
fail: reject,
})
})
const avatarUrl = app.globalData.baseUrl + uploadRes.data.url
this.setData({ avatar: avatarUrl })
await app.request({
url: '/api/miniprogram/user/profile',
method: 'POST',
data: { userId: app.globalData.userInfo?.id, avatar: avatarUrl },
})
if (app.globalData.userInfo) {
app.globalData.userInfo.avatar = avatarUrl
wx.setStorageSync('userInfo', app.globalData.userInfo)
}
wx.hideLoading()
wx.showToast({ title: '头像已更新', icon: 'success' })
} catch (e) {
wx.hideLoading()
wx.showToast({ title: e.message || '上传失败', icon: 'none' })
}
},
})
},
async saveProfile() {
const userId = app.globalData.userInfo?.id
if (!userId) {
wx.showToast({ title: '请先登录', icon: 'none' })
return
}
this.setData({ saving: true })
try {
const s = (v) => (v || '').toString().trim()
const isVip = this.data.isVip
const payload = {
userId,
avatar: s(this.data.avatar),
nickname: s(this.data.nickname),
mbti: s(this.data.mbti),
region: s(this.data.region),
industry: s(this.data.industry),
businessScale: s(this.data.businessScale),
position: s(this.data.position),
phone: s(this.data.phone),
wechatId: s(this.data.wechatId),
}
const showHelp = isVip || this.data.helpOffer || this.data.helpNeed
if (isVip) {
payload.skills = s(this.data.skills)
payload.storyBestMonth = s(this.data.storyBestMonth)
payload.storyAchievement = s(this.data.storyAchievement)
payload.storyTurning = s(this.data.storyTurning)
payload.projectIntro = s(this.data.projectIntro)
}
if (showHelp) {
payload.helpOffer = s(this.data.helpOffer)
payload.helpNeed = s(this.data.helpNeed)
}
if (payload.wechatId) wx.setStorageSync('user_wechat', payload.wechatId)
if (payload.phone) wx.setStorageSync('user_phone', payload.phone)
const hasUpdate = Object.keys(payload).some(k => k !== 'userId' && payload[k] !== '')
if (!hasUpdate) {
wx.showToast({ title: '无变更', icon: 'none' })
this.setData({ saving: false })
return
}
await app.request({
url: '/api/miniprogram/user/profile',
method: 'POST',
data: payload,
})
wx.showToast({ title: '保存成功', icon: 'success' })
if (app.globalData.userInfo) {
if (payload.nickname) app.globalData.userInfo.nickname = payload.nickname
if (payload.avatar) app.globalData.userInfo.avatar = payload.avatar
wx.setStorageSync('userInfo', app.globalData.userInfo)
}
setTimeout(() => getApp().goBackOrToHome(), 800)
} catch (e) {
wx.showToast({ title: e.message || '保存失败', icon: 'none' })
}
this.setData({ saving: false })
},
})