FPGA_WebLab/src/views/AuthView.vue

289 lines
8.0 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="flex items-center justify-center min-h-screen bg-base-200">
<div class="relative w-full max-w-md">
<!-- Login Card -->
<div v-if="!showSignUp" class="card card-dash h-80 w-100 shadow-xl bg-base-100">
<div class="card-body">
<h1 class="card-title place-self-center my-3 text-2xl">用户登录</h1>
<div class="flex flex-col w-full h-full">
<label class="input w-full my-3">
<User class="h-[1em] opacity-50" />
<input
type="text"
class="grow"
placeholder="用户名"
v-model="username"
@keyup.enter="handleLogin"
/>
</label>
<label class="input w-full my-3">
<Lock class="h-[1em] opacity-50" />
<input
type="password"
class="grow"
placeholder="密码"
v-model="password"
@keyup.enter="handleLogin"
/>
</label>
</div>
<div class="flex justify-end mx-3">
<RouterLink to="/">忘记密码?</RouterLink>
</div>
<div class="card-actions flex items-end my-3">
<button class="btn flex-1" @click="handleRegister">注册</button>
<button
class="btn btn-primary flex-3"
@click="handleLogin"
:disabled="isLoading"
>
{{ isLoading ? "登录中..." : "登录" }}
</button>
</div>
</div>
</div>
<!-- Sign Up Card -->
<div v-if="showSignUp" class="card card-dash h-96 w-100 shadow-xl bg-base-100">
<div class="card-body">
<h1 class="card-title place-self-center my-3 text-2xl">用户注册</h1>
<div class="flex flex-col w-full h-full">
<label class="input w-full my-2">
<User class="h-[1em] opacity-50" />
<input
type="text"
class="grow"
placeholder="用户名"
v-model="signUpData.username"
@keyup.enter="handleSignUp"
/>
</label>
<label class="input w-full my-2">
<Mail class="h-[1em] opacity-50" />
<input
type="email"
class="grow"
placeholder="邮箱"
v-model="signUpData.email"
@keyup.enter="handleSignUp"
/>
</label>
<label class="input w-full my-2">
<Lock class="h-[1em] opacity-50" />
<input
type="password"
class="grow"
placeholder="密码"
v-model="signUpData.password"
@keyup.enter="handleSignUp"
/>
</label>
</div>
<div class="card-actions flex items-end my-3">
<button class="btn flex-1" @click="backToLogin">返回登录</button>
<button
class="btn btn-primary flex-3"
@click="handleSignUp"
:disabled="isSignUpLoading"
>
{{ isSignUpLoading ? "注册中..." : "注册" }}
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { useRouter } from "vue-router";
import { AuthManager } from "@/utils/AuthManager";
import { useAlertStore } from "@/components/Alert";
import { User, Lock, Mail } from "lucide-vue-next";
import { DataClient } from "@/APIClient";
const router = useRouter();
// 获取Alert store
const alertStore = useAlertStore();
// 创建API客户端实例
const dataClient = new DataClient();
// 响应式数据
const username = ref("");
const password = ref("");
const isLoading = ref(false);
// 注册相关数据
const showSignUp = ref(false);
const isSignUpLoading = ref(false);
const signUpData = ref({
username: "",
email: "",
password: ""
});
// 登录处理函数
const handleLogin = async () => {
// 验证输入
if (!username.value.trim()) {
alertStore?.show("请输入用户名", "error");
return;
}
if (!password.value.trim()) {
alertStore?.show("请输入密码", "error");
return;
}
isLoading.value = true;
try {
// 调用AuthManager的登录函数
await AuthManager.login(username.value.trim(), password.value.trim());
// 登录成功,显示成功消息并跳转
alertStore?.show("登录成功", "success", 1000);
// 短暂延迟后跳转到project页面
setTimeout(async () => {
await router.push("/project");
}, 1000);
} catch (error: any) {
console.error("Login error:", error);
// 处理不同类型的错误
let errorMessage = "登录失败,请检查网络连接";
if (error.status === 400) {
errorMessage = "用户名或密码错误";
} else if (error.status === 401) {
errorMessage = "用户名或密码错误";
} else if (error.status === 500) {
errorMessage = "服务器错误,请稍后重试";
} else if (error.message) {
errorMessage = error.message;
}
alertStore?.show(errorMessage, "error");
} finally {
isLoading.value = false;
}
};
// 注册处理函数
const handleRegister = () => {
showSignUp.value = true;
// 清空注册表单
signUpData.value = {
username: "",
email: "",
password: ""
};
};
// 返回登录页面
const backToLogin = () => {
showSignUp.value = false;
};
// 注册提交处理函数
const handleSignUp = async () => {
// 验证输入
if (!signUpData.value.username.trim()) {
alertStore?.show("请输入用户名", "error");
return;
}
if (!signUpData.value.email.trim()) {
alertStore?.show("请输入邮箱", "error");
return;
}
// 简单的邮箱格式验证
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(signUpData.value.email.trim())) {
alertStore?.show("请输入有效的邮箱地址", "error");
return;
}
if (!signUpData.value.password.trim()) {
alertStore?.show("请输入密码", "error");
return;
}
// 密码长度验证
if (signUpData.value.password.length < 6) {
alertStore?.show("密码长度至少6位", "error");
return;
}
isSignUpLoading.value = true;
try {
// 调用注册API
const result = await dataClient.signUpUser(
signUpData.value.username.trim(),
signUpData.value.email.trim(),
signUpData.value.password.trim()
);
if (result) {
// 注册成功
alertStore?.show("注册成功!请登录", "success", 2000);
// 延迟后返回登录页面
setTimeout(() => {
backToLogin();
}, 2000);
} else {
alertStore?.show("注册失败,请重试", "error");
}
} catch (error: any) {
console.error("Sign up error:", error);
let errorMessage = "注册失败,请检查网络连接";
if (error.status === 400) {
// 检查是否有详细的错误信息
if (error.result && error.result.detail) {
errorMessage = error.result.detail;
} else {
errorMessage = "注册信息无效,请检查输入";
}
} else if (error.status === 500) {
errorMessage = "服务器错误,请稍后重试";
} else if (error.message) {
errorMessage = error.message;
}
alertStore?.show(errorMessage, "error");
} finally {
isSignUpLoading.value = false;
}
};
// 页面初始化时检查是否已有有效token
const checkExistingToken = async () => {
try {
const isValid = await AuthManager.verifyToken();
if (isValid) {
// 如果token仍然有效直接跳转到project页面
await router.push("/project");
}
} catch (error) {
// token无效或验证失败继续显示登录页面
console.log("Token verification failed, showing login page");
}
};
// 组件挂载时检查已存在的token
onMounted(() => {
checkExistingToken();
});
</script>
<style scoped></style>