|
|
@@ -0,0 +1,62 @@
|
|
|
+<template>
|
|
|
+ <main class="qsfl-login-page">
|
|
|
+ <div class="login-glow glow-blue"></div>
|
|
|
+ <div class="login-glow glow-red"></div>
|
|
|
+ <section class="login-card" aria-live="polite">
|
|
|
+ <span class="login-orbit orbit-one"></span>
|
|
|
+ <span class="login-orbit orbit-two"></span>
|
|
|
+ <div class="login-mark">AI</div>
|
|
|
+ <h1>AI 智能问答</h1>
|
|
|
+ <p>{{ statusText }}</p>
|
|
|
+ <div v-if="isLoading" class="loading-line"><i></i><i></i><i></i></div>
|
|
|
+ <button v-else type="button" @click="startLogin">重新进入</button>
|
|
|
+ </section>
|
|
|
+ </main>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { onMounted, ref } from 'vue'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+import { autoLogin } from '@/utils/loginUtils.js'
|
|
|
+
|
|
|
+// 强生菲林 AI 问答专用的固定登录配置。
|
|
|
+const QSFL_LOGIN_CONFIG = Object.freeze({
|
|
|
+ tenantName: import.meta.env.VITE_APP_TITLE,
|
|
|
+ username: 'test',
|
|
|
+ password: 'test',
|
|
|
+ redirectPath: '/ai-qa'
|
|
|
+})
|
|
|
+
|
|
|
+const router = useRouter()
|
|
|
+const isLoading = ref(false)
|
|
|
+const statusText = ref('正在验证访问权限…')
|
|
|
+
|
|
|
+const startLogin = async () => {
|
|
|
+ if (isLoading.value) return
|
|
|
+ isLoading.value = true
|
|
|
+ statusText.value = '正在安全登录…'
|
|
|
+ const success = await autoLogin(
|
|
|
+ QSFL_LOGIN_CONFIG.tenantName,
|
|
|
+ QSFL_LOGIN_CONFIG.username,
|
|
|
+ QSFL_LOGIN_CONFIG.password,
|
|
|
+ router,
|
|
|
+ QSFL_LOGIN_CONFIG.redirectPath
|
|
|
+ )
|
|
|
+ if (!success) {
|
|
|
+ statusText.value = '登录失败,请稍后重试'
|
|
|
+ isLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(startLogin)
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.qsfl-login-page { position: fixed; inset: 0; display: grid; place-items: center; overflow: hidden; color: #edf4ff; background: radial-gradient(circle at 50% 20%, #183c79, #071a41 52%, #020a1d 100%); }
|
|
|
+.login-glow { position: absolute; pointer-events: none; filter: blur(35px); }.glow-blue { width: 45vw; height: 45vw; top: -28vw; right: -8vw; border-radius: 50%; background: rgba(87, 150, 255, .29); }.glow-red { width: 42vw; height: 60vw; bottom: -40vw; left: -17vw; background: rgba(214, 35, 57, .38); transform: rotate(-35deg); }
|
|
|
+.login-card { position: relative; display: flex; width: min(360px, calc(100vw - 48px)); min-height: 260px; align-items: center; flex-direction: column; justify-content: center; overflow: hidden; border: 1px solid rgba(190, 215, 255, .25); border-radius: 22px; background: rgba(7, 25, 60, .65); box-shadow: 0 28px 80px rgba(0, 0, 0, .32), inset 0 1px rgba(255, 255, 255, .12); backdrop-filter: blur(18px); }
|
|
|
+.login-mark { position: relative; z-index: 1; display: grid; width: 58px; height: 58px; margin-bottom: 19px; place-items: center; border: 1px solid rgba(225, 236, 255, .5); border-radius: 17px; background: linear-gradient(135deg, #e33a4a, #3f82dc); box-shadow: 0 10px 28px rgba(58, 128, 225, .3); font-size: 21px; font-weight: 700; letter-spacing: .06em; }
|
|
|
+h1, p, button { position: relative; z-index: 1; }h1 { margin: 0; font-size: 24px; font-weight: 600; letter-spacing: .03em; }p { margin: 11px 0 0; color: rgba(222, 234, 255, .7); font-size: 14px; }button { margin-top: 20px; padding: 8px 15px; border: 1px solid rgba(201, 221, 255, .32); border-radius: 8px; color: #eff5ff; background: rgba(255,255,255,.08); cursor: pointer; }
|
|
|
+.loading-line { position: relative; z-index: 1; display: flex; gap: 6px; margin-top: 24px; }.loading-line i { width: 6px; height: 6px; border-radius: 50%; background: #a6c9ff; animation: loading-dot 1s ease-in-out infinite; }.loading-line i:nth-child(2) { animation-delay: .15s; }.loading-line i:nth-child(3) { animation-delay: .3s; }.login-orbit { position: absolute; width: 180px; height: 180px; border: 1px solid rgba(127, 173, 250, .15); border-radius: 50%; }.orbit-one { top: -112px; right: -80px; }.orbit-two { bottom: -120px; left: -95px; border-style: dashed; animation: orbit 15s linear infinite; }
|
|
|
+@keyframes loading-dot { 50% { transform: translateY(-5px); opacity: .4; } } @keyframes orbit { to { transform: rotate(360deg); } }
|
|
|
+</style>
|