Authorization group front-end page production
Permission groups manage the relationship between roles and menus, and operators manage the relationship between users and roles.
The English input box must have a prefix, and the English name of the role in SpringSecurity needs to be prefixed with ROLE_
upper code
<div>
<div class="permissManaTool">
<el-input placeholder="请输入角色英文名" v-model="role.name">
<template slot="prepend">ROLE_</template>
</el-input>
<el-input placeholder="请输入角色中文名" v-model="role.nameZh"></el-input>
</div>
</div>
data(){
return{
role:{
name:"",
nameZh:"",
}
}
}
add button
<el-button type="primary" size="small" icon="el-icon-plus">添加角色</el-button>
Add input box style
.permissManaTool{
display: flex;
justify-content: flex-start;
}
.permissManaTool .el-input{
width: 300px;
margin-right: 8px;
}
Add a accordion
It can be seen that the second one is expanded, and
only one is enough
. Get all the roles from the database and display them on the page. Note that the backend not only returns all the roles but also returns the role operation menu, and returns which resources the roles can operate.
Front-end and back-end docking of authority user roles
Let's first query all the roles and display them on the front end
PermissController
@RestController
@RequestMapping("/system/basic/permiss")
public class PermissController {
@Autowired
RoleService roleService;
@GetMapping("/")
public List<Role> getAllRoles(){
return roleService.getAllRoles();
}
}
RoleService
@Service
public class RoleService {
@Autowired
RoleMapper roleMapper;
public List<Role> getAllRoles(){
return roleMapper.getAllRoles();
}
}
RoleMapper
List<Role> getAllRoles();
RoleMapper.xml
<select id="getAllRoles" resultMap="BaseResultMap">
select *
from role;
</select>
docking front
<div style="margin-top: 15px;width: 720px">
<el-collapse accordion>
<el-collapse-item :title="item.namezh" :name="index" v-for="(item,index) in roles" :key="index">
<div>与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div>
<div>在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div>
</el-collapse-item>
</el-collapse>
</div>
Display effect
The content displayed inside should be a card
component
<div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>卡片名称</span>
<el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>
</div>
<div v-for="o in 4" :key="o" class="text item">
{
{
'列表内容 ' + o }}
</div>
</el-card>
</div>
Change button style to trash can icon
<el-button style="float: right; padding: 3px 0;color: #ff2a0c" type="text" icon="el-icon-delete"></el-button>
Permission group menu tree display
Query all menus to display the tree structure, which needs to be processed and returned on the server side.
Query all parent-child menus, and associate yourself three times to form a table.
select m1.id as id1,m1.name as name1,m2.id as id2,m2.name as name2,m3.id as id3,m3.name as name3
from menu m1,menu m2,menu m3
where m1.id = m2.parentId and m2.id =m3.parentId and m3.enabled = true
ORDER BY m1.id,m2.id,m3.id```
### PermissController
![在这里插入图片描述](https://img-blog.csdnimg.cn/8bf2e5f06fc647038f6066e6603dfa49.png)
```java
@RestController
@RequestMapping("/system/basic/permiss")
public class PermissController {
@Autowired
RoleService roleService;
@Autowired
MenuService menuService;
@GetMapping("/")
public List<Role> getAllRoles(){
return roleService.getAllRoles();
}
@PostMapping("/menus")
public List<Menu> getAllMenus(){
return menuService.getAllMenus();
}
}
MenuService
@Service
public class MenuService {
@Autowired
MenuMapper menuMapper;
public RespBean getMenusByHrId() {
return RespBean.ok("操作成功!",menuMapper.getMenusByHrId( ((Hr) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId()));//Id从哪里来呢,前端传过来的信息是不可信,我们登录的用户信息保存在security,可以从Security里获取登录用户信息
}
/**
* 获取所有的菜单角色 一对多 一个菜单项有多个角色
* @return
*/
// @Cacheable
public List<Menu> getAllMenusWithRole(){
return menuMapper.getAllMenusWithRole();
}
public List<Menu> getAllMenus() {
return menuMapper.getAllMenus();
}
}
MenuMapper
List<Menu> getAllMenus();
MenuMapper.xml
A parent menu has multiple submenus, and there are menus in the submenus, three-level menus, direct query
If you don’t know how many levels of menus you can use recursion
<resultMap id="MenuWithChildren" type="com.xyg.pojo.Menu" extends="BaseResultMap">
<id column="id1" property="id"></id>
<result column="name1" property="name"></result>
<collection property="children" ofType="com.xyg.pojo.Menu">
<id column="id2" property="id"></id>
<result column="name2" property="name"></result>
<collection property="children" ofType="com.xyg.pojo.Menu">
<id column="id3" property="id"></id>
<result column="name3" property="name"></result>
</collection>
</collection>
</resultMap>
<select id="getAllMenus" resultMap="MenuWithChildren">
select m1.id as id1,m1.name as name1,m2.id as id2,m2.name as name2,m3.id as id3,m3.name as name3
from menu m1,menu m2,menu m3
where m1.id = m2.parentId and m2.id =m3.parentId and m3.enabled = true
ORDER BY m1.id,m2.id,m3.id
</select>
test
front end
Copy it over
, define the corresponding variables
, add a click event for the folding panel,
and make a request to load data from the backend
change(name){
if (name){
this.getAllMenus();//点击有id就执行
}
},
getAllMenus(){
this.postRequest("/system/basic/permiss/menus").then(resp=>{
if(resp){
console.log(resp)
this.allmenus=resp
}
})
},
Add multi-select box
display effect
Modification of menu role relationship
All the roles are displayed, and there is still a problem of pre-selection, which is to write the menu that the selected role can operate. See the
database has a menu_role menu role association table, query which menu can be operated according to the role id, and query the id of the menu that the role can operate come out.
Use components
to hardcode the data to see the effect of the default selection
Show the effect
Dynamically modify the data returned by the hardcoded data server, you can query the menu mid according to the role rid
PermissController
@GetMapping("/mids/{rid}")
public List<Integer> getMidsByTid(@PathVariable Integer rid){
return menuService.getMidsByTid(rid);
}
menuMapper
public List<Integer> getMidsByTid(Integer rid) {
return menuMapper.getMidsByTid(rid);
}
MenuMapper
List<Integer> getMidsByTid(Integer rid);
MenuMapper.xml
<select id="getMidsByTid" resultType="integer">
select mid from menu_role where rid=#{rid}
</select>
docking front
The name parameter is required to bind the role id
Set the default expanded and default checked nodes through default-expanded-keys and default-checked-keys respectively. It should be noted that node-key must be set at this time, and its value is a field name in the node data, which is unique in the entire tree.
Dock the backend
Click the event chance, pass the role id, call getSelectedMenus to pass the role id, query the id of the menu and assign the selectedMenus array, and tree will pre-select the multi-selection box by default
change(rid){
if (rid){
this.getAllMenus();//点击有id就执行
this.getSelectedMenus(rid)
}
},
getSelectedMenus(rid){
this.getRequest("/system/basic/permiss/mids/"+rid).then(resp=>{
if (resp){
this.selectedMenus=resp
}
})
},
Modification of menu role relationship
The component element can be obtained by ref="tree"
If the getCheckedKeys method can be selected (that is, the show-checkbox is true), it will return an array of the keys of the currently selected nodes, (leafOnly) accepts a parameter of boolean type, and if it is true, only the selected leaves will be returned The keys of the node, the default value is false,
print it out and have a look
methods:{
doUpdate(rid,index){
console.log(rid)
let tree = this.$refs.tree[index];//返回当前选中的元素
let selectedKeys = tree.getCheckedKeys(true)//getCheckedKeys方法获取选中菜单节点的key值就是菜单id,若为true就返回叶子节点也就是子节点
console.log(selectedKeys)
},
Write modification operation backend interface
The update operation here is a bit cumbersome, such as user ## authority group front-end page production
authority group management role and the relationship between the menu, the operator manages the relationship between the user and the role. The English input box must have a prefix, and the English name of the role in SpringSecurity needs to be prefixed with a ROLE_. The above
code
<div>
<div class="permissManaTool">
<el-input placeholder="请输入角色英文名" v-model="role.name"> <template slot="prepend">ROLE_</template>
</el-input>
<el-input placeholder="请输入角色中文名" v-model="role.nameZh"> </el-input>
</div>
</div>
data(){
return{
role:{
name:"",
nameZh:"",
}
}
}
Add buttonAdd bash <el-button type="primary" size="small" icon="el-icon-plus">添加角色</el-button>
input box style
permissManaTool{
display: flex;
justify-content: flex-start;
}
.permissManaTool .el-input{
width: 300px;
margin-right: 8px;
}
Add a folding panel  

It can be seen that the second one is expanded one
is enough to
get all the roles from the database and display them on the page. Note that the backend not only returns all roles but also returns the role operation menu, role Which resources can be operated should also be returned ## Permission user role front-end docking Let's first query all roles and display them on the front end ### PermissController
java @RestController@RequestMapping("/system/basic/permiss")public class PermissController { @Autowired RoleService roleService; @GetMapping("/") public List<Role> getAllRoles(){ return roleService.getAllRoles(); }}
### RoleService java@Servicepublic class RoleService { @Autowired RoleMapper roleMapper; public List<Role> getAllRoles(){ return roleMapper.getAllRoles(); }}
### RoleMapper java List<Role> getAllRoles();
### RoleMapper.xml xml <select id="getAllRoles" resultMap="BaseResultMap"> select * from role; </select>
### Docking front-endDisplay effectThe content displayed inside should be cardcomponentThe button style is changed to the trash can icon ## Permission group menu tree display Query all menu display tree structures bash <div style="margin-top: 15px;width: 720px"> <el-collapse accordion> <el-collapse-item :title="item.namezh" :name="index" v-for="(item,index) in roles" :key="index"> <div>与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div> <div>在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div> </el-collapse-item> </el-collapse> </div>
, which need to be processed and returned on the server side Query all parent-child menus, associate yourself three times to form a table,  ### PermissController ### MenuService ### MenuMapper ### MenuMapper.xml A parent menu has multiple submenus, and there are also submenus in the submenu Menu, three-level menu, direct query If you don’t confirm how many levels of menu you can use recursive test ## Front end Copy over Define the corresponding variable Add a click event for the folding panel  bash <div> <el-card class="box-card"> <div slot="header" class="clearfix"> <span>卡片名称</span> <el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button> </div> <div v-for="o in 4" :key="o" class="text item"> {
{'列表内容 ' + o }} </div> </el-card> </div>
bash <el-button style="float: right; padding: 3px 0;color: #ff2a0c" type="text" icon="el-icon-delete"></el-button>
sqlselect m1.id as id1,m1.name as name1,m2.id as id2,m2.name as name2,m3.id as id3,m3.name as name3 from menu m1,menu m2,menu m3 where m1.id = m2.parentId and m2.id =m3.parentId and m3.enabled = true ORDER BY m1.id,m2.id,m3.id
java@RestController@RequestMapping("/system/basic/permiss")public class PermissController { @Autowired RoleService roleService; @Autowired MenuService menuService; @GetMapping("/") public List<Role> getAllRoles(){ return roleService.getAllRoles(); } @PostMapping("/menus") public List<Menu> getAllMenus(){ return menuService.getAllMenus(); }}
java@Servicepublic class MenuService { @Autowired MenuMapper menuMapper; public RespBean getMenusByHrId() { return RespBean.ok("操作成功!",menuMapper.getMenusByHrId( ((Hr) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId()));//Id从哪里来呢,前端传过来的信息是不可信,我们登录的用户信息保存在security,可以从Security里获取登录用户信息 } /** * 获取所有的菜单角色 一对多 一个菜单项有多个角色 * @return */// @Cacheable public List<Menu> getAllMenusWithRole(){ return menuMapper.getAllMenusWithRole(); } public List<Menu> getAllMenus() { return menuMapper.getAllMenus(); }}
java List<Menu> getAllMenus();
xml <resultMap id="MenuWithChildren" type="com.xyg.pojo.Menu" extends="BaseResultMap"> <id column="id1" property="id"></id> <result column="name1" property="name"></result> <collection property="children" ofType="com.xyg.pojo.Menu"> <id column="id2" property="id"></id> <result column="name2" property="name"></result> <collection property="children" ofType="com.xyg.pojo.Menu"> <id column="id3" property="id"></id> <result column="name3" property="name"></result> </collection> </collection> </resultMap> <select id="getAllMenus" resultMap="MenuWithChildren"> select m1.id as id1,m1.name as name1,m2.id as id2,m2.name as name2,m3.id as id3,m3.name as name3 from menu m1,menu m2,menu m3 where m1.id = m2.parentId and m2.id =m3.parentId and m3.enabled = true ORDER BY m1.id,m2.id,m3.id </select>
Make a request to load data at the back end Add
java change(name){ if (name){ this.getAllMenus();//点击有id就执行 } }, getAllMenus(){ this.postRequest("/system/basic/permiss/menus").then(resp=>{ if(resp){ console.log(resp) this.allmenus=resp } }) },
multi-selection boxes Display effect
## Menu role relationship modification All roles are displayed, and there is still a problem of pre-selection, which is the selected role can be operated. Write the menu to see that the database has a menu_role menu role In the association table, query which menus can be operated according to the role id, and query the id of the menu that the role can operate. Use components 
Write
dead data to see the default selection effect 
Display effect 
Dynamically modify the data returned by the dead written data server, you can query the menu mid according to the role rid ### PermissController
java @GetMapping("/mids/{rid}") public List<Integer> getMidsByTid(@PathVariable Integer rid){ return menuService.getMidsByTid(rid); }
### menuMapper java public List<Integer> getMidsByTid(Integer rid) { return menuMapper.getMidsByTid(rid); }
### MenuMapper javaList<Integer> getMidsByTid(Integer rid);
MenuMapper.xml xml <select id="getMidsByTid" resultType="integer"> select mid from menu_role where rid=#{rid} </select>
### The name parameter is required to bind the role id to the front end. Set
the default expanded and default selected nodes through default-expanded-keys and default-checked-keys respectively. It should be noted that node-key must be set at this time, and its value is a field name in the node data, which is unique in the entire tree. Docking
the backend Click
the event chance, pass the role id, call getSelectedMenus to pass the role id, query the id of the menu and assign the selectedMenus array, and the tree will pre-select the multi-selection box by default ### Menu role modification can be referenced
java change(rid){ if (rid){ this.getAllMenus();//点击有id就执行 this.getSelectedMenus(rid) } }, getSelectedMenus(rid){ this.getRequest("/system/basic/permiss/mids/"+rid).then(resp=>{ if (resp){ this.selectedMenus=resp } }) },
by ref ="tree" Get the component element 


If the getCheckedKeys method can be selected (that is, the show-checkbox is true), it will return an array of the keys of the currently selected nodes, (leafOnly) accepts a parameter of boolean type, and if it is true, only the selected leaves will be returned Node’s keys, the default value is falsePrint
it out and have a look ### It’s a bit troublesome to write and modify the back-end interface
. The update operation here is a bit troublesome. For example, the user has checked a few and canceled a few. Judgment one by one, here directly delete the original, direct update operation
java methods:{ doUpdate(rid,index){ console.log(rid) let tree = this.$refs.tree[index];//返回当前选中的元素 let selectedKeys = tree.getCheckedKeys(true)//getCheckedKeys方法获取选中菜单节点的key值就是菜单id,若为true就返回叶子节点也就是子节点 console.log(selectedKeys) },
PermissController
@PutMapping("/")
public RespBean updateMenuRole(Integer rid,Integer[] mids){
if(menuService.updateMenuRole(rid,mids)){
return RespBean.ok("更新成功");
}
return RespBean.err("更新失败");
}
MenuService
@Transactional
public boolean updateMenuRole(Integer rid, Integer[] mids) {
menuRoleMapper.deleteById(rid);
Integer result=menuRoleMapper.insertRecord(rid,mids);
return result==mids.length;
}
MenuRoleMapper
void deleteById(Integer rid);
Integer insertRecord(@Param("rid") Integer rid,@Param("mids") Integer[] mids);
MenuRoleMapper.xml
<delete id="deleteById">
delete from menu_role where rid=#{rid}
</delete>
<insert id="insertRecord">
insert into menu_role (mid,rid) values
<foreach collection="mids" separator="," item="mid">
(#{mid},#{rid})
</foreach>
</insert>
docking front
doUpdate(rid,index){
let tree = this.$refs.tree[index];//返回当前选中的元素
let selectedKeys = tree.getCheckedKeys(true)//getCheckedKeys方法获取选中菜单节点的key值就是菜单id,为true就获取子节点
let url='/system/basic/permiss/?rid='+rid
selectedKeys.forEach(key=>{
url +='&mids='+key;
console.log(url)
})
this.putRequest(url).then(resp=>{
if(resp){
this.getRolesAll()
}
})
},
The control panel is bound to an attribute with a
value of -1, that is, no one will display
activeName. If its value is equal to the name value in the figure, it will be displayed. If it is equal to -1, there is no corresponding value and it will not be displayed.
doUpdate(rid,index){
let tree = this.$refs.tree[index];//返回当前选中的元素
let selectedKeys = tree.getCheckedKeys(true)//getCheckedKeys方法获取选中菜单节点的key值就是菜单id,为true就获取子节点
let url='/system/basic/permiss/?rid='+rid
selectedKeys.forEach(key=>{
url +='&mids='+key;
console.log(url)
})
this.putRequest(url).then(resp=>{
if(resp){
this.getRolesAll()
this.activeName=-1
}
})
},
It will not be displayed if the modification is cancelled.
cancelUpdate(){
this.activeName=-1
},
Add permission group role
PermissController
@PostMapping("/role")
public RespBean addRole(@RequestBody Role role){
if(roleService.addRole(role)==1){
return RespBean.ok("添加成功");
}
return RespBean.err("添加失败");
}
RoleService
Because the role of SpringSecurity needs to start with ROLE data
public Integer addRole(Role role) {
if(!role.getName().startsWith("ROLE_")){
role.setName("ROLE"+role.getName());
}
return roleMapper.insert(role);
}
mapper generated using reverse engineering tools
Add role interface docking front end
Determine whether the data in the input box is empty, and execute the backend interface if it is not empty
permission group role deletion
PermissController
@DeleteMapping("/")
public RespBean deletePositionByIds(Integer[] ids){
if(positionsService.deletePositionsByIds(ids)==ids.length){
return RespBean.ok("删除成功");
}
return RespBean.err("删除失败");
}
PositionService
public int deletePositionsByIds(Integer[] ids) {
return positionMapper.deletePositionsByIds(ids);
}
RoleMapper
delete docking frontend