Files
BYW-VoiceHub/app/pages/forgot-password.vue
T
Henry_Du a82ff6747e
构建并部署 BYW VoiceHub / Preflight 语法与构建检查 (push) Successful in 2m8s
构建并部署 BYW VoiceHub / 构建并推送容器镜像 (push) Successful in 9m11s
构建并部署 BYW VoiceHub / 部署到生产服务器 (push) Successful in 7s
feat(site): 对齐参考站点UI与交互调整
- 页脚:响应耗时文字统一为「响应耗时 XXXms」,版本链接改为 GitHub 官方仓库,默认 ICP 备案号设置为粤ICP备2025450093号
- 顶部栏:恢复主题切换按钮与语言按钮(语言暂为占位提示),放置于用户区左侧
- 主题:修复首屏内联脚本默认主题白名单校验,避免 localStorage 中残留的 light/dark/System 等非法值生效,首屏默认改为 ClassicLight(仅允许 ClassicLight/ModernLight)
- 登录页:在密码输入框下方恢复「忘记密码?」入口,新增配套的找回密码引导页 /forgot-password
- 默认配置:system-settings 兜底记录与 SYSTEM_SETTINGS_DEFAULTS 新增 icpNumber 默认值
2026-09-12 11:56:30 +08:00

270 lines
6.1 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.
<template>
<div class="auth-layout">
<div class="auth-container">
<div class="form-section">
<div class="form-header">
<div class="logo-row">
<img
:src="brandLogoSrc"
alt="Brand Logo"
class="brand-logo-center"
width="96"
height="96"
decoding="async"
fetchpriority="high"
>
<div v-if="schoolLogoHomeUrl && schoolLogoHomeUrl.trim()" class="logo-divider" />
<img
v-if="schoolLogoHomeUrl && schoolLogoHomeUrl.trim()"
:src="schoolLogoHomeUrl"
alt="学校Logo"
class="school-logo"
width="160"
height="160"
decoding="async"
fetchpriority="high"
>
</div>
<h1 class="form-title">{{ siteTitle ? siteTitle + ' | VoiceHub' : 'VoiceHub' }}</h1>
<div class="header-divider" />
</div>
<div class="forgot-password-form">
<div class="page-intro">
<h2 class="page-heading">找回密码</h2>
<p class="page-subtitle">请联系管理员重置您的账号密码</p>
</div>
<div class="contact-card">
<div class="contact-card-icon">
<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</div>
<div class="contact-card-body">
<h3>联系管理员</h3>
<p>为保障账号安全,系统暂未开放自助密码找回。请通过以下方式联系管理员进行密码重置:</p>
<ul class="contact-tips">
<li>站内联系:登录有管理员权限的账号</li>
<li>线下联系:前往广播站办公室或指导老师</li>
<li>邮件联系:如有公开的管理员邮箱</li>
</ul>
</div>
</div>
<div class="form-actions">
<NuxtLink to="/login" class="back-to-login-btn">
返回登录
</NuxtLink>
</div>
</div>
</div>
</div>
<SiteFooter />
</div>
</template>
<script setup>
import { onMounted, computed } from 'vue'
import logo from '~~/public/images/logo.png'
const { siteTitle, initSiteConfig, schoolLogoHomeUrl } = useSiteConfig()
const brandLogoSrc = computed(() => {
return logo
})
onMounted(async () => {
await initSiteConfig()
if (typeof document !== 'undefined' && siteTitle.value) {
document.title = `找回密码 | ${siteTitle.value}`
}
})
</script>
<style scoped>
.auth-layout {
min-height: 100vh;
background: var(--bg-primary);
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding: 20px;
}
.auth-container {
width: 100%;
max-width: 520px;
background: var(--bg-secondary);
border-radius: var(--radius-2xl);
border: 1px solid var(--border-primary);
box-shadow: var(--shadow-lg);
overflow: hidden;
margin: auto 0;
margin-bottom: 40px;
}
.form-section {
padding: 40px 32px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: var(--bg-secondary);
}
.form-header {
text-align: center;
margin-bottom: 24px;
width: 100%;
}
.logo-row {
display: flex;
align-items: center;
justify-content: center;
gap: 24px;
margin-bottom: 12px;
}
.logo-divider {
width: 1px;
height: 96px;
background: var(--border-secondary);
}
.brand-logo-center {
width: 96px;
height: 96px;
object-fit: contain;
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.15));
}
.school-logo {
width: 160px;
height: 160px;
object-fit: contain;
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.15));
}
.form-title {
font-size: 24px;
font-weight: var(--font-bold);
margin: 0;
color: var(--text-primary);
}
.header-divider {
height: 1px;
background: var(--border-secondary);
margin: 14px auto 0;
width: 100%;
}
.forgot-password-form {
width: 100%;
max-width: 400px;
}
.page-intro {
text-align: center;
margin-bottom: 28px;
}
.page-heading {
font-size: 28px;
font-weight: var(--font-bold);
color: var(--text-primary);
margin: 0 0 8px 0;
}
.page-subtitle {
font-size: 14px;
color: var(--text-tertiary);
margin: 0;
}
.contact-card {
display: flex;
gap: 16px;
padding: 24px;
background: var(--bg-tertiary);
border: 1px solid var(--border-secondary);
border-radius: var(--radius-lg);
margin-bottom: 28px;
}
.contact-card-icon {
width: 40px;
height: 40px;
border-radius: 12px;
background: rgba(59, 130, 246, 0.12);
color: var(--primary);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.contact-card-icon svg {
width: 20px;
height: 20px;
}
.contact-card-body h3 {
font-size: 16px;
font-weight: var(--font-semibold);
color: var(--text-primary);
margin: 0 0 8px 0;
}
.contact-card-body p {
font-size: 14px;
color: var(--text-secondary);
margin: 0 0 12px 0;
line-height: 1.6;
}
.contact-tips {
margin: 0;
padding-left: 18px;
color: var(--text-secondary);
font-size: 13px;
line-height: 1.9;
}
.form-actions {
display: flex;
flex-direction: column;
gap: 12px;
}
.back-to-login-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
padding: 14px;
background: var(--btn-primary-bg);
color: var(--btn-primary-text);
border: 1px solid var(--btn-primary-border);
border-radius: var(--radius-lg);
font-size: 16px;
font-weight: var(--font-semibold);
text-decoration: none;
transition: all 0.2s ease;
}
.back-to-login-btn:hover {
background: var(--btn-primary-hover);
transform: translateY(-1px);
box-shadow: var(--shadow-md);
}
@media (max-width: 768px) {
.auth-layout { padding: 10px; }
.auth-container { border-radius: 16px; }
.form-section { padding: 30px 20px; }
.contact-card { padding: 18px; gap: 12px; }
}
</style>