提交 17bf4b1a authored 作者: liuhaiquan's avatar liuhaiquan

上传履约服务

上级
*/target/
!.mvn/wrapper/maven-wrapper.jar
/logs/
/errorLogs/
.mvn/
mvnw
mvnw.cmd
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
*.log
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.clx.cy</groupId>
<artifactId>performance-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>performance-api</name>
<parent>
<groupId>com.msl</groupId>
<artifactId>msl-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.msl</groupId>
<artifactId>msl-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.msl</groupId>
<artifactId>convertor-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Releases</name>
<url>http://139.129.222.24:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-releases</id>
<name>Snapshot</name>
<url>http://139.129.222.24:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.clx.order.common;
/**
* 数据可解析
*
* @author wanglq
* Date 2023/7/20
* Time 17:37
*/
public interface DataResolvable {
/**
* @return 供应商编码
*/
String getSupplierCode();
/**
* @return 设备类型编码
*/
String getTypeCode();
/**
* @return 设备型号
*/
String getModelNo();
/**
* @return 设备序列号
*/
String getDeviceNo();
/**
* @return 是否批量
*/
boolean isBatch();
/**
* @return 数据
*/
String getData();
}
package com.clx.order.feign;
import com.msl.common.result.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.constraints.NotBlank;
@FeignClient(name = "msl-document")
public interface DocumentFeign {
/**
* 获取用户协议
*
* @param agreementNo
* @return
*/
@RequestMapping(method = {RequestMethod.GET}, value = {"/msl-document/agreement/getCurrentUserVersion"})
String getCurrentUserVersion(@RequestParam("agreementNo") @NotBlank(message = "编号不可为空") String agreementNo);
/**
* @Author kavin
* @Description 获取oss的domain
* @Param []
* @return
**/
@GetMapping({"/msl-document/fileUpload/getHost"})
Result<String> getHost();
}
package com.clx.order.util;
public class BusinessUtil {
}
*/target/
!.mvn/wrapper/maven-wrapper.jar
/logs/
.mvn/
mvnw
mvnw.cmd
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
HELP.md
target/
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>clx-performance</artifactId>
<groupId>com.clx.cy</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>performance-web</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.msl</groupId>
<artifactId>msl-common</artifactId>
</dependency>
<dependency>
<groupId>com.clx.cy</groupId>
<artifactId>performance-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.msl</groupId>
<artifactId>user-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.msl</groupId>
<artifactId>msl-esign-v3-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.msl</groupId>
<artifactId>trace-spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.msl</groupId>-->
<!-- <artifactId>message-api</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>com.msl</groupId>
<artifactId>coding-api</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.msl</groupId>-->
<!-- <artifactId>cache-spring-boot-starter</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-cache</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<!-- nacos注册中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- nacos配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
</dependency>
<!-- mapStruct 对象转换 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
</dependency>
<dependency>
<groupId>com.msl</groupId>
<artifactId>dao-spring-boot-starter</artifactId>
<!-- <version>1.0.1</version>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.msl</groupId>
<artifactId>job-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.clx.order;
import com.msl.common.config.ViewScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableDiscoveryClient
@EnableAsync
//@ComponentScans({
// @ComponentScan("com.clx.user.*"),
// @ComponentScan("com.msl.common.utils.*"),
//})
@ComponentScan({"com.clx.order.*", "com.msl.*"})
@EnableFeignClients(basePackages = {"com.msl.*","com.clx.order.*"})
@ViewScan(basePackage = "com.clx.user.view")
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
//package com.clx.user.aspect;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.TypeReference;
//import com.google.gson.Gson;
//import com.msl.common.base.Optional;
//import com.msl.common.dto.HttpDTO;
//import com.msl.common.result.Result;
//import com.msl.common.utils.EncryptUtil;
//import com.clx.user.dao.ThirdPartyEntryDao;
//import com.clx.user.enums.ThirdRequestStatusEnum;
//import com.clx.user.enums.ThirdRequestTypeEnum;
//import com.clx.user.enums.result.QualityResultEnum;
//import com.clx.user.model.ThirdPartRequestLog;
//import com.clx.user.model.ThirdPartyEntry;
//import com.clx.user.service.ThirdPartRequestLogService;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.io.BufferedReader;
//import java.io.InputStreamReader;
//import java.util.Objects;
//import java.util.UUID;
//
//import static com.clx.user.constant.CommonConstants.*;
//
//
//@Aspect
//@Component
//@Slf4j
//public class HttpAspect {
//
// @Autowired
// private ThirdPartyEntryDao thirdPartyEntryDao;
// @Autowired
// private ThirdPartRequestLogService thirdPartRequestLogService;
//
// public HttpAspect() {
// }
//
// @Pointcut("execution(public * com.clx.user.controller.encrypt.*.*(..))")
// public void all() {
// }
//
// @Around("all()")
// public Object trackInfo(ProceedingJoinPoint pjp) throws Throwable {
// // 从body里面取数据
// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// HttpServletRequest request = attributes.getRequest();
// String pathUrl = request.getRequestURI();
// BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
// String line = null;
// StringBuilder sb = new StringBuilder();
// while ((line = br.readLine()) != null) {
// sb.append(line);
// }
// br.close();
//
// HttpDTO httpDTO = JSON.parseObject(sb.toString(), HttpDTO.class);
// log.info("http接收到的加密参数-->{}", httpDTO);
// ThirdPartyEntry thirdPartyEntry = thirdPartyEntryDao.getByAppId(httpDTO.getUserNo()).orElseThrow(QualityResultEnum.SIGN_NULL);
// // 验证签名
// if (!Objects.equals(httpDTO.getSign(), EncryptUtil.sign(thirdPartyEntry.getAppId(), thirdPartyEntry.getSecret(), httpDTO.getData(), httpDTO.getTimestamp()))) {
// return back(Result.fail(QualityResultEnum.SIGN_ERROR), null, pathUrl, thirdPartyEntry);
// }
//
// // 验证请求时间戳是否超过10分钟
// long currentTimeMillis = System.currentTimeMillis();
// if (currentTimeMillis < httpDTO.getTimestamp() || (currentTimeMillis - httpDTO.getTimestamp()) > 600000) {
// return back(Result.fail(QualityResultEnum.TIMESTAMP_ERROR), null, pathUrl, thirdPartyEntry);
// }
//
// // 解密后参数
// String decrypt = EncryptUtil.decrypt(httpDTO.getData(), thirdPartyEntry.getSecret());
// String param = JSON.parseObject(decrypt, String.class);
// log.info("http接收到解密后的参数-->{}", param);
// request.setAttribute(APP_ID, thirdPartyEntry.getAppId());
// request.setAttribute(DATA, param);
//
// Object proceed;
// try {
// proceed = pjp.proceed();
// } catch (Exception e) {
// log.error("", e);
// proceed = Result.fail();
// }
// return back(proceed, param, pathUrl, thirdPartyEntry);
// }
//
// private HttpDTO back(Object obj, String param, String pathUrl, ThirdPartyEntry thirdPartyEntry) throws Exception {
// Optional.ofNullable(obj)
// .filter(p -> StringUtils.isNotBlank(param))
// .filter(p -> Objects.nonNull(thirdPartyEntry))
// .map(JSON::toJSONString)
// .mapWithObj(new TypeReference<Result<Object>>() {
// }, this::covertResult)
// .peek(p -> thirdPartRequestLogService.save(new ThirdPartRequestLog()
// .setRequestId(UUID.randomUUID().toString())
// .setAppId(thirdPartyEntry.getAppId())
// .setRequestType(ThirdRequestTypeEnum.RECEIVE.getCode())
// .setUrl(pathUrl)
// .setRequestContent(param)
// .setResponseContent(JSON.toJSONString(p))
// .setStatusCode(p.getCode())
// .setStatus(p.succeed() ? ThirdRequestStatusEnum.SUCCESS.getCode() : ThirdRequestStatusEnum.FAIL.getCode())
// .setRetryTimes(0)));
// return EncryptUtil.buildDTO(thirdPartyEntry.getAppId(), JSON.toJSONString(obj), thirdPartyEntry.getSecret(), System.currentTimeMillis());
// }
//
// private <T> Result<T> covertResult(String result, TypeReference<Result<T>> reference) {
// return new Gson().fromJson(result, reference.getType());
// }
//}
package com.clx.order.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @ClassName AliCertificateOcrProperties
* @Description
* @Author kavin
* @Date 2023/8/22 19:00
* @Version 1.0
*/
@ConfigurationProperties(prefix = "ali.certificate.ocr")
@Data
@Component
public class AliCertificateOcrProperties {
private String appKey;
private String appSecret;
private String appCode;
private String idCardHost; //身份证
private String idCardPath;
private String driverLicenceHost; //驾照
private String driverLicencePath;
private String truckHost; //车辆
private String truckPath;
private String transportHost; //运营证
private String transportPath;
}
package com.clx.order.config;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
@EnableConfigurationProperties({CacheProperties.class})
@Configuration
@EnableCaching
public class CacheRedisConfiguration {
/**
* redis注解缓存配置
*
* @param cacheProperties
* @return
*/
@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
/**
* redisTemplate配置
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(RedisSerializer.json());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
redisTemplate.setHashValueSerializer(RedisSerializer.json());
return redisTemplate;
}
}
package com.clx.order.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Config {
}
package com.clx.order.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
* @author wanglq
* Date 2023/7/28
* Time 23:38
*/
@RefreshScope
@Configuration
@Getter
@Setter
public class DeviceConfig {
@Value("${device.kaiYuan.errorDeviceNo:1192206067}")
private String kaiYuanErrorDeviceNo;
}
package com.clx.order.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 硬件设备redis配置
*
* @author wanglq
* Date 2023/7/20
* Time 11:56
*/
@Configuration
@ConfigurationProperties(prefix = "device.redis")
@Getter
@Setter
public class DeviceRedisConfig {
private String type = "single";
private String password;
private String nodes;
public boolean isCluster() {
return "cluster".equals(type);
}
}
package com.clx.order.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.NumberSerializers;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
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;
import java.io.IOException;
@Configuration
public class JsonSerializerConfig {
final static Long jsTopLimit = 999999999999999L;
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder){
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
//全局配置序列化返回json处理
SimpleModule simpleModule = new SimpleModule();
//JSON Long ==> String
simpleModule.addSerializer(Long.class, MslNoToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
return objectMapper;
}
static class MslNoToStringSerializer extends JsonSerializer<Object> {
private static final MslNoToStringSerializer instance = new MslNoToStringSerializer();
private final ToStringSerializer stringSerializer = ToStringSerializer.instance;
private final NumberSerializers.LongSerializer longSerializer = new NumberSerializers.LongSerializer(Long.class);
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
Long no = (Long) o;
if (no < jsTopLimit){
longSerializer.serialize(o, jsonGenerator, serializerProvider);
}else {
stringSerializer.serialize(o, jsonGenerator, serializerProvider);
}
}
}
}
package com.clx.order.config;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestParameterBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ParameterType;
import springfox.documentation.service.RequestParameter;
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;
@Profile({"dev", "test", "release"})
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Knife4jConfig {
@Value("${spring.application.name}")
private String appName;
@Bean
public Docket createRestApi() {
List<RequestParameter> requestParameters = new ArrayList<>();
requestParameters.add(new RequestParameterBuilder()
.name("token")
.description("用户登录凭证(token)")
.in(ParameterType.HEADER)
.query(parameterSpecificationBuilder -> parameterSpecificationBuilder.defaultValue("143215321432151234")
.allowEmptyValue(false))
.required(true)
.build());
requestParameters.add(new RequestParameterBuilder()
.name("product-code")
.description("产品code")
.in(ParameterType.HEADER)
.query(parameterSpecificationBuilder -> parameterSpecificationBuilder.defaultValue("msl-quality")
.allowEmptyValue(false))
.required(true)
.build());
Docket docker = new Docket(DocumentationType.SWAGGER_2)
.forCodeGeneration(true)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
docker.globalRequestParameters(requestParameters);
return docker;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("诚联信承运用户说明文档")
.description("<div style='font-size=14px;color:red'>诚联信承运用户接口说明</div>")
.termsOfServiceUrl("http://api.clx.cn")
.version("1.0")
.build();
}
}
package com.clx.order.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.aop.interceptor.PerformanceMonitorInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@MapperScan("com.clx.order.mapper")
public class MybatisPlusConfig {
/**
* Mybatis-Plus中分页插件PaginationInterceptor, MybatisPlusInterceptor在SpringBoot中的使用
* https://blog.csdn.net/qq_41359651/article/details/112260207
* mybatis-plus分页插件<br>
* 文档:http://mp.baomidou.com<br>
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分页插件(根据实际情况指定数据库类型,具体查看DbType枚举)
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
paginationInnerInterceptor.setDbType(DbType.MYSQL);
//乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//防止全表更新
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
paginationInnerInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInnerInterceptor.setMaxLimit(1000L);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
/**
* 打印 sql,性能分析拦截器,不建议生产使用
* 设置 dev test 环境开启
*/
@Bean
@Profile({"dev", "test"})
public PerformanceMonitorInterceptor performanceInterceptor() {
return new PerformanceMonitorInterceptor();
}
}
package com.clx.order.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @Author liumingchao
* @Date 2023/7/26 11:45
*/
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "notice")
public class NoticeConfig {
private Sms sms = new Sms();
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "notice.sms")
public static class Sms {
private boolean enable = true;
private Template template = new Template();
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "notice.sms.template")
public static class Template {
/**
* 通知客户化验结果
*/
private String assayResultNotice = "assayResultNotice";
}
}
}
package com.clx.order.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @Author liumingchao
* @Date 2023/7/13 14:48
*/
@Configuration
@Getter
@Setter
@ConfigurationProperties(prefix = "plat.company")
public class PlatCompanyConfig {
private Long companyNo;
}
package com.clx.order.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
@Configuration
public class RedissonConfig {
/**
* redisson协议前缀
*/
private static final String SCHEMA_PREFIX = "redis://";
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient(RedisProperties redisProperties) {
Config config = new Config();
RedisProperties.Cluster redisPropertiesCluster = redisProperties.getCluster();
if (redisPropertiesCluster != null) {
//集群redis
ClusterServersConfig clusterServersConfig = config.useClusterServers();
for (String cluster : redisPropertiesCluster.getNodes()) {
clusterServersConfig.addNodeAddress(SCHEMA_PREFIX + cluster);
}
if (StringUtils.hasText(redisProperties.getPassword())) {
clusterServersConfig.setPassword(redisProperties.getPassword());
}
} else if (StringUtils.hasText(redisProperties.getHost())) {
//单点redis
SingleServerConfig singleServerConfig = config.useSingleServer().setTimeout(10000).
setAddress(SCHEMA_PREFIX + redisProperties.getHost() + ":" + redisProperties.getPort());
if (StringUtils.hasText(redisProperties.getPassword())) {
singleServerConfig.setPassword(redisProperties.getPassword());
}
singleServerConfig.setDatabase(redisProperties.getDatabase());
}
config.setLockWatchdogTimeout(30000);
return Redisson.create(config);
}
}
package com.clx.order.config;
import com.msl.common.trace.context.TracedThreadPoolExecutor;
import org.apache.skywalking.apm.toolkit.trace.RunnableWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author wanglq
* Date 2022/6/30
* Time 11:14 上午
*/
@Configuration
public class ThreadPool {
public static final ThreadPoolExecutor COMMON;
public static final Scheduler SCHEDULER;
static {
COMMON = new TracedThreadPoolExecutor(10, 30, 120,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(500),
new CustomizableThreadFactory("common-pool-"),
new ThreadPoolExecutor.CallerRunsPolicy()) {
@Override
public void execute(Runnable command) {
super.execute(RunnableWrapper.of(command));
}
};
SCHEDULER = Schedulers.fromExecutor(COMMON);
}
@Bean("common")
public ThreadPoolExecutor getThreadPool() {
return COMMON;
}
}
package com.clx.order.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.validation.Validation;
import javax.validation.Validator;
/**
* 快速校验,参数错误不校验剩余参数直接抛出异常
*
* @author wanglq
* Date 2022/5/23
* Time 14:35
*/
@Configuration
public class ValidConfig {
@Bean
public Validator validator() {
return Validation.byProvider(HibernateValidator.class)
.configure()
//快速失败模式
.failFast(true)
.buildValidatorFactory()
.getValidator();
}
}
package com.clx.order.config.exception;
import cn.dev33.satoken.exception.NotLoginException;
import com.msl.common.enums.ResultCodeEnum;
import com.msl.common.exception.ServiceSystemException;
import com.msl.common.result.Result;
import com.msl.user.enums.result.AuthorityResultEnum;
import com.msl.user.exception.LogoutSignException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@Autowired
private RequestMappingHandlerMapping handlerMapping;
@ExceptionHandler(value = ServiceSystemException.class)
public Result exceptionHandler(ServiceSystemException e) {
log.info("ServiceSystemException异常, code:{}, msg:{}, detail:{}", e.getResultEnum().getCode(), e.getResultEnum().getMsg(), e.getDetail(),e.getException());
if (e.getException() != null){
log.info("【ExceptionHandler】全局自定义业务异常捕获", e.getResultEnum());
}
return Result.fail(e.getResultEnum(), e.getDetail());
}
@ExceptionHandler(value = LogoutSignException.class)
public Result exceptionHandler(LogoutSignException e) {
log.info("======特殊异常,捕获到此异常,请将踢出登陆=====");
if (e.getException() != null){
log.info("【ExceptionHandler】全局自定义业务异常捕获", e.getResultEnum());
}
return Result.fail(AuthorityResultEnum.LOGOUT_SIGN);
}
@ExceptionHandler(value = Exception.class)
public Result exceptionHandler(Exception e) {
log.info("【ExceptionHandler】全局通用异常捕获", e);
return Result.fail(ResultCodeEnum.FAIL.getMsg());
}
/**
* token相关异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(NotLoginException.class)
public Result<String> handlerNotLoginException(NotLoginException e) {
log.info("NotLoginException异常-->{}", e.getMessage());
// 判断场景值,定制化异常信息
String message = e.getMessage();
switch (e.getType()) {
case NotLoginException.NOT_TOKEN:
message = NotLoginException.NOT_TOKEN_MESSAGE;
break;
case NotLoginException.INVALID_TOKEN:
message = NotLoginException.INVALID_TOKEN_MESSAGE;
break;
case NotLoginException.TOKEN_TIMEOUT:
message = NotLoginException.TOKEN_TIMEOUT_MESSAGE;
break;
case NotLoginException.BE_REPLACED:
message = NotLoginException.BE_REPLACED_MESSAGE;
break;
case NotLoginException.KICK_OUT:
message = NotLoginException.KICK_OUT_MESSAGE;
break;
default:
message = NotLoginException.DEFAULT_MESSAGE;
break;
}
return Result.fail(AuthorityResultEnum.TOKEN_ERROR, message);
}
/**
* 统一处理请求参数校验(普通传参)
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleConstraintViolationException(ConstraintViolationException e) {
StringBuilder sb = new StringBuilder();
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
for (ConstraintViolation<?> violation : violations) {
// Path path = violation.getPropertyPath();
// String[] pathArr = path.toString().split("\\.");
// sb.append(pathArr[1]).append(violation.getMessage()).append(",");
sb.append(violation.getMessage()).append(",");
}
String errMsg = sb.substring(0, sb.length() - 1);
return Result.fail(ResultCodeEnum.ILLEGAL_PARAMETER, errMsg);
}
/**
* 统一处理请求参数校验(被@RequestBody注解的实体对象传参)
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
StringBuilder sb = new StringBuilder();
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
for (FieldError error : fieldErrors) {
// sb.append(error.getField()).append(error.getDefaultMessage()).append(",");
sb.append(error.getDefaultMessage()).append(",");
}
String errMsg = sb.substring(0, sb.length() - 1);
return Result.fail(ResultCodeEnum.ILLEGAL_PARAMETER, errMsg);
}
/**
* 统一处理请求参数校验(普通实体对象传参)
*/
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleBindException(BindException e) {
StringBuilder sb = new StringBuilder();
List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
for (FieldError error : fieldErrors) {
// sb.append(error.getField()).append(error.getDefaultMessage()).append(",");
sb.append(error.getDefaultMessage()).append(",");
}
String errMsg = sb.substring(0, sb.length() - 1);
return Result.fail(ResultCodeEnum.ILLEGAL_PARAMETER, errMsg);
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public Result<String> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
log.info("请求方式错误-->{}", e.getMessage());
// 获取当前请求的方法
String requestMethod = request.getMethod();
// 获取接口支持的请求方式
List<String> supportedMethods = getSupportedMethods(request);
String supportedMethodsString = String.join(", ", supportedMethods);
return Result.fail(ResultCodeEnum.ILLEGAL_METHOD, "请求方法错误,不支持请求方式:"+requestMethod+",请使用正确的请求方式:"+supportedMethodsString);
}
private List<String> getSupportedMethods(HttpServletRequest request) {
RequestMappingInfo info = handlerMapping.getHandlerMethods().keySet().stream()
.filter(mappingInfo -> mappingInfo.getPatternsCondition().getMatchingCondition(request) != null)
.findFirst()
.orElse(null);
if (info != null) {
RequestMethodsRequestCondition condition = info.getMethodsCondition();
return condition.getMethods().stream()
.map(Enum::toString)
.collect(Collectors.toList());
}
return null;
}
}
package com.clx.order.controller.pc;
import com.clx.order.service.OrderGoodsService;
import com.msl.common.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName GoodsOrderController
* @Description
* @Author kavin
* @Date 2023/9/17 17:16
* @Version 1.0
*/
@Slf4j
@RestController
@RequestMapping("/pc/goodsOrder")
@Validated
@Api(tags = "PC-货单")
public class GoodsOrderController {
@Autowired
OrderGoodsService orderGoodsService;
@ApiOperation(value = "提交货单",notes = "<br>By:刘海泉")
@PostMapping("/saveGoodsOrder")
public Result saveGoodName(@RequestBody @Validated String msg) {
return Result.ok();
}
}
package com.clx.order.dao;
import com.msl.common.dao.BaseDao;
import com.clx.order.mapper.OrderGoodsMapper;
import com.clx.order.model.OrderGoods;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface OrderGoodsDao extends BaseDao<OrderGoodsMapper, OrderGoods, Integer> {
}
package com.clx.order.dao;
import com.msl.common.dao.BaseDao;
import com.clx.order.mapper.OrderGoodsDriverTruckMapper;
import com.clx.order.model.OrderGoodsDriverTruck;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface OrderGoodsDriverTruckDao extends BaseDao<OrderGoodsDriverTruckMapper, OrderGoodsDriverTruck, Integer> {
}
package com.clx.order.dao;
import com.msl.common.dao.BaseDao;
import com.clx.order.mapper.SeniorLogisticsManagerMapper;
import com.clx.order.model.SeniorLogisticsManager;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface SeniorLogisticsManagerDao extends BaseDao<SeniorLogisticsManagerMapper, SeniorLogisticsManager, Integer> {
}
package com.clx.order.dao.impl;
import com.msl.common.dao.BaseDao;
import com.msl.common.dao.impl.BaseDaoImpl;
import com.clx.order.dao.OrderGoodsDao;
import com.clx.order.mapper.OrderGoodsMapper;
import com.clx.order.model.OrderGoods;
import org.springframework.stereotype.Repository;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Repository
public class OrderGoodsDaoImpl extends BaseDaoImpl<OrderGoodsMapper, OrderGoods, Integer> implements BaseDao<OrderGoodsMapper, OrderGoods, Integer> {
}
package com.clx.order.dao.impl;
import com.msl.common.dao.BaseDao;
import com.msl.common.dao.impl.BaseDaoImpl;
import com.clx.order.dao.OrderGoodsDriverTruckDao;
import com.clx.order.mapper.OrderGoodsDriverTruckMapper;
import com.clx.order.model.OrderGoodsDriverTruck;
import org.springframework.stereotype.Repository;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Repository
public class OrderGoodsDriverTruckDaoImpl extends BaseDaoImpl<OrderGoodsDriverTruckMapper, OrderGoodsDriverTruck, Integer> implements BaseDao<OrderGoodsDriverTruckMapper, OrderGoodsDriverTruck, Integer> {
}
package com.clx.order.dao.impl;
import com.msl.common.dao.BaseDao;
import com.msl.common.dao.impl.BaseDaoImpl;
import com.clx.order.dao.SeniorLogisticsManagerDao;
import com.clx.order.mapper.SeniorLogisticsManagerMapper;
import com.clx.order.model.SeniorLogisticsManager;
import org.springframework.stereotype.Repository;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Repository
public class SeniorLogisticsManagerDaoImpl extends BaseDaoImpl<SeniorLogisticsManagerMapper, SeniorLogisticsManager, Integer> implements BaseDao<SeniorLogisticsManagerMapper, SeniorLogisticsManager, Integer> {
}
package com.clx.order.extranal.user;
import com.msl.common.base.Optional;
import com.msl.user.param.user.external.PageProductUsersParam;
import com.msl.user.vo.company.external.ListUserCompanyVo;
import com.msl.user.vo.user.UserVo;
import com.msl.user.vo.user.external.PageProductUserVo;
import com.msl.user.vo.user.external.UserDetailInfoVo;
import java.util.List;
/**
* @Author liumingchao
* @Date 2023/7/12 11:23
*/
public interface UserService {
/**
* 根据用户编号查询用户信息
*/
Optional<UserVo> getUserByNo(Long userNo, boolean containDeleted);
/**
* 根据用户编号查询实名认证信息
*/
Optional<List<PageProductUserVo>> pageProductUsers(PageProductUsersParam param);
Optional<UserDetailInfoVo> getUserDetailInfo(Long userNo);
void bindUserProduct(Long userNo, String productCode);
Optional<List<ListUserCompanyVo>> listUserCompany(Long userNo);
}
package com.clx.order.extranal.user.impl;
import com.clx.order.extranal.user.UserService;
import com.msl.common.base.Optional;
import com.msl.user.param.user.external.PageProductUsersParam;
import com.msl.user.vo.company.external.ListUserCompanyVo;
import com.msl.user.vo.user.UserVo;
import com.msl.user.vo.user.external.PageProductUserVo;
import com.msl.user.vo.user.external.UserDetailInfoVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Slf4j
@AllArgsConstructor
public class UserServiceImpl implements UserService {
@Override
public Optional<UserVo> getUserByNo(Long userNo, boolean containDeleted) {
return null;
}
@Override
public Optional<List<PageProductUserVo>> pageProductUsers(PageProductUsersParam param) {
return null;
}
@Override
public Optional<UserDetailInfoVo> getUserDetailInfo(Long userNo) {
return null;
}
@Override
public void bindUserProduct(Long userNo, String productCode) {
}
@Override
public Optional<List<ListUserCompanyVo>> listUserCompany(Long userNo) {
return null;
}
}
package com.clx.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.clx.order.model.OrderGoodsDriverTruck;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface OrderGoodsDriverTruckMapper extends BaseMapper<OrderGoodsDriverTruck> {
}
package com.clx.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.clx.order.model.OrderGoods;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface OrderGoodsMapper extends BaseMapper<OrderGoods> {
}
package com.clx.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.clx.order.model.SeniorLogisticsManager;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface SeniorLogisticsManagerMapper extends BaseMapper<SeniorLogisticsManager> {
}
package com.clx.order.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.msl.common.config.KeyColumn;
import com.msl.common.model.HasKey;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("order_goods")
public class OrderGoods implements HasKey<Integer> {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("order_no")
@ApiModelProperty("订单编号")
private String orderNo;
@TableField("order_goods_no")
@ApiModelProperty("货单编号")
private String orderGoodsNo;
@TableField("order_goods_status")
@ApiModelProperty("货单状态")
private Integer orderGoodsStatus;
@TableField("extract_weight")
@ApiModelProperty("提取吨数")
private BigDecimal extractWeight;
@TableField("residue_transport_weight")
@ApiModelProperty("剩余拉运吨数")
private BigDecimal residueTransportWeight;
@TableField("send_address_id")
@ApiModelProperty("发货地址ID")
private Integer sendAddressId;
@TableField("send_address_shorter")
@ApiModelProperty("发货地址简称")
private String sendAddressShorter;
@TableField("send_longitude")
@ApiModelProperty("发货地址经度")
private BigDecimal sendLongitude;
@TableField("send_latitude")
@ApiModelProperty("发货地址纬度")
private BigDecimal sendLatitude;
@TableField("receive_address_id")
@ApiModelProperty("收货地址ID")
private Integer receiveAddressId;
@TableField("receive_address_shorter")
@ApiModelProperty("收货地址简称")
private String receiveAddressShorter;
@TableField("receive_longitude")
@ApiModelProperty("收货地址经度")
private BigDecimal receiveLongitude;
@TableField("receive_latitude")
@ApiModelProperty("收货地址纬度")
private BigDecimal receiveLatitude;
@TableField("goods_name")
@ApiModelProperty("货物名称")
private String goodsName;
@TableField("pending_order_way")
@ApiModelProperty("挂单方式 1公开派单 2定向派单")
private Integer pendingOrderWay;
@TableField("directional_expire_time")
@ApiModelProperty("定向运单失效时间")
private LocalDateTime directionalExpireTime;
@TableField("last_arrive_send_time")
@ApiModelProperty("最晚到达货源地时间/运单的最晚装货时间")
private LocalDateTime lastArriveSendTime;
@TableField("pending_order_time")
@ApiModelProperty("挂单时间")
private LocalDateTime pendingOrderTime;
@TableField("extract_way")
@ApiModelProperty("提取方式 1提取全部 2提取部分")
private Integer extractWay;
@TableField("need_truck_num")
@ApiModelProperty("需要车辆/辆")
private Integer needTruckNum;
@TableField("senior_logistics_manager_id")
@ApiModelProperty("高级物流经理id")
private Integer seniorLogisticsManagerId;
@TableField("senior_logistics_manager_name")
@ApiModelProperty("高级物流经理姓名")
private String seniorLogisticsManagerName;
@TableField("pending_order_freight")
@ApiModelProperty("挂单运费")
private BigDecimal pendingOrderFreight;
@TableField("user_no")
@ApiModelProperty("创建人用户编号")
private Long userNo;
@TableField("user_name")
@ApiModelProperty("创建人姓名")
private String userName;
@TableField("create_time")
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@TableField("modified_time")
@ApiModelProperty("修改时间")
private LocalDateTime modifiedTime;
@Override
@KeyColumn("id")
public Integer gainKey() {
return this.id;
}
}
package com.clx.order.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.msl.common.config.KeyColumn;
import com.msl.common.model.HasKey;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("order_goods_driver_truck")
public class OrderGoodsDriverTruck implements HasKey<Integer> {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("order_no")
@ApiModelProperty("订单编号")
private String orderNo;
@TableField("order_goods_no")
@ApiModelProperty("货单编号")
private String orderGoodsNo;
@TableField("truck_id")
@ApiModelProperty("车辆ID")
private Integer truckId;
@TableField("truck_no")
@ApiModelProperty("车牌号")
private String truckNo;
@TableField("order_user_no")
@ApiModelProperty("接单人用户编号")
private Long orderUserNo;
@TableField("create_time")
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@TableField("modified_time")
@ApiModelProperty("修改时间")
private LocalDateTime modifiedTime;
@Override
@KeyColumn("id")
public Integer gainKey() {
return this.id;
}
}
package com.clx.order.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.msl.common.config.KeyColumn;
import com.msl.common.model.HasKey;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("senior_logistics_manager")
public class SeniorLogisticsManager implements HasKey<Integer> {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField("user_no")
@ApiModelProperty("用户编号")
private String userNo;
@TableField("user_name")
@ApiModelProperty("用户姓名")
private String userName;
@TableField("mobile")
@ApiModelProperty("联系电话")
private String mobile;
@TableField("create_by")
@ApiModelProperty("创建者编号")
private Long createBy;
@TableField("create_name")
@ApiModelProperty("创建者姓名")
private String createName;
@TableField("create_time")
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@TableField("modified_time")
@ApiModelProperty("修改时间")
private LocalDateTime modifiedTime;
@Override
@KeyColumn("id")
public Integer gainKey() {
return this.id;
}
}
package com.clx.order.service;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface OrderGoodsDriverTruckService {
}
package com.clx.order.service;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface OrderGoodsService {
}
package com.clx.order.service;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
public interface SeniorLogisticsManagerService {
}
package com.clx.order.service.impl;
import com.msl.common.service.impl.BaseServiceImpl;
import com.clx.order.dao.OrderGoodsDriverTruckDao;
import com.clx.order.model.OrderGoodsDriverTruck;
import com.clx.order.service.OrderGoodsDriverTruckService;
import org.springframework.stereotype.Service;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Service
public class OrderGoodsDriverTruckServiceImpl implements OrderGoodsDriverTruckService {
}
package com.clx.order.service.impl;
import com.msl.common.service.impl.BaseServiceImpl;
import com.clx.order.dao.OrderGoodsDao;
import com.clx.order.model.OrderGoods;
import com.clx.order.service.OrderGoodsService;
import org.springframework.stereotype.Service;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Service
public class OrderGoodsServiceImpl implements OrderGoodsService {
}
package com.clx.order.service.impl;
import com.clx.order.service.SeniorLogisticsManagerService;
import org.springframework.stereotype.Service;
/**
* @author kavin
* Date 2023-09-17
* Time 16:45
*/
@Service
public class SeniorLogisticsManagerServiceImpl implements SeniorLogisticsManagerService {
}
package com.clx.order.utils;
import java.math.BigDecimal;
/**
* @ClassName MoneyConvertUtils
* @Description 金额转换工具类
* @Author kavin
* @Date 2023/9/17 16:10
* @Version 1.0
*/
public class MoneyConvertUtils {
/**
* @Author kavin
* @Description 元转分
* @Param [data, exp]
* @return
**/
public static BigDecimal convertCent(BigDecimal data) {
return convert(data,2);
}
public static BigDecimal convert(BigDecimal data, int exp) {
if (data == null) {
return null;
}
return exp == 0 ? data : (exp < 0 ? data.movePointRight(-exp) : data.movePointLeft(exp));
}
}
package com.clx.order.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class RedisUtil {
public static final String NAMESPACE_SEPARATOR = "clx_order::";
private final ThreadLocal<String> lockSeqThreadLocal = new ThreadLocal<>();
private final static String COMPARE_AND_DELETE =
"if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) " + "else return 0 end";
@Autowired
private StringRedisTemplate redisTemplate;
private ObjectMapper objectMapper;
public void setValue(String key, Object value) throws Exception {
objectMapper = new ObjectMapper();
this.redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(value));
}
public void setValue(String key, Object value, Long timeout, TimeUnit timeUnit) throws JsonProcessingException {
objectMapper = new ObjectMapper();
this.redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(value), timeout, timeUnit);
}
public boolean setIfAbsent(String key, Object value, Long timeout, TimeUnit timeUnit) throws JsonProcessingException {
boolean result = this.redisTemplate.opsForValue().setIfAbsent(key, objectMapper.writeValueAsString(value));
if (result) this.redisTemplate.expire(key, timeout, timeUnit);
return result;
}
public <T> T getValue(String key, Class<T> tClass) throws IOException {
String value = getValue(key);
if (value == null) {
return null;
}
objectMapper = new ObjectMapper();
return objectMapper.readValue(value, tClass);
}
public <T> T getValue(String key, TypeReference typeReference) throws IOException {
String value = getValue(key);
if (value == null) {
return null;
}
objectMapper = new ObjectMapper();
return (T) objectMapper.readValue(value, typeReference);
}
private String getValue(String key) {
return this.redisTemplate.opsForValue().get(key);
}
public boolean delete(String key) {
this.redisTemplate.delete(key);
return true;
}
public boolean lock(String key, String lockSeqId) {
return setAtomicLockKey(key, lockSeqId);
}
public boolean lock(String key, String lockSeqId, int second) {
return setAtomicLockKey(key, lockSeqId, second);
}
private void setLockSeqId(String lockSeqId) {
lockSeqThreadLocal.set(lockSeqId);
}
private String getLockSeqId() {
return lockSeqThreadLocal.get();
}
public Boolean unlock(String key, String uuid) {
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
return redisConnection.eval(COMPARE_AND_DELETE.getBytes(), ReturnType.BOOLEAN, 1, key.getBytes(), uuid.getBytes());
}
private Boolean setAtomicLockKey(String lockKey, String uuid) {
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
return redisConnection.set(lockKey.getBytes(),
uuid.getBytes(),
Expiration.seconds(60),
RedisStringCommands.SetOption.SET_IF_ABSENT);
}
private Boolean setAtomicLockKey(String lockKey, String uuid, int second) {
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
return redisConnection.set(lockKey.getBytes(),
uuid.getBytes(),
Expiration.seconds(second),
RedisStringCommands.SetOption.SET_IF_ABSENT);
}
/**
* @return
* @Author kavin
* @Description 获取某个key 的过期时间
* @Param [key]
**/
public long getExpireTime(String key) {
return redisTemplate.opsForValue().getOperations().getExpire(key);
}
/**
* 多服务器集群,使用下面的方法,代替System.currentTimeMillis(),获取redis时间,避免多服务的时间不一致问题!!!
* @return
*/
public long currtTimeForRedis(){
return redisTemplate.execute((RedisCallback<Long>) redisConnection -> redisConnection.time());
}
/**
* @Author kavin
* @Description key是否存在
* @Param [key]
* @return
**/
public boolean exists(String key){
return redisTemplate.hasKey(key);
}
/**
* @Author kavin
* @Description 原子性自增
* @Param [key]
* @return
**/
public Long incr(String key){
return redisTemplate.opsForValue().increment(key);
}
}
package com.clx.order.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* @Author liumingchao
* @Date 2023/7/21 13:22
*/
public class RoundingUtil {
/**
* 化验结果修约
* @param value
* @param scale
* @return
*/
public static BigDecimal round(BigDecimal value, int scale) {
BigDecimal roundedValue = value.setScale(scale, RoundingMode.HALF_EVEN); // 四舍六入五单双
// 获取末位有效数字后面的第一位数字
int firstDigit = roundedValue.movePointRight(scale + 1).intValue() % 10;
if (firstDigit > 5) {
// 末位有效数字后面的第一位数字大于5,增加1
roundedValue = roundedValue.add(BigDecimal.ONE);
} else if (firstDigit < 5) {
// 末位有效数字后面的第一位数字小于5,直接舍去
} else {
// 末位有效数字后面的第一位数字等于5
int nextDigit = roundedValue.movePointRight(scale + 2).intValue() % 10;
if (nextDigit != 0) {
// 5后面的数字不全为0,增加1
roundedValue = roundedValue.add(BigDecimal.ONE);
} else {
// 5后面的数字全部为0
int leftDigit = roundedValue.movePointRight(scale).intValue() % 10;
if (leftDigit % 2 != 0) {
// 5前面一位为奇数,增加1
roundedValue = roundedValue.add(BigDecimal.ONE);
}
// 5前面一位为偶数(包括0),直接舍去
}
}
// 特殊处理末位有效数字在个位或者十位的情况
if (scale == 1 || scale == 0) {
roundedValue = roundedValue.setScale(0, RoundingMode.DOWN);
}
return roundedValue.setScale(scale, RoundingMode.DOWN); // 设置最终结果的保留小数位数
}
private static int roundIntValue(int value, int scale) {
// 获取末位有效数字后面的第一位数字
int firstDigit = value % 10;
if (firstDigit > 5) {
// 末位有效数字后面的第一位数字大于5,增加1
value = value + 10 - firstDigit;
} else if (firstDigit < 5) {
// 末位有效数字后面的第一位数字小于5,直接舍去
value = value - firstDigit;
} else {
// 末位有效数字后面的第一位数字等于5
int nextDigit = (value / 10) % 10;
if (nextDigit != 0) {
// 5后面的数字不全为0,增加1
value = value + 10 - firstDigit;
} else {
// 5后面的数字全部为0
int leftDigit = (value / 100) % 10;
if (leftDigit % 2 != 0) {
// 5前面一位为奇数,增加1
value = value + 10 - firstDigit;
} else {
// 5前面一位为偶数(包括0),直接舍去
value = value - firstDigit;
}
}
}
// 修约到个位时需要将其他位数设为0
if (scale == 0) {
value = value - (value % 10);
}
return value;
}
public static void main(String[] args) {
BigDecimal value1 = new BigDecimal("10.544500");
BigDecimal value2 = new BigDecimal("15.542");
BigDecimal value3 = new BigDecimal("5.500");
BigDecimal value4 = new BigDecimal("2251.2251525");
BigDecimal value5 = new BigDecimal("2251.525");
System.out.println("修约后的值1: " + round(value1, 3)); // 输出:修约后的值1: 10.56
System.out.println("修约后的值2: " + round(value2, 2)); // 输出:修约后的值2: 15.54
System.out.println("修约后的值3: " + round(value3, 2)); // 输出:修约后的值3: 5.50
System.out.println("修约后的值4: " + round(value4, 0)); // 输出:修约后的值4: 2.52
System.out.println("修约后的值4: " + round(value4, 3)); // 输出:修约后的值4: 2.52
System.out.println("修约后的值4: " + round(value4, 4)); // 输出:修约后的值4: 2.52
System.out.println(roundIntValue(value5.setScale(0, RoundingMode.DOWN).intValue(), 0));
System.out.println(roundIntValue(value5.setScale(0, RoundingMode.DOWN).intValue(), 1));
}
}
package com.clx.order.utils.excel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* 将数据以Excel的格式写入输出流
* EasyExcel参考文档:https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write
*
* @author wangrubin
* @date 2022-08-02
*/
@Slf4j
@Component
public class ExcelExportHandler {
/**
* 下载Excel格式的数据
*
* @param response response
* @param fileName 文件名(支持中文)
* @param data 待下载的数据
* @param clazz 封装数据的POJO
* @param <T> 数据泛型
*/
public <T> void export(HttpServletResponse response, String fileName,
List<T> data, Class<T> clazz) {
try {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
// 这里需要设置不关闭流
EasyExcel.write(response.getOutputStream(), clazz)
.sheet("Sheet1")
// 设置单元格宽度自适应
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
// 设置单元格高度和字体
.registerWriteHandler(getHeightAndFontStrategy())
.doWrite(data);
log.info("下载{}条记录到文件{}", data.size(), fileName);
} catch (Exception e) {
// 重置response
log.warn("文件下载失败,异常原因:{}" , ExceptionUtils.getStackTrace(e));
}
}
/**
* 自定义Excel导出策略,设置表头和数据行的字体和高度
*
* @return Excel导出策略
*/
private HorizontalCellStyleStrategy getHeightAndFontStrategy() {
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 11);
headWriteFont.setBold(true);
headWriteCellStyle.setWriteFont(headWriteFont);
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
WriteFont contentWriteFont = new WriteFont();
contentWriteFont.setFontHeightInPoints((short) 11);
contentWriteCellStyle.setWriteFont(contentWriteFont);
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
}
}
\ No newline at end of file
server:
port: 8081
spring:
rabbitmq:
host: 192.168.9.20
port: 5672
username: clxmq
password: clxmq711
redis:
host: 47.92.223.27
port: 6379
password: clx!2022clx
jedis:
pool:
max-idle: 100
min-idle: 1
max-active: 1000
max-wait: -1
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://rm-8vb9qx47d6dh4b9s25o.mysql.zhangbei.rds.aliyuncs.com:3306/clx_order?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
username: clxdevelop
password: CLXdevelop#20231
druid:
initial-size: 4
min-idle: 4
max-active: 8
max-wait: 10000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 1800000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache。
pool-prepared-statements: true
# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
max-pool-prepared-statement-per-connection-size: 20
filters: stat,wall
# filter相关配置
filter:
stat:
enabled: true
db-type: mysql
log-slow-sql: true
slow-sql-millis: 500
merge-sql: true
slf4j:
enabled: true
statement-log-error-enabled: true
statement-create-after-log-enabled: false
statement-close-after-log-enabled: false
result-set-open-after-log-enabled: false
result-set-close-after-log-enabled: false
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "/druid/*"
session-stat-enable: true
session-stat-max-count: 1000
# 监控页面相关配置
stat-view-servlet:
enabled: true
allow: ""
url-pattern: /druid/*
reset-enable: false
login-username: clx
login-password: Apm!Q@Wm888
aop-patterns: "com.msl.report.dao.*"
xxl:
job:
admin:
address: http://job.devclx.cn/xxl-job
executor:
access-token: default_token
app-name: clx-performance
log-path: ./logs/clx-performance/job/
log-retention-days: 15
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: token
# token有效期,单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒,默认-1 代表不限制 (例如可以设置为1800代表30分钟内无操作就过期)
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: simple-uuid
# 是否打印操作日志
is-log: false
# 是否在初始化配置时打印版本字符画
is-print: false
alone-redis:
# Redis数据库索引(默认为0)
database: 0
# Redis服务器地址
host: 192.168.9.30
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码(默认为空)
password: clx!2022clx
# 连接超时时间
timeout: 10s
# 日志级别
logging:
level:
root: INFO
server:
port: 80
servlet:
context-path: /${spring.application.name}
spring:
profiles:
active: dev
application:
name: clx-performance
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: nacos.devclx.cn:8848
username: nacos
password: nacos
register-enabled: false
# namespace: ${spring.profiles.active}
config:
file-extension: yml
server-addr: nacos.devclx.cn:8848
username: nacos
password: nacos
shared-configs:
# - common-redis-${spring.profiles.active}.yml
# - common-mq-${spring.profiles.active}.yml
# - common-druid-${spring.profiles.active}.yml
# - common-satoken-${spring.profiles.active}.yml
# - common-esign-${spring.profiles.active}.yml
namespace: new-clx-dev
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
说明:
1、日志级别及文件
日志记录采用分级记录,级别与日志文件名相对应,不同级别的日志信息记录到不同的日志文件中
例如:error级别记录到log_error_xxx.log或log_error.log(该文件为当前记录的日志文件),而log_error_xxx.log为归档日志,
日志文件按日期记录,同一天内,若日志文件大小等于或大于2M,则按0、1、2...顺序分别命名
例如log-level-2013-12-21.0.log
其它级别的日志也是如此。
2、文件路径
若开发、测试用,在Eclipse中运行项目,则到Eclipse的安装路径查找logs文件夹,以相对路径../logs。
若部署到Tomcat下,则在Tomcat下的logs文件中
3、Appender
FILEERROR对应error级别,文件名以log-error-xxx.log形式命名
FILEWARN对应warn级别,文件名以log-warn-xxx.log形式命名
FILEINFO对应info级别,文件名以log-info-xxx.log形式命名
FILEDEBUG对应debug级别,文件名以log-debug-xxx.log形式命名
stdout将日志信息输出到控制上,为方便开发测试使用
-->
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<contextName>order-service</contextName>
<property name="LOG_PATH" value="/logs" />
<!--设置系统日志目录-->
<property name="APPDIR" value="clx-performance" />
<!-- 日志记录器,日期滚动记录 -->
<appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${APPDIR}/log_error.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过20M,若超过20M,日志文件会以索引0开始,
命名日志文件,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>20MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器,日期滚动记录 -->
<appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${APPDIR}/log_warn.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过20M,若超过20M,日志文件会以索引0开始,
命名日志文件,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>20MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器,日期滚动记录 -->
<appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/${APPDIR}/log_info.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,例如今天是2013-12-21日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
而2013-12-21的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 除按日志记录之外,还配置了日志文件不能超过20M,若超过20M,日志文件会以索引0开始,
命名日志文件,例如log-error-2013-12-21.0.log -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>20MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger Line:%-3L - %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--encoder 默认配置为PatternLayoutEncoder-->
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
</appender>
<!-- <logger name="org.springframework" level="WARN" /> -->
<!-- <logger name="org.hibernate" level="WARN" /> -->
<!-- 生产环境下,将此级别配置为适合的级别,以免日志文件太多或影响程序性能 -->
<root level="INFO">
<appender-ref ref="FILEERROR" />
<appender-ref ref="FILEWARN" />
<appender-ref ref="FILEINFO" />
生产环境将请stdout,testfile去掉
<appender-ref ref="STDOUT" />
</root>
</configuration>
\ No newline at end of file
package com.clx.order;
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;
@SpringBootTest
@RunWith(SpringRunner.class)
public class JobTest {
@Autowired
private QuotationJob quotationJob;
@Test
public void test1() {
quotationJob.quotationExpired();
}
}
package com.clx.order;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class OrderWebApplicationTests {
@Test
void contextLoads() {
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.msl</groupId>
<artifactId>msl-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.clx.cy</groupId>
<artifactId>clx-performance</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>clx-performance</name>
<modules>
<module>performance-api</module>
<module>performance-web</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论