UP 登录视图加强 增加注册,忘记密码,二维码登录,手机号登录
This commit is contained in:
parent
6fe2a88903
commit
a2371261a0
|
|
@ -3,6 +3,8 @@ export default {
|
||||||
slogan: 'High performance / delicate / grace',
|
slogan: 'High performance / delicate / grace',
|
||||||
describe: 'Vue3 + element plus based front-end solutions in the background.',
|
describe: 'Vue3 + element plus based front-end solutions in the background.',
|
||||||
signInTitle: 'Sign in',
|
signInTitle: 'Sign in',
|
||||||
|
accountLogin: 'Account sign in',
|
||||||
|
mobileLogin: 'Mobile sign in',
|
||||||
rememberMe: 'Remember me',
|
rememberMe: 'Remember me',
|
||||||
forgetPassword: 'Forget password',
|
forgetPassword: 'Forget password',
|
||||||
signIn: 'Sign in',
|
signIn: 'Sign in',
|
||||||
|
|
@ -12,7 +14,18 @@ export default {
|
||||||
PWPlaceholder: 'Please input a password',
|
PWPlaceholder: 'Please input a password',
|
||||||
PWError: 'Please input a password',
|
PWError: 'Please input a password',
|
||||||
admin: 'Administrator',
|
admin: 'Administrator',
|
||||||
user: 'User'
|
user: 'User',
|
||||||
|
mobilePlaceholder: 'Mobile',
|
||||||
|
mobileError: 'Please input mobile',
|
||||||
|
smsPlaceholder: 'SMS Code',
|
||||||
|
smsError: 'Please input sms code',
|
||||||
|
smsGet: 'Get SMS Code',
|
||||||
|
smsSent: 'SMS sent to mobile number',
|
||||||
|
noAccount: 'No account?',
|
||||||
|
createAccount: 'Create a new account',
|
||||||
|
wechatLoginTitle: 'QR code sign in',
|
||||||
|
wechatLoginMsg: 'Please use wechat to scan and log in | Auto scan after 3 seconds of simulation',
|
||||||
|
wechatLoginResult: 'Scanned | Please click authorize login in the device'
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
dynamic: 'Dynamic',
|
dynamic: 'Dynamic',
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@ export default {
|
||||||
slogan: '高性能 / 精致 / 优雅',
|
slogan: '高性能 / 精致 / 优雅',
|
||||||
describe: '基于Vue3 + Element-Plus 的中后台前端解决方案。',
|
describe: '基于Vue3 + Element-Plus 的中后台前端解决方案。',
|
||||||
signInTitle: '用户登录',
|
signInTitle: '用户登录',
|
||||||
rememberMe: '记住我',
|
accountLogin: '账号登录',
|
||||||
|
mobileLogin: '手机号登录',
|
||||||
|
rememberMe: '24小时免登录',
|
||||||
forgetPassword: '忘记密码',
|
forgetPassword: '忘记密码',
|
||||||
signIn: '登录',
|
signIn: '登录',
|
||||||
signInOther: '其他登录方式',
|
signInOther: '其他登录方式',
|
||||||
|
|
@ -12,7 +14,18 @@ export default {
|
||||||
PWPlaceholder: '请输入密码',
|
PWPlaceholder: '请输入密码',
|
||||||
PWError: '请输入密码',
|
PWError: '请输入密码',
|
||||||
admin: '管理员',
|
admin: '管理员',
|
||||||
user: '用户'
|
user: '用户',
|
||||||
|
mobilePlaceholder: '手机号码',
|
||||||
|
mobileError: '请输入手机号码',
|
||||||
|
smsPlaceholder: '短信验证码',
|
||||||
|
smsError: '请输入短信验证码',
|
||||||
|
smsGet: '获取验证码',
|
||||||
|
smsSent: '已发送短信至手机号码',
|
||||||
|
noAccount: '还没有账号?',
|
||||||
|
createAccount: '创建新账号',
|
||||||
|
wechatLoginTitle: '二维码登录',
|
||||||
|
wechatLoginMsg: '请使用微信扫一扫登录 | 模拟3秒后自动扫描',
|
||||||
|
wechatLoginResult: '已扫描 | 请在设备中点击授权登录'
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
dynamic: '近期动态',
|
dynamic: '近期动态',
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,11 @@ router.beforeEach(async (to, from, next) => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(routes.findIndex(r => r.path === to.path) >= 0){
|
||||||
|
next();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!token){
|
if(!token){
|
||||||
next({
|
next({
|
||||||
path: '/login'
|
path: '/login'
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,24 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: "/login",
|
||||||
component: () => import(/* webpackChunkName: "login" */ '@/views/userCenter/login'),
|
component: () => import(/* webpackChunkName: "login" */ '@/views/login'),
|
||||||
meta: {
|
meta: {
|
||||||
title: "登录"
|
title: "登录"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/user_register",
|
||||||
|
component: () => import(/* webpackChunkName: "userRegister" */ '@/views/login/userRegister'),
|
||||||
|
meta: {
|
||||||
|
title: "注册"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/reset_password",
|
||||||
|
component: () => import(/* webpackChunkName: "resetPassword" */ '@/views/login/resetPassword'),
|
||||||
|
meta: {
|
||||||
|
title: "重置密码"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,4 +43,8 @@
|
||||||
.adminui-main > .el-container > .el-container > .el-header .right-panel {display: block;margin-top: 15px;}
|
.adminui-main > .el-container > .el-container > .el-header .right-panel {display: block;margin-top: 15px;}
|
||||||
|
|
||||||
.sc-page {width: 100%;margin: 0;}
|
.sc-page {width: 100%;margin: 0;}
|
||||||
|
|
||||||
|
.common-main .el-form {width: 100% !important;}
|
||||||
|
.common-header-logo label {display: none;}
|
||||||
|
.common-header-title {display: none;}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,24 @@
|
||||||
.header-tabs .el-tabs__nav {border-radius: 0 !important;}
|
.header-tabs .el-tabs__nav {border-radius: 0 !important;}
|
||||||
.header-tabs .el-tabs__item {font-size: 13px;}
|
.header-tabs .el-tabs__item {font-size: 13px;}
|
||||||
.header-tabs .el-tabs__item.is-active {background-color: var(--el-bg-color-overlay);}
|
.header-tabs .el-tabs__item.is-active {background-color: var(--el-bg-color-overlay);}
|
||||||
|
|
||||||
|
/*common-page*/
|
||||||
|
.common-page {}
|
||||||
|
.common-header-left {display: flex;align-items: center;}
|
||||||
|
.common-header-logo {display: flex;align-items: center;}
|
||||||
|
.common-header-logo img {height:30px;margin-right: 10px;vertical-align: bottom;}
|
||||||
|
.common-header-logo label {font-size: 20px;}
|
||||||
|
.common-header-title {font-size: 16px;border-left: 1px solid var(--el-border-color-light);margin-left: 15px;padding-left: 15px;}
|
||||||
|
.common-header-right {display: flex;align-items: center;}
|
||||||
|
.common-header-right a {font-size: 14px;color: var(--el-color-primary);cursor: pointer;}
|
||||||
|
.common-header-right a:hover {color: var(--el-color-primary-light-3);}
|
||||||
|
.common-container {max-width: 1240px;margin:30px auto 30px auto;}
|
||||||
|
.common-main {padding:20px;}
|
||||||
|
.common-title {font-size: 26px;margin-bottom: 20px;font-weight: normal;}
|
||||||
|
.common-main .el-form {width: 500px;margin:30px auto;}
|
||||||
|
.common-main .el-steps .el-step__title {font-size: 14px;}
|
||||||
|
.common-main .el-steps .el-step__icon {border: 1px solid;}
|
||||||
|
.common-main .yzm {display: flex;width: 100%;}
|
||||||
|
.common-main .yzm .el-button {margin-left: 10px;}
|
||||||
|
.common-main .link {color: var(--el-color-primary);cursor: pointer;}
|
||||||
|
.common-main .link:hover {color: var(--el-color-primary-light-3);}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<template>
|
||||||
|
<el-container>
|
||||||
|
<el-header style="height:50px;">
|
||||||
|
<div class="common-header-left">
|
||||||
|
<div class="common-header-logo">
|
||||||
|
<img :alt="$CONFIG.APP_NAME" src="img/logo.png">
|
||||||
|
<label>{{$CONFIG.APP_NAME}}</label>
|
||||||
|
</div>
|
||||||
|
<div class="common-header-title">{{title}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="common-header-right">
|
||||||
|
<router-link to="/login">返回登录</router-link>
|
||||||
|
</div>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<div class="common-container">
|
||||||
|
<h2 class="common-title">{{title}}</h2>
|
||||||
|
<div class="common-main el-card">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
title: { type: String, default: "" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
<template>
|
||||||
|
<el-form ref="loginForm" :model="form" :rules="rules" label-width="0" size="large">
|
||||||
|
<el-form-item prop="user">
|
||||||
|
<el-input v-model="form.user" prefix-icon="el-icon-user" clearable :placeholder="$t('login.userPlaceholder')">
|
||||||
|
<template #append>
|
||||||
|
<el-select v-model="userType" style="width: 130px;">
|
||||||
|
<el-option :label="$t('login.admin')" value="admin"></el-option>
|
||||||
|
<el-option :label="$t('login.user')" value="user"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input v-model="form.password" prefix-icon="el-icon-lock" clearable show-password :placeholder="$t('login.PWPlaceholder')"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item style="margin-bottom: 10px;">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-checkbox :label="$t('login.rememberMe')" v-model="form.autologin"></el-checkbox>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12" class="login-forgot">
|
||||||
|
<router-link to="/reset_password">{{ $t('login.forgetPassword') }}?</router-link>
|
||||||
|
</el-col>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" style="width: 100%;" :loading="islogin" round @click="login">{{ $t('login.signIn') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="login-reg">
|
||||||
|
{{$t('login.noAccount')}} <router-link to="/user_register">{{$t('login.createAccount')}}</router-link>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userType: 'admin',
|
||||||
|
form: {
|
||||||
|
user: "admin",
|
||||||
|
password: "admin",
|
||||||
|
autologin: false
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
user: [
|
||||||
|
{required: true, message: this.$t('login.userError'), trigger: 'blur'}
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{required: true, message: this.$t('login.PWError'), trigger: 'blur'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
islogin: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
userType(val){
|
||||||
|
if(val == 'admin'){
|
||||||
|
this.form.user = 'admin'
|
||||||
|
this.form.password = 'admin'
|
||||||
|
}else if(val == 'user'){
|
||||||
|
this.form.user = 'user'
|
||||||
|
this.form.password = 'user'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async login(){
|
||||||
|
|
||||||
|
var validate = await this.$refs.loginForm.validate().catch(()=>{})
|
||||||
|
if(!validate){ return false }
|
||||||
|
|
||||||
|
this.islogin = true
|
||||||
|
var data = {
|
||||||
|
username: this.form.user,
|
||||||
|
password: this.$TOOL.crypto.MD5(this.form.password)
|
||||||
|
}
|
||||||
|
//获取token
|
||||||
|
var user = await this.$API.auth.token.post(data)
|
||||||
|
if(user.code == 200){
|
||||||
|
this.$TOOL.cookie.set("TOKEN", user.data.token, {
|
||||||
|
expires: this.form.autologin? 24*60*60 : 0
|
||||||
|
})
|
||||||
|
this.$TOOL.data.set("USER_INFO", user.data.userInfo)
|
||||||
|
}else{
|
||||||
|
this.islogin = false
|
||||||
|
this.$message.warning(user.message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
//获取菜单
|
||||||
|
var menu = null
|
||||||
|
if(this.form.user == 'admin'){
|
||||||
|
menu = await this.$API.system.menu.myMenus.get()
|
||||||
|
}else{
|
||||||
|
menu = await this.$API.demo.menu.get()
|
||||||
|
}
|
||||||
|
if(menu.code == 200){
|
||||||
|
if(menu.data.menu.length==0){
|
||||||
|
this.islogin = false
|
||||||
|
this.$alert("当前用户无任何菜单权限,请联系系统管理员", "无权限访问", {
|
||||||
|
type: 'error',
|
||||||
|
center: true
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this.$TOOL.data.set("MENU", menu.data.menu)
|
||||||
|
this.$TOOL.data.set("PERMISSIONS", menu.data.permissions)
|
||||||
|
}else{
|
||||||
|
this.islogin = false
|
||||||
|
this.$message.warning(menu.message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$router.replace({
|
||||||
|
path: '/'
|
||||||
|
})
|
||||||
|
this.$message.success("Login Success 登录成功")
|
||||||
|
this.islogin = false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<template>
|
||||||
|
<el-form ref="loginForm" :model="form" :rules="rules" label-width="0" size="large">
|
||||||
|
<el-form-item prop="phone">
|
||||||
|
<el-input v-model="form.phone" prefix-icon="el-icon-iphone" clearable :placeholder="$t('login.mobilePlaceholder')">
|
||||||
|
<template #prepend>+86</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="yzm" style="margin-bottom: 35px;">
|
||||||
|
<div class="login-msg-yzm">
|
||||||
|
<el-input v-model="form.yzm" prefix-icon="el-icon-unlock" clearable :placeholder="$t('login.smsPlaceholder')"></el-input>
|
||||||
|
<el-button @click="getYzm" :disabled="disabled">{{this.$t('login.smsGet')}}<span v-if="disabled"> ({{time}})</span></el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" style="width: 100%;" :loading="islogin" round @click="login">{{ $t('login.signIn') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="login-reg">
|
||||||
|
{{$t('login.noAccount')}} <router-link to="/user_register">{{$t('login.createAccount')}}</router-link>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
phone: "",
|
||||||
|
yzm: "",
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
phone: [
|
||||||
|
{required: true, message: this.$t('login.mobileError')}
|
||||||
|
],
|
||||||
|
yzm: [
|
||||||
|
{required: true, message: this.$t('login.smsError')}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
disabled: false,
|
||||||
|
time: 0,
|
||||||
|
islogin: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getYzm(){
|
||||||
|
var validate = await this.$refs.loginForm.validateField("phone").catch(()=>{})
|
||||||
|
if(!validate){ return false }
|
||||||
|
|
||||||
|
this.$message.success(this.$t('login.smsSent'))
|
||||||
|
this.disabled = true
|
||||||
|
this.time = 60
|
||||||
|
var t = setInterval(() => {
|
||||||
|
this.time -= 1
|
||||||
|
if(this.time < 1){
|
||||||
|
clearInterval(t)
|
||||||
|
this.disabled = false
|
||||||
|
this.time = 0
|
||||||
|
}
|
||||||
|
},1000)
|
||||||
|
},
|
||||||
|
async login(){
|
||||||
|
var validate = await this.$refs.loginForm.validate().catch(()=>{})
|
||||||
|
if(!validate){ return false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -42,64 +42,44 @@
|
||||||
<img :alt="$CONFIG.APP_NAME" src="img/logo.png">
|
<img :alt="$CONFIG.APP_NAME" src="img/logo.png">
|
||||||
<label>{{$CONFIG.APP_NAME}}</label>
|
<label>{{$CONFIG.APP_NAME}}</label>
|
||||||
</div>
|
</div>
|
||||||
<h2>{{ $t('login.signInTitle') }}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
<el-form ref="loginForm" :model="ruleForm" :rules="rules" label-width="0" size="large">
|
<el-tabs>
|
||||||
<el-form-item prop="user">
|
<el-tab-pane :label="$t('login.accountLogin')" lazy>
|
||||||
<el-input v-model="ruleForm.user" prefix-icon="el-icon-user" clearable :placeholder="$t('login.userPlaceholder')">
|
<password-form></password-form>
|
||||||
<template #append>
|
</el-tab-pane>
|
||||||
<el-select v-model="userType" style="width: 130px;">
|
<el-tab-pane :label="$t('login.mobileLogin')" lazy>
|
||||||
<el-option :label="$t('login.admin')" value="admin"></el-option>
|
<phone-form></phone-form>
|
||||||
<el-option :label="$t('login.user')" value="user"></el-option>
|
</el-tab-pane>
|
||||||
</el-select>
|
</el-tabs>
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item prop="password">
|
|
||||||
<el-input v-model="ruleForm.password" prefix-icon="el-icon-lock" clearable show-password :placeholder="$t('login.PWPlaceholder')"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item style="margin-bottom: 10px;">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-checkbox :label="$t('login.rememberMe')" v-model="ruleForm.autologin"></el-checkbox>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12" style="text-align: right;">
|
|
||||||
<el-link type="primary" :underline="false">{{ $t('login.forgetPassword') }}?</el-link>
|
|
||||||
</el-col>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" style="width: 100%;" :loading="islogin" round @click="login">{{ $t('login.signIn') }}</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-divider>{{ $t('login.signInOther') }}</el-divider>
|
<el-divider>{{ $t('login.signInOther') }}</el-divider>
|
||||||
|
|
||||||
<div class="login-oauth">
|
<div class="login-oauth">
|
||||||
<el-button size="small" type="success" icon="sc-icon-wechat" circle></el-button>
|
<el-button type="success" icon="sc-icon-wechat" circle @click="wechatLogin"></el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<el-dialog v-model="showWechatLogin" :title="$t('login.wechatLoginTitle')" :width="400" destroy-on-close>
|
||||||
|
<div class="qrCodeLogin">
|
||||||
|
<sc-qr-code class="qrCode" :text="WechatLoginCode" :size="200"></sc-qr-code>
|
||||||
|
<p class="msg">{{$tc('login.wechatLoginMsg', 1)}}<br/>{{$tc('login.wechatLoginMsg', 2)}}</p>
|
||||||
|
<div class="qrCodeLogin-result" v-if="isWechatLoginResult">
|
||||||
|
<el-result icon="success" :title="$tc('login.wechatLoginResult', 1)" :sub-title="$tc('login.wechatLoginResult', 2)"></el-result>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import passwordForm from './components/passwordForm'
|
||||||
|
import phoneForm from './components/phoneForm'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
passwordForm,
|
||||||
|
phoneForm
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
userType: 'admin',
|
|
||||||
ruleForm: {
|
|
||||||
user: "admin",
|
|
||||||
password: "admin",
|
|
||||||
autologin: false
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
user: [
|
|
||||||
{required: true, message: this.$t('login.userError'), trigger: 'blur'}
|
|
||||||
],
|
|
||||||
password: [
|
|
||||||
{required: true, message: this.$t('login.PWError'), trigger: 'blur'}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
islogin: false,
|
|
||||||
config: {
|
config: {
|
||||||
lang: this.$TOOL.data.get('APP_LANG') || this.$CONFIG.LANG,
|
lang: this.$TOOL.data.get('APP_LANG') || this.$CONFIG.LANG,
|
||||||
dark: this.$TOOL.data.get('APP_DARK') || false
|
dark: this.$TOOL.data.get('APP_DARK') || false
|
||||||
|
|
@ -117,19 +97,13 @@
|
||||||
name: '日本語',
|
name: '日本語',
|
||||||
value: 'ja',
|
value: 'ja',
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
WechatLoginCode: "",
|
||||||
|
showWechatLogin: false,
|
||||||
|
isWechatLoginResult: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch:{
|
watch:{
|
||||||
userType(val){
|
|
||||||
if(val == 'admin'){
|
|
||||||
this.ruleForm.user = 'admin'
|
|
||||||
this.ruleForm.password = 'admin'
|
|
||||||
}else if(val == 'user'){
|
|
||||||
this.ruleForm.user = 'user'
|
|
||||||
this.ruleForm.password = 'user'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'config.dark'(val){
|
'config.dark'(val){
|
||||||
if(val){
|
if(val){
|
||||||
document.documentElement.classList.add("dark")
|
document.documentElement.classList.add("dark")
|
||||||
|
|
@ -156,63 +130,19 @@
|
||||||
console.log('%c SCUI %c Gitee: https://gitee.com/lolicode/scui', 'background:#666;color:#fff;border-radius:3px;', '')
|
console.log('%c SCUI %c Gitee: https://gitee.com/lolicode/scui', 'background:#666;color:#fff;border-radius:3px;', '')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async login(){
|
|
||||||
|
|
||||||
var validate = await this.$refs.loginForm.validate().catch(()=>{})
|
|
||||||
if(!validate){ return false }
|
|
||||||
|
|
||||||
this.islogin = true
|
|
||||||
var data = {
|
|
||||||
username: this.ruleForm.user,
|
|
||||||
password: this.$TOOL.crypto.MD5(this.ruleForm.password)
|
|
||||||
}
|
|
||||||
//获取token
|
|
||||||
var user = await this.$API.auth.token.post(data)
|
|
||||||
if(user.code == 200){
|
|
||||||
this.$TOOL.cookie.set("TOKEN", user.data.token, {
|
|
||||||
expires: this.ruleForm.autologin? 24*60*60 : 0
|
|
||||||
})
|
|
||||||
this.$TOOL.data.set("USER_INFO", user.data.userInfo)
|
|
||||||
}else{
|
|
||||||
this.islogin = false
|
|
||||||
this.$message.warning(user.message)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
//获取菜单
|
|
||||||
var menu = null
|
|
||||||
if(this.ruleForm.user == 'admin'){
|
|
||||||
menu = await this.$API.system.menu.myMenus.get()
|
|
||||||
}else{
|
|
||||||
menu = await this.$API.demo.menu.get()
|
|
||||||
}
|
|
||||||
if(menu.code == 200){
|
|
||||||
if(menu.data.menu.length==0){
|
|
||||||
this.islogin = false
|
|
||||||
this.$alert("当前用户无任何菜单权限,请联系系统管理员", "无权限访问", {
|
|
||||||
type: 'error',
|
|
||||||
center: true
|
|
||||||
})
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
this.$TOOL.data.set("MENU", menu.data.menu)
|
|
||||||
this.$TOOL.data.set("PERMISSIONS", menu.data.permissions)
|
|
||||||
}else{
|
|
||||||
this.islogin = false
|
|
||||||
this.$message.warning(menu.message)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$router.replace({
|
|
||||||
path: '/'
|
|
||||||
})
|
|
||||||
this.$message.success("Login Success 登录成功")
|
|
||||||
this.islogin = false
|
|
||||||
},
|
|
||||||
configDark(){
|
configDark(){
|
||||||
this.config.dark = this.config.dark ? false : true
|
this.config.dark = this.config.dark ? false : true
|
||||||
},
|
},
|
||||||
configLang(command){
|
configLang(command){
|
||||||
this.config.lang = command.value
|
this.config.lang = command.value
|
||||||
|
},
|
||||||
|
wechatLogin(){
|
||||||
|
this.showWechatLogin = true
|
||||||
|
this.WechatLoginCode = "SCUI-823677237287236-" + new Date().getTime()
|
||||||
|
this.isWechatLoginResult = false
|
||||||
|
setTimeout(()=>{
|
||||||
|
this.isWechatLoginResult = true
|
||||||
|
},3000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -234,22 +164,40 @@
|
||||||
|
|
||||||
.login_main {flex: 1;overflow: auto;display:flex;}
|
.login_main {flex: 1;overflow: auto;display:flex;}
|
||||||
.login-form {width: 400px;margin: auto;padding:20px 0;}
|
.login-form {width: 400px;margin: auto;padding:20px 0;}
|
||||||
.login-header {margin-bottom: 20px;}
|
.login-header {margin-bottom: 40px;}
|
||||||
.login-header .logo {display: flex;align-items: center;}
|
.login-header .logo {display: flex;align-items: center;}
|
||||||
.login-header .logo img {width: 35px;height: 35px;vertical-align: bottom;margin-right: 10px;}
|
.login-header .logo img {width: 40px;height: 40px;vertical-align: bottom;margin-right: 10px;}
|
||||||
.login-header .logo label {font-size: 24px;}
|
.login-header .logo label {font-size: 26px;font-weight: bold;}
|
||||||
.login-header h2 {font-size: 24px;font-weight: bold;margin-top: 50px;}
|
|
||||||
.login-oauth {display: flex;justify-content:space-around;}
|
.login-oauth {display: flex;justify-content:space-around;}
|
||||||
.login-form .el-divider {margin-top:40px;}
|
.login-form .el-divider {margin-top:40px;}
|
||||||
|
|
||||||
|
.login-form {}
|
||||||
|
.login-form:deep(.el-tabs) .el-tabs__header {margin-bottom: 25px;}
|
||||||
|
.login-form:deep(.el-tabs) .el-tabs__header .el-tabs__item {font-size: 14px;}
|
||||||
|
|
||||||
|
.login-form:deep(.login-forgot) {text-align: right;}
|
||||||
|
.login-form:deep(.login-forgot) a {color: var(--el-color-primary);}
|
||||||
|
.login-form:deep(.login-forgot) a:hover {color: var(--el-color-primary-light-3);}
|
||||||
|
.login-form:deep(.login-reg) {font-size: 14px;color: var(--el-text-color-primary);}
|
||||||
|
.login-form:deep(.login-reg) a {color: var(--el-color-primary);}
|
||||||
|
.login-form:deep(.login-reg) a:hover {color: var(--el-color-primary-light-3);}
|
||||||
|
|
||||||
.login_config {position: absolute;top:20px;right: 20px;}
|
.login_config {position: absolute;top:20px;right: 20px;}
|
||||||
.el-dropdown-menu__item.selected {color: var(--el-color-primary);}
|
|
||||||
|
.login-form:deep(.login-msg-yzm) {display: flex;width: 100%;}
|
||||||
|
.login-form:deep(.login-msg-yzm) .el-button {margin-left: 10px;--el-button-size:42px;}
|
||||||
|
|
||||||
|
.qrCodeLogin {text-align: center;position: relative;padding: 20px 0;}
|
||||||
|
.qrCodeLogin img.qrCode {background: #fff;padding:20px;border-radius:10px;}
|
||||||
|
.qrCodeLogin p.msg {margin-top: 15px;}
|
||||||
|
.qrCodeLogin .qrCodeLogin-result {position: absolute;top:0;left:0;right: 0;bottom: 0;text-align: center;background: var(--el-mask-color);}
|
||||||
|
|
||||||
@media (max-width: 1200px){
|
@media (max-width: 1200px){
|
||||||
.login-form {width: 340px;}
|
.login-form {width: 340px;}
|
||||||
}
|
}
|
||||||
@media (max-width: 1000px){
|
@media (max-width: 1000px){
|
||||||
.login_main {display: block;}
|
.login_main {display: block;}
|
||||||
|
.login_main .login_config {position: static;padding:20px 20px 0 20px;text-align: right;}
|
||||||
.login-form {width:100%;padding:20px 40px;}
|
.login-form {width:100%;padding:20px 40px;}
|
||||||
.login_adv {display: none;}
|
.login_adv {display: none;}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
<template>
|
||||||
|
<common-page title="重置密码">
|
||||||
|
<el-steps :active="stepActive" simple finish-status="success">
|
||||||
|
<el-step title="填写新密码" />
|
||||||
|
<el-step title="完成重置" />
|
||||||
|
</el-steps>
|
||||||
|
<el-form v-if="stepActive==0" ref="form" :model="form" :rules="rules" :label-width="120">
|
||||||
|
<el-form-item label="登录账号" prop="user">
|
||||||
|
<el-input v-model="form.user" placeholder="请输入登录账号"></el-input>
|
||||||
|
<div class="el-form-item-msg">请输入注册时填写的登录账号</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号码" prop="phone">
|
||||||
|
<el-input v-model="form.phone" placeholder="请输入手机号码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="短信验证码" prop="yzm">
|
||||||
|
<div class="yzm">
|
||||||
|
<el-input v-model="form.yzm" placeholder="请输入6位短信验证码"></el-input>
|
||||||
|
<el-button @click="getYzm" :disabled="disabled">获取验证码<span v-if="disabled"> ({{time}})</span></el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="新密码" prop="newpw">
|
||||||
|
<el-input v-model="form.newpw" show-password placeholder="请输入新密码"></el-input>
|
||||||
|
<div class="el-form-item-msg">请输入包含英文、数字的8位以上密码</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="确认新密码" prop="newpw2">
|
||||||
|
<el-input v-model="form.newpw2" show-password placeholder="请再一次输入新密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="save">提交</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-result v-if="stepActive==1" icon="success" title="密码重置成功" sub-title="请牢记自己的新密码,返回登录后使用新密码登录">
|
||||||
|
<template #extra>
|
||||||
|
<el-button type="primary" @click="backLogin">返回登录</el-button>
|
||||||
|
</template>
|
||||||
|
</el-result>
|
||||||
|
</common-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import commonPage from './components/commonPage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
commonPage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
stepActive: 0,
|
||||||
|
form: {
|
||||||
|
user: "",
|
||||||
|
phone: "",
|
||||||
|
yzm: "",
|
||||||
|
newpw: "",
|
||||||
|
newpw2: ""
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
user: [
|
||||||
|
{ required: true, message: '请输入登录账号'}
|
||||||
|
],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: '请输入手机号'}
|
||||||
|
],
|
||||||
|
yzm: [
|
||||||
|
{ required: true, message: '请输入短信验证码'}
|
||||||
|
],
|
||||||
|
newpw: [
|
||||||
|
{ required: true, message: '请输入新的密码'}
|
||||||
|
],
|
||||||
|
newpw2: [
|
||||||
|
{ required: true, message: '请再次输入新的密码'},
|
||||||
|
{validator: (rule, value, callback) => {
|
||||||
|
if (value !== this.form.newpw) {
|
||||||
|
callback(new Error('两次输入密码不一致'));
|
||||||
|
}else{
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
disabled: false,
|
||||||
|
time: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getYzm(){
|
||||||
|
var validate = await this.$refs.form.validateField("phone").catch(()=>{})
|
||||||
|
if(!validate){ return false }
|
||||||
|
|
||||||
|
this.$message.success("已发送短信至手机号码")
|
||||||
|
this.disabled = true
|
||||||
|
this.time = 60
|
||||||
|
var t = setInterval(() => {
|
||||||
|
this.time -= 1
|
||||||
|
if(this.time < 1){
|
||||||
|
clearInterval(t)
|
||||||
|
this.disabled = false
|
||||||
|
this.time = 0
|
||||||
|
}
|
||||||
|
},1000)
|
||||||
|
},
|
||||||
|
async save(){
|
||||||
|
var validate = await this.$refs.form.validate().catch(()=>{})
|
||||||
|
if(!validate){ return false }
|
||||||
|
|
||||||
|
this.stepActive = 1
|
||||||
|
},
|
||||||
|
backLogin(){
|
||||||
|
this.$router.push({
|
||||||
|
path: '/login'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
<template>
|
||||||
|
<common-page title="注册新账号">
|
||||||
|
<el-steps :active="stepActive" simple finish-status="success">
|
||||||
|
<el-step title="基础信息" />
|
||||||
|
<el-step title="详细信息" />
|
||||||
|
<el-step title="完成注册" />
|
||||||
|
</el-steps>
|
||||||
|
<el-form v-if="stepActive==0" ref="stepForm_0" :model="form" :rules="rules" :label-width="120">
|
||||||
|
<el-form-item label="登录账号" prop="user">
|
||||||
|
<el-input v-model="form.user" placeholder="请输入登录账号"></el-input>
|
||||||
|
<div class="el-form-item-msg">登录账号将作为登录时的唯一凭证</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="登录密码" prop="password">
|
||||||
|
<el-input v-model="form.password" type="password" show-password placeholder="请输入登录密码"></el-input>
|
||||||
|
<div class="el-form-item-msg">请输入包含英文、数字的8位以上密码</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="确认密码" prop="password2">
|
||||||
|
<el-input v-model="form.password2" type="password" show-password placeholder="请再一次输入登录密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="" prop="agree">
|
||||||
|
<el-checkbox v-model="form.agree" label="">已阅读并同意</el-checkbox><span class="link" @click="showAgree=true">《平台服务协议》</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-form v-if="stepActive==1" ref="stepForm_1" :model="form" :rules="rules" :label-width="120">
|
||||||
|
<el-form-item label="真实姓名" prop="userName">
|
||||||
|
<el-input v-model="form.userName" placeholder="请输入真实姓名"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="邮箱" prop="email">
|
||||||
|
<el-input v-model="form.email" placeholder="请输入邮箱地址"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="账号类型" prop="userType">
|
||||||
|
<el-radio-group v-model="form.userType">
|
||||||
|
<el-radio-button label="1">企业开发者</el-radio-button>
|
||||||
|
<el-radio-button label="2">企业开发者</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="开通类别" prop="open">
|
||||||
|
<el-checkbox-group v-model="form.open">
|
||||||
|
<el-checkbox label="1">云存储API</el-checkbox>
|
||||||
|
<el-checkbox label="2">云检索API</el-checkbox>
|
||||||
|
<el-checkbox label="3">Javescript API</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div v-if="stepActive==2">
|
||||||
|
<el-result icon="success" title="注册成功" sub-title="可以使用登录账号以及手机号登录系统">
|
||||||
|
<template #extra>
|
||||||
|
<el-button type="primary" @click="goLogin">前去登录</el-button>
|
||||||
|
</template>
|
||||||
|
</el-result>
|
||||||
|
</div>
|
||||||
|
<el-form style="text-align: center;">
|
||||||
|
<el-button v-if="stepActive>0 && stepActive<2" @click="pre">上一步</el-button>
|
||||||
|
<el-button v-if="stepActive<1" type="primary" @click="next">下一步</el-button>
|
||||||
|
<el-button v-if="stepActive==1" type="primary" @click="save">提交</el-button>
|
||||||
|
</el-form>
|
||||||
|
<el-dialog v-model="showAgree" title="平台服务协议" :width="800" destroy-on-close>
|
||||||
|
平台服务协议
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="showAgree=false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="showAgree=false;form.agree=true;">我已阅读并同意</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</common-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import commonPage from './components/commonPage'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
commonPage
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
stepActive: 0,
|
||||||
|
showAgree: false,
|
||||||
|
form: {
|
||||||
|
user: "",
|
||||||
|
password: "",
|
||||||
|
password2: "",
|
||||||
|
agree: false,
|
||||||
|
userName: "",
|
||||||
|
email: "",
|
||||||
|
userType: "1",
|
||||||
|
open: []
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
user: [
|
||||||
|
{ required: true, message: '请输入账号名'}
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{ required: true, message: '请输入密码'}
|
||||||
|
],
|
||||||
|
password2: [
|
||||||
|
{ required: true, message: '请再次输入密码'},
|
||||||
|
{validator: (rule, value, callback) => {
|
||||||
|
if (value !== this.form.password) {
|
||||||
|
callback(new Error('两次输入密码不一致'));
|
||||||
|
}else{
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
agree: [
|
||||||
|
{validator: (rule, value, callback) => {
|
||||||
|
if (!value) {
|
||||||
|
callback(new Error('请阅读并同意协议'));
|
||||||
|
}else{
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
userName: [
|
||||||
|
{ required: true, message: '请输入真实姓名'}
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{ required: true, message: '请输入邮箱地址'}
|
||||||
|
],
|
||||||
|
userType: [
|
||||||
|
{ required: true, message: '请选择账户类型'}
|
||||||
|
],
|
||||||
|
open: [
|
||||||
|
{ required: true, message: '请选择开通类别'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
pre(){
|
||||||
|
this.stepActive -= 1
|
||||||
|
},
|
||||||
|
next(){
|
||||||
|
const formName = `stepForm_${this.stepActive}`
|
||||||
|
this.$refs[formName].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.stepActive += 1
|
||||||
|
}else{
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
save(){
|
||||||
|
const formName = `stepForm_${this.stepActive}`
|
||||||
|
this.$refs[formName].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.stepActive += 1
|
||||||
|
}else{
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
goLogin(){
|
||||||
|
this.$router.push({
|
||||||
|
path: '/login'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue