切换导航条
切换导航条
当前项目
正在载入...
登录
术习电报
/
electron-vue-template
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
构建
提交
问题看板
文件
提交
网络
比较
分支
标签
作者
张恒
2019-08-17 19:10:42 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
提交
ce6bc8f25d3fb0c38a097b2849cda61b380d55c3
ce6bc8f2
1 个父辈
1ea21908
加入登录验证,配合花裤衩大大最新的远程mock结果
隐藏空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
245 行增加
和
172 行删除
.electron-vue/webpack.main.config.js
config/prod.env.js
package.json
src/main/index.js
src/renderer/api/login.js
src/renderer/api/operationalData.js
src/renderer/components/LandingPage.vue
src/renderer/components/LandingPage/SystemInformation.vue
src/renderer/components/Tinymce/dynamicLoadScript.js
src/renderer/layout/components/Navbar.vue
src/renderer/permission.js
src/renderer/router/constantRouterMap.js
src/renderer/store/getters.js
src/renderer/store/modules/user.js
src/renderer/utils/request.js
src/renderer/views/login/index.vue
src/renderer/views/home/index.vue → src/renderer/views/table/index.vue
.electron-vue/webpack.main.config.js
查看文件 @
ce6bc8f
...
...
@@ -52,6 +52,7 @@ let mainConfig = {
new
webpack
.
NoEmitOnErrorsPlugin
()
],
resolve
:
{
extensions
:
[
'.js'
,
'.json'
,
'.node'
]
},
target
:
'electron-main'
...
...
config/prod.env.js
查看文件 @
ce6bc8f
module
.
exports
=
{
NODE_ENV
:
'"production"'
,
BASE_API
:
'""'
BASE_API
:
'"
https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin
"'
}
...
...
package.json
查看文件 @
ce6bc8f
...
...
@@ -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
}
...
...
src/main/index.js
查看文件 @
ce6bc8f
...
...
@@ -5,7 +5,6 @@ import {
BrowserWindow
,
Menu
}
from
'electron'
import
'../renderer/store'
import
menuconfig
from
'./menu'
/**
...
...
src/renderer/api/login.js
查看文件 @
ce6bc8f
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
})
}
...
...
src/renderer/api/operationalData.js
查看文件 @
ce6bc8f
import
db
from
'
..
/utils/db'
import
db
from
'
@
/utils/db'
export
default
{
adddata
(
data
)
{
...
...
src/renderer/components/LandingPage.vue
查看文件 @
ce6bc8f
<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)
},
}
};
...
...
src/renderer/components/LandingPage/SystemInformation.vue
查看文件 @
ce6bc8f
<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 {
...
...
src/renderer/components/Tinymce/dynamicLoadScript.js
查看文件 @
ce6bc8f
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
)
{
...
...
src/renderer/layout/components/Navbar.vue
查看文件 @
ce6bc8f
...
...
@@ -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="
LogO
ut">
<el-dropdown-item @click.native="
logo
ut">
<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("销毁计时器------------");
...
...
src/renderer/permission.js
查看文件 @
ce6bc8f
/* 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
()
}
}
})
...
...
src/renderer/router/constantRouterMap.js
查看文件 @
ce6bc8f
...
...
@@ -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'
}
}
]
}
]
...
...
src/renderer/store/getters.js
查看文件 @
ce6bc8f
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
...
...
src/renderer/store/modules/user.js
0 → 100644
查看文件 @
ce6bc8f
/* 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
src/renderer/utils/request.js
查看文件 @
ce6bc8f
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字符串
...
...
src/renderer/views/login/index.vue
查看文件 @
ce6bc8f
<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: 0
px
;
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%;
...
...
src/renderer/views/
hom
e/index.vue
→
src/renderer/views/
tabl
e/index.vue
查看文件 @
ce6bc8f
文件被删除
请
注册
或
登录
后发表评论