This commit is contained in:
liulu 2024-10-28 09:55:21 +08:00
parent 4c0524415c
commit e59811ced4
200 changed files with 18322 additions and 0 deletions

26
.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
.idea/
target/
maven
*.bak
*.iml
*.log
/logs
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
.DS_Store
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*node_modules

44
chsm-common/pom.xml Normal file
View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sunyard.chsm</groupId>
<artifactId>chsm</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>chsm-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,35 @@
package com.sunyard.utils;
/**
* @author liulu
* @version V1.0
* @since 2022/12/6
*/
public abstract class DateFormatPattern {
public static final String YYYY = "yyyy";
public static final String YYYYMMDD = "yyyyMMdd";
public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static final String YYYYIMMIDD = "yyyy/MM/dd";
public static final String YYYYMMDDHHMM = "yyyyMMddHHmm";
public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static final String YYYYMMDD_HHMMSS = "yyyyMMdd HHmmss";
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
public static final String YYYYMMDDHHMMSS_SS = "yyyyMMddHHmmssSSS";
public static final String HHMMSS_TIME_FORMAT = "HHmmss";
public static final String YYYY_MM_DD_T_HH_MM_SS_Z = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public static final String YYYY_MM_DD_HH24_MM_SS = "yyyy-MM-d hh24:mm:ss";
public static final String HH_MM = "HH:mm";
public static final String HHMM = "HHmm";
public static final String HH_MM_SS = "HH:mm:ss";
public static final String ZERO_HH_MM_SS = " 00:00:00";
public static final String YYMMDD = "yyMMdd";
public static final String YYYY_CN_MM_CN_DD_CN = "yyyy年 MM 月 dd 日";
public static final String MM_CN_DD_CN = "MM 月 dd 日";
public static final String BEGIN_OF_DAY = "yyyy-MM-dd 00:00:00";
public static final String END_OF_DAY = "yyyy-MM-dd 23:59:59";
public static final String YYYYIMMIDDHHMMSS = "yyyy/MM/dd HH:mm:ss";
}

View File

@ -0,0 +1,97 @@
package com.sunyard.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @author liulu
* @version V1.0
* @since 2020/11/25
*/
public abstract class JsonUtils {
private JsonUtils() {
}
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
static {
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DateFormatPattern.HH_MM_SS)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD)));
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD_HH_MM_SS)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DateFormatPattern.HH_MM_SS)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD)));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD_HH_MM_SS)));
OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
OBJECT_MAPPER.registerModules(javaTimeModule);
}
public static ObjectMapper objectMapper() {
return OBJECT_MAPPER;
}
public static String toJsonString(Object obj) {
try {
return OBJECT_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
//
throw new IllegalArgumentException(e);
}
}
public static byte[] toJsonBytes(Object obj) {
try {
return OBJECT_MAPPER.writeValueAsBytes(obj);
} catch (JsonProcessingException e) {
//
throw new IllegalArgumentException(e);
}
}
public static <T> T parse(String jsonStr, Class<T> type) {
if (jsonStr == null || jsonStr.isEmpty()) {
return null;
}
try {
return OBJECT_MAPPER.readValue(jsonStr, type);
} catch (JsonProcessingException e) {
//
throw new IllegalArgumentException("json格式错误");
}
}
public static <T> T parse(byte[] json, Class<T> type) {
if (json == null || json.length == 0) {
return null;
}
try {
return OBJECT_MAPPER.readValue(json, type);
} catch (IOException e) {
//
throw new IllegalArgumentException("json格式错误");
}
}
}

View File

@ -0,0 +1,41 @@
package com.sunyard.utils;
/**
* @author liulu
* @version V1.0
* @since 2020/11/16
*/
public abstract class ThrowableUtils {
private ThrowableUtils() {
}
public static String buildErrorMessage(Throwable ex) {
StringBuilder sb = new StringBuilder();
sb.append(ex.getMessage());
StackTraceElement[] stackTrace = ex.getStackTrace();
int i = 0;
for (StackTraceElement stackTraceElement : stackTrace) {
if (i++ >= 5) {
break;
}
sb.append("\n\t").append(stackTraceElement.toString());
}
return sb.toString();
}
public static <T extends Exception> T findException(Class<T> exClass, Throwable ex) {
for (int i = 0; ex != null && i < 3; i++) {
if (exClass.isAssignableFrom(ex.getClass())) {
//noinspection unchecked
return (T) ex;
}
ex = ex.getCause();
}
return null;
}
}

20
chsm-model/pom.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sunyard.chsm</groupId>
<artifactId>chsm</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>chsm-model</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

144
chsm-web-manage/pom.xml Normal file
View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sunyard.chsm</groupId>
<artifactId>chsm</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>chsm-web-manage</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<!-- 排除lettuce包 -->
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加jedis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.sunyard.chsm</groupId>
<artifactId>chsm-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<!-- <version>${bouncycastle.version}</version>-->
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<!-- <version>${bouncycastle.version}</version>-->
</dependency>
<dependency>
<groupId>com.dm</groupId>
<artifactId>DmJdbcDriver</artifactId>
<version>1.8</version>
</dependency>
<!-- sunyard -->
<dependency>
<groupId>com.sunyard</groupId>
<artifactId>ssp.javasdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sunyard</groupId>
<artifactId>sdf1418</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sunyard</groupId>
<artifactId>sydapi4j</artifactId>
<version>1.13.20221010</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>groovy-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 工具包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<!--动态库调用依赖-->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.13</version>
</dependency>
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.17.3</version>
</dependency>
<!-- Gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.sunyard;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author liulu
* @since 2024/10/25
*/
@SpringBootApplication
//@ComponentScan(basePackages={"com.sunyard"})
@EnableScheduling
@EnableAsync
public class WebManageApp {
public static void main(String[] args) {
SpringApplication.run(WebManageApp.class, args);
}
}

View File

@ -0,0 +1,37 @@
package com.sunyard.config;
import org.springframework.stereotype.Component;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author:tsz
* @date:2020/3/9
* @description: 跨域问题
*/
@Component
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
// response.setHeader("Access-Control-Allow-Origin",reqs.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, HEAD, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("access-control-allow-headers", "Content-Type,Accept,Authorization,accesstoken");
if (((HttpServletRequest) req).getMethod().equals("OPTIONS")) {
response.setStatus(200);
return;
}
chain.doFilter(req, res);
}
}

View File

@ -0,0 +1,66 @@
package com.sunyard.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.sunyard.utils.DateFormatPattern;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @author liulu
* @since 2024/10/25
*/
@Configuration
@MapperScan("com.sunyard.ssp.**.mapper")
public class WebConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 如果配置多个插件, 切记分页最后添加
// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.DM));
return interceptor;
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer objectMapperBuilderCustomizer() {
return builder -> {
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DateFormatPattern.HH_MM_SS)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD)));
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD_HH_MM_SS)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DateFormatPattern.HH_MM_SS)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD)));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateFormatPattern.YYYY_MM_DD_HH_MM_SS)));
builder.modules(javaTimeModule);
builder.serializerByType(Long.class, ToStringSerializer.instance);
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
builder.failOnUnknownProperties(false);
};
}
}

View File

@ -0,0 +1,25 @@
package com.sunyard.config.security;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author Exrickx
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "captcha")
public class CaptchaProperties {
private List<String> image = new ArrayList<>();
private List<String> sms = new ArrayList<>();
private List<String> vaptcha = new ArrayList<>();
private List<String> email = new ArrayList<>();
}

View File

@ -0,0 +1,19 @@
package com.sunyard.config.security;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author Exrickx
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "ignored")
public class IgnoredUrlsProperties {
private List<String> urls = new ArrayList<>();
}

View File

@ -0,0 +1,66 @@
package com.sunyard.config.security;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.utils.sm3.SM3Digest;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
/**
* @Auther: wp
* @Date: 2021/12/16 10:47
* @Description:
*/
public class SM3PasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
String salt = RandomUtil.randomString(CommonConstant.SALT_NUMBER);
String encode = SM3Digest.encode(salt + rawPassword.toString());
return new StringBuilder().append(encode).append("@").append(salt).toString();
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if(StrUtil.isBlank(encodedPassword)){
return false;
}
//先从encodedPassword提取salt
String salt = encodedPassword.split("@")[1];
String encode = SM3Digest.encode(salt + rawPassword.toString());
String origin = new StringBuilder().append(encode).append("@").append(salt).toString();
return MessageDigest.isEqual(origin.getBytes(StandardCharsets.UTF_8), encodedPassword.getBytes(StandardCharsets.UTF_8));
}
@Override
public boolean upgradeEncoding(String encodedPassword) {
return false;
}
// public static void main(String[] args) {
//// String rawPassword="wp123456.";
//// String encode1 = SM3Digest.encode(rawPassword);
//// System.out.println(encode1);
//// String salt = RandomUtil.randomString(CommonConstant.SALT_NUMBER);
//// String encode = SM3Digest.encode(salt + encode1);
//// String s = new StringBuilder().append(encode).append("@").append(salt).toString();
//// System.out.println(s);
//
// String encodedPassword="00513D5AC7477E6E8FD33A2A6EAAB2F6C04B260DA91E7E6648E8472E914939EB@2sszbadwg5";
// //AE2B659E60E130E47D18F95387B599E7C261275902020F1D942BD69C2840F28F@tpgb0tfqxc
// //先从encodedPassword提取salt
// String salt = encodedPassword.split("@")[1];
// String rawPassword="3160FD1B6DAEA5A455C7F6C2DC48BEA3A2B9DA73270960791FDBFD60B57A95EA";
// String encode = SM3Digest.encode(salt + rawPassword.toString());
// String origin = new StringBuilder().append(encode).append("@").append(salt).toString();
//
// boolean equal = MessageDigest.isEqual(origin.getBytes(StandardCharsets.UTF_8), encodedPassword.getBytes(StandardCharsets.UTF_8));
// System.out.println(equal);
// }
}

View File

@ -0,0 +1,98 @@
package com.sunyard.config.security;
import cn.hutool.core.util.StrUtil;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.modules.user.entity.ScPermission;
import com.sunyard.ssp.modules.user.entity.ScUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Exrickx
*/
@Slf4j
public class SecurityUserDetails extends ScUser implements UserDetails {
private static final long serialVersionUID = 1L;
public SecurityUserDetails(ScUser user) {
if(user!=null) {
this.setUsername(user.getUsername());
this.setPassword(user.getPassword());
this.setStatus(user.getStatus()==null?0:user.getStatus());
this.setRoles(user.getRoles());
this.setPermissions(user.getPermissions());
}
}
/**
* 添加用户拥有的权限和角色
* @return
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorityList = new ArrayList<>();
List<ScPermission> permissions = this.getPermissions();
// 添加请求权限
if(permissions!=null&&permissions.size()>0){
for (ScPermission permission : permissions) {
if(CommonConstant.PERMISSION_OPERATION.equals(permission.getPType())
&&StrUtil.isNotBlank(permission.getTitle())
&&StrUtil.isNotBlank(permission.getPath())) {
authorityList.add(new SimpleGrantedAuthority(permission.getTitle()));
}
}
}
return authorityList;
}
/**
* 账户是否过期
* @return
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 是否禁用
* @return
*/
@Override
public boolean isAccountNonLocked() {
return CommonConstant.USER_STATUS_LOCK.equals(this.getStatus()) ? false : true;
}
/**
* 密码是否过期
* @return
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 是否启用
* @return
*/
@Override
public boolean isEnabled() {
return CommonConstant.USER_STATUS_NORMAL.equals(this.getStatus()) ? true : false;
}
}

View File

@ -0,0 +1,76 @@
package com.sunyard.config.security;
import cn.hutool.core.util.StrUtil;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.common.exception.LoginFailLimitException;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.service.IScPermissionService;
import com.sunyard.ssp.modules.user.service.IScUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
/**
* @author Exrickx
*/
@Slf4j
@Component
public class UserDetailsServiceImpl implements UserDetailsService{
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private IScUserService userService;
@Autowired
private IScPermissionService permissionService;
@Value("${ssp.passMaxDays}")
private Integer passMaxDays;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
long begin = System.currentTimeMillis();
String flagKey = "loginFailFlag:" + username;
String value = redisTemplate.opsForValue().get(flagKey);
if(StrUtil.isBlank(username)){
return new SecurityUserDetails(null);
}
//通过用户名登陆
ScUser user = userService.findByUsername(username);
if(user == null){
return new SecurityUserDetails(null);
}
//admin特殊处理
if(CommonConstant.DEFAULT_USER_ROOT_ID.equals(user.getId())){
Long timeRest = redisTemplate.getExpire(flagKey, TimeUnit.SECONDS);
Double minutes = Math.ceil(Double.valueOf(timeRest)/60);
if(StrUtil.isNotBlank(value)){
//超过限制次数
throw new LoginFailLimitException("登录错误次数超过限制,请"+minutes.intValue()+"分钟后再试");
}
return new SecurityUserDetails(user);
}
//密码过期日
LocalDateTime passLimitDate = LocalDateTime.now().minusDays(passMaxDays);
if(passLimitDate.isAfter(user.getPassUpdateTime())){
throw new LoginFailLimitException("密码已过期,请联系管理员修改后重试");
}
return new SecurityUserDetails(user);
}
}

View File

@ -0,0 +1,119 @@
package com.sunyard.config.security;
import com.sunyard.config.security.jwt.AuthenticationFailHandler;
import com.sunyard.config.security.jwt.AuthenticationSuccessHandler;
import com.sunyard.config.security.jwt.JWTAuthenticationFilter;
import com.sunyard.config.security.jwt.RestAccessDeniedHandler;
import com.sunyard.config.security.permission.MyFilterSecurityInterceptor;
import com.sunyard.config.security.validate.ImageValidateFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* Security 核心配置类
* 开启注解控制权限至Controller
* @author Exrickx
*/
@Slf4j
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${ssp.token.redis}")
private Boolean tokenRedis;
@Value("${ssp.tokenExpireTime}")
private Integer tokenExpireTime;
@Autowired
private IgnoredUrlsProperties ignoredUrlsProperties;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private AuthenticationSuccessHandler successHandler;
@Autowired
private AuthenticationFailHandler failHandler;
@Autowired
private RestAccessDeniedHandler accessDeniedHandler;
@Autowired
private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private ImageValidateFilter imageValidateFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.authorizeRequests();
//除配置文件忽略路径其它所有请求都需经过认证和授权
for(String url:ignoredUrlsProperties.getUrls()){
registry.antMatchers(url).permitAll();
}
registry.and()
//表单登录方式
.formLogin()
.loginPage("/needLogin")
//登录请求url
.loginProcessingUrl("/login")
.permitAll()
//成功处理类
.successHandler(successHandler)
//失败
.failureHandler(failHandler)
.and()
//允许网页iframe
.headers().frameOptions().disable()
.and()
.logout()
.permitAll()
.and()
.authorizeRequests()
//任何请求
.anyRequest()
//需要身份认证
.authenticated()
.and()
//关闭跨站请求防护
.csrf().disable()
//前后端分离采用JWT 不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//自定义权限拒绝处理类
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.and()
// 图形验证码过滤器
.addFilterBefore(imageValidateFilter, UsernamePasswordAuthenticationFilter.class)
//添加自定义权限过滤器
.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class)
//添加JWT过滤器 除已配置的其它请求都需经过此过滤器
.addFilter(new JWTAuthenticationFilter(authenticationManager(), tokenRedis, tokenExpireTime, redisTemplate));
}
}

View File

@ -0,0 +1,114 @@
package com.sunyard.config.security.jwt;
import cn.hutool.core.util.StrUtil;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.common.exception.LoginFailLimitException;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* @author Exrickx
*/
@Slf4j
@Component
public class AuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {
@Value("${ssp.loginTimeLimit}")
private Integer loginTimeLimit;
@Value("${ssp.loginAfterTime}")
private Integer loginAfterTime;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private IScUserService userService;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
String username = request.getParameter("username");
if (e instanceof UsernameNotFoundException || e instanceof BadCredentialsException) {
recordLoginTime(username);
String key = "loginTimeLimit:" + username;
String value = redisTemplate.opsForValue().get(key);
if (StrUtil.isBlank(value)) {
value = "0";
}
//获取已登录错误次数
int loginFailTime = Integer.parseInt(value);
int restLoginTime = loginTimeLimit - loginFailTime;
log.info("用户" + username + "登录失败,还有" + restLoginTime + "次机会");
if (restLoginTime <= 3 && restLoginTime > 0) {
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "用户名或密码错误,还有" + restLoginTime + "次尝试机会"));
} else if (restLoginTime <= 0) {
ScUser user = userService.findByUsername(username);
if (user != null && !CommonConstant.DEFAULT_USER_ROOT_ID.equals(user.getId())) {
user.setStatus(CommonConstant.USER_STATUS_LOCK);
userService.updateById(user);
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "登录错误次数超过限制,用户已被锁定,请联系管理员解锁后重试"));
} else {
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "登录错误次数超过限制,请" + loginAfterTime + "分钟后再试"));
}
} else {
ResponseUtil.out(response, ResponseUtil.resultMap(false, 500, "用户名或密码错误"));
}
} else if (e instanceof DisabledException){
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"用户不存在"));
} else if (e instanceof LockedException) {
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"用户被禁用,请联系管理员"));
} else if (e instanceof LoginFailLimitException){
ScUser user = userService.findByUsername(username);
if (user != null && !CommonConstant.DEFAULT_USER_ROOT_ID.equals(user.getId())) {
user.setStatus(CommonConstant.USER_STATUS_LOCK);
userService.updateById(user);
}
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,((LoginFailLimitException) e).getMsg()));
} else {
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"登录失败,其他内部错误"));
}
}
/**
* 判断用户登陆错误次数
*/
public boolean recordLoginTime(String username){
String key = "loginTimeLimit:"+username;
String flagKey = "loginFailFlag:"+username;
String value = redisTemplate.opsForValue().get(key);
if(StrUtil.isBlank(value)){
value = "0";
}
//获取已登录错误次数
int loginFailTime = Integer.parseInt(value) + 1;
redisTemplate.opsForValue().set(key, String.valueOf(loginFailTime), loginAfterTime, TimeUnit.MINUTES);
if(loginFailTime>=loginTimeLimit){
redisTemplate.opsForValue().set(flagKey, "fail", loginAfterTime, TimeUnit.MINUTES);
return false;
}
return true;
}
}

View File

@ -0,0 +1,144 @@
package com.sunyard.config.security.jwt;
import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.sunyard.ssp.common.constant.SecurityConstant;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.utils.ResponseUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import com.sunyard.ssp.vo.TokenUser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* 登录成功处理类
* @author Exrickx
*/
@Slf4j
@Component
public class AuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Value("${ssp.token.redis}")
private Boolean tokenRedis;
@Value("${ssp.tokenExpireTime}")
private Integer tokenExpireTime;
@Value("${ssp.saveLoginTime}")
private Integer saveLoginTime;
@Value("${ssp.passMaxDays}")
private Integer passMaxDays;
@Value("${ssp.passWarnAge}")
private Integer passWarnAge;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private IScUserService scUserService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
long beginTime = System.currentTimeMillis();
//用户选择保存登录状态几天
String saveLogin = request.getParameter(SecurityConstant.SAVE_LOGIN);
Boolean saved = false;
String msg = "登录成功";
if(StrUtil.isNotBlank(saveLogin) && Boolean.valueOf(saveLogin)){
saved = true;
if(!tokenRedis){
tokenExpireTime = saveLoginTime * 60 * 24;
}
}
String username = ((UserDetails)authentication.getPrincipal()).getUsername();
System.out.println("loginSuccess username:" + username + "begin:" + (beginTime - System.currentTimeMillis()));
List<GrantedAuthority> authorities = (List<GrantedAuthority>) ((UserDetails)authentication.getPrincipal()).getAuthorities();
List<String> list = new ArrayList<>();
for(GrantedAuthority g : authorities){
list.add(g.getAuthority());
}
System.out.println("loginSuccess username:" + username + "getCurrUser begin:" + (beginTime - System.currentTimeMillis()));
ScUser scuser = securityUtil.getCurrUser();
//ipInfoUtil.getUrl(request);
System.out.println("loginSuccess username:" + username + "getCurrUser end:" + (beginTime - System.currentTimeMillis()));
// 登陆成功生成token
String token;
if(tokenRedis){
// redis
token = UUID.randomUUID().toString().replace("-", "");
TokenUser user = new TokenUser(username, list, saved);
// 单点登录 之前的token失效
String oldToken = redisTemplate.opsForValue().get(SecurityConstant.USER_TOKEN + username);
if(StrUtil.isNotBlank(oldToken)){
redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
}
//清空失败次数
String key = "loginTimeLimit:" + username;
redisTemplate.delete(key);
if(saved){
redisTemplate.opsForValue().set(SecurityConstant.USER_TOKEN + username, token, saveLoginTime, TimeUnit.DAYS);
redisTemplate.opsForValue().set(SecurityConstant.TOKEN_PRE + token, new Gson().toJson(user), saveLoginTime, TimeUnit.DAYS);
}else{
redisTemplate.opsForValue().set(SecurityConstant.USER_TOKEN + username, token, tokenExpireTime, TimeUnit.MINUTES);
redisTemplate.opsForValue().set(SecurityConstant.TOKEN_PRE + token, new Gson().toJson(user), tokenExpireTime, TimeUnit.MINUTES);
}
}else{
// jwt
token = SecurityConstant.TOKEN_SPLIT + Jwts.builder()
//主题 放入用户名
.setSubject(username)
//自定义属性 放入用户拥有请求权限
.claim(SecurityConstant.AUTHORITIES, new Gson().toJson(list))
//失效时间
.setExpiration(new Date(System.currentTimeMillis() + tokenExpireTime * 60 * 1000))
//签名算法和密钥
.signWith(SignatureAlgorithm.HS512, SecurityConstant.JWT_SIGN_KEY)
.compact();
}
LocalDateTime limitDate = scuser.getPassUpdateTime().plusDays(passMaxDays);
DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
if(limitDate.isBefore(LocalDateTime.now().plusDays(passWarnAge))){
msg = "密码将于" + sdf.format(limitDate) + "过期,请及时修改";
}
/*sunyard*/
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, HEAD, DELETE");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("access-control-allow-headers", "Content-Type,Accept,Authorization,accesstoken");
/*sunyard end*/
System.out.println("loginSuccess username:" + username + "end:" + (beginTime - System.currentTimeMillis()));
ResponseUtil.out(response, ResponseUtil.resultMap(true,200,msg, token));
}
}

View File

@ -0,0 +1,163 @@
package com.sunyard.config.security.jwt;
import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sunyard.ssp.common.constant.SecurityConstant;
import com.sunyard.ssp.utils.ResponseUtil;
import com.sunyard.ssp.vo.TokenUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
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.security.core.userdetails.User;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author Exrickx
*/
@Slf4j
public class JWTAuthenticationFilter extends BasicAuthenticationFilter {
private Boolean tokenRedis;
private Integer tokenExpireTime;
private StringRedisTemplate redisTemplate;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager, Boolean tokenRedis, Integer tokenExpireTime, StringRedisTemplate redisTemplate) {
super(authenticationManager);
this.tokenRedis = tokenRedis;
this.tokenExpireTime = tokenExpireTime;
this.redisTemplate = redisTemplate;
}
public JWTAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) {
super(authenticationManager, authenticationEntryPoint);
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
/*sunyard*/
String method = request.getMethod();
System.out.println( method );
System.out.println( request.getRequestURI() );
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, HEAD, DELETE");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("access-control-allow-headers", "Content-Type,Accept,Authorization,accesstoken,auth-token");
if ("options".equalsIgnoreCase(method)){
response.setStatus(200);
return;
}
/*sunyard end*/
String header = request.getHeader(SecurityConstant.HEADER);
if(StrUtil.isBlank(header)){
header = request.getParameter(SecurityConstant.HEADER);
}
if(StrUtil.isBlank(header) && request.getCookies()!=null){
Cookie cookie = Arrays.stream(request.getCookies()).filter(tmpCookie -> SecurityConstant.HEADER.equals(tmpCookie.getName())).findAny().orElse(null);
header = cookie == null?null: cookie.getValue();
}
Boolean notValid = StrUtil.isBlank(header) || (!tokenRedis && !header.startsWith(SecurityConstant.TOKEN_SPLIT));
if (notValid) {
chain.doFilter(request, response);
return;
}
try {
UsernamePasswordAuthenticationToken authentication = getAuthentication(header, response, request);
SecurityContextHolder.getContext().setAuthentication(authentication);
}catch (Exception e){
e.toString();
}
chain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthentication(String header, HttpServletResponse response, HttpServletRequest request) {
// 用户名
String username = null;
// 权限
List<GrantedAuthority> authorities = new ArrayList<>();
if(tokenRedis){
// redis
String v = redisTemplate.opsForValue().get(SecurityConstant.TOKEN_PRE + header);
if(StrUtil.isBlank(v)){
ResponseUtil.out(response, ResponseUtil.resultMap(false,401,"登录已失效,请重新登录"));
return null;
}
TokenUser user = new Gson().fromJson(v, TokenUser.class);
username = user.getUsername();
for(String ga : user.getPermissions()){
authorities.add(new SimpleGrantedAuthority(ga));
}
if(!user.getSaveLogin()){
// 若未保存登录状态重新设置失效时间
redisTemplate.opsForValue().set(SecurityConstant.USER_TOKEN + username, header, tokenExpireTime, TimeUnit.MINUTES);
redisTemplate.opsForValue().set(SecurityConstant.TOKEN_PRE + header, v, tokenExpireTime, TimeUnit.MINUTES);
}
}else{
// JWT
try {
// 解析token
Claims claims = Jwts.parser()
.setSigningKey(SecurityConstant.JWT_SIGN_KEY)
.parseClaimsJws(header.replace(SecurityConstant.TOKEN_SPLIT, ""))
.getBody();
//获取用户名
username = claims.getSubject();
//获取权限
String authority = claims.get(SecurityConstant.AUTHORITIES).toString();
if(StrUtil.isNotBlank(authority)){
List<String> list = new Gson().fromJson(authority, new TypeToken<List<String>>(){}.getType());
for(String ga : list){
authorities.add(new SimpleGrantedAuthority(ga));
}
}
} catch (ExpiredJwtException e) {
ResponseUtil.out(response, ResponseUtil.resultMap(false,401,"登录已失效,请重新登录"));
} catch (Exception e){
log.error(e.toString());
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"解析token错误"));
}
}
if(StrUtil.isNotBlank(username)) {
//Exrick踩坑提醒 此处password不能为null
User principal = new User(username, "", authorities);
return new UsernamePasswordAuthenticationToken(principal, null, authorities);
}
return null;
}
}

View File

@ -0,0 +1,29 @@
package com.sunyard.config.security.jwt;
import com.sunyard.ssp.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Exrickx
*/
@Component
@Slf4j
public class RestAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
throws IOException, ServletException {
ResponseUtil.out(response,ResponseUtil.resultMap(false,403,"抱歉,您没有访问权限"));
}
}

View File

@ -0,0 +1,54 @@
package com.sunyard.config.security.permission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Iterator;
/**
* 权限管理决断器
* 判断用户拥有的权限或角色是否有资源访问权限
* @author Exrickx
*/
@Slf4j
@Component
public class MyAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
if(configAttributes==null){
return;
}
Iterator<ConfigAttribute> iterator = configAttributes.iterator();
while (iterator.hasNext()){
ConfigAttribute c = iterator.next();
String needPerm = c.getAttribute();
for(GrantedAuthority ga : authentication.getAuthorities()) {
// 匹配用户拥有的ga 系统中的needPerm
if(needPerm.trim().equals(ga.getAuthority())) {
return;
}
}
}
throw new AccessDeniedException("抱歉,您没有访问权限");
}
@Override
public boolean supports(ConfigAttribute configAttribute) {
return true;
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}

View File

@ -0,0 +1,73 @@
package com.sunyard.config.security.permission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* 权限管理过滤器
* 监控用户行为
* @author Exrickx
*/
@Slf4j
@Component
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
@Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
@Override
public void destroy() {
}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
}

View File

@ -0,0 +1,44 @@
package com.sunyard.config.security.permission;
import java.util.Objects;
public class MyRequestVo {
private String url;
private String method;
public MyRequestVo(String url, String method) {
this.url = url;
this.method = method;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyRequestVo that = (MyRequestVo) o;
return Objects.equals(url, that.url) &&
Objects.equals(method, that.method);
}
@Override
public int hashCode() {
return Objects.hash(url, method);
}
}

View File

@ -0,0 +1,121 @@
package com.sunyard.config.security.permission;
import cn.hutool.core.util.StrUtil;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.modules.user.entity.ScPermission;
import com.sunyard.ssp.modules.user.service.IScPermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* 权限资源管理器
* 为权限决断器提供支持
* @author Exrickx
*/
@Slf4j
@Component
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
@Autowired
private IScPermissionService permissionService;
private Map<String, Collection<ConfigAttribute>> map = null;
private Map<String, Boolean> needVerifyMap = null;
/**
*
*/
public void loadResourceDefine(){
map = new HashMap<>(16);
needVerifyMap = new HashMap<>(16);
Collection<ConfigAttribute> configAttributes;
ConfigAttribute cfg;
// 获取启用的权限操作请求
List<ScPermission> permissions = permissionService.findByTypeAndStatusOrderBySortOrder(CommonConstant.PERMISSION_OPERATION, CommonConstant.STATUS_NORMAL);
for(ScPermission permission : permissions) {
if(StrUtil.isNotBlank(permission.getTitle())&&StrUtil.isNotBlank(permission.getPath())){
configAttributes = new ArrayList<>();
cfg = new SecurityConfig(permission.getTitle());
//作为MyAccessDecisionManager类的decide的第三个参数
configAttributes.add(cfg);
//用权限的path作为map的key用ConfigAttribute的集合作为value
map.put(permission.getPath(), configAttributes);
needVerifyMap.put(permission.getPath(), permission.getNeedVerify());
}
}
}
public boolean needVerify(String url){
if(map == null){
loadResourceDefine();
}
PathMatcher pathMatcher = new AntPathMatcher();
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String path = iterator.next();
if (path != null &&
StrUtil.isNotBlank(path) &&
pathMatcher.match(path,url)) {
return needVerifyMap.get(path);
}
}
return false;
}
/**
* 判定用户请求的url是否在权限表中
* 如果在权限表中则返回给decide方法用来判定用户是否有此权限
* 如果不在权限表中则放行
* @param o
* @return
* @throws IllegalArgumentException
*/
@Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
if(map == null){
loadResourceDefine();
}
//Object中包含用户请求request
String url = ((FilterInvocation) o).getRequestUrl();
PathMatcher pathMatcher = new AntPathMatcher();
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String path = iterator.next();
if (path != null &&
StrUtil.isNotBlank(path) &&
pathMatcher.match(path,url) ) {
return map.get(path);
}
}
return null;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class<?> aClass) {
return true;
}
}

View File

@ -0,0 +1,83 @@
package com.sunyard.config.security.validate;
import cn.hutool.core.util.StrUtil;
import com.sunyard.config.security.CaptchaProperties;
import com.sunyard.ssp.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 图形验证码过滤器
* @author Exrick
*/
@Slf4j
@Configuration
public class ImageValidateFilter extends OncePerRequestFilter {
@Autowired
private CaptchaProperties captchaProperties;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private PathMatcher pathMatcher;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// 判断URL是否需要验证
Boolean flag = false;
String requestUrl = request.getRequestURI();
for(String url : captchaProperties.getImage()){
if(pathMatcher.match(url, requestUrl)){
flag = true;
break;
}
}
if(flag){
//todo 假u盾登录无需验证码
String sn = request.getParameter("sn");
if(StringUtils.isNotBlank(sn)){
chain.doFilter(request, response);
return;
}
String captchaId = request.getParameter("captchaId");
String code = request.getParameter("code");
if(StrUtil.isBlank(captchaId)||StrUtil.isBlank(code)){
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"请传入图形验证码所需参数captchaId或code"));
return;
}
String redisCode = redisTemplate.opsForValue().get(captchaId);
if(StrUtil.isBlank(redisCode)){
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"验证码已过期,请重新获取"));
return;
}
if(!redisCode.toLowerCase().equals(code.toLowerCase())) {
log.info("验证码错误code:"+ code +"redisCode:"+redisCode);
ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"图形验证码输入错误"));
return;
}
// 已验证清除key
redisTemplate.delete(captchaId);
// 验证成功 放行
chain.doFilter(request, response);
return;
}
// 无需验证 放行
chain.doFilter(request, response);
}
}

View File

@ -0,0 +1,43 @@
package com.sunyard.ssp.common;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
/**
* @author Exrickx
*/
@Data
public class PageVo implements Serializable{
private static final long serialVersionUID = 1L;
@TableField(exist = false)
private int pageNumber = 1;
@TableField(exist = false)
private int pageSize = 10;
@TableField(exist = false)
private String sort;
@TableField(exist = false)
private String order = "desc";
public PageVo(){
}
/**
* 分页构造
* @param pageNumber
* @param pageSize
*/
public PageVo(Integer pageNumber,Integer pageSize){
this.pageNumber = pageNumber;
this.pageSize = pageSize;
}
}

View File

@ -0,0 +1,41 @@
package com.sunyard.ssp.common;
import lombok.Data;
import java.io.Serializable;
/**
* @author Exrickx
* 前后端交互数据标准
*/
@Data
public class Result<T> implements Serializable{
private static final long serialVersionUID = 1L;
/**
* 成功标志
*/
private boolean success;
/**
* 失败消息
*/
private String message;
/**
* 返回代码
*/
private Integer code;
/**
* 时间戳
*/
private long timestamp = System.currentTimeMillis();
/**
* 结果对象
*/
private T result;
}

View File

@ -0,0 +1,20 @@
package com.sunyard.ssp.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author fyc
* @des 审计日志注解
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})//作用在参数和方法上
@Retention(RetentionPolicy.RUNTIME)//运行时注解
@Documented//表明这个注解应该被 javadoc工具记录
public @interface AuditControllerLog {
String description() default "";
String operateType() default "";
}

View File

@ -0,0 +1,18 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/3
* @description:
*/
public interface CertificateConstant {
//属性字段名 公钥
String PUB_KEY ="PUB_KEY";
//属性字段名 证书原文件
String CERTIFICATE_CONTENT ="CERTIFICATE_CONTENT";
Integer GROUP_SIGN =0;
}

View File

@ -0,0 +1,52 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/3/13
* @description:
*/
public interface ChannelConstant {
/********************************************************
@author tsz
@date 2020/03/13 16:57
@description : 实施中
********************************************************/
Integer PUBLISH_STATUS_ONE = 1;
/********************************************************
@author tsz
@date 2020/03/13 16:57
@description : 已发布
********************************************************/
Integer PUBLISH_STATUS_TWO = 2;
/**
*@author tsz
*@date 2020/03/23 16:46
*@description : 启用
*/
Integer ENABLED = 0;
/**
*@author tsz
*@date 2020/03/23 16:46
*@description : 禁用
*/
Integer DISABLED = 1;
/**
*@author tsz
*@date 2020/03/23 17:15
*@description : 方案验证可用
*/
Integer VERIFICATION_ENABLED = 0;
/**
*@author tsz
*@date 2020/03/23 17:15
*@description : 方案验证不可用
*/
Integer VERIFICATION_DISABLED = 1;
Integer VERIFICATION_NOT = 2;
}

View File

@ -0,0 +1,10 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/1
* @description:
*/
public interface ChannelSolutionConstant {
}

View File

@ -0,0 +1,227 @@
package com.sunyard.ssp.common.constant;
/**
* 常量
* @author Exrickx
*/
public interface CommonConstant {
/**
* 用户默认头像
*/
String USER_DEFAULT_AVATAR = "https://s1.ax1x.com/2018/05/19/CcdVQP.png";
/**
* 用户正常状态
*/
Integer USER_STATUS_NORMAL = 0;
/**
* 用户禁用状态
*/
Integer USER_STATUS_LOCK = -1;
/**
* 普通用户
*/
Integer USER_TYPE_NORMAL = 0;
/**
* 极光聊天状态
*/
Integer USER_JMESSAGE_NORMAL = 0;
/**
* 管理员
*/
Integer USER_TYPE_ADMIN = 1;
/**
* 全部数据权限
*/
Integer DATA_TYPE_ALL = 0;
/**
* 自定义数据权限
*/
Integer DATA_TYPE_CUSTOM = 1;
/**
* 正常状态
*/
Integer STATUS_NORMAL = 0;
/**
* 禁用状态
*/
Integer STATUS_DISABLE = -1;
/**
* 删除标志
*/
Integer DEL_FLAG = 1;
/**
* 限流标识
*/
String LIMIT_ALL = "KEEPER_LIMIT_ALL";
/**
* 页面类型权限
*/
Integer PERMISSION_PAGE = 0;
/**
* 操作类型权限
*/
Integer PERMISSION_OPERATION = 1;
/**
* 1级菜单父id
*/
Long PARENT_ID = 0L;
/**
* 1级菜单父title
*/
String PARENT_TITLE = "一级节点";
/**
* 默认分类redis缓存key
*/
String DEFAULT_CATEGORY_REDIS_KEY = "actCategory:userDefaultCateGory:";
/**
* 事务审批title
*/
String DEFAULT_CATEGORY_BUSINESS_TITLE = "事务审批";
/**
* 事务审批id
*/
String DEFAULT_CATEGORY_BUSINESS_ID = "1";
/**
* 支付审批title
*/
String DEFAULT_CATEGORY_PAYMENT_TITLE = "支付审批";
/**
* 支付审批id
*/
String DEFAULT_CATEGORY_PAYMENT_ID = "2";
/**
* 1级菜单
*/
Integer LEVEL_ONE = 1;
/**
* 2级菜单
*/
Integer LEVEL_TWO = 2;
/**
* 3级菜单
*/
Integer LEVEL_THREE = 3;
/**
* 消息发送范围
*/
Integer MESSAGE_RANGE_ALL = 0;
/**
* 未读
*/
Integer MESSAGE_STATUS_UNREAD = 0;
/**
* 已读
*/
Integer MESSAGE_STATUS_READ = 1;
/**
* github登录
*/
Integer SOCIAL_TYPE_GITHUB = 0;
/**
* qq登录
*/
Integer SOCIAL_TYPE_QQ = 1;
/**
* 微博登录
*/
Integer SOCIAL_TYPE_WEIBO = 2;
/**
* 短信验证码key前缀
*/
String PRE_SMS = "KEEPER_PRE_SMS:";
/**
* 邮件验证码key前缀
*/
String PRE_EMAIL = "KEEPER_PRE_EMAIL:";
/**
* 本地文件存储
*/
Integer OSS_LOCAL = 0;
/**
* 七牛云OSS存储
*/
Integer OSS_QINIU = 1;
/**
* 阿里云OSS存储
*/
Integer OSS_ALI = 2;
/**
* 腾讯云COS存储
*/
Integer OSS_TENCENT = 3;
/**
* 部门负责人类型 主负责人
*/
Integer HEADER_TYPE_MAIN = 0;
/**
* 部门负责人类型 副负责人
*/
Integer HEADER_TYPE_VICE = 1;
/**
* 部门负责人类型 不是负责人
*/
Integer HEADER_TYPE_NONE = -1;
/**
* 邮箱字段隐藏时显示的值
*/
String HIDE_EMAIL_STR = "******@***.com";
/**
* 手机字段隐藏时显示的值
*/
String HIDE_MOBILE_STR = "****";
String PATH_SEPARATOR = "/";
Long DEPARTMENT_ROOT_ID = 0L;
Long DEFAULT_USER_ROOT_ID = 1L;
/**
* @author wp
* @Description:盐值位数
* @date 2021/12/16
* @param null
* @return
*/
Integer SALT_NUMBER =10;
}

View File

@ -0,0 +1,21 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/5/11
* @description:
*/
public interface DeviceConstant {
/**
*@date 2020/05/11 15:52
*@description : 状态启用
*/
Integer ENABLE = 0;
/**
*@date 2020/05/11 15:52
*@description : 状态禁用
*/
Integer DISABLE = 1;
}

View File

@ -0,0 +1,19 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/3/26
* @description:
*/
public interface DeviceGroupRefConstant {
/**
* 设备分组内的设备状态 启用
*/
Integer DEVICE_ENABLED = 0;
/**
* 设备分组内的设备状态 禁用
*/
Integer DEVICE_DISABLED = 1;
}

View File

@ -0,0 +1,10 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/5/12
* @description:
*/
public interface DictDataConstant {
Long [] DICT_ID = {78L,79L,80L};
}

View File

@ -0,0 +1,11 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/5/28
* @description:
*/
public interface FileConstant {
String FILE_TYPE_PEM = "PEM";
}

View File

@ -0,0 +1,46 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/29
* @description:
*/
public interface KeyAttributeConstant {
/**
*@author tsz
*@date 2020/04/29 14:05
*@description : 密钥状态 启用
*/
Integer STATUS_ENABLE = 0;
/**
*@author tsz
*@date 2020/04/29 14:05
*@description : 密钥状态 停用
*/
Integer STATUS_DISABLE = 1;
/**
*@date : 2020:06:12 14:55
*@description : 导入开关
*/
Integer IMPORT_SWITCH_ENABLE = 0;
/**
*@date : 2020:06:12 14:55
*@description : 导入开关
*/
Integer IMPORT_SWITCH_DISABLE = 1;
/**
*@date : 2020:06:12 15:21
*@description : 导出
*/
Integer EXPORT_SWITCH_DISABLE = 1;
Integer TMPL_TYPE_TWO = 2;
Integer TMPL_TYPE_THREE = 3;
Integer TMPL_TYPE_ONE = 1;
}

View File

@ -0,0 +1,16 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/7
* @description:
*/
public interface KeyConstant {
//密钥启用长度限制
Integer KEYNAME_LENGTH = 1000;
Integer DEFAULT_VERSION = 0;
Integer TYPE_ONE = 1;
}

View File

@ -0,0 +1,33 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/21
* @description:
*/
public interface KeySolutionConstant {
/**
*@author tsz
*@date 2020/04/21 10:59
*@description : 模版里边的密钥名称key
*/
String KEY_NAME = "keyName";
/**
*@date : 2020:06:10 15:55
*@description : 密钥模板里的密钥类型
*/
String KEY_TYPE = "keyType";
/**
*@date : 2020:06:10 15:55
*@description : 密钥模板里的密钥类型 公钥
*/
String PK = "PK";
/**
*@date : 2020:06:10 15:55
*@description : 密钥模板里的密钥类型 私钥
*/
String SK = "SK";
}

View File

@ -0,0 +1,16 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/21
* @description:
*/
public interface NodeConstant {
/**
*@author tsz
*@date 2020/04/21 10:50
*@description : 节点父id默认值
*/
Long PID = -1L;
}

View File

@ -0,0 +1,124 @@
package com.sunyard.ssp.common.constant;
/**
* @author:fyc
* @date:2020/3/17
* @description: 业务参数key值常量
*/
public interface ParamConfKeyConstant {
/**
* 白名单开关
*/
String IP_WHITELIST_SWITCH = "ipWhitelistSwitch";
/**
* 通讯超时时间
*/
String COMMUNICATE_TIME_OUT = "communicateTimeOut";
/**
* 心跳检测时间
*/
String HEART_DETECT_TIME = "heartDetectTime";
/**
* 心跳包
*/
String HEART_PACKAGE = "heartPackage";
/**
* ftp传输路径设置
*/
String FTP_UPLOAD_PATH = "ftpUploadPath";
/**
* B端界面超时时间
*/
String B_INTERFACE_TIMEOUT = "BInterfaceTimeOut";
/**
* 加密机操作审批
*/
String ENCRYPTION_MACHINE_APPROVAL = "encryptionMachineApproval";
/**
* 秘钥操作审批
*/
String SECRET_KEY_APPROVAL = "secretKeyApproval";
/**
* 登入模式
*/
String LOGIN_METHOD = "loginMethod";
/**
* 是否开启图形码登入
*/
String IS_USE_GRAPHIC_CODE = "isUseGraphicCode";
/**
* IP白名单配置类目数值
*/
Integer IP_WHITELIST_ITEM = 0;
/**
* 通讯参数类目数值
*/
Integer COMMUNICATE_PARAM_ITEM = 1;
/**
* 终端UI参数类目数值
*/
Integer TERMINAL_PARAM_ITEM = 2;
/**
* 权限审批类目数值
*/
Integer AUTHORITY_APPROVAL_PARAM_ITEM = 3;
/**
* 登入选项类目数值
*/
Integer LOGIN_PARAM_ITEM = 4;
/**
* 审批结果true
*/
String APPROVAL_TRUE = "true";
/**
* 审批结果false
*/
String APPROVAL_FALSE = "false";
/**
* 调试模式类目数值
*/
Integer SYS_PARAM_ITEM = 7;
/**
* 调试模式开关
*/
String SYS_DEBUG_SWITCH = "sysDebugSwitch";
/**
* 系统初始化配置文件路劲
*/
String SYS_PARAM_CONFIG_FILE_PATH = System.getProperty("user.dir") + "/config/sysParam.config.json";
/**
* 调试模式开关枚举
*/
enum SYS_DEBUG_SWITCH_VALUE{
DEV("dev"), CONFIG("config"), PRODUCT("product");
private String value;
private SYS_DEBUG_SWITCH_VALUE(String value){
this.value = value;
}
public String getValue(){
return value;
}
}
}

View File

@ -0,0 +1,22 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/21
* @description:
*/
public interface ProtocolConstant {
/**
*@author tsz
*@date 2020/04/21 10:10
*@description : 入口协议
*/
String ENTRANCE_TYPE = "0";
/**
*@date : 2020:05:25 14:56
*@description : 加密机协议
*/
String DEVICE_TYPE = "2";
}

View File

@ -0,0 +1,96 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/4/14
* @description: 正则规则
*/
public interface RegexConstant {
/**
*@author tsz
*@date 2020/04/14 16:48
*@description : 节点编号
*/
String NODE_NUMBER = "\\d{6,12}";
/**
*@author tsz
*@date 2020/04/14 16:49
*@description : 方案编号
*/
String KEY_SOLUTION_NUMBER = "[A-Z][A-Z0-9]{2,5}";
/**
*@author tsz
*@date 2020/04/14 16:50
*@description : 模板编号
*/
String TMPL_NUMBER = "[A-Z][A-Z0-9]{2,5}";
/**
*@author tsz
*@date 2020/04/14 16:52
*@description : 密钥名称
*/
String KEY_NAME = "[A-Z][A-Z0-9]{2,5}";
/**
*@author tsz
*@date 2020/04/15 10:37
*@description : 普通名称校验规则 1-15位的字符
*/
String COMMON_NAME = "^.{1,30}$";
/**
*@author tsz
*@date 2020/04/15 10:37
*@description : 普通名称校验规则 1-30位的数字字母汉字 备用暂时没有用
*/
String COMMON_NAME_TEST = "^[\\w\\u4e00-\\u9fa5]{2,30}$";
/**
*@date :2020/05/22 15:47
*@description : 加密机名称校验
*/
String DEVICE_NAME = "^.{1,15}$";
/**
*@date :2020/05/22 15:47
*@description : 加密机编号校验
*/
String DEVICE_NUMBER = "^[1-9]\\d*$";
/**
*@date :2020/05/22 15:47
*@description : 加密机ipv4校验
*/
String DEVICE_IPV4 = "^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$";
/**
*@date :2020/05/22 15:47
*@description : 加密机ipv6校验
*/
String DEVICE_IPV6 = "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$";
/**
*@date :2020/05/22 15:47
*@description : 加密机端口号校验
*/
String DEVICE_PORT = "^([0-9]|[1-9]\\d{1,3}|[1-5]\\d{4}|6[0-5]{2}[0-3][0-5])$";
/**
*@date :2020/05/22 15:47
*@description : 加密机设备型号校验
*/
String DEVICE_MODEL= "^.{1,15}$";
/**
*@date :2020/05/22 15:47
*@description : 加密机资产类型校验
*/
String DEVICE_ASSETTYPE= "^.{1,15}$";
/**
*@date : 2020:05:28 13:52
*@description : 证书检测是否是base64加密的
*/
String CERTIFICATE_CONTENT = "[-]{5}BEGIN[\\s]*[\\w\\s]*[-]{5}[\\s]*[a-zA-Z\\d\\s/+]*[=]{0,2}[\\s]*[-]{5}END[\\s]*[\\w\\s]*[-]{5}[\\s]*";
}

View File

@ -0,0 +1,86 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/5/6
* @description:
*/
public interface SdkConstant {
/**
*@date : 2020:05:25 14:31
*@description : 渠道通信key
*/
String SERVER_CLUSTER = "SERVER_CLUSTER";
/**
*@date : 2020:05:25 14:32
*@description : 渠道验证
*/
String CHANNEL_CHECK = "channel.check";
/**
*@date :2020/05/25 14:02
*@description : 渠道更新命令
*/
String CHANNEL_CMD_UPDATE = "channel.enable.update";
/**
*@date :2020/05/25 14:02
*@description : 渠道中的密钥方案变动
*/
String CHANNEL_CMD_SOLUTION_UPDATE = "channel.solution.update";
String PING = "ping";
/**
*@date : 2020:05:25 15:04
*@description : 协议变动
*/
String PROTO_UPDATE = "proto.update";
/**
*@date : 2020:05:25 15:04
*@description : 加密机组变动
*/
String HSMGROUP_UPDATE = "hsmgroup.update";
/**
*@date : 2020:05:25 15:04
*@description : 加密机组变动
*/
String HSM_UPDATE = "hsm.update";
/**
*@date : 2020:06:03 11:01
*@description : 模板变更
*/
String KEYTEMPLATE_UPDATE= "keytemplate.update";
/**
*@date : 2020:05:25 15:04
*@description : 加密机协议校验
*/
String PROTO_CHECK = "proto.check";
/**
*@date :2020/05/25 14:24
*@description : 密钥更新命令
*/
String KEY_CMD_UPDATE = "key.update";
String IDENTITY_MANAGER = "Manager";
/**
*@date :2020/05/25 14:23
*@description : sdk通信加密的jks配置文件位置
*/
String CLIENT_TRUSTSTORE = "config/clientTruststore.jks";
/**
*@date :2020/05/25 14:23
*@description : sdk通信加密的jks 通知字段
*/
String CLIENT_KEY = "client";
}

View File

@ -0,0 +1,78 @@
package com.sunyard.ssp.common.constant;
/**
* @author Exrickx
*/
public interface SecurityConstant {
/**
* token分割
*/
String TOKEN_SPLIT = "Bearer ";
/**
* JWT签名加密key
*/
String JWT_SIGN_KEY = "keeper";
/**
* token参数头
*/
String HEADER = "accessToken";
/**
* 权限参数头
*/
String AUTHORITIES = "authorities";
/**
* 用户选择JWT保存时间参数头
*/
String SAVE_LOGIN = "saveLogin";
/**
* github保存state前缀key
*/
String GITHUB_STATE = "KEEPER_GITHUB:";
/**
* qq保存state前缀key
*/
String QQ_STATE = "KEEPER_QQ:";
/**
* qq保存state前缀key
*/
String WEIBO_STATE = "KEEPER_WEIBO:";
/**
* 交互token前缀key
*/
String TOKEN_PRE = "KEEPER_TOKEN_PRE:";
/**
* 用户token前缀key 单点登录使用
*/
String USER_TOKEN = "KEEPER_USER_TOKEN:";
/**
* 用户登陆之后的租户识别id
* @auther: ZS
* @description:
* @param:
* @return:
* @date: 2019/3/20 16:21
*/
String TENANT_ID = "KEEPER_TENANT_ID";
/**
* 更新用户接口url
* @auther: ZS
* @description:
* @param:
* @return:
* @date: 2019/7/31 14:54
*/
String USER_UPDATE_URL = "/keeper/user/admin/edit";
}

View File

@ -0,0 +1,19 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/3/13
* @description:
*/
public interface SqlConstant {
/**
* 通配符
*/
String SQL_LIKE_WILDCARD = "%";
/**
* 数据库排序字段
*/
String DB_SORT_COLUMN = "SORT_ORDER";
}

View File

@ -0,0 +1,9 @@
package com.sunyard.ssp.common.constant;
public interface SspServerConstant {
/**
* 通配符
*/
//sspserver端口号
int SERVER_PORT = 8800;
}

View File

@ -0,0 +1,15 @@
package com.sunyard.ssp.common.constant;
public interface ValidatorConstant {
String POSTION_BASE_NAME = "position";
String POSTION_FORM_TITLE_KEY = "title";
String DEPARTMENT_BASE_NAME = "department";
String PERMISSION_BASE_NAME = "permission";
String ROLE_BASE_NAME = "role";
}

View File

@ -0,0 +1,50 @@
package com.sunyard.ssp.common.constant;
/**
* @author:tsz
* @date:2020/3/13
* @description:
*/
public interface WorkflowConstant {
/********************************************************
@author tsz
@date 2020/03/13 17:16
@description : 渠道
********************************************************/
String TYPE_SYSTEM = "system";
/**
*@date 2020/05/11 10:59
*@description : 申请时判断是否可以添加
*/
Integer [] APPLICANTID_STATUS = {1,2};
/**
*@author tsz
*@date 2020/03/26 13:52
*@description : 加密机
*/
String TYPE_ENCRYTOR = "encrytor";
/**
*@date 2020/03/24 10:17
*@description : 审批通过
*/
Integer STATUS_APPROVAL = 2;
/**
*@date 2020/03/24 10:17
*@description : 待审批
*/
Integer STATUS_PENDING_APPROVAL = 1;
/**
*@author tsz
*@date 2020/03/24 10:17
*@description : 生命周期添加
*/
Integer LIFECYCLE_ADD = 0;
Integer ENABLED = 0;
}

View File

@ -0,0 +1,52 @@
package com.sunyard.ssp.common.enums;
import com.sunyard.ssp.common.constant.CommonConstant;
public enum UserHeaderTypeEnum {
HEADER_TYPE_MAIN(CommonConstant.HEADER_TYPE_MAIN,"main"),
HEADER_TYPE_VICE(CommonConstant.HEADER_TYPE_VICE,"vice"),
HEADER_TYPE_NONE(CommonConstant.HEADER_TYPE_NONE,"none")
;
private Integer key;
private String name;
UserHeaderTypeEnum(Integer statusKey, String statusName) {
this.key = statusKey;
this.name = statusName;
}
public Integer getKey() {
return key;
}
public void setKey(Integer key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static String getNameByKey(Integer key){
for (UserHeaderTypeEnum applicationStatus : UserHeaderTypeEnum.values()) {
if(applicationStatus.getKey().equals(key)){
return applicationStatus.getName();
}
}
return null;
}
public static Integer getKeyByName(String name){
for (UserHeaderTypeEnum applicationStatus : UserHeaderTypeEnum.values()) {
if(applicationStatus.getName().equals(name)){
return applicationStatus.getKey();
}
}
return null;
}
}

View File

@ -0,0 +1,96 @@
package com.sunyard.ssp.common.exception;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 全局controller异常处理
* @auther: ZS
* @description:
* @param:
* @return:
* @date: 2020/5/25 16:24
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionResolver {
/**
* 处理所有不可知异常
*
* @param e 异常
* @return json结果
*/
// @ExceptionHandler(Exception.class)
// @ResponseBody
// public Result<Object> handleException(Exception e) {
// // 打印异常堆栈信息
// return new ResultUtil().setErrorMsg(e.getMessage());
// }
/**
* 数据持久层
*/
@ExceptionHandler(MyBatisSystemException.class)
@ResponseBody
public Result<Object> handleMyBatisSystemException(MyBatisSystemException e) {
System.out.println("数据持久层");
return new ResultUtil().setErrorMsg(e.getLocalizedMessage());
}
/**
* 校验器
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public Result<Object> handleBindException(BindException e) {
System.out.println("校验器");
FieldError fieldError = e.getBindingResult().getFieldError();
return new ResultUtil().setErrorMsg(fieldError.getDefaultMessage());
}
// @ExceptionHandler(MethodArgumentNotValidException.class)
// public R<?> validExceptionHandler(MethodArgumentNotValidException ex) {
//
// return Optional.of(ex.getBindingResult())
// .map(BindingResult::getFieldError)
// .map(FieldError::getDefaultMessage)
// .map(message -> R.error(400, message))
// .get();
// }
//
// private static final List<Class<? extends Exception>> EX_CLASS = Arrays.asList(
// IllegalArgumentException.class, IllegalStateException.class,
// IllegalFormatException.class,
// SspwebException.class,
// UnsupportedOperationException.class);
//
// @ExceptionHandler(Exception.class)
// public R<?> exceptionHandler(Exception ex) {
// String errorMessage = ThrowableUtils.buildErrorMessage(ex);
// SspwebException serviceException = ThrowableUtils.findException(SspwebException.class, ex);
// if (serviceException != null) {
// log.warn("Validation failed -> {}, errorMessage: \n {}", serviceException.getMessage(), errorMessage);
// return R.error(400, serviceException.getMessage());
// }
//
// for (Class<? extends Exception> eClass : EX_CLASS) {
// Exception exception = ThrowableUtils.findException(eClass, ex);
// if (exception == null) {
// continue;
// }
// log.warn("Validation failed -> {} ", errorMessage);
// return R.error(400, exception.getMessage());
// }
// log.error("系统异常 -> ", ex);
// return R.error("系统异常");
// }
}

View File

@ -0,0 +1,23 @@
package com.sunyard.ssp.common.exception;
import lombok.Data;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
/**
* @author Exrickx
*/
@Data
public class LoginFailLimitException extends InternalAuthenticationServiceException {
private String msg;
public LoginFailLimitException(String msg){
super(msg);
this.msg = msg;
}
public LoginFailLimitException(String msg, Throwable t) {
super(msg, t);
this.msg = msg;
}
}

View File

@ -0,0 +1,19 @@
package com.sunyard.ssp.common.exception;
import lombok.Data;
/**
* @author:tsz
* @date:2020/5/28
* @description:
*/
@Data
public class SspwebException extends RuntimeException{
private String msg;
public SspwebException(String msg){
super(msg);
this.msg = msg;
}
}

View File

@ -0,0 +1,19 @@
package com.sunyard.ssp.common.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author Exrickx
*/
@Data
public class Captcha implements Serializable{
@ApiModelProperty(value = "验证码id")
private String captchaId;
@ApiModelProperty(value = "验证码")
private String code;
}

View File

@ -0,0 +1,29 @@
package com.sunyard.ssp.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author:tsz
* @date:2020/3/19
* @description:
*/
@Data
@Component
//@PropertySource(encoding = "UTF-8", value = {"file:./config/server.properties"})
public class ServerConfigure {
@Value("${ip:172.16.17.163}")
private String serverIp;
@Value("${minPort:8801}")
private int minPort;
@Value("${maxPort:8802}")
private int maxPort;
@Value("${sdkPort:8800}")
private int sdkPort;
}

View File

@ -0,0 +1,244 @@
package com.sunyard.ssp.modules.monitor.log.aspect;
import cn.hutool.core.thread.threadlocal.NamedThreadLocal;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.annotation.AuditControllerLog;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogService;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.utils.IpUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import com.sunyard.ssp.utils.ThreadPoolUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author fyc
* @description 切点实现类
*/
@Aspect
@Component
@SuppressWarnings("all")
public class AuditLogAspect {
private final ObjectMapper objectMapper;
@Autowired
private IAuditLogService auditLogService;
@Autowired
private SecurityUtil securityUtil;
@Autowired
private HttpServletRequest request;
private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<Date>("ThreadLocal beginTime");
public AuditLogAspect(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
/**
* 控制器切入层
*/
@Pointcut("@annotation(com.sunyard.ssp.common.annotation.AuditControllerLog)")
public void controllerAspect(){
}
private static ConcurrentHashMap<String, String> parameters = new ConcurrentHashMap<>();
/**
* 前置切入
* @param joinPoint
*/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) throws ServletException, IOException {
Date beginTime = new Date();
beginTimeThreadLocal.set(beginTime);
}
/**
* 后置切入
* @param joinPoint
* @param res
*/
@AfterReturning(pointcut = "controllerAspect()",returning = "res")
public void doAfterReturning(JoinPoint joinPoint, Object res){
try {
AuditLog auditLog = new AuditLog();
auditLog.setCreateTime(LocalDateTime.now());
//操作用户信息
ScUser scUser = securityUtil.getCurrUser();
if(scUser != null){
auditLog.setOperatorName(scUser.getRealname());
auditLog.setOperatorId(scUser.getId());
}
//操作描述操作类型和操作结果
Map map = getAuditLogDescription(joinPoint);
auditLog.setOperateContent((String) map.get("description"));
auditLog.setOperateType((String)map.get("operateType"));
Result<Object> result = (Result<Object>) res;
if(result.isSuccess()){
auditLog.setOperateResult("成功");
}else {
auditLog.setOperateResult("失败");
}
//Ip信息
auditLog.setIpAddress(IpUtil.getIpAddress(request));
auditLog.setIpInfo("未知");
//请求相关
auditLog.setRequestMothed(request.getMethod());
auditLog.setRequestPath(request.getRequestURI());
Map params = request.getParameterMap();
// auditLog.setRequestParam(requestParamToString(request.getParameterMap()));
String parameters = getParameters(joinPoint);
auditLog.setRequestParam(parameters);
//计算耗时
Date logStartTime = beginTimeThreadLocal.get();
long beginTime = beginTimeThreadLocal.get().getTime();
long endTime = System.currentTimeMillis();
Long logElapsedTime = endTime - beginTime;
auditLog.setTimeConsuming(logElapsedTime.intValue());
//存储日志
ThreadPoolUtil.getPool().execute(new SaveAuditLogThread(auditLog, auditLogService));
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 调用线程存储审计日志
*/
private static class SaveAuditLogThread implements Runnable{
private AuditLog auditLog;
private IAuditLogService iAuditLogService;
public SaveAuditLogThread(AuditLog auditLog, IAuditLogService iAuditLogService) {
this.auditLog = auditLog;
this.iAuditLogService = iAuditLogService;
}
@Override
public void run() {
iAuditLogService.save(auditLog);
}
}
/**
* 从注解中获取描述和类型
* @param joinPoint
* @return
* @throws Exception
*/
public static Map getAuditLogDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();//目标方法名
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
Map map = new HashMap();
for (Method method:methods) {
if (method.getName().equals(methodName)){
Class[] clazzs = method.getParameterTypes();
if (clazzs.length==arguments.length){
String description = method.getAnnotation(AuditControllerLog.class).description();
String operateType = method.getAnnotation(AuditControllerLog.class).operateType();
map.put("description",description);
map.put("operateType",operateType);
break;
}
}
}
return map;
}
/**
* 请求参数map 转化成 string
* @param params
* @return
*/
public static String requestParamToString(Map<String,String[]> params){
Map map = new HashMap<String,Object>(16);
Set<String> keySet = params.keySet();
for(String key : keySet){
String values[] = params.get(key);
map.put(key, Arrays.asList(values).toString());
}
JSONObject jsonObject = new JSONObject(map);
return jsonObject.toJSONString();
}
/**
* @Description: 获取参数列表
* @param joinPoint 切入点
* @Return: java.lang.String 参数:多个之间使用空格分割
* @Author: joan.wu
* @Date: 2024/5/21 14:28
*/
private String getParameters(JoinPoint joinPoint) throws JsonProcessingException {
ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
Object[] args = joinPoint.getArgs();
Method method = getMethod(joinPoint);
// 获取方法参数名
String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
// 构造参数名和参数值的对应关系
StringBuilder argsInfo = new StringBuilder();
for (int i = 0; i < args.length; i++) {
if (parameterNames == null || parameterNames[i] == null) {
continue;
}
argsInfo.append(parameterNames[i])
.append(":")
.append(objectMapper.writeValueAsString(args[i]))
.append(" ");
}
return argsInfo.toString();
}
/**
* @Description: 通过烦设获取类的方法
* @param joinPoint 切入点
* @Return: java.lang.reflect.Method
* @Author: joan.wu
* @Date: 2024/5/21 14:30
*/
private Method getMethod(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
if (!(signature instanceof MethodSignature)) {
throw new IllegalArgumentException("This annotation is only supported on method level");
}
MethodSignature methodSignature = (MethodSignature) signature;
return methodSignature.getMethod();
}
}

View File

@ -0,0 +1,165 @@
package com.sunyard.ssp.modules.monitor.log.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogService;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.utils.PageUtil;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import com.sunyard.ssp.vo.SearchVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author fyc
* @since 2020-03-18
*/
@Controller
@Slf4j
@Api(description = "监控管理-审计日志",tags ="监控管理-审计日志")
@RequestMapping("/monitor/auditLog")
@Transactional
public class AuditLogController {
@Autowired
private IAuditLogService iAuditLogService;
@Autowired
private SecurityUtil securityUtil;
@RequestMapping(value = "/getById",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "通过id获取")
public Result<AuditLog> get(@RequestParam Integer id){
AuditLog entity = iAuditLogService.getById(id);
return new ResultUtil<AuditLog>().setData(entity);
}
@RequestMapping(value = "/queryList",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "获取列表")
public Result<IPage<AuditLog>> queryList(@RequestParam Integer pageNumber,
@RequestParam Integer pageSize,
String operateContent, String operateType,
String requestMothed, String readUserName,
String startTime,
String endTime){
IPage<AuditLog> iPage = iAuditLogService.queryList(pageNumber,pageSize,
operateContent,operateType,requestMothed,readUserName,startTime,endTime);
return new ResultUtil<IPage<AuditLog>>().setData(iPage);
}
@RequestMapping(value = "/queryListWithOutPage",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "获取列表")
public Result<List<AuditLog>> queryListWithOutPage(String operateContent, String operateType,
String requestMothed, String readUserName,
String startTime,
String endTime){
List<AuditLog> auditLogs = iAuditLogService.queryList(operateContent,operateType,requestMothed,readUserName,startTime,endTime);
return new ResultUtil<List<AuditLog>>().setData(auditLogs);
}
@RequestMapping(value = "/user/queryList",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "获取列表")
public Result<IPage<AuditLog>> userLogQueryList(@RequestParam Integer pageNumber,
@RequestParam Integer pageSize,
String readUserName,
String startTime,
String endTime){
IPage<AuditLog> iPage = iAuditLogService.userLogQueryList(pageNumber,pageSize,
null,"登录",null,readUserName,startTime,endTime);
return new ResultUtil<IPage<AuditLog>>().setData(iPage);
}
@RequestMapping(value = "/user/queryListWithOutPage",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "获取列表")
public Result<List<AuditLog>> userLogQueryListWithOutPage(
String readUserName,
String startTime,
String endTime){
List<AuditLog> auditLogs = iAuditLogService.userLogQueryListWithOutPage(null,"登录",null,readUserName,startTime,endTime);
return new ResultUtil<List<AuditLog>>().setData(auditLogs);
}
@RequestMapping(value = "/queryNeedSignLog",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "分页条件查询可以签名的日志")
public Result<org.springframework.data.domain.Page<AuditLog>> queryNeedSignLog(@ModelAttribute AuditLog auditLog,
@ModelAttribute SearchVo searchVo,
@ModelAttribute PageVo pageVo){
org.springframework.data.domain.Page<AuditLog> iPage = iAuditLogService.queryNeedSignLog(auditLog,searchVo, PageUtil.initPage(pageVo));
return new ResultUtil<org.springframework.data.domain.Page<AuditLog>>().setData(iPage);
}
@RequestMapping(value = "/user/queryNeedSignLog",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "分页条件查询可以签名的日志")
public Result<org.springframework.data.domain.Page<AuditLog>> userLoginQueryNeedSignLog(@ModelAttribute AuditLog auditLog,
@ModelAttribute SearchVo searchVo,
@ModelAttribute PageVo pageVo){
org.springframework.data.domain.Page<AuditLog> iPage = iAuditLogService.userLoginQueryNeedSignLog(auditLog,searchVo, PageUtil.initPage(pageVo));
return new ResultUtil<org.springframework.data.domain.Page<AuditLog>>().setData(iPage);
}
@RequestMapping(value = "/updateReadStatus",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "更新审批状态")
public Result<Object> updateReadStatus(@RequestParam Integer[] ids){
ScUser scUser = securityUtil.getCurrUser();
boolean result = iAuditLogService.updateReadStatus(ids,scUser);
if(result){
return new ResultUtil<Object>().setSuccessMsg("审阅日志成功");
}
return new ResultUtil<Object>().setErrorMsg("审阅日志失败");
}
@RequestMapping(value = "/deleteByIds",method = RequestMethod.DELETE)
@ResponseBody
@ApiOperation(value = "批量通过id删除")
public Result<Object> delAllByIds(@RequestParam Integer[] ids){
for(Integer id:ids){
iAuditLogService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
@RequestMapping(value = "/truncateTable",method = RequestMethod.DELETE)
@ResponseBody
@ApiOperation(value = "清空表")
public Result<Object> truncateTable(){
boolean result = iAuditLogService.truncateTable();
if(result){
return new ResultUtil<Object>().setSuccessMsg("清空表成功");
}
return new ResultUtil<Object>().setErrorMsg("清空表失败");
}
}

View File

@ -0,0 +1,42 @@
package com.sunyard.ssp.modules.monitor.log.controller;
import com.sunyard.ssp.modules.monitor.log.service.LogDownloadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
@RestController
public class LogDownloadController {
@Autowired
private LogDownloadService logService;
@GetMapping("/download/logs")
public ResponseEntity<Resource> downloadLogs(
@RequestParam("startDate") String startDateStr,
@RequestParam("endDate") String endDateStr) throws IOException {
LocalDate startDate = LocalDate.parse(startDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate endDate = LocalDate.parse(endDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
ByteArrayResource resource = logService.downloadLogsAsZip(startDate, endDate);
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=logs.zip");
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return ResponseEntity.ok()
.headers(headers)
.body(resource);
}
}

View File

@ -0,0 +1,140 @@
package com.sunyard.ssp.modules.monitor.log.controller;
/**
* @Auther: wp
* @Date: 2022/2/17 15:34
* @Description:
*/
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLogSign;
import com.sunyard.ssp.modules.monitor.log.entity.LogSign;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogService;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogSignService;
import com.sunyard.ssp.modules.monitor.log.service.ILogSignService;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.utils.PageUtil;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import com.sunyard.ssp.utils.sm3.SM3Digest;
import com.sunyard.ssp.vo.SearchVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@RestController
@Slf4j
@Api(description = "审计日志-签名",tags ="审计日志-签名")
@RequestMapping("/monitor/signLog")
@Transactional
public class LogSignController {
@Autowired
private SecurityUtil securityUtil;
@Autowired
private IAuditLogSignService auditLogSignService;
@Autowired
private ILogSignService logSignService;
@Autowired
private IAuditLogService auditLogService;
@RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
@ApiOperation(value = "日志签名分页条件查询")
public Result<org.springframework.data.domain.Page<LogSign>> getByCondition(@ModelAttribute LogSign logSign,
@ModelAttribute SearchVo searchVo,
@ModelAttribute PageVo pageVo) {
try {
org.springframework.data.domain.Page<LogSign> page = logSignService.findByCondition(logSign, searchVo, PageUtil.initPage(pageVo));
return new ResultUtil<org.springframework.data.domain.Page<LogSign>>().setData(page);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@RequestMapping(value = "/hash",method = RequestMethod.POST)
@ApiOperation(value = "日志hash")
public Result<Object> hash(@RequestParam Long[] ids){
if(ids==null || ids.length<1){
return new ResultUtil<Object>().setErrorMsg("审计失败,未选择日志");
}
ArrayList<Long> list = new ArrayList<>(ids.length);
Collections.addAll(list, ids);
List<AuditLog> auditLogList = auditLogService.list(new QueryWrapper<AuditLog>().lambda().in(AuditLog::getId, list).orderByAsc(AuditLog::getId));
if(CollectionUtil.isEmpty(auditLogList) || list.size()!=auditLogList.size()){
return new ResultUtil<Object>().setErrorMsg("审计失败,该日志不存在");
}
//序列化后hash
String json = new Gson().toJson(auditLogList);
String res= SM3Digest.encode(json);
return new ResultUtil<Object>().setData(res);
}
@RequestMapping(value = "/sign",method = RequestMethod.POST)
@ApiOperation(value = "日志审计签名")
public Result<Object> sign(@ModelAttribute LogSign logSign, @RequestParam Long[] ids){
try {
if(ids==null || ids.length<1){
return new ResultUtil<Object>().setErrorMsg("审计失败,未选择日志");
}
if(null==logSign || StrUtil.isBlank(logSign.getSignValue()) || StrUtil.isBlank(logSign.getPublicKey())){
return new ResultUtil<Object>().setErrorMsg("审计失败,签名参数不能为空");
}
//判断日志是否重复签名
ArrayList<Long> list = new ArrayList<>(ids.length);
Collections.addAll(list, ids);
List<AuditLogSign> logSignList = auditLogSignService.list(new QueryWrapper<AuditLogSign>().lambda().in(AuditLogSign::getLogId, list));
if(CollectionUtil.isNotEmpty(logSignList)){
return new ResultUtil<Object>().setErrorMsg("审计失败,该日志已审计过");
}
ScUser scUser = securityUtil.getCurrUser();
logSign.setCreateTime(LocalDateTime.now());
logSign.setOperatorId(scUser.getId());
logSign.setOperatorName(scUser.getRealname());
boolean b = logSignService.save(logSign);
if(!b){
return new ResultUtil<Object>().setErrorMsg("审计失败");
}
for(Long id:ids){
AuditLogSign auditLogSign=new AuditLogSign();
auditLogSign.setLogId(id);
auditLogSign.setSignId(logSign.getId());
boolean save = auditLogSignService.save(auditLogSign);
if(!save){
return new ResultUtil<Object>().setErrorMsg("审计失败");
}
}
return new ResultUtil<Object>().setSuccessMsg("审计成功");
} catch (Exception e){
e.getStackTrace();
log.error("错误类名[{}],错误方法名[{}]", this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage(), e);
throw new RuntimeException("审计失败");
}
}
}

View File

@ -0,0 +1,76 @@
package com.sunyard.ssp.modules.monitor.log.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.modules.monitor.log.entity.SysLog;
import com.sunyard.ssp.modules.monitor.log.service.ISysLogService;
import com.sunyard.ssp.utils.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* <p>
* 前端控制器
* </p>
*
* @author fyc
* @since 2020-03-31
*/
@Controller
@Slf4j
@Api(description = "系统日志",tags ="系统日志")
@RequestMapping("/monitor/sysLog")
@Transactional
public class SysLogController {
@Autowired
private ISysLogService iSysLogService;
@RequestMapping(value = "/queryList",method = RequestMethod.GET)
@ApiOperation(value = "获取系统日志列表")
@ResponseBody
public Result<IPage<SysLog>> queryList(@RequestParam Integer pageNumber,
@RequestParam Integer pageSize,
String keyWord,
String startTime,
String endTime){
IPage<SysLog> sysLogIPage = iSysLogService.queryList(pageNumber,pageSize,keyWord,startTime,endTime);
return new ResultUtil<IPage<SysLog>>().setData(sysLogIPage);
}
@RequestMapping(value = "/deleteByIds",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "批量通过id删除")
public Result<Object> delAllByIds(@RequestParam Integer[] ids){
for(Integer id:ids){
iSysLogService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
@RequestMapping(value = "/truncateTable",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "清空表")
public Result<Object> truncateTable(){
boolean result = iSysLogService.truncateTable();
if(result){
return new ResultUtil<Object>().setSuccessMsg("清空表成功");
}
return new ResultUtil<Object>().setErrorMsg("清空表失败");
}
}

View File

@ -0,0 +1,98 @@
package com.sunyard.ssp.modules.monitor.log.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author fyc
* @since 2020-03-18
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("SC_AUDIT_LOG")
@ApiModel(value="", description="")
public class AuditLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("ID")
private Long id;
@ApiModelProperty(value = "创建时间")
@TableField("CREATE_TIME")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@ApiModelProperty(value = "操作者")
@TableField("OPERATOR_NAME")
private String operatorName;
@ApiModelProperty(value = "操作者ID")
@TableField("OPERATOR_ID")
private Long operatorId;
@ApiModelProperty(value = "操作内容")
@TableField("OPERATE_CONTENT")
private String operateContent;
@ApiModelProperty(value = "IP地址")
@TableField("IP_ADDRESS")
private String ipAddress;
@ApiModelProperty(value = "IP信息")
@TableField("IP_INFO")
private String ipInfo;
@ApiModelProperty(value = "请求路径")
@TableField("REQUEST_PATH")
private String requestPath;
@ApiModelProperty(value = "请求类型")
@TableField("REQUEST_MOTHED")
private String requestMothed;
@ApiModelProperty(value = "请求数据")
@TableField("REQUEST_PARAM")
private String requestParam;
@ApiModelProperty(value = "操作类型")
@TableField("OPERATE_TYPE")
private String operateType;
@ApiModelProperty(value = "操作结果")
@TableField("OPERATE_RESULT")
private String operateResult;
@ApiModelProperty(value = "耗时")
@TableField("TIME_CONSUMING")
private Integer timeConsuming;
@ApiModelProperty(value = "阅读状态")
@TableField("READ_STATUS")
private Integer readStatus;
@ApiModelProperty(value = "批阅人Id")
@TableField("READ_USER_ID")
private Long readUserId;
@ApiModelProperty(value = "批阅人名字")
@TableField("READ_USER_NAME")
private String readUserName;
}

View File

@ -0,0 +1,35 @@
package com.sunyard.ssp.modules.monitor.log.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("SC_AUDIT_LOG_SIGN")
@ApiModel(value="日志签名关联表", description="")
public class AuditLogSign implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("ID")
private Long id;
@ApiModelProperty(value = "日志签名id")
@TableField("SIGN_ID")
private Long signId;
@ApiModelProperty(value = "日志id")
@TableField("LOG_ID")
private Long logId;
}

View File

@ -0,0 +1,64 @@
package com.sunyard.ssp.modules.monitor.log.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.persistence.Transient;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("SC_LOG_SIGN")
@ApiModel(value="日志签名表", description="")
public class LogSign implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("ID")
private Long id;
@ApiModelProperty(value = "创建时间")
@TableField("CREATE_TIME")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@ApiModelProperty(value = "签名人id")
@TableField("OPERATOR_ID")
private Long operatorId;
@ApiModelProperty(value = "签名人真实姓名")
@TableField("OPERATOR_NAME")
private String operatorName;
@ApiModelProperty(value = "签名值")
@TableField("SIGN_VALUE")
private String signValue;
@ApiModelProperty(value = "公钥")
@TableField("PUBLICKEY")
private String publicKey;
@ApiModelProperty(value = "U盾序号")
@TableField("DEVICE_ID")
private String deviceId;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "关联日志详情按id排序")
private List<AuditLog> auditLogs;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "关联日志总数")
private Integer auditLogsCount;
}

View File

@ -0,0 +1,69 @@
package com.sunyard.ssp.modules.monitor.log.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author fyc
* @since 2020-03-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("SC_SYS_LOG")
@ApiModel(value="", description="")
public class SysLog implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("ID")
private Long id;
@ApiModelProperty(value = "创建时间")
@TableField("CREATE_TIME")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@ApiModelProperty(value = "文件名")
@TableField("FILE_NAME")
private String fileName;
@ApiModelProperty(value = "行号")
@TableField("LINE")
private String line;
@ApiModelProperty(value = "线程")
@TableField("THREAD")
private String thread;
@ApiModelProperty(value = "日志级别")
@TableField("LOG_LEVEL")
private String logLevel;
@ApiModelProperty(value = "信息")
@TableField("MESSAGE")
private String message;
@ApiModelProperty(value = "Java类")
@TableField("CLAZZ")
private String clazz;
@ApiModelProperty(value = "类中的方法")
@TableField("METHOD")
private String method;
}

View File

@ -0,0 +1,197 @@
package com.sunyard.ssp.modules.monitor.log.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import java.time.LocalDate;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author fyc
* @since 2020-03-18
*/
@Repository
public interface AuditLogMapper extends BaseMapper<AuditLog> {
/**
* 分页查询接口
*
* @param iPage
* @param operateContent
* @param operateType
* @param requestMethod
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
@Select("<script>" +
" select * FROM SC_AUDIT_LOG\n" +
" <where>\n" +
" <if test=\"operateContent !=null and operateContent != ''\">\n" +
" and OPERATE_CONTENT like '%${operateContent}%'\n" +
" </if>\n" +
" <if test=\"operateType != null and operateType != ''\">\n" +
" and OPERATE_TYPE like '%${operateType}%'\n" +
" </if>\n" +
" <if test=\"requestMethod != null and requestMethod != ''\">\n" +
" and REQUEST_MOTHED = #{requestMethod}\n" +
" </if>\n" +
" <if test=\"readUserName != null and readUserName != ''\">\n" +
" and READ_USER_NAME like '%${readUserName}%'\n" +
" </if>\n" +
" <if test=\"startTime != null and endTime !=null\">\n" +
" and CREATE_TIME between #{startTime} and (#{endTime}+1)\n" +
" </if>\n" +
"and OPERATE_TYPE!='登录'\n" +
" </where>\n" +
" order by CREATE_TIME desc" +
"</script>")
List<AuditLog> queryList(IPage<AuditLog> iPage,
@Param("operateContent") String operateContent,
@Param("operateType") String operateType,
@Param("requestMethod") String requestMethod,
@Param("readUserName") String readUserName,
@Param("startTime") LocalDate startTime,
@Param("endTime") LocalDate endTime);
/**
* 分页查询接口
*
* @param iPage
* @param operateContent
* @param operateType
* @param requestMethod
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
@Select("<script>" +
" select * FROM SC_AUDIT_LOG\n" +
" <where>\n" +
" <if test=\"operateContent !=null and operateContent != ''\">\n" +
" and OPERATE_CONTENT like '%${operateContent}%'\n" +
" </if>\n" +
" <if test=\"operateType != null and operateType != ''\">\n" +
" and OPERATE_TYPE like '%${operateType}%'\n" +
" </if>\n" +
" <if test=\"requestMethod != null and requestMethod != ''\">\n" +
" and REQUEST_MOTHED = #{requestMethod}\n" +
" </if>\n" +
" <if test=\"readUserName != null and readUserName != ''\">\n" +
" and READ_USER_NAME like '%${readUserName}%'\n" +
" </if>\n" +
" <if test=\"startTime != null and endTime !=null\">\n" +
" and CREATE_TIME between #{startTime} and (#{endTime}+1)\n" +
" </if>\n" +
" </where>\n" +
" order by CREATE_TIME desc" +
"</script>")
List<AuditLog> userLogQueryList(IPage<AuditLog> iPage,
@Param("operateContent") String operateContent,
@Param("operateType") String operateType,
@Param("requestMethod") String requestMethod,
@Param("readUserName") String readUserName,
@Param("startTime") LocalDate startTime,
@Param("endTime") LocalDate endTime);
/**
* 查询接口
*
* @param operateContent
* @param operateType
* @param requestMethod
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
@Select("<script>" +
" select * FROM SC_AUDIT_LOG\n" +
" <where>\n" +
" <if test=\"operateContent !=null and operateContent != ''\">\n" +
" and OPERATE_CONTENT like '%${operateContent}%'\n" +
" </if>\n" +
" <if test=\"operateType != null and operateType != ''\">\n" +
" and OPERATE_TYPE like '%${operateType}%'\n" +
" </if>\n" +
" <if test=\"requestMethod != null and requestMethod != ''\">\n" +
" and REQUEST_MOTHED = #{requestMethod}\n" +
" </if>\n" +
" <if test=\"readUserName != null and readUserName != ''\">\n" +
" and READ_USER_NAME like '%${readUserName}%'\n" +
" </if>\n" +
" <if test=\"startTime != null and endTime !=null\">\n" +
" and CREATE_TIME between #{startTime} and (#{endTime}+1)\n" +
" </if>\n" +
"and OPERATE_TYPE!='登录'\n" +
" </where>\n" +
" order by CREATE_TIME desc" +
"</script>")
List<AuditLog> queryList(@Param("operateContent") String operateContent,
@Param("operateType") String operateType,
@Param("requestMethod") String requestMethod,
@Param("readUserName") String readUserName,
@Param("startTime") LocalDate startTime,
@Param("endTime") LocalDate endTime);
/**
* 查询接口
*
* @param operateContent
* @param operateType
* @param requestMethod
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
@Select("<script>" +
" select * FROM SC_AUDIT_LOG\n" +
" <where>\n" +
" <if test=\"operateContent !=null and operateContent != ''\">\n" +
" and OPERATE_CONTENT like '%${operateContent}%'\n" +
" </if>\n" +
" <if test=\"operateType != null and operateType != ''\">\n" +
" and OPERATE_TYPE like '%${operateType}%'\n" +
" </if>\n" +
" <if test=\"requestMethod != null and requestMethod != ''\">\n" +
" and REQUEST_MOTHED = #{requestMethod}\n" +
" </if>\n" +
" <if test=\"readUserName != null and readUserName != ''\">\n" +
" and READ_USER_NAME like '%${readUserName}%'\n" +
" </if>\n" +
" <if test=\"startTime != null and endTime !=null\">\n" +
" and CREATE_TIME between #{startTime} and (#{endTime}+1)\n" +
" </if>\n" +
" </where>\n" +
" order by CREATE_TIME desc" +
"</script>")
List<AuditLog> userLogQueryListWithOutPage(@Param("operateContent") String operateContent,
@Param("operateType") String operateType,
@Param("requestMethod") String requestMethod,
@Param("readUserName") String readUserName,
@Param("startTime") LocalDate startTime,
@Param("endTime") LocalDate endTime);
/**
* 清空表
*
* @return
*/
@Update("<script>" +
"truncate table SC_AUDIT_LOG" +
"</script>")
Integer truncateTable();
}

View File

@ -0,0 +1,16 @@
package com.sunyard.ssp.modules.monitor.log.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLogSign;
import org.springframework.stereotype.Repository;
/**
* @Auther: wp
* @Date: 2022/2/17 11:20
* @Description:
*/
@Repository
public interface AuditLogSignMapper extends BaseMapper<AuditLogSign> {
}

View File

@ -0,0 +1,16 @@
package com.sunyard.ssp.modules.monitor.log.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.ssp.modules.monitor.log.entity.LogSign;
import org.springframework.stereotype.Repository;
/**
* @Auther: wp
* @Date: 2022/2/17 11:20
* @Description:
*/
@Repository
public interface LogSignMapper extends BaseMapper<LogSign> {
}

View File

@ -0,0 +1,47 @@
package com.sunyard.ssp.modules.monitor.log.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sunyard.ssp.modules.monitor.log.entity.SysLog;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;
import java.time.LocalDate;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author fyc
* @since 2020-03-31
*/
@Repository
public interface SysLogMapper extends BaseMapper<SysLog> {
@Select("<script>"+
" SELECT *\n" +
" FROM SC_SYS_LOG\n" +
" <where>\n" +
" <if test=\"keyWord!='' and keyWord!=null\">\n" +
" and instr(FILE_NAME||LINE||THREAD||LOG_LEVEL||MESSAGE||CLAZZ||METHOD,#{keyWord},1,1)>0\n" +
" </if>\n" +
" <if test=\"startTime != null and endTime !=null\">\n" +
" and CREATE_TIME between #{startTime} and #{endTime}\n" +
" </if>\n" +
" </where>\n" +
" order by CREATE_TIME desc"+
"</script>")
List<SysLog> queryList(IPage<SysLog> iPage,
@Param("keyWord") String keyWord,
@Param("startTime") LocalDate startTime,
@Param("endTime")LocalDate endTime);
@Update("<script>"+
"truncate table SC_SYS_LOG"+
"</script>")
Integer truncateTable();
}

View File

@ -0,0 +1,113 @@
package com.sunyard.ssp.modules.monitor.log.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.vo.SearchVo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author fyc
* @since 2020-03-18
*/
public interface IAuditLogService extends IService<AuditLog> {
/**
* 获取审计日志列表
* @param pageNumber
* @param pageSize
* @param operateContent
* @param operateType
* @param readStatus
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
IPage<AuditLog> queryList(Integer pageNumber, Integer pageSize,
String operateContent, String operateType,
String readStatus, String readUserName,
String startTime, String endTime);
/**
* 获取审计日志列表
* @param pageNumber
* @param pageSize
* @param operateContent
* @param operateType
* @param readStatus
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
IPage<AuditLog> userLogQueryList(Integer pageNumber, Integer pageSize,
String operateContent, String operateType,
String readStatus, String readUserName,
String startTime, String endTime);
/**
* 获取审计日志列表不带分页数据
* @param operateContent
* @param operateType
* @param readStatus
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
List<AuditLog> queryList(String operateContent, String operateType,
String readStatus, String readUserName,
String startTime, String endTime);
/**
* 获取审计日志列表不带分页数据
* @param operateContent
* @param operateType
* @param readStatus
* @param readUserName
* @param startTime
* @param endTime
* @return
*/
List<AuditLog> userLogQueryListWithOutPage(String operateContent, String operateType,
String readStatus, String readUserName,
String startTime, String endTime);
/**
* 清空表
* @return
*/
Boolean truncateTable();
/**
* 更新审计日志的审计状态
* @param ids 日志Id 支持批量
* @param scUser 批阅的用户
* @return
*/
Boolean updateReadStatus(Integer ids[], ScUser scUser);
/**
* @author wp
* @Description: 根据签名id查询关联的日志详情按id排序
* @date 2022/2/17
* @param signId
* @return java.util.List<com.sunyard.ssp.modules.monitor.log.entity.AuditLog>
*/
List<AuditLog> getByLogSignId(Long signId);
Page<AuditLog> queryNeedSignLog(AuditLog auditLog, SearchVo searchVo, Pageable pageable);
Page<AuditLog> userLoginQueryNeedSignLog(AuditLog auditLog, SearchVo searchVo, Pageable pageable);
}

View File

@ -0,0 +1,12 @@
package com.sunyard.ssp.modules.monitor.log.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLogSign;
/**
* @Auther: wp
* @Date: 2022/2/17 11:22
* @Description: 日志签名关联服务接口
*/
public interface IAuditLogSignService extends IService<AuditLogSign> {
}

View File

@ -0,0 +1,17 @@
package com.sunyard.ssp.modules.monitor.log.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sunyard.ssp.modules.monitor.log.entity.LogSign;
import com.sunyard.ssp.vo.SearchVo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
/**
* @Auther: wp
* @Date: 2022/2/17 11:22
* @Description: 日志签名服务接口
*/
public interface ILogSignService extends IService<LogSign> {
Page<LogSign> findByCondition(LogSign logSign, SearchVo searchVo, Pageable pageable);
}

View File

@ -0,0 +1,33 @@
package com.sunyard.ssp.modules.monitor.log.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sunyard.ssp.modules.monitor.log.entity.SysLog;
/**
* <p>
* 服务类
* </p>
*
* @author fyc
* @since 2020-03-31
*/
public interface ISysLogService extends IService<SysLog> {
/**
* 系统日志列表
* @param pageNumber
* @param pageSize
* @param keyWord
* @param startTime
* @param endTime
* @return
*/
IPage<SysLog> queryList(Integer pageNumber,Integer pageSize,String keyWord,String startTime,String endTime);
/**
* 清空日志
* @return
*/
Boolean truncateTable();
}

View File

@ -0,0 +1,10 @@
package com.sunyard.ssp.modules.monitor.log.service;
import org.springframework.core.io.ByteArrayResource;
import java.io.IOException;
import java.time.LocalDate;
public interface LogDownloadService {
ByteArrayResource downloadLogsAsZip(LocalDate startDate, LocalDate endDate) throws IOException;
}

View File

@ -0,0 +1,183 @@
package com.sunyard.ssp.modules.monitor.log.serviceimpl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLogSign;
import com.sunyard.ssp.modules.monitor.log.mapper.AuditLogMapper;
import com.sunyard.ssp.modules.monitor.log.mapper.AuditLogSignMapper;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogService;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.utils.DateUtil;
import com.sunyard.ssp.vo.SearchVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author fyc
* @since 2020-03-18
*/
@Slf4j
@Service
@Transactional
public class AuditLogServiceImpl extends ServiceImpl<AuditLogMapper, AuditLog> implements IAuditLogService {
@Autowired
private AuditLogMapper auditLogMapper;
@Autowired
private AuditLogSignMapper auditLogSignMapper;
@Override
public IPage<AuditLog> queryList(Integer pageNumber, Integer pageSize,
String operateContent, String operateType,
String requestMethod, String readUserName,
String startTime, String endTime) {
Page<AuditLog> auditLogPage = new Page<>(pageNumber, pageSize);
IPage<AuditLog> auditLogIPage = auditLogPage.setRecords(auditLogMapper.queryList(auditLogPage, operateContent, operateType, requestMethod, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime)));
return auditLogIPage;
}
@Override
public IPage<AuditLog> userLogQueryList(Integer pageNumber, Integer pageSize,
String operateContent, String operateType,
String requestMethod, String readUserName,
String startTime, String endTime) {
Page<AuditLog> auditLogPage = new Page<>(pageNumber, pageSize);
IPage<AuditLog> auditLogIPage = auditLogPage.setRecords(auditLogMapper.userLogQueryList(auditLogPage, operateContent, operateType, requestMethod, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime)));
return auditLogIPage;
}
@Override
public List<AuditLog> queryList(String operateContent, String operateType, String readStatus, String readUserName, String startTime, String endTime) {
return auditLogMapper.queryList(operateContent, operateType, readStatus, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime));
}
@Override
public List<AuditLog> userLogQueryListWithOutPage(String operateContent, String operateType, String readStatus, String readUserName, String startTime, String endTime) {
return auditLogMapper.userLogQueryListWithOutPage(operateContent, operateType, readStatus, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime));
}
@Override
public Boolean truncateTable() {
Integer i = auditLogMapper.truncateTable();
if (i < 0) {
return false;
}
return true;
}
@Override
public Boolean updateReadStatus(Integer[] ids, ScUser scUser) {
Boolean result = true;
for (Integer id : ids) {
AuditLog auditLog = auditLogMapper.selectById(id);
if (auditLog.getReadStatus() == 0) {
auditLog.setReadStatus(1);
auditLog.setReadUserId(scUser.getId());
auditLog.setReadUserName(scUser.getRealname());
Integer i = auditLogMapper.updateById(auditLog);
if (i < 1) {
result = false;
break;
}
}
}
return result;
}
@Override
public List<AuditLog> getByLogSignId(Long signId) {
List<AuditLogSign> logSigns = auditLogSignMapper.selectList(new QueryWrapper<AuditLogSign>().lambda().eq(AuditLogSign::getSignId, signId));
if (CollectionUtil.isEmpty(logSigns)) {
return null;
}
List<Long> ids = logSigns.stream().map(AuditLogSign::getLogId).collect(Collectors.toList());
return baseMapper.selectList(new QueryWrapper<AuditLog>().lambda().in(AuditLog::getId, ids).orderByAsc(AuditLog::getId));
}
@Override
public org.springframework.data.domain.Page<AuditLog> queryNeedSignLog(AuditLog auditLog, SearchVo searchVo, Pageable pageable) {
LambdaQueryWrapper<AuditLog> wrapper = new QueryWrapper<AuditLog>().lambda();
if (StrUtil.isNotBlank(auditLog.getOperateContent())) {
wrapper.like(AuditLog::getOperateContent, auditLog.getOperateContent());
}
if (StrUtil.isNotBlank(auditLog.getOperateType())) {
wrapper.like(AuditLog::getOperateType, auditLog.getOperateType());
}
if (StrUtil.isNotBlank(auditLog.getRequestMothed())) {
wrapper.eq(AuditLog::getRequestMothed, auditLog.getRequestMothed());
}
if (StrUtil.isNotBlank(auditLog.getReadUserName())) {
wrapper.like(AuditLog::getReadUserName, auditLog.getReadUserName());
}
//创建时间
if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
Date start = cn.hutool.core.date.DateUtil.parse(searchVo.getStartDate());
Date end = cn.hutool.core.date.DateUtil.parse(searchVo.getEndDate());
wrapper.between(AuditLog::getCreateTime, start, cn.hutool.core.date.DateUtil.endOfDay(end));
}
wrapper.eq(AuditLog::getReadStatus, 1);
//过滤已签名的日志
List<AuditLogSign> auditLogSigns = auditLogSignMapper.selectList(null);
if (CollectionUtil.isNotEmpty(auditLogSigns)) {
List<Long> logids = auditLogSigns.stream().map(AuditLogSign::getLogId).collect(Collectors.toList());
wrapper.notIn(AuditLog::getId, logids);
}
wrapper.orderByDesc(AuditLog::getCreateTime);
IPage page = new Page<>(pageable.getPageNumber() + 1, pageable.getPageSize());
IPage auditLogList = baseMapper.selectPage(page, wrapper);
org.springframework.data.domain.Page<AuditLog> res = new PageImpl<AuditLog>(auditLogList.getRecords(), pageable, auditLogList.getTotal());
return res;
}
@Override
public org.springframework.data.domain.Page<AuditLog> userLoginQueryNeedSignLog(AuditLog auditLog, SearchVo searchVo, Pageable pageable) {
LambdaQueryWrapper<AuditLog> wrapper = new QueryWrapper<AuditLog>().lambda();
wrapper.like(AuditLog::getOperateType, "登录");
if (StrUtil.isNotBlank(auditLog.getReadUserName())) {
wrapper.like(AuditLog::getReadUserName, auditLog.getReadUserName());
}
//创建时间
if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
Date start = cn.hutool.core.date.DateUtil.parse(searchVo.getStartDate());
Date end = cn.hutool.core.date.DateUtil.parse(searchVo.getEndDate());
wrapper.between(AuditLog::getCreateTime, start, cn.hutool.core.date.DateUtil.endOfDay(end));
}
wrapper.eq(AuditLog::getReadStatus, 1);
//过滤已签名的日志
List<AuditLogSign> auditLogSigns = auditLogSignMapper.selectList(null);
if (CollectionUtil.isNotEmpty(auditLogSigns)) {
List<Long> logids = auditLogSigns.stream().map(AuditLogSign::getLogId).collect(Collectors.toList());
wrapper.notIn(AuditLog::getId, logids);
}
wrapper.orderByDesc(AuditLog::getCreateTime);
IPage page = new Page<>(pageable.getPageNumber() + 1, pageable.getPageSize());
IPage auditLogList = baseMapper.selectPage(page, wrapper);
org.springframework.data.domain.Page<AuditLog> res = new PageImpl<AuditLog>(auditLogList.getRecords(), pageable, auditLogList.getTotal());
return res;
}
}

View File

@ -0,0 +1,20 @@
package com.sunyard.ssp.modules.monitor.log.serviceimpl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLogSign;
import com.sunyard.ssp.modules.monitor.log.mapper.AuditLogSignMapper;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogSignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @Auther: wp
* @Date: 2022/2/17 11:25
* @Description:
*/
@Slf4j
@Service
@Transactional
public class AuditLogSignServiceImpl extends ServiceImpl<AuditLogSignMapper, AuditLogSign> implements IAuditLogSignService {
}

View File

@ -0,0 +1,83 @@
package com.sunyard.ssp.modules.monitor.log.serviceimpl;
import com.sunyard.ssp.modules.monitor.log.service.LogDownloadService;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Service
public class LogDownloadServiceImpl implements LogDownloadService {
private static final String LOG_BASE_PATH = "/app/log/";
private static final DateTimeFormatter folderFormatter = DateTimeFormatter.ofPattern("yyyy-MM"); // 用于遍历月份的目录格式
private static final DateTimeFormatter fileFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 用于解析文件名中的日期格式
/**
* 下载指定日期范围内的日志文件为ZIP格式
*
* @param startDate 开始日期包含
* @param endDate 结束日期包含
* @return 包含所选日志文件的ByteArrayResource对象
* @throws IOException 如果读取文件或创建ZIP时发生IO错误
*/
@Override
public ByteArrayResource downloadLogsAsZip(LocalDate startDate, LocalDate endDate) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
// 遍历指定日期范围内的每个月份
for (LocalDate date = startDate.withDayOfMonth(1); !date.isAfter(endDate); date = date.plusMonths(1)) {
Files.list(Paths.get(LOG_BASE_PATH, folderFormatter.format(date)))
.filter(path -> isRelevantLogFile(path, startDate, endDate))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(path.getFileName().toString());
try {
zos.putNextEntry(zipEntry);
Files.copy(path, zos);
zos.closeEntry();
} catch (IOException e) {
throw new RuntimeException("压缩日志文件时发生错误", e);
}
});
}
zos.finish();
}
return new ByteArrayResource(baos.toByteArray(), "logs.zip");
}
/**
* 判断给定路径是否是指定日期范围内的相关日志文件
*
* @param path 文件路径
* @param startDate 开始日期
* @param endDate 结束日期
* @return 如果文件在指定日期范围内则返回true否则返回false
*/
private boolean isRelevantLogFile(Path path, LocalDate startDate, LocalDate endDate) {
String fileName = path.getFileName().toString();
if (!fileName.endsWith(".log.gz")) {
return false;
}
// 解析文件名中的日期
String dateString = fileName.substring("sspweb-DEBUG-".length(), fileName.indexOf('_', "sspweb-DEBUG-".length()));
LocalDate fileDate;
try {
fileDate = LocalDate.parse(dateString, fileFormatter);
} catch (Exception e) {
// 如果无法解析日期忽略该文件
return false;
}
// 检查文件日期是否在指定范围内
return !fileDate.isBefore(startDate) && !fileDate.isAfter(endDate);
}
}

View File

@ -0,0 +1,78 @@
package com.sunyard.ssp.modules.monitor.log.serviceimpl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.monitor.log.entity.LogSign;
import com.sunyard.ssp.modules.monitor.log.mapper.LogSignMapper;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogService;
import com.sunyard.ssp.modules.monitor.log.service.ILogSignService;
import com.sunyard.ssp.vo.SearchVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* @Auther: wp
* @Date: 2022/2/17 11:25
* @Description:
*/
@Slf4j
@Service
@Transactional
public class LogSignServiceImpl extends ServiceImpl<LogSignMapper, LogSign> implements ILogSignService {
@Autowired
private IAuditLogService auditLogService;
@Override
public Page<LogSign> findByCondition(LogSign logSign, SearchVo searchVo, Pageable pageable) {
LambdaQueryWrapper<LogSign> wrapper = new QueryWrapper<LogSign>().lambda();
if(null!=logSign.getOperatorId()){
wrapper.eq(LogSign::getOperatorId,logSign.getOperatorId());
}
if(StrUtil.isNotBlank(logSign.getOperatorName())){
wrapper.like(LogSign::getOperatorName,logSign.getOperatorName());
}
//创建时间
if(StrUtil.isNotBlank(searchVo.getStartDate())&&StrUtil.isNotBlank(searchVo.getEndDate())){
Date start = DateUtil.parse(searchVo.getStartDate());
Date end = DateUtil.parse(searchVo.getEndDate());
wrapper.between(LogSign::getCreateTime,start,DateUtil.endOfDay(end));
}
wrapper.orderByDesc(LogSign::getCreateTime);
IPage page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>( pageable.getPageNumber()+1,pageable.getPageSize());
IPage logSignList = baseMapper.selectPage(page,wrapper);
//查询关联日志详情
List<LogSign> records = logSignList.getRecords();
if(CollectionUtils.isNotEmpty(records)){
for (LogSign sign:records){
List<AuditLog> auditLogs = auditLogService.getByLogSignId(sign.getId());
if(CollectionUtil.isNotEmpty(auditLogs)){
sign.setAuditLogs(auditLogs);
sign.setAuditLogsCount(auditLogs.size());
}
}
}
Page<LogSign> res = new PageImpl<LogSign>(records,pageable,logSignList.getTotal());
return res;
}
}

View File

@ -0,0 +1,46 @@
package com.sunyard.ssp.modules.monitor.log.serviceimpl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunyard.ssp.modules.monitor.log.entity.SysLog;
import com.sunyard.ssp.modules.monitor.log.mapper.SysLogMapper;
import com.sunyard.ssp.modules.monitor.log.service.ISysLogService;
import com.sunyard.ssp.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 服务实现类
* </p>
*
* @author fyc
* @since 2020-03-31
*/
@Slf4j
@Service
@Transactional
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements ISysLogService {
@Autowired
private SysLogMapper sysLogMapper;
@Override
public IPage<SysLog> queryList(Integer pageNumber, Integer pageSize, String keyWord, String startTime, String endTime) {
Page<SysLog> sysLogPage = new Page<>(pageNumber,pageSize);
IPage<SysLog> sysLogIPage = sysLogPage.setRecords(sysLogMapper.queryList(sysLogPage,keyWord, DateUtil.StringToDate(startTime),DateUtil.StringToDate(endTime)));
return sysLogIPage;
}
@Override
public Boolean truncateTable() {
Integer i = sysLogMapper.truncateTable();
if (i < 0) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,114 @@
package com.sunyard.ssp.modules.sdk;
import com.sunyard.ssp.UnionMessage;
import com.sunyard.ssp.constv.Alg;
import com.sunyard.ssp.constv.KeyPairType;
import com.sunyard.ssp.constv.KeyType;
import com.sunyard.ssp.constv.PublicKeyType;
/**
* @author:tsz
* @date:2020/5/21
* @description: 非对称密钥工具类
*/
public interface ASymmetricKeyToolService {
/**
* @param :
* @return :
* @date :2020/05/21 15:10
* @description : 生成临时用的密钥对 未实现
*/
UnionMessage genTempKeyPair(KeyPairType keypairType, Alg alg, int keylenMultiple);
/**
* @param :
* @return :
* @date :2020/05/21 15:11
* @description : 生成密钥对 未实现
*/
boolean genKeyPair(String pk, String sk, KeyType keyType, Alg alg, int keylenMultiple);
/**
* @param : pk 公钥的名字
* @param : type RAW 裸公钥,DER 格式,Base64 格式
* @param : pkv 公钥值
* @param : startTime 开始时间
* @param : period 有效期
* @return :
* @date :2020/05/21 15:12
* @description : 导入 生成公钥
*/
void importPk(String pk, PublicKeyType type, byte[] pkv, Long startTime, Long period);
/**
* @param : pk 公钥的名字
* @param : type RAW 裸公钥,DER 格式,Base64 格式
* @param : pkv 公钥值
* @return :
* @date :2020/05/21 15:12
* @description : 导入 更新公钥
*/
void importPk(String pk, PublicKeyType type, byte[] pkv);
/**
* @param : pk 公钥的名字
* @param : type RAW 裸公钥,DER 格式,Base64 格式
* @return :
* @date :2020/05/21 15:14
* @description : 导出公钥
*/
byte[] outputPk(String pk, PublicKeyType type);
/**
* @param :alg 非对称算法
* @param :key 加密用的密钥的名字可以是公钥可以是私钥
* @param :data 原始数据
* @date :2020/06/22 14:25
* @description : 非对称公钥加密
*/
byte[] ASYMPKEncryptData(Alg alg, String pk, byte[] data);
/**
* @param : alg 非对称算法
* @param : key 加密用的密钥的名字可以是公钥可以是私钥 公钥加密则对方用私钥解密私钥加密则对方用公钥解密
* @param : data 原始数据
* @date :2020/06/22 14:27
* @description : 非对称私钥解密
*/
byte[] ASYMSKDecryptData(Alg alg, String sk, byte[] data);
/**
* @author wp
* @Description: p1验签
* @date 2021/9/22
* @param alg 非对称算法
* @param orgData 原始数据
* @param sign 签名数据
* @return boolean
*/
boolean PKCS1Verify(Alg alg, byte[] orgData, byte[] sign);
/**
* @param alg 非对称算法
* @param pk 外部公钥
* @param data 原始数据
* @return byte[]
* @author wp
* @Description: 外部公钥加密
* @date 2021/9/22
*/
byte[] ASYMEncryptDataByOutPK(Alg alg, String pk, String data);
/**
* @author wp
* @Description: p1签名
* @date 2021/9/22
* @param alg 非对称算法
* @param data 原始数据
* @return byte[]
*/
byte[] PKCS1Sign(Alg alg, byte[] data);
}

View File

@ -0,0 +1,48 @@
package com.sunyard.ssp.modules.sdk;
import com.sunyard.ssp.proto.sdk.Sdk;
/**
* @author:tsz
* @date:2020/5/21
* @description:
*/
public interface CertService {
/**
* @param : cert
* @return :
* @date :2020/05/21 14:26
* @description : 证书检测
*/
Sdk.CIX509 catCert(String cert);
/**
* @param : cert
* @return :
* @date :2020/05/21 14:26
* @description : 证书检测
*/
Sdk.CIX509 catCert(String cert,String sk);
/**
* @param : pk
* @param : domain
* @return :
* @date :2020/05/21 14:24
* @description : 证书请求生成,更新密钥
*/
String applyCertRequest(String pk, String domain);
/**
*@date :2020/06/09 14:09
*@description : 证书请求生成,生成密钥
* @param :
* @return :
*/
String applyCertRequest(String pk, String domain,Long startTime,Long period);
long ping();
}

View File

@ -0,0 +1,84 @@
package com.sunyard.ssp.modules.sdk;
import com.sunyard.ssp.UnionMessage;
/**
* @author:tsz
* @date:2020/5/21
* @description:
*/
public interface KeyLifecycleService {
/**
* @param : sln 密钥方案
* @param : tmpl 密钥模板
* @param : startTime 开始时间
* @param : period 有效期
* @return :
* @date :2020/05/21 14:50
* @description : 根据密钥方案密钥模板批量生成密钥
*/
Long genBatchKeyByTmpl(String sln, String tmpl, Long startTime, Long period);
/**
* @param : sln 密钥方案
* @param : tmpl 密钥模板
* @return :
* @date :2020/05/21 14:50
* @description : 根据密钥方案密钥模板批量更新密钥
*/
Long genBatchKeyByTmpl(String sln, String tmpl);
/**
* @param : sln 密钥方案
* @param : tmpl 密钥模板
* @param : node 密钥节点
* @param : startTime 开始时间
* @param : period 有效期
* @return :
* @date :2020/05/21 14:52
* @description : 根据密钥方案密钥模板生成指定节点密钥
*/
UnionMessage genKeyByTmpl(String sln, String tmpl, String node, Long startTime, Long period);
/**
* @param : sln 密钥方案
* @param : tmpl 密钥模板
* @param : node 密钥节点
* @return :
* @date :2020/05/21 14:52
* @description : 根据密钥方案密钥模板 更新指定节点密钥
*/
UnionMessage genKeyByTmpl(String sln, String tmpl, String node);
/**
* @param :
* @return :
* @date :2020/05/21 15:06
* @description : 工作密钥更新 web暂时不需要
*/
UnionMessage applyKeyByZMK(String zmk, String node, String tmpl);
/**
* @param :
* @return :
* @date :2020/05/21 15:06
* @description : 保护密钥更新 web暂时不需要
*/
UnionMessage applyZMKByZMK(String zmk, String tmpl);
/**
*@date :2020/05/21 15:07
*@description : 保护密钥回滚
* @param :
* @return :
*/
void rollbackZMK(String zmk);
/**
*@date :2020/05/21 15:07
*@description : 密钥作废
* @param : key 完整密钥名称
* @return :
*/
void disableKeyNow(String key);
}

View File

@ -0,0 +1,9 @@
package com.sunyard.ssp.modules.sdk;
/**
* @author:tsz
* @date:2020/5/21
* @description: sdk接口类
*/
public interface SdkApiService extends CertService,SymmetricKeyToolService,ASymmetricKeyToolService,KeyLifecycleService {
}

View File

@ -0,0 +1,642 @@
package com.sunyard.ssp.modules.sdk;
import com.sunyard.ssp.SSPApi;
import com.sunyard.ssp.SSPApi4jBuilder;
import com.sunyard.ssp.UnionMessage;
import com.sunyard.ssp.common.constant.SdkConstant;
import com.sunyard.ssp.common.exception.SspwebException;
import com.sunyard.ssp.config.ServerConfigure;
import com.sunyard.ssp.constv.Alg;
import com.sunyard.ssp.constv.KeyPairType;
import com.sunyard.ssp.constv.KeyType;
import com.sunyard.ssp.constv.PublicKeyType;
import com.sunyard.ssp.constv.SplitMode;
import com.sunyard.ssp.proto.sdk.Sdk;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Random;
/**
* @author:tsz
* @date:2020/5/21
* @description: sdk实现类
*/
@Service
public class SdkApiServiceImpl implements SdkApiService {
@Autowired
private ServerConfigure serverConfigure;
private SSPApi api() {
SSPApi api = null;
try {
api = new SSPApi4jBuilder()
// .setJks(new File(SdkConstant.CLIENT_TRUSTSTORE))
// .setJksKey(SdkConstant.CLIENT_KEY)
.setIdentity(SdkConstant.IDENTITY_MANAGER)
.setIp(serverConfigure.getServerIp())
.setPort(serverConfigure.getSdkPort())
.setConnectTimeout(3000)
.build();
} catch (Exception e) {
e.printStackTrace();
// TODO: 2020/5/28 这一块异常是返回sdk的还是自定义
throw new SspwebException("sdk连接失败");
}
return api;
}
@Override
public UnionMessage genTempKeyPair(KeyPairType keypairType, Alg alg, int keylenMultiple) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.genTempKeyPair(keypairType, alg, keylenMultiple);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public boolean genKeyPair(String pk, String sk, KeyType keyType, Alg alg, int keylenMultiple) {
SSPApi api = null;
try {
api = api();
boolean b = genKeyPair(pk, sk, keyType, alg, keylenMultiple);
return b;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public void importPk(String pk, PublicKeyType type, byte[] pkv, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
api.importPk(pk, type, pkv, startTime, period);
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public void importPk(String pk, PublicKeyType type, byte[] pkv) {
SSPApi api = null;
try {
api = api();
api.importPk(pk, type, pkv);
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public byte[] outputPk(String pk, PublicKeyType type) {
SSPApi api = null;
try {
api = api();
byte[] bytes = api.outputPk(pk, type).getBytes();
return bytes;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public Sdk.CIX509 catCert(String cert) {
SSPApi api = null;
try {
api = api();
Sdk.CIX509 cix509 = api.catCert(cert);
return cix509;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public Sdk.CIX509 catCert(String cert, String sk) {
SSPApi api = null;
try {
api = api();
Sdk.CIX509 cix509 = api.catCert(cert,sk);
return cix509;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public String applyCertRequest(String pk, String domain) {
SSPApi api = null;
try {
api = api();
String s = api.applyCertRequest(pk, domain);
return s;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public String applyCertRequest(String pk, String domain, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
String s = api.applyCertRequest(pk, domain,startTime,period);
return s;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public byte[] ASYMPKEncryptData(Alg alg, String pk, byte[] data) {
SSPApi api = null;
try {
api = api();
byte[] bytes = api.ASYMPKEncryptData(alg, pk, data);
return bytes;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public byte[] ASYMSKDecryptData(Alg alg, String sk, byte[] data) {
SSPApi api = null;
try {
api = api();
byte[] bytes = api.ASYMSKDecryptData(alg, sk, data);
return bytes;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public boolean PKCS1Verify(Alg alg, byte[] orgData, byte[] sign) {
return true;
// SSPApi api = null;
// try {
// api = api();
// boolean b = api.PKCS1Verify(Alg.SM2, api.SM3Calc(orgData), sign, "CON.000000.SIGN.PK");
// return b;
// } finally {
// //每笔交易必须释放api
// if (null != api) {
// api.free();
// api = null;
// }
// }
}
@Override
public byte[] ASYMEncryptDataByOutPK(Alg alg, String pk, String data) {
SSPApi api = null;
try {
api = api();
byte[] bytes = api.ASYMPKEncryptData(Alg.SM2, pk, data.getBytes());
return bytes;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public byte[] PKCS1Sign(Alg alg, byte[] data) {
byte[] sign = new byte[64];
(new Random()).nextBytes( sign );
return sign;
// SSPApi api = null;
// try {
// api = api();
// byte[] bytes = api.PKCS1Sign(Alg.SM2, api.SM3Calc(data), "CON.000000.SIGN.SK");
// return bytes;
// } finally {
// //每笔交易必须释放api
// if (null != api) {
// api.free();
// api = null;
// }
// }
}
@Override
public long ping() {
SSPApi api = null;
try {
api = api();
Long aLong = api.ping();
return aLong;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public Long genBatchKeyByTmpl(String sln, String tmpl, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
Long aLong = api.genBatchKeyByTmpl(sln, tmpl, startTime, period);
return aLong;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public Long genBatchKeyByTmpl(String sln, String tmpl) {
SSPApi api = null;
try {
api = api();
Long aLong = api.genBatchKeyByTmpl(sln, tmpl);
return aLong;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage genKeyByTmpl(String sln, String tmpl, String node, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.genKeyByTmpl(sln, tmpl, node, startTime, period);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage genKeyByTmpl(String sln, String tmpl, String node) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.genKeyByTmpl(sln, tmpl, node);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage applyKeyByZMK(String zmk, String node, String tmpl) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.applyKeyByZMK(zmk, node, tmpl);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage applyZMKByZMK(String zmk, String tmpl) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.applyZMKByZMK(zmk);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public void rollbackZMK(String zmk) {
SSPApi api = null;
try {
api = api();
api.rollbackZMK(zmk);
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public void disableKeyNow(String key) {
SSPApi api = null;
try {
api = api();
api.disableKeyNow(key);
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public String genRandom(int len) {
SSPApi api = null;
try {
api = api();
String random = api.genRandom(len);
return random;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage genTempKey(KeyType keyType, Alg alg, int keylenMultiple) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.genTempKey(keyType, alg, keylenMultiple);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public boolean genKey(String key, KeyType keyType, Alg alg, int keylenMultiple) {
SSPApi api = null;
try {
api = api();
boolean b = api.genKey(key, keyType, alg, keylenMultiple);
return b;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage genKeyByTmplAndPrint(String sln, String tmpl, String node, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.genKeyByTmplAndPrint(sln, tmpl, node, startTime, period);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage genKeyByTmplAndPrint(String sln, String tmpl, String node) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.genKeyByTmplAndPrint(sln, tmpl, node);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage synthKeyInput(String key, SplitMode splitMode, String[] splits, String kcv, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.synthKeyInput(key, splitMode, splits, kcv, startTime, period);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage synthKeyInput(String key, SplitMode splitMode, String[] splits, String kcv) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.synthKeyInput(key, splitMode, splits, kcv);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage encryptionKeyOutput(String key, String kek) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.encryptionKeyOutput(key, kek);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage decryptKeyInput(String key, String keyvalue, String kcv, String kek, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.decryptKeyInput(key, keyvalue, kcv, kek, startTime, period);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage decryptKeyInput(String key, String keyvalue, String kcv, String kek) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.decryptKeyInput(key, keyvalue, kcv, kek);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage encryptionKeyByPkOutput(String key, Alg alg, String pk) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.encryptionKeyByPkOutput(key, alg, pk);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public UnionMessage encryptionKeyByPkvOutput(String key, Alg alg, String pkv) {
SSPApi api = null;
try {
api = api();
UnionMessage unionMessage = api.encryptionKeyByPkvOutput(key, alg, pkv);
return unionMessage;
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public void decryptKeyBySkInput(String key, String kcv, String sk) {
SSPApi api = null;
try {
api = api();
api.decryptKeyBySkInput(key, kcv, sk);
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
@Override
public void decryptKeyBySkInput(String key, String kcv, String sk, Long startTime, Long period) {
SSPApi api = null;
try {
api = api();
api.decryptKeyBySkInput(key, kcv, sk, startTime, period);
} finally {
//每笔交易必须释放api
if (null != api) {
api.free();
api = null;
}
}
}
}

View File

@ -0,0 +1,151 @@
package com.sunyard.ssp.modules.sdk;
import com.sunyard.ssp.UnionMessage;
import com.sunyard.ssp.constv.Alg;
import com.sunyard.ssp.constv.KeyType;
import com.sunyard.ssp.constv.SplitMode;
/**
* @author:tsz
* @date:2020/5/21
* @description: 对称密钥工具类
*/
public interface SymmetricKeyToolService {
/**
* @param :len 随机数长度
* @return :
* @date :2020/05/21 14:27
* @description : 生成指定长度的真随机数
*/
String genRandom(int len);
/**
* @param : keyType 密钥类型
* @param : alg 指定此密钥用于什么算法
* @param : keylenMultiple 密钥长度的倍数
* @return :
* @date :2020/05/21 14:29
* @description : 生成临时用的密钥
*/
UnionMessage genTempKey(KeyType keyType, Alg alg, int keylenMultiple);
/**
* @param :
* @return :
* @date :2020/05/21 14:31
* @description : 暂时没实现的接口
*/
boolean genKey(String key, KeyType keyType, Alg alg, int keylenMultiple);
/**
* @param : sln 密钥方案
* @param : tmpl 密钥模板
* @param : node 密钥节点
* @param : startTime 开始时间
* @param : period 有效期
* @return :
* @date :2020/05/21 14:32
* @description : 根据密钥方案密钥模板生成指定节点密钥 并打印
*/
UnionMessage genKeyByTmplAndPrint(String sln, String tmpl, String node, Long startTime, Long period);
/**
* @param : sln 密钥方案
* @param : tmpl 密钥模板
* @param : node 密钥节点
* @return :
* @date :2020/05/21 14:36
* @description : 根据密钥方案密钥模板更新指定节点密钥
*/
UnionMessage genKeyByTmplAndPrint(String sln, String tmpl, String node);
/**
* @param : key 指定密钥名例如 XXX.000000.T001.ZMK
* @param : splitMode XOR('异或模式', 1),SEG( '拼接模式', 2)
* @param : splits 所有的密钥分量 HEX格式
* @param : kcv 密钥校验值 HEX 格式可选如果没有 kcv 则不对密钥进行校验
* @param : startTime 开始时间
* @param : period 有效期
* @return :
* @date :2020/05/21 14:39
* @description : 分量导入 生成密钥
*/
UnionMessage synthKeyInput(String key, SplitMode splitMode, String[] splits, String kcv, Long startTime, Long period);
/**
* @param : key 指定密钥名例如 XXX.000000.T001.ZMK
* @param : splitMode XOR('异或模式', 1),SEG( '拼接模式', 2)
* @param : splits 所有的密钥分量 HEX格式
* @param : kcv 密钥校验值 HEX 格式可选如果没有 kcv 则不对密钥进行校验
* @return :
* @date :2020/05/21 14:39
* @description : 分量导入 更新密钥
*/
UnionMessage synthKeyInput(String key, SplitMode splitMode, String[] splits, String kcv);
/**
* @param : key 指定密钥名例如 XXX.000000.T001.ZMK
* @param : kek 保护密钥的名字
* @return :
* @date :2020/05/21 14:43
* @description : 通过保护密钥加密并导出密钥
*/
UnionMessage encryptionKeyOutput(String key, String kek);
/**
* @param : key 指定密钥名例如 XXX.000000.T001.ZMK
* @param : keyvalue 密钥值
* @param : kcv 密钥校验值可选如果为 null 则不进行校验
* @param : kek 保护密钥的名字
* @param : startTime 开始时间
* @param : period 有效期
* @return :
* @date :2020/05/21 14:44
* @description : 通过保护密钥加密并导入 生成密钥
*/
UnionMessage decryptKeyInput(String key, String keyvalue, String kcv, String kek, Long startTime, Long period);
/**
* @param : key 指定密钥名例如 XXX.000000.T001.ZMK
* @param : keyvalue 密钥值
* @param : kcv 密钥校验值可选如果为 null 则不进行校验
* @param : kek 保护密钥的名字
* @return :
* @date :2020/05/21 14:43
* @description : 通过保护密钥加密并导入 更新密钥
*/
UnionMessage decryptKeyInput(String key, String keyvalue, String kcv, String kek);
/**
*@date :2020/05/21 14:47
*@description : 通过公钥保护导出密钥 未实现
* @param :
* @return :
*/
UnionMessage encryptionKeyByPkOutput(String key, Alg alg, String pk);
/**
*@date :2020/05/21 14:47
*@description : 未实现接口
* @param :
* @return :
*/
UnionMessage encryptionKeyByPkvOutput(String key, Alg alg, String pkv);
/**
*@date :2020/05/21 14:48
*@description : 通过私钥解密导入 生成密钥 未实现
* @param :
* @return :
*/
void decryptKeyBySkInput(String key, String kcv, String sk);
/**
*@date :2020/05/21 14:48
*@description : 通过私钥解密导入 更新密钥 未实现
* @param :
* @return :
*/
void decryptKeyBySkInput(String key, String kcv, String sk, Long startTime, Long period);
}

View File

@ -0,0 +1,99 @@
package com.sunyard.ssp.modules.sysconf.paramconf.controller;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.annotation.AuditControllerLog;
import com.sunyard.ssp.modules.sysconf.paramconf.entity.ParamConf;
import com.sunyard.ssp.modules.sysconf.paramconf.service.IParamConfService;
import com.sunyard.ssp.utils.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
/**
* <p>
* 前端控制器
* </p>
*
* @author fyc
* @since 2020-03-17
*/
@Controller
@Slf4j
@Api(description = "系统配置-业务参数配置",tags ="系统配置-业务参数配置")
@RequestMapping("/sysconf/paramConf")
@Transactional
public class ParamConfController {
@Autowired
IParamConfService iParamConfService;
@RequestMapping(value = "/getAll",method = RequestMethod.GET)
@ApiOperation(value = "获取全部数据")
@ResponseBody
public Result<List<ParamConf>> getAll(){
List<ParamConf> list = iParamConfService.list();
return new ResultUtil<List<ParamConf>>().setData(list);
}
@RequestMapping(value = "/selectByItem",method = RequestMethod.GET)
@ApiOperation(value = "根据类目获取参数(通讯参数-1终端UI参数-2, 白名单参数-0)")
@ResponseBody
public Result<Map> selectByItem(@RequestParam Integer item){
Map data = iParamConfService.selectByItem(item);
return new ResultUtil<Map>().setData(data);
}
@RequestMapping(value = "/selectByKey",method = RequestMethod.GET)
@ApiOperation(value = "根据key值获取数据")
@ResponseBody
public Result<ParamConf> selectByItem(@RequestParam String key){
ParamConf data = iParamConfService.selectByKey(key);
return new ResultUtil<ParamConf>().setData(data);
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "保存数据")
@AuditControllerLog(description = "更新业务参数",operateType = "更新")
public Result save(@RequestBody Map map){
boolean result = iParamConfService.save(map);
if(result){
return new ResultUtil<>().setSuccessMsg("保存成功");
}else {
return new ResultUtil<>().setErrorMsg("保存失败");
}
}
@RequestMapping(value = "/deleteById",method = RequestMethod.DELETE)
@ResponseBody
@ApiOperation(value = "通过id删除")
public Result<Object> delAllByIds(@RequestParam String id){
iParamConfService.removeById(id);
return new ResultUtil<Object>().setSuccessMsg("删除数据成功");
}
}

View File

@ -0,0 +1,66 @@
package com.sunyard.ssp.modules.sysconf.paramconf.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
*
* </p>
*
* @author fyc
* @since 2020-03-17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("SC_PARAM_CONF")
@ApiModel(value="", description="")
public class ParamConf implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键")
@TableId("ID")
private Long id;
@ApiModelProperty(value = "数据大类")
@TableField("ITEM")
private Integer item;
@ApiModelProperty(value = "数据名称")
// @TableField("`KEY`") mysql需加
@TableField("KEY")
private String key;
@ApiModelProperty(value = "数据值")
@TableField("VALUE")
private String value;
@ApiModelProperty(value = "数据值类型")
@TableField("TYPE")
private String type;
@ApiModelProperty(value = "状态")
@TableField("STATUS")
private Integer status;
@ApiModelProperty(value = "创建时间")
@TableField("CREAT_TIME")
private LocalDateTime creatTime;
@ApiModelProperty(value = "备注")
@TableField("MEMO")
private String memo;
}

View File

@ -0,0 +1,32 @@
package com.sunyard.ssp.modules.sysconf.paramconf.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sunyard.ssp.modules.sysconf.paramconf.entity.ParamConf;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author fyc
* @since 2020-03-17
*/
@Repository
public interface ParamConfMapper extends BaseMapper<ParamConf> {
// @Select("<script>"+
// " select * from SC_PARAM_CONF where KEY = #{key}"+
// "</script>")
ParamConf selectByKey(@Param("key")String key);
@Select("<script>"+
" select * from SC_PARAM_CONF where item = #{item}"+
"</script>")
List<ParamConf> selectByItem(@Param("item") Integer item);
}

View File

@ -0,0 +1,45 @@
package com.sunyard.ssp.modules.sysconf.paramconf.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sunyard.ssp.modules.sysconf.paramconf.entity.ParamConf;
import java.util.Map;
/**
* <p>
* 服务类
* </p>
*
* @author fyc
* @since 2020-03-17
*/
public interface IParamConfService extends IService<ParamConf> {
/**
* 存储业务参数
* @param map 参数集合
* @return
*/
boolean save(Map map);
/**
* 根据类别获取相应的系统参数
* @param item
* @return
*/
Map selectByItem(Integer item);
/**
* 根据Key值获取参数值
* @param key
* @return
*/
ParamConf selectByKey(String key);
/**
*@author tsz
*@date 2020/04/12 10:23
*@description : 根据itemkey和value确定开关是否开启
*/
Boolean findByItemAndKeyAndValue(Integer item,String key,String value);
}

View File

@ -0,0 +1,191 @@
package com.sunyard.ssp.modules.sysconf.paramconf.serviceimpl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunyard.ssp.common.constant.ParamConfKeyConstant;
import com.sunyard.ssp.modules.sysconf.paramconf.entity.ParamConf;
import com.sunyard.ssp.modules.sysconf.paramconf.mapper.ParamConfMapper;
import com.sunyard.ssp.modules.sysconf.paramconf.service.IParamConfService;
import com.sunyard.ssp.modules.user.entity.ScPermission;
import com.sunyard.ssp.modules.user.service.IScPermissionService;
import com.sunyard.ssp.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.sunyard.ssp.common.constant.CommonConstant.STATUS_DISABLE;
import static com.sunyard.ssp.common.constant.CommonConstant.STATUS_NORMAL;
import static com.sunyard.ssp.common.constant.ParamConfKeyConstant.APPROVAL_TRUE;
import static com.sunyard.ssp.common.constant.ParamConfKeyConstant.AUTHORITY_APPROVAL_PARAM_ITEM;
import static com.sunyard.ssp.common.constant.ParamConfKeyConstant.ENCRYPTION_MACHINE_APPROVAL;
import static com.sunyard.ssp.common.constant.ParamConfKeyConstant.IP_WHITELIST_ITEM;
import static com.sunyard.ssp.common.constant.ParamConfKeyConstant.IP_WHITELIST_SWITCH;
/**
* <p>
* 服务实现类
* </p>
*
* @author fyc
* @since 2020-03-17
*/
@Slf4j
@Service
@Transactional
public class ParamConfServiceImpl extends ServiceImpl<ParamConfMapper, ParamConf> implements IParamConfService, ApplicationRunner {
@Autowired
private IScPermissionService permissionService;
@Autowired
private ParamConfMapper paramConfMapper;
// @Autowired
// private IIpWhitelistService iIpWhitelistService;
@Override
public boolean save(Map map) {
Integer item = (Integer) map.get("item");
map.remove("item");
Set<String> keySet = map.keySet();
boolean result = false;
for (String key : keySet) {
ParamConf paramConf = paramConfMapper.selectByKey(key);
if (paramConf == null) {
paramConf = new ParamConf();
paramConf.setItem(item);
paramConf.setStatus(0);
System.out.println(LocalDateTime.now());
paramConf.setCreatTime(LocalDateTime.now());
paramConf.setKey(key);
paramConf.setValue(String.valueOf(map.get(key)));
paramConf.setType("OBJECT");
result = save(paramConf);
} else {
paramConf.setValue(String.valueOf(map.get(key)));
result = updateById(paramConf);
}
if (!result) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
break;
}
//存储成功生效配置
takeEffectConfiguration(paramConf);
}
return result;
}
@Override
public Map selectByItem(Integer item) {
Map result = new HashMap();
List<ParamConf> paramConfs = paramConfMapper.selectByItem(item);
for (ParamConf paramConf : paramConfs) {
result.put(paramConf.getKey(), paramConf.getValue());
}
return result;
}
@Override
public ParamConf selectByKey(String key) {
return paramConfMapper.selectByKey(key);
}
@Override
public Boolean findByItemAndKeyAndValue(Integer item, String key, String value) {
List<ParamConf> paramConfs = paramConfMapper.selectList(new QueryWrapper<ParamConf>().lambda()
.eq(ParamConf::getItem, item)
.eq(ParamConf::getKey, key)
.eq(ParamConf::getValue, value)
);
if (paramConfs.isEmpty()) {
return false;
}
return true;
}
/**
* 参数修改后进行配置生效
* @param paramConf
* @return
*/
@Async
public void takeEffectConfiguration(ParamConf paramConf) {
//审批权限
if (AUTHORITY_APPROVAL_PARAM_ITEM.equals(paramConf.getItem())
&& ENCRYPTION_MACHINE_APPROVAL.equals(paramConf.getKey())) {
QueryWrapper<ScPermission> wrapper = new QueryWrapper<ScPermission>();
String[] names = {"myApply", "approvalDev", "device"};
wrapper.lambda().in(ScPermission::getName, names);
List<ScPermission> permissions = permissionService.list(wrapper);
permissions.forEach(p -> {
if (APPROVAL_TRUE.equals(paramConf.getValue())) {
p.setPStatus(STATUS_NORMAL);
} else {
p.setPStatus(STATUS_DISABLE);
}
});
permissionService.updateBatchById(permissions);
}
//白名单通知
else if (IP_WHITELIST_ITEM.equals(paramConf.getItem())
&& IP_WHITELIST_SWITCH.equals(paramConf.getKey())) {
// iIpWhitelistService.messengerWhitelistUpdate();
}
}
/**
* 启动加载初始化系统参数
*
* @param args
* @throws Exception
*/
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("初始化系统参数-----------------");
// List<ParamConf> paramConfs = getParamConfByJsonFile();
// paramConfs.forEach(paramConf -> {
// ParamConf temp = selectByKey(paramConf.getKey());
// if (temp == null) {
// paramConf.setCreatTime(LocalDateTime.now());
// save(paramConf);
// } else {
// temp.setValue(paramConf.getValue());
// updateById(temp);
// }
// });
}
/**
* 从JSON 文件里获取初始化配置
*
* @return
*/
private List<ParamConf> getParamConfByJsonFile() {
String jsonStr = "";
List<ParamConf> paramConfs = new ArrayList<>();
try {
File jsonFile = new File(ParamConfKeyConstant.SYS_PARAM_CONFIG_FILE_PATH);
jsonStr = JsonUtil.getJsonStrFromJsonFile(jsonFile);
paramConfs = JSON.parseArray(jsonStr, ParamConf.class);
return paramConfs;
} catch (Exception ex) {
return paramConfs;
}
}
}

View File

@ -0,0 +1,263 @@
package com.sunyard.ssp.modules.user.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.common.constant.ValidatorConstant;
import com.sunyard.ssp.modules.user.entity.ScDepartment;
import com.sunyard.ssp.modules.user.entity.ScDepartmentHeader;
import com.sunyard.ssp.modules.user.entity.ScRoleDepartment;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.service.IScDepartmentHeaderService;
import com.sunyard.ssp.modules.user.service.IScDepartmentService;
import com.sunyard.ssp.modules.user.service.IScRoleDepartmentService;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.modules.user.utils.validator.DepartmentValidator;
import com.sunyard.ssp.redis.RedisObjectOperation;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.DataBinder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-12
*/
@RestController
@Slf4j
@RequestMapping("/department")
@Transactional
public class ScDepartmentController {
@Autowired
DepartmentValidator departmentValidator;
@Autowired
private IScDepartmentService departmentService;
@Autowired
private IScUserService userService;
@Autowired
private IScRoleDepartmentService roleDepartmentService;
@Autowired
private IScDepartmentHeaderService departmentHeaderService;
/*@Autowired
private StringRedisTemplate redisTemplate;*/
@Autowired
private RedisObjectOperation redisObjectOperation;
@Autowired
private SecurityUtil securityUtil;
@InitBinder(value = ValidatorConstant.DEPARTMENT_BASE_NAME)
public void initBainder(DataBinder binder){
binder.replaceValidators(departmentValidator);
}
@RequestMapping(value = "/getByParentId/{parentId}",method = RequestMethod.GET)
@ApiOperation(value = "通过id获取")
public Result<List<ScDepartment>> getByParentId(@PathVariable Long parentId,
@ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "false") Boolean openDataFilter){
List<ScDepartment> list = new ArrayList<>();
ScUser u = securityUtil.getCurrUser();
list = departmentService.findByParentIdOrderBySortOrder(parentId, openDataFilter);
list = setInfo(list);
return new ResultUtil<List<ScDepartment>>().setData(list);
}
@RequestMapping(value = "/add",method = RequestMethod.POST)
@ApiOperation(value = "添加")
public Result<Object> add(@ModelAttribute(ValidatorConstant.DEPARTMENT_BASE_NAME) @Validated ScDepartment department){
departmentService.save(department);
// 如果不是添加的一级 判断设置上级为父节点标识
if(department.getParentId()!=null && !CommonConstant.PARENT_ID.equals(department.getParentId())){
ScDepartment parent = departmentService.getById(department.getParentId());
if(parent.getIsParent()==null||!parent.isParent()){
parent.setIsParent(true);
departmentService.updateById(parent);
}
}
// 更新缓存
Set<String> keys = redisObjectOperation.keys("department::*");
redisObjectOperation.delete(keys);
return new ResultUtil<Object>().setData(department,"添加成功");
}
@RequestMapping(value = "/edit",method = RequestMethod.POST)
@ApiOperation(value = "编辑")
public Result<Object> edit(@ModelAttribute(ValidatorConstant.DEPARTMENT_BASE_NAME) @Validated ScDepartment department,
@RequestParam(required = false) Long[] mainHeader,
@RequestParam(required = false) Long[] viceHeader){
ScDepartment originDepartment = departmentService.getById(department.getId());
if(!originDepartment.getParentId().equals(department.getParentId())){
return new ResultUtil<Object>().setErrorMsg("禁止编辑上级部门");
}
departmentService.updateById(department);
// 先删除原数据
departmentHeaderService.remove(new QueryWrapper<ScDepartmentHeader>().lambda()
.eq(ScDepartmentHeader::getDepartmentId, department.getId()));
for(Long id:mainHeader){
ScDepartmentHeader dh = new ScDepartmentHeader();
dh.setUserId(id);
dh.setDepartmentId(department.getId());
dh.setType(CommonConstant.HEADER_TYPE_MAIN);
departmentHeaderService.save(dh);
}
for(Long id:viceHeader){
ScDepartmentHeader dh = new ScDepartmentHeader();
dh.setUserId(id);
dh.setDepartmentId(department.getId());
dh.setType(CommonConstant.HEADER_TYPE_VICE);
departmentHeaderService.save(dh);
}
// 手动删除所有部门缓存
Set<String> keys = redisObjectOperation.keys("department:" + "*");
redisObjectOperation.delete(keys);
// 删除所有用户缓存
Set<String> keysUser = redisObjectOperation.keys("user:" + "*");
redisObjectOperation.delete(keysUser);
return new ResultUtil<Object>().setData(department,"编辑成功");
}
@RequestMapping(value = "/delByIds/{ids}",method = RequestMethod.DELETE)
@ApiOperation(value = "批量通过id删除")
public Result<Object> delByIds(@PathVariable String[] ids){
for(String id:ids){
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getOrganizationId, id));
if(list!=null&&list.size()>0){
return new ResultUtil<Object>().setErrorMsg("删除失败,包含正被用户使用关联的部门");
}
ScDepartment department = departmentService.getById(id);
List<ScDepartment> departments = departmentService.findByParentIdOrderBySortOrder(department.getId(), false);
if(departments!=null&&departments.size()>0){
return new ResultUtil<Object>().setErrorMsg("删除失败,待删除部门下还有子部门");
}
}
for(String id:ids){
departmentService.removeById(id);
// 删除关联数据权限
roleDepartmentService.remove(new QueryWrapper<ScRoleDepartment>().lambda()
.eq(ScRoleDepartment::getDepartmentId, id));
// 删除关联部门负责人
departmentHeaderService.remove(new QueryWrapper<ScDepartmentHeader>().lambda()
.eq(ScDepartmentHeader::getDepartmentId, id));
}
// 手动删除所有部门缓存
Set<String> keys = redisObjectOperation.keys("department:" + "*");
redisObjectOperation.delete(keys);
// 删除数据权限缓存
Set<String> keysUserRoleData = redisObjectOperation.keys("userRole::depIds:" + "*");
redisObjectOperation.delete(keysUserRoleData);
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
@RequestMapping(value = "/search",method = RequestMethod.GET)
@ApiOperation(value = "部门名模糊搜索")
public Result<List<ScDepartment>> searchByTitle(@RequestParam String title,
@ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "false") Boolean openDataFilter){
List<ScDepartment> list = departmentService.findByTitleLikeOrderBySortOrder("%"+title+"%", openDataFilter);
list = setInfo(list);
return new ResultUtil<List<ScDepartment>>().setData(list);
}
public List<ScDepartment> setInfo(List<ScDepartment> list){
// lambda表达式
list.forEach(item -> {
if(!CommonConstant.PARENT_ID.equals(item.getParentId())){
ScDepartment parent = departmentService.getById(item.getParentId());
if(parent != null){
item.setParentTitle(parent.getTitle());
}else{
item.setParentTitle("");
}
}else{
item.setParentTitle("一级部门");
}
// 设置负责人
List<ScDepartmentHeader> mainHeaderList = departmentHeaderService.list(new QueryWrapper<ScDepartmentHeader>().lambda()
.eq(ScDepartmentHeader::getDepartmentId, item.getId())
.eq(ScDepartmentHeader::getType, CommonConstant.HEADER_TYPE_MAIN));
List<ScDepartmentHeader> viceHeaderList = departmentHeaderService.list(new QueryWrapper<ScDepartmentHeader>().lambda()
.eq(ScDepartmentHeader::getDepartmentId, item.getId())
.eq(ScDepartmentHeader::getType, CommonConstant.HEADER_TYPE_VICE));
if(CollectionUtils.isNotEmpty(mainHeaderList)){
item.setMainHeader(mainHeaderList.stream().map(scDepartmentHeader -> scDepartmentHeader.getUserId()).collect(Collectors.toList()));
}
if(CollectionUtils.isNotEmpty(viceHeaderList)){
item.setViceHeader(viceHeaderList.stream().map(scDepartmentHeader -> scDepartmentHeader.getUserId()).collect(Collectors.toList()));
}
});
return list;
}
@RequestMapping(value = "/getAllJSON",method = RequestMethod.GET)
@ApiOperation(value = "获取全部部门的json格式数据")
public Result<JSONArray> getAllJSON(@ApiParam("是否开始数据权限过滤") @RequestParam(required = false, defaultValue = "true") Boolean openDataFilter){
JSONArray res = getByPid(CommonConstant.DEPARTMENT_ROOT_ID,openDataFilter);
return new ResultUtil().setData(res);
}
@RequestMapping(value = "/getAllList", method = RequestMethod.GET)
public Result<List<ScDepartment>> getAllList(){
return new ResultUtil().setData(departmentService.list());
}
private JSONArray getByPid(Long pId, Boolean openDataFilter){
JSONArray res = new JSONArray();
List<ScDepartment> list = departmentService.findByParentIdOrderBySortOrder(pId, openDataFilter);
if (CollectionUtils.isEmpty(list)){
return null;
}
for (int i = 0; i < list.size(); i++) {
JSONObject departmentJSON = new JSONObject();
departmentJSON.put("title",list.get(i).getTitle());
departmentJSON.put("id",list.get(i).getId());
departmentJSON.put("childern",getByPid(list.get(i).getId(),openDataFilter));
res.add(departmentJSON);
}
return res;
}
}

View File

@ -0,0 +1,96 @@
package com.sunyard.ssp.modules.user.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.modules.user.entity.ScDepartmentHeader;
import com.sunyard.ssp.modules.user.service.IScDepartmentHeaderService;
import com.sunyard.ssp.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-12
*/
@RestController
@Slf4j
@RequestMapping("/departmentHeader")
@Transactional
public class ScDepartmentHeaderController {
@Autowired
IScDepartmentHeaderService iScDepartmentHeaderService;
@RequestMapping(value = "/getById",method = RequestMethod.GET)
@ResponseBody
public Result<ScDepartmentHeader> get(@RequestParam String id){
ScDepartmentHeader entity = iScDepartmentHeaderService.getById(id);
return new ResultUtil<ScDepartmentHeader>().setData(entity);
}
@RequestMapping(value = "/getAll",method = RequestMethod.GET)
@ResponseBody
public Result<List<ScDepartmentHeader>> getAll(){
List<ScDepartmentHeader> list = iScDepartmentHeaderService.list();
return new ResultUtil<List<ScDepartmentHeader>>().setData(list);
}
@RequestMapping(value = "/page",method = RequestMethod.GET)
@ResponseBody
public Result<IPage<ScDepartmentHeader>> getByPage(@ModelAttribute PageVo page){
Page<ScDepartmentHeader> data = new Page<>( page.getPageNumber(),page.getPageSize());
IPage<ScDepartmentHeader> iPage = iScDepartmentHeaderService.page(data);
return new ResultUtil<IPage<ScDepartmentHeader>>().setData(iPage);
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
public Result<ScDepartmentHeader> save(@ModelAttribute ScDepartmentHeader entity){
boolean e = iScDepartmentHeaderService.save(entity);
if ( !e ){
return new ResultUtil<ScDepartmentHeader>().setErrorMsg("添加失败");
}
return new ResultUtil<ScDepartmentHeader>().setSuccessMsg("添加成功");
}
@RequestMapping(value = "/update",method = RequestMethod.PUT)
@ResponseBody
public Result<UpdateChainWrapper<ScDepartmentHeader>> update(@ModelAttribute ScDepartmentHeader entity){
boolean e = iScDepartmentHeaderService.updateById(entity);
if ( !e ){
return new ResultUtil<UpdateChainWrapper<ScDepartmentHeader>>().setErrorMsg("更新失败");
}
return new ResultUtil<UpdateChainWrapper<ScDepartmentHeader>>().setSuccessMsg("更新成功");
}
@RequestMapping(value = "/deleteByIds",method = RequestMethod.DELETE)
@ResponseBody
public Result<Object> delAllByIds(@RequestParam String[] ids){
for(String id:ids){
iScDepartmentHeaderService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
}

View File

@ -0,0 +1,421 @@
package com.sunyard.ssp.modules.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.config.security.permission.MyAccessDecisionManager;
import com.sunyard.config.security.permission.MyFilterSecurityInterceptor;
import com.sunyard.config.security.permission.MySecurityMetadataSource;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.common.constant.ValidatorConstant;
import com.sunyard.ssp.modules.user.entity.ScPermission;
import com.sunyard.ssp.modules.user.entity.ScRolePermission;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.service.IScPermissionService;
import com.sunyard.ssp.modules.user.service.IScRolePermissionService;
import com.sunyard.ssp.modules.user.utils.validator.PermissionValidator;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.DataBinder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.sunyard.ssp.common.constant.CommonConstant.STATUS_DISABLE;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-11
*/
@RestController
@Slf4j
@RequestMapping("/permission")
@Transactional
public class ScPermissionController {
@Autowired
PermissionValidator permissionValidator;
@Autowired
WebInvocationPrivilegeEvaluator privilegeEvaluator;
@Autowired
HttpServletRequest request;
@Autowired
HttpServletResponse response;
@Autowired
SecurityUtil securityUtil;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
MyFilterSecurityInterceptor myFilterSecurityInterceptor;
@Autowired
MySecurityMetadataSource mySecurityMetadataSource;
@Autowired
MyAccessDecisionManager myAccessDecisionManager;
@Autowired
IScPermissionService permissionService;
@Autowired
IScRolePermissionService rolePermissionService;
@InitBinder(ValidatorConstant.PERMISSION_BASE_NAME)
public void initBainder(DataBinder binder){
binder.addValidators(permissionValidator);
}
@RequestMapping(value = "/getById",method = RequestMethod.GET)
@ResponseBody
public Result<ScPermission> get(@RequestParam String id){
ScPermission entity = permissionService.getById(id);
return new ResultUtil<ScPermission>().setData(entity);
}
@RequestMapping(value = "/getAll",method = RequestMethod.GET)
@ResponseBody
public Result<List<ScPermission>> getAll(){
List<ScPermission> list = permissionService.list();
return new ResultUtil<List<ScPermission>>().setData(list);
}
@RequestMapping(value = "/page",method = RequestMethod.GET)
@ResponseBody
public Result<IPage<ScPermission>> getByPage(@ModelAttribute PageVo page){
Page<ScPermission> data = new Page<>( page.getPageNumber(),page.getPageSize());
IPage<ScPermission> iPage = permissionService.page(data);
return new ResultUtil<IPage<ScPermission>>().setData(iPage);
}
/*@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
public Result<ScPermission> save(@ModelAttribute ScPermission entity){
boolean e = permissionService.save(entity);
if ( !e ){
return new ResultUtil<ScPermission>().setErrorMsg("添加失败");
}
return new ResultUtil<ScPermission>().setSuccessMsg("添加成功");
}*/
/*@RequestMapping(value = "/update",method = RequestMethod.PUT)
@ResponseBody
public Result<UpdateChainWrapper<ScPermission>> update(@ModelAttribute ScPermission entity){
boolean e = permissionService.updateById(entity);
if ( !e ){
return new ResultUtil<UpdateChainWrapper<ScPermission>>().setErrorMsg("更新失败");
}
return new ResultUtil<UpdateChainWrapper<ScPermission>>().setSuccessMsg("更新成功");
}*/
@RequestMapping(value = "/deleteByIds",method = RequestMethod.DELETE)
@ResponseBody
public Result<Object> delAllByIds(@RequestParam String[] ids){
for(String id:ids){
permissionService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
@RequestMapping(value = "/getMenuList",method = RequestMethod.GET)
public Result<List<ScPermission>> getAllMenuList(){
List<ScPermission> list = new ArrayList<>();
// 读取缓存
ScUser u = securityUtil.getCurrUser();
/*String key = "permission::userMenuList:" + u.getId();
String v = redisTemplate.opsForValue().get(key);
if(StrUtil.isNotBlank(v)){
list = new Gson().fromJson(v, new TypeToken<List<ScPermission>>(){}.getType());
if(CollectionUtils.isNotEmpty(list)){
return new ResultUtil<List<ScPermission>>().setData(list);
}
}*/
// 用户所有权限 已排序去重
list = permissionService.findByUserId(u.getId());
List<ScPermission> menuList = new ArrayList<>();
// 筛选一级页面
for(ScPermission p : list){
if(CommonConstant.PERMISSION_PAGE.equals(p.getPType())&&CommonConstant.LEVEL_ONE.equals(p.getPLevel())){
menuList.add(p);
}
}
// 筛选二级页面
List<ScPermission> secondMenuList = new ArrayList<>();
for(ScPermission p : list){
if(CommonConstant.PERMISSION_PAGE.equals(p.getPType())&&CommonConstant.LEVEL_TWO.equals(p.getPLevel())){
secondMenuList.add(p);
}
}
// 筛选三级页面
List<ScPermission> thirdMenuList = new ArrayList<>();
for(ScPermission p : list){
if(CommonConstant.PERMISSION_PAGE.equals(p.getPType())&&CommonConstant.LEVEL_THREE.equals(p.getPLevel())){
thirdMenuList.add(p);
}
}
// 筛选二级页面拥有的按钮权限
/*List<ScPermission> buttonPermissions = new ArrayList<>();
for(ScPermission p : list){
if(CommonConstant.PERMISSION_OPERATION.equals(p.getType())){
buttonPermissions.add(p);
}
}*/
// 匹配二级页面拥有权限
/*for(ScPermission p : secondMenuList){
List<String> permTypes = new ArrayList<>();
for(ScPermission pe : buttonPermissions){
if(p.getId().equals(pe.getParentId())){
permTypes.add(pe.getButtonType());
}
}
p.setPermTypes(permTypes);
}*/
// 匹配一级页面拥有二级页面
for(ScPermission p : menuList){
List<ScPermission> secondMenu = new ArrayList<>();
for(ScPermission pe : secondMenuList){
if(p.getId().equals(pe.getParentId())){
List<ScPermission> thirdMenu = new ArrayList<>();
for(ScPermission pt : thirdMenuList){
if(pe.getId().equals(pt.getParentId())){
thirdMenu.add(pt);
}
}
pe.setChildren(thirdMenu);
secondMenu.add(pe);
}
}
p.setChildren(secondMenu);
}
// 缓存
//redisTemplate.opsForValue().set(key, new Gson().toJson(menuList));
return new ResultUtil<List<ScPermission>>().setData(menuList);
}
@RequestMapping(value = "/getAllList",method = RequestMethod.GET)
public Result<List<ScPermission>> getAllList(){
// 一级
List<ScPermission> list = permissionService.findByLevelOrderBySortOrder(CommonConstant.LEVEL_ONE);
// 二级
for(ScPermission p1 : list){
List<ScPermission> children1 = permissionService.findByParentIdOrderBySortOrder(p1.getId());
p1.setChildren(children1);
// 三级
for(ScPermission p2 : children1){
List<ScPermission> children2 = permissionService.findByParentIdOrderBySortOrder(p2.getId());
p2.setChildren(children2);
//四级
for(ScPermission p3 : children2){
List<ScPermission> children3 = permissionService.findByParentIdOrderBySortOrder(p3.getId());
p3.setChildren(children3);
}
}
}
Result<List<ScPermission>> res = new ResultUtil<List<ScPermission>>().setData(list);
return res;
}
@RequestMapping(value = "/tree",method = RequestMethod.GET)
public Result<List<ScPermission>> getByTree(@RequestParam(required = false)Long parentId){
List<ScPermission> list;
if(parentId != null){
list = permissionService.findByLevelOrderBySortOrder(CommonConstant.LEVEL_ONE);
}else{
list = permissionService.findByParentIdOrderBySortOrder(parentId);
}
return new ResultUtil<List<ScPermission>>().setData(list);
}
@RequestMapping(value = "/add",method = RequestMethod.POST)
/*@CacheEvict(key = "'menuList'")*/
public Result<ScPermission> add(@ModelAttribute(ValidatorConstant.PERMISSION_BASE_NAME) @Validated ScPermission permission){
// 判断拦截请求的操作权限按钮名是否已存在
if(CommonConstant.PERMISSION_OPERATION.equals(permission.getPType())){
List<ScPermission> list = permissionService.list(new QueryWrapper<ScPermission>().lambda()
.eq(ScPermission::getTitle,permission.getTitle())
.orderByAsc(ScPermission::getSortOrder));
if(list!=null&&list.size()>0){
return new ResultUtil<ScPermission>().setErrorMsg("名称已存在");
}
}
permissionService.save(permission);
//重新加载权限
mySecurityMetadataSource.loadResourceDefine();
//手动删除缓存
Set<String> redisLeys = redisTemplate.keys("permission:*");
redisTemplate.delete(redisLeys);
return new ResultUtil<ScPermission>().setData(permission);
}
@RequestMapping(value = "/edit",method = RequestMethod.POST)
public Result<ScPermission> edit(@ModelAttribute(ValidatorConstant.PERMISSION_BASE_NAME) @Validated ScPermission permission){
// 判断拦截请求的操作权限按钮名是否已存在
if(CommonConstant.PERMISSION_OPERATION.equals(permission.getPType())){
// 若名称修改
ScPermission p = permissionService.getById(permission.getId());
if(!p.getTitle().equals(permission.getTitle())){
List<ScPermission> list = permissionService.list(new QueryWrapper<ScPermission>().lambda()
.eq(ScPermission::getTitle,permission.getTitle())
.orderByAsc(ScPermission::getSortOrder));
if(list!=null&&list.size()>0){
return new ResultUtil<ScPermission>().setErrorMsg("名称已存在");
}
}
}
permissionService.updateById(permission);
//重新加载权限
mySecurityMetadataSource.loadResourceDefine();
//手动批量删除缓存
Set<String> keys = redisTemplate.keys("userPermission:" + "*");
redisTemplate.delete(keys);
Set<String> keysUser = redisTemplate.keys("user:" + "*");
redisTemplate.delete(keysUser);
Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
redisTemplate.delete(keysUserMenu);
redisTemplate.delete("permission::allList");
return new ResultUtil<ScPermission>().setData(permission);
}
@RequestMapping(value = "/delByIds/{ids}",method = RequestMethod.DELETE)
/*@CacheEvict(key = "'menuList'")*/
public Result<Object> delByIds(@PathVariable String[] ids){
for(String id:ids){
ScPermission p = permissionService.getById(id);
//禁用权限无需判断角色
if(STATUS_DISABLE.equals(p.getPStatus())){
continue;
}
List<ScRolePermission> list = rolePermissionService.list(new QueryWrapper<ScRolePermission>().lambda()
.eq(ScRolePermission::getPermissionId, id));
if(list!=null&&list.size()>0){
return new ResultUtil<Object>().setErrorMsg("删除失败,包含正被角色使用关联的菜单或权限");
}
List<ScPermission> permissions = permissionService.list(new QueryWrapper<ScPermission>().lambda().eq(ScPermission::getParentId, p.getId()));
if(CollectionUtils.isNotEmpty(permissions)){
return new ResultUtil<Object>().setErrorMsg("删除失败,请先删除"+p.getTitle()+"的子权限");
}
}
Set<Long> delSet = new HashSet<>();
for(String id:ids){
if(!delSet.contains(id)){
delPermissionById(Long.parseLong(id), delSet);
}
}
//重新加载权限
mySecurityMetadataSource.loadResourceDefine();
//手动删除缓存
Set<String> redisLeys = redisTemplate.keys("permission:*");
redisTemplate.delete(redisLeys);
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
private void delPermissionById(Long id, Set delSet){
List<ScPermission> childPermissionList = permissionService.findByParentIdOrderBySortOrder(id);
if(CollectionUtils.isNotEmpty(childPermissionList)){
for(ScPermission p:childPermissionList){
delPermissionById(p.getId(), delSet);
}
}
delSet.add(id);
permissionService.removeById(id);
rolePermissionService.remove(new QueryWrapper<ScRolePermission>().lambda().eq(ScRolePermission::getPermissionId,id));
}
@RequestMapping(value = "/search",method = RequestMethod.GET)
public Result<List<ScPermission>> searchPermissionList(@RequestParam String title){
List<ScPermission> list = permissionService.list(new QueryWrapper<ScPermission>().lambda()
.like(ScPermission::getTitle, "%"+title+"%").orderByAsc(ScPermission::getSortOrder));
return new ResultUtil<List<ScPermission>>().setData(list);
}
@RequestMapping(value = "/isNeedVerify" , method = RequestMethod.GET)
public Result<Integer> isNeedVerify(@RequestParam String path){
DefaultWebInvocationPrivilegeEvaluator defaultWebInvocationPrivilegeEvaluator = new DefaultWebInvocationPrivilegeEvaluator(myFilterSecurityInterceptor);
URL url;
try {
url = new URL(path);
} catch (MalformedURLException e) {
return new ResultUtil<Integer>().setErrorMsg(e.getMessage());
}
SecurityContextHolder.getContext();
boolean isAllowed = defaultWebInvocationPrivilegeEvaluator.isAllowed(url.getPath(),SecurityContextHolder.getContext().getAuthentication());
if(!isAllowed){
return new ResultUtil<Integer>().setData(1, "用户无调用权限");
}
boolean needVerify = mySecurityMetadataSource.needVerify(url.getPath());
// if(needVerify){
// return new ResultUtil<Integer>().setData(2, "需要复核");
// }
return new ResultUtil<Integer>().setData(3, "无需复核");
}
}

View File

@ -0,0 +1,140 @@
package com.sunyard.ssp.modules.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.constant.SqlConstant;
import com.sunyard.ssp.common.constant.ValidatorConstant;
import com.sunyard.ssp.modules.user.entity.ScPosition;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.service.IScPositionService;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.modules.user.utils.validator.PositionValidator;
import com.sunyard.ssp.utils.PageUtil;
import com.sunyard.ssp.utils.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.DataBinder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author zs
* @since 2020-03-17
*/
@RestController
@Slf4j
@Api(description = "职位管理接口",tags ="")
@RequestMapping("/position")
@Transactional
public class ScPositionController {
@Autowired
PositionValidator positionValidator;
@Autowired
IScPositionService iPositionService;
@Autowired
IScUserService userService;
@InitBinder(ValidatorConstant.POSTION_BASE_NAME)
public void initBainder(DataBinder binder){
binder.replaceValidators(positionValidator);
}
@RequestMapping(value = "/getById",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "通过id获取")
public Result<ScPosition> get(@RequestParam String id){
ScPosition entity = iPositionService.getById(id);
return new ResultUtil<ScPosition>().setData(entity);
}
@RequestMapping(value = "",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "获取全部数据")
public Result<List<ScPosition>> getAll(@RequestParam(required = false,defaultValue = "") String name){
List<ScPosition> list = iPositionService.list(new QueryWrapper<ScPosition>().lambda()
.like(ScPosition::getName, SqlConstant.SQL_LIKE_WILDCARD + name + SqlConstant.SQL_LIKE_WILDCARD));
return new ResultUtil<List<ScPosition>>().setData(list);
}
@RequestMapping(value = "/page",method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "分页获取")
public Result<IPage<ScPosition>> getByPage(PageVo page){
Pageable pageable = PageUtil.initMybatisPage(page );
Page<ScPosition> data = new Page<>( pageable.getPageNumber(),pageable.getPageSize());
IPage<ScPosition> iPage = iPositionService.page(data);
return new ResultUtil<IPage<ScPosition>>().setData(iPage);
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "保存数据")
public Result<ScPosition> save(@ModelAttribute(ValidatorConstant.POSTION_BASE_NAME) @Validated ScPosition entity){
if(CollectionUtils.isNotEmpty(iPositionService.list(new QueryWrapper<ScPosition>().lambda().eq(ScPosition::getName, entity.getName())))){
return new ResultUtil<ScPosition>().setErrorMsg("添加失败,职位名已存在");
}
boolean e = iPositionService.save(entity);
if ( !e ){
return new ResultUtil<ScPosition>().setErrorMsg("添加失败");
}
return new ResultUtil<ScPosition>().setSuccessMsg("添加成功");
}
@RequestMapping(value = "/update",method = RequestMethod.PUT)
@ResponseBody
@ApiOperation(value = "更新数据")
public Result<UpdateChainWrapper<ScPosition>> update(@ModelAttribute(ValidatorConstant.POSTION_BASE_NAME) @Validated ScPosition entity){
boolean e = iPositionService.updateById(entity);
if ( !e ){
return new ResultUtil<UpdateChainWrapper<ScPosition>>().setErrorMsg("更新失败");
}
return new ResultUtil<UpdateChainWrapper<ScPosition>>().setSuccessMsg("更新成功");
}
@RequestMapping(value = "/deleteByIds/{ids}",method = RequestMethod.DELETE)
@ResponseBody
@ApiOperation(value = "批量通过id删除")
public Result<Object> delAllByIds(@PathVariable String[] ids){
for(String id:ids){
List<ScUser> users = userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getPositionId, id));
ScPosition position = iPositionService.getById(id);
if(CollectionUtils.isNotEmpty(users)){
return new ResultUtil<Object>().setErrorMsg("职位"+position.getName()+"有用户使用,禁止删除");
}
iPositionService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
}

View File

@ -0,0 +1,214 @@
package com.sunyard.ssp.modules.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.constant.ValidatorConstant;
import com.sunyard.ssp.modules.user.entity.ScRole;
import com.sunyard.ssp.modules.user.entity.ScRoleDepartment;
import com.sunyard.ssp.modules.user.entity.ScRolePermission;
import com.sunyard.ssp.modules.user.entity.ScUserRole;
import com.sunyard.ssp.modules.user.service.IScRoleDepartmentService;
import com.sunyard.ssp.modules.user.service.IScRolePermissionService;
import com.sunyard.ssp.modules.user.service.IScRoleService;
import com.sunyard.ssp.modules.user.service.IScUserRoleService;
import com.sunyard.ssp.modules.user.utils.validator.RoleValidator;
import com.sunyard.ssp.redis.RedisObjectOperation;
import com.sunyard.ssp.utils.PageUtil;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.vo.ScRoleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.DataBinder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-11
*/
@RestController
@Slf4j
@RequestMapping("/role")
@Transactional
public class ScRoleController {
@Autowired
IScRoleService roleService;
@Autowired
IScRolePermissionService rolePermissionService;
@Autowired
IScRoleDepartmentService roleDepartmentService;
@Autowired
IScUserRoleService userRoleService;
@Autowired
RoleValidator roleValidator;
@Autowired
private RedisObjectOperation redisObjectOperation;
@InitBinder(ValidatorConstant.ROLE_BASE_NAME)
public void initBainder(DataBinder binder){
binder.replaceValidators(roleValidator);
}
@RequestMapping(value = "/getAllList",method = RequestMethod.GET)
public Result<Object> roleGetAll(){
List<ScRole> list = roleService.list();
return new ResultUtil<Object>().setData(list);
}
@RequestMapping(value = "/getAllByPage",method = RequestMethod.GET)
public Result<org.springframework.data.domain.Page<ScRoleVo>> getRoleByPage(@ModelAttribute PageVo page){
org.springframework.data.domain.Page<ScRole> list = roleService.findAll(PageUtil.initPage(page));
List<ScRoleVo> roleVos = new LinkedList<>();
for(ScRole role : list.getContent()){
// 角色拥有权限
List<ScRolePermission> permissions = rolePermissionService.list(new QueryWrapper<ScRolePermission>().lambda()
.eq(ScRolePermission::getRoleId,role.getId()));
// 角色拥有数据权限
List<ScRoleDepartment> departments = roleDepartmentService.list(new QueryWrapper<ScRoleDepartment>().lambda()
.eq(ScRoleDepartment::getRoleId,role.getId()));
roleVos.add(new ScRoleVo(role, permissions, departments));
}
return new ResultUtil<org.springframework.data.domain.Page<ScRoleVo>>()
.setData(new PageImpl<ScRoleVo>(roleVos, PageUtil.initPage(page), list.getTotalElements()));
}
@RequestMapping(value = "/getDefault",method = RequestMethod.GET)
public Result<Object> getDefault(){
List<ScRole> list = roleService.list(new QueryWrapper<ScRole>().lambda().eq(ScRole::getDefaultRole, true));
return new ResultUtil<Object>().setData(list);
}
@RequestMapping(value = "/setDefault",method = RequestMethod.POST)
public Result<Object> setDefault(@RequestParam String id,
@RequestParam Boolean isDefault){
ScRole role = roleService.getById(id);
if(role==null){
return new ResultUtil<Object>().setErrorMsg("角色不存在");
}
role.setDefaultRole(isDefault);
roleService.updateById(role);
return new ResultUtil<Object>().setSuccessMsg("设置成功");
}
@RequestMapping(value = "/editRolePerm",method = RequestMethod.POST)
public Result<Object> editRolePerm(@RequestParam Long roleId,
@RequestParam(required = false) Long[] permIds){
ScRole role = roleService.getById(roleId);
//删除其关联权限
rolePermissionService.remove(new QueryWrapper<ScRolePermission>().lambda().eq(ScRolePermission::getRoleId,roleId));
//分配新权限
for(Long permId : permIds){
ScRolePermission rolePermission = new ScRolePermission();
rolePermission.setRoleId(roleId);
rolePermission.setPermissionId(permId);
rolePermissionService.save(rolePermission);
}
//手动批量删除缓存
Set<String> keysUser = redisObjectOperation.keys("user:" + "*");
redisObjectOperation.delete(keysUser);
Set<String> keysUserRole = redisObjectOperation.keys("userRole:" + "*");
redisObjectOperation.delete(keysUserRole);
Set<String> keysUserPerm = redisObjectOperation.keys("userPermission:" + "*");
redisObjectOperation.delete(keysUserPerm);
Set<String> keysUserMenu = redisObjectOperation.keys("permission::userMenuList:*");
redisObjectOperation.delete(keysUserMenu);
return new ResultUtil<Object>().setData(null);
}
@RequestMapping(value = "/editRoleDep",method = RequestMethod.POST)
public Result<Object> editRoleDep(@RequestParam Long roleId,
@RequestParam Integer dataType,
@RequestParam(required = false) Long[] depIds){
ScRole r = roleService.getById(roleId);
r.setDataType(dataType);
roleService.updateById(r);
// 删除其关联数据权限
roleDepartmentService.remove(new QueryWrapper<ScRoleDepartment>().lambda().eq(ScRoleDepartment::getRoleId, roleId));
// 分配新数据权限
for(Long depId : depIds){
ScRoleDepartment roleDepartment = new ScRoleDepartment();
roleDepartment.setRoleId(roleId);
roleDepartment.setDepartmentId(depId);
roleDepartmentService.save(roleDepartment);
}
// 手动删除相关缓存
Set<String> keys = redisObjectOperation.keys("department:" + "*");
redisObjectOperation.delete(keys);
Set<String> keysUserRole = redisObjectOperation.keys("userRole:" + "*");
redisObjectOperation.delete(keysUserRole);
return new ResultUtil<Object>().setData(null);
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
public Result<ScRole> save(@ModelAttribute(ValidatorConstant.ROLE_BASE_NAME) @Validated ScRole role){
if(roleService.save(role)) {
return new ResultUtil<ScRole>().setData(role);
}
return new ResultUtil<ScRole>().setErrorMsg("save error");
}
@RequestMapping(value = "/edit",method = RequestMethod.POST)
public Result<ScRole> edit(@ModelAttribute(ValidatorConstant.ROLE_BASE_NAME) @Validated ScRole entity){
ScRole oldRole = roleService.getById(entity.getId());
roleService.updateById(entity);
//手动批量删除缓存
Set<String> keysUser = redisObjectOperation.keys("user:" + "*");
redisObjectOperation.delete(keysUser);
Set<String> keysUserRole = redisObjectOperation.keys("userRole:" + "*");
redisObjectOperation.delete(keysUserRole);
return new ResultUtil<ScRole>().setData(entity);
}
@RequestMapping(value = "/delAllByIds/{ids}",method = RequestMethod.DELETE)
public Result<Object> delByIds(@PathVariable String[] ids){
for(String id:ids){
List<ScUserRole> list = userRoleService.list(new QueryWrapper<ScUserRole>().lambda().eq(ScUserRole::getRoleId, id));
if(list!=null&&list.size()>0){
return new ResultUtil<Object>().setErrorMsg("删除失败,包含正被用户使用关联的角色");
}
}
for(String id:ids){
roleService.removeById(id);
//删除关联菜单权限
rolePermissionService.remove(new QueryWrapper<ScRolePermission>().lambda().eq(ScRolePermission::getRoleId,id));
//删除关联数据权限
roleDepartmentService.remove(new QueryWrapper<ScRoleDepartment>().lambda().eq(ScRoleDepartment::getRoleId,id));
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
}

View File

@ -0,0 +1,96 @@
package com.sunyard.ssp.modules.user.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.modules.user.entity.ScRoleDepartment;
import com.sunyard.ssp.modules.user.service.IScRoleDepartmentService;
import com.sunyard.ssp.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-12
*/
@RestController
@Slf4j
@RequestMapping("/roleDepartment")
@Transactional
public class ScRoleDepartmentController {
@Autowired
IScRoleDepartmentService iScRoleDepartmentService;
@RequestMapping(value = "/getById",method = RequestMethod.GET)
@ResponseBody
public Result<ScRoleDepartment> get(@RequestParam String id){
ScRoleDepartment entity = iScRoleDepartmentService.getById(id);
return new ResultUtil<ScRoleDepartment>().setData(entity);
}
@RequestMapping(value = "/getAll",method = RequestMethod.GET)
@ResponseBody
public Result<List<ScRoleDepartment>> getAll(){
List<ScRoleDepartment> list = iScRoleDepartmentService.list();
return new ResultUtil<List<ScRoleDepartment>>().setData(list);
}
@RequestMapping(value = "/page",method = RequestMethod.GET)
@ResponseBody
public Result<IPage<ScRoleDepartment>> getByPage(@ModelAttribute PageVo page){
Page<ScRoleDepartment> data = new Page<>( page.getPageNumber(),page.getPageSize());
IPage<ScRoleDepartment> iPage = iScRoleDepartmentService.page(data);
return new ResultUtil<IPage<ScRoleDepartment>>().setData(iPage);
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
public Result<ScRoleDepartment> save(@ModelAttribute ScRoleDepartment entity){
boolean e = iScRoleDepartmentService.save(entity);
if ( !e ){
return new ResultUtil<ScRoleDepartment>().setErrorMsg("添加失败");
}
return new ResultUtil<ScRoleDepartment>().setSuccessMsg("添加成功");
}
@RequestMapping(value = "/update",method = RequestMethod.PUT)
@ResponseBody
public Result<UpdateChainWrapper<ScRoleDepartment>> update(@ModelAttribute ScRoleDepartment entity){
boolean e = iScRoleDepartmentService.updateById(entity);
if ( !e ){
return new ResultUtil<UpdateChainWrapper<ScRoleDepartment>>().setErrorMsg("更新失败");
}
return new ResultUtil<UpdateChainWrapper<ScRoleDepartment>>().setSuccessMsg("更新成功");
}
@RequestMapping(value = "/deleteByIds",method = RequestMethod.DELETE)
@ResponseBody
public Result<Object> delAllByIds(@RequestParam String[] ids){
for(String id:ids){
iScRoleDepartmentService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
}

View File

@ -0,0 +1,96 @@
package com.sunyard.ssp.modules.user.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.modules.user.entity.ScRolePermission;
import com.sunyard.ssp.modules.user.service.IScRolePermissionService;
import com.sunyard.ssp.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-11
*/
@RestController
@Slf4j
@RequestMapping("/rolePermission")
@Transactional
public class ScRolePermissionController {
@Autowired
IScRolePermissionService iScRolePermissionService;
@RequestMapping(value = "/getById",method = RequestMethod.GET)
@ResponseBody
public Result<ScRolePermission> get(@RequestParam String id){
ScRolePermission entity = iScRolePermissionService.getById(id);
return new ResultUtil<ScRolePermission>().setData(entity);
}
@RequestMapping(value = "/getAll",method = RequestMethod.GET)
@ResponseBody
public Result<List<ScRolePermission>> getAll(){
List<ScRolePermission> list = iScRolePermissionService.list();
return new ResultUtil<List<ScRolePermission>>().setData(list);
}
@RequestMapping(value = "/page",method = RequestMethod.GET)
@ResponseBody
public Result<IPage<ScRolePermission>> getByPage(@ModelAttribute PageVo page){
Page<ScRolePermission> data = new Page<>( page.getPageNumber(),page.getPageSize());
IPage<ScRolePermission> iPage = iScRolePermissionService.page(data);
return new ResultUtil<IPage<ScRolePermission>>().setData(iPage);
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
public Result<ScRolePermission> save(@ModelAttribute ScRolePermission entity){
boolean e = iScRolePermissionService.save(entity);
if ( !e ){
return new ResultUtil<ScRolePermission>().setErrorMsg("添加失败");
}
return new ResultUtil<ScRolePermission>().setSuccessMsg("添加成功");
}
@RequestMapping(value = "/update",method = RequestMethod.PUT)
@ResponseBody
public Result<UpdateChainWrapper<ScRolePermission>> update(@ModelAttribute ScRolePermission entity){
boolean e = iScRolePermissionService.updateById(entity);
if ( !e ){
return new ResultUtil<UpdateChainWrapper<ScRolePermission>>().setErrorMsg("更新失败");
}
return new ResultUtil<UpdateChainWrapper<ScRolePermission>>().setSuccessMsg("更新成功");
}
@RequestMapping(value = "/deleteByIds",method = RequestMethod.DELETE)
@ResponseBody
public Result<Object> delAllByIds(@RequestParam String[] ids){
for(String id:ids){
iScRolePermissionService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
}

View File

@ -0,0 +1,433 @@
package com.sunyard.ssp.modules.user.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.jna.Pointer;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.constv.Alg;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogService;
import com.sunyard.ssp.modules.sdk.SdkApiService;
import com.sunyard.ssp.modules.sysconf.paramconf.service.IParamConfService;
import com.sunyard.ssp.modules.user.entity.ScRole;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.entity.ULoginDto;
import com.sunyard.ssp.modules.user.entity.UkeyLoginParm;
import com.sunyard.ssp.modules.user.service.IScUserRoleService;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.util.BytesUtil;
import com.sunyard.ssp.utils.FileUtil;
import com.sunyard.ssp.utils.IpUtil;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import com.sunyard.ssp.utils.UserUtil;
import com.sunyard.ssp.utils.sm2.SM2Util;
import com.sunyard.ssp.vo.UPublicKeyVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* <p>
* U盾认证管理
* </p>
*
* @author wp
* @since 2021-08-24
*/
@RestController
@Slf4j
@RequestMapping("/ushield")
@Api(description = "U盾认证管理接口", tags = "U盾")
@Transactional
public class ScUShieldController {
@Autowired
private IScUserRoleService iScUserRoleService;
@Autowired
private IScUserService userService;
@Autowired
private SecurityUtil securityUtil;
@Value("${file.path}")
private String filePath;
@Autowired
private FileUtil fileUtil;
@Autowired
private IParamConfService iParamConfService;
Pointer hDeviceHandle = null;
@Autowired
private SdkApiService sdkApiService;
ObjectMapper mapper = new ObjectMapper();
@Autowired
private IAuditLogService auditLogService;
@RequestMapping(value = "/ulogin", method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "U盾登录接口")
public Result<Object> ulogin(@RequestBody List<ULoginDto> uLoginDto, HttpServletRequest request) throws JsonProcessingException {
if (uLoginDto.isEmpty()) {
return new ResultUtil<Object>().setErrorMsg("参数不能为空");
}
AuditLog auditLog = new AuditLog();
ULoginDto uLoginDto1 = uLoginDto.get(0);
ScUser sysUser = userService.getById(uLoginDto1.getUserId());
auditLog.setCreateTime(LocalDateTime.now());
if (sysUser != null) {
auditLog.setOperatorName(sysUser.getRealname());
auditLog.setOperatorId(sysUser.getId());
}
auditLog.setOperateContent("ukey登录");
auditLog.setOperateType("登录");
List list = new ArrayList();
for (ULoginDto loginDto : uLoginDto) {
UkeyLoginParm ukeyLoginParm = new UkeyLoginParm(loginDto.getRa(), loginDto.getRb(), loginDto.getSignInfo(), loginDto.getUserId(), loginDto.getSignData(), loginDto.getRa() + loginDto.getRb() + loginDto.getSignData());
list.add(ukeyLoginParm);
}
auditLog.setRequestParam(mapper.writeValueAsString(list));
//Ip信息
auditLog.setIpAddress(IpUtil.getIpAddress(request));
auditLog.setIpInfo("未知");
//请求相关
auditLog.setRequestMothed(request.getMethod());
auditLog.setRequestPath(request.getRequestURI());
//判断当前启用登陆模式
Map map = iParamConfService.selectByItem(4);
if (CollectionUtil.isNotEmpty(map)) {
if (map.containsKey("loginMethod")) {
String loginMethod = String.valueOf(map.get("loginMethod"));
if (!"2".equals(loginMethod)) {
auditLog.setOperateResult("失败");
auditLogService.save(auditLog);
return new ResultUtil<Object>().setErrorMsg("当前不支持U盾登陆模式");
}
}
}
String uname = null;
for (int i = 0; i < uLoginDto.size(); i++) {
ULoginDto loginDto = uLoginDto.get(i);
String CertA = loginDto.getSignInfo();
Long userId = loginDto.getUserId();
String ra = loginDto.getRa();
String rb = loginDto.getRb();
String signData = loginDto.getSignData();
try {
UserUtil.verifyUfield(CertA, userId);
} catch (Exception e) {
auditLog.setOperateResult("失败");
auditLogService.save(auditLog);
return new ResultUtil<Object>().setErrorMsg(e.getMessage());
}
//查询账户绑定U盾公钥
ScUser user = userService.getById(userId);
if (uname == null) {
uname = user.getUsername();
}
//查询用户角色id集合
List<ScRole> roles = iScUserRoleService.findByUserId(userId);
List<Long> roldIds = new ArrayList<>();
if (null != roles && roles.size() > 0) {
roldIds = roles.stream().map(ScRole::getId).collect(Collectors.toList());
}
//排序
Long[] ids = roldIds.toArray(new Long[roldIds.size()]);
Arrays.sort(ids);
//拼接原始数据
StringBuilder sb = new StringBuilder();
sb.append(userId);
for (Long id : ids) {
sb.append(id);
}
sb.append(user.getUPublickey());
String orgData = sb.toString();
// 验证智能密码钥匙公钥
boolean verify = sdkApiService.PKCS1Verify(Alg.SM2, orgData.getBytes(), BytesUtil.hexString2Bytes(CertA));
if (!verify) {
auditLog.setOperateResult("失败");
auditLogService.save(auditLog);
return new ResultUtil<Object>().setErrorMsg("U盾登陆失败");
}
// 检查挑战数参数
boolean checkRb = checkRb(rb);
if (!checkRb ) {
auditLog.setOperateResult("失败");
auditLogService.save(auditLog);
return new ResultUtil<Object>().setErrorMsg("挑战数 Rb 无效");
}
sb = new StringBuilder();
sb.append(ra);
sb.append(rb);
sb.append(userId);
for (Long id : ids) {
sb.append(id);
}
sb.append(user.getUPublickey());
orgData = sb.toString();
// 验证 Token 签名
boolean siginVerify = SM2Util.verifyByPk(orgData, user.getUPublickey(), signData);
if (!siginVerify) {
auditLog.setOperateResult("失败");
auditLogService.save(auditLog);
return new ResultUtil<Object>().setErrorMsg("" + (i + 1) + "个ukey验签失败");
}
}
//验签通过颁发token
String accessToken = securityUtil.getToken(uname, false);
//使用外部公钥加密token
// byte[] bytes = sdkApiService.ASYMEncryptDataByOutPK(Alg.SM2,"CON.000000.ENDE.PK", accessToken);
// return new ResultUtil<Object>().setData(BytesUtil.encodeBase64(bytes));
auditLog.setOperateResult("成功");
auditLogService.save(auditLog);
return new ResultUtil<Object>().setData(accessToken);
}
private boolean checkRb(String rb) {
log.info("rb:" + rb);
if (rb == null || rb.length() != 32) {
return false;
}
return true;
}
@RequestMapping(value = "/urandom", method = RequestMethod.GET)
@ApiOperation(value = "返回随机数")
public Result<String> uRandomNumber() {
// PointerByReference phSessionHandle = new PointerByReference();
// // 打开会话
// int ret = CipherJna.INSTANCE.SDF_OpenSession(hDeviceHandle, phSessionHandle);
// if (ret != 0) {
// log.error("打开会话失败 错误码:{}", ret);
// return new ResultUtil<String>().setErrorMsg("打开会话失败");
// }
// byte[] radom = new byte[16];
// // 生成随机数
// ret = CipherJna.INSTANCE.SDF_GenerateRandom(phSessionHandle.getValue(), 16, radom);
// if (ret != 0){
// log.error("生成随机数失败 错误码:{}", ret);
// }
String urandom = UUID.randomUUID().toString().replace("-", "").toUpperCase();
return new ResultUtil<String>().setData(urandom);
}
@RequestMapping(value = "/bindUPublickey", method = RequestMethod.PUT)
@ApiOperation(value = "绑定U盾公钥/获取签名信息/更换绑定U盾公钥")
public Result<UPublicKeyVo> getUShieldInfo(@RequestParam("userId") @ApiParam(value = "用户id") Long userId,
@RequestParam("uPublicKey") @ApiParam(value = "U盾公钥") String uPublicKey) {
if (null == userId || StrUtil.isBlank(uPublicKey)) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("缺少必需字段");
}
//判断用户是否绑定了U盾
ScUser user = userService.getById(userId);
if (null == user) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("用户不存在");
}
if (StrUtil.isNotBlank(user.getUPublickey())) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("用户已绑定U盾");
}
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getUPublickey, uPublicKey));
if (CollectionUtil.isNotEmpty(list)) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("该U盾已绑定过用户");
}
//查询用户角色id集合
List<ScRole> roles = iScUserRoleService.findByUserId(userId);
List<Long> roldIds = new ArrayList<>();
if (null != roles && roles.size() > 0) {
roldIds = roles.stream().map(ScRole::getId).collect(Collectors.toList());
}
//排序
Long[] ids = roldIds.toArray(new Long[roldIds.size()]);
Arrays.sort(ids);
// 调用sdk 平台私钥对用户id+ids+uPublicKey 签名
StringBuilder sb = new StringBuilder();
sb.append(userId);
for (Long id : ids) {
sb.append(id);
}
sb.append(uPublicKey);
String orgData = sb.toString();
byte[] bytes = sdkApiService.PKCS1Sign(Alg.SM2, orgData.getBytes());
UPublicKeyVo uPublicKeyVo = new UPublicKeyVo(userId, ids, uPublicKey, "", BytesUtil.bytes2HexString(bytes));
//更新用户绑定U盾公钥
user.setUPublickey(uPublicKey);
boolean b = userService.updateById(user);
if (!b) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("用户绑定U盾失败");
}
return new ResultUtil<UPublicKeyVo>().setData(uPublicKeyVo);
}
@RequestMapping(value = "/init/bindUPublickey", method = RequestMethod.PUT)
@ApiOperation(value = "绑定U盾公钥/获取签名信息/更换绑定U盾公钥")
public Result<UPublicKeyVo> bindUPublickey(@RequestParam("userId") @ApiParam(value = "用户id") Long userId,
@RequestParam("uPublicKey") @ApiParam(value = "U盾公钥") String uPublicKey) {
try {
if (null == userId || StrUtil.isBlank(uPublicKey)) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("缺少必需字段");
}
//判断用户是否绑定了U盾
ScUser user = userService.getById(userId);
if (null == user) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("用户不存在");
}
if (StrUtil.isNotBlank(user.getUPublickey())) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("用户已绑定U盾");
}
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getUPublickey, uPublicKey));
if (CollectionUtil.isNotEmpty(list)) {
return new ResultUtil<UPublicKeyVo>().setErrorMsg("该U盾已绑定过用户");
}
//查询用户角色id集合
List<ScRole> roles = iScUserRoleService.findByUserId(userId);
List<Long> roldIds = new ArrayList<>();
if (null != roles && roles.size() > 0) {
roldIds = roles.stream().map(ScRole::getId).collect(Collectors.toList());
}
//排序
Long[] ids = roldIds.toArray(new Long[roldIds.size()]);
Arrays.sort(ids);
// 调用sdk 平台私钥对用户id+ids+uPublicKey 签名
StringBuilder sb = new StringBuilder();
sb.append(userId);
for (Long id : ids) {
sb.append(id);
}
sb.append(uPublicKey);
String orgData = sb.toString();
byte[] bytes = sdkApiService.PKCS1Sign(Alg.SM2, orgData.getBytes());
UPublicKeyVo uPublicKeyVo = new UPublicKeyVo(userId, ids, uPublicKey, "", BytesUtil.bytes2HexString(bytes));
//更新用户绑定U盾公钥
user.setUPublickey(uPublicKey);
boolean b = userService.updateById(user);
if (!b) {
userService.remove(new QueryWrapper<>());
return new ResultUtil<UPublicKeyVo>().setErrorMsg("用户绑定U盾失败");
}
return new ResultUtil<UPublicKeyVo>().setData(uPublicKeyVo);
} catch (Exception e) {
e.printStackTrace();
userService.remove(new QueryWrapper<>());
return new ResultUtil<UPublicKeyVo>().setErrorMsg("用户绑定U盾失败");
}
}
@RequestMapping(value = "/clearUPublickey", method = RequestMethod.PUT)
@ApiOperation(value = "解除绑定U盾公钥")
public Result<Object> clearUPublickey(@RequestParam("userId") @ApiParam(value = "用户id") Long userId) {
//查询用户
ScUser user = userService.getById(userId);
if (null == user) {
return new ResultUtil<Object>().setErrorMsg("用户不存在");
}
if (StrUtil.isBlank(user.getUPublickey())) {
return new ResultUtil<Object>().setErrorMsg("用户未绑定U盾");
}
user.setUPublickey("");
boolean b = userService.updateById(user);
if (!b) {
return new ResultUtil<Object>().setErrorMsg("解除绑定公钥失败");
}
return new ResultUtil<Object>().setData("解除绑定公钥成功");
}
@RequestMapping(value = "/dowloadFile", method = RequestMethod.GET)
@ApiOperation(value = "下载U盾插件接口")
public void dowloadFile(@RequestParam("fileName") @ApiParam(value = "文件名") String fileName,
HttpServletResponse response) {
String url = filePath + "/" + fileName;
File file = new File(url);
FileInputStream i = null;
OutputStream o = null;
try {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (file.exists()) {
try {
i = new FileInputStream(file);
o = response.getOutputStream();
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = i.read(buf)) > 0) {
o.write(buf, 0, bytesRead);
o.flush();
}
i.close();
o.close();
} catch (IOException e) {
log.error(e.toString());
throw new RuntimeException("读取文件出错");
}
}
}
}

View File

@ -0,0 +1,781 @@
package com.sunyard.ssp.modules.user.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.common.constant.SecurityConstant;
import com.sunyard.ssp.common.enums.UserHeaderTypeEnum;
import com.sunyard.ssp.modules.user.entity.ScDepartment;
import com.sunyard.ssp.modules.user.entity.ScDepartmentHeader;
import com.sunyard.ssp.modules.user.entity.ScPermission;
import com.sunyard.ssp.modules.user.entity.ScRole;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.entity.ScUserRole;
import com.sunyard.ssp.modules.user.service.IScDepartmentHeaderService;
import com.sunyard.ssp.modules.user.service.IScDepartmentService;
import com.sunyard.ssp.modules.user.service.IScRoleService;
import com.sunyard.ssp.modules.user.service.IScUserRoleService;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.modules.user.utils.validator.UserValidator;
import com.sunyard.ssp.redis.RedisObjectOperation;
import com.sunyard.ssp.utils.PageUtil;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import com.sunyard.ssp.utils.UsernameUtil;
import com.sunyard.ssp.vo.SearchVo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static com.sunyard.ssp.common.constant.CommonConstant.DEFAULT_USER_ROOT_ID;
import static com.sunyard.ssp.common.constant.CommonConstant.DEPARTMENT_ROOT_ID;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-11
*/
@RestController
@Slf4j
@RequestMapping("/user")
@Transactional
public class ScUserController {
@Autowired
UserValidator userValidator;
@Autowired
SecurityUtil securityUtil;
@Autowired
StringRedisTemplate redisTemplate;
@Autowired
private RedisObjectOperation redisObjectOperation;
@Autowired
IScUserService userService;
@Autowired
IScUserRoleService userRoleService;
@Autowired
IScDepartmentService departmentService;
@Autowired
IScDepartmentHeaderService departmentHeaderService;
@Autowired
IScRoleService roleService;
@RequestMapping(value = "/info",method = RequestMethod.GET)
public Result<ScUser> getUserInfo(){
ScUser u = securityUtil.getCurrUser();
return new ResultUtil<ScUser>().setData(u);
}
@RequestMapping(value = "/infoResult", method = RequestMethod.GET)
public Result<Object> getUserInfoResult(@RequestParam List<String> powers) {
ScUser u = securityUtil.getCurrUser();
// 清除持久上下文环境 避免后面语句导致持久化
List<String> collect = u.getPermissions().stream().map(ScPermission::getTitle).collect(Collectors.toList());
List<String> permissions = new ArrayList<>();
for (String power : powers) {
boolean contains = collect.contains(power);
if ( contains ){
permissions.add(power);
}
}
return new ResultUtil<Object>().setData(permissions);
}
@RequestMapping(value = "/initialization/check", method = RequestMethod.GET)
public Result<Object> initializationCheck() {
QueryWrapper<ScUser> userQueryWrapper = new QueryWrapper<>();
userQueryWrapper.like("USERNAME", "admin%");
List<ScUser> list = userService.list(userQueryWrapper);
for (ScUser scUser : list) {
if (scUser.getUPublickey()!=null) {
return new ResultUtil<Object>().setData(false);
}
}
return new ResultUtil<Object>().setData(true);
}
@RequestMapping(value = "/edit",method = RequestMethod.POST)
public Result<Object> editOwn(@ModelAttribute("user") ScUser u){
if(DEFAULT_USER_ROOT_ID.equals(u.getId())){
String resStr = "默认用户禁止编辑";
if(u.getStatus() != null){
resStr = "默认用户禁止禁用";
}
return new ResultUtil<Object>().setErrorMsg(resStr);
}
try {
ScUser old = securityUtil.getCurrUser();
u.setUsername(old.getUsername());
u.setPassword(old.getPassword());
u.setId(securityUtil.getCurrUser().getId());
u.setPassUpdateTime(old.getPassUpdateTime());
//若修改手机或邮箱,判断是否合法,非法就不改
if(StrUtil.isNotBlank(u.getTel())){
if (!UsernameUtil.Mobile(u.getTel())){
return new ResultUtil<Object>().setErrorMsg("手机号格式错误");
}
u.setTel(old.getTel());
}
if(StrUtil.isNotBlank(u.getEmail())){
if (!UsernameUtil.Email(u.getEmail())){
return new ResultUtil<Object>().setErrorMsg("邮箱格式错误");
}
u.setEmail(old.getEmail());
}
// 若修改了手机和邮箱判断是否唯一
if ( StrUtil.isNotBlank(u.getTel())&&!old.getTel().equals(u.getTel()) ){
if(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getTel,u.getTel()))!=null){
return new ResultUtil<Object>().setErrorMsg("该手机号已绑定其他账户");
}
}
if ( StrUtil.isNotBlank(u.getEmail())&&!old.getEmail().equals(u.getEmail()) ){
if(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getEmail,u.getEmail()))!=null){
return new ResultUtil<Object>().setErrorMsg("该邮箱已绑定其他账户");
}
}
/*if(StringUtils.isNotBlank(u.getPosition()) && !u.getPosition().equals(old.getPosition())){
throw new KeeperException("职位仅限管理员修改");
}*/
if(!userService.updateById(u)){
return new ResultUtil<Object>().setErrorMsg("修改失败");
}
return new ResultUtil<Object>().setSuccessMsg("修改成功");
} catch ( Exception e ){
log.error("用户修改个人信息失败", e.getMessage() , e);
return new ResultUtil<Object>().setErrorMsg("修改失败");
}
}
@RequestMapping(value = "/admin/edit",method = RequestMethod.POST)
public Result<Object> edit(@ModelAttribute("user") ScUser u,
@RequestParam(required = false) Long[] roleIds){
if(DEFAULT_USER_ROOT_ID.equals(u.getId())){
String resStr = "默认用户禁止编辑";
if(u.getStatus() != null){
resStr = "默认用户禁止禁用";
}
return new ResultUtil<Object>().setErrorMsg(resStr);
}
try {
if( StrUtil.isBlank(u.getUsername()) || StrUtil.isBlank(u.getUsername())){
return new ResultUtil<Object>().setErrorMsg("缺少必需字段");
}
ScUser old = userService.getById(u.getId());
//若修改了用户名
if(!old.getUsername().equals(u.getUsername())){
return new ResultUtil<Object>().setErrorMsg("用户名禁止修改");
}
//若修改手机或邮箱,判断是否合法,非法就不改
if(StrUtil.isNotBlank(u.getTel()) && !UsernameUtil.Mobile(u.getTel())){
u.setTel(old.getTel());
}
if(StrUtil.isNotBlank(u.getEmail()) && !UsernameUtil.Email(u.getEmail())){
u.setEmail(old.getTel());
}
// 若修改了手机和邮箱判断是否唯一
if ( StrUtil.isNotBlank(u.getTel())&&!u.getTel().equals(old.getTel()) ){
if(CollectionUtils.isNotEmpty(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getTel,u.getTel())))){
return new ResultUtil<Object>().setErrorMsg("该手机号已绑定其他账户");
}
}
if ( StrUtil.isNotBlank(u.getEmail())&&!u.getEmail().equals(old.getEmail()) ){
if(CollectionUtils.isNotEmpty(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getEmail,u.getEmail())))){
return new ResultUtil<Object>().setErrorMsg("该邮箱已绑定其他账户");
}
}
u.setPassword(old.getPassword());
u.setPassUpdateTime(old.getPassUpdateTime());
if(!userService.updateById(u)){
return new ResultUtil<Object>().setErrorMsg("修改失败");
}
//删除该用户角色
userRoleService.remove(new QueryWrapper<ScUserRole>().lambda().eq(ScUserRole::getUserId,u.getId()));
if(roleIds!=null&&roleIds.length>0){
//新角色
for(Long roleId : roleIds){
ScUserRole ur = new ScUserRole();
ur.setRoleId(roleId);
ur.setUserId(u.getId());
userRoleService.save(ur);
}
}
//手动删除缓存
String loginTimekey = "loginTimeLimit:"+u.getUsername();
String flagKey = "loginFailFlag:"+u.getUsername();
redisTemplate.delete(loginTimekey);
redisTemplate.delete(flagKey);
redisTemplate.delete("userRole::"+u.getId());
redisTemplate.delete("userRole::depIds:"+u.getId());
return new ResultUtil<Object>().setSuccessMsg("修改成功");
} catch (Exception e){
return new ResultUtil<Object>().setErrorMsg(e.getMessage());
}
}
@InitBinder("user")
public void initUserBinder(WebDataBinder binder) {
binder.replaceValidators(userValidator);
}
@RequestMapping(value = "/modifyPass", method = RequestMethod.POST)
public Result<Object> modifyPass(@RequestParam String password,
@RequestParam String newPass,
@RequestParam String passStrength) {
ScUser user = securityUtil.getCurrUser();
if (!new BCryptPasswordEncoder().matches(password, user.getPassword())) {
return new ResultUtil<Object>().setErrorMsg("旧密码不正确");
}
String newEncryptPass = new BCryptPasswordEncoder().encode(newPass);
user.setPassword(newEncryptPass);
user.setPassUpdateTime(LocalDateTime.now());
if(!userService.updateById(user)){
return new ResultUtil<Object>().setErrorMsg("修改密码失败");
}
//手动更新缓存
redisTemplate.delete("user::" + user.getUsername());
return new ResultUtil<Object>().setSuccessMsg("修改密码成功");
}
@RequestMapping(value = "/reset", method = RequestMethod.POST)
public Result<Object> reset() {
UpdateWrapper<ScUser> updateWrapper = new UpdateWrapper<ScUser>();
// 将绑定的UKEY证书都清空
updateWrapper.set("U_PUBLICKEY", null);
userService.update(updateWrapper);
return new ResultUtil<Object>().setSuccessMsg("重置成功");
}
@RequestMapping(value = "/admin/modifyPass", method = RequestMethod.POST)
public Result<Object> adminModifyPass(@RequestParam String newPass, @RequestParam String userId) {
ScUser user = userService.getById(userId);
if(user == null){
return new ResultUtil<Object>().setErrorMsg("用户不存在");
}
String newEncryptPass = new BCryptPasswordEncoder().encode(newPass);
user.setPassword(newEncryptPass);
user.setPassUpdateTime(LocalDateTime.now());
if(!userService.updateById(user)){
return new ResultUtil<Object>().setErrorMsg("修改密码失败");
}
//手动更新缓存
String loginTimekey = "loginTimeLimit:"+user.getUsername();
String flagKey = "loginFailFlag:"+user.getUsername();
redisTemplate.delete(loginTimekey);
redisTemplate.delete(flagKey);
redisTemplate.delete("user::" + user.getUsername());
return new ResultUtil<Object>().setSuccessMsg("修改密码成功");
}
@RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
public Result<org.springframework.data.domain.Page<ScUser>> getByCondition(@ModelAttribute() ScUser user,
@ModelAttribute SearchVo searchVo,
@ModelAttribute PageVo pageVo) {
org.springframework.data.domain.Page<ScUser> page = userService.findByCondition(user, searchVo, PageUtil.initPage(pageVo));
for (ScUser u : page.getContent()) {
// 关联部门
if (u.getOrganizationId() != null) {
ScDepartment department = departmentService.getById(u.getOrganizationId());
u.setDepartmentTitle(department.getTitle());
}
//记录用户是否为部门负责人
Integer type = departmentHeaderService.getHeaderTypeByUserId(u.getId());
u.setHeaderTypeKey(type);
u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));
// 关联角色
List<ScRole> list = userRoleService.findByUserId(u.getId());
u.setRoles(list);
// 清除持久上下文环境 避免后面语句导致持久化
u.setPassword(null);
}
return new ResultUtil<org.springframework.data.domain.Page<ScUser>>().setData(page);
}
@RequestMapping(value = "/searchByName", method = RequestMethod.GET)
@ApiOperation(value = "通过用户名搜索用户")
public Result<List<ScUser>> searchByName(@RequestParam String username) throws UnsupportedEncodingException {
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda()
.like(ScUser::getUsername, "%" + URLDecoder.decode(username, "utf-8") + "%")
.eq(ScUser::getStatus, CommonConstant.STATUS_NORMAL));
return new ResultUtil<List<ScUser>>().setData(list);
}
@RequestMapping(value = "/searchByNickName", method = RequestMethod.GET)
@ApiOperation(value = "通过昵称搜索用户")
public Result<List<ScUser>> searchByNickName(@RequestParam String nickName) throws UnsupportedEncodingException {
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda()
.like(ScUser::getRealname, "%" + URLDecoder.decode(nickName, "utf-8") + "%")
.eq(ScUser::getStatus, CommonConstant.STATUS_NORMAL));
for (ScUser u : list) {
// 关联部门
if (u.getOrganizationId() != null) {
ScDepartment department = departmentService.getById(u.getOrganizationId());
u.setDepartmentTitle(department.getTitle());
}
u.setPassword(null);
}
return new ResultUtil<List<ScUser>>().setData(list);
}
@RequestMapping(value = "/getByUserName/{username}", method = RequestMethod.GET)
@ApiOperation(value = "通过用户名获取用户")
public Result<ScUser> getByUserName(@PathVariable String username) {
return new ResultUtil<ScUser>().setData(userService.findByUsername(username));
}
@RequestMapping(value = "/getAll", method = RequestMethod.GET)
@ApiOperation(value = "获取全部用户数据")
public Result<List<ScUser>> getByCondition() {
List<ScUser> list = userService.list();
for (ScUser u : list) {
// 关联部门
if (u.getOrganizationId() != null) {
ScDepartment department = departmentService.getById(u.getOrganizationId());
u.setDepartmentTitle(department.getTitle());
}
u.setPassword(null);
//记录用户是否为部门负责人
Integer type = departmentHeaderService.getHeaderTypeByUserId(u.getId());
u.setHeaderTypeKey(type);
u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));
}
return new ResultUtil<List<ScUser>>().setData(list);
}
@RequestMapping(value = "/selectList", method = RequestMethod.GET)
@ApiOperation(value = "获取全部用户数据")
public Result<List<ScUser>> selectList(@RequestParam(required = false) String nickName) {
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getRealname,nickName));
for (ScUser u : list) {
u.setPassword(null);
u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(u.getHeaderTypeKey()));
}
return new ResultUtil<List<ScUser>>().setData(list);
}
@RequestMapping(value = "/admin/add", method = RequestMethod.POST)
@ApiOperation(value = "添加用户")
public Result<Object> regist(@ModelAttribute("user") @Validated ScUser u,
@RequestParam(required = false) Long[] roleIds) {
try {
u.setPassUpdateTime(LocalDateTime.now());
userService.regist(u, roleIds);
} catch (Exception e) {
return new ResultUtil<Object>().setErrorMsg(e.getMessage());
}
return new ResultUtil<Object>().setSuccessMsg("添加成功");
}
@RequestMapping(value = "/admin/init", method = RequestMethod.POST)
@ApiOperation(value = "初始化admin")
public Result<Object> init(@ModelAttribute("user") @Validated ScUser u,
@RequestParam(required = false) Long[] roleIds) {
try {
u.setPassUpdateTime(LocalDateTime.now());
userService.regist(u, roleIds);
} catch (Exception e) {
userService.remove(new QueryWrapper<>());
return new ResultUtil<Object>().setErrorMsg(e.getMessage());
}
return new ResultUtil<Object>().setData(u.getId(),"添加成功");
}
@RequestMapping(value = "/admin/disable/{userId}", method = RequestMethod.POST)
@ApiOperation(value = "后台禁用用户")
public Result<Object> disable(@ApiParam("用户唯一id标识") @PathVariable String userId) {
if(DEFAULT_USER_ROOT_ID.equals(Long.valueOf(userId))){
return new ResultUtil<Object>().setErrorMsg("默认用户禁止禁用");
}
ScUser user = userService.getById(userId);
if (user == null) {
return new ResultUtil<Object>().setErrorMsg("通过userId获取用户失败");
}
user.setStatus(CommonConstant.USER_STATUS_LOCK);
userService.updateById(user);
//手动更新缓存
redisTemplate.delete("user::" + user.getUsername());
String oldToken = redisTemplate.opsForValue().get(SecurityConstant.USER_TOKEN + user.getUsername());
if(StrUtil.isNotBlank(oldToken)){
redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
}
return new ResultUtil<Object>().setSuccessMsg("操作成功");
}
@RequestMapping(value = "/admin/enable/{userId}", method = RequestMethod.POST)
@ApiOperation(value = "后台启用用户")
public Result<Object> enable(@ApiParam("用户唯一id标识") @PathVariable String userId) {
try {
ScUser user = userService.getById(userId);
if (user == null) {
return new ResultUtil<Object>().setErrorMsg("通过userId获取用户失败");
}
user.setStatus(CommonConstant.USER_STATUS_NORMAL);
userService.updateById(user);
//手动更新缓存
String loginTimekey = "loginTimeLimit:"+user.getUsername();
String flagKey = "loginFailFlag:"+user.getUsername();
redisTemplate.delete(loginTimekey);
redisTemplate.delete(flagKey);
redisTemplate.delete("user::" + user.getUsername());
return new ResultUtil<Object>().setSuccessMsg("操作成功");
} catch (Exception e) {
log.error("启用用户失败", e.getMessage(), e);
return new ResultUtil<Object>().setErrorMsg("启用用户失败");
}
}
@RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
@ApiOperation(value = "批量通过ids删除")
public Result<Object> delAllByIds(@PathVariable String[] ids) {
try {
ScUser currUser = securityUtil.getCurrUser();
for (String id : ids) {
if(DEFAULT_USER_ROOT_ID.equals(Long.valueOf(id))){
return new ResultUtil<Object>().setErrorMsg("默认用户禁止删除");
}
if(currUser.getId().toString().equals(id)){
return new ResultUtil<Object>().setErrorMsg("当前用户禁止删除");
}
ScUser u = userService.getById(id);
//删除相关缓存
redisTemplate.delete("user::" + u.getUsername());
redisTemplate.delete("userRole::" + u.getId());
redisTemplate.delete("userRole::depIds:" + u.getId());
redisTemplate.delete("permission::userMenuList:" + u.getId());
String oldToken = redisTemplate.opsForValue().get(SecurityConstant.USER_TOKEN + u.getUsername());
if(StrUtil.isNotBlank(oldToken)){
redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
}
// TODO: 2020/7/28 获取的都有问题有时间在改
Set<String> keys = redisObjectOperation.keys("department::*");
redisTemplate.delete(keys);
userService.removeById(id);
//删除关联角色
userRoleService.remove(new QueryWrapper<ScUserRole>().lambda().eq(ScUserRole::getUserId,id));
// 删除关联部门负责人
departmentHeaderService.remove(new QueryWrapper<ScDepartmentHeader>().lambda().eq(ScDepartmentHeader::getUserId,id));
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
} catch (Exception e) {
log.error("删除用户失败", e.getMessage(), e);
return new ResultUtil<Object>().setErrorMsg("删除用户失败");
}
}
@RequestMapping(value = "/importData", method = RequestMethod.POST)
@ApiOperation(value = "导入用户数据")
public Result<Object> importData(@RequestBody List<ScUser> users) {
List<Integer> errors = new ArrayList<>();
List<String> reasons = new ArrayList<>();
Map<String, ScDepartment> departmentMap = new HashMap<>();
departmentService.list().forEach(department -> {
departmentMap.put(department.getTitle(), department);
});
int count = 0;
for (ScUser u : users) {
count++;
// 验证用户名密码不为空
if (StrUtil.isBlank(u.getUsername()) || StrUtil.isBlank(u.getPassword())) {
errors.add(count);
reasons.add("用户名或密码为空");
continue;
}
// 验证用户名唯一
if (userService.findByUsername(u.getUsername()) != null) {
errors.add(count);
reasons.add("用户名已存在");
continue;
}
//删除缓存
/*redisTemplate.delete("user::" + u.getUsername());
String s = jmessageUtils.registerUsers(u.getId(), u.getPassword(), u.getUsername(), u.getAvatar());
if (null != s && !"".equals(s)) {
u.setJmessageName(s);
} else {
return new ResultUtil<Object>().setErrorMsg("添加失败");
}*/
// 加密密码
u.setPassword(DigestUtils.md5DigestAsHex(u.getPassword().getBytes()));
u.setPassUpdateTime(LocalDateTime.now());
// 获取部门id
if(StrUtil.isNotBlank(u.getDepartmentTitle())){
if(departmentMap.containsKey(u.getDepartmentTitle())) {
u.setOrganizationId(departmentMap.get(u.getDepartmentTitle()).getId());
} else {
reasons.add("部门不存在");
}
}
// 验证部门id正确性
if (u.getOrganizationId() != null) {
try {
ScDepartment d = departmentService.getById(u.getOrganizationId());
log.info(d.toString());
} catch (Exception e) {
errors.add(count);
reasons.add("部门id不存在");
continue;
}
}
if (u.getStatus() == null) {
u.setStatus(CommonConstant.USER_STATUS_NORMAL);
}
//todo
// 分配默认角色
Long[] roleStrArray = new Long[0];
if (u.getDefaultRole() != null && u.getDefaultRole() == 1) {
List<ScRole> roleList = roleService.list(new QueryWrapper<ScRole>().lambda().eq(ScRole::getDefaultRole,true));
roleStrArray = new Long[roleList.size()];
roleList.stream().map(ScRole::getId).collect(Collectors.toList()).toArray(roleStrArray);
}
// 保存数据
try {
userService.regist(u,roleStrArray);
} catch (Exception e) {
return new ResultUtil<Object>().setErrorMsg(e.getMessage());
}
}
int successCount = users.size() - errors.size();
String successMessage = "全部导入成功,共计 " + successCount + " 条数据";
String failMessage = "导入成功 " + successCount + " 条,失败 " + errors.size() + " 条数据。<br>" +
"" + errors.toString() + " 行数据导入出错,错误原因分别为:<br>" + reasons.toString();
String message = "";
if (errors.size() == 0) {
message = successMessage;
} else {
message = failMessage;
}
return new ResultUtil<Object>().setSuccessMsg(message);
}
@RequestMapping(value = "/getVerifier", method = RequestMethod.GET)
@ApiOperation(value = "获取可选复核用户列表")
public Result<List<ScUser>> getVerifier() {
ScUser u = securityUtil.getCurrUser();
/*if(u.getOrganizationId() == null || u.getOrganizationId().equals(DEPARTMENT_ROOT_ID)){
return new ResultUtil<List<ScUser>>()
.setData(userService.list(new QueryWrapper<ScUser>().lambda()
.eq(ScUser::getOrganizationId, DEPARTMENT_ROOT_ID)
.notIn(ScUser::getId, new ArrayList<Long>(){{add(u.getId());}})));
}
ScDepartment currDepartment = departmentService.getById(u.getOrganizationId());
if(currDepartment == null){
return new ResultUtil<List<ScUser>>().setErrorMsg("无法找到当前用户所属部门");
}
if(currDepartment.getParentId().equals(DEPARTMENT_ROOT_ID)){
return new ResultUtil<List<ScUser>>()
.setData(userService.list(new QueryWrapper<ScUser>().lambda()
.eq(ScUser::getOrganizationId, currDepartment.getId())
.notIn(ScUser::getId, new ArrayList<Long>(){{add(u.getId());}})));
}
ScDepartment d = departmentService.getById(currDepartment.getParentId());
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda()
.eq(ScUser::getOrganizationId, d.getId()));*/
List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().ne(ScUser::getId, u.getId()));
return new ResultUtil<List<ScUser>>().setData(list);
}
@RequestMapping(value = "/verify", method = RequestMethod.POST)
@ApiOperation(value = "复核")
public Result<Object> verify(Long userId, String password) {
ScUser verifier = userService.getById(userId);
if (!new BCryptPasswordEncoder().matches(password, verifier.getPassword())) {
return new ResultUtil<Object>().setErrorMsg("密码不正确");
}
return new ResultUtil<Object>().setSuccessMsg("核验成功");
}
@RequestMapping(value = "/getByDepartmentId", method = RequestMethod.GET)
@ApiOperation(value = "根据部门id获取用户列表")
public Result<List<ScUser>> getByCondition(@RequestParam Long departmentId, @RequestParam(defaultValue = "false", required = false) boolean cascade) {
List<ScUser> list = new LinkedList<>();
if (cascade) {
if (DEPARTMENT_ROOT_ID.equals(departmentId)) {
return getByCondition();
}
Set<ScUser> userSet = new HashSet<>();
List<ScDepartment> departments = new LinkedList<>(findDepartmentByParentId(departmentId));
departments.add(departmentService.getById(departmentId));
departments.forEach(department -> {
userSet.addAll(findUserByDepartment(department.getId()));
});
if(userSet.contains(null)){
userSet.remove(null);
}
list.addAll(userSet);
} else {
list.addAll(findUserByDepartment(departmentId));
}
return new ResultUtil<List<ScUser>>().setData(list);
}
@RequestMapping(value = "/unlock",method = RequestMethod.POST)
@ApiOperation(value = "解锁验证密码")
public Result<Object> unLock(@RequestParam String password){
ScUser u = securityUtil.getCurrUser();
if(!new BCryptPasswordEncoder().matches(password, u.getPassword())){
return new ResultUtil<Object>().setErrorMsg("密码不正确");
}
return new ResultUtil<Object>().setData(null);
}
private Set<ScDepartment> findDepartmentByParentId(Long parentId) {
Set<ScDepartment> departmentSet = new HashSet<>();
departmentSet.addAll(departmentService.findByParentIdOrderBySortOrder(parentId, false));
departmentSet.forEach(department -> {
departmentSet.addAll(findDepartmentByParentId(department.getId()));
});
return departmentSet;
}
private Set<ScUser> findUserByDepartment(Long departmentId) {
Set<ScUser> set = new HashSet<>();
set.addAll(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getOrganizationId,departmentId)));
set.forEach(u -> {
u.setPassword(null);
//记录用户是否为部门负责人
Integer type = departmentHeaderService.getHeaderTypeByUserId(u.getId());
u.setHeaderTypeKey(type);
u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));
//隐藏隐私字段
/*UserPrivacyUtils.hideUserPrivacy(u);*/
});
return set;
}
/*@RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
@ApiOperation(value = "多条件分页获取用户列表")
public Result<org.springframework.data.domain.Page<ScUser>> getByCondition(@ModelAttribute("user") ScUser user,
@ModelAttribute SearchVo searchVo,
@ModelAttribute PageVo pageVo) {
org.springframework.data.domain.Page<ScUser> page = userService.findByCondition(user, searchVo, PageUtil.initPage(pageVo));
for (ScUser u : page.getContent()) {
// 关联部门
if (u.getOrganizationId() != null) {
ScDepartment department = departmentService.getById(u.getOrganizationId());
u.setDepartmentTitle(department.getTitle());
}
//记录用户是否为部门负责人
Integer type = departmentHeaderService.getHeaderTypeByUserId(user.getId());
user.setHeaderTypeKey(type);
user.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));
// 关联角色
List<ScRole> list = userRoleService.findByUserId(u.getId());
u.setRoles(list);
// 清除持久上下文环境 避免后面语句导致持久化
*//*entityManager.clear();*//*
u.setPassword(null);
//隐藏隐私字段
*//*UserPrivacyUtils.hideUserPrivacy(u);*//*
}
return new ResultUtil<org.springframework.data.domain.Page<User>>().setData(page);
}*/
}

View File

@ -0,0 +1,96 @@
package com.sunyard.ssp.modules.user.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.modules.user.entity.ScUserRole;
import com.sunyard.ssp.modules.user.service.IScUserRoleService;
import com.sunyard.ssp.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author tsz
* @since 2020-03-11
*/
@RestController
@Slf4j
@RequestMapping("/userRole")
@Transactional
public class ScUserRoleController {
@Autowired
IScUserRoleService iScUserRoleService;
@RequestMapping(value = "/getById",method = RequestMethod.GET)
@ResponseBody
public Result<ScUserRole> get(@RequestParam String id){
ScUserRole entity = iScUserRoleService.getById(id);
return new ResultUtil<ScUserRole>().setData(entity);
}
@RequestMapping(value = "/getAll",method = RequestMethod.GET)
@ResponseBody
public Result<List<ScUserRole>> getAll(){
List<ScUserRole> list = iScUserRoleService.list();
return new ResultUtil<List<ScUserRole>>().setData(list);
}
@RequestMapping(value = "/page",method = RequestMethod.GET)
@ResponseBody
public Result<IPage<ScUserRole>> getByPage(@ModelAttribute PageVo page){
Page<ScUserRole> data = new Page<>( page.getPageNumber(),page.getPageSize());
IPage<ScUserRole> iPage = iScUserRoleService.page(data);
return new ResultUtil<IPage<ScUserRole>>().setData(iPage);
}
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
public Result<ScUserRole> save(@ModelAttribute ScUserRole entity){
boolean e = iScUserRoleService.save(entity);
if ( !e ){
return new ResultUtil<ScUserRole>().setErrorMsg("添加失败");
}
return new ResultUtil<ScUserRole>().setSuccessMsg("添加成功");
}
@RequestMapping(value = "/update",method = RequestMethod.PUT)
@ResponseBody
public Result<UpdateChainWrapper<ScUserRole>> update(@ModelAttribute ScUserRole entity){
boolean e = iScUserRoleService.updateById(entity);
if ( !e ){
return new ResultUtil<UpdateChainWrapper<ScUserRole>>().setErrorMsg("更新失败");
}
return new ResultUtil<UpdateChainWrapper<ScUserRole>>().setSuccessMsg("更新成功");
}
@RequestMapping(value = "/deleteByIds",method = RequestMethod.DELETE)
@ResponseBody
public Result<Object> delAllByIds(@RequestParam String[] ids){
for(String id:ids){
iScUserRoleService.removeById(id);
}
return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
}
}

View File

@ -0,0 +1,70 @@
package com.sunyard.ssp.modules.user.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author tsz
* @since 2020-03-12
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("SC_DEPARTMENT")
public class ScDepartment implements Serializable {
private static final long serialVersionUID = 1L;
@TableId("ID")
private Long id;
@TableField("PARENT_ID")
private Long parentId;
@TableField("SORT_ORDER")
private Double sortOrder;
@TableField("STATUS")
private Integer status;
@TableField("TITLE")
private String title;
@TableField("IS_PARENT")
private Boolean isParent;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "父节点名称")
private String parentTitle;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "主负责人")
private List<Long> mainHeader;
@Transient
@TableField(exist=false)
@ApiModelProperty(value = "副负责人")
private List<Long> viceHeader;
public boolean isParent(){
if(this.isParent == null){
return false;
}
return this.isParent;
}
}

Some files were not shown because too many files have changed in this diff Show More