一.首先說一下 表
1.用戶表
2.用戶角色表
3.角色表
4.角色權限表
5.權限表(包含菜單表)
二.整個邏輯如下:
1. 一個後臺可能多個用戶 (用戶表)
用戶角色表連接 1 - 2
2.每一個用戶可能用戶多個角色,例如,AA用戶 既是超級管理員 又是客服管理 (角色表)
角色權限表 連接 2 - 3
3.每個角色又有多種權限 ,例如,超級管理員,可以查看權限列表,後臺客服管理又可以瀏覽日誌模塊,(權限表)
三 .表字段
用戶表: 基本字段 + ids(角色表id集合)
角色表: id ,角色名稱, 角色代碼,描述,創建角色id, ids,權限ids
用戶角色表: 用戶id ,角色id
權限表: id,權限名稱,權限代碼,icon ,權限path, 排序sort. 菜單,父parentId
角色權限表: 角色id,權限id
四.JWT實現,引入JWT maven依賴,
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
<!-- StringUtils工具類包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<!-- spring security依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
JWTutil
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
* JWT安全工具類
*
* @ClassName: JwtUtil
* @author xie
* @date 2019年1月10日
*/
@ConfigurationProperties("jwt.config")
@Component
public class JwtUtil {
private String key;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
/**
* 生成JWT
*
* @param id
* @param subject
* @return
*/
public String createJWT(String id, String subject, String headPic, String roles, long ttl) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder().setId(id).setSubject(subject).setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, getKeyInstance(key)).claim("roles", roles)
.claim("headPic", headPic);
if (ttl > 0) {
builder.setExpiration(new Date(nowMillis + ttl));
}
return builder.compact();
}
/**
* 獲取生成token的key
*
* @return
*/
private static Key getKeyInstance(String key) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(key);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
return signingKey;
}
/**
* 解析JWT
*
* @param jwtStr
* @return
*/
public Claims parseJWT(String jwtStr) {
return Jwts.parser().setSigningKey(getKeyInstance(key)).parseClaimsJws(jwtStr).getBody();
}
/**
* 獲取用戶ID
*
* @return
*/
public Long getUserId(Claims claims) {
return Long.parseLong(claims.get("jti").toString());
}
/**
* 刷新TOKEN
*
* @param refreshClaims
* @param ttl
* @param refttl
* @return
*/
public Map<String, String> refreshToken(Claims refreshClaims, Long ttl, Long refttl) {
String id = refreshClaims.getId();
String subject = refreshClaims.getSubject();
String roles = refreshClaims.get("roles").toString();
String headPic = refreshClaims.get("headPic").toString();
// 重新生成TOKEN
String accessToken = createJWT(id, subject, headPic, roles, ttl);
String refreshToken = createJWT(id, subject, headPic, roles, refttl);
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("accessToken", accessToken);
tokenMap.put("refreshToken", refreshToken);
return tokenMap;
}
}
代碼思路:
一。登陸
前端傳入User信息到controller
調用用戶服務查詢當前用戶
根據賬戶查詢用戶表,
如果不存在,返回賬戶密碼錯誤
獲取當前第一個用戶
校驗密碼,如果該密碼爲空,或者傳進來的用戶密碼與數據庫的密碼不一致,不等,返回帳戶密碼錯誤
校驗狀態,如果查到的用戶狀態爲0,請聯繫管理員
查詢角色列表,根據用戶id查詢當前用戶擁有多少角色,
如果角色未空,返回該用戶未分配角色
如果不爲空,(可以判斷該角色是否滿足當前權限,如果不滿足,返回權限不足)
創建authToken map。
創建訪問TOKEN
創建刷新TOKEN
將訪問和刷新token 放入map。
給查到當前的用戶設置刷新時間
更新用戶表
根據用戶id 加載權限列表
-------------------------------------------------------
從緩存中獲取用戶權限列表
如果權限爲空
獲取用戶的角色
如果角色中包含超級管理員,查詢所有可用權限
否則查詢用戶制定全選
將權限放入redis
設置過期時間 優化緩存(2小時)
返回權限
-------------------------------------------------------
如果返回結果爲ture
獲取authtoken。
將訪問token設置到相應頭中,key,salt,accesstoken,
將刷新token設置到相應頭中,refrekey ,refreshtoken。
返回結果。
因爲我們用了security 加密密碼。所以在設置攔截器的時候,要先放行。security的所有請求。
啓動類注入Spring Security的 密碼加密
@Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* Security 配置類
* @ClassName: SecurityConfig
* @author sans
* @date 2019年1月11日
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
System.out.println("進入放權所有請求");
http.authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated().and().csrf().disable();
}
@Override
public void configure(WebSecurity web)throws Exception{
System.out.println("進入放權所有靜態頁面");
web.ignoring()
.antMatchers("**/favicon.ico")
.antMatchers("**/webjars/**")
.antMatchers("**/v2**")
.antMatchers("**/swagger-resources/**")
.antMatchers("**/resources/**")
.antMatchers("/swagger-resources/configuration/ui")
.antMatchers("/swagger-resources")
.antMatchers("/swagger-resources/configuration/security")
.antMatchers("**/swagger-ui.html/**");
System.out.println("進入放權所有靜態頁面======結束");
}
}
並添加攔截器
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.qiluodz.interceptor.SyncPermissionInteceptor;
import com.qiluodz.interceptor.WebInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.ArrayList;
import java.util.List;
/**
* 配置類
*
* @ClassName: FastJsonHttpMessageConfig
* @author xie
* @date 2019年1月9日
*/
@SpringBootConfiguration
public class FastJsonHttpMessageConfig extends WebMvcConfigurationSupport {
@Autowired
private WebInterceptor webInterceptor; //web攔截器
@Autowired
private SyncPermissionInteceptor syncPermissionInteceptor; //同步權限攔截器
/**
* 配置fastjson
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
// 添加fastJson 的配置信息
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteDateUseDateFormat);
// 處理中文亂碼問題
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastConverter.setSupportedMediaTypes(fastMediaTypes);
// 在convert中添加配置信息.
fastConverter.setFastJsonConfig(fastJsonConfig);
// 將convert添加到converters當中
converters.add(fastConverter);
}
/**
* 配置攔截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 放行登錄註冊
registry.addInterceptor(webInterceptor).addPathPatterns("/**");
registry.addInterceptor(syncPermissionInteceptor).addPathPatterns("/**");
// 放行swagger
registry.addInterceptor(webInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/user/login")
.excludePathPatterns("**/swagger-resources/**", "**/webjars/**", "**/v2/**", "**/swagger-ui.html");
registry.addInterceptor(syncPermissionInteceptor)
.addPathPatterns("/**")
.excludePathPatterns("/user/login")
.excludePathPatterns("**/swagger-resources/**", "**/webjars/**", "**/v2/**", "**/swagger-ui.html");
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("**/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
---------------------------------------------------------------------------------------
web攔截器
import com.alibaba.fastjson.JSONObject;
import com.qiluodz.pojo.vo.DzResult;
import com.qiluodz.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* WEB過濾器
*
* @ClassName: WebInteceptor
* @author xie
* @date 2019年1月9日
*
*/
@Component
public class WebInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(WebInterceptor.class);
@Autowired
private JwtUtil jwtUtil;
@Value("${auth.key}")
private String key;
@Value("${auth.refrekey}")
private String refrekey;
@Value("${auth.salt}")
private String salt;
@Value("${auth.ttl}")
private Long ttl;
@Value("${auth.refrettl}")
private Long refttl;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("_____進入WebInterceptor_______");
System.out.println("========當前請求路徑爲=======");
System.out.println(request.getRequestURL().toString());
// 配置跨域
System.out.println("攔截所有請求");
System.out.println("設置請求頭");
String origin = request.getHeader("Origin");
if (origin != null && !"".equals(origin)) {
System.out.println("獲取頭,請求頭頭不等於空");
System.out.println("開始設置相應頭");
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Max-Age", "3600");
response.addHeader("allowCredentials", "true");
response.addHeader("Access-Control-Expose-Headers", "Authorization, RefreAuth");
if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
System.out.println("請求頭中有options,忽略大小寫");
System.out.println("設置響應頭的方法");
response.addHeader("Access-Control-Allow-Methods", "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,PATCH");
response.addHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, RefreAuth");
}
}
if (request.getRequestURL().toString().contains("/api/user/login")) {
System.out.println("訪問的是登錄頁面,放行");
return true;
}
//-----sans
if (request.getRequestURL().toString().contains("/api/customer/loginByUserName")) {
System.out.println("2.進入前端登錄頁面,放行");
return true;
}
if (request.getRequestURL().toString().contains("/swagger")) {
System.out.println("3.進入SWAGGER-UI.html.放行");
return true;
}
if (request.getRequestURL().toString().contains("/webjars")) {
System.out.println("3.進入SWAGGER-UI.html.放行");
return true;
}
// 驗權
String token = request.getHeader("Authorization");
System.out.println("開始驗權限");
Claims claims = null;
if (StringUtils.isNotBlank(token)) {
System.out.println("token不等於空");
System.out.println("token+個鹽");
token = token.substring(salt.length() + 1);
if (StringUtils.isNotBlank(token)) {
System.out.println("token加鹽後再次判斷,不爲空");
try {
// 解析token
System.out.println("JWT解析Token");
claims = jwtUtil.parseJWT(token);
request.setAttribute("authInfo", claims);
System.out.println("解析成功,授權該請求");
return true;
} catch (Exception e1) {
System.out.println("jwt,解析失敗");
// 驗權失敗,獲取刷新TOKEN
System.out.println("開始刷新token,");
try {
System.out.println("頭已經存在,已登錄的");
String refreToken = request.getHeader("RefreAuth");
System.out.println("在請求頭中,獲取刷新token");
Claims refreshClaims = jwtUtil.parseJWT(refreToken);
System.out.println("解析刷新頭");
Map<String, String> tokenMap = jwtUtil.refreshToken(refreshClaims, ttl, refttl);
// 設置請求和響應信息
request.setAttribute("authInfo", refreshClaims);
System.out.println("授權");
System.out.println("獲取koken並加鹽,然後設置到相應頭中");
response.setHeader(key, salt + " " + tokenMap.get("accessToken"));
System.out.println("獲取刷新頭,並設置到相應頭中");
response.setHeader(refrekey, tokenMap.get("refreshToken"));
logger.info("TOKEN在攔截器一刷新");
System.out.println("__________________________________結束WebInterceptor__________________________________");
return true;
} catch (Exception e2) {
System.out.println("刷新頭不存在,首次登陸");
e2.printStackTrace();
}
}
}
}
System.out.println("token不存在,或者爲空,驗籤失敗");
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
response.getWriter().append(JSONObject.toJSONString(new DzResult().error(2002, "驗籤失敗")));
return false;
}
}
---------------------------------------------------------------------------------------
同步權限攔截器
import com.alibaba.fastjson.JSONArray;
import com.qiluodz.exception.AuthenticationException;
import com.qiluodz.pojo.entity.DzUser;
import com.qiluodz.service.managerService.RoleService;
import com.qiluodz.service.managerService.UserService;
import com.qiluodz.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 同步權限攔截器
*
* @ClassName: ReloadPermissionInteceptor
* @author xie
* @date 2019年1月15日
*/
@Component
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SyncPermissionInteceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(SyncPermissionInteceptor.class);
@Autowired
private JwtUtil jwtUtil;
@Value("${auth.ttl}")
private Long ttl;
@Value("${auth.refrettl}")
private Long refttl;
@Value("${auth.key}")
private String key;
@Value("${auth.refrekey}")
private String refrekey;
@Value("${auth.salt}")
private String salt;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Value("${PERMISSION_LIST_KEY}")
private String permissionListKey;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("=============進入同步權限攔截器===============");
System.out.println("========當前請求路徑爲============");
System.out.println(request.getRequestURL().toString());
System.out.println("=========== ===============");
if (request.getRequestURL().toString().contains("/api/user/login")) {
System.out.println("1.進入登錄頁面,放行");
return true;
}
//-----sans
if (request.getRequestURL().toString().contains("/api/customer/loginByUserName")) {
System.out.println("2.進入前端登錄頁面,放行");
return true;
}
if (request.getRequestURL().toString().contains("/swagger")) {
System.out.println("3.進入SWAGGER-UI.html.放行");
return true;
}
if (request.getRequestURL().toString().contains("/webjars")) {
System.out.println("3.進入SWAGGER-UI.html.放行");
return true;
}
// 獲取當前用戶
Claims claims = (Claims) request.getAttribute("authInfo");
if (claims!=null){
System.out.println("2.獲取當前用戶");
System.out.println("---------------------------");
System.out.println("claims:__"+claims);
System.out.println("___________________________");
}
Long uid = Long.parseLong(claims.getId());
// 查詢權限緩存
String permissionJson = (String) redisTemplate.boundValueOps(permissionListKey + uid).get();
System.out.println("查詢權限緩存");
if (StringUtils.isBlank(permissionJson)) {
System.out.println("權限不存在");
// 重新加載權限
System.out.println("重新加載權限,獲取當前用戶的所有權限");
String loadPermission = userService.loadPermissionByUserId(uid);
if (StringUtils.isBlank(loadPermission)) {
System.out.println("權限爲空,權限不足");
throw new AuthenticationException(403, "權限不足");
}
// 刷新角色及TOKEN
DzUser currentUser = userService.findUserById(uid);
System.out.println("獲取最新角色和token");
if (currentUser == null) {
System.out.println("用戶不存在,權限不足");
throw new AuthenticationException(403, "權限不足");
}
List<String> roles = roleService.findRoleListByUser(uid);
System.out.println("查詢角色表中是否有該用戶");
if (roles == null || roles.size() <= 0) {
System.out.println("沒有.權限不足");
throw new AuthenticationException(403, "權限不足");
}
System.out.println("滿足以上條件,創建訪問token");
// 創建訪問TOKEN
String accessToken = jwtUtil.createJWT(currentUser.getId() + "", currentUser.getUsername(),
currentUser.getHeadPic(), JSONArray.toJSONString(roles), ttl);
// 創建刷新TOKEN
System.out.println("創建刷新token");
String refreshToken = jwtUtil.createJWT(currentUser.getId() + "", currentUser.getUsername(),
currentUser.getHeadPic(), JSONArray.toJSONString(roles), refttl);
Claims reloadClaims = jwtUtil.parseJWT(accessToken);
System.out.println("授權訪問.");
request.setAttribute("authInfo", reloadClaims);
response.setHeader(key, salt + " " + accessToken);
response.setHeader(refrekey, refreshToken);
logger.info("TOKEN在攔截器二刷新,用戶ID[" + claims.getId() + "] 用戶名[" + claims.getSubject() + "]");
}
System.out.println("權限存在,放行");
return true;
}
}
---------------------------------------------------------------------------------------
創建用戶controller
注入請求與相應
@Autowired
private HttpServletResponse response;
@Autowired
private HttpServletRequest request;
@Value("${auth.key}")
private String key;
@Value("${auth.refrekey}")
private String refrekey;
@Value("${auth.salt}")
private String salt;
---------------- 用戶登陸 -----------------------------------------------------------------------
在登錄時,根據用戶服務,判斷當前用戶登錄賬戶及密碼正確
/**
* 用戶登錄
*
* @param user
* @return
*/
@PostMapping("/login")
@ApiOperation("用戶登錄")
@SuppressWarnings("unchecked")
public DzResult login(@RequestBody DzUser user) {
DzResult result = userService.findUserByUsernameAndPassword(user);
if (result.getFlag() == true) {
Map<String, String> authToken = (Map<String, String>) result.getData();
String accessToken = authToken.get("accessToken");
String refreshToken = authToken.get("refreshToken");
response.setHeader(key, salt + " " + accessToken);
response.setHeader(refrekey, refreshToken);
result.setData(null);
}
return result;
}
@Override
public DzResult findUserByUsernameAndPassword(DzUser user) {
DzUserExample example = new DzUserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo(user.getUsername());
List<DzUser> userList = userMapper.selectByExample(example);
if (userList == null || userList.size() <= 0) {
return new DzResult().error(StatusCode.LOGIN_ERROR, "用戶名或密碼錯誤");
}
DzUser existUser = userList.get(0);
// 校驗密碼
if (StringUtils.isBlank(user.getPassword())
|| !passwordEncoder.matches(user.getPassword(), existUser.getPassword())) {
return new DzResult().error(StatusCode.LOGIN_ERROR, "用戶名或密碼錯誤");
}
// 校驗狀態
// 狀態 1:正常使用 0:禁用
if (existUser.getStatus().equals("0")) {
return new DzResult().error(StatusCode.LOGIN_USER_PROHIBIT, "賬戶已被禁用,請聯繫管理員");
}
// 查詢角色列表
List<String> roles = roleMapper.findRolesByUser(existUser.getId());
if (roles == null || roles.size() <= 0) {
return new DzResult().error(StatusCode.LOGIN_ROLE_NONE, "用戶未分配角色");
} else {
if (roles.contains("MANUFACTURER") || roles.contains("SURVEYOR") ) {
System.out.println("該賬戶權限不足,請聯繫客服");
throw new AuthenticationException(403, "權限不足,該賬戶是廠商/量體,請聯繫客服");
}
}
Map<String, String> authToken = new HashMap<>();
// 創建訪問TOKEN
String accessToken = jwtUtil.createJWT(existUser.getId() + "", existUser.getUsername(), existUser.getHeadPic(),
JSONArray.toJSONString(roles), ttl);
// 創建刷新TOKEN
String refreshToken = jwtUtil.createJWT(existUser.getId() + "", existUser.getUsername(), existUser.getHeadPic(),
JSONArray.toJSONString(roles), refttl);
authToken.put("accessToken", accessToken);
authToken.put("refreshToken", refreshToken);
// 刷新登錄時間
existUser.setLoginTime(new Date());
userMapper.updateByPrimaryKey(existUser);
// 加載權限列表
loadPermissionByUserId(existUser.getId());
return new DzResult().success(authToken);
}
--------------------------------------------------------------------------
userRoleMapper
<select id="findRoleIdsByUserId" parameterType="long" resultType="long">
SELECT role_id AS id
FROM dz_user_role
WHERE user_id=#{id}
</select>
--------------------------------------------------------------------------
rolerMapper
<select id="findRolesByUser" parameterType="long" resultType="string">
SELECT role_code AS roleCode
FROM dz_user du INNER JOIN dz_user_role dur
ON du.id = dur.user_id
INNER JOIN dz_role dr
ON dr.id = dur.role_id AND dr.`status` != '0' AND du.`status` != '0' AND du.id=#{uid}
</select>
--------------------------------------------------------------------------
PermissionMapper
<select id="findMenuByUser" parameterType="map" resultType="com.qiluodz.pojo.entity.DzPermission">
SELECT DISTINCT dp.id,dp.`name`,icon,path
FROM dz_user du INNER JOIN dz_user_role dur
ON du.id = dur.user_id AND du.`status`='1' AND du.id=#{uid}
INNER JOIN dz_role dr
ON dr.id = dur.role_id AND dr.`status`='1'
INNER JOIN dz_role_permission drp
ON dr.id = drp.role_id
INNER JOIN dz_permission dp
ON dp.id = drp.permission_id AND dp.`status`='1' AND dp.parent_id=#{isParent} AND dp.is_menu='1'
ORDER BY dp.sort ASC
</select>
<select id="findMenuByAdmin" parameterType="long" resultType="com.qiluodz.pojo.entity.DzPermission">
SELECT DISTINCT id,`name`,icon,path
FROM dz_permission
WHERE `status`='1' AND is_menu='1' AND parent_id=#{isParent}
ORDER BY sort ASC
</select>
<select id="findPermissionListByUser" parameterType="long" resultType="string">
SELECT DISTINCT permission_code AS permissionCode
FROM dz_user du INNER JOIN dz_user_role dur
ON du.id = dur.user_id AND du.`status`='1' AND du.id=#{uid}
INNER JOIN dz_role dr
ON dr.id = dur.role_id AND dr.`status`='1'
INNER JOIN dz_role_permission drp
ON dr.id = drp.role_id
INNER JOIN dz_permission dp
ON dp.id = drp.permission_id AND dp.`status`='1'
</select>
<select id="findPermissionByAdmin" resultType="string">
SELECT DISTINCT permission_code
FROM dz_permission
WHERE `status`='1'
</select>
<select id="findAllPermissionList" resultType="com.qiluodz.pojo.vo.PermissionGroup">
SELECT id,`name` as label,sort
FROM dz_permission
WHERE `status`=1 AND parent_id=0
ORDER BY sort ASC
</select>
<select id="findPermissionIdListByAdmin" resultType="long">
SELECT id
FROM dz_permission
WHERE `status`='1'
</select>
--------------------------------------------------------------------------
RolePermissionMapper
<select id="findPermissionIdsByRoleId" parameterType="long" resultType="long">
SELECT permission_id AS id
FROM dz_role_permission
WHERE role_id=#{id}
</select>
--------------------------------------------------------------------------
代碼思路 -- 添加用戶
密碼加密,補全屬性,設置頭像
關聯角色信息,如果用戶傳過來的角色id爲空,拋異常,綁定錯誤
切割所有角色id,便利
創建關聯對象,設置角色id & 設置用戶id,插入關聯對象表
代碼思路 - - 更新用戶
查到當前用戶,
更新用戶信息,執行更新
獲取用戶所有角色ID , 如果角色id爲空,授權失敗
查找已存在的用戶id的綁定的所有角色 清空角色,
獲取,當前更新的用戶的 所有角色.
便利獲取每個角色id,
創建用戶角色關聯對象,
設置用戶id和角色id .
插入角色表,
調用清除權限緩存
代碼思路 - - 刪除用戶
獲取刪除用戶的 id集合
便利,獲取每一個用戶
設置僞刪除,設置更新時間
更新.
調用清除權限緩存
--------------------------------------------------------------------------------------------------------------------------