You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

341 lines
6.4 KiB

7 months ago
<template>
<view class="container">
<view class="bottom-sign">
<image v-if="theme" :src="`/static/public/login_bg_${theme}.png`"></image>
</view>
<view class="back-btn" @click="navBack">
<image src="@/static/icons/left_back@3x.png"></image>
</view>
7 months ago
<view class="wrapper">
<view class="tips">
<view class="tips_title">{{tips.title}}</view>
<view class="tips_text">{{tips.text}}</view>
7 months ago
</view>
<view class="input_box">
<view class="area_select">
<view class="area">{{area}}</view>
<image class="icon_down" src="@/static/icons/icon_down.png"></image>
7 months ago
</view>
<input type="number" maxlength="11" v-model="mobile" placeholder="输入手机号" />
<image v-if="mobile" class="icon_clear" src="@/static/icons/icon_clear.png" @click="mobile=''"></image>
7 months ago
</view>
<button :class="{'confirm-btn':true,disbled:!canSend}" :disabled="!canSend"
@click="getCode">获取短信验证码</button>
<view class="checkbox_box">
<label class="radio" @click="isRead = !isRead">
<radio value="" :checked="isRead" />已阅读并同意用户协议隐私政策
</label>
</view>
<view class="login_icon">
<image class="wechat" src="@/static/icons/icon_wechat.png"></image>
<image class="apple" src="@/static/icons/icon_apple.png"></image>
7 months ago
</view>
</view>
<check-code :data="showData" @closeModal="closeModal" @login="doLogin" @regetCode="regetCode" v-if="isShowCode"
class="modal-box" />
7 months ago
</view>
</template>
<script>
import {
mapState,
7 months ago
mapMutations
} from 'vuex';
import {
sendsms,
appLogin,
wxIdLogin,
memberInfo
7 months ago
} from '@/api/member.js';
import CheckCode from './components/checkCode.vue'
import rule from '@/utils/rule.js'
7 months ago
export default {
data() {
return {
tips: {
title: '注册/登录',
text: '输入手机号,开启雀乐;未注册手机,将自动注册'
},
// 地区编号
area: '+86',
// 手机号
mobile: '',
// 验证码
mobileCheckCode: '',
// 是否同意隐私策略
isRead: false,
// 是否显示验证码输入
isShowCode: false,
// 登录中禁用按钮
isLogining: false,
// 传给验证码输入组件
showData: {
area: '',
mobile: '',
deviceId: '',
mobileCheckCode: '',
deviceBrand: ''
}
7 months ago
}
},
components: {
CheckCode
},
computed: {
...mapState(['theme', 'deviceId', 'deviceBrand']),
canSend() {
return this.mobile.length === 11 && !this.isLogining
}
7 months ago
},
onLoad() {},
7 months ago
methods: {
...mapMutations(['login']),
navBack() {
uni.navigateBack();
},
getCode() {
if (!rule.mobile(this.mobile)) {
this.$api.msg('请输入正确的手机号码');
return;
}
if (!this.isRead) {
this.$api.msg('请先同意隐私政策');
return;
}
this.regetCode()
},
closeModal(type) {
if (type === 'code') {
this.isShowCode = false
}
7 months ago
},
async doLogin(data) {
uni.showLoading({
title: '登录中……',
mask: true
})
appLogin(data)
.then(res => {
if(res.code === 200 && res.data) {
uni.setStorageSync('token',res.data);
memberInfo().then(response=>{
this.login(response.data);
uni.navigateBack();
});
}
})
.catch(err => {
console.log('err', err)
uni.showToast({
title: '登录失败',
icon: 'error'
})
})
.finally(
() => {
uni.hideLoading()
}
)
7 months ago
},
regetCode() {
this.isLogining = true
sendsms({
mobile: this.mobile,
deviceId: this.deviceId
})
.then(res => {
if (res.code === 200) {
this.showData = {
area: this.area,
mobile: this.mobile,
deviceId: this.deviceId,
deviceBrand: this.deviceBrand,
mobileCheckCode: '',
}
this.isShowCode = true
}
})
.catch(
err => {
console.log(err)
uni.showToast({
duration: 3000,
title: err
})
})
.finally(() => {
this.isLogining = false
})
}
7 months ago
},
}
</script>
<style lang='scss' scoped>
7 months ago
.container {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
.bottom-sign {
position: fixed;
left: 0;
bottom: 0;
width: 100vw;
height: 100vw;
7 months ago
image {
width: 100%;
height: 100%;
}
}
7 months ago
.back-btn {
position: absolute;
left: 40upx;
padding-top: var(--status-bar-height);
top: 40upx;
font-size: 40upx;
color: $font-color-dark;
z-index: 9;
image {
width: 40rpx;
height: 40rpx;
}
}
7 months ago
.wrapper {
position: relative;
padding-top: 200upx;
7 months ago
.tips {
width: 100%;
height: 136upx;
padding: 0 48rpx;
7 months ago
.tips_title {
font-size: 64upx;
margin-bottom: 26upx;
}
7 months ago
.tips_text {
font-size: 28upx;
}
}
7 months ago
.input_box {
display: flex;
align-items: center;
padding: 88upx 48upx;
position: relative;
7 months ago
.area_select {
display: flex;
align-items: center;
7 months ago
.area {
font-size: 34upx;
}
7 months ago
.icon_down {
width: 48upx;
height: 48upx;
margin: 0 23upx 0 14upx;
}
}
7 months ago
input {
font-size: 34upx;
border-left: 2upx solid rgba(0, 0, 0, 0.4);
padding-left: 54upx;
}
7 months ago
.icon_clear {
width: 48upx;
height: 48upx;
position: absolute;
right: 48upx;
top: 50%;
margin-top: -24upx;
}
7 months ago
}
7 months ago
.confirm-btn {
width: 566upx;
height: 88upx;
line-height: 88upx;
border-radius: 999px;
background: #C43737;
color: #fff;
font-size: $font-lg;
7 months ago
&:after {
border-radius: 100px;
}
}
.confirm-btn.disbled {
background-color: #ccc;
}
.checkbox_box {
padding: 42upx;
.radio {
font-size: 24upx;
}
radio {
transform: scale(0.7)
}
}
.login_icon {
padding-top: 32upx;
display: flex;
justify-content: center;
image {
width: 92upx;
height: 92upx;
}
image.wechat {
margin-right: 24upx;
}
image.apple {
margin-left: 24upx;
}
}
7 months ago
}
.modal-box {
position: absolute;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
background: #fff;
z-index: 9;
}
7 months ago
}
/* 暗黑模式 */
@media (prefers-color-scheme: dark) {
.container {
.wrapper .input_box input {
border-left: 2upx solid #fff;
}
7 months ago
.back-btn {
color: #fff;
}
7 months ago
}
}
</style>