TrainingPlatform_VUE/src/views/SignIn.vue
2025-06-03 16:28:46 +08:00

136 lines
5.8 KiB
Vue

<template>
<div class="page page-center">
<div class="container container-tight py-4">
<div class="text-center mb-4">
<!-- <a href="." class="navbar-brand navbar-brand-autodark">
<img src="/public/logo.ico" width="110" height="32" alt="Tabler" class="navbar-brand-image">
</a> -->
<h1 class="navbar-brand-name" style="font-size: 24px; margin-left: 10px;">算法工厂</h1>
<!-- 使用 h1 标签并增加样式 -->
</div>
<div class="card card-md">
<div class="card-body">
<h2 class="h2 text-center mb-4">登录</h2>
<div autocomplete="off" novalidate>
<div class="mb-3">
<label class="form-label">邮箱地址</label>
<input type="email" v-model="formData.email" class="form-control" placeholder="输入邮箱"
required>
<div v-if="emailError" class="text-danger">{{ emailError }}</div>
</div>
<div class="mb-2">
<label class="form-label">
密码
<span class="form-label-description">
<a href="./forgot-password.html">忘记密码</a>
</span>
</label>
<div class="input-group input-group-flat">
<input type="password" v-model="formData.password" class="form-control"
placeholder="输入密码" required>
<span class="input-group-text">
<a href="#" class="link-secondary" title="Show password"
data-bs-toggle="tooltip"><!-- Download SVG icon from http://tabler-icons.io/i/eye -->
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path
d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
</svg>
</a>
</span>
</div>
<div v-if="passwordError" class="text-danger">{{ passwordError }}</div>
</div>
<div class="mb-2">
<label class="form-check">
<input type="checkbox" class="form-check-input" />
<span class="form-check-label">下次自动登录</span>
</label>
</div>
<div class="form-footer">
<button @click="handleSubmit" class="btn btn-primary w-100">登录</button>
</div>
</div>
</div>
</div>
<div class="text-center text-secondary mt-3">
还没有账号? <a href="./sign-up" tabindex="-1">注册</a>
</div>
</div>
</div>
</template>
<script lang="ts" setup name="SignIn">
import { ref, reactive } from 'vue'
import { API_URL } from '@/config/config'
import { useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/mytoken'
import axios from 'axios' // 引入 axios
import router from '@/router'
const authStore = useAuthStore(); // 使用 Pinia store
let formData = reactive({
email: '',
password: ''
})
const emailError = ref('')
const passwordError = ref('')
const handleSubmit = async () => {
emailError.value = ''
passwordError.value = ''
if (!formData.email) {
emailError.value = '邮箱地址是必填的'
} else if (!validateEmail(formData.email)) {
emailError.value = '邮箱地址格式不正确'
}
if (!formData.password) {
passwordError.value = '密码是必填的'
}
if (formData.email && formData.password && !emailError.value) {
try {
// 提交请求的逻辑
const response = await axios.post(`${API_URL}/accounts/login/`, formData)
if (response.data.success) {
console.log(response.data.token)
// pinia存储 JWT
authStore.saveTokens(response.data.token); // 使用 Pinia store 保存 token
// 提取用户信息
let user = {
username: response.data.username,
email: response.data.email
};
// 存储用户信息到 Pinia store
authStore.saveUser(user);
// 登录成功后的逻辑,例如跳转到主页
router.push('/project'); // 假设主页的路由是 '/home'
} else {
// 处理登录失败的情况
console.error('登录失败', response.data.message);
}
} catch (error) {
console.log(error)
alert('登录异常')
// window.location.reload()
}
}
}
const validateEmail = (email: string) => {
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // 邮箱格式正则表达式
return emailPattern.test(email);
}
</script>