This commit is contained in:
那些花儿
2025-04-24 19:05:25 +08:00
parent bdaea43795
commit 4ad01ea72d
10 changed files with 1090 additions and 75 deletions
+239
View File
@@ -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>