帝国cms 微信小程序的登录逻辑

// pages/member/login.js

Page({

/**

* 页面的初始数据

*/

data: {

isLoading: false,

returnUrl: '', // 存储返回的URL

needRegister: false,

showLoginBtn: false, // 控制登录按钮显示

showAgreementModal: false, // 控制协议弹窗显示

userInfo: {

avatar: '',

nickname: ''

}

},

/**

* 生命周期函数--监听页面加载

*/

onLoad(options) {

// 保存redirect参数(兼容旧版returnUrl)

const redirectUrl = options.redirect || options.returnUrl;

if (redirectUrl) {

this.setData({

returnUrl: decodeURIComponent(redirectUrl),

options: options // 保存所有选项参数

});

}

this.checkLoginStatus();

},

/**

* 生命周期函数--监听页面显示

*/

onShow() {

this.checkLoginStatus(); // 页面展示时重新检查登录状态

},

// 检查登录状态

checkLoginStatus() {

const token = wx.getStorageSync('token');

if (!token) {

console.log('用户未登录,显示登录页面');

this.setData({ showLoginBtn: true });

return;

}

// 先检查本地过期时间

const tokenExpire = wx.getStorageSync('tokenExpire');

if (tokenExpire > Date.now()) {

console.log('用户已登录,跳转到会员中心');

wx.redirectTo({

url: '/pages/index/index'

});

return;

}

// 本地token过期,调用接口验证

this.verifyTokenExpiry(token);

},

// 调用接口验证token是否过期

verifyTokenExpiry(token) {

wx.request({

url: 'https://www.ailu520.com/ecmsapi/index.php?mod=user\&act=logintime',

method: 'POST',

header: {

'Content-Type': 'application/x-www-form-urlencoded'

},

data: { token },

success: (res) => {

if (res.data && res.data.code === 1) {

// token仍然有效,更新过期时间

const expireTime = Date.now() + 7 * 24 * 60 * 60 * 1000; // 7天有效期

wx.setStorageSync('tokenExpire', expireTime);

wx.redirectTo({

url: '/pages/index/index'

});

} else {

// token已过期,显示登录按钮

wx.removeStorageSync('token');

wx.removeStorageSync('tokenExpire');

this.setData({ showLoginBtn: true });

}

},

fail: () => {

// 网络错误,保守处理:显示登录按钮

this.setData({ showLoginBtn: true });

}

});

},

// 显示协议弹窗

showAgreementModal() {

this.setData({ showAgreementModal: true });

},

// 用户同意协议

handleAgree() {

this.setData({ showAgreementModal: false });

// 继续执行登录流程

this.doLogin();

},

// 用户拒绝协议

handleDisagree() {

this.setData({ showAgreementModal: false });

},

// 实际执行登录的方法

doLogin() {

this.setData({ isLoading: true });

wx.getUserProfile({

desc: '用于完善会员资料',

success: (profileRes) => {

// 获取用户信息成功后,开始微信登录流程

this.handleLogin(profileRes.userInfo);

},

fail: (err) => {

this.setData({ isLoading: false });

wx.showToast({

title: '获取用户信息失败',

icon: 'none'

});

console.error('获取用户信息失败:', err);

}

});

},

// 获取用户信息授权(点击触发)

handleUserProfile() {

// 先显示协议弹窗

this.showAgreementModal();

},

// 处理登录逻辑

handleLogin(userInfo) {

this.setData({ isLoading: true });

wx.login({

success: (res) => {

if (!res.code) {

this.handleLoginError('获取登录code失败', 'wxLogin');

return;

}

// 第一步:获取 openid 和 session_key

wx.request({

url: 'url=wxopenid',

method: 'POST',

header: {

'Content-Type': 'application/x-www-form-urlencoded'

},

data: {

wxCode: res.code

},

success: (openidRes) => {

console.log('获取 openid 成功', openidRes.data);

if (openidRes.data.code === 1) {

const { openid, unionid, session_key } = openidRes.data.data;

// 保存openid到本地存储,供后续使用

wx.setStorageSync('openid', openid);

// 第二步:发送用户信息登录

wx.request({

url: 'url=wxlogin',

method: 'POST',

header: {

'Content-Type': 'application/x-www-form-urlencoded'

},

data: {

wxopenid: openid,

unionid: unionid,

session_key: session_key,

nickname: userInfo.nickName,

avatar: userInfo.avatarUrl

},

success: (loginRes) => {

console.log('登录接口返回数据', loginRes.data);

if (loginRes.data && loginRes.data.code === 1) {

// 登录成功

const expireTime = Date.now() + 30 * 24 * 60 * 60 * 1000; // 30天有效期

wx.setStorageSync('token', loginRes.data.data.token);

wx.setStorageSync('tokenExpire', expireTime);

wx.setStorageSync('userInfo', loginRes.data.data);

this.setData({ isLoading: false });

wx.showToast({

title: '登录成功',

icon: 'success',

success: () => {

// 登录成功后跳转到returnUrl或首页

setTimeout(() => {

let targetUrl = this.data.returnUrl || '/pages/index/index';

if (targetUrl.startsWith('/')) {

// 解码URL参数

try {

targetUrl = decodeURIComponent(targetUrl);

} catch (e) {

console.warn('URL解码失败:', e);

}

// 检查是否有额外参数需要添加

const showComment = this.data.options?.showComment;

if (showComment && !targetUrl.includes('showComment=')) {

targetUrl += targetUrl.includes('?') ? '&' : '?';

targetUrl += 'showComment=true';

}

wx.redirectTo({

url: targetUrl

});

} else {

// 防止XSS攻击,只允许跳转小程序内部页面

wx.redirectTo({

url: '/pages/index/index'

});

}

}, 1500);

}

});

} else if (loginRes.data && loginRes.data.code === 0) {

// 用户不存在,触发注册流程

this.handleRegister(openid, unionid, session_key, userInfo);

} else {

this.handleLoginError(loginRes.data?.message || '登录失败', 'wxlogin');

}

},

fail: (err) => {

this.handleLoginError(`登录失败: ${err.errMsg || '网络请求异常'}`, 'wxlogin');

}

});

} else {

this.handleLoginError(openidRes.data?.message || '获取openid失败', 'wxopenid');

}

},

fail: (err) => {

this.handleLoginError(`获取openid失败: ${err.errMsg || '网络请求异常'}`, 'wxopenid');

}

});

},

fail: (err) => {

this.handleLoginError(`微信登录失败: ${err.errMsg || '未知错误'}`, 'wxLogin');

}

});

},

// 处理注册流程

handleRegister(openid, unionid, session_key, userInfo) {

// 设置用户信息到data中,供注册使用

this.setData({

needRegister: true,

'userInfo.nickname': userInfo.nickName || '',

'userInfo.avatar': userInfo.avatarUrl || this.data.userInfo.avatar

});

// 保存注册所需信息

this.registerInfo = {

openid: openid,

unionid: unionid,

session_key: session_key,

username: this.data.userInfo.nickname // 使用当前输入的昵称值

};

wx.showToast({

title: '请完善个人资料',

icon: 'none'

});

this.setData({ isLoading: false });

},

// 处理用户选择头像

onChooseAvatar(e) {

const { avatarUrl } = e.detail;

console.log('用户选择的头像:', avatarUrl);

// 检查是否有头像URL

if (!avatarUrl) {

wx.showToast({

title: '获取头像失败',

icon: 'none'

});

return;

}

// 先在界面上显示选择的头像

this.setData({

'userInfo.avatar': avatarUrl

});

// 判断是否是微信头像(通常以特定域名开头)

const isWechatAvatar = avatarUrl.indexOf('https://thirdwx.qlogo.cn/') !== -1;

if (isWechatAvatar) {

// 如果是微信头像,直接使用,不需要上传

console.log('使用微信头像,无需上传:', avatarUrl);

return;

}

// 如果不是微信头像,则需要上传到API接口

// 显示加载状态

wx.showLoading({

title: '处理头像中...',

mask: true

});

// 先下载临时文件到本地

wx.getImageInfo({

src: avatarUrl,

success: (imageInfo) => {

console.log('获取图片信息成功:', imageInfo);

// 使用获取到的本地路径上传

wx.uploadFile({

url: 'https://www.ailu520.com/ecmsapi/index.php?mod=user\&act=uploaduserpic',

filePath: imageInfo.path,

name: 'file',

success: (res) => {

try {

const data = JSON.parse(res.data);

console.log('头像上传结果', data);

if (data.code === 1 && data.data && data.data.location) {

// 上传成功,使用返回的URL

const avatarUrl = data.data.location;

console.log('头像上传成功,URL:', avatarUrl);

this.setData({

'userInfo.avatar': avatarUrl

});

} else {

wx.showToast({

title: '头像上传失败',

icon: 'none'

});

console.error('头像上传失败:', data);

}

} catch (error) {

console.error('解析上传结果失败:', error, res.data);

wx.showToast({

title: '头像上传失败',

icon: 'none'

});

}

},

fail: (err) => {

console.error('头像上传请求失败:', err);

wx.showToast({

title: '头像上传失败',

icon: 'none'

});

},

complete: () => {

wx.hideLoading();

}

});

},

fail: (err) => {

console.error('获取图片信息失败:', err);

wx.hideLoading();

wx.showToast({

title: '处理头像失败',

icon: 'none'

});

}

});

},

// 昵称输入变化

onNicknameChange(e) {

if (e.currentTarget.dataset.type === 'nickname') {

this.setData({

'userInfo.nickname': e.detail.value

});

if (this.registerInfo) {

this.registerInfo.username = e.detail.value;

}

}

},

// 获取手机号

getPhoneNumber(e) {

if (!e.detail.code) {

wx.showToast({

title: '获取手机号失败',

icon: 'none'

});

return;

}

if (!this.registerInfo) {

wx.showToast({

title: '注册信息不完整',

icon: 'none'

});

return;

}

if (!this.data.userInfo.nickname) {

wx.showToast({

title: '请输入昵称',

icon: 'none'

});

return;

}

this.setData({ isLoading: true });

// 获取手机号

wx.request({

url: 'url=getphone',

method: 'POST',

header: {

'Content-Type': 'application/x-www-form-urlencoded'

},

data: {

code: e.detail.code,

openid: this.registerInfo.openid

},

success: (res) => {

if (res.data && res.data.code === 1 && res.data.data && res.data.data.phone) {

// 获取手机号成功,执行注册

this.doRegister(res.data.data.phone);

} else {

this.setData({ isLoading: false });

wx.showToast({

title: res.data?.message || '获取手机号失败',

icon: 'none'

});

}

},

fail: (err) => {

this.setData({ isLoading: false });

wx.showToast({

title: '获取手机号失败',

icon: 'none'

});

console.error('获取手机号失败:', err);

}

});

},

// 执行注册

doRegister(phone) {

if (!this.registerInfo || !this.data.userInfo.avatar || !this.data.userInfo.nickname) {

wx.showToast({

title: '请完善个人资料',

icon: 'none'

});

this.setData({ isLoading: false });

return;

}

wx.showLoading({

title: '正在注册',

mask: true

});

// 调用注册API

wx.request({

url: 'url=wreg',

method: 'POST',

header: {

'Content-Type': 'application/x-www-form-urlencoded'

},

data: {

username: this.data.userInfo.nickname,

wxopenid: this.registerInfo.openid,

unionid: this.registerInfo.unionid,

userpic: this.data.userInfo.avatar,

session_key: this.registerInfo.session_key,

phone: phone

},

success: (res) => {

wx.hideLoading();

if (res.data && res.data.code === 1) {

// 注册成功,保存token和用户信息(保持与登录一致的数据结构)

const expireTime = Date.now() + 30 * 24 * 60 * 60 * 1000; // 30天有效期

wx.setStorageSync('token', res.data.data.token);

wx.setStorageSync('tokenExpire', expireTime);

// 构建与登录保存一致的userInfo结构

const userInfo = {

userid: res.data.data.userid, // 统一使用userid作为字段名

openid: res.data.data.openid,

unionid: res.data.data.unionid,

nickname: this.data.userInfo.nickname,

avatar: this.data.userInfo.avatar,

phone: res.data.data.phone,

level: res.data.data.level || '普通会员',

// 其他与登录保存一致的字段...

};

wx.setStorageSync('userInfo', userInfo);

this.setData({ isLoading: false });

wx.showToast({

title: '注册成功',

icon: 'success',

success: () => {

// 注册成功后跳转到会员中心

setTimeout(() => {

wx.redirectTo({

url: '/pages/index/index'

});

}, 1500);

}

});

} else {

// 注册失败

this.setData({ isLoading: false });

wx.showToast({

title: res.data?.message || '注册失败',

icon: 'none'

});

}

},

fail: (err) => {

wx.hideLoading();

this.setData({ isLoading: false });

wx.showToast({

title: '注册失败,请重试',

icon: 'none'

});

console.error('注册请求失败:', err);

}

});

},

// 统一处理登录错误

handleLoginError(message, type) {

this.setData({ isLoading: false });

let detail = message;

if (type === 'wxlogin') {

detail += '\n请检查网络或稍后再试';

}

wx.showModal({

title: '提示',

content: detail,

confirmText: '重试',

cancelText: '取消',

success: (modalRes) => {

if (modalRes.confirm) {

setTimeout(() => {

this.handleUserProfile();

}, 1000);

}

}

});

console.error(`[登录错误][${type}]`, message);

}

});

相关推荐
じòぴé南冸じょうげん7 分钟前
APP本地调试正常,但是打包后出现账号密码解析错误,且前端未使用加密解密
小程序·uni-app·web app
小小黑00714 分钟前
快手小程序-实现插屏广告的功能
前端·javascript·小程序
计算机毕设指导620 分钟前
基于微信小程序的鸟博士系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
周杰伦fans22 分钟前
微信小程序信息提示组件大全
微信小程序·小程序
QQ_216962909642 分钟前
Spring Boot大学生社团管理平台 【部署教程+可完整运行源码+数据库】
java·数据库·spring boot·微信小程序
说私域2 小时前
基于开源链动2+1模式、AI智能名片与S2B2C商城小程序的运营创新研究
人工智能·小程序
我很苦涩的3 小时前
原生小程序使用echarts
前端·小程序·echarts
小小王app小程序开发3 小时前
盲盒小程序避坑指南:开发运营全流程风险规避策略
小程序
风月歌4 小时前
基于微信小程序的学习资料销售平台源代码(源码+文档+数据库)
java·数据库·mysql·微信小程序·小程序·毕业设计·源码
多仔ヾ4 小时前
微信小程序开发实战之 05-微信小程序常用 API(下)
微信小程序