fix: 完成 login 页面
@ -29,6 +29,7 @@
|
|||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.25.3",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"eslint-plugin-vue": "^8.2.0",
|
"eslint-plugin-vue": "^8.2.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.5.1",
|
||||||
"sass": "^1.43.2",
|
"sass": "^1.43.2",
|
||||||
"sass-loader": "^12.2.0",
|
"sass-loader": "^12.2.0",
|
||||||
|
2
pnpm-lock.yaml
generated
@ -15,6 +15,7 @@ specifiers:
|
|||||||
eslint-plugin-import: ^2.25.3
|
eslint-plugin-import: ^2.25.3
|
||||||
eslint-plugin-prettier: ^4.0.0
|
eslint-plugin-prettier: ^4.0.0
|
||||||
eslint-plugin-vue: ^8.2.0
|
eslint-plugin-vue: ^8.2.0
|
||||||
|
lodash: ^4.17.21
|
||||||
mockjs: ^1.1.0
|
mockjs: ^1.1.0
|
||||||
naive-ui: ^2.19.9
|
naive-ui: ^2.19.9
|
||||||
pinia: ^2.0.6
|
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-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-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
|
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
|
prettier: rg.cnpmjs.org/prettier/2.5.1
|
||||||
sass: rg.cnpmjs.org/sass/1.44.0
|
sass: rg.cnpmjs.org/sass/1.44.0
|
||||||
sass-loader: rg.cnpmjs.org/sass-loader/12.4.0_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
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/images/chart/bar_y.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/images/chart/funnel.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
src/assets/images/chart/heatmap.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
src/assets/images/chart/line.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
src/assets/images/chart/line_gradient.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/images/chart/map.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/images/chart/photo.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
src/assets/images/chart/pie.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/images/chart/point.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
src/assets/images/chart/radar.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
src/assets/images/chart/static.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
src/assets/images/chart/tree_map.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
src/assets/images/chart/variable.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 34 KiB |
0
src/hooks/index.ts
Normal file
@ -1,6 +1,7 @@
|
|||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import {
|
import {
|
||||||
create,
|
create,
|
||||||
|
NA,
|
||||||
NConfigProvider,
|
NConfigProvider,
|
||||||
NMessageProvider,
|
NMessageProvider,
|
||||||
NDialogProvider,
|
NDialogProvider,
|
||||||
@ -67,11 +68,13 @@ import {
|
|||||||
NBackTop,
|
NBackTop,
|
||||||
NSkeleton,
|
NSkeleton,
|
||||||
NCarousel,
|
NCarousel,
|
||||||
|
NScrollbar,
|
||||||
NCollapseTransition
|
NCollapseTransition
|
||||||
} from 'naive-ui';
|
} from 'naive-ui';
|
||||||
|
|
||||||
const naive = create({
|
const naive = create({
|
||||||
components: [
|
components: [
|
||||||
|
NA,
|
||||||
NMessageProvider,
|
NMessageProvider,
|
||||||
NDialogProvider,
|
NDialogProvider,
|
||||||
NConfigProvider,
|
NConfigProvider,
|
||||||
@ -138,6 +141,7 @@ const naive = create({
|
|||||||
NBackTop,
|
NBackTop,
|
||||||
NSkeleton,
|
NSkeleton,
|
||||||
NCarousel,
|
NCarousel,
|
||||||
|
NScrollbar,
|
||||||
NCollapseTransition
|
NCollapseTransition
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -31,3 +31,6 @@ export const theme = {
|
|||||||
|
|
||||||
// 修改边框圆角
|
// 修改边框圆角
|
||||||
export const borderRadius = '8px'
|
export const borderRadius = '8px'
|
||||||
|
|
||||||
|
// 轮播间隔
|
||||||
|
export const carouselInterval = 5000
|
@ -1,3 +1,4 @@
|
|||||||
|
// 淡入淡出
|
||||||
.v-modal-enter {
|
.v-modal-enter {
|
||||||
animation: v-modal-in 0.2s ease;
|
animation: v-modal-in 0.2s ease;
|
||||||
}
|
}
|
||||||
@ -21,3 +22,16 @@
|
|||||||
opacity: 0;
|
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;
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ $--color-text-2: hsla(0, 0%, 100%, 0.7);
|
|||||||
$--color-text-3: hsla(0, 0%, 100%, 0.5);
|
$--color-text-3: hsla(0, 0%, 100%, 0.5);
|
||||||
$--color-text-4: hsla(0, 0%, 100%, 0.3);
|
$--color-text-4: hsla(0, 0%, 100%, 0.3);
|
||||||
|
|
||||||
|
$--max-width: 1920px;
|
||||||
// 顶部距离
|
// 顶部距离
|
||||||
$--header-height: 60px;
|
$--header-height: 60px;
|
||||||
// 模糊
|
// 模糊
|
||||||
|
@ -13,12 +13,18 @@ export function getUUID(randomLength: number) {
|
|||||||
).toString(36);
|
).toString(36);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * render 图标
|
* * render 图标
|
||||||
*/
|
*/
|
||||||
export const renderIcon = (icon: any) => {
|
export const renderIcon = (icon: typeof NIcon) => {
|
||||||
return () => h(NIcon, null, { default: () => h(icon) });
|
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
|
||||||
|
}
|
||||||
|
@ -1,15 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="go-login-box">
|
<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" />
|
<n-divider class="go-login-box-header" />
|
||||||
|
|
||||||
<div class="go-login">
|
<div class="go-login">
|
||||||
<div class="go-login-carousel">
|
<div class="go-login-carousel">
|
||||||
<n-carousel autoplay>
|
<n-carousel autoplay :interval="Number(carouselInterval)">
|
||||||
<img
|
<img
|
||||||
v-for="(e, i) in imgList"
|
v-for="(item, i) in carouselImgList"
|
||||||
:key="i"
|
:key="i"
|
||||||
class="go-login-carousel-img"
|
class="go-login-carousel-img"
|
||||||
:src="e"
|
:src="getImageUrl(item, 'login')"
|
||||||
alt="展示图片"
|
alt="展示图片"
|
||||||
/>
|
/>
|
||||||
</n-carousel>
|
</n-carousel>
|
||||||
@ -84,26 +98,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="go-login-box-footer">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, onMounted } from 'vue'
|
import { reactive, ref, onMounted } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useMessage } from 'naive-ui'
|
import { useMessage } from 'naive-ui'
|
||||||
import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5'
|
import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5'
|
||||||
import imgOne from '@/assets/images/login/one.png'
|
import { requireUrl } from '@/utils/index'
|
||||||
import imgTwo from '@/assets/images/login/two.png'
|
import { shuffle } from 'lodash'
|
||||||
import imgThree from '@/assets/images/login/three.png'
|
import { carouselInterval } from '@/settings/designSetting'
|
||||||
|
|
||||||
interface FormState {
|
interface FormState {
|
||||||
username: string
|
username: string
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -126,11 +145,38 @@ const rules = {
|
|||||||
password: { required: true, message: '请输入密码', trigger: 'blur' }
|
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) => {
|
const handleSubmit = (e: Event) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
formRef.value.validate(async (errors: any) => {
|
formRef.value.validate(async (errors: any) => {
|
||||||
@ -145,55 +191,67 @@ const handleSubmit = (e: Event) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
shuffleHandle()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
$width: 450px;
|
$width: 450px;
|
||||||
|
$go-login-height: 100vh;
|
||||||
$account-img-height: 270px;
|
$account-img-height: 270px;
|
||||||
$footer-height: 50px;
|
$footer-height: 50px;
|
||||||
$account-height: calc(100vh - $footer-height);
|
$carousel-width: 30%;
|
||||||
$--filter-color-base-login: rgba(51, 55, 61, 0.3);
|
$carousel-image-height: 60vh;
|
||||||
|
$--filter-color-base-login: rgba(89, 95, 103, 0.45);
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@include go(login-box) {
|
@include go(login-box) {
|
||||||
height: 100vh;
|
height: $go-login-height;
|
||||||
overflow: hidden;
|
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 {
|
&-header {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding-top: $--header-height;
|
padding-top: $--header-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include go(login) {
|
@include go(login) {
|
||||||
|
z-index: 2;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-evenly;
|
justify-content: space-around;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: -$--header-height;
|
margin-top: -$--header-height;
|
||||||
padding-top: $--header-height;
|
height: $go-login-height;
|
||||||
|
max-width: $--max-width;
|
||||||
&-carousel {
|
&-carousel {
|
||||||
width: 50%;
|
width: $carousel-width;
|
||||||
|
margin-top: 100px;
|
||||||
|
min-width: 500px;
|
||||||
&-img {
|
&-img {
|
||||||
height: 70vh;
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
height: $carousel-image-height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.login-account {
|
.login-account {
|
||||||
z-index: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: $account-height;
|
margin: 0 160px;
|
||||||
&-container {
|
&-container {
|
||||||
flex: 1;
|
|
||||||
padding: 32px 0;
|
|
||||||
width: $width;
|
width: $width;
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: 100px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-card {
|
&-card {
|
||||||
@extend .go-background-filter;
|
@extend .go-background-filter;
|
||||||
background-color: $--filter-color-base-login;
|
background-color: $--filter-color-base-login;
|
||||||
|
box-shadow: 0 0 105px 50px #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-top {
|
&-top {
|
||||||
@ -206,8 +264,11 @@ $--filter-color-base-login: rgba(51, 55, 61, 0.3);
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-footer {
|
&-footer {
|
||||||
|
z-index: 2;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
height: $footer-height;
|
height: $footer-height;
|
||||||
margin-top: -$--header-height;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: $footer-height;
|
line-height: $footer-height;
|
||||||
color: $--color-text-2;
|
color: $--color-text-2;
|
||||||
@ -216,21 +277,41 @@ $--filter-color-base-login: rgba(51, 55, 61, 0.3);
|
|||||||
&-bg {
|
&-bg {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 100vw;
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
width: $--max-width;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: url('@/assets/images/login/login-bg.png') no-repeat 750px -120px;
|
background: url('@/assets/images/login/login-bg.png') no-repeat 0 -120px;
|
||||||
|
.bg-slot{
|
||||||
|
width: $carousel-width;
|
||||||
|
}
|
||||||
|
.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 (min-width: 768px) {
|
|
||||||
.login-account {
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 50%;
|
|
||||||
background-size: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-account-container {
|
|
||||||
padding: 32px 0 24px 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@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>
|
</style>
|
||||||
|