界面优化

This commit is contained in:
stardrophere
2026-03-12 19:38:14 +08:00
parent 19a61e6567
commit 6fbcf2c81b
5 changed files with 244 additions and 22 deletions
+117 -6
View File
@@ -19,6 +19,8 @@ const showPassword = ref(false)
const errorMessage = ref('')
const successMessage = ref('')
const countdown = ref(0)
const isSubmitting = ref(false)
const isSendingCode = ref(false)
const form = reactive({
email: '',
@@ -83,6 +85,7 @@ async function handleSendLoginCode() {
return
}
isSendingCode.value = true
try {
const result = await authStore.sendLoginVerificationCode(form.email.trim())
successMessage.value = result.message || '验证码已发送'
@@ -93,6 +96,8 @@ async function handleSendLoginCode() {
startCooldown(retryAfter)
}
errorMessage.value = error instanceof Error ? error.message : '验证码发送失败,请稍后重试'
} finally {
isSendingCode.value = false
}
}
@@ -106,6 +111,7 @@ async function handleSubmit() {
return
}
isSubmitting.value = true
try {
if (loginMode.value === 'password') {
await authStore.loginWithPassword({
@@ -123,6 +129,8 @@ async function handleSubmit() {
await router.replace(redirect)
} catch (error) {
errorMessage.value = error instanceof Error ? error.message : '登录失败,请稍后重试'
} finally {
isSubmitting.value = false
}
}
@@ -146,6 +154,30 @@ onUnmounted(() => {
<p class="brand-desc">
聚合多平台趋势自动完成热点归并与摘要你可以用密码登录也可以直接使用邮箱验证码快速登录
</p>
<div class="feature-list">
<div class="feature-item">
<div class="feature-icon">🚀</div>
<div class="feature-text">
<strong>实时热搜追踪</strong>
<span>分钟级更新覆盖微博知乎抖音等主流平台</span>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">🤖</div>
<div class="feature-text">
<strong>AI 智能聚类</strong>
<span>自动识别同源事件告别重复阅读的信息轰炸</span>
</div>
</div>
<div class="feature-item">
<div class="feature-icon"></div>
<div class="feature-text">
<strong>核心内容摘要</strong>
<span>一键获取事件全貌省时省力掌握核心脉络</span>
</div>
</div>
</div>
</div>
<div class="ambient-glow"></div>
</aside>
@@ -204,9 +236,9 @@ onUnmounted(() => {
placeholder="请输入密码"
autocomplete="current-password"
/>
<button type="button" class="input-action-btn" @click="showPassword = !showPassword">
<!-- <button type="button" class="input-action-btn" @click="showPassword = !showPassword">
{{ showPassword ? '隐藏' : '显示' }}
</button>
</button> -->
</div>
</div>
@@ -222,8 +254,8 @@ onUnmounted(() => {
placeholder="请输入 6 位验证码"
inputmode="numeric"
/>
<button type="button" class="input-action-btn" :disabled="!canSendCode" @click="handleSendLoginCode">
{{ countdown > 0 ? `${countdown}s` : '发送验证码' }}
<button type="button" class="input-action-btn" :disabled="!canSendCode || isSendingCode" @click="handleSendLoginCode">
{{ isSendingCode ? '发送中...' : (countdown > 0 ? `${countdown}s` : '发送验证码') }}
</button>
</div>
</div>
@@ -251,7 +283,7 @@ onUnmounted(() => {
</div>
<button class="btn-primary" :disabled="authStore.loading" type="submit">
{{ authStore.loading ? '登录中...' : loginMode === 'password' ? '密码登录' : '邮箱验证码登录' }}
{{ isSubmitting ? '登录中...' : (loginMode === 'password' ? '密码登录' : '邮箱验证码登录') }}
</button>
</form>
@@ -277,13 +309,38 @@ onUnmounted(() => {
.brand-panel {
flex: 1;
display: none;
background: linear-gradient(135deg, var(--bg-surface), var(--bg-base));
background: var(--bg-surface);
border-right: 1px solid var(--border-subtle);
padding: 80px;
position: relative;
overflow: hidden;
}
/* 动态网格背景 */
.brand-panel::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
right: -50%;
bottom: -50%;
background-image:
linear-gradient(rgba(128, 128, 128, 0.15) 1px, transparent 1px),
linear-gradient(90deg, rgba(128, 128, 128, 0.15) 1px, transparent 1px);
background-size: 32px 32px;
background-position: center;
z-index: 0;
pointer-events: none;
animation: grid-move 20s linear infinite;
mask-image: radial-gradient(circle at center, black 40%, transparent 80%);
-webkit-mask-image: radial-gradient(circle at center, black 40%, transparent 80%);
}
@keyframes grid-move {
0% { transform: translate(0, 0); }
100% { transform: translate(32px, 32px); }
}
@media (min-width: 900px) {
.brand-panel {
display: flex;
@@ -332,6 +389,60 @@ onUnmounted(() => {
line-height: 1.7;
color: var(--text-secondary);
font-weight: 500;
margin-bottom: 40px;
}
.feature-list {
display: flex;
flex-direction: column;
gap: 24px;
margin-top: 32px;
}
.feature-item {
display: flex;
align-items: flex-start;
gap: 16px;
padding: 16px;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: var(--radius-lg);
transition: transform 0.3s ease, background 0.3s ease;
}
.feature-item:hover {
transform: translateY(-2px);
background: rgba(255, 255, 255, 0.06);
}
.feature-icon {
font-size: 24px;
background: rgba(255, 255, 255, 0.1);
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-md);
flex-shrink: 0;
}
.feature-text {
display: flex;
flex-direction: column;
gap: 4px;
}
.feature-text strong {
color: var(--text-primary);
font-size: 16px;
font-weight: 600;
}
.feature-text span {
color: var(--text-secondary);
font-size: 14px;
line-height: 1.5;
}
.ambient-glow {