Files
lanecarford_front/src/views/login/LoginPage.vue
2025-10-31 14:36:23 +08:00

326 lines
7.2 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.
<template>
<div class="login-page">
<div class="content">
<div class="back-button" @click="goBack">
<img src="@/assets/images/arrow_left.png" class="back-icon" />
</div>
<div class="header">
<div class="title">Log in.</div>
<p class="subtitle">Redefine the styling experience with AI.</p>
<p class="subtitle">Use Styling Angel to speed up your fashion journey.</p>
</div>
<div class="login-container">
<div class="login-form">
<div class="input-group">
<input type="email" v-model="formData.email" placeholder="Email" class="input-field" />
</div>
<div class="input-group pwd">
<input
type="password"
v-model="formData.password"
placeholder="Your Password"
class="input-field"
/>
</div>
<div class="login-button" @click="handleLogin">Log in</div>
<div class="forgot-password" @click="handleForgotPassword">Forgot password?</div>
<div type="button" class="google-button" @click="handleGoogleLogin">
<img :src="google" class="google-icon" />
Sign in with Google
</div>
<div class="sign-up-button" @click="handleSignup">Dont have an account? Sign Up</div>
</div>
</div>
</div>
<div class="footer">
<p>Powered by AiDLab for Lane Crawford</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useUserInfoStore } from '@/stores'
import { showToast } from 'vant'
import { google } from '@/assets/base64'
import { fetchRegisterOrLogin } from '@/api/login'
import { encryptPassword } from '@/utils/tools'
const router = useRouter()
const userInfoStore = useUserInfoStore()
// 表单数据
const formData = reactive({
email: '',
password: ''
})
// 加载状态
const isLoading = ref(false)
// 表单验证规则
const validateEmail = (email: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email)
}
const validatePassword = (password: string) => {
return password.length >= 6
}
// 验证表单
const validateForm = () => {
// 验证邮箱
if (!formData.email) {
showToast('Please input your email')
return false
} else if (!validateEmail(formData.email)) {
showToast('Please input valid email')
return false
}
// 验证密码
if (!formData.password) {
showToast('Please input password')
return false
} else if (!validatePassword(formData.password)) {
showToast('Please input correct password')
return false
}
return true
}
// 返回上一页
const goBack = () => {
router.go(-1)
}
// 处理登录
const handleLogin = async () => {
if (!validateForm()) {
return
}
isLoading.value = true
const encryptedPassword = encryptPassword(formData.password)
fetchRegisterOrLogin({ ...formData, password: encryptedPassword, operationType: 'LOGIN' }).then((response) => {
console.log('登录成功', response)
userInfoStore.setToken(response.token)
userInfoStore.setUserInfo(response.user)
showToast('login success')
router.replace('/stylist/customer')
})
}
// 处理忘记密码
const handleForgotPassword = () => {
// 这里可以跳转到忘记密码页面
router.push('/reset')
}
// 处理Google登录
const handleGoogleLogin = async () => {
try {
isLoading.value = true
showToast('Google login is not available yet')
// 这里添加Google OAuth登录逻辑
// const response = await googleLoginAPI()
} catch (error) {
console.error('Google登录失败:', error)
showToast('Google login failed, please try again')
} finally {
isLoading.value = false
}
}
// 处理注册
const handleSignup = () => {
router.push('/signup')
}
// 移除实时验证输入的错误显示逻辑,改用表单提交时统一验证
</script>
<style scoped lang="less">
.login-page {
position: relative;
color: #fff;
width: 100%;
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
background-image: url('@/assets/images/login_bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
padding-top: 12rem;
font-family: 'satoshiRegular';
}
.back-button {
// position: absolute;
// top: 2rem;
// left: 2rem;
margin-top: 2.4rem;
margin-left: 6.1rem;
width: 2rem;
height: 3.4rem;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 3;
font-size: 3.4rem;
.back-icon {
width: 2.83rem;
height: 3.47rem;
}
}
.header {
margin-top: 1.42rem;
padding-left: 15.5rem;
color: white;
font-family: 'satoshiRegular';
.title {
font-size: 11rem;
font-weight: bold;
margin-bottom: 0.8rem;
color: white;
font-family: 'satoshiBold';
}
.subtitle {
font-size: 3rem;
color: white;
font-weight: 400;
line-height: 141%;
letter-spacing: 0.08rem;
}
}
.content {
position: relative;
// z-index: 2;
flex: 1;
}
.login-container {
display: flex;
align-items: center;
justify-content: center;
margin-top: 7.2rem;
.login-form {
position: relative;
width: calc(100% - 28.4rem);
height: 107.8rem;
background: radial-gradient(
100% 100% at 0% 0%,
rgba(115, 115, 115, 0.4) 0%,
rgba(0, 0, 0, 0) 100%
);
backdrop-filter: blur(35px);
-webkit-backdrop-filter: blur(35px);
-moz-backdrop-filter: blur(35px);
-ms-backdrop-filter: blur(35px);
-o-backdrop-filter: blur(35px);
border: 2px solid rgba(255, 255, 255, 0.15);
border-radius: 4.79rem;
padding: 11.2rem 8.62rem 14.28rem 7.18rem;
box-shadow: 0 0.8rem 3.2rem rgba(0, 0, 0, 0.1);
overflow: hidden;
border: 2px solid #fff;
font-size: 3.83rem;
}
.input-field {
width: 100%;
height: 10rem;
padding: 1.6rem 2rem;
border: 2px solid #fff;
background: transparent;
border-radius: 7.1rem;
color: white;
outline: none;
font-size: 3.83rem;
padding: 0 5.5rem;
}
.input-field::placeholder {
color: rgba(255, 255, 255, 0.6);
font-size: 3.83rem;
}
.input-group {
margin-bottom: 4rem;
&.pwd {
margin-bottom: 6.7rem;
}
}
.login-button {
width: 100%;
height: 10rem;
background: #000;
color: white;
border: none;
border-radius: 7rem;
font-size: 4rem;
margin-bottom: 1.67rem;
text-align: center;
line-height: 10rem;
}
.forgot-password {
font-family: 'satoshiRegular';
font-size: 2.39rem;
font-weight: 400;
text-align: center;
text-decoration: underline;
text-decoration-style: bold;
margin-bottom: 21.47rem;
}
}
.google-button {
width: 100%;
padding: 1.6rem;
border: 2px solid #fff;
border-radius: 7rem;
font-size: 3.83rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
column-gap: 3.1rem;
margin-bottom: 1.67rem;
}
.sign-up-button {
font-family: 'satoshiRegular';
font-size: 2.39rem;
font-weight: 400;
text-align: center;
}
.google-icon {
width: 4.8rem;
height: 4.8rem;
}
.footer {
position: relative;
text-align: center;
color: white;
font-size: 3rem;
margin-bottom: 15.5rem;
}
</style>