Browse Source

fix: 完成 login 页面

MTrun 3 năm trước cách đây
mục cha
commit
ed49e4add8

+ 1 - 0
package.json

@@ -29,6 +29,7 @@
     "eslint-plugin-import": "^2.25.3",
     "eslint-plugin-prettier": "^4.0.0",
     "eslint-plugin-vue": "^8.2.0",
+    "lodash": "^4.17.21",
     "prettier": "^2.5.1",
     "sass": "^1.43.2",
     "sass-loader": "^12.2.0",

+ 2 - 0
pnpm-lock.yaml

@@ -15,6 +15,7 @@ specifiers:
   eslint-plugin-import: ^2.25.3
   eslint-plugin-prettier: ^4.0.0
   eslint-plugin-vue: ^8.2.0
+  lodash: ^4.17.21
   mockjs: ^1.1.0
   naive-ui: ^2.19.9
   pinia: ^2.0.6
@@ -52,6 +53,7 @@ devDependencies:
   eslint-plugin-import: rg.cnpmjs.org/eslint-plugin-import/2.25.3_eslint@8.4.1
   eslint-plugin-prettier: rg.cnpmjs.org/eslint-plugin-prettier/4.0.0_90bd2ba582f6d1348d73031482d782e2
   eslint-plugin-vue: rg.cnpmjs.org/eslint-plugin-vue/8.2.0_eslint@8.4.1
+  lodash: rg.cnpmjs.org/lodash/4.17.21
   prettier: rg.cnpmjs.org/prettier/2.5.1
   sass: rg.cnpmjs.org/sass/1.44.0
   sass-loader: rg.cnpmjs.org/sass-loader/12.4.0_sass@1.44.0

BIN
src/assets/images/chart/bar_x.png


BIN
src/assets/images/chart/bar_y.png


BIN
src/assets/images/chart/funnel.png


BIN
src/assets/images/chart/heatmap.png


BIN
src/assets/images/chart/line.png


BIN
src/assets/images/chart/line_gradient.png


BIN
src/assets/images/chart/map.png


BIN
src/assets/images/chart/photo.png


BIN
src/assets/images/chart/pie.png


BIN
src/assets/images/chart/point.png


BIN
src/assets/images/chart/radar.png


BIN
src/assets/images/chart/static.png


BIN
src/assets/images/chart/tree_map.png


BIN
src/assets/images/chart/variable.png


BIN
src/assets/images/login/login-bg.png


BIN
src/assets/images/login/one.png


BIN
src/assets/images/login/three.png


BIN
src/assets/images/login/two.png


+ 0 - 0
src/hooks/index.ts


+ 4 - 0
src/plugins/naive.ts

@@ -1,6 +1,7 @@
 import type { App } from 'vue';
 import {
   create,
+  NA,
   NConfigProvider,
   NMessageProvider,
   NDialogProvider,
@@ -67,11 +68,13 @@ import {
   NBackTop,
   NSkeleton,
   NCarousel,
+  NScrollbar,
   NCollapseTransition
 } from 'naive-ui';
 
 const naive = create({
   components: [
+    NA,
     NMessageProvider,
     NDialogProvider,
     NConfigProvider,
@@ -138,6 +141,7 @@ const naive = create({
     NBackTop,
     NSkeleton,
     NCarousel,
+    NScrollbar,
     NCollapseTransition
   ],
 });

+ 4 - 1
src/settings/designSetting.ts

@@ -30,4 +30,7 @@ export const theme = {
 };
 
 // 修改边框圆角
-export const borderRadius = '8px'
+export const borderRadius = '8px'
+
+// 轮播间隔
+export const carouselInterval = 5000

+ 14 - 0
src/styles/common/animation.scss

@@ -1,3 +1,4 @@
+// 淡入淡出
 .v-modal-enter {
   animation: v-modal-in 0.2s ease;
 }
@@ -21,3 +22,16 @@
     opacity: 0;
   }
 }
+
+// 移动动画
+.list-complete-item {
+  transition: all 1s;
+}
+.list-complete-enter,
+.list-complete-leave-to {
+  opacity: 0;
+  transform: translateY(30px);
+}
+.list-complete-leave-active {
+  position: absolute;
+}

+ 1 - 0
src/styles/common/var.scss

@@ -10,6 +10,7 @@ $--color-text-2: hsla(0, 0%, 100%, 0.7);
 $--color-text-3: hsla(0, 0%, 100%, 0.5);
 $--color-text-4: hsla(0, 0%, 100%, 0.3);
 
+$--max-width: 1920px;
 // 顶部距离
 $--header-height: 60px;
 // 模糊

+ 9 - 3
src/utils/index.ts

@@ -13,12 +13,18 @@ export function getUUID(randomLength: number) {
   ).toString(36);
 }
 
-
 /**
  * * render 图标
  */
-export const renderIcon = (icon: any) => {
+export const renderIcon = (icon: typeof NIcon) => {
   return () => h(NIcon, null, { default: () => h(icon) });
 }
 
-
+/**
+ * * 处理 vite 中无法使用 require 的问题
+ * @param name 
+ * @returns 
+ */
+export const requireUrl = (path: string, name: string) => {
+  return new URL(`${path}/${name}`, import.meta.url).href
+}

+ 120 - 39
src/views/login/index.vue

@@ -1,15 +1,29 @@
 <template>
   <div class="go-login-box">
-    <div class="go-login-box-bg"></div>
+    <div class="go-login-box-bg">
+      <aside class="bg-slot"></aside>
+      <aside class="bg-img-box">
+        <transition-group name="list-complete">
+          <template v-for="item in bgList" :key="item">
+            <div class="bg-img-box-li list-complete-item">
+              <n-collapse-transition :appear="true" :show="show">
+                <img :src="getImageUrl(item, 'chart')" alt="chart" />
+              </n-collapse-transition>
+            </div>
+          </template>
+        </transition-group>
+      </aside>
+    </div>
     <n-divider class="go-login-box-header" />
+
     <div class="go-login">
       <div class="go-login-carousel">
-        <n-carousel autoplay>
+        <n-carousel autoplay :interval="Number(carouselInterval)">
           <img
-            v-for="(e, i) in imgList"
+            v-for="(item, i) in carouselImgList"
             :key="i"
             class="go-login-carousel-img"
-            :src="e"
+            :src="getImageUrl(item, 'login')"
             alt="展示图片"
           />
         </n-carousel>
@@ -84,26 +98,31 @@
         </div>
       </div>
     </div>
+
     <div class="go-login-box-footer">
-      文档地址: http://www.mtruning.club/
+      <n-a>文档地址: </n-a>
+      <n-a italic href="http://www.mtruning.club/">
+        http://www.mtruning.club/
+      </n-a>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
 import { reactive, ref, onMounted } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
+import { useRouter } from 'vue-router'
 import { useMessage } from 'naive-ui'
 import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5'
-import imgOne from '@/assets/images/login/one.png'
-import imgTwo from '@/assets/images/login/two.png'
-import imgThree from '@/assets/images/login/three.png'
+import { requireUrl } from '@/utils/index'
+import { shuffle } from 'lodash'
+import { carouselInterval } from '@/settings/designSetting'
 
 interface FormState {
   username: string
   password: string
 }
 
+const router = useRouter()
 const formRef = ref()
 const message = useMessage()
 const loading = ref(false)
@@ -126,11 +145,38 @@ const rules = {
   password: { required: true, message: '请输入密码', trigger: 'blur' }
 }
 
-const imgList = [imgOne, imgTwo, imgThree]
+// 定时器
+const shuffleTimiing = ref()
 
-const router = useRouter()
-const route = useRoute()
+// 轮播图
+const carouselImgList = ['one', 'two', 'three']
+
+// 背景图
+const bgList = ref([
+  'bar_y',
+  'bar_x',
+  'line_gradient',
+  'line',
+  'funnel',
+  'heatmap',
+  'map',
+  'pie',
+  'radar',
+])
+
+// 处理url获取
+const getImageUrl = (name: string, folder: string) => {
+  return requireUrl(`../assets/images/${folder}`, `${name}.png`)
+}
 
+// 打乱
+const shuffleHandle = () => {
+  shuffleTimiing.value = setInterval(() => {
+    bgList.value = shuffle(bgList.value)
+  }, carouselInterval)
+}
+
+// 点击事件
 const handleSubmit = (e: Event) => {
   e.preventDefault()
   formRef.value.validate(async (errors: any) => {
@@ -145,55 +191,67 @@ const handleSubmit = (e: Event) => {
     }
   })
 }
+
+onMounted(() => {
+  shuffleHandle()
+})
 </script>
 
 <style lang="scss" scoped>
 $width: 450px;
+$go-login-height: 100vh;
 $account-img-height: 270px;
 $footer-height: 50px;
-$account-height: calc(100vh - $footer-height);
-$--filter-color-base-login: rgba(51, 55, 61, 0.3);
+$carousel-width: 30%;
+$carousel-image-height: 60vh;
+$--filter-color-base-login: rgba(89, 95, 103, 0.45);
 
 * {
   box-sizing: border-box;
 }
 @include go(login-box) {
-  height: 100vh;
+  height: $go-login-height;
   overflow: hidden;
-  background-image: linear-gradient(120deg, $--color-bg-1 0%, $--color-bg-2 100%);
+  background-image: linear-gradient(
+    120deg,
+    $--color-bg-1 0%,
+    $--color-bg-2 100%
+  );
   &-header {
     margin: 0px;
     padding-top: $--header-height;
   }
 
   @include go(login) {
+    z-index: 2;
     display: flex;
-    justify-content: space-evenly;
+    justify-content: space-around;
     align-items: center;
     margin-top: -$--header-height;
-    padding-top: $--header-height;
+    height: $go-login-height;
+    max-width: $--max-width;
     &-carousel {
-      width: 50%;
+      width: $carousel-width;
+      margin-top: 100px;
+      min-width: 500px;
       &-img {
-        height: 70vh;
+        display: block;
+        margin: 0 auto;
+        height: $carousel-image-height;
       }
     }
     .login-account {
-      z-index: 1;
       display: flex;
       flex-direction: column;
-      height: $account-height;
+      margin: 0 160px;
       &-container {
-        flex: 1;
-        padding: 32px 0;
         width: $width;
-        margin: 0 auto;
-        margin-top: 100px;
       }
 
       &-card {
         @extend .go-background-filter;
         background-color: $--filter-color-base-login;
+        box-shadow: 0 0 105px 50px #202020;
       }
 
       &-top {
@@ -206,8 +264,11 @@ $--filter-color-base-login: rgba(51, 55, 61, 0.3);
   }
 
   &-footer {
+    z-index: 2;
+    position: fixed;
+    bottom: 0;
+    width: 100%;
     height: $footer-height;
-    margin-top: -$--header-height;
     text-align: center;
     line-height: $footer-height;
     color: $--color-text-2;
@@ -216,21 +277,41 @@ $--filter-color-base-login: rgba(51, 55, 61, 0.3);
   &-bg {
     z-index: 0;
     position: fixed;
-    width: 100vw;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    width: $--max-width;
     height: 100vh;
-    background: url('@/assets/images/login/login-bg.png') no-repeat 750px -120px;
-  }
-
-  @media (min-width: 768px) {
-    .login-account {
-      background-repeat: no-repeat;
-      background-position: 50%;
-      background-size: 100%;
+    background: url('@/assets/images/login/login-bg.png') no-repeat 0 -120px;
+    .bg-slot{
+      width: $carousel-width;
     }
-
-    .page-account-container {
-      padding: 32px 0 24px 0;
+    .bg-img-box {
+      position: relative;
+      display: flex;
+      flex-wrap: wrap;
+      width: 770px;
+      margin-right: -20px;
+      &-li {
+        img {
+          margin-right: 20px;
+          margin-top: 20px;
+          height: 230px;
+          border-radius: 2 * $--border-radius-base;
+          opacity: 0.9;
+        }
+      }
     }
   }
 }
+@media only screen and (max-width: 1200px) {
+  .bg-img-box,
+  .bg-slot,
+  .go-login-carousel {
+    display: none !important;
+  }
+  .go-login-box-footer {
+    position: relative;
+  }
+}
 </style>