Files
geminiWX/wechat-mini-program/pages/profile/profile.js
2025-12-09 16:27:48 +08:00

360 lines
12 KiB
JavaScript
Raw 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.
const app = getApp()
Page({
data: {
user: {},
isFormOpen: false,
isDevtools: false,
region: [],
formData: {
name: '',
phone: '',
age: '',
city: '',
company_name: '',
position: '',
wechat_nickname: '',
avatar: ''
}
},
onLoad(options) {
try {
let isDevtools = false
if (wx.getDeviceInfo) {
const info = wx.getDeviceInfo()
isDevtools = info.platform === 'devtools'
} else {
const sys = wx.getSystemInfoSync()
isDevtools = sys.platform === 'devtools'
}
this.setData({ isDevtools })
} catch (e) {}
// 检查是否已登录
const app = getApp();
if (app.globalData.userInfo) {
this.setData({ user: app.globalData.userInfo });
this.initFormData(app.globalData.userInfo);
} else {
// 设置回调,等待登录完成
app.loginCallback = (user) => {
this.setData({ user: user });
this.initFormData(user);
}
}
this.fetchUser(); // Still fetch latest data just in case
if (options.action === 'bind_phone') {
this.checkBindPhone();
}
this.ensureNickname()
},
onShow() {
const app = getApp();
if (app.globalData.profileAction === 'bind_phone') {
app.globalData.profileAction = null; // Clear it
this.checkBindPhone();
}
this.ensureNickname()
this.fetchUser() // Always refresh user data on show to update stats
},
checkBindPhone() {
// Only prompt if phone is truly missing
const app = getApp()
const hasPhone = this.data.user.phone || (app.globalData.userInfo && app.globalData.userInfo.phone);
if (!hasPhone) {
this.setData({ isFormOpen: true });
wx.showToast({
title: '请先激活手机号',
icon: 'none',
duration: 2000
})
}
},
initFormData(user) {
this.setData({
region: user.city ? user.city.split(' ') : [],
formData: {
name: user.name,
phone: user.phone,
age: user.age,
city: user.city,
company_name: user.company_name,
position: user.position,
wechat_nickname: user.wechat_nickname,
avatar: user.avatar
}
})
},
toggleForm() {
this.setData({
isFormOpen: !this.data.isFormOpen
});
},
fetchUser() {
const { request } = require('../../utils/request')
request({ url: '/user/' })
.then((data) => {
this.setData({
user: data,
region: data.city ? data.city.split(' ') : [],
formData: {
name: data.name,
phone: data.phone,
age: data.age,
city: data.city,
company_name: data.company_name,
position: data.position,
wechat_nickname: data.wechat_nickname,
avatar: data.avatar
}
})
this.ensureNickname()
})
.catch(() => {
this.setData({
user: {
id: '8839201',
name: '学员用户',
avatar:
'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=200&auto=format&fit=crop&q=60',
stats: {
learning: 12,
coupons: 3,
hours: 28
}
}
})
})
},
onCityChange(e) {
const val = e.detail.value;
this.setData({
region: val,
'formData.city': val.join(' ')
});
},
handleInput(e) {
const field = e.currentTarget.dataset.field;
const value = e.detail.value;
this.setData({
[`formData.${field}`]: value
});
},
onChooseAvatar(e) {
const { avatarUrl } = e.detail
const app = getApp()
wx.showLoading({ title: '上传中...' })
const header = {}
if (app.globalData.token) {
header['Authorization'] = `Bearer ${app.globalData.token}`
}
wx.uploadFile({
url: `${app.globalData.baseUrl}/file/`,
filePath: avatarUrl,
name: 'file',
header: header,
success: (res) => {
wx.hideLoading()
if (res.statusCode === 200 || res.statusCode === 201) {
const data = JSON.parse(res.data)
// Handle wrapped response from FitJSONRenderer
const path = data.data && data.data.path ? data.data.path : data.path;
if (path) {
this.setData({
'formData.avatar': path,
'user.avatar': path
})
} else {
wx.showToast({ title: '上传失败:无路径', icon: 'none' })
console.error('Upload response missing path:', data)
}
} else {
wx.showToast({ title: '上传失败', icon: 'none' })
console.error('Upload failed:', res)
}
},
fail: (err) => {
wx.hideLoading()
console.error(err)
wx.showToast({ title: '上传出错', icon: 'none' })
}
})
},
onNicknameChange(e) {
this.setData({
'formData.wechat_nickname': e.detail.value
})
},
ensureNickname() {
const has = this.data.formData && this.data.formData.wechat_nickname
if (has) return
// Only auto-fetch if we are in devtools (mock mode).
// Real getUserProfile requires a tap event, so we cannot auto-call it.
if (this.data.isDevtools) {
this.fetchNickname()
}
},
fetchNickname() {
if (this.data.isDevtools) {
const nick = '微信用户'
const app = getApp()
app.globalData.userInfo = {
...app.globalData.userInfo,
wechat_nickname: nick,
name: app.globalData.userInfo && app.globalData.userInfo.name ? app.globalData.userInfo.name : nick
}
this.setData({
'formData.wechat_nickname': nick,
'formData.name': this.data.formData.name || nick,
'user.name': this.data.user.name || nick
})
return
}
if (wx.getUserProfile) {
wx.getUserProfile({ desc: '完善资料' }).then(res => {
const info = res.userInfo || {}
const nick = info.nickName || '微信用户'
const avatar = info.avatarUrl || this.data.formData.avatar
const app = getApp()
app.globalData.userInfo = {
...app.globalData.userInfo,
wechat_nickname: nick,
name: app.globalData.userInfo && app.globalData.userInfo.name ? app.globalData.userInfo.name : nick,
avatar: avatar
}
this.setData({
'formData.wechat_nickname': nick,
'formData.name': this.data.formData.name || nick,
'formData.avatar': avatar,
'user.name': this.data.user.name || nick,
'user.avatar': avatar
})
}).catch(err => {
console.error('getUserProfile error:', err)
})
}
},
getPhoneNumber(e) {
const detail = e && e.detail ? e.detail : {}
if (detail.code) {
const { request } = require('../../utils/request')
wx.showLoading({ title: '获取中...' })
request({
url: '/user/phone/',
method: 'POST',
data: { code: detail.code }
}).then(res => {
wx.hideLoading()
const app = getApp()
app.globalData.userInfo = {
...app.globalData.userInfo,
phone: res.phone
}
this.setData({
'user.phone': res.phone,
'formData.phone': res.phone
})
wx.showToast({ title: '获取成功', icon: 'success' })
}).catch(err => {
wx.hideLoading()
console.error('user/phone request error:', err)
wx.showToast({ title: '获取失败,请检查网络', icon: 'none' })
})
} else {
// DevTools 兜底:工具环境无法下发 code直接模拟请求后端获取默认手机号
if (this.data.isDevtools) {
const { request } = require('../../utils/request')
wx.showLoading({ title: '模拟获取中...' })
request({
url: '/user/phone/',
method: 'POST',
data: { code: 'mock_devtools' }
}).then(res => {
wx.hideLoading()
const app = getApp()
app.globalData.userInfo = {
...app.globalData.userInfo,
phone: res.phone
}
this.setData({
'user.phone': res.phone,
'formData.phone': res.phone
})
wx.showToast({ title: '工具模拟成功', icon: 'success' })
}).catch(err => {
wx.hideLoading()
console.error('devtools mock phone error:', err)
wx.showToast({ title: '工具模拟失败', icon: 'none' })
})
return
}
const msg = detail.errMsg || '未获取到授权码'
console.error('getPhoneNumber error:', detail)
wx.showToast({ title: msg.includes('deny') ? '用户拒绝授权' : msg, icon: 'none' })
}
},
simulateGetPhone() {
if (!this.data.isDevtools) return
const { request } = require('../../utils/request')
wx.showLoading({ title: '模拟获取中...' })
request({
url: '/user/phone/',
method: 'POST',
data: { code: 'mock_devtools' }
}).then(res => {
wx.hideLoading()
const app = getApp()
app.globalData.userInfo = {
...app.globalData.userInfo,
phone: res.phone
}
this.setData({
'user.phone': res.phone,
'formData.phone': res.phone
})
wx.showToast({ title: '工具模拟成功', icon: 'success' })
}).catch(err => {
wx.hideLoading()
console.error('simulateGetPhone error:', err)
wx.showToast({ title: '工具模拟失败', icon: 'none' })
})
},
handleSubmit() {
this.submitData();
},
submitData() {
const { request } = require('../../utils/request')
console.log(this.data.formData);
request({ url: '/user/', method: 'POST', data: this.data.formData })
.then((data) => {
console.log(data)
// Update user data to reflect changes immediately
const app = getApp()
app.globalData.userInfo = {
...app.globalData.userInfo,
...data
}
this.setData({
user: {
...this.data.user,
...data,
stats: this.data.user.stats // preserve stats
},
isFormOpen: false
});
wx.showToast({
title: '保存成功',
icon: 'success'
})
})
},
navigateToCoupons() {
wx.navigateTo({
url: '/pages/coupon/coupon'
})
}
})