Browse Source

提交代码

master
刘力 4 years ago
parent
commit
30554d0455
  1. 16
      src/api/login.js
  2. 45
      src/api/system/menu.js
  3. 2
      src/components/ParentView/index.vue
  4. 37
      src/layout/TopMenus.vue
  5. 0
      src/layout/index.vue
  6. 22
      src/main.js
  7. 20
      src/router/index.js
  8. 18
      src/router/routers.js
  9. 14
      src/settings.js
  10. 4
      src/store/index.js
  11. 16
      src/store/modules/api.js
  12. 8
      src/store/modules/permission.js
  13. 10
      src/utils/auth.js
  14. 2
      src/utils/index.js
  15. 8
      src/utils/permission.js
  16. 66
      src/utils/request.js
  17. 12
      src/utils/rsaEncrypt.js
  18. 77
      src/views/login.vue

16
src/api/login.js

@ -1,14 +1,12 @@
/*
* @Author: liu·li
* @Date: 2021-09-Fr 05:18:30
* @Last Modified by: mikey.zhaopeng
* @Last
* @Last Modified time: 2021-09-Fr 05:18:30
*/
import request from '@/utils/request'
//登录方法
// 登录方法
export function login(username, password, code, uuid) {
return request({
url: 'auth/login',
@ -22,16 +20,15 @@ export function login(username, password, code, uuid) {
})
}
//获取用户信息
// 获取用户信息
export function getInfo() {
return request({
url: 'auth/info',
method: 'get',
method: 'get'
})
}
//获取验证码
// 获取验证码
export function getCodeImg() {
return request({
url: 'auth/code',
@ -39,8 +36,7 @@ export function getCodeImg() {
})
}
//登出方法
// 登出方法
export function logout() {
return request({
url: 'auth/logout',

45
src/api/system/menu.js

@ -1,11 +1,11 @@
import request from '@/utils/request';
import request from '@/utils/request'
//根据pid 获取菜单
// 根据pid 获取菜单
export function getMenusTree(pid) {
return request({
url: 'api/menus/lazy?pid=' + pid,
method: 'get'
});
})
}
export function getMenus(params) {
@ -13,71 +13,54 @@ export function getMenus(params) {
url: 'api/menus',
method: 'get',
params
});
})
}
//根据id获取上级菜单
export function getMenuSuperior(ids) {
const data = ids.length || ids.length === 0 ? ids : Array.of(ids);
const data = ids.length || ids.length === 0 ? ids : Array.of(ids)
return request({
url: 'api/menus/superior',
method: 'post',
data
});
})
}
//获取子菜单
export function getChild(id) {
return request({
url: 'api/menus/child?id=' + id,
method: 'get'
});
})
}
//构建菜单
export function buildMenus() {
return request({
url: 'api/menus',
method: 'post',
data
});
url: 'api/menus/build',
method: 'get'
})
}
//新增菜单
export function add(data) {
return request({
url: 'api/menus',
method: 'post',
data
});
})
}
//删除菜单
export function del(ids) {
return request({
url: 'api/menus',
method: 'delete',
data: ids
});
})
}
//修改菜单
export function edit(data) {
return request({
url: 'api/menus',
method: 'put',
data
});
})
}
export default {
add,
edit,
del,
getMenus,
getMenusTree,
getMenuSuperior,
getChild,
getMenusTree
};
export default { add, edit, del, getMenus, getMenusTree, getMenuSuperior, getChild }

2
src/components/ParentView/index.vue

@ -1,3 +1,3 @@
<template>
<router-view/>
<router-view />
</template>

37
src/layout/TopMenus.vue

@ -1,30 +1,27 @@
<template>
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="1">处理中心</el-menu-item>
<el-submenu index="2">
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4"><a href="https://www.ele.me" target="_blank">订单管理</a></el-menu-item>
<el-menu :default-active="activeMenu" :background-color="variables.menuBg" :text-color="variables.menuText" :active-text-color="variables.menuActiveText" :collapse-transition="false" mode="horizontal">
<sidebar-item v-for="route in sidebarRouters" :key="route.path" :item="route" :base-path="route.path" />
</el-menu>
</template>
<script>
import { mapGetters } from 'vuex'
import variables from '@/assets/styles/variables.scss'
export default {
name: 'TopMenus',
data() {
return {
activeIndex: '1',
activeIndex2: '1'
computed: {
...mapGetters(['sidebarRouters', 'sidebar']),
activeMenu() {
const route = this.$route
const { meta, path } = route
if (meta.activeMenu) {
return meta.activeMenu
}
return path
},
variables() {
return variables
}
},
methods: {

0
src/layout/index.vue

22
src/main.js

@ -10,21 +10,21 @@ import store from './store'
import 'element-ui/lib/theme-chalk/index.css'
// 加载权限控制
//import './router/index'
import './router/index'
//加载权限指令
//import checkPer from '@/utils/permission'
//import permission from './components/Permission'
// 加载权限指令
import checkPer from '@/utils/permission'
import permission from './components/Permission'
import './assets/styles/element-variables.scss'
//全局CSS
//import './assets/styles/index.scss'
// 全局CSS
// import './assets/styles/index.scss'
// 代码高亮
import VueHighlightJS from 'vue-highlightjs'
import 'highlight.js/styles/atom-one-dark.css'
//icon
//import './assets/icons'
// icon
// import './assets/icons'
// 加载代码高亮
Vue.use(VueHighlightJS)
@ -33,9 +33,9 @@ Vue.use(ElementUI, {
// 设置element-ui默认大小
size: Cookies.get('size') || 'small'
})
//加载权限指令
//Vue.use(checkPer)
//Vue.use(permission)
// 加载权限指令
Vue.use(checkPer)
Vue.use(permission)
Vue.config.productionTip = false
new Vue({

20
src/router/index.js

@ -74,15 +74,9 @@ export const loadMenus = (next, to) => {
buildMenus().then(res => {
const sdata = JSON.parse(JSON.stringify(res))
const rdata = JSON.parse(JSON.stringify(res))
const sidebarRoutes = filterAsyncRouter()
})
rewriteRoutes.push({
path: '*',
redirect: '/404',
hidden: true
})
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, true)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
// 存储路由
store.dispatch('GenerateRoutes', rewriteRoutes).then(() => {
/*
@ -98,14 +92,12 @@ export const loadMenus = (next, to) => {
* 告诉VUE本次操作后
* 不能通过浏览器后退按钮返回前一个路由
*/
next({
// ...to,
replace: true
})
next({ ...to, replace: true })
})
store.dispatch('SetSidebarRouters', sidebarRoutes)
})
}
// 进度条
router.afterEach(() => {
NProgress.done()
})

18
src/router/routers.js

@ -1,14 +1,28 @@
import Vue from 'vue'
import Router from 'vue-router'
import Layout from '../layout/index'
Vue.use(Router)
export const constantRouterMap = [
{
path: '/menu',
component: resolve => require(['@/layout/TopMenus'], resolve),
path: '/login',
meta: { title: '登录', noCache: true },
component: (resolve) => require(['@/views/login'], resolve),
hidden: true
},
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path*',
component: (resolve) => require(['@/views/features/redirect'], resolve)
}
]
}
]
export default new Router({

14
src/settings.js

@ -1,24 +1,24 @@
// 全局设置
module.exports = {
//网站标题
// 网站标题
title: '阅行资源库后台管理系统',
//记住密码状态下的token在Cookie中存储的天数,默认1天
// 记住密码状态下的token在Cookie中存储的天数,默认1天
tokenCookieExpires: 1,
//记住密码状态下的密码在Cookie中存储的天数,默认1天s
// 记住密码状态下的密码在Cookie中存储的天数,默认1天s
passCookieExpires: 1,
//token key
// token key
TokenKey: 'YXK-ADMIN-TOKEN',
//请求超时时间,毫秒(默认2分钟)
// 请求超时时间,毫秒(默认2分钟)
timeout: 1200000,
//是否显示设置底部信息
// 是否显示设置底部信息
showFooter: true,
//底部文字,支持html语法
// 底部文字,支持html语法
footerTxt:
'© 2021 <a href="https://www.aixylib.com" target="_blank">阅行后台集成管理系统</a>'
}

4
src/store/index.js

@ -4,11 +4,11 @@ import getters from './getters'
Vue.use(Vuex)
//实现自动导入模块
// 实现自动导入模块
const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
//获取上级目录modules的 所有后缀名为 .js的文件
// 获取上级目录modules的 所有后缀名为 .js的文件
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default

16
src/store/modules/api.js

@ -1,26 +1,26 @@
//适配Nginx反向代理
// 适配Nginx反向代理
const baseUrl =
process.env.VUE_APP_BASE_API === '/' ? '' : process.env.VUE_APP_BASE_API
//适配API路径
// 适配API路径
const api = {
state: {
//部署包上传
//deployUploadApi: baseUrl + '/api/deploy/upload',
// 部署包上传
// deployUploadApi: baseUrl + '/api/deploy/upload',
//图片上传
// 图片上传
imagesUplaodApi: baseUrl + '/api/localStorage/pictures',
//上传图像
// 上传图像
updateAvatarApi: baseUrl + '/api/users/updateAvatar',
//文件上传
// 文件上传
fileUploadApi: baseUrl + '/api/localStorage',
// swagger
swaggerApi: baseUrl + '/swagger-ui.html',
//基础url
// 基础url
baseApi: baseUrl
}
}

8
src/store/modules/permission.js

@ -3,13 +3,13 @@ import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
const permission = {
//存放状态
// 存放状态
state: {
routers: constantRouterMap,
addRouters: [],
sidebarRouters: []
},
//同步更改状态
// 同步更改状态
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
@ -19,7 +19,7 @@ const permission = {
state.sidebarRouters = constantRouterMap.concat(routers)
}
},
//发送异步请求拿到数据
// 发送异步请求拿到数据
actions: {
GenerateRoutes({ commit }, asyncRouter) {
commit('SET_ROUTERS', asyncRouter)
@ -30,7 +30,7 @@ const permission = {
}
}
//遍历后台传来的路由字符串,转换为组件对象
// 遍历后台传来的路由字符串,转换为组件对象
export const filterAsyncRouter = (routers, isRewrite = false) => {
return routers.filter(router => {
if (isRewrite && router.children) {

10
src/utils/auth.js

@ -1,16 +1,14 @@
import Cookies from 'js-cookie';
import Cookies from 'js-cookie'
import Config from '@/settings'
const TokenKey = Config.TokenKey
//获取Token
// 获取Token
export function getToken() {
return Cookies.get(TokenKey)
}
//写入Token
// 写入Token
export function setToken(token, rememberMe) {
if (rememberMe) {
return Cookies.set(TokenKey, token, {
@ -19,7 +17,7 @@ export function setToken(token, rememberMe) {
} else return Cookies.set(TokenKey, token)
}
//移除Token
// 移除Token
export function removeToken() {
return Cookies.remove(TokenKey)
}

2
src/utils/index.js

@ -4,7 +4,7 @@
* @param {string} cFormat
* @returns {string}
*/
export function parseTime(time, cFormat) {
export function parseTime(time, cFormat) {
if (arguments.length === 0) {
return null
}

8
src/utils/permission.js

@ -1,4 +1,4 @@
import store from '@/store' //引入状态管理组件
import store from '@/store' // 引入状态管理组件
export default {
install(Vue) {
@ -10,18 +10,18 @@ export default {
const permissionRoles = value
const hasPermission = roles.some(role => {
//检测role值并返回
// 检测role值并返回
return permissionRoles.includes(role)
})
//判断hasPermission
// 判断hasPermission
if (!hasPermission) {
return false
}
return true
// 否则返回错误
} else {
//需要角色拥有admin editor 权限
// 需要角色拥有admin editor 权限
console.error(`need roles! Like v-permission="['admin','editor']"`)
return false
}

66
src/utils/request.js

@ -1,62 +1,62 @@
import axios from 'axios'
import router from '@/router/routers'
import { Notification } from 'element-ui' //elementUI 提示框组件
import { Notification } from 'element-ui' // elementUI 提示框组件
import store from '../store'
import { getToken } from '@/utils/auth'
import Config from '@/settings'
import Cookies from 'js-cookie'
//二次封装axios,创建axios 实例
// 二次封装axios,创建axios 实例
const service = axios.create({
//api 的 base_url在.env.development有配置
// api 的 base_url在.env.development有配置
baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/',
//baseURL: 'http://localhost:8000',
//请求超时时间
// baseURL: 'http://localhost:8000',
// 请求超时时间
timeout: Config.timeout
})
//添加请求拦截器
// 添加请求拦截器
service.interceptors.request.use(
// 在发送请求之前做些什么
config => {
//如果获取token
// 如果获取token
if (getToken()) {
//每次请求都附带上header的Authorization
// 每次请求都附带上header的Authorization
config.headers['Authorization'] = getToken()
}
//请求格式
// 请求格式
config.headers['Content-Type'] = 'application/json'
return config
},
error => {
//对请求错误的处理
// 对请求错误的处理
Promise.reject(error)
}
)
//添加响应拦截器
// 添加响应拦截器
service.interceptors.response.use(
//响应后要做的事情
// 响应后要做的事情
response => {
//返回响应数据
// 返回响应数据
return response.data
},
//响应错误处理
// 响应错误处理
error => {
//兼容blob下载出错json提示
// 兼容blob下载出错json提示
if (
error.response.data instanceof Blob &&
error.response.data.type.toLowerCase().indexOf('json') !== -1
) {
//创建文件读取对象
// 创建文件读取对象
const reader = new FileReader()
//读取指定的Blob中错误信息内容
// 读取指定的Blob中错误信息内容
reader.readAsText(error.response.data, 'utf-8')
//读取文件完成后触发onload事件
reader.onload = function (e) {
//转换错误信息
// 读取文件完成后触发onload事件
reader.onload = function(e) {
// 转换错误信息
const errorMsg = JSON.parse(reader.result).message
//通知提醒框返回错误信息
// 通知提醒框返回错误信息
Notification.error({
title: errorMsg,
duration: 5000
@ -64,42 +64,42 @@ service.interceptors.response.use(
}
} else {
let code = 0
//捕获错误信息
// 捕获错误信息
try {
//获取响应错误状态码
// 获取响应错误状态码
code = error.response.data.status
} catch (e) {
//做请求超时判断
// 做请求超时判断
if (error.toString().indexOf('Error:timeout') !== -1) {
Notification.error({
title: '网络请求超时',
duration: 5000
})
//拿到回调信息并返回
// 拿到回调信息并返回
return Promise.reject(error)
}
}
console.log(code)
//错误代码判断
// 错误代码判断
if (code) {
if (code === 401) {
//跳转401并写入Cookies
// 跳转401并写入Cookies
store.dispatch('LogOut').then(() => {
// 用户登录界面提示
Cookies.set('point', 401)
//重新加载
// 重新加载
location.reload()
})
} else if (code === 403) {
//如果是403直接返回401页面路径
// 如果是403直接返回401页面路径
router.push({
path: '/401'
})
} else {
//获取错误信息
// 获取错误信息
const errorMsg = error.response.data.message
if (errorMsg !== undefined) {
//告知提示框错误信息
// 告知提示框错误信息
Notification.error({
title: errorMsg,
duration: 5000
@ -107,7 +107,7 @@ service.interceptors.response.use(
}
}
} else {
//否则把请求接口失败告知提示框
// 否则把请求接口失败告知提示框
Notification.error({
title: '接口请求失败',
duration: 5000
@ -115,7 +115,7 @@ service.interceptors.response.use(
}
}
//返回错误
// 返回错误
return Promise.reject(error)
}
)

12
src/utils/rsaEncrypt.js

@ -1,13 +1,11 @@
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
//密钥对生成:http://web.chacuo.net/netrsakeypair
//设置公钥
// 密钥对生成:http://web.chacuo.net/netrsakeypair
// 设置公钥
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMEOuFWzyferOY27HOOKkeNCexTXunvK\n' +
'Bk62mavgNn6G6r9PB4gT71YdXkk/3JmnrUue3L/MPOIpAD5ZadAXdBcCAwEAAQ=='
//设置私钥
// 设置私钥
const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAwQ64VbPJ96s5jbsc\n' +
'44qR40J7FNe6e8oGTraZq+A2fobqv08HiBPvVh1eST/cmaetS57cv8w84ikAPllp\n' +
'0Bd0FwIDAQABAkBf3tB5dsPoIvZ8xJuu/2Q9KAl5KzwnNwb01cbwTHKjV7yORPaL\n' +
@ -17,14 +15,14 @@ const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAwQ64VbPJ96s5
'SLmqkYyNsdsyd2eZ73IpQ7+TN/EAJQIgWmJh6+b5sw4Q/Emb9ypPAE3peP09QmhP\n' +
'ZnAyYEuUiNY='
//输入加密
// 输入加密
export function encrypt(txt) {
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey) // 设置公钥
return encryptor.encrypt(txt) // 对需要加密的数据进行加密
}
//输入解密
// 输入解密
export function decrypt(txt) {
const encryptor = new JSEncrypt()
encryptor.setPrivateKey(privateKey)

77
src/views/login.vue

@ -1,87 +1,43 @@
<template>
<div class="login" :style="'background-image:url(' + Background + ');'">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
label-position="left"
label-width="0px"
class="login-form"
>
<h3 class="title">
阅行集成后台管理
</h3>
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form">
<h3 class="title">阅行集成后台管理</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon
slot="prefix"
icon-class="user"
class="el-input__icon input-icon"
/>
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="password"
class="el-input__icon input-icon"
/>
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon
slot="prefix"
icon-class="validCode"
class="el-input__icon input-icon"
/>
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" />
<img :src="codeUrl" @click="getCode">
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;">
记住我
</el-checkbox>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleLogin"
>
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
</el-form-item>
</el-form>
<!-- 底部 -->
<div v-if="$store.state.settings.showFooter" id="el-login-footer">
<!-- <div v-if="$store.state.settings.showFooter" id="el-login-footer">
<span v-html="$store.state.settings.footerTxt" />
<span> </span>
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">{{
$store.state.settings.caseNumber
}}</a>
</div>
</div> -->
</div>
</template>
@ -93,7 +49,7 @@ import Background from '@/assets/images/background.jpg'
import { getCodeImg } from '@/api/login'
export default {
//
//
name: 'Login',
data() {
return {
@ -201,13 +157,10 @@ export default {
Cookies.remove('password')
Cookies.remove('rememberMe')
}
this.$store
.dispatch('Login', user)
.then(() => {
this.$store.dispatch('Login', user).then(() => {
this.loading = false
this.$router.push({ path: this.redirect || '/' })
})
.catch(() => {
}).catch(() => {
this.loading = false
this.getCode()
})

Loading…
Cancel
Save