添加菜单权限
This commit is contained in:
@ -28,4 +28,57 @@ export function logout() {
|
||||
url: '/admin/logout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function fetchList(params) {
|
||||
return request({
|
||||
url: '/admin/list',
|
||||
method: 'get',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
export function createAdmin(data) {
|
||||
return request({
|
||||
url: '/admin/register',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
export function updateAdmin(id, data) {
|
||||
return request({
|
||||
url: '/admin/update/' + id,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
export function updateStatus(id, params) {
|
||||
return request({
|
||||
url: '/admin/updateStatus/' + id,
|
||||
method: 'post',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteAdmin(id) {
|
||||
return request({
|
||||
url: '/admin/delete/' + id,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
export function getRoleByAdmin(id) {
|
||||
return request({
|
||||
url: '/admin/role/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function allocRole(params) {
|
||||
return request({
|
||||
url: '/admin/role/update',
|
||||
method: 'post',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
@ -6,4 +6,56 @@ export const getRouters = () => {
|
||||
url: '/getRouters',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
}
|
||||
export function fetchList(parentId, params) {
|
||||
return request({
|
||||
url: '/menu/list/' + parentId,
|
||||
method: 'get',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteMenu(id) {
|
||||
return request({
|
||||
url: '/menu/delete/' + id,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
export function createMenu(data) {
|
||||
return request({
|
||||
url: '/menu/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
export function updateMenu(id, data) {
|
||||
return request({
|
||||
url: '/menu/update/' + id,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
export function getMenu(id) {
|
||||
return request({
|
||||
url: '/menu/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function updateHidden(id, params) {
|
||||
return request({
|
||||
url: '/menu/updateHidden/' + id,
|
||||
method: 'post',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchTreeList() {
|
||||
return request({
|
||||
url: '/menu/treeList',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
39
src/api/resource.js
Normal file
39
src/api/resource.js
Normal file
@ -0,0 +1,39 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function fetchList(params) {
|
||||
return request({
|
||||
url: '/resource/list',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
export function createResource(data) {
|
||||
return request({
|
||||
url: '/resource/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateResource(id, data) {
|
||||
return request({
|
||||
url: '/resource/update/' + id,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteResource(id) {
|
||||
return request({
|
||||
url: '/resource/delete/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchAllResourceList() {
|
||||
return request({
|
||||
url: '/resource/listAll',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
31
src/api/resourceCategory.js
Normal file
31
src/api/resourceCategory.js
Normal file
@ -0,0 +1,31 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listAllCate() {
|
||||
return request({
|
||||
url: '/resourceCategory/listAll',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function createResourceCategory(data) {
|
||||
return request({
|
||||
url: '/resourceCategory/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateResourceCategory(id, data) {
|
||||
return request({
|
||||
url: '/resourceCategory/update/' + id,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteResourceCategory(id) {
|
||||
return request({
|
||||
url: '/resourceCategory/delete/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
81
src/api/role.js
Normal file
81
src/api/role.js
Normal file
@ -0,0 +1,81 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function fetchList(params) {
|
||||
return request({
|
||||
url: '/role/list',
|
||||
method: 'get',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
export function createRole(data) {
|
||||
return request({
|
||||
url: '/role/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
export function updateRole(id, data) {
|
||||
return request({
|
||||
url: '/role/update/' + id,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
export function updateStatus(id, params) {
|
||||
return request({
|
||||
url: '/role/updateStatus/' + id,
|
||||
method: 'post',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteRole(params) {
|
||||
return request({
|
||||
url: '/role/delete',
|
||||
method: 'post',
|
||||
// data:
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchAllRoleList() {
|
||||
return request({
|
||||
url: '/role/listAll',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function listMenuByRole(roleId) {
|
||||
return request({
|
||||
url: '/role/listMenu/' + roleId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function listResourceByRole(roleId) {
|
||||
return request({
|
||||
url: '/role/listResource/' + roleId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function allocMenu(params) {
|
||||
return request({
|
||||
url: '/role/allocMenu',
|
||||
method: 'post',
|
||||
// data:data
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
export function allocResource(params) {
|
||||
return request({
|
||||
url: '/role/allocResource',
|
||||
method: 'post',
|
||||
// data: data,
|
||||
params
|
||||
});
|
||||
}
|
@ -1,65 +1,52 @@
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import { Message } from 'element-ui'
|
||||
import NProgress from 'nprogress'
|
||||
import 'nprogress/nprogress.css'
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
NProgress.configure({ showSpinner: false })
|
||||
|
||||
const whiteList = ['/login', '/auth-redirect', '/bind', '/register']
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
import NProgress from 'nprogress'; // Progress 进度条
|
||||
import 'nprogress/nprogress.css'; // Progress 进度条样式
|
||||
import { Message } from 'element-ui';
|
||||
import { getToken } from '@/utils/auth'; // 验权
|
||||
NProgress.configure({ showSpinner: false });
|
||||
|
||||
const whiteList = ['/login', '/auth-redirect', '/bind', '/register'];
|
||||
router.beforeEach((to, from, next) => {
|
||||
NProgress.start()
|
||||
NProgress.start();
|
||||
if (getToken()) {
|
||||
/* has token*/
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' })
|
||||
NProgress.done()
|
||||
next({ path: '/' });
|
||||
NProgress.done(); // if current page is dashboard will not trigger afterEach hook, so manually handle it
|
||||
} else {
|
||||
if (store.getters.roles.length === 0) {
|
||||
// 判断当前用户是否已拉取完user_info信息
|
||||
store.dispatch('GetInfo').then(res => {
|
||||
// 拉取user_info
|
||||
// console.log(res.roles);
|
||||
const roles = res.roles
|
||||
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
|
||||
// 测试 默认静态页面
|
||||
// store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
|
||||
// 根据roles权限生成可访问的路由表
|
||||
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
||||
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
|
||||
store
|
||||
.dispatch('GetInfo')
|
||||
.then(res => {
|
||||
// 拉取用户信息
|
||||
let menus = res.data.menus;
|
||||
let username = res.data.username;
|
||||
store.dispatch('GenerateRoutes', { menus, username }).then(() => {
|
||||
// 生成可访问的路由表
|
||||
router.addRoutes(store.getters.addRoutes); // 动态添加可访问路由表
|
||||
next({ ...to, replace: true });
|
||||
});
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
store.dispatch('FedLogOut').then(() => {
|
||||
Message.error(err)
|
||||
next({ path: '/' })
|
||||
})
|
||||
})
|
||||
Message.error(err || 'Verification failed, please login again');
|
||||
next({ path: '/' });
|
||||
});
|
||||
});
|
||||
} else {
|
||||
next()
|
||||
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
|
||||
// if (hasPermission(store.getters.roles, to.meta.roles)) {
|
||||
// next()
|
||||
// } else {
|
||||
// next({ path: '/401', replace: true, query: { noGoBack: true }})
|
||||
// }
|
||||
// 可删 ↑
|
||||
next();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 没有token
|
||||
if (whiteList.indexOf(to.path) !== -1) {
|
||||
// 在免登录白名单,直接进入
|
||||
next()
|
||||
next();
|
||||
} else {
|
||||
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||
NProgress.done()
|
||||
next('/login');
|
||||
NProgress.done();
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
router.afterEach(() => {
|
||||
NProgress.done()
|
||||
})
|
||||
NProgress.done(); // 结束Progress
|
||||
});
|
||||
|
@ -11,6 +11,7 @@ import customerManagement from './modules/customerManagement';
|
||||
import accountManagement from './modules/accountManagement';
|
||||
import customerService from './modules/customerService';
|
||||
import feedback from './modules/feedback';
|
||||
import settings from './modules/settings';
|
||||
|
||||
export const DynamicRoutes = [
|
||||
// 政策管理
|
||||
@ -26,7 +27,9 @@ export const DynamicRoutes = [
|
||||
// 客服中心
|
||||
customerService,
|
||||
// 意见反馈
|
||||
feedback
|
||||
feedback,
|
||||
// 系统设置
|
||||
settings
|
||||
];
|
||||
|
||||
export default DynamicRoutes;
|
||||
|
@ -23,6 +23,7 @@ import Layout from '@/layout'
|
||||
breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示
|
||||
}
|
||||
*/
|
||||
import DynamicRoutes from './dynamicRoutes'
|
||||
|
||||
// 公共路由
|
||||
export const constantRoutes = [
|
||||
@ -61,7 +62,7 @@ export const constantRoutes = [
|
||||
path: 'index',
|
||||
component: (resolve) => require(['@/views/index'], resolve),
|
||||
name: '首页',
|
||||
meta: { title: '首页', noCache: true, affix: true }
|
||||
meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true }
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -119,6 +120,7 @@ export const constantRoutes = [
|
||||
]
|
||||
}
|
||||
]
|
||||
export const asyncRouterMap = DynamicRoutes
|
||||
|
||||
export default new Router({
|
||||
mode: 'history', // 去掉url中的#
|
||||
|
@ -8,8 +8,8 @@ const nestedRouter = {
|
||||
{
|
||||
path: 'account',
|
||||
component: resolve => require(['@/views/account/index'], resolve),
|
||||
name: '账号管理',
|
||||
meta: { title: '账号管理' }
|
||||
name: 'account',
|
||||
meta: { title: '账号管理', icon: 'user' }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -6,14 +6,15 @@ const nestedRouter = {
|
||||
path: '/front',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
meta: { title: '前端配置' },
|
||||
name:'front',
|
||||
meta: { title: '前端配置', icon: 'swagger' },
|
||||
children: [
|
||||
{
|
||||
path: 'unscramble',
|
||||
component: resolve =>
|
||||
require(['@/views/front/unscramble/index'], resolve),
|
||||
name: 'unscramble',
|
||||
meta: { title: '政策解读' }
|
||||
meta: { title: '政策解读', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'addUnscramble',
|
||||
@ -27,7 +28,7 @@ const nestedRouter = {
|
||||
component: resolve =>
|
||||
require(['@/views/front/expressNews/index'], resolve),
|
||||
name: 'expressNews',
|
||||
meta: { title: '资讯快报' }
|
||||
meta: { title: '资讯快报', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'addExpressNews',
|
||||
|
@ -8,8 +8,8 @@ const nestedRouter = {
|
||||
{
|
||||
path: 'customer',
|
||||
component: resolve => require(['@/views/customer/index'], resolve),
|
||||
name: '客户管理',
|
||||
meta: { title: '客户管理' }
|
||||
name: 'customer',
|
||||
meta: { title: '客户管理', icon: 'peoples' }
|
||||
},
|
||||
{
|
||||
path: 'addCustomer',
|
||||
|
@ -8,8 +8,8 @@ const nestedRouter = {
|
||||
{
|
||||
path: 'service',
|
||||
component: resolve => require(['@/views/service/index'], resolve),
|
||||
name: '客服中心',
|
||||
meta: { title: '客服中心' }
|
||||
name: 'service',
|
||||
meta: { title: '客服中心', icon:'people' }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ const nestedRouter = {
|
||||
path: 'feedback',
|
||||
component: resolve => require(['@/views/feedback/index'], resolve),
|
||||
name: 'feedback',
|
||||
meta: { title: '意见反馈' }
|
||||
meta: { title: '意见反馈', icon: 'message' }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -6,13 +6,14 @@ const nestedRouter = {
|
||||
path: '/policy',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
meta: { title: '政策管理' },
|
||||
name:'policy',
|
||||
meta: { title: '政策管理', icon: 'row' },
|
||||
children: [
|
||||
{
|
||||
path: 'library',
|
||||
component: resolve => require(['@/views/policy/library/index'], resolve),
|
||||
name: 'library',
|
||||
meta: { title: '政策库' }
|
||||
meta: { title: '政策库', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'add',
|
||||
@ -25,7 +26,7 @@ const nestedRouter = {
|
||||
path: 'tag',
|
||||
component: resolve => require(['@/views/policy/tag/index'], resolve),
|
||||
name: 'tag',
|
||||
meta: { title: '政策标签' }
|
||||
meta: { title: '政策标签', icon: 'list' }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
72
src/router/modules/settings.js
Normal file
72
src/router/modules/settings.js
Normal file
@ -0,0 +1,72 @@
|
||||
import Layout from '@/layout';
|
||||
// 账号管理
|
||||
const nestedRouter = {
|
||||
path: '/ums',
|
||||
component: Layout,
|
||||
redirect: '/ums/admin',
|
||||
name: 'ums',
|
||||
meta: { title: '系统设置', icon: 'system' },
|
||||
children: [
|
||||
{
|
||||
path: 'admin',
|
||||
name: 'admin',
|
||||
component: () => import('@/views/ums/admin/index'),
|
||||
meta: { title: '用户列表', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: 'role',
|
||||
component: () => import('@/views/ums/role/index'),
|
||||
meta: { title: '角色列表', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'allocMenu',
|
||||
name: 'allocMenu',
|
||||
component: () => import('@/views/ums/role/allocMenu'),
|
||||
meta: { title: '分配菜单' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'allocResource',
|
||||
name: 'allocResource',
|
||||
component: () => import('@/views/ums/role/allocResource'),
|
||||
meta: { title: '分配资源' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'menu',
|
||||
name: 'menu',
|
||||
component: () => import('@/views/ums/menu/index'),
|
||||
meta: { title: '菜单列表', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'addMenu',
|
||||
name: 'addMenu',
|
||||
component: () => import('@/views/ums/menu/add'),
|
||||
meta: { title: '添加菜单' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'updateMenu',
|
||||
name: 'updateMenu',
|
||||
component: () => import('@/views/ums/menu/update'),
|
||||
meta: { title: '修改菜单' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'resource',
|
||||
name: 'resource',
|
||||
component: () => import('@/views/ums/resource/index'),
|
||||
meta: { title: '资源列表', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'resourceCategory',
|
||||
name: 'resourceCategory',
|
||||
component: () => import('@/views/ums/resource/categoryList'),
|
||||
meta: { title: '资源分类' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default nestedRouter;
|
@ -6,14 +6,15 @@ const nestedRouter = {
|
||||
path: '/technology',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
meta: { title: '技术转移' },
|
||||
name:'technology',
|
||||
meta: { title: '技术转移', icon: 'clipboard'},
|
||||
children: [
|
||||
{
|
||||
path: 'demand',
|
||||
component: resolve =>
|
||||
require(['@/views/technology/demand/index'], resolve),
|
||||
name: 'demand',
|
||||
meta: { title: '企业需求' }
|
||||
meta: { title: '企业需求', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'addDemand',
|
||||
@ -27,7 +28,7 @@ const nestedRouter = {
|
||||
component: resolve =>
|
||||
require(['@/views/technology/achievement/index'], resolve),
|
||||
name: 'achievement',
|
||||
meta: { title: '科技成果' }
|
||||
meta: { title: '科技成果', icon: 'list' }
|
||||
},
|
||||
{
|
||||
path: 'addAchievement',
|
||||
|
@ -10,6 +10,7 @@ const getters = {
|
||||
introduction: state => state.user.introduction,
|
||||
roles: state => state.user.roles,
|
||||
permissions: state => state.user.permissions,
|
||||
permission_routes: state => state.permission.routes
|
||||
}
|
||||
export default getters
|
||||
permission_routes: state => state.permission.routes,
|
||||
addRoutes: state => state.permission.addRoutes
|
||||
};
|
||||
export default getters;
|
||||
|
@ -1,60 +1,109 @@
|
||||
import { constantRoutes } from '@/router'
|
||||
// import { getRouters } from '@/api/menu'
|
||||
import Layout from '@/layout/index'
|
||||
import DynamicRoutes from '@/router/dynamicRoutes'
|
||||
import { asyncRouterMap, constantRoutes } from '@/router/index';
|
||||
|
||||
const permission = {
|
||||
state: {
|
||||
routes: [],
|
||||
addRoutes: []
|
||||
},
|
||||
mutations: {
|
||||
SET_ROUTES: (state, routes) => {
|
||||
state.addRoutes = routes
|
||||
state.routes = constantRoutes.concat(routes)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
// 生成路由
|
||||
GenerateRoutes({ commit }) {
|
||||
return new Promise(resolve => {
|
||||
// console.log(DynamicRoutes);
|
||||
const accessedRoutes = filterAsyncRouter(DynamicRoutes)
|
||||
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
||||
commit('SET_ROUTES', accessedRoutes)
|
||||
resolve(accessedRoutes)
|
||||
// 向后端请求路由数据
|
||||
// getRouters().then(res => {
|
||||
// const accessedRoutes = filterAsyncRouter(res.data)
|
||||
// accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
|
||||
// commit('SET_ROUTES', accessedRoutes)
|
||||
// resolve(accessedRoutes)
|
||||
// })
|
||||
})
|
||||
//判断是否有权限访问该菜单
|
||||
function hasPermission(menus, route) {
|
||||
if (route.name) {
|
||||
let currMenu = getMenu(route.name, menus);
|
||||
if (currMenu != null) {
|
||||
//设置菜单的标题、图标和可见性
|
||||
if (currMenu.title != null && currMenu.title !== '') {
|
||||
route.meta.title = currMenu.title;
|
||||
}
|
||||
if (currMenu.icon != null && currMenu.title !== '') {
|
||||
route.meta.icon = currMenu.icon;
|
||||
}
|
||||
if (currMenu.hidden != null) {
|
||||
route.hidden = currMenu.hidden !== 0;
|
||||
}
|
||||
if (currMenu.sort != null && currMenu.sort !== '') {
|
||||
route.sort = currMenu.sort;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
route.sort = 0;
|
||||
if (route.hidden !== undefined && route.hidden === true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历后台传来的路由字符串,转换为组件对象
|
||||
function filterAsyncRouter(asyncRouterMap) {
|
||||
return asyncRouterMap.filter(route => {
|
||||
// if (route.component) {
|
||||
// // Layout组件特殊处理
|
||||
// if (route.component === 'Layout') {
|
||||
// route.component = Layout
|
||||
// } else {
|
||||
// route.component = loadView(route.component)
|
||||
// }
|
||||
// }
|
||||
if (route.children != null && route.children && route.children.length) {
|
||||
route.children = filterAsyncRouter(route.children)
|
||||
//根据路由名称获取菜单
|
||||
function getMenu(name, menus) {
|
||||
for (let i = 0; i < menus.length; i++) {
|
||||
let menu = menus[i];
|
||||
if (name === menu.name) {
|
||||
return menu;
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export const loadView = (view) => { // 路由懒加载
|
||||
return (resolve) => require([`@/views/${view}`], resolve)
|
||||
//对菜单进行排序
|
||||
function sortRouters(accessedRouters) {
|
||||
for (let i = 0; i < accessedRouters.length; i++) {
|
||||
let router = accessedRouters[i];
|
||||
if (router.children && router.children.length > 0) {
|
||||
router.children.sort(compare('sort'));
|
||||
}
|
||||
}
|
||||
accessedRouters.sort(compare('sort'));
|
||||
}
|
||||
|
||||
export default permission
|
||||
//降序比较函数
|
||||
function compare(p) {
|
||||
return function(m, n) {
|
||||
let a = m[p];
|
||||
let b = n[p];
|
||||
return b - a;
|
||||
};
|
||||
}
|
||||
|
||||
const permission = {
|
||||
state: {
|
||||
routes: constantRoutes,
|
||||
addRoutes: []
|
||||
},
|
||||
mutations: {
|
||||
SET_ROUTERS: (state, routes) => {
|
||||
state.addRoutes = routes;
|
||||
state.routes = constantRoutes.concat(routes);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
GenerateRoutes({ commit }, data) {
|
||||
return new Promise(resolve => {
|
||||
const { menus } = data;
|
||||
const { username } = data;
|
||||
const accessedRouters = asyncRouterMap.filter(v => {
|
||||
//admin帐号直接返回所有菜单
|
||||
// if (username === 'admin') return true;
|
||||
if (hasPermission(menus, v)) {
|
||||
if (v.children && v.children.length > 0) {
|
||||
v.children = v.children.filter(child => {
|
||||
if (hasPermission(menus, child)) {
|
||||
return child;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return v;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
//对菜单进行排序
|
||||
sortRouters(accessedRouters);
|
||||
commit('SET_ROUTERS', accessedRouters);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default permission;
|
||||
|
42
src/utils/date.js
Normal file
42
src/utils/date.js
Normal file
@ -0,0 +1,42 @@
|
||||
// date.js
|
||||
export function formatDate(date, fmt) {
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
|
||||
}
|
||||
let o = {
|
||||
'M+': date.getMonth() + 1,
|
||||
'd+': date.getDate(),
|
||||
'h+': date.getHours(),
|
||||
'm+': date.getMinutes(),
|
||||
's+': date.getSeconds()
|
||||
};
|
||||
for (let k in o) {
|
||||
if (new RegExp(`(${k})`).test(fmt)) {
|
||||
let str = o[k] + '';
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
|
||||
}
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
function padLeftZero(str) {
|
||||
return ('00' + str).substr(str.length);
|
||||
}
|
||||
|
||||
export function str2Date(dateStr, separator) {
|
||||
if (!separator) {
|
||||
separator = "-";
|
||||
}
|
||||
let dateArr = dateStr.split(separator);
|
||||
let year = parseInt(dateArr[0]);
|
||||
let month;
|
||||
//处理月份为04这样的情况
|
||||
if (dateArr[1].indexOf("0") == 0) {
|
||||
month = parseInt(dateArr[1].substring(1));
|
||||
} else {
|
||||
month = parseInt(dateArr[1]);
|
||||
}
|
||||
let day = parseInt(dateArr[2]);
|
||||
let date = new Date(year, month - 1, day);
|
||||
return date;
|
||||
}
|
393
src/views/ums/admin/index.vue
Normal file
393
src/views/ums/admin/index.vue
Normal file
@ -0,0 +1,393 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="filter-container" shadow="never">
|
||||
<div>
|
||||
<i class="el-icon-search"></i>
|
||||
<span>筛选搜索</span>
|
||||
<el-button
|
||||
style="float:right"
|
||||
type="primary"
|
||||
@click="handleSearchList()"
|
||||
size="small"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 15px">
|
||||
<el-form
|
||||
:inline="true"
|
||||
:model="listQuery"
|
||||
size="small"
|
||||
label-width="140px"
|
||||
@submit.native.prevent
|
||||
>
|
||||
<el-form-item label="输入搜索:">
|
||||
<el-input
|
||||
v-model="listQuery.keyword"
|
||||
class="input-width"
|
||||
placeholder="帐号/姓名"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="operate-container" shadow="never">
|
||||
<i class="el-icon-tickets"></i>
|
||||
<span>数据列表</span>
|
||||
<el-button
|
||||
size="mini"
|
||||
class="btn-add"
|
||||
@click="handleAdd()"
|
||||
style="margin-left: 20px"
|
||||
>添加</el-button
|
||||
>
|
||||
</el-card>
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="adminTable"
|
||||
:data="list"
|
||||
style="width: 100%;"
|
||||
v-loading="listLoading"
|
||||
border
|
||||
>
|
||||
<el-table-column label="编号" width="100" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.id }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="帐号" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.username }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="姓名" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.nickName }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="邮箱" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.email }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="添加时间" width="160" align="center">
|
||||
<template slot-scope="scope">{{
|
||||
scope.row.createTime | formatDateTime
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="最后登录" width="160" align="center">
|
||||
<template slot-scope="scope">{{
|
||||
scope.row.loginTime | formatDateTime
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否启用" width="140" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
@change="handleStatusChange(scope.$index, scope.row)"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
v-model="scope.row.status"
|
||||
>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleSelectRole(scope.$index, scope.row)"
|
||||
>分配角色
|
||||
</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleUpdate(scope.$index, scope.row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleDelete(scope.$index, scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
layout="total, sizes,prev, pager, next,jumper"
|
||||
:current-page.sync="listQuery.pageNum"
|
||||
:page-size="listQuery.pageSize"
|
||||
:page-sizes="[10, 15, 20]"
|
||||
:total="total"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="isEdit ? '编辑用户' : '添加用户'"
|
||||
:visible.sync="dialogVisible"
|
||||
width="40%"
|
||||
>
|
||||
<el-form :model="admin" ref="adminForm" label-width="150px" size="small">
|
||||
<el-form-item label="帐号:">
|
||||
<el-input v-model="admin.username" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名:">
|
||||
<el-input v-model="admin.nickName" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱:">
|
||||
<el-input v-model="admin.email" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码:">
|
||||
<el-input
|
||||
v-model="admin.password"
|
||||
type="password"
|
||||
style="width: 250px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注:">
|
||||
<el-input
|
||||
v-model="admin.note"
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
style="width: 250px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用:">
|
||||
<el-radio-group v-model="admin.status">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false" size="small">取 消</el-button>
|
||||
<el-button type="primary" @click="handleDialogConfirm()" size="small"
|
||||
>确 定</el-button
|
||||
>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-dialog title="分配角色" :visible.sync="allocDialogVisible" width="30%">
|
||||
<el-select
|
||||
v-model="allocRoleIds"
|
||||
multiple
|
||||
placeholder="请选择"
|
||||
size="small"
|
||||
style="width: 80%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in allRoleList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="allocDialogVisible = false" size="small"
|
||||
>取 消</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleAllocDialogConfirm()"
|
||||
size="small"
|
||||
>确 定</el-button
|
||||
>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
fetchList,
|
||||
createAdmin,
|
||||
updateAdmin,
|
||||
updateStatus,
|
||||
deleteAdmin,
|
||||
getRoleByAdmin,
|
||||
allocRole
|
||||
} from '@/api/login';
|
||||
import { fetchAllRoleList } from '@/api/role';
|
||||
import { formatDate } from '@/utils/date';
|
||||
|
||||
const defaultListQuery = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
keyword: null
|
||||
};
|
||||
const defaultAdmin = {
|
||||
id: null,
|
||||
username: null,
|
||||
password: null,
|
||||
nickName: null,
|
||||
email: null,
|
||||
note: null,
|
||||
status: 1
|
||||
};
|
||||
export default {
|
||||
name: 'adminList',
|
||||
data() {
|
||||
return {
|
||||
listQuery: Object.assign({}, defaultListQuery),
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: false,
|
||||
dialogVisible: false,
|
||||
admin: Object.assign({}, defaultAdmin),
|
||||
isEdit: false,
|
||||
allocDialogVisible: false,
|
||||
allocRoleIds: [],
|
||||
allRoleList: [],
|
||||
allocAdminId: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
this.getAllRoleList();
|
||||
},
|
||||
filters: {
|
||||
formatDateTime(time) {
|
||||
if (time == null || time === '') {
|
||||
return 'N/A';
|
||||
}
|
||||
let date = new Date(time);
|
||||
return formatDate(date, 'yyyy-MM-dd hh:mm:ss');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSearchList() {
|
||||
this.listQuery.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.pageNum = 1;
|
||||
this.listQuery.pageSize = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.pageNum = val;
|
||||
this.getList();
|
||||
},
|
||||
handleAdd() {
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = false;
|
||||
this.admin = Object.assign({}, defaultAdmin);
|
||||
},
|
||||
handleStatusChange(index, row) {
|
||||
this.$confirm('是否要修改该状态?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
updateStatus(row.id, { status: row.status }).then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '修改成功!'
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: '取消修改'
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
handleDelete(index, row) {
|
||||
this.$confirm('是否要删除该用户?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteAdmin(row.id).then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
handleUpdate(index, row) {
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = true;
|
||||
this.admin = Object.assign({}, row);
|
||||
},
|
||||
handleDialogConfirm() {
|
||||
this.$confirm('是否要确认?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (this.isEdit) {
|
||||
updateAdmin(this.admin.id, this.admin).then(response => {
|
||||
this.$message({
|
||||
message: '修改成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
createAdmin(this.admin).then(response => {
|
||||
this.$message({
|
||||
message: '添加成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
handleAllocDialogConfirm() {
|
||||
this.$confirm('是否要确认?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let params = new URLSearchParams();
|
||||
params.append('adminId', this.allocAdminId);
|
||||
params.append('roleIds', this.allocRoleIds);
|
||||
allocRole(params).then(response => {
|
||||
this.$message({
|
||||
message: '分配成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.allocDialogVisible = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
handleSelectRole(index, row) {
|
||||
this.allocAdminId = row.id;
|
||||
this.allocDialogVisible = true;
|
||||
this.getRoleListByAdmin(row.id);
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.listLoading = false;
|
||||
this.list = response.data.list;
|
||||
this.total = response.data.total;
|
||||
});
|
||||
},
|
||||
getAllRoleList() {
|
||||
fetchAllRoleList().then(response => {
|
||||
this.allRoleList = response.data;
|
||||
});
|
||||
},
|
||||
getRoleListByAdmin(adminId) {
|
||||
getRoleByAdmin(adminId).then(response => {
|
||||
let allocRoleList = response.data;
|
||||
this.allocRoleIds = [];
|
||||
if (allocRoleList != null && allocRoleList.length > 0) {
|
||||
for (let i = 0; i < allocRoleList.length; i++) {
|
||||
this.allocRoleIds.push(allocRoleList[i].id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style></style>
|
14
src/views/ums/menu/add.vue
Normal file
14
src/views/ums/menu/add.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<menu-detail :is-edit='false'></menu-detail>
|
||||
</template>
|
||||
<script>
|
||||
import MenuDetail from './components/MenuDetail'
|
||||
export default {
|
||||
name: 'addMenu',
|
||||
components: { MenuDetail }
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
164
src/views/ums/menu/components/MenuDetail.vue
Normal file
164
src/views/ums/menu/components/MenuDetail.vue
Normal file
@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<el-card class="form-container" shadow="never">
|
||||
<el-form :model="menu" :rules="rules" ref="menuFrom" label-width="150px">
|
||||
<el-form-item label="菜单名称:" prop="title">
|
||||
<el-input v-model="menu.title"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="上级菜单:">
|
||||
<el-select v-model="menu.parentId" placeholder="请选择菜单">
|
||||
<el-option
|
||||
v-for="item in selectMenuList"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="前端名称:" prop="name">
|
||||
<el-input v-model="menu.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="前端图标:" prop="icon">
|
||||
<el-input v-model="menu.icon" style="width: 80%"></el-input>
|
||||
<svg-icon style="margin-left: 8px" :icon-class="menu.icon"></svg-icon>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示:">
|
||||
<el-radio-group v-model="menu.hidden">
|
||||
<el-radio :label="0">是</el-radio>
|
||||
<el-radio :label="1">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序:">
|
||||
<el-input v-model="menu.sort"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit('menuFrom')">提交</el-button>
|
||||
<el-button v-if="!isEdit" @click="resetForm('menuFrom')"
|
||||
>重置</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchList, createMenu, updateMenu, getMenu } from '@/api/menu';
|
||||
|
||||
const defaultMenu = {
|
||||
title: '',
|
||||
parentId: '0',
|
||||
name: '',
|
||||
icon: '',
|
||||
hidden: 0,
|
||||
sort: 0
|
||||
};
|
||||
export default {
|
||||
name: 'MenuDetail',
|
||||
props: {
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
menu: Object.assign({}, defaultMenu),
|
||||
selectMenuList: [],
|
||||
rules: {
|
||||
title: [
|
||||
{ required: true, message: '请输入菜单名称', trigger: 'blur' },
|
||||
{
|
||||
min: 2,
|
||||
max: 140,
|
||||
message: '长度在 2 到 140 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: '请输入前端名称', trigger: 'blur' },
|
||||
{
|
||||
min: 2,
|
||||
max: 140,
|
||||
message: '长度在 2 到 140 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
icon: [
|
||||
{ required: true, message: '请输入前端图标', trigger: 'blur' },
|
||||
{
|
||||
min: 2,
|
||||
max: 140,
|
||||
message: '长度在 2 到 140 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
activated() {
|
||||
if (this.isEdit) {
|
||||
getMenu(this.$route.query.id).then(response => {
|
||||
this.menu = response.data;
|
||||
});
|
||||
} else {
|
||||
this.menu = Object.assign({}, defaultMenu);
|
||||
}
|
||||
this.getSelectMenuList();
|
||||
},
|
||||
methods: {
|
||||
getSelectMenuList() {
|
||||
fetchList(0, { pageSize: 100, pageNum: 1 }).then(response => {
|
||||
this.selectMenuList = response.data.list;
|
||||
this.selectMenuList.unshift({ id: '0', title: '无上级菜单' });
|
||||
});
|
||||
},
|
||||
onSubmit(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (valid) {
|
||||
this.$confirm('是否提交数据', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (this.isEdit) {
|
||||
updateMenu(this.$route.query.id, this.menu).then(response => {
|
||||
this.$message({
|
||||
message: '修改成功',
|
||||
type: 'success',
|
||||
duration: 1000
|
||||
});
|
||||
this.$router.back();
|
||||
});
|
||||
} else {
|
||||
createMenu(this.menu).then(response => {
|
||||
this.$refs[formName].resetFields();
|
||||
this.resetForm(formName);
|
||||
this.$message({
|
||||
message: '提交成功',
|
||||
type: 'success',
|
||||
duration: 1000
|
||||
});
|
||||
this.$router.back();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message({
|
||||
message: '验证失败',
|
||||
type: 'error',
|
||||
duration: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
this.menu = Object.assign({}, defaultMenu);
|
||||
this.getSelectMenuList();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
196
src/views/ums/menu/index.vue
Normal file
196
src/views/ums/menu/index.vue
Normal file
@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="operate-container" shadow="never">
|
||||
<i class="el-icon-tickets" style="margin-top: 5px"></i>
|
||||
<span style="margin-top: 5px">数据列表</span>
|
||||
<el-button
|
||||
class="btn-add"
|
||||
@click="handleAddMenu()"
|
||||
size="mini">
|
||||
添加
|
||||
</el-button>
|
||||
</el-card>
|
||||
<div class="table-container">
|
||||
<el-table ref="menuTable"
|
||||
style="width: 100%"
|
||||
:data="list"
|
||||
v-loading="listLoading" border>
|
||||
<el-table-column label="编号" width="100" align="center">
|
||||
<template slot-scope="scope">{{scope.row.id}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="菜单名称" align="center">
|
||||
<template slot-scope="scope">{{scope.row.title}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="菜单级数" width="100" align="center">
|
||||
<template slot-scope="scope">{{scope.row.level | levelFilter}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="前端名称" align="center">
|
||||
<template slot-scope="scope">{{scope.row.name}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="前端图标" width="100" align="center">
|
||||
<template slot-scope="scope"><svg-icon :icon-class="scope.row.icon"></svg-icon></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否显示" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
@change="handleHiddenChange(scope.$index, scope.row)"
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
v-model="scope.row.hidden">
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" width="100" align="center">
|
||||
<template slot-scope="scope">{{scope.row.sort }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="设置" width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
:disabled="scope.row.level | disableNextLevel"
|
||||
@click="handleShowNextLevel(scope.$index, scope.row)">查看下级
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleUpdate(scope.$index, scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleDelete(scope.$index, scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
layout="total, sizes,prev, pager, next,jumper"
|
||||
:page-size="listQuery.pageSize"
|
||||
:page-sizes="[10,15,20]"
|
||||
:current-page.sync="listQuery.pageNum"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {fetchList,deleteMenu,updateMenu,updateHidden} from '@/api/menu'
|
||||
|
||||
export default {
|
||||
name: "menuList",
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
},
|
||||
parentId: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.resetParentId();
|
||||
this.getList();
|
||||
},
|
||||
watch: {
|
||||
$route(route) {
|
||||
this.resetParentId();
|
||||
this.getList();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resetParentId(){
|
||||
this.listQuery.pageNum = 1;
|
||||
if (this.$route.query.parentId != null) {
|
||||
this.parentId = this.$route.query.parentId;
|
||||
} else {
|
||||
this.parentId = 0;
|
||||
}
|
||||
},
|
||||
handleAddMenu() {
|
||||
this.$router.push('/ums/addMenu');
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
fetchList(this.parentId, this.listQuery).then(response => {
|
||||
this.listLoading = false;
|
||||
this.list = response.data.list;
|
||||
this.total = response.data.total;
|
||||
});
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.pageNum = 1;
|
||||
this.listQuery.pageSize = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.pageNum = val;
|
||||
this.getList();
|
||||
},
|
||||
handleHiddenChange(index, row) {
|
||||
updateHidden(row.id,{hidden:row.hidden}).then(response=>{
|
||||
this.$message({
|
||||
message: '修改成功',
|
||||
type: 'success',
|
||||
duration: 1000
|
||||
});
|
||||
});
|
||||
},
|
||||
handleShowNextLevel(index, row) {
|
||||
this.$router.push({path: '/ums/menu', query: {parentId: row.id}})
|
||||
},
|
||||
handleUpdate(index, row) {
|
||||
this.$router.push({path:'/ums/updateMenu',query:{id:row.id}});
|
||||
},
|
||||
handleDelete(index, row) {
|
||||
this.$confirm('是否要删除该菜单', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteMenu(row.id).then(response => {
|
||||
this.$message({
|
||||
message: '删除成功',
|
||||
type: 'success',
|
||||
duration: 1000
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
levelFilter(value) {
|
||||
if (value === 0) {
|
||||
return '一级';
|
||||
} else if (value === 1) {
|
||||
return '二级';
|
||||
}
|
||||
},
|
||||
disableNextLevel(value) {
|
||||
if (value === 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
14
src/views/ums/menu/update.vue
Normal file
14
src/views/ums/menu/update.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<menu-detail :is-edit='true'></menu-detail>
|
||||
</template>
|
||||
<script>
|
||||
import MenuDetail from './components/MenuDetail'
|
||||
export default {
|
||||
name: 'updateMenu',
|
||||
components: { MenuDetail }
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
156
src/views/ums/resource/categoryList.vue
Normal file
156
src/views/ums/resource/categoryList.vue
Normal file
@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card shadow="never" class="operate-container">
|
||||
<i class="el-icon-tickets"></i>
|
||||
<span>数据列表</span>
|
||||
<el-button size="mini" class="btn-add" @click="handleAdd()">添加</el-button>
|
||||
</el-card>
|
||||
<div class="table-container">
|
||||
<el-table ref="resourceCategoryTable"
|
||||
:data="list"
|
||||
style="width: 100%;"
|
||||
v-loading="listLoading" border>
|
||||
<el-table-column label="编号" width="100" align="center">
|
||||
<template slot-scope="scope">{{scope.row.id}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="名称" align="center">
|
||||
<template slot-scope="scope">{{scope.row.name}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center">
|
||||
<template slot-scope="scope">{{scope.row.createTime | formatDateTime}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" align="center">
|
||||
<template slot-scope="scope">{{scope.row.sort}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini"
|
||||
type="text"
|
||||
@click="handleUpdate(scope.$index, scope.row)">编辑
|
||||
</el-button>
|
||||
<el-button size="mini"
|
||||
type="text"
|
||||
@click="handleDelete(scope.$index, scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-dialog
|
||||
title="添加分类"
|
||||
:visible.sync="dialogVisible"
|
||||
width="40%">
|
||||
<el-form :model="resourceCategory"
|
||||
ref="resourceCategoryForm"
|
||||
label-width="150px" size="small">
|
||||
<el-form-item label="名称:">
|
||||
<el-input v-model="resourceCategory.name" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序:">
|
||||
<el-input v-model="resourceCategory.sort" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false" size="small">取 消</el-button>
|
||||
<el-button type="primary" @click="handleDialogConfirm()" size="small">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {listAllCate,createResourceCategory,updateResourceCategory,deleteResourceCategory} from '@/api/resourceCategory';
|
||||
import {formatDate} from '@/utils/date';
|
||||
const defaultResourceCategory={
|
||||
name:null,
|
||||
sort:0
|
||||
};
|
||||
export default {
|
||||
name: 'resourceCategoryList',
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: false,
|
||||
dialogVisible:false,
|
||||
isEdit:false,
|
||||
resourceCategory:Object.assign({},defaultResourceCategory)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
filters:{
|
||||
formatDateTime(time) {
|
||||
if (time == null || time === '') {
|
||||
return 'N/A';
|
||||
}
|
||||
let date = new Date(time);
|
||||
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleAdd() {
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = false;
|
||||
this.resourceCategory = Object.assign({},defaultResourceCategory);
|
||||
},
|
||||
handleUpdate(index,row){
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = true;
|
||||
this.resourceCategory = Object.assign({},row);
|
||||
},
|
||||
handleDelete(index,row){
|
||||
this.$confirm('是否要删除该分类?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteResourceCategory(row.id).then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
handleDialogConfirm() {
|
||||
this.$confirm('是否要确认?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (this.isEdit) {
|
||||
updateResourceCategory(this.resourceCategory.id,this.resourceCategory).then(response => {
|
||||
this.$message({
|
||||
message: '修改成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible =false;
|
||||
this.getList();
|
||||
})
|
||||
} else {
|
||||
createResourceCategory(this.resourceCategory).then(response => {
|
||||
this.$message({
|
||||
message: '添加成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible =false;
|
||||
this.getList();
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
listAllCate({}).then(response => {
|
||||
this.listLoading = false;
|
||||
this.list = response.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
|
||||
|
273
src/views/ums/resource/index.vue
Normal file
273
src/views/ums/resource/index.vue
Normal file
@ -0,0 +1,273 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="filter-container" shadow="never">
|
||||
<div>
|
||||
<i class="el-icon-search"></i>
|
||||
<span>筛选搜索</span>
|
||||
<el-button
|
||||
style="float:right"
|
||||
type="primary"
|
||||
@click="handleSearchList()"
|
||||
size="small">
|
||||
查询搜索
|
||||
</el-button>
|
||||
<el-button
|
||||
style="float:right;margin-right: 15px"
|
||||
@click="handleResetSearch()"
|
||||
size="small">
|
||||
重置
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 15px">
|
||||
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
|
||||
<el-form-item label="资源名称:">
|
||||
<el-input v-model="listQuery.nameKeyword" class="input-width" placeholder="资源名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="资源路径:">
|
||||
<el-input v-model="listQuery.urlKeyword" class="input-width" placeholder="资源路径" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="资源分类:">
|
||||
<el-select v-model="listQuery.categoryId" placeholder="全部" clearable class="input-width">
|
||||
<el-option v-for="item in categoryOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="operate-container" shadow="never">
|
||||
<i class="el-icon-tickets"></i>
|
||||
<span>数据列表</span>
|
||||
<el-button size="mini" class="btn-add" @click="handleAdd()" style="margin-left: 20px">添加</el-button>
|
||||
<el-button size="mini" class="btn-add" @click="handleShowCategory()">资源分类</el-button>
|
||||
</el-card>
|
||||
<div class="table-container">
|
||||
<el-table ref="resourceTable"
|
||||
:data="list"
|
||||
style="width: 100%;"
|
||||
v-loading="listLoading" border>
|
||||
<el-table-column label="编号" width="100" align="center">
|
||||
<template slot-scope="scope">{{scope.row.id}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="资源名称" align="center">
|
||||
<template slot-scope="scope">{{scope.row.name}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="资源路径" align="center">
|
||||
<template slot-scope="scope">{{scope.row.url}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述" align="center">
|
||||
<template slot-scope="scope">{{scope.row.description}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="添加时间" width="160" align="center">
|
||||
<template slot-scope="scope">{{scope.row.createTime | formatDateTime}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini"
|
||||
type="text"
|
||||
@click="handleUpdate(scope.$index, scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button size="mini"
|
||||
type="text"
|
||||
@click="handleDelete(scope.$index, scope.row)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
layout="total, sizes,prev, pager, next,jumper"
|
||||
:current-page.sync="listQuery.pageNum"
|
||||
:page-size="listQuery.pageSize"
|
||||
:page-sizes="[10,15,20]"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="isEdit?'编辑资源':'添加资源'"
|
||||
:visible.sync="dialogVisible"
|
||||
width="40%">
|
||||
<el-form :model="resource"
|
||||
ref="resourceForm"
|
||||
label-width="150px" size="small">
|
||||
<el-form-item label="资源名称:">
|
||||
<el-input v-model="resource.name" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="资源路径:">
|
||||
<el-input v-model="resource.url" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="资源分类:">
|
||||
<el-select v-model="resource.categoryId" placeholder="全部" clearable style="width: 250px">
|
||||
<el-option v-for="item in categoryOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述:">
|
||||
<el-input v-model="resource.description"
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false" size="small">取 消</el-button>
|
||||
<el-button type="primary" @click="handleDialogConfirm()" size="small">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {fetchList,createResource,updateResource,deleteResource} from '@/api/resource';
|
||||
import {listAllCate} from '@/api/resourceCategory';
|
||||
import {formatDate} from '@/utils/date';
|
||||
|
||||
const defaultListQuery = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
nameKeyword: null,
|
||||
urlKeyword: null,
|
||||
categoryId:null
|
||||
};
|
||||
const defaultResource = {
|
||||
id: null,
|
||||
name: null,
|
||||
url: null,
|
||||
categoryId: null,
|
||||
description:''
|
||||
};
|
||||
export default {
|
||||
name: 'resourceList',
|
||||
data() {
|
||||
return {
|
||||
listQuery: Object.assign({}, defaultListQuery),
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: false,
|
||||
dialogVisible: false,
|
||||
resource: Object.assign({}, defaultResource),
|
||||
isEdit: false,
|
||||
categoryOptions:[],
|
||||
defaultCategoryId:null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
this.getCateList();
|
||||
},
|
||||
filters: {
|
||||
formatDateTime(time) {
|
||||
if (time == null || time === '') {
|
||||
return 'N/A';
|
||||
}
|
||||
let date = new Date(time);
|
||||
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleResetSearch() {
|
||||
this.listQuery = Object.assign({}, defaultListQuery);
|
||||
},
|
||||
handleSearchList() {
|
||||
this.listQuery.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.pageNum = 1;
|
||||
this.listQuery.pageSize = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.pageNum = val;
|
||||
this.getList();
|
||||
},
|
||||
handleAdd() {
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = false;
|
||||
this.resource = Object.assign({},defaultResource);
|
||||
this.resource.categoryId = this.defaultCategoryId;
|
||||
},
|
||||
handleDelete(index, row) {
|
||||
this.$confirm('是否要删除该资源?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteResource(row.id).then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
handleUpdate(index, row) {
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = true;
|
||||
this.resource = Object.assign({},row);
|
||||
},
|
||||
handleDialogConfirm() {
|
||||
this.$confirm('是否要确认?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (this.isEdit) {
|
||||
updateResource(this.resource.id,this.resource).then(response => {
|
||||
this.$message({
|
||||
message: '修改成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible =false;
|
||||
this.getList();
|
||||
})
|
||||
} else {
|
||||
createResource(this.resource).then(response => {
|
||||
this.$message({
|
||||
message: '添加成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible =false;
|
||||
this.getList();
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleShowCategory(){
|
||||
this.$router.push({path: '/ums/resourceCategory'})
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.listLoading = false;
|
||||
this.list = response.data.list;
|
||||
this.total = response.data.total;
|
||||
});
|
||||
},
|
||||
getCateList(){
|
||||
listAllCate().then(response=>{
|
||||
let cateList = response.data;
|
||||
for(let i=0;i<cateList.length;i++){
|
||||
let cate = cateList[i];
|
||||
this.categoryOptions.push({label:cate.name,value:cate.id});
|
||||
}
|
||||
this.defaultCategoryId=cateList[0].id;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
|
100
src/views/ums/role/allocMenu.vue
Normal file
100
src/views/ums/role/allocMenu.vue
Normal file
@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<el-card class="form-container" shadow="never">
|
||||
<el-tree
|
||||
:data="menuTreeList"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
node-key="id"
|
||||
ref="tree"
|
||||
highlight-current
|
||||
:props="defaultProps"
|
||||
>
|
||||
</el-tree>
|
||||
<div style="margin-top: 20px" align="center">
|
||||
<el-button type="primary" @click="handleSave()">保存</el-button>
|
||||
<el-button @click="handleClear()">清空</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fetchTreeList } from '@/api/menu';
|
||||
import { listMenuByRole, allocMenu } from '@/api/role';
|
||||
|
||||
export default {
|
||||
name: 'allocMenu',
|
||||
data() {
|
||||
return {
|
||||
menuTreeList: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'title'
|
||||
},
|
||||
roleId: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.roleId = this.$route.query.roleId;
|
||||
this.treeList();
|
||||
this.getRoleMenu(this.roleId);
|
||||
},
|
||||
methods: {
|
||||
treeList() {
|
||||
fetchTreeList().then(response => {
|
||||
console.log(response.data);
|
||||
this.menuTreeList = response.data;
|
||||
});
|
||||
},
|
||||
getRoleMenu(roleId) {
|
||||
listMenuByRole(roleId).then(response => {
|
||||
let menuList = response.data;
|
||||
let checkedMenuIds = [];
|
||||
if (menuList != null && menuList.length > 0) {
|
||||
for (let i = 0; i < menuList.length; i++) {
|
||||
let menu = menuList[i];
|
||||
if (menu.parentId !== 0) {
|
||||
checkedMenuIds.push(menu.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$refs.tree.setCheckedKeys(checkedMenuIds);
|
||||
});
|
||||
},
|
||||
handleSave() {
|
||||
let checkedNodes = this.$refs.tree.getCheckedNodes();
|
||||
let checkedMenuIds = new Set();
|
||||
if (checkedNodes != null && checkedNodes.length > 0) {
|
||||
for (let i = 0; i < checkedNodes.length; i++) {
|
||||
let checkedNode = checkedNodes[i];
|
||||
checkedMenuIds.add(checkedNode.id);
|
||||
if (checkedNode.parentId !== 0) {
|
||||
checkedMenuIds.add(checkedNode.parentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$confirm('是否分配菜单?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let params = new URLSearchParams();
|
||||
params.append('roleId', this.roleId);
|
||||
params.append('menuIds', Array.from(checkedMenuIds));
|
||||
allocMenu(params).then(response => {
|
||||
this.$message({
|
||||
message: '分配成功',
|
||||
type: 'success',
|
||||
duration: 1000
|
||||
});
|
||||
this.$router.back();
|
||||
});
|
||||
});
|
||||
},
|
||||
handleClear() {
|
||||
this.$refs.tree.setCheckedKeys([]);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
187
src/views/ums/role/allocResource.vue
Normal file
187
src/views/ums/role/allocResource.vue
Normal file
@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<el-card class="form-container" shadow="never">
|
||||
<div v-for="(cate,index) in allResourceCate" :class="index===0?'top-line':null" :key="'cate'+cate.id">
|
||||
<el-row class="table-layout" style="background: #F2F6FC;">
|
||||
<el-checkbox v-model="cate.checked"
|
||||
:indeterminate="isIndeterminate(cate.id)"
|
||||
@change="handleCheckAllChange(cate)">
|
||||
{{cate.name}}
|
||||
</el-checkbox>
|
||||
</el-row>
|
||||
<el-row class="table-layout">
|
||||
<el-col :span="8" v-for="resource in getResourceByCate(cate.id)" :key="resource.id" style="padding: 4px 0">
|
||||
<el-checkbox v-model="resource.checked" @change="handleCheckChange(resource)">
|
||||
{{resource.name}}
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div style="margin-top: 20px" align="center">
|
||||
<el-button type="primary" @click="handleSave()">保存</el-button>
|
||||
<el-button @click="handleClear()">清空</el-button>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {fetchAllResourceList} from '@/api/resource';
|
||||
import {listAllCate} from '@/api/resourceCategory';
|
||||
import {allocResource,listResourceByRole} from '@/api/role';
|
||||
|
||||
export default {
|
||||
name: "allocResource",
|
||||
data() {
|
||||
return {
|
||||
roleId: null,
|
||||
allResource: null,
|
||||
allResourceCate: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.roleId = this.$route.query.roleId;
|
||||
this.getAllResourceCateList();
|
||||
},
|
||||
methods: {
|
||||
getAllResourceList() {
|
||||
fetchAllResourceList().then(response => {
|
||||
this.allResource = response.data;
|
||||
for (let i = 0; i < this.allResource.length; i++) {
|
||||
this.allResource[i].checked = false;
|
||||
}
|
||||
this.getResourceByRole(this.roleId);
|
||||
});
|
||||
},
|
||||
getAllResourceCateList() {
|
||||
listAllCate().then(response => {
|
||||
this.allResourceCate = response.data;
|
||||
for (let i = 0; i < this.allResourceCate.length; i++) {
|
||||
this.allResourceCate[i].checked = false;
|
||||
}
|
||||
this.getAllResourceList();
|
||||
});
|
||||
},
|
||||
getResourceByCate(categoryId) {
|
||||
let cateResource = [];
|
||||
if (this.allResource == null) return null;
|
||||
for (let i = 0; i < this.allResource.length; i++) {
|
||||
let resource = this.allResource[i];
|
||||
if (resource.categoryId === categoryId) {
|
||||
cateResource.push(resource);
|
||||
}
|
||||
}
|
||||
return cateResource;
|
||||
},
|
||||
getResourceByRole(roleId){
|
||||
listResourceByRole(roleId).then(response=>{
|
||||
let allocResource = response.data;
|
||||
this.allResource.forEach(item=>{
|
||||
item.checked = this.getResourceChecked(item.id,allocResource);
|
||||
});
|
||||
this.allResourceCate.forEach(item=>{
|
||||
item.checked = this.isAllChecked(item.id);
|
||||
});
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
getResourceChecked(resourceId,allocResource){
|
||||
if(allocResource==null||allocResource.length===0) return false;
|
||||
for(let i=0;i<allocResource.length;i++){
|
||||
if(allocResource[i].id===resourceId){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
isIndeterminate(categoryId) {
|
||||
let cateResources = this.getResourceByCate(categoryId);
|
||||
if (cateResources == null) return false;
|
||||
let checkedCount = 0;
|
||||
for (let i = 0; i < cateResources.length; i++) {
|
||||
if (cateResources[i].checked === true) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
return !(checkedCount === 0 || checkedCount === cateResources.length);
|
||||
},
|
||||
isAllChecked(categoryId) {
|
||||
let cateResources = this.getResourceByCate(categoryId);
|
||||
if (cateResources == null) return false;
|
||||
let checkedCount = 0;
|
||||
for (let i = 0; i < cateResources.length; i++) {
|
||||
if (cateResources[i].checked === true) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
if(checkedCount===0){
|
||||
return false;
|
||||
}
|
||||
return checkedCount === cateResources.length;
|
||||
},
|
||||
handleSave() {
|
||||
this.$confirm('是否分配资源?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let checkedResourceIds = new Set();
|
||||
if (this.allResource != null && this.allResource.length > 0) {
|
||||
this.allResource.forEach(item => {
|
||||
if (item.checked) {
|
||||
checkedResourceIds.add(item.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
let params = new URLSearchParams();
|
||||
params.append("roleId", this.roleId);
|
||||
params.append("resourceIds", Array.from(checkedResourceIds));
|
||||
allocResource(params).then(response => {
|
||||
this.$message({
|
||||
message: '分配成功',
|
||||
type: 'success',
|
||||
duration: 1000
|
||||
});
|
||||
this.$router.back();
|
||||
})
|
||||
})
|
||||
},
|
||||
handleClear() {
|
||||
this.allResourceCate.forEach(item => {
|
||||
item.checked = false;
|
||||
});
|
||||
this.allResource.forEach(item => {
|
||||
item.checked = false;
|
||||
});
|
||||
this.$forceUpdate();
|
||||
},
|
||||
handleCheckAllChange(cate) {
|
||||
let cateResources = this.getResourceByCate(cate.id);
|
||||
for (let i = 0; i < cateResources.length; i++) {
|
||||
cateResources[i].checked = cate.checked;
|
||||
}
|
||||
this.$forceUpdate();
|
||||
},
|
||||
handleCheckChange(resource) {
|
||||
this.allResourceCate.forEach(item=>{
|
||||
if(item.id===resource.categoryId){
|
||||
item.checked = this.isAllChecked(resource.categoryId);
|
||||
}
|
||||
});
|
||||
this.$forceUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-layout {
|
||||
padding: 20px;
|
||||
border-left: 1px solid #DCDFE6;
|
||||
border-right: 1px solid #DCDFE6;
|
||||
border-bottom: 1px solid #DCDFE6;
|
||||
}
|
||||
|
||||
.top-line {
|
||||
border-top: 1px solid #DCDFE6;
|
||||
}
|
||||
</style>
|
348
src/views/ums/role/index.vue
Normal file
348
src/views/ums/role/index.vue
Normal file
@ -0,0 +1,348 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="filter-container" shadow="never">
|
||||
<div>
|
||||
<i class="el-icon-search"></i>
|
||||
<span>筛选搜索</span>
|
||||
<el-button
|
||||
style="float:right"
|
||||
type="primary"
|
||||
@click="handleSearchList()"
|
||||
size="small"
|
||||
>
|
||||
查询搜索
|
||||
</el-button>
|
||||
<el-button
|
||||
style="float:right;margin-right: 15px"
|
||||
@click="handleResetSearch()"
|
||||
size="small"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
</div>
|
||||
<div style="margin-top: 15px">
|
||||
<el-form
|
||||
:inline="true"
|
||||
:model="listQuery"
|
||||
size="small"
|
||||
label-width="140px"
|
||||
>
|
||||
<el-form-item label="输入搜索:">
|
||||
<el-input
|
||||
v-model="listQuery.keyword"
|
||||
class="input-width"
|
||||
placeholder="角色名称"
|
||||
clearable
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="operate-container" shadow="never">
|
||||
<i class="el-icon-tickets"></i>
|
||||
<span>数据列表</span>
|
||||
<el-button
|
||||
size="mini"
|
||||
class="btn-add"
|
||||
@click="handleAdd()"
|
||||
style="margin-left: 20px"
|
||||
>添加</el-button
|
||||
>
|
||||
</el-card>
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="roleTable"
|
||||
:data="list"
|
||||
style="width: 100%;"
|
||||
v-loading="listLoading"
|
||||
border
|
||||
>
|
||||
<el-table-column label="编号" width="100" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.id }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="角色名称" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述" align="center">
|
||||
<template slot-scope="scope">{{ scope.row.description }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="添加时间" width="160" align="center">
|
||||
<template slot-scope="scope">{{
|
||||
scope.row.createTime | formatDateTime
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否启用" width="140" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-switch
|
||||
@change="handleStatusChange(scope.$index, scope.row)"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
v-model="scope.row.status"
|
||||
:disabled="
|
||||
scope.row.id === '1385165161056309248' ||
|
||||
scope.row.id === '1418108522993946624'
|
||||
"
|
||||
>
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="160" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-row>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleSelectMenu(scope.$index, scope.row)"
|
||||
:disabled="
|
||||
scope.row.id === '1385165161056309248' ||
|
||||
scope.row.id === '1418108522993946624'
|
||||
"
|
||||
>分配菜单
|
||||
</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleSelectResource(scope.$index, scope.row)"
|
||||
:disabled="
|
||||
scope.row.id === '1385165161056309248' ||
|
||||
scope.row.id === '1418108522993946624'
|
||||
"
|
||||
>分配资源
|
||||
</el-button>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleUpdate(scope.$index, scope.row)"
|
||||
:disabled="
|
||||
scope.row.id === '1385165161056309248' ||
|
||||
scope.row.id === '1418108522993946624'
|
||||
"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@click="handleDelete(scope.$index, scope.row)"
|
||||
:disabled="
|
||||
scope.row.id === '1385165161056309248' ||
|
||||
scope.row.id === '1418108522993946624'
|
||||
"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
layout="total, sizes,prev, pager, next,jumper"
|
||||
:current-page.sync="listQuery.pageNum"
|
||||
:page-size="listQuery.pageSize"
|
||||
:page-sizes="[5, 10, 15]"
|
||||
:total="total"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="isEdit ? '编辑角色' : '添加角色'"
|
||||
:visible.sync="dialogVisible"
|
||||
width="40%"
|
||||
>
|
||||
<el-form :model="role" ref="roleForm" label-width="150px" size="small">
|
||||
<el-form-item label="角色名称:">
|
||||
<el-input v-model="role.name" style="width: 250px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述:">
|
||||
<el-input
|
||||
v-model="role.description"
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
style="width: 250px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用:">
|
||||
<el-radio-group v-model="role.status">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false" size="small">取 消</el-button>
|
||||
<el-button type="primary" @click="handleDialogConfirm()" size="small"
|
||||
>确 定</el-button
|
||||
>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
fetchList,
|
||||
createRole,
|
||||
updateRole,
|
||||
updateStatus,
|
||||
deleteRole
|
||||
} from '@/api/role';
|
||||
import { formatDate } from '@/utils/date';
|
||||
|
||||
const defaultListQuery = {
|
||||
pageNum: 1,
|
||||
pageSize: 5,
|
||||
keyword: null
|
||||
};
|
||||
const defaultRole = {
|
||||
id: null,
|
||||
name: null,
|
||||
description: null,
|
||||
adminCount: 0,
|
||||
status: 1
|
||||
};
|
||||
export default {
|
||||
name: 'roleList',
|
||||
data() {
|
||||
return {
|
||||
listQuery: Object.assign({}, defaultListQuery),
|
||||
list: null,
|
||||
total: null,
|
||||
listLoading: false,
|
||||
dialogVisible: false,
|
||||
role: Object.assign({}, defaultRole),
|
||||
isEdit: false
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
filters: {
|
||||
formatDateTime(time) {
|
||||
if (time == null || time === '') {
|
||||
return 'N/A';
|
||||
}
|
||||
let date = new Date(time);
|
||||
return formatDate(date, 'yyyy-MM-dd hh:mm:ss');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleResetSearch() {
|
||||
this.listQuery = Object.assign({}, defaultListQuery);
|
||||
},
|
||||
handleSearchList() {
|
||||
this.listQuery.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.listQuery.pageNum = 1;
|
||||
this.listQuery.pageSize = val;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.listQuery.pageNum = val;
|
||||
this.getList();
|
||||
},
|
||||
handleAdd() {
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = false;
|
||||
this.role = Object.assign({}, defaultRole);
|
||||
},
|
||||
handleStatusChange(index, row) {
|
||||
this.$confirm('是否要修改该状态?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
updateStatus(row.id, { status: row.status }).then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '修改成功!'
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: '取消修改'
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
handleDelete(index, row) {
|
||||
this.$confirm('是否要删除该角色?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let ids = [];
|
||||
ids.push(row.id);
|
||||
let params = new URLSearchParams();
|
||||
params.append('ids', ids);
|
||||
deleteRole(params).then(response => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功!'
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
handleUpdate(index, row) {
|
||||
this.dialogVisible = true;
|
||||
this.isEdit = true;
|
||||
this.role = Object.assign({}, row);
|
||||
},
|
||||
handleDialogConfirm() {
|
||||
this.$confirm('是否要确认?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (this.isEdit) {
|
||||
updateRole(this.role.id, this.role).then(response => {
|
||||
this.$message({
|
||||
message: '修改成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
createRole(this.role).then(response => {
|
||||
this.$message({
|
||||
message: '添加成功!',
|
||||
type: 'success'
|
||||
});
|
||||
this.dialogVisible = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
handleSelectMenu(index, row) {
|
||||
this.$router.push({ path: '/ums/allocMenu', query: { roleId: row.id } });
|
||||
},
|
||||
handleSelectResource(index, row) {
|
||||
this.$router.push({
|
||||
path: '/ums/allocResource',
|
||||
query: { roleId: row.id }
|
||||
});
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
fetchList(this.listQuery).then(response => {
|
||||
this.listLoading = false;
|
||||
this.list = response.data.list;
|
||||
this.total = response.data.total;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style></style>
|
Reference in New Issue
Block a user