PC 2 tahun lalu
induk
melakukan
7660dd4ffa
21 mengubah file dengan 268 tambahan dan 76 penghapusan
  1. 2 1
      sckw-auth/src/main/java/com/sckw/auth/AuthApplication.java
  2. 2 2
      sckw-auth/src/main/java/com/sckw/auth/controller/IndexController.java
  3. 8 1
      sckw-auth/src/main/java/com/sckw/auth/model/vo/res/LoginResVo.java
  4. 30 10
      sckw-auth/src/main/java/com/sckw/auth/service/impl/IndexServiceImpl.java
  5. 49 0
      sckw-auth/src/main/resources/bootstrap-dev.yml
  6. 0 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/handle/CustomDataSource.java
  7. 0 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/handle/CustomMetaHandle.java
  8. 0 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/handle/MyConfig.java
  9. 31 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/interceptor/CustomWebMvcConfigurer.java
  10. 72 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/interceptor/LoginInterceptor.java
  11. 0 45
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/interceptor/WebInterceptor.java
  12. 2 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/web/constant/HttpStatus.java
  13. 10 4
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/RemoteUserService.java
  14. 21 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/res/KwsRoleResDto.java
  15. 0 0
      sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/res/LoginResDto.java
  16. 0 8
      sckw-modules/sckw-system/src/main/java/com/sckw/system/controller/KwsDeptController.java
  17. 10 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/dao/KwsRoleDao.java
  18. 10 4
      sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteUserServiceImpl.java
  19. 12 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/service/KwsRoleService.java
  20. 1 1
      sckw-modules/sckw-system/src/main/resources/bootstrap.yml
  21. 8 0
      sckw-modules/sckw-system/src/main/resources/mapper/KwsRoleDao.xml

+ 2 - 1
sckw-auth/src/main/java/com/sckw/auth/AuthApplication.java

@@ -13,7 +13,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
 @EnableDubbo
 @EnableFeignClients({"com.sckw.*.api.feign"})
 @EnableDiscoveryClient
-@SpringBootApplication
+@SpringBootApplication(scanBasePackages = {"com.sckw.core.*", "com.sckw.redis","com.sckw.auth.*"})
 public class AuthApplication {
     public static void main(String[] args) {
         // 关闭nacos日志
@@ -25,3 +25,4 @@ public class AuthApplication {
         }
     }
 }
+

+ 2 - 2
sckw-auth/src/main/java/com/sckw/auth/controller/IndexController.java

@@ -23,13 +23,13 @@ public class IndexController {
     @Autowired
     private IIndexService indexService;
 
-    @GetMapping("index")
+    @GetMapping("/index")
     public String index() {
         //auth 服务 调用 system服务提供的feign接口
         return remoteUserFService.getUserInfo("312");
     }
 
-    @GetMapping("getUserInfo")
+    @GetMapping("/getUserInfo")
     public String getUserInfo(String account) {
         //auth 服务 调用example实现的dubbo接口
         return remoteUserService.getUserInfoV1(account);

+ 8 - 1
sckw-auth/src/main/java/com/sckw/auth/model/vo/res/LoginResVo.java

@@ -1,13 +1,15 @@
 package com.sckw.auth.model.vo.res;
 
+import com.sckw.system.api.model.dto.res.KwsRoleResDto;
 import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.util.List;
 
 /**
  * @author czh
- * @desc TODO
+ * @desc 登录返参
  * @date 2023/6/12
  */
 @Data
@@ -70,4 +72,9 @@ public class LoginResVo implements Serializable {
      * 企业信息
      */
     private EntInfoResVo entInfo;
+
+    /**
+     * 角色信息
+     */
+    private List<KwsRoleResDto> roleInfo;
 }

+ 30 - 10
sckw-auth/src/main/java/com/sckw/auth/service/impl/IndexServiceImpl.java

@@ -5,9 +5,13 @@ import com.sckw.auth.model.vo.req.LoginReqVo;
 import com.sckw.auth.model.vo.res.DeptInfoResVo;
 import com.sckw.auth.model.vo.res.EntInfoResVo;
 import com.sckw.auth.model.vo.res.LoginResVo;
+import com.sckw.system.api.model.dto.res.KwsRoleResDto;
+import com.sckw.core.exception.SystemException;
+import com.sckw.core.model.constant.Global;
 import com.sckw.core.utils.BeanUtils;
 import com.sckw.core.utils.CollectionUtils;
-import com.sckw.core.utils.UUIDUtils;
+import com.sckw.core.utils.EncryUtil;
+import com.sckw.core.web.constant.HttpStatus;
 import com.sckw.redis.utils.RedissonUtils;
 import com.sckw.system.api.model.dto.req.RegisterReqDto;
 import com.sckw.system.api.model.dto.res.*;
@@ -42,16 +46,21 @@ public class IndexServiceImpl implements IIndexService {
         LoginResVo loginResVo = new LoginResVo();
         BeanUtils.copyProperties(kwsUser, loginResVo);
 
-        /*2、登录成功,查询用户机构*/
+        /*2、登录成功,查询角色信息*/
+        Long userId = kwsUser.getId();
+        List<KwsRoleResDto> kwsRoleResDtos = remoteUserService.queryRoleInfoByUserId(userId);
         EntInfoResVo entInfoResVo = new EntInfoResVo();
         loginResVo.setEntInfo(entInfoResVo);
-        List<KwsUserDeptResDto> kwsUserDepts = remoteUserService.queryUserDeptByUserId(kwsUser.getId());
-        if (CollectionUtils.isEmpty(kwsUserDepts)) {
-            //没有认证,没有所属机构
+        loginResVo.setRoleInfo(kwsRoleResDtos);
+        if (CollectionUtils.isEmpty(kwsRoleResDtos)) {
+            //角色信息为空,没有认证
             saveToCache(loginResVo);
             return loginResVo;
         }
-        List<Long> deptIds = kwsUserDepts.stream().map(KwsUserDeptResDto::getDeptId).toList();
+
+
+        /*2、登录成功,查询用户机构*/
+        List<Long> deptIds = kwsRoleResDtos.stream().map(KwsRoleResDto::getDeptId).toList();
         List<KwsDeptResDto> kwsDepts = remoteUserService.queryDeptByIds(deptIds);
         if (CollectionUtils.isEmpty(kwsDepts)) {
             //数据不全,直接返回
@@ -68,20 +77,31 @@ public class IndexServiceImpl implements IIndexService {
         Long entId = kwsDepts.get(0).getEntId();
         KwsEnterpriseResDto kwsEnterprise = remoteUserService.queryEnterpriseById(entId);
         if (Objects.isNull(kwsEnterprise)) {
+            //只要查出了机构,这个if其实不会进的,做保险起见还是加上判空
             saveToCache(loginResVo);
             return loginResVo;
         }
-        BeanUtils.copyProperties(kwsEnterprise, loginResVo);
+        BeanUtils.copyProperties(kwsEnterprise, entInfoResVo);
 
         /*4、以uuid作为主键存redis,也是会话token*/
         saveToCache(loginResVo);
         return loginResVo;
     }
 
+    /**
+     * @param  loginResDto 登录的返参
+     * @desc: 生成token,存redis
+     * @author: czh
+     * @date: 2023/6/12
+     */
     private void saveToCache(LoginResVo loginResDto) {
-        String key = UUIDUtils.get32UUID();
-        loginResDto.setToken(key);
-        redissonUtils.add(key, JSON.toJSONString(loginResDto));
+        try {
+            String token = EncryUtil.encry(Global.PRI_KEY, JSON.toJSONString(loginResDto));
+            loginResDto.setToken(token);
+            redissonUtils.add(token, JSON.toJSONString(loginResDto));
+        } catch (Exception e) {
+            throw new SystemException(HttpStatus.GLOBAL_EXCEPTION_CODE, HttpStatus.GLOBAL_EXCEPTION_MESSAGE);
+        }
     }
 
     @Override

+ 49 - 0
sckw-auth/src/main/resources/bootstrap-dev.yml

@@ -17,6 +17,55 @@ spring:
         namespace: sckw-service-platform-dev
         # 共享配置
         group: sckw-service-platform
+  data:
+    redis:
+      #redis机器ip
+      host: 127.0.0.1
+      #redis端口
+      port: 6379
+      #redis密码
+      password:
+      #数据库
+      database: 1
+      #redis超时时间(毫秒),如果不设置,取默认值2000
+      timeout: 10000
+      #最大空闲数
+      maxIdle: 300
+        #连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
+        #maxActive=600
+        #控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
+      maxTotal: 1000
+        #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
+      maxWaitMillis: 1000
+        #连接的最小空闲时间 默认1800000毫秒(30分钟)
+      minEvictableIdleTimeMillis: 300000
+        #每次释放连接的最大数目,默认3
+      numTestsPerEvictionRun: 1024
+        #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
+      timeBetweenEvictionRunsMillis: 30000
+        #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
+      testOnBorrow: true
+        #在空闲时检查有效性, 默认false
+      testWhileIdle: true
+        #连接池最大连接数(如果配置<=0,则没有限制)
+      jedis:
+        pool:
+          max-active: -1
+  datasource:
+    dynamic:
+      primary: master #设置默认的数据源或者数据源组,默认值即为master
+      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
+      datasource:
+        master:
+          url: jdbc:mysql://47.108.162.14:3306/sckw_system?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
+          username: root
+          password: Yy123...
+          driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
+        slave_1:
+          url: jdbc:mysql://47.108.162.14:3306/wph_system?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
+          username: root
+          password: Yy123...
+          driver-class-name: com.mysql.jdbc.Driver
 
 dubbo:
   application:

+ 0 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/handle/CustomDataSource.java


+ 0 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/handle/CustomMetaHandle.java


+ 0 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/handle/MyConfig.java


+ 31 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/interceptor/CustomWebMvcConfigurer.java

@@ -0,0 +1,31 @@
+package com.sckw.core.interceptor;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author czh
+ * @desc TODO
+ * @date 2023/6/12
+ */
+@Configuration
+public class CustomWebMvcConfigurer implements WebMvcConfigurer {
+
+    /**
+     * @param * registry
+     * @desc: 配置拦截规则与注入拦截器
+     * @author: czh
+     * @date: 2023/6/12
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // addPathPattern 添加拦截规则 /** 拦截所有包括静态资源
+        // excludePathPattern 排除拦截规则 所以我们需要放开静态资源的拦截
+        registry.addInterceptor(new LoginInterceptor())
+                .addPathPatterns("/**");
+    }
+}

+ 72 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/interceptor/LoginInterceptor.java

@@ -0,0 +1,72 @@
+package com.sckw.core.interceptor;
+
+import com.sckw.core.exception.SystemException;
+import com.sckw.core.model.constant.Global;
+import com.sckw.core.utils.EncryUtil;
+import com.sckw.core.utils.StringUtils;
+import com.sckw.core.web.constant.HttpStatus;
+import com.sckw.core.web.constant.RequestConstant;
+import com.sckw.redis.utils.RedissonUtils;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author czh
+ * @desc 拦截器
+ * @date 2023/6/12
+ */
+@Slf4j
+public class LoginInterceptor implements HandlerInterceptor {
+
+    private static final List<String> excludePath = new ArrayList<>();
+
+    static {
+        excludePath.add("/auth/login");
+    }
+
+    @Resource
+    private RedissonUtils redissonUtils;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+
+        //1、定义不拦截的接口
+        log.info("==============>getRequestURI:{} ", request.getRequestURI());
+        if (excludePath.contains(request.getRequestURI())) {
+            return true;
+        }
+
+//        if(handler instanceof HandlerMethod){
+//            return true;
+//        }
+
+        //2、非登录接口,校验token是否过期
+        String token = request.getHeader(RequestConstant.TOKEN);
+        if (StringUtils.isBlank(token)) {
+            throw new SystemException(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.TOKEN_MISSING);
+        }
+
+        String key = null;
+        try {
+            key = EncryUtil.descry(Global.PRI_KEY, token);
+        } catch (Exception e) {
+            throw new SystemException(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.TOKEN_ERROR);
+        }
+        Object object = redissonUtils.get(key);
+        if (Objects.isNull(object)) {
+            throw new SystemException(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.TOKEN_INVAILD);
+        }
+
+        return true;
+    }
+
+
+}

+ 0 - 45
sckw-common/sckw-common-core/src/main/java/com/sckw/core/interceptor/WebInterceptor.java

@@ -1,45 +0,0 @@
-package com.sckw.core.interceptor;
-
-import com.sckw.core.web.constant.RequestConstant;
-import com.sckw.redis.utils.RedissonUtils;
-import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-@Slf4j
-@Component
-public class WebInterceptor implements HandlerInterceptor {
-
-    public static final List<String> EXCLUDEMETHOD = new ArrayList<>();
-
-    static {
-        EXCLUDEMETHOD.add("/auth/login");
-    }
-
-    @Resource
-    private RedissonUtils redissonUtils;
-
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-        //1、解析请求的url,如果是登录接口则直接放行
-        String method = request.getMethod();
-        if (EXCLUDEMETHOD.contains(method)) {
-            log.info("登录接口");
-        }
-
-        //2、非登录接口,校验token是否过期
-        String token = request.getHeader(RequestConstant.TOKEN);
-        Object object = redissonUtils.get(token);
-        if (Objects.isNull(object)) {
-            log.error("过期抛异常。。。。");
-        }
-        return true;
-    }
-
-}

+ 2 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/web/constant/HttpStatus.java

@@ -31,6 +31,8 @@ public class HttpStatus {
     public static final String ACCOUNT_EXISTS = "用户账号已存在!";
     public static final String PWD_MISSING = "密码不能为空!";
     public static final String TOKEN_MISSING = "token不能为空!";
+    public static final String TOKEN_INVAILD = "无效token";
+    public static final String TOKEN_ERROR = "非法token!";
 
 
     /**其他自定义状态码*/

+ 10 - 4
sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/RemoteUserService.java

@@ -1,10 +1,7 @@
 package com.sckw.system.api;
 
 import com.sckw.system.api.model.dto.req.RegisterReqDto;
-import com.sckw.system.api.model.dto.res.KwsDeptResDto;
-import com.sckw.system.api.model.dto.res.KwsEnterpriseResDto;
-import com.sckw.system.api.model.dto.res.KwsUserDeptResDto;
-import com.sckw.system.api.model.dto.res.KwsUserResDto;
+import com.sckw.system.api.model.dto.res.*;
 
 import java.util.List;
 
@@ -58,4 +55,13 @@ public interface RemoteUserService {
      * @return
      */
     KwsEnterpriseResDto queryEnterpriseById(Long entId);
+
+    /**
+     * @param * @param 用户id
+     * @return
+     * @desc: 根据用户id查角色
+     * @author: czh
+     * @date: 2023/6/12
+     */
+    List<KwsRoleResDto> queryRoleInfoByUserId(Long userId);
 }

+ 21 - 0
sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/res/KwsRoleResDto.java

@@ -0,0 +1,21 @@
+package com.sckw.system.api.model.dto.res;
+
+import lombok.Data;
+
+/**
+ * @author czh
+ * @desc 角色信息
+ * @date 2023/6/12
+ */
+@Data
+public class KwsRoleResDto {
+
+    private String id;
+
+    private String name;
+
+    private long deptId;
+
+    private String remark;
+
+}

+ 0 - 0
sckw-modules-api/sckw-system-api/src/main/java/com/sckw/system/api/model/dto/res/LoginResDto.java


+ 0 - 8
sckw-modules/sckw-system/src/main/java/com/sckw/system/controller/KwsDeptController.java

@@ -1,19 +1,11 @@
 package com.sckw.system.controller;
 
-import com.github.pagehelper.PageHelper;
-import com.github.pagehelper.PageInfo;
-import com.sckw.core.model.auth.LoginEnterpriseInfo;
-import com.sckw.core.model.auth.context.LoginEnterpriseHolder;
-import com.sckw.core.model.page.PageHelperUtil;
-import com.sckw.core.model.page.PageResult;
-import com.sckw.core.web.context.LoginEntHolder;
 import com.sckw.core.web.response.HttpResult;
 import com.sckw.system.model.KwsDept;
 import com.sckw.system.service.KwsDeptService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import java.util.HashMap;
-import java.util.List;
 
 /**
  * 组织机构

+ 10 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/dao/KwsRoleDao.java

@@ -1,5 +1,6 @@
 package com.sckw.system.dao;
 
+import com.sckw.system.api.model.dto.res.KwsRoleResDto;
 import com.sckw.system.model.KwsRole;
 import org.apache.ibatis.annotations.Mapper;
 import java.util.List;
@@ -40,4 +41,13 @@ public interface KwsRoleDao {
      * @throws Exception
      */
     List<KwsRole> findPage(Map<String, Object> params);
+
+    /**
+     * @param  userId 用户id
+     * @return KwsRoleResDto
+     * @desc: 根据用户id查角色
+     * @author: czh
+     * @date: 2023/6/12
+     */
+    List<KwsRoleResDto> queryRoleByUserId(Long userId);
 }

+ 10 - 4
sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteUserServiceImpl.java

@@ -4,15 +4,13 @@ import com.sckw.core.utils.BeanUtils;
 import com.sckw.core.utils.CollectionUtils;
 import com.sckw.system.api.RemoteUserService;
 import com.sckw.system.api.model.dto.req.RegisterReqDto;
-import com.sckw.system.api.model.dto.res.KwsDeptResDto;
-import com.sckw.system.api.model.dto.res.KwsEnterpriseResDto;
-import com.sckw.system.api.model.dto.res.KwsUserDeptResDto;
-import com.sckw.system.api.model.dto.res.KwsUserResDto;
+import com.sckw.system.api.model.dto.res.*;
 import com.sckw.system.model.KwsDept;
 import com.sckw.system.model.KwsEnterprise;
 import com.sckw.system.model.KwsUser;
 import com.sckw.system.model.KwsUserDept;
 import com.sckw.system.service.KwsEnterpriseService;
+import com.sckw.system.service.KwsRoleService;
 import com.sckw.system.service.KwsUserService;
 import jakarta.annotation.Resource;
 import org.apache.dubbo.config.annotation.DubboService;
@@ -39,6 +37,9 @@ public class RemoteUserServiceImpl implements RemoteUserService {
     @Resource
     private KwsEnterpriseService kwsEnterpriseService;
 
+    @Resource
+    private KwsRoleService kwsRoleService;
+
     @Override
     public String getUserInfoV1(String account) {
         return null;
@@ -85,6 +86,11 @@ public class RemoteUserServiceImpl implements RemoteUserService {
         return kwsEnterpriseResDto;
     }
 
+    @Override
+    public List<KwsRoleResDto> queryRoleInfoByUserId(Long userId) {
+        return kwsRoleService.queryRoleByUserId(userId);
+    }
+
     @Override
     public void register(RegisterReqDto reqDto) {
 

+ 12 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/service/KwsRoleService.java

@@ -3,6 +3,7 @@ package com.sckw.system.service;
 import com.sckw.core.model.constant.Global;
 import com.sckw.core.utils.StringUtils;
 import com.sckw.core.web.response.HttpResult;
+import com.sckw.system.api.model.dto.res.KwsRoleResDto;
 import com.sckw.system.dao.KwsRoleDao;
 import com.sckw.system.model.KwsRole;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -89,4 +90,15 @@ public class KwsRoleService {
     public List<KwsRole> findPage(Map<String, Object> params) throws Exception{
         return kwsRoleDao.findPage(params);
     }
+
+    /**
+     * @param * @param 用户id
+     * @return
+     * @desc: 根据用户id查角色
+     * @author: czh
+     * @date: 2023/6/12
+     */
+    public List<KwsRoleResDto> queryRoleByUserId(Long userId) {
+        return kwsRoleDao.queryRoleByUserId(userId);
+    }
 }

+ 1 - 1
sckw-modules/sckw-system/src/main/resources/bootstrap.yml

@@ -1,5 +1,5 @@
 server:
-  port: 10030
+  port: 10040
 
 spring:
   application:

+ 8 - 0
sckw-modules/sckw-system/src/main/resources/mapper/KwsRoleDao.xml

@@ -141,4 +141,12 @@
     </if>
     ORDER BY sr.create_time desc
   </select>
+  <select id="queryRoleByUserId" resultType="com.sckw.system.api.model.dto.res.KwsRoleResDto">
+    select a.*
+      from kws_user_role a
+      left join kws_role b on a.role_id = b.id
+      where a.del_flag = 0
+        and b.del_flag = 0
+        and a.user_id = #{userId}
+  </select>
 </mapper>