| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- <template>
- <div class="login-root">
- <div class="bg-image" v-if="!ui.loginBgVideo"></div>
- <video v-if="ui.loginBgVideo" class="bg-video" autoplay muted loop playsinline poster="@/assets/login/login-bg.jpg">
- <source src="@/assets/login/login-bg.mp4" type="video/mp4" />
- </video>
- <header class="top-bar">
- <img class="kyland-logo" :src="brand.logo" :alt="brand.title" />
- <div class="top-right-actions">
- <FullscreenToggle />
- </div>
- </header>
- <div class="main-content">
- <div class="left-panel">
- <div class="login-box">
- <div class="title-wrap">
- <img v-if="!brand.loginTitle" class="title-img" :src="brand.loginTitle" :alt="brand.title" />
- <div v-else class="title-text glow-text">{{ brand.title }}</div>
- </div>
- <LoginForm @login-success="onLoginSuccess" />
- </div>
- </div>
- <div class="right-panel"></div>
- </div>
- <footer class="copyright">{{ brand.company }}</footer>
- </div>
- </template>
- <script>
- import LoginForm from "@/components/ui/LoginForm.vue";
- import FullscreenToggle from "@/components/ui/FullscreenToggle.vue";
- import brand, { ui } from "@/utils/brand";
- // webpack 解析为带 hash 的真实 URL,用于在登录页预取主页背景视频
- import mainBgVideo from "@/assets/main/main-bg.mp4";
- export default {
- name: "LoginPage",
- components: { LoginForm, FullscreenToggle },
- data() {
- return {
- brand,
- ui,
- };
- },
- mounted() {
- this.prefetchMainBgVideo();
- },
- methods: {
- onLoginSuccess() {
- this.$router.push('/main').catch(() => {});
- },
- // Login→Main 为固定路径,提前预取主页背景视频,进入主页时即命中缓存。
- // 仅在主页视频开启时预取,避免为关闭视频的部署浪费带宽。
- prefetchMainBgVideo() {
- if (!this.ui.mainBgVideo || !mainBgVideo) return;
- const link = document.createElement("link");
- link.rel = "prefetch";
- link.as = "video";
- link.href = mainBgVideo;
- document.head.appendChild(link);
- },
- },
- };
- </script>
- <style scoped>
- .login-root {
- width: 100vw;
- height: 100vh;
- position: relative;
- overflow: hidden;
- background: #050a17;
- display: flex;
- flex-direction: column;
- }
- .bg-image {
- position: absolute;
- inset: 0;
- background: url('@/assets/login/login-bg.jpg') no-repeat center / cover;
- z-index: 0;
- }
- .bg-video {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 100%;
- height: 100%;
- object-fit: cover;
- z-index: 1;
- }
- .top-bar {
- position: relative;
- z-index: 2;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 10vh;
- flex-shrink: 0;
- }
- .kyland-logo {
- height: clamp(30px, 5vh, 56px);
- width: auto;
- }
- .top-right-actions {
- position: absolute;
- top: 50%;
- right: 50px;
- transform: translateY(-50%);
- display: flex;
- align-items: center;
- gap: 12px;
- }
- .main-content {
- position: relative;
- z-index: 2;
- flex: 1;
- display: grid;
- grid-template-columns: 45fr 55fr;
- align-items: center;
- padding: 0 8vw;
- min-height: 0;
- }
- .left-panel {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- .login-box {
- width: 566px;
- background: transparent;
- border: none;
- box-shadow: none;
- padding: 0;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- }
- .title-wrap {
- display: flex;
- align-items: center;
- margin-bottom: 22px;
- flex-shrink: 0;
- }
- .title-img {
- width: auto;
- max-width: 100%;
- }
- .title-text {
- font-family: var(--title-font-family);
- font-size: 48px;
- color: #ffffff;
- line-height: 63px;
- text-align: center;
- font-style: normal;
- text-transform: none;
- white-space: nowrap;
- }
- .right-panel {
- height: 100%;
- }
- .copyright {
- position: relative;
- z-index: 2;
- text-align: center;
- color: rgba(255, 255, 255, 0.85);
- font-size: clamp(12px, 1vw, 18px);
- padding-bottom: clamp(10px, 1.8vh, 22px);
- flex-shrink: 0;
- text-shadow: 0 0 8px rgba(0, 150, 255, 0.6), 0 1px 3px rgba(0, 0, 0, 0.8);
- letter-spacing: 1px;
- }
- :fullscreen .login-root .top-bar {
- height: 14vh;
- }
- </style>
|