wu
2024-06-26 c59cbfa92147058b828f78ed35b15d4ef4a7ef94
恢复Git删除的代码
30个文件已添加
1个文件已删除
1655 ■■■■■ 已修改文件
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/OptimizeLayoutMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/config/RedisConfig.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/config/TokenWebSecurityConfig.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/filter/JwtAuthenticationTokenFilter.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/JwtAccessDeniedHandler.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/JwtAuthenticationEntryPoint.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/JwtLogoutSuccessHandler.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/LoginFailureHandler.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/LoginSuccessHandler.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/FastJsonRedisSerializer.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/JwtUtil.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/RedisUtil.java 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/UserInfoUtils.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/WebUtils.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/controller/SysMenuController.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/entity/SysMenu.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/mapper/SysMenuMapper.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/service/SysMenuService.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/service/impl/SysMenuServiceImpl.java 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/controller/SysRoleController.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/entity/SysRole.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/entity/SysRoleMenu.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/entity/vo/SysRoleVO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/SysRoleMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/SysRoleMenuMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/xml/SysRoleMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/xml/SysRoleMenuMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/SysRoleMenuService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/SysRoleService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/impl/SysRoleMenuServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/impl/SysRoleServiceImpl.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/pp/mapper/OptimizeLayoutMapper.java
File was deleted
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/config/RedisConfig.java
New file
@@ -0,0 +1,37 @@
package com.mes.common.config;
import com.mes.common.utils.FastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
 * @Author : zhoush
 * @Date: 2024/4/9 19:13
 * @Description:
 */
@Configuration
public class RedisConfig {
    @Bean
    @SuppressWarnings(value = {"unchecked", "rawtypes"})
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/config/TokenWebSecurityConfig.java
New file
@@ -0,0 +1,94 @@
package com.mes.common.config;
import com.mes.common.filter.JwtAuthenticationTokenFilter;
import com.mes.common.handler.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    @Autowired
    LoginFailureHandler loginFailureHandler;
    @Autowired
    LoginSuccessHandler loginSuccessHandler;
    @Autowired
    JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    @Autowired
    JwtAccessDeniedHandler jwtAccessDeniedHandler;
    @Autowired
    JwtLogoutSuccessHandler jwtLogoutSuccessHandler;
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    /**
     * 配置过滤规则
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                // 登录配置
                .formLogin()
                .successHandler(loginSuccessHandler)
                .failureHandler(loginFailureHandler)
                .and()
                .logout()
                .logoutSuccessHandler(jwtLogoutSuccessHandler)
                // 禁用session
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                // 配置拦截规则
                .and()
                .authorizeRequests()
                .antMatchers("/sys/user/login").anonymous()
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/v2/**").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/**").permitAll()
                .anyRequest().authenticated()
                // 异常处理器
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .accessDeniedHandler(jwtAccessDeniedHandler)
                // 配置自定义的过滤器
                .and()
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/filter/JwtAuthenticationTokenFilter.java
New file
@@ -0,0 +1,80 @@
package com.mes.common.filter;
import com.mes.common.utils.JwtUtil;
import com.mes.common.utils.RedisUtil;
import com.mes.common.utils.UserInfoUtils;
import com.mes.userinfo.entity.LoginUser;
import com.mes.userinfo.service.SysUserService;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * @Author : zhoush
 * @Date: 2024/4/10 9:42
 * @Description:
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    // 此处解释为什么不去实现Filter接口,因为在某些情况下会过滤两次,执行两次Filter里面的方法,所以我们选择继承SpringSecurity中的OncePerRequestFilter
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private SysUserService sysUserService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取token
        String token = request.getHeader("token");
        if (!StringUtils.hasText(token)) {
            //放行
            filterChain.doFilter(request, response);
            return; // 此处加上return好处是后面结果返回的时候就不会再走一遍此过滤器的方法了
        }
        //解析token
        String userid;
        try {
            Claims claims = JwtUtil.getClaimByToken(token);
            userid = claims.getSubject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("token非法");
        }
        //从redis中获取用户信息
        String redisKey = "login:" + userid;
        LoginUser loginUser = redisUtil.getCacheObject(redisKey);
        if (Objects.isNull(loginUser)) {
            response.setHeader("token", "");
            throw new RuntimeException("用户未登录");
        }
        //将用户信息放入当前线程
        UserInfoUtils.set(loginUser.getUser());
        //存入SecurityContextHolder,以供后面的过滤器使用
        List<String> permissionKeyList = sysUserService.getUserAuthorityInfo(Long.parseLong(userid));
        List<GrantedAuthority> authorities = permissionKeyList.stream().
                map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser, null, authorities);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(request, response);
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/JwtAccessDeniedHandler.java
New file
@@ -0,0 +1,35 @@
package com.mes.common.handler;
import cn.hutool.json.JSONUtil;
import com.mes.utils.Result;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        ServletOutputStream outputStream = response.getOutputStream();
        Result result = Result.error(HttpStatus.FORBIDDEN.value(), "权限不足");
        outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));
        outputStream.flush();
        outputStream.close();
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/JwtAuthenticationEntryPoint.java
New file
@@ -0,0 +1,33 @@
package com.mes.common.handler;
import cn.hutool.json.JSONUtil;
import com.mes.utils.Result;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        ServletOutputStream outputStream = response.getOutputStream();
        Result result = Result.error(HttpStatus.UNAUTHORIZED.value(), "认证失败请重新登录");
        outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));
        outputStream.flush();
        outputStream.close();
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/JwtLogoutSuccessHandler.java
New file
@@ -0,0 +1,40 @@
package com.mes.common.handler;
import cn.hutool.json.JSONUtil;
import com.mes.utils.Result;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {
    private static final String header = "Authorization";
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        if (authentication != null) {
            new SecurityContextLogoutHandler().logout(request, response, authentication);
        }
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = response.getOutputStream();
        response.setHeader(header, "");
        Result result = Result.success("");
        outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));
        outputStream.flush();
        outputStream.close();
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/LoginFailureHandler.java
New file
@@ -0,0 +1,31 @@
package com.mes.common.handler;
import cn.hutool.json.JSONUtil;
import com.mes.utils.Result;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class LoginFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = response.getOutputStream();
        Result result = Result.error("用户名或密码错误");
        outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));
        outputStream.flush();
        outputStream.close();
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/handler/LoginSuccessHandler.java
New file
@@ -0,0 +1,38 @@
package com.mes.common.handler;
import cn.hutool.json.JSONUtil;
import com.mes.common.utils.JwtUtil;
import com.mes.utils.Result;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    private static final String header = "Authorization";
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = response.getOutputStream();
        // 生成jwt,并放置到请求头中
        String jwt = JwtUtil.generateToken(authentication.getName());
        response.setHeader(header, jwt);
        Result result = Result.success("");
        outputStream.write(JSONUtil.toJsonStr(result).getBytes("UTF-8"));
        outputStream.flush();
        outputStream.close();
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/FastJsonRedisSerializer.java
New file
@@ -0,0 +1,55 @@
package com.mes.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
/**
 * @Author : zhoush
 * @Date: 2024/4/11 15:28
 * @Description:
 */
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private Class<T> clazz;
    static {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
    }
    public FastJsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }
    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return JSON.parseObject(str, clazz);
    }
    protected JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/JwtUtil.java
New file
@@ -0,0 +1,55 @@
package com.mes.common.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import java.util.Date;
/**
 * @Author : zhoush
 * @Date: 2024/4/9 19:15
 * @Description:
 */
@Data
public class JwtUtil {
    private static final long expire = 60 * 60 * 1000L;
    private static final String secret = "beibo";
    private static final String header = "Authorization";
    // 生成jwt
    public static String generateToken(String username) {
        Date nowDate = new Date();
        Date expireDate = new Date(nowDate.getTime() + 1000 * expire);
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setSubject(username)
                .setIssuedAt(nowDate)
                .setExpiration(expireDate)// 7天過期
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }
    // 解析jwt
    public static Claims getClaimByToken(String jwt) {
        try {
            return Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(jwt)
                    .getBody();
        } catch (Exception e) {
            return null;
        }
    }
    // jwt是否过期
    public boolean isTokenExpired(Claims claims) {
        return claims.getExpiration().before(new Date());
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/RedisUtil.java
New file
@@ -0,0 +1,235 @@
package com.mes.common.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * spring redis 工具类
 **/
@Component
public class RedisUtil {
    @Autowired
    public RedisTemplate redisTemplate;
    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key   缓存的键值
     * @param value 缓存的值
     */
    public <T> void setCacheObject(final String key, final T value) {
        redisTemplate.opsForValue().set(key, value);
    }
    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }
    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout) {
        return expire(key, timeout, TimeUnit.SECONDS);
    }
    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @param unit    时间单位
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }
    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }
    /**
     * 删除单个对象
     *
     * @param key
     */
    public boolean deleteObject(final String key) {
        return redisTemplate.delete(key);
    }
    /**
     * 删除集合对象
     *
     * @param collection 多个对象
     * @return
     */
    public long deleteObject(final Collection collection) {
        return redisTemplate.delete(collection);
    }
    /**
     * 缓存List数据
     *
     * @param key      缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
    public <T> long setCacheList(final String key, final List<T> dataList) {
        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
        return count == null ? 0 : count;
    }
    /**
     * 获得缓存的list对象
     *
     * @param key 缓存的键值
     * @return 缓存键值对应的数据
     */
    public <T> List<T> getCacheList(final String key) {
        return redisTemplate.opsForList().range(key, 0, -1);
    }
    /**
     * 缓存Set
     *
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
        Iterator<T> it = dataSet.iterator();
        while (it.hasNext()) {
            setOperation.add(it.next());
        }
        return setOperation;
    }
    /**
     * 获得缓存的set
     *
     * @param key
     * @return
     */
    public <T> Set<T> getCacheSet(final String key) {
        return redisTemplate.opsForSet().members(key);
    }
    /**
     * 缓存Map
     *
     * @param key
     * @param dataMap
     */
    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
        if (dataMap != null) {
            redisTemplate.opsForHash().putAll(key, dataMap);
        }
    }
    /**
     * 获得缓存的Map
     *
     * @param key
     * @return
     */
    public <T> Map<String, T> getCacheMap(final String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * 往Hash中存入数据
     *
     * @param key   Redis键
     * @param hKey  Hash键
     * @param value 值
     */
    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
        redisTemplate.opsForHash().put(key, hKey, value);
    }
    /**
     * 获取Hash中的数据
     *
     * @param key  Redis键
     * @param hKey Hash键
     * @return Hash中的对象
     */
    public <T> T getCacheMapValue(final String key, final String hKey) {
        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
        return opsForHash.get(key, hKey);
    }
    /**
     * 删除Hash中的数据
     *
     * @param key
     * @param hkey
     */
    public void delCacheMapValue(final String key, final String hkey) {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.delete(key, hkey);
    }
    /**
     * 获取多个Hash中的数据
     *
     * @param key   Redis键
     * @param hKeys Hash键集合
     * @return Hash对象集合
     */
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
        return redisTemplate.opsForHash().multiGet(key, hKeys);
    }
    /**
     * 获得缓存的基本对象列表
     *
     * @param pattern 字符串前缀
     * @return 对象列表
     */
    public Collection<String> keys(final String pattern) {
        return redisTemplate.keys(pattern);
    }
    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/UserInfoUtils.java
New file
@@ -0,0 +1,26 @@
package com.mes.common.utils;
import com.mes.userinfo.entity.SysUser;
/**
 * @Author : zhoush
 * @Date: 2024/4/25 15:41
 * @Description:
 */
public class UserInfoUtils {
    private static InheritableThreadLocal<SysUser> tokenPool = new InheritableThreadLocal<SysUser>();
    public static SysUser get() {
        return tokenPool.get();
    }
    public static void set(SysUser user) {
        tokenPool.set(user);
    }
    public static void remove() {
        if (get() != null) {
            tokenPool.remove();
        }
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/common/utils/WebUtils.java
New file
@@ -0,0 +1,30 @@
package com.mes.common.utils;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @Author : zhoush
 * @Date: 2024/4/9 19:16
 * @Description:
 */
public class WebUtils {
    /**
     * 将字符串渲染到客户端
     *
     * @param response 渲染对象
     * @param string   待渲染的字符串
     * @return null
     */
    public static String renderString(HttpServletResponse response, String string) {
        try {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/controller/SysMenuController.java
New file
@@ -0,0 +1,77 @@
package com.mes.menu.controller;
import com.mes.entity.request.GeneralRequest;
import com.mes.menu.entity.SysMenu;
import com.mes.menu.service.SysMenuService;
import com.mes.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
 * @author zhoush
 * @since 2024-04-11
 */
@Api(description = "菜单管理")
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController {
    @Autowired
    private SysMenuService sysMenuService;
    @ApiOperation("新增菜单")
    @PostMapping("/save")
//    @PreAuthorize("hasAuthority('sys:menu:save')")
    public Result save(@Validated @RequestBody SysMenu sysMenu) {
        return Result.success(sysMenuService.save(sysMenu));
    }
    @ApiOperation("修改菜单信息")
    @PostMapping("/updateMenu")
//    @PreAuthorize("hasAuthority('sys:menu:update')")
    public Result updateMenu(@Validated @RequestBody SysMenu sysMenu) {
        sysMenuService.updateMenu(sysMenu);
        return Result.success(sysMenu);
    }
    @ApiOperation("获取用户有权限的所有菜单")
    @GetMapping("/getMenuTree")
    public Result<List<SysMenu>> getMenuTree(GeneralRequest request) {
        return Result.success(sysMenuService.getMenuTree(request));
    }
    @ApiOperation("获取用户的权限")
    @GetMapping("/getAuthorityInfo")
    public Result<List<String>> getAuthorityInfo() {
        return Result.success(sysMenuService.getAuthorityInfo());
    }
    @ApiOperation("用户当前用户的菜单和权限信息")
    @GetMapping("/nav")
    public Result<Map<Object, Object>> nav() {
        return Result.success(sysMenuService.nav());
    }
    @ApiOperation("删除菜单")
    @PostMapping("/deleteMenu")
//    @PreAuthorize("hasAuthority('sys:menu:delete')")
    public Result<String> deleteMenu(Long menuId) {
        return Result.success(sysMenuService.deleteMenu(menuId));
    }
    @ApiOperation("批量删除菜单")
    @PostMapping("/batchDeleteMenu")
//    @PreAuthorize("hasAuthority('sys:menu:delete')")
    public Result<String> batchDeleteMenu(@RequestBody List<Long> menuIds) {
        return Result.success(sysMenuService.batchDeleteMenu(menuIds));
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/entity/SysMenu.java
New file
@@ -0,0 +1,87 @@
package com.mes.menu.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * <p>
 *
 * </p>
 *
 * @author zhoush
 * @since 2024-04-13
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class SysMenu implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 自增id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 父id
     */
    private Long parentId;
    /**
     * 模块名称
     */
    private String menuName;
    /**
     * 图标
     */
    private String icon;
    /**
     * 地址
     */
    private String url;
    /**
     * 语言类型
     */
    private String languageType;
    /**
     * 状态
     */
    private Integer status;
    /**
     * 排序
     */
    private String listSort;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 权限
     */
    private String perms;
    /**
     * 子菜单
     */
    @TableField(exist = false)
    private List<SysMenu> children;
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/mapper/SysMenuMapper.java
New file
@@ -0,0 +1,21 @@
package com.mes.menu.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.mes.menu.entity.SysMenu;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * <p>
 * 菜单表 Mapper 接口
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Mapper
public interface SysMenuMapper extends MPJBaseMapper<SysMenu> {
    List<String> selectPermsByUserId(long parseLong);
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/service/SysMenuService.java
New file
@@ -0,0 +1,66 @@
package com.mes.menu.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.entity.request.GeneralRequest;
import com.mes.menu.entity.SysMenu;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 菜单表 服务类
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
public interface SysMenuService extends IService<SysMenu> {
    /**
     * 更新菜单信息
     *
     * @param menu
     * @return
     */
    SysMenu updateMenu(SysMenu menu);
    /**
     * 获取用户有权限的菜单树
     *
     * @return
     */
    List<SysMenu> getMenuTree(GeneralRequest request);
    /**
     * 获取用户的权限
     *
     * @return
     */
    List<String> getAuthorityInfo();
    /**
     * 获取用户菜单及权限信息
     *
     * @return
     */
    Map<Object, Object> nav();
    /**
     * 删除菜单信息
     *
     * @param menuId
     * @return
     */
    String deleteMenu(Long menuId);
    /**
     * 批量删除菜单信息
     *
     * @param menuIds
     * @return
     */
    String batchDeleteMenu(List<Long> menuIds);
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/menu/service/impl/SysMenuServiceImpl.java
New file
@@ -0,0 +1,148 @@
package com.mes.menu.service.impl;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.mes.common.utils.UserInfoUtils;
import com.mes.entity.request.GeneralRequest;
import com.mes.menu.entity.SysMenu;
import com.mes.menu.mapper.SysMenuMapper;
import com.mes.menu.service.SysMenuService;
import com.mes.role.entity.SysRoleMenu;
import com.mes.role.service.SysRoleMenuService;
import com.mes.userinfo.entity.SysUser;
import com.mes.userinfo.entity.SysUserRole;
import com.mes.userinfo.mapper.SysUserRoleMapper;
import com.mes.userinfo.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Service
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    SysRoleMenuService sysRoleMenuService;
    @Override
    public SysMenu updateMenu(SysMenu menu) {
        baseMapper.updateById(menu);
        // 清除所有与该菜单相关的权限缓存
        sysUserService.clearUserAuthorityInfoByMenuId(menu.getId());
        return menu;
    }
    @Override
    public List<SysMenu> getMenuTree(GeneralRequest request) {
        //todo:需要先获取用户的角色,角色下的菜单权限,拿到菜单id获取所有菜单
        SysUser user = UserInfoUtils.get();
        MPJLambdaWrapper<SysUserRole> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(SysMenu.class).distinct()
                .innerJoin(SysUser.class, SysUser::getId, SysUserRole::getUserId)
                .innerJoin(SysRoleMenu.class, SysRoleMenu::getRoleId, SysUserRole::getRoleId)
                .innerJoin(SysMenu.class, SysMenu::getId, SysRoleMenu::getMenuId)
                .eq(SysUser::getId, user.getId())
                .like(StringUtils.isNotBlank(request.getKey()), SysMenu::getMenuName, request.getKey());
        //
        List<SysMenu> menuList = sysUserRoleMapper.selectJoinList(SysMenu.class, wrapper);
        log.info("userinfos:{}",menuList);
        return create(menuList);
    }
    @Override
    public List<String> getAuthorityInfo() {
        SysUser user = UserInfoUtils.get();
        log.info("获取用户信息,用户名为{}", user);
        // 获取权限信息
        // ROLE_admin,ROLE_normal,sys:user:list,....
        return sysUserService.getUserAuthorityInfo(user.getId());
    }
    @Override
    public Map<Object, Object> nav() {
        List<SysMenu> menuTree = getMenuTree(new GeneralRequest());
        List<String> authorityInfo = getAuthorityInfo();
        return MapUtil.builder().put("authoritys", authorityInfo)
                .put("tree", menuTree).map();
    }
    @Override
    public String deleteMenu(Long menuId) {
        int count = this.count(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
        if (count > 0) {
            return "无法删除,请先删除子菜单";
        }
        // 清除所有与该菜单相关的权限缓存
        sysUserService.clearUserAuthorityInfoByMenuId(menuId);
        this.removeById(menuId);
        // 同步删除中间关联表
        sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getMenuId, menuId));
        return "删除成功";
    }
    @Override
    public String batchDeleteMenu(List<Long> menuIds) {
        menuIds.stream().forEach(e -> deleteMenu(e));
        return "批量删除成功";
    }
    /**
     * 将数据库中查询出来的list集合传入此方法即可获得排成树形结构的list集合
     *
     * @param lists
     * @return
     */
    public List<SysMenu> create(List<SysMenu> lists) {
        List<SysMenu> deptTreeList = lists.stream()
                .filter(item -> item.getParentId() == 0)
                .map(item -> {
                    item.setChildren(getChildren(item, lists));
                    return item;
                }).collect(Collectors.toList());
        return deptTreeList;
    }
    /**
     * 此方法将被递归调用
     *
     * @param menu
     * @param menus
     * @return
     */
    private List<SysMenu> getChildren(SysMenu menu, List<SysMenu> menus) {
        List<SysMenu> res = menus.stream()
                .filter(item -> item.getParentId().equals(menu.getId()))
                .collect(Collectors.toList());
        log.info("菜单树:{}", JSONUtil.toJsonStr(res));
        return res;
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/controller/SysRoleController.java
New file
@@ -0,0 +1,63 @@
package com.mes.role.controller;
import com.mes.entity.request.GeneralRequest;
import com.mes.role.entity.SysRole;
import com.mes.role.entity.vo.SysRoleVO;
import com.mes.role.service.SysRoleService;
import com.mes.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * @author zhoush
 * @since 2024-04-11
 */
@Api(description = "角色管理")
@RestController
@RequestMapping("/sys/role")
public class SysRoleController {
    @Autowired
    private SysRoleService sysRoleService;
    @ApiOperation("新增角色及角色下的权限信息")
    @PostMapping("/saveRole")
//    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result<SysRole> saveRole(@Validated @RequestBody SysRoleVO sysRoleVO) {
        return Result.success(sysRoleService.saveRole(sysRoleVO));
    }
    @ApiOperation("编辑角色及角色下的权限信息")
    @PostMapping("/updateRole")
//    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result<String> updateRole(@Validated @RequestBody SysRoleVO sysRoleVO) {
        return Result.success(sysRoleService.updateRole(sysRoleVO));
    }
    @ApiOperation("查询角色及角色下的权限信息")
    @PostMapping("/queryRole")
//    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result<List<SysRoleVO>> queryRole(@Validated @RequestBody GeneralRequest request) {
        return Result.success(sysRoleService.queryRole(request));
    }
    @ApiOperation("删除角色及角色下的权限信息")
    @PostMapping("/delete")
//    @PreAuthorize("hasAuthority('sys:role:delete')")
    @Transactional
    public Result<String> deleteRole(@RequestBody List<Long> ids) {
        return Result.success(sysRoleService.deleteRole(ids));
    }
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/entity/SysRole.java
New file
@@ -0,0 +1,50 @@
package com.mes.role.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
 * <p>
 * 角色表
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class SysRole implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    private String name;
    /**
     * 角色权限字符串
     */
    private String roleKey;
    /**
     * 角色状态(0正常 1停用)
     */
    private String status;
    /**
     * 删除标志
     */
    private Integer delFlag;
    /**
     * 备注
     */
    private String remark;
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/entity/SysRoleMenu.java
New file
@@ -0,0 +1,36 @@
package com.mes.role.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
 * <p>
 *
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Data
@EqualsAndHashCode(callSuper = false)
public class SysRoleMenu implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 角色ID
     */
    @TableId(type = IdType.NONE)
    private Long roleId;
    /**
     * 菜单id
     */
    private Long menuId;
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/entity/vo/SysRoleVO.java
New file
@@ -0,0 +1,44 @@
package com.mes.role.entity.vo;
import com.mes.menu.entity.SysMenu;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * @Author : zhoush
 * @Date: 2024/4/26 13:57
 * @Description:
 */
@Api(description = "角色信息")
@Data
public class SysRoleVO implements Serializable {
    @ApiModelProperty(hidden = true)
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "角色ID", position = 2)
    private Long id;
    @ApiModelProperty(value = "角色名称", position = 3)
    private String name;
    @ApiModelProperty(value = "角色权限字符串", position = 4)
    private String roleKey;
    @ApiModelProperty(value = "角色状态(0正常 1停用)", position = 5)
    private String status;
    @ApiModelProperty(value = "删除标志", position = 6)
    private Integer delFlag;
    @ApiModelProperty(value = "备注", position = 7)
    private String remark;
    @ApiModelProperty(value = "角色菜单信息", position = 8)
    private List<SysMenu> menuList;
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/SysRoleMapper.java
New file
@@ -0,0 +1,18 @@
package com.mes.role.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.mes.role.entity.SysRole;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * 角色表 Mapper 接口
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Mapper
public interface SysRoleMapper extends MPJBaseMapper<SysRole> {
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/SysRoleMenuMapper.java
New file
@@ -0,0 +1,18 @@
package com.mes.role.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mes.role.entity.SysRoleMenu;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * Mapper 接口
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Mapper
public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenu> {
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/xml/SysRoleMapper.xml
New file
@@ -0,0 +1,5 @@
<?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="com.mes.role.mapper.SysRoleMapper">
</mapper>
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/mapper/xml/SysRoleMenuMapper.xml
New file
@@ -0,0 +1,5 @@
<?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="com.mes.role.mapper.SysRoleMenuMapper">
</mapper>
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/SysRoleMenuService.java
New file
@@ -0,0 +1,16 @@
package com.mes.role.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.role.entity.SysRoleMenu;
/**
 * <p>
 * 服务类
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
public interface SysRoleMenuService extends IService<SysRoleMenu> {
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/SysRoleService.java
New file
@@ -0,0 +1,51 @@
package com.mes.role.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mes.entity.request.GeneralRequest;
import com.mes.role.entity.SysRole;
import com.mes.role.entity.vo.SysRoleVO;
import java.util.List;
/**
 * <p>
 * 角色表 服务类
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
public interface SysRoleService extends IService<SysRole> {
    /**
     * 创建角色信息
     *
     * @param sysRoleVO
     * @return
     */
    SysRole saveRole(SysRoleVO sysRoleVO);
    /**
     * 修改角色信息及权限
     *
     * @param sysRoleVO
     * @return
     */
    String updateRole(SysRoleVO sysRoleVO);
    /**
     * 按照角色名查询角色信息
     *
     * @param request
     * @return
     */
    List<SysRoleVO> queryRole(GeneralRequest request);
    /**
     * 查询角色及角色下的权限信息
     *
     * @param ids
     * @return
     */
    String deleteRole(List<Long> ids);
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/impl/SysRoleMenuServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.mes.role.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.role.entity.SysRoleMenu;
import com.mes.role.mapper.SysRoleMenuMapper;
import com.mes.role.service.SysRoleMenuService;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Service
public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRoleMenu> implements SysRoleMenuService {
}
hangzhoumesParent/common/springsecurity/src/main/java/com/mes/role/service/impl/SysRoleServiceImpl.java
New file
@@ -0,0 +1,123 @@
package com.mes.role.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.mes.entity.request.GeneralRequest;
import com.mes.menu.entity.SysMenu;
import com.mes.role.entity.SysRole;
import com.mes.role.entity.SysRoleMenu;
import com.mes.role.entity.vo.SysRoleVO;
import com.mes.role.mapper.SysRoleMapper;
import com.mes.role.service.SysRoleMenuService;
import com.mes.role.service.SysRoleService;
import com.mes.userinfo.entity.SysUserRole;
import com.mes.userinfo.service.SysUserRoleService;
import com.mes.userinfo.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author zhoush
 * @since 2024-04-11
 */
@Service
@Slf4j
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    @Autowired
    SysRoleMenuService sysRoleMenuService;
    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysUserRoleService sysUserRoleService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysRole saveRole(SysRoleVO sysRoleVO) {
        log.info("保存角色信息,生成对应的角色id");
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleVO, sysRole);
        this.save(sysRole);
        //保存角色权限信息
        saveRoleMenu(sysRole.getId(), sysRoleVO.getMenuList());
        return sysRole;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateRole(SysRoleVO sysRoleVO) {
        log.info("保存角色信息,生成对应的角色id");
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleVO, sysRole);
        this.updateById(sysRole);
        //保存角色权限信息
        return saveRoleMenu(sysRole.getId(), sysRoleVO.getMenuList());
    }
    @Override
    public List<SysRoleVO> queryRole(GeneralRequest request) {
        MPJLambdaWrapper<SysRole> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(SysRole.class)
                .selectCollection(SysMenu.class, SysRoleVO::getMenuList)
                .leftJoin(SysRoleMenu.class, SysRoleMenu::getRoleId, SysRole::getId)
                .leftJoin(SysMenu.class, SysMenu::getId, SysRoleMenu::getMenuId)
                .like(StringUtils.hasText(request.getKey()), SysRole::getName, request.getKey());
        return baseMapper.selectJoinList(SysRoleVO.class, wrapper);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String deleteRole(List<Long> ids) {
        log.info("删除角色信息");
        this.removeByIds(ids);
        log.info("删除中间表信息");
        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getRoleId, ids));
        sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, ids));
        log.info("清空缓存中的权限信息");
        ids.stream().forEach(id -> sysUserService.clearUserAuthorityInfoByRoleId(id));
        return "success";
    }
    /**
     * 保存角色权限信息
     *
     * @param roleId
     * @param menuList
     * @return
     */
    private String saveRoleMenu(Long roleId, List<SysMenu> menuList) {
        log.info("配置角色菜单关心");
        List<SysRoleMenu> roleMenuList = menuList.stream().map(menu -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menu.getId());
            return roleMenu;
        }).collect(Collectors.toList());
        log.info("清空角色权限表中该角色信息");
        // 先删除原来的记录,再保存新的
        sysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
        sysRoleMenuService.saveBatch(roleMenuList);
        // 删除缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        return "success";
    }
}