Files
uni-qnc-mini/src/pages/login.vue
liangzai 55db6946e7
Some checks failed
Check / lint (18.x, macos-latest) (push) Has been cancelled
Check / lint (18.x, ubuntu-latest) (push) Has been cancelled
Check / lint (18.x, windows-latest) (push) Has been cancelled
Check / lint (20.x, macos-latest) (push) Has been cancelled
Check / lint (20.x, ubuntu-latest) (push) Has been cancelled
Check / lint (20.x, windows-latest) (push) Has been cancelled
Check / lint (22.x, macos-latest) (push) Has been cancelled
Check / lint (22.x, ubuntu-latest) (push) Has been cancelled
Check / lint (22.x, windows-latest) (push) Has been cancelled
Check / typecheck (18.x, macos-latest) (push) Has been cancelled
Check / typecheck (18.x, ubuntu-latest) (push) Has been cancelled
Check / typecheck (18.x, windows-latest) (push) Has been cancelled
Check / typecheck (20.x, macos-latest) (push) Has been cancelled
Check / typecheck (20.x, ubuntu-latest) (push) Has been cancelled
Check / typecheck (20.x, windows-latest) (push) Has been cancelled
Check / typecheck (22.x, macos-latest) (push) Has been cancelled
Check / typecheck (22.x, ubuntu-latest) (push) Has been cancelled
Check / typecheck (22.x, windows-latest) (push) Has been cancelled
Check / build (build, 18.x, macos-latest) (push) Has been cancelled
Check / build (build, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build, 18.x, windows-latest) (push) Has been cancelled
Check / build (build, 20.x, macos-latest) (push) Has been cancelled
Check / build (build, 20.x, ubuntu-latest) (push) Has been cancelled
Check / build (build, 20.x, windows-latest) (push) Has been cancelled
Check / build (build, 22.x, macos-latest) (push) Has been cancelled
Check / build (build, 22.x, ubuntu-latest) (push) Has been cancelled
Check / build (build, 22.x, windows-latest) (push) Has been cancelled
Check / build (build:app, 18.x, macos-latest) (push) Has been cancelled
Check / build (build:app, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:app, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:app, 20.x, macos-latest) (push) Has been cancelled
Check / build (build:app, 20.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:app, 20.x, windows-latest) (push) Has been cancelled
Check / build (build:app, 22.x, macos-latest) (push) Has been cancelled
Check / build (build:app, 22.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:app, 22.x, windows-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, macos-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 20.x, macos-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 20.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 20.x, windows-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 22.x, macos-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 22.x, ubuntu-latest) (push) Has been cancelled
Check / build (build:mp-weixin, 22.x, windows-latest) (push) Has been cancelled
first commit
2024-11-18 14:21:31 +08:00

215 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { getCode, login } from '@/api/apis'
const phoneNumber = ref('')
const verificationCode = ref('')
const password = ref('')
const isPasswordLogin = ref(false)
const isAgreed = ref(false)
const isCountingDown = ref(false)
const countdown = ref(60)
let timer = null
// 聚焦状态变量
const phoneFocused = ref(false)
const codeFocused = ref(false)
const passwordFocused = ref(false)
// function toggleLoginMethod() {
// isPasswordLogin.value = !isPasswordLogin.value
// }
const isPhoneNumberValid = computed(() => {
return /^1[3-9]\d{9}$/.test(phoneNumber.value)
})
const canLogin = computed(() => {
if (!isPhoneNumberValid.value)
return false
if (isPasswordLogin.value) {
return password.value.length >= 6
}
else {
return verificationCode.value.length === 6
}
})
function sendVerificationCode() {
if (!isPhoneNumberValid.value) {
uni.showToast({ title: '请输入有效的手机号', icon: 'none' })
return
}
getCode({
mobile: phoneNumber.value,
actionType: 'login',
}).then((res) => {
if (res.code === 200) {
uni.showToast({ title: '获取成功', icon: 'none' })
startCountdown()
}
})
}
function startCountdown() {
isCountingDown.value = true
countdown.value = 60
timer = setInterval(() => {
if (countdown.value > 0) {
countdown.value--
}
else {
clearInterval(timer)
isCountingDown.value = false
}
}, 1000)
}
function handleLogin() {
if (!canLogin.value) {
uni.showToast({ title: '请完善信息', icon: 'none' })
return
}
if (!isAgreed.value) {
uni.showToast({ title: '请先同意用户协议', icon: 'none' })
return
}
login({ mobile: phoneNumber.value, code: verificationCode.value }).then((res) => {
console.log('res.data.AccessToken', res.data.accessToken)
if (res.code === 200) {
uni.setStorageSync('token', res.data.accessToken)
uni.showToast({ title: '登录成功', icon: 'none' })
uni.reLaunch({
url: '/pages/index',
})
}
else {
uni.showToast({ title: res.msg, icon: 'none' })
}
})
}
function openUserAgreement() {
// 打开用户协议页面
}
function openPrivacyPolicy() {
// 打开隐私政策页面
}
onUnmounted(() => {
if (timer) {
clearInterval(timer)
}
})
</script>
<template>
<view class="max-w-md px-8">
<view class="mb-8 pt-8 text-left">
<view class="mb-2 text-2xl text-gray-800 font-bold">
用户登录
</view>
</view>
<view class="space-y-5">
<view class="input-container" :class="[phoneFocused ? 'focused' : '']">
<input
v-model="phoneNumber"
class="input-field"
type="number"
placeholder="请输入手机号"
maxlength="11"
@focus="phoneFocused = true"
@blur="phoneFocused = false"
>
</view>
<view v-if="!isPasswordLogin">
<view class="flex items-center justify-between">
<view class="input-container" :class="[codeFocused ? 'focused' : '']">
<input
v-model="verificationCode"
class="input-field"
type="number"
placeholder="请输入验证码"
maxlength="6"
@focus="codeFocused = true"
@blur="codeFocused = false"
>
</view>
<wd-button
class="ml-2 text-sm text-blue-500 font-bold transition duration-300 disabled:cursor-not-allowed disabled:text-gray-400 focus:outline-none"
:disabled="isCountingDown || !isPhoneNumberValid"
@click="sendVerificationCode"
>
{{ isCountingDown ? `${countdown}s重新获取` : '获取验证码' }}
</wd-button>
</view>
</view>
<view v-if="isPasswordLogin" class="input-container" :class="[passwordFocused ? 'focused' : '']">
<input
v-model="password"
class="input-field"
type="password"
placeholder="请输入密码"
@focus="passwordFocused = true"
@blur="passwordFocused = false"
>
</view>
<view class="flex items-start space-x-2">
<wd-checkbox v-model="isAgreed" class="mt-1" />
<text class="text-xs text-gray-400 leading-tight">
未注册手机号登录后将自动生成账号并且代表您已阅读并同意
<text class="cursor-pointer text-blue-400" @click="openUserAgreement">
用户协议
</text>
<text class="cursor-pointer text-blue-400" @click="openPrivacyPolicy">
隐私政策
</text>
</text>
</view>
</view>
<button
class="mt-20 block w-full rounded-full bg-blue-500 py-3 text-lg text-white font-bold transition duration-300"
@click="handleLogin"
>
登录
</button>
<!-- <wd-divider class="my-8">
更多登陆方式
</wd-divider>
<view class="mt-4 text-center text-right text-sm text-blue-500 underline" @click="toggleLoginMethod">
{{ isPasswordLogin ? '验证码登录' : '密码登录' }}
</view> -->
</view>
</template>
<style scoped>
.input-container {
border: 2px solid rgba(125, 211, 252, 0.0); /* 蓝色边框 */
border-radius: 1rem;
background-color: rgba(125, 211, 252, 0.3); /* sky-200/30 */
@apply transition duration-200
}
.input-container.focused {
border: 2px solid #3b82f6; /* 蓝色边框 */
}
.input-field {
width: 100%;
padding: 1rem;
transition: border-color 0.3s ease;
outline: none;
background: transparent;
}
</style>
<route lang="json">
{
"layout": "login"
}
</route>