mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-22 17:31:03 +01:00
updated logo
This commit is contained in:
@@ -1,75 +0,0 @@
|
||||
<template>
|
||||
<el-scrollbar wrap-class="scrollbar-wrapper">
|
||||
<div class="sidebar-logo" :class="isCollapse ? 'collapsed' : ''">
|
||||
<span>C</span><span v-show="!isCollapse">rawlab</span>
|
||||
</div>
|
||||
<el-menu
|
||||
:show-timeout="200"
|
||||
:default-active="routeLevel1"
|
||||
:collapse="isCollapse"
|
||||
:background-color="variables.menuBg"
|
||||
:text-color="variables.menuText"
|
||||
:active-text-color="variables.menuActiveText"
|
||||
mode="vertical"
|
||||
>
|
||||
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path"/>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import variables from '@/styles/variables.scss'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default {
|
||||
components: { SidebarItem },
|
||||
computed: {
|
||||
...mapState('user', [
|
||||
'adminPaths'
|
||||
]),
|
||||
...mapGetters([
|
||||
'sidebar'
|
||||
]),
|
||||
routeLevel1 () {
|
||||
let pathArray = this.$route.path.split('/')
|
||||
return `/${pathArray[1]}`
|
||||
},
|
||||
routes () {
|
||||
return this.$router.options.routes.filter(d => {
|
||||
const role = this.$store.getters['user/userInfo'].role
|
||||
if (role === 'admin') return true
|
||||
return !this.adminPaths.includes(d.path)
|
||||
})
|
||||
},
|
||||
variables () {
|
||||
return variables
|
||||
},
|
||||
isCollapse () {
|
||||
return !this.sidebar.opened
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app .sidebar-container .el-menu {
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.sidebar-container .sidebar-logo {
|
||||
height: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 20px;
|
||||
color: #fff;
|
||||
background: rgb(48, 65, 86);
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
font-family: "Verdana", serif;
|
||||
}
|
||||
|
||||
.sidebar-container .sidebar-logo.collapsed {
|
||||
padding-left: 7px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,411 +0,0 @@
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<canvas id="canvas"></canvas>
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
|
||||
label-position="left">
|
||||
<h3 class="title">
|
||||
CRAWLAB
|
||||
</h3>
|
||||
<el-form-item prop="username" style="margin-bottom: 28px;">
|
||||
<el-input
|
||||
v-model="loginForm.username"
|
||||
name="username"
|
||||
type="text"
|
||||
auto-complete="on"
|
||||
:placeholder="$t('Username')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password" style="margin-bottom: 28px;">
|
||||
<el-input
|
||||
:type="pwdType"
|
||||
v-model="loginForm.password"
|
||||
name="password"
|
||||
auto-complete="on"
|
||||
:placeholder="$t('Password')"
|
||||
@keyup.enter.native="onKeyEnter"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="isSignUp" prop="confirmPassword" style="margin-bottom: 28px;">
|
||||
<el-input
|
||||
:type="pwdType"
|
||||
v-model="loginForm.confirmPassword"
|
||||
name="password"
|
||||
auto-complete="on"
|
||||
:placeholder="$t('Confirm Password')"
|
||||
@keyup.enter.native="onKeyEnter"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item style="border: none">
|
||||
<el-button v-if="isSignUp" :loading="loading" type="primary" style="width:100%;"
|
||||
@click.native.prevent="handleSignup">
|
||||
{{$t('Sign up')}}
|
||||
</el-button>
|
||||
<el-button v-if="!isSignUp" :loading="loading" type="primary" style="width:100%;"
|
||||
@click.native.prevent="handleLogin">
|
||||
{{$t('Sign in')}}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<div class="alternatives">
|
||||
<div class="left">
|
||||
<span v-if="!isSignUp" class="forgot-password">{{$t('Forgot Password')}}</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<span v-if="isSignUp">{{$t('Has Account')}}, </span>
|
||||
<span v-if="isSignUp" class="sign-in" @click="$router.push('/login')">{{$t('Sign-in')}} ></span>
|
||||
<span v-if="!isSignUp">{{$t('New to Crawlab')}}, </span>
|
||||
<span v-if="!isSignUp" class="sign-up" @click="$router.push('/signup')">{{$t('Sign-up')}} ></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tips">
|
||||
<span>{{$t('Initial Username/Password')}}: admin/admin</span>
|
||||
<a href="https://github.com/tikazyq/crawlab" target="_blank" style="float:right">
|
||||
<img src="https://img.shields.io/badge/github-crawlab-blue">
|
||||
</a>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isValidUsername } from '../../utils/validate'
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
data () {
|
||||
const validateUsername = (rule, value, callback) => {
|
||||
if (!isValidUsername(value)) {
|
||||
callback(new Error(this.$t('Please enter the correct username')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validatePass = (rule, value, callback) => {
|
||||
if (value.length < 5) {
|
||||
callback(new Error(this.$t('Password length should be no shorter than 5')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
const validateConfirmPass = (rule, value, callback) => {
|
||||
if (!this.isSignUp) return callback()
|
||||
if (value !== this.loginForm.password) {
|
||||
callback(new Error(this.$t('Two passwords must be the same')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
loginForm: {
|
||||
username: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
},
|
||||
loginRules: {
|
||||
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
|
||||
password: [{ required: true, trigger: 'blur', validator: validatePass }],
|
||||
confirmPassword: [{ required: true, trigger: 'blur', validator: validateConfirmPass }]
|
||||
},
|
||||
loading: false,
|
||||
pwdType: 'password'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isSignUp () {
|
||||
return this.$route.path === '/signup'
|
||||
},
|
||||
redirect () {
|
||||
return this.$route.query.redirect
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleLogin () {
|
||||
this.$refs.loginForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
this.$store.dispatch('user/login', this.loginForm).then(() => {
|
||||
this.loading = false
|
||||
this.$router.push({ path: this.redirect || '/' })
|
||||
this.$store.dispatch('user/getInfo')
|
||||
}).catch(() => {
|
||||
this.$message.error(this.$t('Error when logging in (Please check username and password)'))
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSignup () {
|
||||
this.$refs.loginForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.loading = true
|
||||
this.$store.dispatch('user/register', this.loginForm).then(() => {
|
||||
this.handleLogin()
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$t(err))
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
onKeyEnter () {
|
||||
const func = this.isSignUp ? this.handleSignup : this.handleLogin
|
||||
func()
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
initCanvas()
|
||||
}
|
||||
}
|
||||
|
||||
const initCanvas = () => {
|
||||
var canvas = document.getElementById('canvas')
|
||||
var ctx = canvas.getContext('2d')
|
||||
|
||||
resize()
|
||||
window.onresize = resize
|
||||
|
||||
function resize () {
|
||||
canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
|
||||
canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
|
||||
}
|
||||
|
||||
var RAF = (function () {
|
||||
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
|
||||
window.setTimeout(callback, 1000 / 60)
|
||||
}
|
||||
})()
|
||||
|
||||
// 鼠标活动时,获取鼠标坐标
|
||||
var warea = { x: null, y: null, max: 20000 }
|
||||
// window.onmousemove = function (e) {
|
||||
// e = e || window.event
|
||||
//
|
||||
// warea.x = e.clientX
|
||||
// warea.y = e.clientY
|
||||
// }
|
||||
// window.onmouseout = function (e) {
|
||||
// warea.x = null
|
||||
// warea.y = null
|
||||
// }
|
||||
|
||||
// 添加粒子
|
||||
// x,y为粒子坐标,xa, ya为粒子xy轴加速度,max为连线的最大距离
|
||||
var dots = []
|
||||
for (var i = 0; i < 300; i++) {
|
||||
var x = Math.random() * canvas.width
|
||||
var y = Math.random() * canvas.height
|
||||
var xa = Math.random() * 2 - 1
|
||||
var ya = Math.random() * 2 - 1
|
||||
|
||||
dots.push({
|
||||
x: x,
|
||||
y: y,
|
||||
xa: xa,
|
||||
ya: ya,
|
||||
max: 6000
|
||||
})
|
||||
}
|
||||
|
||||
// 延迟100秒开始执行动画,如果立即执行有时位置计算会出错
|
||||
setTimeout(function () {
|
||||
animate()
|
||||
}, 100)
|
||||
|
||||
// 每一帧循环的逻辑
|
||||
function animate () {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
|
||||
// 将鼠标坐标添加进去,产生一个用于比对距离的点数组
|
||||
var ndots = [warea].concat(dots)
|
||||
|
||||
dots.forEach(function (dot) {
|
||||
// 粒子位移
|
||||
dot.x += dot.xa
|
||||
dot.y += dot.ya
|
||||
|
||||
// 遇到边界将加速度反向
|
||||
dot.xa *= (dot.x > canvas.width || dot.x < 0) ? -1 : 1
|
||||
dot.ya *= (dot.y > canvas.height || dot.y < 0) ? -1 : 1
|
||||
|
||||
// 绘制点
|
||||
ctx.fillRect(dot.x - 0.5, dot.y - 0.5, 1, 1)
|
||||
|
||||
// 循环比对粒子间的距离
|
||||
for (var i = 0; i < ndots.length; i++) {
|
||||
var d2 = ndots[i]
|
||||
|
||||
if (dot === d2 || d2.x === null || d2.y === null) continue
|
||||
|
||||
var xc = dot.x - d2.x
|
||||
var yc = dot.y - d2.y
|
||||
|
||||
// 两个粒子之间的距离
|
||||
var dis = xc * xc + yc * yc
|
||||
|
||||
// 距离比
|
||||
var ratio
|
||||
|
||||
// 如果两个粒子之间的距离小于粒子对象的max值,则在两个粒子间画线
|
||||
if (dis < d2.max) {
|
||||
// 如果是鼠标,则让粒子向鼠标的位置移动
|
||||
if (d2 === warea && dis > (d2.max / 2)) {
|
||||
dot.x -= xc * 0.03
|
||||
dot.y -= yc * 0.03
|
||||
}
|
||||
|
||||
// 计算距离比
|
||||
ratio = (d2.max - dis) / d2.max
|
||||
|
||||
// 画线
|
||||
ctx.beginPath()
|
||||
ctx.lineWidth = ratio / 2
|
||||
// 线条颜色
|
||||
ctx.strokeStyle = 'rgba(64,158,255,' + (ratio + 0.1) + ')'
|
||||
ctx.moveTo(dot.x, dot.y)
|
||||
ctx.lineTo(d2.x, d2.y)
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
// 将已经计算过的粒子从数组中删除
|
||||
ndots.splice(ndots.indexOf(dot), 1)
|
||||
})
|
||||
|
||||
RAF(animate)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
$bg: #2d3a4b;
|
||||
$light_gray: #eee;
|
||||
|
||||
/* reset element-ui css */
|
||||
.login-container {
|
||||
.el-input {
|
||||
display: inline-block;
|
||||
width: calc(100% - 44px);
|
||||
margin-left: 22px;
|
||||
|
||||
input {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0;
|
||||
padding: 12px 5px 12px 15px;
|
||||
color: #666;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
border: 1px solid #ddd;
|
||||
background: #fff;
|
||||
border-radius: 22px;
|
||||
color: #454545;
|
||||
height: 44px;
|
||||
/*margin-bottom: 28px;*/
|
||||
|
||||
.el-form-item__content {
|
||||
line-height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
height: 44px;
|
||||
border-radius: 22px;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
$bg: transparent;
|
||||
$dark_gray: #889aa4;
|
||||
$light_gray: #aaa;
|
||||
.login-container {
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: $bg;
|
||||
|
||||
.login-form {
|
||||
background: transparent;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 480px;
|
||||
max-width: 100%;
|
||||
padding: 35px 35px 15px 35px;
|
||||
margin: 120px auto;
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
background: transparent;
|
||||
|
||||
span {
|
||||
&:first-of-type {
|
||||
margin-right: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.svg-container {
|
||||
padding: 6px 5px 6px 15px;
|
||||
color: $dark_gray;
|
||||
vertical-align: middle;
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: "Verdana", serif;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-size: 32px;
|
||||
/*color: ;*/
|
||||
margin: 0px auto 20px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.show-pwd {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 7px;
|
||||
font-size: 16px;
|
||||
color: $dark_gray;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.alternatives {
|
||||
border-bottom: 1px solid #ccc;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
||||
.forgot-password {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sign-in,
|
||||
.sign-up {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<el-scrollbar wrap-class="scrollbar-wrapper">
|
||||
<div class="sidebar-logo" :class="isCollapse ? 'collapsed' : ''">
|
||||
<span>C</span><span v-show="!isCollapse">rawlab</span>
|
||||
</div>
|
||||
<el-menu
|
||||
:show-timeout="200"
|
||||
:default-active="routeLevel1"
|
||||
@@ -36,7 +39,6 @@ export default {
|
||||
return this.$router.options.routes.filter(d => {
|
||||
const role = this.$store.getters['user/userInfo'].role
|
||||
if (role === 'admin') return true
|
||||
console.log(role)
|
||||
return !this.adminPaths.includes(d.path)
|
||||
})
|
||||
},
|
||||
@@ -49,3 +51,26 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app .sidebar-container .el-menu {
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.sidebar-container .sidebar-logo {
|
||||
height: 50px;
|
||||
display: flex;
|
||||
/*justify-content: center;*/
|
||||
align-items: center;
|
||||
padding-left: 20px;
|
||||
color: #fff;
|
||||
background: rgb(48, 65, 86);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
font-family: "Verdana", serif;
|
||||
}
|
||||
|
||||
.sidebar-container .sidebar-logo.collapsed {
|
||||
padding-left: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
|
||||
label-position="left">
|
||||
<h3 class="title">
|
||||
Crawlab
|
||||
CRAWLAB
|
||||
</h3>
|
||||
<el-form-item prop="username" style="margin-bottom: 28px;">
|
||||
<el-input
|
||||
@@ -367,11 +367,13 @@ const initCanvas = () => {
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: "Verdana", serif;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-size: 32px;
|
||||
color: #666;
|
||||
/*color: ;*/
|
||||
margin: 0px auto 20px auto;
|
||||
text-align: center;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.show-pwd {
|
||||
|
||||
Reference in New Issue
Block a user