feat(新增): 菜单管理CURD

This commit is contained in:
bunny 2024-09-29 10:47:23 +08:00
parent ac47b31122
commit b4ab274cd4
20 changed files with 417 additions and 185 deletions

View File

@ -14,13 +14,13 @@ public class NewCodeGet {
// 作者名称
public static final String author = "Bunny";
// 公共路径
// public static final String outputDir = "D:\\MyFolder\\auth-admin\\auth-server-java\\service";
public static final String outputDir = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service";
public static final String outputDir = "D:\\MyFolder\\auth-admin\\auth-server-java\\service";
// public static final String outputDir = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service";
// 实体类名称
public static final String entity = "Bunny";
public static void main(String[] args) {
Generation("sys_i18n", "sys_i18n_type");
Generation("sys_router");
}
/**

View File

@ -0,0 +1,43 @@
package cn.bunny.common.service.config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import java.io.IOException;
@ControllerAdvice
public class ControllerStringParamTrimConfig {
@InitBinder
public void initBinder(WebDataBinder binder) {
// 创建 String trim 编辑器
// 构造方法中 boolean 参数含义为如果是空白字符串,是否转换为null
// 即如果为true,那么 " " 会被转换为 null,否者为 ""
StringTrimmerEditor propertyEditor = new StringTrimmerEditor(false);
// String 类对象注册编辑器
binder.registerCustomEditor(String.class, propertyEditor);
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return jacksonObjectMapperBuilder -> {
// String 类型自定义反序列化操作
jacksonObjectMapperBuilder
.deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
// 去除前后空格
return StringUtils.trimAllWhitespace(jsonParser.getValueAsString());
}
});
};
}
}

View File

@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.time.LocalDateTime;
/**
* 配置MP在修改和新增时的操作
@ -20,11 +20,11 @@ public class MyBatisPlusFieldConfig implements MetaObjectHandler {
public void insertFill(MetaObject metaObject) {
// 设置属性值
this.strictInsertFill(metaObject, "isDeleted", Integer.class, 0);
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
if (BaseContext.getUsername() != null) {
this.setFieldValByName("createUser", BaseContext.getUsername(), metaObject);
this.setFieldValByName("updateUser", BaseContext.getUsername(), metaObject);
this.setFieldValByName("createUser", BaseContext.getUserId(), metaObject);
this.setFieldValByName("updateUser", BaseContext.getUserId(), metaObject);
}
}
@ -34,8 +34,8 @@ public class MyBatisPlusFieldConfig implements MetaObjectHandler {
@Override
public void updateFill(MetaObject metaObject) {
if (BaseContext.getUserId() != null) {
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("updateUser", BaseContext.getUsername(), metaObject);
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
this.setFieldValByName("updateUser", BaseContext.getUserId(), metaObject);
}
}
}

View File

@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.io.FileNotFoundException;
import java.nio.file.AccessDeniedException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.regex.Matcher;
@ -34,10 +33,10 @@ public class GlobalExceptionHandler {
// 运行时异常信息
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public Result<Object> exceptionHandler(RuntimeException exception) throws FileNotFoundException {
public Result<Object> exceptionHandler(RuntimeException exception) {
log.error("GlobalExceptionHandler===>运行时异常信息:{}", exception.getMessage());
exception.printStackTrace();
return Result.error(null, 500, "出错了");
return Result.error(null, 500, "服务器异常");
}
// 捕获系统异常

View File

@ -0,0 +1,76 @@
package cn.bunny.dao.dto.router;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "RouterManageDto对象", title = "路由添加表单", description = "路由添加表单")
public class RouterAddDto {
@ApiModelProperty("菜单类型")
@NotNull(message = "菜单类型不能为空")
private Integer menuType;
@ApiModelProperty("父级id")
private Long parentId;
@ApiModelProperty("菜单名称")
@NotBlank(message = "菜单名称不能为空")
private String title;
@ApiModelProperty("路由名称")
@NotBlank(message = "路由名称不能为空")
@JsonProperty("name")
private String routeName;
@ApiModelProperty("在项目中路径")
@NotBlank(message = "路由路径不能为空")
private String path;
@ApiModelProperty("组件位置")
private String component;
@ApiModelProperty("等级")
@JsonProperty("rank")
private Integer routerRank = 99;
@ApiModelProperty("重定向")
private String redirect;
@ApiModelProperty("图标")
private String icon;
@ApiModelProperty("进入动画")
private String enterTransition;
@ApiModelProperty("退出动画")
private String leaveTransition;
@ApiModelProperty("frame路径")
private String frameSrc;
@ApiModelProperty("是否隐藏标签")
private Boolean hiddenTag = false;
@ApiModelProperty("是否固定标签")
private Boolean fixedTag = false;
@ApiModelProperty("是否显示 返给前端为 showLink")
@JsonProperty("showLink")
private Boolean visible = false;
@ApiModelProperty("是否显示父级")
private Boolean showParent = false;
}

View File

@ -0,0 +1,78 @@
package cn.bunny.dao.dto.router;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "RouterManageDto对象", title = "路由更新表单", description = "路由更新表单")
public class RouterUpdateDto {
@ApiModelProperty("唯一标识")
private Long id;
@ApiModelProperty("菜单类型")
@NotNull(message = "菜单类型不能为空")
private Integer menuType;
@ApiModelProperty("父级id")
private Long parentId;
@ApiModelProperty("菜单名称")
@NotBlank(message = "菜单名称不能为空")
private String title;
@ApiModelProperty("路由名称")
@NotBlank(message = "路由名称不能为空")
@JsonProperty("name")
private String routeName;
@ApiModelProperty("在项目中路径")
@NotBlank(message = "路由路径不能为空")
private String path;
@ApiModelProperty("组件位置")
private String component;
@ApiModelProperty("等级")
@JsonProperty("rank")
private Integer routerRank = 99;
@ApiModelProperty("重定向")
private String redirect;
@ApiModelProperty("图标")
private String icon;
@ApiModelProperty("进入动画")
private String enterTransition;
@ApiModelProperty("退出动画")
private String leaveTransition;
@ApiModelProperty("frame路径")
private String frameSrc;
@ApiModelProperty("是否隐藏标签")
private Boolean hiddenTag = false;
@ApiModelProperty("是否固定标签")
private Boolean fixedTag = false;
@ApiModelProperty("是否显示 返给前端为 showLink")
@JsonProperty("showLink")
private Boolean visible = false;
@ApiModelProperty("是否显示父级")
private Boolean showParent = false;
}

View File

@ -1,55 +0,0 @@
package cn.bunny.dao.entity.system;
import cn.bunny.dao.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
* 系统菜单表
* </p>
*
* @author Bunny
* @since 2024-09-28
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("sys_router")
@ApiModel(value = "Router对象", description = "系统菜单表")
public class Router extends BaseEntity {
@ApiModelProperty("在项目中路径")
private String path;
@ApiModelProperty("路由名称")
private String routeName;
@ApiModelProperty("父级id")
private Long parentId;
@ApiModelProperty("菜单类型 `0`代表菜单、`1`代表`iframe`、`2`代表外链、`3`代表按钮)")
private Integer menuType;
@ApiModelProperty("路由title")
private String title;
@ApiModelProperty("图标")
private String icon;
@ApiModelProperty("进入动画")
private String enterTransition;
@ApiModelProperty("退出动画")
private String leaveTransition;
@ApiModelProperty("等级")
private Integer routerRank;
@ApiModelProperty("是否显示")
private Boolean visible;
}

View File

@ -9,6 +9,12 @@ import lombok.Getter;
public enum ResultCodeEnum {
// 成功操作 200
SUCCESS(200, "操作成功"),
ADD_SUCCESS(200, "添加成功"),
UPDATE_SUCCESS(200, "修改成功"),
DELETE_SUCCESS(200, "删除成功"),
SORT_SUCCESS(200, "排序成功"),
SUCCESS_UPLOAD(200, "上传成功"),
SUCCESS_LOGOUT(200, "退出成功"),
LOGOUT_SUCCESS(200, "退出成功"),
EMAIL_CODE_REFRESH(200, "邮箱验证码已刷新"),
EMAIL_CODE_SEND_SUCCESS(200, "邮箱验证码已发送"),
@ -23,6 +29,8 @@ public enum ResultCodeEnum {
GET_BUCKET_EXCEPTION(201, "获取文件信息失败"),
SEND_MAIL_CODE_ERROR(201, "邮件发送失败"),
EMAIL_CODE_EMPTY(201, "邮箱验证码过期或不存在"),
DATA_EXIST(201, "数据已存在"),
DATA_NOT_EXIST(201, "数据不存在"),
// 数据相关 206
ILLEGAL_REQUEST(206, "非法请求"),

View File

@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.*;
import java.util.List;
@ -19,40 +20,59 @@ import java.util.List;
@ApiModel(value = "RouterControllerVo对象", description = "路由管理端返回对象")
public class RouterManageVo extends BaseVo {
@ApiModelProperty("在项目中路径")
private String path;
@ApiModelProperty("路由名称")
@JsonProperty("name")
private String routeName;
@ApiModelProperty("父级id")
@JsonProperty("parentId")
@JsonFormat(shape = JsonFormat.Shape.STRING)
@JSONField(serializeUsing = ToStringSerializer.class)
private Long parentId;
@ApiModelProperty("菜单类型")
private Integer menuType;
@ApiModelProperty("在项目中路径")
private String path;
@ApiModelProperty("组件位置")
private String component;
@ApiModelProperty("frame路径")
private String frameSrc;
@ApiModelProperty("重定向")
private String redirect;
@ApiModelProperty("路由名称")
@NotBlank(message = "路由名称不能为空")
@JsonProperty("name")
private String routeName;
@ApiModelProperty("路由title")
private String title;
@ApiModelProperty("菜单类型")
private Integer menuType;
@ApiModelProperty("图标")
private String icon;
@ApiModelProperty("链接地址(需要内嵌的`iframe`链接地址)")
private String frameSrc;
@ApiModelProperty("进入动画")
private String enterTransition;
@ApiModelProperty("退出动画")
private String leaveTransition;
@ApiModelProperty("等级")
@JsonProperty("rank")
private Integer routerRank;
@ApiModelProperty("是否显示")
private Boolean visible;
@ApiModelProperty("是否隐藏标签")
private Boolean hiddenTag;
@ApiModelProperty("是否显示")
private Boolean frameLoading;
@ApiModelProperty("是否固定标签")
private Boolean fixedTag;
@ApiModelProperty("是否显示父级")
private Boolean showParent;
@ApiModelProperty("是否显示 返给前端为 showLink")
private Boolean visible;
@ApiModelProperty("子路由")
private List<RouterManageVo> children;

View File

@ -1,5 +1,6 @@
package cn.bunny.dao.vo.router;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
@ -31,6 +32,22 @@ public class RouterMeta {
@ApiModelProperty(value = "权限列表")
private List<String> auths;
@ApiModelProperty("是否显示父级")
private Boolean showParent;
@ApiModelProperty("是否显示 返给前端为 showLink")
@JsonProperty("showLink")
private Boolean visible;
@ApiModelProperty("路由动画")
private RouterTransition transition;
@ApiModelProperty("frame路径")
private String frameSrc;
@ApiModelProperty("是否隐藏标签")
private Boolean hiddenTag;
@ApiModelProperty("是否固定标签")
private Boolean fixedTag;
}

View File

@ -13,9 +13,11 @@ import lombok.NoArgsConstructor;
@Builder
@ApiModel(value = "RouterTransition对象", description = "路由动画")
public class RouterTransition {
@ApiModelProperty("进入动画")
private String enterTransition;
@ApiModelProperty("退出动画")
private String leaveTransition;
}

View File

@ -20,11 +20,15 @@ import java.util.List;
@Builder
@ApiModel(value = "UserRouterVo对象", description = "系统菜单表")
public class UserRouterVo {
@Schema(name = "id", title = "主键")
@JsonProperty("id")
@JsonFormat(shape = JsonFormat.Shape.STRING)
@JSONField(serializeUsing = ToStringSerializer.class)
private Long id;
@ApiModelProperty("菜单类型")
private Integer menuType;
@ApiModelProperty("父级id")
@JsonProperty("parentId")
@ -32,20 +36,27 @@ public class UserRouterVo {
@JSONField(serializeUsing = ToStringSerializer.class)
private Long parentId;
@ApiModelProperty("在项目中路径")
private String path;
@ApiModelProperty("菜单类型")
private Integer menuType;
@ApiModelProperty("菜单名称")
private String title;
@ApiModelProperty("路由名称")
@JsonProperty("name")
private String routeName;
@ApiModelProperty("路由动画")
private RouterTransition transition;
@ApiModelProperty("在项目中路径")
private String path;
@ApiModelProperty("meta内容")
@ApiModelProperty("组件位置")
private String component;
@ApiModelProperty("等级")
@JsonProperty("rank")
private Integer routerRank;
@ApiModelProperty("重定向")
private String redirect;
@ApiModelProperty("路由Meta")
private RouterMeta meta;
@ApiModelProperty("子路由")

View File

@ -1,9 +1,12 @@
package cn.bunny.services.controller;
import cn.bunny.dao.dto.router.RouterAddDto;
import cn.bunny.dao.dto.router.RouterManageDto;
import cn.bunny.dao.dto.router.RouterUpdateDto;
import cn.bunny.dao.entity.system.Router;
import cn.bunny.dao.pojo.result.PageResult;
import cn.bunny.dao.pojo.result.Result;
import cn.bunny.dao.pojo.result.ResultCodeEnum;
import cn.bunny.dao.vo.router.RouterManageVo;
import cn.bunny.dao.vo.router.UserRouterVo;
import cn.bunny.services.service.RouterService;
@ -12,10 +15,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import java.util.List;
@ -59,9 +59,30 @@ public class RouterController {
@Operation(summary = "管理菜单列表", description = "管理菜单列表")
@GetMapping("getMenus")
public Mono<Result<List<RouterManageVo>>> getMenu(RouterManageDto dto) {
List<RouterManageVo> voPageResult = routerService.getMenu(dto);
public Mono<Result<List<RouterManageVo>>> getMenu() {
List<RouterManageVo> voPageResult = routerService.getMenu();
return Mono.just(Result.success(voPageResult));
}
@Operation(summary = "添加路由菜单", description = "添加路由菜单")
@PostMapping("addMenu")
public Mono<Result<String>> addMenu(@RequestBody RouterAddDto dto) {
routerService.addMenu(dto);
return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
}
@Operation(summary = "更新路由菜单", description = "更新路由菜单")
@PutMapping("updateMenu")
public Mono<Result<String>> updateMenu(@RequestBody RouterUpdateDto dto) {
routerService.updateMenu(dto);
return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
}
@Operation(summary = "删除路由菜单", description = "删除路由菜单")
@DeleteMapping("deletedMenuByIds")
public Mono<Result<String>> deletedMenuByIds(@RequestBody List<Long> ids) {
routerService.deletedMenuByIds(ids);
return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS));
}
}

View File

@ -47,7 +47,7 @@ public class UserFactory {
String avatar = user.getAvatar();
// 判断用户是否有头像如果没有头像设置默认头像
avatar = StringUtils.hasText(avatar) ? UserConstant.USER_AVATAR : minioUtil.getObjectNameFullPath(avatar);
avatar = StringUtils.hasText(avatar) ? minioUtil.getObjectNameFullPath(avatar) : UserConstant.USER_AVATAR;
// 设置用户IP地址并更新用户信息
AdminUser updateUser = new AdminUser();

View File

@ -46,4 +46,11 @@ public interface RouterMapper extends BaseMapper<Router> {
* @return 分页结果
*/
IPage<Router> selectListByPage(@Param("page") Page<Router> pageParams, @Param("dto") RouterManageDto dto);
/**
* * 物理删除路由菜单
*
* @param ids 删除id列表
*/
void deletedMenuByIds(List<Long> ids);
}

View File

@ -1,6 +1,8 @@
package cn.bunny.services.service;
import cn.bunny.dao.dto.router.RouterAddDto;
import cn.bunny.dao.dto.router.RouterManageDto;
import cn.bunny.dao.dto.router.RouterUpdateDto;
import cn.bunny.dao.entity.system.Router;
import cn.bunny.dao.pojo.result.PageResult;
import cn.bunny.dao.vo.router.RouterManageVo;
@ -38,8 +40,28 @@ public interface RouterService extends IService<Router> {
/**
* * 管理菜单列表
*
* @param dto 路由查询表单
* @return 系统菜单表
*/
List<RouterManageVo> getMenu(RouterManageDto dto);
List<RouterManageVo> getMenu();
/**
* * 添加路由菜单
*
* @param dto 添加菜单表单
*/
void addMenu(RouterAddDto dto);
/**
* * 更新路由菜单
*
* @param dto 更新表单
*/
void updateMenu(RouterUpdateDto dto);
/**
* * 删除路由菜单
*
* @param ids 删除id列表
*/
void deletedMenuByIds(List<Long> ids);
}

View File

@ -2,20 +2,23 @@ package cn.bunny.services.service.impl;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.common.service.exception.BunnyException;
import cn.bunny.dao.dto.router.RouterAddDto;
import cn.bunny.dao.dto.router.RouterManageDto;
import cn.bunny.dao.dto.router.RouterUpdateDto;
import cn.bunny.dao.entity.system.Router;
import cn.bunny.dao.pojo.constant.RedisUserConstant;
import cn.bunny.dao.pojo.result.PageResult;
import cn.bunny.dao.pojo.result.ResultCodeEnum;
import cn.bunny.dao.vo.router.RouterManageVo;
import cn.bunny.dao.vo.router.RouterMeta;
import cn.bunny.dao.vo.router.RouterTransition;
import cn.bunny.dao.vo.router.UserRouterVo;
import cn.bunny.dao.vo.user.LoginVo;
import cn.bunny.services.factory.RouterServiceFactory;
import cn.bunny.services.mapper.RouterMapper;
import cn.bunny.services.service.RouterService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
@ -25,6 +28,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
@ -77,12 +81,16 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
// 构建返回路由列表
List<UserRouterVo> routerVoList = routerList.stream()
.sorted(Comparator.comparing(Router::getRouterRank))
.filter(Router::getVisible)
.map(router -> {
// 复制对象
UserRouterVo routerVo = new UserRouterVo();
BeanUtils.copyProperties(router, routerVo);
routerVo.setPath(router.getPath().trim());
// 复制路由动画
RouterTransition transition = new RouterTransition();
BeanUtils.copyProperties(router, transition);
// 设置
RouterMeta meta = RouterMeta.builder()
@ -90,7 +98,10 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
.icon(router.getIcon())
.title(router.getTitle())
.roles(roleList)
.auths(powerCodeList).build();
.auths(powerCodeList)
.transition(transition)
.build();
routerVo.setMeta(meta);
return routerVo;
}).distinct().toList();
@ -135,24 +146,65 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
/**
* * 管理菜单列表
*
* @param dto 路由查询表单
* @return 系统菜单表
*/
@Override
public List<RouterManageVo> getMenu(RouterManageDto dto) {
String title = dto.getTitle();
Boolean visible = dto.getVisible();
// 构建查询条件
LambdaQueryWrapper<Router> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.like(title != null, Router::getTitle, title)
.or()
.eq(visible != null, Router::getVisible, visible);
public List<RouterManageVo> getMenu() {
return list().stream().map(router -> {
RouterManageVo routerManageVo = new RouterManageVo();
BeanUtils.copyProperties(router, routerManageVo);
return routerManageVo;
}).toList();
}
/**
* * 添加路由菜单
*
* @param dto 添加菜单表单
*/
@Override
public void addMenu(RouterAddDto dto) {
// 查找是否添加过路由名称
String routeName = dto.getRouteName();
Router router = getOne(Wrappers.<Router>lambdaQuery().eq(Router::getRouteName, routeName));
if (router != null) throw new BunnyException(ResultCodeEnum.DATA_EXIST);
// 添加路由
router = new Router();
BeanUtils.copyProperties(dto, router);
save(router);
}
/**
* * 更新路由菜单
*
* @param dto 更新表单
*/
@Override
public void updateMenu(RouterUpdateDto dto) {
Long id = dto.getId();
Router router = getOne(Wrappers.<Router>lambdaQuery().eq(Router::getId, id));
if (router == null) {
throw new BunnyException(ResultCodeEnum.DATA_EXIST);
}
router = new Router();
BeanUtils.copyProperties(dto, router);
updateById(router);
}
/**
* * 删除路由菜单
*
* @param ids 删除id列表
*/
@Override
public void deletedMenuByIds(List<Long> ids) {
// 查找子级菜单一起删除
List<Long> longList = list(Wrappers.<Router>lambdaQuery().in(Router::getParentId, ids)).stream().map(Router::getId).toList();
ids.addAll(longList);
baseMapper.deletedMenuByIds(ids);
}
}

View File

@ -22,4 +22,4 @@ bunny:
endpointUrl: "http://192.168.3.98:9000"
accessKey: bunny
secretKey: "02120212"
bucket-name: bunny-bbs
bucket-name: auth-admin

View File

@ -22,4 +22,4 @@ bunny:
endpointUrl: "http://192.168.3.98:9000"
accessKey: bunny
secretKey: "02120212"
bucket-name: bunny-bbs
bucket-name: auth-admin

View File

@ -1,69 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bunny.services.mapper.RouterMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.bunny.dao.entity.system.Router">
<id column="id" property="id"/>
<result column="path" property="path"/>
<result column="route_name" property="routeName"/>
<result column="parent_id" property="parentId"/>
<result column="menu_type" property="menuType"/>
<result column="title" property="title"/>
<result column="icon" property="icon"/>
<result column="enter_transition" property="enterTransition"/>
<result column="leave_transition" property="leaveTransition"/>
<result column="router_rank" property="routerRank"/>
<result column="visible" property="visible"/>
<result column="create_user" property="createUser"/>
<result column="update_user" property="updateUser"/>
<result column="update_time" property="updateTime"/>
<result column="create_time" property="createTime"/>
<result column="is_deleted" property="isDeleted"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, path, route_name, parent_id, menu_type, title, icon, enter_transition, leave_transition, router_rank, visible, create_user, update_user, update_time, create_time, is_deleted
</sql>
<!-- 根据用户ID查找路由列表 -->
<select id="selectListByUserId" resultType="java.lang.Long">
SELECT router.id
FROM sys_user_role user_role
LEFT JOIN sys_user user ON user_role.user_id = user.id
LEFT JOIN sys_router_role router_role ON user_role.role_id = router_role.role_id
LEFT JOIN sys_router router ON router_role.router_id = router.id
WHERE user.id = #{userId}
</select>
<!-- 递归查询所有父级Id直到查询到父级Id为0 -->
<select id="selectParentListByRouterId" resultType="cn.bunny.dao.entity.system.Router">
WITH RECURSIVE ParentChain AS (
SELECT * FROM sys_router
WHERE id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
UNION ALL
SELECT r.* FROM sys_router r
INNER JOIN ParentChain pc ON r.id = pc.parent_id
)
SELECT
<include refid="Base_Column_List"/>
FROM ParentChain;
</select>
<!-- 管理菜单列表 -->
<select id="selectListByPage" resultType="cn.bunny.dao.entity.system.Router">
select *
from sys_router
<if test="dto.title != null and dto.title != ''">
title like CONCAT('%',#{dto.title},'%')
</if>
<if test="dto.visible != null">
visible = #{dto.visible}
</if>
</select>
</mapper>