站长要求全站一致(小程序端已单独提交)。本次只改**用户可见文案与默认值**: - 服务端默认值/兜底:system-settings-defaults、admin/system-settings(GET/POST)、 site-config.get、utils/siteUtils —— 原来是 'VoiceHub' / '校园广播站点歌系统' - 用户可见通知文案:MeoW 绑定验证码与标题、MeoW 测试通知、微信订阅测试通知 - 2FA 应用名(authenticator.keyuri)、WebAuthn rpName(出现在系统密钥弹窗里) - 网页版界面:首页副标题、后台侧栏品牌名、登录/注册/找回/改密标题与文案、 年度回顾(IntroSlide / ShareCard / 页面标题)、用户教程、通知发送预览、 API 密钥与数据库导入说明、酷狗 sidecar 说明、打印页脚与歌单卡片页脚、Logo alt **刻意不动**:localStorage/sessionStorage 的 `voicehub_*` 键、`voicehub:` 前缀的 STORAGE_KEY 与缓存/Redis 前缀、`window.voiceHubPlayer` 之类代码标识、MeoW 的 User-Agent、以及上游项目链接 `github.com/laoshuikaixue/VoiceHub`(那是对原项目的署名)。 注意:站点名**数据**(systemSettings.siteTitle)仍是你后台里设置的「宝一外校园点歌」, 代码只保证默认值与文案一致;要让全站显示完整名称,请在后台「站点配置 → 站点标题」 改成「宝一外校园点歌系统」。
270 lines
6.0 KiB
Vue
270 lines
6.0 KiB
Vue
<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">宝一外校园点歌系统</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>
|