更换git仓库后的提交

This commit is contained in:
2025-09-25 10:57:37 +08:00
parent 9e8662efc0
commit 5c8088e808
741 changed files with 62243 additions and 0 deletions

175
carry_capacity/pom.xml Normal file
View File

@@ -0,0 +1,175 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.njcn.product</groupId>
<artifactId>CN_Product</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.njcn</groupId>
<artifactId>carry_capacity</artifactId>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>com.njcn</groupId>-->
<!-- <artifactId>njcn-common</artifactId>-->
<!-- <version>0.0.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.njcn</groupId>-->
<!-- <artifactId>mybatis-plus</artifactId>-->
<!-- <version>0.0.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.njcn</groupId>-->
<!-- <artifactId>spingboot2.3.12</artifactId>-->
<!-- <version>2.3.12</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.njcn</groupId>
<artifactId>common-redis</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>com.njcn</groupId>
<artifactId>common-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.njcn</groupId>-->
<!-- <artifactId>common-core</artifactId>-->
<!-- <version>${project.version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.njcn</groupId>
<artifactId>common-db</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>pqs-influx</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version> <!-- 使用最新稳定版 -->
</dependency>
<!-- OAuth2 认证服务器-->
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<!--图形验证码-->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>common-web</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>common-microservice</artifactId>
<groupId>com.njcn</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
<resources>
<!-- 对大多数资源文件进行过滤 -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<!-- 排除二进制文件,防止过滤破坏文件格式 -->
<exclude>**/*.jks</exclude>
<exclude>**/*.keystore</exclude>
<exclude>**/*.p12</exclude>
</excludes>
</resource>
<!-- 对二进制文件不进行过滤 -->
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.jks</include>
<include>**/*.keystore</include>
<include>**/*.p12</include>
</includes>
</resource>
<!-- 保留原有的Java目录下XML文件配置 -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@@ -0,0 +1,33 @@
package com.njcn.product;
import com.njcn.web.advice.ResponseAdvice;
import com.njcn.web.config.FeignConfig;
import com.njcn.web.exception.GlobalBusinessExceptionHandler;
import com.njcn.web.service.ILogService;
import com.njcn.web.service.impl.LogServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.FilterType;
@Slf4j
@DependsOn("proxyMapperRegister")
@SpringBootApplication(scanBasePackages = "com.njcn")
@MapperScan("com.njcn.**.mapper")
@ComponentScan(
basePackages = "com.njcn",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes ={ FeignConfig.class, ILogService.class, GlobalBusinessExceptionHandler.class, ResponseAdvice.class}
)
)
public class CarryCapacityApplication {
public static void main(String[] args) {
SpringApplication.run(CarryCapacityApplication.class, args);
}
}

View File

@@ -0,0 +1,234 @@
package com.njcn.product.auth.config;
import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.enums.auth.ClientEnum;
import com.njcn.product.auth.filter.CustomClientCredentialsTokenEndpointFilter;
import com.njcn.product.auth.pojo.bo.BusinessUser;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.security.clientdetails.ClientDetailsServiceImpl;
import com.njcn.product.auth.security.granter.CaptchaTokenGranter;
import com.njcn.product.auth.security.granter.PreAuthenticatedUserDetailsService;
import com.njcn.product.auth.security.granter.SmsTokenGranter;
import com.njcn.product.auth.service.UserDetailsServiceImpl;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.web.utils.WebUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import java.security.KeyPair;
import java.util.*;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年05月11日 13:16
*/
@Configuration
@AllArgsConstructor
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager;
private final ClientDetailsServiceImpl clientDetailsService;
private final UserDetailsServiceImpl userDetailsService;
private final PasswordEncoder passwordEncoder;
private final RedisUtil redisUtil;
/**
* 客户端信息配置
*/
@Override
@SneakyThrows
public void configure(ClientDetailsServiceConfigurer clients) {
clients.withClientDetails(clientDetailsService);
}
/**
* 配置授权authorization以及令牌token的访问端点和令牌服务(token services)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
tokenEnhancers.add(tokenEnhancer());
tokenEnhancers.add(jwtAccessTokenConverter());
tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
// 获取原有默认授权模式(授权码模式、密码模式、客户端模式、简化模式)的授权者
List<TokenGranter> granterList = new ArrayList<>(Collections.singletonList(endpoints.getTokenGranter()));
// 添加验证码授权模式授权者
granterList.add(new CaptchaTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(),
endpoints.getOAuth2RequestFactory(), authenticationManager, redisUtil
));
// 添加短信授权模式授权者
granterList.add(new SmsTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(),
endpoints.getOAuth2RequestFactory(), authenticationManager, redisUtil
));
//todo... 后续可以扩展更多授权模式比如微信小程序、移动app
CompositeTokenGranter compositeTokenGranter = new CompositeTokenGranter(granterList);
endpoints.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter())
//设置grant_type类型集合
.tokenEnhancer(tokenEnhancerChain)
.tokenGranter(compositeTokenGranter)
/*
* refresh_token有两种使用方式重复使用(true)、非重复使用(false)默认为true
* 1.重复使用access_token过期刷新时 refresh token过期时间未改变仍以初次生成的时间为准
* 2.非重复使用access_token过期刷新时 refresh_token过期时间延续在refresh_token有效期内刷新而无需失效再次登录
*/
.reuseRefreshTokens(true)
.tokenServices(tokenServices(endpoints));
}
public DefaultTokenServices tokenServices(AuthorizationServerEndpointsConfigurer endpoints) {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
tokenEnhancers.add(tokenEnhancer());
tokenEnhancers.add(jwtAccessTokenConverter());
tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setTokenStore(endpoints.getTokenStore());
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setTokenEnhancer(tokenEnhancerChain);
// 多用户体系下刷新token再次认证客户端ID和 UserDetailService 的映射Map
Map<String, UserDetailsService> clientUserDetailsServiceMap = new HashMap<>(16);
// 系统管理客户端
clientUserDetailsServiceMap.put(ClientEnum.WEB_CLIENT.getClientId(), userDetailsService);
clientUserDetailsServiceMap.put(ClientEnum.WEB_CLIENT_TEST.getClientId(), userDetailsService);
clientUserDetailsServiceMap.put(ClientEnum.APP_CLIENT.getClientId(), userDetailsService);
clientUserDetailsServiceMap.put(ClientEnum.SCREEN_CLIENT.getClientId(), userDetailsService);
clientUserDetailsServiceMap.put(ClientEnum.WE_CHAT_APP_CLIENT.getClientId(), userDetailsService);
//todo .. 后面扩展微信小程序、app实现服务
// 刷新token模式下重写预认证提供者替换其AuthenticationManager可自定义根据客户端ID和认证方式区分用户体系获取认证用户信息
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(new PreAuthenticatedUserDetailsService<>(clientUserDetailsServiceMap));
tokenServices.setAuthenticationManager(new ProviderManager(Collections.singletonList(provider)));
return tokenServices;
}
/**
* 使用非对称加密算法对token签名
*/
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setKeyPair(keyPair());
return converter;
}
/**
* 从classpath下的密钥库中获取密钥对(公钥+私钥)
*/
@Bean
public KeyPair keyPair() {
KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource("njcn.jks"), "njcnpqs".toCharArray());
return factory.getKeyPair("njcn", "njcnpqs".toCharArray());
}
/**
* 自定义认证异常响应数据
*/
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
return (request, response, e) -> {
WebUtil.responseInfo(response, UserResponseEnum.CLIENT_AUTHENTICATION_FAILED.getCode(), UserResponseEnum.CLIENT_AUTHENTICATION_FAILED.getMessage());
};
}
/**
* JWT内容增强
*/
@Bean
public TokenEnhancer tokenEnhancer() {
return (accessToken, authentication) -> {
String clientId = authentication.getOAuth2Request().getClientId();
BusinessUser user = (BusinessUser) authentication.getUserAuthentication().getPrincipal();
Map<String, Object> map = new HashMap<>(8);
map.put(SecurityConstants.USER_INDEX_KEY, user.getUserIndex());
map.put(SecurityConstants.USER_TYPE, user.getType());
map.put(SecurityConstants.USER_NICKNAME_KEY, user.getNickName());
map.put(SecurityConstants.CLIENT_ID_KEY, clientId);
map.put(SecurityConstants.DEPT_INDEX_KEY, user.getDeptIndex());
map.put(SecurityConstants.USER_HEAD_KEY, user.getHeadSculpture());
if (StrUtil.isNotBlank(user.getAuthenticationMethod())) {
map.put(SecurityConstants.AUTHENTICATION_METHOD, user.getAuthenticationMethod());
}
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(map);
return accessToken;
};
}
/**
* 配置自定义密码认证过滤器
* @param security .
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
CustomClientCredentialsTokenEndpointFilter endpointFilter = new CustomClientCredentialsTokenEndpointFilter(security);
endpointFilter.afterPropertiesSet();
endpointFilter.setAuthenticationEntryPoint(authenticationEntryPoint());
security.addTokenEndpointAuthenticationFilter(endpointFilter);
security
.authenticationEntryPoint(authenticationEntryPoint())
/* .allowFormAuthenticationForClients()*/ //如果使用表单认证则需要加上
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setHideUserNotFoundExceptions(false);
provider.setUserDetailsService(userDetailsService);
provider.setPasswordEncoder(passwordEncoder);
return provider;
}
}

View File

@@ -0,0 +1,110 @@
package com.njcn.product.auth.config;
import com.njcn.product.auth.filter.AuthGlobalFilter;
import com.njcn.product.auth.security.provider.Sm4AuthenticationProvider;
import com.njcn.product.auth.security.provider.SmsAuthenticationProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* @author hongawen
*/
@Slf4j
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService sysUserDetailsService;
private final Sm4AuthenticationProvider sm4AuthenticationProvider;
private final SmsAuthenticationProvider smsAuthenticationProvider;
private final AuthGlobalFilter authGlobalFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user/generateSm2Key","/oauth/token","/theme/getTheme").permitAll()
.antMatchers("/webjars/**","/doc.html","/swagger-resources/**","/v2/api-docs").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable();
http.addFilterAfter(authGlobalFilter, UsernamePasswordAuthenticationFilter.class);
}
/**
* 认证管理对象
*
* @throws Exception .
* @return .
*/
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(daoAuthenticationProvider());
}
/**
* 重写父类自定义AuthenticationManager 将provider注入进去
* 当然我们也可以考虑不重写 在父类的manager里面注入provider
*/
@Bean
@Override
protected AuthenticationManager authenticationManager(){
return new ProviderManager(sm4AuthenticationProvider,smsAuthenticationProvider);
}
/**
* 用户名密码认证授权提供者
*/
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(sysUserDetailsService);
provider.setPasswordEncoder(passwordEncoder());
// 是否隐藏用户不存在异常,默认:true-隐藏false-抛出异常;
provider.setHideUserNotFoundExceptions(false);
return provider;
}
/**
* 密码编码器
* <p>
* 委托方式根据密码的前缀选择对应的encoder例如{bcypt}前缀->标识BCYPT算法加密{noop}->标识不使用任何加密即明文的方式
* 密码判读 DaoAuthenticationProvider#additionalAuthenticationChecks
*/
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}

View File

@@ -0,0 +1,222 @@
package com.njcn.product.auth.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.LogInfo;
import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.dto.UserTokenInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.common.utils.sm.DesUtils;
import com.njcn.common.utils.sm.Sm2;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.service.IUserService;
import com.njcn.product.auth.service.UserTokenService;
import com.njcn.product.auth.utils.AuthPubUtil;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.RequestUtil;
import com.njcn.web.utils.RestTemplateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import springfox.documentation.annotations.ApiIgnore;
import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.interfaces.RSAPublicKey;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author hongawen
*/
@Api(tags = "认证中心")
@Slf4j
@RestController
@RequestMapping("/oauth")
@AllArgsConstructor
public class AuthController extends BaseController {
private final TokenEndpoint tokenEndpoint;
private final KeyPair keyPair;
private final RedisUtil redisUtil;
private final IUserService userService;
private final UserTokenService userTokenService;
@ApiIgnore
@OperateInfo(info = LogEnum.SYSTEM_SERIOUS, operateType = OperateType.AUTHENTICATE)
@ApiOperation("登录认证")
@ApiImplicitParams({
@ApiImplicitParam(name = SecurityConstants.GRANT_TYPE, defaultValue = "password", value = "授权模式", required = true),
@ApiImplicitParam(name = SecurityConstants.CLIENT_ID, defaultValue = "njcn", value = "Oauth2客户端ID", required = true),
@ApiImplicitParam(name = SecurityConstants.CLIENT_SECRET, defaultValue = "njcnpqs", value = "Oauth2客户端秘钥", required = true),
@ApiImplicitParam(name = SecurityConstants.REFRESH_TOKEN, value = "刷新token"),
@ApiImplicitParam(name = SecurityConstants.USERNAME, value = "登录用户名"),
@ApiImplicitParam(name = SecurityConstants.PASSWORD, value = "登录密码"),
@ApiImplicitParam(name = SecurityConstants.IMAGE_CODE, value = "图形验证码"),
@ApiImplicitParam(name = SecurityConstants.PHONE, value = "手机号"),
@ApiImplicitParam(name = SecurityConstants.SMS_CODE, value = "短信验证码"),
})
@PostMapping("/token")
public Object postAccessToken(@ApiIgnore Principal principal, @RequestParam @ApiIgnore Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
String methodDescribe = getMethodDescribe("postAccessToken");
String username = parameters.get(SecurityConstants.USERNAME);
String grantType = parameters.get(SecurityConstants.GRANT_TYPE);
if (grantType.equalsIgnoreCase(SecurityConstants.GRANT_CAPTCHA) || grantType.equalsIgnoreCase(SecurityConstants.REFRESH_TOKEN_KEY)) {
username = DesUtils.aesDecrypt(username);
} else if (grantType.equalsIgnoreCase(SecurityConstants.GRANT_SMS_CODE)) {
//短信方式登录,将手机号赋值为用户名
username = parameters.get(SecurityConstants.PHONE);
}
if (grantType.equalsIgnoreCase(SecurityConstants.REFRESH_TOKEN_KEY)) {
//如果是刷新token需要去黑名单校验
userTokenService.judgeRefreshToken(parameters.get(SecurityConstants.REFRESH_TOKEN_KEY));
}
RequestUtil.saveLoginName(username);
OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
//用户的登录名&密码校验成功后,判断当前该用户是否可以正常使用系统
if (!grantType.equalsIgnoreCase(SecurityConstants.GRANT_SMS_CODE)) {
userService.judgeUserStatus(username);
}
//登录成功后记录token信息并处理踢人效果
userTokenService.recordUserInfo(oAuth2AccessToken, RequestUtil.getRealIp());
if (!grantType.equalsIgnoreCase(SecurityConstants.PASSWORD)) {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, oAuth2AccessToken, methodDescribe);
} else {
return oAuth2AccessToken;
}
}
@OperateInfo(info = LogEnum.SYSTEM_SERIOUS, operateType = OperateType.LOGOUT)
@ApiOperation("用户登出系统")
@DeleteMapping("/logout")
public HttpResult<Object> logout() {
String methodDescribe = getMethodDescribe("logout");
String userIndex = RequestUtil.getUserIndex();
String username = RequestUtil.getUsername();
LogUtil.njcnDebug(log, "{},用户名为:{}", methodDescribe, username);
String blackUserKey = SecurityConstants.TOKEN_BLACKLIST_PREFIX + userIndex;
String onlineUserKey = SecurityConstants.TOKEN_ONLINE_PREFIX + userIndex;
Object onlineTokenInfoOld = redisUtil.getObjectByKey(onlineUserKey);
List<UserTokenInfo> blackUsers = (List<UserTokenInfo>) redisUtil.getObjectByKey(blackUserKey);
UserTokenInfo userTokenInfo;
if (!Objects.isNull(onlineTokenInfoOld)) {
//清除在线token信息
redisUtil.delete(onlineUserKey);
userTokenInfo = (UserTokenInfo) onlineTokenInfoOld;
if (CollectionUtils.isEmpty(blackUsers)) {
blackUsers = new ArrayList<>();
}
blackUsers.add(userTokenInfo);
LocalDateTime refreshTokenExpire = userTokenInfo.getRefreshTokenExpire();
long lifeTime = Math.abs(refreshTokenExpire.plusMinutes(5L).toEpochSecond(ZoneOffset.of("+8")) - LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
redisUtil.saveByKeyWithExpire(blackUserKey, blackUsers, lifeTime);
}
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}
/**
* 文档隐藏该接口
*/
@ApiIgnore
@ApiOperation("RSA公钥获取接口")
@GetMapping("/getPublicKey")
public Map<String, Object> getPublicKey() {
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAKey key = new RSAKey.Builder(publicKey).build();
return new JWKSet(key).toJSONObject();
}
/**
* 自动登录
*/
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.AUTHENTICATE)
@ApiOperation("自动登录")
@PostMapping("/autoLogin")
@ApiImplicitParam(name = "phone", value = "手机号", required = true, paramType = "query")
@ApiIgnore
public HttpResult<Object> autoLogin(@RequestParam String phone) {
String methodDescribe = getMethodDescribe("autoLogin");
String userUrl = "http://127.0.0.1:10214/oauth/token";
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(userUrl)
.queryParam("grant_type", "sms_code")
.queryParam("client_id", "njcnapp")
.queryParam("client_secret", "njcnpqs")
.queryParam("phone", phone)
.queryParam("smsCode", "123456789");
URI uri = builder.build().encode().toUri();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, Objects.requireNonNull(RestTemplateUtil.post(uri, HttpResult.class).getBody()).getData(), methodDescribe);
}
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@GetMapping("/generateSm2Key")
@ApiOperation("根据登录名获取公钥")
@ApiImplicitParam(name = "loginName", value = "登录名", required = true)
public HttpResult<String> generateSm2Key(String loginName, @ApiIgnore HttpServletRequest request) {
System.out.println("request1==:" + request);
if (StrUtil.isBlankIfStr(loginName)) {
RequestUtil.saveLoginName(LogInfo.UNKNOWN_USER);
throw new BusinessException(UserResponseEnum.LOGIN_USERNAME_INVALID);
}
String methodDescribe = getMethodDescribe("generateSm2Key");
loginName = DesUtils.aesDecrypt(loginName);
RequestUtil.saveLoginName(loginName);
Map<String, String> keyMap;
try {
keyMap = Sm2.getSm2CipHer();
} catch (NoSuchAlgorithmException e) {
throw new BusinessException(CommonResponseEnum.SM2_CIPHER_ERROR);
}
String publicKey = keyMap.get("publicKey");
String privateKey = keyMap.get("privateKey");
String ip = request.getHeader(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP);
if (redisUtil.hasKey(loginName + ip)) {
//秘钥先删除再添加
redisUtil.delete(loginName + ip);
}
// 保存私钥到 redis
redisUtil.saveByKeyWithExpire(loginName + ip, privateKey, 5 * 60L);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, publicKey, methodDescribe);
}
}

View File

@@ -0,0 +1,121 @@
package com.njcn.product.auth.controller;
import cn.hutool.json.JSONObject;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Objects;
/**
* @author hongawen
* @version 1.0.0
* @date 2022年04月27日 11:22
*/
@Slf4j
@RestController
@AllArgsConstructor
@Api(tags = "校验第三方token")
@RequestMapping("/judgeToken")
public class JudgeThirdToken extends BaseController {
/**
* 校验广州超高压token有效性
*
* @param token token数据
*/
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@PostMapping("/guangZhou")
@ApiOperation("校验广州超高压token有效性")
@ApiImplicitParam(name = "token", required = true)
public HttpResult<Object> guangZhou(String token) {
RestTemplate restTemplate = new RestTemplate();
String methodDescribe = getMethodDescribe("guangZhou");
LogUtil.njcnDebug(log, "{}token{}", methodDescribe, token);
// 请求地址
String url = "http://10.121.17.9:9080/ehv/auth_valid";
// 请求头设置,x-www-form-urlencoded格式的数据
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//提交参数设置
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("token", token);
// 组装请求体
HttpEntity<MultiValueMap<String, String>> request =
new HttpEntity<>(map, headers);
// 发送post请求并打印结果以String类型接收响应结果JSON字符串
String result = restTemplate.postForObject(url, request, String.class);
JSONObject resultJson = new JSONObject(result);
if (Objects.equals(resultJson.getInt("status"), DataStateEnum.ENABLE.getCode())) {
//成功
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} else {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
}
}
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@PostMapping("/heBei")
@ApiOperation("校验河北token有效性")
@ApiImplicitParam(name = "token", required = true)
public HttpResult<Object> heBei(String token) {
RestTemplate restTemplate = new RestTemplate();
String methodDescribe = getMethodDescribe("heBei");
LogUtil.njcnDebug(log, "{}token{}", methodDescribe, token);
/* // 请求地址
String url = "http://dwzyywzt-test.com/baseCenter/oauth2/user/token";
// 请求头设置,x-www-form-urlencoded格式的数据
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//提交参数设置
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("token", token);
// 组装请求体
HttpEntity<MultiValueMap<String, String>> request =
new HttpEntity<>(map, headers);
// 发送post请求并打印结果以String类型接收响应结果JSON字符串
String result = restTemplate.postForObject(url, request, String.class);
JSONObject resultJson = new JSONObject(result);
if (Objects.equals(resultJson.getInt("status"), DataStateEnum.ENABLE.getCode())) {
//成功
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} else {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
}*/
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "HE_DNZLJCYW", methodDescribe);
}
}

View File

@@ -0,0 +1,80 @@
package com.njcn.product.auth.controller;
import cn.hutool.core.io.IoUtil;
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.util.Config;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.product.auth.utils.AuthPubUtil;
import com.njcn.redis.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import springfox.documentation.annotations.ApiIgnore;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Properties;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年06月04日 15:25
*/
@Api(tags = "认证中心")
@Slf4j
@Controller
@RequestMapping("/auth")
@AllArgsConstructor
public class KaptchaController {
private final RedisUtil redisUtil;
@ApiIgnore
@ApiOperation("获取图形验证码")
@GetMapping("/getImgCode")
public void getImgCode(@ApiIgnore HttpServletResponse resp, @ApiIgnore HttpServletRequest request) {
ServletOutputStream out = null;
try {
out = resp.getOutputStream();
// resp.setContentType("image/jpeg");"/pqs-auth/auth/getImgCode",
if (null != out) {
Properties props = new Properties();
Producer kaptchaProducer;
ImageIO.setUseCache(false);
props.put("kaptcha.border", "no");
props.put("kaptcha.textproducer.font.color", "black");
/*props.put("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.ShadowGimpy");*/
/*props.put("kaptcha.noise.impl", "com.sso.utils.ComplexNoise");*/
props.put("kaptcha.textproducer.char.space", "5");
props.put("kaptcha.textproducer.char.length", "4");
Config config = new Config(props);
kaptchaProducer = config.getProducerImpl();
//此处需要固定采用字母和数字混合
String capText = AuthPubUtil.getKaptchaText(4);
String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
String ip = request.getHeader(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP);
String key = userAgent + ip;
redisUtil.delete(key);
redisUtil.saveByKeyWithExpire(key, capText, 30*60L);
BufferedImage bi = kaptchaProducer.createImage(capText);
ImageIO.write(bi, "jpg", out);
out.flush();
}
} catch (IOException ioException) {
log.error("获取图形验证码异常,异常为:{}", ioException.toString());
} finally {
IoUtil.close(out);
}
}
}

View File

@@ -0,0 +1,203 @@
package com.njcn.product.auth.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.LogInfo;
import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.common.utils.sm.DesUtils;
import com.njcn.common.utils.sm.Sm2;
import com.njcn.product.auth.pojo.dto.UserDTO;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.pojo.param.UserParam;
import com.njcn.product.auth.pojo.po.User;
import com.njcn.product.auth.pojo.vo.UserVO;
import com.njcn.product.auth.service.IUserService;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.RequestUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* <p>
* 前端控制器
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
@Validated
@Slf4j
@RestController
@RequestMapping("/user")
@Api(tags = "用户信息管理")
@AllArgsConstructor
public class UserController extends BaseController {
private final IUserService userService;
private final RedisUtil redisUtil;
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@GetMapping("/getUserByName/{loginName}")
@ApiOperation("根据登录名查询用户信息")
@ApiImplicitParam(name = "loginName", value = "登录名", required = true)
public HttpResult<UserDTO> getUserByName(@PathVariable String loginName) {
RequestUtil.saveLoginName(loginName);
String methodDescribe = getMethodDescribe("getUserByName");
LogUtil.njcnDebug(log, "{},登录名为:{}", methodDescribe, loginName);
UserDTO user = userService.getUserByName(loginName);
if (Objects.isNull(user)) {
throw new BusinessException(UserResponseEnum.LOGIN_WRONG_PWD);
} else {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, user, methodDescribe);
}
}
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@ApiIgnore
@GetMapping("/getUserByPhone/{phone}")
@ApiOperation("根据手机号查询用户信息")
@ApiImplicitParam(name = "phone", value = "手机号", required = true)
public HttpResult<UserDTO> getUserByPhone(@PathVariable String phone) {
RequestUtil.saveLoginName(phone);
String methodDescribe = getMethodDescribe("getUserByPhone");
LogUtil.njcnDebug(log, "{},手机号为:{}", methodDescribe, phone);
UserDTO user = userService.loadUserByPhone(phone);
if (Objects.isNull(user)) {
throw new BusinessException(UserResponseEnum.LOGIN_PHONE_NOT_REGISTER);
} else {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, user, methodDescribe);
}
}
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@GetMapping("/judgeUserStatus/{loginName}")
@ApiOperation("认证后根据用户名判断用户状态")
@ApiImplicitParam(name = "loginName", value = "登录名", required = true)
public HttpResult<Boolean> judgeUserStatus(@PathVariable String loginName) {
RequestUtil.saveLoginName(loginName);
String methodDescribe = getMethodDescribe("judgeUserStatus");
LogUtil.njcnDebug(log, "{},登录名为:{}", methodDescribe, loginName);
userService.judgeUserStatus(loginName);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
}
/**
* 根据用户id获取用户详情
*
* @param id 用户id
*/
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@GetMapping("/getUserById")
@ApiOperation("用户详情")
@ApiImplicitParam(name = "id", value = "用户id", required = true)
public HttpResult<UserVO> getUserById(@RequestParam @Validated String id) {
String methodDescribe = getMethodDescribe("getUserById");
LogUtil.njcnDebug(log, "{}用户id为{}", methodDescribe, id);
UserVO userVO = userService.getUserById(id);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, userVO, methodDescribe);
}
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@GetMapping("/generateSm2Key")
@ApiOperation("根据登录名获取公钥")
@ApiImplicitParam(name = "loginName", value = "登录名", required = true)
public HttpResult<String> generateSm2Key(String loginName, @ApiIgnore HttpServletRequest request) {
System.out.println("request1==:" + request);
if (StrUtil.isBlankIfStr(loginName)) {
RequestUtil.saveLoginName(LogInfo.UNKNOWN_USER);
throw new BusinessException(UserResponseEnum.LOGIN_USERNAME_INVALID);
}
String methodDescribe = getMethodDescribe("generateSm2Key");
loginName = DesUtils.aesDecrypt(loginName);
RequestUtil.saveLoginName(loginName);
Map<String, String> keyMap;
try {
keyMap = Sm2.getSm2CipHer();
} catch (NoSuchAlgorithmException e) {
throw new BusinessException(CommonResponseEnum.SM2_CIPHER_ERROR);
}
String publicKey = keyMap.get("publicKey");
String privateKey = keyMap.get("privateKey");
String ip = request.getHeader(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP);
if (redisUtil.hasKey(loginName + ip)) {
//秘钥先删除再添加
redisUtil.delete(loginName + ip);
}
// 保存私钥到 redis
redisUtil.saveByKeyWithExpire(loginName + ip, privateKey, 5 * 60L);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, publicKey, methodDescribe);
}
@OperateInfo(operateType = OperateType.UPDATE, info = LogEnum.SYSTEM_SERIOUS)
@PutMapping("/updateUserLoginErrorTimes/{loginName}")
@ApiOperation("更新用户登录认证密码错误次数")
@ApiImplicitParam(name = "loginName", value = "登录名", required = true)
public HttpResult<String> updateUserLoginErrorTimes(@PathVariable String loginName) {
RequestUtil.saveLoginName(loginName);
String methodDescribe = getMethodDescribe("updateUserLoginErrorTimes");
LogUtil.njcnDebug(log, "{},登录名为:{}", methodDescribe, loginName);
String result = userService.updateUserLoginErrorTimes(loginName);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
/**
* 查询所有用户包含管理员
*/
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@GetMapping("/getAllUserSimpleList")
@ApiOperation("查询所有用户作为下拉框")
public HttpResult<Object> getAllUserSimpleList() {
String methodDescribe = getMethodDescribe("getAllUserSimpleList");
List<User> result = userService.simpleList(true);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
}

View File

@@ -0,0 +1,93 @@
package com.njcn.product.auth.exception;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.JWSObject;
import com.njcn.common.pojo.constant.LogInfo;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.service.IUserService;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年05月17日 12:46
*/
@Slf4j
@RestControllerAdvice
@RequiredArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthExceptionHandler {
private final IUserService userService;
// private final ILogService logService;
/**
* 用户名和密码非法
*/
@ExceptionHandler(InvalidGrantException.class)
public HttpResult<String> handleInvalidGrantException(HttpServletRequest httpServletRequest, InvalidGrantException invalidGrantException) {
String loginName = invalidGrantException.getMessage();
log.error("捕获用户名密码错误");
String result = userService.updateUserLoginErrorTimes(loginName);
if (result.equals(UserResponseEnum.LOGIN_USER_LOCKED.getMessage())) {
// logService.recodeAuthExceptionLog(invalidGrantException, httpServletRequest, UserResponseEnum.LOGIN_USER_LOCKED.getMessage(), loginName);
return HttpResultUtil.assembleResult(UserResponseEnum.LOGIN_USER_LOCKED.getCode(), null, UserResponseEnum.LOGIN_USER_LOCKED.getMessage());
} else {
// logService.recodeAuthExceptionLog(invalidGrantException, httpServletRequest, UserResponseEnum.LOGIN_WRONG_PWD.getMessage(), loginName);
return HttpResultUtil.assembleResult(UserResponseEnum.LOGIN_WRONG_PWD.getCode(), null, UserResponseEnum.LOGIN_WRONG_PWD.getMessage());
}
}
/**
* 不支持的认证方式
* <p>
* 不支持的认证方式 目前支持用户名密码password、刷新tokenrefresh-token
*/
@ExceptionHandler(UnsupportedGrantTypeException.class)
public HttpResult<String> unsupportedGrantTypeExceptionException(HttpServletRequest httpServletRequest, UnsupportedGrantTypeException unsupportedGrantTypeException) {
String loginName = RequestUtil.getLoginName(httpServletRequest);
// logService.recodeAuthExceptionLog(unsupportedGrantTypeException, httpServletRequest, UserResponseEnum.UNSUPPORTED_GRANT_TYPE.getMessage(), loginName);
return HttpResultUtil.assembleResult(UserResponseEnum.UNSUPPORTED_GRANT_TYPE.getCode(), null, UserResponseEnum.UNSUPPORTED_GRANT_TYPE.getMessage());
}
/**
* oAuth2中token校验异常
*/
@SneakyThrows
@ExceptionHandler(InvalidTokenException.class)
public HttpResult<String> invalidTokenExceptionException(HttpServletRequest httpServletRequest, InvalidTokenException invalidTokenException) {
final String EXPIRED_KEY = "Invalid refresh token (expired):";
if (invalidTokenException.getMessage().startsWith(EXPIRED_KEY)) {
String message = invalidTokenException.getMessage();
message = message.substring(EXPIRED_KEY.length());
JWSObject jwsObject = JWSObject.parse(message);
String payload = jwsObject.getPayload().toString();
JSONObject jsonObject = JSONUtil.parseObj(payload);
// logService.recodeAuthExceptionLog(invalidTokenException, httpServletRequest, UserResponseEnum.REFRESH_TOKEN_EXPIRE_JWT.getMessage(), jsonObject.getStr(SecurityConstants.USER_NAME_KEY));
return HttpResultUtil.assembleResult(UserResponseEnum.REFRESH_TOKEN_EXPIRE_JWT.getCode(), null, UserResponseEnum.REFRESH_TOKEN_EXPIRE_JWT.getMessage());
}
// logService.recodeAuthExceptionLog(invalidTokenException, httpServletRequest, UserResponseEnum.PARSE_TOKEN_FORBIDDEN_JWT.getMessage(), LogInfo.UNKNOWN_USER);
return HttpResultUtil.assembleResult(UserResponseEnum.PARSE_TOKEN_FORBIDDEN_JWT.getCode(), null, UserResponseEnum.PARSE_TOKEN_FORBIDDEN_JWT.getMessage());
}
}

View File

@@ -0,0 +1,256 @@
package com.njcn.product.auth.exception;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.common.utils.ReflectCommonUtil;
import com.njcn.web.utils.ControllerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.util.NestedServletException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 全局通用业务异常处理器
*
* @author hongawen
* @version 1.0.0
* @date 2021年04月20日 18:04
*/
@Slf4j
@AllArgsConstructor
@RestControllerAdvice
public class GlobalBusinessExceptionHandler {
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(
4, 8, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100),
// 队列满时由主线程执行
new ThreadPoolExecutor.CallerRunsPolicy()
);
/**
* 捕获业务功能异常,通常为业务数据抛出的异常
*
* @param businessException 业务异常
*/
@ExceptionHandler(BusinessException.class)
public HttpResult<String> handleBusinessException(BusinessException businessException) {
String operate = ReflectCommonUtil.getMethodDescribeByException(businessException);
// recodeBusinessExceptionLog(businessException, businessException.getMessage());
return HttpResultUtil.assembleBusinessExceptionResult(businessException, null, operate);
}
/**
* 空指针异常捕捉
*
* @param nullPointerException 空指针异常
*/
@ExceptionHandler(NullPointerException.class)
public HttpResult<String> handleNullPointerException(NullPointerException nullPointerException) {
LogUtil.logExceptionStackInfo(CommonResponseEnum.NULL_POINTER_EXCEPTION.getMessage(), nullPointerException);
//recodeBusinessExceptionLog(nullPointerException, CommonResponseEnum.NULL_POINTER_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.NULL_POINTER_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(nullPointerException));
}
/**
* 算数运算异常
*
* @param arithmeticException 算数运算异常由于除数为0引起的异常
*/
@ExceptionHandler(ArithmeticException.class)
public HttpResult<String> handleArithmeticException(ArithmeticException arithmeticException) {
LogUtil.logExceptionStackInfo(CommonResponseEnum.ARITHMETIC_EXCEPTION.getMessage(), arithmeticException);
// recodeBusinessExceptionLog(arithmeticException, CommonResponseEnum.ARITHMETIC_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ARITHMETIC_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(arithmeticException));
}
/**
* 类型转换异常捕捉
*
* @param classCastException 类型转换异常
*/
@ExceptionHandler(ClassCastException.class)
public HttpResult<String> handleClassCastException(ClassCastException classCastException) {
LogUtil.logExceptionStackInfo(CommonResponseEnum.CLASS_CAST_EXCEPTION.getMessage(), classCastException);
// recodeBusinessExceptionLog(classCastException, CommonResponseEnum.CLASS_CAST_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.CLASS_CAST_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(classCastException));
}
/**
* 索引下标越界异常捕捉
*
* @param indexOutOfBoundsException 索引下标越界异常
*/
@ExceptionHandler(IndexOutOfBoundsException.class)
public HttpResult<String> handleIndexOutOfBoundsException(IndexOutOfBoundsException indexOutOfBoundsException) {
LogUtil.logExceptionStackInfo(CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMessage(), indexOutOfBoundsException);
// recodeBusinessExceptionLog(indexOutOfBoundsException, CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.INDEX_OUT_OF_BOUNDS_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(indexOutOfBoundsException));
}
/**
* 前端请求后端,请求中参数的媒体方式不支持异常
*
* @param httpMediaTypeNotSupportedException 请求中参数的媒体方式不支持异常
*/
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public HttpResult<String> httpMediaTypeNotSupportedExceptionHandler(HttpMediaTypeNotSupportedException httpMediaTypeNotSupportedException) {
LogUtil.logExceptionStackInfo(CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getMessage(), httpMediaTypeNotSupportedException);
// 然后提取错误提示信息进行返回
// recodeBusinessExceptionLog(httpMediaTypeNotSupportedException, CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.HTTP_MEDIA_TYPE_NOT_SUPPORTED_EXCEPTION, null, ReflectCommonUtil.getMethodDescribeByException(httpMediaTypeNotSupportedException));
}
/**
* 前端请求后端,参数校验异常捕捉
* RequestBody注解参数异常
*
* @param methodArgumentNotValidException 参数校验异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public HttpResult<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException methodArgumentNotValidException) {
// 从异常对象中拿到allErrors数据
String messages = methodArgumentNotValidException.getBindingResult().getAllErrors()
.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(""));
// 然后提取错误提示信息进行返回
LogUtil.njcnDebug(log, "参数校验异常,异常为:{}", messages);
// recodeBusinessExceptionLog(methodArgumentNotValidException, CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages, ControllerUtil.getMethodArgumentNotValidException(methodArgumentNotValidException));
}
/**
* 前端请求后端,参数校验异常捕捉
* PathVariable注解、RequestParam注解参数异常
*
* @param constraintViolationException 参数校验异常
*/
@ExceptionHandler(ConstraintViolationException.class)
public HttpResult<String> constraintViolationExceptionExceptionHandler(ConstraintViolationException constraintViolationException) {
String exceptionMessage = constraintViolationException.getMessage();
StringBuilder messages = new StringBuilder();
if (exceptionMessage.indexOf(StrUtil.COMMA) > 0) {
String[] tempMessage = exceptionMessage.split(StrUtil.COMMA);
Stream.of(tempMessage).forEach(message -> {
messages.append(message.substring(message.indexOf(StrUtil.COLON) + 2)).append(';');
});
} else {
messages.append(exceptionMessage.substring(exceptionMessage.indexOf(StrUtil.COLON) + 2));
}
// 然后提取错误提示信息进行返回
LogUtil.njcnDebug(log, "参数校验异常,异常为:{}", messages);
// recodeBusinessExceptionLog(constraintViolationException, CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getMessage());
List<ConstraintViolation<?>> constraintViolationList = new ArrayList<>(constraintViolationException.getConstraintViolations());
ConstraintViolation<?> constraintViolation = constraintViolationList.get(0);
Class<?> rootBeanClass = constraintViolation.getRootBeanClass();
//判断校验参数异常捕获的根源是controller还是service处
if (rootBeanClass.getName().endsWith("Controller")) {
String methodName = constraintViolation.getPropertyPath().toString().substring(0, constraintViolation.getPropertyPath().toString().indexOf(StrUtil.DOT));
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages.toString(), ReflectCommonUtil.getMethodDescribeByClassAndMethodName(rootBeanClass, methodName));
} else {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION, messages.toString(), ReflectCommonUtil.getMethodDescribeByException(constraintViolationException));
}
}
/**
* 索引下标越界异常捕捉
*
* @param illegalArgumentException 参数校验异常
*/
@ExceptionHandler(IllegalArgumentException.class)
public HttpResult<String> handleIndexOutOfBoundsException(IllegalArgumentException illegalArgumentException) {
LogUtil.logExceptionStackInfo(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage(), illegalArgumentException);
// recodeBusinessExceptionLog(illegalArgumentException, CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ILLEGAL_ARGUMENT_EXCEPTION, illegalArgumentException.getMessage(), ReflectCommonUtil.getMethodDescribeByException(illegalArgumentException));
}
/**
* 未声明异常捕捉
*
* @param exception 未声明异常
*/
@ExceptionHandler(Exception.class)
public HttpResult<String> handleException(Exception exception) {
//针对fallbackFactory降级异常特殊处理
Exception tempException = exception;
String exceptionCause = CommonResponseEnum.UN_DECLARE.getMessage();
String code = CommonResponseEnum.UN_DECLARE.getCode();
if (exception instanceof NestedServletException) {
Throwable cause = exception.getCause();
if (cause instanceof AssertionError) {
if (cause.getCause() instanceof BusinessException) {
tempException = (BusinessException) cause.getCause();
BusinessException tempBusinessException = (BusinessException) cause.getCause();
exceptionCause = tempBusinessException.getMessage();
code = tempBusinessException.getCode();
}
}
}
LogUtil.logExceptionStackInfo(exceptionCause, tempException);
// recodeBusinessExceptionLog(exception, exceptionCause);
//判断方法上是否有自定义注解,做特殊处理
// Method method = ReflectCommonUtil.getMethod(exception);
// if (!Objects.isNull(method)){
// if(method.isAnnotationPresent(ReturnMsg.class)){
// return HttpResultUtil.assembleResult(code, null, StrFormatter.format("{}",exceptionCause));
// }
// }
return HttpResultUtil.assembleResult(code, null, StrFormatter.format("{}{}{}", ReflectCommonUtil.getMethodDescribeByException(tempException), StrUtil.C_COMMA, exceptionCause));
}
/**
* json解析异常
*
* @param jsonException json参数
*/
@ExceptionHandler(JSONException.class)
public HttpResult<String> handleIndexOutOfBoundsException(JSONException jsonException) {
LogUtil.logExceptionStackInfo(CommonResponseEnum.JSON_CONVERT_EXCEPTION.getMessage(), jsonException);
// recodeBusinessExceptionLog(jsonException, CommonResponseEnum.JSON_CONVERT_EXCEPTION.getMessage());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.JSON_CONVERT_EXCEPTION, jsonException.getMessage(), ReflectCommonUtil.getMethodDescribeByException(jsonException));
}
/*
private void recodeBusinessExceptionLog(Exception businessException, String methodDescribe) {
HttpServletRequest httpServletRequest = HttpServletUtil.getRequest();
Future<?> future = executor.submit(() -> {
HttpServletUtil.setRequest(httpServletRequest);
sysLogAuditService.recodeBusinessExceptionLog(businessException, methodDescribe);
});
try {
// 抛出 ExecutionException
future.get();
} catch (ExecutionException | InterruptedException e) {
log.error("保存审计日志异常,异常为:" + e.getMessage());
}
}*/
}

View File

@@ -0,0 +1,207 @@
package com.njcn.product.auth.filter;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.JWSObject;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.dto.UserTokenInfo;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.web.utils.IpUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.*;
/**
* 全局过滤器
*
* @author hongawen
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class AuthGlobalFilter extends OncePerRequestFilter {
private final static List<String> REPALCEURL = Arrays.asList("/user-boot","/system-boot","/device-boot","/advance-boot");
private final RedisUtil redisUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
ServerHttpRequest serverHttpRequest = new ServletServerHttpRequest(request);
Map<String, String> customHeaders = new HashMap<>();
String realIp = IpUtils.getRealIpAddress(serverHttpRequest);
String token = request.getHeader(SecurityConstants.AUTHORIZATION_KEY);
String path = request.getRequestURI();
for (String s : REPALCEURL) {
if(path.contains(s)){
path = path.replace(s,"");
}
}
if (StrUtil.isBlank(token) || !token.startsWith(SecurityConstants.AUTHORIZATION_PREFIX)) {
customHeaders.put(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP, realIp);
chain.doFilter(new ModifiedHttpServletRequest(request, path, customHeaders), response);
return;
}
token = token.replace(SecurityConstants.AUTHORIZATION_PREFIX, Strings.EMPTY);
JWSObject jwsObject = null;
try {
jwsObject = JWSObject.parse(token);
} catch (ParseException e) {
sendErrorResponse(response,CommonResponseEnum.PARSE_TOKEN_ERROR);
return;
}
String payload = jwsObject.getPayload().toString();
JSONObject jsonObject = JSONUtil.parseObj(payload);
String userIndex = jsonObject.getStr(SecurityConstants.USER_INDEX_KEY);
String jti = jsonObject.getStr(SecurityConstants.JWT_JTI);
String exp = jsonObject.getStr(SecurityConstants.JWT_EXP);
LocalDateTime expTime = LocalDateTimeUtil.of(Long.parseLong(exp + "000"));
if(expTime.isBefore(LocalDateTimeUtil.now())){
sendErrorResponse(response,CommonResponseEnum.TOKEN_EXPIRE_JWT);
return;
}
String blackUserKey = SecurityConstants.TOKEN_BLACKLIST_PREFIX + userIndex;
List<UserTokenInfo> blackUsers = (List<UserTokenInfo>) redisUtil.getObjectByKey(blackUserKey);
if (CollectionUtils.isNotEmpty(blackUsers)) {
for (UserTokenInfo blackUser : blackUsers) {
//存在当前的刷新token则抛出业务异常
if(blackUser.getAccessTokenJti().equalsIgnoreCase(jti)){
sendErrorResponse(response,CommonResponseEnum.TOKEN_EXPIRE_JWT);
return;
}
}
}
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(request.getUserPrincipal(),null,null);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
customHeaders.put(SecurityConstants.JWT_PAYLOAD_KEY, URLEncoder.encode(payload, StandardCharsets.UTF_8.toString()));
customHeaders.put(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP, realIp);
chain.doFilter(new ModifiedHttpServletRequest(request, path, customHeaders), response);
}
private void sendErrorResponse(HttpServletResponse response, CommonResponseEnum error) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json;charset=UTF-8");
response.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Cache-Control", "no-cache");
HttpResult<String> httpResult = new HttpResult<>();
httpResult.setCode(error.getCode());
httpResult.setMessage(error.getMessage());
response.getWriter().write(new JSONObject(httpResult, false).toString());
}
// 自定义HttpServletRequest包装器
private static class ModifiedHttpServletRequest extends HttpServletRequestWrapper {
private final String modifiedUri;
public ModifiedHttpServletRequest(HttpServletRequest request, String modifiedUri, Map<String, String> customHeaders) {
super(request);
this.modifiedUri = modifiedUri;
this.customHeaders = customHeaders;
}
@Override
public String getRequestURI() {
return modifiedUri;
}
@Override
public String getServletPath() {
return modifiedUri;
}
private final Map<String, String> customHeaders;
// 添加/修改Header
public void putHeader(String name, String value) {
this.customHeaders.put(name, value);
}
@Override
public String getHeader(String name) {
String customValue = customHeaders.get(name);
return (customValue != null) ? customValue : super.getHeader(name);
}
@Override
public Enumeration<String> getHeaders(String name) {
if (customHeaders.containsKey(name)) {
return Collections.enumeration(Collections.singletonList(customHeaders.get(name)));
}
return super.getHeaders(name);
}
@Override
public Enumeration<String> getHeaderNames() {
Set<String> names = new HashSet<>(customHeaders.keySet());
Enumeration<String> originalNames = super.getHeaderNames();
while (originalNames.hasMoreElements()) {
names.add(originalNames.nextElement());
}
return Collections.enumeration(names);
}
}
public static String getClientIp(HttpServletRequest request) {
// 1. 优先从代理头获取
String[] headerNames = {
"X-Forwarded-For", // 标准代理头
"Proxy-Client-IP", // Apache 代理
"WL-Proxy-Client-IP", // WebLogic 代理
"HTTP_X_FORWARDED_FOR",
"HTTP_CLIENT_IP"
};
for (String header : headerNames) {
String ip = request.getHeader(header);
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
// X-Forwarded-For 可能有多个IPclient, proxy1, proxy2
if (ip.contains(",")) {
ip = ip.split(",")[0].trim(); // 取第一个IP
}
return ip;
}
}
// 2. 没有代理头时直接获取
return request.getRemoteAddr();
}
}

View File

@@ -0,0 +1,42 @@
package com.njcn.product.auth.filter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter;
import org.springframework.security.web.AuthenticationEntryPoint;
/**
* @author hongawen
* @version 1.0.0
* @createTime 2021年05月24日 15:39
*/
public class CustomClientCredentialsTokenEndpointFilter extends ClientCredentialsTokenEndpointFilter {
private final AuthorizationServerSecurityConfigurer configurer;
private AuthenticationEntryPoint authenticationEntryPoint;
public CustomClientCredentialsTokenEndpointFilter(AuthorizationServerSecurityConfigurer configurer) {
this.configurer = configurer;
}
@Override
public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
super.setAuthenticationEntryPoint(null);
this.authenticationEntryPoint = authenticationEntryPoint;
}
@Override
protected AuthenticationManager getAuthenticationManager() {
return configurer.and().getSharedObject(AuthenticationManager.class);
}
@Override
public void afterPropertiesSet() {
setAuthenticationFailureHandler((request, response, e) -> authenticationEntryPoint.commence(request, response, e));
setAuthenticationSuccessHandler((request, response, authentication) -> {
});
}
}

View File

@@ -0,0 +1,16 @@
package com.njcn.product.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.auth.pojo.po.AuthClient;
/**
* <p>
* Mapper 接口
* </p>
*
* @author hongawen
* @since 2021-12-15
*/
public interface AuthClientMapper extends BaseMapper<AuthClient> {
}

View File

@@ -0,0 +1,22 @@
package com.njcn.product.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.auth.pojo.po.Role;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface RoleMapper extends BaseMapper<Role> {
}

View File

@@ -0,0 +1,23 @@
package com.njcn.product.auth.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.auth.pojo.po.User;
import com.njcn.product.auth.pojo.vo.UserVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface UserMapper extends BaseMapper<User> {
}

View File

@@ -0,0 +1,29 @@
package com.njcn.product.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.auth.pojo.po.Role;
import com.njcn.product.auth.pojo.po.UserRole;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface UserRoleMapper extends BaseMapper<UserRole> {
/**
* 根据用户id获取角色详情
* @param userId 用户id
* @author cdf
* @date 2022/9/8
* @return 角色结果集
*/
List<Role> getRoleListByUserId(String userId);
}

View File

@@ -0,0 +1,17 @@
package com.njcn.product.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.auth.pojo.po.UserSet;
/**
* <p>
* Mapper 接口
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface UserSetMapper extends BaseMapper<UserSet> {
}

View File

@@ -0,0 +1,16 @@
package com.njcn.product.auth.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.auth.pojo.po.UserStrategy;
/**
* <p>
* Mapper 接口
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface UserStrategyMapper extends BaseMapper<UserStrategy> {
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.product.auth.mapper.UserRoleMapper">
<select id="getRoleListByUserId" resultType="Role">
select b.* from sys_user_role a
inner join sys_role b on a.role_id = b.id
where a.user_id = #{userId}
and b.state = 1
</select>
</mapper>

View File

@@ -0,0 +1,96 @@
package com.njcn.product.auth.pojo.bo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
/**
* @author hongawen
* @version 1.0.0
* @createTime 2021年04月28日 13:31
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BusinessUser implements UserDetails {
private String userIndex;
private String username;
private String nickName;
private String password;
private String clientId;
private String deptIndex;
private Collection<? extends GrantedAuthority> authorities;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
private String secretKey;
private String standBy;
private String authenticationMethod;
private Integer type;
private String headSculpture;
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities(){
return authorities;
}
public BusinessUser(String username, String password, List<GrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.authorities =authorities;
}
}

View File

@@ -0,0 +1,15 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author denghuajun
* @date 2021/12/28
*
*/
public interface DeptState {
/**
* 部门状态 0-删除1-正常;默认正常
*/
int DELETE = 0;
int ENABLE = 1;
}

View File

@@ -0,0 +1,16 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author denghuajun
* @date 2021/12/28
*
*/
public interface DeptType {
/**
* 部门类型 0-非自定义1-web自定义2-App自定义
*/
int UNCUSTOM = 0;
int WEBCUSTOM = 1;
int APPCUSTOM = 2;
}

View File

@@ -0,0 +1,38 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author 徐扬
*/
public interface FunctionState {
/**
* 权限资源状态 0-删除1-正常;默认正常
*/
int DELETE = 0;
int ENABLE = 1;
/**
* 顶层父类的pid
*/
String FATHER_PID = "0";
/**
* 驾驶舱父类名称
*/
String DRIVER_NAME = "/home";
/**
* 权限资源类型 0-菜单、1-按钮、2-公共资源、3-服务间调用资源、4-tab页面
*/
int MENU = 0;
int BUTTON = 1;
int PUBLIC = 2;
int IN_SERVICE = 3;
int TAB = 4;
}

View File

@@ -0,0 +1,19 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author 徐扬
*/
public interface HomePageState {
/**
* 状态 0-删除1-正常;默认正常
*/
int DELETE = 0;
int ENABLE = 1;
/**
* 默认首页 用户的id
*/
String DEFAULT_USER_ID = "0";
}

View File

@@ -0,0 +1,18 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author 徐扬
*/
public interface RoleType {
/**
* 角色类型 0超级管理员1管理员2用户 3:APP角色
*/
int SUPER_ADMINISTRATOR = 0;
int ADMINISTRATOR = 1;
int USER = 2;
int APP = 3;
}

View File

@@ -0,0 +1,13 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author 徐扬
*/
public interface UserDefaultPassword {
/**
* 新增用户初始密码
*/
String DEFAULT_PASSWORD = "123456";
}

View File

@@ -0,0 +1,41 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年12月15日 15:00
*/
public interface UserState {
/**
* 用户状态 0删除1正常2锁定3待审核4休眠5密码过期
*/
int DELETE = 0;
int ENABLE = 1;
int LOCKED = 2;
int UNCHECK = 3;
int SLEEP = 4;
int OVERDUE = 5;
/**
* 数据来源0-外部推送 1-正常新增
*/
int OUT_ORIGIN = 0;
int NORMAL_ORIGIN = 1;
/**
* 密码状态0-不需要修改 1-需要修改
*/
int NEEDLESS = 0;
int NEED = 1;
/**
* 初始密码错误次数
*/
int ERROR_PASSWORD_TIMES = 0;
}

View File

@@ -0,0 +1,30 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年12月15日 19:39
*/
public interface UserType {
/**
* 用户类型 0临时用户1正式用户
*/
int CASUAL = 0;
int OFFICIAL = 1;
/**
* 用户权限类型 0超级管理员1管理员2用户3APP用户
*/
int SUPER_ADMINISTRATOR = 0;
int ADMINISTRATOR = 1;
int USER = 2;
int APP = 3;
String SUPER_ADMIN = "root";
}

View File

@@ -0,0 +1,73 @@
package com.njcn.product.auth.pojo.constant;
/**
* @author xy
* @date 2021/12/29 15:10
*/
public interface UserValidMessage {
String ID_NOT_BLANK = "id不能为空请检查id参数";
String USERNAME_NOT_BLANK = "名称不能为空请检查name参数";
String USERNAME_FORMAT_ERROR = "用户名格式错误需中英文1-16请检查name参数";
String LOGIN_NAME_NOT_BLANK = "登录名不能为空请检查loginName参数";
String LOGIN_NAME_FORMAT_ERROR = "登录名格式错误需3-16位的英文字母或数字请检查loginName参数";
String PASSWORD_NOT_BLANK = "密码不能为空请检查password参数";
String PASSWORD_FORMAT_ERROR = "密码格式错误需包含特殊字符字母数字长度为8-16请检查password参数";
String DEPT_NOT_BLANK = "部门不能为空请检查deptId参数";
String PHONE_FORMAT_ERROR = "电话号码格式错误请检查phone参数";
String EMAIL_FORMAT_ERROR = "邮箱格式错误请检查email参数";
String LIMIT_IP_START_NOT_BLANK = "起始IP不能为空请检查limitIpStart参数";
String LIMIT_IP_START_FORMAT_ERROR = "起始IP格式错误请检查limitIpStart参数";
String LIMIT_IP_END_NOT_BLANK = "结束IP不能为空请检查limitIpEnd参数";
String LIMIT_IP_END_FORMAT_ERROR = "结束IP格式错误请检查limitIpEnd参数";
String LIMIT_TIME_NOT_BLANK = "时间段不能为空请检查limitTime参数";
String CASUAL_USER_NOT_BLANK = "类型不能为空";
String SMS_NOTICE_NOT_BLANK = "短信通知不能为空请检查smsNotice参数";
String EMAIL_NOTICE_NOT_BLANK = "邮件通知不能为空请检查emailNotice参数";
String PARAM_FORMAT_ERROR = "参数值非法";
String ROLE_NOT_BLANK = "角色不能为空请检查role参数";
String PID_NOT_BLANK = "父节点不能为空请检查pid参数";
String CODE_NOT_BLANK = "资源标识不能为空请检查code参数";
String PATH_NOT_BLANK = "资源路径不能为空请检查path参数";
String PATH_FORMAT_ERROR = "路径格式错误请检查path参数";
String SORT_NOT_BLANK = "排序不能为空请检查sort参数";
String TYPE_NOT_BLANK = "资源类型不能为空请检查type参数";
String LAYOUT_NOT_BLANK = "模板不能为空请检查layout参数";
String FUNCTION_ID_NOT_BLANK = "资源id不能为空请检查functionId参数";
String FUNCTION_ID_FORMAT_ERROR = "资源id格式错误请检查functionId参数";
String FUNCTION_GROUP_NOT_BLANK = "功能数组不能为空请检查functionGroup参数";
String FUNCTION_GROUP_FORMAT_ERROR = "功能数组格式错误请检查functionGroup参数";
String COMPONENT_CODE_NOT_BLANK = "功能组件表示不能为空请检查code参数";
}

View File

@@ -0,0 +1,48 @@
package com.njcn.product.auth.pojo.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年05月08日 15:12
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
private String userIndex;
private String username;
private String nickname;
private String password;
/**
* 角色集合
*/
private List<String> roleName;
/**
* sm4加密秘钥
*/
private String secretKey;
/**
* sm4中间过程校验
*/
private String standBy;
private String deptIndex;
private Integer type;
private String headSculpture;
}

View File

@@ -0,0 +1,125 @@
package com.njcn.product.auth.pojo.enums;
import lombok.Getter;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年04月13日 10:50
*/
@Getter
public enum UserResponseEnum {
/**
* A0100 ~ A0199 用于用户模块的枚举
* <p>
* 大致可以分为:
* 登录失败状态码 A0101 + 各种登录失败的原因
* 注册失败状态码 A0103 + 各种注册失败的原因
* 用户权限升级失败暂时用于app账号不同角色升级 A0103 + 各种升级app权限失败的原因
* token校验失败 A0104 + 各种token失败的原因
* client校验失败 A0105 + 各种客户端失败的原因
*/
LOGIN_USERNAME_NOT_FOUND("A0101", "用户不存在"),
LOGIN_USERNAME_INVALID("A0101", "用户名非法"),
LOGIN_USER_INDEX_INVALID("A0101", "用户索引非法"),
LOGIN_PHONE_NOT_FOUND("A0101", "手机号不存在"),
LOGIN_PHONE_NOT_REGISTER("A0101", "手机号未注册"),
KEY_WRONG("A0101","登录密码/验证码为空"),
LOGIN_WRONG_PWD("A0101", "用户名密码错误"),
LOGIN_WRONG_PHONE_CODE("A0101", "短信验证码错误"),
LOGIN_WRONG_CODE("A0101", "验证码错误"),
CODE_TYPE_ERROR("A0101","验证码类型非法"),
SEND_CODE_FAIL("A0101","验证码发送失败"),
LOGIN_USER_DELETE("A0101", "账号已被注销"),
LOGIN_USER_OVERLIMIT("A0101", "登陆用户数不能大于配置用户并发量"),
LOGIN_USER_LOCKED("A0102", "账号已被锁定"),
LOGIN_USER_UNAUDITED("A0101", "账号未审核"),
NEED_MODIFY_PASSWORD("A0101", "密码需修改"),
LOGIN_USER_SLEEP("A0101", "账号已休眠"),
LOGIN_USER_PASSWORD_EXPIRED("A0101", "账号密码过期"),
LOGIN_ERROR("A0101", "登录失败"),
LOGIN_FIRST_LOGIN("A0101", "账号首次登录"),
NEED_MODIFY_PWD("A0101", "密码失效,请重置"),
PASSWORD_INVALID("A0101", "密码非法"),
PASSWORD_SET_ERROR("A0101", "密码设置错误"),
LACK_USER_STRATEGY("A0101", "缺失用户策略配置"),
UNSUPPORTED_GRANT_TYPE("A0101", "非法认证方式"),
INVALID_IP("A0101", "非法IP访问系统"),
INVALID_TIME("A0101", "用户当前时间段禁止访问"),
PASSWORD_TRANSPORT_ERROR("A0101", "密码传输完整性被破坏"),
SPECIAL_PASSWORD("A0101", "密码需要包含特殊字符字母数字长度为8-16"),
APP_PASSWORD("A0101", "密码长度为8-16"),
REPEAT_PASSWORD("A0101", "新密码与旧密码不能一致"),
MESSAGE_SEND_FAIL("A0102", "短信发送失败"),
REGISTER_FAIL("A0102", "注册失败"),
REGISTER_PHONE_FAIL("A0102", "该号码已注册"),
REGISTER_LOGIN_NAME_FAIL("A0102", "该账号已注册"),
REGISTER_PHONE_WRONG("A0102", "手机号非法"),
REGISTER_PHONE_REPEAT("A0102", "手机号已注册"),
REGISTER_PASSWORD_WRONG("A0102", "账号密码非法"),
DEV_CODE_WRONG("A0102","设备码非法"),
REGISTER_LOGIN_NAME_EXIST("A0102", "该登录名已存在,请检查loginName字段"),
REGISTER_HOMEPAGE_NAME_EXIST("A0102", "该驾驶舱名已存在,请检查name字段"),
FUNCTION_PATH_EXIST("A0102", "菜单路径已存在,请检查path字段"),
COMPONENT_NAME_EXIST("A0102", "组件名已存在,请检查name字段"),
UPDATE_ROLE_REFERRAL_CODE_ERROR("A0103", "推荐码非法"),
PARSE_TOKEN_FORBIDDEN_JWT("A0104", "token已被禁止访问"),
REFRESH_TOKEN_EXPIRE_JWT("A0104", "refresh_token已过期"),
CLIENT_AUTHENTICATION_FAILED("A0105", "客户端认证失败"),
NOT_FOUND_CLIENT("A0105", "客户端不存在"),
DEPT_MISSING("A0106", "未找到此部门"),
DEPT_NODATA("A0107", "部门下暂无用户"),
BIND_USER_DATA("A0108", "已绑定用户,先解绑用户"),
CHILD_DEPT_DATA("A0109", "已绑定子部门,先解绑部门"),
BIND_MONITOR_DATA("A0110", "已绑定监测点,先解绑监测点"),
BINDING_BUTTON("A0110", "已绑定按钮,先删除按钮"),
NO_MENU_DATA("A0111","未找到菜单"),
CHILD_DATA("A0112","数据已绑子节点"),
BIND_ROLE_DATA("A0113","已有角色绑定,请先解绑"),
NO_ROLE_DATA("A0114","未找到此角色"),
BIND_FUNCTION_DATA("A0115","已绑定资源,先解绑资源"),
DEPT_NAME_REPEAT("A0116","部门名称重复"),
ROLE_NAME_REPEAT("A0117","角色名称重复"),
DEPT_PID_EXCEPTION("A0118","新增部门父节点信息异常"),
REFERRAL_CODE_LAPSE("A0119","角色推荐码失效,请联系管理员"),
REFERRAL_CODE_ERROR("A0119","角色推荐码错误,请联系管理员"),
;
private final String code;
private final String message;
UserResponseEnum(String code, String message) {
this.code = code;
this.message = message;
}
public static String getCodeByMsg(String msg){
for (UserResponseEnum userCodeEnum : UserResponseEnum.values()) {
if (userCodeEnum.message.equalsIgnoreCase(msg)) {
return userCodeEnum.code;
}
}
return "";
}
}

View File

@@ -0,0 +1,32 @@
package com.njcn.product.auth.pojo.enums;
import lombok.Getter;
/**
* @author hongawen
* @version 1.0.0
* @createTime 2021年05月25日 15:40
*/
@Getter
public enum UserStatusEnum {
/**
* 用户状态0删除1正常2锁定3待审核4休眠5密码过期
*/
DESTROY(0, "用户已注销"),
NORMAL(1, "正常"),
LOCKED(2, "用户已经被锁定"),
UNCHECK(3, "用户未审核"),
SLEEP(4, "用户已休眠"),
OVERDUE(5, "用户密码已经过期");
private final int code;
private final String message;
UserStatusEnum(int code, String message) {
this.code=code;
this.message=message;
}
}

View File

@@ -0,0 +1,136 @@
package com.njcn.product.auth.pojo.param;
import com.njcn.common.pojo.constant.PatternRegex;
import com.njcn.product.auth.pojo.constant.UserValidMessage;
import com.njcn.web.pojo.param.BaseParam;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.List;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2021/12/29 14:56
*/
@Data
public class UserParam {
@ApiModelProperty("用户名")
@NotBlank(message = UserValidMessage.USERNAME_NOT_BLANK)
@Pattern(regexp = PatternRegex.USERNAME_REGEX, message = UserValidMessage.USERNAME_FORMAT_ERROR)
private String name;
@ApiModelProperty("部门id")
private String deptId;
@ApiModelProperty("电话号码")
@Pattern(regexp = PatternRegex.PHONE_REGEX_OR_NULL, message = UserValidMessage.PHONE_FORMAT_ERROR)
private String phone;
@ApiModelProperty("邮箱")
@Pattern(regexp = PatternRegex.EMAIL_REGEX_OR_NULL, message = UserValidMessage.EMAIL_FORMAT_ERROR)
private String email;
@ApiModelProperty("起始IP")
@NotBlank(message = UserValidMessage.LIMIT_IP_START_NOT_BLANK)
@Pattern(regexp = PatternRegex.IP_REGEX, message = UserValidMessage.LIMIT_IP_START_FORMAT_ERROR)
private String limitIpStart;
@ApiModelProperty("结束IP")
@NotBlank(message = UserValidMessage.LIMIT_IP_END_NOT_BLANK)
@Pattern(regexp = PatternRegex.IP_REGEX, message = UserValidMessage.LIMIT_IP_END_FORMAT_ERROR)
private String limitIpEnd;
@ApiModelProperty("时间段")
@NotBlank(message = UserValidMessage.LIMIT_TIME_NOT_BLANK)
private String limitTime;
@ApiModelProperty("用户类型")
@NotNull(message = UserValidMessage.CASUAL_USER_NOT_BLANK)
@Range(min = 0, max = 1, message = UserValidMessage.PARAM_FORMAT_ERROR)
private Integer casualUser;
@ApiModelProperty("用户权限类型")
@NotNull(message = UserValidMessage.CASUAL_USER_NOT_BLANK)
@Range(min = 0, max = 2, message = UserValidMessage.PARAM_FORMAT_ERROR)
private Integer type;
@ApiModelProperty("短信通知")
@NotNull(message = UserValidMessage.SMS_NOTICE_NOT_BLANK)
@Range(min = 0, max = 1, message = UserValidMessage.PARAM_FORMAT_ERROR)
private Integer smsNotice;
@ApiModelProperty("邮件通知")
@NotNull(message = UserValidMessage.EMAIL_NOTICE_NOT_BLANK)
@Range(min = 0, max = 1, message = UserValidMessage.PARAM_FORMAT_ERROR)
private Integer emailNotice;
@ApiModelProperty("角色")
@NotEmpty(message = UserValidMessage.ROLE_NOT_BLANK)
private List<String> role;
@ApiModelProperty("手机识别码")
private String devCode;
@ApiModelProperty("移动端用户头像")
private String headSculpture;
/**
* 用户新增操作实体
*
* 需要填写的参数:登录名、密码
*/
@Data
@EqualsAndHashCode(callSuper = true)
public static class UserAddParam extends UserParam {
@ApiModelProperty("登录名")
@NotBlank(message = UserValidMessage.LOGIN_NAME_NOT_BLANK)
@Pattern(regexp = PatternRegex.LOGIN_NAME_REGEX, message = UserValidMessage.LOGIN_NAME_FORMAT_ERROR)
private String loginName;
@ApiModelProperty("用户表Id")
@NotNull(message = UserValidMessage.ID_NOT_BLANK)
private String id;
}
/**
* 用户更新操作实体
*
* 需要填写的参数用户的id
*/
@Data
@EqualsAndHashCode(callSuper = true)
public static class UserUpdateParam extends UserParam {
@ApiModelProperty("用户表Id")
@NotBlank(message = UserValidMessage.ID_NOT_BLANK)
private String id;
}
/**
* 分页查询实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
public static class UserQueryParam extends BaseParam {
@ApiModelProperty("用户类型")
@NotNull(message = UserValidMessage.CASUAL_USER_NOT_BLANK)
@Range(min = -1, max = 1, message = UserValidMessage.PARAM_FORMAT_ERROR)
private Integer casualUser;
}
}

View File

@@ -0,0 +1,81 @@
package com.njcn.product.auth.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* @author hongawen
* @since 2021-12-15
*/
@Data
@TableName("sys_auth_client")
public class AuthClient {
private static final long serialVersionUID = 1L;
/**
* 认证客户端Id
*/
private String id;
/**
* 客户端名称
*/
private String name;
/**
* 资源Id列表
*/
private String resourceIds;
/**
* 客户端秘钥
*/
private String clientSecret;
/**
* 域
*/
private String scope;
/**
* 授权方式
*/
private String authorizedGrantTypes;
/**
* 回调地址
*/
private String webServerRedirectUri;
/**
* 权限列表
*/
private String authorities;
/**
* 认证令牌时效 单位:秒
*/
private Integer accessTokenValidity;
/**
* 刷新令牌时效 单位:秒
*/
private Integer refreshTokenValidity;
/**
* 扩展信息
*/
private String additionalInformation;
/**
* 是否自动放行 0-不放行 1-放行
*/
private Boolean autoApprove;
/**
* 状态0-删除 1-正常
*/
private Integer state;
}

View File

@@ -0,0 +1,49 @@
package com.njcn.product.auth.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
* @author hongawen
* @since 2021-12-13
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_role")
public class Role extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 角色表Id
*/
private String id;
/**
* 角色名称
*/
private String name;
/**
* 角色代码有需要用做匹配时候用关联字典表id
*/
private String code;
/**
* 角色描述
*/
private String remark;
/**
* 角色状态0-删除1-正常;默认正常
*/
private Integer state;
/**
* 角色类型0-超级管理员 1-其他管理员 2-其他用户
*/
private Integer type;
}

View File

@@ -0,0 +1,148 @@
package com.njcn.product.auth.pojo.po;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
/**
* @author hongawen
* @since 2021-12-13
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user")
public class User extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private String id;
/**
* 用户名
*/
private String name;
/**
* 登录名
*/
private String loginName;
/**
* 密码
*/
private String password;
/**
* 部门Id
*/
private String deptId;
/**
* 电话号码
*/
private String phone;
/**
* 邮箱
*/
private String email;
/**
* 用户状态0-删除1-正常2-锁定3-待审核4-休眠5-密码过期
*/
private Integer state;
/**
* 用户类型 0:超级管理员1:管理员2:普通用户
*/
private Integer type;
/**
* 数据来源0-外部推送1-正常新增;默认正常新增
*/
private Integer origin;
/**
* 用户类型0-临时用户 1-正式用户
*/
private Integer casualUser;
/**
* 密码状态0-不需要修改 1-需要修改
*/
private Integer pwdState;
/**
* 短信通知0-不通知1-通知)默认不通知
*/
private Integer smsNotice;
/**
* 邮件通知0-不通知1-通知)默认不通知
*/
private Integer emailNotice;
/**
* 推荐码
*/
private String referralCode;
/**
* 注册时间
*/
private LocalDateTime registerTime;
/**
* 密码有效期字段(初始化的时候跟注册时间一样)
*/
private LocalDateTime pwdValidity;
/**
* 最后一次登录时间
*/
private LocalDateTime loginTime;
/**
* 限制登录起始IP
*/
private String limitIpStart;
/**
* 限制登录结束IP
*/
private String limitIpEnd;
/**
* 限制登录时间段(用'-'分割)
*/
private String limitTime;
/**
* 密码错误次数
*/
private Integer loginErrorTimes;
/**
* 首次密码错误时间半个小时错误次数超过N次数则锁定解锁后密码错误次数、首次密码错误时间重置
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime firstErrorTime;
/**
* 用户密码错误锁定时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime lockTime;
private String devCode;
private String headSculpture;
}

View File

@@ -0,0 +1,28 @@
package com.njcn.product.auth.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
*
* @author hongawen
* @since 2021-12-13
*/
@Data
@TableName("sys_user_role")
public class UserRole {
private static final long serialVersionUID = 1L;
/**
* 用户Id
*/
private String userId;
/**
* 角色Id
*/
private String roleId;
}

View File

@@ -0,0 +1,38 @@
package com.njcn.product.auth.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
*
* @author hongawen
* @since 2021-12-13
*/
@Data
@TableName("sys_user_set")
public class UserSet {
private static final long serialVersionUID = 1L;
/**
* 用户配置表Id
*/
private String id;
/**
* 用户Id
*/
private String userId;
/**
* 工作秘钥
*/
private String secretKey;
/**
* SM4-1值
*/
private String standBy;
}

View File

@@ -0,0 +1,72 @@
package com.njcn.product.auth.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
* @author hongawen
* @since 2021-12-13
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user_strategy")
public class UserStrategy extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 用户策略Id
*/
private String id;
/**
* 密码有效期1-6月默认3个月
*/
private Integer limitPwdDate;
/**
* 密码错误次数限定3-20次默认5次
*/
private Integer limitPwdTimes;
/**
* 验证密码错误次数时间范围5-60分钟默认30分钟
*/
private Integer lockPwdCheck;
/**
* 用户锁定时间30-60分钟默认30分钟
*/
private Integer lockPwdTime;
/**
* 用户休眠1-180天默认90天临时用户默认3天
*/
private Integer sleep;
/**
* 用户注销1-360天正常用户默认180天临时用户默认7天
*/
private Integer logout;
/**
* 最大并发数10-99默认50
*/
private Integer maxNum;
/**
* 类型0-临时用户 1-正常用户
*/
private Integer type;
/**
* 状态0-删除 1-正常
*/
private Integer state;
}

View File

@@ -0,0 +1,64 @@
package com.njcn.product.auth.pojo.vo;
import com.njcn.product.auth.pojo.param.UserParam;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2021/12/29 14:31
*/
@Data
public class UserVO extends UserParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户Id")
private String id;
@ApiModelProperty("用户名")
private String name;
@ApiModelProperty("登录名")
private String loginName;
@ApiModelProperty("状态")
private Integer state;
@ApiModelProperty("注册时间")
private String registerTime;
@ApiModelProperty("登录时间")
private String loginTime;
@ApiModelProperty("部门编号")
private String deptId;
@ApiModelProperty("部门名称")
private String deptName;
@ApiModelProperty("区域id")
private String areaId;
@ApiModelProperty("区域名称")
private String areaName;
@ApiModelProperty("部门层级")
private Integer deptLevel;
@ApiModelProperty("角色id")
private List<String> roleList;
@ApiModelProperty("头像")
private String headSculpture;
@ApiModelProperty("角色编码")
private List<String> roleCode;
}

View File

@@ -0,0 +1,58 @@
package com.njcn.product.auth.security.clientdetails;
import com.njcn.common.pojo.enums.auth.PasswordEncoderTypeEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.product.auth.pojo.po.AuthClient;
import com.njcn.product.auth.service.IAuthClientService;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Service;
/**
* OAuth2 客户端信息
* @author hongawen
*/
@Service
@RequiredArgsConstructor
public class ClientDetailsServiceImpl implements ClientDetailsService {
private final IAuthClientService authClientService;
@Override
public ClientDetails loadClientByClientId(String clientName) {
try {
AuthClient authClient = authClientService.getAuthClientByName(clientName);
BaseClientDetails clientDetails = new BaseClientDetails(
authClient.getName(),
authClient.getResourceIds(),
authClient.getScope(),
authClient.getAuthorizedGrantTypes(),
authClient.getAuthorities(),
authClient.getWebServerRedirectUri()
);
clientDetails.setClientSecret(PasswordEncoderTypeEnum.BCRYPT.getPrefix() + authClient.getClientSecret());
clientDetails.setAccessTokenValiditySeconds(authClient.getAccessTokenValidity());
clientDetails.setRefreshTokenValiditySeconds(authClient.getRefreshTokenValidity());
return clientDetails;
} catch (EmptyResultDataAccessException var4) {
throw new NoSuchClientException("No client with requested id: " + clientName);
}
}
public static void main(String[] args) {
PasswordEncoder delegatingPasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
String njcnpqs = delegatingPasswordEncoder.encode("njcnpqs");
//{bcrypt}$2a$10$xIP3g5Rc11zDdclsKXpQXuOobvZ9gaw2Mix1rkOm1MJN1.hTVY7ci
System.out.println(njcnpqs);
System.out.println(delegatingPasswordEncoder.matches("njcnpqs","{bcrypt}$2a$10$xIP3g5Rc11zDdclsKXpQXuOobvZ9gaw2Mix1rkOm1MJN1.hTVY7ci"));
}
}

View File

@@ -0,0 +1,108 @@
package com.njcn.product.auth.security.granter;
import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.sm.DesUtils;
import com.njcn.common.utils.sm.Sm2;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.web.utils.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年12月15日 14:23
*/
@Slf4j
public class CaptchaTokenGranter extends AbstractTokenGranter {
private final AuthenticationManager authenticationManager;
private final RedisUtil redisUtil;
public CaptchaTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
OAuth2RequestFactory requestFactory, AuthenticationManager authenticationManager,
RedisUtil redisUtil
) {
//SecurityConstants.GRANT_CAPTCHA申明为验证码模式
super(tokenServices, clientDetailsService, requestFactory, SecurityConstants.GRANT_CAPTCHA);
this.authenticationManager = authenticationManager;
this.redisUtil = redisUtil;
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
String username = parameters.get(SecurityConstants.USERNAME);
username = DesUtils.aesDecrypt(username);
String verifyCode = parameters.get(SecurityConstants.VERIFY_CODE);
//判断是否需要校验图形验证码,用户错误后,前端要求用户填写验证码
if(StrUtil.isEmpty(verifyCode)||verifyCode.equals("1")){
if (!judgeImageCode(parameters.get(SecurityConstants.IMAGE_CODE), RequestUtil.getRequest())) {
throw new BusinessException(UserResponseEnum.LOGIN_WRONG_CODE);
}
}
String password = parameters.get(SecurityConstants.PASSWORD);
String ip = Objects.requireNonNull(RequestUtil.getRequest()).getHeader(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP);
//密码处理
String privateKey = redisUtil.getStringByKey(username + ip);
//秘钥用完即删
redisUtil.delete(username + ip);
//对SM2解密面进行验证
password = Sm2.getPasswordSM2Verify(privateKey, password);
if (StrUtil.isBlankIfStr(password)) {
throw new BusinessException(UserResponseEnum.PASSWORD_TRANSPORT_ERROR);
}
//1、不将密码放入details内防止密码泄漏
parameters.remove(SecurityConstants.PASSWORD);
//2、组装用户密码模式的认证信息
Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password);
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
try {
//3、认证组装好的信息
userAuth = authenticationManager.authenticate(userAuth);
} catch (AccountStatusException | BadCredentialsException ase) {
//covers expired, locked, disabled cases
throw new InvalidGrantException(ase.getMessage());
}
// If the username/password are wrong the spec says we should send 400/invalid grant
if (userAuth == null || !userAuth.isAuthenticated()) {
throw new InvalidGrantException("无法认证用户: " + username);
}
OAuth2Request storedOauth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
return new OAuth2Authentication(storedOauth2Request, userAuth);
}
/**
* @param imageCode 图形验证码
*/
private boolean judgeImageCode(String imageCode, HttpServletRequest request) {
if (StrUtil.isBlankIfStr(imageCode)) {
return false;
}
String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
String ip = request.getHeader(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP);
String key = userAgent + ip;
String redisImageCode = redisUtil.getStringByKey(key);
if (imageCode.equalsIgnoreCase(redisImageCode)) {
redisUtil.delete(key);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,56 @@
package com.njcn.product.auth.security.granter;
import com.njcn.web.utils.RequestUtil;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.util.Assert;
import java.util.Map;
/**
* 刷新token再次认证 UserDetailsService
*
* @author hongawen
* @date 2021/10/2
*/
@NoArgsConstructor
public class PreAuthenticatedUserDetailsService<T extends Authentication> implements AuthenticationUserDetailsService<T>, InitializingBean {
/**
* 客户端ID和用户服务 UserDetailService 的映射
*
*/
private Map<String, UserDetailsService> userDetailsServiceMap;
public PreAuthenticatedUserDetailsService(Map<String, UserDetailsService> userDetailsServiceMap) {
Assert.notNull(userDetailsServiceMap, "userDetailsService cannot be null.");
this.userDetailsServiceMap = userDetailsServiceMap;
}
@Override
public void afterPropertiesSet() {
Assert.notNull(this.userDetailsServiceMap, "UserDetailsService must be set");
}
/**
* 重写PreAuthenticatedAuthenticationProvider 的 preAuthenticatedUserDetailsService 属性,可根据客户端和认证方式选择用户服务 UserDetailService 获取用户信息 UserDetail
*
* @param authentication .
* @return .
* @throws UsernameNotFoundException .
*/
@Override
public UserDetails loadUserDetails(T authentication) throws UsernameNotFoundException {
String clientId = RequestUtil.getOAuth2ClientId();
// 获取认证方式,默认是用户名 username
UserDetailsService userDetailsService = userDetailsServiceMap.get(clientId);
return userDetailsService.loadUserByUsername(authentication.getName());
}
}

View File

@@ -0,0 +1,98 @@
package com.njcn.product.auth.security.granter;
import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.constant.PatternRegex;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.PubUtils;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.security.token.SmsCodeAuthenticationToken;
import com.njcn.redis.pojo.enums.RedisKeyEnum;
import com.njcn.redis.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AccountStatusException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年12月15日 14:23
*/
@Slf4j
public class SmsTokenGranter extends AbstractTokenGranter {
private final AuthenticationManager authenticationManager;
private final RedisUtil redisUtil;
public SmsTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
OAuth2RequestFactory requestFactory, AuthenticationManager authenticationManager,
RedisUtil redisUtil
) {
//SecurityConstants.GRANT_CAPTCHA申明为手机短信模式
super(tokenServices, clientDetailsService, requestFactory, SecurityConstants.GRANT_SMS_CODE);
this.authenticationManager = authenticationManager;
this.redisUtil = redisUtil;
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
String phone = parameters.get(SecurityConstants.PHONE);
String smsCode = parameters.get(SecurityConstants.SMS_CODE);
if (StrUtil.isBlank(phone) || !PubUtils.match(PatternRegex.PHONE_REGEX, phone)) {
throw new BusinessException(UserResponseEnum.REGISTER_PHONE_WRONG);
}
if (!judgeSmsCode(phone, smsCode)) {
throw new BusinessException(UserResponseEnum.LOGIN_WRONG_CODE);
}
//2、组装用户手机号认证信息
Authentication userAuth = new SmsCodeAuthenticationToken(phone, null);
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
try {
//3、认证组装好的信息
userAuth = authenticationManager.authenticate(userAuth);
} catch (AccountStatusException | BadCredentialsException ase) {
throw new InvalidGrantException(ase.getMessage());
}
if (userAuth == null || !userAuth.isAuthenticated()) {
throw new InvalidGrantException("无法认证用户: " + phone);
}
OAuth2Request storedOauth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
return new OAuth2Authentication(storedOauth2Request, userAuth);
}
/**
* 验证用户的短信验证码是否正确
*
* @param phone 手机号
* @param smsCode 用户输入的短信验证码
* @return boolean
* @author hongawen
* @date 2023/6/14 15:25
*/
private boolean judgeSmsCode(String phone, String smsCode) {
if (StrUtil.isBlankIfStr(smsCode)) {
return false;
}
String key = RedisKeyEnum.SMS_LOGIN_KEY.getKey().concat(phone);
String redisImageCode = redisUtil.getStringByKey(key);
if (smsCode.equalsIgnoreCase(redisImageCode) || Objects.equals(smsCode,"123456789")) {
redisUtil.delete(key);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,341 @@
package com.njcn.product.auth.security.provider;
import com.njcn.product.auth.security.token.SmsCodeAuthenticationToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UserCache;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.cache.NullUserCache;
import org.springframework.util.Assert;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年06月15日 10:08
*/
public abstract class AbstractSmsAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware {
protected final Log logger = LogFactory.getLog(getClass());
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private UserCache userCache = new NullUserCache();
private boolean forcePrincipalAsString = false;
protected boolean hideUserNotFoundExceptions = true;
private UserDetailsChecker preAuthenticationChecks = new DefaultPreAuthenticationChecks();
private UserDetailsChecker postAuthenticationChecks = new DefaultPostAuthenticationChecks();
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
// ~ Methods
// ========================================================================================================
/**
* Allows subclasses to perform any additional checks of a returned (or cached)
* <code>UserDetails</code> for a given authentication request. Generally a subclass
* will at least compare the {@link Authentication#getCredentials()} with a
* {@link UserDetails#getPassword()}. If custom logic is needed to compare additional
* properties of <code>UserDetails</code> and/or
* <code>SmsCodeAuthenticationToken</code>, these should also appear in this
* method.
*
* @param userDetails as retrieved from the
* {@link #retrieveUser(String, SmsCodeAuthenticationToken)} or
* <code>UserCache</code>
* @param authentication the current request that needs to be authenticated
*
* @throws AuthenticationException AuthenticationException if the credentials could
* not be validated (generally a <code>BadCredentialsException</code>, an
* <code>AuthenticationServiceException</code>)
*/
protected abstract void additionalAuthenticationChecks(UserDetails userDetails,
SmsCodeAuthenticationToken authentication)
throws AuthenticationException;
@Override
public final void afterPropertiesSet() throws Exception {
Assert.notNull(this.userCache, "A user cache must be set");
Assert.notNull(this.messages, "A message source must be set");
doAfterPropertiesSet();
}
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
Assert.isInstanceOf(SmsCodeAuthenticationToken.class, authentication,
() -> messages.getMessage(
"AbstractSmsAuthenticationProvider.onlySupports",
"Only SmsCodeAuthenticationToken is supported"));
// Determine username
String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED"
: authentication.getName();
boolean cacheWasUsed = true;
UserDetails user = this.userCache.getUserFromCache(username);
if (user == null) {
cacheWasUsed = false;
try {
user = retrieveUser(username,
(SmsCodeAuthenticationToken) authentication);
}
catch (UsernameNotFoundException notFound) {
logger.debug("User '" + username + "' not found");
if (hideUserNotFoundExceptions) {
throw new BadCredentialsException(messages.getMessage(
"AbstractSmsAuthenticationProvider.badCredentials",
"Bad credentials"));
}
else {
throw notFound;
}
}
Assert.notNull(user,
"retrieveUser returned null - a violation of the interface contract");
}
try {
preAuthenticationChecks.check(user);
additionalAuthenticationChecks(user,
(SmsCodeAuthenticationToken) authentication);
}
catch (AuthenticationException exception) {
if (cacheWasUsed) {
// There was a problem, so try again after checking
// we're using latest data (i.e. not from the cache)
cacheWasUsed = false;
user = retrieveUser(username,
(SmsCodeAuthenticationToken) authentication);
preAuthenticationChecks.check(user);
additionalAuthenticationChecks(user,
(SmsCodeAuthenticationToken) authentication);
}
else {
throw exception;
}
}
postAuthenticationChecks.check(user);
if (!cacheWasUsed) {
this.userCache.putUserInCache(user);
}
Object principalToReturn = user;
if (forcePrincipalAsString) {
principalToReturn = user.getUsername();
}
return createSuccessAuthentication(principalToReturn, authentication, user);
}
/**
* Creates a successful {@link Authentication} object.
* <p>
* Protected so subclasses can override.
* </p>
* <p>
* Subclasses will usually store the original credentials the user supplied (not
* salted or encoded passwords) in the returned <code>Authentication</code> object.
* </p>
*
* @param principal that should be the principal in the returned object (defined by
* the {@link #isForcePrincipalAsString()} method)
* @param authentication that was presented to the provider for validation
* @param user that was loaded by the implementation
*
* @return the successful authentication token
*/
protected Authentication createSuccessAuthentication(Object principal,
Authentication authentication, UserDetails user) {
// Ensure we return the original credentials the user supplied,
// so subsequent attempts are successful even with encoded passwords.
// Also ensure we return the original getDetails(), so that future
// authentication events after cache expiry contain the details
SmsCodeAuthenticationToken result = new SmsCodeAuthenticationToken(
principal, authentication.getCredentials(),
authoritiesMapper.mapAuthorities(user.getAuthorities()));
result.setDetails(authentication.getDetails());
return result;
}
protected void doAfterPropertiesSet() {
}
public UserCache getUserCache() {
return userCache;
}
public boolean isForcePrincipalAsString() {
return forcePrincipalAsString;
}
public boolean isHideUserNotFoundExceptions() {
return hideUserNotFoundExceptions;
}
/**
* Allows subclasses to actually retrieve the <code>UserDetails</code> from an
* implementation-specific location, with the option of throwing an
* <code>AuthenticationException</code> immediately if the presented credentials are
* incorrect (this is especially useful if it is necessary to bind to a resource as
* the user in order to obtain or generate a <code>UserDetails</code>).
* <p>
* Subclasses are not required to perform any caching, as the
* <code>AbstractSmsAuthenticationProvider</code> will by default cache the
* <code>UserDetails</code>. The caching of <code>UserDetails</code> does present
* additional complexity as this means subsequent requests that rely on the cache will
* need to still have their credentials validated, even if the correctness of
* credentials was assured by subclasses adopting a binding-based strategy in this
* method. Accordingly it is important that subclasses either disable caching (if they
* want to ensure that this method is the only method that is capable of
* authenticating a request, as no <code>UserDetails</code> will ever be cached) or
* ensure subclasses implement
* {@link #additionalAuthenticationChecks(UserDetails, SmsCodeAuthenticationToken)}
* to compare the credentials of a cached <code>UserDetails</code> with subsequent
* authentication requests.
* </p>
* <p>
* Most of the time subclasses will not perform credentials inspection in this method,
* instead performing it in
* {@link #additionalAuthenticationChecks(UserDetails, SmsCodeAuthenticationToken)}
* so that code related to credentials validation need not be duplicated across two
* methods.
* </p>
*
* @param username The username to retrieve
* @param authentication The authentication request, which subclasses <em>may</em>
* need to perform a binding-based retrieval of the <code>UserDetails</code>
*
* @return the user information (never <code>null</code> - instead an exception should
* the thrown)
*
* @throws AuthenticationException if the credentials could not be validated
* (generally a <code>BadCredentialsException</code>, an
* <code>AuthenticationServiceException</code> or
* <code>UsernameNotFoundException</code>)
*/
protected abstract UserDetails retrieveUser(String username,
SmsCodeAuthenticationToken authentication)
throws AuthenticationException;
public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
this.forcePrincipalAsString = forcePrincipalAsString;
}
/**
* By default the <code>AbstractSmsAuthenticationProvider</code> throws a
* <code>BadCredentialsException</code> if a username is not found or the password is
* incorrect. Setting this property to <code>false</code> will cause
* <code>UsernameNotFoundException</code>s to be thrown instead for the former. Note
* this is considered less secure than throwing <code>BadCredentialsException</code>
* for both exceptions.
*
* @param hideUserNotFoundExceptions set to <code>false</code> if you wish
* <code>UsernameNotFoundException</code>s to be thrown instead of the non-specific
* <code>BadCredentialsException</code> (defaults to <code>true</code>)
*/
public void setHideUserNotFoundExceptions(boolean hideUserNotFoundExceptions) {
this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
}
@Override
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
}
@Override
public boolean supports(Class<?> authentication) {
return (SmsCodeAuthenticationToken.class
.isAssignableFrom(authentication));
}
protected UserDetailsChecker getPreAuthenticationChecks() {
return preAuthenticationChecks;
}
/**
* Sets the policy will be used to verify the status of the loaded
* <tt>UserDetails</tt> <em>before</em> validation of the credentials takes place.
*
* @param preAuthenticationChecks strategy to be invoked prior to authentication.
*/
public void setPreAuthenticationChecks(UserDetailsChecker preAuthenticationChecks) {
this.preAuthenticationChecks = preAuthenticationChecks;
}
protected UserDetailsChecker getPostAuthenticationChecks() {
return postAuthenticationChecks;
}
public void setPostAuthenticationChecks(UserDetailsChecker postAuthenticationChecks) {
this.postAuthenticationChecks = postAuthenticationChecks;
}
public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) {
this.authoritiesMapper = authoritiesMapper;
}
private class DefaultPreAuthenticationChecks implements UserDetailsChecker {
@Override
public void check(UserDetails user) {
if (!user.isAccountNonLocked()) {
logger.debug("User account is locked");
throw new LockedException(messages.getMessage(
"AbstractSmsAuthenticationProvider.locked",
"User account is locked"));
}
if (!user.isEnabled()) {
logger.debug("User account is disabled");
throw new DisabledException(messages.getMessage(
"AbstractSmsAuthenticationProvider.disabled",
"User is disabled"));
}
if (!user.isAccountNonExpired()) {
logger.debug("User account is expired");
throw new AccountExpiredException(messages.getMessage(
"AbstractSmsAuthenticationProvider.expired",
"User account has expired"));
}
}
}
private class DefaultPostAuthenticationChecks implements UserDetailsChecker {
@Override
public void check(UserDetails user) {
if (!user.isCredentialsNonExpired()) {
logger.debug("User account credentials have expired");
throw new CredentialsExpiredException(messages.getMessage(
"AbstractSmsAuthenticationProvider.credentialsExpired",
"User credentials have expired"));
}
}
}
}

View File

@@ -0,0 +1,92 @@
package com.njcn.product.auth.security.provider;
import com.njcn.common.utils.sm.Sm4Utils;
import com.njcn.product.auth.pojo.bo.BusinessUser;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年06月08日 15:43
*/
@Slf4j
@Component
@AllArgsConstructor
public class Sm4AuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
private final UserDetailsService userDetailsService;
/**
* 校验密码有效性.
*
* @param userDetails 用户详细信息
* @param authentication 用户登录的密码
* @throws AuthenticationException .
*/
@Override
protected void additionalAuthenticationChecks(
UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
if (authentication.getCredentials() == null) {
logger.debug("Authentication failed: no credentials provided");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials",
"Bad credentials"));
}
String presentedPassword = authentication.getCredentials().toString();
BusinessUser businessUser = (BusinessUser)userDetails;
String secretKey = businessUser.getSecretKey();
Sm4Utils sm4 = new Sm4Utils(secretKey);
//SM4加密密码
String sm4PwdOnce = sm4.encryptData_ECB(presentedPassword);
//SM4加密(密码+工作秘钥)
String sm4PwdTwice = sm4.encryptData_ECB(sm4PwdOnce + secretKey);
if(!businessUser.getPassword().equalsIgnoreCase(sm4PwdTwice)){
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials",
businessUser.getUsername()));
}
}
/**
* 获取用户
*
* @param username 用户名
* @param authentication 认证token
* @throws AuthenticationException .
*/
@Override
protected UserDetails retrieveUser(
String username, UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
UserDetails loadedUser = userDetailsService.loadUserByUsername(username);
if (loadedUser == null) {
throw new InternalAuthenticationServiceException(
"UserDetailsService returned null, which is an interface contract violation");
}
return loadedUser;
}
/**
* 授权持久化.
*/
@Override
protected Authentication createSuccessAuthentication(Object principal,
Authentication authentication, UserDetails user) {
return super.createSuccessAuthentication(principal, authentication, user);
}
}

View File

@@ -0,0 +1,74 @@
package com.njcn.product.auth.security.provider;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.security.token.SmsCodeAuthenticationToken;
import com.njcn.product.auth.service.UserDetailsServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
/**
* 手机短信码验证完后,返回用户的
* @author hongawen
* @version 1.0.0
* @date 2021年06月08日 15:43
*/
@Slf4j
@Component
@AllArgsConstructor
public class SmsAuthenticationProvider extends AbstractSmsAuthenticationProvider {
private final UserDetailsServiceImpl userDetailsService;
/**
* 校验密码有效性.
* 因为手机号验证码登录验证码没问题后密码无需校验直接返回该用户的token信息便可以
*
* @param userDetails 用户详细信息
* @param authentication 用户登录的密码
* @throws AuthenticationException .
*/
@Override
protected void additionalAuthenticationChecks(
UserDetails userDetails, SmsCodeAuthenticationToken authentication)
throws AuthenticationException {
}
/**
* 获取用户
*
* @param phone 手机号
* @param authentication 认证token
* @throws AuthenticationException .
*/
@Override
protected UserDetails retrieveUser(
String phone, SmsCodeAuthenticationToken authentication)
throws AuthenticationException {
//根据手机号获取用户信息
UserDetails loadedUser = userDetailsService.loadUserByPhone(phone);
if (loadedUser == null) {
throw new BusinessException(UserResponseEnum.LOGIN_PHONE_NOT_REGISTER);
}
return loadedUser;
}
/**
* 授权持久化.
*/
@Override
protected Authentication createSuccessAuthentication(Object principal,
Authentication authentication, UserDetails user) {
return super.createSuccessAuthentication(principal, authentication, user);
}
}

View File

@@ -0,0 +1,62 @@
package com.njcn.product.auth.security.token;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert;
import java.util.Collection;
/**
* UsernamePasswordAuthenticationToken 一样,
* 继承 AbstractAuthenticationToken 抽象类,
* 需要实现 getPrincipal 和 getCredentials 两个方法。
* 在用户名/密码认证中principal 表示用户名,
* credentials 表示密码,在此,我们可以让它们指代手机号和验证码。
*
* @author hongawen
* @version 1.0.0
* @date 2023年06月14日 16:25
*/
public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private Object credentials;
public SmsCodeAuthenticationToken(Object principal, Object credentials) {
super(null);
this.principal = principal;
this.credentials = credentials;
setAuthenticated(false);
}
public SmsCodeAuthenticationToken(Object principal, Object credentials,
Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return this.credentials;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
Assert.isTrue(!isAuthenticated,
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
this.credentials = null;
}
}

View File

@@ -0,0 +1,27 @@
package com.njcn.product.auth.service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年06月15日 10:26
*/
public interface CustomUserDetailsService extends UserDetailsService {
/**
* @param username 用户名
* @return 用户信息
*/
@Override
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
/**
* @param phone 手机号
* @return 用户信息
*/
UserDetails loadUserByPhone(String phone) throws UsernameNotFoundException;
}

View File

@@ -0,0 +1,22 @@
package com.njcn.product.auth.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.product.auth.pojo.po.AuthClient;
/**
* <p>
* 服务类
* </p>
*
* @author hongawen
* @since 2021-12-15
*/
public interface IAuthClientService extends IService<AuthClient> {
/**
* 根据客户端名称获取客户端
* @param clientName 客户端名称
* @return .
*/
AuthClient getAuthClientByName(String clientName);
}

View File

@@ -0,0 +1,26 @@
package com.njcn.product.auth.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.product.auth.pojo.po.Role;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface IRoleService extends IService<Role> {
/**
* 根据用户id获取角色名
* @param id 用户id
* @return 角色名集合
*/
List<String> getRoleNameByUserId(String id);
}

View File

@@ -0,0 +1,30 @@
package com.njcn.product.auth.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.product.auth.pojo.po.UserRole;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface IUserRoleService extends IService<UserRole> {
/**
* 根据用户索引获取 用户--角色关系数据
* @param id 用户ID
* @return 关系数据
*/
List<UserRole> getUserRoleByUserId(String id);
}

View File

@@ -0,0 +1,61 @@
package com.njcn.product.auth.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.product.auth.pojo.dto.UserDTO;
import com.njcn.product.auth.pojo.param.UserParam;
import com.njcn.product.auth.pojo.po.User;
import com.njcn.product.auth.pojo.vo.UserVO;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface IUserService extends IService<User> {
/**
* 根据登录名获取用户信息
* @param loginName 登录名
* @return 用户信息
*/
UserDTO getUserByName(String loginName);
/**
* 认证结束后,判断用户状态是否能正常访问系统
* @param loginName 登录名
*/
void judgeUserStatus(String loginName);//used
/**
* 功能描述:修改用户登录认证密码错误次数
* @param loginName 登录名
* @return boolean
* @author xy
*/
String updateUserLoginErrorTimes(String loginName);//used
UserDTO loadUserByPhone(String phone);
/**
* 功能描述:根据用户id获取用户详情
* TODO
*
* @param id
* @return com.njcn.user.pojo.vo.UserVO
* @author xy
* @date 2022/1/13 17:10
*/
UserVO getUserById(String id);
List<User> simpleList(Boolean allUserFlag);
}

View File

@@ -0,0 +1,18 @@
package com.njcn.product.auth.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.product.auth.pojo.po.UserSet;
/**
* <p>
* 服务类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface IUserSetService extends IService<UserSet> {
}

View File

@@ -0,0 +1,22 @@
package com.njcn.product.auth.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.product.auth.pojo.po.UserStrategy;
/**
* <p>
* 服务类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
public interface IUserStrategyService extends IService<UserStrategy> {
/**
* 查询用户策略数据
* @return 用户策略信息
* @param casualUser 是否为 casual用户
*/
UserStrategy getUserStrategy(Integer casualUser);
}

View File

@@ -0,0 +1,64 @@
package com.njcn.product.auth.service;
import cn.hutool.core.bean.BeanUtil;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.LogUtil;
import com.njcn.product.auth.pojo.bo.BusinessUser;
import com.njcn.product.auth.pojo.dto.UserDTO;
import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
/**
* @author hongawen
* <p>
* 自定义用户认证和授权
*/
@Slf4j
@Service
@AllArgsConstructor
public class UserDetailsServiceImpl implements CustomUserDetailsService {
private final IUserService userService;
@SneakyThrows
@Override
public UserDetails loadUserByUsername(String loginName) throws UsernameNotFoundException {
String clientId = RequestUtil.getOAuth2ClientId();
BusinessUser businessUser = new BusinessUser(loginName, null, null);
businessUser.setClientId(clientId);
UserDTO userDTO = userService.getUserByName(loginName);
LogUtil.njcnDebug(log, "用户认证时,用户名:{}获取用户信息:{}", loginName, userDTO.toString());
//成功获取用户信息
BeanUtil.copyProperties(userDTO, businessUser, true);
//处理头像
// dealHead(businessUser);
businessUser.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",", userDTO.getRoleName())));
return businessUser;
}
@Override
public UserDetails loadUserByPhone(String phone) throws UsernameNotFoundException {
String clientId = RequestUtil.getOAuth2ClientId();
BusinessUser businessUser = new BusinessUser(phone, null, null);
businessUser.setClientId(clientId);
UserDTO userDTO = userService.loadUserByPhone(phone);
LogUtil.njcnDebug(log, "用户验证码认证时,用户名:{}获取用户信息:{}", phone, userDTO.toString());
//成功获取用户信息
BeanUtil.copyProperties(userDTO, businessUser, true);
// dealHead(businessUser);
businessUser.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",", userDTO.getRoleName())));
return businessUser;
}
}

View File

@@ -0,0 +1,128 @@
package com.njcn.product.auth.service;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.JWSObject;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.dto.UserTokenInfo;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.redis.utils.RedisUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author hongawen
* @version 1.0.0
* @date 2022年03月11日 10:34
*/
@Slf4j
@Service
@AllArgsConstructor
public class UserTokenService {
private final RedisUtil redisUtil;
/**
* 记录用户token信息并经过处理后达到最新登录的使用者将之前的token信息置为黑名单过期状态
* 1、从在线名单中获取该用户的token信息key为:TOKEN_ONLINE_PREFIX+useridvalue为userTokenInfo的json对象
* 1.1 有,则表示有人使用该账户登录过
* 1.1.1 将在线名单的用户信息添加到黑名单并清除黑名单中已经过期的token信息
* 重新赋值黑名单信息key为TOKEN_BLACKLIST_PREFIX+userid,value为userTokenInfo的集合
* 1.2 没有该账号当前只有本人在登录将当前token等信息保存到白名单
*
* @param oAuth2AccessToken 认证后的最新token信息
*/
@Async("asyncExecutor")
public void recordUserInfo(OAuth2AccessToken oAuth2AccessToken, String ip) {
UserTokenInfo userTokenInfo = new UserTokenInfo();
String accessTokenValue = oAuth2AccessToken.getValue();
JWSObject accessJwsObject;
try {
accessJwsObject = JWSObject.parse(accessTokenValue);
} catch (ParseException e) {
throw new BusinessException(CommonResponseEnum.PARSE_TOKEN_ERROR);
}
JSONObject accessJson = JSONUtil.parseObj(accessJwsObject.getPayload().toString());
String userIndex = accessJson.getStr(SecurityConstants.USER_INDEX_KEY);
// String nickName = accessJson.getStr(SecurityConstants.USER_NICKNAME_KEY);
// String loginName = accessJson.getStr(SecurityConstants.USER_NAME_KEY);
//查询是否有在线的当前用户
String onlineUserKey = SecurityConstants.TOKEN_ONLINE_PREFIX + userIndex;
Object onlineTokenInfoOld = redisUtil.getObjectByKey(onlineUserKey);
if (!Objects.isNull(onlineTokenInfoOld)) {
//存在在线用户,将在线用户添加到黑名单列表
String blackUserKey = SecurityConstants.TOKEN_BLACKLIST_PREFIX + userIndex;
List<UserTokenInfo> blackUsers = (List<UserTokenInfo>) redisUtil.getObjectByKey(blackUserKey);
if (CollectionUtils.isEmpty(blackUsers)) {
blackUsers = new ArrayList<>();
}
blackUsers.add((UserTokenInfo) onlineTokenInfoOld);
//筛选黑名单中是否存在过期的token信息
blackUsers.removeIf(userTokenInfoTemp -> userTokenInfoTemp.getRefreshTokenExpire().isBefore(LocalDateTime.now()));
//将黑名单集合重新缓存此处根据最新的黑名单计算当前这个key的生命周期在时间差的基础上增加5分钟的延迟时间
LocalDateTime refreshTokenExpire = ((UserTokenInfo) onlineTokenInfoOld).getRefreshTokenExpire();
long lifeTime = Math.abs(refreshTokenExpire.plusMinutes(5L).toEpochSecond(ZoneOffset.of("+8")) - LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
redisUtil.saveByKeyWithExpire(blackUserKey, blackUsers, lifeTime);
}
String accessJti = accessJson.getStr(SecurityConstants.JWT_JTI);
OAuth2RefreshToken refreshToken = oAuth2AccessToken.getRefreshToken();
JWSObject refreshJwsObject;
try {
refreshJwsObject = JWSObject.parse(refreshToken.getValue());
} catch (ParseException e) {
throw new BusinessException(CommonResponseEnum.PARSE_TOKEN_ERROR);
}
JSONObject refreshJson = JSONUtil.parseObj(refreshJwsObject.getPayload().toString());
// String refreshJti = refreshJson.getStr(SecurityConstants.JWT_JTI);
Long refreshExpireTime = refreshJson.getLong(SecurityConstants.JWT_EXP);
userTokenInfo.setAccessTokenJti(accessJti);
userTokenInfo.setRefreshToken(refreshToken.getValue());
LocalDateTime refreshLifeTime = LocalDateTime.ofEpochSecond(refreshExpireTime, 0, ZoneOffset.of("+8"));
userTokenInfo.setRefreshTokenExpire(refreshLifeTime);
//生命周期在refreshToken的基础上延迟5分钟
redisUtil.saveByKeyWithExpire(onlineUserKey, userTokenInfo, refreshLifeTime.plusMinutes(5L).toEpochSecond(ZoneOffset.of("+8")) - LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
//记录成功登录后的信息
//LogInfoDTO logInfoDTO = new LogInfoDTO(loginName, nickName, ip, "登录认证", OperateType.AUTHENTICATE, 1, "", 0, 1, generalInfo.getMicroServiceName(), userIndex,LocalDateTime.now());
//publisher.send("/userLog", PubUtils.obj2json(logInfoDTO), 2, false);
}
/**
* 校验刷新token是否被加入黑名单
*
* @param refreshToken 刷新token
*/
public void judgeRefreshToken(String refreshToken) {
JWSObject refreshJwsObject;
try {
refreshJwsObject = JWSObject.parse(refreshToken);
} catch (ParseException e) {
throw new BusinessException();
}
JSONObject refreshJson = JSONUtil.parseObj(refreshJwsObject.getPayload().toString());
String userIndex = refreshJson.getStr(SecurityConstants.USER_INDEX_KEY);
String blackUserKey = SecurityConstants.TOKEN_BLACKLIST_PREFIX + userIndex;
List<UserTokenInfo> blackUsers = (List<UserTokenInfo>) redisUtil.getObjectByKey(blackUserKey);
if (CollectionUtils.isNotEmpty(blackUsers)) {
blackUsers.forEach(temp -> {
//存在当前的刷新token则抛出业务异常
if (temp.getRefreshToken().equalsIgnoreCase(refreshToken)) {
throw new BusinessException(CommonResponseEnum.TOKEN_EXPIRE_JWT);
}
});
}
}
}

View File

@@ -0,0 +1,32 @@
package com.njcn.product.auth.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.product.auth.mapper.AuthClientMapper;
import com.njcn.product.auth.pojo.po.AuthClient;
import com.njcn.product.auth.service.IAuthClientService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author hongawen
* @since 2021-12-15
*/
@Service
@RequiredArgsConstructor
public class AuthClientServiceImpl extends ServiceImpl<AuthClientMapper, AuthClient> implements IAuthClientService {
@Override
public AuthClient getAuthClientByName(String clientName) {
return lambdaQuery()
.eq(AuthClient::getName,clientName)
.eq(AuthClient::getState,DataStateEnum.ENABLE.getCode())
.one();
}
}

View File

@@ -0,0 +1,57 @@
package com.njcn.product.auth.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.product.auth.mapper.RoleMapper;
import com.njcn.product.auth.pojo.po.Role;
import com.njcn.product.auth.pojo.po.UserRole;
import com.njcn.product.auth.service.IRoleService;
import com.njcn.product.auth.service.IUserRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
private final IUserRoleService iUserRoleService;
@Override
public List<String> getRoleNameByUserId(String id) {
List<UserRole> userRoles = iUserRoleService.getUserRoleByUserId(id);
if (CollectionUtils.isEmpty(userRoles)) {
return new ArrayList<>();
}
List<Role> roles = this.lambdaQuery()
.select(Role::getCode)
.eq(Role::getState, DataStateEnum.ENABLE.getCode())
.in(Role::getId, userRoles.stream()
.map(UserRole::getRoleId)
.collect(Collectors.toList())
).list();
return roles
.stream()
.map(Role::getCode)
.distinct()
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,39 @@
package com.njcn.product.auth.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.product.auth.mapper.UserRoleMapper;
import com.njcn.product.auth.pojo.po.Role;
import com.njcn.product.auth.pojo.po.UserRole;
import com.njcn.product.auth.service.IUserRoleService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
@Service
@AllArgsConstructor
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements IUserRoleService {
private final UserRoleMapper userRoleMapper;
@Override
public List<UserRole> getUserRoleByUserId(String id) {
return this.lambdaQuery().eq(UserRole::getUserId, id).list();
}
}

View File

@@ -0,0 +1,309 @@
package com.njcn.product.auth.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.config.GeneralInfo;
import com.njcn.common.pojo.constant.LogInfo;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.PubUtils;
import com.njcn.product.auth.pojo.dto.UserDTO;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.pojo.enums.UserStatusEnum;
import com.njcn.product.auth.mapper.UserMapper;
import com.njcn.product.auth.pojo.constant.UserState;
import com.njcn.product.auth.pojo.po.*;
import com.njcn.product.auth.pojo.vo.UserVO;
import com.njcn.product.auth.service.*;
import com.njcn.product.system.dept.pojo.po.Dept;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
/**
* <p>
* 服务实现类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
private final IUserStrategyService userStrategyService;
private final IRoleService roleService;
private final IUserSetService userSetService;
@Override
public UserDTO getUserByName(String loginName) {
User user = getUserByLoginName(loginName);
if (Objects.isNull(user)) {
return null;
}
List<String> roleNames = roleService.getRoleNameByUserId(user.getId());
UserSet userSet = userSetService.lambdaQuery().eq(UserSet::getUserId, user.getId()).one();
return new UserDTO(user.getId(), user.getLoginName(), user.getName(), user.getPassword(), roleNames, userSet.getSecretKey(), userSet.getStandBy(), user.getDeptId(), user.getType(), user.getHeadSculpture());
}
@Override
public void judgeUserStatus(String loginName) {
User user = getUserByLoginName(loginName);
if (Objects.isNull(user)) {
throw new BusinessException(UserResponseEnum.LOGIN_WRONG_PWD);
}
//超级管理员则不做任何逻辑判断
if (user.getType() == 0) {
//更新用户登录时间,以及错误登录记录的信息归零。
user.setState(UserState.ENABLE);
user.setLoginErrorTimes(0);
user.setLoginTime(LocalDateTime.now());
user.setFirstErrorTime(null);
user.setLockTime(null);
this.baseMapper.updateById(user);
return;
}
//根据用户类型获取对应用户策略
UserStrategy userStrategy = userStrategyService.lambdaQuery()
.eq(UserStrategy::getType, user.getCasualUser())
.eq(UserStrategy::getState, DataStateEnum.ENABLE.getCode())
.one();
switch (user.getState()) {
case UserState.LOCKED:
LocalDateTime lockTime = user.getLockTime();
lockTime = lockTime.plusMinutes(userStrategy.getLockPwdTime());
LocalDateTime nowTime = LocalDateTime.now();
//判断是否满足锁定时间
if (nowTime.isBefore(lockTime)) {
CommonResponseEnum testEnum = CommonResponseEnum.DYNAMIC_RESPONSE_ENUM;
testEnum.setMessage("账号已被锁定:锁定剩余时长" + ChronoUnit.MINUTES.between(nowTime, lockTime) + "分钟");
throw new BusinessException(testEnum);
}
break;
case UserState.DELETE:
//用户已注销
throw new BusinessException(UserResponseEnum.LOGIN_USER_DELETE);
case UserState.UNCHECK:
//用户未审核
throw new BusinessException(UserResponseEnum.LOGIN_USER_UNAUDITED);
case UserState.SLEEP:
//用户已休眠
throw new BusinessException(UserResponseEnum.LOGIN_USER_SLEEP);
case UserState.OVERDUE:
//用户密码已过期
throw new BusinessException(UserResponseEnum.LOGIN_USER_PASSWORD_EXPIRED);
default:
if (user.getPwdState() == 1) {
throw new BusinessException(UserResponseEnum.NEED_MODIFY_PWD);
}
//用户状态正常,判断其他细节
judgeFirstLogin(user, userStrategy);
}
//所有验证通过后,更新用户登录时间,以及错误登录记录的信息归零。
user.setState(UserState.ENABLE);
user.setLoginErrorTimes(0);
user.setLoginTime(LocalDateTime.now());
user.setFirstErrorTime(null);
user.setLockTime(null);
this.baseMapper.updateById(user);
}
/**
* 根据登录名查询用户
*
* @param loginName 登录名
* @return 用户信息
*/
private User getUserByLoginName(String loginName) {
return lambdaQuery()
.eq(User::getLoginName, loginName)
.one();
}
/**
* 判断是否需要修改密码
*/
private void judgeFirstLogin(@NotNull User user, UserStrategy userStrategy) {
if (user.getPwdState() == 1) {
throw new BusinessException(UserResponseEnum.NEED_MODIFY_PWD);
} else {
judgeIp(user, userStrategy);
}
}
/**
* 判断用户是否在合理的IP内登录
*/
private void judgeIp(@NotNull User user, UserStrategy userStrategy) {
String ipSection = user.getLimitIpStart() + "-" + user.getLimitIpEnd();
log.error("用户实际ip:" + RequestUtil.getRealIp());
log.error("用户限制ip:" + ipSection);
if (RequestUtil.getRealIp().equalsIgnoreCase(LogInfo.UNKNOWN_IP)) {
//feign接口可能获取的IP是空的
throw new BusinessException(UserResponseEnum.INVALID_IP);
} else if (!PubUtils.ipExistsInRange(RequestUtil.getRealIp(), ipSection)) {
throw new BusinessException(UserResponseEnum.INVALID_IP);
} else {
judgeLimitTime(user, userStrategy);
}
judgeLimitTime(user, userStrategy);
}
/**
* 判断用户是否在允许的时间段内登录
*/
private void judgeLimitTime(@NotNull User user, UserStrategy userStrategy) {
int nowHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
String[] limitTime = user.getLimitTime().split(StrUtil.DASHED);
if (nowHour >= Integer.parseInt(limitTime[0]) && nowHour < Integer.parseInt(limitTime[1])) {
judgePwdTimeValidity(user, userStrategy);
} else {
throw new BusinessException(UserResponseEnum.INVALID_TIME);
}
}
/**
* 判断用户密码是否已经过期
*/
private void judgePwdTimeValidity(@NotNull User user, UserStrategy userStrategy) {
LocalDateTime pwdValidity = user.getPwdValidity();
pwdValidity = pwdValidity.plusMonths(userStrategy.getLimitPwdDate());
if (LocalDateTime.now().isBefore(pwdValidity)) {
judgeLeisurePwd(user, userStrategy);
} else {
//将用户状态置为过期
user.setState(UserState.OVERDUE);
this.baseMapper.updateById(user);
throw new BusinessException(UserResponseEnum.LOGIN_USER_PASSWORD_EXPIRED);
}
}
/**
* 判断用户闲置
*/
private void judgeLeisurePwd(@NotNull User user, UserStrategy userStrategy) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime sleepTime = user.getLoginTime().plusDays(userStrategy.getSleep());
LocalDateTime logoutTime = user.getLoginTime().plusDays(userStrategy.getLogout());
if (now.isAfter(sleepTime) && now.isBefore(logoutTime)) {
//将用户状态置为休眠
user.setState(UserState.SLEEP);
this.baseMapper.updateById(user);
throw new BusinessException(UserResponseEnum.LOGIN_USER_SLEEP);
} else if (now.isAfter(logoutTime)) {
//将用户状态置为注销
user.setState(UserState.DELETE);
this.baseMapper.updateById(user);
throw new BusinessException(UserResponseEnum.LOGIN_USER_DELETE);
}
}
@Override
public UserDTO loadUserByPhone(String phone) {
User user = getUserByPhone(phone, false, null);
if (Objects.isNull(user)) {
return null;
}
List<String> roleNames = roleService.getRoleNameByUserId(user.getId());
UserSet userSet = userSetService.lambdaQuery().eq(UserSet::getUserId, user.getId()).one();
return new UserDTO(user.getId(), user.getLoginName(), user.getName(), user.getPassword(), roleNames, userSet.getSecretKey(), userSet.getStandBy(), user.getDeptId(), user.getType(), user.getHeadSculpture());
}
@Override
public UserVO getUserById(String id) {
UserVO userVO = new UserVO();
User user = lambdaQuery().eq(User::getId, id).one();
if (Objects.isNull(user)) {
return null;
}
BeanUtil.copyProperties(user, userVO);
return userVO;
}
@Override
public List<User> simpleList(Boolean allUserFlag) {
LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
userLambdaQueryWrapper.select(User::getId, User::getName,User::getLoginName).eq(User::getState, DataStateEnum.ENABLE.getCode());
if(!allUserFlag){
userLambdaQueryWrapper.eq(User::getType,2);
}
return this.baseMapper.selectList(userLambdaQueryWrapper);
}
/**
* 根据手机号查询用户
*
* @param phone 手机号码
* @return 用户信息
*/
private User getUserByPhone(String phone, boolean result, String id) {
if (result) {
return lambdaQuery()
.eq(User::getPhone, phone)
.ne(User::getId, id)
.one();
} else {
return lambdaQuery()
.eq(User::getPhone, phone)
.one();
}
}
@Override
public String updateUserLoginErrorTimes(String loginName) {
User user = this.lambdaQuery().eq(User::getLoginName, loginName).one();
LocalDateTime now = LocalDateTime.now();
if (Objects.nonNull(user)) {
UserStrategy userStrategy = userStrategyService.getUserStrategy(user.getCasualUser());
Integer loginErrorTimes = user.getLoginErrorTimes();
++loginErrorTimes;
if (Objects.isNull(user.getFirstErrorTime())) {
//首次错误错误1次、记录第一次错误时间
user.setLoginErrorTimes(loginErrorTimes);
user.setFirstErrorTime(LocalDateTime.now());
} else if (loginErrorTimes <= userStrategy.getLimitPwdTimes()) {
//如果次数在策略之内,还未被锁定
LocalDateTime firstErrorTime = user.getFirstErrorTime();
firstErrorTime = firstErrorTime.plusMinutes(userStrategy.getLockPwdCheck());
if (now.isAfter(firstErrorTime)) {
//重置密码错误次数、时间等记录
user.setLoginErrorTimes(1);
user.setFirstErrorTime(LocalDateTime.now());
} else {
user.setLoginErrorTimes(loginErrorTimes);
}
} else {
user.setLockTime(LocalDateTime.now());
user.setState(UserStatusEnum.LOCKED.getCode());
user.setLoginErrorTimes(loginErrorTimes);
this.baseMapper.updateById(user);
return UserResponseEnum.LOGIN_USER_LOCKED.getMessage();
}
this.baseMapper.updateById(user);
}
return CommonResponseEnum.SUCCESS.getMessage();
}
}

View File

@@ -0,0 +1,29 @@
package com.njcn.product.auth.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.product.auth.mapper.UserSetMapper;
import com.njcn.product.auth.pojo.po.UserSet;
import com.njcn.product.auth.service.IUserSetService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>
* 服务实现类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
@Service
@RequiredArgsConstructor
public class UserSetServiceImpl extends ServiceImpl<UserSetMapper, UserSet> implements IUserSetService {
}

View File

@@ -0,0 +1,37 @@
package com.njcn.product.auth.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.mapper.UserStrategyMapper;
import com.njcn.product.auth.pojo.po.UserStrategy;
import com.njcn.product.auth.service.IUserStrategyService;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
* <p>
* 服务实现类
* </p>
*
* @author hongawen
* @since 2021-12-13
*/
@Service
public class UserStrategyServiceImpl extends ServiceImpl<UserStrategyMapper, UserStrategy> implements IUserStrategyService {
@Override
public UserStrategy getUserStrategy(Integer casualUser) {
UserStrategy userStrategy = this.lambdaQuery()
.eq(UserStrategy::getState, DataStateEnum.ENABLE.getCode())
.eq(UserStrategy::getType, casualUser)
.one();
if (Objects.isNull(userStrategy)) {
throw new BusinessException(UserResponseEnum.LACK_USER_STRATEGY);
}
return userStrategy;
}
}

View File

@@ -0,0 +1,41 @@
package com.njcn.product.auth.utils;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.JWSObject;
import lombok.SneakyThrows;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年06月04日 14:00
*/
public class AuthPubUtil {
public static String getKaptchaText(int codeLength) {
StringBuilder code = new StringBuilder();
int letterLength = RandomUtil.randomInt(codeLength - 1) + 1;
code.append(RandomUtil.randomString(RandomUtil.BASE_CHAR, letterLength).toUpperCase(Locale.ROOT));
int numberLength = codeLength - letterLength;
code.append(RandomUtil.randomString(RandomUtil.BASE_NUMBER, numberLength));
List<String> textList = Arrays.asList(code.toString().split(""));
//填充完字符后,打乱顺序,返回字符串
Collections.shuffle(textList);
return String.join("", textList);
}
@SneakyThrows
public static JSONObject getLoginByToken(String token){
JWSObject jwsObject = JWSObject.parse(token);
String payload = jwsObject.getPayload().toString();
return JSONUtil.parseObj(payload);
}
}

View File

@@ -0,0 +1,133 @@
package com.njcn.product.carrycapacity.controller;
import com.alibaba.excel.EasyExcel;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.product.carrycapacity.pojo.excel.CarryCapcityDataEexcel;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityCalParam;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityEvaluateParam;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityQueryDataParam;
import com.njcn.product.carrycapacity.pojo.param.ExcelDataParam;
import com.njcn.product.carrycapacity.pojo.vo.CarryCapacityDResultVO;
import com.njcn.product.carrycapacity.pojo.vo.CarryCapacityDataIVO;
import com.njcn.product.carrycapacity.pojo.vo.CarryCapacityDataQVO;
import com.njcn.product.carrycapacity.pojo.vo.CarryCapacityDataVO;
import com.njcn.product.carrycapacity.service.CarryCapacityService;
import com.njcn.product.carrycapacity.util.EasyExcelUtil;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年07月21日 10:06
*/
@RestController
@RequestMapping("carrycapacity")
@Api(tags = "承载能力评估")
@RequiredArgsConstructor
public class CarryCapacityController extends BaseController {
private final CarryCapacityService carryCapcityService;
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queryCarryCapacityData")
@ApiOperation("承载能力评估数据查询-主页面")
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
public HttpResult<CarryCapacityDataVO> queryCarryCapacityData(@RequestBody @Validated CarryCapacityQueryDataParam queryParam) {
String methodDescribe = getMethodDescribe("queryCarryCapacityData");
CarryCapacityDataVO carryCapacityDataVO = carryCapcityService.queryCarryCapacityData(queryParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, carryCapacityDataVO, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queryCarryCapacityQData")
@ApiOperation("承载能力评估数据查询-无功功率")
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
public HttpResult<CarryCapacityDataQVO> queryCarryCapacityQData(@RequestBody @Validated CarryCapacityQueryDataParam queryParam) {
String methodDescribe = getMethodDescribe("queryCarryCapacityQData");
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, carryCapcityService.queryCarryCapacityqData(queryParam), methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queryCarryCapacityIData")
@ApiOperation("承载能力评估数据查询-谐波电流幅值")
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
public HttpResult<CarryCapacityDataIVO> queryCarryCapacityIData(@RequestBody @Validated CarryCapacityQueryDataParam queryParam) {
String methodDescribe = getMethodDescribe("queryCarryCapacityIData");
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, carryCapcityService.queryCarryCapacityiData(queryParam), methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/carryCapacityCal")
@ApiOperation("承载能力评估")
@ApiImplicitParam(name = "calParam", value = "计算参数", required = true)
public HttpResult<CarryCapacityDResultVO> carryCapacityCal(@RequestBody @Validated CarryCapacityCalParam calParam) {
String methodDescribe = getMethodDescribe("carryCapacityCal");
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, carryCapcityService.carryCapacityCal(calParam), methodDescribe);
}
// @OperateInfo(info = LogEnum.BUSINESS_COMMON)
// @GetMapping("/carryCapacityTree")
// @ApiOperation("承载能力评估-台账树")
// public HttpResult<List<TerminalTree>> carryCapacityTree() {
// String methodDescribe = getMethodDescribe("carryCapacityTree");
// List<TerminalTree> terminalTree = carryCapcityService.carryCapacityTree();
// return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, terminalTree, methodDescribe);
// }
@ResponseBody
@ApiOperation("导出数据集模板")
@GetMapping(value = "getExcelTemplate")
public HttpResult<String> getExcelTemplate(HttpServletResponse response) throws IOException {
String sheetName = "数据集模版";
List<CarryCapcityDataEexcel> excels = new ArrayList<>();
CarryCapcityDataEexcel exportHeadersExcel = new CarryCapcityDataEexcel();
excels.add(exportHeadersExcel);
EasyExcel.write(response.getOutputStream(), CarryCapcityDataEexcel.class)
.sheet(sheetName)
.doWrite(excels);
EasyExcelUtil.writeWithSheetsWeb(response, "数据集模版.xlsx");
return null;
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/uploadExcel")
@ApiOperation("上传数据集")
public HttpResult<Boolean> uploadExcel(@Validated ExcelDataParam excelDataParam) throws Exception {
String methodDescribe = getMethodDescribe("uploadExcel");
boolean flag = carryCapcityService.uploadExcel(excelDataParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/carryCapacityEvaluate")
@ApiOperation("承载能力评估_充电站、电加热负荷、电气化铁路承载能力评估")
@ApiImplicitParam(name = "calParam", value = "计算参数", required = true)
public HttpResult<CarryCapacityDResultVO> carryCapacityEvaluate(@RequestBody @Validated CarryCapacityEvaluateParam calParam) {
String methodDescribe = getMethodDescribe("carryCapacityEvaluate");
CarryCapacityDResultVO vo = carryCapcityService.carryCapacityEvaluate(calParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, vo, methodDescribe);
}
}

View File

@@ -0,0 +1,85 @@
package com.njcn.product.carrycapacity.controller;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityDeviceParam;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityDevicePO;
import com.njcn.product.carrycapacity.service.CarryCapacityDevicePOService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年07月21日 10:06
*/
@RestController
@RequestMapping("carrycapacitydev")
@Api(tags = "承载能力评估用户设备")
@RequiredArgsConstructor
public class CarryCapacityDevController extends BaseController {
private final CarryCapacityDevicePOService carryCapacityDevicePOService;
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/add")
@ApiOperation("承载能力评估用户设备新增")
@ApiImplicitParam(name = "capacityDeviceParam", value = "新增参数", required = true)
public HttpResult<Boolean> add(@RequestBody @Validated CarryCapacityDeviceParam capacityDeviceParam) {
String methodDescribe = getMethodDescribe("add");
Boolean flag = carryCapacityDevicePOService.add(capacityDeviceParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/remove")
@ApiOperation("承载能力评估用户设备批量删除")
@ApiImplicitParam(name = "devIds", value = "用户id集合", required = true)
public HttpResult<Boolean> remove(@RequestParam("devIds") List<String> devIds) {
String methodDescribe = getMethodDescribe("remove");
Boolean flag = carryCapacityDevicePOService.removeByIds(devIds);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/update")
@ApiOperation("承载能力评估用户设备编辑")
@ApiImplicitParam(name = "deviceParam", value = "编辑参数", required = true)
public HttpResult<Boolean> update(@RequestBody @Validated CarryCapacityDeviceParam.CarryCapacityDeviceUpdateParam deviceParam) {
String methodDescribe = getMethodDescribe("update");
Boolean flag = carryCapacityDevicePOService.updateDevice(deviceParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queyDeviceList")
@ApiOperation("承载能力评估用户设备查询")
@ApiImplicitParam(name = "deviceParam", value = "编辑参数", required = true)
public HttpResult<List<CarryCapacityDevicePO>> queyDeviceList(@RequestBody @Validated CarryCapacityDeviceParam.CarryCapacityDeviceQueryParam deviceParam) {
String methodDescribe = getMethodDescribe("queyDeviceList");
List<CarryCapacityDevicePO> list = carryCapacityDevicePOService.lambdaQuery()
.eq(StringUtils.isNotBlank(deviceParam.getDevId()), CarryCapacityDevicePO::getDevId, deviceParam.getDevId())
.eq(StringUtils.isNotBlank(deviceParam.getUserId()), CarryCapacityDevicePO::getUserId, deviceParam.getUserId()).list();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, list, methodDescribe);
}
}

View File

@@ -0,0 +1,69 @@
package com.njcn.product.carrycapacity.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityQueryDataParam;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityResultPO;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityResultParam;
import com.njcn.product.carrycapacity.pojo.vo.CarryCapacityDResultVO;
import com.njcn.product.carrycapacity.service.CarryCapacityResultPOService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年07月21日 10:06
*/
@RestController
@RequestMapping("result")
@Api(tags = "承载能力评估结果")
@RequiredArgsConstructor
public class CarryCapacityResultController extends BaseController {
private final CarryCapacityResultPOService carryCapacityResultPOService;
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queryResultList")
@ApiOperation("承载能力评估列表查询")
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
public HttpResult<IPage<CarryCapacityDResultVO>> queryResultList(@RequestBody @Validated CarryCapacityResultParam.CarryCapacityResultPageParam queryParam) {
String methodDescribe = getMethodDescribe("queryResultList");
IPage<CarryCapacityDResultVO> vo = carryCapacityResultPOService.queryResultList(queryParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, vo, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queryResultbyCondition")
@ApiOperation("承载能力评估列表查询")
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
public HttpResult<CarryCapacityDResultVO> queryResultbyCondition(@RequestBody @Validated CarryCapacityQueryDataParam queryParam) {
String methodDescribe = getMethodDescribe("queryResultbyCondition");
CarryCapacityDResultVO vo = carryCapacityResultPOService.queryResultbyCondition(queryParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, vo, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/remove")
@ApiOperation("承载能力评估用户批量删除")
public HttpResult<Boolean> remove(@RequestParam("ids") List<String> ids) {
String methodDescribe = getMethodDescribe("remove");
Boolean flag = carryCapacityResultPOService.lambdaUpdate().in(CarryCapacityResultPO::getId, ids).set(CarryCapacityResultPO::getStatus, 0).update();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
}

View File

@@ -0,0 +1,100 @@
package com.njcn.product.carrycapacity.controller;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityStrategyParam;
import com.njcn.product.carrycapacity.pojo.vo.CarryCapacityStrategyDhlVO;
import com.njcn.product.carrycapacity.pojo.vo.CarryCapacityStrategyVO;
import com.njcn.product.carrycapacity.service.CarryCapacityStrategyDhlPOService;
import com.njcn.product.carrycapacity.service.CarryCapacityStrategyPOService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* Description:
* Date: 2024/3/5 10:35【需求编号】
*
* @author clam
* @version V1.0.0
*/
@RestController
@RequestMapping("carrycapacity")
@Api(tags = "承载能力评估策略配置")
@RequiredArgsConstructor
public class CarryCapacityStrategyController extends BaseController {
private final CarryCapacityStrategyPOService carryCapacityStrategyPOService;
private final CarryCapacityStrategyDhlPOService carryCapacityStrategyDhlPOService;
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/add")
@ApiOperation("用户新增承载能力评估策略(光伏)")
@ApiImplicitParam(name = "carryCapacityStrategyParam", value = "新增参数", required = true)
public HttpResult<Boolean> add(@RequestBody @Validated CarryCapacityStrategyParam carryCapacityStrategyParam) {
String methodDescribe = getMethodDescribe("add");
Boolean flag = carryCapacityStrategyPOService.add(carryCapacityStrategyParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/addList")
@ApiOperation("用户新增承载能力评估策略组(光伏)")
@ApiImplicitParam(name = "carryCapacityStrategyParamList", value = "新增参数", required = true)
public HttpResult<Boolean> addList(@RequestBody @Validated List<CarryCapacityStrategyParam> carryCapacityStrategyParamList) {
String methodDescribe = getMethodDescribe("addList");
Boolean flag = carryCapacityStrategyPOService.addList(carryCapacityStrategyParamList);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queyDetail")
@ApiOperation("承载能力评估策略初始化查询(光伏)")
public HttpResult<List<CarryCapacityStrategyVO>> queyDetail() {
String methodDescribe = getMethodDescribe("queyDetail");
List<CarryCapacityStrategyVO> carryCapacityStrategyVOList = carryCapacityStrategyPOService.queyDetail();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, carryCapacityStrategyVOList, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/restore")
@ApiOperation("承载能力评估策略一键还原")
public HttpResult<Boolean> restore() {
String methodDescribe = getMethodDescribe("restore");
Boolean flag = carryCapacityStrategyPOService.restore();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/adddhl")
@ApiOperation("用户新增承载能力评估策略(电弧炉)")
@ApiImplicitParam(name = "capacityStrategyDhlVO", value = "新增参数", required = true)
public HttpResult<Boolean> adddhl(@RequestBody @Validated CarryCapacityStrategyDhlVO capacityStrategyDhlVO) {
String methodDescribe = getMethodDescribe("adddhl");
Boolean flag = carryCapacityStrategyDhlPOService.adddhl(capacityStrategyDhlVO);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queyDetailDhl")
@ApiOperation("承载能力评估策略初始化查询(电弧炉)")
public HttpResult<List<CarryCapacityStrategyDhlVO>> queyDetailDhl() {
String methodDescribe = getMethodDescribe("queyDetailDhl");
List<CarryCapacityStrategyDhlVO> car = carryCapacityStrategyDhlPOService.queyDetailDhl();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, car, methodDescribe);
}
}

View File

@@ -0,0 +1,90 @@
package com.njcn.product.carrycapacity.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.product.carrycapacity.pojo.param.CarryCapacityUserParam;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityUserPO;
import com.njcn.product.carrycapacity.service.CarryCapacityUserPOService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author hongawen
* @version 1.0.0
* @date 2023年07月21日 10:06
*/
@RestController
@RequestMapping("carrycapacityuser")
@Api(tags = "承载能力评估用户")
@RequiredArgsConstructor
public class CarryCapacityUserController extends BaseController {
private final CarryCapacityUserPOService carryCapacityUserPOService;
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/add")
@ApiOperation("承载能力评估用户新增")
@ApiImplicitParam(name = "carryCapacityUserParam", value = "新增参数", required = true)
public HttpResult<Boolean> add(@RequestBody @Validated CarryCapacityUserParam carryCapacityUserParam) {
String methodDescribe = getMethodDescribe("add");
Boolean flag = carryCapacityUserPOService.add(carryCapacityUserParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/remove")
@ApiOperation("承载能力评估用户批量删除")
@ApiImplicitParam(name = "userIds", value = "用户id集合", required = true)
public HttpResult<Boolean> remove(@RequestParam("userIds") List<String> userIds) {
String methodDescribe = getMethodDescribe("remove");
Boolean flag = carryCapacityUserPOService.lambdaUpdate().in(CarryCapacityUserPO::getUserId,userIds).set(CarryCapacityUserPO::getStatus,0).update();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/update")
@ApiOperation("承载能力评估用户编辑")
@ApiImplicitParam(name = "userUpdateParam", value = "编辑参数", required = true)
public HttpResult<Boolean> update(@RequestBody @Validated CarryCapacityUserParam.CarryCapacityUserUpdateParam userUpdateParam) {
String methodDescribe = getMethodDescribe("update");
Boolean flag = carryCapacityUserPOService.updateUser(userUpdateParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, flag, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queyDetailUser")
@ApiOperation("承载能力评估用户查询")
@ApiImplicitParam(name = "pageParam", value = "编辑参数", required = true)
public HttpResult<IPage<CarryCapacityUserPO>> queyDetailUser(@RequestBody @Validated CarryCapacityUserParam.CarryCapacityUserPageParam pageParam) {
String methodDescribe = getMethodDescribe("queyDetailUser");
IPage<CarryCapacityUserPO> page = carryCapacityUserPOService.queyDetailUser(pageParam);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, page, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/queyDetailUserById")
@ApiOperation("承载能力评估用户查询")
public HttpResult<CarryCapacityUserPO> queyDetailUserById(@RequestParam("userId") String userId) {
String methodDescribe = getMethodDescribe("queyDetailUserById");
CarryCapacityUserPO po = carryCapacityUserPOService.queyDetailUserById(userId);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, po, methodDescribe);
}
}

View File

@@ -0,0 +1,103 @@
package com.njcn.product.carrycapacity.enums;
import lombok.Getter;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年04月13日 10:50
*/
@Getter
public enum CarryCapacityResponseEnum {
ANALYSIS_USER_DATA_ERROR("A0101","解析用采数据内容失败"),
INTERNAL_ERROR("A0101","系统内部异常"),
USER_DATA_EMPTY("A0101","用采数据内容为空"),
USER_DATA_NOT_FOUND("A0101","未找到用采数据"),
RESP_DATA_NOT_FOUND("A0101","未找到责任划分数据"),
WIN_TIME_ERROR("A0101","限值时间小于窗口"),
CALCULATE_INTERVAL_ERROR("A0101","对齐计算间隔值非法"),
RESP_RESULT_DATA_NOT_FOUND("A0101","未找到责任划分缓存数据"),
USER_DATA_P_NODE_PARAMETER_ERROR("A0101","无用采用户或所有用户的完整性均不满足条件"),
RESPONSIBILITY_PARAMETER_ERROR("A0101","调用接口程序计算失败,参数非法"),
EVENT_EMPTY("A0102","没有查询到未分析事件"),
USER_NAME_EXIST("A0103","用户名已存在"),
DATA_NOT_FOUND("A0104","选择时间内暂无数据,请上传离线数据"),
DATA_UNDERRUN("A0104","数据量不足,请根据模版上传充足近两周数据"),
DOCUMENT_FORMAT_ERROR("A0105","数据缺失,导入失败!请检查导入文档的格式是否正确"),
DEVICE_LOST("A0104","用户下缺少设备"),
USER_LOST("A0106","干扰源用户缺失"),
UNCOMPLETE_STRATEGY("A0106","配置安全III级预警,II级预警,I级预警4条完整策略"),
EXISTENCE_EVALUATION_RESULT("A0104","存在评结果结果,如要评估,请删除后评估"),
SG_USER_NAME_REPEAT("A0102","业务用户名重复"),
SG_PRODUCT_LINE_NAME_REPEAT("A0102","生产线名重复"),
SG_USER_ID_MISS("A0102","业务用户id缺失"),
SG_PRODUCT_LINE_ID_MISS("A0102","生产线id缺失"),
SG_MACHINE_ID_MISS("A0102","设备id缺失"),
IMPORT_EVENT_DATA_FAIL("A0102","请检查导入数据的准确性"),
PRODUCT_LINE_DATA_MISS("A0102","生产线数据缺失"),
MACHINE_DATA_MISS("A0102","设备数据缺失"),
INCOMING_LINE_DATA_MISS("A0102","进线数据缺失"),
EVENT_DATA_MISS("A0102","没有可供参考的暂降数据"),
WIN_DATA_ERROR("A0102","算法校验窗宽超限"),
DATA_ERROR("A0102","算法校验数据长度超限"),
INIT_DATA_ERROR("A0102","算法初始化数据失败"),
USER_HAS_PRODUCT("A0102","当前用户存在生产线"),
PRODUCT_HAS_MACHINE("A0102","当前生产线存在设备"),
MACHINE_HAS_UNIT("A0102","当前设备存在元器件"),
EVENT_TIME_ERROR("A0102","暂降事件时间格式有误,请检查"),
INVALID_FILE_TYPE("A0102","请选择CSV文件"),
;
private final String code;
private final String message;
CarryCapacityResponseEnum(String code, String message) {
this.code = code;
this.message = message;
}
public static String getCodeByMsg(String msg){
for (CarryCapacityResponseEnum userCodeEnum : CarryCapacityResponseEnum.values()) {
if (userCodeEnum.message.equalsIgnoreCase(msg)) {
return userCodeEnum.code;
}
}
return "";
}
}

View File

@@ -0,0 +1,164 @@
package com.njcn.product.carrycapacity.enums;
import lombok.Getter;
/**
* @Description: 承载能力评估相关枚举
* @Author: clam
* @Date: 2024/1/31
*/
@Getter
public enum CarryingCapacityEnum {
K("K","0.8","海南日照修正系数"),
/**
* h 3 ,5 ,7 ,9 ,11 ,13或者偶次
* k_h 1.62, ,1.28 ,0.72 ,0.18 ,0.08 ,0
*/
K_H_2("K_H_2","0.00","2次谐波电流K_2系数"),
K_H_3("K_H_3","1.62","3次谐波电流K_3系数"),
K_H_4("K_H_4","0.00","4次谐波电流K_4系数"),
K_H_5("K_H_5","1.28","5次谐波电流K_5系数"),
K_H_6("K_H_6","0.00","6次谐波电流K_6系数"),
K_H_7("K_H_7","0.72","7次谐波电流K_7系数"),
K_H_8("K_H_8","0.00","8次谐波电流K_8系数"),
K_H_9("K_H_9","0.18","9次谐波电流K_9系数"),
K_H_10("K_H_10","0.00","10次谐波电流K_10系数"),
K_H_11("K_H_11","0.08","11次谐波电流K_11系数"),
K_H_12("K_H_12","0.00","12次谐波电流K_12系数"),
K_H_13("K_H_13","0.00","13次谐波电流K_13系数"),
K_H_14("K_H_14","0.00","14次谐波电流K_14系数"),
K_H_15("K_H_15","0.00","15次谐波电流K_15系数"),
K_H_16("K_H_16","0.00","16次谐波电流K_16系数"),
K_H_17("K_H_17","0.00","17次谐波电流K_17系数"),
K_H_18("K_H_18","0.00","18次谐波电流K_18系数"),
K_H_19("K_H_19","0.00","19次谐波电流K_19系数"),
K_H_20("K_H_20","0.00","20次谐波电流K_20系数"),
K_H_21("K_H_21","0.00","21次谐波电流K_21系数"),
K_H_22("K_H_22","0.00","22次谐波电流K_22系数"),
K_H_23("K_H_23","0.00","23次谐波电流K_23系数"),
K_H_24("K_H_24","0.00","24次谐波电流K_24系数"),
K_H_25("K_H_25","0.00","25次谐波电流K_25系数"),
//光伏逆变器第h次的典型谐波电流含有率:I_INV_H
I_INV_2("I_INV_2","0.254","2次典型谐波电流含有率"),
I_INV_3("I_INV_3","0.121","3次典型谐波电流含有率"),
I_INV_4("I_INV_4","0.087","4次典型谐波电流含有率"),
I_INV_5("I_INV_5","2.446","5次典型谐波电流含有率"),
I_INV_6("I_INV_6","0.024","6次典型谐波电流含有率"),
I_INV_7("I_INV_7","1.629","7次典型谐波电流含有率"),
I_INV_8("I_INV_8","0.042","8次典型谐波电流含有率"),
I_INV_9("I_INV_9","0.039","9次典型谐波电流含有率"),
I_INV_10("I_INV_10","0.037","10次典型谐波电流含有率"),
I_INV_11("I_INV_11","0.439","11次典型谐波电流含有率"),
I_INV_12("I_INV_12","0.021","12次典型谐波电流含有率"),
I_INV_13("I_INV_13","0.379","13次典型谐波电流含有率"),
I_INV_14("I_INV_14","0.042","14次典型谐波电流含有率"),
I_INV_15("I_INV_15","0.037","15次典型谐波电流含有率"),
I_INV_16("I_INV_16","0.043","16次典型谐波电流含有率"),
I_INV_17("I_INV_17","0.263","17次典型谐波电流含有率"),
I_INV_18("I_INV_18","0.017","18次典型谐波电流含有率"),
I_INV_19("I_INV_19","0.197","19次典型谐波电流含有率"),
I_INV_20("I_INV_20","0.062","20次典型谐波电流含有率"),
I_INV_21("I_INV_21","0.024","21次典型谐波电流含有率"),
I_INV_22("I_INV_22","0.032","22次典型谐波电流含有率"),
I_INV_23("I_INV_23","0.304","23次典型谐波电流含有率"),
I_INV_24("I_INV_24","0.03","24次典型谐波电流含有率"),
I_INV_25("I_INV_25","0.176","25次典型谐波电流含有率"),
I_INV_26("I_INV_26","0.032","26次典型谐波电流含有率"),
I_INV_27("I_INV_27","0.038","27次典型谐波电流含有率"),
I_INV_28("I_INV_28","0.031","28次典型谐波电流含有率"),
I_INV_29("I_INV_29","0.158","29次典型谐波电流含有率"),
I_INV_30("I_INV_30","0.024","30次典型谐波电流含有率"),
I_INV_31("I_INV_31","0.028","31次典型谐波电流含有率"),
I_INV_32("I_INV_32","0.026","32次典型谐波电流含有率"),
I_INV_33("I_INV_33","0.033","33次典型谐波电流含有率"),
I_INV_34("I_INV_34","0.018","34次典型谐波电流含有率"),
I_INV_35("I_INV_35","0.072","35次典型谐波电流含有率"),
//电弧炉谐波电流含有率
// EAF_I_2("EAF_I_2","0.6112","2次电弧炉谐波电流含有率"),
EAF_I_3("EAF_I_3","0.13484","3次电弧炉谐波电流含有率"),
// EAF_I_4("EAF_I_4","0.9906","4次电弧炉谐波电流含有率"),
EAF_I_5("EAF_I_5","0.017327","5次电弧炉谐波电流含有率"),
// EAF_I_6("EAF_I_6","0.5750","6次电弧炉谐波电流含有率"),
EAF_I_7("EAF_I_7","0.015288","7次电弧炉谐波电流含有率"),
// EAF_I_8("EAF_I_8","0.4782","8次电弧炉谐波电流含有率"),
EAF_I_9("EAF_I_9","0.001495","9次电弧炉谐波电流含有率"),
// EAF_I_10("EAF_I_10","0.6003","10次电弧炉谐波电流含有率"),
EAF_I_11("EAF_I_11","0.001203","11次电弧炉谐波电流含有率"),
// EAF_I_12("EAF_I_12","0.5242","12次电弧炉谐波电流含有率"),
EAF_I_13("EAF_I_13","0.001407","13次电弧炉谐波电流含有率"),
// EAF_I_14("EAF_I_14","0.5720","14次电弧炉谐波电流含有率"),
EAF_I_15("EAF_I_15","0.001676","15次电弧炉谐波电流含有率"),
// EAF_I_16("EAF_I_16","0.8234","16次电弧炉谐波电流含有率"),
EAF_I_17("EAF_I_17","0.001555","17次电弧炉谐波电流含有率"),
// EAF_I_18("EAF_I_18","0.8848","18次电弧炉谐波电流含有率"),
EAF_I_19("EAF_I_19","0.001159","19次电弧炉谐波电流含有率"),
// EAF_I_20("EAF_I_20","0.6789","20次电弧炉谐波电流含有率"),
//充电桩谐波电流含有率
// CP_I_2("CP_I_2","5.00","2次电弧炉谐波电流含有率"),
CP_I_3("CP_I_3","0.2011","3次电弧炉谐波电流含有率"),
// CP_I_4("CP_I_4","4.00","4次电弧炉谐波电流含有率"),
CP_I_5("CP_I_5","0.1069","5次电弧炉谐波电流含有率"),
// CP_I_6("CP_I_6","4.00","6次电弧炉谐波电流含有率"),
CP_I_7("CP_I_7","0.0647","7次电弧炉谐波电流含有率"),
// CP_I_8("CP_I_8","2.00","8次电弧炉谐波电流含有率"),
CP_I_9("CP_I_9","0.0376","9次电弧炉谐波电流含有率"),
// CP_I_10("CP_I_10","1.50","10次电弧炉谐波电流含有率"),
CP_I_11("CP_I_11","0.0232","11次电弧炉谐波电流含有率"),
// CP_I_12("CP_I_12","0.50","12次电弧炉谐波电流含有率"),
CP_I_13("CP_I_13","0.0155","13次电弧炉谐波电流含有率"),
// CP_I_14("CP_I_14","0.00","14次电弧炉谐波电流含有率"),
CP_I_15("CP_I_15","0.005956","15次电弧炉谐波电流含有率"),
// CP_I_16("CP_I_16","0.00","16次电弧炉谐波电流含有率"),
CP_I_17("CP_I_17","0.054185","17次电弧炉谐波电流含有率"),
// CP_I_18("CP_I_18","0.00","18次电弧炉谐波电流含有率"),
CP_I_19("CP_I_19","0.023503","19次电弧炉谐波电流含有率"),
// CP_I_20("CP_I_20","0.00","20次电弧炉谐波电流含有率"),
//电气化铁路典型
ER_I_3("ER_I_3","0.0068935","3次电弧炉谐波电流含有率"),
ER_I_5("ER_I_5","0.069575","5次电弧炉谐波电流含有率"),
ER_I_7("ER_I_7","0.032731","7次电弧炉谐波电流含有率"),
ER_I_9("ER_I_9","0.005197","9次电弧炉谐波电流含有率"),
ER_I_11("ER_I_11","0.045631","11次电弧炉谐波电流含有率"),
ER_I_13("ER_I_13","0.029196","13次电弧炉谐波电流含有率"),
ER_I_15("ER_I_15","0.017","15次电弧炉谐波电流含有率"),
ER_I_17("ER_I_17","0.0095","17次电弧炉谐波电流含有率"),
ER_I_19("ER_I_19","0.0080","19次电弧炉谐波电流含有率"),
;
/**
* 字段code
*/
private final String Code;
/**
* 字段值
*/
private final String value;
/**
* 字段描述
*/
private final String description;
CarryingCapacityEnum(String code, String value, String description) {
Code = code;
this.value = value;
this.description = description;
}
public static String getValueByCode(String code) {
for (CarryingCapacityEnum item : CarryingCapacityEnum.values()) {
if (item.Code.equals(code)) {
return item.value;
}
}
return null;
}
}

View File

@@ -0,0 +1,15 @@
package com.njcn.product.carrycapacity.mapper;
import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityDataPO;
/**
*
* Description:
* Date: 2024/3/6 14:45【需求编号】
*
* @author clam
* @version V1.0.0
*/
public interface CarryCapacityDataPOMapper extends MppBaseMapper<CarryCapacityDataPO> {
}

View File

@@ -0,0 +1,15 @@
package com.njcn.product.carrycapacity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityDevicePO;
/**
*
* Description:
* Date: 2024/3/19 16:36【需求编号】
*
* @author clam
* @version V1.0.0
*/
public interface CarryCapacityDevicePOMapper extends BaseMapper<CarryCapacityDevicePO> {
}

View File

@@ -0,0 +1,14 @@
package com.njcn.product.carrycapacity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityResultPO;
/**
* Description:
* Date: 2024/3/8 16:23【需求编号】
*
* @author clam
* @version V1.0.0
*/
public interface CarryCapacityResultPOMapper extends BaseMapper<CarryCapacityResultPO> {
}

View File

@@ -0,0 +1,15 @@
package com.njcn.product.carrycapacity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityStrategyDhlPO;
/**
*
* Description:
* Date: 2024/3/15 10:45【需求编号】
*
* @author clam
* @version V1.0.0
*/
public interface CarryCapacityStrategyDhlPOMapper extends BaseMapper<CarryCapacityStrategyDhlPO> {
}

View File

@@ -0,0 +1,14 @@
package com.njcn.product.carrycapacity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityStrategyPO;
/**
* Description:
* Date: 2024/3/5 10:54【需求编号】
*
* @author clam
* @version V1.0.0
*/
public interface CarryCapacityStrategyPOMapper extends BaseMapper<CarryCapacityStrategyPO> {
}

View File

@@ -0,0 +1,15 @@
package com.njcn.product.carrycapacity.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityUserPO;
/**
*
* Description:
* Date: 2024/2/20 11:15【需求编号】
*
* @author clam
* @version V1.0.0
*/
public interface CarryCapacityUserPOMapper extends BaseMapper<CarryCapacityUserPO> {
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.product.carrycapacity.mapper.CarryCapacityDataPOMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.product.carrycapacity.mapper.CarryCapacityDevicePOMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.product.carrycapacity.mapper.CarryCapacityResultPOMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.product.carrycapacity.mapper.CarryCapacityStrategyDhlPOMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.product.carrycapacity.mapper.CarryCapacityStrategyPOMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.product.carrycapacity.mapper.CarryCapacityUserPOMapper">
</mapper>

View File

@@ -0,0 +1,292 @@
package com.njcn.product.carrycapacity.pojo.excel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.converters.localdatetime.LocalDateTimeStringConverter;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2022/5/12 9:13
*/
@Data
public class CarryCapcityDataEexcel {
@ExcelProperty(index = 0,value = "时间(格式为yyyy-MM-dd hh:mm:ss)",converter = LocalDateTimeStringConverter.class)
@JSONField(format = "yyyy-MM-dd hh:mm:ss")
private LocalDateTime time;
@ExcelProperty(index =1,value = {"电压","A"})
private Double u_a;
@ExcelProperty(index =2,value = {"电压","B"})
private Double u_b;
@ExcelProperty(index =3,value = {"电压","C"})
private Double u_c;
@ExcelProperty(index =4,value = {"有功功率","A"})
private Double p_a;
@ExcelProperty(index =5,value = {"有功功率","B"})
private Double p_b;
@ExcelProperty(index =6,value = {"有功功率","C"})
private Double p_c;
@ExcelProperty(index =7,value = {"无功功率","A"})
private Double q_a;
@ExcelProperty(index =8,value = {"无功功率","B"})
private Double q_b;
@ExcelProperty(index =9,value = {"无功功率","C"})
private Double q_c;
@ExcelProperty(index =10,value = {"电流","2次","A"})
private Double i2_a;
@ExcelProperty(index =11,value = {"电流","2次","B"})
private Double i2_b;
@ExcelProperty(index =12,value = {"电流","2次","C"})
private Double i2_c;
@ExcelProperty(index =13,value = {"电流","3次","A"})
private Double i3_a;
@ExcelProperty(index =14,value = {"电流","3次","B"})
private Double i3_b;
@ExcelProperty(index =15,value = {"电流","3次","C"})
private Double i3_c;
@ExcelProperty(index =16,value = {"电流","4次","A"})
private Double i4_a;
@ExcelProperty(index =17,value = {"电流","4次","B"})
private Double i4_b;
@ExcelProperty(index =18,value = {"电流","4次","C"})
private Double i4_c;
@ExcelProperty(index =19,value = {"电流","5次","A"})
private Double i5_a;
@ExcelProperty(index =20,value = {"电流","5次","B"})
private Double i5_b;
@ExcelProperty(index =21,value = {"电流","5次","C"})
private Double i5_c;
@ExcelProperty(index =22,value = {"电流","6次","A"})
private Double i6_a;
@ExcelProperty(index =23,value = {"电流","6次","B"})
private Double i6_b;
@ExcelProperty(index =24,value = {"电流","6次","C"})
private Double i6_c;
@ExcelProperty(index =25,value = {"电流","7次","A"})
private Double i7_a;
@ExcelProperty(index =26,value = {"电流","7次","B"})
private Double i7_b;
@ExcelProperty(index =27,value = {"电流","7次","C"})
private Double i7_c;
@ExcelProperty(index =28,value = {"电流","8次","A"})
private Double i8_a;
@ExcelProperty(index =29,value = {"电流","8次","B"})
private Double i8_b;
@ExcelProperty(index =30,value = {"电流","8次","C"})
private Double i8_c;
@ExcelProperty(index =31,value = {"电流","9次","A"})
private Double i9_a;
@ExcelProperty(index =32,value = {"电流","9次","B"})
private Double i9_b;
@ExcelProperty(index =33,value = {"电流","9次","C"})
private Double i9_c;
@ExcelProperty(index =34,value = {"电流","10次","A"})
private Double i10_a;
@ExcelProperty(index =35,value = {"电流","10次","B"})
private Double i10_b;
@ExcelProperty(index =36,value = {"电流","10次","C"})
private Double i10_c;
@ExcelProperty(index =37,value = {"电流","11次","A"})
private Double i11_a;
@ExcelProperty(index =38,value = {"电流","11次","B"})
private Double i11_b;
@ExcelProperty(index =39,value = {"电流","11次","C"})
private Double i11_c;
@ExcelProperty(index =40,value = {"电流","12次","A"})
private Double i12_a;
@ExcelProperty(index =41,value = {"电流","12次","B"})
private Double i12_b;
@ExcelProperty(index =42,value = {"电流","12次","C"})
private Double i12_c;
@ExcelProperty(index =43,value = {"电流","13次","A"})
private Double i13_a;
@ExcelProperty(index =44,value = {"电流","13次","B"})
private Double i13_b;
@ExcelProperty(index =45,value = {"电流","13次","C"})
private Double i13_c;
@ExcelProperty(index =46,value = {"电流","14次","A"})
private Double i14_a;
@ExcelProperty(index =47,value = {"电流","14次","B"})
private Double i14_b;
@ExcelProperty(index =48,value = {"电流","14次","C"})
private Double i14_c;
@ExcelProperty(index =49,value = {"电流","15次","A"})
private Double i15_a;
@ExcelProperty(index =50,value = {"电流","15次","B"})
private Double i15_b;
@ExcelProperty(index =51,value = {"电流","15次","C"})
private Double i15_c;
@ExcelProperty(index =52,value = {"电流","16次","A"})
private Double i16_a;
@ExcelProperty(index =53,value = {"电流","16次","B"})
private Double i16_b;
@ExcelProperty(index =54,value = {"电流","16次","C"})
private Double i16_c;
@ExcelProperty(index =55,value = {"电流","17次","A"})
private Double i17_a;
@ExcelProperty(index =56,value = {"电流","17次","B"})
private Double i17_b;
@ExcelProperty(index =57,value = {"电流","17次","C"})
private Double i17_c;
@ExcelProperty(index =58,value = {"电流","18次","A"})
private Double i18_a;
@ExcelProperty(index =59,value = {"电流","18次","B"})
private Double i18_b;
@ExcelProperty(index =60,value = {"电流","18次","C"})
private Double i18_c;
@ExcelProperty(index =61,value = {"电流","19次","A"})
private Double i19_a;
@ExcelProperty(index =62,value = {"电流","19次","B"})
private Double i19_b;
@ExcelProperty(index =63,value = {"电流","19次","C"})
private Double i19_c;
@ExcelProperty(index =64,value = {"电流","20次","A"})
private Double i20_a;
@ExcelProperty(index =65,value = {"电流","20次","B"})
private Double i20_b;
@ExcelProperty(index =66,value = {"电流","20次","C"})
private Double i20_c;
@ExcelProperty(index =67,value = {"电流","21次","A"})
private Double i21_a;
@ExcelProperty(index =68,value = {"电流","21次","B"})
private Double i21_b;
@ExcelProperty(index =69,value = {"电流","21次","C"})
private Double i21_c;
@ExcelProperty(index =70,value = {"电流","22次","A"})
private Double i22_a;
@ExcelProperty(index =71,value = {"电流","22次","B"})
private Double i22_b;
@ExcelProperty(index =72,value = {"电流","22次","C"})
private Double i22_c;
@ExcelProperty(index =73,value = {"电流","23次","A"})
private Double i23_a;
@ExcelProperty(index =74,value = {"电流","23次","B"})
private Double i23_b;
@ExcelProperty(index =75,value = {"电流","23次","C"})
private Double i23_c;
@ExcelProperty(index =76,value = {"电流","24次","A"})
private Double i24_a;
@ExcelProperty(index =77,value = {"电流","24次","B"})
private Double i24_b;
@ExcelProperty(index =78,value = {"电流","24次","C"})
private Double i24_c;
@ExcelProperty(index =79,value = {"电流","25次","A"})
private Double i25_a;
@ExcelProperty(index =80,value = {"电流","25次","B"})
private Double i25_b;
@ExcelProperty(index =81,value = {"电流","25次","C"})
private Double i25_c;
public static void main(String[] args) {
// List<CarryCapcityDataEexcel> objects = EasyExcelUtil.syncReadModel("C:\\Users\\无名\\Desktop\\11.xlsx", CarryCapcityDataEexcel.class, 0,3);
// System.out.println(objects);
String sheetName = "sheetName";
List<CarryCapcityDataEexcel> excels = new ArrayList<>();
CarryCapcityDataEexcel exportHeadersExcel = new CarryCapcityDataEexcel();
excels.add(exportHeadersExcel);
EasyExcel.write("C:\\\\Users\\\\无名\\\\Desktop\\\\22.xlsx", CarryCapcityDataEexcel.class)
.sheet(sheetName)
.doWrite(excels);
EasyExcel.write("C:\\\\Users\\\\无名\\\\Desktop\\\\22.xlsx", CarryCapcityDataEexcel.class)
.sheet("sheetName2")
.doWrite(excels);
}
}

View File

@@ -0,0 +1,424 @@
package com.njcn.product.carrycapacity.pojo.excel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.njcn.influx.pojo.po.DataI;
import lombok.Data;
import org.influxdb.annotation.Column;
import org.springframework.beans.BeanUtils;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2022/5/12 9:13
*/
@Data
public class CarryCapcityDataIEexcel {
@Excel(name = "时间",width = 30)
private Instant time;
@Column(name = "line_id")
@Excel(name = "监测点id",width = 30)
private String lineId;
@Excel(name = "数据类型(CP95)",width = 30)
private String valueType;
@Column(name = "i_2")
@Excel(name = "A项2次谐波幅值",width = 15)
private Double i2_a;
@Column(name = "i_3")
@Excel(name = "A项3次谐波幅值",width = 15)
private Double i3_a;
@Column(name = "i_4")
@Excel(name = "A项4次谐波幅值",width = 15)
private Double i4_a;
@Column(name = "i_5")
@Excel(name = "A项5次谐波幅值",width = 15)
private Double i5_a;
@Column(name = "i_6")
@Excel(name = "A项6次谐波幅值",width = 15)
private Double i6_a;
@Column(name = "i_7")
@Excel(name = "A项7次谐波幅值",width = 15)
private Double i7_a;
@Column(name = "i_8")
@Excel(name = "A项8次谐波幅值",width = 15)
private Double i8_a;
@Column(name = "i_9")
@Excel(name = "A项9次谐波幅值",width = 15)
private Double i9_a;
@Column(name = "i_10")
@Excel(name = "A项10次谐波幅值",width = 15)
private Double i10_a;
@Column(name = "i_11")
@Excel(name = "A项11次谐波幅值",width = 15)
private Double i11_a;
@Column(name = "i_12")
@Excel(name = "A项12次谐波幅值",width = 15)
private Double i12_a;
@Column(name = "i_13")
@Excel(name = "A项13次谐波幅值",width = 15)
private Double i13_a;
@Column(name = "i_14")
@Excel(name = "A项14次谐波幅值",width = 15)
private Double i14_a;
@Column(name = "i_15")
@Excel(name = "A项15次谐波幅值",width = 15)
private Double i15_a;
@Column(name = "i_16")
@Excel(name = "A项16次谐波幅值",width = 15)
private Double i16_a;
@Column(name = "i_17")
@Excel(name = "A项17次谐波幅值",width = 15)
private Double i17_a;
@Column(name = "i_18")
@Excel(name = "A项18次谐波幅值",width = 15)
private Double i18_a;
@Column(name = "i_19")
@Excel(name = "A项19次谐波幅值",width = 15)
private Double i19_a;
@Column(name = "i_20")
@Excel(name = "A项20次谐波幅值",width = 15)
private Double i20_a;
@Column(name = "i_21")
@Excel(name = "A项21次谐波幅值",width = 15)
private Double i21_a;
@Column(name = "i_22")
@Excel(name = "A项22次谐波幅值",width = 15)
private Double i22_a;
@Column(name = "i_23")
@Excel(name = "A项23次谐波幅值",width = 15)
private Double i23_a;
@Column(name = "i_24")
@Excel(name = "A项24次谐波幅值",width = 15)
private Double i24_a;
@Column(name = "i_25")
@Excel(name = "A项25次谐波幅值",width = 15)
private Double i25_a;
@Column(name = "i_2")
@Excel(name = "B项2次谐波幅值",width = 15)
private Double i2_b;
@Column(name = "i_3")
@Excel(name = "B项3次谐波幅值",width = 15)
private Double i3_b;
@Column(name = "i_4")
@Excel(name = "B项4次谐波幅值",width = 15)
private Double i4_b;
@Column(name = "i_5")
@Excel(name = "B项5次谐波幅值",width = 15)
private Double i5_b;
@Column(name = "i_6")
@Excel(name = "B项6次谐波幅值",width = 15)
private Double i6_b;
@Column(name = "i_7")
@Excel(name = "B项7次谐波幅值",width = 15)
private Double i7_b;
@Column(name = "i_8")
@Excel(name = "B项8次谐波幅值",width = 15)
private Double i8_b;
@Column(name = "i_9")
@Excel(name = "B项9次谐波幅值",width = 15)
private Double i9_b;
@Column(name = "i_10")
@Excel(name = "B项10次谐波幅值",width = 15)
private Double i10_b;
@Column(name = "i_11")
@Excel(name = "B项11次谐波幅值",width = 15)
private Double i11_b;
@Column(name = "i_12")
@Excel(name = "B项12次谐波幅值",width = 15)
private Double i12_b;
@Column(name = "i_13")
@Excel(name = "B项13次谐波幅值",width = 15)
private Double i13_b;
@Column(name = "i_14")
@Excel(name = "B项14次谐波幅值",width = 15)
private Double i14_b;
@Column(name = "i_15")
@Excel(name = "B项15次谐波幅值",width = 15)
private Double i15_b;
@Column(name = "i_16")
@Excel(name = "B项16次谐波幅值",width = 15)
private Double i16_b;
@Column(name = "i_17")
@Excel(name = "B项17次谐波幅值",width = 15)
private Double i17_b;
@Column(name = "i_18")
@Excel(name = "B项18次谐波幅值",width = 15)
private Double i18_b;
@Column(name = "i_19")
@Excel(name = "B项19次谐波幅值",width = 15)
private Double i19_b;
@Column(name = "i_20")
@Excel(name = "B项20次谐波幅值",width = 15)
private Double i20_b;
@Column(name = "i_21")
@Excel(name = "B项21次谐波幅值",width = 15)
private Double i21_b;
@Column(name = "i_22")
@Excel(name = "B项22次谐波幅值",width = 15)
private Double i22_b;
@Column(name = "i_23")
@Excel(name = "B项23次谐波幅值",width = 15)
private Double i23_b;
@Column(name = "i_24")
@Excel(name = "B项24次谐波幅值",width = 15)
private Double i24_b;
@Column(name = "i_25")
@Excel(name = "B项25次谐波幅值",width = 15)
private Double i25_b;
@Column(name = "i_2")
@Excel(name = "C项2次谐波幅值",width = 15)
private Double i2_c;
@Column(name = "i_3")
@Excel(name = "C项3次谐波幅值",width = 15)
private Double i3_c;
@Column(name = "i_4")
@Excel(name = "C项4次谐波幅值",width = 15)
private Double i4_c;
@Column(name = "i_5")
@Excel(name = "C项5次谐波幅值",width = 15)
private Double i5_c;
@Column(name = "i_6")
@Excel(name = "C项6次谐波幅值",width = 15)
private Double i6_c;
@Column(name = "i_7")
@Excel(name = "C项7次谐波幅值",width = 15)
private Double i7_c;
@Column(name = "i_8")
@Excel(name = "C项8次谐波幅值",width = 15)
private Double i8_c;
@Column(name = "i_9")
@Excel(name = "C项9次谐波幅值",width = 15)
private Double i9_c;
@Column(name = "i_10")
@Excel(name = "C项10次谐波幅值",width = 15)
private Double i10_c;
@Column(name = "i_11")
@Excel(name = "C项11次谐波幅值",width = 15)
private Double i11_c;
@Column(name = "i_12")
@Excel(name = "C项12次谐波幅值",width = 15)
private Double i12_c;
@Column(name = "i_13")
@Excel(name = "C项13次谐波幅值",width = 15)
private Double i13_c;
@Column(name = "i_14")
@Excel(name = "C项14次谐波幅值",width = 15)
private Double i14_c;
@Column(name = "i_15")
@Excel(name = "C项15次谐波幅值",width = 15)
private Double i15_c;
@Column(name = "i_16")
@Excel(name = "C项16次谐波幅值",width = 15)
private Double i16_c;
@Column(name = "i_17")
@Excel(name = "C项17次谐波幅值",width = 15)
private Double i17_c;
@Column(name = "i_18")
@Excel(name = "C项18次谐波幅值",width = 15)
private Double i18_c;
@Column(name = "i_19")
@Excel(name = "C项19次谐波幅值",width = 15)
private Double i19_c;
@Column(name = "i_20")
@Excel(name = "C项20次谐波幅值",width = 15)
private Double i20_c;
@Column(name = "i_21")
@Excel(name = "C项21次谐波幅值",width = 15)
private Double i21_c;
@Column(name = "i_22")
@Excel(name = "C项22次谐波幅值",width = 15)
private Double i22_c;
@Column(name = "i_23")
@Excel(name = "C项23次谐波幅值",width = 15)
private Double i23_c;
@Column(name = "i_24")
@Excel(name = "C项24次谐波幅值",width = 15)
private Double i24_c;
@Column(name = "i_25")
@Excel(name = "C项25次谐波幅值",width = 15)
private Double i25_c;
//excel对象转DataI
public static List<DataI> excelToPO(CarryCapcityDataIEexcel carryCapcityDataIEexcel) {
List<DataI> data = new ArrayList<>();
if (carryCapcityDataIEexcel == null) {
return null;
}
List<String> phaseList = Stream.of("A", "B", "C").collect(Collectors.toList());
for (String phase : phaseList) {
DataI dataI = new DataI();
BeanUtils.copyProperties(carryCapcityDataIEexcel,dataI);
dataI.setPhaseType(phase);
dataI.setTime(carryCapcityDataIEexcel.getTime());
if (phase.equals("A")) {
dataI.setI2( carryCapcityDataIEexcel.getI2_a());
dataI.setI3( carryCapcityDataIEexcel.getI3_a());
dataI.setI4( carryCapcityDataIEexcel.getI4_a());
dataI.setI5( carryCapcityDataIEexcel.getI5_a());
dataI.setI6( carryCapcityDataIEexcel.getI6_a());
dataI.setI7( carryCapcityDataIEexcel.getI7_a());
dataI.setI8( carryCapcityDataIEexcel.getI8_a());
dataI.setI9( carryCapcityDataIEexcel.getI9_a());
dataI.setI10( carryCapcityDataIEexcel.getI10_a());
dataI.setI11( carryCapcityDataIEexcel.getI11_a());
dataI.setI12( carryCapcityDataIEexcel.getI12_a());
dataI.setI13( carryCapcityDataIEexcel.getI13_a());
dataI.setI14( carryCapcityDataIEexcel.getI14_a());
dataI.setI15( carryCapcityDataIEexcel.getI15_a());
dataI.setI16( carryCapcityDataIEexcel.getI16_a());
dataI.setI17( carryCapcityDataIEexcel.getI17_a());
dataI.setI18( carryCapcityDataIEexcel.getI18_a());
dataI.setI19( carryCapcityDataIEexcel.getI19_a());
dataI.setI20( carryCapcityDataIEexcel.getI20_a());
dataI.setI21( carryCapcityDataIEexcel.getI21_a());
dataI.setI22( carryCapcityDataIEexcel.getI22_a());
dataI.setI23( carryCapcityDataIEexcel.getI23_a());
dataI.setI24( carryCapcityDataIEexcel.getI24_a());
dataI.setI25( carryCapcityDataIEexcel.getI25_a());
} else if (phase.equals("B")) {
dataI.setI2( carryCapcityDataIEexcel.getI2_b());
dataI.setI3( carryCapcityDataIEexcel.getI3_b());
dataI.setI4( carryCapcityDataIEexcel.getI4_b());
dataI.setI5( carryCapcityDataIEexcel.getI5_b());
dataI.setI6( carryCapcityDataIEexcel.getI6_b());
dataI.setI7( carryCapcityDataIEexcel.getI7_b());
dataI.setI8( carryCapcityDataIEexcel.getI8_b());
dataI.setI9( carryCapcityDataIEexcel.getI9_b());
dataI.setI10( carryCapcityDataIEexcel.getI10_b());
dataI.setI11( carryCapcityDataIEexcel.getI11_b());
dataI.setI12( carryCapcityDataIEexcel.getI12_b());
dataI.setI13( carryCapcityDataIEexcel.getI13_b());
dataI.setI14( carryCapcityDataIEexcel.getI14_b());
dataI.setI15( carryCapcityDataIEexcel.getI15_b());
dataI.setI16( carryCapcityDataIEexcel.getI16_b());
dataI.setI17( carryCapcityDataIEexcel.getI17_b());
dataI.setI18( carryCapcityDataIEexcel.getI18_b());
dataI.setI19( carryCapcityDataIEexcel.getI19_b());
dataI.setI20( carryCapcityDataIEexcel.getI20_b());
dataI.setI21( carryCapcityDataIEexcel.getI21_b());
dataI.setI22( carryCapcityDataIEexcel.getI22_b());
dataI.setI23( carryCapcityDataIEexcel.getI23_b());
dataI.setI24( carryCapcityDataIEexcel.getI24_b());
dataI.setI25( carryCapcityDataIEexcel.getI25_b());
}else if (phase.equals("C")){
dataI.setI2( carryCapcityDataIEexcel.getI2_c());
dataI.setI3( carryCapcityDataIEexcel.getI3_c());
dataI.setI4( carryCapcityDataIEexcel.getI4_c());
dataI.setI5( carryCapcityDataIEexcel.getI5_c());
dataI.setI6( carryCapcityDataIEexcel.getI6_c());
dataI.setI7( carryCapcityDataIEexcel.getI7_c());
dataI.setI8( carryCapcityDataIEexcel.getI8_c());
dataI.setI9( carryCapcityDataIEexcel.getI9_c());
dataI.setI10( carryCapcityDataIEexcel.getI10_c());
dataI.setI11( carryCapcityDataIEexcel.getI11_c());
dataI.setI12( carryCapcityDataIEexcel.getI12_c());
dataI.setI13( carryCapcityDataIEexcel.getI13_c());
dataI.setI14( carryCapcityDataIEexcel.getI14_c());
dataI.setI15( carryCapcityDataIEexcel.getI15_c());
dataI.setI16( carryCapcityDataIEexcel.getI16_c());
dataI.setI17( carryCapcityDataIEexcel.getI17_c());
dataI.setI18( carryCapcityDataIEexcel.getI18_c());
dataI.setI19( carryCapcityDataIEexcel.getI19_c());
dataI.setI20( carryCapcityDataIEexcel.getI20_c());
dataI.setI21( carryCapcityDataIEexcel.getI21_c());
dataI.setI22( carryCapcityDataIEexcel.getI22_c());
dataI.setI23( carryCapcityDataIEexcel.getI23_c());
dataI.setI24( carryCapcityDataIEexcel.getI24_c());
dataI.setI25( carryCapcityDataIEexcel.getI25_c());
}
data.add(dataI);
}
return data;
}
}

View File

@@ -0,0 +1,65 @@
package com.njcn.product.carrycapacity.pojo.excel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.njcn.influx.pojo.bo.CarryCapcityData;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2022/5/12 9:13
*/
@Data
public class CarryCapcityDataPEexcel {
@Excel(name = "时间",width = 30)
private Instant time;
@Excel(name = "监测点id",width = 30)
private String lineId;
@Excel(name = "数据类型(CP95)",width = 30)
private String valueType;
@Excel(name = "数据(A项有功功率)",width = 30)
private Double value_a;
@Excel(name = "数据(B项有功功率)",width = 30)
private Double value_b;
@Excel(name = "数据(C项有功功率)",width = 30)
private Double value_c;
public static List<CarryCapcityData> excelToPO(CarryCapcityDataPEexcel carryCapcityDataPEexcel) {
List<CarryCapcityData> data = new ArrayList<>();
if (carryCapcityDataPEexcel == null) {
return null;
}
List<String> phaseList = Stream.of("A", "B", "C").collect(Collectors.toList());
for (String phase : phaseList) {
CarryCapcityData carryCapcityData = new CarryCapcityData();
BeanUtils.copyProperties(carryCapcityDataPEexcel,carryCapcityData);
carryCapcityData.setPhaseType(phase);
carryCapcityData.setTime(carryCapcityDataPEexcel.getTime());
if (phase.equals("A")) {
carryCapcityData.setValue(carryCapcityDataPEexcel.getValue_a());
} else if (phase.equals("B")) {
carryCapcityData.setValue(carryCapcityDataPEexcel.getValue_b());
}else if (phase.equals("C")){
carryCapcityData.setValue(carryCapcityDataPEexcel.getValue_c());
}
data.add(carryCapcityData);
}
return data;
}
}

View File

@@ -0,0 +1,67 @@
package com.njcn.product.carrycapacity.pojo.excel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.njcn.influx.pojo.bo.CarryCapcityData;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2022/5/12 9:13
*/
@Data
public class CarryCapcityDataQEexcel {
@Excel(name = "时间",width = 30)
private Instant time;
@Excel(name = "监测点id",width = 30)
private String lineId;
@Excel(name = "数据类型(CP95)",width = 30)
private String valueType;
@Excel(name = "数据(A项无功功率)",width = 30)
private Double value_a;
@Excel(name = "数据(B项无功功率)",width = 30)
private Double value_b;
@Excel(name = "数据(C项无功功率)",width = 30)
private Double value_c;
public static List<CarryCapcityData> excelToPO(CarryCapcityDataQEexcel carryCapcityDataQEexcel) {
List<CarryCapcityData> data = new ArrayList<>();
if (carryCapcityDataQEexcel == null) {
return null;
}
List<String> phaseList = Stream.of("A", "B", "C").collect(Collectors.toList());
for (String phase : phaseList) {
CarryCapcityData carryCapcityData = new CarryCapcityData();
BeanUtils.copyProperties(carryCapcityDataQEexcel,carryCapcityData);
carryCapcityData.setPhaseType(phase);
carryCapcityData.setTime(carryCapcityDataQEexcel.getTime());
if (phase.equals("A")) {
carryCapcityData.setValue(carryCapcityDataQEexcel.getValue_a());
} else if (phase.equals("B")) {
carryCapcityData.setValue(carryCapcityDataQEexcel.getValue_b());
}else if (phase.equals("C")){
carryCapcityData.setValue(carryCapcityDataQEexcel.getValue_c());
}
data.add(carryCapcityData);
}
return data;
}
}

View File

@@ -0,0 +1,65 @@
package com.njcn.product.carrycapacity.pojo.excel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.njcn.influx.pojo.bo.CarryCapcityData;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 类的介绍:
*
* @author xuyang
* @version 1.0.0
* @createTime 2022/5/12 9:13
*/
@Data
public class CarryCapcityDataVEexcel {
@Excel(name = "时间",width = 30)
private Instant time;
@Excel(name = "监测点id",width = 30)
private String lineId;
@Excel(name = "数据类型(CP95)",width = 30)
private String valueType;
@Excel(name = "数据(A项电压)",width = 30)
private Double value_a;
@Excel(name = "数据(B项电压)",width = 30)
private Double value_b;
@Excel(name = "数据(C项电压)",width = 30)
private Double value_c;
public static List<CarryCapcityData> excelToPO(CarryCapcityDataVEexcel carryCapcityDataVEexcel) {
List<CarryCapcityData> data = new ArrayList<>();
if (carryCapcityDataVEexcel == null) {
return null;
}
List<String> phaseList = Stream.of("A", "B", "C").collect(Collectors.toList());
for (String phase : phaseList) {
CarryCapcityData carryCapcityData = new CarryCapcityData();
BeanUtils.copyProperties(carryCapcityDataVEexcel,carryCapcityData);
carryCapcityData.setPhaseType(phase);
carryCapcityData.setTime(carryCapcityDataVEexcel.getTime());
if (phase.equals("A")) {
carryCapcityData.setValue(carryCapcityDataVEexcel.getValue_a());
} else if (phase.equals("B")) {
carryCapcityData.setValue(carryCapcityDataVEexcel.getValue_b());
}else if (phase.equals("C")){
carryCapcityData.setValue(carryCapcityDataVEexcel.getValue_c());
}
data.add(carryCapcityData);
}
return data;
}
}

View File

@@ -0,0 +1,24 @@
package com.njcn.product.carrycapacity.pojo.excel;
import com.njcn.influx.pojo.bo.CarryCapcityData;
import com.njcn.influx.pojo.po.DataI;
import lombok.Data;
import java.util.List;
/**
* Description:
* Date: 2024/3/12 14:31【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
public class ExcelDataDTO {
private List<CarryCapcityData> dataHarmPowerPList;
private List<CarryCapcityData> dataHarmPowerQList;
private List<DataI> dataIList;
private List<CarryCapcityData> dataHarmPowerP2List;
private List<CarryCapcityData> dataHarmPowerQ2List;
private List<CarryCapcityData> dataHarmPowerU2List;
}

View File

@@ -0,0 +1,54 @@
package com.njcn.product.carrycapacity.pojo.param;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
/**
*
* Description:
* Date: 2024/2/20 11:15【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarryCapacityCalParam {
@NotBlank(message = "参数不能为空")
@ApiModelProperty("监测点索引")
private String lineId;
@ApiModelProperty("用户Id")
private String userId;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
private LocalDate startTime;
@ApiModelProperty("结束时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
private LocalDate endTime;
@ApiModelProperty(name = "scale",value = "电压等级")
private String scale;
@ApiModelProperty(name = "S_T",value = "S_T为配变额定容量监测点基准容量")
private Double S_T;
@ApiModelProperty(name = "S_pv",value = "S_pv为拟接入光伏容量")
private Double S_pv;
@ApiModelProperty(name = "stringMap",value = "首端电流模型参数A,B,C三项")
private Map<String, Double[]> stringMap;
@ApiModelProperty(name = "P_βminMap",value = "有功功率最小CP95值A,B,C三项")
private Map<String, Double> P_βminMap;
@ApiModelProperty(name = "Q_βminMap",value = "无功功率最小CP95值A,B,C三项")
private Map<String, Double> Q_βminMap;
@ApiModelProperty(name = "I_βmax",value = "2-25次谐波幅值最大95概率值A,B,C三项中的最大值")
private List<Double> I_βmax;
}

View File

@@ -0,0 +1,51 @@
package com.njcn.product.carrycapacity.pojo.param;
import com.njcn.common.pojo.constant.PatternRegex;
import com.njcn.web.constant.ValidMessage;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
/**
* Description:
* Date: 2024/3/20 9:59【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
public class CarryCapacityDeviceParam {
private String userId;
/**
* 设备名称
*/
private String devName;
private String devScale;
/**
* 设备用户协议容量(MVA)
*/
private Double protocolCapacity;
@Data
@EqualsAndHashCode(callSuper = true)
public static class CarryCapacityDeviceUpdateParam extends CarryCapacityDeviceParam {
@ApiModelProperty("设备Id")
@NotBlank(message = "设备Id不能为空")
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = ValidMessage.ID_FORMAT_ERROR)
private String devId;
}
@Data
@EqualsAndHashCode(callSuper = true)
public static class CarryCapacityDeviceQueryParam extends CarryCapacityDeviceParam {
@ApiModelProperty("设备Id")
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = ValidMessage.ID_FORMAT_ERROR)
private String devId;
}
}

View File

@@ -0,0 +1,51 @@
package com.njcn.product.carrycapacity.pojo.param;
import com.njcn.product.carrycapacity.pojo.po.CarryCapacityDevicePO;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
*
* Description:
* Date: 2024/2/20 11:15【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarryCapacityEvaluateParam {
@ApiModelProperty(value = "接线类型不可为空\"星型接法_0\", \"三角型接法_1\", \"开口三角型接法_2\"")
@NotBlank(message = "接线类型不能为空")
private String ptType;
@ApiModelProperty(value = "变压器连接方式")
private String connectionMode;
@ApiModelProperty(value = "功率因数0.95-1之间")
@NotNull(message = "功率因数不能为空")
private Double k;
@ApiModelProperty(value = "专变用户,公变用户")
@NotBlank(message = "用户类型不能为空")
private String userMode;
@ApiModelProperty(name = "scale",value = "电压等级")
@NotBlank(message = "电压等级不能为空")
private String scale;
@ApiModelProperty(name = "shortCapacity",value = "短路容量")
private Float shortCapacity;
@ApiModelProperty(name = "deviceCapacity",value = "设备容量")
private Float deviceCapacity;
@ApiModelProperty(name = "userList",value = "干扰源用户设备列表")
private List<CarryCapacityDevicePO> devList;
}

View File

@@ -0,0 +1,42 @@
package com.njcn.product.carrycapacity.pojo.param;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.time.LocalDate;
/**
*
* Description:
* Date: 2024/2/20 11:15【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarryCapacityQueryDataParam {
@ApiModelProperty("监测点索引")
private String lineId;
@ApiModelProperty("用户Id")
private String userId;
@ApiModelProperty("开始时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
private LocalDate startTime;
@ApiModelProperty("结束时间")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
private LocalDate endTime;
@Min(2)
@Max(25)
@ApiModelProperty("谐波次数")
private Integer time=2;
}

View File

@@ -0,0 +1,52 @@
package com.njcn.product.carrycapacity.pojo.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/**
* Description:
* Date: 2024/3/8 16:23【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarryCapacityResultParam {
/**
* 承载能力评估id
*/
private String id;
private String evaluateType;
@Data
@EqualsAndHashCode(callSuper = true)
public static class CarryCapacityResultPageParam extends CarryCapacityResultParam {
@NotNull(message="当前页不能为空!")
@Min(value = 1, message = "当前页不能为0")
@ApiModelProperty(value = "当前页",name = "pageNum",dataType ="Integer",required = true)
private Integer pageNum;
/**显示条数*/
@NotNull(message="显示条数不能为空!")
@ApiModelProperty(value = "显示条数",name = "pageSize",dataType ="Integer",required = true)
private Integer pageSize;
@ApiModelProperty(value="起始时间")
private String startTime;
@ApiModelProperty(value="结束时间")
private String endTime;
}
}

View File

@@ -0,0 +1,53 @@
package com.njcn.product.carrycapacity.pojo.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* Description:
* Date: 2024/3/5 10:47【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarryCapacityStrategyParam {
private String id;
/**
* 总承载能力评估结果1-安全2-III级预警3-II级预警4-I 级预警)
*/
@ApiModelProperty(value = "总承载能力评估结果1-安全2-III级预警3-II级预警4-I 级预警)")
@NotNull(message = "总承载能力评估结果不能为空")
private Integer result;
/**
* 指标评估结果1-安全2-III级预警3-II级预警4-I 级预警)
*/
@ApiModelProperty(value = "指标评估结果1-安全2-III级预警3-II级预警4-I 级预警)")
@NotNull(message = "指标评估结果不能为空")
private Integer indexResult;
/**
* 比较符
*/
@ApiModelProperty(value = "比较符")
@NotBlank(message = "比较符不能为空")
private String comparisonOperators;
/**
* 数量
*/
@ApiModelProperty(value = "数量")
@NotNull(message = "数量不能为空")
private Integer count;
}

View File

@@ -0,0 +1,103 @@
package com.njcn.product.carrycapacity.pojo.param;
import com.njcn.common.pojo.constant.PatternRegex;
import com.njcn.web.constant.ValidMessage;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.List;
/**
*
* Description:
* Date: 2024/2/20 11:15【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarryCapacityUserParam {
/**
* 用户名称
*/
private String userName;
/**
* 用户类型
*/
private String userType;
/**
* 电压等级(V)
*/
private String voltage;
/**
* 用户协议容量(MVA)
*/
private Double protocolCapacity;
/**
* 省
*/
private String province;
/**
* 市
*/
private String city;
/**
* 区
*/
private String region;
/**
* 所属区域
*/
private String area;
/**
* 更新操作实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
public static class CarryCapacityUserUpdateParam extends CarryCapacityUserParam {
@ApiModelProperty("用户Id")
@NotBlank(message = "用户Id不能为空")
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = ValidMessage.ID_FORMAT_ERROR)
private String userId;
}
@Data
@EqualsAndHashCode(callSuper = true)
public static class CarryCapacityUserPageParam extends CarryCapacityUserParam {
private String userId;
@NotNull(message="当前页不能为空!")
@Min(value = 1, message = "当前页不能为0")
@ApiModelProperty(value = "当前页",name = "pageNum",dataType ="Integer",required = true)
private Integer pageNum;
/**显示条数*/
@NotNull(message="显示条数不能为空!")
@ApiModelProperty(value = "显示条数",name = "pageSize",dataType ="Integer",required = true)
private Integer pageSize;
private String voltage;
@ApiModelProperty(value="起始时间")
private String startTime;
@ApiModelProperty(value="结束时间")
private String endTime;
private List<String> userTypeList;
}
}

View File

@@ -0,0 +1,29 @@
package com.njcn.product.carrycapacity.pojo.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotBlank;
/**
* Description:
* Date: 2024/3/6 17:30【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
public class ExcelDataParam {
@NotBlank(message = "监测点索引为空")
@ApiModelProperty("监测点索引")
private String lineId;
@ApiModelProperty("开始时间")
private String startTime;
@ApiModelProperty("结束时间")
private String endTime;
@ApiModelProperty(value = "excel文件")
private MultipartFile file;
}

View File

@@ -0,0 +1,51 @@
package com.njcn.product.carrycapacity.pojo.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
import com.njcn.db.bo.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
/**
*
* Description:
* Date: 2024/3/6 14:45【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "carry_capacity_data")
public class CarryCapacityDataPO extends BaseEntity{
/**
* 台区id
*/
@MppMultiId(value = "line_id")
private String lineId;
/**
* 开始时间
*/
@MppMultiId(value = "start_time")
private LocalDate startTime;
/**
* 结束时间
*/
@MppMultiId(value = "end_time")
private LocalDate endTime;
/**
* 上传数据集地址
*/
@TableField(value = "date_list")
private String dateList;
}

View File

@@ -0,0 +1,50 @@
package com.njcn.product.carrycapacity.pojo.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.bo.BaseEntity;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
* Description:
* Date: 2024/3/19 16:36【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@NoArgsConstructor
@TableName(value = "carry_capacity_device")
public class CarryCapacityDevicePO extends BaseEntity {
/**
* 设备id
*/
@TableId(value = "dev_id", type = IdType.ASSIGN_UUID)
private String devId;
@TableField(value = "user_id")
private String userId;
/**
* 设备名称
*/
@TableField(value = "dev_name")
private String devName;
/**
* 设备额定电压
*/
@TableField(value = "dev_scale")
private String devScale;
/**
* 设备用户协议容量(MVA)
*/
@TableField(value = "protocol_capacity")
private Double protocolCapacity;
}

View File

@@ -0,0 +1,129 @@
package com.njcn.product.carrycapacity.pojo.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.bo.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
/**
* Description:
* Date: 2024/3/8 16:23【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "carry_capacity_result")
public class CarryCapacityResultPO extends BaseEntity {
/**
* 承载能力评估id
*/
@TableId(value = "id",type = IdType.ASSIGN_UUID)
private String id;
/**
* 台区id
*/
@TableField(value = "line_id")
private String lineId;
/**
* 用户id
*/
@TableField(value = "user_id")
private String userId;
/**
* 开始时间
*/
@TableField(value = "start_time")
private LocalDate startTime;
/**
* 结束时间
*/
@TableField(value = "end_time")
private LocalDate endTime;
/**
* 配变首端电压等级1-安全2-III级预警3-II级预警4-I 级预警)
*/
@TableField(value = "u_t_level")
private Integer uTLevel;
/**
* 配变的功率因等级1-安全2-III级预警3-II级预警4-I 级预警)
*/
@TableField(value = "pf_t_level")
private Integer pfTLevel;
/**
* 等效负载率最小值等级1-安全2-III级预警3-II级预警4-I 级预警)
*/
@TableField(value = "b_t_level")
private Integer bTLevel;
/**
* 各次谐波电流幅值等级 1-安全2-III级预警3-II级预警4-I 级预警)
*/
@TableField(value = "i_level")
private Integer iLevel;
/**
* 总结果等级1-安全2-III级预警3-II级预警4-I 级预警,5-禁止接入6-允许接入)
*/
@TableField(value = "reslut_level")
private Integer reslutLevel;
/**
* 评估日期
*/
@TableField(value = "evaluate_date")
private LocalDate evaluateDate;
/**
* 是否删除0无效1有效
*/
@TableField(value = "status")
private Integer status;
@TableField(value = "evaluate_type")
private String evaluateType;
@TableField(value = "first_result")
private double firstResult;
@TableField(value = "i_result_list")
private String iResultList;
@TableField(value = "pt_type")
private String ptType;
@TableField(value = "connection_mode")
private String connectionMode;
@TableField(value = "k")
private Double k;
@TableField(value = "user_mode")
private String userMode;
@TableField(value = "scale")
private String scale;
@TableField(value = "short_capacity")
private Float shortCapacity;
@TableField(value = "device_capacity")
private Float deviceCapacity;
}

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