This commit is contained in:
@fawn-nine
2023-03-03 12:11:23 +08:00
commit f8e1a3015b
502 changed files with 57308 additions and 0 deletions

869
pages/user/login.vue Normal file
View File

@@ -0,0 +1,869 @@
<template>
<view style="background-color: #fff;">
<!-- <z-nav-bar :shadow="false"></z-nav-bar> -->
<!-- 公共组件-每个页面必须引入 -->
<public-module></public-module>
<view class="logo_bg">
<text>您好<br>欢迎来到 疯子读书</text>
<image src="../../static/icon/login_icon_1.png" mode="aspectFit" class="icon_hua_1"></image>
<image src="../../static/icon/login_icon_2.png" mode="aspectFit" class="icon_hua_2"></image>
</view>
<view class="register_page">
<view class="login_method">
<view class="title" :class="{ active: type == 2000 }" v-if="type == 2000">验证码登录/注册</view>
<view class="title" :class="{ active: type == 1000 }" v-if="type == 1000">密码登录</view>
<!-- <view class="title" :class="{ active: type == 2000 }" @click="type = 2000">验证码登录/注册</view>
<view class="title" :class="{ active: type == 1000 }" @click="type = 1000">密码登录</view> -->
</view>
<view class="input_tit">手机号</view>
<view class="input_box triangle" :clasfs="[type == 1000 ? 'left_triangle': 'right_triangle']">
<input type="text" v-model="phone" @input="onInput" placeholder="请输入您的手机号" placeholder-class="grey" />
</view>
<view class="input_tit" v-if="type == 1000">密码</view>
<view class="input_box" v-if="type == 1000">
<input class="input_item" v-model="password" @input="onInput" :password="!isSee" placeholder="请输入密码"
placeholder-class="grey" @confirm="onSubmit" />
<image v-if="isSee" src="../../static/icon/ic_logon_display.png" mode="aspectFit"
@click="isSee = false">
</image>
<image v-else-if="!isSee" src="../../static/icon/ic_logon_hide.png" mode="aspectFit"
@click="isSee = true">
</image>
</view>
<view class="input_tit" v-if="type == 2000">验证码</view>
<view class="input_box" v-if="type == 2000">
<input v-model="code" placeholder="请输入您的验证码" placeholder-class="grey" @input="onInput" maxlength="6"
@confirm="onSubmit" />
<button class="active" @click="onSetCode">{{ codeText }}</button>
</view>
<view class="protocol_box">
<view class="select" :class="{active: agree}" @click="agree = !agree"></view>
我已同意
<text @click="onPageJump('/pages/user/protocol')">用户协议</text>
<text @click="onPageJump('/pages/user/protocol')">隐私协议</text>
</view>
<view class="btn_box">
<button @click="onSubmit" class="active" v-if="btnShow"> </button>
<button v-else> </button>
</view>
<view class="password_register" style="margin: 0 auto; text-align: center; display: block;">
<button @click="onPageJump('/pages/user/register')">注册账号</button>
<text v-if="type == 1000" @click="onPageJump('/pages/user/forget')">忘记密码</text>
</view>
<view class="third_party_login_box">
<view class="third_party_title"><text>第三方登录</text></view>
<view class="third_party_content">
<image src="../../static/icon/ic_login_health.png" @click="onHealthLogin" mode="aspectFit"></image>
</view>
</view>
<view class="qie_huan" style="display: flex; justify-content: center;">
<view style="width: 30%;" @click="type = 1000" v-if="type == 2000">密码登录</view>
<view style="width: 30%;" @click="type = 2000" v-if="type == 1000">验证码登录</view>
</view>
<z-popup v-model="HealthOpen" type="center" :hideOnBlur="false">
<view class="popup_box">
<view class="popup_title">
<view>
<image src="../../static/icon/ic_login_health.png" mode="aspectFit"></image>
一路健康用户 - 登录
</view>
</view>
<view class="popup_content">
<view class="input_tit">账号</view>
<view class="input_box triangle" :class="[type == 1000 ? 'left_triangle': 'right_triangle']">
<input type="text" v-model="health_phone" placeholder="请输入您的一路健康账号"
placeholder-class="grey" />
</view>
<view class="input_tit">密码</view>
<view class="input_box">
<input class="input_item" v-model="health_password" :password="!isSee_H" placeholder="请输入密码"
placeholder-class="grey" @confirm="onSubmit_Health" />
<image v-if="isSee_H" src="../../static/icon/ic_logon_display.png" mode="aspectFit"
@click="isSee_H = false">
</image>
<image v-else-if="!isSee_H" src="../../static/icon/ic_logon_hide.png" mode="aspectFit"
@click="isSee_H = true">
</image>
</view>
</view>
<view class="popup_footer">
<view @click="HealthOpen = false">取消</view>
<view @click="onSubmit_Health">确定</view>
</view>
</view>
</z-popup>
<!-- #ifdef APP-PLUS -->
<view class="third_party_login_box" v-if="isIos && system >= 13">
<view class="third_party_title"><text>第三方登录</text></view>
<view class="third_party_content">
<image src="../../static/icon/ic_login_weixin.png" v-if="isWeixin" @click="onWxAppLogin"
mode="aspectFit"></image>
<image src="../../static/icon/ic_login_ios.png" v-if="isIos && system >= 13" @click="onAppleLogin"
mode="aspectFit"></image>
</view>
</view>
<!-- #endif -->
</view>
</view>
</template>
<script>
import md5 from '@/plugins/md5';
var clear;
import {
mapState,
mapMutations
} from 'vuex';
import socket from '@/config/socket';
export default {
data() {
return {
type: 2000,
isSee: false,
code: '',
// phone: '15022449475',
phone: '18047689535',
password: '123456z',
//验证码
codeText: '获取验证码',
//验证码已发
readonly: false,
btnShow: true,
agree: false,
isIos: true,
isWeixin: true,
system: 13,
clearTime: null,
HealthOpen: false,
health_phone: '13333333333',
health_password: '123456',
isSee_H: false,
};
},
//第一次加载
onLoad(e) {
// #ifdef APP-PLUS
this.isIos = (plus.os.name == "iOS");
let systemInfo = uni.getSystemInfoSync();
this.system = parseFloat(systemInfo['system'].replace(/[a-zA-Z]/g, ""));
this.isWeixin = plus.runtime.isApplicationExist({
pname: 'com.tencent.mm',
action: "weixin://"
});
// #endif
},
//页面显示
onShow() {},
//方法
methods: {
...mapMutations(['setUserInfo']),
...mapMutations(['setHealthMes']),
onPageJump(url) {
uni.navigateTo({
url: url
});
},
onInput() {
// this.clearTime && clearTimeout(this.clearTime)
// this.clearTime = setTimeout(() => {
// if (this.type == 2000) {
// if (this.phone && this.code) {
// this.btnShow = true;
// } else {
// this.btnShow = false;
// }
// } else {
// if (this.phone && this.password) {
// this.btnShow = true;
// } else {
// this.btnShow = false;
// }
// }
// }, 500);
},
//验证码按钮文字状态
getCodeState() {
clear && clearInterval(clear);
const _this = this;
this.readonly = true;
this.codeText = '60S';
var s = 60;
clear = setInterval(() => {
s--;
_this.codeText = s + 'S';
if (s <= 0) {
clearInterval(clear);
_this.codeText = '获取验证码';
_this.readonly = false;
}
}, 1000);
},
// 发送验证码
onSetCode() {
if (this.readonly) {
return;
}
if (!this.phone) {
uni.showToast({
title: '请输入手机号',
icon: 'none'
});
return;
}
if (!this.$base.phoneRegular.test(this.phone)) {
uni.showToast({
title: '手机格式不正确',
icon: 'none'
});
return;
}
if (!this.agree) {
uni.showToast({
title: '请先同意《用户协议》和《隐私协议》',
icon: 'none'
});
return;
}
this.$http
.get('book/user/sms/sendcode', {
phone: this.phone,
type: 2000
})
.then(res => {
uni.showToast({
title: '验证码发送成功',
icon: 'none'
});
this.getCodeState();
});
},
// 手机密码登录
onSubmit() {
if (!this.agree) {
uni.showToast({
title: '请先同意《用户协议》和《隐私协议》',
icon: 'none'
});
return;
}
if (!this.phone) {
uni.showToast({
title: '请输入手机号',
icon: 'none'
});
return;
}
if (!this.$base.phoneRegular.test(this.phone)) {
uni.showToast({
title: '手机格式不正确',
icon: 'none'
});
return;
}
let httpData = {};
if (this.type == 2000) {
if (!this.code) {
uni.showToast({
title: '请输入验证码',
icon: 'none'
});
return;
}
httpData.code = this.code;
httpData.tel = this.phone;
this.$http
.get('book/user/registerOrLogin', httpData)
.then(res => {
res.userInfo.token = res.token.token;
this.setUserInfo(res.userInfo);
// socket.init();
uni.showToast({
title: '登录成功',
duration: 1000,
});
setTimeout(() => {
uni.switchTab({
url: '/pages/peanut/home'
});
}, 1000);
});
} else {
if (!this.password) {
uni.showToast({
title: '请输入密码',
icon: 'none'
});
return;
}
// httpData.password = md5(this.password);
httpData.password = this.password;
httpData.phone = this.phone;
this.$http
.post('book/user/login', httpData)
.then(res => {
res.userInfo.token = res.token.token;
this.setUserInfo(res.userInfo);
// socket.init();
uni.showToast({
title: '登录成功',
duration: 1000,
});
setTimeout(() => {
uni.switchTab({
url: '/pages/peanut/home'
});
}, 1000);
});
}
},
// 一路健康APP登录进入
onSubmit_Health() {
if (!this.health_phone) {
uni.showToast({
title: '请输入一路健康账号',
icon: 'none'
});
return;
}
if (!this.health_password) {
uni.showToast({
title: '请输入密码',
icon: 'none'
});
return;
}
let healthData = {};
healthData.phone = this.health_phone;
healthData.password = this.health_password
this.$http
.post('book/user/getEverhealthInfo', healthData)
.then(res => {
this.setHealthMes(res.everhealthInfo);
if (res.userInfo) {
res.userInfo.token = res.token.token;
this.setUserInfo(res.userInfo);
uni.showToast({
title: '登录成功',
duration: 1000,
});
setTimeout(() => {
uni.switchTab({
url: '/pages/peanut/home'
});
}, 1000);
} else {
setTimeout(() => {
uni.navigateTo({
url: '/pages/user/healthLog'
});
}, 600);
uni.showToast({
title: '账号验证成功',
duration: 600,
});
}
// if (!IsPhoneHealth) {
// setTimeout(() => {
// uni.navigateTo({
// url: '/pages/user/healthLog'
// });
// }, 600);
// uni.showToast({
// title: '验证成功',
// duration: 600,
// });
// } else {
// uni.showModal({
// title: '提示',
// content: '验证您的一路健康账号成功,请问您要通过该账户登录花生吗?',
// success: function(res) {
// if (res.confirm) {
// this.setUserInfo(res.userInfo);
// // socket.init();
// uni.switchTab({
// url: "/pages/home/home"
// });
// } else if (res.cancel) {
// console.log('用户点击取消');
// }
// }
// });
// }
});
},
// 一路健康APP登录
onHealthLogin() {
if (!this.agree) {
uni.showToast({
title: '请先同意《用户协议》和《隐私协议》',
icon: 'none'
});
return;
}
this.HealthOpen = true
},
// 微信APP登录
onWxAppLogin() {
uni.login({
provider: 'weixin',
success: res => {
uni.getUserInfo({
success: (info) => {
this.userInfo = info.userInfo;
if (res.authResult.openid && res.authResult.unionid) {
this.$http
.post('api/open/v1/login', {
wxAppOpenId: res.authResult.openid,
unionid: res.authResult.unionid,
nickname: this.userInfo.nickName,
headImg: this.userInfo.avatarUrl
})
.then(data => {
this.setUserInfo({
openId: res.authResult.openid,
unionid: res.authResult.unionid,
...data,
});
if (data.thirdLoginSuccess) {
socket.init();
uni.showToast({
title: '登录成功',
duration: 2000
});
setTimeout(() => {
uni.switchTab({
url: "/pages/home/home"
});
}, 2000);
} else {
uni.showModal({
title: '提示',
content: '您还未绑定手机号,请先绑定~',
confirmText: '去绑定',
cancelText: '再逛会',
success: res => {
if (res.confirm) {
uni.redirectTo({
url: '/pages/user/bindPhone'
});
}
}
});
}
});
} else {
uni.showToast({
title: '点击无效,请再次点击',
icon: "none"
});
}
},
fail: () => {
console.log("未授权");
}
})
},
fail(err) {
console.log(err);
}
});
},
// 苹果登录
onAppleLogin() {
uni.login({
provider: 'apple',
success: loginRes => {
uni.getUserInfo({
provider: 'apple',
success: userInfoRes => {
if (userInfoRes.userInfo.identityToken) {
this.$http
.post('api/open/v1/ios_login', {
identityToken: userInfoRes.userInfo.identityToken
})
.then(data => {
this.setUserInfo(data);
if (data.thirdLoginSuccess) {
socket.init();
uni.showToast({
title: '登录成功',
duration: 2000
});
setTimeout(() => {
uni.switchTab({
url: "/pages/home/home"
});
}, 2000);
} else {
uni.showModal({
title: '提示',
content: '您还未绑定手机号,请先绑定~',
confirmText: '去绑定',
cancelText: '再逛会',
success: res => {
if (res.confirm) {
uni.redirectTo({
url: '/pages/user/bindPhone'
});
}
}
});
}
});
}
}
})
},
fail: err => {
uni.showToast({
title: '登录失败',
icon: 'none'
})
}
})
}
},
//页面隐藏
onHide() {},
//页面卸载
onUnload() {},
//页面下来刷新
onPullDownRefresh() {},
//页面上拉触底
onReachBottom() {},
//用户点击分享
onShareAppMessage(e) {
return this.wxShare();
}
};
</script>
<style lang="scss" scoped>
@import '@/style/mixin.scss';
.logo_bg {
background-image: url('@/static/icon/login_bg.png');
// background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
height: 25vh;
position: relative;
text {
font-size: 45upx;
line-height: 65rpx;
position: absolute;
bottom: 110rpx;
left: 60rpx;
color: #fff;
letter-spacing: 6rpx;
}
.icon_hua_1 {
position: absolute;
bottom: 60rpx;
left: 245rpx;
width: 150rpx;
height: 150rpx;
opacity: 0.08;
}
.icon_hua_2 {
position: absolute;
bottom: 10rpx;
right: 30rpx;
width: 250rpx;
height: 250rpx;
opacity: 0.15;
}
}
.register_page {
padding: calc(var(--status-bar-height)) 60rpx 50rpx 60rpx;
background-color: #fff;
min-height: 75vh;
.login_method {
// display: flex;
justify-content: space-between;
padding: 0 96rpx;
// padding-bottom: 5rpx;
text-align: center;
.title {
margin: 0 auto;
font-size: 40rpx;
letter-spacing: 3rpx;
color: #666;
&.active {
position: relative;
color: $themeColor;
padding-bottom: 35rpx;
font-weight: bold;
}
&.active::after {
bottom: 0;
left: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
content: '';
width: 150rpx;
height: 6rpx;
background-color: $themeColor;
}
}
}
.left_triangle {
&::before {
left: 140rpx;
}
&::after {
left: 140rpx;
}
}
.right_triangle {
&::before {
left: 470rpx;
}
&::after {
left: 470rpx;
}
}
.input_tit {
margin-top: 20rpx;
font-size: 34rpx;
font-weight: bold;
}
.input_box {
display: flex;
align-items: center;
border-radius: 8rpx;
border-bottom: solid 2rpx #efeef4;
margin: 30rpx 0;
image {
width: 36rpx;
height: 24rpx;
}
input {
flex: 1;
font-size: 28rpx;
color: #333;
height: 70rpx;
}
.input_item {
font-size: 28rpx;
border: 0px;
flex: 1;
background-color: #f8f9fb;
height: 70rpx;
width: 100%;
outline: none;
//margin-left: 32rpx;
}
button {
height: 60rpx;
background-color: #f8f9fb;
font-size: 28rpx;
padding: 0 14rpx;
color: $themeColor;
line-height: 60rpx;
margin-left: 20rpx;
//margin-right: 40rpx;
}
.grey {
color: #999999;
}
}
.btn_box {
margin-top: 40rpx;
button {
font-size: 32rpx;
background-color: #e5e5e5;
color: #fff;
height: 80rpx;
line-height: 80rpx;
border-radius: 50rpx;
&.active {
@include theme('btn_bg') color: #fff;
}
}
}
.password_register {
margin-top: 40rpx;
display: flex;
justify-content: space-between;
//text-align: center;
text {
font-size: 28rpx;
color: #333333;
//text-decoration: underline;
}
}
.protocol_box {
margin-top: 40rpx;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
font-size: 28rpx;
color: #333333;
.select {
width: 36rpx;
height: 36rpx;
background-image: url("../../static/icon/ic_gender_unselected.png");
background-position: center center;
background-repeat: no-repeat;
background-size: 100% auto;
margin-right: 15rpx;
&.active {
background-image: url("../../static/icon/ic_agreed.png");
}
}
>text {
color: $themeColor;
}
}
}
.station {
height: 230rpx;
}
.third_party_login_box {
position: fixed;
bottom: 60rpx;
width: 100%;
left: 0;
padding: 0 30rpx;
.third_party_title {
display: flex;
align-items: center;
&:before,
&:after {
content: '';
flex: 1;
height: 2rpx;
background-color: #f5f5f5;
}
text {
font-size: 24rpx;
color: #999999;
flex-shrink: 0;
padding: 0 20rpx;
}
}
.third_party_content {
margin-top: 60rpx;
display: flex;
justify-content: center;
align-items: center;
image {
width: 80upx;
height: 80upx;
margin: 0 20rpx;
}
}
}
.popup_box {
width: 600upx;
border-radius: 10rpx;
.popup_title {
display: flex;
justify-content: center;
height: 88upx;
line-height: 88upx;
view {
align-items: center;
font-size: 30upx;
display: flex;
image {
width: 50upx;
height: 50upx;
margin: 0 20rpx 0 0;
}
}
}
.popup_content {
padding: 30rpx 40rpx;
}
.popup_footer {
display: flex;
justify-content: center;
view {
width: 45%;
flex-shrink: 0;
text-align: center;
font-size: 28upx;
color: #999;
line-height: 70upx;
margin: 0 0 30rpx 0;
}
view:last-child {
background-color: $themeColor;
color: #fff;
border-radius: 50rpx;
}
}
}
.qie_huan{
font-size: 26rpx;
margin: 20rpx 0 0 0;
text-align: center;
}
</style>