mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-04 23:18:44 +08:00
优化登录页面,添加登录按钮的加载状态管理,确保用户体验流畅。
This commit is contained in:
+2
-25
@@ -17,9 +17,6 @@ globalTheme.name.value = themeValue === 'auto' ? autoTheme : themeValue
|
|||||||
const localeValue = getBrowserLocale()
|
const localeValue = getBrowserLocale()
|
||||||
setI18nLanguage(localeValue as SupportedLocale)
|
setI18nLanguage(localeValue as SupportedLocale)
|
||||||
|
|
||||||
// 从 provide 中获取全局设置
|
|
||||||
const globalSettings: any = inject('globalSettings')
|
|
||||||
|
|
||||||
// 显示状态
|
// 显示状态
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
|
|
||||||
@@ -30,16 +27,6 @@ const isLogin = computed(() => authStore.token)
|
|||||||
// 生成背景图片key
|
// 生成背景图片key
|
||||||
const loginStateKey = computed(() => (isLogin.value ? 'logged-in' : 'logged-out'))
|
const loginStateKey = computed(() => (isLogin.value ? 'logged-in' : 'logged-out'))
|
||||||
|
|
||||||
// 监听登录状态变化
|
|
||||||
watch(isLogin, newValue => {
|
|
||||||
if (newValue) {
|
|
||||||
// 登录后先清空背景图片数组,强制视图更新
|
|
||||||
backgroundImages.value = []
|
|
||||||
// 然后重新加载背景图片
|
|
||||||
fetchBackgroundImages().then(() => startBackgroundRotation())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 背景图片
|
// 背景图片
|
||||||
const backgroundImages = ref<string[]>([])
|
const backgroundImages = ref<string[]>([])
|
||||||
const activeImageIndex = ref(0)
|
const activeImageIndex = ref(0)
|
||||||
@@ -117,7 +104,6 @@ function startBackgroundRotation() {
|
|||||||
function preloadImage(url: string): Promise<boolean> {
|
function preloadImage(url: string): Promise<boolean> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
const imageUrl = getImgUrl(url)
|
|
||||||
|
|
||||||
img.onload = () => resolve(true)
|
img.onload = () => resolve(true)
|
||||||
img.onerror = () => resolve(false)
|
img.onerror = () => resolve(false)
|
||||||
@@ -128,7 +114,7 @@ function preloadImage(url: string): Promise<boolean> {
|
|||||||
resolve(false)
|
resolve(false)
|
||||||
}, 5000) // 5秒超时
|
}, 5000) // 5秒超时
|
||||||
|
|
||||||
img.src = imageUrl
|
img.src = url
|
||||||
|
|
||||||
// 如果图片已经缓存,onload可能不会触发
|
// 如果图片已经缓存,onload可能不会触发
|
||||||
if (img.complete) {
|
if (img.complete) {
|
||||||
@@ -138,15 +124,6 @@ function preloadImage(url: string): Promise<boolean> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算图片地址
|
|
||||||
function getImgUrl(url: string) {
|
|
||||||
// 使用图片缓存
|
|
||||||
if (globalSettings.GLOBAL_IMAGE_CACHE && isLogin.value) {
|
|
||||||
return `${import.meta.env.VITE_API_BASE_URL}system/cache/image?url=${encodeURIComponent(url)}`
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加logo动画效果并延迟移除加载界面
|
// 添加logo动画效果并延迟移除加载界面
|
||||||
function animateAndRemoveLoader() {
|
function animateAndRemoveLoader() {
|
||||||
const loadingBg = document.querySelector('#loading-bg') as HTMLElement
|
const loadingBg = document.querySelector('#loading-bg') as HTMLElement
|
||||||
@@ -238,7 +215,7 @@ onUnmounted(() => {
|
|||||||
:key="`bg-${index}-${loginStateKey}`"
|
:key="`bg-${index}-${loginStateKey}`"
|
||||||
class="background-image"
|
class="background-image"
|
||||||
:class="{ 'active': index === activeImageIndex }"
|
:class="{ 'active': index === activeImageIndex }"
|
||||||
:style="{ backgroundImage: `url(${getImgUrl(imageUrl)})` }"
|
:style="{ 'backgroundImage': `url(${imageUrl})` }"
|
||||||
></div>
|
></div>
|
||||||
<!-- 全局磨砂层 -->
|
<!-- 全局磨砂层 -->
|
||||||
<div v-if="isLogin && isTransparentTheme" class="global-blur-layer"></div>
|
<div v-if="isLogin && isTransparentTheme" class="global-blur-layer"></div>
|
||||||
|
|||||||
+14
-1
@@ -48,6 +48,9 @@ const currentLocale = ref(getCurrentLocale())
|
|||||||
// 可用的语言列表
|
// 可用的语言列表
|
||||||
const locales = Object.values(SUPPORTED_LOCALES)
|
const locales = Object.values(SUPPORTED_LOCALES)
|
||||||
|
|
||||||
|
// 登录按钮 loading
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
// 切换语言
|
// 切换语言
|
||||||
async function switchLanguage(locale: SupportedLocale) {
|
async function switchLanguage(locale: SupportedLocale) {
|
||||||
await setI18nLanguage(locale)
|
await setI18nLanguage(locale)
|
||||||
@@ -103,6 +106,8 @@ async function afterLogin(superuser: boolean) {
|
|||||||
router.push(authStore.originalPath ?? '/')
|
router.push(authStore.originalPath ?? '/')
|
||||||
// 订阅推送通知
|
// 订阅推送通知
|
||||||
if (superuser) await subscribeForPushNotifications()
|
if (superuser) await subscribeForPushNotifications()
|
||||||
|
// 登录按钮 loading
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登录获取token事件
|
// 登录获取token事件
|
||||||
@@ -113,6 +118,10 @@ function login() {
|
|||||||
if (!form.value.username || !form.value.password || (isOTP.value && !form.value.otp_password)) {
|
if (!form.value.username || !form.value.password || (isOTP.value && !form.value.otp_password)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 登录按钮 loading
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
// 用户名密码
|
// 用户名密码
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
|
|
||||||
@@ -155,6 +164,8 @@ function login() {
|
|||||||
else if (error.response.status === 403) errorMessage.value = t('login.permissionDenied')
|
else if (error.response.status === 403) errorMessage.value = t('login.permissionDenied')
|
||||||
else if (error.response.status === 500) errorMessage.value = t('login.serverError')
|
else if (error.response.status === 500) errorMessage.value = t('login.serverError')
|
||||||
else errorMessage.value = `${t('login.loginFailed')} ${error.response.status},${t('login.checkCredentials')}`
|
else errorMessage.value = `${t('login.loginFailed')} ${error.response.status},${t('login.checkCredentials')}`
|
||||||
|
// 登录按钮 loading
|
||||||
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +263,9 @@ onMounted(async () => {
|
|||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<!-- login button -->
|
<!-- login button -->
|
||||||
<VBtn block type="submit" @click="login" prepend-icon="mdi-login"> {{ t('login.login') }} </VBtn>
|
<VBtn block type="submit" @click="login" prepend-icon="mdi-login" :loading="loading">
|
||||||
|
{{ t('login.login') }}
|
||||||
|
</VBtn>
|
||||||
<VAlert v-if="errorMessage" type="error" variant="tonal" class="mt-3">
|
<VAlert v-if="errorMessage" type="error" variant="tonal" class="mt-3">
|
||||||
{{ errorMessage }}
|
{{ errorMessage }}
|
||||||
</VAlert>
|
</VAlert>
|
||||||
|
|||||||
Reference in New Issue
Block a user