Files
soul-yongping/miniprogram/pages/profile-edit/profile-edit.js

223 lines
8.2 KiB
JavaScript
Raw Normal View History

/**
* 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 })
},
})