yfs/pages/user/login.vue
2025-05-04 16:55:07 +08:00

602 lines
14 KiB
Vue
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.

<template>
<view class="all">
<!-- 小程序登录界面 -->
<view v-if="isCanUse && isMpWeixin">
<view>
<view class="header">
<image :src="$img1('common/logo.png?x=1')"></image>
</view>
<view class="content">
<view>申请获取以下权限</view>
<text style="color: #979797;">获得你的公开信息</text>
</view>
<view @click="isAgree = !isAgree" class="agree">
<view class="icon">
<image v-if="isAgree" :src="$img1('common/check_act.png')" lazy-load></image>
<image v-else :src="$img1('common/check.png')" lazy-load></image>
</view>
<view class="agree-r">
我已阅读并同意
<text @click.stop="$customRouter.navigateTo('/pages/guize/guize', {type: 4})">
《用户协议》
</text>
<text @click.stop="$customRouter.navigateTo('/pages/guize/guize', {type: 5})">
《隐私政策》
</text>
</view>
</view>
<view class="btn-list">
<view @click="navigateBack()" class="cancel">
拒绝
</view>
<button class="bottom center" type="primary" withCredentials="true" lang="zh_CN" @click="getUserProfile">
<text>授权登录</text>
</button>
</view>
<view style="font-size: 20rpx;color: #979797;position: fixed;bottom: 20rpx;right:47rpx;">version:v1.0.3
</view>
</view>
</view>
<!-- H5手机号登录界面 -->
<view v-if="isCanUse && !isMpWeixin">
<view>
<view class="header">
<image :src="$img1('common/logo.png?x=1')"></image>
</view>
<view class="h5-login-form">
<view class="input-item">
<input type="number" v-model="mobile" placeholder="请输入手机号" maxlength="11" class="phone-input" />
</view>
<view class="input-item code-item">
<input type="number" v-model="verifyCode" placeholder="请输入验证码" maxlength="6" class="code-input" />
<view @click="sendVerifyCode" class="send-code-btn" :class="{ disabled: countdown > 0 }">
{{ countdown > 0 ? countdown + '秒' : '发送验证码' }}
</view>
</view>
<view @click="isAgree = !isAgree" class="agree">
<view class="icon">
<image v-if="isAgree" :src="$img1('common/check_act.png')" lazy-load></image>
<image v-else :src="$img1('common/check.png')" lazy-load></image>
</view>
<view class="agree-r">
我已阅读并同意
<text @click.stop="$customRouter.navigateTo('/pages/guize/guize', {type: 4})">
《用户协议》
</text>
<text @click.stop="$customRouter.navigateTo('/pages/guize/guize', {type: 5})">
《隐私政策》
</text>
</view>
</view>
<view class="btn-list">
<view @click="navigateBack()" class="cancel">
拒绝
</view>
<view class="bottom center" @click="phoneLogin">
<text>登录</text>
</view>
</view>
</view>
<view style="font-size: 20rpx;color: #979797;position: fixed;bottom: 20rpx;right:47rpx;">version:v1.0.3
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
z_imgPath: this.$z_img2,
SessionKey: '',
OpenId: '',
nickName: null,
avatarUrl: null,
isCanUse: uni.getStorageSync('isCanUse') || true, //默认为true
code: '',
isAgree: false,
// H5手机号登录相关数据
isMpWeixin: false, // 是否为小程序环境
mobile: '', // 手机号
verifyCode: '', // 验证码
countdown: 0, // 发送验证码倒计时
timer: null, // 倒计时定时器
codeSent: false // 是否已发送验证码
}
},
onLoad(option) {
// 判断当前环境
// #ifdef MP-WEIXIN
this.isMpWeixin = true;
// #endif
//默认加载
if (option != null) {
if (option.code != null) {
}
}
},
onUnload() {
// 清除定时器
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
methods: {
//返回上一页
navigateBack() {
uni.navigateBack({
delta: 1,
fail: () => {
// 如果没有上一页,则跳转到首页
this.$customRouter.navigateTo('/pages/shouye/index', {}, 'switchTab');
}
});
},
//第一授权获取用户信息===》按钮触发
getUserProfile(e) {
if (!this.isAgree) {
return uni.showToast({
title: '请阅读并同意《用户协议》和《隐私政策》',
icon: 'none'
});
}
// #ifdef MP-WEIXIN
this.wxUserProfile();
// #endif
},
// 发送验证码
async sendVerifyCode() {
// 如果正在倒计时,不允许重复发送
if (this.countdown > 0) {
return;
}
// 检查是否同意协议
if (!this.isAgree) {
return uni.showToast({
title: '请阅读并同意《用户协议》和《隐私政策》',
icon: 'none'
});
}
// 验证手机号
if (!this.mobile || !/^1\d{10}$/.test(this.mobile)) {
return uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
}
// 发送验证码请求
try {
const res = await this.$request.post('v2/account/sendSms', {
phone: this.mobile
});
if (res.status == 1) {
uni.showToast({
title: '验证码已发送',
icon: 'none'
});
// 标记已发送验证码(仅当前会话有效)
this.codeSent = true;
// 开始倒计时,使用接口返回的时间
this.countdown = res.data || 60; // 使用返回的秒数默认60秒
this.timer = setInterval(() => {
this.countdown--;
if (this.countdown <= 0) {
clearInterval(this.timer);
this.timer = null;
}
}, 1000);
} else {
uni.showToast({
title: res.msg || '发送失败,请稍后重试',
icon: 'none'
});
}
} catch (error) {
uni.showToast({
title: '发送验证码失败,请稍后重试',
icon: 'none'
});
console.error('发送验证码失败:', error);
}
},
// 手机号登录
async phoneLogin() {
// 验证表单
if (!this.isAgree) {
return uni.showToast({
title: '请阅读并同意《用户协议》和《隐私政策》',
icon: 'none'
});
}
if (!this.mobile || !/^1\d{10}$/.test(this.mobile)) {
return uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
}
if (!this.verifyCode) {
return uni.showToast({
title: '请输入验证码',
icon: 'none'
});
}
// 检查当前会话中是否发送过验证码
// if (!this.codeSent) {
// return uni.showToast({
// title: '请先发送验证码',
// icon: 'none'
// });
// }
// 发送登录请求
try {
const res = await this.$request.post('mobileLogin', {
mobile: this.mobile,
code: this.verifyCode,
pid: uni.getStorageSync('pid')
});
if (res.status == 1) {
uni.setStorageSync('token', res.data);
this.$c.msg("登录成功");
// 检查重定向URL
const redirectUrl = uni.getStorageSync('redirect');
if (redirectUrl) {
// 清除重定向信息
uni.removeStorageSync('redirect');
// 使用公共方法处理重定向
this.handleRedirect(redirectUrl);
} else {
// 无重定向页面,检查是否需要绑定手机号
setTimeout(() => {
this.getdata();
}, 1000);
}
} else {
this.$c.msg("登录失败!" + res.msg);
}
} catch (error) {
this.$c.msg("登录请求失败,请稍后重试");
console.error('登录失败:', error);
}
},
/**
* 处理登录成功后的重定向逻辑
* @param {String} redirectUrl 重定向URL
*/
handleRedirect(redirectUrl) {
let that = this;
// 获取当前页面栈
const pages = getCurrentPages();
// 检查是否有上一页以及redirect URL是否与上一页相同
if (pages.length > 1) {
const prevPage = pages[pages.length - 2];
// 构建完整的上一页路径(带参数)
let prevPageUrl = '/' + prevPage.route;
if (prevPage.options && Object.keys(prevPage.options).length > 0) {
const paramStr = Object.keys(prevPage.options)
.map(key => `${key}=${prevPage.options[key]}`)
.join('&');
prevPageUrl += '?' + paramStr;
}
// 比较redirect URL和上一页URL
const redirectUrlPath = redirectUrl.split('?')[0];
const prevPageUrlPath = prevPageUrl.split('?')[0];
if (redirectUrlPath === prevPageUrlPath) {
// 如果路径相同,直接返回上一页
console.log('重定向URL与上一页相同直接返回');
setTimeout(() => {
uni.navigateBack();
}, 1000);
return true;
}
}
// 重定向到指定URL
setTimeout(() => {
that.$customRouter.navigateTo(redirectUrl).catch(err => {
console.error('重定向跳转失败:', err)
// 失败时跳转到首页
that.$customRouter.navigateTo('/pages/user/index')
})
}, 1000);
return true;
},
async wxUserProfile() {
try {
const profileRes = await new Promise((resolve, reject) => {
uni.getUserProfile({
desc: '用于向用户发送商品',
lang: 'zh_CN',
success: resolve,
fail: reject,
complete: (e) => {
console.log(e, '用于向用户发送商品');
}
});
});
try {
const loginRes = await new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: resolve,
fail: (e) => {
this.$c.msg("登录失败,网络错误!" + e.msg);
console.log(e, '登录失败', e);
reject(e);
},
complete: (e) => {
console.log(e, '登录');
}
});
});
try {
const res = await this.$request.post('login', {
code: loginRes.code,
nickname: '',
headimg: '',
pid: uni.getStorageSync('pid')
});
if (res.status == 1) {
uni.setStorageSync('token', res.data);
this.$c.msg("登录成功");
// 检查重定向URL
const redirectUrl = uni.getStorageSync('redirect');
if (redirectUrl) {
// 清除重定向信息
uni.removeStorageSync('redirect');
// 使用公共方法处理重定向
this.handleRedirect(redirectUrl);
} else {
// 无重定向页面,检查是否需要绑定手机号
setTimeout(() => {
this.getdata();
}, 1000);
}
} else {
this.$c.msg("登录失败!" + res.msg);
}
} catch (error) {
console.error('请求登录失败:', error);
}
} catch (error) {
console.error('微信登录失败:', error);
}
} catch (error) {
this.$c.msg("登录失败,申请获取微信用户数据失败");
console.log(error, '获取微信用户数据失败');
}
},
async h5Login(code) {
try {
const res = await this.$request.post('h5login', {
code: code,
pid: uni.getStorageSync('pid')
});
if (res.status == 1) {
uni.setStorageSync('token', res.data);
// 检查重定向URL
const redirectUrl = uni.getStorageSync('redirect');
if (redirectUrl) {
// 清除重定向信息
uni.removeStorageSync('redirect');
// 使用公共方法处理重定向
this.handleRedirect(redirectUrl);
} else {
// 无重定向页面,检查是否需要绑定手机号
setTimeout(() => {
this.getdata();
}, 1000);
}
}
} catch (error) {
console.error('H5登录失败:', error);
}
},
h5UserProfile() {
console.log('进入h5');
this.$c.msg('暂未开放登录');
// window.location.href = this.$wxloginPage;
},
async getdata() {
try {
const res = await this.$request.post('user');
if (res.status == 1 && res.data.userinfo != null && res.data.userinfo.mobile_is == 0) {
console.log("判断用户有没有手机号", res.data.userinfo.mobile_is);
// 使用新的路由守卫方法跳转到绑定页面
this.$customRouter.navigateTo('/pages/user/bangding', {}, 'navigateTo');
} else {
// 使用新的路由守卫方法跳转到用户首页
this.$customRouter.navigateTo('/pages/user/index', {}, 'navigateTo');
}
} catch (error) {
console.error('获取用户数据失败:', error);
}
}
}
}
</script>
<style lang="scss">
.all {
min-height: 100vh;
background-color: #FFFFFF;
// background: url($imgurl+'common/pageBg1.png') no-repeat 0 0 / 100% auto;
}
.header {
margin: 0 0 90rpx 50rpx;
padding: 90rpx 0 0;
border-bottom: 1px solid #E8E8E8;
text-align: center;
width: 650rpx;
height: 300rpx;
line-height: 450rpx;
}
.header image {
width: 200rpx;
height: 200rpx;
border-radius: 50%;
}
.content {
margin-left: 50rpx;
margin-bottom: 90rpx;
color: #333333;
}
.content text {
display: block;
margin-top: 28rpx;
}
// H5登录表单样式
.h5-login-form {
padding: 0 50rpx;
.input-item {
height: 90rpx;
border-bottom: 1px solid #E8E8E8;
margin-bottom: 40rpx;
input {
height: 100%;
width: 100%;
font-size: 28rpx;
}
}
.code-item {
display: flex;
justify-content: space-between;
align-items: center;
.code-input {
flex: 1;
}
.send-code-btn {
width: 200rpx;
height: 70rpx;
background-color: #333333;
color: #CDEF27;
font-size: 24rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 12rpx;
&.disabled {
background-color: #cccccc;
color: #ffffff;
}
}
}
}
.agree {
display: flex;
padding: 0 50rpx;
margin: 40rpx 0;
.icon {
width: 32rpx;
height: 32rpx;
}
.agree-r {
flex: 1;
word-wrap: break-word;
word-break: break-all;
padding-left: 20rpx;
line-height: 32rpx;
font-size: 20rpx;
color: #999999;
text {
color: #333333;
}
}
}
.btn-list {
display: flex;
justify-content: space-evenly;
padding: 50rpx 0 0;
.cancel {
width: 200rpx;
height: 80rpx;
box-sizing: border-box;
border-radius: 16rpx;
font-size: 28rpx;
color: #333333;
display: flex;
justify-content: center;
align-items: center;
background-color: #CDEF27;
// filter: grayscale(1);
}
.bottom {
background: #333333;
margin: 0;
width: 416rpx;
height: 80rpx;
text-align: center;
box-sizing: border-box;
border-radius: 16rpx;
font-size: 28rpx;
color: #CDEF27;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>