Files
sharepi/template/src/views/Login.vue
2026-01-07 10:36:09 +08:00

522 lines
10 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.

<script setup>
import { ref } from 'vue'
import axios from 'axios';
//读取全局变量
import { inject } from 'vue'
import { useRouter } from 'vue-router';
const routesConfig = inject('routesConfig')
const apiConfig = inject('apiConfig')
const router = useRouter()
const info = ref()
const username = ref("")
const password = ref("")
function login() {
console.log(username.value + " " + password.value)
axios.post(apiConfig.login, { username: username.value, password: password.value }, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(res => {
if (res.data.status === 'Success') {
// 登录成功,返回上一页
router.back();
} else {
// 登录失败,存储错误信息
info.value = res.data.message || '登录失败';
}
})
.catch(err => {
console.error(err);
info.value = '网络错误,请稍后重试';
});
}
</script>
<template>
<div class="page-content">
<div class="login-card">
<h1 class="login-title">欢迎回来</h1>
<p class="login-subtitle">登录校享派继续你的校园共享生活</p>
<div class="tab-group">
<div class="tab active">手机登录</div>
</div>
<div class="lock-message" style="display: none;">
<i class="layui-icon layui-icon-warning"></i>
账号已被锁定请30分钟后再试
</div>
<div class="error-message" style="display: none;">
<i class="layui-icon layui-icon-close-circle"></i>
密码错误请重新输入
</div>
<form>
<div class="form-group">
<label class="input-label" for="phone">手机号</label>
<div class="input-wrapper">
<input type="text" id="phone" placeholder="请输入手机号" maxlength="11" v-model="username">
</div>
</div>
<div class="form-group">
<label class="input-label" for="password">密码</label>
<div class="input-wrapper">
<input type="password" id="password" placeholder="请输入密码" v-model="password">
<i class="layui-icon layui-icon-eye toggle-password"></i>
</div>
<div class="attempts-message" style="display: none;">
剩余尝试次数3/5连续失败5次将锁定账号30分钟
</div>
</div>
<div class="link-group">
<a href="">登录说明</a>
<a href="">忘记密码</a>
</div>
<button type="button" class="login-btn" @click="login()">
登录
</button>
<div class="register-link">
<span>还没有账号</span>
<router-link :to="routesConfig.reg">立即注册</router-link>
</div>
</form>
</div>
<div class="register-modal" style="display: none;">
<div class="modal-content">
<h3 class="modal-title">欢迎使用校享派</h3>
<p class="modal-text">您还没有注册账号是否现在注册</p>
<div class="modal-buttons">
<router-link :to="routesConfig.reg">立即注册</router-link>
<button class="modal-btn later">稍后再说</button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
/* 所有样式保持不变但添加了scoped属性 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.page-content {
width: 100%;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.login-card {
background-color: #ffffff;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 48px;
width: 100%;
max-width: 500px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
animation: slideUp 0.5s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.login-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15)
}
.login-title {
text-align: center;
color: #667eea;
font-size: 28px;
font-weight: 700;
margin-bottom: 8px;
}
.login-subtitle {
text-align: center;
color: #666;
font-size: 14px;
margin-bottom: 32px;
}
.tab-group {
display: flex;
justify-content: center;
margin-bottom: 32px;
border-bottom: 1px solid #e5e7eb;
padding-bottom: 12px;
}
.tab {
cursor: pointer;
padding: 0 32px;
font-size: 18px;
color: #666;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
font-weight: 500;
}
.tab.active {
color: #667eea;
font-weight: 600;
}
.tab.active::after {
content: "";
position: absolute;
bottom: -13px;
left: 50%;
transform: translateX(-50%);
width: 48px;
height: 3px;
background-color: #667eea;
border-radius: 3px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.tab:hover:not(.active) {
color: #667eea;
}
.form-group {
margin-bottom: 24px;
position: relative;
}
.input-label {
display: block;
color: #333;
font-size: 14px;
font-weight: 500;
margin-bottom: 8px;
}
.input-wrapper {
position: relative;
}
input {
padding: 14px 16px;
border: 1px solid #e5e7eb;
border-radius: 8px;
width: 100%;
font-size: 16px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background-color: #fff;
}
input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
input::placeholder {
color: #999;
font-size: 14px;
}
.toggle-password {
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
color: #999;
font-size: 18px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.toggle-password:hover {
color: #667eea;
}
.login-btn {
padding: 14px 20px;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
width: 100%;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
margin-bottom: 20px;
position: relative;
overflow: hidden;
}
.login-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.login-btn:hover::before {
left: 100%;
}
.login-btn:hover {
background: linear-gradient(135deg, #5a6edb, #6b4498);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}
.login-btn:active {
transform: translateY(0);
}
.link-group {
display: flex;
justify-content: space-between;
margin-bottom: 24px;
}
.link-group a {
color: #667eea;
text-decoration: none;
font-size: 14px;
font-weight: 500;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.link-group a:hover {
color: #5a6edb;
text-decoration: underline;
}
.register-link {
text-align: center;
margin-top: 16px;
}
.register-link a {
color: #667eea;
text-decoration: none;
font-size: 14px;
font-weight: 500;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.register-link a:hover {
color: #5a6edb;
text-decoration: underline;
}
.error-message {
background-color: #fff2f0;
border: 1px solid #ffccc7;
color: #ff4d4f;
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 24px;
font-size: 14px;
display: none;
align-items: center;
gap: 8px;
animation: shake 0.3s ease-in-out;
}
@keyframes shake {
0%,
100% {
transform: translateX(0);
}
25% {
transform: translateX(-3px);
}
75% {
transform: translateX(3px);
}
}
.lock-message {
background-color: #fff7e6;
border: 1px solid #ffe7ba;
color: #faad14;
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 24px;
font-size: 14px;
display: none;
align-items: center;
gap: 8px;
}
.attempts-message {
color: #faad14;
font-size: 12px;
margin-top: 6px;
display: none;
}
.register-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
animation: fadeIn 0.3s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.modal-content {
background-color: white;
padding: 32px;
border-radius: 12px;
max-width: 400px;
width: 90%;
text-align: center;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
animation: modalSlideUp 0.3s ease-out;
}
@keyframes modalSlideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.modal-title {
color: #667eea;
font-size: 20px;
font-weight: 700;
margin-bottom: 16px;
}
.modal-text {
color: #666;
margin-bottom: 28px;
line-height: 1.6;
font-size: 14px;
}
.modal-buttons {
display: flex;
gap: 16px;
justify-content: center;
}
.modal-btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
font-weight: 600;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
flex: 1;
}
.register-now {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
}
.register-now:hover {
background: linear-gradient(135deg, #5a6edb, #6b4498);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}
.later {
background-color: #f8f9fa;
color: #333;
border: 1px solid #e5e7eb;
}
.later:hover {
background-color: #e6e8eb;
border-color: #667eea;
}
@media (max-width: 480px) {
.page-content {
padding: 16px;
}
.login-card {
padding: 32px 24px;
}
.login-title {
font-size: 24px;
}
.tab {
padding: 0 20px;
font-size: 16px;
}
.link-group {
flex-direction: column;
gap: 12px;
align-items: center;
}
.modal-buttons {
flex-direction: column;
}
}
</style>