1 #3

Merged
pxf8gw7s3 merged 5 commits from hrm/hzz into develop 3 months ago

@ -18,91 +18,148 @@ import java.util.List;
/**
* <p>
*
*
* HTTP
* </p>
*
* @author qiujie
* @since 2022-02-28
*/
@RestController
@RequestMapping("/menu")
@RequestMapping("/menu") // 基础请求路径,所有接口均以/menu开头
public class MenuController {
// 注入菜单业务逻辑层对象
@Autowired
private MenuService menuService;
@ApiOperation("新增")
/**
*
* @param menu
* @return /
*/
@ApiOperation("新增菜单")
@PostMapping
@PreAuthorize("hasAnyAuthority('permission:menu:add')")
@PreAuthorize("hasAnyAuthority('permission:menu:add')") // 权限校验:需拥有菜单新增权限
public ResponseDTO add(@RequestBody Menu menu) {
return this.menuService.add(menu);
}
@ApiOperation("逻辑删除")
/**
*
* @param id ID
* @return
*/
@ApiOperation("逻辑删除菜单")
@DeleteMapping("/{id}")
@PreAuthorize("hasAnyAuthority('permission:menu:delete')")
@PreAuthorize("hasAnyAuthority('permission:menu:delete')") // 权限校验:需拥有菜单删除权限
public ResponseDTO deleteById(@PathVariable Integer id) {
return this.menuService.delete(id);
}
@ApiOperation("批量逻辑删除")
/**
*
* @param ids ID
* @return
*/
@ApiOperation("批量逻辑删除菜单")
@DeleteMapping("/batch/{ids}")
@PreAuthorize("hasAnyAuthority('permission:menu:delete')")
@PreAuthorize("hasAnyAuthority('permission:menu:delete')") // 权限校验:需拥有菜单删除权限
public ResponseDTO deleteBatch(@PathVariable List<Integer> ids) {
return this.menuService.deleteBatch(ids);
}
@ApiOperation("编辑更新")
/**
*
* @param menu
* @return
*/
@ApiOperation("编辑更新菜单")
@PutMapping
@PreAuthorize("hasAnyAuthority('permission:menu:edit','permission:menu:enable')")
@PreAuthorize("hasAnyAuthority('permission:menu:edit','permission:menu:enable')") // 权限校验:需拥有菜单编辑或启用权限
public ResponseDTO edit(@RequestBody Menu menu) {
return this.menuService.edit(menu);
}
@ApiOperation("查询")
/**
* ID
* @param id ID
* @return
*/
@ApiOperation("查询菜单详情")
@GetMapping("/{id}")
public ResponseDTO query(@PathVariable Integer id) {
return this.menuService.query(id);
}
@ApiOperation("分页条件查询")
/**
*
* @param current 1
* @param size 10
* @param name
* @return
*/
@ApiOperation("分页条件查询菜单")
@GetMapping
@PreAuthorize("hasAnyAuthority('permission:menu:list','permission:menu:search')")
@PreAuthorize("hasAnyAuthority('permission:menu:list','permission:menu:search')") // 权限校验:需拥有菜单列表或查询权限
public ResponseDTO list(@RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size, String name) {
return this.menuService.list(current, size, name);
}
@ApiOperation("数据导出接口")
/**
*
* @param response HTTP
* @param filename
* @throws IOException IO
*/
@ApiOperation("导出菜单数据")
@GetMapping("/export/{filename}")
@PreAuthorize("hasAnyAuthority('permission:menu:export')")
@PreAuthorize("hasAnyAuthority('permission:menu:export')") // 权限校验:需拥有菜单导出权限
public void export(HttpServletResponse response,@PathVariable String filename) throws IOException {
this.menuService.export(response,filename);
this.menuService.export(response,filename);
}
@ApiOperation("数据导入接口")
/**
*
* @param file
* @return /
* @throws IOException IO
*/
@ApiOperation("导入菜单数据")
@PostMapping("/import")
@PreAuthorize("hasAnyAuthority('permission:menu:import')")
@PreAuthorize("hasAnyAuthority('permission:menu:import')") // 权限校验:需拥有菜单导入权限
public ResponseDTO imp(MultipartFile file) throws IOException {
return this.menuService.imp(file);
}
@ApiOperation("查询所有")
/**
*
* @return
*/
@ApiOperation("查询所有菜单(树形结构)")
@GetMapping("/all")
public ResponseDTO queryAll(){
return this.menuService.queryAll();
}
@ApiOperation("获取员工的菜单")
/**
* ID
* @param id ID
* @return 访
*/
@ApiOperation("获取指定员工的菜单权限")
@GetMapping("/staff/{id}")
public ResponseDTO queryByStaffId(@PathVariable Integer id){
return this.menuService.queryByStaffId(id);
}
@ApiOperation("查询权限")
/**
* ID"user:add""menu:delete"
* @param id ID
* @return
*/
@ApiOperation("查询指定员工的权限标识集合")
@GetMapping("/permission/{id}")
public ResponseDTO queryPermission(@PathVariable Integer id){
return this.menuService.queryPermission(id);
}
}

@ -18,93 +18,154 @@ import java.util.List;
/**
* <p>
*
*
* HTTP
* </p>
*
* @author qiujie
* @since 2022-02-28
*/
@RestController
@RequestMapping("/role")
@RequestMapping("/role") // 基础请求路径,所有接口均以/role开头
public class RoleController {
// 注入角色业务逻辑层对象
@Autowired
private RoleService roleService;
// 注入角色-菜单关联业务逻辑层对象(用于处理角色与菜单的权限关联)
@Autowired
private RoleMenuService roleMenuService;
@ApiOperation("新增")
/**
*
* @param role
* @return /
*/
@ApiOperation("新增角色")
@PostMapping
@PreAuthorize("hasAnyAuthority('permission:role:add')")
@PreAuthorize("hasAnyAuthority('permission:role:add')") // 权限校验:需拥有角色新增权限
public ResponseDTO add(@RequestBody Role role) {
return this.roleService.add(role);
}
@ApiOperation("逻辑删除")
/**
*
* @param id ID
* @return
*/
@ApiOperation("逻辑删除角色")
@DeleteMapping("/{id}")
@PreAuthorize("hasAnyAuthority('permission:role:delete')")
@PreAuthorize("hasAnyAuthority('permission:role:delete')") // 权限校验:需拥有角色删除权限
public ResponseDTO delete(@PathVariable Integer id) {
return this.roleService.delete(id);
}
@ApiOperation("批量逻辑删除")
/**
*
* @param ids ID
* @return
*/
@ApiOperation("批量逻辑删除角色")
@DeleteMapping("/batch/{ids}")
@PreAuthorize("hasAnyAuthority('permission:role:delete')")
@PreAuthorize("hasAnyAuthority('permission:role:delete')") // 权限校验:需拥有角色删除权限
public ResponseDTO deleteBatch(@PathVariable List<Integer> ids) {
return this.roleService.deleteBatch(ids);
}
@ApiOperation("编辑更新")
/**
*
* @param role
* @return
*/
@ApiOperation("编辑更新角色")
@PutMapping
@PreAuthorize("hasAnyAuthority('permission:role:edit')")
@PreAuthorize("hasAnyAuthority('permission:role:edit')") // 权限校验:需拥有角色编辑权限
public ResponseDTO edit(@RequestBody Role role) {
return this.roleService.edit(role);
}
@ApiOperation("查询")
/**
* ID
* @param id ID
* @return
*/
@ApiOperation("查询角色详情")
@GetMapping("/{id}")
public ResponseDTO query(@PathVariable Integer id) {
return this.roleService.query(id);
}
@ApiOperation("查询所有")
/**
*
* @return
*/
@ApiOperation("查询所有角色")
@GetMapping("/all")
public ResponseDTO queryAll(){
return this.roleService.queryAll();
}
@ApiOperation("分页条件查询")
/**
*
* @param current 1
* @param size 10
* @param name
* @return
*/
@ApiOperation("分页条件查询角色")
@GetMapping
@PreAuthorize("hasAnyAuthority('permission:role:list','permission:role:search')")
@PreAuthorize("hasAnyAuthority('permission:role:list','permission:role:search')") // 权限校验:需拥有角色列表或查询权限
public ResponseDTO list(@RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size, String name) {
return this.roleService.list(current, size, name);
}
@ApiOperation("数据导出接口")
/**
*
* @param response HTTP
* @param filename
* @throws IOException IO
*/
@ApiOperation("导出角色数据")
@GetMapping("/export/{filename}")
@PreAuthorize("hasAnyAuthority('permission:role:export')")
@PreAuthorize("hasAnyAuthority('permission:role:export')") // 权限校验:需拥有角色导出权限
public void export(HttpServletResponse response,@PathVariable String filename) throws IOException {
this.roleService.export(response,filename);
this.roleService.export(response,filename);
}
@ApiOperation("数据导入接口")
/**
*
* @param file
* @return /
* @throws IOException IO
*/
@ApiOperation("导入角色数据")
@PostMapping("/import")
@PreAuthorize("hasAnyAuthority('permission:role:import')")
@PreAuthorize("hasAnyAuthority('permission:role:import')") // 权限校验:需拥有角色导入权限
public ResponseDTO imp(MultipartFile file) throws IOException {
return this.roleService.imp(file);
}
@ApiOperation("为角色设置菜单")
/**
*
* @param id ID
* @param menuIds ID
* @return
*/
@ApiOperation("为角色设置菜单权限")
@PostMapping("/set/{id}")
@PreAuthorize("hasAnyAuthority('permission:role:set_menu')")
@PreAuthorize("hasAnyAuthority('permission:role:set_menu')") // 权限校验:需拥有角色菜单分配权限
public ResponseDTO setMenu(@PathVariable Integer id, @RequestBody List<Integer> menuIds){
return this.roleMenuService.setMenu(id, menuIds);
}
@ApiOperation("得到角色所属的菜单")
/**
*
* @param id ID
* @return ID
*/
@ApiOperation("查询角色所属的菜单权限")
@GetMapping("/role/{id}")
public ResponseDTO queryByRoleId(@PathVariable Integer id){
return this.roleMenuService.queryByRoleId(id);
}
}
}

@ -18,70 +18,126 @@ import lombok.Data;
/**
* <p>
*
*
*
* </p>
*
* @author qiujie
* @since 2022-02-28
*/
@Data
@TableName("per_menu")
@ApiModel(value = "Menu对象", description = "")
@Data // Lombok注解自动生成getter、setter、toString等方法
@TableName("per_menu") // 对应数据库表名per_menu权限_菜单
@ApiModel(value = "Menu对象", description = "系统菜单及权限点信息实体类")
public class Menu implements Serializable {
@Serial
@Serial // 序列化版本号标识,用于对象序列化时的版本一致性校验
private static final long serialVersionUID = 1L;
@ApiModelProperty("菜单id")
/**
* ID
* /
*/
@ApiModelProperty("菜单id主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("菜单编码")
/**
*
*
*/
@ApiModelProperty("菜单编码(唯一标识)")
@TableField("code")
private String code;
@ApiModelProperty("菜单名称")
/**
*
* "用户管理""角色配置"
*/
@ApiModelProperty("菜单名称(显示用)")
@TableField("name")
private String name;
/**
*
* FontAwesome
*/
@TableField("icon")
private String icon;
@ApiModelProperty("权限标识")
/**
*
* Spring Security"user:list""role:add"
*/
@ApiModelProperty("权限标识(用于权限控制)")
@TableField("permission")
private String permission;
/**
* ID
* 0
*/
@ApiModelProperty("父菜单id0代表根菜单")
@TableField("parent_id")
private Integer parentId;
/**
*
* 0
* 1
* 2
*/
@ApiModelProperty("0一级菜单1二级菜单2权限点")
@TableField("level")
private Integer level;
/**
*
* 0
* 1
*/
@ApiModelProperty("权限点是否启用0禁用、1正常默认1")
@TableField("status")
private Integer status;
@ApiModelProperty("备注")
/**
*
*
*/
@ApiModelProperty("备注信息")
@TableField("remark")
private String remark;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
/**
*
* JSON
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") // 格式化日期时间,指定时区
@ApiModelProperty("创建时间")
@TableField("create_time")
private Timestamp createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
/**
*
* JSON
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty("更新时间")
@TableField("update_time")
private Timestamp updateTime;
/**
*
* MyBatis-Plus01
*/
@TableField("is_deleted")
@TableLogic
@TableLogic // 标识为逻辑删除字段
private Integer deleteFlag;
@TableField(exist = false)
/**
*
* exist=false
*/
@TableField(exist = false) // 标识该字段不对应数据库表列
private List<Menu> children;
}

@ -3,23 +3,20 @@ package com.qiujie.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serial;
import java.io.Serializable;
import java.sql.Timestamp;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
/**
* <p>
*
*
*
* </p>
*
* @author qiujie
@ -27,22 +24,34 @@ import lombok.experimental.Accessors;
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("per_role_menu")
@ApiModel(value = "RoleMenu对象", description = "")
@Accessors(chain = true) // 开启链式调用支持setter方法连续赋值
@TableName("per_role_menu") // 对应数据库表名per_role_menu权限_角色_菜单
@ApiModel(value = "RoleMenu对象", description = "角色与菜单的关联关系实体")
public class RoleMenu implements Serializable {
@Serial
@Serial // 序列化版本号标识,用于对象序列化时的版本一致性校验
private static final long serialVersionUID = 1L;
/**
* ID
* -
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("角色id")
/**
* ID
*
*/
@ApiModelProperty("角色id关联角色表主键")
@TableField("role_id")
private Integer roleId;
@ApiModelProperty("菜单id")
/**
* ID
*
*/
@ApiModelProperty("菜单id关联菜单表主键")
@TableField("menu_id")
private Integer menuId;
}
}

@ -21,7 +21,8 @@ import java.util.*;
/**
* <p>
*
*
*
* </p>
*
* @author qiujie
@ -31,16 +32,27 @@ import java.util.*;
public class MenuService extends ServiceImpl<MenuMapper, Menu> {
@Autowired
private MenuMapper menuMapper;
private MenuMapper menuMapper; // 注入菜单数据访问层对象
/**
*
* @param menu
* @return /
*/
public ResponseDTO add(Menu menu) {
// 调用MyBatis-Plus的save方法保存菜单成功返回成功响应否则返回失败响应
if (save(menu)) {
return Response.success();
}
return Response.error();
}
/**
* IDMyBatis-Plus
* @param id ID
* @return
*/
public ResponseDTO delete(Integer id) {
if (removeById(id)) {
return Response.success();
@ -48,7 +60,12 @@ public class MenuService extends ServiceImpl<MenuMapper, Menu> {
return Response.error();
}
@Transactional(rollbackFor = Exception.class)
/**
*
* @param ids ID
* @return
*/
@Transactional(rollbackFor = Exception.class) // 声明事务,发生异常时回滚
public ResponseDTO deleteBatch(List<Integer> ids) {
if (removeBatchByIds(ids)) {
return Response.success();
@ -57,6 +74,11 @@ public class MenuService extends ServiceImpl<MenuMapper, Menu> {
}
/**
*
* @param menu
* @return
*/
public ResponseDTO edit(Menu menu) {
if (updateById(menu)) {
return Response.success();
@ -65,6 +87,11 @@ public class MenuService extends ServiceImpl<MenuMapper, Menu> {
}
/**
* ID
* @param id ID
* @return
*/
public ResponseDTO query(Integer id) {
Menu menu = getById(id);
if (menu != null) {
@ -74,23 +101,26 @@ public class MenuService extends ServiceImpl<MenuMapper, Menu> {
}
/**
*
*
* @return
*
* @return
*/
public ResponseDTO queryAll() {
// 查询所有状态为"正常"1的菜单
List<Menu> list = list(new QueryWrapper<Menu>().eq("status",1));
// 为父级菜单设置子菜单
// 一级菜单
// 筛选一级菜单level=0
List<Menu> firstList = list.stream().parallel()
.filter(menu -> menu.getLevel() == 0).toList();
// 为一级菜单设置二级菜单
for (Menu firstMenu : firstList) {
// 二级菜单
// 筛选当前一级菜单的二级菜单parentId=一级菜单IDlevel=1
List<Menu> secondList = list.stream().parallel()
.filter(menu -> Objects.equals(menu.getParentId(), firstMenu.getId())).toList();
firstMenu.setChildren(secondList);
// 为二级菜单设置权限点level=2
for (Menu secondMenu : secondList) {
// 权限点
List<Menu> thirdList = list.stream().parallel()
.filter(menu -> Objects.equals(menu.getParentId(), secondMenu.getId())).toList();
secondMenu.setChildren(thirdList);
@ -100,28 +130,45 @@ public class MenuService extends ServiceImpl<MenuMapper, Menu> {
}
/**
*
* @param current
* @param size
* @param name
* @return
*/
public ResponseDTO list(Integer current, Integer size, String name) {
// 构建分页对象
IPage<Menu> config = new Page<>(current, size);
QueryWrapper<Menu> wrapper = new QueryWrapper<>();
// 若名称不为空,添加模糊查询条件
if (name != "" && name != null) {
wrapper.like("name", name);
}
// 仅查询一级菜单level=0
wrapper.eq("level", 0);
// 执行分页查询
IPage<Menu> page = page(config, wrapper);
// 查询所有非一级菜单(用于构建子菜单)
List<Menu> list = list(new QueryWrapper<Menu>().ne("level", 0));
// 菜单
// 为一级菜单设置子菜单
List<Menu> firstList = page.getRecords();
for (Menu firstMenu : firstList) {
// 设置子菜单
// 筛选二级菜单
List<Menu> secondList = list.stream().filter(menu -> Objects.equals(menu.getParentId(), firstMenu.getId())).toList();
firstMenu.setChildren(secondList);
// 为二级菜单设置权限点
for (Menu secondMenu : secondList) {
// 设置子菜单
List<Menu> thirdList = list.stream().filter(menu -> Objects.equals(menu.getParentId(), secondMenu.getId())).toList();
secondMenu.setChildren(thirdList);
}
}
// 将响应数据填充到map中
// 封装分页结果(总页数、总条数、菜单列表)
Map map = new HashMap();
map.put("pages", page.getPages());
map.put("total", page.getTotal());
@ -130,40 +177,50 @@ public class MenuService extends ServiceImpl<MenuMapper, Menu> {
}
/**
*
*
* @param response
* @return
* Excel
* @param response HTTP
* @param filename
* @throws IOException IO
*/
public void export(HttpServletResponse response, String filename) throws IOException {
// 查询所有菜单
List<Menu> list = list();
// 调用工具类导出Excel
HutoolExcelUtil.writeExcel(response, list, filename, Menu.class);
}
/**
*
*
* @param file
* @return
* Excel
* @param file Excel
* @return
* @throws IOException IO
*/
@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class) // 声明事务,确保批量插入的原子性
public ResponseDTO imp(MultipartFile file) throws IOException {
InputStream inputStream = file.getInputStream();
// 调用工具类读取Excel从第2行开始读取跳过表头
List<Menu> list = HutoolExcelUtil.readExcel(inputStream, 1, Menu.class);
// IService接口中的方法.批量插入数据
// 批量插入数据
if (saveBatch(list)) {
return Response.success();
}
return Response.error();
}
/**
* ID
* @param id ID
* @return 访
*/
public ResponseDTO queryByStaffId(Integer id) {
// 通过mapper查询该员工拥有的所有菜单
List<Menu> list = this.menuMapper.queryByStaffId(id);
// 一级菜单
// 筛选一级菜单并构建树形结构
List<Menu> firstList = list.stream().parallel()
.filter(menu -> menu.getLevel() == 0).toList();
for (Menu firstMenu : firstList) {
// 二级菜单
// 为一级菜单设置二级菜单
List<Menu> secondList = list.stream().parallel()
.filter(menu -> Objects.equals(menu.getParentId(), firstMenu.getId())).toList();
firstMenu.setChildren(secondList);
@ -172,11 +229,12 @@ public class MenuService extends ServiceImpl<MenuMapper, Menu> {
}
/**
* ID"user:add""role:delete"
* @param id ID
* @return
*/
public ResponseDTO queryPermission(Integer id){
return Response.success(this.menuMapper.queryPermission(id));
}
}
}
Loading…
Cancel
Save