From 1b56968717bb9e07744f6c04cd6d3dd0675eb370 Mon Sep 17 00:00:00 2001 From: chenjf <1004990705@qq.com> Date: Wed, 9 Aug 2023 11:42:56 +0800 Subject: [PATCH] init --- readme.md | 49 ++ .../ils/order/IlsOrderServiceApplication.java | 15 + .../ils/order/annotation/TokenAnnotation.java | 15 + .../org/ils/order/aspect/TokenAspect.java | 57 +++ .../java/org/ils/order/config/BaseConfig.java | 20 + .../ils/order/config/MyBatisPlusConfig.java | 34 ++ .../org/ils/order/config/RedisConfig.java | 46 ++ .../ils/order/config/RestTemplateConfig.java | 61 +++ .../org/ils/order/config/SwaggerConfig.java | 70 +++ .../org/ils/order/config/WebMvcConfig.java | 24 + .../java/org/ils/order/entity/BaseEntity.java | 27 ++ .../org/ils/order/entity/IlsMainLine.java | 33 ++ .../order/handler/GlobalExceptionHandler.java | 27 ++ .../order/handler/MysqlMetaObjectHandler.java | 36 ++ .../ils/order/mapper/IlsMainLineMapper.java | 11 + .../org/ils/order/model/DTO/BasePageDto.java | 16 + .../org/ils/order/model/DTO/MainLineDto.java | 21 + .../ils/order/model/DTO/MainLinePageDto.java | 15 + .../org/ils/order/model/DTO/OrderPageDto.java | 15 + .../org/ils/order/rabbitmq/RabbitQueue.java | 28 ++ .../ils/order/rabbitmq/RabbitReceiver.java | 22 + .../org/ils/order/rabbitmq/RabbitSender.java | 29 ++ .../org/ils/order/result/GlobalException.java | 50 ++ .../org/ils/order/result/JwtVerifyResult.java | 54 +++ .../java/org/ils/order/result/Result.java | 152 ++++++ .../ils/order/service/MainLineService.java | 42 ++ .../ils/order/service/impl/BaseService.java | 17 + .../service/impl/MainLineServiceImpl.java | 58 +++ .../org/ils/order/utils/CommonConstant.java | 46 ++ .../org/ils/order/utils/IdGeneratorUtil.java | 37 ++ .../java/org/ils/order/utils/JwtUtil.java | 108 +++++ .../java/org/ils/order/utils/RedisUtil.java | 431 ++++++++++++++++++ .../ils/order/utils/SpringContextUtils.java | 77 ++++ src/main/resources/application-dev.yml | 101 ++++ src/main/resources/application.yml | 5 + .../java/org/ils/order/RabbitMqHelloTest.java | 31 ++ .../java/org/ils/order/RestTemplateTest.java | 45 ++ 37 files changed, 1925 insertions(+) create mode 100644 readme.md create mode 100644 src/main/java/org/ils/order/IlsOrderServiceApplication.java create mode 100644 src/main/java/org/ils/order/annotation/TokenAnnotation.java create mode 100644 src/main/java/org/ils/order/aspect/TokenAspect.java create mode 100644 src/main/java/org/ils/order/config/BaseConfig.java create mode 100644 src/main/java/org/ils/order/config/MyBatisPlusConfig.java create mode 100644 src/main/java/org/ils/order/config/RedisConfig.java create mode 100644 src/main/java/org/ils/order/config/RestTemplateConfig.java create mode 100644 src/main/java/org/ils/order/config/SwaggerConfig.java create mode 100644 src/main/java/org/ils/order/config/WebMvcConfig.java create mode 100644 src/main/java/org/ils/order/entity/BaseEntity.java create mode 100644 src/main/java/org/ils/order/entity/IlsMainLine.java create mode 100644 src/main/java/org/ils/order/handler/GlobalExceptionHandler.java create mode 100644 src/main/java/org/ils/order/handler/MysqlMetaObjectHandler.java create mode 100644 src/main/java/org/ils/order/mapper/IlsMainLineMapper.java create mode 100644 src/main/java/org/ils/order/model/DTO/BasePageDto.java create mode 100644 src/main/java/org/ils/order/model/DTO/MainLineDto.java create mode 100644 src/main/java/org/ils/order/model/DTO/MainLinePageDto.java create mode 100644 src/main/java/org/ils/order/model/DTO/OrderPageDto.java create mode 100644 src/main/java/org/ils/order/rabbitmq/RabbitQueue.java create mode 100644 src/main/java/org/ils/order/rabbitmq/RabbitReceiver.java create mode 100644 src/main/java/org/ils/order/rabbitmq/RabbitSender.java create mode 100644 src/main/java/org/ils/order/result/GlobalException.java create mode 100644 src/main/java/org/ils/order/result/JwtVerifyResult.java create mode 100644 src/main/java/org/ils/order/result/Result.java create mode 100644 src/main/java/org/ils/order/service/MainLineService.java create mode 100644 src/main/java/org/ils/order/service/impl/BaseService.java create mode 100644 src/main/java/org/ils/order/service/impl/MainLineServiceImpl.java create mode 100644 src/main/java/org/ils/order/utils/CommonConstant.java create mode 100644 src/main/java/org/ils/order/utils/IdGeneratorUtil.java create mode 100644 src/main/java/org/ils/order/utils/JwtUtil.java create mode 100644 src/main/java/org/ils/order/utils/RedisUtil.java create mode 100644 src/main/java/org/ils/order/utils/SpringContextUtils.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/test/java/org/ils/order/RabbitMqHelloTest.java create mode 100644 src/test/java/org/ils/order/RestTemplateTest.java diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..adcc9c9 --- /dev/null +++ b/readme.md @@ -0,0 +1,49 @@ +=============== +ils 订单服务 +- ils订单管理,包括excel下单,表单下单以及轨迹查询等功能 +- 更新时间2023-8-8 +## 使用步骤 +- java -jar ils-order-service-1.0.jar +- ## 接口文档地址 +- http://127.0.0.1:9097/doc.html +## 开发说明和约定 +- ## mybatis-plus 插件使用方法 +- 实现下面方法即可 + - @Mapper + public interface XXXMapper extends BaseMapper { + } + - 如果需要自定义,需要同时新增接口和xml方法 +- ## JwtUtil +- token工具类 +- ## TokenAnnotation 接口注解拦截 +- 在需要拦截的controller 加上注解@TokenAnnotation(description = "备注")即可 +- ## IdGeneratorUtil 插件说明 +- String batchId(String prefix) -- 生成递增批次号 prefix + 12位数字 +- long snowflakeId() -- 雪花算法唯一id +- ## RedisUtil +- redis工具类 +- ## hutool 工具类 +- 一个Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类,同时提供以下组件: +- 模块 介绍 +- hutool-aop JDK动态代理封装,提供非IOC下的切面支持 +- hutool-bloomFilter 布隆过滤,提供一些Hash算法的布隆过滤 +- hutool-cache 简单缓存实现 +- hutool-core 核心,包括Bean操作、日期、各种Util等 +- hutool-cron 定时任务模块,提供类Crontab表达式的定时任务 +- hutool-crypto 加密解密模块,提供对称、非对称和摘要算法封装 +- hutool-db JDBC封装后的数据操作,基于ActiveRecord思想 +- hutool-dfa 基于DFA模型的多关键字查找 +- hutool-extra 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等) +- hutool-http 基于HttpUrlConnection的Http客户端封装 +- hutool-log 自动识别日志实现的日志门面 +- hutool-script 脚本执行封装,例如Javascript +- hutool-setting 功能更强大的Setting配置文件和Properties封装 +- hutool-system 系统参数调用封装(JVM信息等) +- hutool-json JSON实现 +- hutool-captcha 图片验证码实现 +- hutool-poi 针对POI中Excel和Word的封装 +- hutool-socket 基于Java的NIO和AIO的Socket封装 +- hutool-jwt JSON Web Token (JWT)封装实现 +可以根据需求对每个模块单独引入,也可以通过引入hutool-all方式引入所有模块。 +- ## 开发使用规范 +- diff --git a/src/main/java/org/ils/order/IlsOrderServiceApplication.java b/src/main/java/org/ils/order/IlsOrderServiceApplication.java new file mode 100644 index 0000000..2515f92 --- /dev/null +++ b/src/main/java/org/ils/order/IlsOrderServiceApplication.java @@ -0,0 +1,15 @@ +package org.ils.order; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * 主程序 + * @author chenjf + */ +@SpringBootApplication +public class IlsOrderServiceApplication { + public static void main(String[] args) { + SpringApplication.run(IlsOrderServiceApplication.class, args); + } +} \ No newline at end of file diff --git a/src/main/java/org/ils/order/annotation/TokenAnnotation.java b/src/main/java/org/ils/order/annotation/TokenAnnotation.java new file mode 100644 index 0000000..ff3e247 --- /dev/null +++ b/src/main/java/org/ils/order/annotation/TokenAnnotation.java @@ -0,0 +1,15 @@ +package org.ils.order.annotation; + +import java.lang.annotation.*; + +/** + * token 全局拦截注解 + * @author chenjf + */ + +@Target({ElementType.PARAMETER, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface TokenAnnotation { + String description() default ""; +} diff --git a/src/main/java/org/ils/order/aspect/TokenAspect.java b/src/main/java/org/ils/order/aspect/TokenAspect.java new file mode 100644 index 0000000..46d5ce2 --- /dev/null +++ b/src/main/java/org/ils/order/aspect/TokenAspect.java @@ -0,0 +1,57 @@ +package org.ils.order.aspect; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.ils.order.result.GlobalException; +import org.ils.order.result.JwtVerifyResult; +import org.ils.order.utils.CommonConstant; +import org.ils.order.utils.JwtUtil; +import org.ils.order.utils.SpringContextUtils; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; + +/** + * token 全局拦截处理 + */ +@Slf4j +@Aspect +@Component +public class TokenAspect { + //controller层切点 + @Pointcut("@annotation(org.ils.order.annotation.TokenAnnotation)") + public void TokenAspect() { + } + + /** + * 前置通知 用于拦截Controller层记录用户的操作 + * + * @param joinPoint 切点 + */ + @Before("TokenAspect()") + public void doBeforeControl(JoinPoint joinPoint) throws GlobalException { + try { + log.info("Execute Controller: {}.{}()", joinPoint.getTarget().getClass().getName(), joinPoint.getSignature().getClass()); + //获取request + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + String token = request.getHeader(CommonConstant.ACCESS_TOKEN).toString(); + log.info("token: {}", token); + JwtVerifyResult jwtVerifyResult = JwtUtil.validateToken(token); + if(!jwtVerifyResult.getSuccess()){ + log.error("验证失败:"+jwtVerifyResult.toString()); + throw new GlobalException(CommonConstant.ACCESS_TOKEN + "错误" ); + } + } catch (Exception e) { + StringBuilder sb = new StringBuilder(); + sb.append(CommonConstant.ACCESS_TOKEN ); + sb.append(" error: " ); + sb.append(e.getMessage() ); + log.error("{} ", sb.toString()); + throw new GlobalException(sb.toString()); + } + } + +} diff --git a/src/main/java/org/ils/order/config/BaseConfig.java b/src/main/java/org/ils/order/config/BaseConfig.java new file mode 100644 index 0000000..ace5bac --- /dev/null +++ b/src/main/java/org/ils/order/config/BaseConfig.java @@ -0,0 +1,20 @@ +package org.ils.order.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * 系统获取yml基本参数 + * @author chenjf + * @datetime 2023/08/09 + */ +@Component +@Data +public class BaseConfig { + @Value("${spring.rabbitmq.queue.orderQueue}") + private String ilsOrderQueue; + + @Value("${ils.other.host.baiduUrl}") + private String baiduUrl; +} diff --git a/src/main/java/org/ils/order/config/MyBatisPlusConfig.java b/src/main/java/org/ils/order/config/MyBatisPlusConfig.java new file mode 100644 index 0000000..d2932f8 --- /dev/null +++ b/src/main/java/org/ils/order/config/MyBatisPlusConfig.java @@ -0,0 +1,34 @@ +package org.ils.order.config; + + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +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; + +import java.util.Collections; + +@EnableTransactionManagement +@Configuration +@MapperScan("org.ils.order.mapper") +public class MyBatisPlusConfig { + @Bean + public PaginationInnerInterceptor paginationInnerInterceptor() { + PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(); + // 设置最大单页限制数量,默认 500 条,-1 不受限制 + paginationInterceptor.setMaxLimit(-1L); + paginationInterceptor.setDbType(DbType.MYSQL); + // 开启 count 的 join 优化,只针对部分 left join + paginationInterceptor.setOptimizeJoin(true); + return paginationInterceptor; + } + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor(){ + MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); + mybatisPlusInterceptor.setInterceptors(Collections.singletonList(paginationInnerInterceptor())); + return mybatisPlusInterceptor; + } +} diff --git a/src/main/java/org/ils/order/config/RedisConfig.java b/src/main/java/org/ils/order/config/RedisConfig.java new file mode 100644 index 0000000..9db30bb --- /dev/null +++ b/src/main/java/org/ils/order/config/RedisConfig.java @@ -0,0 +1,46 @@ +package org.ils.order.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.net.UnknownHostException; + +/** + * @author chenjf + */ +@Configuration +public class RedisConfig { + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) + throws UnknownHostException { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConnectionFactory); + //Json序列化配置 + //注意:SpringBoot默认的redis序列化方式是jdk序列化有兴趣可以看默认RedisTemplate源码 + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); + jackson2JsonRedisSerializer.setObjectMapper(om); + StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); + //key采用string的序列化方式 + template.setKeySerializer(stringRedisSerializer); + //hash的key也采用string的序列化方式 + template.setHashKeySerializer(stringRedisSerializer); + //value序列化方式采用jackson + template.setValueSerializer(stringRedisSerializer); + //hash的value序列化方式采用jackson + template.setHashValueSerializer(jackson2JsonRedisSerializer); + template.afterPropertiesSet(); + return template; + } +} diff --git a/src/main/java/org/ils/order/config/RestTemplateConfig.java b/src/main/java/org/ils/order/config/RestTemplateConfig.java new file mode 100644 index 0000000..6cd3de8 --- /dev/null +++ b/src/main/java/org/ils/order/config/RestTemplateConfig.java @@ -0,0 +1,61 @@ +package org.ils.order.config; + +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; + +import org.springframework.web.client.RestTemplate; + + +/** + * restTemplate 数据池配置类 + * @author chenjf + */ +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(httpRequestFactory()); + } + + + @Bean + public ClientHttpRequestFactory httpRequestFactory() { + return new HttpComponentsClientHttpRequestFactory(httpClient()); + } + + + @Bean + public HttpClient httpClient() { + Registry registry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", SSLConnectionSocketFactory.getSocketFactory()) + .build(); + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); + //设置整个连接池最大连接数 + connectionManager.setMaxTotal(400); + + //路由是对maxTotal的细分 + connectionManager.setDefaultMaxPerRoute(100); + RequestConfig requestConfig = RequestConfig.custom() + .setSocketTimeout(3000) //返回数据的超时时间 + .setConnectTimeout(2000) //连接上服务器的超时时间 + .setConnectionRequestTimeout(1000) //从连接池中获取连接的超时时间 + .build(); + return HttpClientBuilder.create() + .setDefaultRequestConfig(requestConfig) + .setConnectionManager(connectionManager) + .build(); + } +} diff --git a/src/main/java/org/ils/order/config/SwaggerConfig.java b/src/main/java/org/ils/order/config/SwaggerConfig.java new file mode 100644 index 0000000..50a30c7 --- /dev/null +++ b/src/main/java/org/ils/order/config/SwaggerConfig.java @@ -0,0 +1,70 @@ +package org.ils.order.config; + + +import io.swagger.annotations.ApiOperation; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author chenjf + */ + +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + //配置了 Swagger 的Docket的bean实例 + @Bean + public Docket docket(){ + + ParameterBuilder ticketPar = new ParameterBuilder(); + List pars = new ArrayList<>(); + ticketPar.name("Authorization").description("token") + .modelRef(new ModelRef("string")).parameterType("header") + .required(false).build(); + pars.add(ticketPar.build()); + + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + //RequestHandlerSelectors, 配置要扫描接口的方式 + //basePackage:指定要扫描的包 + //any():扫描全部 + //withClassAnnotation: 扫描类上的注解 + //withMethodAnnotation: 扫描方法上的注解 + .apis(RequestHandlerSelectors.basePackage("org.ils.order")) + .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + .paths(PathSelectors.any()) + .build() + .globalOperationParameters(pars); + } + + //配置Swagger 信息=apiInfo + private ApiInfo apiInfo(){ + return new ApiInfo( + "ils engine Api", + "ils 订单服务接口文档", + "v1.0", + "127.0.0.1:9097/", + null,//contact + "Apache 2.0", + "http://www.apache.org/licenses/LICENSE-2.0", + new ArrayList() + ); + } +} diff --git a/src/main/java/org/ils/order/config/WebMvcConfig.java b/src/main/java/org/ils/order/config/WebMvcConfig.java new file mode 100644 index 0000000..8b495ed --- /dev/null +++ b/src/main/java/org/ils/order/config/WebMvcConfig.java @@ -0,0 +1,24 @@ +package org.ils.order.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @author chenjf + */ + + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + registry.addResourceHandler("doc.html") + .addResourceLocations("classpath:/META-INF/resources/"); + } +} diff --git a/src/main/java/org/ils/order/entity/BaseEntity.java b/src/main/java/org/ils/order/entity/BaseEntity.java new file mode 100644 index 0000000..4c84713 --- /dev/null +++ b/src/main/java/org/ils/order/entity/BaseEntity.java @@ -0,0 +1,27 @@ +package org.ils.order.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class BaseEntity implements Serializable { + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建时间") + private Long createTime; + + @TableField(fill = FieldFill.INSERT) + @ApiModelProperty(value = "创建人") + private String createBy; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "更新时间") + private Long updateTime; + + @TableField(fill = FieldFill.INSERT_UPDATE) + @ApiModelProperty(value = "更新人") + private String updateBy; +} diff --git a/src/main/java/org/ils/order/entity/IlsMainLine.java b/src/main/java/org/ils/order/entity/IlsMainLine.java new file mode 100644 index 0000000..63b4fb5 --- /dev/null +++ b/src/main/java/org/ils/order/entity/IlsMainLine.java @@ -0,0 +1,33 @@ +package org.ils.order.entity; + + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +@Data +@Builder +public class IlsMainLine extends BaseEntity implements Serializable { + + @JsonFormat(shape = JsonFormat.Shape.STRING) + @ApiModelProperty(value = "主键id", name = "id" ) + private Long id; + + @ApiModelProperty(value = "主线模型编码", name = "mainLineCode" ) + private String mainLineCode; + + @ApiModelProperty(value = "主线模型名称", name = "mainLineName" ) + private String mainLineName; + + @ApiModelProperty(value = "主线模型类型(0=海运1=空运2=首重续重)", name = "mainLineType" ) + private Integer mainLineType; + + @ApiModelProperty(value = "备注", name = "note" ) + private String note; + + + +} diff --git a/src/main/java/org/ils/order/handler/GlobalExceptionHandler.java b/src/main/java/org/ils/order/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..5fac2b2 --- /dev/null +++ b/src/main/java/org/ils/order/handler/GlobalExceptionHandler.java @@ -0,0 +1,27 @@ +package org.ils.order.handler; + +import lombok.extern.slf4j.Slf4j; +import org.ils.order.result.Result; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * 全局异常捕获 + * @author chenjf + */ +@Slf4j +@ControllerAdvice +public class GlobalExceptionHandler { + /** + * 处理除0异常捕获 + * @param exception + * @return + */ + @ExceptionHandler(value = Exception.class) + @ResponseBody + public Result exceptionHandler(Exception exception){ + log.error("exceptionHandler: {}", exception.getMessage()); + return Result.error(exception.getMessage()); + } +} diff --git a/src/main/java/org/ils/order/handler/MysqlMetaObjectHandler.java b/src/main/java/org/ils/order/handler/MysqlMetaObjectHandler.java new file mode 100644 index 0000000..017b43b --- /dev/null +++ b/src/main/java/org/ils/order/handler/MysqlMetaObjectHandler.java @@ -0,0 +1,36 @@ +package org.ils.order.handler; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class MysqlMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + log.info("start insert fill ...."); + this.strictInsertFill(metaObject, "createTime", Long.class, System.currentTimeMillis()); + // 或者 + this.strictInsertFill(metaObject, "createTime", () -> System.currentTimeMillis(), Long.class); + // 或者 + this.fillStrategy(metaObject, "createTime",System.currentTimeMillis()); + + metaObject.setValue("createBy", "admin"); + + } + + @Override + public void updateFill(MetaObject metaObject) { + log.info("start update fill ...."); + this.strictUpdateFill(metaObject, "updateTime", Long.class,System.currentTimeMillis()); + // 或者 + this.strictUpdateFill(metaObject, "updateTime", () -> System.currentTimeMillis(), Long.class); + // 或者 + this.fillStrategy(metaObject, "updateTime", System.currentTimeMillis()); + + metaObject.setValue("updateBy", "admin1"); + } +} diff --git a/src/main/java/org/ils/order/mapper/IlsMainLineMapper.java b/src/main/java/org/ils/order/mapper/IlsMainLineMapper.java new file mode 100644 index 0000000..107a8e3 --- /dev/null +++ b/src/main/java/org/ils/order/mapper/IlsMainLineMapper.java @@ -0,0 +1,11 @@ +package org.ils.order.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.ils.order.entity.IlsMainLine; + + +@Mapper +public interface IlsMainLineMapper extends BaseMapper { +} diff --git a/src/main/java/org/ils/order/model/DTO/BasePageDto.java b/src/main/java/org/ils/order/model/DTO/BasePageDto.java new file mode 100644 index 0000000..a1b7a07 --- /dev/null +++ b/src/main/java/org/ils/order/model/DTO/BasePageDto.java @@ -0,0 +1,16 @@ +package org.ils.order.model.DTO; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class BasePageDto implements Serializable { + + @ApiModelProperty(value = "当前页", name = "pageNo" , required = true) + private Integer pageNo; + + @ApiModelProperty(value = "分页大小", name = "pageSize" , required = true) + private Integer pageSize; +} diff --git a/src/main/java/org/ils/order/model/DTO/MainLineDto.java b/src/main/java/org/ils/order/model/DTO/MainLineDto.java new file mode 100644 index 0000000..6d699c0 --- /dev/null +++ b/src/main/java/org/ils/order/model/DTO/MainLineDto.java @@ -0,0 +1,21 @@ +package org.ils.order.model.DTO; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +@Data +@Builder +public class MainLineDto implements Serializable { + + @ApiModelProperty(value = "主线模型名称", name = "mainLineName" , required = true) + private String mainLineName; + + @ApiModelProperty(value = "主线模型类型(0=海运1=空运2=首重续重)", name = "mainLineType" , required = true) + private Integer mainLineType; + + @ApiModelProperty(value = "备注", name = "note" , required = true) + private String note; +} diff --git a/src/main/java/org/ils/order/model/DTO/MainLinePageDto.java b/src/main/java/org/ils/order/model/DTO/MainLinePageDto.java new file mode 100644 index 0000000..edd628e --- /dev/null +++ b/src/main/java/org/ils/order/model/DTO/MainLinePageDto.java @@ -0,0 +1,15 @@ +package org.ils.order.model.DTO; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class MainLinePageDto extends BasePageDto implements Serializable { + + @ApiModelProperty(value = "主线线模型名称", name = "mainLineName", required = true) + private String mainLineName; + + +} diff --git a/src/main/java/org/ils/order/model/DTO/OrderPageDto.java b/src/main/java/org/ils/order/model/DTO/OrderPageDto.java new file mode 100644 index 0000000..1b94402 --- /dev/null +++ b/src/main/java/org/ils/order/model/DTO/OrderPageDto.java @@ -0,0 +1,15 @@ +package org.ils.order.model.DTO; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class OrderPageDto extends BasePageDto implements Serializable { + + + @ApiModelProperty(value = "订单编号", name = "orderId" , required = true) + private String orderId; + +} diff --git a/src/main/java/org/ils/order/rabbitmq/RabbitQueue.java b/src/main/java/org/ils/order/rabbitmq/RabbitQueue.java new file mode 100644 index 0000000..8af87e6 --- /dev/null +++ b/src/main/java/org/ils/order/rabbitmq/RabbitQueue.java @@ -0,0 +1,28 @@ +package org.ils.order.rabbitmq; + +import org.ils.order.config.BaseConfig; +import org.springframework.amqp.core.Queue; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * rabbitmq 绑定队列 + * @author chenjf + * @datetime 2023/08/09 + */ +@Configuration +public class RabbitQueue { + + @Autowired + private BaseConfig baseConfig; + + /** + * 订单队列 + */ + @Bean + public Queue IlsOrderQueue() { + return new Queue(baseConfig.getIlsOrderQueue()); + } + +} diff --git a/src/main/java/org/ils/order/rabbitmq/RabbitReceiver.java b/src/main/java/org/ils/order/rabbitmq/RabbitReceiver.java new file mode 100644 index 0000000..60c6e28 --- /dev/null +++ b/src/main/java/org/ils/order/rabbitmq/RabbitReceiver.java @@ -0,0 +1,22 @@ +package org.ils.order.rabbitmq; + + +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Component; + +/** + * 订单队列接收消息 + * @author chenjf + * @datetime 2023/08/09 + */ +@Slf4j +@Component +@RabbitListener(queues = "${spring.rabbitmq.queue.orderQueue}") +public class RabbitReceiver { + @RabbitHandler + public void process(String json) { + log.info("Receiver: {}", json); + } +} diff --git a/src/main/java/org/ils/order/rabbitmq/RabbitSender.java b/src/main/java/org/ils/order/rabbitmq/RabbitSender.java new file mode 100644 index 0000000..f380489 --- /dev/null +++ b/src/main/java/org/ils/order/rabbitmq/RabbitSender.java @@ -0,0 +1,29 @@ +package org.ils.order.rabbitmq; + +import org.ils.order.config.BaseConfig; +import org.springframework.amqp.core.AmqpTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +/** + * rabbitmq 发送消息 + * @author chenjf + * @datetime 2023/08/09 + */ +@Component +public class RabbitSender { + @Autowired + private AmqpTemplate rabbitTemplate; + @Autowired + private BaseConfig baseConfig ; + + /** + * 队列发送消息 + * @param queueName 队列名称 + * @param json json字符串 + */ + public void sendOrderQueue(String queueName,String json) { + this.rabbitTemplate.convertAndSend(queueName, json); + } +} diff --git a/src/main/java/org/ils/order/result/GlobalException.java b/src/main/java/org/ils/order/result/GlobalException.java new file mode 100644 index 0000000..65754f3 --- /dev/null +++ b/src/main/java/org/ils/order/result/GlobalException.java @@ -0,0 +1,50 @@ +package org.ils.order.result; + +/** + * + * @describe 全局异常处理类 + * @author chenjf + * @since 2023/8/8 + */ +public class GlobalException extends Exception{ + private String code; + private String message; + + public GlobalException() { + super(); + } + + public GlobalException(String message) { + super(message); + this.message = message; + } + + public GlobalException(String code, String message) { + super(code + ": " + message); + this.code = code; + this.message = message; + } + + public GlobalException(String message, Throwable throwable) { + super(message, throwable); + this.message = message; + } + + public GlobalException(Throwable throwable) { + super(throwable); + } + + public String getCode() { + return code; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public String toString() { + return code + ": " + message; + } +} diff --git a/src/main/java/org/ils/order/result/JwtVerifyResult.java b/src/main/java/org/ils/order/result/JwtVerifyResult.java new file mode 100644 index 0000000..94f93fc --- /dev/null +++ b/src/main/java/org/ils/order/result/JwtVerifyResult.java @@ -0,0 +1,54 @@ +package org.ils.order.result; + +import java.util.Map; + +public class JwtVerifyResult { + /** 1 是否成功 **/ + private Boolean success; + /** 2 返回消息 **/ + private String msg; + /** 3 jwt负载 **/ + private Map payload; + + public JwtVerifyResult() { + } + + public JwtVerifyResult(Boolean success, String msg) { + this.success = success; + this.msg = msg; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public Map getPayload() { + return payload; + } + + public void setPayload(Map payload) { + this.payload = payload; + } + + @Override + public String toString() { + return "JwtResult{" + + "success=" + success + + ", msg='" + msg + '\'' + + ", payload=" + payload + + '}'; + } + +} diff --git a/src/main/java/org/ils/order/result/Result.java b/src/main/java/org/ils/order/result/Result.java new file mode 100644 index 0000000..d57ef04 --- /dev/null +++ b/src/main/java/org/ils/order/result/Result.java @@ -0,0 +1,152 @@ +package org.ils.order.result; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.ils.order.utils.CommonConstant; + +import java.io.Serializable; + +/** + * 接口返回数据格式 + * @author chenjf + * @date 2023/07/14 + * @param + */ +@Data +public class Result implements Serializable { + + private static final long serialVersionUID = 1L; + + + @ApiModelProperty(value = "成功标志") + private boolean success = true; + + + @ApiModelProperty(value = "返回处理消息") + private String message = ""; + + + @ApiModelProperty(value = "返回代码") + private Integer code = CommonConstant.HTTP_CODE_200; + + + @ApiModelProperty(value = "返回数据对象") + private T result; + + + @ApiModelProperty(value = "时间戳") + private long timestamp = System.currentTimeMillis(); + + public Result() { + } + + /** + * + * @param code 响应code + * @param message 消息 + */ + public Result(Integer code, String message) { + this.code = code; + this.message = message; + } + + /** + * + * @param message 消息 + */ + public Result success(String message) { + this.message = message; + this.code = CommonConstant.HTTP_CODE_200; + this.success = true; + return this; + } + + public static Result ok() { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.HTTP_CODE_200); + return r; + } + + public static Result ok(String msg) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.HTTP_CODE_200); + //Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D + r.setResult((T) msg); + r.setMessage(msg); + return r; + } + + public static Result ok(T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.HTTP_CODE_200); + r.setResult(data); + return r; + } + + public static Result OK() { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.HTTP_CODE_200); + return r; + } + + + public static Result OK(String msg) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.HTTP_CODE_200); + r.setMessage(msg); + r.setResult((T) msg); + return r; + } + + public static Result OK(T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.HTTP_CODE_200); + r.setResult(data); + return r; + } + + public static Result OK(String msg, T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.HTTP_CODE_200); + r.setMessage(msg); + r.setResult(data); + return r; + } + + public static Result error(String msg, T data) { + Result r = new Result(); + r.setSuccess(false); + r.setCode(CommonConstant.HTTP_CODE_201); + r.setMessage(msg); + r.setResult(data); + return r; + } + + public static Result error(String msg) { + return error(CommonConstant.HTTP_CODE_201, msg); + } + + public static Result error(int code, String msg) { + Result r = new Result(); + r.setCode(code); + r.setMessage(msg); + r.setSuccess(false); + return r; + } + + public Result error500(String message) { + this.message = message; + this.code = CommonConstant.HTTP_CODE_500; + this.success = false; + return this; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/ils/order/service/MainLineService.java b/src/main/java/org/ils/order/service/MainLineService.java new file mode 100644 index 0000000..5531dc4 --- /dev/null +++ b/src/main/java/org/ils/order/service/MainLineService.java @@ -0,0 +1,42 @@ +package org.ils.order.service.impl; + + +import org.ils.order.model.DTO.MainLineDto; +import org.ils.order.model.DTO.MainLinePageDto; + +/** + * 计费引擎主线计费主线模型接口 + * @author chenjf + */ +public interface MainLineService { + + /** + * 新增 + * @param model + * @return 返回成功结果 + */ + public T add(T model); + + /** + * 删除 + * @param model + * @return + */ + public T del(T model); + + /** + * 修改 + * @param id + * @param model + * @return + */ + public T edit(String id, MainLineDto model); + + + /** + * 列表 + * @param model + * @return + */ + public T list(MainLinePageDto model); +} diff --git a/src/main/java/org/ils/order/service/impl/BaseService.java b/src/main/java/org/ils/order/service/impl/BaseService.java new file mode 100644 index 0000000..8580a3c --- /dev/null +++ b/src/main/java/org/ils/order/service/impl/BaseService.java @@ -0,0 +1,17 @@ +package org.ils.order.service.impl; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 基础 service + * @author chenjf + */ +@Slf4j +@Service +public class BaseService { + + + + +} diff --git a/src/main/java/org/ils/order/service/impl/MainLineServiceImpl.java b/src/main/java/org/ils/order/service/impl/MainLineServiceImpl.java new file mode 100644 index 0000000..a28ff20 --- /dev/null +++ b/src/main/java/org/ils/order/service/impl/MainLineServiceImpl.java @@ -0,0 +1,58 @@ +package org.ils.order.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; + + +import org.ils.order.entity.IlsMainLine; +import org.ils.order.mapper.IlsMainLineMapper; +import org.ils.order.model.DTO.MainLineDto; +import org.ils.order.model.DTO.MainLinePageDto; +import org.ils.order.result.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + + + +/** + * 计费引擎主线计费规则属性接口 + * @author chenjf + */ +@Slf4j +@Service +public class MainLineServiceImpl implements org.ils.order.service.impl.MainLineService { + + @Autowired + private IlsMainLineMapper ilsMainLineMapper; + + + @Override + public Result add(Object model) { + + return Result.OK("success", null); + } + + @Override + public Result del(Object model) { + + return Result.OK("success", null); + } + + @Override + public Result edit(String id, MainLineDto model) { + return Result.OK("success", null); + } + + @Override + public Result list(MainLinePageDto model) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like("main_line_name", model.getMainLineName()); + queryWrapper.orderByDesc("id"); + Page page = new Page<>(model.getPageNo(), model.getPageSize()); + IPage pageList = ilsMainLineMapper.selectPage(page, queryWrapper); + return Result.OK("success", pageList); + } +} diff --git a/src/main/java/org/ils/order/utils/CommonConstant.java b/src/main/java/org/ils/order/utils/CommonConstant.java new file mode 100644 index 0000000..2f6740e --- /dev/null +++ b/src/main/java/org/ils/order/utils/CommonConstant.java @@ -0,0 +1,46 @@ +package org.ils.order.utils; + +/** + * 通用常量 + * @author chenjf + */ +public interface CommonConstant { + + /** + * 没有服务 + */ + Integer HTTP_CODE_500 = 500; + /** + * 响应正常 + */ + Integer HTTP_CODE_200 = 200; + + /** + * 无授权 + */ + Integer HTTP_CODE_510 = 510; + + + /** + * 400错误 + */ + Integer HTTP_CODE_400 = 400; + + /** + * 响应正常,错误提示 + */ + Integer HTTP_CODE_201 = 201; + + + /** + * 下划线关键字 + */ + String UNDER_LINE = "_"; + + /** + * header 令牌 + */ + String ACCESS_TOKEN = "Access-Token"; + + +} diff --git a/src/main/java/org/ils/order/utils/IdGeneratorUtil.java b/src/main/java/org/ils/order/utils/IdGeneratorUtil.java new file mode 100644 index 0000000..aa2c2b4 --- /dev/null +++ b/src/main/java/org/ils/order/utils/IdGeneratorUtil.java @@ -0,0 +1,37 @@ +package org.ils.order.utils; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.IdUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +@Component +public class IdGeneratorUtil { + private static volatile AtomicInteger atomicInteger = new AtomicInteger(1001); + private static Snowflake snowflake = IdUtil.createSnowflake(2, 1); + + public static void main(String[] args) { + log.info("{}", IdGeneratorUtil.batchId("TAI")); + + } + + /** + * 生成递增批次号 prefix + 12位数字 + * @param prefix 前缀 + */ + public static synchronized String batchId(String prefix) { + String no = DateTime.now().toString(DatePattern.PURE_DATE_PATTERN); + return prefix + no + atomicInteger.getAndIncrement(); + } + + /** + * 获取唯一主键id 19位 + */ + public static synchronized long snowflakeId() { + return snowflake.nextId(); + } +} diff --git a/src/main/java/org/ils/order/utils/JwtUtil.java b/src/main/java/org/ils/order/utils/JwtUtil.java new file mode 100644 index 0000000..3c7458f --- /dev/null +++ b/src/main/java/org/ils/order/utils/JwtUtil.java @@ -0,0 +1,108 @@ +package org.ils.order.utils; + + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.exceptions.ValidateException; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import cn.hutool.jwt.JWT; +import cn.hutool.jwt.JWTPayload; +import cn.hutool.jwt.RegisteredPayload; +import cn.hutool.jwt.signers.JWTSigner; +import cn.hutool.jwt.signers.JWTSignerUtil; +import lombok.extern.slf4j.Slf4j; +import org.ils.order.result.JwtVerifyResult; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Component +public class JwtUtil { + private static final JWTSigner jwtSigner = JWTSignerUtil.hs256("!34ADAS3ddfdssdfhii@#$$@#efh3".getBytes()); + private static final String AUTH_TOKEN_KEY = "ils"; + + private static final String APP_KEY = "ilsTestKey2023"; + private static final String APP_SECRET = "ilsTestKey2023"; + public static void main(String[] args) { + Map payload = new HashMap<>(); + payload.put("userName","ilsadmin"); + payload.put("passWord", "123456"); + String token = createToken(payload); + log.info("token: {}",token ); + + JwtVerifyResult jwtVerifyResult = validateToken(token); + if(jwtVerifyResult.getSuccess()){ + payload = jwtVerifyResult.getPayload(); + log.info("userName: {}, passWord: {}", payload.get("userName"), payload.get("passWord")); + }else{ + log.error("验证失败:"+jwtVerifyResult.toString()); + } + } + + /** + * 生成安全的 jwt token + * @param payload jwt负载 + * @return + */ + public static String createToken(Map payload) { + Date dateNow = new Date(); + String authToken = SecureUtil.md5(SecureUtil.sha256(APP_KEY + "_" + DateUtil.formatDateTime(dateNow) + "_" + APP_SECRET)); + payload.put(AUTH_TOKEN_KEY, authToken); + return JWT.create() + .addPayloads(payload) + .setIssuedAt(dateNow) + .setExpiresAt(DateUtil.endOfDay(dateNow)) + .sign(jwtSigner); + } + + /** + * jwt 验证,1)hash256签名,2)失效时间,3)自定义二重安全校验 + * @param token 生成的jwt token + * @return map :当error = "ok",会额外多出 payload + */ + public static JwtVerifyResult validateToken(String token) { + + try { + JWT jwt = JWT.of(token); + jwt.setSigner(jwtSigner); + + //1.验证hash256签名 + Boolean hs256Bool = jwt.verify(); + if (!hs256Bool) { + return new JwtVerifyResult(false, "hash256签名校验失败"); + } + //2.验证签名的时间,单位s + Boolean validateBool = jwt.validate(60*60*24); + if (!validateBool) { + return new JwtVerifyResult(false, "时间负载校验失败"); + } + //3.获取二重 authToken 认证校验 + JWTPayload jwtPayload = jwt.getPayload(); + Date subAtDate = jwtPayload.getClaimsJson().getDate(RegisteredPayload.ISSUED_AT); + + String atScource = String.valueOf(jwtPayload.getClaim(AUTH_TOKEN_KEY)); + String authToken = SecureUtil.md5(SecureUtil.sha256(APP_KEY + "_" +DateUtil.formatDateTime(subAtDate) + "_" + APP_SECRET)); + + if (StrUtil.isEmpty(atScource) || !atScource.equals(authToken)) { + return new JwtVerifyResult(false, "二重身份认证校验失败"); + } + + //4.将负载参数转换成map返回 + JSONObject payloadJson = jwtPayload.getClaimsJson(); + payloadJson.remove(AUTH_TOKEN_KEY); + JwtVerifyResult jwtVerifyResult = new JwtVerifyResult(true, "签名有效"); + jwtVerifyResult.setPayload(JSONUtil.toBean(payloadJson, new TypeReference>() { + }, true)); + return jwtVerifyResult; + + } catch (ValidateException e) { + return new JwtVerifyResult(true, "无效的签名"); + } + } +} diff --git a/src/main/java/org/ils/order/utils/RedisUtil.java b/src/main/java/org/ils/order/utils/RedisUtil.java new file mode 100644 index 0000000..a613c29 --- /dev/null +++ b/src/main/java/org/ils/order/utils/RedisUtil.java @@ -0,0 +1,431 @@ +package org.ils.order.utils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author chenjf + * @datetime 2023/07/27 + */ +@Component +public class RedisUtil { + + @Autowired + private RedisTemplate redisTemplate; + + + /** + * 指定缓存失效时间 @param key 键 @param time 时间(秒) @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key 获取过期时间 @param key 键 不能为null @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 @param key 键 @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除缓存 @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length ==0) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete((Collection) CollectionUtils.arrayToList(key)); + } + } + } + + + /** + * 普通缓存获取 @param key 键 @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 @param key 键 @param value 值 @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 普通缓存放入并设置时间 @param key 键 @param value 值 @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 递增 @param key 键 @param delta 要增加几(大于0) @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 @param key 键 @param delta 要减少几(小于0) @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + /* ================================Map=================================*/ + + /** + * HashGet @param key 键 不能为null @param item 项 不能为null @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 @param key 键 @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet @param key 键 @param map 对应多个键值 @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * HashSet 并设置时间 @param key 键 @param map 对应多个键值 @param time 时间(秒) @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 @param key 键 @param item 项 @param value 值 @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 @param key 键 @param item 项 @param value 值 @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除hash表中的值 @param key 键 不能为null @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 @param key 键 不能为null @param item 项 不能为null @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 @param key 键 @param item 项 @param by 要增加几(大于0) @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 @param key 键 @param item 项 @param by 要减少记(小于0) @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + + /** + * 根据key获取Set中的所有值 @param key 键 @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 @param key 键 @param value 值 @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将数据放入set缓存 @param key 键 @param values 值 可以是多个 @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 将set数据放入缓存 @param key 键 @param time 时间(秒) @param values 值 可以是多个 @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取set缓存的长度 @param key 键 @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 移除值为value的 @param key 键 @param values 值 可以是多个 @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + return redisTemplate.opsForSet().remove(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /* ===============================list=================================*/ + + /** + * 获取list缓存的内容 @param key 键 @param start 开始 @param end 结束 0 到 -代表所有值 @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取list缓存的长度 @param key 键 @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 通过索引 获取list中的值 @param key 键 @param index 索引 index>=0时, 0 表头, 第二个元素,依次类推;index<0时,-,表尾,-倒数第二个元素,依次类推 @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将list放入缓存 @param key 键 @param value 值 @param time 时间(秒) @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 @param key 键 @param value 值 @param time 时间(秒) @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 @param key 键 @param value 值 @param time 时间(秒) @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 @param key 键 @param value 值 @param time 时间(秒) @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 @param key 键 @param index 索引 @param value 值 @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移除N个值为value @param key 键 @param count 移除多少个 @param value 值 @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } +} diff --git a/src/main/java/org/ils/order/utils/SpringContextUtils.java b/src/main/java/org/ils/order/utils/SpringContextUtils.java new file mode 100644 index 0000000..98d1547 --- /dev/null +++ b/src/main/java/org/ils/order/utils/SpringContextUtils.java @@ -0,0 +1,77 @@ +package org.ils.order.utils; + +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; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @Description: spring上下文工具类 + * @author: jeecg-boot + */ +@Component +public class SpringContextUtils implements ApplicationContextAware { + + /** + * 上下文对象实例 + */ + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringContextUtils.applicationContext = applicationContext; + } + + /** + * 获取applicationContext + */ + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + /** + * 获取HttpServletRequest + */ + public static HttpServletRequest getHttpServletRequest() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } + /** + * 获取HttpServletResponse + */ + public static HttpServletResponse getHttpServletResponse() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + } + + + + public static String getOrigin(){ + HttpServletRequest request = getHttpServletRequest(); + return request.getHeader("Origin"); + } + + /** + * 通过name获取 Bean. + */ + public static Object getBean(String name) { + return getApplicationContext().getBean(name); + } + + /** + * 通过class获取Bean. + */ + public static T getBean(Class clazz) { + return getApplicationContext().getBean(clazz); + } + + /** + * 通过name,以及Clazz返回指定的Bean + */ + public static T getBean(String name, Class clazz) { + return getApplicationContext().getBean(name, clazz); + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..c3d4912 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,101 @@ +server: + port: 9097 +spring: + mvc: + pathmatch: + matching-strategy: ant_path_matcher + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB + datasource: + url: jdbc:mysql://127.0.0.1:3306/ils_order?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True&useSSL=false + username: root + password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver + druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置) + # 连接池的配置信息 + # 初始化大小,最小,最大 + initial-size: 50 + min-idle: 5 + maxActive: 200 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + # 打开PSCache,并且指定每个连接上PSCache的大小 + poolPreparedStatements: true + maxPoolPreparedStatementPerConnectionSize: 20 + # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 + #filters: stat,wall,slf4j + filters: stat,slf4j + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 + # connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 + #redis 配置 + redis: + database: 9 + host: 127.0.0.1 + timeout: 60s + lettuce: + pool: + max-active: 8 #最大连接数据库连接数,设 -1 为没有限制 + max-idle: 30 #最大等待连接中的数量,设 0 为没有限制 + max-wait: 10000 #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 + min-idle: 0 #最小等待连接中的数量,设 0 为没有限制 + shutdown-timeout: 100ms + password: '' + port: 6379 + # rabbitmq 配置 + rabbitmq: + virtual-host: / + host: localhost + port: 5672 + username: guest + password: guest + mode: single # cluster 集群模式 + #超时时间 + connection-timeout: 10000s + #开启消息确认模式 + publisher-confirms: false + #开启消息送达提示 + publisher-returns: true + #开启不可达消息不会被broker给删除 + template: + mandatory: true + # 表示消息确认方式,其有三种配置方式,分别是none、manual和auto;默认auto + listener: + simple: + acknowledge-mode: auto + # 配置rabbitmq队列 + queue: + orderQueue: ilsOrderQueue #订单队列 +# mybatis-plus 配置 +mybatis-plus: + mapper-locations: mapper/*.xml + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + map-underscore-to-camel-case: true + type-aliases-package: org.ils.billing.entity +## swagger文档的部分配置 #### +knife4j: + # 生产环境可改为 false(改为false后 swagger将不能使用) + enable: true +logging: + level: + com.baomidou.samples.metainfo: debug +# 调用外部连接url +ils: + other: + host: + baiduUrl: https://www.baidu.com + + + + + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..c64a441 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,5 @@ +spring: + application: + name: ils-order-service + profiles: + active: 'dev' \ No newline at end of file diff --git a/src/test/java/org/ils/order/RabbitMqHelloTest.java b/src/test/java/org/ils/order/RabbitMqHelloTest.java new file mode 100644 index 0000000..679d0ef --- /dev/null +++ b/src/test/java/org/ils/order/RabbitMqHelloTest.java @@ -0,0 +1,31 @@ +package org.ils.order; + +import cn.hutool.json.JSONObject; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.ils.order.config.BaseConfig; +import org.ils.order.rabbitmq.RabbitSender; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@Slf4j +@RunWith(SpringRunner.class) +@SpringBootTest +public class RabbitMqHelloTest{ + @Autowired + private BaseConfig baseConfig; + + @Autowired + private RabbitSender rabbitSender; + @Test + public void test(){ + JSONObject json = new JSONObject(); + json.put("userName","test123"); + json.put("passWord","123456"); + rabbitSender.sendOrderQueue(baseConfig.getIlsOrderQueue(), JSON.toJSONString(json)); + log.info( "send: {}", true); + } +} \ No newline at end of file diff --git a/src/test/java/org/ils/order/RestTemplateTest.java b/src/test/java/org/ils/order/RestTemplateTest.java new file mode 100644 index 0000000..a03148e --- /dev/null +++ b/src/test/java/org/ils/order/RestTemplateTest.java @@ -0,0 +1,45 @@ +package org.ils.order; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.ils.order.config.BaseConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +@Slf4j +@RunWith(SpringRunner.class) +@SpringBootTest +public class RestTemplateTest { + @Autowired + private RestTemplate restTemplate; + + @Autowired + private BaseConfig baseConfig; + @Test + public void test(){ + log.info("url :{}", baseConfig.getBaiduUrl()); + String content = restTemplate.getForObject( baseConfig.getBaiduUrl(), String.class); + log.info("get content :{}", content); + + JSONObject param = new JSONObject(); + param.put("alarmType", 2); + param.put("optType", 2); + param.put("optDesc", "自动处理"); + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type","application/json;charset=UTF-8"); + headers.add("Accept", MediaType.APPLICATION_JSON.toString()); + HttpEntity formEntity = new HttpEntity(param.toString(),headers); + ResponseEntity response2 = restTemplate.postForEntity( baseConfig.getBaiduUrl(), formEntity, JSONObject.class); + log.info("response2--->{}",response2.getBody()); + + + } +} \ No newline at end of file