From a865ed59c2ac30c9ac93c1281143c0c67e459981 Mon Sep 17 00:00:00 2001 From: Yen Date: Tue, 27 Sep 2022 17:52:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/qs/cost/Application.java | 42 ++ .../com/qs/cost/common/conf/CacheConfig.java | 19 + .../qs/cost/common/conf/JacksonConfig.java | 28 + .../common/conf/MainServerProperties.java | 27 + .../qs/cost/common/conf/MyBatisConfig.java | 40 ++ .../qs/cost/common/conf/SpringMvcConfig.java | 47 ++ .../qs/cost/common/consts/ApiUrlConst.java | 50 ++ .../com/qs/cost/common/dto/BeanParams.java | 17 + .../com/qs/cost/common/dto/HttpResult.java | 30 ++ .../java/com/qs/cost/common/dto/PageVo.java | 45 ++ src/main/java/com/qs/cost/common/dto/R.java | 105 ++++ .../qs/cost/common/dto/u8/U8CallbackVo.java | 51 ++ .../qs/cost/common/dto/u8/U8RequestBo.java | 74 +++ .../com/qs/cost/common/enums/HttpCode.java | 32 ++ .../framework/exception/BaseException.java | 17 + .../exception/BusinessException.java | 27 + .../exception/UnifiedExceptionHandler.java | 90 ++++ .../interceptor/ForbiddenInterceptor.java | 31 ++ .../framework/mvc/CustomizationBean.java | 21 + .../mvc/HttpServletRequestFilter.java | 161 ++++++ .../java/com/qs/cost/common/utils/Assert.java | 20 + .../qs/cost/common/utils/BeanCopierUtil.java | 93 ++++ .../qs/cost/common/utils/CollectionUtil.java | 131 +++++ .../com/qs/cost/common/utils/DateUtil.java | 194 +++++++ .../com/qs/cost/common/utils/HttpService.java | 479 ++++++++++++++++++ .../com/qs/cost/common/utils/HttpUtil.java | 121 +++++ .../java/com/qs/cost/common/utils/IdUtil.java | 16 + .../com/qs/cost/common/utils/IdWorker.java | 155 ++++++ .../com/qs/cost/common/utils/JsonUtil.java | 83 +++ .../com/qs/cost/common/utils/SecureUtil.java | 47 ++ .../com/qs/cost/common/utils/ServletUtil.java | 123 +++++ .../cost/common/utils/StringCreateUtil.java | 132 +++++ .../com/qs/cost/common/utils/StringUtil.java | 20 + .../qs/cost/common/utils/model/DesUtils.java | 126 +++++ .../module/controller/LzOrderController.java | 24 + .../qs/cost/module/domain/VmSupplierPo.java | 64 +++ .../qs/cost/module/domain/dto/U8Vendor.java | 39 ++ .../cost/module/mapper/VmSupplierMapper.java | 13 + .../module/service/VmSupplierService.java | 59 +++ src/main/resources/application-dev.yml | 34 ++ src/main/resources/application.yml | 3 + src/main/resources/logback-spring.xml | 51 ++ 42 files changed, 2981 insertions(+) create mode 100644 src/main/java/com/qs/cost/Application.java create mode 100644 src/main/java/com/qs/cost/common/conf/CacheConfig.java create mode 100644 src/main/java/com/qs/cost/common/conf/JacksonConfig.java create mode 100644 src/main/java/com/qs/cost/common/conf/MainServerProperties.java create mode 100644 src/main/java/com/qs/cost/common/conf/MyBatisConfig.java create mode 100644 src/main/java/com/qs/cost/common/conf/SpringMvcConfig.java create mode 100644 src/main/java/com/qs/cost/common/consts/ApiUrlConst.java create mode 100644 src/main/java/com/qs/cost/common/dto/BeanParams.java create mode 100644 src/main/java/com/qs/cost/common/dto/HttpResult.java create mode 100644 src/main/java/com/qs/cost/common/dto/PageVo.java create mode 100644 src/main/java/com/qs/cost/common/dto/R.java create mode 100644 src/main/java/com/qs/cost/common/dto/u8/U8CallbackVo.java create mode 100644 src/main/java/com/qs/cost/common/dto/u8/U8RequestBo.java create mode 100644 src/main/java/com/qs/cost/common/enums/HttpCode.java create mode 100644 src/main/java/com/qs/cost/common/framework/exception/BaseException.java create mode 100644 src/main/java/com/qs/cost/common/framework/exception/BusinessException.java create mode 100644 src/main/java/com/qs/cost/common/framework/exception/UnifiedExceptionHandler.java create mode 100644 src/main/java/com/qs/cost/common/framework/interceptor/ForbiddenInterceptor.java create mode 100644 src/main/java/com/qs/cost/common/framework/mvc/CustomizationBean.java create mode 100644 src/main/java/com/qs/cost/common/framework/mvc/HttpServletRequestFilter.java create mode 100644 src/main/java/com/qs/cost/common/utils/Assert.java create mode 100644 src/main/java/com/qs/cost/common/utils/BeanCopierUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/CollectionUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/DateUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/HttpService.java create mode 100644 src/main/java/com/qs/cost/common/utils/HttpUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/IdUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/IdWorker.java create mode 100644 src/main/java/com/qs/cost/common/utils/JsonUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/SecureUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/ServletUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/StringCreateUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/StringUtil.java create mode 100644 src/main/java/com/qs/cost/common/utils/model/DesUtils.java create mode 100644 src/main/java/com/qs/cost/module/controller/LzOrderController.java create mode 100644 src/main/java/com/qs/cost/module/domain/VmSupplierPo.java create mode 100644 src/main/java/com/qs/cost/module/domain/dto/U8Vendor.java create mode 100644 src/main/java/com/qs/cost/module/mapper/VmSupplierMapper.java create mode 100644 src/main/java/com/qs/cost/module/service/VmSupplierService.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/logback-spring.xml diff --git a/src/main/java/com/qs/cost/Application.java b/src/main/java/com/qs/cost/Application.java new file mode 100644 index 0000000..44d7ca0 --- /dev/null +++ b/src/main/java/com/qs/cost/Application.java @@ -0,0 +1,42 @@ +package com.qs.cost; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import java.util.TimeZone; + +/** + * @author USER + */ +@EnableScheduling +@EnableTransactionManagement +@SpringBootApplication +public class Application extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(Application.class,args); + } + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + super.onStartup(servletContext); + } + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { + return builder.sources(Application.class); + } + + @PostConstruct + void started() { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); + } + +} diff --git a/src/main/java/com/qs/cost/common/conf/CacheConfig.java b/src/main/java/com/qs/cost/common/conf/CacheConfig.java new file mode 100644 index 0000000..85305e8 --- /dev/null +++ b/src/main/java/com/qs/cost/common/conf/CacheConfig.java @@ -0,0 +1,19 @@ +package com.qs.cost.common.conf; + +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@EnableCaching +@Configuration +public class CacheConfig { + + @Bean + public ConcurrentMapCacheManager cacheManager() { + ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); + //cacheManager.setStoreByValue(true); //true表示缓存一份副本,否则缓存引用 + return cacheManager; + } + +} diff --git a/src/main/java/com/qs/cost/common/conf/JacksonConfig.java b/src/main/java/com/qs/cost/common/conf/JacksonConfig.java new file mode 100644 index 0000000..0f465d5 --- /dev/null +++ b/src/main/java/com/qs/cost/common/conf/JacksonConfig.java @@ -0,0 +1,28 @@ +package com.qs.cost.common.conf; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +/** + * @Author: YenHex + * @Date: 2021/3/11 + * @Version: 1.0 + **/ +@Slf4j +@Configuration +public class JacksonConfig { + @Bean + @Primary + @ConditionalOnMissingBean(ObjectMapper.class) + public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { + ObjectMapper objectMapper = builder.createXmlMapper(false).build(); + objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); + return objectMapper; + } +} diff --git a/src/main/java/com/qs/cost/common/conf/MainServerProperties.java b/src/main/java/com/qs/cost/common/conf/MainServerProperties.java new file mode 100644 index 0000000..61059fe --- /dev/null +++ b/src/main/java/com/qs/cost/common/conf/MainServerProperties.java @@ -0,0 +1,27 @@ +package com.qs.cost.common.conf; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @author YenHex + * @since 2022/7/7 + */ + +@Getter +@Setter +@Component +@ConfigurationProperties(prefix = "server") +public class MainServerProperties { + + private String host; + + private String book; + + private String year; + + private String u8url; + +} diff --git a/src/main/java/com/qs/cost/common/conf/MyBatisConfig.java b/src/main/java/com/qs/cost/common/conf/MyBatisConfig.java new file mode 100644 index 0000000..a03ad09 --- /dev/null +++ b/src/main/java/com/qs/cost/common/conf/MyBatisConfig.java @@ -0,0 +1,40 @@ +package com.qs.cost.common.conf; + +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; +import lombok.extern.slf4j.Slf4j; +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: YenHex + * @Date: 2021/3/4 + * @Version: 1.0 + **/ +@Slf4j +@Configuration +@EnableTransactionManagement +@MapperScan({ + "com.qs.cost.module.mapper", +}) +public class MyBatisConfig { + + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 添加防止全表更新与删除拦截器 + interceptor.addInnerInterceptor(blockAttackInnerInterceptor()); + return interceptor; + } + + public BlockAttackInnerInterceptor blockAttackInnerInterceptor(){ + BlockAttackInnerInterceptor blockAttackInnerInterceptor=new BlockAttackInnerInterceptor(); + return blockAttackInnerInterceptor; + } + + +} diff --git a/src/main/java/com/qs/cost/common/conf/SpringMvcConfig.java b/src/main/java/com/qs/cost/common/conf/SpringMvcConfig.java new file mode 100644 index 0000000..d4272d9 --- /dev/null +++ b/src/main/java/com/qs/cost/common/conf/SpringMvcConfig.java @@ -0,0 +1,47 @@ +package com.qs.cost.common.conf; + +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @author YenHex + * @since 2022/2/24 + */ +@AllArgsConstructor +@Configuration(proxyBeanMethods = false) +public class SpringMvcConfig implements WebMvcConfigurer { + + + @Bean + public CorsFilter corsFilter() { + final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); + final CorsConfiguration corsConfiguration = new CorsConfiguration(); + /*是否允许请求带有验证信息*/ + corsConfiguration.setAllowCredentials(false); + /*允许访问的客户端域名*/ + corsConfiguration.addAllowedOrigin("*"); + /*允许服务端访问的客户端请求头*/ + corsConfiguration.addAllowedHeader("*"); + /*允许访问的方法名,GET POST等*/ + corsConfiguration.addAllowedMethod("*"); + urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); + return new CorsFilter(urlBasedCorsConfigurationSource); + } + + //@Bean + public MultipartResolver multipartResolver(){ + CommonsMultipartResolver resolver = new CommonsMultipartResolver(); + resolver.setMaxInMemorySize(5120); + resolver.setMaxInMemorySize(300 * 1024 * 1024); + resolver.setDefaultEncoding("UTF-8"); + return resolver; + } + +} diff --git a/src/main/java/com/qs/cost/common/consts/ApiUrlConst.java b/src/main/java/com/qs/cost/common/consts/ApiUrlConst.java new file mode 100644 index 0000000..0392acb --- /dev/null +++ b/src/main/java/com/qs/cost/common/consts/ApiUrlConst.java @@ -0,0 +1,50 @@ +package com.qs.cost.common.consts; + +/** + * ERP API地址 + * @Author: YenHex + * @Date: 2021/3/12 + * @Version: 1.0 + **/ +public class ApiUrlConst { + + public static final String lzyunli = "lzyunli"; + + public static final String U8API = "/Service/13Service.asmx/U8API"; + + /** + * 删除专业发票 + */ + public static final String GET_ORDER = "https://sc.gdjiajin.com/index.php/getOrder"; + + /** + * 删除普通发票 + */ + public static final String UPD_ORDER = "https://sc.gdjiajin.com/index.php/upOrder"; + + /** + * 添加销售订单 + */ + public static final String U8_ADD_XSDD = "XSDDAdd"; + + /** + * 添加销售报价单 + */ + public static final String U8_ADD_XSBJ = "XSBJDAdd"; + + /** + * 添加专业发票 + */ + public static final String U8_ADD_ZYFP = "ZYFPAdd"; + + /** + * 添加普通发票 + */ + public static final String U8_ADD_PTFP = "PTFPAdd"; + + /** + * 获取销售订单编码 + */ + public static final String U8_GET_XSDD_CODE = "GETXSDDCODE"; + +} diff --git a/src/main/java/com/qs/cost/common/dto/BeanParams.java b/src/main/java/com/qs/cost/common/dto/BeanParams.java new file mode 100644 index 0000000..ad340d4 --- /dev/null +++ b/src/main/java/com/qs/cost/common/dto/BeanParams.java @@ -0,0 +1,17 @@ +package com.qs.cost.common.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * @author YenHex + * @since 2022/2/25 + */ +@Getter +@Setter +@AllArgsConstructor +public class BeanParams{ + private String json; + private String keyId; +} diff --git a/src/main/java/com/qs/cost/common/dto/HttpResult.java b/src/main/java/com/qs/cost/common/dto/HttpResult.java new file mode 100644 index 0000000..b9340ad --- /dev/null +++ b/src/main/java/com/qs/cost/common/dto/HttpResult.java @@ -0,0 +1,30 @@ +package com.qs.cost.common.dto; + +import lombok.Data; + +/** + * 对请求结果统一封装 + * @author YenHex + * @since 2022/2/25 + */ +@Data +public class HttpResult { + + public HttpResult(Integer code,String message){ + this.message = message; + this.code = code; + } + + public HttpResult(Integer code,String message,String data){ + this.data = data; + this.message = message; + this.code = code; + } + + private String message; + + private Integer code; + + private String data; + +} diff --git a/src/main/java/com/qs/cost/common/dto/PageVo.java b/src/main/java/com/qs/cost/common/dto/PageVo.java new file mode 100644 index 0000000..821292f --- /dev/null +++ b/src/main/java/com/qs/cost/common/dto/PageVo.java @@ -0,0 +1,45 @@ +package com.qs.cost.common.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Date; +import java.util.List; + +@Getter +@Setter +public class PageVo{ + + /** + * 页幅 + */ + private Integer pageSize; + + /** + * 页眉 + */ + private Integer pageNum; + + /** + * 总数据数 + */ + private Integer total; + + /** + * 总页数 + */ + private Integer totalPage; + + /** + * 数据列表 + */ + private List list; + + public void initPageNum(Integer total,Integer pageSize,Integer pageNum){ + this.pageNum = pageNum; + this.pageSize = pageSize; + if(pageSize==null||pageSize==0){ return; } + this.totalPage = total%pageSize==0?total/pageSize:(total/pageSize+1); + } + +} diff --git a/src/main/java/com/qs/cost/common/dto/R.java b/src/main/java/com/qs/cost/common/dto/R.java new file mode 100644 index 0000000..6cbb807 --- /dev/null +++ b/src/main/java/com/qs/cost/common/dto/R.java @@ -0,0 +1,105 @@ +package com.qs.cost.common.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 统一返回封装 + * 1.替代旧版的ViewResult + * 2.支持SmartDoc + * @author JcYen + * @date 2021/4/22 + * @version 2.0 + */ +@Getter +@Setter +public class R{ + + public R( int status, String message) { + this.status = status; + this.message = message; + } + + public R( int status, String message, T data) { + this.status = status; + this.message = message; + this.data = data; + } + + /** + * 状态码 + */ + private Integer status; + + /** + * 信息 + */ + private String message; + + /** + * 数据 + */ + private T data; + + public static final int SUCCESS_STATUS = 200; + public static final int LOGOUT_STATUS = 401; + public static final int FORBIDDEN_STATUS = 403; + public static final int NOT_FOUND_STATUS = 434; + public static final int FAILED_STATUS = 500; + + public static final String SUCCESS_TIPS = "操作成功"; + public static final String FAILED_TIPS = "操作失败"; + public static final String LOGOUT_TIPS = "登录无效"; + public static final String FORBIDDEN_TIPS = "无权限访问"; + public static final String NOT_FOUND_TIPS = "数据不存在或被移除"; + + public static R ok() { + return new R(SUCCESS_STATUS,SUCCESS_TIPS,null); + } + + public static R ok(String msg) { + return new R<>(SUCCESS_STATUS,msg,null); + } + + public static R ok(TYPE data) { + return new R<>(SUCCESS_STATUS,SUCCESS_TIPS,data); + } + + public static R ok(TYPE data,String message) { + return new R<>(SUCCESS_STATUS,message,data); + } + + public static R isTrue(Boolean bool){ + if(bool==null|| !bool){ + return error(); + } + return ok(); + } + + public R isTrue(Boolean bool, String message){ + if(bool==null|| !bool){ + return error(message); + } + return ok(null,message); + } + + + public static R isNotNull(TYPE object){ + if(object==null){ + return error(); + } + return ok(object,SUCCESS_TIPS); + } + + public static R error(String message) { + return new R<>(FAILED_STATUS,message,null); + } + + public static R error() { + return new R<>(FAILED_STATUS,FAILED_TIPS,null); + } + + +} diff --git a/src/main/java/com/qs/cost/common/dto/u8/U8CallbackVo.java b/src/main/java/com/qs/cost/common/dto/u8/U8CallbackVo.java new file mode 100644 index 0000000..41d559f --- /dev/null +++ b/src/main/java/com/qs/cost/common/dto/u8/U8CallbackVo.java @@ -0,0 +1,51 @@ +package com.qs.cost.common.dto.u8; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; + +/** + * 请求记录历史 实体类 + * @author YenHex + * @since 2022-02-28 + */ +@Data +public class U8CallbackVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** id */ + @TableId(type = IdType.INPUT) + private String id; + + /** 账套、租户 */ + private String tenant; + + /** 客户端IP */ + private String clientHost; + + /** 接口名称 */ + private String apiCmd; + + /** 接口数据主键 */ + private String apiPk; + + /** 接口年份 */ + private String apiYear; + + /** 接口keyId */ + private String apiKeyId; + + /** 请求参数 */ + private String reqParams; + + + /** 数据返回结果 */ + private String respContext; + + + +} + diff --git a/src/main/java/com/qs/cost/common/dto/u8/U8RequestBo.java b/src/main/java/com/qs/cost/common/dto/u8/U8RequestBo.java new file mode 100644 index 0000000..4b17724 --- /dev/null +++ b/src/main/java/com/qs/cost/common/dto/u8/U8RequestBo.java @@ -0,0 +1,74 @@ +package com.qs.cost.common.dto.u8; + +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +/** + * @author YenHex + * @since 2022/2/25 + */ +@Data +public class U8RequestBo { + + /** + * 业务主键ID + *

用于记录,便于维护查询

+ *

实例:订单号,订单id

+ */ + private String pk; + + /** + * U8业务请求命令 + */ + @NotNull + private String cmd; + + /** + * 年度 + */ + @NotNull(message = "年度不能为空") + private String year; + + /** + * 账套 + */ + @NotNull(message = "账套不能为空") + private String book; + + /** + * 请求json字符串 + */ + @NotNull(message = "请求json字符串不能为空") + private String jsonBody; + + /** + * 暂无意义 + */ + private String keyId; + + /** + * 设置失败重连次数 + */ + @Max(value = 10,message = "重连次数不能超过10次") + @Min(value = 1,message = "重连次数不能少于1次") + private Integer settingRetryTimes; + + /** + * 是否回调(0-否;1-是) + */ + private String callbackState; + + /** + * 回调地址(callbackState=1时,不能为空) + */ + private String callbackHost; + + /** + * 立马运行(默认false) + */ + private Boolean immediatelyRun; + +} diff --git a/src/main/java/com/qs/cost/common/enums/HttpCode.java b/src/main/java/com/qs/cost/common/enums/HttpCode.java new file mode 100644 index 0000000..7a4761e --- /dev/null +++ b/src/main/java/com/qs/cost/common/enums/HttpCode.java @@ -0,0 +1,32 @@ +package com.qs.cost.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 请求状态码 + * @author YenHex + * @since 2022/2/28 + */ +@Getter +@AllArgsConstructor +public enum HttpCode { + + /** 基本参数 */ + SUCCESS(200,"操作成功"), + ERROR(200,"操作失败"), + ERROR_CALLBACK_URL_EMPTY(200,"回调地址为空"), + + /** 资源权限相关 */ + FORBIDDEN_403(403,"无权访问"), + FORBIDDEN_403_1(403,"账套未注册,无权访问"), + FORBIDDEN_403_2(403,"IP地址未注册,无权访问"), + + FORBIDDEN_404(404,"资源不存在或被移除"), + + ; + + Integer code; + String msg; + +} diff --git a/src/main/java/com/qs/cost/common/framework/exception/BaseException.java b/src/main/java/com/qs/cost/common/framework/exception/BaseException.java new file mode 100644 index 0000000..1f11d1f --- /dev/null +++ b/src/main/java/com/qs/cost/common/framework/exception/BaseException.java @@ -0,0 +1,17 @@ +package com.qs.cost.common.framework.exception; + +/** + * @author JcYen + * @Date 2020/6/11 + * @Version 1.0 + */ +public abstract class BaseException extends RuntimeException { + + public BaseException(String message){ + super(message); + } + + public abstract int getCode(); + + +} diff --git a/src/main/java/com/qs/cost/common/framework/exception/BusinessException.java b/src/main/java/com/qs/cost/common/framework/exception/BusinessException.java new file mode 100644 index 0000000..bd5a1ee --- /dev/null +++ b/src/main/java/com/qs/cost/common/framework/exception/BusinessException.java @@ -0,0 +1,27 @@ +package com.qs.cost.common.framework.exception; + +import lombok.Getter; + +import java.io.Serializable; + +/** + * @author JcYen + * @Date 2020/6/11 + * @Version 1.0 + */ +public class BusinessException extends BaseException implements Serializable { + + private static final long serialVersionUID = 1L; + + private Integer status; + + public BusinessException(String message,Integer status) { + super(message); + this.status = status; + } + + @Override + public int getCode() { + return status; + } +} diff --git a/src/main/java/com/qs/cost/common/framework/exception/UnifiedExceptionHandler.java b/src/main/java/com/qs/cost/common/framework/exception/UnifiedExceptionHandler.java new file mode 100644 index 0000000..ae3d6d4 --- /dev/null +++ b/src/main/java/com/qs/cost/common/framework/exception/UnifiedExceptionHandler.java @@ -0,0 +1,90 @@ +package com.qs.cost.common.framework.exception; + +import com.qs.cost.common.dto.R; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.ConversionNotSupportedException; +import org.springframework.beans.TypeMismatchException; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindException; +import org.springframework.validation.ObjectError; +import org.springframework.web.HttpMediaTypeNotAcceptableException; +import org.springframework.web.HttpMediaTypeNotSupportedException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingPathVariableException; +import org.springframework.web.bind.MissingServletRequestParameterException; +import org.springframework.web.bind.ServletRequestBindingException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.async.AsyncRequestTimeoutException; +import org.springframework.web.multipart.support.MissingServletRequestPartException; +import org.springframework.web.servlet.NoHandlerFoundException; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author JcYen + * @Date 2019/6/7 + * @Version 1.0 + */ +@Slf4j +@Component +@ControllerAdvice +public class UnifiedExceptionHandler { + + @ExceptionHandler(value = BindException.class) + @ResponseBody + public R handleBindException(BindException e) { + log.warn("参数绑定异常", e); + return R.error(); + } + + @ExceptionHandler(value = BusinessException.class) + @ResponseBody + public R handleBindException(BusinessException e) { + return new R(e.getCode(),e.getMessage()); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseBody + public R handleValidException(MethodArgumentNotValidException e) { + StringBuilder sb = new StringBuilder(); + List allErrors = e.getBindingResult().getAllErrors(); + String message = allErrors.stream().map(s -> s.getDefaultMessage()).collect(Collectors.joining(";")); + log.warn("参数校验异常:{}",message); + return R.error(); + } + + @ExceptionHandler({ + NoHandlerFoundException.class, + HttpRequestMethodNotSupportedException.class, + HttpMediaTypeNotSupportedException.class, + MissingPathVariableException.class, + MissingServletRequestParameterException.class, + TypeMismatchException.class, + HttpMessageNotReadableException.class, + HttpMessageNotWritableException.class, + HttpMediaTypeNotAcceptableException.class, + ServletRequestBindingException.class, + ConversionNotSupportedException.class, + MissingServletRequestPartException.class, + AsyncRequestTimeoutException.class + }) + @ResponseBody + public R handleServletException(Exception e) { + log.error("Servlet异常\n异常类型:{}\n异常信息:{}\n异常体:",e.getClass().getSimpleName(),e.getMessage(),e); + return R.error(); + } + + + @ExceptionHandler(value = Exception.class) + @ResponseBody + public R handleException(Exception e) { + log.error("Servlet异常\n异常类型:{}\n异常信息:{}\n异常体:",e.getClass().getSimpleName(),e.getMessage(),e); + return R.error(); + } +} diff --git a/src/main/java/com/qs/cost/common/framework/interceptor/ForbiddenInterceptor.java b/src/main/java/com/qs/cost/common/framework/interceptor/ForbiddenInterceptor.java new file mode 100644 index 0000000..e4820c8 --- /dev/null +++ b/src/main/java/com/qs/cost/common/framework/interceptor/ForbiddenInterceptor.java @@ -0,0 +1,31 @@ +package com.qs.cost.common.framework.interceptor; + + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.servlet.HandlerInterceptor; + +import java.io.IOException; +import java.io.PrintWriter; + + +/** + * @author JcYen + * @Date 2020/6/11 + * @Version 1.0 + */ +public class ForbiddenInterceptor implements HandlerInterceptor { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + try { + PrintWriter printWriter = response.getWriter(); + printWriter.println("{\"status\":403,\"message\":\"403 forbidden\"}"); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + +} diff --git a/src/main/java/com/qs/cost/common/framework/mvc/CustomizationBean.java b/src/main/java/com/qs/cost/common/framework/mvc/CustomizationBean.java new file mode 100644 index 0000000..2445fd4 --- /dev/null +++ b/src/main/java/com/qs/cost/common/framework/mvc/CustomizationBean.java @@ -0,0 +1,21 @@ +package com.qs.cost.common.framework.mvc; + +import io.undertow.server.DefaultByteBufferPool; +import io.undertow.websockets.jsr.WebSocketDeploymentInfo; +import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.stereotype.Component; + +@Component +public class CustomizationBean implements WebServerFactoryCustomizer { + + @Override + public void customize(UndertowServletWebServerFactory factory) { + factory.addDeploymentInfoCustomizers(deploymentInfo -> { + WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo(); + webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 1024)); + deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo); + }); + } + +} diff --git a/src/main/java/com/qs/cost/common/framework/mvc/HttpServletRequestFilter.java b/src/main/java/com/qs/cost/common/framework/mvc/HttpServletRequestFilter.java new file mode 100644 index 0000000..a9a1c39 --- /dev/null +++ b/src/main/java/com/qs/cost/common/framework/mvc/HttpServletRequestFilter.java @@ -0,0 +1,161 @@ +package com.qs.cost.common.framework.mvc; + +import com.qs.cost.common.utils.DateUtil; +import com.qs.cost.common.utils.ServletUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +/** + * HttpServletRequest 过滤器 + * 解决: request.getInputStream()只能读取一次的问题 + * 目标: 流可重复读 + * @Author YenHex + * @Date 2021/4/9 + * @Version: 1.0 + **/ +@Slf4j +@Component +@WebFilter(filterName = "HttpServletRequestFilter", urlPatterns = "/") +@Order(10000) +public class HttpServletRequestFilter implements Filter{ + + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + RequestWrapper requestWrapper = null; + if(servletRequest instanceof HttpServletRequest) { + requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest); + } + //servletResponse.setContentType("allowedOriginPatterns"); + long startTime = System.currentTimeMillis(); + //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中 + // 在chain.doFiler方法中传递新的request对象 + if(null == requestWrapper) { + filterChain.doFilter(servletRequest, servletResponse); + } else { + filterChain.doFilter(requestWrapper, servletResponse); + } + long endTime = System.currentTimeMillis(); + double diffTime = DateUtil.printRunTime(startTime,endTime); + assert servletRequest instanceof HttpServletRequest; + HttpServletRequest request = (HttpServletRequest)servletRequest; + //String tenant = request.getHeader("tenant"); + //String authorization = request.getHeader("Authorization"); + String url = request.getRequestURL().toString(); + String method = request.getMethod(); + String queryStr = request.getQueryString(); + String ip = request.getRemoteHost(); + //HttpSession session = request.getSession(); + //session.removeAttribute("JSESSIONID"); + //String sessionId = session.getId(); + String reqBody = ""; + if (ServletUtil.isJsonRequest(request)) { + reqBody = requestWrapper.getBody(); + } + //String host = request.getRemoteHost(); + //String servletPath = request.getServletPath(); + StringBuffer buffer = new StringBuffer("["+method+"] "+url + " IP: "+ip); + if(!StringUtils.isEmpty(queryStr)){ + buffer.append("\n参数: "+queryStr); + } + if(!StringUtils.isEmpty(reqBody)){ + buffer.append("\n请求体: "+reqBody); + } + buffer.append("\n耗时: "+diffTime+"秒"); + if(diffTime>4){ + log.warn("访问速度:{}秒,接口:{},参数:{},请求体:{}",diffTime,"["+method+"] "+url,queryStr,reqBody); + } + //buffer.append("\n耗时: "+diffTime+"秒 Session:"+sessionId); + System.out.println(buffer.toString()); + } + + @Override + public void destroy() { + + } + + /*** + * HttpServletRequest 包装器 + * 解决: request.getInputStream()只能读取一次的问题 + * 目标: 流可重复读 + */ + public class RequestWrapper extends HttpServletRequestWrapper { + + /** + * 请求体 + */ + private String mBody; + + public RequestWrapper(HttpServletRequest request) { + super(request); + mBody = getBody(request); + } + + /** + * 获取请求体 + * @param request 请求 + * @return 请求体 + */ + private String getBody(HttpServletRequest request) { + return ServletUtil.getBodyString(request); + } + + /** + * 获取请求体 + * @return 请求体 + */ + public String getBody() { + return mBody; + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException { + // 创建字节数组输入流 + final ByteArrayInputStream bais = new ByteArrayInputStream(mBody.getBytes(StandardCharsets.UTF_8)); + + return new ServletInputStream() { + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + } + + @Override + public int read() throws IOException { + return bais.read(); + } + }; + } + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/Assert.java b/src/main/java/com/qs/cost/common/utils/Assert.java new file mode 100644 index 0000000..cd56e61 --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/Assert.java @@ -0,0 +1,20 @@ +package com.qs.cost.common.utils; + +import com.qs.cost.common.enums.HttpCode; +import com.qs.cost.common.framework.exception.BusinessException; + +/** + * @author YenHex + * @since 2022/2/25 + */ +public class Assert { + + public static void throwEx(Integer code,String msg){ + throw new BusinessException(msg, code); + } + + public static void throwEx(HttpCode httpCode){ + throw new BusinessException(httpCode.getMsg(),httpCode.getCode()); + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/BeanCopierUtil.java b/src/main/java/com/qs/cost/common/utils/BeanCopierUtil.java new file mode 100644 index 0000000..f59ac50 --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/BeanCopierUtil.java @@ -0,0 +1,93 @@ +package com.qs.cost.common.utils; + +import org.springframework.cglib.beans.BeanCopier; + +import java.io.*; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 取代BeanUtils.CP + * @Author JcYen + * @Date 2019/6/3 + * @Version 1.0 + */ +public class BeanCopierUtil { + + private static final Map BEAN_COPIERS = new ConcurrentHashMap(); + + private static String genKey(Class source, Class target) { + return source.getName() + target.getName(); + } + + /** + * target字段值,会被source字段值覆盖(包括null) + * @param source + * @param target + */ + public static T copy(Object source, T target) { + String key = genKey(source.getClass(), target.getClass()); + BeanCopier copier; + if (!BEAN_COPIERS.containsKey(key)) { + copier = BeanCopier.create(source.getClass(), target.getClass(), false); + BEAN_COPIERS.put(key, copier); + } else { + copier = BEAN_COPIERS.get(key); + } + copier.copy(source, target, null); + return target; + } + + + /** + * 采用对象的序列化完成对象的深克隆 + * @param obj 待克隆的对象 + * @return + */ + @SuppressWarnings("unchecked") + public static T cloneObject(T obj) { + T cloneObj = null; + try { + // 写入字节流 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream obs = new ObjectOutputStream(out); + obs.writeObject(obj); + obs.close(); + + // 分配内存,写入原始对象,生成新对象 + ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(ios); + // 返回生成的新对象 + cloneObj = (T) ois.readObject(); + ois.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return cloneObj; + } + + /** + * 利用序列化完成集合的深克隆 + * + * @param collection 待克隆的集合 + * @return + * @throws ClassNotFoundException + * @throws IOException + */ + @SuppressWarnings("unchecked") + public static Collection cloneCollection(Collection collection) throws ClassNotFoundException, IOException{ + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(byteOut); + out.writeObject(collection); + out.close(); + + ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); + ObjectInputStream in = new ObjectInputStream(byteIn); + Collection dest = (Collection) in.readObject(); + in.close(); + + return dest; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/CollectionUtil.java b/src/main/java/com/qs/cost/common/utils/CollectionUtil.java new file mode 100644 index 0000000..3976efd --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/CollectionUtil.java @@ -0,0 +1,131 @@ +package com.qs.cost.common.utils; + +import java.util.*; + +/** + * 常用数据工具类 + * + * @Author JcYen + * @Date 2019/5/23 + * @Version 1.0 + */ +public class CollectionUtil { + + private CollectionUtil() { + super(); + } + + /** + * 判断一个集合是否为空 + */ + public static boolean isEmpty(Collection col) { + if (col == null || col.isEmpty()) { + return true; + } + return false; + } + + public static List setToList(Set colSet){ + if (colSet == null || colSet.isEmpty()){ + return new ArrayList<>(); + } + List rs = new ArrayList<>(colSet); + return rs; + } + + /** + * 判断一个集合是否不为空 + */ + public static boolean isNotEmpty(Collection col) { + return !isEmpty(col); + } + + /** + * 判断Map是否为空 + */ + public static boolean isEmpty(Map map) { + if (map == null || map.isEmpty()) { + return true; + } + return false; + } + + /** + * 判断Map是否不为空为空 + */ + public static boolean isNotEmpty(Map map) { + return !isEmpty(map); + } + + /** + * 去除list中的重复数据 + */ + public static List removeRepeat(List list) { + if (isEmpty(list)) { + return list; + } + List result = new ArrayList(); + for (T e : list) { + if (!result.contains(e)) { + result.add(e); + } + } + return result; + } + + public static boolean hasNull(Object... objects){ + for (int i = 0; i < objects.length; i++) { + if(objects[i]==null){return true;} + } + return false; + } + + public static boolean hasNotNull(Object... objects){ + for (int i = 0; i < objects.length; i++) { + if(objects[i]!=null){return true;} + } + return false; + } + + /** + * 将集合转换为String数组 + */ + public static String[] toArray(List list) { + if (isEmpty(list)) { + return null; + } + String[] result = new String[list.size()]; + for (int i = 0; i < list.size(); i++) { + result[i] = String.valueOf(list.get(i)); + } + return result; + } + + /** + * 将list拆分成多给指定的大小的list + */ + public static List> createList(List target, int size) { + List> listArr = new ArrayList<>(); + //获取被拆分的数组个数 + int arrSize = target.size()%size==0?target.size()/size:target.size()/size+1; + for(int i=0;i sub = new ArrayList(); + //把指定索引数据放入到list中 + for(int j=i*size;j<=size*(i+1)-1;j++) { + if(j<=target.size()-1) { + sub.add(target.get(j)); + } + } + listArr.add(sub); + } + return listArr; + } + + public static T selectFirst(List list){ + if(isNotEmpty(list)){ + return list.get(0); + } + return null; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/DateUtil.java b/src/main/java/com/qs/cost/common/utils/DateUtil.java new file mode 100644 index 0000000..94ff60d --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/DateUtil.java @@ -0,0 +1,194 @@ +package com.qs.cost.common.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; + +/** + * 日期工具类 + * Created by macro on 2019/1/29. + */ +public class DateUtil { + + public static final String FORMAT_SIMPLE_DATE_OF_YEAR_NUM = "MMdd"; + public static final String FORMAT_SIMPLE_DATE_OF_YEAR = "MM-dd"; + public static final String FORMAT_DATE_OF_YEAR = "MM-dd HH:mm:ss"; + public static final String FORMAT_DATE = "yyyy-MM-dd HH:mm:ss"; + public static final String FORMAT_SIMPLE_DATE_NUM = "yyyyMMdd"; + public static final String FORMAT_DATE_NUM = "yyyyMMddHHmmss"; + public static final String FORMAT_CRON = "ss mm HH dd MM ?"; + + public static final String FORMAT_SIMPLE_DATE_ZH = "yyyy年MM月dd日"; + public static final String FORMAT_DATE_ZH = "yyyy年MM月dd日 HH时mm分ss秒"; + + + public static final String FORMAT_SIMPLE_DATE = "yyyy-MM-dd"; + public static final String FORMAT_SIMPLE_DATE2 = "yyyy/MM/dd"; + public static final String FORMAT_SIMPLE_MONTH = "yyyy-MM"; + public static final String FORMAT_SIMPLE_YEAR = "yyyy"; + + + /** + * LocalDateTime转为日期 + * + * @param localDateTime LocalDateTime + * @return 日期 + */ + public static Date localDateTimeToDate(final LocalDateTime localDateTime) { + if (null == localDateTime) { + return null; + } + final ZoneId zoneId = ZoneId.systemDefault(); + final ZonedDateTime zdt = localDateTime.atZone(zoneId); + final Date date = Date.from(zdt.toInstant()); + return date; + } + + /** + * 转换格式 + * @param dateStr + * @param format + * @return + */ + public static Date getDateByFormatStr(String dateStr,String format){ + if(dateStr==null||format==null){return null;} + SimpleDateFormat sdf = new SimpleDateFormat(format); + Date date = null; + try { + date = sdf.parse(dateStr); + } catch (ParseException e) { + e.printStackTrace(); + } + return date; + } + + public static Double getDiffSecond(long beganTime, long endTime){ + return (double)(endTime - beganTime) / 1000.0D; + } + + /** 格式化日期字符串*/ + public static String formatDate(Date date,String format){ + SimpleDateFormat sdf = new SimpleDateFormat(format); + if(date!=null){ + return sdf.format(date); + } + return null; + } + + public static Date format(Date date,String format){ + String dateString = formatDate(date, format); + SimpleDateFormat sdf = new SimpleDateFormat(format); + try { + if(dateString!=null){ + return sdf.parse(dateString); + } + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + + public static double printRunTime(long beganTime, long endTime) { + return (double)(endTime - beganTime) / 1000.0D; + } + + /** 获取一天的起始时间*/ + public static Date getBeginDateOfDay(Date date){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int day = calendar.get(Calendar.DATE); + calendar.set(Calendar.DATE,day-1); + calendar.set(Calendar.HOUR_OF_DAY,23); + calendar.set(Calendar.MINUTE,59); + calendar.set(Calendar.SECOND,59); + calendar.set(Calendar.MILLISECOND,99); + /*calendar.set(Calendar.HOUR_OF_DAY,0); + calendar.set(Calendar.MINUTE,0); + calendar.set(Calendar.SECOND,0); + calendar.set(Calendar.MILLISECOND,0);*/ + return calendar.getTime(); + } + + /** 获取一天的结束时间(23:59:59)*/ + public static Date getEndDateOfDay(Date date){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int day = calendar.get(Calendar.DATE); + calendar.set(Calendar.DATE,day+1); + calendar.set(Calendar.HOUR_OF_DAY,0); + calendar.set(Calendar.MINUTE,0); + calendar.set(Calendar.SECOND,0); + calendar.set(Calendar.MILLISECOND,0); + /*calendar.set(Calendar.HOUR_OF_DAY,23); + calendar.set(Calendar.MINUTE,59); + calendar.set(Calendar.SECOND,59); + calendar.set(Calendar.MILLISECOND,999);*/ + return calendar.getTime(); + } + + /** + * 获取未来某时间 + * @param date + * @param somedate + * @param calendarTimeSpan + */ + public static Date getAfterSomedate(Date date,int somedate,int calendarTimeSpan){ + final Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(calendarTimeSpan,somedate); + return calendar.getTime(); + } + + /** 获取传入日期在某时间第一天 */ + public static Date getFirstDay(Date date,int calendarTimeSpan) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int last = cal.getActualMinimum(calendarTimeSpan); + cal.set(calendarTimeSpan, last); + return cal.getTime(); + } + + /** 获取传入日期在某时间最后一天 */ + public static Date getLastDay(Date date,int calendarTimeSpan) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int last = cal.getActualMaximum(calendarTimeSpan); + cal.set(calendarTimeSpan, last); + return cal.getTime(); + + } + + /** + * 计算时差 + * @param smallDate + * @param bigDate + * @param unit 0天 1时 2分 3秒 + * @return + */ + public static Long diffTime(Date smallDate,Date bigDate,int unit){ + long nd = 1000*24*60*60;//一天的毫秒数 + long nh = 1000*60*60;//一小时的毫秒数 + long nm = 1000*60;//一分钟的毫秒数 + long ns = 1000;//一秒钟的毫秒数 + + long t1 = smallDate.getTime(); + long t2 = bigDate.getTime(); + long diff = t2 - t1; + if(unit==0){ + return diff/nd; + }else if (unit==1){ + return diff%nd/nh; + }else if(unit==2){ + return diff%nd%nh/nm; + }else if(unit==3){ + return diff%nd%nh%nm/ns; + } + return null; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/HttpService.java b/src/main/java/com/qs/cost/common/utils/HttpService.java new file mode 100644 index 0000000..9fb76b1 --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/HttpService.java @@ -0,0 +1,479 @@ +package com.qs.cost.common.utils; + +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.protocol.HTTP; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; + +import javax.net.ssl.SSLContext; +import java.io.*; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.*; + +/** + * Created by JcYen on 2019/5/13 + * + * @Version v1.0 + **/ +@Slf4j +public class HttpService { + + private static PoolingHttpClientConnectionManager cm; + private static RequestConfig requestConfig; + private static String UTF_8 = "UTF-8"; + + private static void init() { + Integer poolSize = 10; + Integer connSize = 5; + Integer socketTimeout = 200; + Integer reqTimeout = 200; + Integer connTimeout = 200; + if (cm == null) { + cm = new PoolingHttpClientConnectionManager(); + cm.setMaxTotal(poolSize);// 整个连接池最大连接数 + cm.setDefaultMaxPerRoute(connSize);// 每路由最大连接数,默认值是2 + requestConfig = RequestConfig.custom() // 建立构造器 + .setConnectTimeout(connTimeout*1000)// 设置连接超时 + .setConnectionRequestTimeout(reqTimeout*1000)// 设置从连接池获取连接实例的超时 + .setSocketTimeout(socketTimeout*1000)// 设置读取超时 + .build();// 在提交请求之前 测试连接是否可用 + } + } + + /* 通过连接池获取HttpClient */ + private static CloseableHttpClient getHttpClient() { + init(); + return HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build(); + } + + /* get的URL请求 */ + public static String httpGetRequest(String url) { + HttpGet httpGet = new HttpGet(url); + return getResult(httpGet); + } + + public static InputStream httpGetStream(String url) { + HttpGet httpGet = new HttpGet(url); + CloseableHttpClient httpClient = getHttpClient(); + try { + CloseableHttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (entity != null) { + return entity.getContent(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /* get的URL的参数map请求 */ + public static String httpGetRequest(String url, Map params) throws URISyntaxException { + URIBuilder ub = new URIBuilder(); + ub.setPath(url); + ArrayList pairs = covertParams2NVPS(params); + ub.setParameters(pairs); + HttpGet httpGet = new HttpGet(ub.build()); + return getResult(httpGet); + } + + /* get的URL参数map,头map参数 */ + public static String httpGetRequest(String url, Map headers, Map params) + throws URISyntaxException { + URIBuilder ub = new URIBuilder(); + ub.setPath(url); + ArrayList pairs = covertParams2NVPS(params); + ub.setParameters(pairs); + HttpGet httpGet = new HttpGet(ub.build()); + for (Map.Entry param : headers.entrySet()) { + httpGet.addHeader(param.getKey(), String.valueOf(param.getValue())); + } + return getResult(httpGet); + } + + /* post的URL请求 */ + public static String httpPostRequest(String url) { + HttpPost httpPost = new HttpPost(url); + return getResult(httpPost); + } + + /* post的URL的参数map请求 */ + public static String httpPostRequest(String url, Map params) throws UnsupportedEncodingException { + HttpPost httpPost = new HttpPost(url); + ArrayList pairs = covertParams2NVPS(params); + httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8)); + log.debug("httpPostRequest -> URL:",httpPost.getURI().getPath()); + return getResult(httpPost); + } + /* post的URL的参数map请求 */ + public static HttpResult httpPostRequestWithResult(String url, Map params) { + HttpPost httpPost = new HttpPost(url); + ArrayList pairs = covertParams2NVPS(params); + try { + httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + log.debug("httpPostRequest -> URL:",httpPost.getURI().getPath()); + return getHttpResult(httpPost); + } + + /* post的URL的参数map请求map头 */ + public static String httpPostRequest(String url, Map headers, Map params) + throws UnsupportedEncodingException { + HttpPost httpPost = new HttpPost(url); + for (Map.Entry param : headers.entrySet()) { + httpPost.addHeader(param.getKey(), String.valueOf(param.getValue())); + } + ArrayList pairs = covertParams2NVPS(params); + httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8)); + return getResult(httpPost); + } + + /* post的URL的参数map请求map头及body信息 */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static String postMap(String url, Map headerMap, Map contentMap) { + String result = null; + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost post = new HttpPost(url); + List content = new ArrayList(); + Iterator iterator = contentMap.entrySet().iterator(); // 将content生成entity + while (iterator.hasNext()) { + Map.Entry elem = (Map.Entry) iterator.next(); + content.add(new BasicNameValuePair(elem.getKey(), elem.getValue())); + } + CloseableHttpResponse response = null; + try { + Iterator headerIterator = headerMap.entrySet().iterator(); // 循环增加header + while (headerIterator.hasNext()) { + Map.Entry elem = (Map.Entry) headerIterator.next(); + post.addHeader(elem.getKey(), elem.getValue()); + } + if (content.size() > 0) { + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(content, "UTF-8"); + post.setEntity(entity); + } + response = httpClient.execute(post); // 发送请求并接收返回数据 + if (response != null && response.getStatusLine().getStatusCode() == 200) { + HttpEntity entity = response.getEntity(); // 获取response的body部分 + result = EntityUtils.toString(entity); // 读取reponse的body部分并转化成字符串 + } + return result; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + httpClient.close(); + if (response != null) { + response.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + + /* 中间工具 */ + private static ArrayList covertParams2NVPS(Map params) { + ArrayList pairs = new ArrayList(); + for (Map.Entry param : params.entrySet()) { + pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue()))); + } + return pairs; + } + + /* 发送的json的参数请求 */ + public static String httpPostJSON(String url, String json) throws UnsupportedEncodingException { + log.info("json"+json); + HttpPost httpPost = new HttpPost(url); + StringEntity entity = new StringEntity(json); + entity.setContentEncoding(UTF_8); + entity.setContentType("application/json");// 发送json数据需要设置contentType + httpPost.setEntity(entity); + return getResult(httpPost); + } + + /* 发送的json的参数请求 */ + public static HttpResponse httpImagePostJSON(String url, String json) throws UnsupportedEncodingException { + CloseableHttpClient httpClient = HttpClientBuilder.create().build(); + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json"); + StringEntity entity; + entity = new StringEntity(json); + entity.setContentType("image/png"); + httpPost.setEntity(entity); + HttpResponse response = null; + try { + response = httpClient.execute(httpPost); + } catch (IOException e) { + e.printStackTrace(); + } + return response; + } + + /* 发送的xml字符串 */ + public static String httpPostXML(String url, String xmlData) throws UnsupportedEncodingException { + HttpPost post = new HttpPost(url); + StringEntity entity = new StringEntity(xmlData); + entity.setContentEncoding(UTF_8); + entity.setContentType("text/xml;charset=UTF-8"); + return getResult(post); + } + + private static String getResult(HttpRequestBase request) { + return getHttpResult(request).getData(); + } + + private static HttpResult getHttpResult(HttpRequestBase request) { + CloseableHttpClient httpClient = getHttpClient(); + String errMsg = null; + Integer code = 500; + try { + CloseableHttpResponse response = httpClient.execute(request); + code = response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + if (entity != null) { + String data = EntityUtils.toString(entity, UTF_8); + response.close(); + HttpResult result = new HttpResult(code,null,data); + return result; + } + } catch (ClientProtocolException e) { + log.error(e.getMessage()); + errMsg = e.getMessage(); + } catch (IOException e) { + log.error(e.getMessage()); + errMsg = e.getMessage(); + } + return new HttpResult(code,errMsg); + } + + public static String getXMLString() { + StringBuffer sb = new StringBuffer(); + sb.append(""); + sb.append(""); + sb.append("Hello world!"); + sb.append("Enter value"); + sb.append("http://localhost/xmlserver/test.do"); + sb.append("value"); + sb.append(""); + sb.append(""); + return sb.toString(); + } + + public static String doPost(String apiUrl, Object json) { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + stringEntity.setContentType("application/json"); + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + System.out.println(response.getStatusLine().getStatusCode()); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + /** + * 发送 SSL POST 请求(HTTPS),K-V形式 + */ + public static String doPostSSLXml(String apiUrl, String xml) { + CloseableHttpClient httpClient = createSSLClientDefault(); + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + String httpStr = null; + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(xml, "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + stringEntity.setContentType("text/xml;charset=UTF-8"); + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + System.out.println(response); + // int statusCode = response.getStatusLine().getStatusCode(); + // if (statusCode != HttpStatus.SC_OK) { + // return null; + // } + HttpEntity entity = response.getEntity(); + // if (entity == null) { + // return null; + // } + httpStr = EntityUtils.toString(entity, "utf-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + public static String doGetSSL(String apiUrl) throws ClientProtocolException, IOException { + CloseableHttpClient httpClient = createSSLClientDefault(); + HttpGet httpget = new HttpGet(apiUrl); + CloseableHttpResponse response = null; + String httpStr = null; + httpget.setConfig(requestConfig); + response = httpClient.execute(httpget); + HttpEntity entity = response.getEntity(); + httpStr = EntityUtils.toString(entity, "utf-8"); + return httpStr; + } + + public static String doPostSSL(String apiUrl, Map params) + throws ClientProtocolException, IOException { + CloseableHttpClient httpClient = createSSLClientDefault(); + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + String httpStr = null; + httpPost.setConfig(requestConfig); + List pairList = new ArrayList(params.size()); + for (Map.Entry entry : params.entrySet()) { + NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString()); + pairList.add(pair); + } + httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8"))); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + httpStr = EntityUtils.toString(entity, "utf-8"); + return httpStr; + } + + /** + * 发送 SSL POST 请求(HTTPS),JSON形式 + * + * @param apiUrl + * API接口URL + * @param json + * JSON对象 + * @return + */ + public static String doPostSSL(String apiUrl, Object json) { + CloseableHttpClient httpClient = createSSLClientDefault(); + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + String httpStr = null; + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + stringEntity.setContentType("application/json"); + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + return null; + } + HttpEntity entity = response.getEntity(); + if (entity == null) { + return null; + } + httpStr = EntityUtils.toString(entity, "utf-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + + + public static CloseableHttpClient createSSLClientDefault() { + try { + SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { + public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { + return true; + } + }).build(); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext); + return HttpClients.custom().setSSLSocketFactory(sslsf).build(); + } catch (Exception e) { + e.printStackTrace(); + } + return HttpClients.createDefault(); + } + + @Getter + @Setter + public static class HttpResult { + + public HttpResult(Integer code,String message){ + this.massage = message; + this.code = code; + } + + public HttpResult(Integer code,String message,String data){ + this.data = data; + this.massage = message; + this.code = code; + } + + private String massage; + + private Integer code; + + private String data; + + } + + +} diff --git a/src/main/java/com/qs/cost/common/utils/HttpUtil.java b/src/main/java/com/qs/cost/common/utils/HttpUtil.java new file mode 100644 index 0000000..4bc66d4 --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/HttpUtil.java @@ -0,0 +1,121 @@ +package com.qs.cost.common.utils; + +import com.qs.cost.common.dto.HttpResult; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Map; + +/** + * @author YenHex + * @since 2022/2/28 + */ +@Slf4j +public class HttpUtil { + + private static PoolingHttpClientConnectionManager cm; + private static RequestConfig requestConfig; + private static String UTF8 = "UTF-8"; + + private static void init() { + int poolSize = 10; + int connSize = 5; + int socketTimeout = 2000; + int reqTimeout = 2000; + int connTimeout = 2000; + if (cm == null) { + cm = new PoolingHttpClientConnectionManager(); + // 整个连接池最大连接数 + cm.setMaxTotal(poolSize); + // 每路由最大连接数,默认值是2 + cm.setDefaultMaxPerRoute(connSize); + // 建立构造器 + requestConfig = RequestConfig.custom() + // 设置连接超时 + .setConnectTimeout(connTimeout*1000) + // 设置从连接池获取连接实例的超时 + .setConnectionRequestTimeout(reqTimeout*1000) + // 设置读取超时 + .setSocketTimeout(socketTimeout*1000) + // 在提交请求之前 测试连接是否可用 + .build(); + } + } + /** 通过连接池获取HttpClient */ + private static CloseableHttpClient getHttpClient() { + init(); + return HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build(); + } + + public static HttpResult get(String url){ + HttpGet httpGet = new HttpGet(url); + httpGet.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"); + return getHttpResult(httpGet); + } + + /** post的URL的参数map请求 */ + public static HttpResult post(String url, String json) { + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("Accept","application/json"); + httpPost.setHeader("Content-Type","application/json"); + httpPost.setEntity(new StringEntity(json, StandardCharsets.UTF_8)); + return getHttpResult(httpPost); + } + + /** + * 请求返回统一封装 + * @param request + * @return + */ + private static HttpResult getHttpResult(HttpRequestBase request) { + CloseableHttpClient httpClient = getHttpClient(); + String errMsg = null; + Integer code = 500; + try { + CloseableHttpResponse response = httpClient.execute(request); + code = response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + if (entity != null) { + String data = EntityUtils.toString(entity, UTF8); + response.close(); + HttpResult result = new HttpResult(code,null,data); + return result; + } + } catch (ClientProtocolException e) { + log.error(e.getMessage()); + errMsg = e.getMessage(); + } catch (IOException e) { + log.error(e.getMessage()); + errMsg = e.getMessage(); + } + return new HttpResult(code,errMsg); + } + + /** 中间工具 */ + private static ArrayList covertParams2NVPS(Map params) { + ArrayList pairs = new ArrayList<>(); + for (Map.Entry param : params.entrySet()) { + pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue()))); + } + return pairs; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/IdUtil.java b/src/main/java/com/qs/cost/common/utils/IdUtil.java new file mode 100644 index 0000000..f8055b4 --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/IdUtil.java @@ -0,0 +1,16 @@ +package com.qs.cost.common.utils; + +import java.util.UUID; + +/** + * @author YenHex + * @since 2022/2/28 + */ +public class IdUtil { + + public static final IdWorker ID_WORKER = new IdWorker(0,0); + + public static Long getLong(){ + return ID_WORKER.nextId()-1541318968076140673L; + } +} diff --git a/src/main/java/com/qs/cost/common/utils/IdWorker.java b/src/main/java/com/qs/cost/common/utils/IdWorker.java new file mode 100644 index 0000000..019918e --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/IdWorker.java @@ -0,0 +1,155 @@ +package com.qs.cost.common.utils; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.NetworkInterface; + +/** + *

名称:IdWorker.java

+ *

描述:分布式自增长ID

+ *
+ *     Twitter的 Snowflake JAVA实现方案
+ * 
+ * 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用: + * 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000 + * 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间, + * 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识), + * 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。 + * 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分), + * 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。 + *

+ * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)) + * @author USER + */ +public class IdWorker { + + // 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动) + private final static long twepoch = 1288834974657L; + // 机器标识位数 + private final static long workerIdBits = 5L; + // 数据中心标识位数 + private final static long datacenterIdBits = 5L; + // 机器ID最大值 + private final static long maxWorkerId = -1L ^ (-1L << workerIdBits); + // 数据中心ID最大值 + private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + // 毫秒内自增位 + private final static long sequenceBits = 12L; + // 机器ID偏左移12位 + private final static long workerIdShift = sequenceBits; + // 数据中心ID左移17位 + private final static long datacenterIdShift = sequenceBits + workerIdBits; + // 时间毫秒左移22位 + private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + + private final static long sequenceMask = -1L ^ (-1L << sequenceBits); + /* 上次生产id时间戳 */ + private static long lastTimestamp = -1L; + // 0,并发控制 + private long sequence = 0L; + + private final long workerId; + // 数据标识id部分 + private final long datacenterId; + + public IdWorker(){ + this.datacenterId = getDatacenterId(maxDatacenterId); + this.workerId = getMaxWorkerId(datacenterId, maxWorkerId); + } + /** + * @param workerId 工作机器ID + * @param datacenterId 序列号 + */ + public IdWorker(long workerId, long datacenterId) { + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + } + if (datacenterId > maxDatacenterId || datacenterId < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + } + this.workerId = workerId; + this.datacenterId = datacenterId; + } + /** + * 获取下一个ID + * @return + */ + public synchronized long nextId() { + long timestamp = timeGen(); + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + if (lastTimestamp == timestamp) { + // 当前毫秒内,则+1 + sequence = (sequence + 1) & sequenceMask; + if (sequence == 0) { + // 当前毫秒内计数满了,则等待下一秒 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0L; + } + lastTimestamp = timestamp; + // ID偏移组合生成最终的ID,并返回ID + long nextId = ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) | sequence; + + return nextId; + } + + private long tilNextMillis(final long lastTimestamp) { + long timestamp = this.timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = this.timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + /** + * 获取 maxWorkerId + */ + protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) { + StringBuffer mpid = new StringBuffer(); + mpid.append(datacenterId); + String name = ManagementFactory.getRuntimeMXBean().getName(); + if (!name.isEmpty()) { + /* + * GET jvmPid + */ + mpid.append(name.split("@")[0]); + } + /* + * MAC + PID 的 hashcode 获取16个低位 + */ + return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1); + } + + /** + * 数据标识id部分 + */ + protected static long getDatacenterId(long maxDatacenterId) { + long id = 0L; + try { + InetAddress ip = InetAddress.getLocalHost(); + NetworkInterface network = NetworkInterface.getByInetAddress(ip); + if (network == null) { + id = 1L; + } else { + byte[] mac = network.getHardwareAddress(); + id = ((0x000000FF & (long) mac[mac.length - 1]) + | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6; + id = id % (maxDatacenterId + 1); + } + } catch (Exception e) { + System.out.println(" getDatacenterId: " + e.getMessage()); + } + return id; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/JsonUtil.java b/src/main/java/com/qs/cost/common/utils/JsonUtil.java new file mode 100644 index 0000000..532111f --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/JsonUtil.java @@ -0,0 +1,83 @@ +package com.qs.cost.common.utils; + +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +//import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JavaType; +//import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.List; +import java.util.Map; + + +/** + * Jackson json序列化和反序列化工具类 + * @Author JcYen + * @Date 2019/6/3 + * @Version 1.0 + */ +public class JsonUtil { + + /** + * jackson对象 + */ + static final ObjectMapper MAPPER = new ObjectMapper(); + + static { + MAPPER.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); + MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + /** + * 将对象转换成json字符串。 + */ + public static String objectToJson(Object data) { + try { + String string = MAPPER.writeValueAsString(data); + return string; + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 将json结果集转化为对象 + * + * @param jsonData json数据 + * @param beanType 对象中的object类型 + */ + public static T jsonToPojo(String jsonData, Class beanType) { + try { + T t = MAPPER.readValue(jsonData, beanType); + return t; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 将json数据转换成pojo对象list + */ + public static List jsonToList(String jsonData, Class beanType) { + JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); + try { + List list = MAPPER.readValue(jsonData, javaType); + return list; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static Map jsonToMap(String jsonStr){ + Map json = JSONObject.parseObject(jsonStr, Map.class); + return json; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/SecureUtil.java b/src/main/java/com/qs/cost/common/utils/SecureUtil.java new file mode 100644 index 0000000..44f9eb3 --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/SecureUtil.java @@ -0,0 +1,47 @@ +package com.qs.cost.common.utils; + +import com.qs.cost.common.utils.model.DesUtils; + +/** + * @author YenHex + * @since 2022/2/25 + */ +public class SecureUtil extends cn.hutool.crypto.SecureUtil { + + + + /** + * 加密 + * @param secretKey + * @param clientId + * @return + */ + public static String desEncrypt(String secretKey,String clientId){ + String formatStr = clientId+"-"+System.currentTimeMillis(); + DesUtils des = new DesUtils(secretKey); + try { + return des.encrypt(formatStr); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 解密 + * @param secretKey + * @param encryptText + * @return clientId + */ + public static String desDecrypt(String secretKey,String encryptText){ + DesUtils des = new DesUtils(secretKey); + try { + String formatStr = des.decrypt(encryptText); + return formatStr.split("-")[0]; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/ServletUtil.java b/src/main/java/com/qs/cost/common/utils/ServletUtil.java new file mode 100644 index 0000000..b950613 --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/ServletUtil.java @@ -0,0 +1,123 @@ +package com.qs.cost.common.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * @author YenHex + * @since 2022/2/25 + */ +@Slf4j +public class ServletUtil { + + /** + * 获取用户真实IP + * + * @return + */ + public static String getIpAddress(HttpServletRequest request) { + // 优先取X-Real-IP + String ip = request.getHeader("X-Real-IP"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("x-forwarded-for"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + if ("0:0:0:0:0:0:0:1".equals(ip)) { + ip = "undefined"; + } + } + if ("unknown".equalsIgnoreCase(ip)) { + ip = "undefined"; + return ip; + } + int pos = ip.indexOf(','); + if (pos >= 0) { + ip = ip.substring(0, pos); + } + return ip; + } + + /** + * 判断本次请求的数据类型是否为json + * @param request request + * @return true: 是 JSON 数据; false: 非 json 数据 + */ + public static boolean isJsonRequest(HttpServletRequest request) { + if (request.getContentType() != null) { + return request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) || + request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE); + } + return false; + } + + /** + * 获取query参数 + * @param request + * @return + */ + public static Map getParameterMapAll(HttpServletRequest request) { + Enumeration parameters = request.getParameterNames(); + Map params = new HashMap<>(); + while (parameters.hasMoreElements()) { + String parameter = parameters.nextElement(); + String value = request.getParameter(parameter); + params.put(parameter, value); + } + return params; + } + + /** + * 获取请求Body + * + * @param request + * @return + */ + public static String getBodyString(ServletRequest request) { + StringBuilder sb = new StringBuilder(); + InputStream inputStream = null; + BufferedReader reader = null; + try { + inputStream = request.getInputStream(); + reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); + String line = ""; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return sb.toString(); + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/StringCreateUtil.java b/src/main/java/com/qs/cost/common/utils/StringCreateUtil.java new file mode 100644 index 0000000..45a33df --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/StringCreateUtil.java @@ -0,0 +1,132 @@ +package com.qs.cost.common.utils; + +import java.text.NumberFormat; +import java.util.Random; + +/** + * @Description 创建字符串工具类 + * @Author JcYen + * @Date 2019/4/9 + * @Version v1.0 + **/ +public class StringCreateUtil { + + private static final String CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + private static final String CHARSET2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + /** + * 根据长度随机生成字符串(根据时间,有出现重复现象) + */ + public static String randomTimeStr(int length) { + String randomStr = ""; + int randomInt; + Random random = new Random(System.currentTimeMillis()); + for (int i = 0; i < length; i++) { + randomInt = random.nextInt(CHARSET.length()); + randomStr += CHARSET.charAt(randomInt); + } + return randomStr; + } + + /** + * ID对应字符串匹配 + * @param id + * @return + */ + public static String caveIdString(Long id){ + String idString = id.toString(); + String rs = ""; + for(int i=0;ilen){ + return title.substring(len)+"..."; + }return title; + } + + + /** + * description: 格式化数字,实现左侧补 0. + * @param num 格式化的数字 + * @param min 最小位数 + * @param max 最大位数 + */ + public static String fill(int num , int min , int max) { + NumberFormat numberFormat = NumberFormat.getInstance(); + // 禁用数字格式化分组。 如: 000,001 + numberFormat.setGroupingUsed(false); + // 保留最小位数 + numberFormat.setMinimumIntegerDigits(min); + // 保留最大位数 + numberFormat.setMaximumIntegerDigits(max); + return numberFormat.format(num); + } + + +} diff --git a/src/main/java/com/qs/cost/common/utils/StringUtil.java b/src/main/java/com/qs/cost/common/utils/StringUtil.java new file mode 100644 index 0000000..243b3df --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/StringUtil.java @@ -0,0 +1,20 @@ +package com.qs.cost.common.utils; + +import org.springframework.util.StringUtils; + +/** + * @author YenHex + * @version 1.0 + * @date 2021/6/16 + **/ +public class StringUtil { + + public static boolean isEmpty(Object obj){ + return StringUtils.isEmpty(obj); + } + + public static boolean isNotEmpty(String str){ + return str!=null && str.trim().length()>0; + } + +} diff --git a/src/main/java/com/qs/cost/common/utils/model/DesUtils.java b/src/main/java/com/qs/cost/common/utils/model/DesUtils.java new file mode 100644 index 0000000..58fbe5f --- /dev/null +++ b/src/main/java/com/qs/cost/common/utils/model/DesUtils.java @@ -0,0 +1,126 @@ +package com.qs.cost.common.utils.model; + +import java.security.Key; + +import javax.crypto.Cipher; + +/** + * 使用DES算法对字符串进行加密解密 (加密解密的操作步骤正好相反, 参考 {@link #encrypt(String)}, {@link #decrypt(String)}) + */ +public class DesUtils { + private static String defaultSecretKey = "default_secret_key"; //默认密钥 + private Cipher encryptCipher = null; //加密器 + private Cipher decryptCipher = null; //解密器 + + public DesUtils() throws Exception { + this(defaultSecretKey); + } + + /** + * @param secretKey 加密解密使用的密钥 + */ + public DesUtils(String secretKey) { + Key key; + try { + key = getKey(secretKey.getBytes()); + encryptCipher = Cipher.getInstance("DES"); + encryptCipher.init(Cipher.ENCRYPT_MODE, key); + decryptCipher = Cipher.getInstance("DES"); + decryptCipher.init(Cipher.DECRYPT_MODE, key); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 加密 (逻辑: 1. 将要加密的字符串转换为字节数组(byte array)
+ * 2. 将第一步的字节数组作为输入使用加密器(Cipher)的doFinal方法进行加密, 返回字节数组
+ * 3. 把加密后的字节数组转换成十六进制的字符串)
+ * @param strIn 要加密的字符串 + * @return 返回加密后的十六进制字符串 + * @throws Exception + */ + public String encrypt(String strIn) throws Exception { + return byteArr2HexStr(encrypt(strIn.getBytes())); + } + + public byte[] encrypt(byte[] arrB) throws Exception { + return encryptCipher.doFinal(arrB); + } + + /** + * 解密 (逻辑: 1. 把加密后的十六进制字符串转换成字节数组(byte array)
+ * 2. 将第一步的字节数组作为输入使用加密器(Cipher)的doFinal方法进行解密, 返回字节数组(byte array)
+ * 3. 把解密后的字节数组转换成字符串)
+ * @param strIn + * @return + * @throws Exception + */ + public String decrypt(String strIn) throws Exception { + return new String(decrypt(hexStr2ByteArr(strIn))); + } + + public byte[] decrypt(byte[] arrB) throws Exception { + return decryptCipher.doFinal(arrB); + } + + public static String byteArr2HexStr(byte[] arrB) throws Exception { + int iLen = arrB.length; + // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍 + StringBuffer sb = new StringBuffer(iLen * 2); + for (int i = 0; i < iLen; i++) { + int intTmp = arrB[i]; + // 把负数转换为正数 + while (intTmp < 0) { + intTmp = intTmp + 256; + } + // 小于0F的数需要在前面补0 + if (intTmp < 16) { + sb.append("0"); + } + sb.append(Integer.toString(intTmp, 16)); + } + return sb.toString(); + } + + public static byte[] hexStr2ByteArr(String strIn) throws Exception { + byte[] arrB = strIn.getBytes(); + int iLen = arrB.length; + // 两个字符表示一个字节,所以字节数组长度是字符串长度除以2 + byte[] arrOut = new byte[iLen / 2]; + for (int i = 0; i < iLen; i = i + 2) { + String strTmp = new String(arrB, i, 2); + arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16); + } + return arrOut; + } + + private Key getKey(byte[] arrBTmp) throws Exception { + // 创建一个空的8位字节数组(默认值为0) + byte[] arrB = new byte[8]; + // 将原始字节数组转换为8位 + for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) { + arrB[i] = arrBTmp[i]; + } + // 生成密钥 + Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES"); + return key; + } + + + /** + * 用法实例 + */ + public static void main(String[] args) { + try { + String test = "liwc"; + DesUtils des = new DesUtils("leemenz"); //自定义密钥 + System.out.println("加密前的字符:" + test); + System.out.println("加密后的字符:" + des.encrypt(test)); + System.out.println("解密后的字符:" + des.decrypt(des.encrypt(test))); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/qs/cost/module/controller/LzOrderController.java b/src/main/java/com/qs/cost/module/controller/LzOrderController.java new file mode 100644 index 0000000..d5edc71 --- /dev/null +++ b/src/main/java/com/qs/cost/module/controller/LzOrderController.java @@ -0,0 +1,24 @@ +package com.qs.cost.module.controller; + +import com.qs.cost.common.dto.R; +import com.qs.cost.common.dto.u8.U8CallbackVo; +import com.qs.cost.common.utils.JsonUtil; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + +/** + * @author YenHex + * @since 2022/7/7 + */ +@AllArgsConstructor +@RestController +@RequestMapping("/u8") +public class LzOrderController { + + @PostMapping("/callback") + public R callback(@RequestBody U8CallbackVo requestVo){ + System.out.println(JsonUtil.objectToJson(requestVo)); + return R.ok(); + } + +} diff --git a/src/main/java/com/qs/cost/module/domain/VmSupplierPo.java b/src/main/java/com/qs/cost/module/domain/VmSupplierPo.java new file mode 100644 index 0000000..aa18710 --- /dev/null +++ b/src/main/java/com/qs/cost/module/domain/VmSupplierPo.java @@ -0,0 +1,64 @@ +package com.qs.cost.module.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.util.Date; + +/** + * @author YenHex + * @since 2022/9/27 + */ +@Data +public class VmSupplierPo { + + @TableId(value = "serialNumber") + private String serialNumber; + + @TableField(value = "empNo") + private String empNo; + + @TableField(value = "name") + private String name; + + @TableField(value = "applyDate") + private Date applyDate; + + @TableField(value = "applyType") + private String applyType; + + @TableField(value = "cVenCode") + private String cVenCode; + + @TableField(value = "cVenName") + private String cVenName; + + @TableField(value = "cVenAbbName") + private String cVenAbbName; + + @TableField(value = "cVCCode") + private String cVCCode; + + @TableField(value = "cVCName") + private String cVCName; + + @TableField(value = "cDCCode") + private String cDCCode; + + @TableField(value = "cDCName") + private String cDCName; + + @TableField(value = "cCusAddress") + private String cCusAddress; + + @TableField(value = "cCusEmail") + private String cCusEmail; + + @TableField(value = "cCusPerson") + private String cCusPerson; + + @TableField(value = "cCusPhone") + private String cCusPhone; + +} diff --git a/src/main/java/com/qs/cost/module/domain/dto/U8Vendor.java b/src/main/java/com/qs/cost/module/domain/dto/U8Vendor.java new file mode 100644 index 0000000..e14f461 --- /dev/null +++ b/src/main/java/com/qs/cost/module/domain/dto/U8Vendor.java @@ -0,0 +1,39 @@ +package com.qs.cost.module.domain.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * + * Vendor t = new Vendor(); + * t.Editprop = "A";//编辑属性:A表新增,M表修改 string类型 + * t.cVenCode = "01020302";//供应商编码 (必填) + * t.cVenName = "测试名称";//供应商名称 (必填) + * t.cVenAbbName = "测试";//供应商简称 + * t.cVCCode = "01";//供应商分类编码(必填) + * t.cDCCode = "";//地区编码 + * + * @author YenHex + * @since 2022/9/27 + */ +@Data +public class U8Vendor { + + @JsonProperty("Editprop") + private String editprop; + + @JsonProperty("cVenCode") + private String cVenCode; + + @JsonProperty("cVenName") + private String cVenName; + + @JsonProperty("cVenAbbName") + private String cVenAbbName; + + @JsonProperty("cVCCode") + private String cVcCode; + + @JsonProperty("cDCCode") + private String cDCCode; +} diff --git a/src/main/java/com/qs/cost/module/mapper/VmSupplierMapper.java b/src/main/java/com/qs/cost/module/mapper/VmSupplierMapper.java new file mode 100644 index 0000000..da13a14 --- /dev/null +++ b/src/main/java/com/qs/cost/module/mapper/VmSupplierMapper.java @@ -0,0 +1,13 @@ +package com.qs.cost.module.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.qs.cost.module.domain.VmSupplierPo; +import org.apache.ibatis.annotations.Mapper; + +/** + * @author YenHex + * @since 2022/9/27 + */ +public interface VmSupplierMapper extends BaseMapper { + +} diff --git a/src/main/java/com/qs/cost/module/service/VmSupplierService.java b/src/main/java/com/qs/cost/module/service/VmSupplierService.java new file mode 100644 index 0000000..308db6d --- /dev/null +++ b/src/main/java/com/qs/cost/module/service/VmSupplierService.java @@ -0,0 +1,59 @@ +package com.qs.cost.module.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.qs.cost.common.conf.MainServerProperties; +import com.qs.cost.common.dto.u8.U8RequestBo; +import com.qs.cost.common.utils.HttpUtil; +import com.qs.cost.common.utils.JsonUtil; +import com.qs.cost.module.domain.VmSupplierPo; +import com.qs.cost.module.domain.dto.U8Vendor; +import com.qs.cost.module.mapper.VmSupplierMapper; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +/** + * @author YenHex + * @since 2022/9/27 + */ +@Service +@AllArgsConstructor +public class VmSupplierService { + + private final VmSupplierMapper vmSupplierMapper; + private final MainServerProperties mainServerProperties; + + public void test() { + String host = mainServerProperties.getHost(); + String year = mainServerProperties.getYear(); + String book = mainServerProperties.getBook(); + List supplierPoList = vmSupplierMapper.selectList(new QueryWrapper<>()); + for (VmSupplierPo supplierPo : supplierPoList) { + U8Vendor vendor = new U8Vendor(); + //编辑属性:A表新增,M表修改 string类型 + vendor.setEditprop("A"); + vendor.setCVenCode(supplierPo.getCVenCode()); + vendor.setCVenName(supplierPo.getCVenName()); + vendor.setCVenAbbName(supplierPo.getCVenAbbName()); + vendor.setCDCCode(supplierPo.getCDCCode()); + vendor.setCVcCode(supplierPo.getCVCCode()); + String jsonBody = JsonUtil.objectToJson(vendor); + //发起U8服务中台 + U8RequestBo requestBo = new U8RequestBo(); + requestBo.setPk(vendor.getCVenCode()); + requestBo.setCmd("BasicVendor"); + requestBo.setYear(year); + requestBo.setBook(book); + requestBo.setJsonBody(jsonBody); + requestBo.setKeyId(""); + requestBo.setSettingRetryTimes(2); + requestBo.setCallbackState("1"); + requestBo.setCallbackHost( host + "/lzOrder/callback"); + HttpUtil.post(mainServerProperties.getU8url(),JsonUtil.objectToJson(requestBo)); + + } + } + +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..3363488 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,34 @@ +#服务配置 +server: + port: 7101 + #本服务访问根地址,用于回调 + host: 'http://127.0.0.1:7101' + #帐套 + book: 999 + #年份 + year: 2020 + #U8平台 + u8url: http://127.0.0.1:7100/api/jobRequest +#SpringBoot相关 +spring: + #数据源 + datasource: + #url: jdbc:mysql://127.0.0.1:3333/jsl_cost_api?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai + url: jdbc:sqlserver://192.168.10.7:1433;DatabaseName=JSLGROUPDB + username: sa + password: '#JSL2282125' + #driverClassName: com.mysql.cj.jdbc.Driver + driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver +#mybatis plus +mybatis-plus: + type-aliases-package: com.qs.cost.module.domain + configuration: + map-underscore-to-camel-case: true + global-config: + banner: false + db-config: + logic-delete-value: 1 # 逻辑已删除值(默认为 1) + logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) +# 日志配置 +logging: + config: classpath:logback-spring.xml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..3d7808a --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: dev diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..83d11fe --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + ${PATTERN} + + + + + + + + + + + + + + ${PROD_FILE_PATH}${file.separator}${LOG_NAME}.log + + + ${PROD_FILE_PATH}${file.separator}${LOG_NAME}-%d{yyyy-MM-dd}.%i.log + + 7 + 100MB + 1GB + + + + [%date{yyyy-MM-dd HH:mm:ss.SSS}] %X{logthreadId} %-5level %logger{80} %method %line - %msg%n + + + + + + + +