..
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<view class="login-container">
|
||||
<image
|
||||
class="banner-image"
|
||||
src="https://res.firstui.cn/template/loginB/login/img_banner_3x.png"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
|
||||
<view class="login-form">
|
||||
<text class="title">登录</text>
|
||||
|
||||
<t-input
|
||||
class="input-item"
|
||||
v-model="loginForm.phone"
|
||||
placeholder="请输入手机号码"
|
||||
>
|
||||
</t-input>
|
||||
|
||||
<t-input
|
||||
class="input-item"
|
||||
v-model="loginForm.smsCode"
|
||||
placeholder="请输入验证码"
|
||||
>
|
||||
<template #suffix>
|
||||
<t-button variant="text" class="verify-btn" @click="getSmsCode" :disabled="isCountingDown">
|
||||
{{ countDownText }}
|
||||
</t-button>
|
||||
</template>
|
||||
</t-input>
|
||||
|
||||
<!-- <view class="login-options">-->
|
||||
<!-- <text>账号登录</text>-->
|
||||
<!-- <text>注册</text>-->
|
||||
<!-- </view>-->
|
||||
|
||||
<t-button block theme="primary" size="large" class="login-btn" @click="handleLogin">
|
||||
登录
|
||||
</t-button>
|
||||
|
||||
<!-- <view class="other-login">-->
|
||||
<!-- <text class="other-text">其他登录方式</text>-->
|
||||
<!-- <view class="login-methods">-->
|
||||
<!-- <t-button shape="circle" variant="outline" icon="qq" class="method-btn" />-->
|
||||
<!-- <t-button shape="circle" variant="outline" icon="wechat" class="method-btn" />-->
|
||||
<!-- <t-button shape="circle" variant="outline" icon="image" class="method-btn" />-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, reactive, computed, onMounted} from 'vue'
|
||||
import {Toast} from 'tdesign-mobile-vue';
|
||||
import {useRequest} from "@/util/request";
|
||||
|
||||
const request = useRequest()
|
||||
|
||||
const loginForm = reactive({
|
||||
phone: '',
|
||||
smsCode: ''
|
||||
})
|
||||
|
||||
const countdown = ref(0)
|
||||
const timer = ref(null)
|
||||
// 是否在倒计时中
|
||||
const isCountingDown = computed(() => countdown.value > 0)
|
||||
// 验证码按钮文字
|
||||
const countDownText = computed(() => {
|
||||
return isCountingDown.value ? `${countdown.value}秒后重试` : '获取验证码'
|
||||
})
|
||||
|
||||
// 开始倒计时
|
||||
const startCountDown = () => {
|
||||
countdown.value = 60
|
||||
timer.value = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(timer.value)
|
||||
timer.value = null
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
|
||||
// 获取验证码
|
||||
async function getSmsCode() {
|
||||
if (!loginForm.phone) {
|
||||
Toast.error('请输入手机号码');
|
||||
return
|
||||
}
|
||||
|
||||
if (isCountingDown.value) return
|
||||
try {
|
||||
const {code, data, msg} = await request.post('/client/auth/send-sms-code/' + loginForm.phone)
|
||||
if (code === 0) {
|
||||
Toast.success('验证码发送成功')
|
||||
// 开始倒计时
|
||||
startCountDown()
|
||||
} else {
|
||||
Toast.error(msg)
|
||||
}
|
||||
} catch (e) {
|
||||
Toast.error(e.message)
|
||||
} finally {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async function handleLogin() {
|
||||
if (!loginForm.phone) {
|
||||
Toast.error('请输入手机号码');
|
||||
return
|
||||
}
|
||||
if (!loginForm.smsCode) {
|
||||
Toast.error('请输入验证码');
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const {data, code, msg} = await useRequest().post('/client/auth/sms-login', loginForm)
|
||||
if (code === 0) {
|
||||
Toast.success('登录成功')
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
} else {
|
||||
Toast.error(msg)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
Toast.error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (timer.value) {
|
||||
clearInterval(timer.value)
|
||||
timer.value = null
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.login-container {
|
||||
min-height: 100vh;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 260px;
|
||||
background-color: #4080ff;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
padding: 20px;
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin: 20px 0;
|
||||
display: block;
|
||||
color: var(--td-brand-color-5);
|
||||
}
|
||||
|
||||
.input-item {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.country-code {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.verify-btn {
|
||||
color: var(--td-brand-color-5);
|
||||
}
|
||||
|
||||
.login-options {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.other-login {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
|
||||
.other-text {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 0 10px;
|
||||
background: #fff;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 60px;
|
||||
height: 1px;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: -70px;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: -70px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-methods {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 30px;
|
||||
margin-top: 20px;
|
||||
|
||||
.method-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user