You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.3 KiB
198 lines
5.3 KiB
<template>
|
|
<div class="login-container">
|
|
<div class="login-box">
|
|
<h2 style="color: white;padding-bottom: 10px">登录</h2>
|
|
<form @submit.prevent="login">
|
|
<!-- Username Field -->
|
|
<div class="input-group">
|
|
<i class="fas fa-user"></i>
|
|
<input type="text" v-model="username" placeholder="用户名" required />
|
|
</div>
|
|
|
|
<!-- Password Field -->
|
|
<div class="input-group">
|
|
<i class="fas fa-lock"></i>
|
|
<input type="password" v-model="password" placeholder="密码" required />
|
|
</div>
|
|
|
|
<!-- Captcha Field -->
|
|
<div class="input-group captcha-group">
|
|
<i class="fas fa-shield-alt"></i>
|
|
<input type="text" v-model="code" placeholder="验证码" required />
|
|
<img :src="captchaUrl" @click="refreshCaptcha" alt="验证码" class="captcha-image" style="margin-top: 5px"/>
|
|
</div>
|
|
|
|
<!-- Login Button -->
|
|
<button type="submit" class="login-button">登录</button>
|
|
</form>
|
|
<p>没有账户?<router-link to="/register">注册</router-link></p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import axios from 'axios';
|
|
import { mapActions } from "vuex";
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
// role: 'student', // Default value, either 'teacher' or 'student'
|
|
username: '',
|
|
password: '',
|
|
code: '', // 存储用户输入的验证码
|
|
captchaUrl: '', // 验证码图片的 URL
|
|
uuid: ''
|
|
};
|
|
},
|
|
methods: {
|
|
fetchCaptcha() {
|
|
fetch('http://localhost:8080/captchaImage')
|
|
.then(response => response.json()) // 将响应解析为 JSON
|
|
.then(data => {
|
|
if (data.code === 200) {
|
|
this.captchaUrl = `data:image/jpeg;base64,${data.img}`;
|
|
this.uuid = data.uuid; // 存储 uuid
|
|
} else {
|
|
console.error('获取验证码失败:', data.msg);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('获取验证码时出现错误:', error);
|
|
});
|
|
},
|
|
async login() {
|
|
try {
|
|
const response = await axios.post('http://localhost:8080/login', {
|
|
role: this.role, // Send the selected role (teacher or student)
|
|
username: this.username,
|
|
password: this.password,
|
|
code: this.code, // Send the captcha
|
|
uuid: this.uuid,
|
|
}, {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
});
|
|
|
|
if (response.data.code === 200) {
|
|
|
|
const res = await axios.get('http://localhost:8080/getInfo',{
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': response.data.token,
|
|
'Content-Type': 'application/json',
|
|
}});
|
|
if(res.data.code==200){
|
|
const token = response.data.token;
|
|
const userId = res.data.user.userId;
|
|
this.$store.dispatch('setToken', { userId, token });
|
|
if(res.data.roles[0] === 'student'){
|
|
this.$router.push({
|
|
path: '/user/profile',
|
|
query: { userId: userId }
|
|
});
|
|
}else if(res.data.roles[0] === 'teacher'){
|
|
this.$router.push({
|
|
path: '/teacher/correct',
|
|
query: { userId: userId }
|
|
});
|
|
// window.location.href = 'http://localhost:8081/teacher/correct';
|
|
}else{
|
|
alert('该角色无权限');
|
|
this.refreshCaptcha();
|
|
}
|
|
}else{
|
|
alert('登录失败,请重试');
|
|
this.refreshCaptcha(); // Handle error and refresh captcha
|
|
}
|
|
} else {
|
|
console.error('登录失败', response.data.msg);
|
|
alert('登录失败,' + response.data.msg);
|
|
this.refreshCaptcha(); // Refresh captcha on failure
|
|
}
|
|
} catch (error) {
|
|
console.error('登录失败', error);
|
|
alert('登录失败,' + error);
|
|
this.refreshCaptcha(); // Handle error and refresh captcha
|
|
}
|
|
},
|
|
// Vuex action 映射
|
|
...mapActions(['setToken']),
|
|
|
|
// Refresh captcha image
|
|
refreshCaptcha() {
|
|
this.fetchCaptcha();
|
|
}
|
|
},
|
|
mounted() {
|
|
this.fetchCaptcha(); // Get captcha when component is mounted
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.login-container {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
background-color: #2e3a4e;
|
|
}
|
|
|
|
.login-box {
|
|
width: 350px;
|
|
padding: 20px;
|
|
background-color: #3c4d63;
|
|
border-radius: 8px;
|
|
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
|
|
text-align: center;
|
|
}
|
|
|
|
.input-group {
|
|
margin-bottom: 15px;
|
|
position: relative;
|
|
}
|
|
|
|
.input-group i {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 10px;
|
|
transform: translateY(-50%);
|
|
color: #aaa;
|
|
}
|
|
|
|
.input-group input,
|
|
.input-group select {
|
|
width: 100%;
|
|
padding: 10px 10px 10px 30px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background-color: #e8f0fe; /* Set background color to #e8f0fe */
|
|
color: #333; /* Set text color to dark for readability */
|
|
}
|
|
|
|
.captcha-image {
|
|
height: 40px;
|
|
cursor: pointer;
|
|
margin-left: 10px;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.login-button {
|
|
width: 100%;
|
|
padding: 10px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background-color: #007bff;
|
|
color: #fff;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.login-button:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
</style>
|
|
|