mall-app-t/pages/index/login.vue

178 lines
4.5 KiB
Vue

<template>
<pb-layout :leftIcon="''" navbar="inner" :bgStyle="{ backgroundColor: '#fff' }">
<view class="login-module ss-p-x-30">
<view class="login-title ss-font-56 ss-m-b-72">
{{ title }}
</view>
<uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind">
<uni-forms-item name="mobile">
<uni-easyinput :styles="state.inputStyle" trim="all" placeholder="请输入手机号" v-model="state.model.mobile"
:inputBorder="false" type="number" />
</uni-forms-item>
<uni-forms-item name="code">
<uni-easyinput :styles="state.inputStyle" trim="all" placeholder="验证码" v-model="state.model.code"
:inputBorder="false" type="number" maxlength="4">
<template #right>
<button :disabled="state.isMobileEnd" :class="{ 'code-btn-end': state.isMobileEnd }"
class="ss-reset-button code-btn code-btn-start" @tap="getSmsCode('smsLogin', state.model.mobile)">
{{ getSmsTimer('smsLogin') }}
</button>
</template>
</uni-easyinput>
</uni-forms-item>
</uni-forms>
<button class="ss-reset-button login-btn-start" @tap="smsLoginSubmit">登录</button>
<view class="agreement-box ss-flex ss-row-center" :class="{ shake: state.isShaking }">
<label class="radio ss-flex" @tap="onChange">
<radio :checked="state.agreeStatus" color="var(--ui-BG-Main)" style="transform: scale(0.8)"
@tap.stop="onChange" />
<view class="agreement-text ss-flex ss-m-l-8">
我已阅读并遵守
<view class="tcp-text" @tap.stop="onProtocol('商家入驻协议')"> 《商家入驻协议》 </view>
</view>
</label>
</view>
</view>
</pb-layout>
</template>
<script setup>
import { ref } from 'vue'
import { code, mobile } from '@/peach/validate/form'
import AuthUtil from '@/peach/api/member/auth'
import peach from '@/peach'
import { showAuthModal, closeAuthModal, getSmsCode, getSmsTimer } from '@/peach/hooks/useModal'
const title = ref('欢迎登录')
const smsLoginRef = ref(null)
const state = ref({
isMobileEnd: false,
agreeStatus: false,
isShaking: false,
model: {
mobile: '15036370128',
code: '9999',
},
rules: {
mobile,
code,
},
inputStyle: {
backgroundColor: '#ECECEC',
},
})
function onChange() {
state.value.agreeStatus = !state.value.agreeStatus
}
function onProtocol() {
peach.$router.go('/pages/public/richtext?title=商家入驻协议')
}
async function smsLoginSubmit() {
const validate = await smsLoginRef.value.validate().catch((err) => {
console.log('err', err)
})
if (!validate) return
if (!state.value.agreeStatus) {
state.value.isShaking = true
setTimeout(() => {
state.value.isShaking = false
}, 1000)
peach.$helper.toast('请勾选同意')
return
}
const { code } = await AuthUtil.smsLogin(state.value.model)
}
</script>
<style lang="scss">
.login-module {
.uni-easyinput {
::v-deep .uni-easyinput__content {
border-radius: 41rpx;
padding: 0 10rpx;
}
.is-focused {
::v-deep .content-clear-icon {
.uniui-clear {
color: red !important;
}
}
}
}
}
</style>
<style lang="scss" scoped>
.login-module {
margin-top: 50%;
overflow: hidden;
.login-title {
color: '#1818d';
font-weight: 600;
}
.login-btn-start {
height: 82rpx;
line-height: normal;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
border-radius: 28rpx;
font-size: 26rpx;
font-weight: 500;
color: #fff;
}
.code-btn-start {
width: 160rpx;
height: 56rpx;
line-height: normal;
border-radius: 28rpx;
font-size: 26rpx;
font-weight: 400;
color: var(--ui-BG-Main);
opacity: 1;
}
.agreement-box {
margin: -10px auto 10px;
position: absolute;
bottom: 30rpx;
width: 100%;
.protocol-check {
transform: scale(0.7);
}
.agreement-text {
font-size: 26rpx;
font-weight: 500;
color: #999999;
.tcp-text {
color: var(--ui-BG-Main);
}
}
}
.shake {
animation: shake 0.05s linear 4 alternate;
}
@keyframes shake {
from {
transform: translateX(-5rpx);
}
to {
transform: translateX(5rpx);
}
}
}
</style>