376 lines
8.6 KiB
JavaScript
376 lines
8.6 KiB
JavaScript
// pages/edit-profile/index.js
|
||
const { userApi } = require("../../utils/api");
|
||
const AuthUtil = require("../../utils/auth");
|
||
|
||
Page({
|
||
/**
|
||
* 页面的初始数据
|
||
*/
|
||
data: {
|
||
username: '',
|
||
nickname: '',
|
||
originalUsername: '',
|
||
originalNickname: '',
|
||
loading: false,
|
||
// 密码相关
|
||
hasPassword: false, // 用户是否已设置密码
|
||
oldPassword: '',
|
||
newPassword: '',
|
||
confirmPassword: '',
|
||
},
|
||
|
||
/**
|
||
* 生命周期函数--监听页面加载
|
||
*/
|
||
onLoad(options) {
|
||
this.loadUserInfo();
|
||
},
|
||
|
||
/**
|
||
* 生命周期函数--监听页面显示
|
||
*/
|
||
onShow() {
|
||
// 每次显示时刷新用户信息
|
||
this.loadUserInfo();
|
||
},
|
||
|
||
/**
|
||
* 加载用户信息
|
||
*/
|
||
loadUserInfo() {
|
||
const userInfo = AuthUtil.getUserInfo();
|
||
|
||
// 对于编辑页面,为了确保has_password字段的准确性,总是从服务器获取最新信息
|
||
// 但先使用本地信息快速显示,避免页面闪烁
|
||
if (userInfo && userInfo.username) {
|
||
this.setData({
|
||
username: userInfo.username || '',
|
||
nickname: userInfo.nickname || '',
|
||
originalUsername: userInfo.username || '',
|
||
originalNickname: userInfo.nickname || '',
|
||
hasPassword: !!(userInfo.has_password), // 使用本地缓存的has_password
|
||
});
|
||
}
|
||
|
||
// 总是从服务器获取最新信息,确保has_password字段准确
|
||
this.fetchUserInfo();
|
||
},
|
||
|
||
/**
|
||
* 从服务器获取用户信息
|
||
*/
|
||
fetchUserInfo() {
|
||
wx.showLoading({ title: '加载中...' });
|
||
|
||
userApi.getCurrentUser()
|
||
.then(res => {
|
||
if ((res.code === 1 || res.code === 200) && res.data && res.data.user) {
|
||
const user = res.data.user;
|
||
this.setData({
|
||
username: user.username || '',
|
||
nickname: user.nickname || '',
|
||
originalUsername: user.username || '',
|
||
originalNickname: user.nickname || '',
|
||
hasPassword: !!(user.has_password || user.password), // 判断用户是否已设置密码
|
||
});
|
||
|
||
// 更新本地存储
|
||
AuthUtil.setUserInfo(user);
|
||
} else {
|
||
wx.showToast({
|
||
title: '获取用户信息失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
})
|
||
.catch(err => {
|
||
wx.showToast({
|
||
title: '获取用户信息失败',
|
||
icon: 'none'
|
||
});
|
||
})
|
||
.finally(() => {
|
||
wx.hideLoading();
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 用户名输入变化
|
||
*/
|
||
onUsernameChange(e) {
|
||
this.setData({
|
||
username: e.detail.value,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 昵称输入变化
|
||
*/
|
||
onNicknameChange(e) {
|
||
this.setData({
|
||
nickname: e.detail.value,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 当前密码输入变化
|
||
*/
|
||
onOldPasswordChange(e) {
|
||
this.setData({
|
||
oldPassword: e.detail.value,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 新密码输入变化
|
||
*/
|
||
onNewPasswordChange(e) {
|
||
this.setData({
|
||
newPassword: e.detail.value,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 确认密码输入变化
|
||
*/
|
||
onConfirmPasswordChange(e) {
|
||
this.setData({
|
||
confirmPassword: e.detail.value,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 验证密码输入
|
||
*/
|
||
validatePassword() {
|
||
const { hasPassword, oldPassword, newPassword, confirmPassword } = this.data;
|
||
|
||
// 如果没有输入新密码,说明不想修改密码
|
||
if (!newPassword.trim() && !confirmPassword.trim()) {
|
||
return { valid: true, changePassword: false };
|
||
}
|
||
|
||
// 如果用户已有密码,必须输入当前密码
|
||
if (hasPassword && !oldPassword.trim()) {
|
||
wx.showToast({
|
||
title: '请输入当前密码',
|
||
icon: 'none'
|
||
});
|
||
return { valid: false, changePassword: false };
|
||
}
|
||
|
||
// 新密码长度检查
|
||
if (newPassword.length < 6 || newPassword.length > 50) {
|
||
wx.showToast({
|
||
title: '新密码长度必须在6-50字符之间',
|
||
icon: 'none'
|
||
});
|
||
return { valid: false, changePassword: false };
|
||
}
|
||
|
||
// 确认密码检查
|
||
if (newPassword !== confirmPassword) {
|
||
wx.showToast({
|
||
title: '确认密码与新密码不一致',
|
||
icon: 'none'
|
||
});
|
||
return { valid: false, changePassword: false };
|
||
}
|
||
|
||
return { valid: true, changePassword: true };
|
||
},
|
||
|
||
/**
|
||
* 验证输入
|
||
*/
|
||
validateInput() {
|
||
const { username, nickname } = this.data;
|
||
|
||
if (!username.trim()) {
|
||
wx.showToast({
|
||
title: '请输入用户名',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (username.length < 3 || username.length > 50) {
|
||
wx.showToast({
|
||
title: '用户名长度必须在3-50字符之间',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 检查用户名格式(只能包含字母和数字)
|
||
const usernameRegex = /^[a-zA-Z0-9]+$/;
|
||
if (!usernameRegex.test(username)) {
|
||
wx.showToast({
|
||
title: '用户名只能包含字母和数字',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (!nickname.trim()) {
|
||
wx.showToast({
|
||
title: '请输入昵称',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (nickname.length < 2 || nickname.length > 50) {
|
||
wx.showToast({
|
||
title: '昵称长度必须在2-50字符之间',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
/**
|
||
* 检查是否有修改
|
||
*/
|
||
hasChanges() {
|
||
const { username, nickname, originalUsername, originalNickname, newPassword } = this.data;
|
||
return username !== originalUsername ||
|
||
nickname !== originalNickname ||
|
||
newPassword.trim() !== '';
|
||
},
|
||
|
||
/**
|
||
* 保存用户信息修改
|
||
*/
|
||
saveProfileChanges() {
|
||
const { username, nickname } = this.data;
|
||
|
||
return userApi.updateProfile({
|
||
username: username.trim(),
|
||
nickname: nickname.trim()
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 保存密码修改
|
||
*/
|
||
savePasswordChanges() {
|
||
const { hasPassword, oldPassword, newPassword, confirmPassword } = this.data;
|
||
|
||
return userApi.changePassword(
|
||
hasPassword ? oldPassword : '',
|
||
newPassword,
|
||
confirmPassword
|
||
);
|
||
},
|
||
|
||
/**
|
||
* 保存修改
|
||
*/
|
||
handleSave() {
|
||
if (!this.validateInput()) {
|
||
return;
|
||
}
|
||
|
||
const passwordValidation = this.validatePassword();
|
||
if (!passwordValidation.valid) {
|
||
return;
|
||
}
|
||
|
||
if (!this.hasChanges()) {
|
||
wx.showToast({
|
||
title: '没有修改内容',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
this.setData({ loading: true });
|
||
|
||
// 检查是否需要修改个人信息
|
||
const { username, nickname, originalUsername, originalNickname } = this.data;
|
||
const profileChanged = username !== originalUsername || nickname !== originalNickname;
|
||
|
||
// 需要执行的保存操作
|
||
const saveOperations = [];
|
||
|
||
if (profileChanged) {
|
||
saveOperations.push(this.saveProfileChanges());
|
||
}
|
||
|
||
if (passwordValidation.changePassword) {
|
||
saveOperations.push(this.savePasswordChanges());
|
||
}
|
||
|
||
// 执行所有保存操作
|
||
Promise.all(saveOperations)
|
||
.then(results => {
|
||
// 检查所有操作是否都成功(支持code: 1和code: 200)
|
||
const allSuccess = results.every(res => res.code === 1 || res.code === 200);
|
||
|
||
if (allSuccess) {
|
||
wx.showToast({
|
||
title: '保存成功',
|
||
icon: 'success'
|
||
});
|
||
|
||
// 如果有个人信息更新,更新本地用户信息
|
||
const profileResult = results.find(res => res.data && res.data.user);
|
||
if (profileResult) {
|
||
AuthUtil.setUserInfo(profileResult.data.user);
|
||
}
|
||
|
||
// 延时返回上一页
|
||
setTimeout(() => {
|
||
wx.navigateBack();
|
||
}, 1500);
|
||
} else {
|
||
// 找出失败的操作
|
||
const failedResults = results.filter(res => res.code !== 1);
|
||
const errorMsg = failedResults.map(res => res.msg).join(';');
|
||
wx.showToast({
|
||
title: errorMsg || '保存失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
})
|
||
.catch(err => {
|
||
wx.showToast({
|
||
title: err.message || '保存失败,请稍后重试',
|
||
icon: 'none'
|
||
});
|
||
})
|
||
.finally(() => {
|
||
this.setData({ loading: false });
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 取消修改
|
||
*/
|
||
handleCancel() {
|
||
if (this.hasChanges()) {
|
||
wx.showModal({
|
||
title: '提示',
|
||
content: '确定要放弃修改吗?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
wx.navigateBack();
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
wx.navigateBack();
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 页面卸载时的处理
|
||
*/
|
||
onUnload() {
|
||
// 如果有未保存的修改,可以在这里提示用户
|
||
}
|
||
});
|