Files
mini-yu/pages/login/login.vue
lingxiao865 c5af079d8c first commit
2026-02-10 08:05:03 +08:00

264 lines
5.9 KiB
Vue

<template>
<view class="login-container">
<view class="login-header">
<text class="title">欢迎使用预约系统</text>
<text class="subtitle">请登录或注册</text>
</view>
<view class="login-form">
<!-- 手机号输入 -->
<view class="form-item">
<t-input v-model:value="phone" placeholder="请输入手机号" type="number" :maxlength="11" clearable>
<template #prefixIcon>
<text class="prefix-icon">📱</text>
</template>
</t-input>
</view>
<!-- 验证码登录 -->
<view class="form-item" v-if="loginType === 'code'">
<t-input v-model:value="code" placeholder="请输入验证码" type="number" :maxlength="6" clearable>
<template #prefixIcon>
<text class="prefix-icon">🔐</text>
</template>
<template #suffix>
<t-button size="small" variant="text" :disabled="codeDisabled" @click="sendCode">
{{ codeButtonText }}
</t-button>
</template>
</t-input>
</view>
<!-- 登录按钮 -->
<view class="form-actions">
<t-button v-if="loginType === 'code'" t-class="btn-primary" theme="primary" size="large" block :loading="loading"
@click="codeLogin">
验证码登录
</t-button>
<t-button v-else t-class="btn-primary" theme="primary" size="large" block :loading="loading" @click="oneClickLogin">
一键登录
</t-button>
</view>
<view class="form-switch">
<text @click="toggleLoginType">
{{ loginType === 'code' ? '使用一键登录' : '使用验证码登录' }}
</text>
<text class="register-link" @click="goToRegister">注册新账号</text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { api } from '@/utils/api'
const phone = ref('13777777777')
const code = ref('')
const loginType = ref<'code' | 'one-click'>('one-click')
const loading = ref(false)
const codeDisabled = ref(false)
const countdown = ref(0)
const codeButtonText = ref('发送验证码')
// 切换登录方式
const toggleLoginType = () => {
loginType.value = loginType.value === 'code' ? 'one-click' : 'code'
}
// 发送验证码
const sendCode = async () => {
console.log(phone.value);
if (!phone.value || phone.value.length !== 11) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
})
return
}
try {
await api.auth.sendCode('+86' + phone.value)
uni.showToast({
title: '验证码已发送',
icon: 'success'
})
// 开始倒计时
codeDisabled.value = true
countdown.value = 60
const timer = setInterval(() => {
countdown.value--
codeButtonText.value = `${countdown.value}秒后重发`
if (countdown.value <= 0) {
clearInterval(timer)
codeDisabled.value = false
codeButtonText.value = '发送验证码'
}
}, 1000)
} catch (error) {
console.error('发送验证码失败', error)
}
}
// 验证码登录
const codeLogin = async () => {
if (!phone.value || phone.value.length !== 11) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
})
return
}
if (!code.value || code.value.length !== 6) {
uni.showToast({
title: '请输入验证码',
icon: 'none'
})
return
}
loading.value = true
try {
const res = await api.auth.verificationLogin('+86' + phone.value, code.value)
uni.setStorageSync('token', res.token)
uni.setStorageSync('user', res.user)
uni.showToast({
title: '登录成功',
icon: 'success'
})
// 直接跳转到首页
uni.reLaunch({ url: '/pages/index/index' })
} catch (error) {
console.error('登录失败', error)
} finally {
loading.value = false
}
}
// 一键登录
const oneClickLogin = async () => {
if (!phone.value || phone.value.length !== 11) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
})
return
}
loading.value = true
try {
const res = await api.auth.oneClickLogin('+86' + phone.value)
uni.setStorageSync('token', res.token)
uni.setStorageSync('user', res.user)
uni.showToast({
title: '登录成功',
icon: 'success'
})
// 直接跳转到首页
uni.reLaunch({ url: '/pages/index/index' })
} catch (error) {
console.error('登录失败', error)
} finally {
loading.value = false
}
}
// 跳转到注册页
const goToRegister = () => {
uni.navigateTo({ url: '/pages/register/register' })
}
</script>
<style scoped>
.login-container {
min-height: 100vh;
background: linear-gradient(135deg, #FF7A00 0%, #FF9500 100%);
padding: 80rpx 40rpx;
}
.login-header {
text-align: center;
margin-bottom: 100rpx;
}
.title {
display: block;
font-size: 48rpx;
font-weight: bold;
color: #ffffff;
margin-bottom: 20rpx;
}
.subtitle {
display: block;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
.login-form {
background: #ffffff;
border-radius: 32rpx;
padding: 60rpx 40rpx;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.1);
}
.form-item {
margin-bottom: 32rpx;
}
.prefix-icon {
font-size: 32rpx;
color: #FF7A00;
}
.form-actions {
margin-top: 60rpx;
}
.form-switch {
display: flex;
justify-content: space-between;
margin-top: 32rpx;
font-size: 28rpx;
color: #666;
}
.form-switch text {
padding: 16rpx 0;
}
.register-link {
color: #FF7A00 !important;
font-weight: bold;
}
</style>
<style>
/* 按钮自定义样式 - 使用全局样式 */
.btn-primary {
background: linear-gradient(135deg, #FF7A00 0%, #FF9500 100%) !important;
border: none !important;
border-radius: 8rpx !important;
color: #FFFFFF !important;
box-shadow: 0 4rpx 12rpx rgba(255, 122, 0, 0.3) !important;
outline: none !important;
}
.btn-primary::after {
border: none !important;
box-shadow: none !important;
}
.btn-primary:active {
background: linear-gradient(135deg, #FF6900 0%, #FF8500 100%) !important;
}
</style>