提交 3b6d2072 authored 作者: inroi's avatar inroi

创建

上级
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.semiconductor</groupId>
<artifactId>semiconductor</artifactId>
<version>0.0.1</version>
<name>semiconductor</name>
<description>Demo project for Spring Boot</description>
<packaging>pom</packaging>
<modules>
<module>semiconductor-framework</module>
<module>semiconductor-system</module>
</modules>
<properties>
<java.version>1.8</java.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<semiconductor.version>0.0.1-SNAPSHOT</semiconductor.version>
<project.encoding>UTF-8</project.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.5.6</spring-boot.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
<alibaba.nacos.version>2.0.3</alibaba.nacos.version>
<fastjson.version>1.2.78</fastjson.version>
<minio.version>8.0.3</minio.version>
<seata.version>1.4.2</seata.version>
<!-- 数据库连接池 -->
<druid.version>1.2.8</druid.version>
<sentinel.version>1.8.2</sentinel.version>
<hutools.version>5.7.18</hutools.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.semiconductor</groupId>
<artifactId>semiconductor-framework-core</artifactId>
<version>${semiconductor.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutools.version}</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.2.3</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<!--使用 mvn clean package -Pprod 进行激活prod环境的配置,否则激活默认环境-->
<profile>
<id>dev</id>
<properties>
<!-- 环境标识,需要与配置文件的名称相对应 -->
<profiles.active>dev</profiles.active>
<!-- 默认的命名空间不要去设置namespace -->
<nacos.namespace/>
</properties>
<activation>
<!-- 默认环境 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
<nacos.namespace>test</nacos.namespace>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
<nacos.namespace>prod</nacos.namespace>
</properties>
</profile>
</profiles>
</project>
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.semiconductor</groupId>
<artifactId>semiconductor</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>semiconductor-framework</artifactId>
<description>公共框架</description>
<packaging>pom</packaging>
<modules>
<module>semiconductor-framework-core</module>
</modules>
</project>
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.semiconductor</groupId>
<artifactId>semiconductor-framework</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>semiconductor-framework-core</artifactId>
<name>semiconductor-framework-core</name>
<description>semiconductor-framework-core</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<version>2.2.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.4.3</version>
</dependency>
<!--minio文件服务-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
<!--excel导入导出-->
<!--test1-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<!-- Swagger API文档 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<!-- # 增加两个配置解决 NumberFormatException -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<!--<version>1.7.21</version>-->
</dependency>
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.5.4</version>
</dependency>
<!--Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>
</project>
package com.system.framework.core.common.api;
public interface CommonAPI {
/**
* 1字典表的 翻译
* @param table
* @param text
* @param code
* @param key
* @return
*/
String translateDictFromTable(String table, String text, String code, String key);
/**
* 2普通字典的翻译
* @param code
* @param key
* @return
*/
String translateDict(String code, String key);
}
package com.system.framework.core.common.aspect;
import com.system.framework.core.common.aspect.annotation.NoRepeatSubmit;
import com.system.framework.core.response.StarBosResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* @author
* @date 2022/3/31 15:07
*/
@Aspect
@Component
@Slf4j
@SuppressWarnings("all")
public class RepeatSubmitAspect {
public static final String KEYPREX="noRpeat:user:";
@Autowired
private RedisTemplate redisTemplate;
/**
* 进行接口防重复操作处理
* @param pjp
* @param noRepeatSubmit
* @return
*/
@Around("execution(* com.system..controller.*.*(..)) && @annotation(noRepeatSubmit)")
public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
try {
//获取request
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
//拿到token和请求路径
StringBuilder sb = new StringBuilder();
// Authorization同等token
sb.append(KEYPREX).append(request.getHeader("Authorization").toString()).append(request.getRequestURI().toString());
//获取现在时间
long now = System.currentTimeMillis();
if (redisTemplate.hasKey(sb.toString())){
//上次请求时间
long lastTime= Long.valueOf(redisTemplate.opsForValue().get(sb.toString()).toString()) ;
// 如果现在距离上次提交时间小于设置的默认时间 则 判断为重复提交 否则 正常提交 -> 进入业务处理
if ((now - lastTime)>noRepeatSubmit.lockTime()){
//重新记录时间 10分钟过期时间
redisTemplate.opsForValue().set(sb.toString(),String.valueOf(now),10, TimeUnit.MINUTES);
//处理业务
Object result = pjp.proceed();
return result;
}else {
return StarBosResult.fail("-1","点击的太快了,请慢一点!");
}
}else {
//第一次操作
redisTemplate.opsForValue().set(sb.toString(),String.valueOf(now),10, TimeUnit.MINUTES);
Object result = pjp.proceed();
return result;
}
}catch (Throwable e){
log.error("校验表单重复提交时异常: {}", e.getMessage());
return StarBosResult.fail("-1","校验重复提交时异常");
}
}
}
package com.system.framework.core.common.aspect.annotation;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
/**
* @author fueen
* @date 2020/7/4
* 自定义防重复提交注解
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface NoRepeatSubmit {
/**
* 默认时间 默认1秒钟
* @return
*/
int lockTime() default 1000;
}
package com.system.framework.core.common.vo;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
/**
* 阿里java开发手册: 【强制】表必备三字段:id, create_time, update_time。 说明:其中 id 必为主键,类型为 bigint
* unsigned、单表时自增、步长为 1。create_time, update_time 的类型均为 datetime
* 类型,前者现在时表示主动式创建,后者过去分词表示被动式更新。
*
* @author Starbos
*/
public class BaseVO {
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
protected Date createTime;
/**
* 更新时间
*/
@ApiModelProperty("更新时间")
protected Date updateTime;
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "BaseDTO{" + "createTime=" + createTime + ", updateTime=" + updateTime + '}';
}
}
package com.system.framework.core.config;
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
//@RefreshScope
@Data
@Component
@ConfigurationProperties(prefix = "doc.oss")
public class MinioConfig {
// endPoint是一个URL,域名,IPv4或者IPv6地址
private String endpoint;
private String resourcesUrl;
// TCP/IP端口号
// private int port;
private String accessKeyId;
private String accessKeySecret;
// 如果是true,则用的是https而不是http,默认值是true
// private Boolean secure;
private Integer type;
// 默认存储桶
private String bucket;
@Value("${doc.oss.maxLength:20}")
private Integer maxLength;
// @Bean
// public MinioClient getMinioClient() throws InvalidPortException, InvalidEndpointException {
// MinioClient minioClient = new MinioClient(endpoint, port, accessKeyId, accessKeySecret, secure);
// return minioClient;
// }
@Bean
public MinioClient getMinioClient() {
MinioClient build = MinioClient.builder().endpoint(endpoint)
.credentials(accessKeyId, accessKeySecret)
.build();
return build;
}
}
package com.system.framework.core.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author Inori
*/
@EnableTransactionManagement
@MapperScan("com.**.mapper*")
@Configuration
public class MybatisPlusConfiguration {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//向Mybatis过滤器链中添加分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//乐观锁mybatis插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
package com.system.framework.core.config;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MapperFacade 用于dto ->entity的转换
*
* @author FrozenWatermelon
* @date 2022/4/11
*/
@Configuration
public class OrikaConfig {
@Bean
public MapperFactory mapperFactory() {
return new DefaultMapperFactory.Builder().build();
}
@Bean
public MapperFacade mapperFacade() {
return mapperFactory().getMapperFacade();
}
}
package com.system.framework.core.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.system.framework.core.constant.CacheConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
import javax.annotation.Resource;
import java.time.Duration;
import static java.util.Collections.singletonMap;
/**
* 开启缓存支持
* @Return:
*/
@Slf4j
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Resource
private LettuceConnectionFactory lettuceConnectionFactory;
// /**
// * @description 自定义的缓存key的生成策略 若想使用这个key
// * 只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
// * @return 自定义策略生成的key
// */
// @Override
// @Bean
// public KeyGenerator keyGenerator() {
// return new KeyGenerator() {
// @Override
// public Object generate(Object target, Method method, Object... params) {
// StringBuilder sb = new StringBuilder();
// sb.append(target.getClass().getName());
// sb.append(method.getDeclaringClass().getName());
// Arrays.stream(params).map(Object::toString).forEach(sb::append);
// return sb.toString();
// }
// };
// }
/**
* RedisTemplate配置
*
* @param lettuceConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
log.info(" --- redis config init --- ");
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
om.enableDefaultTyping(DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 缓存配置管理器
*
* @param factory
* @return
*/
// @Bean
public CacheManager cacheManager(LettuceConnectionFactory factory) {
// 配置序列化(缓存默认有效期 6小时)
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6));
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
// 以锁写入的方式创建RedisCacheWriter对象
// RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
// 创建默认缓存配置对象
/* 默认配置,设置缓存有效期 1小时*/
// RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));
/* 自定义配置test:demo 的超时时间为 5分钟*/
RedisCacheManager cacheManager = RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter(factory)).cacheDefaults(redisCacheConfiguration)
.withInitialCacheConfigurations(singletonMap(CacheConstant.TEST_DEMO_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).disableCachingNullValues()))
.transactionAware().build();
return cacheManager;
}
@Bean
public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = getRedisCacheConfiguration();
RedisCacheManager cacheManager = RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration)
.build();
return cacheManager;
}
private RedisCacheConfiguration getRedisCacheConfiguration() {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer)
).entryTtl(Duration.ofDays(7));
return redisCacheConfiguration;
}
// @Bean
// public JedisConnectionFactory jedisConnectionFactory() {
// RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(hostName, port);
// redisStandaloneConfiguration.setPassword(password);
// JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
// return jedisConnectionFactory;
// }
}
package com.system.framework.core.config;
//import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import com.system.framework.core.constant.CommonConstant;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Configuration
@EnableSwagger2
//@ConditionalOnProperty(name = "swagger.enabled", havingValue = "true")
public class SwaggerConfig implements WebMvcConfigurer {
//api接口包扫描路径
public static final String SWAGGER_SCAN_BASE_PACKAGE = "com";
@Value("${spring.application.name}")
public String applicationName;
public static final String VERSION = "1.0.0";
/**
* swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等
*
* @return Docket
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
// .enable(true)
.select()
//此包路径下的类,才生成接口文档
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
//加了ApiOperation注解的类,才生成接口文档
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build()
.securitySchemes(Collections.singletonList(securityScheme()))
.securityContexts(securityContexts());
//.globalOperationParameters(setHeaderToken());
}
/***
* oauth2配置
* 需要增加swagger授权回调地址
* http://localhost:8888/webjars/springfox-swagger-ui/o2c.html
* @return
*/
@Bean
SecurityScheme securityScheme() {
return new ApiKey(CommonConstant.X_ACCESS_TOKEN, CommonConstant.X_ACCESS_TOKEN, "header");
}
/**
* JWT token
*
* @return
*/
private List<Parameter> setHeaderToken() {
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> pars = new ArrayList<>();
tokenPar.name(CommonConstant.X_ACCESS_TOKEN).description("Authorization").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
pars.add(tokenPar.build());
return pars;
}
/**
* 新增 securityContexts 保持登录状态
*/
private List<SecurityContext> securityContexts() {
return new ArrayList(
Collections.singleton(SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$"))
.build())
);
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return new ArrayList(
Collections.singleton(new SecurityReference(CommonConstant.X_ACCESS_TOKEN, authorizationScopes)));
}
/**
* api文档的详细信息函数,注意这里的注解引用的是哪个
*
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// //大标题
.title("后台服务API接口文档")
// 版本号
.version("1.0")
// .termsOfServiceUrl("NO terms of service")
// 描述
.description(applicationName + "后台API接口")
// 作者
// .contact("")
.license("The Apache License, Version 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.build();
}
/**
* 防止@EnableMvc把默认的静态资源路径覆盖了,手动设置的方式
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
}
}
package com.system.framework.core.constant;
/**
* @author: starbos
* @date: 2021-11-24
* @description: 缓存常量
*/
public interface CacheConstant {
/**
* 字典信息缓存
*/
public static final String SYS_DICT_CACHE = "sys:cache:dict";
/**
* 表字典信息缓存
*/
public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable";
public static final String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys";
/**
* 数据权限配置缓存
*/
public static final String SYS_DATA_PERMISSIONS_CACHE = "sys:cache:permission:datarules";
/**
* 缓存用户信息
*/
public static final String SYS_USERS_CACHE = "sys:cache:user";
/**
* 全部部门信息缓存
*/
public static final String SYS_DEPARTS_CACHE = "sys:cache:depart:alldata";
/**
* 全部部门ids缓存
*/
public static final String SYS_DEPART_IDS_CACHE = "sys:cache:depart:allids";
/**
* 测试缓存key
*/
public static final String TEST_DEMO_CACHE = "test:demo";
/**
* 字典信息缓存
*/
public static final String SYS_DYNAMICDB_CACHE = "sys:cache:dbconnect:dynamic:";
/**
* gateway路由缓存
*/
public static final String GATEWAY_ROUTES = "geteway_routes";
/**
* gateway路由 reload key
*/
public static final String ROUTE_JVM_RELOAD_TOPIC = "gateway_jvm_route_reload_topic";
/**
* 表字段
*/
public static final String META_DATA_FLIED = "meta:cache:flied";
}
package com.system.framework.core.constant;
public interface CommonConstant {
/**
* 正常状态
*/
public static final Integer STATUS_NORMAL = 0;
/**
* 禁用状态
*/
public static final Integer STATUS_DISABLE = -1;
/**
* 删除标志
*/
public static final Integer DEL_FLAG_1 = 1;
/**
* 未删除
*/
public static final Integer DEL_FLAG_0 = 0;
/**
* 系统日志类型: 登录
*/
public static final int LOG_TYPE_1 = 1;
/**
* 系统日志类型: 操作
*/
public static final int LOG_TYPE_2 = 2;
/**
* 操作日志类型: 查询
*/
public static final int OPERATE_TYPE_1 = 1;
/**
* 操作日志类型: 添加
*/
public static final int OPERATE_TYPE_2 = 2;
/**
* 操作日志类型: 更新
*/
public static final int OPERATE_TYPE_3 = 3;
/**
* 操作日志类型: 删除
*/
public static final int OPERATE_TYPE_4 = 4;
/**
* 操作日志类型: 倒入
*/
public static final int OPERATE_TYPE_5 = 5;
/**
* 操作日志类型: 导出
*/
public static final int OPERATE_TYPE_6 = 6;
/**
* {@code 500 Server Error} (HTTP/1.0 - RFC 1945)
*/
public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
/**
* {@code 200 OK} (HTTP/1.0 - RFC 1945)
*/
public static final Integer SC_OK_200 = 200;
/**
* 访问权限认证未通过 510
*/
public static final Integer SC_STARBOS_NO_AUTHZ = 510;
/**
* 登录用户Shiro权限缓存KEY前缀
*/
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.starbos.config.shiro.ShiroRealm.authorizationCache:";
/**
* 登录用户Token令牌缓存KEY前缀
*/
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
/**
* Token缓存时间:3600秒即一小时
*/
public static final int TOKEN_EXPIRE_TIME = 3600;
/**
* 0:一级菜单
*/
public static final Integer MENU_TYPE_0 = 0;
/**
* 1:子菜单
*/
public static final Integer MENU_TYPE_1 = 1;
/**
* 2:按钮权限
*/
public static final Integer MENU_TYPE_2 = 2;
/**
* 通告对象类型(USER:指定用户,ALL:全体用户)
*/
public static final String MSG_TYPE_UESR = "USER";
public static final String MSG_TYPE_ALL = "ALL";
/**
* 发布状态(0未发布,1已发布,2已撤销)
*/
public static final String NO_SEND = "0";
public static final String HAS_SEND = "1";
public static final String HAS_CANCLE = "2";
/**
* 阅读状态(0未读,1已读)
*/
public static final String HAS_READ_FLAG = "1";
public static final String NO_READ_FLAG = "0";
/**
* 优先级(L低,M中,H高)
*/
public static final String PRIORITY_L = "L";
public static final String PRIORITY_M = "M";
public static final String PRIORITY_H = "H";
/**
* 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板
*/
public static final String SMS_TPL_TYPE_0 = "0";
public static final String SMS_TPL_TYPE_1 = "1";
public static final String SMS_TPL_TYPE_2 = "2";
/**
* 状态(0无效1有效)
*/
public static final String STATUS_0 = "0";
public static final String STATUS_1 = "1";
/**
* 同步工作流引擎1同步0不同步
*/
public static final Integer ACT_SYNC_1 = 1;
public static final Integer ACT_SYNC_0 = 0;
/**
* 消息类型1:通知公告2:系统消息
*/
public static final String MSG_CATEGORY_1 = "1";
public static final String MSG_CATEGORY_2 = "2";
/**
* 是否配置菜单的数据权限 1是0否
*/
public static final Integer RULE_FLAG_0 = 0;
public static final Integer RULE_FLAG_1 = 1;
/**
* 是否用户已被冻结 1正常(解冻) 2冻结
*/
public static final Integer USER_UNFREEZE = 1;
public static final Integer USER_FREEZE = 2;
/**
* 字典翻译文本后缀
*/
public static final String DICT_TEXT_SUFFIX = "_dictText";
/**
* 表单设计器主表类型
*/
public static final Integer DESIGN_FORM_TYPE_MAIN = 1;
/**
* 表单设计器子表表类型
*/
public static final Integer DESIGN_FORM_TYPE_SUB = 2;
/**
* 表单设计器URL授权通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
/**
* 表单设计器URL授权未通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
/**
* 表单设计器新增 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_ADD = "add";
/**
* 表单设计器修改 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit";
/**
* 表单设计器详情 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
/**
* 表单设计器复用数据 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
/**
* 表单设计器编辑 Flag (已弃用)
*/
public static final String DESIGN_FORM_URL_TYPE_VIEW = "view";
/**
* online参数值设置(是:Y, 否:N)
*/
public static final String ONLINE_PARAM_VAL_IS_TURE = "Y";
public static final String ONLINE_PARAM_VAL_IS_FALSE = "N";
/**
* 文件上传类型(本地:local,Minio:minio,阿里云:alioss)
*/
public static final String UPLOAD_TYPE_LOCAL = "local";
public static final String UPLOAD_TYPE_MINIO = "minio";
public static final String UPLOAD_TYPE_OSS = "alioss";
/**
* 文档上传自定义桶名称
*/
public static final String UPLOAD_CUSTOM_BUCKET = "eoafile";
/**
* 文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH = "eoafile";
/**
* 文件外链接有效天数
*/
public static final Integer UPLOAD_EFFECTIVE_DAYS = 1;
/**
* 员工身份 (1:普通员工 2:上级)
*/
public static final Integer USER_IDENTITY_1 = 1;
public static final Integer USER_IDENTITY_2 = 2;
/**
* sys_user 表 username 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
/**
* sys_user 表 work_no 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
/**
* sys_user 表 phone 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
/**
* sys_user 表 email 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
/**
* sys_quartz_job 表 job_class_name 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
/**
* sys_position 表 code 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_CODE = "uniq_code";
/**
* sys_role 表 code 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
/**
* sys_depart 表 code 唯一键索引
*/
public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
/**
* 在线聊天 是否为默认分组
*/
public static final String IM_DEFAULT_GROUP = "1";
/**
* 在线聊天 图片文件保存路径
*/
public static final String IM_UPLOAD_CUSTOM_PATH = "imfile";
/**
* 在线聊天 用户状态
*/
public static final String IM_STATUS_ONLINE = "online";
/**
* 在线聊天 SOCKET消息类型
*/
public static final String IM_SOCKET_TYPE = "chatMessage";
/**
* 在线聊天 是否开启默认添加好友 1是 0否
*/
public static final String IM_DEFAULT_ADD_FRIEND = "1";
/**
* 在线聊天 用户好友缓存前缀
*/
public static final String IM_PREFIX_USER_FRIEND_CACHE = "im_prefix_user_friend_";
/**
* 考勤补卡业务状态 (1:同意 2:不同意)
*/
public static final String SIGN_PATCH_BIZ_STATUS_1 = "1";
public static final String SIGN_PATCH_BIZ_STATUS_2 = "2";
/**
* 公文文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc";
/**
* 公文文档下载自定义路径
*/
public static final String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown";
/**
* WPS存储值类别(1 code文号 2 text(WPS模板还是公文发文模板))
*/
public static final String WPS_TYPE_1 = "1";
public static final String WPS_TYPE_2 = "2";
// public final static String X_ACCESS_TOKEN = "X-Access-Token";
public final static String X_ACCESS_TOKEN = "Authorization";
/**
* 多租户 请求头
*/
public final static String TENANT_ID = "tenant_id";
/**
* 微服务读取配置文件属性 服务地址
*/
public final static String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr";
/**
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
*/
public final static String THIRD_LOGIN_CODE = "third_login_code";
}
package com.system.framework.core.constant;
/**
* 规则值生成 编码常量类
* @author: taoyan
* @date: 2021-11-25
*/
public class FillRuleConstant {
/**
* 公文发文编码
*/
public static final String DOC_SEND = "doc_send_code";
/**
* 部门编码
*/
public static final String DEPART = "org_num_role";
/**
* 分类字典编码
*/
public static final String CATEGORY = "category_code_rule";
/**
* 收费单编码规则
*/
public static final String ReceivingNoteRule = "receiving_note_rule";
}
package com.system.framework.core.constant;
public class GlobalConstants {
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/**
* GBK 字符集
*/
public static final String GBK = "GBK";
/**
* RMI 远程方法调用
*/
public static final String LOOKUP_RMI = "rmi://";
/**
* LDAP 远程方法调用
*/
public static final String LOOKUP_LDAP = "ldap://";
/**
* http请求
*/
public static final String HTTP = "http://";
/**
* https请求
*/
public static final String HTTPS = "https://";
/**
* 成功标记
*/
public static final Integer SUCCESS = 200;
/**
* 失败标记
*/
public static final Integer FAIL = 500;
/**
* 登录成功
*/
public static final String LOGIN_SUCCESS = "Success";
/**
* 注销
*/
public static final String LOGOUT = "Logout";
/**
* 注册
*/
public static final String REGISTER = "Register";
/**
* 登录失败
*/
public static final String LOGIN_FAIL = "Error";
}
package com.system.framework.core.constant;
/**
* codegenerator模块用Constant
*/
public interface TablePathConstant {
String tableEntity="/tableEntity";
String findTableFormat="/findTableFormat";
String findList="/findList";//
String addModel="/addModel";
String deleteModel="/deleteModel";
String editModel="/editModel";
}
package com.system.framework.core.constant;
/**
* @Description: Websocket常量类
* @author:
* @date: 2022年04月23日
*/
public class WebsocketConst {
/**
* 消息json key:cmd
*/
public static final String MSG_CMD = "cmd";
/**
* 消息json key:msgId
*/
public static final String MSG_ID = "msgId";
/**
* 消息json key:msgTxt
*/
public static final String MSG_TXT = "msgTxt";
/**
* 消息json key:userId
*/
public static final String MSG_USER_ID = "userId";
/**
* 消息类型 heartcheck
*/
public static final String CMD_CHECK = "heartcheck";
/**
* 消息类型 user 用户消息
*/
public static final String CMD_USER = "user";
/**
* 消息类型 topic 系统通知
*/
public static final String CMD_TOPIC = "topic";
/**
* 消息类型 email
*/
public static final String CMD_EMAIL = "email";
/**
* 消息类型 meetingsign 会议签到
*/
public static final String CMD_SIGN = "sign";
/**
* 消息类型 新闻发布/取消
*/
public static final String NEWS_PUBLISH = "publish";
}
package com.system.framework.core.excel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.IService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* @description: Listener
* @author:
* @create: 2022-04-25 10:16
*/
@Slf4j
@Data
public class AuthExcelModelListener<T> extends AnalysisEventListener<T> {
/**
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
List<T> cachedDataList = new ArrayList<T>(BATCH_COUNT);
private IService<T> demoDAO;
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*
* @param demoDAO
*/
public AuthExcelModelListener(IService<T> demoDAO) {
this.demoDAO = demoDAO;
}
@Override
public void invoke(T data, AnalysisContext context) {
// System.out.println(data);
log.info("解析到一条数据:{}", JSON.toJSONString(data));
cachedDataList.add(data);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
cachedDataList = new ArrayList<T>(BATCH_COUNT);
}
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
log.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
private void saveData() {
log.info("{}条数据,开始存储数据库!", cachedDataList.size());
demoDAO.saveBatch(cachedDataList);
log.info("存储数据库成功!");
}
}
package com.system.framework.core.excel.util;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
/**
* 描述:
* EasyExcel的基础封装
*
* @author
* @create 2022-04-19
*/
@Slf4j
public class EasyExcelSetting {
/**
* 设置响应头
*
* @param response 回应的请求数据
* @param fileName 文件名字
*/
public static void setHead(HttpServletResponse response, String fileName) {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
log.error("编码异常");
}
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
}
/**
* 设置Excel的格式
*
* @return 格式化后的Excel
*/
public static HorizontalCellStyleStrategy formatExcel() {
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setFillBackgroundColor(IndexedColors.WHITE.getIndex());
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 10);
headWriteCellStyle.setWriteFont(headWriteFont);
// 内容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
WriteFont contentWriteFont = new WriteFont();
// 字体大小
contentWriteFont.setFontHeightInPoints((short) 10);
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 设置自动换行
contentWriteCellStyle.setWrapped(true);
// 设置垂直居中
contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置水平居中
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
}
/**
* 设置头部单元格宽度
*/
public static class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
@Override
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
// 设置宽度
Sheet sheet = writeSheetHolder.getSheet();
sheet.setColumnWidth(cell.getColumnIndex(), 5000);
}
}
}
package com.system.framework.core.excel.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;
/**
* @ClassName: EasyExcelUtils
* @Description: EasyExcel工具类
* @Author:
* @Data: 2022/4/19
* @Version: 1.0
*/
@Slf4j
public class EasyExcelUtils {
/**
* 每个sheet的容量,即超过60000时就会把数据分sheet
*/
private static final int PAGE_SIZE = 60000;
/**
* 导出报表(使用注解方式设置Excel头数据)
*
* @param response 响应请求
* @param data 报表数据
* @param fileName 文件名字
* @param excelClass 报表实体类的Class(根据该Class的属性来设置Excel的头属性)
*/
public static void exportByExcel(HttpServletResponse response, List<?> data, String fileName, Class<?> excelClass) throws IOException {
@Cleanup ByteArrayOutputStream os = new ByteArrayOutputStream();
// ServletOutputStream os = response.getOutputStream();
long exportStartTime = System.currentTimeMillis();;
log.info("报表导出Size: " + data.size() + "条。");
// 把查询到的数据按设置的sheet的容量进行切割
List<? extends List<?>> lists = SplitList.splitList(data, PAGE_SIZE);
// 设置响应头
EasyExcelSetting.setHead(response, fileName);
// 格式化Excel数据
// EasyExcelBasic.formatExcel():设置Excel的格式
// EasyExcelBasic.ExcelWidthStyleStrategy():设置头部单元格宽度
// ExcelWriter excelWriter = EasyExcel.write(os, excelClass).registerWriteHandler(com.starbos.cloud.oauth.system.file.util.EasyExcel.formatExcel()).registerWriteHandler(new com.starbos.cloud.oauth.system.file.util.EasyExcel.ExcelWidthStyleStrategy()).build();
// 浏览器访问url直接下载文件的方式
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), excelClass).registerWriteHandler(EasyExcelSetting.formatExcel()).registerWriteHandler(new EasyExcelSetting.ExcelWidthStyleStrategy()).build();
// EasyExcel.write(response.getOutputStream(), excelClass).
ExcelWriterSheetBuilder excelWriterSheetBuilder;
WriteSheet writeSheet;
for (int i = 1; i <= lists.size(); ++i) {
excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
excelWriterSheetBuilder.sheetNo(i).sheetName("sheet" + i);
writeSheet = excelWriterSheetBuilder.build();
excelWriter.write(lists.get(i - 1), writeSheet);
}
// 必须要finish才会写入,不finish只会创建empty的文件
excelWriter.finish();
// byte[] content = os.toByteArray();
// @Cleanup InputStream is = new ByteArrayInputStream(content);
//
// // 文件落地,用来测试文件的格式和数据的完整性
// @Cleanup
//// :lombok关流注解
// FileOutputStream fileOutputStream = new FileOutputStream("D:\\data/logs/" + fileName + ".xlsx");
// @Cleanup BufferedInputStream bis = new BufferedInputStream(is);
// @Cleanup BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
// byte[] buff = new byte[2048];
// int bytesRead;
// while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
// bos.write(buff, 0, bytesRead);
// }
// log.info("文件落地磁盘");
// 文件上传到OSS
// FileUploadUtil_Test.upLocalFileToOss(is, fileName);
log.info("报表导出结束时间:" + new Date() + ";导出耗时: " + (System.currentTimeMillis() - exportStartTime) + "ms");
}
}
package com.system.framework.core.excel.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @ClassName: SplitList
* @Description: EasyExcelUtils类的辅助类(切割查询的数据)
* @Author:
* @Data: 2022/4/19
* @Version: 1.0
*/
public class SplitList {
/**
* 切割查询的数据
* @param list 需要切割的数据
* @param len 按照什么长度切割
* @param <T>
* @return
*/
public static <T> List<List<T>> splitList(List<T> list, int len) {
if (list == null || list.size() == 0 || len < 1) {
return null;
}
List<List<T>> result = new ArrayList<List<T>>();
int size = list.size();
int count = (size + len - 1) / len;
for (int i = 0; i < count; i++) {
List<T> subList = list.subList(i * len, (Math.min((i + 1) * len, size)));
result.add(subList);
}
return result;
}
/**
* 集合平均分组
* @param source 源集合
* @param n 分成n个集合
* @param <T> 集合类型
* @return 平均分组后的集合
*/
public static <T> List<List<T>> groupList(List<T> source, int n) {
if (source == null || source.size() == 0 || n < 1) {
return null;
}
if (source.size() < n) {
return Collections.singletonList(source);
}
List<List<T>> result = new ArrayList<List<T>>();
int number = source.size() / n;
int remaider = source.size() % n;
// 偏移量,每有一个余数分配,就要往右偏移一位
int offset = 0;
for (int i = 0; i < n;i++) {
List<T> list1 = null;
if (remaider > 0){
list1 = source.subList(i * number + offset,(i + 1) * number + offset + 1);
remaider--;
offset++;
}else {
list1 = source.subList(i * number + offset, (i+1) * number + offset);
}
result.add(list1);
}
return result;
}
}
package com.system.framework.core.exception;
import com.system.framework.core.response.StarBosResult;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/*每次增加异常,需要在日志切面类里面增加异常通知的异常类型,否则将无法记录接口发生异常的日志*/
@ControllerAdvice
public class GlobalExceptionHandler {
/*金蝶云操作异常*/
@ResponseBody
@ExceptionHandler(MetaDataQueryException.class)
public StarBosResult kingdeeException(HttpServletRequest req, MetaDataQueryException e)
{
/* Result r=new Result();
r.setResult(e.getResult());*/
return StarBosResult.fail(e.getMessage());
}
}
package com.system.framework.core.exception;
import lombok.Data;
import java.util.List;
@Data
public class MetaDataQueryException extends RuntimeException{
public List<String> result;
public int code;
public MetaDataQueryException(String message, List<String> result, int code) {
super(message);
this.result=result;
this.code=code;
}
public MetaDataQueryException(String message) {
super(message);
}
public List<String> getResult() {
return result;
}
public void setResult(List<String> result) {
this.result = result;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
\ No newline at end of file
package com.system.framework.core.exception;
public class ReflectException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ReflectException(String message){
super(message);
}
public ReflectException(Throwable cause)
{
super(cause);
}
public ReflectException(String message, Throwable cause)
{
super(message,cause);
}
}
package com.system.framework.core.exception;
import com.system.framework.core.response.StarBosResultEnum;
public class StarBosException extends RuntimeException {
private static final long serialVersionUID = 1L;
public StarBosException(String message){
super(message);
}
private Object object;
private StarBosResultEnum starBosResultEnum;
public StarBosException(String msg, Object object) {
super(msg);
this.object = object;
}
public StarBosException(String msg, Throwable cause) {
super(msg, cause);
}
public StarBosException(StarBosResultEnum starBosResultEnum) {
super(starBosResultEnum.getMsg());
this.starBosResultEnum = starBosResultEnum;
}
public StarBosException(StarBosResultEnum starBosResultEnum, Object object) {
super(starBosResultEnum.getMsg());
this.starBosResultEnum = starBosResultEnum;
this.object = object;
}
public Object getObject() {
return object;
}
public StarBosResultEnum getResponseEnum() {
return starBosResultEnum;
}
}
package com.system.framework.core.handler;
import com.alibaba.fastjson.JSONObject;
/**
* 填值规则接口
*
* @author Yan_东
* 如需使用填值规则功能,规则实现类必须实现此接口
*/
public interface IFillRuleHandler {
/**
* @param params 页面配置固定参数
* @param formData 动态表单参数
* @return
*/
public Object execute(JSONObject params, JSONObject formData);
}
package com.system.framework.core.response;
/**
* @author FrozenWatermelon
* @date 2020/7/9
*/
public enum ResponseEnum {
/**
* ok
*/
OK("00000", "ok"),
/**
* 用于直接显示提示用户的错误,内容由输入内容决定
*/
SHOW_FAIL("A00001", ""),
/**
* 方法参数没有校验,内容由输入内容决定
*/
METHOD_ARGUMENT_NOT_VALID("A00002", ""),
/**
* 无法读取获取请求参数
*/
HTTP_MESSAGE_NOT_READABLE("A00003", "请求参数格式有误"),
/**
* 未授权
*/
UNAUTHORIZED("A00004", "Unauthorized"),
/**
* 服务器出了点小差
*/
EXCEPTION("A00005", "服务器出了点小差"),
/**
* 数据异常
*/
DATA_ERROR("A00007", "数据异常,请刷新后重新操作"),
/**
* 一些需要登录的接口,而实际上因为前端无法知道token是否已过期,导致token已失效时,
* 应该返回一个状态码,告诉前端token已经失效了,及时清理
*/
CLEAN_TOKEN("A00008", "clean token"),
/**
* 刷新token已过期
*/
REFRESH_TOKEN_EXIST("A00009", "refresh token exist"),
/**
* 数据不完整
*/
DATA_INCOMPLETE("A00010", "数据不完整"),
/**
* 01开头代表商品
*/
SPU_NOT_EXIST("A01000", "spu not exist"),
/**
* 02开头代表购物车
*/
SHOP_CART_NOT_EXIST("A02000", "shop cart not exist"),
/**
* 03开头代表订单
*/
ORDER_NOT_EXIST("A03000", "order not exist"),
/**
* 请勿重复提交订单,
* 1.当前端遇到该异常时,说明前端防多次点击没做好
* 2.提示用户 订单已发生改变,请勿重复下单
*/
REPEAT_ORDER("A03002", "please don't repeat order"),
/**
* 订单已过期,当前端看到该状态码的时候,提示订单信息已过期,请重新确认后提交,此时用户点击确定,前端刷新页面。
*/
ORDER_EXPIRED("A03003", "order expired"),
/**
* 订单已支付,无法取消订单
*/
ORDER_PAYED("A03007", "order payed"),
/**
* 订单未发货,无法确认收货
*/
ORDER_NO_DELIVERY("A03008", "order no delivery"),
/**
* 库存不足,body会具体返回那个skuid的库存不足
*/
NOT_STOCK("A03010", "not stock"),
/**
* 订单未完成或未关闭,无法删除订单
*/
ORDER_NOT_FINISH_OR_CLOSE("A03011", "order not finish or close"),
/**
* 订单未支付
*/
ORDER_NOT_PAYED("A03012", "order not payed"),
/**
* 订单已失败
*/
ORDER_HAS_FAILED("A03013", "order has failed"),
/**
* 没有查询权限
*/
REFUND_NOT_PERMISSION("A03024", "refund not permission"),
/**
* 撤销失败 当前状态不允许此操作
*/
REFUND_STATUS_CHECK("A03034", "refund status check"),
/**
* 04 开头代表注册登录之类的异常状态
* 社交账号未绑定,当前端看到该异常时,应该在合适的时间(比如在购买的时候跳)根据社交账号的类型,跳转到绑定系统账号的页面
*/
SOCIAL_ACCOUNT_NOT_BIND("A04001", "social account not bind"),
/**
* 有些时候第三方系统授权之后,会有个临时的key,比如小程序的session_key
* 这个异常代表session_key过期,前端遇到这个问题的时候,应该再次调用社交登录的接口,刷新session_key
*/
BIZ_TEMP_SESSION_KEY_EXPIRE("A04002", "biz temp session key expire"),
/**
* 账号未注册,前端看到这个状态码,弹出选择框,提示用户账号未注册,是否进入注册页面,用户选择是,进入注册页面
*/
ACCOUNT_NOT_REGISTER("A04003", "account not register");
private final String code;
private final String msg;
public String value() {
return code;
}
public String getMsg() {
return msg;
}
ResponseEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public String toString() {
return "ResponseEnum{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + "} " + super.toString();
}
}
package com.system.framework.core.response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.Objects;
/**
* 统一的返回数据
*
* @author FrozenWatermelon
* @date 2020/7/3
*/
public class ServerResponseEntity<T> implements Serializable {
private static final Logger log = LoggerFactory.getLogger(ServerResponseEntity.class);
/**
* 状态码
*/
private String code;
/**
* 信息
*/
private String msg;
/**
* 数据
*/
private T data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public boolean isSuccess() {
return Objects.equals(ResponseEnum.OK.value(), this.code);
}
@Override
public String toString() {
return "ServerResponseEntity{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + '}';
}
public static <T> ServerResponseEntity<T> success(T data) {
ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
serverResponseEntity.setData(data);
serverResponseEntity.setCode(ResponseEnum.OK.value());
return serverResponseEntity;
}
public static <T> ServerResponseEntity<T> success() {
ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
serverResponseEntity.setCode(ResponseEnum.OK.value());
serverResponseEntity.setMsg(ResponseEnum.OK.getMsg());
return serverResponseEntity;
}
/**
* 前端显示失败消息
* @param msg 失败消息
* @return
*/
public static <T> ServerResponseEntity<T> showFailMsg(String msg) {
log.error(msg);
ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
serverResponseEntity.setMsg(msg);
serverResponseEntity.setCode(ResponseEnum.SHOW_FAIL.value());
return serverResponseEntity;
}
public static <T> ServerResponseEntity<T> fail(ResponseEnum responseEnum) {
log.error(responseEnum.toString());
ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
serverResponseEntity.setMsg(responseEnum.getMsg());
serverResponseEntity.setCode(responseEnum.value());
return serverResponseEntity;
}
public static <T> ServerResponseEntity<T> fail(ResponseEnum responseEnum, T data) {
log.error(responseEnum.toString());
ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
serverResponseEntity.setMsg(responseEnum.getMsg());
serverResponseEntity.setCode(responseEnum.value());
serverResponseEntity.setData(data);
return serverResponseEntity;
}
public static <T> ServerResponseEntity<T> transform(ServerResponseEntity<?> oldServerResponseEntity) {
ServerResponseEntity<T> serverResponseEntity = new ServerResponseEntity<>();
serverResponseEntity.setMsg(oldServerResponseEntity.getMsg());
serverResponseEntity.setCode(oldServerResponseEntity.getCode());
log.error(serverResponseEntity.toString());
return serverResponseEntity;
}
}
package com.system.framework.core.response;
import com.system.framework.core.constant.GlobalConstants;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.Objects;
/**
* 全局返回对象
*
* @param <T>
*/
@ApiModel(value="全局返回对象",description="接口返回对象")
public class StarBosResult<T> implements Serializable {
private static final Logger log = LoggerFactory.getLogger(StarBosResult.class);
private static final long serialVersionUID = 1L;
/**
* 成功
*/
public static final int SUCCESS = GlobalConstants.SUCCESS;
/**
* 失败
*/
public static final int FAIL = GlobalConstants.FAIL;
@ApiModelProperty(value = "状态码")
private int code;
@ApiModelProperty(value = "返回处理消息")
private String msg;
@ApiModelProperty(value = "数据")
private T data;
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static <T> StarBosResult<T> ok() {
return restStarBosResultesult(null, SUCCESS, null);
}
public static <T> StarBosResult<T> ok(T data) {
return restStarBosResultesult(data, SUCCESS, null);
}
public static <T> StarBosResult<T> ok(T data, String msg) {
return restStarBosResultesult(data, SUCCESS, msg);
}
public static <T> StarBosResult<T> fail() {
return restStarBosResultesult(null, FAIL, null);
}
public static <T> StarBosResult<T> fail(String msg) {
return restStarBosResultesult(null, FAIL, msg);
}
public static <T> StarBosResult<T> fail(T data) {
return restStarBosResultesult(data, FAIL, null);
}
public static <T> StarBosResult<T> fail(T data, String msg) {
return restStarBosResultesult(data, FAIL, msg);
}
public static <T> StarBosResult<T> fail(int code, String msg) {
return restStarBosResultesult(null, code, msg);
}
private static <T> StarBosResult<T> restStarBosResultesult(T data, int code, String msg) {
StarBosResult<T> apiStarBosResultesult = new StarBosResult<>();
apiStarBosResultesult.setCode(code);
apiStarBosResultesult.setData(data);
apiStarBosResultesult.setMsg(msg);
return apiStarBosResultesult;
}
public StarBosResult<T> error500(String message) {
this.msg = message;
this.code = GlobalConstants.FAIL;
return this;
}
public StarBosResult<T> success(String message) {
this.msg = message;
this.code = SUCCESS;
return this;
}
public static <T> StarBosResult<T> success(T data) {
StarBosResult<T> serverResponseEntity = new StarBosResult<>();
serverResponseEntity.setData(data);
serverResponseEntity.setCode(StarBosResultEnum.OK.value());
return serverResponseEntity;
}
public static <T> StarBosResult<T> success() {
StarBosResult<T> serverResponseEntity = new StarBosResult<>();
serverResponseEntity.setCode(StarBosResultEnum.OK.value());
serverResponseEntity.setMsg(StarBosResultEnum.OK.getMsg());
return serverResponseEntity;
}
public StarBosResult<T> error500(String message, T data) {
this.msg = message;
this.code = GlobalConstants.FAIL;
this.data = data;
return this;
}
public StarBosResult<T> successOk(String message, T data) {
this.msg = message;
this.code = StarBosResultEnum.OK.value();
this.data = data;
return this;
}
public StarBosResult<T> successOk( T data) {
this.code = StarBosResultEnum.OK.value();
this.data = data;
return this;
}
public boolean isSuccess() {
return Objects.equals(StarBosResultEnum.OK.value(), this.code);
}
public static <T> StarBosResult<T> fail(StarBosResultEnum starBosResultEnum) {
log.error(starBosResultEnum.toString());
StarBosResult<T> starBosResult = new StarBosResult<>();
starBosResult.setMsg(starBosResultEnum.getMsg());
starBosResult.setCode(starBosResultEnum.value());
return starBosResult;
}
public static <T> StarBosResult<T> fail(StarBosResultEnum starBosResultEnum, T data) {
log.error(starBosResultEnum.toString());
StarBosResult<T> starBosResult = new StarBosResult<>();
starBosResult.setMsg(starBosResultEnum.getMsg());
starBosResult.setCode(starBosResultEnum.value());
starBosResult.setData(data);
return starBosResult;
}
public static <T> StarBosResult<T> transform(StarBosResult<?> oldStarBosResult) {
StarBosResult<T> starBosResult = new StarBosResult<>();
starBosResult.setMsg(oldStarBosResult.getMsg());
starBosResult.setCode(oldStarBosResult.getCode());
log.error(starBosResult.toString());
return starBosResult;
}
public int getCode() {
return code;
}
}
package com.system.framework.core.response;
public enum StarBosResultEnum {
/**
* ok
*/
OK(200, "ok"),
/**
* 用于直接显示提示用户的错误,内容由输入内容决定
*/
SHOW_FAIL(1, ""),
/**
* 方法参数没有校验,内容由输入内容决定
*/
METHOD_ARGUMENT_NOT_VALID(2, ""),
/**
* 无法读取获取请求参数
*/
HTTP_MESSAGE_NOT_READABLE(3, "请求参数格式有误"),
/**
* 未授权
*/
UNAUTHORIZED(4, "Unauthorized"),
/**
* 服务器出了点小差
*/
EXCEPTION(500, "服务器出了点小差"),
/**
* 数据异常
*/
DATA_ERROR(7, "数据异常,请刷新后重新操作"),
/**
* 一些需要登录的接口,而实际上因为前端无法知道token是否已过期,导致token已失效时,
* 应该返回一个状态码,告诉前端token已经失效了,及时清理
*/
CLEAN_TOKEN(8, "clean token"),
/**
* 刷新token已过期
*/
REFRESH_TOKEN_EXIST(9, "refresh token exist"),
/**
* 数据不完整
*/
DATA_INCOMPLETE(10, "数据不完整"),
/**
* 没有查询权限
*/
REFUND_NOT_PERMISSION(3024, "refund not permission"),
/**
* 撤销失败 当前状态不允许此操作
*/
REFUND_STATUS_CHECK(03034, "refund status check"),
/**
* 04 开头代表注册登录之类的异常状态
* 社交账号未绑定,当前端看到该异常时,应该在合适的时间(比如在购买的时候跳)根据社交账号的类型,跳转到绑定系统账号的页面
*/
SOCIAL_ACCOUNT_NOT_BIND(4001, "social account not bind"),
/**
* 有些时候第三方系统授权之后,会有个临时的key,比如小程序的session_key
* 这个异常代表session_key过期,前端遇到这个问题的时候,应该再次调用社交登录的接口,刷新session_key
*/
BIZ_TEMP_SESSION_KEY_EXPIRE(4002, "biz temp session key expire"),
/**
* 账号未注册,前端看到这个状态码,弹出选择框,提示用户账号未注册,是否进入注册页面,用户选择是,进入注册页面
*/
ACCOUNT_NOT_REGISTER(4003, "account not register");
private final int code;
private final String msg;
public int value() {
return code;
}
public String getMsg() {
return msg;
}
StarBosResultEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public String toString() {
return "StarBosResultEnum{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + "} " + super.toString();
}
}
package com.system.framework.core.text;
import com.system.framework.core.utils.XstringUtils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class CharsetKit {
/** ISO-8859-1 */
public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */
public static final String UTF_8 = "UTF-8";
/** GBK */
public static final String GBK = "GBK";
/** ISO-8859-1 */
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/** UTF-8 */
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/** GBK */
public static final Charset CHARSET_GBK = Charset.forName(GBK);
/**
* 转换为Charset对象
*
* @param charset 字符集,为空则返回默认字符集
* @return Charset
*/
public static Charset charset(String charset)
{
return XstringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集,默认ISO-8859-1
* @param destCharset 目标字符集,默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, String srcCharset, String destCharset)
{
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集,默认ISO-8859-1
* @param destCharset 目标字符集,默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, Charset srcCharset, Charset destCharset)
{
if (null == srcCharset)
{
srcCharset = StandardCharsets.ISO_8859_1;
}
if (null == destCharset)
{
destCharset = StandardCharsets.UTF_8;
}
if (XstringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{
return source;
}
return new String(source.getBytes(srcCharset), destCharset);
}
/**
* @return 系统字符集编码
*/
public static String systemCharset()
{
return Charset.defaultCharset().name();
}
}
package com.system.framework.core.text;
import com.system.framework.core.utils.XstringUtils;
public class StringFormat {
public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}';
/**
* 格式化字符串<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* 例:<br>
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param strPattern 字符串模板
* @param argArray 参数列表
* @return 结果
*/
public static String format(final String strPattern, final Object... argArray)
{
if (XstringUtils.isEmpty(strPattern) || XstringUtils.isEmpty(argArray))
{
return strPattern;
}
final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0;
int delimIndex;// 占位符所在位置
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
{
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1)
{
if (handledPosition == 0)
{
return strPattern;
}
else
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString();
}
}
else
{
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
{
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
{
// 转义符之前还有一个转义符,占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
else
{
// 占位符被转义
argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1;
}
}
else
{
// 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
}
}
// 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString();
}
}
package com.system.framework.core.utils;
import net.sf.json.JSONObject;
import org.springframework.security.core.context.SecurityContextHolder;
public class AuthUtils {
private static final String id = "id";
private static final String username = "username";
// 通过请求头的Authorization jwt获取用户id
public static String getAccountId() {
JSONObject fromObject = JSONObject.fromObject(SecurityContextHolder.getContext().getAuthentication().getPrincipal());//转换数据类型
return fromObject.get(id).toString();
}
// 通过请求头的Authorization jwt获取用户账号的username
public static String getUsername() {
JSONObject fromObject = JSONObject.fromObject(SecurityContextHolder.getContext().getAuthentication().getPrincipal());//转换数据类型
return fromObject.get(username).toString();
}
}
package com.system.framework.core.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.system.framework.core.handler.IFillRuleHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
/**
* 规则值自动生成工具类
*
* @author qinfeng
* @举例: 自动生成订单号;自动生成当前日期
*/
@Slf4j
public class FillRuleUtils {
/**
* @param ruleCode ruleCode
* @return
*/
@SuppressWarnings("unchecked")
public static Object executeRule(String ruleCode, JSONObject formData) {
if (!StringUtils.isEmpty(ruleCode)) {
try {
// 获取 Service
ServiceImpl impl = (ServiceImpl) SpringContextUtils.getBean("sysFillRuleServiceImpl");
// 根据 ruleCode 查询出实体
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("rule_code", ruleCode);
JSONObject entity = JSON.parseObject(JSON.toJSONString(impl.getOne(queryWrapper)));
if (entity == null) {
log.warn("填值规则:" + ruleCode + " 不存在");
return null;
}
// 获取必要的参数
String ruleClass = entity.getString("ruleClass");
JSONObject params = entity.getJSONObject("ruleParams");
if (params == null) {
params = new JSONObject();
}
if (formData == null) {
formData = new JSONObject();
}
// 通过反射执行配置的类里的方法
IFillRuleHandler ruleHandler = (IFillRuleHandler) Class.forName(ruleClass).newInstance();
return ruleHandler.execute(params, formData);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
package com.system.framework.core.utils;
import java.security.MessageDigest;
public class MD5Util {
public static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++){
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n += 256;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname)) {
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
} else {
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
}
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
package com.system.framework.core.utils;
import cn.hutool.core.util.StrUtil;
import java.util.regex.Pattern;
/**
* 正则表达式工具
*
* @author FrozenWatermelon
*/
public class PrincipalUtil {
/**
* 以1开头,后面跟10位数
*/
public static final String MOBILE_REGEXP = "1[0-9]{10}";
/**
* 1. 用户名不能为纯数字 2. 由数字字母下划线 4-16位组成
*/
public static final String USER_NAME_REGEXP = "(?!\\d+$)([a-zA-Z0-9_]{4,16})";
/**
* 字段名,数字字母下划线
*/
public static final String FIELD_REGEXP = "([a-zA-Z0-9_]+)";
/**
* 由简单的字母数字拼接而成的字符串 不含有下划线,大写字母
*/
public static final String SIMPLE_CHAR_REGEXP = "([a-z0-9]+)";
/**
* 邮箱正则
*/
public static final String EMAIL_REGEXP = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?";
/**
* http协议正则
*/
public static final String HTTP_PROTOCOL_REGEXP = "^((http[s]{0,1})://)";
/**
* 是否是手机号
* @param value 输入值
* @return 匹配结果
*/
public static boolean isMobile(String value) {
return isMatching(MOBILE_REGEXP, value);
}
/**
* 是否是用户名
* @param value 输入值
* @return 匹配结果
*/
public static boolean isUserName(String value) {
return isMatching(USER_NAME_REGEXP, value);
}
/**
* 是否符合字段规则
* @param value 输入值
* @return 匹配结果
*/
public static boolean isField(String value) {
return !isMatching(FIELD_REGEXP, value);
}
/**
* 是否是邮箱
* @param value 输入值
* @return 匹配结果
*/
public static boolean isEmail(String value) {
return isMatching(EMAIL_REGEXP, value);
}
/**
* 是否是由简单的字母数字拼接而成的字符串
* @param value 输入值
* @return 匹配结果
*/
public static boolean isSimpleChar(String value) {
return isMatching(SIMPLE_CHAR_REGEXP, value);
}
/**
* 是否是HTTP协议
* @param value 输入值
* @return 匹配结果
*/
public static boolean isHttpProtocol(String value) {
return isFind(HTTP_PROTOCOL_REGEXP, value);
}
public static boolean isMatching(String regexp, String value) {
if (StrUtil.isBlank(value)) {
return false;
}
return Pattern.matches(regexp, value);
}
public static boolean isFind(String regexp, String value) {
if (StrUtil.isBlank(value)) {
return false;
}
Pattern pattern= Pattern.compile(regexp);
return pattern.matcher(value).find();
}
}
package com.system.framework.core.utils;
import com.system.framework.core.exception.ReflectException;
import java.lang.reflect.Field;
public class ReflectUtils {
//enum转map
public static Object getValueByFieldName(String fieldName, Object object){
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object obj = field.get(object);
return obj;
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new ReflectException("通过 " + fieldName + " 字段获取对应值失败!" + e.getMessage());
}
}
}
package com.system.framework.core.utils;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* List去除重复数据的五种方式
*/
public class RemoveRepeatDataUtil {
/**
* 1.使用LinkedHashSet删除arrayList中的重复数据
* LinkedHashSet是一个再ArrayList删除重复数据的最佳方法。
* LinkedHashSet在内部完成两件事情:
* a.删除重复数据
* b.保持添加到其中的数据的顺序
*
* @param t 入参
* @param <T> 返回数据类型
* @return array
*/
public <T> ArrayList<T> linkedHashSet(T[] t) {
ArrayList<T> arrayList = new ArrayList<>(Arrays.asList(t));
// System.out.println("源数组:" + arrayList);
LinkedHashSet<T> hashSet = new LinkedHashSet<>(arrayList);
return new ArrayList<>(hashSet);
}
/**
* 2. 使用Java8新特性stream进行List去重
* 使用stream的distinct()方法返回一个由不同数据组成的流,通过对象的equals()方法进行比较。
* 收集所有区域数据List使用Collectors.toList();
* 在不使用Set的情况下,从Java中的arrayList中删除重复项。
*
* @param t 入参
* @param <T> 返回数据类型
* @return array
*/
public <T> List<T> stream(T[] t) {
ArrayList<T> arrayList = new ArrayList<>(Arrays.asList(t));
Collector<T, ?, List<T>> collectors = Collectors.toList();
Stream<T> stream = arrayList.stream();
Stream<T> distinct = stream.distinct();
return distinct.collect(collectors);
}
/**
* 3. 利用HashSet不能添加重复数据的特性。
* 由于HashSet不能保证添加顺序,所以只能作为判断条件保证顺序。
*
* @param t 入参
* @param <T> 返回数据类型
* @return array
*/
public <T> List<T> hashSet(T[] t) {
List<T> list = new ArrayList<>(Arrays.asList(t));
HashSet<T> hashSet = new HashSet<>(list.size());
List<T> result = new ArrayList<>(list.size());
for (T value: list ) {
if(hashSet.add(value)){
result.add(value);
}
}
list.clear();
list.addAll(result);
return list;
}
/**
* 4. 利用List的contains方法循环遍历,重新排序,只添加一次数据,避免重复。
*
* @param t 入参
* @param <T> 返回数据类型
* @return array
*/
public <T> List<T> containsFor(T[] t) {
List<T> list = new ArrayList<>(Arrays.asList(t));
List<T> result = new ArrayList<>(list.size());
for (T value: list ) {
if(!result.contains(value)) {
result.add(value);
}
}
list.clear();
list.addAll(result);
return list;
}
/**
* 5.双重for循环去重
*
* @param t 入参
* @param <T> 返回数据类型
* @return array
*/
public <T> List<T> twinFor(T[] t) {
List<T> list = new ArrayList<>(Arrays.asList(t));
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.size(); j++) {
if(i != j && list.get(i) == list.get(j)){
list.remove(list.get(j));
}
}
}
return list;
}
}
package com.system.framework.core.utils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.system.framework.core.constant.GlobalConstants;
import com.system.framework.core.response.StarBosResult;
import com.system.framework.core.text.Convert;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSONObject;
import reactor.core.publisher.Mono;
public class RequestUtils {
/**
* 获取String参数
*/
public static String getParameter(String name)
{
return getRequest().getParameter(name);
}
/**
* 获取String参数
*/
public static String getParameter(String name, String defaultValue)
{
return Convert.toStr(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name)
{
return Convert.toInt(getRequest().getParameter(name));
}
/**
* 获取Integer参数
*/
public static Integer getParameterToInt(String name, Integer defaultValue)
{
return Convert.toInt(getRequest().getParameter(name), defaultValue);
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name)
{
return Convert.toBool(getRequest().getParameter(name));
}
/**
* 获取Boolean参数
*/
public static Boolean getParameterToBool(String name, Boolean defaultValue)
{
return Convert.toBool(getRequest().getParameter(name), defaultValue);
}
/**
* 获取request
*/
public static HttpServletRequest getRequest()
{
try
{
return getRequestAttributes().getRequest();
}
catch (Exception e)
{
return null;
}
}
/**
* 获取response
*/
public static HttpServletResponse getResponse()
{
try
{
return getRequestAttributes().getResponse();
}
catch (Exception e)
{
return null;
}
}
/**
* 获取session
*/
public static HttpSession getSession()
{
return getRequest().getSession();
}
public static ServletRequestAttributes getRequestAttributes()
{
try
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
}
catch (Exception e)
{
return null;
}
}
public static String getHeader(HttpServletRequest request, String name)
{
String value = request.getHeader(name);
if (XstringUtils.isEmpty(value))
{
return XstringUtils.EMPTY;
}
return urlDecode(value);
}
public static Map<String, String> getHeaders(HttpServletRequest request)
{
Map<String, String> map = new LinkedHashMap<>();
Enumeration<String> enumeration = request.getHeaderNames();
if (enumeration != null)
{
while (enumeration.hasMoreElements())
{
String key = enumeration.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
}
return map;
}
/**
* 将字符串渲染到客户端
*
* @param response 渲染对象
* @param string 待渲染的字符串
* @return null
*/
public static String renderString(HttpServletResponse response, String string)
{
try
{
response.setStatus(200);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
/**
* 是否是Ajax异步请求
*
* @param request
*/
public static boolean isAjaxRequest(HttpServletRequest request)
{
String accept = request.getHeader("accept");
if (accept != null && accept.indexOf("application/json") != -1)
{
return true;
}
String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
{
return true;
}
String uri = request.getRequestURI();
if (XstringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
{
return true;
}
String ajax = request.getParameter("__ajax");
if (XstringUtils.inStringIgnoreCase(ajax, "json", "xml"))
{
return true;
}
return false;
}
/**
* 内容编码
*
* @param str 内容
* @return 编码后的内容
*/
public static String urlEncode(String str)
{
try
{
return URLEncoder.encode(str, GlobalConstants.UTF8);
}
catch (UnsupportedEncodingException e)
{
return XstringUtils.EMPTY;
}
}
/**
* 内容解码
*
* @param str 内容
* @return 解码后的内容
*/
public static String urlDecode(String str)
{
try
{
return URLDecoder.decode(str, GlobalConstants.UTF8);
}
catch (UnsupportedEncodingException e)
{
return XstringUtils.EMPTY;
}
}
/**
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value)
{
return webFluxResponseWriter(response, HttpStatus.OK, value, StarBosResult.FAIL);
}
/**
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param code 响应状态码
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code)
{
return webFluxResponseWriter(response, HttpStatus.OK, value, code);
}
/**
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param status http状态码
* @param code 响应状态码
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code)
{
return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);
}
/**
* 设置webflux模型响应
*
* @param response ServerHttpResponse
* @param contentType content-type
* @param status http状态码
* @param code 响应状态码
* @param value 响应内容
* @return Mono<Void>
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code)
{
response.setStatusCode(status);
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
StarBosResult<?> result = StarBosResult.fail(code, value.toString());
DataBuffer dataBuffer = response.bufferFactory().wrap(JSONObject.toJSONString(result).getBytes());
return response.writeWith(Mono.just(dataBuffer));
}
}
package com.system.framework.core.utils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Component
public class SpringContextUtils implements ApplicationContextAware {
/**
* 上下文对象实例
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
/**
* 获取applicationContext
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取HttpServletRequest
*/
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
public static String getDomain(){
HttpServletRequest request = getHttpServletRequest();
StringBuffer url = request.getRequestURL();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
}
public static String getOrigin(){
HttpServletRequest request = getHttpServletRequest();
return request.getHeader("Origin");
}
/**
* 通过name获取 Bean.
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通过name,以及Clazz返回指定的Bean
*
* @param name
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
package com.system.framework.core.utils;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import com.system.framework.core.exception.StarBosException;
import javax.servlet.http.HttpServletRequest;
/**
* sql注入处理工具类
*
* @author Starbos
*/
@Slf4j
public class SqlInjectionUtils {
/**
* sign 用于表字典加签的盐值【SQL漏洞】
* (上线修改值 20200501,同步修改前端的盐值)
*/
private final static String TABLE_DICT_SIGN_SALT = "20200501";
private final static String xssStr = "'|and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|,";
/*
* 针对表字典进行额外的sign签名校验(增加安全机制)
* @param dictCode:
* @param sign:
* @param request:
* @Return: void
*/
public static void checkDictTableSign(String dictCode, String sign, HttpServletRequest request) {
//表字典SQL注入漏洞,签名校验
String accessToken = request.getHeader("X-Access-Token");
String signStr = dictCode + SqlInjectionUtils.TABLE_DICT_SIGN_SALT + accessToken;
String javaSign = SecureUtil.md5(signStr);
if (!javaSign.equals(sign)) {
log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);
throw new StarBosException("无权限访问!");
}
log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode);
}
/**
* sql注入过滤处理,遇到注入关键字抛异常
*
* @param value
* @return
*/
public static void filterContent(String value) {
if (value == null || "".equals(value)) {
return;
}
// 统一转为小写
value = value.toLowerCase();
String[] xssArr = xssStr.split("\\|");
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1) {
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
}
}
return;
}
/**
* sql注入过滤处理,遇到注入关键字抛异常
*
* @param values
* @return
*/
public static void filterContent(String[] values) {
String[] xssArr = xssStr.split("\\|");
for (String value : values) {
if (value == null || "".equals(value)) {
return;
}
// 统一转为小写
value = value.toLowerCase();
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1) {
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
}
}
}
return;
}
/**
* @特殊方法(不通用) 仅用于字典条件SQL参数,注入过滤
* @param value
* @return
*/
@Deprecated
public static void specialFilterContent(String value) {
String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|";
String[] xssArr = specialXssStr.split("\\|");
if (value == null || "".equals(value)) {
return;
}
// 统一转为小写
value = value.toLowerCase();
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
}
}
return;
}
/**
* @特殊方法(不通用) 仅用于Online报表SQL解析,注入过滤
* @param value
* @return
*/
@Deprecated
public static void specialFilterContentForOnlineReport(String value) {
String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |";
String[] xssArr = specialXssStr.split("\\|");
if (value == null || "".equals(value)) {
return;
}
// 统一转为小写
value = value.toLowerCase();
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意,值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
}
}
return;
}
}
package com.system.framework.core.utils;
import java.util.Map;
//线程共享数据工具类
public class ThreadLocalUtils {
// jdk建议将 ThreadLocal 定义为 private static ,这样就不会有弱引用,内存泄漏的问题了
private static ThreadLocal<Map> mapThreadLocal = new ThreadLocal<>();
//获取当前线程的存的变量
public static Map get() {
return mapThreadLocal.get();
}
//设置当前线程的存的变量
public static void set(Map map) {
ThreadLocalUtils.mapThreadLocal.set(map);
}
//移除当前线程的存的变量
public static void remove() {
ThreadLocalUtils.mapThreadLocal.remove();
}
}
package com.system.framework.core.utils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
/**
* 日期工具类
*/
public class XDateUtils extends org.apache.commons.lang3.time.DateUtils{
public static String YYYY = "yyyy";
public static String YYYY_MM = "yyyy-MM";
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public static Date getNowDate()
{
return new Date();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*
* @return String
*/
public static String getDate()
{
return dateTimeNow(YYYY_MM_DD);
}
public static final String getTime()
{
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static final String dateTimeNow()
{
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static final String dateTimeNow(final String format)
{
return parseDateToStr(format, new Date());
}
public static final String dateTime(final Date date)
{
return parseDateToStr(YYYY_MM_DD, date);
}
public static final String parseDateToStr(final String format, final Date date)
{
return new SimpleDateFormat(format).format(date);
}
public static final Date dateTime(final String format, final String ts)
{
try
{
return new SimpleDateFormat(format).parse(ts);
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
/**
* 日期路径 即年/月/日 如2018/08/08
*/
public static final String datePath()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年/月/日 如20180808
*/
public static final String dateTime()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate(Object str)
{
if (str == null)
{
return null;
}
try
{
return parseDate(str.toString(), parsePatterns);
}
catch (ParseException e)
{
return null;
}
}
/**
* 获取服务器启动时间
*/
public static Date getServerStartDate()
{
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算两个时间差
*/
public static String getDatePoor(Date endDate, Date nowDate)
{
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "天" + hour + "小时" + min + "分钟";
}
}
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER Inori
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /semiconductor-system
WORKDIR /semiconductor-system
EXPOSE 8090
ADD ./target/semiconductor-system.jar /semiconductor-system
CMD sleep 15;java -Djava.security.egd=file:/dev/./urandom -jar semiconductor-system.jar
\ No newline at end of file
差异被折叠。
FROM mysql:latest
MAINTAINER Inori
ENV TZ=Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY ./Api.sql /docker-entrypoint-initdb.d
\ No newline at end of file
version: '2'
services:
semiconductor-mysql:
build:
context: ./db
environment:
MYSQL_ROOT_PASSWORD: gf^*i6%&9J83&(*kJ653F&L
restart: always
container_name: semiconductor-mysql
image: semiconductor-mysql
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--max_allowed_packet=128M
ports:
- 3306:3306
semiconductor-system:
build:
context: ./
restart: always
container_name: semiconductor-system
image: semiconductor-system
ports:
- 8090:8090
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.semiconductor</groupId>
<artifactId>semiconductor</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>semiconductor-system</artifactId>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.72</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!--k3cloud-WebAPI-->
<dependency>
<groupId>webapi</groupId>
<artifactId>k3cloud-webapi-client</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${project.basedir}/src/main/resources/lib/k3cloud-webapi-client.jar</systemPath>
</dependency>
<dependency>
<groupId>com.semiconductor</groupId>
<artifactId>semiconductor-framework-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<finalName>semiconductor-system</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.5.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.system;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* @author Inori
*/
@MapperScan(value = {"com.system.dao", "com.system.quartz.dao"})
@SpringBootApplication(scanBasePackages = "com")
public class SystemApplication {
public static void main(String[] args) throws UnknownHostException {
ConfigurableApplicationContext run = SpringApplication.run(SystemApplication.class, args);
Environment env = run.getEnvironment();
String ip = InetAddress.getLocalHost().getHostAddress();
String port = env.getProperty("server.port");
System.out.println("\n----------------------------------------------------------\n\t" +
"Application starbos is running! Access URLs:\n\t" +
"Local: \t\thttp://localhost:" + port + "/\n\t" +
"External: \thttp://" + ip + ":" + port + "/\n\t" +
"Swagger-ui: \thttp://" + ip + ":" + port + "/swagger-ui.html\n\t" +
"Doc文档: \thttp://" + ip + ":" + port + "/doc.html\n" +
"----------------------------------------------------------");
}
}
package com.system.api;
import com.system.config.ThreadLocalConfig;
import kingdee.bos.json.JSONObject;
import kingdee.bos.webapi.client.ApiHttpClient;
import kingdee.bos.webapi.client.ApiRequest;
import kingdee.bos.webapi.client.ApiServiceRequest;
import org.apache.http.client.CookieStore;
import java.util.Map;
/**
* @author Inori
*/
public class KingDeeApiClient {
private String serverUrl;
private CookieStore cookieStore;
public KingDeeApiClient(String serverUrl) {
this.serverUrl = serverUrl;
}
public <T> ApiRequest<T> createRequest(String serviceName, Object[] parameters, Class<T> returnType) {
return new ApiServiceRequest<>(this.serverUrl, this.cookieStore, serviceName, parameters, returnType);
}
public <T> T execute(String serviceName, Object[] parameters, Class<T> returnType) throws Exception {
ApiRequest<T> request = this.createRequest(serviceName, parameters, returnType);
ApiHttpClient<T> httpClient = new ApiHttpClient<>();
request.setListener(httpClient);
System.out.println("------------>" + request.getServerUrl());
long start = System.currentTimeMillis();
T send = httpClient.Send(request, returnType);
long costTime = System.currentTimeMillis() - start;
Map<String, Object> map = ThreadLocalConfig.get();
map.put("costTime", costTime);
ThreadLocalConfig.set(map);
return send;
}
public Boolean login(String dbId, String userName, String password, int lcid) {
try {
Object[] loginInfo = new Object[]{dbId, userName, password, lcid};
ApiRequest<String> request = this.createRequest("Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser", loginInfo, String.class);
ApiHttpClient<String> httpClient = new ApiHttpClient<>();
request.setListener(httpClient);
String ret = httpClient.Send(request, String.class);
System.out.println(ret);
int result = (new JSONObject(ret)).getInt("LoginResultType");
if (result == 1) {
this.cookieStore = request.getCookieStore();
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
package com.system.api;
import com.system.utils.JsonUtil;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author Inori
*/
public class KingDeeK3CloudApi extends KingDeeApiClient {
public KingDeeK3CloudApi(String serverUrl) {
super(serverUrl);
}
public String excuteOperation(String formid, String opNumber, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExcuteOperation", new Object[]{formid, opNumber, data}, Object.class);
return JsonUtil.toString(execute);
}
public String save(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
public String batchSave(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.BatchSave", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
public String audit(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Audit", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
public String delete(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Delete", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
public String unAudit(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.UnAudit", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
public String submit(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Submit", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
public String view(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.View", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
public List<List<Object>> executeBillQuery(String data) throws Exception {
List execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery", new Object[]{data}, ArrayList.class);
if (CollectionUtils.isEmpty(execute)) {
execute = new ArrayList<>();
}
return execute;
}
public String draft(String formid, String data) throws Exception {
Object execute = this.execute("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Draft", new Object[]{formid, data}, Object.class);
return JsonUtil.toString(execute);
}
}
package com.system.config;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 快捷获取HttpServletRequest,HttpServletResponse
*
* @author Inori
*/
public class HttpContext {
/**
* 获取当前请求的Request对象
*
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return null;
} else {
return requestAttributes.getRequest();
}
}
/**
* 获取当前请求的Response对象
*
*/
public static HttpServletResponse getResponse() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return null;
} else {
return requestAttributes.getResponse();
}
}
}
package com.system.config;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.Map;
/**
* @author Inori
*/
public class ThreadLocalConfig {
private static ThreadLocal<Map<String, Object>> THREAD_LOCAL = new ThreadLocal<>();
public static Map<String, Object> get() {
if (CollectionUtils.isEmpty(THREAD_LOCAL.get())) {
ThreadLocalConfig.set(new HashMap<>());
}
return THREAD_LOCAL.get();
}
public static void set(Map<String, Object> map) {
THREAD_LOCAL.set(map);
}
public static void remove() {
THREAD_LOCAL.remove();
}
}
package com.system.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.system.constants.SpringContextHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/**
* @author Inori
*/
@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//创建fastJson消息转换器
FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
//创建配置类
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//过滤并修改配置返回内容
fastJsonConfig.setSerializerFeatures(
//List字段如果为null,输出为[],而非null
SerializerFeature.WriteNullListAsEmpty,
//字符类型字段如果为null,输出为"",而非null
SerializerFeature.WriteNullStringAsEmpty,
//消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
SerializerFeature.DisableCircularReferenceDetect,
//是否输出值为null的字段,默认为false。
SerializerFeature.WriteMapNullValue
);
//处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON);
fastMediaTypes.add(MediaType.parseMediaType(MediaType.TEXT_PLAIN_VALUE + ";charset=ISO-8859-1"));
fastJsonConverter.setSupportedMediaTypes(fastMediaTypes);
fastJsonConverter.setFastJsonConfig(fastJsonConfig);
converters.add(0, fastJsonConverter);
}
@Bean
public SpringContextHolder springContextHolder() {
return new SpringContextHolder();
}
}
\ No newline at end of file
package com.system.constants;
/**
* @author Inori
*/
public interface Constants {
String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
String FILE_FORMAT = "lic.tmp";
String EFFECTIVE_TIME = "effectiveTime";
String VERIFICATION_INTERVAL = "verificationInterval";
String CODE_NAME = "code";
}
package com.system.constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.dao.KingDeeCommonConfigMapper;
import com.system.transfer.kingdee.KingDeeCommonConfigListInVo;
import com.system.transfer.kingdee.KingDeeCommonConfigOneInVo;
import com.system.transfer.kingdee.KingdeeCommonConfigListOutVoRecords;
import com.system.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Inori
*/
@Component
public class KingDeeCommonPushConstants {
private Map<String, Map<String, String>> map = new ConcurrentHashMap<>();
@Autowired
private KingDeeCommonConfigMapper kingDeeCommonConfigMapper;
@PostConstruct
public void init() {
List<KingdeeCommonConfigListOutVoRecords> recordsList = kingDeeCommonConfigMapper.kingDeeCommonConfigList(new Page<>(1, 10000), new KingDeeCommonConfigListInVo(1));
for (KingdeeCommonConfigListOutVoRecords records : recordsList) {
this.map.put(records.getDocType(), this.getKingDeeCommonConfigDetail(records));
}
}
public Map<String, String> get(String formId) {
if (CollectionUtils.isEmpty(this.map)) {
return new HashMap<>(1);
}
return this.map.get(formId);
}
public void set(String docType) {
KingdeeCommonConfigListOutVoRecords records = kingDeeCommonConfigMapper.kingDeeCommonConfigOne(new KingDeeCommonConfigOneInVo("", docType, 1));
if (StringUtil.isNotNull(records)) {
this.map.remove(docType);
this.map.put(records.getDocType(), this.getKingDeeCommonConfigDetail(records));
}
}
private Map<String, String> getKingDeeCommonConfigDetail(KingdeeCommonConfigListOutVoRecords records) {
Map<String, String> result = new HashMap<>(10);
result.put("docType", records.getDocType());
result.put("sFormId", records.getSFormId());
result.put("kingDeeLogName", records.getName());
result.put("entryName", records.getEntryName());
result.put("fathersFormId", records.getFathersFormId());
result.put("fatherEntryName", records.getFatherEntryName());
result.put("pushRule", records.getPushRule());
result.put("isInTransaction", String.valueOf(records.getIsInTransaction()));
result.put("isAutoPerform", String.valueOf(records.getIsAutoPerform()));
result.put("kingDeeFiledDetail", records.getKingdeeFiledDetail());
result.put("plugInUrl", records.getPlugInUrl());
result.put("customSql", records.getCustomSql());
return result;
}
public void del(String docType) {
this.map.remove(docType);
}
}
package com.system.constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.dao.KingDeeCommonConfigMapper;
import com.system.transfer.kingdee.KingDeeCommonConfigListInVo;
import com.system.transfer.kingdee.KingDeeCommonConfigOneInVo;
import com.system.transfer.kingdee.KingdeeCommonConfigListOutVoRecords;
import com.system.utils.JsonUtil;
import com.system.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Inori
*/
@Component
public class KingDeeCommonSynConstants {
private Map<String, Map<String, String>> map = new ConcurrentHashMap<>();
@Autowired
private KingDeeCommonConfigMapper kingDeeCommonConfigMapper;
@PostConstruct
public void init() {
List<KingdeeCommonConfigListOutVoRecords> recordsList = kingDeeCommonConfigMapper.kingDeeCommonConfigList(new Page<>(1, 10000), new KingDeeCommonConfigListInVo(-1));
for (KingdeeCommonConfigListOutVoRecords records : recordsList) {
this.map.put(records.getSFormId(), this.purchaseKingDeeSyn(records));
}
}
public Map<String, String> get(String sFormId) {
return this.map.get(sFormId);
}
public Map<String, String> getKingDee(String docType) {
KingdeeCommonConfigListOutVoRecords records = kingDeeCommonConfigMapper.kingDeeCommonConfigOne(new KingDeeCommonConfigOneInVo("", docType, -1));
if (StringUtil.isNull(records)) {
return new HashMap<>(0);
}
return this.map.get(records.getSFormId());
}
public void set(String sFormId) {
KingdeeCommonConfigListOutVoRecords records = kingDeeCommonConfigMapper.kingDeeCommonConfigOne(new KingDeeCommonConfigOneInVo(sFormId, "", -1));
if (records != null) {
this.map.remove(sFormId);
this.map.put(records.getSFormId(), this.purchaseKingDeeSyn(records));
}
}
private Map<String, String> purchaseKingDeeSyn(KingdeeCommonConfigListOutVoRecords records) {
Map<String, String> temp = new HashMap<>(6);
temp.put("sFormId", records.getSFormId());
temp.put("docType", records.getDocType());
temp.put("name", records.getName());
temp.put("primaryKeyField", records.getPrimaryKeyField());
temp.put("mesEntryName", records.getMesEntryName());
temp.put("kingdeeFiledDetail", records.getKingdeeFiledDetail());
temp.put("plugInUrl", records.getPlugInUrl());
temp.put("customSql", records.getCustomSql());
return temp;
}
public void del(String formId) {
this.map.remove(formId);
}
/**
* 封装金蝶字段
*/
public static Map<String, String> purchaseKingDee(List<Map<String, String>> fieldList) {
Map<String, String> key = new LinkedHashMap<>();
for (Map<String, String> map : fieldList) {
String kingDeeField = map.get("kingdeeField");
String indexField = map.get("indexField");
if (StringUtil.isNotBlank(indexField)) {
kingDeeField = kingDeeField + "." + indexField;
}
key.put(kingDeeField, kingDeeField);
}
return key;
}
/**
* 封装第三方字段
*/
public static void purchaseIms(List<List<Object>> list, List<Map<String, String>> fieldList, Map<String, Object> map, List<Map<String, Object>> imsList) {
for (List<Object> objectList : list) {
Map<String, Object> temp = new HashMap<>(fieldList.size());
for (int i = 0; i < fieldList.size(); i++) {
//是否是明细字段
if ("true".equals(fieldList.get(i).get("isDetailField"))) {
temp.put(fieldList.get(i).get("thirdPartyField"), objectList.get(i));
} else {
map.put(fieldList.get(i).get("thirdPartyField"), objectList.get(i));
}
}
if (!CollectionUtils.isEmpty(temp)) {
imsList.add(temp);
}
}
}
/**
* 封装第三方字段
*/
public static void purchaseSqlIms(List<Object> list, List<Map<String, String>> fieldList, Map<String, Object> map) {
List<Map<String, Object>> imsList = new ArrayList<>();
for (Object object : list) {
Map<String, Object> temp = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);
Map<String, Object> request = new LinkedHashMap<>();
for (Map<String, String> temp02Map : fieldList) {
if ("true".equals(temp02Map.get("isDetailField"))) {
request.put(temp02Map.get("thirdPartyField"), temp.get(temp02Map.get("kingdeeField")));
} else {
map.put(temp02Map.get("thirdPartyField"), temp.get(temp02Map.get("kingdeeField")));
}
}
if (!CollectionUtils.isEmpty(request)) {
imsList.add(request);
}
}
map.put("children", imsList);
}
}
package com.system.constants;
/**
* @author Inori
*/
public interface KingDeeConstants {
String CODE_NAME = "resultCode";
String MSG_NAME = "resultMsg";
String SUCCESS_CODE = "0000";
String ERROR_CODE = "0002";
String OVERTIME_CODE = "0101";
String NOT_LOGGED_IN_CODE = "0010";
String DATA_NAME = "data";
}
package com.system.constants;
import com.system.utils.FileUtil;
import lombok.Data;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Inori
*/
@Data
@Component
public class RsaKeyConstant {
/**
* 公钥
*/
private String publicKey;
@PostConstruct
public void init() {
try {
ClassPathResource pubClassPath = new ClassPathResource("key/" + "publicKey.pub");
if (pubClassPath.exists()) {
InputStream inputStream = pubClassPath.getInputStream();
publicKey = FileUtil.read(inputStream);
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.system.constants;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* 静态获取spring容器中的bean
*
* @author Inori
*/
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
assertApplicationContext();
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
assertApplicationContext();
return (T) applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> requiredType) {
assertApplicationContext();
return applicationContext.getBean(requiredType);
}
private static void assertApplicationContext() {
if (SpringContextHolder.applicationContext == null) {
throw new RuntimeException("applicationContext属性为null,请检查是否注入了SpringContextHolder!");
}
}
}
package com.system.controller;
import com.system.serivce.IKingDeeCommonConfigService;
import com.system.transfer.kingdee.*;
import com.system.transfer.response.RestResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author Inori
*/
@Api(tags = "金蝶通用配置")
@RestController
@RequestMapping("/api")
public class KingDeeCommonConfigController {
@Autowired
private IKingDeeCommonConfigService kingDeeCommonConfigService;
@ApiOperation("金蝶通用配置列表")
@GetMapping("/kingdee/common/config/list")
public RestResponse kingDeeCommonConfigList(@ModelAttribute KingDeeCommonConfigListInVo inVo) {
KingdeeCommonConfigListOutVo outVo = kingDeeCommonConfigService.kingDeeCommonConfigList(inVo);
return RestResponse.success(outVo);
}
@ApiOperation("金蝶通用配置创建")
@PostMapping("/kingdee/common/config/create")
public RestResponse kingDeeCommonConfigCreate(@RequestBody KingdeeCommonConfigCreateInVo inVo) {
return kingDeeCommonConfigService.kingDeeCommonConfigCreate(inVo);
}
@ApiOperation("金蝶通用配置更新")
@PutMapping("/kingdee/common/config/update")
public RestResponse kingDeeCommonConfigUpdate(@RequestBody KingdeeCommonConfigUpdateInVo inVo) {
return kingDeeCommonConfigService.kingDeeCommonConfigUpdate(inVo);
}
@ApiOperation("金蝶通用配置删除")
@DeleteMapping("/kingdee/common/config/delete")
public RestResponse kingDeeCommonConfigDelete(@ModelAttribute KingdeeCommonConfigDeleteInVo inVo) {
return kingDeeCommonConfigService.kingDeeCommonConfigDelete(inVo);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论