add(接口):添加授权、用户、好友关系服务接口

This commit is contained in:
2025-10-28 16:52:59 +08:00
parent d85e906b39
commit c67c666135
20 changed files with 967 additions and 8 deletions
+386
View File
@@ -0,0 +1,386 @@
<template>
<div class="login-content">
<div class="login-header">
<h2 class="login-title">欢迎登录</h2>
<p class="login-subtitle">请输入您的账号信息</p>
</div>
<form @submit.prevent="handleLogin" class="login-form">
<div class="input-group">
<div class="input-container">
<input id="username" type="text" v-model="username" placeholder=" " required>
<label for="username" class="floating-label">用户名</label>
<div class="input-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 21V19C20 16.7909 18.2091 15 16 15H8C5.79086 15 4 16.7909 4 19V21" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
<circle cx="12" cy="7" r="4" stroke="currentColor" stroke-width="2"/>
</svg>
</div>
</div>
</div>
<div class="input-group">
<div class="input-container">
<input id="password" type="password" v-model="password" placeholder=" " required>
<label for="password" class="floating-label">密码</label>
<div class="input-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="3" y="11" width="18" height="11" rx="2" stroke="currentColor" stroke-width="2"/>
<path d="M7 11V7C7 4.23858 9.23858 2 12 2C14.7614 2 17 4.23858 17 7V11" stroke="currentColor" stroke-width="2"/>
</svg>
</div>
</div>
</div>
<div class="options-row">
<label class="remember-me">
<input type="checkbox">
<span class="checkmark"></span>
记住我
</label>
<a href="#" class="forgot-link">忘记密码?</a>
</div>
<button type="submit" class="login-btn">
<span>登录</span>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<p v-if="errorMsg" class="error">{{ errorMsg }}</p>
</form>
<div class="login-footer">
<p>还没有账号? <a href="#" class="register-link">立即注册</a></p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const username = ref('')
const password = ref('')
const errorMsg = ref('')
const handleLogin = () => {
if (!username.value || !password.value) {
errorMsg.value = '用户名或密码不能为空'
return
}
if (username.value === 'admin' && password.value === '123456') {
alert('登录成功!')
errorMsg.value = ''
// TODO: 跳转到IM主界面
} else {
errorMsg.value = '用户名或密码错误'
}
}
</script>
<style scoped>
.login-content {
padding: 40px 30px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
border-radius: 0 0 8px 8px;
position: relative;
overflow: hidden;
}
/* 添加背景装饰元素 */
.login-content::before {
content: '';
position: absolute;
top: -50%;
right: -20%;
width: 300px;
height: 300px;
border-radius: 50%;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(37, 99, 235, 0.1) 100%);
z-index: 0;
}
.login-content::after {
content: '';
position: absolute;
bottom: -30%;
left: -10%;
width: 200px;
height: 200px;
border-radius: 50%;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(37, 99, 235, 0.08) 100%);
z-index: 0;
}
.login-header {
text-align: center;
margin-bottom: 32px;
position: relative;
z-index: 1;
}
.login-title {
font-size: 26px;
font-weight: 700;
color: #1e293b;
margin-bottom: 8px;
letter-spacing: -0.5px;
}
.login-subtitle {
font-size: 14px;
color: #64748b;
font-weight: 500;
}
.login-form {
display: flex;
flex-direction: column;
gap: 20px;
max-width: 320px;
margin: 0 auto;
width: 100%;
position: relative;
z-index: 1;
}
/* 输入组 */
.input-group {
margin-bottom: 8px;
}
.input-container {
position: relative;
margin-top: 8px;
}
.input-container input {
width: 100%;
padding: 16px 16px 16px 48px;
border: 1.5px solid #e2e8f0;
border-radius: 10px;
font-size: 15px;
outline: none;
transition: all 0.3s ease;
background-color: #ffffff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
position: relative;
z-index: 1;
}
.input-container input:focus {
border-color: #3b82f6;
background-color: #ffffff;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1), 0 2px 6px rgba(59, 130, 246, 0.1);
transform: translateY(-1px);
}
.input-container input:focus + .floating-label,
.input-container input:not(:placeholder-shown) + .floating-label {
top: -8px;
left: 48px;
font-size: 12px;
color: #3b82f6;
background: linear-gradient(180deg, #f8fafc 50%, #ffffff 50%);
padding: 0 6px;
font-weight: 600;
}
.floating-label {
position: absolute;
top: 16px;
left: 48px;
font-size: 15px;
color: #64748b;
pointer-events: none;
transition: all 0.3s ease;
z-index: 2;
}
.input-icon {
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
color: #94a3b8;
transition: color 0.3s ease;
z-index: 2;
}
.input-container input:focus ~ .input-icon {
color: #3b82f6;
}
/* 选项行 */
.options-row {
display: flex;
justify-content: space-between;
align-items: center;
margin: 10px 0 5px;
}
.remember-me {
display: flex;
align-items: center;
font-size: 14px;
color: #64748b;
cursor: pointer;
font-weight: 500;
}
.remember-me input {
display: none;
}
.checkmark {
width: 18px;
height: 18px;
border: 2px solid #cbd5e1;
border-radius: 4px;
margin-right: 8px;
position: relative;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
}
.remember-me:hover .checkmark {
border-color: #94a3b8;
}
.remember-me input:checked + .checkmark {
background-color: #3b82f6;
border-color: #3b82f6;
}
.remember-me input:checked + .checkmark::after {
content: '';
position: absolute;
left: 5px;
top: 2px;
width: 4px;
height: 8px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
.forgot-link {
font-size: 14px;
color: #3b82f6;
text-decoration: none;
transition: color 0.3s ease;
font-weight: 500;
}
.forgot-link:hover {
color: #2563eb;
text-decoration: underline;
}
/* 按钮 */
.login-btn {
width: 100%;
padding: 14px;
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
color: #fff;
font-weight: 600;
font-size: 15px;
border: none;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
margin-top: 10px;
box-shadow: 0 4px 6px rgba(59, 130, 246, 0.25);
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: left 0.5s;
}
.login-btn:hover {
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
box-shadow: 0 6px 12px rgba(59, 130, 246, 0.35);
transform: translateY(-2px);
}
.login-btn:hover::before {
left: 100%;
}
.login-btn:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.4);
}
/* 错误提示 */
.error {
color: #ef4444;
margin-top: 16px;
font-size: 14px;
text-align: center;
padding: 12px;
background-color: #fef2f2;
border-radius: 8px;
border-left: 4px solid #ef4444;
box-shadow: 0 2px 4px rgba(239, 68, 68, 0.1);
font-weight: 500;
}
/* 登录页脚 */
.login-footer {
margin-top: 24px;
text-align: center;
font-size: 14px;
color: #64748b;
position: relative;
z-index: 1;
}
.register-link {
color: #3b82f6;
text-decoration: none;
font-weight: 600;
transition: color 0.3s ease;
position: relative;
}
.register-link::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: #3b82f6;
transition: width 0.3s ease;
}
.register-link:hover {
color: #2563eb;
}
.register-link:hover::after {
width: 100%;
}
</style>