feat: 添加登录页系统维护升级提示,暂时关闭登录入口

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
mzl
2026-04-27 10:21:47 +08:00
parent 3f0f5334e8
commit 08eab43034
8 changed files with 104 additions and 5 deletions
+6 -1
View File
@@ -186,5 +186,10 @@
"lastMonth": "Last Month", "lastMonth": "Last Month",
"thisYear": "This Year", "thisYear": "This Year",
"lastYear": "Last Year" "lastYear": "Last Year"
},
"maintenance": {
"title": "System Upgrade",
"message": "The system is under maintenance. Expected to resume at 23:59 tonight. Please wait patiently.",
"estimatedTime": "Estimated recovery: 23:59 tonight"
} }
} }
+6 -1
View File
@@ -161,5 +161,10 @@
"lastMonth": "Mes Pasado", "lastMonth": "Mes Pasado",
"thisYear": "Este Año", "thisYear": "Este Año",
"lastYear": "Año Pasado" "lastYear": "Año Pasado"
},
"maintenance": {
"title": "Actualización del sistema",
"message": "El sistema está en mantenimiento. Se espera que se reanude a las 23:59 de esta noche. Por favor, espere pacientemente.",
"estimatedTime": "Hora estimada de recuperación: 23:59 esta noche"
} }
} }
+6 -1
View File
@@ -161,5 +161,10 @@
"lastMonth": "Mois Dernier", "lastMonth": "Mois Dernier",
"thisYear": "Cette Année", "thisYear": "Cette Année",
"lastYear": "Année Dernière" "lastYear": "Année Dernière"
},
"maintenance": {
"title": "Mise à jour du système",
"message": "Le système est en maintenance. Reprise prévue à 23h59 ce soir. Veuillez patienter.",
"estimatedTime": "Heure de reprise estimée : 23h59 ce soir"
} }
} }
+6 -1
View File
@@ -161,5 +161,10 @@
"lastMonth": "В прошлом месяце", "lastMonth": "В прошлом месяце",
"thisYear": "В этом году", "thisYear": "В этом году",
"lastYear": "В прошлом году" "lastYear": "В прошлом году"
},
"maintenance": {
"title": "Обновление системы",
"message": "Система находится на техническом обслуживании. Ожидаемое восстановление в 23:59 сегодня. Пожалуйста, подождите.",
"estimatedTime": "Ожидаемое восстановление: сегодня 23:59"
} }
} }
+6 -1
View File
@@ -186,5 +186,10 @@
"lastMonth": "上月", "lastMonth": "上月",
"thisYear": "今年", "thisYear": "今年",
"lastYear": "去年" "lastYear": "去年"
},
"maintenance": {
"title": "系统升级中",
"message": "系统维护升级中,预计今晚 23:59 恢复,请耐心等待",
"estimatedTime": "预计恢复时间:今晚 23:59"
} }
} }
+19
View File
@@ -1,16 +1,35 @@
import { useState } from 'react' import { useState } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { Button, Input, Toast } from 'antd-mobile' import { Button, Input, Toast } from 'antd-mobile'
import { useTranslation } from 'react-i18next'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import loginStyles from '../login/login.module.css'
import styles from './login-simple.module.css' import styles from './login-simple.module.css'
// 维护模式开关 - 恢复时改为 false 重新部署即可
const MAINTENANCE_MODE = true
export default function SimpleLogin() { export default function SimpleLogin() {
const { t } = useTranslation()
const navigate = useNavigate() const navigate = useNavigate()
const { login } = useUserStore() const { login } = useUserStore()
const [username, setUsername] = useState('') const [username, setUsername] = useState('')
const [password, setPassword] = useState('') const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
if (MAINTENANCE_MODE) {
return (
<div className={loginStyles.login}>
<div className={loginStyles.maintenanceContainer}>
<div className={loginStyles.maintenanceIcon}>🔧</div>
<h1 className={loginStyles.maintenanceTitle}>{t('maintenance.title')}</h1>
<p className={loginStyles.maintenanceMessage}>{t('maintenance.message')}</p>
<p className={loginStyles.maintenanceTime}>{t('maintenance.estimatedTime')}</p>
</div>
</div>
)
}
const handleLogin = async () => { const handleLogin = async () => {
if (!username || !password) { if (!username || !password) {
Toast.show('请输入用户名和密码') Toast.show('请输入用户名和密码')
+18
View File
@@ -1,10 +1,14 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { Toast } from 'antd-mobile' import { Toast } from 'antd-mobile'
import { useTranslation } from 'react-i18next'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import QRCodeLogin from './QRCodeLogin' import QRCodeLogin from './QRCodeLogin'
import styles from './login.module.css' import styles from './login.module.css'
// 维护模式开关 - 恢复时改为 false 重新部署即可
const MAINTENANCE_MODE = true
// 声明飞书 JSAPI 类型 // 声明飞书 JSAPI 类型
declare global { declare global {
interface Window { interface Window {
@@ -16,6 +20,7 @@ declare global {
} }
export default function Login() { export default function Login() {
const { t } = useTranslation()
const navigate = useNavigate() const navigate = useNavigate()
const { login } = useUserStore() const { login } = useUserStore()
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
@@ -23,6 +28,19 @@ export default function Login() {
const [showQRCode, setShowQRCode] = useState(false) const [showQRCode, setShowQRCode] = useState(false)
const [shouldSkipAutoLogin, setShouldSkipAutoLogin] = useState(false) // 防止重复执行免登 const [shouldSkipAutoLogin, setShouldSkipAutoLogin] = useState(false) // 防止重复执行免登
if (MAINTENANCE_MODE) {
return (
<div className={styles.login}>
<div className={styles.maintenanceContainer}>
<div className={styles.maintenanceIcon}>🔧</div>
<h1 className={styles.maintenanceTitle}>{t('maintenance.title')}</h1>
<p className={styles.maintenanceMessage}>{t('maintenance.message')}</p>
<p className={styles.maintenanceTime}>{t('maintenance.estimatedTime')}</p>
</div>
</div>
)
}
// 检查登录状态 // 检查登录状态
useEffect(() => { useEffect(() => {
const urlParams = new URLSearchParams(window.location.search) const urlParams = new URLSearchParams(window.location.search)
+37
View File
@@ -102,3 +102,40 @@
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
.maintenanceContainer {
text-align: center;
padding: 40px 30px;
max-width: 360px;
}
.maintenanceIcon {
font-size: 64px;
margin-bottom: 24px;
animation: bounce 2s ease-in-out infinite;
}
.maintenanceTitle {
color: #fff;
font-size: 24px;
font-weight: 600;
margin: 0 0 16px 0;
}
.maintenanceMessage {
color: rgba(255, 255, 255, 0.9);
font-size: 16px;
line-height: 1.6;
margin: 0 0 12px 0;
}
.maintenanceTime {
color: rgba(255, 255, 255, 0.7);
font-size: 14px;
margin: 0;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}