目录:
(1)职称管理页面设计
(2)职称管理接口调用
(3)职称管理编辑功能实现
(4)职称管理批量删除功能实现
(5)权限组页面设计
(6) 权限组树形菜单展示
(7)角色菜单功能实现
(8)角色操作功能实现
(9)部门展示与搜索功能实现
(10)部门操作按钮设计
(11)部门添加功能实现
(12) 部门删除功能实现
(1)职称管理页面设计
JoblevelMana.vue
(2)职称管理接口调用
添加职称:
删除方法:
点击取消
点击确定:
(3)职称管理编辑功能实现
更新方法:
(4)职称管理批量删除功能实现
添加批量删除按钮:
JoblevelMana.vue:详细代码:
<template>
<div>
<div>
<el-input size="small" v-model="jl.name" style="width: 300px" prefix-icon="el-icon-plus"
placeholder="添加职称...">
</el-input>
<!--下拉框-->
<el-select v-model="jl.titleLevel" palaceholder="职称等级" size="small" style="margin-left: 6px;margin-right: 6px">
<el-option v-for="item in titleLevels"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-button type="primary" icon="el-icon-plus" size="small" @click="addJl">添加</el-button>
</div>
<div style="margin-top: 10px">
<el-table :data="jls"
border
stripe
size="small"
@selection-change="handleSelectionChange"
style="width: 80%">
<!-- 多选框 -->
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
prop="id"
label="编号"
width="55">
</el-table-column>
<el-table-column
prop="name"
label="职称名称"
width="150">
</el-table-column>
<el-table-column
prop="titleLevel"
label="职称级别"
width="150">
</el-table-column>
<el-table-column
prop="createDate"
label="创建时间"
width="150">
</el-table-column>
<el-table-column prop="enabled"
label="是否启用"
width="150">
<template slot-scope="scope">
<el-tag v-if="scope.row.enabled" type="success">已启用</el-tag>
<el-tag v-else type="danger">未启用</el-tag>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="small" @click="showEditView(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="deleteHandler(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 批量删除按钮 -->
<el-button type="danger" size="small" style="margin-top: 10px" :disabled="multipleSelection.length == 0"
@click="deleteMany">批量删除
</el-button>
</div>
<!--弹出框-->
<el-dialog
title="编辑职称"
:visible.sync="dialogVisible"
width="30%">
<div>
<table>
<tr>
<td>
<el-tag>职称名称</el-tag>
</td>
<td>
<el-input v-model="updateJl.name" size="small" style="margin-left: 6px"></el-input>
</td>
</tr>
<tr>
<td>
<el-tag>职称级别</el-tag>
</td>
<td>
<el-select v-model="updateJl.titleLevel"
placeholder="职称等级" size="small"
style="margin-left: 6px;margin-right:6px">
<el-option
v-for="item in titleLevels"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</td>
</tr>
<tr>
<td>
<el-tag>是否启用</el-tag>
</td>
<td>
<el-switch
style="margin-left: 6px"
v-model="updateJl.enabled"
activecolor="#13ce66"
inactive-color="#ff4949"
active-text="启用"
inactive-text="禁用">
</el-switch>
</td>
</tr>
</table>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogVisible = false">取 消</el-button>
<el-button size="small" type="primary" @click="doUpdate">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "JoblevelMana",
data() {
return {
//json对象
jl: {
name: '',
titleLevel: ''
},
//更新的json数据
updateJl: {
name: '',
titleLevel: '',
enabled: false
},
titleLevels: [
'正高级',
'副高级',
'中级',
'初级',
'员级',
],
jls: [],
dialogVisible: false,
//数组
multipleSelection: []
}
},
//当页面刚加载的时候调用initJls方法调用后端接口,获取所有职称列表
mounted() {
this.initJls();
},
methods:{
//批量删除方法
deleteMany() {
this.$confirm('此操作将永久删除【' + this.multipleSelection.length + '】条记录,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let ids = '?';
this.multipleSelection.forEach(item => {
ids += 'ids=' + item.id + '&';
})
this.deleteRequest('/system/basic/joblevel/' + ids).then(resp => {
if (resp) {
//批量删除之后,在次获取称列表,进行刷新
this.initJls();
}
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
//表单勾选的对象,放到multipleSelection数组里面
handleSelectionChange(val) {
this.multipleSelection = val;
},
//显示编辑框
showEditView(data) {
//在编辑框里显示数据,采用Object.assign()这个方式
Object.assign(this.updateJl, data);
//把日期传过去,否则更改的时候会报错
this.updateJl.createDate = '';
//显示弹出框
this.dialogVisible = true;
},
//修改职称方法
doUpdate() {
this.putRequest('/system/basic/joblevel/', this.updateJl).then(resp => {
if (resp) {
//更改数据之后,再次获取职位列表,进行更新
this.initJls();
this.updateJl.name = '';
this.updateJl.titleLevel = '';
//把弹出框隐藏
this.dialogVisible = false;
}
})
},
//删除职称方法
deleteHandler(data) {
//删除
this.$confirm('此操作将永久删除【' + data.name + '】职称, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.deleteRequest('/system/basic/joblevel/' +
data.id).then(resp => {
if (resp) {
//删除之后,再次获取职位列表,进行更新
this.initJls();
}
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
//添加职称方法
addJl() {
//判断输入框是否为空
if (this.jl.name && this.jl.titleLevel) {
//调用后端接口/system/basic/joblevel
this.postRequest('/system/basic/joblevel/', this.jl).then(resp => {
if (resp) {
//添加之后,再次获取职位列表,进行更新
this.initJls();
//添加完之后,输入框设为空
this.jl.name = '';
this.jl.titleLevel = '';
}
})
} else {
this.$message.error("字段不能为空!");
}
},
//初始化获取职称列表
initJls() {
this.getRequest('/system/basic/joblevel/').then(resp => {
if (resp) {
this.jls = resp;
/*this.jl = {
name: '',
titleLevel: ''
}*/
}
})
}
}
}
</script>
<style scoped>
</style>
(5)权限组页面设计
权限组主要用来干什么呢?主要用来更新以及展示咱们不同的角色所拥有的不同的菜单权限,这里涉及到很多操作,以及角色的添加,角色的查询,角色的删除,以及跟角色相关的菜单一个权限的操作,比如说菜单权限的展示,每一个角色所对应的一个菜单权限的展示,以及你去更新你的角色菜单权限
(6) 权限组树形菜单展示
(7)角色菜单功能实现
设置默认菜单列表的选中状态
这样每个角色默认拥有的菜单权限,就进行相应的一个展示了
更新角色菜单:
在mian.js中添加:
这样以后在使用elementUI的时候就不用每次进行设置size:small了
(8)角色操作功能实现
删除角色:
PermissManan.vue:详细代码:
<template>
<div>
<div class="permissManaTool">
<el-input size="small" placeholder="请输入角色英文名" v-model="role.name">
<!--自带的前缀 -->
<template slot="prepend">ROLE_</template>
</el-input>
<!--@keydown.enter.native="doAddRole":添加键盘回车事件,调用添加角色的方法-->
<el-input size="small" placeholder="请输入角色中文名" v-model="role.nameZh" @keydown.enter.native="doAddRole"></el-input>
<el-button type="primary" size="small" icon="el-icon-plus" @click="doAddRole">添加角色</el-button>
</div>
<div class="permissManaMain">
<!--采用elementUI的折叠面板(手风琴模式)-->
<el-collapse v-model="activeName" accordion @change="change">
<el-collapse-item :title="r.nameZh" :name="r.id" v-for="(r,index) in roles" :key="index">
<!--使用elementUI的卡片-->
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>可访问资源</span>
<el-button style="float: right;padding: 3px 0;color: #ff0000" icon="el-icon-delete"
type="text" @click="doDeleteRole(r)">
</el-button>
</div>
<div>
<!-- 使用树形控件展示 show-checkbox:多选框-->
<el-tree
show-checkbox
:key="index"
ref="tree"
:default-checked-keys="selectedMenus"
node-key="id"
:data="allMenus" :props="defaultProps">
</el-tree>
<div style="display: flex;justify-content: flex-end">
<el-button @click="cancelUpdate">取消修改</el-button>
<el-button type="primary" @click="doUpdate(r.id,index)">确认修改</el-button>
</div>
</div>
</el-card>
</el-collapse-item>
</el-collapse>
</div>
</div>
</template>
<script>
export default {
name: "PermissMana",
data() {
return {
//默认打开,上面第二个div
activeName: '2',
//json对象
role: {
name: '',
nameZh: ''
},
//角色数组
roles: [],
//所有菜单数据
allMenus: [],
//菜单选中的数组
selectedMenus: [],
//让接口返回的数据与树形控件对应 指定节点对象的某个属性值
defaultProps: {
children: 'children',
label: 'name'
}
}
},
//当页面刚加载的时候调用initRoles方法调用后端接口,获取所有角色列表
mounted() {
this.initRoles();
},
methods:{
//删除角色方法
doDeleteRole(role) {
this.$confirm('此操作将永久删除该【' + role.nameZh + '】角色, 是否继 ? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
//调用后端接口/system/basic/permission/role/
this.deleteRequest('/system/basic/permission/role/' + role.id).then(resp => {
if (resp) {
//删除完之后,更新一下角色列表
this.initRoles();
}
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
//添加角色方法
doAddRole() {
//首先判断两个输入框不为空
if (this.role.name && this.role.nameZh) {
//调用后端接口/system/basic/permission/
this.postRequest('/system/basic/permission/role', this.role).then(resp => {
if (resp) {
//添加完之后输入框为空
this.name = '';
this.nameZh = '';
//添加完之后,更新一下角色列表
this.initRoles();
}
})
} else {
this.$message.error('字段不能为空!');
}
},
//更新角色菜单方法
doUpdate(rid, index) {
let tree = this.$refs.tree[index];
//获取所有的key,只获取叶子节点
let selectedKeys = tree.getCheckedKeys(true);
let url = '/system/basic/permission/?rid=' + rid;
selectedKeys.forEach(key => {
url += '&mids=' + key;
})
//调用后端接口/system/basic/permission
this.putRequest(url).then(resp => {
if (resp) {
//等于-1 更新完之后下拉框就会关掉
this.activeName = -1;
}
})
},
//取消更新
cancelUpdate() {
this.activeName = -1;
},
//改变事件
change(rid) {
if (rid) {
//调用initAllMenus方法
this.initAllMenus();
//调用initSelectedMenus方法获取角色对应的菜单
this.initSelectedMenus(rid);
}
},
//初始化所有菜单
initAllMenus() {
//调用后端接口
this.getRequest('/system/basic/permission/menus').then(resp => {
//让allMenus数组接收返回的数据resp
this.allMenus = resp;
})
},
//根据id获取角色拥有的菜单方法
initSelectedMenus(rid) {
//调用后端接口/system/basic/permission/mid
this.getRequest('/system/basic/permission/mid/' + rid).then(resp => {
//让定义的数组接收返回的数据resp
this.selectedMenus = resp;
})
},
//查询所有角色
initRoles() {
//调用后端接口
this.getRequest('/system/basic/permission/').then(resp => {
if (resp) {
this.roles = resp;
}
})
}
}
}
</script>
<style>
.permissManaTool {
display: flex;
justify-content: flex-start;
}
.permissManaTool .el-input {
width: 300px;
margin-right: 6px;
}
.permissManaMain {
margin-top: 10px;
width: 700px
}
</style>
以上权限功能都实现完了,有哪些功能呢?添加角色、查询角色、删除角色
查询角色:使用折叠面板(手风琴形式) 角色里面,还有菜单与角色相关的功能:查询所有菜单(使用了树形控件)查询角色所拥有的的菜单权限
(9)部门展示与搜索功能实现
DepManan.vue:
(10)部门操作按钮设计
在每一行下面都要有一个添加删除的按钮
(11)部门添加功能实现
点击添加部门弹出一个弹出框
这里不是刷新列表,而是调用方法手动添加到树形节点,因为刷新的话,添加成功后列表的关闭了
(12) 部门删除功能实现
当aaa部门下有子部门,删除失败:
先删除111:
DepManan.vue:详细代码:
<template>
<div style="width: 500px">
<el-input placeholder="请输入部门名称进行搜索..."
prefix-icon="el-icon-search"
v-model="filterText">
</el-input>
<!--:expand-on-click-node="false":当点击添加部门按钮的时候节点不会展开-->
<el-tree
:data="deps"
:props="defaultProps"
:filter-node-method="filterNode"
:expand-on-click-node="false"
ref="tree">
<!--eleementUI按钮自定义节点 -->
<span class="custom-tree-node" style="display: flex;justify-content: space-between;width: 100%;"
slot-scope="{node,data}">
<span>{{data.name}}</span>
<span>
<el-button
type="primary"
size="mini"
class="depBtn"
@click="()=>showAddDepView(data)">
添加部门
</el-button>
<el-button
type="danger"
size="mini"
class="depBtn"
@click="()=>deleteDep(data)">
删除部门
</el-button>
</span>
</span>
</el-tree>
<!--添加部门弹出框 -->
<el-dialog
title="添加部门"
:visible.sync="dialogVisible"
width="30%">
<div>
<table>
<tr>
<td>
<el-tag>上级部门</el-tag>
</td>
<td>{{pname}}</td>
</tr>
<tr>
<td>
<el-tag>部门名称</el-tag>
</td>
<td>
<el-input v-model="dep.name" placeholder="请输入部门名称..."></el-input>
</td>
</tr>
</table>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible= false">取消</el-button>
<el-button type="primary" @click="doAddDep">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
name: "DepMana",
data() {
return {
filterText: '',
//返回的数据数组
deps: [],
//接口返回数据与树形节点的属性的相对应
defaultProps: {
children: 'children',
label: 'name'
},
//添加部门的数据对象
dep: {
name: '',
parentId: -1
},
pname: '',
//定义弹出框是否可见
dialogVisible: false
}
},
//观察者事件,观察上面filterText的值,有值的话去找树形控件tree,filter调用下面filterNode方法
watch: {
filterText(val) {
this.$refs.tree.filter(val);
}
},
//当页面刚加载的时候调用initRoles方法调用后端接口,获取所有角色列表
mounted() {
this.initDeps();
},
methods: {
//获取数据部门列表的方法
initDeps() {
//调用后端接口,/system/basic/department
this.getRequest('/system/basic/department/').then(resp => {
if (resp) {
this.deps = resp;
}
})
},
//手动添加到树形控件的方法
addDep2Deps(deps, dep) {
//循环所有部门
for (let i = 0; i < deps.length; i++) {
let d = deps[i];
//deps是所有部门 dep是添加的部门,当添加的部门是所有部门中的一个的id相等的话,添加进去
if (d.id == dep.parentId) {
d.children = d.children.concat(dep);
//添加完后,判断它子部门长度是否大于0,有的话它的属性parent变为true
if (d.children.length > 0) {
d.isParent = true;
}
return;
} else {
//递归循环子部门知道id相等
this.addDep2Deps(d.children, dep);
}
}
},
//添加部门,让弹出框显示,并把数据在弹出框内显示
showAddDepView(data) {
this.pname = data.name;
this.dep.parentId = data.id;
this.dialogVisible = true;
},
//初始化部门
initDep() {
this.dep = {
name: '',
parentId: -1
}
this.pname = '';
},
//添加部门方法
doAddDep() {
//调用后端接口/system/basic/department
this.postRequest('/system/basic/department/',
this.dep).then(resp => {
if (resp) {
//调用手动添加到树形控件的方法
this.addDep2Deps(this.deps, resp.obj);
//添加成功后,弹出框隐藏
this.dialogVisible = false;
//添加成功后,弹出框,初始化部门设为空
this.initDep();
}
})
},
//手动删除属性节点的方法
removeDepFromDeps(p, deps, id) {
for (let i = 0; i < deps.length; i++) {
let d = deps[i];
//当循环的id和删除的id一样进行删除
if (d.id ==id) {
deps.splice(i,1);
//删除子部门后,判断一下deps是否为0,0的话改为false,否则副部们一直不能删除
if (deps.length == 0) {
p.isParent = false;
}
return;
} else {
//递归查找id
this.removeDepFromDeps(d, d.children, id);
}
}
},
//删除部门
deleteDep(data) {
//删除的时候,可以判断一下,是否是parent,是parent的话不能删
if (data.isParent) {
this.$message.error("父部门删除失败!");
} else {
this.$confirm('此操作将永久删除该【' + data.name + '】部门, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//调用后端接口/system/basic/department
this.deleteRequest('/system/basic/department/' + data.id).then(resp => {
if (resp) {
//手动删除属性节点的方法
this.removeDepFromDeps(null, this.deps, data.id);
}
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
},
//拦截节点的方法,对树的节点筛选的一个方法
filterNode(value, data) {
if (!value) return true;//输入为空,返回true节点展示,false节点隐藏
return data.name.indexOf(value) !== -1;//返回true的话节点展示
}
}
}
</script>
<style>
.depBtn {
padding: 2px;
}
</style>