136 lines
5.8 KiB
Vue
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>
|