请求接口更新,添加500页面,修复初始状态下服务器连接失败造成直接退出登录的问题,修复ESLint问题。
This commit is contained in:
parent
bb55eaedad
commit
cd59783e90
|
@ -74,6 +74,7 @@ module.exports = defineConfig({
|
||||||
'prefer-rest-params': 'error',
|
'prefer-rest-params': 'error',
|
||||||
'prefer-spread': 'error',
|
'prefer-spread': 'error',
|
||||||
'prefer-template': 'error',
|
'prefer-template': 'error',
|
||||||
|
'eslint-comments/no-unlimited-disable': 'off',
|
||||||
|
|
||||||
'no-redeclare': 'off',
|
'no-redeclare': 'off',
|
||||||
'@typescript-eslint/no-redeclare': 'error',
|
'@typescript-eslint/no-redeclare': 'error',
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable */
|
||||||
import { markRaw, nextTick, ref } from 'vue'
|
import { markRaw, nextTick, ref } from 'vue'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import { describe, expect, it, test } from 'vitest'
|
import { describe, expect, it, test } from 'vitest'
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import NProgress from 'nprogress'
|
import NProgress from 'nprogress'
|
||||||
import type { RouteRawConfig, RouterTypes, rawConfig } from '~/basic'
|
import type { RouteRawConfig, RouterTypes, rawConfig } from '~/basic'
|
||||||
import type { RouteRecordName } from 'vue-router'
|
import type { RouteRecordName } from 'vue-router'
|
||||||
import { RouterView } from 'vue-router'
|
|
||||||
/**
|
/**
|
||||||
* 根据请求,过滤异步路由
|
* 根据请求,过滤异步路由
|
||||||
* @param:menuList 异步路由数组
|
* @param:menuList 异步路由数组
|
||||||
|
@ -17,7 +16,6 @@ import router, { asyncRoutes, constantRoutes } from '@/router'
|
||||||
import 'nprogress/nprogress.css'
|
import 'nprogress/nprogress.css'
|
||||||
import { useBasicStore } from '@/store/basic'
|
import { useBasicStore } from '@/store/basic'
|
||||||
import { isArray } from 'xe-utils'
|
import { isArray } from 'xe-utils'
|
||||||
import settings from '@/settings'
|
|
||||||
|
|
||||||
const buttonCodes: Array<Number> = [] //按钮权限
|
const buttonCodes: Array<Number> = [] //按钮权限
|
||||||
interface menuRow {
|
interface menuRow {
|
||||||
|
|
|
@ -7,11 +7,14 @@ import { getRouterList } from '@/api/router'
|
||||||
|
|
||||||
//路由进入前拦截
|
//路由进入前拦截
|
||||||
//to:将要进入的页面 vue-router4.0 不推荐使用next()
|
//to:将要进入的页面 vue-router4.0 不推荐使用next()
|
||||||
const whiteList = ['/login', '/404', '/401'] // no redirect whitelist
|
const whiteList = ['/login', '/404', '/401', '/500'] // no redirect whitelist
|
||||||
router.beforeEach(async (to) => {
|
router.beforeEach(async (to) => {
|
||||||
progressStart()
|
progressStart()
|
||||||
document.title = langTitle(to.meta?.title) // i18 page title
|
document.title = langTitle(to.meta?.title) // i18 page title
|
||||||
const basicStore = useBasicStore()
|
const basicStore = useBasicStore()
|
||||||
|
if (to.path === '/500') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
//1.判断token
|
//1.判断token
|
||||||
if (basicStore.token) {
|
if (basicStore.token) {
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
|
@ -36,7 +39,7 @@ router.beforeEach(async (to) => {
|
||||||
console.error(`route permission error${e}`)
|
console.error(`route permission error${e}`)
|
||||||
basicStore.resetState()
|
basicStore.resetState()
|
||||||
progressClose()
|
progressClose()
|
||||||
return `/login?redirect=${to.path}`
|
return `/500?redirect=${to.path}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -19,6 +19,11 @@ export const constantRoutes: RouterTypes = [
|
||||||
component: () => import('@/views/error-page/401.vue'),
|
component: () => import('@/views/error-page/401.vue'),
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/500',
|
||||||
|
component: () => import('@/views/error-page/500.vue'),
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
|
|
@ -13,7 +13,7 @@ export function mobilePhone(str) {
|
||||||
/*
|
/*
|
||||||
* 传入一串num四个 一个空格
|
* 传入一串num四个 一个空格
|
||||||
* */
|
* */
|
||||||
export function toSplitNumFor(num, numToSpace) {
|
export function toSplitNumFor(num) {
|
||||||
return num.replace(/(.{4})/g, '$1 ')
|
return num.replace(/(.{4})/g, '$1 ')
|
||||||
}
|
}
|
||||||
// 匹配银行卡号
|
// 匹配银行卡号
|
||||||
|
|
|
@ -46,6 +46,7 @@ service.interceptors.response.use(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
console.log(`err${error}`) // for debug
|
console.log(`err${error}`) // for debug
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: error.ElMessage,
|
message: error.ElMessage,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { AxiosRequestConfig } from 'axios'
|
import type { AxiosRequestConfig } from 'axios'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useBasicStore } from '@/store/basic'
|
import { useBasicStore } from '@/store/basic'
|
||||||
|
|
||||||
//使用axios.create()创建一个axios请求实例
|
//使用axios.create()创建一个axios请求实例
|
||||||
|
@ -31,6 +31,8 @@ service.interceptors.request.use(
|
||||||
//请求后拦截
|
//请求后拦截
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(res) => {
|
(res) => {
|
||||||
|
const type = (res.headers['content-type'] as string) || ''
|
||||||
|
if (!type.startsWith('application/json')) return res.data
|
||||||
const { code } = res.data
|
const { code } = res.data
|
||||||
const successCode = '0,200,20000'
|
const successCode = '0,200,20000'
|
||||||
const noAuthCode = '401,403'
|
const noAuthCode = '401,403'
|
||||||
|
@ -38,30 +40,39 @@ service.interceptors.response.use(
|
||||||
return res.data
|
return res.data
|
||||||
} else {
|
} else {
|
||||||
if (noAuthCode.includes(code) && !location.href.includes('/login')) {
|
if (noAuthCode.includes(code) && !location.href.includes('/login')) {
|
||||||
ElMessageBox.confirm('请重新登录', {
|
|
||||||
confirmButtonText: '重新登录',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning'
|
|
||||||
}).then(() => {
|
|
||||||
useBasicStore().resetStateAndToLogin()
|
useBasicStore().resetStateAndToLogin()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return Promise.reject(res.data)
|
return Promise.reject(new Error(res.data?.msg ?? '未知异常'))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//响应报错
|
//响应报错
|
||||||
(err) => {
|
(err) => {
|
||||||
|
const { response } = err
|
||||||
|
if (response?.status === 401) {
|
||||||
|
useBasicStore().resetStateAndToLogin()
|
||||||
|
} else {
|
||||||
|
const { msg } = response?.data ?? { msg: '未知异常' }
|
||||||
ElMessage.error({
|
ElMessage.error({
|
||||||
message: err,
|
message: msg || err,
|
||||||
duration: 2 * 1000
|
duration: 2 * 1000
|
||||||
})
|
})
|
||||||
|
}
|
||||||
return Promise.reject(err)
|
return Promise.reject(err)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const baseUrl: string = (() => {
|
||||||
|
let port = import.meta.env.VITE_APP_BASE_URL
|
||||||
|
if (/:\d{1,5}/.test(port)) port = port.match(/(?<port>:\d{1,5})/)?.groups?.port ?? ''
|
||||||
|
else port = `:${location.port}`
|
||||||
|
return `${location.protocol}//${location.hostname}${port}`
|
||||||
|
})()
|
||||||
|
|
||||||
//导出service实例给页面调用 , config->页面的配置
|
//导出service实例给页面调用 , config->页面的配置
|
||||||
export default function request(config: AxiosRequestConfig) {
|
export default function request(config: AxiosRequestConfig) {
|
||||||
return service({
|
return service({
|
||||||
baseURL: import.meta.env.VITE_APP_BASE_URL,
|
//baseURL: import.meta.env.VITE_APP_BASE_URL,
|
||||||
|
baseURL: baseUrl,
|
||||||
timeout: 8000,
|
timeout: 8000,
|
||||||
...config
|
...config
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,8 +42,7 @@ export function isName(value) {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isIP(ip) {
|
export function isIP(ip) {
|
||||||
const reg =
|
const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
|
||||||
/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
|
|
||||||
return reg.test(ip)
|
return reg.test(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +52,7 @@ export function isIP(ip) {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isUrl(url) {
|
export function isUrl(url) {
|
||||||
const reg =
|
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||||||
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
|
||||||
return reg.test(url)
|
return reg.test(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,8 +122,7 @@ export function isObject(arg) {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isPort(str) {
|
export function isPort(str) {
|
||||||
const reg =
|
const reg = /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/
|
||||||
/^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/
|
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +142,7 @@ export function isPhone(str) {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isIdCard(str) {
|
export function isIdCard(str) {
|
||||||
const reg =
|
const reg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
|
||||||
/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
|
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,13 +172,7 @@ export function isChina(str) {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isBlank(str) {
|
export function isBlank(str) {
|
||||||
return (
|
return str == null || false || str === '' || str.trim() === '' || str.toLocaleLowerCase().trim() === 'null'
|
||||||
str == null ||
|
|
||||||
false ||
|
|
||||||
str === '' ||
|
|
||||||
str.trim() === '' ||
|
|
||||||
str.toLocaleLowerCase().trim() === 'null'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,8 +181,7 @@ export function isBlank(str) {
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isTel(str) {
|
export function isTel(str) {
|
||||||
const reg =
|
const reg = /^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))?$/
|
||||||
/^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))?$/
|
|
||||||
return reg.test(str)
|
return reg.test(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,14 +199,14 @@ export function isNum(str) {
|
||||||
* @param cid 18为的身份证号码
|
* @param cid 18为的身份证号码
|
||||||
* @return Boolean 是否有效
|
* @return Boolean 是否有效
|
||||||
**/
|
**/
|
||||||
export function isIdentityNumber(cid) {
|
export function isIdentityNumber(cid: string) {
|
||||||
const arrExp = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] //加权因子
|
const arrExp = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] //加权因子
|
||||||
const arrValid = '1 0 X 9 8 7 6 5 4 3 2'.split(' ') //校检码
|
const arrValid = '1 0 X 9 8 7 6 5 4 3 2'.split(' ') //校检码
|
||||||
if (/^\d{17}\d|x$/i.test(cid)) {
|
if (/^\d{17}\d|x$/i.test(cid)) {
|
||||||
let sum = 0
|
let sum = 0
|
||||||
for (let i = 0; i < cid.length - 1; i++) {
|
for (let i = 0; i < cid.length - 1; i++) {
|
||||||
// 对前17位数字与权值乘积求和
|
// 对前17位数字与权值乘积求和
|
||||||
sum += Number.parseInt(cid.substr(i, 1), 10) * arrExp[i]
|
sum += Number.parseInt(cid.slice(i, i + 1), 10) * arrExp[i]
|
||||||
}
|
}
|
||||||
// 计算模(固定算法)
|
// 计算模(固定算法)
|
||||||
const idx = sum % 11
|
const idx = sum % 11
|
||||||
|
@ -253,7 +242,7 @@ export class ElValidate {
|
||||||
validate.push({
|
validate.push({
|
||||||
required: true,
|
required: true,
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
message: isString(canEmpty) ? canEmpty : '请输入文本',
|
message: isString(canEmpty) ? canEmpty : '请输入文本'
|
||||||
})
|
})
|
||||||
return validate
|
return validate
|
||||||
}
|
}
|
||||||
|
@ -271,8 +260,8 @@ export class ElValidate {
|
||||||
validator(rule, value, callback) {
|
validator(rule, value, callback) {
|
||||||
if (/^1[3456789]\d{9}$/g.test(value)) callback()
|
if (/^1[3456789]\d{9}$/g.test(value)) callback()
|
||||||
else callback(new Error('无效的手机号'))
|
else callback(new Error('无效的手机号'))
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,8 +280,8 @@ export class ElValidate {
|
||||||
} else {
|
} else {
|
||||||
callback(new Error('无效的身份证号'))
|
callback(new Error('无效的身份证号'))
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,8 +310,8 @@ export class ElValidate {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
callback()
|
callback()
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
237
src/views/error-page/500.vue
Normal file
237
src/views/error-page/500.vue
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
<template>
|
||||||
|
<div class="wscn-http404-container">
|
||||||
|
<div class="wscn-http404">
|
||||||
|
<div class="pic-404">
|
||||||
|
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" />
|
||||||
|
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" />
|
||||||
|
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" />
|
||||||
|
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" />
|
||||||
|
</div>
|
||||||
|
<div class="bullshit">
|
||||||
|
<div class="bullshit__oops">OOPS!</div>
|
||||||
|
<div class="bullshit__info">
|
||||||
|
All rights reserved
|
||||||
|
<a style="color: #20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a>
|
||||||
|
</div>
|
||||||
|
<div class="bullshit__headline">服务器内部异常,请稍候重试</div>
|
||||||
|
<div class="bullshit__info">
|
||||||
|
或询问管理员服务器后台是否正常运行
|
||||||
|
</div>
|
||||||
|
<router-link :to="target" class="bullshit__return-home">重试</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const target = computed(() => useRoute().query.redirect || "/dashboard");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.wscn-http404-container {
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
position: absolute;
|
||||||
|
top: 40%;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wscn-http404 {
|
||||||
|
position: relative;
|
||||||
|
width: 1200px;
|
||||||
|
padding: 0 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.pic-404 {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
width: 600px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__parent {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__child {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
width: 80px;
|
||||||
|
top: 17px;
|
||||||
|
left: 220px;
|
||||||
|
opacity: 0;
|
||||||
|
animation-name: cloudLeft;
|
||||||
|
animation-duration: 2s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mid {
|
||||||
|
width: 46px;
|
||||||
|
top: 10px;
|
||||||
|
left: 420px;
|
||||||
|
opacity: 0;
|
||||||
|
animation-name: cloudMid;
|
||||||
|
animation-duration: 2s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-delay: 1.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
width: 62px;
|
||||||
|
top: 100px;
|
||||||
|
left: 500px;
|
||||||
|
opacity: 0;
|
||||||
|
animation-name: cloudRight;
|
||||||
|
animation-duration: 2s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes cloudLeft {
|
||||||
|
0% {
|
||||||
|
top: 17px;
|
||||||
|
left: 220px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
top: 33px;
|
||||||
|
left: 188px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
top: 81px;
|
||||||
|
left: 92px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 97px;
|
||||||
|
left: 60px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes cloudMid {
|
||||||
|
0% {
|
||||||
|
top: 10px;
|
||||||
|
left: 420px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
top: 40px;
|
||||||
|
left: 360px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
top: 130px;
|
||||||
|
left: 180px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 160px;
|
||||||
|
left: 120px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes cloudRight {
|
||||||
|
0% {
|
||||||
|
top: 100px;
|
||||||
|
left: 500px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
top: 120px;
|
||||||
|
left: 460px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
top: 180px;
|
||||||
|
left: 340px;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
top: 200px;
|
||||||
|
left: 300px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bullshit {
|
||||||
|
position: relative;
|
||||||
|
float: left;
|
||||||
|
width: 300px;
|
||||||
|
padding: 30px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__oops {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 40px;
|
||||||
|
color: #1482f0;
|
||||||
|
opacity: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__headline {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #222;
|
||||||
|
font-weight: bold;
|
||||||
|
opacity: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-delay: 0.1s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 21px;
|
||||||
|
color: grey;
|
||||||
|
opacity: 0;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__return-home {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
width: 110px;
|
||||||
|
height: 36px;
|
||||||
|
background: #1482f0;
|
||||||
|
border-radius: 100px;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 36px;
|
||||||
|
cursor: pointer;
|
||||||
|
animation-name: slideUp;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-delay: 0.3s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
0% {
|
||||||
|
transform: translateY(60px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user