张恒

加入登录验证,配合花裤衩大大最新的远程mock结果

......@@ -52,6 +52,7 @@ let mainConfig = {
new webpack.NoEmitOnErrorsPlugin()
],
resolve: {
extensions: ['.js', '.json', '.node']
},
target: 'electron-main'
......
module.exports = {
NODE_ENV: '"production"',
BASE_API: '""'
BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"'
}
......
......@@ -31,7 +31,8 @@
"dist/electron/**/*"
],
"dmg": {
"contents": [{
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
......@@ -61,6 +62,7 @@
"js-cookie": "^2.2.0",
"nedb": "^1.8.0",
"nprogress": "^0.2.0",
"sortablejs": "^1.10.0-rc3",
"vue": "^2.6.10",
"vue-electron": "^1.0.6",
"vue-router": "^3.0.7",
......@@ -132,4 +134,4 @@
"webpack-hot-middleware": "^2.25.0",
"webpack-merge": "^4.2.1"
}
}
\ No newline at end of file
}
......
......@@ -5,7 +5,6 @@ import {
BrowserWindow,
Menu
} from 'electron'
import '../renderer/store'
import menuconfig from './menu'
/**
......
import request from '@/utils/request'
export function login (username, password) {
export function login (data) {
return request({
url: '/user/login',
method: 'post',
data: {
username,
password
}
data
})
}
......
import db from '../utils/db'
import db from '@/utils/db'
export default {
adddata (data) {
......
<template>
<div id="wrapper">
<img id="logo" src="~@/assets/logo.png" alt="electron-vue">
<img id="logo" src="~@/assets/logo.png" alt="electron-vue" />
<main>
<div class="left-side">
<span class="title">Welcome to your new project!</span>
<span class="title">欢迎进入本框架</span>
<system-information></system-information>
<div v-if="textarray.length === 0">
<span>{{text}}</span>
......@@ -17,7 +17,7 @@
<div class="right-side">
<div class="doc">
<div class="title alt">Other Documentation</div>
<div class="title alt">您可以点击的按钮</div>
<el-button type="primary" round @click="open()">控制台打印</el-button>
<el-button type="primary" round @click="setdata">写入数据</el-button>
<el-button type="primary" round @click="getdata">读取数据</el-button>
......@@ -30,7 +30,7 @@
<script>
import SystemInformation from "./LandingPage/SystemInformation";
import api from '../tools/dialog'
import api from "../tools/dialog";
export default {
name: "landing-page",
components: { SystemInformation },
......@@ -45,7 +45,7 @@ export default {
methods: {
// 获取electron方法
open() {
console.log(this.$electron);
console.log(this.$store);
},
// 设置数据库的数据
setdata() {
......@@ -66,28 +66,28 @@ export default {
.catch(err => console.log(err));
},
// 清空数据库的数据
deledata(){
deledata() {
// dialog为electron实例,data则是显示需要的参数,fun是需要执行的函数,此选项不是为必选的
const dialog = this.$electron.remote.dialog
const dialog = this.$electron.remote.dialog;
const data = {
title: "清除数据",
buttons: ["OK", "Cancel"],
message: "此操作会清空本地数据库中的所有数据,是否继续?"
};
const fun = this.$db.deleall({ name: "yyy" });
api.MessageBox(dialog, data, fun).then(res => {
this.getdata();
this.$message({
showClose: true,
message: "成功删除" + res + "条",
type: "success"
});
});
// const data = {
// title:'清除数据',
// buttons:['OK', 'Cancel'],
// message:'此操作会清空本地数据库中的所有数据,是否继续?'
// title:'发生致命错误',
// message:'?'
// }
// const fun = this.$db.deleall({name:'yyy'})
// api.MessageBox(dialog,data,fun).then(res=>{
// this.getdata()
// this.$message({
// showClose: true,
// message: '成功删除'+res+'条',
// type: 'success'
// });
// })
const data = {
title:'发生致命错误',
message:'?'
}
api.ErrorMessageBox(dialog,data)
// api.ErrorMessageBox(dialog,data)
},
}
};
......
<template>
<div>
<div class="title">Information</div>
<div class="title">关于系统</div>
<div class="items">
<div class="item">
<div class="name">Path:</div>
<div class="name">当前所在页面:</div>
<div class="value">{{ path }}</div>
</div>
<div class="item">
<div class="name">Route Name:</div>
<div class="name">当前页面名称:</div>
<div class="value">{{ name }}</div>
</div>
<div class="item">
<div class="name">Vue.js:</div>
<div class="name">Vue.js版本:</div>
<div class="value">{{ vue }}</div>
</div>
<div class="item">
<div class="name">Electron:</div>
<div class="name">Electron版本:</div>
<div class="value">{{ electron }}</div>
</div>
<div class="item">
<div class="name">Node:</div>
<div class="name">Node版本:</div>
<div class="value">{{ node }}</div>
</div>
<div class="item">
<div class="name">Platform:</div>
<div class="name">所运行的系统:</div>
<div class="value">{{ platform }}</div>
</div>
</div>
......@@ -41,6 +41,9 @@
platform: require('os').platform(),
vue: require('vue/package.json').version
}
},
mounted(){
console.log(this.$route)
}
}
</script>
......@@ -58,7 +61,9 @@
.item {
display: flex;
align-items: center;
margin-bottom: 6px;
line-height: 24px;
}
.item .name {
......
let callbacks = []
function loadedTinymce() {
function loadedTinymce () {
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
// check is successfully downloaded script
return window.tinymce
......@@ -8,7 +8,7 @@ function loadedTinymce() {
const dynamicLoadScript = (src, callback) => {
const existingScript = document.getElementById(src)
const cb = callback || function() {}
const cb = callback || function () {}
if (!existingScript) {
const script = document.createElement('script')
......@@ -28,8 +28,8 @@ const dynamicLoadScript = (src, callback) => {
}
}
function stdOnEnd(script) {
script.onload = function() {
function stdOnEnd (script) {
script.onload = function () {
// this.onload = null here is necessary
// because even IE9 works not like others
this.onerror = this.onload = null
......@@ -38,14 +38,14 @@ const dynamicLoadScript = (src, callback) => {
}
callbacks = null
}
script.onerror = function() {
script.onerror = function () {
this.onerror = this.onload = null
cb(new Error('无法加载 ' + src), script)
}
}
function ieOnEnd(script) {
script.onreadystatechange = function() {
function ieOnEnd (script) {
script.onreadystatechange = function () {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
this.onreadystatechange = null
for (const cb of callbacks) {
......
......@@ -21,7 +21,7 @@
</div>
</el-image>
<div class="el-dropdown-link">
这里是用户名
尊敬的: {{name}}
<i class="el-icon-arrow-down el-icon--right"></i>
</div>
</div>
......@@ -29,10 +29,10 @@
<router-link to="/">
<el-dropdown-item>返回首页</el-dropdown-item>
</router-link>
<el-dropdown-item @click.native="change_user">
<el-dropdown-item @click.native="logout">
<span>切换账号</span>
</el-dropdown-item>
<el-dropdown-item @click.native="LogOut">
<el-dropdown-item @click.native="logout">
<span>退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
......@@ -55,7 +55,7 @@ export default {
},
data: () => ({
time: "",
userImage:require('@/assets/user.png')
userImage: require("@/assets/user.png")
}),
mounted() {
this.set_time();
......@@ -69,25 +69,11 @@ export default {
},
logout() {
this.$store.dispatch("LogOut").then(() => {
location.reload(); // 为了重新实例化vue-router对象 避免bug
});
},
change_user() {
this.$store.dispatch("LogOut").then(() => {
this.$message({
message: "退出成功",
type: "success"
});
this.$router.push({ path: "/new/login", query: { to: "server" } });
});
},
LogOut() {
this.$store.dispatch("LogOut").then(() => {
this.$message({
message: "退出成功",
type: "success"
});
this.$router.push("/");
location.reload(); // 为了重新实例化vue-router对象 避免bug
});
},
set_time() {
......@@ -95,7 +81,7 @@ export default {
}
},
computed: {
...mapGetters(["user_data", "sidebar"])
...mapGetters(["name", "role", "sidebar"])
},
beforeDestroy() {
console.log("销毁计时器------------");
......
/* eslint-disable no-tabs */
import router from './router'
import store from './store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
// import { Message } from 'element-ui'
import { Message } from 'element-ui'
// const whiteList = ['/login'] // 不重定向白名单
const whiteList = ['/login'] // 不重定向白名单
router.beforeEach((to, from, next) => {
NProgress.start()
if (store.getters.token) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
} else {
// if (store.getters.roles.length === 0) {
// store.dispatch('GetInfo').then(res => { // 拉取用户信息
// next()
// }).catch((err) => {
// store.dispatch('FedLogOut').then(() => {
// Message.error(err || '请重新登录')
// next({ path: '/' })
// })
// })
// } else {
// next()
// }
if (store.getters.roles.length === 0) {
store.dispatch('GetInfo').then(res => { // 拉取用户信息
next()
}).catch((err) => {
store.dispatch('FedLogOut').then(() => {
Message.error(err || 'Verification failed, please login again')
next({ path: '/' })
})
})
} else {
next()
}
}
} else {
// if (whiteList.indexOf(to.path) !== -1) {
// next()
// } else {
// next('/login')
// NProgress.done()
// }
next()
NProgress.done()
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next('/login')
NProgress.done()
}
}
})
......
......@@ -32,10 +32,11 @@ export default [
path: '/',
component: Layout,
redirect: '/dashboard',
name: 'Dashboard',
name: '主页',
hidden: true,
children: [{
path: 'dashboard',
name: '总览',
component: () => import('@/components/LandingPage')
}]
},
......@@ -51,5 +52,17 @@ export default [
meta: { title: '表单', icon: 'form' }
}
]
},
{
path: '/table',
component: Layout,
children: [
{
path: 'index',
name: '表格',
component: () => import('@/views/table/index'),
meta: { title: '表格', icon: 'table' }
}
]
}
]
......
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
roles: state => state.user.roles
}
export default getters
......
/* eslint-disable prefer-promise-reject-errors */
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
const user = {
state: {
token: getToken(),
name: '',
avatar: '',
roles: []
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
}
},
actions: {
// 登录
Login ({ commit }, userInfo) {
console.log(userInfo)
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
const data = {
username: username,
password: userInfo.password
}
login(data).then(response => {
const data = response.data.data
setToken(data.token)
commit('SET_TOKEN', data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo ({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const data = response.data.data
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', data.roles)
} else {
reject('getInfo: roles must be a non-null array !')
}
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
resolve(response)
}).catch(error => {
reject(error)
})
})
},
// 登出
LogOut ({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut ({ commit }) {
return new Promise(resolve => {
removeToken()
commit('SET_TOKEN', '')
resolve()
})
}
}
}
export default user
import axios from 'axios'
import {
Message
} from 'element-ui'
import { Message } from 'element-ui'
const serves = axios.create({
baseURL: process.env.BASE_API,
timeout: 5000
......@@ -9,8 +7,6 @@ const serves = axios.create({
// 设置请求发送之前的拦截器
serves.interceptors.request.use(config => {
console.log(config)
console.log(process.env)
// 设置发送之前数据需要做什么处理
return config
}, err => Promise.reject(err))
......@@ -18,6 +14,9 @@ serves.interceptors.request.use(config => {
// 设置请求接受拦截器
serves.interceptors.response.use(res => {
// 设置接受数据之后,做什么处理
if (res.data.code === 50000) {
Message.error(res.data.data)
}
return res
}, err => {
// 判断请求异常信息中是否含有超时timeout字符串
......
<template>
<div class="login-container">
<el-form
class="login-form"
autocomplete="on"
:model="loginForm"
:rules="loginRules"
ref="loginForm"
label-position="left"
>
<h3 class="title">vue-element-admin</h3>
<el-form class="login-form" autoComplete="on" :model="loginForm" :rules="loginRules" ref="loginForm" label-position="left">
<h3 class="title">后台管理框架</h3>
<el-form-item prop="username">
<span class="svg-container svg-container_login">
<svg-icon icon-class="user" />
</span>
<el-input
name="username"
type="text"
v-model="loginForm.username"
autocomplete="on"
placeholder="用户名"
/>
<el-input name="username" type="text" v-model="loginForm.username" autoComplete="on" placeholder="用户名" />
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password"></svg-icon>
</span>
<el-input
name="password"
:type="pwdType"
@keyup.enter.native="handleLogin"
v-model="loginForm.password"
autocomplete="on"
placeholder="密码"
></el-input>
<span class="show-pwd" @click="showPwd">
<svg-icon icon-class="eye" />
</span>
<el-input name="password" :type="pwdType" @keyup.enter.native="handleLogin" v-model="loginForm.password" autoComplete="on"
placeholder="密码"></el-input>
<span class="show-pwd" @click="showPwd"><svg-icon icon-class="eye" /></span>
</el-form-item>
<el-form-item>
<el-button
type="primary"
style="width:100%;"
:loading="loading"
@click.native.prevent="handleLogin"
>登录</el-button>
<el-button type="primary" style="width:100%;" :loading="loading" @click.native.prevent="handleLogin">
登录
</el-button>
</el-form-item>
<div class="tips">
<span style="margin-right:20px;">username: admin</span>
<span>password: admin</span>
<span style="margin-right:20px;">用户名: admin</span>
<span> 密码:随便什么都行</span>
</div>
</el-form>
</div>
</template>
<script>
import { isvalidUsername } from "@/utils/validate";
import { login } from "@/api/login";
import { isvalidUsername } from '@/utils/validate'
export default {
name: "login",
name: 'login',
data() {
const validateUsername = (rule, value, callback) => {
if (!isvalidUsername(value)) {
callback(new Error("请输入正确的用户名"));
callback(new Error('请输入正确的用户名'))
} else {
callback();
callback()
}
};
}
const validatePass = (rule, value, callback) => {
if (value.length < 5) {
callback(new Error("密码不能小于5位"));
callback(new Error('密码不能小于5位'))
} else {
callback();
callback()
}
};
}
return {
loginForm: {
username: "admin",
password: "admin"
username: 'admin',
password: 'admin'
},
loginRules: {
username: [
{ required: true, trigger: "blur", validator: validateUsername }
],
password: [{ required: true, trigger: "blur", validator: validatePass }]
username: [{ required: true, trigger: 'blur', validator: validateUsername }],
password: [{ required: true, trigger: 'blur', validator: validatePass }]
},
loading: false,
pwdType: "password"
};
pwdType: 'password'
}
},
methods: {
showPwd() {
if (this.pwdType === "password") {
this.pwdType = "";
if (this.pwdType === 'password') {
this.pwdType = ''
} else {
this.pwdType = "password";
this.pwdType = 'password'
}
},
handleLogin() {
this.loading = true;
console.log(11111)
this.$refs.loginForm.validate(valid => {
console.log(valid)
if (valid) {
// this.$store.dispatch('Login', this.loginForm).then(() => {
this.loading = false;
this.$router.push({ path: "/" });
// login(this.loginForm).then(res=>console.log(res))
// }).catch(() => {
// this.loading = false
// })
this.loading = true
this.$store.dispatch('Login', this.loginForm).then(() => {
this.loading = false
this.$router.push({ path: '/' })
}).catch(() => {
this.loading = false
})
} else {
console.log("输入错误");
return false;
console.log('error submit!!')
return false
}
});
})
}
}
};
}
</script>
<style rel="stylesheet/scss" lang="scss">
$bg: #2d3a4b;
$light_gray: #eee;
$bg:#2d3a4b;
$light_gray:#eee;
/* reset element-ui css */
.login-container {
left: 0px;
left: 0;
.el-input {
display: inline-block;
height: 47px;
......@@ -149,12 +124,13 @@ $light_gray: #eee;
color: #454545;
}
}
</style>
<style rel="stylesheet/scss" lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
$bg:#2d3a4b;
$dark_gray:#889aa4;
$light_gray:#eee;
.login-container {
position: fixed;
height: 100%;
......