Commit c0e507d8 by Sendya

add: register

parent 8ac1ae0b
...@@ -103,6 +103,10 @@ ...@@ -103,6 +103,10 @@
body { body {
// 打开滚动条固定显示 // 打开滚动条固定显示
overflow-y: scroll; overflow-y: scroll;
&.userLayout {
overflow-y: auto;
}
} }
.layout { .layout {
......
<template>
<div id="userLayout" class="user-layout-wrapper">
<div class="container">
<div class="top">
<div class="header">
<a href="/">
<img src="~@/assets/logo.svg" class="logo" alt="logo">
<span class="title">Ant Design</span>
</a>
</div>
<div class="desc">
Ant Design 是西湖区最具影响力的 Web 设计规范
</div>
</div>
<div class="main">
<route-view></route-view>
</div>
<div class="footer">
<div class="links">
<a href="_self">帮助</a>
<a href="_self">隐私</a>
<a href="_self">条款</a>
</div>
<div class="copyright">
Copyright &copy; 2018 白鹭学园技术组出品
</div>
</div>
</div>
</div>
</template>
<script>
import RouteView from "@/components/layout/RouteView"
export default {
name: "UserLayout",
components: { RouteView },
data () {
return {}
},
mounted () {
document.body.classList.add('userLayout')
},
beforeDestroy () {
document.body.classList.remove('userLayout')
},
}
</script>
<style lang="scss" scoped>
#userLayout.user-layout-wrapper {
height: 100%;
.container {
width: 100%;
min-height: 100%;
background: #f0f2f5 url(~@/assets/background.svg) no-repeat 50%;
background-size: 100%;
padding: 110px 0 144px;
position: relative;
a {
text-decoration: none;
}
.top {
text-align: center;
.header {
height: 44px;
line-height: 44px;
.badge {
position: absolute;
display: inline-block;
line-height: 1;
vertical-align: middle;
margin-left: -12px;
margin-top: -10px;
opacity: 0.8;
}
.logo {
height: 44px;
vertical-align: top;
margin-right: 16px;
border-style: none;
}
.title {
font-size: 33px;
color: rgba(0, 0, 0, .85);
font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-weight: 600;
position: relative;
top: 2px;
}
}
.desc {
font-size: 14px;
color: rgba(0, 0, 0, 0.45);
margin-top: 12px;
margin-bottom: 40px;
}
}
.main {
width: 368px;
margin: 0 auto;
}
.footer {
position: absolute;
width: 100%;
bottom: 0;
padding: 0 16px;
margin: 48px 0 24px;
text-align: center;
.links {
margin-bottom: 8px;
font-size: 14px;
a {
color: rgba(0, 0, 0, 0.45);
transition: all 0.3s;
&:not(:last-child) {
margin-right: 40px;
}
}
}
.copyright {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
}
}
}
}
</style>
\ No newline at end of file
...@@ -8,14 +8,14 @@ import { ACCESS_TOKEN } from "@/store/mutation-types" ...@@ -8,14 +8,14 @@ import { ACCESS_TOKEN } from "@/store/mutation-types"
NProgress.configure({ showSpinner: false })// NProgress Configuration NProgress.configure({ showSpinner: false })// NProgress Configuration
const whiteList = ['/login']// no redirect whitelist const whiteList = ['/user/login', '/user/register']// no redirect whitelist
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar NProgress.start() // start progress bar
if (Vue.ls.get(ACCESS_TOKEN)) { if (Vue.ls.get(ACCESS_TOKEN)) {
/* has token */ /* has token */
if (to.path === '/login') { if (to.path === '/user/login') {
next({ path: '/dashboard/workplace' }) next({ path: '/dashboard/workplace' })
NProgress.done() NProgress.done()
} else { } else {
...@@ -28,7 +28,7 @@ router.beforeEach((to, from, next) => { ...@@ -28,7 +28,7 @@ router.beforeEach((to, from, next) => {
}) })
}).catch(() => { }).catch(() => {
store.dispatch('Logout').then(() => { store.dispatch('Logout').then(() => {
next({ path: '/login' }) next({ path: '/user/login' })
}) })
}) })
...@@ -40,7 +40,7 @@ router.beforeEach((to, from, next) => { ...@@ -40,7 +40,7 @@ router.beforeEach((to, from, next) => {
if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入 if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
next() next()
} else { } else {
next('/login') next('/user/login')
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
} }
......
...@@ -2,6 +2,7 @@ import Vue from 'vue' ...@@ -2,6 +2,7 @@ import Vue from 'vue'
import Router from 'vue-router' import Router from 'vue-router'
import Layout from '../components/layout/LayoutView' import Layout from '../components/layout/LayoutView'
import LayoutBase from '../components/layout/LayoutBaseView' import LayoutBase from '../components/layout/LayoutBaseView'
import LayoutUser from '@/components/layout/UserLayout'
Vue.use(Router) Vue.use(Router)
/** /**
...@@ -14,17 +15,31 @@ Vue.use(Router) ...@@ -14,17 +15,31 @@ Vue.use(Router)
export const constantRouterMap = [ export const constantRouterMap = [
{ {
path: '/login', path: '/user',
component: () => import('../views/Login') component: LayoutUser,
redirect: '/user/login',
hidden: true,
children: [
{
path: 'login',
name: 'login',
component: () => import(/* webpackChunkName: "user" */ '@/views/Login')
},
{
path: 'register',
name: 'register',
component: () => import(/* webpackChunkName: "user" */ '@/views/Register')
}
]
}, },
{ {
path: '/404', path: '/404',
component: () => import(/* webpackChunkName: "fail" */ '../views/exception/404') component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')
}, },
{ {
path: '/', path: '/',
component: Layout, component: Layout,
redirect: '/login', redirect: { name: 'login' },
name: 'home', name: 'home',
hidden: true hidden: true
} }
...@@ -48,20 +63,20 @@ export const asyncRouterMap = [ ...@@ -48,20 +63,20 @@ export const asyncRouterMap = [
{ {
path: '/dashboard/analysis', path: '/dashboard/analysis',
name: 'Analysis', name: 'Analysis',
component: () => import('../views/dashboard/Analysis'), component: () => import('@/views/dashboard/Analysis'),
meta: { title: '分析页', hideHeader: true, permission: [ 'dashboard' ] } meta: { title: '分析页', hideHeader: true, permission: [ 'dashboard' ] }
}, },
{ {
path: '/dashboard/monitor', path: '/dashboard/monitor',
name: 'Monitor', name: 'Monitor',
hidden: true, hidden: true,
component: () => import('../views/dashboard/Monitor'), component: () => import('@/views/dashboard/Monitor'),
meta: { title: '监控页', hideHeader: true, permission: [ 'dashboard' ] } meta: { title: '监控页', hideHeader: true, permission: [ 'dashboard' ] }
}, },
{ {
path: '/dashboard/workplace', path: '/dashboard/workplace',
name: 'Workplace', name: 'Workplace',
component: () => import('../views/dashboard/Workplace'), component: () => import('@/views/dashboard/Workplace'),
meta: { title: '工作台', permission: [ 'dashboard' ] } meta: { title: '工作台', permission: [ 'dashboard' ] }
} }
] ]
...@@ -76,19 +91,19 @@ export const asyncRouterMap = [ ...@@ -76,19 +91,19 @@ export const asyncRouterMap = [
{ {
path: '/form/base-form', path: '/form/base-form',
name: 'BaseForm', name: 'BaseForm',
component: () => import('../views/form/BasicForm'), component: () => import('@/views/form/BasicForm'),
meta: { title: '基础表单', permission: [ 'form' ] } meta: { title: '基础表单', permission: [ 'form' ] }
}, },
{ {
path: '/form/step-form', path: '/form/step-form',
name: 'StepForm', name: 'StepForm',
component: () => import('../views/form/stepForm/StepForm'), component: () => import('@/views/form/stepForm/StepForm'),
meta: { title: '分步表单', permission: [ 'form' ] } meta: { title: '分步表单', permission: [ 'form' ] }
}, },
{ {
path: '/form/advanced-form', path: '/form/advanced-form',
name: 'AdvanceForm', name: 'AdvanceForm',
component: () => import('../views/form/advancedForm/AdvancedForm'), component: () => import('@/views/form/advancedForm/AdvancedForm'),
meta: { title: '高级表单', permission: [ 'form' ] } meta: { title: '高级表单', permission: [ 'form' ] }
} }
] ]
......
<template>
<div class="user-layout-register">
<h3><span>注册</span></h3>
<a-form ref="formRegister" :autoFormCreate="(form)=>{this.form = form}" id="formRegister">
<a-form-item
fieldDecoratorId="email"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请输入邮箱地址' }], validateTrigger: 'blur'}">
<a-input size="large" type="text" placeholder="邮箱"></a-input>
</a-form-item>
<a-form-item
fieldDecoratorId="password"
:fieldDecoratorOptions="{rules: [{ required: true, message: '至少6位密码,区分大小写' }], validateTrigger: 'blur'}">
<a-input size="large" type="password" placeholder="至少6位密码,区分大小写"></a-input>
</a-form-item>
<a-form-item
fieldDecoratorId="password2"
:fieldDecoratorOptions="{rules: [{ required: true, message: '至少6位密码,区分大小写' }], validateTrigger: 'blur'}">
<a-input size="large" type="password" placeholder="确认密码"></a-input>
</a-form-item>
<a-form-item
fieldDecoratorId="mobile"
:fieldDecoratorOptions="{rules: [{ required: true, message: '手机号' }], validateTrigger: 'blur'}">
<a-input-group size="large" compact>
<a-select style="width: 20%" size="large" defaultValue="+86">
<a-select-option value="+86">+86</a-select-option>
<a-select-option value="+87">+87</a-select-option>
</a-select>
<a-input style="width: 80%" placeholder="11 位手机号"></a-input>
</a-input-group>
</a-form-item>
<a-row :gutter="16">
<a-col class="gutter-row" :span="16">
<a-form-item
fieldDecoratorId="captcha"
:fieldDecoratorOptions="{rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}">
<a-input size="large" type="text" placeholder="验证码">
<a-icon slot="prefix" type='mail' :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
</a-col>
<a-col class="gutter-row" :span="8">
<span class="ivu-input-prefix">
<a-button
class="getCaptcha"
size="large"
:disabled="state.smsSendBtn"
@click.stop.prevent="getCaptcha"
v-text="!state.smsSendBtn && '获取验证码'||(state.time+' s')"></a-button>
</span>
</a-col>
</a-row>
<a-form-item>
<a-button
size="large"
type="primary"
htmlType="submit"
class="register-button"
:loading="registerBtn"
@click.stop.prevent="handleSubmit"
:disabled="registerBtn">注册
</a-button>
<router-link class="login" :to="{ name: 'login' }">使用已有账户登录</router-link>
</a-form-item>
</a-form>
</div>
</template>
<script>
import api from '@/api/'
import UserLayout from '@/components/layout/UserLayout'
export default {
name: "Register",
components: {
UserLayout
},
data () {
return {
form: null,
state: {
time: 60,
smsSendBtn: false,
},
registerBtn: false
}
},
methods: {
handleSubmit () {
this.form.validateFields((err, values) => {
if (!err) {
console.log('form data', values)
}
})
},
getCaptcha (e) {
e.preventDefault()
let that = this
this.form.validateFields([ 'mobile' ], { force: true },
(err) => {
if (!err) {
this.state.smsSendBtn = true;
let interval = window.setInterval(() => {
if (that.state.time-- <= 0) {
that.state.time = 60;
that.state.smsSendBtn = false;
window.clearInterval(interval);
}
}, 1000);
const hide = this.$message.loading('验证码发送中..', 0);
this.$http.post(api.SendSms, { mobile: that.formRegister.mobile })
.then(res => {
setTimeout(hide, 2500);
this.$notification[ 'success' ]({
message: '提示',
description: '验证码获取成功,您的验证码为:' + res.result.captcha,
duration: 8
})
})
.catch(err => {
setTimeout(hide, 1);
clearInterval(interval);
that.state.time = 60;
that.state.smsSendBtn = false;
this.requestFailed(err);
});
}
}
);
},
requestFailed (err) {
this.$notification[ 'error' ]({
message: '错误',
description: ((err.response || {}).data || {}).message || "请求出现错误,请稍后再试",
duration: 4,
});
this.registerBtn = false;
},
}
}
</script>
<style lang="scss" scoped>
.user-layout-register {
&> h3 {
font-size: 16px;
margin-bottom: 20px;
}
.getCaptcha {
display: block;
width: 100%;
height: 40px;
}
.register-button {
width: 50%;
}
.login {
float: right;
line-height: 40px;
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment