批量提交一次迁移的代码

完成 get-info 接口,完成和前端 vue 的对接
This commit is contained in:
YunaiV 2021-01-05 01:19:25 +08:00
parent 1345c663eb
commit 823c26a567
16 changed files with 205 additions and 49 deletions

View File

@ -12,8 +12,6 @@ ruoyi:
profile: D:/ruoyi/uploadPath profile: D:/ruoyi/uploadPath
# 获取ip地址开关 # 获取ip地址开关
addressEnabled: false addressEnabled: false
# 验证码类型 math 数组计算 char 字符验证
captchaType: math
# 开发环境配置 # 开发环境配置
server: server:
@ -59,7 +57,7 @@ spring:
# redis 配置 # redis 配置
redis: redis:
# 地址 # 地址
host: localhost host: 127.0.0.1
# 端口默认为6379 # 端口默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
@ -79,15 +77,6 @@ spring:
# #连接池最大阻塞等待时间(使用负值表示没有限制) # #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms max-wait: -1ms
# token配置
token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期默认30分钟
expireTime: 30
# MyBatis配置 # MyBatis配置
mybatis: mybatis:
# 搜索指定包别名 # 搜索指定包别名

View File

@ -51,7 +51,7 @@ const user = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getInfo(state.token).then(res => { getInfo(state.token).then(res => {
const user = res.user const user = res.user
const avatar = user.avatar == "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar; const avatar = user.avatar === "" ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.roles) commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions) commit('SET_PERMISSIONS', res.permissions)

View File

@ -0,0 +1,15 @@
package cn.iocoder.dashboard.common.core;
/**
* 可生成 Int 数组的接口
*
* @author 芋道源码
*/
public interface IntArrayValuable {
/**
* @return int 数组
*/
int[] array();
}

View File

@ -0,0 +1,27 @@
package cn.iocoder.dashboard.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 通用状态枚举
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum CommonStatusEnum {
ENABLE("0", "开启"),
DISABLE("1", "关闭");
/**
* 状态值
*/
private final String status;
/**
* 状态名
*/
private final String name;
}

View File

@ -0,0 +1,12 @@
package cn.iocoder.dashboard.framework.datasource;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* 数据库匹配类
*/
@Configuration
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理
public class DataSourceConfiguration {
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.dashboard.framework.mybatis.config;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
/**
* MyBaits 配置类
*
* @author 芋道源码
*/
@Configuration
@MapperScan(value = "cn.iocoder.dashboard", annotationClass = Mapper.class)
public class MybatisConfiguration {
}

View File

@ -2,18 +2,42 @@ package cn.iocoder.dashboard.modules.system.controller.auth.vo;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set; import java.util.Set;
@ApiModel("获得用户信息 Resp VO") @ApiModel("获得用户信息 Resp VO")
@Data @Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SysAuthGetInfoRespVO { public class SysAuthGetInfoRespVO {
@ApiModelProperty(value = "用户信息", required = true)
private UserVO user;
@ApiModelProperty(value = "角色权限数组", required = true) @ApiModelProperty(value = "角色权限数组", required = true)
private Set<String> roles; private Set<String> roles;
@ApiModelProperty(value = "菜单权限数组", required = true) @ApiModelProperty(value = "菜单权限数组", required = true)
private Set<String> permissions; private Set<String> permissions;
@ApiModel("用户信息 VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class UserVO {
@ApiModelProperty(value = "用户昵称", required = true, example = "芋道源码")
private String nickname;
@ApiModelProperty(value = "用户头像", required = true, example = "http://www.iocoder.cn/xx.jpg")
private String avatar;
}
} }

View File

@ -22,10 +22,11 @@ public interface SysAuthConvert {
LoginUser convert(SysUserDO bean); LoginUser convert(SysUserDO bean);
default SysAuthGetInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) { default SysAuthGetInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) {
SysAuthGetInfoRespVO respVO = new SysAuthGetInfoRespVO(); return SysAuthGetInfoRespVO.builder()
respVO.setRoles(CollectionUtils.convertSet(roleList, SysRoleDO::getRoleKey)); .user(SysAuthGetInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build())
respVO.setPermissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPerms)); .roles(CollectionUtils.convertSet(roleList, SysRoleDO::getRoleKey))
return respVO; .permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPerms))
.build();
} }
SysAuthGetRouterRespVO convertTreeNode(SysMenuDO menu); SysAuthGetRouterRespVO convertTreeNode(SysMenuDO menu);

View File

@ -0,0 +1,25 @@
package cn.iocoder.dashboard.modules.system.enums.permission;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 菜单类型枚举类
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum MenuTypeEnum {
DIR("M"), // 目录
MENU("C"), // 菜单
BUTTON("F") // 按钮
;
/**
* 类型
*/
private final String type;
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.service.auth.impl;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties; import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.framework.security.core.LoginUser; import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO; import cn.iocoder.dashboard.modules.system.controller.auth.vo.SysAuthGetInfoRespVO;
@ -12,6 +13,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRo
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO; import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO;
import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum; import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum;
import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum;
import cn.iocoder.dashboard.modules.system.enums.user.UserStatus; import cn.iocoder.dashboard.modules.system.enums.user.UserStatus;
import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService;
import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService; import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService;
@ -19,6 +21,7 @@ import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionServi
import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService;
import cn.iocoder.dashboard.modules.system.service.user.SysUserService; import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import cn.iocoder.dashboard.util.collection.CollectionUtils; import cn.iocoder.dashboard.util.collection.CollectionUtils;
import cn.iocoder.dashboard.util.collection.SetUtils;
import cn.iocoder.dashboard.util.date.DateUtils; import cn.iocoder.dashboard.util.date.DateUtils;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException; import io.jsonwebtoken.JwtException;
@ -231,22 +234,24 @@ public class SysAuthServiceImpl implements SysAuthService {
// 获得角色列表 // 获得角色列表
List<SysRoleDO> roleList = roleService.listRolesFromCache(roleIds); List<SysRoleDO> roleList = roleService.listRolesFromCache(roleIds);
// 获得菜单列表 // 获得菜单列表
List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds); List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds,
SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()),
SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus()));
// 拼接结果返回 // 拼接结果返回
return SysAuthConvert.INSTANCE.convert(user, roleList, menuList); return SysAuthConvert.INSTANCE.convert(user, roleList, menuList);
} }
@Override @Override
public List<SysAuthGetRouterRespVO> getRouters(Long userId, Set<Long> roleIds) { public List<SysAuthGetRouterRespVO> getRouters(Long userId, Set<Long> roleIds) {
// TODO 芋艿去除 F 的类型去除 禁用 List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds,
List<SysMenuDO> menuList = permissionService.listRoleMenusFromCache(roleIds); SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()),
SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus()));
// 转换成 Tree 结构返回 // 转换成 Tree 结构返回
return buildRouterTree(menuList); return buildRouterTree(menuList);
} }
private static List<SysAuthGetRouterRespVO> buildRouterTree(List<SysMenuDO> menuList) { private static List<SysAuthGetRouterRespVO> buildRouterTree(List<SysMenuDO> menuList) {
// 排序保证菜单的有序性 // 排序保证菜单的有序性
menuList = new ArrayList<>(menuList); // 使用 ArrayList 套一下因为 menuList 是不可修改的 List
menuList.sort(Comparator.comparing(SysMenuDO::getOrderNum)); menuList.sort(Comparator.comparing(SysMenuDO::getOrderNum));
// 构建菜单树 // 构建菜单树
// 使用 LinkedHashMap 的原因是为了排序 实际也可以用 Stream API 就是太丑了 // 使用 LinkedHashMap 的原因是为了排序 实际也可以用 Stream API 就是太丑了

View File

@ -18,16 +18,25 @@ public interface SysMenuService {
/** /**
* 获得所有菜单从缓存中 * 获得所有菜单从缓存中
* *
* 任一参数为空时则返回为空
*
* @param menuTypes 菜单类型数组
* @param menusStatuses 菜单状态数组
* @return 菜单列表 * @return 菜单列表
*/ */
List<SysMenuDO> listMenusFromCache(); List<SysMenuDO> listMenusFromCache(Collection<String> menuTypes, Collection<String> menusStatuses);
/** /**
* 获得指定编号的菜单数组从缓存中 * 获得指定编号的菜单数组从缓存中
* *
* 任一参数为空时则返回为空
*
* @param menuIds 菜单编号数组 * @param menuIds 菜单编号数组
* @param menuTypes 菜单类型数组
* @param menusStatuses 菜单状态数组
* @return 菜单数组 * @return 菜单数组
*/ */
List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds); List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds, Collection<String> menuTypes,
Collection<String> menusStatuses);
} }

View File

@ -22,10 +22,15 @@ public interface SysPermissionService {
/** /**
* 获得角色们拥有的菜单列表从缓存中获取 * 获得角色们拥有的菜单列表从缓存中获取
* *
* @param roleIds 角色编号素组 * 任一参数为空时则返回为空
*
* @param roleIds 角色编号数组
* @param menuTypes 菜单类型数组
* @param menusStatuses 菜单状态数组
* @return 菜单列表 * @return 菜单列表
*/ */
List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds); List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds, Collection<String> menuTypes,
Collection<String> menusStatuses);
/** /**
* 获得用户拥有的角色编号数组 * 获得用户拥有的角色编号数组

View File

@ -1,10 +1,9 @@
package cn.iocoder.dashboard.modules.system.service.permission.impl; package cn.iocoder.dashboard.modules.system.service.permission.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission.SysMenuMapper; import cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission.SysMenuMapper;
import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO;
import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService; import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService;
import com.google.common.collect.ImmutableList; import cn.iocoder.dashboard.util.collection.CollectionUtils;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
@ -13,10 +12,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -64,18 +60,27 @@ public class SysMenuServiceImpl implements SysMenuService {
} }
@Override @Override
public List<SysMenuDO> listMenusFromCache() { public List<SysMenuDO> listMenusFromCache(Collection<String> menuTypes, Collection<String> menusStatuses) {
// Guava ImmutableMap 对应的 value 类型为 ImmutableCollection // 任一一个参数为空则返回空
// ImmutableList copyof 如果入参类型为 ImmutableCollection 会进行包装而不会进行复制 if (CollectionUtils.isAnyEmpty(menuTypes, menusStatuses)) {
return ImmutableList.copyOf(menuCache.values()); return Collections.emptyList();
}
// 创建新数组避免缓存被修改
return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getMenuType())
&& menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList());
} }
@Override @Override
public List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds) { public List<SysMenuDO> listMenusFromCache(Collection<Long> menuIds, Collection<String> menuTypes,
if (CollectionUtil.isEmpty(menuIds)) { Collection<String> menusStatuses) {
// 任一一个参数为空则返回空
if (CollectionUtils.isAnyEmpty(menuIds, menuTypes, menusStatuses)) {
return Collections.emptyList(); return Collections.emptyList();
} }
return menuCache.values().stream().filter(menuDO -> menuIds.contains(menuDO.getMenuId())) return menuCache.values().stream().filter(menu -> menuIds.contains(menu.getMenuId())
&& menuTypes.contains(menu.getMenuType())
&& menusStatuses.contains(menu.getStatus()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
} }

View File

@ -17,6 +17,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
@ -77,16 +78,21 @@ public class SysPermissionServiceImpl implements SysPermissionService {
} }
@Override @Override
public List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds) { public List<SysMenuDO> listRoleMenusFromCache(Collection<Long> roleIds, Collection<String> menuTypes,
Collection<String> menusStatuses) {
// 任一一个参数为空时不返回任何菜单
if (CollectionUtils.isAnyEmpty(roleIds, menusStatuses, menusStatuses)) {
return Collections.emptyList();
}
// 判断角色是否包含管理员 // 判断角色是否包含管理员
List<SysRoleDO> roleList = roleService.listRolesFromCache(roleIds); List<SysRoleDO> roleList = roleService.listRolesFromCache(roleIds);
boolean hasAdmin = roleService.hasAnyAdmin(roleList); boolean hasAdmin = roleService.hasAnyAdmin(roleList);
// 获得角色拥有的菜单关联 // 获得角色拥有的菜单关联
if (hasAdmin) { // 管理员获取到全部 if (hasAdmin) { // 管理员获取到全部
return menuService.listMenusFromCache(); return menuService.listMenusFromCache(menuTypes, menusStatuses);
} }
List<Long> menuIds = MapUtils.getList(roleMenuCache, roleIds); List<Long> menuIds = MapUtils.getList(roleMenuCache, roleIds);
return menuService.listMenusFromCache(menuIds); return menuService.listMenusFromCache(menuIds, menuTypes, menusStatuses);
} }
@Override @Override

View File

@ -14,8 +14,8 @@ import java.util.stream.Collectors;
*/ */
public class CollectionUtils { public class CollectionUtils {
public static <T> Set<T> asSet(T... objs) { public static boolean isAnyEmpty(Collection<?>... collections) {
return new HashSet<>(Arrays.asList(objs)); return Arrays.stream(collections).anyMatch(CollectionUtil::isEmpty);
} }
public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) { public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) {

View File

@ -0,0 +1,18 @@
package cn.iocoder.dashboard.util.collection;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* Set 工具类
*
* @author 芋道源码
*/
public class SetUtils {
public static <T> Set<T> asSet(T... objs) {
return new HashSet<>(Arrays.asList(objs));
}
}