Commit 61317410 authored by dupengyu's avatar dupengyu

Squashed commit of the following:

commit b1aba8b5
Author: wuxth <wuxth@foxmail.com>
Date:   Thu Jan 16 19:22:49 2025 +0800

    路由 角色 权限 模块对接完成 整体流程未测试

commit 3bbb3783
Author: wuxth <wuxth@foxmail.com>
Date:   Thu Jan 16 11:27:04 2025 +0800

    路由角色权限等调试

# Conflicts:
#	src/api/menu.js
parent 8e9af031
File deleted
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"echarts": "^5.3.1", "echarts": "^5.3.1",
"element-ui": "2.13.2", "element-ui": "2.13.2",
"events": "^3.3.0", "events": "^3.3.0",
"file-saver": "^2.0.5",
"inquirer": "^8.2.0", "inquirer": "^8.2.0",
"js-cookie": "2.2.0", "js-cookie": "2.2.0",
"moment": "^2.29.1", "moment": "^2.29.1",
......
...@@ -4,6 +4,6 @@ import request from '@/utils/request' ...@@ -4,6 +4,6 @@ import request from '@/utils/request'
export const getRouters = () => { export const getRouters = () => {
return request({ return request({
url: '/api/user/getRouters', url: '/api/user/getRouters',
method: 'get' method: 'post'
}) })
} }
\ No newline at end of file
<template >
<router-view />
</template>
...@@ -10,7 +10,6 @@ export default { ...@@ -10,7 +10,6 @@ export default {
const { value } = binding const { value } = binding
const all_permission = "*:*:*"; const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions const permissions = store.getters && store.getters.permissions
console.log(permissions)
if (value && value instanceof Array && value.length > 0) { if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value const permissionFlag = value
......
<template>
<div
:style="'height:' + height"
v-loading="loading"
element-loading-text="正在加载页面,请稍候!"
>
<iframe
:id="iframeId"
style="width: 100%; height: 100%"
:src="src"
frameborder="no"
></iframe>
</div>
</template>
<script>
export default {
props: {
src: {
type: String,
default: "/",
},
iframeId: {
type: String,
},
},
data() {
return {
loading: false,
height: document.documentElement.clientHeight - 94.5 + "px;",
};
},
mounted() {
var _this = this;
const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/");
const iframe = document.querySelector(iframeId);
// iframe页面loading控制
if (iframe.attachEvent) {
this.loading = true;
iframe.attachEvent("onload", function () {
_this.loading = false;
});
} else {
this.loading = true;
iframe.onload = function () {
_this.loading = false;
};
}
},
};
</script>
...@@ -17,25 +17,17 @@ export default { ...@@ -17,25 +17,17 @@ export default {
const vnodes = [] const vnodes = []
if (icon) { if (icon) {
if (icon.includes('el-icon')) {
vnodes.push(<i class={[icon, 'sub-el-icon']} />)
} else {
vnodes.push(<svg-icon icon-class={icon}/>) vnodes.push(<svg-icon icon-class={icon}/>)
} }
}
if (title) { if (title) {
if (title.length > 5) {
vnodes.push(<span slot='title' title={(title)}>{(title)}</span>)
} else {
vnodes.push(<span slot='title'>{(title)}</span>) vnodes.push(<span slot='title'>{(title)}</span>)
} }
}
return vnodes return vnodes
} }
} }
</script> </script>
<style scoped>
.sub-el-icon {
color: currentColor;
width: 1em;
height: 1em;
}
</style>
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
!item.alwaysShow !item.alwaysShow
" "
> >
<app-link <app-link
v-if="onlyOneChild.meta" v-if="onlyOneChild.meta"
:to=" :to="
...@@ -29,12 +30,13 @@ ...@@ -29,12 +30,13 @@
</template> </template>
<template v-else> <template v-else>
<el-submenu id="subid" ref="subMenu" :index="resolvePath(item.path)"> <el-submenu id="subid" ref="subMenu" :index="resolvePath(item.path)">
<template slot="title"> <template slot="title">
<icon-item <icon-item
v-if="item.meta" v-if="item.meta"
:icon="item.meta && item.meta.icon" :icon="item.meta && item.meta.icon"
:title="item.meta.title" :title="item.meta.title||item.menuName"
/> />
</template> </template>
<sidebar-item <sidebar-item
......
...@@ -34,11 +34,13 @@ export default { ...@@ -34,11 +34,13 @@ export default {
'sidebar' 'sidebar'
]), ]),
routes() { routes() {
console.log('routes',this.$store.state.permission.routes)
return this.$store.state.permission.routes return this.$store.state.permission.routes
}, },
activeMenu() { activeMenu() {
const route = this.$route; const route = this.$route;
const { meta, path } = route; const { meta, path } = route;
// if set path, the sidebar will highlight the path you set // if set path, the sidebar will highlight the path you set
if (meta.activeMenu) { if (meta.activeMenu) {
return meta.activeMenu; return meta.activeMenu;
......
...@@ -10,6 +10,7 @@ import router from './router' ...@@ -10,6 +10,7 @@ import router from './router'
import '@/icons' // icon import '@/icons' // icon
import '@/permission' // permission control import '@/permission' // permission control
import performLoader from '@/utils/global_main_loader.js' import performLoader from '@/utils/global_main_loader.js'
import plugins from './plugins' // plugins
import WS from '@/utils/websocket' import WS from '@/utils/websocket'
import { getDicts } from "@/api/system/dict/data"; import { getDicts } from "@/api/system/dict/data";
import directive from './directive' // directive import directive from './directive' // directive
...@@ -31,6 +32,7 @@ Vue.prototype.resetForm = resetForm ...@@ -31,6 +32,7 @@ Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels Vue.prototype.selectDictLabels = selectDictLabels
Vue.use(plugins)
Vue.component('RightToolbar', RightToolbar) Vue.component('RightToolbar', RightToolbar)
Vue.component('DictTag', DictTag) Vue.component('DictTag', DictTag)
Vue.use(directive) Vue.use(directive)
......
import router from './router' import router from './router'
import store from './store' import store from './store'
import { Message } from 'element-ui' import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar import NProgress from 'nprogress'
import 'nprogress/nprogress.css' // progress bar style import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth' // get token from cookie import { getToken } from '@/utils/auth'
import getPageTitle from '@/utils/get-page-title' import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false }) // NProgress Configuration NProgress.configure({ showSpinner: false })
const whiteList = ['/login'] const whiteList = ['/login', '/register']
router.beforeEach(async (to, from, next) => { router.beforeEach((to, from, next) => {
console.log('console.log(to)',to)
NProgress.start() NProgress.start()
if (getToken()) {
document.title = getPageTitle(to.meta.title) to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
/* has token*/
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') { if (to.path === '/login') {
next({ path: '/' }) next({ path: '/' })
NProgress.done() NProgress.done()
} else { } else if (whiteList.indexOf(to.path) !== -1) {
const hasRoles = store.state.user && store.state.user.roles.length > 0
if (hasRoles) {
next() next()
} else { } else {
try { if (store.getters.roles.length === 0) {
const { isAdmin } = await store.dispatch('user/getInfo') console.log('console.log(store.getters.roles.length)',store.getters.roles)
const roles = isAdmin == 1 ? ['admin'] : ['editor'] isRelogin.show = true
const accessRoutes = await store.dispatch('permission/generateRoutes', roles) // 判断当前用户是否已拉取完user_info信息
router.addRoutes(accessRoutes) store.dispatch('user/getInfo').then(() => {
next({ ...to, replace: true }) isRelogin.show = false
} catch (error) { store.dispatch('GenerateRoutes').then(accessRoutes => {
await store.dispatch('user/resetToken') console.log('accessRoutes',accessRoutes)
Message.error(error || 'Has Error') // 根据roles权限生成可访问的路由表
next(`/login?redirect=${to.path}`) router.addRoutes(accessRoutes) // 动态添加可访问路由表
NProgress.done() if (to.path == '/') {
var path = accessRoutes[0].path == '/' ? '' : accessRoutes[0].path + '/' + accessRoutes[0].children[0].path
next({ path: path })
} else {
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
} }
})
}).catch(err => {
store.dispatch('LogOut').then(() => {
Message.error(err)
next({ path: '/' })
})
})
} else {
next()
} }
} }
} else { } else {
/* has no token*/ // 没有token
if (whiteList.indexOf(to.path) !== -1) { if (whiteList.indexOf(to.path) !== -1) {
// 在免登录白名单,直接进入
next() next()
} else { } else {
next(`/login?redirect=${to.path}`) next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
NProgress.done() NProgress.done()
} }
} }
......
import store from '@/store'
function authPermission(permission) {
const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions
if (permission && permission.length > 0) {
return permissions.some(v => {
return all_permission === v || v === permission
})
} else {
return false
}
}
function authRole(role) {
const super_admin = "admin";
const roles = store.getters && store.getters.roles
if (role && role.length > 0) {
return roles.some(v => {
return super_admin === v || v === role
})
} else {
return false
}
}
export default {
// 验证用户是否具备某权限
hasPermi(permission) {
return authPermission(permission);
},
// 验证用户是否含有指定权限,只需包含其中一个
hasPermiOr(permissions) {
return permissions.some(item => {
return authPermission(item)
})
},
// 验证用户是否含有指定权限,必须全部拥有
hasPermiAnd(permissions) {
return permissions.every(item => {
return authPermission(item)
})
},
// 验证用户是否具备某角色
hasRole(role) {
return authRole(role);
},
// 验证用户是否含有指定角色,只需包含其中一个
hasRoleOr(roles) {
return roles.some(item => {
return authRole(item)
})
},
// 验证用户是否含有指定角色,必须全部拥有
hasRoleAnd(roles) {
return roles.every(item => {
return authRole(item)
})
}
}
const sessionCache = {
set (key, value) {
if (!sessionStorage) {
return
}
if (key != null && value != null) {
sessionStorage.setItem(key, value)
}
},
get (key) {
if (!sessionStorage) {
return null
}
if (key == null) {
return null
}
return sessionStorage.getItem(key)
},
setJSON (key, jsonValue) {
if (jsonValue != null) {
this.set(key, JSON.stringify(jsonValue))
}
},
getJSON (key) {
const value = this.get(key)
if (value != null) {
return JSON.parse(value)
}
},
remove (key) {
sessionStorage.removeItem(key);
}
}
const localCache = {
set (key, value) {
if (!localStorage) {
return
}
if (key != null && value != null) {
localStorage.setItem(key, value)
}
},
get (key) {
if (!localStorage) {
return null
}
if (key == null) {
return null
}
return localStorage.getItem(key)
},
setJSON (key, jsonValue) {
if (jsonValue != null) {
this.set(key, JSON.stringify(jsonValue))
}
},
getJSON (key) {
const value = this.get(key)
if (value != null) {
return JSON.parse(value)
}
},
remove (key) {
localStorage.removeItem(key);
}
}
export default {
/**
* 会话级缓存
*/
session: sessionCache,
/**
* 本地缓存
*/
local: localCache
}
import axios from 'axios'
import {Loading, Message} from 'element-ui'
import { saveAs } from 'file-saver'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { blobValidate } from "@/utils/ruoyi";
const baseURL = process.env.VUE_APP_BASE_API
let downloadLoadingInstance;
export default {
name(name, isDelete = true) {
var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then((res) => {
const isBlob = blobValidate(res.data);
if (isBlob) {
const blob = new Blob([res.data])
this.saveAs(blob, decodeURIComponent(res.headers['download-filename']))
} else {
this.printErrMsg(res.data);
}
})
},
resource(resource) {
var url = baseURL + "/common/download/resource?resource=" + encodeURIComponent(resource);
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then((res) => {
const isBlob = blobValidate(res.data);
if (isBlob) {
const blob = new Blob([res.data])
this.saveAs(blob, decodeURIComponent(res.headers['download-filename']))
} else {
this.printErrMsg(res.data);
}
})
},
zip(url, name) {
var url = baseURL + url
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
axios({
method: 'get',
url: url,
responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() }
}).then((res) => {
const isBlob = blobValidate(res.data);
if (isBlob) {
const blob = new Blob([res.data], { type: 'application/zip' })
this.saveAs(blob, name)
} else {
this.printErrMsg(res.data);
}
downloadLoadingInstance.close();
}).catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close();
})
},
saveAs(text, name, opts) {
saveAs(text, name, opts);
},
async printErrMsg(data) {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
Message.error(errMsg);
}
}
import tab from './tab'
import auth from './auth'
import cache from './cache'
import modal from './modal'
import download from './download'
export default {
install(Vue) {
// 页签操作
Vue.prototype.$tab = tab
// 认证对象
Vue.prototype.$auth = auth
// 缓存对象
Vue.prototype.$cache = cache
// 模态框对象
Vue.prototype.$modal = modal
// 下载文件
Vue.prototype.$download = download
}
}
import { Message, MessageBox, Notification, Loading } from 'element-ui'
let loadingInstance;
export default {
// 消息提示
msg(content) {
Message.info(content)
},
// 错误消息
msgError(content) {
Message.error(content)
},
// 成功消息
msgSuccess(content) {
Message.success(content)
},
// 警告消息
msgWarning(content) {
Message.warning(content)
},
// 弹出提示
alert(content) {
MessageBox.alert(content, "系统提示")
},
// 错误提示
alertError(content) {
MessageBox.alert(content, "系统提示", { type: 'error' })
},
// 成功提示
alertSuccess(content) {
MessageBox.alert(content, "系统提示", { type: 'success' })
},
// 警告提示
alertWarning(content) {
MessageBox.alert(content, "系统提示", { type: 'warning' })
},
// 通知提示
notify(content) {
Notification.info(content)
},
// 错误通知
notifyError(content) {
Notification.error(content);
},
// 成功通知
notifySuccess(content) {
Notification.success(content)
},
// 警告通知
notifyWarning(content) {
Notification.warning(content)
},
// 确认窗体
confirm(content) {
return MessageBox.confirm(content, "系统提示", {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: "warning",
})
},
// 提交内容
prompt(content) {
return MessageBox.prompt(content, "系统提示", {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: "warning",
})
},
// 打开遮罩层
loading(content) {
loadingInstance = Loading.service({
lock: true,
text: content,
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
})
},
// 关闭遮罩层
closeLoading() {
loadingInstance.close();
}
}
import store from '@/store'
import router from '@/router';
export default {
// 刷新当前tab页签
refreshPage(obj) {
const { path, query, matched } = router.currentRoute;
if (obj === undefined) {
matched.forEach((m) => {
if (m.components && m.components.default && m.components.default.name) {
if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
obj = { name: m.components.default.name, path: path, query: query };
}
}
});
}
return store.dispatch('tagsView/delCachedView', obj).then(() => {
const { path, query } = obj
router.replace({
path: '/redirect' + path,
query: query
})
})
},
// 关闭当前tab页签,打开新页签
closeOpenPage(obj) {
store.dispatch("tagsView/delView", router.currentRoute);
if (obj !== undefined) {
return router.push(obj);
}
},
// 关闭指定tab页签
closePage(obj) {
if (obj === undefined) {
return store.dispatch('tagsView/delView', router.currentRoute).then(({ visitedViews }) => {
const latestView = visitedViews.slice(-1)[0]
if (latestView) {
return router.push(latestView.fullPath)
}
return router.push('/');
});
}
return store.dispatch('tagsView/delView', obj);
},
// 关闭所有tab页签
closeAllPage() {
return store.dispatch('tagsView/delAllViews');
},
// 关闭左侧tab页签
closeLeftPage(obj) {
return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute);
},
// 关闭右侧tab页签
closeRightPage(obj) {
return store.dispatch('tagsView/delRightTags', obj || router.currentRoute);
},
// 关闭其他tab页签
closeOtherPage(obj) {
return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute);
},
// 添加tab页签
openPage(title, url, params) {
const obj = { path: url, meta: { title: title } }
store.dispatch('tagsView/addView', obj);
return router.push({ path: url, query: params });
},
// 修改tab页签
updatePage(obj) {
return store.dispatch('tagsView/updateVisitedView', obj);
}
}
...@@ -11,51 +11,38 @@ import Layout from '@/layout' ...@@ -11,51 +11,38 @@ import Layout from '@/layout'
* all roles can be accessed * all roles can be accessed
*/ */
export const constantRoutes = [ export const constantRoutes = [
{
path: '/404',
component: () => import('@/views/error/404'),
hidden: true
},
{ {
path: '/login', path: '/login',
component: () => import('@/views/login/index'), component: () => import('@/views/login/index'),
meta: { title: "登录" }, meta: { title: "登录" },
hidden: true hidden: true
}, },
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'homePage' }
}]
},
{
path: '/alarm',
component: Layout,
redirect: '/dashboard',
name: 'alarm',
meta: { title: '告警管理', icon: 'alarm' },
children: [
{
path: 'cableTime',
name: 'cableTime',
component: () => import('@/views/alarm/cableTime/index'),
meta: { title: '漏缆监测告警' }
},
// { // {
// path: 'device', // path: '/alarm',
// name: 'device', // component: Layout,
// component: () => import('@/views/alarm/device/index'), // redirect: '/dashboard',
// meta: { title: '设备连接告警' } // name: 'alarm',
// meta: { title: '告警管理', icon: 'alarm' },
// children: [
// {
// path: 'cableTime',
// name: 'cableTime',
// component: () => import('@/views/alarm/cableTime/index'),
// meta: { title: '漏缆监测告警' }
// },
// {
// path: 'statistics',
// name: 'statistics',
// component: () => import('@/views/alarm/statistics/index'),
// meta: { title: '告警信息统计' }
// }
// ]
// }, // },
{
path: 'statistics',
name: 'statistics',
component: () => import('@/views/alarm/statistics/index'),
meta: { title: '告警信息统计' }
}
]
},
{ {
path: '/setting', path: '/setting',
component: Layout, component: Layout,
...@@ -247,7 +234,29 @@ export const constantRoutes = [ ...@@ -247,7 +234,29 @@ export const constantRoutes = [
name: '角色管理', name: '角色管理',
component: () => import('@/views/system/role/index'), component: () => import('@/views/system/role/index'),
meta: { title: '角色管理' } meta: { title: '角色管理' }
},
{
path: 'updateUser',
name: 'UpdateUser',
component: () => import('@/views/system/user/updateUser'),
meta: { title: '个人信息管理', },
},
{
path: 'userList',
name: 'UserList',
component: () => import('@/views/system/user/userList'),
meta: { title: '用户信息列表', },
},
{
path: 'userLog',
name: 'UserLog',
component: () => import('@/views/system/user/userLog'),
meta: { title: '用户操作日志', },
} }
] ]
}, },
] ]
...@@ -282,9 +291,44 @@ export const asyncRoutes = [ ...@@ -282,9 +291,44 @@ export const asyncRoutes = [
}] }]
}, },
// 404 page must be placed at the end !!! // 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true } { path: '*', redirect: '/404', hidden: true },
] {
path: '/404',
component: () => import('@/views/error/404'),
hidden: true
},
]
export const dynamicRoutes = [
{
path: '/system/user-auth',
component: Layout,
hidden: true,
permissions: ['system:user:edit'],
children: [
{
path: 'role/:userId(\\d+)',
component: () => import('@/views/system/user/authRole'),
name: 'AuthRole',
meta: { title: '分配角色', activeMenu: '/system/user' }
}
]
},
{
path: '/system/role-auth',
component: Layout,
hidden: true,
permissions: ['system:role:edit'],
children: [
{
path: 'user/:roleId(\\d+)',
component: () => import('@/views/system/role/authUser'),
name: 'AuthUser',
meta: { title: '分配用户', activeMenu: '/system/role' }
}
]
},
]
const createRouter = () => new Router({ const createRouter = () => new Router({
// mode: 'history', // require service support // mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }), scrollBehavior: () => ({ y: 0 }),
......
...@@ -3,5 +3,7 @@ const getters = { ...@@ -3,5 +3,7 @@ const getters = {
device: state => state.app.device, device: state => state.app.device,
token: state => state.user.token, token: state => state.user.token,
dict: state => state.dict.dict, dict: state => state.dict.dict,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
} }
export default getters export default getters
import { asyncRoutes, constantRoutes } from '@/router' import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink'
/** const permission = {
* Use meta.role to determine if the current user has permission state: {
* @param roles routes: [],
* @param route addRoutes: [],
*/ defaultRoutes: [],
function hasPermission(roles, route) { topbarRouters: [],
if (route.meta && route.meta.roles) { sidebarRouters: []
return roles.some(role => route.meta.roles.includes(role)) },
} else { mutations: {
return true SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
},
SET_DEFAULT_ROUTES: (state, routes) => {
state.defaultRoutes = constantRoutes.concat(routes)
},
SET_TOPBAR_ROUTES: (state, routes) => {
state.topbarRouters = routes
},
SET_SIDEBAR_ROUTERS: (state, routes) => {
state.sidebarRouters = routes
},
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
console.log(res)
const sdata = JSON.parse(JSON.stringify(res))
const rdata = JSON.parse(JSON.stringify(res))
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
console.log(rewriteRoutes)
const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
router.addRoutes(asyncRoutes);
commit('SET_ROUTES', rewriteRoutes)
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
commit('SET_TOPBAR_ROUTES', sidebarRoutes)
resolve(rewriteRoutes)
})
})
}
} }
} }
/** // 遍历后台传来的路由字符串,转换为组件对象
* Filter asynchronous routing tables by recursion function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
* @param routes asyncRoutes return asyncRouterMap.filter(route => {
* @param roles if (type && route.children) {
*/ route.children = filterChildren(route.children)
export function filterAsyncRoutes(routes, roles) { }
const res = [] if (route.component) {
// Layout ParentView 组件特殊处理
routes.forEach(route => { if (route.component === 'Layout') {
const tmp = { ...route } route.component = Layout
if (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles)
} }
res.push(tmp) else if (route.component === 'ParentView') {
route.component = ParentView
} else if (route.component === 'InnerLink') {
route.component = InnerLink
} }
else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type)
} else {
delete route['children']
delete route['redirect']
}
return true
}) })
return res
} }
const state = { function filterChildren(childrenMap, lastRouter = false) {
routes: constantRoutes, var children = []
addRoutes: [] childrenMap.forEach((el, index) => {
} if (el.children && el.children.length) {
if (el.component === 'ParentView' && !lastRouter) {
const mutations = { el.children.forEach(c => {
SET_ROUTES: (state, routes) => { c.path = el.path + '/' + c.path
state.addRoutes = routes if (c.children && c.children.length) {
state.routes = constantRoutes.concat(routes) children = children.concat(filterChildren(c.children, c))
return
}
children.push(c)
})
return
} }
}
if (lastRouter) {
el.path = lastRouter.path + '/' + el.path
if (el.children && el.children.length) {
children = children.concat(filterChildren(el.children, el))
return
}
}
children = children.concat(el)
})
return children
} }
const actions = { // 动态路由遍历,验证是否具备权限
generateRoutes({ commit }, roles) { export function filterDynamicRoutes(routes) {
return new Promise(resolve => { const res = []
let accessedRoutes routes.forEach(route => {
if (roles.includes('admin')) { if (route.permissions) {
accessedRoutes = asyncRoutes || [] if (auth.hasPermiOr(route.permissions)) {
} else { res.push(route)
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) }
} else if (route.roles) {
if (auth.hasRoleOr(route.roles)) {
res.push(route)
} }
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
} }
})
return res
} }
export default { export const loadView = (view) => {
namespaced: true, if (process.env.NODE_ENV === 'development') {
state, return (resolve) => require([`@/views/${view}`], resolve)
mutations, } else {
actions, // 使用 import 实现生产环境的路由懒加载
return () => import(`@/views/${view}`)
}
} }
export default permission
import defaultSettings from '@/settings' import defaultSettings from '@/settings'
const { showSettings, fixedHeader, sidebarLogo } = defaultSettings const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const state = { const state = {
title: '',
theme: storageSetting.theme || '#409EFF',
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings, showSettings: showSettings,
fixedHeader: fixedHeader, topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
sidebarLogo: sidebarLogo tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
} }
const mutations = { const mutations = {
CHANGE_SETTING: (state, { key, value }) => { CHANGE_SETTING: (state, { key, value }) => {
// eslint-disable-next-line no-prototype-builtins
if (state.hasOwnProperty(key)) { if (state.hasOwnProperty(key)) {
state[key] = value state[key] = value
} }
...@@ -18,8 +23,13 @@ const mutations = { ...@@ -18,8 +23,13 @@ const mutations = {
} }
const actions = { const actions = {
// 修改布局设置
changeSetting({ commit }, data) { changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data) commit('CHANGE_SETTING', data)
},
// 设置网页标题
setTitle({ commit }, title) {
state.title = title
} }
} }
......
...@@ -7,7 +7,8 @@ const getDefaultState = () => { ...@@ -7,7 +7,8 @@ const getDefaultState = () => {
token: getToken(), token: getToken(),
userBaseInfo: {}, userBaseInfo: {},
userId: '', userId: '',
roles: [] roles: [],
permissions: []
} }
} }
...@@ -27,7 +28,12 @@ const mutations = { ...@@ -27,7 +28,12 @@ const mutations = {
state.userId = data state.userId = data
}, },
SET_ROLES: (state, data) => { SET_ROLES: (state, data) => {
state.roles = handleRoles(data) console.log('console.log(res.roleNames)')
console.log(data)
state.roles = data
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
} }
} }
...@@ -70,14 +76,20 @@ const actions = { ...@@ -70,14 +76,20 @@ const actions = {
reject('Verification failed, please Login again.') reject('Verification failed, please Login again.')
} }
const { isAdmin } = res if (res.roleNames && res.roleNames.length > 0) { // 验证返回的roles是否是一个非空数组
let roles = isAdmin==1 ? ['admin'] : ['editor'] commit('SET_ROLES', res.roleNames)
// roles must be a non-empty array commit('SET_PERMISSIONS', res.permissions)
if (!roles || roles.length <= 0) { } else {
reject('getInfo: roles must be a non-null array!') commit('SET_ROLES', ['ROLE_DEFAULT'])
} }
// const { isAdmin } = res
// let roles = isAdmin==1 ? ['admin'] : ['editor']
// roles must be a non-empty array
// if (!roleNames || roles.length <= 0) {
// reject('getInfo: roles must be a non-null array!')
// }
commit('SET_ROLES', roles) // commit('SET_ROLES', roles)
commit('SET_BASEINFO', res) commit('SET_BASEINFO', res)
resolve(res) resolve(res)
}).catch(error => { }).catch(error => {
...@@ -124,16 +136,6 @@ const getters = { ...@@ -124,16 +136,6 @@ const getters = {
return state.roles return state.roles
} }
} }
function handleRoles(data) {
if (!data) return
if(data.isAdmin == 1) {
return ['admin']
} else {
return ['editor']
}
}
export default { export default {
namespaced: true, namespaced: true,
state, state,
......
...@@ -215,7 +215,7 @@ ...@@ -215,7 +215,7 @@
>.el-menu--popup { >.el-menu--popup {
max-height: 20vh; max-height: 20vh;
min-width: 80px; min-width: 80px;
overflow-y: auto; // overflow-y: auto;
&::-webkit-scrollbar-track-piece { &::-webkit-scrollbar-track-piece {
background: #d3dce6; background: #d3dce6;
......
export default {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'404': '访问资源不存在',
'default': '系统未知错误,请反馈给管理员'
}
This diff is collapsed.
...@@ -12,6 +12,8 @@ const service = axios.create({ ...@@ -12,6 +12,8 @@ const service = axios.create({
timeout: 5000 // request timeout timeout: 5000 // request timeout
}) })
export let isRelogin = { show: false };
let loading = {} let loading = {}
function startLoading(el) { function startLoading(el) {
if (!el) return if (!el) return
...@@ -55,20 +57,25 @@ let errorShowing = false ...@@ -55,20 +57,25 @@ let errorShowing = false
service.interceptors.response.use( service.interceptors.response.use(
response => { response => {
console.log(response) console.log(response)
let res = response.data.data ? response.data.data : response.data
let res = response.data.data ? response.data.data : response.data
if (response.data.msg == "操作成功") { if (response.data.msg == "操作成功") {
res = response.data res = response.data
} }
// if (response.data.success) {
// res = response.data
// }
if (response.data.recordsTotal) { if (response.data.recordsTotal) {
res = { res = {
recordsTotal: response.data.recordsTotal, recordsTotal: response.data.recordsTotal,
data: res data: res
} }
} }
if (!response.data) {
res = response
}
// if (response.data.success) {
// res = response.data
// }
let config = response.config let config = response.config
endLoading(config.el) endLoading(config.el)
let resFinal = res.rsp || res || {} let resFinal = res.rsp || res || {}
...@@ -80,6 +87,19 @@ service.interceptors.response.use( ...@@ -80,6 +87,19 @@ service.interceptors.response.use(
EventBus.$emit('cancelWS') EventBus.$emit('cancelWS')
return return
} }
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false;
store.dispatch('LogOut').then(() => {
location.href = '/web';
})
}).catch(() => {
isRelogin.show = false;
});
}
}
if (code === 501) { if (code === 501) {
// !config.silence && !errorShowing && Message.error(message) // !config.silence && !errorShowing && Message.error(message)
errorShowing = true errorShowing = true
......
<template>
<div class="errPage-container">
<el-button icon="arrow-left" class="pan-back-btn" @click="back">
返回
</el-button>
<el-row>
<el-col :span="12">
<h1 class="text-jumbo text-ginormous">
401错误!
</h1>
<h2>您没有访问权限!</h2>
<h6>对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面</h6>
<ul class="list-unstyled">
<li class="link-type">
<router-link to="/">
回首页
</router-link>
</li>
</ul>
</el-col>
<el-col :span="12">
<img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream.">
</el-col>
</el-row>
</div>
</template>
<script>
import errGif from '@/assets/401_images/401.gif'
export default {
name: 'Page401',
data() {
return {
errGif: errGif + '?' + +new Date()
}
},
methods: {
back() {
if (this.$route.query.noGoBack) {
this.$router.push({ path: '/' })
} else {
this.$router.go(-1)
}
}
}
}
</script>
<style lang="scss" scoped>
.errPage-container {
width: 800px;
max-width: 100%;
margin: 100px auto;
.pan-back-btn {
background: #008489;
color: #fff;
border: none!important;
}
.pan-gif {
margin: 0 auto;
display: block;
}
.pan-img {
display: block;
margin: 0 auto;
width: 100%;
}
.text-jumbo {
font-size: 60px;
font-weight: 700;
color: #484848;
}
.list-unstyled {
font-size: 14px;
li {
padding-bottom: 5px;
}
a {
color: #008489;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
</style>
<template>
<div class="wscn-http404-container">
<div class="wscn-http404">
<div class="pic-404">
<img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404">
<img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404">
<img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404">
</div>
<div class="bullshit">
<div class="bullshit__oops">
404错误!
</div>
<div class="bullshit__headline">
{{ message }}
</div>
<div class="bullshit__info">
对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
</div>
<router-link to="/" class="bullshit__return-home">
返回首页
</router-link>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Page404',
computed: {
message() {
return '找不到网页!'
}
}
}
</script>
<style lang="scss" scoped>
.wscn-http404-container{
transform: translate(-50%,-50%);
position: absolute;
top: 40%;
left: 50%;
}
.wscn-http404 {
position: relative;
width: 1200px;
padding: 0 50px;
overflow: hidden;
.pic-404 {
position: relative;
float: left;
width: 600px;
overflow: hidden;
&__parent {
width: 100%;
}
&__child {
position: absolute;
&.left {
width: 80px;
top: 17px;
left: 220px;
opacity: 0;
animation-name: cloudLeft;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
&.mid {
width: 46px;
top: 10px;
left: 420px;
opacity: 0;
animation-name: cloudMid;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s;
}
&.right {
width: 62px;
top: 100px;
left: 500px;
opacity: 0;
animation-name: cloudRight;
animation-duration: 2s;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s;
}
@keyframes cloudLeft {
0% {
top: 17px;
left: 220px;
opacity: 0;
}
20% {
top: 33px;
left: 188px;
opacity: 1;
}
80% {
top: 81px;
left: 92px;
opacity: 1;
}
100% {
top: 97px;
left: 60px;
opacity: 0;
}
}
@keyframes cloudMid {
0% {
top: 10px;
left: 420px;
opacity: 0;
}
20% {
top: 40px;
left: 360px;
opacity: 1;
}
70% {
top: 130px;
left: 180px;
opacity: 1;
}
100% {
top: 160px;
left: 120px;
opacity: 0;
}
}
@keyframes cloudRight {
0% {
top: 100px;
left: 500px;
opacity: 0;
}
20% {
top: 120px;
left: 460px;
opacity: 1;
}
80% {
top: 180px;
left: 340px;
opacity: 1;
}
100% {
top: 200px;
left: 300px;
opacity: 0;
}
}
}
}
.bullshit {
position: relative;
float: left;
width: 300px;
padding: 30px 0;
overflow: hidden;
&__oops {
font-size: 32px;
font-weight: bold;
line-height: 40px;
color: #1482f0;
opacity: 0;
margin-bottom: 20px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
&__headline {
font-size: 20px;
line-height: 24px;
color: #222;
font-weight: bold;
opacity: 0;
margin-bottom: 10px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.1s;
animation-fill-mode: forwards;
}
&__info {
font-size: 13px;
line-height: 21px;
color: grey;
opacity: 0;
margin-bottom: 30px;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.2s;
animation-fill-mode: forwards;
}
&__return-home {
display: block;
float: left;
width: 110px;
height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px;
line-height: 36px;
cursor: pointer;
animation-name: slideUp;
animation-duration: 0.5s;
animation-delay: 0.3s;
animation-fill-mode: forwards;
}
@keyframes slideUp {
0% {
transform: translateY(60px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
}
}
</style>
This diff is collapsed.
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> <el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
>
<el-form-item label="用户名称" prop="userName"> <el-form-item label="用户名称" prop="userName">
<el-input <el-input
v-model="queryParams.userName" v-model="queryParams.userName"
...@@ -10,9 +16,9 @@ ...@@ -10,9 +16,9 @@
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="手机号码" prop="phonenumber"> <el-form-item label="手机号码" prop="phone">
<el-input <el-input
v-model="queryParams.phonenumber" v-model="queryParams.phone"
placeholder="请输入手机号码" placeholder="请输入手机号码"
clearable clearable
style="width: 240px" style="width: 240px"
...@@ -20,8 +26,16 @@ ...@@ -20,8 +26,16 @@
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -34,7 +48,8 @@ ...@@ -34,7 +48,8 @@
size="mini" size="mini"
@click="openSelectUser" @click="openSelectUser"
v-hasPermi="['system:role:add']" v-hasPermi="['system:role:add']"
>添加用户</el-button> >添加用户</el-button
>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
...@@ -45,7 +60,8 @@ ...@@ -45,7 +60,8 @@
:disabled="multiple" :disabled="multiple"
@click="cancelAuthUserAll" @click="cancelAuthUserAll"
v-hasPermi="['system:role:remove']" v-hasPermi="['system:role:remove']"
>批量取消授权</el-button> >批量取消授权</el-button
>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
...@@ -54,28 +70,56 @@ ...@@ -54,28 +70,56 @@
icon="el-icon-close" icon="el-icon-close"
size="mini" size="mini"
@click="handleClose" @click="handleClose"
>关闭</el-button> >关闭</el-button
>
</el-col>
<el-col :span="1.5">
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-col> </el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> <el-table
v-loading="loading"
:data="userList"
width="800px"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" /> <el-table-column
<el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" /> label="用户名称"
<el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" /> prop="userName"
<el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" /> :show-overflow-tooltip="true"
<el-table-column label="状态" align="center" prop="status"> />
<!-- <el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" /> -->
<!-- <el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" /> -->
<el-table-column
label="手机"
prop="phone"
:show-overflow-tooltip="true"
/>
<!-- <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column> -->
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column
label="创建时间"
align="center"
prop="creationTime"
width="180"
>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span> <span>{{ parseTime(scope.row.creationTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
size="mini" size="mini"
...@@ -83,16 +127,17 @@ ...@@ -83,16 +127,17 @@
icon="el-icon-circle-close" icon="el-icon-circle-close"
@click="cancelAuthUser(scope.row)" @click="cancelAuthUser(scope.row)"
v-hasPermi="['system:role:remove']" v-hasPermi="['system:role:remove']"
>取消授权</el-button> >取消授权</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="total>0" v-show="total > 0"
:total="total" :total="total"
:page.sync="queryParams.pageNum" :page.sync="queryParams.current"
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.size"
@pagination="getList" @pagination="getList"
/> />
<select-user ref="select" :roleId="queryParams.roleId" @ok="handleQuery" /> <select-user ref="select" :roleId="queryParams.roleId" @ok="handleQuery" />
...@@ -100,12 +145,16 @@ ...@@ -100,12 +145,16 @@
</template> </template>
<script> <script>
import { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role"; import {
allocatedUserList,
authUserCancel,
authUserCancelAll,
} from "@/api/system/role";
import selectUser from "./selectUser"; import selectUser from "./selectUser";
export default { export default {
name: "AuthUser", name: "AuthUser",
dicts: ['sys_normal_disable'], dicts: ["sys_normal_disable"],
components: { selectUser }, components: { selectUser },
data() { data() {
return { return {
...@@ -123,12 +172,12 @@ export default { ...@@ -123,12 +172,12 @@ export default {
userList: [], userList: [],
// 查询参数 // 查询参数
queryParams: { queryParams: {
pageNum: 1, current: 1,
pageSize: 10, size: 10,
roleId: undefined, roleId: undefined,
userName: undefined, userName: undefined,
phonenumber: undefined phonenumber: undefined,
} },
}; };
}, },
created() { created() {
...@@ -142,12 +191,11 @@ export default { ...@@ -142,12 +191,11 @@ export default {
/** 查询授权用户列表 */ /** 查询授权用户列表 */
getList() { getList() {
this.loading = true; this.loading = true;
allocatedUserList(this.queryParams).then(response => { allocatedUserList(this.queryParams).then((response) => {
this.userList = response.rows; this.userList = response.data.records;
this.total = response.total; this.total = response.data.total;
this.loading = false; this.loading = false;
} });
);
}, },
// 返回按钮 // 返回按钮
handleClose() { handleClose() {
...@@ -166,8 +214,8 @@ export default { ...@@ -166,8 +214,8 @@ export default {
}, },
// 多选框选中数据 // 多选框选中数据
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.userIds = selection.map(item => item.userId) this.userIds = selection.map((item) => item.id);
this.multiple = !selection.length this.multiple = !selection.length;
}, },
/** 打开授权用户表弹窗 */ /** 打开授权用户表弹窗 */
openSelectUser() { openSelectUser() {
...@@ -176,24 +224,32 @@ export default { ...@@ -176,24 +224,32 @@ export default {
/** 取消授权按钮操作 */ /** 取消授权按钮操作 */
cancelAuthUser(row) { cancelAuthUser(row) {
const roleId = this.queryParams.roleId; const roleId = this.queryParams.roleId;
this.$modal.confirm('确认要取消该用户"' + row.userName + '"角色吗?').then(function() { this.$modal
return authUserCancel({ userId: row.userId, roleId: roleId }); .confirm('确认要取消该用户"' + row.userName + '"角色吗?')
}).then(() => { .then(function () {
return authUserCancel({ userId: row.id, roleId: roleId });
})
.then(() => {
this.getList(); this.getList();
this.$modal.msgSuccess("取消授权成功"); this.$modal.msgSuccess("取消授权成功");
}).catch(() => {}); })
.catch(() => {});
}, },
/** 批量取消授权按钮操作 */ /** 批量取消授权按钮操作 */
cancelAuthUserAll(row) { cancelAuthUserAll(row) {
const roleId = this.queryParams.roleId; const roleId = this.queryParams.roleId;
const userIds = this.userIds.join(","); const userIds = this.userIds.join(",");
this.$modal.confirm('是否取消选中用户授权数据项?').then(function() { this.$modal
.confirm("是否取消选中用户授权数据项?")
.then(function () {
return authUserCancelAll({ roleId: roleId, userIds: userIds }); return authUserCancelAll({ roleId: roleId, userIds: userIds });
}).then(() => { })
.then(() => {
this.getList(); this.getList();
this.$modal.msgSuccess("取消授权成功"); this.$modal.msgSuccess("取消授权成功");
}).catch(() => {}); })
} .catch(() => {});
} },
},
}; };
</script> </script>
\ No newline at end of file
This diff is collapsed.
...@@ -29,23 +29,23 @@ ...@@ -29,23 +29,23 @@
<el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" /> <el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" /> <el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" />
<el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" /> <el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" />
<el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" /> <el-table-column label="手机" prop="phone" :show-overflow-tooltip="true" />
<el-table-column label="状态" align="center" prop="status"> <el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column label="创建时间" align="center" prop="creationTime" width="180">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span> <span>{{ parseTime(scope.row.creationTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination <pagination
v-show="total>0" v-show="total>0"
:total="total" :total="total"
:page.sync="queryParams.pageNum" :page.sync="queryParams.current"
:limit.sync="queryParams.pageSize" :limit.sync="queryParams.size"
@pagination="getList" @pagination="getList"
/> />
</el-row> </el-row>
...@@ -78,8 +78,8 @@ export default { ...@@ -78,8 +78,8 @@ export default {
userList: [], userList: [],
// 查询参数 // 查询参数
queryParams: { queryParams: {
pageNum: 1, current: 1,
pageSize: 10, size: 10,
roleId: undefined, roleId: undefined,
userName: undefined, userName: undefined,
phonenumber: undefined phonenumber: undefined
...@@ -98,13 +98,14 @@ export default { ...@@ -98,13 +98,14 @@ export default {
}, },
// 多选框选中数据 // 多选框选中数据
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.userIds = selection.map(item => item.userId); console.log(selection);
this.userIds = selection.map(item => item.id);
}, },
// 查询表数据 // 查询表数据
getList() { getList() {
unallocatedUserList(this.queryParams).then(res => { unallocatedUserList(this.queryParams).then(res => {
this.userList = res.rows; this.userList = res.data.records;
this.total = res.total; this.total = res.data.total;
}); });
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
......
import request from '@/utils/request'
const path = {
list: 'api/user/selectUserPage',
create: 'api/user/saveUser',
updatePwd: 'api/user/updatePwd',
updateInfo: 'api/user/updateUserBaseInfo',
logList: 'api/sysLog/selectLogPage',
}
export function list() {
return request.post(path.list, ...arguments);
}
export function create() {
return request.post(path.create, ...arguments);
}
export function updatePwd() {
return request.post(path.updatePwd, ...arguments);
}
export function updateInfo() {
return request.post(path.updateInfo, ...arguments);
}
export function logList() {
return request.post(path.logList, ...arguments);
}
...@@ -17,27 +17,50 @@ ...@@ -17,27 +17,50 @@
</el-form> </el-form>
<h4 class="form-header h4">角色信息</h4> <h4 class="form-header h4">角色信息</h4>
<el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="table" @selection-change="handleSelectionChange" :data="roles.slice((pageNum-1)*pageSize,pageNum*pageSize)"> <el-table
v-loading="loading"
:row-key="getRowKey"
@row-click="clickRow"
ref="table"
@selection-change="handleSelectionChange"
:data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
>
<el-table-column label="序号" type="index" align="center"> <el-table-column label="序号" type="index" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span> <span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column> <el-table-column
type="selection"
:reserve-selection="true"
width="55"
></el-table-column>
<el-table-column label="角色编号" align="center" prop="roleId" /> <el-table-column label="角色编号" align="center" prop="roleId" />
<el-table-column label="角色名称" align="center" prop="roleName" /> <el-table-column label="角色名称" align="center" prop="roleName" />
<el-table-column label="权限字符" align="center" prop="roleKey" /> <el-table-column label="权限字符" align="center" prop="roleKey" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180"> <el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span> <span>{{ parseTime(scope.row.createTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" /> <pagination
v-show="total > 0"
:total="total"
:page.sync="pageNum"
:limit.sync="pageSize"
/>
<el-form label-width="100px"> <el-form label-width="100px">
<el-form-item style="text-align: center;margin-left:-120px;margin-top:30px;"> <el-form-item
style="text-align: center; margin-left: -120px; margin-top: 30px"
>
<el-button type="primary" @click="submitForm()">提交</el-button> <el-button type="primary" @click="submitForm()">提交</el-button>
<el-button @click="close()">返回</el-button> <el-button @click="close()">返回</el-button>
</el-form-item> </el-form-item>
...@@ -59,11 +82,11 @@ export default { ...@@ -59,11 +82,11 @@ export default {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
// 选中角色编号 // 选中角色编号
roleIds:[], roleIds: [],
// 角色信息 // 角色信息
roles: [], roles: [],
// 用户信息 // 用户信息
form: {} form: {},
}; };
}, },
created() { created() {
......
export function formInit(data = {}) {
return {
originName: '',
realName: '',
userName: '',
deptId: '',
password: '123456',
phone: '',
email: '',
userId: '',
...data
}
}
export function formInitPwd(data = {}) {
return {
userName: '',
originPwd: '',
password: '',
sureNewPwd: '',
userId: '',
...data
}
}
export const rules = {
userName: { required: true, message: '请输入用户名', trigger: 'blur' },
deptId: { required: true, message: '请选择所在部门', trigger: 'blur' }
}
<template>
<div>
<div class="title">修改基本信息</div>
<el-form ref="form" :model="form" label-width="130px" :rules="rules">
<el-form-item label="用户名:" prop="userName">
<el-input v-model="form.userName" />
</el-form-item>
<el-form-item label="所在部门:" prop="deptId">
<el-select v-model="form.deptId" style="width:100%" placeholder="请选择">
<el-option
v-for="item in departList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="电话号码:">
<el-input v-model="form.phone" />
</el-form-item>
<el-form-item label="邮箱:">
<el-input v-model="form.email" />
</el-form-item>
</el-form>
<div class="btn">
<el-button type="primary" @click="confirm">确认修改</el-button>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { rules } from '../../const'
import { updateInfo } from '../../api'
export default {
data() {
let { deptId, email, phone, userId, userName } = this.$store.state.user.userBaseInfo
return {
form: {
deptId: deptId,
email: email,
phone: phone,
userId: userId,
userName: userName
},
rules
}
},
computed: {
...mapGetters('depart', ['departList']),
},
methods: {
confirm() {
this.$refs.form.validate((valid) => {
if (valid) {
updateInfo(this.form).then(res => {
this.$message.success('操作成功');
})
} else {
return false;
}
})
}
}
}
</script>
<style lang="scss" scoped>
.btn {
margin-top: 50px;
text-align: center;
}
.title {
width: 100%;
height: 60px;
background: rgba(226, 235, 255, 0.39);
line-height: 60px;
font-size: 18px;
color: #333;
font-weight: 500;
text-align: center;
margin-bottom: 30px;
}
.el-form {
width: 500px;
margin: 0 auto;
}
</style>
<template>
<div>
<div class="title">修改密码</div>
<el-form ref="form" :model="form" label-width="100px" :rules="rules">
<el-form-item label="用户名:" prop="userName">
<el-input v-model="form.userName" />
</el-form-item>
<el-form-item label="原密码:" prop="originPwd">
<el-input type="password" v-model="form.originPwd" />
</el-form-item>
<el-form-item label="新密码:" prop="password">
<el-input type="password" v-model="form.password" />
</el-form-item>
<el-form-item label="确认新密码:" prop="sureNewPwd">
<el-input type="password" v-model="form.sureNewPwd" />
</el-form-item>
</el-form>
<div class="btn">
<el-button type="primary" @click="confirm">确认修改</el-button>
</div>
</div>
</template>
<script>
import { updatePwd } from '../../api';
export default {
data() {
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入新密码'));
} else if (value !== this.form.password) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
}
let { userId, userName } = this.$store.state.user.userBaseInfo
return {
form: {
userName: userName,
originPwd: '',
password: '',
sureNewPwd: '',
userId: userId
},
rules: {
userName: { required: true, message: '请输入用户名', trigger: 'blur' },
originPwd: { required: true, message: '请输入原密码', trigger: 'blur' },
password: { required: true, message: '请输入新密码', trigger: 'blur' },
sureNewPwd: [{ required: true, validator: validatePass2, trigger: 'blur' }]
}
}
},
methods: {
confirm() {
this.$refs.form.validate((valid) => {
if (valid) {
updatePwd(this.form).then(res => {
this.$message.success('操作成功');
})
} else {
return false;
}
})
}
}
}
</script>
<style lang="scss" scoped>
.btn {
margin-top: 50px;
text-align: center;
}
.el-form {
width: 500px;
margin: 0 auto;
}
.title {
width: 100%;
height: 60px;
background: rgba(226, 235, 255, 0.39);
line-height: 60px;
font-size: 18px;
color: #333;
font-weight: 500;
text-align: center;
margin-bottom: 30px;
}
</style>
<template>
<div>
<div class="update-user-container">
<div class="header">
<div class="tab">
<div
v-for="(item, index) in options"
:key="item.id"
class="tab-item"
:class="tabIndex === index ? 'tab-active' : ''"
@click="radioChange(item.value, index)"
>
{{ item.name }}
</div>
</div>
</div>
<base-info v-if="tabIndex === 0" />
<password v-if="tabIndex === 1" />
</div>
</div>
</template>
<script>
import baseInfo from '../updateUser/components/baseInfo.vue';
import Password from '../updateUser/components/password.vue';
export default {
components: { baseInfo, Password },
data() {
return {
options: [{
name: '修改基本信息',
value: 1
},
{
name: '修改密码',
value: 2
}],
tabIndex: 0
}
},
methods: {
radioChange(val, index) {
this.tabIndex = index;
}
}
}
</script>
<style lang="scss" scoped>
.header {
display: flex;
justify-content: center;
margin-bottom: 30px;
.tab {
display: flex;
cursor: pointer;
.tab-item {
margin: 0 50px;
padding-bottom: 10px;
}
.tab-active {
color: #038ed7;
border-bottom: 1px solid #038ed7;
}
}
}
</style>
<template>
<el-dialog
:title="editText"
:visible.sync="visible"
@close="cancel"
width="700px"
:close-on-click-modal="false"
>
<el-form ref="form" :model="form" label-width="100px" :rules="rules">
<el-form-item label="用户名:" prop="userName">
<el-input v-model="form.userName" />
</el-form-item>
<el-form-item label="真实姓名:" prop="realName">
<el-input v-model="form.realName" />
</el-form-item>
<el-form-item label="所在部门:" prop="deptId">
<el-select
v-model="form.deptId"
style="width: 100%"
placeholder="请选择"
>
<el-option
v-for="item in departList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="电话号码:">
<el-input v-model="form.phone" />
</el-form-item>
<el-form-item label="邮箱:">
<el-input v-model="form.email" />
</el-form-item>
<el-form-item label="是否为管理员:">
<el-switch
v-model="form.isAdmin"
active-color="#13ce66"
inactive-color="#ccc"
:active-value="1"
:inactive-value="0"
>
</el-switch>
</el-form-item>
<el-form-item v-if="flag==1">注:新用户初始密码为123456</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="confrim">确定</el-button>
</span>
</el-dialog>
</template>
<script>
import { formInit, rules } from '../../const';
import { updateInfo, create } from '../../api';
import { mapGetters } from 'vuex';
export default {
name: 'edit',
data() {
return {
rules,
form: formInit(),
visible: false
}
},
props: {
flag: {
type: Number,
default: 1
},
curInfo: {
type: Object,
default: () => { }
}
},
watch: {
flag: {
immediate: true,
handler(newV) {
this.visible = !!newV;
this.form = formInit(this.curInfo);
},
},
},
computed: {
...mapGetters('depart', ['departList']),
editText() {
return `${this.flag === 1 ? '新增' : '编辑'}基本信息`;
}
},
methods: {
cancel() {
this.form = formInit();
this.$emit('reset');
},
confrim() {
let apiMap = {
1: create,
2: updateInfo,
}
let api = apiMap[this.flag];
this.$refs['form'].validate(valid => {
let params = {
...this.form
}
if (valid) {
api(params).then(() => {
this.$message.success('操作成功');
this.$emit('reset', true);
})
}
})
}
}
}
</script>
<template>
<el-dialog
title="修改密码"
:visible.sync="visible"
@close="cancel"
width="700px"
:close-on-click-modal="false"
>
<el-form ref="form" :model="form" label-width="100px" :rules="rules">
<el-form-item label="用户名:" prop="userName">
<el-input v-model="form.userName" />
</el-form-item>
<el-form-item label="原密码:" prop="originPwd">
<el-input type="password" v-model="form.originPwd" />
</el-form-item>
<el-form-item label="新密码:" prop="password">
<el-input type="password" v-model="form.password" />
</el-form-item>
<el-form-item label="确认新密码:" prop="sureNewPwd">
<el-input type="password" v-model="form.sureNewPwd" />
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="confrim">确定</el-button>
</span>
</el-dialog>
</template>
<script>
import { formInitPwd } from '../../const';
import { updatePwd } from '../../api';
export default {
name: 'editPwd',
data() {
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入新密码'));
} else if (value !== this.form.password) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
}
return {
rules: {
userName: { required: true, message: '请输入用户名', trigger: 'blur' },
originPwd: { required: true, message: '请输入原密码', trigger: 'blur' },
password: { required: true, message: '请输入新密码', trigger: 'blur' },
sureNewPwd: [{ required: true, validator: validatePass2, trigger: 'blur' }]
},
form: formInitPwd(),
visible: false
}
},
props: {
flag1: {
type: Number,
default: 0
},
curInfo: {
type: Object,
default: () => { }
}
},
watch: {
flag1: {
immediate: true,
handler(newV) {
this.visible = !!newV;
this.form = formInitPwd(this.curInfo);
},
},
},
methods: {
cancel() {
this.form = formInitPwd();
this.$emit('reset');
},
confrim() {
this.$refs['form'].validate(valid => {
let params = {
...this.form
}
if (valid) {
updatePwd(params).then(() => {
this.$message.success('操作成功');
this.$emit('reset', true);
})
}
})
}
}
}
</script>
<template>
<div class="leakage-cable">
<div class="leakage-top">
<div style="color: #666666"></div>
<div class="operate-btn">
<el-button type="primary" @click="addUser">添加新用户</el-button>
</div>
</div>
<el-table
v-loading="loading"
:data="tableData"
class="statistics-table"
style="width: 100%"
:row-class-name="tableRowClassName"
:header-cell-style="{
background: '#eaf1fe',
color: '#000',
fontWeight: 700,
height: '50px',
}"
>
<el-table-column
type="index"
label="用户编号"
align="center"
width="100"
/>
<el-table-column prop="userName" label="用户名" align="center" />
<el-table-column prop="realName" label="真实姓名" align="center" />
<el-table-column prop="deptName" label="用户部门" align="center" />
<el-table-column prop="phone" label="电话号码" align="center" />
<el-table-column prop="email" label="邮箱" align="center" />
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="toEditPwd(scope.row)">修改密码</el-button>
<el-button type="text" @click="toEditInfo(scope.row)">修改基本信息</el-button>
</template>
</el-table-column>
</el-table>
<Pagination
:limit="params.pageSize"
:page="params.pageNum"
:total="total"
class="pagination"
@pagination="handlePageChange"
/>
<edit @reset="reset" :cur-info="curInfo" :flag="flag"></edit>
<ediPwd @reset="reset" :cur-info="curInfo" :flag1="flag1"></ediPwd>
</div>
</template>
<script>
import { list } from '../api';
import edit from './components/editInfo.vue';
import ediPwd from './components/editPwd.vue';
export default {
data() {
return {
params: {
pageNum: 1,
pageSize: 10
},
tableData: [],
total: 5,
loading: false,
curInfo: {},
flag: 0,
flag1: 0
}
},
components: {
edit,
ediPwd
},
methods: {
tableRowClassName({ row, rowIndex }) {
return rowIndex % 2 === 0 ? '' : 'single-row';
},
handlePageChange(pageData) {
this.params.pageSize = pageData.size;
this.params.pageNum = pageData.page;
this.getTableData();
},
getTableData() {
let params = {
current: this.params.pageNum,
size: this.params.pageSize
}
list(params).then(res => {
let list = res.records || [];
list.forEach(item => {
item.userId = item.id;
})
this.tableData = list;
this.total = res.total;
})
},
addUser() {
this.curInfo = {};
this.flag = 1;
},
toEditInfo(row) {
this.curInfo = row;
this.flag = 2;
},
toEditPwd(row) {
this.curInfo = row;
this.flag1 = 3;
},
reset(needRefresh) {
this.flag = 0;
this.flag1 = 0;
if(needRefresh) {
this.getTableData();
}
}
},
mounted() {
this.getTableData();
},
}
</script>
<style lang="scss" scoped>
.leakage-cable {
.leakage-top {
margin-bottom: 20px;
display: flex;
align-items: flex-end;
justify-content: space-between;
}
& ::v-deep .cell {
color: #333333;
}
& ::v-deep .stripe {
background-color: #eaf1fe;
}
& ::v-deep .red {
background-color: #f00;
}
& ::v-deep .green {
background-color: green;
}
.page {
display: flex;
align-items: center;
justify-content: center;
margin: 20px 0;
.pageNum {
margin: 0 20px;
}
}
}
</style>
<style lang="scss">
.statistics-table {
.single-row {
background: #f1f6ff;
}
td {
padding: 5px !important;
}
}
</style>
\ No newline at end of file
<template>
<div>
<el-form
class="search-form"
:model="form"
ref="form"
label-width="80px"
:inline="true"
size="mini"
>
<el-form-item label="操作对象">
<el-select
v-model="form.operateObj"
placeholder="请选择操作对象"
clearable
>
<el-option
v-for="item in operatObj"
:key="item.dictValue"
:label="item.dictValue"
:value="+item.dictValue1"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="操作内容">
<el-select
v-model="form.operateContent"
placeholder="请选择操作内容"
clearable
>
<el-option
v-for="item in operatContent"
:key="item.dictValue"
:label="item.dictValue"
:value="item.dictValue1"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="操作结果">
<el-select
v-model="form.operateResult"
placeholder="请选择操作结果"
clearable
>
<el-option
v-for="(val, key) in resultEnum"
:key="val"
:label="val"
:value="+key"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="success" @click="toSearch">查询</el-button>
<el-button type="primary" @click="reset">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { selectDictType } from '@/api/baseData';
export default {
name: 'search',
data() {
return {
operatContent: [],
operatObj: [],
resultEnum: {
0: '失败',
1: '成功',
},
form: formInit()
}
},
computed: {
},
mounted() {
this.getInit()
},
methods: {
toSearch() {
this.$emit('search', this.form);
},
reset() {
this.form = formInit();
this.$emit('search');
},
getInit() {
selectDictType({ dictType: '06' }).then(res => {
let list = res || [];
this.operatContent = list;
})
selectDictType({ dictType: '07' }).then(res => {
let list = res || [];
this.operatObj = list;
})
}
}
}
function formInit() {
return {
operateContent: '',
operateObj: null,
operateResult: null,
}
}
</script>
<style scoped lang="scss">
.w200 {
width: 200px;
}
.search-form {
padding: 10px;
background-color: #eaf1fe;
margin-bottom: 20px;
border-radius: 8px;
.el-form-item--mini.el-form-item,
.el-form-item--small.el-form-item {
margin-bottom: 0;
}
}
</style>
\ No newline at end of file
<template>
<!-- 用户操作日志 -->
<div class="leakage-cable">
<div class="leakage-top">
<div style="color: #666666"></div>
<div class="operate-btn">
<el-button type="primary" @click="refresh">刷新</el-button>
<el-button type="primary" @click="isQuery = !isQuery">查询</el-button>
<el-button type="primary" @click="exportLog">导出</el-button>
</div>
</div>
<div v-if="isQuery">
<search @search="search" ref="reset" />
</div>
<el-table
:data="tableData"
style="width: 100%"
class="statistics-table"
:row-class-name="tableRowClassName"
:row-style="{ height: '50px' }"
:header-cell-style="{ background: '#EAF1FE', color: '#666666' }"
>
<el-table-column prop="userName" label="用户名" align="center" />
<el-table-column prop="operateTypeName" label="操作类别" align="center" />
<el-table-column prop="operateObjName" label="操作对象" align="center" />
<el-table-column prop="objectName" label="对象名称" align="center" />
<el-table-column prop="operateContent" label="操作内容" align="center" />
<el-table-column
prop="operateResultName"
label="操作结果"
align="center"
/>
<el-table-column prop="creationTime" label="操作时间" align="center" />
</el-table>
<Pagination
:limit="params.size"
:page="params.current"
:total="total"
class="pagination"
@pagination="handlePageChange"
/>
</div>
</template>
<script>
import { logList } from "../api";
import search from "./components/search.vue";
import { exportLog } from "@/api/export";
import download from "@/utils/download";
import { successAlert, warningAlert } from "@/utils/alert";
export default {
data() {
return {
params: {
current: 1,
size: 10,
},
total: 10,
tableData: [],
isQuery: false,
istrue: 0,
searchOption: {},
exids: [],
};
},
components: {
search,
},
methods: {
handlePageChange(pageData) {
this.params.size = pageData.size;
this.params.current = pageData.page;
this.getTableData();
},
refresh() {
this.$refs.reset != undefined
? this.$refs.reset.reset()
: this.getTableData();
},
search(option) {
this.params.current = 1;
this.istrue = 1;
this.searchOption = option;
this.getTableData();
},
getTableData() {
let params = {
...this.params,
...this.searchOption,
};
logList(params).then((res) => {
let list = res.records || [];
this.tableData = list;
this.total = res.total;
this.exids = list.map((i) => i.id);
if (this.istrue == 1) {
if (this.tableData.length != 0) {
successAlert("操作成功");
} else {
warningAlert("查询结果为空");
}
this.istrue = 0;
}
});
},
tableRowClassName({ row, rowIndex }) {
return rowIndex % 2 === 0 ? "" : "single-row";
},
exportLog() {
if (this.exids.length == 0) {
this.$message.warning("暂无数据");
return false;
} else {
exportLog({ ids: this.exids }).then((res) => {
download(res, "vnd.ms-excel", `用户日志.xls`);
});
}
},
},
mounted() {
this.getTableData();
},
};
</script>
<style lang="scss" scoped>
.leakage-cable {
.leakage-top {
margin-bottom: 20px;
display: flex;
align-items: flex-end;
justify-content: space-between;
}
& ::v-deep .cell {
color: #333333;
}
.page {
display: flex;
align-items: center;
justify-content: center;
margin: 20px 0;
.current {
margin: 0 20px;
}
}
}
</style>
<style lang="scss">
.statistics-table {
.single-row {
background: #f1f6ff;
}
td {
padding: 5px !important;
}
}
</style>
\ No newline at end of file
<template>
<div class="app-container">
<h4 class="form-header h4">基本信息</h4>
<el-form ref="form" :model="form" label-width="80px">
<el-row>
<el-col :span="8" :offset="2">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" disabled />
</el-form-item>
</el-col>
<el-col :span="8" :offset="2">
<el-form-item label="登录账号" prop="userName">
<el-input v-model="form.userName" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
<h4 class="form-header h4">角色信息</h4>
<el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="table" @selection-change="handleSelectionChange" :data="roles.slice((pageNum-1)*pageSize,pageNum*pageSize)">
<el-table-column label="序号" type="index" align="center">
<template slot-scope="scope">
<span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
</template>
</el-table-column>
<el-table-column type="selection" :reserve-selection="true" width="55"></el-table-column>
<el-table-column label="角色编号" align="center" prop="roleId" />
<el-table-column label="角色名称" align="center" prop="roleName" />
<el-table-column label="权限字符" align="center" prop="roleKey" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" />
<el-form label-width="100px">
<el-form-item style="text-align: center;margin-left:-120px;margin-top:30px;">
<el-button type="primary" @click="submitForm()">提交</el-button>
<el-button @click="close()">返回</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getAuthRole, updateAuthRole } from "@/api/system/user";
export default {
name: "AuthRole",
data() {
return {
// 遮罩层
loading: true,
// 分页信息
total: 0,
pageNum: 1,
pageSize: 10,
// 选中角色编号
roleIds:[],
// 角色信息
roles: [],
// 用户信息
form: {}
};
},
created() {
const userId = this.$route.params && this.$route.params.userId;
if (userId) {
this.loading = true;
getAuthRole(userId).then((response) => {
this.form = response.user;
this.roles = response.roles;
this.total = this.roles.length;
this.$nextTick(() => {
this.roles.forEach((row) => {
if (row.flag) {
this.$refs.table.toggleRowSelection(row);
}
});
});
this.loading = false;
});
}
},
methods: {
/** 单击选中行数据 */
clickRow(row) {
this.$refs.table.toggleRowSelection(row);
},
// 多选框选中数据
handleSelectionChange(selection) {
this.roleIds = selection.map((item) => item.roleId);
},
// 保存选中的数据编号
getRowKey(row) {
return row.roleId;
},
/** 提交按钮 */
submitForm() {
const userId = this.form.userId;
const roleIds = this.roleIds.join(",");
updateAuthRole({ userId: userId, roleIds: roleIds }).then((response) => {
this.$modal.msgSuccess("授权成功");
this.close();
});
},
/** 关闭按钮 */
close() {
const obj = { path: "/system/user" };
this.$tab.closeOpenPage(obj);
},
},
};
</script>
\ No newline at end of file
...@@ -520,7 +520,7 @@ import { ...@@ -520,7 +520,7 @@ import {
changeUserStatus, changeUserStatus,
deptTreeSelect, deptTreeSelect,
} from "@/api/system/user"; } from "@/api/system/user";
import * as API_cmsParty from "@/api/cmsParty"; // import * as API_cmsParty from "@/api/cmsParty";
import { getToken } from "@/utils/auth"; import { getToken } from "@/utils/auth";
import Treeselect from "@riophae/vue-treeselect"; import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";
...@@ -653,22 +653,22 @@ export default { ...@@ -653,22 +653,22 @@ export default {
this.getConfigKey("sys.user.initPassword").then((response) => { this.getConfigKey("sys.user.initPassword").then((response) => {
this.initPassword = response.msg; this.initPassword = response.msg;
}); });
this.handleQueryOrganizationList(); // this.handleQueryOrganizationList();
}, },
methods: { methods: {
// 获取党组织列表 // 获取党组织列表
handleQueryOrganizationList() { // handleQueryOrganizationList() {
this.loading = true; // this.loading = true;
API_cmsParty.organizationList({}) // API_cmsParty.organizationList({})
.then((res) => { // .then((res) => {
if (res.code == 200) { // if (res.code == 200) {
this.organizeList = res.data; // this.organizeList = res.data;
} // }
}) // })
.finally(() => { // .finally(() => {
this.loading = false; // this.loading = false;
}); // });
}, // },
/** 查询用户列表 */ /** 查询用户列表 */
getList() { getList() {
this.loading = true; this.loading = true;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog"> <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
<el-row> <el-row>
<el-col :xs="24" :md="12" :style="{height: '350px'}"> <el-col :xs="24" :md="12" :style="{height: '350px'}">
<vue-cropper <!-- <vue-cropper
ref="cropper" ref="cropper"
:img="options.img" :img="options.img"
:info="true" :info="true"
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
:outputType="options.outputType" :outputType="options.outputType"
@realTime="realTime" @realTime="realTime"
v-if="visible" v-if="visible"
/> /> -->
</el-col> </el-col>
<el-col :xs="24" :md="12" :style="{height: '350px'}"> <el-col :xs="24" :md="12" :style="{height: '350px'}">
<div class="avatar-upload-preview"> <div class="avatar-upload-preview">
...@@ -55,12 +55,12 @@ ...@@ -55,12 +55,12 @@
<script> <script>
import store from "@/store"; import store from "@/store";
import { VueCropper } from "vue-cropper"; // import { VueCropper } from "vue-cropper";
import { uploadAvatar } from "@/api/system/user"; import { uploadAvatar } from "@/api/system/user";
import { debounce } from '@/utils' import { debounce } from '@/utils'
export default { export default {
components: { VueCropper }, // components: { VueCropper },
data() { data() {
return { return {
// 是否显示弹出层 // 是否显示弹出层
......
...@@ -8,9 +8,9 @@ function resolve(dir) { ...@@ -8,9 +8,9 @@ function resolve(dir) {
const name = defaultSettings.title || '漏缆故障定位监测系统' // page title const name = defaultSettings.title || '漏缆故障定位监测系统' // page title
const port = process.env.port || process.env.npm_config_port || 8890 // dev port const port = process.env.port || process.env.npm_config_port || 8890 // dev port
const href = 'http://101.126.159.207' // const href = 'http://101.126.159.207'
// const href = 'http://127.0.0.1' // const href = 'http://127.0.0.1'
// const href = 'http://192.168.0.122' const href = 'http://192.168.0.122'
......
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