说明
主要包括用户管理,角色管理,系统管理
一、后端
代码: https://gitee.com/leiyuee/manage.git
先通过manage.sql生成数据库表
其余内容:建议使用mybatis代码生成器
二、前端
1 菜单列表修改
前往src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: '管理系统',
component: () => import('@/views/dashboard/index'),
meta: { title: '管理系统', icon: 'dashboard' }
}]
},
{
path: '/sys',
component: Layout,
redirect: '/sys',
name: '系统管理',
meta: { title: '系统管理', icon: 'el-icon-s-help' },
children: [
{
path: 'UserMange',
name: 'UserMange',
component: () => import('@/views/sys/UserManage'),
meta: { title: '用户管理', icon: 'table' }
},
{
path: 'RoleManage',
name: 'RoleManage',
component: () => import('@/views/sys/RoleManage'),
meta: { title: '角色管理', icon: 'table' }
},
{
path: 'MenuManage',
name: 'MenuManage',
component: () => import('@/views/sys/MenuManage'),
meta: { title: '功能管理', icon: 'tree' }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
2 用户管理模块
在src/views 下新建sys文件夹及文件如下
在src/api文件夹下新建文件如下
2.1 用户管理
UserManage.vue
<template>
<div>
<el-card class="box-card">
<div slot="header">
<el-row>
<el-button type="primary" @click=" addForm = true ">新增</el-button>
<el-button type="primary" @click=" toUpdate ">修改</el-button>
<el-button type="primary" @click="toDel">删除</el-button>
<el-button type="primary" @click="toQue">查询</el-button>
</el-row>
</div>
<div >
<el-table
:data="tableData"
highlight-current-row
@current-change="handleCurrentChange"
border
style="width: 100%">
<el-table-column
prop="userName"
label="用户名"
width="180">
</el-table-column>
<el-table-column
prop="nickName"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="password"
label="密码">
</el-table-column>
</el-table>
</div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page= searchData.pageNum
:page-sizes="[10, 20, 30, 40]"
:page-size= searchData.pageSize
layout="total, sizes, prev, pager, next, jumper"
:total= "total">
</el-pagination>
</el-card>
<!-- 分页 -->
<el-dialog title="新增用户" :visible.sync="addForm">
<el-form :model="add">
<el-form-item label="用户名" :label-width="formWidth">
<el-input v-model="add.userName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="别名" :label-width="formWidth">
<el-input v-model="add.nickName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="用户密码" :label-width="formWidth">
<el-input v-model="add.password" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addForm = false">取 消</el-button>
<el-button type="primary" @click="toAdd">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="修改用户" :visible="updateForm">
<el-form :model="currentRow">
<el-form-item label="用户名" :label-width="formWidth">
<el-input v-model="currentRow.userName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="别名" :label-width="formWidth">
<el-input v-model="currentRow.nickName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="用户密码" :label-width="formWidth">
<el-input v-model="currentRow.password" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="updateForm = false">取 消</el-button>
<el-button type="primary" @click="updateU">修 改</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {getUserPages,addUser,updateUser,deleteUser} from '@/api/user'
export default {
data() {
return {
// 分页相关
total:0 ,
// 查询条件,分页数据
searchData: {
pageNum: 1, // 当前页
pageSize: 10,// 页面大小
},
tableData: null,
addForm: false,
updateForm: false,
formWidth: '120px',
add: {},
currentRow: {},
}
},
created() {
this.init()
},
methods: {
init(){
getUserPages(this.searchData).then(res=>{
this.tableData = res.data.records
this.total = res.data.total
})
},
toAdd(){
addUser(this.add).then(res =>{
if(res.code == 200){
this.$message.success(res.msg)
this.addForm = false
this.init()
}else{
this.$message(res.msg)
}
})
},
toUpdate(){
if(this.currentRow == null){
this.$message.error("请选择要修改的用户")
}else{
this.updateForm = true
}
},
updateU(){
updateUser(this.currentRow.userId,this.currentRow).then(res=>{
if(res.code == 200){
this.$message.success(res.msg)
this.updateForm = false
this.init()
}else{
this.$message(res.msg)
}
})
},
toDel(){
if(this.currentRow == null){
this.$message.error("请选择要删除的用户")
}
deleteUser(this.currentRow.userId).then (res =>{
if(res.code == 200){
this.$message.success(res.msg)
this.init()
}else{
this.$message(res.msg)
}
})
},
toQue(){
this.$message('查询')
},
//选择:
handleCurrentChange(val){
this.currentRow = val
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
}
},
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>
user.js
import request from '@/utils/request'
export function login(data) {
return request({
url: '/api/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/api/info',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: '/api/logout',
method: 'post'
})
}
// 查询所有用户
export function getUserList() {
return request({
url: '/api/user/getUserList',
method: 'get',
})
}
export function getUserPages(data) {
return request({
url: '/api/user',
method: 'get',
params: data
})
}
export function addUser(data) {
return request({
url: '/api/user',
method: 'post',
data
})
}
export function updateUser(id, data) {
return request({
url: `/api/user/${id}`,
method: 'put',
data
})
}
export function deleteUser(id) {
return request({
url: `/api/user/${id}`,
method: 'delete'
})
}
2.2 角色管理
RoleManage.vue
<template>
<div>
<el-card class="box-card">
<div slot="header">
<el-row>
<el-button type="primary" @click=" addForm = true ">新增</el-button>
<el-button type="primary" @click=" toUpdate ">修改</el-button>
<el-button type="primary" @click="toDel">删除</el-button>
<el-button type="primary" @click="toQue">查询</el-button>
</el-row>
</div>
<div >
<el-table
:data="tableData"
highlight-current-row
@current-change="handleCurrentChange"
border
style="width: 100%">
<el-table-column
prop="name"
label="名称"
width="180">
</el-table-column>
<el-table-column
prop="code"
label="编码"
width="180">
</el-table-column>
<el-table-column
prop="type"
label="类型"
width="180">
</el-table-column>
<el-table-column
prop="status"
label="状态"
width="180">
</el-table-column>
</el-table>
</div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page= searchData.pageNum
:page-sizes="[10, 20, 30, 40]"
:page-size= searchData.pageSize
layout="total, sizes, prev, pager, next, jumper"
:total= "total">
</el-pagination>
</el-card>
<!-- 分页 -->
<el-dialog title="新增" :visible.sync="addForm">
<el-form :model="add">
<el-form-item label="名称" :label-width="formWidth">
<el-input v-model="add.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="编码" :label-width="formWidth">
<el-input v-model="add.code" autocomplete="off"></el-input>
</el-form-item>
<!-- <el-select v-model="form.nikeName" placeholder="请选择活动区域">
<el-option label="密码" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select> -->
<el-form-item label="英文名称" :label-width="formWidth">
<el-input v-model="add.ename" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="层级" :label-width="formWidth">
<el-input v-model="add.layer" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="父节点" :label-width="formWidth">
<el-input v-model="add.pid" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="类型" :label-width="formWidth">
<el-input v-model="add.type" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="状态" :label-width="formWidth">
<el-input v-model="add.status" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addForm = false">取 消</el-button>
<el-button type="primary" @click="toAdd">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="修改" :visible="updateForm">
<el-form :model="currentRow">
<el-form-item label="名称" :label-width="formWidth">
<el-input v-model="currentRow.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="编码" :label-width="formWidth">
<el-input v-model="currentRow.code" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="英文名称" :label-width="formWidth">
<el-input v-model="currentRow.ename" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="层级" :label-width="formWidth">
<el-input v-model="add.layer" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="父节点" :label-width="formWidth">
<el-input v-model="add.pid" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="类型" :label-width="formWidth">
<el-input v-model="add.type" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="状态" :label-width="formWidth">
<el-input v-model="add.status" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="updateForm = false">取 消</el-button>
<el-button type="primary" @click="updateR">修 改</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {getRolePages,addRole,updateRole,deleteRole} from '@/api/role'
export default {
data() {
return {
// 分页相关
total:0 ,
// 查询条件,分页数据
searchData: {
pageNum: 1, // 当前页
pageSize: 10,// 页面大小
},
tableData: null,
addForm: false,
updateForm: false,
formWidth: '120px',
add: {},
currentRow: {},
}
},
created() {
this.init()
},
methods: {
init(){
getRolePages(this.searchData).then(res=>{
this.tableData = res.data.records
this.total = res.data.total
})
},
toAdd(){
addRole(this.add).then(res =>{
if(res.code == 200){
this.$message.success(res.msg)
this.addForm = false
this.init()
}else{
this.$message(res.msg)
}
})
},
toUpdate(){
if(this.currentRow == null){
this.$message.error("请选择要修改的用户")
}else{
this.updateForm = true
}
},
updateR(){
updateRole(this.currentRow.roleId,this.currentRow).then(res=>{
if(res.code == 200){
this.$message.success(res.msg)
this.updateForm = false
this.init()
}else{
this.$message(res.msg)
}
})
},
toDel(){
if(this.currentRow == null){
this.$message.error("请选择要删除的用户")
}
deleteRole(this.currentRow.roleId).then (res =>{
if(res.code == 200){
this.$message.success(res.msg)
this.init()
}else{
this.$message(res.msg)
}
})
},
toQue(){
this.$message('查询')
},
//选择:
handleCurrentChange(val){
this.currentRow = val
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
}
},
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>
role.js
import request from '@/utils/request'
export function getRolePages(data) {
return request({
url: '/api/role',
method: 'get',
params: data
})
}
export function addRole(data) {
return request({
url: '/api/role',
method: 'post',
data
})
}
export function updateRole(id, data) {
return request({
url: `/api/role/${id}`,
method: 'put',
data
})
}
export function deleteRole(id) {
return request({
url: `/api/role/${id}`,
method: 'delete'
})
}
2.3 菜单管理
MenuManage.vue
<template>
<div>
<el-card class="box-card">
<div slot="header">
<el-row>
<el-button type="primary" @click=" addForm = true ">新增</el-button>
<el-button type="primary" @click=" toUpdate ">修改</el-button>
<el-button type="primary" @click="toDel">删除</el-button>
<el-button type="primary" @click="toQue">查询</el-button>
</el-row>
</div>
<el-table
:data="treeData"
style="width: 100%;margin-bottom: 20px;"
row-key="menuId"
border
highlight-current-row
@current-change ="handleCurrentChange"
default-expand-all
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
<el-table-column
prop="menuName"
label="菜单"
width="180">
</el-table-column>
<el-table-column
prop="path"
label="地址"
width="180">
</el-table-column>
<el-table-column
prop="menuType"
label="类型">
</el-table-column>
</el-table>
</el-card>
<el-dialog title="新增" :visible.sync="addForm">
<el-form :model="add">
<el-form-item label="菜单名称" :label-width="formWidth">
<el-input v-model="add.menuName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="父节点" :label-width="formWidth">
<treeselect v-model="add.parentId"
disable
:options="treeData"
placeholder="功能组菜单"
:normalizer="normalizer"/>
</el-form-item>
<el-form-item label="地址" :label-width="formWidth">
<el-input v-model="add.path" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="类型" :label-width="formWidth">
<el-input v-model="add.meunType" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addForm = false">取 消</el-button>
<el-button type="primary" @click="toAdd">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="修改" :visible.sync="updateForm">
<el-form :model="currentRow">
<el-form-item label="菜单名称" :label-width="formWidth">
<el-input v-model="currentRow.menuName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="父节点" :label-width="formWidth">
<treeselect v-model="add.parentId"
disable
:options="treeData"
placeholder="菜单"
:normalizer="normalizer"/>
</el-form-item>
<el-form-item label="地址" :label-width="formWidth">
<el-input v-model="currentRow.path" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="类型" :label-width="formWidth">
<el-input v-model="currentRow.meunType" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="updateForm = false">取 消</el-button>
<el-button type="primary" @click="updateM">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {addMenu,updateMenu,deleteMenu,menuTree} from '@/api/menu'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
components: {
Treeselect
},
data() {
return {
tableData: null,
addForm: false,
updateForm: false,
formWidth: '120px',
add: {},
currentRow: {},
treeData:[],
// normalizer(node) {
// return {
// id: node.menuId,
// label: node.menuName,
// children: node.children,
// }
// },
}
},
created() {
this.init()
},
methods: {
init(){
menuTree().then(res=>{
console.log(res)
this.treeData = res.data
})
},
normalizer(node) {
return {
id: node.menuId,
label: node.menuName,
children: node.children,
}
},
toAdd(){
console.log("add",this.add)
addMenu(this.add).then(res =>{
if(res.code == 200){
this.$message.success(res.msg)
this.addForm = false
this.init()
}else{
this.$message(res.msg)
}
})
},
toUpdate(){
if(this.currentRow == null){
this.$message.error("请选择要修改的菜单")
}else{
this.updateForm = true
}
},
updateM(){
updateMenu(this.currentRow.menuId,this.currentRow).then(res=>{
if(res.code == 200){
this.$message.success(res.msg)
this.updateForm = false
this.init()
}else{
this.$message(res.msg)
}
})
},
toDel(){
if(this.currentRow == null){
this.$message.error("请选择要删除的菜单")
}
deleteMenu(this.currentRow.menuId).then (res =>{
if(res.code == 200){
this.$message.success(res.msg)
this.init()
}else{
this.$message(res.msg)
}
})
},
toQue(){
this.$message('查询')
},
//选择:
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(val)
// console.log(`当前页: ${val}`);
},
handleNodeClick(data) {
console.log(data);
}
},
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>
menu.js
import request from '@/utils/request'
export function addMenu(data) {
return request({
url: '/api/menu',
method: 'post',
data
})
}
export function updateMenu(id, data) {
return request({
url: `/api/menu/${id}`,
method: 'put',
data
})
}
export function deleteMenu(id) {
return request({
url: `/api/menu/${id}`,
method: 'delete'
})
}
export function menuTree() {
return request({
url: `/api/menu/tree`,
method: 'get'
})
}
重点:选择树的使用
使用 vue-treeselect,
- 项目中安装
命令行 npm install --save @riophae/vue-treeselect - 页面使用
import Treeselect from ‘@riophae/vue-treeselect’
import ‘@riophae/vue-treeselect/dist/vue-treeselect.css’ - normalizer 来设置自定义的id 和lable
更详细内容可以查看官方文档