Browse Source

登录界面

ith5 3 tháng trước cách đây
mục cha
commit
9bd7814ba2
4 tập tin đã thay đổi với 780 bổ sung250 xóa
  1. 2 2
      index.html
  2. 1 1
      src/router/webRouter.js
  3. 408 247
      src/views/login.vue
  4. 369 0
      src/views/login2.vue

+ 2 - 2
index.html

@@ -151,7 +151,7 @@
       <strong>你的浏览器未开启javascript支持,请开启后刷新页面访问!</strong>
     </noscript>
     <div id="app" class="ma-ui">
-      <div class="preload__wrap" id="Loading">
+      <!-- <div class="preload__wrap" id="Loading">
         <div class="preload__container">
           <p class="preload__name">%VITE_APP_TITLE%</p>
           <div class="preload__loading"></div>
@@ -160,7 +160,7 @@
             初次加载资源可能需要较多时间 请耐心等待
           </p>
         </div>
-      </div>
+      </div> -->
     </div>
     <script type="module" src="/src/main.js"></script>
   </body>

+ 1 - 1
src/router/webRouter.js

@@ -11,7 +11,7 @@ const routes = [
   {
     name: "login",
     path: "/login",
-    component: () => import("@/views/login.vue"),
+    component: () => import("@/views/login2.vue"),
     meta: { title: "登录" },
   },
   {

+ 408 - 247
src/views/login.vue

@@ -1,316 +1,477 @@
 <script setup>
-import { reactive, ref } from 'vue'
-import loginApi from '@/api/login'
-import { useUserStore } from '@/store'
-import { useRouter, useRoute } from 'vue-router'
-import packageJson from '../../package.json'
-import { useAppStore } from '@/store'
-import commonApi from '@/views/v1/api/common'
-
-const appStore = useAppStore()
-const router = useRouter()
-const route = useRoute()
-const captcha = ref(null)
-const title = ref('')
-
-const loading = ref(false)
-
-let isDevelop = import.meta.env.VITE_APP_ENV === 'development'
-
-var odata = isDevelop ? { username: 'admin', password: '123456', code: '' } : { username: '', password: '', code: '' }
-
-const form = reactive(odata)
-
+import { reactive, ref } from "vue";
+import loginApi from "@/api/login";
+import { useUserStore } from "@/store";
+import { useRouter, useRoute } from "vue-router";
+import packageJson from "../../package.json";
+import commonApi from "@/views/v1/api/common";
+
+const router = useRouter();
+const route = useRoute();
+const loading = ref(false);
+const title = ref("");
+const captcha = ref(null);
+
+let isDevelop = import.meta.env.VITE_APP_ENV === "development";
+
+const form = reactive({
+  username: isDevelop ? "admin" : "",
+  password: isDevelop ? "123456" : "",
+  code: "",
+  uuid: "",
+});
+
+const userStore = useUserStore();
+const redirect = route.query.redirect ? route.query.redirect : "/";
+
+// 刷新验证码
 const refreshCaptcha = () => {
-  form.code = ''
-  form.uuid = ''
+  form.code = "";
+  form.uuid = "";
   loginApi.getCaptch().then((res) => {
     if (res.code === 200) {
-      captcha.value = res.data.image
-      form.uuid = res.data.uuid
+      captcha.value = res.data.image;
+      form.uuid = res.data.uuid;
     }
-  })
-}
-
-refreshCaptcha()
+  });
+};
 
-const userStore = useUserStore()
+// 初始化验证码
+refreshCaptcha();
 
 // 获取系统配置
 const getSystemConfig = async () => {
-  const { data } = await commonApi.getSystemConfigApi({
-    group_code: 'site_config',
-    key: 'site_name',
-  })
-  title.value = data.value
-}
-
-getSystemConfig()
+  try {
+    const { data } = await commonApi.getSystemConfigApi({
+      group_code: "site_config",
+      key: "site_name",
+    });
+    title.value = data.value || "科技管理系统";
+  } catch (error) {
+    title.value = "科技管理系统";
+  }
+};
 
-const redirect = route.query.redirect ? route.query.redirect : '/'
+getSystemConfig();
 
+// 登录提交
 const handleSubmit = async ({ values, errors }) => {
-  if (loading.value) {
-    return
-  }
-  loading.value = true
+  if (loading.value) return;
+
   if (!errors) {
-    const result = await userStore.login(form)
+    loading.value = true;
+    const result = await userStore.login(form);
+
     if (!result) {
-      loading.value = false
-      refreshCaptcha()
-      return
+      loading.value = false;
+      refreshCaptcha();
+      return;
     }
-    router.push(redirect)
+
+    router.push(redirect);
+    loading.value = false;
   }
-  loading.value = false
-}
+};
 </script>
+
 <template>
-  <div class="login-container" :style="{ background: appStore.mode === 'dark' ? '#2e2e30e3' : '' }">
-    <h3 class="login-logo">
-      <!-- <img src="/logo.png" alt="logo" />
-      <span>{{ $title }}</span> -->
-    </h3>
-
-    <div class="login-width md:w-10/12 w-11/12 mx-auto flex justify-between h-full items-center">
-      <div class="w-6/12 mx-auto left-panel rounded-l pl-5 pr-5 hidden md:block">
-        <div class="logo">
-          <span>{{ title }} v{{ packageJson.version }}</span>
-        </div>
-        <div class="slogan flex justify-end">
-          <!-- <span>---- {{ $t('sys.login.slogan') }}</span> -->
+  <div class="login-container">
+    <!-- 背景装饰 -->
+    <div class="decoration decoration-1"></div>
+    <div class="decoration decoration-2"></div>
+    <div class="shape shape-1"></div>
+    <div class="shape shape-2"></div>
+    <div class="shape shape-3"></div>
+
+    <div class="container">
+      <!-- 右侧登录区 -->
+      <div class="login-section">
+        <div class="login-form">
+          <div class="logo">
+            <h1>系统登录</h1>
+            <div>欢迎回来,请登录您的账号</div>
+          </div>
+
+          <a-form :model="form" @submit="handleSubmit" layout="vertical">
+            <a-form-item
+              field="username"
+              :hide-label="true"
+              :rules="[{ required: true, message: '请输入用户名或邮箱' }]"
+            >
+              <a-input
+                v-model="form.username"
+                placeholder="用户名或邮箱"
+                size="large"
+                allow-clear
+              >
+                <template #prefix>
+                  <icon-user />
+                </template>
+              </a-input>
+            </a-form-item>
+
+            <a-form-item
+              field="password"
+              :hide-label="true"
+              :rules="[{ required: true, message: '请输入密码' }]"
+            >
+              <a-input-password
+                v-model="form.password"
+                placeholder="密码"
+                size="large"
+                allow-clear
+              >
+                <template #prefix>
+                  <icon-lock />
+                </template>
+              </a-input-password>
+            </a-form-item>
+
+            <a-form-item
+              field="code"
+              :hide-label="true"
+              :rules="[
+                {
+                  required: true,
+                  match: /^[a-zA-Z0-9]{4}$/,
+                  message: '请输入4位验证码',
+                },
+              ]"
+            >
+              <a-input
+                v-model="form.code"
+                placeholder="请输入验证码"
+                size="large"
+                allow-clear
+              >
+                <template #prefix>
+                  <icon-safe />
+                </template>
+                <template #append>
+                  <img
+                    :src="captcha"
+                    class="captcha-image"
+                    @click="refreshCaptcha"
+                  />
+                </template>
+              </a-input>
+            </a-form-item>
+
+            <a-form-item :hide-label="true">
+              <a-button
+                html-type="submit"
+                type="primary"
+                size="large"
+                long
+                :loading="loading"
+                class="login-btn"
+              >
+                登 录
+              </a-button>
+            </a-form-item>
+          </a-form>
         </div>
       </div>
-
-      <div class="md:w-6/12 w-11/12 md:rounded-r mx-auto pl-5 pr-5 pb-10">
-        <h2 class="mt-10 text-3xl pb-0 mb-10 login-title">
-          {{ $t('sys.login.title') }}
-        </h2>
-        <a-form :model="form" @submit="handleSubmit">
-          <a-form-item
-            field="username"
-            :hide-label="true"
-            :rules="[{ required: true, message: $t('sys.login.usernameNotice') }]">
-            <a-input
-              v-model="form.username"
-              class="w-full"
-              size="large"
-              :placeholder="$t('sys.login.username')"
-              allow-clear>
-              <template #prefix><icon-user /></template>
-            </a-input>
-          </a-form-item>
-
-          <a-form-item
-            field="password"
-            :hide-label="true"
-            :rules="[{ required: true, message: $t('sys.login.passwordNotice') }]">
-            <a-input-password v-model="form.password" :placeholder="$t('sys.login.password')" size="large" allow-clear>
-              <template #prefix><icon-lock /></template>
-            </a-input-password>
-          </a-form-item>
-
-          <a-form-item
-            field="code"
-            :hide-label="true"
-            :rules="[
-              {
-                required: true,
-                match: /^[a-zA-Z0-9]{4}$/,
-                message: $t('sys.login.verifyCodeNotice'),
-              },
-            ]">
-            <a-input v-model="form.code" :placeholder="$t('sys.login.verifyCode')" size="large" allow-clear>
-              <template #prefix><icon-safe /></template>
-              <template #append>
-                <img :src="captcha" style="height: 120px; height: 36px; cursor: pointer" @click="refreshCaptcha" />
-              </template>
-            </a-input>
-          </a-form-item>
-
-          <a-form-item :hide-label="true" class="mt-5">
-            <a-button html-type="submit" type="primary" long size="large" :loading="loading">
-              {{ $t('sys.login.loginBtn') }}
-            </a-button>
-          </a-form-item>
-
-          <!-- <a-divider orientation="center">{{
-            $t("sys.login.otherLoginType")
-          }}</a-divider>
-          <div class="flex w-3/4 pt-2 mx-auto items-stretch justify-around">
-            <a-avatar class="other-login wechat"><icon-wechat /></a-avatar>
-            <a-avatar class="other-login alipay"
-              ><icon-alipay-circle
-            /></a-avatar>
-            <a-avatar class="other-login qq"><icon-qq /></a-avatar>
-            <a-avatar class="other-login weibo"><icon-weibo /></a-avatar>
-          </div> -->
-        </a-form>
-      </div>
-    </div>
-
-    <div class="login-bg">
-      <div class="fly bg-fly-circle1"></div>
-      <div class="fly bg-fly-circle2"></div>
-      <div class="fly bg-fly-circle3"></div>
-      <div class="fly bg-fly-circle4"></div>
     </div>
   </div>
 </template>
 
 <style scoped lang="less">
 .login-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #6c5ce7 0%, #8e44ad 100%);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 20px;
+  position: relative;
+  overflow: hidden;
+}
+
+.container {
   width: 100%;
-  height: 100%;
-  position: absolute;
-  background: rgb(145 185 233 / 50%);
-  background-size: cover;
-  z-index: 3;
-
-  .login-logo {
-    width: 100%;
-    height: 80px;
-    font-weight: 700;
-    font-size: 20px;
-    line-height: 32px;
-    display: flex;
-    padding: 0 20px;
-    align-items: center;
-    color: var(--color-text-1);
-
-    img {
-      width: 45px;
-      height: 45px;
-      margin-right: 10px;
-    }
-  }
+  max-width: 500px;
+  background: #fff;
+  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
+  border-radius: 12px;
+  overflow: hidden;
+  display: flex;
+  position: relative;
+  z-index: 2;
+}
 
-  .login-width {
-    max-width: 950px;
-    background-color: var(--color-bg-3);
-    padding: 10px;
-    height: 500px;
-    position: relative;
-    top: 40%;
-    margin-top: -255px;
-    border-radius: 10px;
-    z-index: 999;
-    box-shadow: 0 2px 4px 2px #00000014;
-  }
+.image-section {
+  flex: 1;
+  background: linear-gradient(
+    135deg,
+    rgba(108, 92, 231, 0.9) 0%,
+    rgba(142, 68, 173, 0.85) 100%
+  );
+  color: white;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  padding: 40px;
+  position: relative;
+  overflow: hidden;
+}
 
-  .left-panel {
-    height: 491px;
-    background-image: url(@/assets/login_picture.svg);
-    background-repeat: no-repeat;
-    background-position: center 60px;
-    background-size: contain;
-  }
+.image-content {
+  z-index: 2;
+  text-align: center;
+  max-width: 80%;
+}
 
-  .logo {
-    display: flex;
-    margin-top: 20px;
-    color: #333;
-    span {
-      font-size: 28px;
-      margin-left: 15px;
-      color: rgb(var(--primary-6));
-    }
+.image-content h2 {
+  font-size: 2.5rem;
+  font-weight: 300;
+  margin-bottom: 30px;
+  letter-spacing: 2px;
+  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
+}
+
+.image-content p {
+  font-size: 1.1rem;
+  line-height: 1.6;
+  opacity: 0.9;
+  font-weight: 300;
+  max-width: 400px;
+  margin: 0 auto 30px;
+}
+
+.features {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: center;
+  gap: 20px;
+  margin-top: 40px;
+}
+
+.feature {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  margin: 10px 0;
+  font-size: 0.95rem;
+
+  :deep(.arco-icon) {
+    font-size: 1.2rem;
+    color: rgba(255, 255, 255, 0.9);
   }
-  .slogan {
-    font-size: 16px;
-    line-height: 50px;
-    color: var(--color-text-1);
+}
+
+.graphic-element {
+  margin: 40px 0;
+  display: flex;
+  justify-content: center;
+  gap: 15px;
+}
+
+.circle {
+  width: 70px;
+  height: 70px;
+  border-radius: 50%;
+  background: rgba(255, 255, 255, 0.15);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  backdrop-filter: blur(5px);
+  border: 1px solid rgba(255, 255, 255, 0.2);
+
+  :deep(.arco-icon) {
+    font-size: 28px;
+    opacity: 0.9;
   }
+}
+
+.login-section {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  padding: 40px;
+  background: #fff;
+}
 
-  .login-title {
-    color: var(--color-text-1);
+.login-form {
+  width: 100%;
+  max-width: 400px;
+}
+
+.logo {
+  text-align: center;
+  margin-bottom: 50px;
+
+  h1 {
+    font-size: 2.2rem;
+    font-weight: 400;
+    color: #6c5ce7;
+    letter-spacing: 2px;
+    margin-bottom: 10px;
   }
 
-  :deep(.arco-input-append) {
-    padding: 0 !important;
+  p {
+    color: #95a5a6;
+    margin-top: 8px;
+    font-size: 0.95rem;
+    font-weight: 300;
   }
+}
 
-  .other-login {
-    cursor: pointer;
+:deep(.arco-input-wrapper) {
+  border: none;
+  border-bottom: 1px solid #e0e0e0;
+  border-radius: 0;
+  background: transparent;
+  transition: all 0.3s ease;
+
+  &:hover,
+  &.arco-input-focus {
+    border-color: #6c5ce7;
+    background: transparent;
   }
+}
 
-  .qq:hover,
-  .alipay:hover {
-    background: #165dff;
+:deep(.arco-input) {
+  background: transparent;
+}
+
+:deep(.arco-input-wrapper .arco-input-prefix) {
+  color: #95a5a6;
+
+  .arco-icon {
+    font-size: 18px;
   }
-  .wechat:hover {
-    background: #0f9c02;
+}
+
+:deep(.arco-input-wrapper.arco-input-focus .arco-input-prefix) {
+  color: #6c5ce7;
+}
+
+.captcha-image {
+  height: 36px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+  border-radius: 4px;
+
+  &:hover {
+    opacity: 0.8;
   }
+}
+
+:deep(.arco-input-append) {
+  padding: 0 !important;
+}
 
-  .weibo:hover {
-    background: #f3ce2b;
+.login-btn {
+  margin-top: 10px;
+  background: #6c5ce7;
+  border: none;
+  border-radius: 6px;
+  font-weight: 500;
+  letter-spacing: 1px;
+  box-shadow: 0 4px 10px rgba(108, 92, 231, 0.25);
+  transition: all 0.3s ease;
+
+  &:hover {
+    background: #5d4ae0;
+    transform: translateY(-2px);
+    box-shadow: 0 7px 15px rgba(108, 92, 231, 0.35);
   }
 }
 
-.login-bg {
-  width: 100%;
-  overflow: hidden;
+:deep(.arco-form-item) {
+  margin-bottom: 25px;
+}
+
+// 装饰元素
+.decoration {
+  position: absolute;
+  opacity: 0.1;
   z-index: 1;
 }
 
-.fly {
-  pointer-events: none;
-  position: fixed;
-  z-index: 9999;
+.decoration-1 {
+  top: -80px;
+  right: -80px;
+  width: 300px;
+  height: 300px;
+  border-radius: 50%;
+  background: white;
 }
 
-.bg-fly-circle1 {
-  left: 40px;
-  top: 100px;
-  width: 100px;
-  height: 100px;
+.decoration-2 {
+  bottom: -100px;
+  left: -100px;
+  width: 350px;
+  height: 350px;
   border-radius: 50%;
-  background: linear-gradient(to right, rgba(var(--primary-6), 0.07), rgba(var(--primary-6), 0.04));
-  animation: move-ce64e0ea 2.5s linear infinite;
+  background: white;
+}
+
+.shape {
+  position: absolute;
+  background: rgba(255, 255, 255, 0.1);
+  backdrop-filter: blur(5px);
+  border: 1px solid rgba(255, 255, 255, 0.1);
+  z-index: 1;
 }
 
-.bg-fly-circle2 {
+.shape-1 {
+  width: 80px;
+  height: 80px;
+  border-radius: 20px;
+  top: 20%;
   left: 15%;
-  bottom: 5%;
-  width: 150px;
-  height: 150px;
-  border-radius: 50%;
-  background: linear-gradient(to right, rgba(var(--primary-6), 0.08), rgba(var(--primary-6), 0.04));
-  animation: move-ce64e0ea 3s linear infinite;
+  transform: rotate(45deg);
+  animation: float 3s ease-in-out infinite;
 }
 
-.bg-fly-circle3 {
-  right: 12%;
-  top: 90px;
-  width: 145px;
-  height: 145px;
+.shape-2 {
+  width: 100px;
+  height: 100px;
   border-radius: 50%;
-  background: linear-gradient(to right, rgba(var(--primary-6), 0.1), rgba(var(--primary-6), 0.04));
-  animation: move-ce64e0ea 2.5s linear infinite;
+  bottom: 25%;
+  right: 20%;
+  animation: float 4s ease-in-out infinite;
 }
 
-.bg-fly-circle4 {
-  right: 5%;
+.shape-3 {
+  width: 60px;
+  height: 60px;
   top: 60%;
-  width: 160px;
-  height: 160px;
-  border-radius: 50%;
-  background: linear-gradient(to right, rgba(var(--primary-6), 0.02), rgba(var(--primary-6), 0.04));
-  animation: move-ce64e0ea 3.5s linear infinite;
+  left: 25%;
+  transform: rotate(30deg);
+  animation: float 3.5s ease-in-out infinite;
 }
 
-@keyframes move-ce64e0ea {
-  0% {
-    transform: translateY(0) scale(1);
+@keyframes float {
+  0%,
+  100% {
+    transform: translateY(0) rotate(45deg);
   }
-
   50% {
-    transform: translateY(25px) scale(1.1);
+    transform: translateY(-20px) rotate(45deg);
+  }
+}
+
+// 响应式设计
+@media (max-width: 900px) {
+  .container {
+    flex-direction: column;
+    max-width: 500px;
+    min-height: auto;
+  }
+
+  .image-section {
+    padding: 30px;
+    display: none;
   }
 
-  to {
-    transform: translateY(0) scale(1);
+  .login-section {
+    padding: 50px 30px;
   }
 }
 </style>

+ 369 - 0
src/views/login2.vue

@@ -0,0 +1,369 @@
+<script setup>
+import { reactive, ref } from "vue";
+import loginApi from "@/api/login";
+import { useUserStore } from "@/store";
+import { useRouter, useRoute } from "vue-router";
+import packageJson from "../../package.json";
+import { useAppStore } from "@/store";
+import commonApi from "@/views/v1/api/common";
+
+const appStore = useAppStore();
+const router = useRouter();
+const route = useRoute();
+const captcha = ref(null);
+const title = ref("");
+
+const loading = ref(false);
+
+let isDevelop = import.meta.env.VITE_APP_ENV === "development";
+
+var odata = isDevelop
+  ? { username: "admin", password: "123456", code: "" }
+  : { username: "", password: "", code: "" };
+
+const form = reactive(odata);
+
+const refreshCaptcha = () => {
+  form.code = "";
+  form.uuid = "";
+  loginApi.getCaptch().then((res) => {
+    if (res.code === 200) {
+      captcha.value = res.data.image;
+      form.uuid = res.data.uuid;
+    }
+  });
+};
+
+refreshCaptcha();
+
+const userStore = useUserStore();
+
+// 获取系统配置
+const getSystemConfig = async () => {
+  const { data } = await commonApi.getSystemConfigApi({
+    group_code: "site_config",
+    key: "site_name",
+  });
+  title.value = data.value;
+};
+
+getSystemConfig();
+
+const redirect = route.query.redirect ? route.query.redirect : "/";
+
+const handleSubmit = async ({ values, errors }) => {
+  if (loading.value) {
+    return;
+  }
+  loading.value = true;
+  if (!errors) {
+    const result = await userStore.login(form);
+    if (!result) {
+      loading.value = false;
+      refreshCaptcha();
+      return;
+    }
+    router.push(redirect);
+  }
+  loading.value = false;
+};
+</script>
+<template>
+  <div
+    class="login-container"
+    :style="{ background: appStore.mode === 'dark' ? '#2e2e30e3' : '' }"
+  >
+    <h3 class="login-logo">
+      <!-- <img src="/logo.png" alt="logo" />
+      <span>{{ $title }}</span> -->
+    </h3>
+
+    <div
+      class="login-width md:w-10/12 w-11/12 mx-auto flex justify-between h-full items-center"
+    >
+      <div
+        class="w-6/12 mx-auto left-panel rounded-l pl-5 pr-5 hidden md:block"
+      >
+        <div class="logo">
+          <span>{{ title }} v{{ packageJson.version }}</span>
+        </div>
+        <div class="slogan flex justify-end">
+          <!-- <span>---- {{ $t('sys.login.slogan') }}</span> -->
+        </div>
+      </div>
+
+      <div class="md:w-6/12 w-11/12 md:rounded-r mx-auto pl-5 pr-5 pb-10">
+        <h2 class="mt-10 text-3xl pb-0 mb-10 login-title">
+          {{ $t("sys.login.title") }}
+        </h2>
+        <a-form :model="form" @submit="handleSubmit">
+          <a-form-item
+            field="username"
+            :hide-label="true"
+            :rules="[
+              { required: true, message: $t('sys.login.usernameNotice') },
+            ]"
+          >
+            <a-input
+              v-model="form.username"
+              class="w-full"
+              size="large"
+              :placeholder="$t('sys.login.username')"
+              allow-clear
+            >
+              <template #prefix><icon-user /></template>
+            </a-input>
+          </a-form-item>
+
+          <a-form-item
+            field="password"
+            :hide-label="true"
+            :rules="[
+              { required: true, message: $t('sys.login.passwordNotice') },
+            ]"
+          >
+            <a-input-password
+              v-model="form.password"
+              :placeholder="$t('sys.login.password')"
+              size="large"
+              allow-clear
+            >
+              <template #prefix><icon-lock /></template>
+            </a-input-password>
+          </a-form-item>
+
+          <a-form-item
+            field="code"
+            :hide-label="true"
+            :rules="[
+              {
+                required: true,
+                match: /^[a-zA-Z0-9]{4}$/,
+                message: $t('sys.login.verifyCodeNotice'),
+              },
+            ]"
+          >
+            <a-input
+              v-model="form.code"
+              :placeholder="$t('sys.login.verifyCode')"
+              size="large"
+              allow-clear
+            >
+              <template #prefix><icon-safe /></template>
+              <template #append>
+                <img
+                  :src="captcha"
+                  style="height: 120px; height: 36px; cursor: pointer"
+                  @click="refreshCaptcha"
+                />
+              </template>
+            </a-input>
+          </a-form-item>
+
+          <a-form-item :hide-label="true" class="mt-5">
+            <a-button
+              html-type="submit"
+              type="primary"
+              long
+              size="large"
+              :loading="loading"
+            >
+              {{ $t("sys.login.loginBtn") }}
+            </a-button>
+          </a-form-item>
+
+          <!-- <a-divider orientation="center">{{
+            $t("sys.login.otherLoginType")
+          }}</a-divider>
+          <div class="flex w-3/4 pt-2 mx-auto items-stretch justify-around">
+            <a-avatar class="other-login wechat"><icon-wechat /></a-avatar>
+            <a-avatar class="other-login alipay"
+              ><icon-alipay-circle
+            /></a-avatar>
+            <a-avatar class="other-login qq"><icon-qq /></a-avatar>
+            <a-avatar class="other-login weibo"><icon-weibo /></a-avatar>
+          </div> -->
+        </a-form>
+      </div>
+    </div>
+
+    <div class="login-bg">
+      <div class="fly bg-fly-circle1"></div>
+      <div class="fly bg-fly-circle2"></div>
+      <div class="fly bg-fly-circle3"></div>
+      <div class="fly bg-fly-circle4"></div>
+    </div>
+  </div>
+</template>
+
+<style scoped lang="less">
+.login-container {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  background: rgb(145 185 233 / 50%);
+  background-size: cover;
+  z-index: 3;
+
+  .login-logo {
+    width: 100%;
+    height: 80px;
+    font-weight: 700;
+    font-size: 20px;
+    line-height: 32px;
+    display: flex;
+    padding: 0 20px;
+    align-items: center;
+    color: var(--color-text-1);
+
+    img {
+      width: 45px;
+      height: 45px;
+      margin-right: 10px;
+    }
+  }
+
+  .login-width {
+    max-width: 950px;
+    background-color: var(--color-bg-3);
+    padding: 10px;
+    height: 500px;
+    position: relative;
+    top: 40%;
+    margin-top: -255px;
+    border-radius: 10px;
+    z-index: 999;
+    box-shadow: 0 2px 4px 2px #00000014;
+  }
+
+  .left-panel {
+    height: 491px;
+    background-image: url(@/assets/login_picture.svg);
+    background-repeat: no-repeat;
+    background-position: center 60px;
+    background-size: contain;
+  }
+
+  .logo {
+    display: flex;
+    margin-top: 20px;
+    color: #333;
+    span {
+      font-size: 28px;
+      margin-left: 15px;
+      color: rgb(var(--primary-6));
+    }
+  }
+  .slogan {
+    font-size: 16px;
+    line-height: 50px;
+    color: var(--color-text-1);
+  }
+
+  .login-title {
+    color: var(--color-text-1);
+  }
+
+  :deep(.arco-input-append) {
+    padding: 0 !important;
+  }
+
+  .other-login {
+    cursor: pointer;
+  }
+
+  .qq:hover,
+  .alipay:hover {
+    background: #165dff;
+  }
+  .wechat:hover {
+    background: #0f9c02;
+  }
+
+  .weibo:hover {
+    background: #f3ce2b;
+  }
+}
+
+.login-bg {
+  width: 100%;
+  overflow: hidden;
+  z-index: 1;
+}
+
+.fly {
+  pointer-events: none;
+  position: fixed;
+  z-index: 9999;
+}
+
+.bg-fly-circle1 {
+  left: 40px;
+  top: 100px;
+  width: 100px;
+  height: 100px;
+  border-radius: 50%;
+  background: linear-gradient(
+    to right,
+    rgba(var(--primary-6), 0.07),
+    rgba(var(--primary-6), 0.04)
+  );
+  animation: move-ce64e0ea 2.5s linear infinite;
+}
+
+.bg-fly-circle2 {
+  left: 15%;
+  bottom: 5%;
+  width: 150px;
+  height: 150px;
+  border-radius: 50%;
+  background: linear-gradient(
+    to right,
+    rgba(var(--primary-6), 0.08),
+    rgba(var(--primary-6), 0.04)
+  );
+  animation: move-ce64e0ea 3s linear infinite;
+}
+
+.bg-fly-circle3 {
+  right: 12%;
+  top: 90px;
+  width: 145px;
+  height: 145px;
+  border-radius: 50%;
+  background: linear-gradient(
+    to right,
+    rgba(var(--primary-6), 0.1),
+    rgba(var(--primary-6), 0.04)
+  );
+  animation: move-ce64e0ea 2.5s linear infinite;
+}
+
+.bg-fly-circle4 {
+  right: 5%;
+  top: 60%;
+  width: 160px;
+  height: 160px;
+  border-radius: 50%;
+  background: linear-gradient(
+    to right,
+    rgba(var(--primary-6), 0.02),
+    rgba(var(--primary-6), 0.04)
+  );
+  animation: move-ce64e0ea 3.5s linear infinite;
+}
+
+@keyframes move-ce64e0ea {
+  0% {
+    transform: translateY(0) scale(1);
+  }
+
+  50% {
+    transform: translateY(25px) scale(1.1);
+  }
+
+  to {
+    transform: translateY(0) scale(1);
+  }
+}
+</style>