Commit 2b4d6c05 authored by 周健威's avatar 周健威

Merge remote-tracking branch 'origin/base-modify' into base-modify

parents bad3764c 27587260
......@@ -8,4 +8,4 @@ target/
.classpath
ace-modules/ace-tool/src/main/resources/application-dev.yml
src/main/test/**
/logs
logs/**
package com.github.wxiaoqi.security.auth;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.feign.IUserService;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
......@@ -15,6 +14,7 @@ import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@AddBasicConfiguration
@MapperScan("com.github.wxiaoqi.security.auth.mapper")
//@EnableAutoConfiguration
public class AuthBootstrap {
......
package com.github.wxiaoqi.security.auth.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class DenyFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.github.wxiaoqi") ? FilterReply.DENY : FilterReply.ACCEPT;
}
}
\ No newline at end of file
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -18,27 +19,28 @@
</appender>
<appender name="SYSTEM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.auth.filter.DenyFilter"></filter>
<filter class="com.github.wxiaoqi.security.common.filter.DenyFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/sys.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
</appender>
<appender name="WEB_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.auth.filter.AcceptFilter"></filter>
<filter class="com.github.wxiaoqi.security.common.filter.AcceptFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="SYSTEM_FILE" />
......
......@@ -33,7 +33,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
......
package com.github.wxiaoqi.security.common.annotation;
import com.github.wxiaoqi.security.common.config.global.GlobalBasicConfiguration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
@EnableAspectJAutoProxy
@Import(GlobalBasicConfiguration.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AddBasicConfiguration {}
\ No newline at end of file
package com.github.wxiaoqi.security.common.config.global;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.env.Environment;
public class GlobalBasicConfiguration implements ApplicationRunner{
private static Logger log = LoggerFactory.getLogger(GlobalBasicConfiguration.class);
private static Environment env;
@Autowired
private void setEnv(Environment env) {
GlobalBasicConfiguration.env = env;
}
@Override
public void run(ApplicationArguments args) throws Exception {
showApplicationProperties("数据库连接地址: ", "spring.datasource.url");
showApplicationProperties("Redis连接主机: ", "spring.redis.host");
showApplicationProperties("Redis连接端口: ", "spring.redis.port");
showApplicationProperties("rabbitmq连接主机", "spring.rabbitmq.host");
showApplicationProperties("rabbitmq连接虚拟机", "spring.rabbitmq.virtual-host");
}
public static void showApplicationProperties(String key, String value) {
if(env != null) {
log.info(key + "{}", env.getProperty(value));
}
}
}
......@@ -7,6 +7,10 @@ import ch.qos.logback.core.spi.FilterReply;
public class AcceptFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.xxfc.platform") ? FilterReply.ACCEPT : FilterReply.DENY;
if(event.getLoggerName().startsWith("com.xxfc.platform") || event.getLoggerName().startsWith("com.github.wxiaoqi")) {
return FilterReply.ACCEPT;
} else {
return FilterReply.DENY;
}
}
}
\ No newline at end of file
......@@ -7,6 +7,10 @@ import ch.qos.logback.core.spi.FilterReply;
public class DenyFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.xxfc.platform") ? FilterReply.DENY : FilterReply.ACCEPT;
if (event.getLoggerName().startsWith("com.alibaba.nacos") || event.getLoggerName().startsWith("com.xxfc.platform") || event.getLoggerName().startsWith("com.github.wxiaoqi")) {
return FilterReply.DENY;
} else {
return FilterReply.ACCEPT;
}
}
}
\ No newline at end of file
package com.github.wxiaoqi.security.auth.filter;
package com.github.wxiaoqi.security.common.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class AcceptFilter extends Filter<ILoggingEvent> {
public class NacosLogFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.github.wxiaoqi") ? FilterReply.ACCEPT : FilterReply.DENY;
if (event.getLoggerName().startsWith("com.alibaba.nacos")) {
return FilterReply.DENY;
} else {
return FilterReply.ACCEPT;
}
}
}
\ No newline at end of file
package com.github.wxiaoqi.security.common.util;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
public abstract class JsonUtil {
private static final ObjectMapper mapper = new ObjectMapper();
private static final Logger log = LoggerFactory.getLogger(JsonUtil.class);
static {
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
}
public static String objectToJson(Object data) {
try {
return mapper.writeValueAsString(data);
} catch (Exception e) {
log.error("JsonUtil.objectToJson execution failure!");
throw new RuntimeException(e);
}
}
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
if (StringUtils.isEmpty(jsonData)) return null;
return mapper.readValue(jsonData, beanType);
} catch (Exception e) {
log.error("JsonUtil.jsonToPojo execution failure!");
throw new RuntimeException(e);
}
}
public static <T, R> R objectToObject(T srcObj, Class<R> beanType) {
String toJson = objectToJson(srcObj);
return jsonToPojo(toJson, beanType);
}
@SuppressWarnings("rawtypes")
public static <T, R> R objectToObjectByTypeReference(T srcObj, TypeReference valueTypeRef) {
String toJson = objectToJson(srcObj);
return toPojoByTypeReference(toJson, valueTypeRef);
}
@SuppressWarnings("unchecked")
public static <T, R> Map<T, R> jsonToMap(String json) {
return jsonToPojo(json, Map.class);
}
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
try {
if (StringUtils.isEmpty(jsonData)) return null;
JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, beanType);
return mapper.readValue(jsonData, javaType);
} catch (Exception e) {
log.error("JsonUtil.jsonToList execution failure!");
throw new RuntimeException(e);
}
}
@SuppressWarnings("rawtypes")
public static <T> T toPojoByTypeReference(String jsonData, TypeReference valueTypeRef) {
try {
if (StringUtils.isEmpty(jsonData)) return null;
return mapper.readValue(jsonData, valueTypeRef);
} catch (Exception e) {
log.error("JsonUtil.jsonToPojo execution failure!");
throw new RuntimeException(e);
}
}
public static <T> T jsonToGeneric(String jsonData, Class<T> beanType, Class<?> resultType) {
try {
if (StringUtils.isEmpty(jsonData)) return null;
JavaType javaType = mapper.getTypeFactory().constructParametricType(beanType, beanType);
return mapper.readValue(jsonData, javaType);
} catch (Exception e) {
log.error("JsonUtil.jsonToList execution failure!");
throw new RuntimeException(e);
}
}
}
\ No newline at end of file
package com.github.wxiaoqi.security.common.util;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 获取request中的参数
*/
public class RequestContextHolderUtil {
public static HttpServletRequest getRequest() {
return getRequestAttributes().getRequest();
}
public static HttpServletResponse getResponse() {
return getRequestAttributes().getResponse();
}
public static HttpSession getSession(boolean create) {
return getRequest().getSession(create);
}
public static HttpSession getSession() {
return getSession(true);
}
public static String getRequestParameter(String name) {
return getRequest().getParameter(name);
}
public static ServletRequestAttributes getRequestAttributes() {
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
return ((ServletRequestAttributes) requestAttributes);
}
public static ServletContext getServletContext() {
return ContextLoader.getCurrentWebApplicationContext().getServletContext();
}
public static String getRequestHeader(String name) {
return getRequest().getHeader(name);
}
public static String getBaseUrl() {
HttpServletRequest request = getRequest();
StringBuffer requestURL = request.getRequestURL();
String url = requestURL.delete(requestURL.length() - request.getRequestURI().length(), requestURL.length())
.toString();
return url;
}
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ public class ResultCode {
public static int PARAM_ILLEGAL_CODE = Integer.valueOf(SystemProperty.getResultConfig("PARAM_ILLEGAL_CODE"));
//参数时效已过时,不能使用
public static int PARAM_EXPIRE_CODE = Integer.valueOf(SystemProperty.getResultConfig("PARAM_EXPIRE_CODE"));
public static int VEHICLE_IS_BOOKED = Integer.valueOf(SystemProperty.getResultConfig("VEHICLE_IS_BOOKED"));
// 操作成功
public static int SUCCESS_CODE = Integer.valueOf(SystemProperty.getResultConfig("SUCCESS_CODE"));
// 操作失败
......
......@@ -33,6 +33,9 @@ RSTOKEN_NULL_CODE=1007
DB_OPERATION_FAIL_CODE=1008
1008=数据库操作失败
VEHICLE_IS_BOOKED=10080
10080=车辆已经被预定
#参数非法
PARAM_ILLEGAL_CODE=1011
1011=参数非法,请修改
......
......@@ -28,8 +28,8 @@
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-consul-all</artifactId>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-consul-all</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
......
......@@ -39,85 +39,85 @@ import java.util.concurrent.atomic.AtomicLong;
*/
public class NacosWatch implements ApplicationEventPublisherAware, SmartLifecycle {
private static final Logger log = LoggerFactory.getLogger(NacosWatch.class);
private static final Logger log = LoggerFactory.getLogger(NacosWatch.class);
private final NacosDiscoveryProperties properties;
private long watchDelay = 30000;
private final TaskScheduler taskScheduler;
private final NacosDiscoveryProperties properties;
private long watchDelay = 30000;
private final TaskScheduler taskScheduler;
private final AtomicLong nacosWatchIndex = new AtomicLong(0);
private final AtomicLong nacosWatchIndex = new AtomicLong(0);
private final AtomicBoolean running = new AtomicBoolean(false);
private final AtomicBoolean running = new AtomicBoolean(false);
private ApplicationEventPublisher publisher;
private ApplicationEventPublisher publisher;
private ScheduledFuture<?> watchFuture;
private ScheduledFuture<?> watchFuture;
private Set<String> cacheServices = new HashSet<>();
private Set<String> cacheServices = new HashSet<>();
private HashMap<String, EventListener> subscribeListeners = new HashMap<>();
private HashMap<String, EventListener> subscribeListeners = new HashMap<>();
public NacosWatch(NacosDiscoveryProperties properties) {
this(properties, getTaskScheduler());
}
public NacosWatch(NacosDiscoveryProperties properties) {
this(properties, getTaskScheduler());
}
public NacosWatch(NacosDiscoveryProperties properties, TaskScheduler taskScheduler) {
this.properties = properties;
this.taskScheduler = taskScheduler;
}
public NacosWatch(NacosDiscoveryProperties properties, TaskScheduler taskScheduler) {
this.properties = properties;
this.taskScheduler = taskScheduler;
}
private static ThreadPoolTaskScheduler getTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.initialize();
return taskScheduler;
}
private static ThreadPoolTaskScheduler getTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.initialize();
return taskScheduler;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public void stop(Runnable callback) {
this.stop();
callback.run();
}
@Override
public void stop(Runnable callback) {
this.stop();
callback.run();
}
@Override
public void start() {
if (this.running.compareAndSet(false, true)) {
this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(
this::nacosServicesWatch, watchDelay);
}
}
@Override
public void start() {
if (this.running.compareAndSet(false, true)) {
this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(
this::nacosServicesWatch, watchDelay);
}
}
@Override
public void stop() {
if (this.running.compareAndSet(true, false) && this.watchFuture != null) {
this.watchFuture.cancel(true);
}
}
@Override
public void stop() {
if (this.running.compareAndSet(true, false) && this.watchFuture != null) {
this.watchFuture.cancel(true);
}
}
@Override
public boolean isRunning() {
return false;
}
@Override
public boolean isRunning() {
return false;
}
@Override
public int getPhase() {
return 0;
}
@Override
public int getPhase() {
return 0;
}
public void nacosServicesWatch() {
public void nacosServicesWatch() {
// nacos doesn't support watch now , publish an event every 30 seconds.
this.publisher.publishEvent(
new HeartbeatEvent(this, nacosWatchIndex.getAndIncrement()));
// nacos doesn't support watch now , publish an event every 30 seconds.
this.publisher.publishEvent(
new HeartbeatEvent(this, nacosWatchIndex.getAndIncrement()));
}
}
}
......@@ -8,11 +8,11 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class NacosWatchAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled", matchIfMissing = true)
public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties) {
return new NacosWatch(nacosDiscoveryProperties);
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled", matchIfMissing = true)
public NacosWatch nacosWatch(NacosDiscoveryProperties nacosDiscoveryProperties) {
return new NacosWatch(nacosDiscoveryProperties);
}
}
\ No newline at end of file
spring:
application:
name: ace-monitor
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: ace-monitor
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
server:
port: 8764 #启动端口
port: 8764 #启动端口
#
#eureka:
# instance:
......
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ace-security</artifactId>
<groupId>com.github.wxiaoqi</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<artifactId>ace-control</artifactId>
<modules>
<module>ace-monitor</module>
</modules>
<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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ace-security</artifactId>
<groupId>com.github.wxiaoqi</groupId>
<version>2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<artifactId>ace-control</artifactId>
<modules>
<module>ace-monitor</module>
</modules>
</project>
\ No newline at end of file
package com.github.wxiaoqi.security.gate.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class AcceptFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.github.wxiaoqi") ? FilterReply.ACCEPT : FilterReply.DENY;
}
}
\ No newline at end of file
......@@ -13,10 +13,10 @@ import com.github.wxiaoqi.security.common.context.BaseContextHandler;
import com.github.wxiaoqi.security.common.msg.BaseResponse;
import com.github.wxiaoqi.security.common.msg.auth.TokenForbiddenResponse;
import com.github.wxiaoqi.security.gate.feign.IAppUserService;
import com.github.wxiaoqi.security.gate.handler.RequestBodyRoutePredicateFactory;
import com.github.wxiaoqi.security.gate.utils.DBLog;
import com.github.wxiaoqi.security.gate.feign.ILogService;
import com.github.wxiaoqi.security.gate.feign.IUserService;
import com.github.wxiaoqi.security.gate.handler.RequestBodyRoutePredicateFactory;
import com.github.wxiaoqi.security.gate.utils.DBLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
......@@ -24,23 +24,25 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.support.DefaultServerRequest;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
......@@ -52,7 +54,7 @@ import java.util.stream.Stream;
*/
@Configuration
@Slf4j
public class AccessGatewayFilter implements GlobalFilter {
public class AccessGatewayFilter implements GlobalFilter{
@Autowired
@Lazy
private IUserService userService;
......@@ -91,6 +93,7 @@ public class AccessGatewayFilter implements GlobalFilter {
log.info("check token and user permission....");
LinkedHashSet requiredAttribute = serverWebExchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
ServerHttpRequest request = serverWebExchange.getRequest();
setLogService(serverWebExchange, gatewayFilterChain);
String requestUri = request.getPath().pathWithinApplication().value();
if (requiredAttribute != null) {
Iterator<URI> iterator = requiredAttribute.iterator();
......@@ -116,12 +119,6 @@ public class AccessGatewayFilter implements GlobalFilter {
log.error("用户Token过期异常", e);
return getVoidMono(serverWebExchange, new TokenForbiddenResponse("User Token Forbidden or Expired!"));
}
// String requestType = user.getRequestType();
//
// if (requestType == null || requestType.trim().equals("")) {
// requestType = RequestTypeConstants.BASE;
// }
List<PermissionInfo> permissionIfs = userService.getAllPermissionInfo();
// 判断资源是否启用权限约束
Stream<PermissionInfo> stream = getPermissionIfs(requestUri, method, permissionIfs);
......@@ -273,4 +270,66 @@ public class AccessGatewayFilter implements GlobalFilter {
return serverWebExchange.getResponse().setComplete();
}
public void setLogService(ServerWebExchange exchange, GatewayFilterChain chain) {
MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
ServerRequest serverRequest = new DefaultServerRequest(exchange);
// 如果是json格式,将body内容转化为object or map 都可
if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)){
Mono<Object> modifiedBody = serverRequest.bodyToMono(Object.class)
.flatMap(body -> {
recordLog(exchange.getRequest(), body);
return Mono.just(body);
});
}
// 如果是表单请求
else if(MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType)){
Mono<String> modifiedBody = serverRequest.bodyToMono(String.class)
// .log("modify_request_mono", Level.INFO)
.flatMap(body -> {
recordLog(exchange.getRequest(), body);
return Mono.just(body);
});
}
// TODO 这里未来还可以限制一些格式
// 无法兼容的请求,则不读取body,像Get请求这种
recordLog(exchange.getRequest(), "");
}
private void recordLog(ServerHttpRequest request, Object body) {
// 记录要访问的url
StringBuilder builder = new StringBuilder();
log.info("=================请求uri:" + request.getURI().getRawPath());
// 记录访问的方法
HttpMethod method = request.getMethod();
if (null != method){
log.info("=================请求方法:" + method.name());
}
// 记录头部信息
builder.append(", header { ");
for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
builder.append(entry.getKey()).append(":").append(StringUtils.join(entry.getValue(), ",")).append(",");
}
log.info("=================请求头header:" + builder.toString());
// 记录参数
builder = new StringBuilder();
// 处理get的请求
if (null != method && HttpMethod.GET.matches(method.name())) {
// 记录请求的参数信息 针对GET 请求
MultiValueMap<String, String> queryParams = request.getQueryParams();
for (Map.Entry<String, List<String>> entry : queryParams.entrySet()) {
builder.append(entry.getKey()).append("=").append(StringUtils.join(entry.getValue(), ",")).append(",");
}
}
else {
// 从body中读取参数
builder.append(body);
}
log.info("=================请求参数:" + builder.toString());
}
}
package com.github.wxiaoqi.security.gate.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class DenyFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.github.wxiaoqi") ? FilterReply.DENY : FilterReply.ACCEPT;
}
}
\ No newline at end of file
package com.github.wxiaoqi.security.gate.filter;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.cloud.gateway.support.CachedBodyOutputMessage;
import org.springframework.cloud.gateway.support.DefaultClientResponse;
import org.springframework.core.Ordered;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.Encoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.client.reactive.ClientHttpResponse;
import org.springframework.http.codec.ClientCodecConfigurer;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.function.Consumer;
import java.util.function.Function;
@Component
@Slf4j
public class ResponseRecordFilter implements GlobalFilter, Ordered {
Class inClass = String.class;
Class outClass = String.class;
private static Decoder decoder = new Jackson2JsonDecoder();
private static Encoder encoder = new Jackson2JsonEncoder();
private static final ExchangeStrategies STRATEGIES;
static {
STRATEGIES = ExchangeStrategies.builder().codecs(new Consumer<ClientCodecConfigurer>() {
@Override
public void accept(ClientCodecConfigurer clientCodecConfigurer) {
ClientCodecConfigurer.ClientDefaultCodecs clientDefaultCodecs = clientCodecConfigurer.defaultCodecs();
clientDefaultCodecs.jackson2JsonDecoder(decoder);
clientDefaultCodecs.jackson2JsonEncoder(encoder);
}
}).build();
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 响应报文打印
Function responseRead = body -> {
log.info("===============响应体:body = {}", body);
return Mono.just(body);
};
ServerHttpResponseDecorator responseDecorator = new ServerHttpResponseDecorator(exchange.getResponse()) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Content-Type", "application/json");
ResponseAdapter responseAdapter = new ResponseAdapter(body, httpHeaders);
DefaultClientResponse clientResponse = new DefaultClientResponse(responseAdapter, STRATEGIES);
Mono modifiedBody = clientResponse.bodyToMono(inClass).flatMap(responseRead);
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass);
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, exchange.getResponse().getHeaders());
return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
Flux<DataBuffer> messageBody = outputMessage.getBody();
HttpHeaders headers = this.getDelegate().getHeaders();
if (!headers.containsKey("Transfer-Encoding")) {
messageBody = messageBody.doOnNext((data) -> {
headers.setContentLength((long) data.readableByteCount());
});
}
return this.getDelegate().writeWith(messageBody);
}));
}
@Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return this.writeWith(Flux.from(body).flatMapSequential((p) -> {
return p;
}));
}
};
return chain.filter(exchange.mutate().response(responseDecorator).build());
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
public static class ResponseAdapter implements ClientHttpResponse {
private final Flux<DataBuffer> flux;
private final HttpHeaders headers;
public ResponseAdapter(Publisher<? extends DataBuffer> body, HttpHeaders headers) {
this.headers = headers;
if (body instanceof Flux) {
this.flux = (Flux) body;
} else {
this.flux = ((Mono) body).flux();
}
}
@Override
public Flux<DataBuffer> getBody() {
return this.flux;
}
@Override
public HttpHeaders getHeaders() {
return this.headers;
}
@Override
public HttpStatus getStatusCode() {
return null;
}
@Override
public int getRawStatusCode() {
return 0;
}
@Override
public MultiValueMap<String, ResponseCookie> getCookies() {
return null;
}
}
}
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -18,37 +19,27 @@
</appender>
<appender name="SYSTEM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.gate.filter.DenyFilter"></filter>
<filter class="com.github.wxiaoqi.security.common.filter.DenyFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/sys.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="WEB_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.gate.filter.AcceptFilter"></filter>
<filter class="com.github.wxiaoqi.security.common.filter.AcceptFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -3,6 +3,7 @@ package com.github.wxiaoqi.security.admin;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
......@@ -31,6 +32,7 @@ import tk.mybatis.spring.annotation.MapperScan;
@MapperScan("com.github.wxiaoqi.security.admin.mapper")
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
//@EnableSwagger2Doc
@AddBasicConfiguration
public class AdminBootstrap {
public static void main(String[] args) {
new SpringApplicationBuilder(AdminBootstrap.class).run(args); }
......
......@@ -255,6 +255,7 @@ public class AppUserRelationBiz extends BaseBiz<AppUserRelationMapper,AppUserRel
Map<Integer,Integer> memberSateAndCountMap = new HashMap<>();
AppUserRelation appUserRelation = new AppUserRelation();
appUserRelation.setParentId(userId);
appUserRelation.setIsForever(0);
int totalCount = mapper.selectCount(appUserRelation);
appUserRelation.setIsForever(1);
int activityCount = mapper.selectCount(appUserRelation);
......
package com.github.wxiaoqi.security.admin.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class AcceptFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.github.wxiaoqi") ? FilterReply.ACCEPT : FilterReply.DENY;
}
}
\ No newline at end of file
package com.github.wxiaoqi.security.admin.filter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class DenyFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
return event.getLoggerName().startsWith("com.github.wxiaoqi") ? FilterReply.DENY : FilterReply.ACCEPT;
}
}
\ No newline at end of file
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -18,37 +19,27 @@
</appender>
<appender name="SYSTEM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.admin.filter.DenyFilter"></filter>
<filter class="com.github.wxiaoqi.security.common.filter.DenyFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/sys.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="WEB_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.admin.filter.AcceptFilter"></filter>
<filter class="com.github.wxiaoqi.security.common.filter.AcceptFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -97,6 +97,10 @@
<artifactId>fastjson</artifactId>
<version>1.2.33</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
......
......@@ -3,6 +3,7 @@ package com.xxfc.platform.activity;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
......@@ -30,6 +31,7 @@ import tk.mybatis.spring.annotation.MapperScan;
@EnableAceCache
@EnableCaching
@MapperScan(basePackages = "com.xxfc.platform.activity.mapper")
@AddBasicConfiguration
public class ActivityApplication {
public static void main(String[] args) {
......
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -24,7 +25,7 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
......@@ -35,20 +36,10 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -3,6 +3,7 @@ package com.xxfc.platform.app;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
......@@ -19,6 +20,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAceAuthClient
@EnableFeignClients(value = {"com.github.wxiaoqi.security", "com.xxfc.platform"},defaultConfiguration = HeaderConfig.class)
@EnableAceCache
@AddBasicConfiguration
@tk.mybatis.spring.annotation.MapperScan(basePackages = "com.xxfc.platform.app.mapper")
public class AppApplication {
public static void main(String[] args) {
......
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -24,7 +25,7 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
......@@ -35,20 +36,10 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -3,9 +3,9 @@ package com.xxfc.platform.campsite;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableScheduling;
......@@ -27,6 +27,7 @@ import tk.mybatis.spring.annotation.MapperScan;
@EnableScheduling
@EnableFeignClients(value = {"com.github.wxiaoqi.security.auth.client.feign", "com.github.wxiaoqi.security.admin.feign","com.xxfc.platform"},defaultConfiguration = HeaderConfig.class)
@EnableAceCache
@AddBasicConfiguration
@MapperScan(basePackages = "com.xxfc.platform.campsite.mapper")
public class CampSiteApplication {
public static void main(String[] args) {
......
<configuration debug="false" scan="true" scanPeriod="10 seconds">
<!--<include resource="org/springframework/boot/logging/logback/base.xml"/>-->
<!--<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>-->
<contextName>logback</contextName>
<!--输出sql语句-->
<logger name="com.xxfc" level="debug"/>
<property name="path" value="logs"></property>
<property name="maxHistory" value="30"/>
<property name="maxFileSize" value="50MB"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
</appender>
<appender name="debug_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${path}/logback_debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天一归档 -->
<fileNamePattern>${path}/logback_debug.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="${system.log.path:-logs}"/>
<!-- 彩色日志依赖的渲染类 -->
<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}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="info_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${path}/logback_info.log</file>
<appender name="SYSTEM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.common.filter.DenyFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天一归档 -->
<fileNamePattern>${path}/logback_info.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<FileNamePattern>${LOG_HOME}/sys.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="warn_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${path}/logback_warn.log</file>
<appender name="WEB_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.common.filter.AcceptFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天一归档 -->
<fileNamePattern>${path}/logback_warn.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${path}/logback_error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天一归档 -->
<fileNamePattern>${path}/logback_error.log.%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root>
<level value="info"/>
<appender-ref ref="console"/>
<appender-ref ref="debug_file"/>
<appender-ref ref="info_file"/>
<appender-ref ref="warn_file"/>
<appender-ref ref="error_file"/>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="SYSTEM_FILE" />
<appender-ref ref="WEB_FILE" />
</root>
</configuration>
\ No newline at end of file
......@@ -3,6 +3,7 @@ package com.xxfc.platform.im;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
......@@ -22,6 +23,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableFeignClients(value = {"com.github.wxiaoqi.security.auth.client.feign","com.github.wxiaoqi.security.admin.feign", "com.xxfc.platform"},defaultConfiguration = HeaderConfig.class)
@EnableAceCache
@EnableCaching
@AddBasicConfiguration
@tk.mybatis.spring.annotation.MapperScan(basePackages = "com.xxfc.platform.im.mapper")
public class ImApplication {
......
......@@ -25,6 +25,7 @@ import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Service
......@@ -94,7 +95,7 @@ public class MsgBiz {
List<Integer> ids = new ArrayList<>();
ids.add(2);
ids.add(4);
Query query = new Query(Criteria.where("body.type").in(ids));
Query query = new Query(Criteria.where("body.type").in(ids).and("count.praise").gt(1000));
int totalSize = mongoTemplate.find(query, Msg.class, "s_msg").size();
query.with(pageable);
query.with(new Sort(Sort.Direction.DESC, "count.praise"));
......@@ -131,13 +132,11 @@ public class MsgBiz {
* @return
*/
private List<Msg> fetchAndAttach(List<Msg> list, Integer userId) {
for (Msg msg : list) {
//添加评论
Iterator<Msg> iterator = list.iterator();
while (iterator.hasNext()) {
Msg msg = iterator.next();
Query query = new Query(Criteria.where("msgId").is(msg.getId()));
query.with(new Sort(Sort.Direction.DESC, "time"));
List<Comment> comments = mongoTemplate.find(query, Comment.class, "s_comment");
msg.setComments(replaceCommentResult(comments));
//添加点赞
List<Praise> praise = mongoTemplate.find(query, Praise.class, "s_praise");
msg.setPraises(replacePraiseResult(praise));
......@@ -148,7 +147,12 @@ public class MsgBiz {
msg.setIsPraise(0);
msg.setIsCollect(0);
}
//添加评论
List<Comment> comments = mongoTemplate.find(query, Comment.class, "s_comment");
msg.setComments(replaceCommentResult(comments));
}
return list;
}
......
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -24,7 +25,7 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
......@@ -35,20 +36,10 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -4,8 +4,8 @@ import java.util.HashMap;
import java.util.Map;
public enum CrosstownTypeEnum {
RentVehicle(1, "交车"),
TOUR(2, "还车"),
DEPARTURE(1, "交车"),
ARRIVE(2, "还车"),
;
/**
* 编码
......
......@@ -101,6 +101,7 @@ public class OrderVehicleCrosstown {
* deductions: 扣除项
* cost:费用
* id:编号(用于顺序)
* type :费用类型
*/
private String dedDetail;
......
......@@ -20,4 +20,8 @@ public class DedDetailDTO {
* 编号(用于顺序)
*/
Integer id;
//1、延期, 2、车辆损坏 3、其他
Integer type;
}
......@@ -29,4 +29,5 @@ public class OrderVehicleCrosstownDto extends OrderVehicleCrosstown {
private String vehicleNumberPlat;
private String username;
}
......@@ -3,8 +3,7 @@ package com.xxfc.platform.order;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.spring4all.swagger.EnableSwagger2Doc;
import org.mybatis.spring.annotation.MapperScan;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
......@@ -21,6 +20,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAceAuthClient
@EnableFeignClients(value = {"com.github.wxiaoqi.security.auth.client.feign", "com.github.wxiaoqi.security.admin.feign", "com.xxfc.platform"},defaultConfiguration = HeaderConfig.class)
@EnableAceCache
@AddBasicConfiguration
@tk.mybatis.spring.annotation.MapperScan(basePackages = "com.xxfc.platform.order.mapper")
public class OrderApplication {
public static void main(String[] args) {
......
......@@ -63,7 +63,7 @@ public class OrderRefundBiz extends BaseBiz<OrderRefundMapper,OrderRefund> {
if(RefundStatusEnum.NONE.getCode().equals(orderMQDTO.getRefundStatus())) {
OrderVehicleCrosstown crosstown = crosstownBiz.selectOne(new OrderVehicleCrosstown(){{
setOrderId(orderMQDTO.getId());
setType(CrosstownTypeEnum.TOUR.getCode());
setType(CrosstownTypeEnum.ARRIVE.getCode());
}});
//还车扣除款 剩余的 钱,再减去违章预备金
BigDecimal refundAmont = crosstown.getRestDeposit().subtract(illegalReserve);
......
package com.xxfc.platform.order.biz;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.xxfc.platform.activity.user.UserInfoBiz;
import com.xxfc.platform.order.contant.enumerate.CrosstownTypeEnum;
import com.xxfc.platform.order.entity.BaseOrder;
import com.xxfc.platform.order.entity.OrderRentVehicleDetail;
import com.xxfc.platform.order.entity.OrderUserLicense;
......@@ -18,9 +17,12 @@ import com.xxfc.platform.order.pojo.order.OrderVehicleCrosstownDto;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.VehicleArrivalVo;
import com.xxfc.platform.vehicle.pojo.VehicleDepartureVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
......@@ -73,6 +75,7 @@ public class OrderVehicalCrosstownBiz extends BaseBiz<OrderVehicaleCrosstownMapp
return list;
}
@Transactional
public ObjectRestResponse<OrderVehicleCrosstownDto> add(OrderVehicleCrosstownDto orderVehicleCrosstownDto) {
log.info("添加的参数:orderVehicaleCrosstown = {}", orderVehicleCrosstownDto);
UserDTO userDTO = userInfoBiz.getAdminUserInfo();
......@@ -88,25 +91,33 @@ public class OrderVehicalCrosstownBiz extends BaseBiz<OrderVehicaleCrosstownMapp
return ObjectRestResponse.createFailedResult(500,"订单不存在!");
}
OrderRentVehicleDetail orderRentVehicleDetail = orderRentVehicleBiz.selectById(baseOrder.getDetailId());
//出车
if(orderVehicleCrosstownDto.getType() == CrosstownTypeEnum.DEPARTURE.getCode()) { //交车
VehicleDepartureVo vehicleDepartureVo = new VehicleDepartureVo();
vehicleDepartureVo.setVehicleId(orderRentVehicleDetail.getVehicleId());
vehicleDepartureVo.setDepartureBranchCompanyId(orderRentVehicleDetail.getStartCompanyId());
vehicleDepartureVo.setExpectArrivalBranchCompanyId(orderRentVehicleDetail.getEndCompanyId());
vehicleDepartureVo.setMileage(orderVehicleCrosstownDto.getMileage());
vehicleDepartureVo.setUse("用户租车");
vehicleDepartureVo.setBookRecordId(Integer.parseInt(orderRentVehicleDetail.getBookRecordId() + ""));
vehicleDepartureVo.setUser(userDTO.getUsername());
vehicleDepartureVo.setUserTel(userDTO.getTelPhone());
vehicleDepartureVo.setCheckMan(orderVehicleCrosstownDto.getLicenseName());
vehicleDepartureVo.setCheckManTel(orderVehicleCrosstownDto.getLicensePhone());
vehicleFeign.departureBySmall(vehicleDepartureVo);
} else if (orderVehicleCrosstownDto.getType() == CrosstownTypeEnum.ARRIVE.getCode()) { //还车
VehicleArrivalVo vehicleArrivalVo = new VehicleArrivalVo();
vehicleArrivalVo.setVehicleId(orderRentVehicleDetail.getVehicleId());
vehicleArrivalVo.setArrivalBranchCompanyId(userDTO.getCompanyId());
vehicleArrivalVo.setMileage(orderVehicleCrosstownDto.getMileage());
vehicleArrivalVo.setRecycleMan(userDTO.getName());
vehicleArrivalVo.setRecycleManTel(userDTO.getTelPhone());
vehicleFeign.arrivalBySmall(vehicleArrivalVo);
}
//出车成功后修改订单状态
List<OrderVehicleCrosstownDto> oldValue = orderVehicalCrosstownBiz.selectByOrderId(orderVehicleCrosstownDto);
if (oldValue .size() == 1) {
//已有直接返回
//交车完成 设置订单状态为出行中
handleOrderStatus(baseOrder, orderRentVehicleDetail);
OrderVehicleCrosstownDto vehicleCrosstownDto = new OrderVehicleCrosstownDto();
BeanUtil.copyProperties(oldValue.get(0), vehicleCrosstownDto, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
List<OrderUserLicense> orderUserLicenses = orderUserLicenseBiz.selectByIds(oldValue.get(0).getUserLicenseId()).getData();
if(orderUserLicenses != null && orderUserLicenses.size() > 0) {
orderVehicleCrosstownDto.setLicenseIdCard(orderUserLicenses.get(0).getLicenseIdCard());
orderVehicleCrosstownDto.setLicenseImg(orderUserLicenses.get(0).getLicenseImg());
orderVehicleCrosstownDto.setLicenseName(orderUserLicenses.get(0).getLicenseName());
orderVehicleCrosstownDto.setLicensePhone(orderUserLicenses.get(0).getLicensePhone());
}
RestResponse<Vehicle> restResponse = vehicleFeign.findById(orderRentVehicleDetail.getVehicleId());
if(restResponse.getData() != null) {
vehicleCrosstownDto.setVehicleNumberPlat(restResponse.getData().getNumberPlate());
}
return ObjectRestResponse.succ(vehicleCrosstownDto);
return ObjectRestResponse.succ(oldValue.get(0));
} else if(oldValue .size() <= 0) {
getOrderLicense(orderVehicleCrosstownDto);
orderVehicalCrosstownBiz.insertSelective(orderVehicleCrosstownDto);
......
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -24,7 +25,7 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
......@@ -35,20 +36,10 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -3,6 +3,7 @@ package com.xxfc.platform.tour;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
......@@ -27,6 +28,7 @@ import tk.mybatis.spring.annotation.MapperScan;
@EnableFeignClients(value = {"com.github.wxiaoqi.security.auth.client.feign", "com.github.wxiaoqi.security.admin.feign","com.xxfc.platform"},defaultConfiguration = HeaderConfig.class)
@EnableAceCache
@EnableCaching
@AddBasicConfiguration
@MapperScan(basePackages = "com.xxfc.platform.tour.mapper")
public class TourApplication {
......
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="${system.log.path:-logs}"/>
<!-- 彩色日志依赖的渲染类 -->
<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}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
</appender>
<appender name="SYSTEM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.common.filter.DenyFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/sys.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="WEB_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.common.filter.AcceptFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="SYSTEM_FILE" />
<appender-ref ref="WEB_FILE" />
</root>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="${system.log.path:-logs}"/>
<!-- 彩色日志依赖的渲染类 -->
<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}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
</appender>
<appender name="SYSTEM_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.common.filter.DenyFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/sys.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="WEB_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 按照每天生成日志文件 -->
<filter class="com.github.wxiaoqi.security.common.filter.AcceptFilter"></filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}.log</FileNamePattern><!--日志文件输出的文件名 -->
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="SYSTEM_FILE" />
<appender-ref ref="WEB_FILE" />
</root>
</configuration>
\ No newline at end of file
......@@ -60,6 +60,18 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!--zip4j依赖,解压zip压缩-->
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
<!--解压rar压缩-->
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>0.7</version>
</dependency>
</dependencies>
......
package com.xxfc.platform.universal.constant.enumerate;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
public enum FileTypeEnum {
FILE_TYPE_ZIP("application/zip", ".zip"),
FILE_TYPE_RAR("application/octet-stream", ".rar");
public String type;
public String fileStufix;
public static String getFileStufix(String type) {
for (FileTypeEnum orderTypeEnum : FileTypeEnum.values()) {
if (orderTypeEnum.type.equals(type)) {
return orderTypeEnum.fileStufix;
}
}
return null;
}
}
package com.xxfc.platform.universal.utils;
import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.core.ZipFile;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* 解压rar/zip工具类
*/
@Slf4j
public class UnPackeUtil {
/**
* zip文件解压
*
* @param destPath 解压文件路径
* @param zipFile 压缩文件
* @param password 解压密码(如果有)
*/
public static void unPackZip(File zipFile, String password, String destPath) {
try {
ZipFile zip = new ZipFile(zipFile);
/*zip4j默认用GBK编码去解压,这里设置编码为GBK的*/
zip.setFileNameCharset("GBK");
log.info("begin unpack zip file....");
zip.extractAll(destPath);
// 如果解压需要密码
if (zip.isEncrypted()) {
zip.setPassword(password);
}
} catch (Exception e) {
log.error("unPack zip file to " + destPath + " fail ....", e.getMessage(), e);
}
}
/**
* rar文件解压(不支持有密码的压缩包)
*
* @param rarFile rar压缩包
* @param destPath 解压保存路径
*/
public static void unPackRar(File rarFile, String destPath) {
try (Archive archive = new Archive(rarFile)) {
if (null != archive) {
FileHeader fileHeader = archive.nextFileHeader();
File file = null;
while (null != fileHeader) {
// 防止文件名中文乱码问题的处理
String fileName = fileHeader.getFileNameW().isEmpty() ? fileHeader.getFileNameString() : fileHeader.getFileNameW();
if (fileHeader.isDirectory()) {
//是文件夹
file = new File(destPath + File.separator + fileName);
file.mkdirs();
} else {
//不是文件夹
file = new File(destPath + File.separator + fileName.trim());
if (!file.exists()) {
if (!file.getParentFile().exists()) {
// 相对路径可能多级,可能需要创建父目录.
file.getParentFile().mkdirs();
}
file.createNewFile();
}
FileOutputStream os = new FileOutputStream(file);
archive.extractFile(fileHeader, os);
os.close();
}
fileHeader = archive.nextFileHeader();
}
}
} catch (Exception e) {
log.error("unpack rar file fail....", e.getMessage(), e);
}
}
}
\ No newline at end of file
......@@ -3,7 +3,7 @@ package com.xxfc.platform.universal;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import org.mybatis.spring.annotation.MapperScan;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
......@@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableScheduling
@EnableAceCache
@EnableTransactionManagement
@AddBasicConfiguration
@tk.mybatis.spring.annotation.MapperScan(basePackages = "com.xxfc.platform.universal.mapper")
@EnableFeignClients(value = {"com.xxfc.platform","com.github.wxiaoqi.security"},defaultConfiguration = HeaderConfig.class)
public class UniversalApplication {
......
......@@ -13,9 +13,9 @@ public class CommonConfig {
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 单个数据大小
factory.setMaxFileSize("10240KB"); // KB,MB
factory.setMaxFileSize("102400KB"); // KB,MB
/// 总上传数据大小
factory.setMaxRequestSize("102400KB");
factory.setMaxRequestSize("502400KB");
return factory.createMultipartConfig();
}
}
\ No newline at end of file
......@@ -2,9 +2,11 @@ package com.xxfc.platform.universal.controller;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.result.JsonResultUtil;
import com.xxfc.platform.universal.dto.ImgDTO;
import com.xxfc.platform.universal.dto.UploadImgDTO;
import com.xxfc.platform.universal.service.FileUploadService;
import com.xxfc.platform.universal.service.UploadService;
import com.xxfc.platform.universal.utils.ImgBase64Util;
import com.xxfc.platform.universal.utils.PublicMsg;
......@@ -38,6 +40,8 @@ public class UploadController{
@Autowired
UploadService uploadService;
@Autowired
FileUploadService fileUploadService;
private static Integer MAX_DRIVING_LICENSE_SIZE = 10 * 1024 * 1024;//10M
......@@ -158,5 +162,12 @@ public class UploadController{
ueditor.setTitle(upfile.getOriginalFilename());
return ueditor;
}
@RequestMapping(value="/app/unauth/zip", method = RequestMethod.POST)
public ObjectRestResponse zip(
@RequestParam("file")MultipartFile upfile,
@RequestParam(value = "prefix",defaultValue = "renovate")String prefix) throws Exception {
return fileUploadService.handlerUpload(upfile,null,prefix);
}
}
package com.xxfc.platform.universal.service;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import org.springframework.web.multipart.MultipartFile;
public interface FileUploadService {
public ObjectRestResponse handlerUpload(MultipartFile zipFile,String password,String prefix)throws Exception;
}
......@@ -23,7 +23,7 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Service
public class UploadService {
public class UploadService {
public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
@Value("${universal.baseUploadPath}")
......
package com.xxfc.platform.universal.service.impl;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.universal.constant.enumerate.FileTypeEnum;
import com.xxfc.platform.universal.service.FileUploadService;
import com.xxfc.platform.universal.utils.UnPackeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
@Service
@Slf4j
public class FileUploadServiceImpl implements FileUploadService {
@Value("${universal.uploadPath}")
private String uploadPath ;
@Value("${universal.url}")
private String xx_url ;
@Override
public ObjectRestResponse handlerUpload(MultipartFile zipFile,String password,String prefix)throws Exception {
if (null == zipFile) {
return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE,"请上传压缩文件!");
}
boolean isZipPack = true;
String fileContentType = zipFile.getContentType();
//将压缩包保存在指定路径
String packFilePath = uploadPath + File.separator + zipFile.getName();
if (FileTypeEnum.FILE_TYPE_ZIP.type.equals(fileContentType)) {
//zip解压缩处理
packFilePath += FileTypeEnum.FILE_TYPE_ZIP.fileStufix;
} else if (FileTypeEnum.FILE_TYPE_RAR.type.equals(fileContentType)) {
//rar解压缩处理
packFilePath += FileTypeEnum.FILE_TYPE_RAR.fileStufix;
isZipPack = false;
} else {
return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE,"上传的压缩包格式不正确,仅支持rar和zip压缩文件!");
}
File file = new File(packFilePath);
try {
zipFile.transferTo(file);
} catch (IOException e) {
log.error("zip file save to " + uploadPath + " error", e.getMessage(), e);
return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE,"保存压缩文件到:" + uploadPath + " 失败!");
}
if (isZipPack) {
//zip压缩包
UnPackeUtil.unPackZip(file, password, uploadPath);
} else {
//rar压缩包
UnPackeUtil.unPackRar(file, uploadPath);
}
String path=readZipFile(packFilePath);
if (StringUtils.isNotBlank(path)){
path=xx_url+"/"+prefix+"/"+path;
return ObjectRestResponse.succ(path);
}else {
return ObjectRestResponse.createDefaultFail();
}
}
public static String readZipFile(String file) throws Exception {
ZipFile zf = new ZipFile(file);
InputStream in = new BufferedInputStream(new FileInputStream(file));
ZipInputStream zin = new ZipInputStream(in);
ZipEntry ze;
String path=null;
while ((ze = zin.getNextEntry()) != null) {
if (ze.isDirectory()) {
} else {
path= ze.getName();
}
}
zin.closeEntry();
return path;
}
}
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -24,7 +25,7 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
......@@ -35,20 +36,10 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -17,12 +17,12 @@ public enum ResCode {
VEHICLE_INFO_CODE_EXIST(102003,"车辆编码已存在"),
VEHICLE_INFO_SAME_NUM_PLATE_AND_CODE_EMPTY(102004,"车辆编码和车牌号为空"),
VEHICLE_INFO_SAME_NUM_PLATE_AND_CODE_EXIST(102004,"车辆编码或车牌号已存在"),
VEHICLE_INFO_IS_BOOKED(102004,"车辆已经被预定"),
//车辆信息相关返回码-预定申请信息
VEHICLE_BOOKED_RECORD_ALREADY_CHANGED(103001,"车辆预定申请已被审批,请刷新后继续操作"),
VEHICLE_BOOKED_RECORD_STATUS_CHANGED(103002,"车辆预定申请状态已变更,请刷新后继续操作"),
VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED(103003,"车辆预定里程数不符合,请刷新后继续操作"),
VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED(103003,"请输入仪表盘内当前显示的公里数"),
VEHICLE_DEPARTURE_VEHICLE_UNEXIST(104001,"车辆不存在"),
VEHICLE_DEPARTURE_VEHICLE_DISABLE(104002,"车辆不可用"),
......
......@@ -4,14 +4,13 @@ import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.vo.GoodDataVO;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.entity.*;
import com.xxfc.platform.vehicle.pojo.CompanyDetail;
import com.xxfc.platform.vehicle.pojo.RentVehicleBookDTO;
import com.xxfc.platform.vehicle.pojo.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.Set;
/**
* Created by ace on 2017/9/15.
......@@ -30,6 +29,14 @@ public interface VehicleFeign {
@RequestMapping(value = "/vehicleInfo/getByIds", method = RequestMethod.GET)
public RestResponse< List<Vehicle>> getByIds(@RequestParam(value = "ids") List<String> id);
//提车
@PostMapping("/active/small/departure")
public RestResponse departureBySmall(@RequestBody VehicleDepartureVo departureVo);
//还车
@PostMapping("/active/small/arrival")
public RestResponse arrivalBySmall(@RequestBody VehicleArrivalVo arrivalVo);
//修改评分
@RequestMapping(value = "/vehicleModel/app/addScore", method = RequestMethod.GET)
public RestResponse addScore(@RequestParam(value="id")Integer id, @RequestParam(value="score")Integer score);
......
......@@ -4,6 +4,8 @@ import com.github.wxiaoqi.security.common.vo.PageParam;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class VehiclePlanDto extends PageParam {
......@@ -31,7 +33,7 @@ public class VehiclePlanDto extends PageParam {
@ApiModelProperty(value = "所属分公司大区")
private Integer zoneId;
private String[] companyIds;
private List<String> companyIds;
private String[] zoneIds;
private List<String> zoneIds;
}
......@@ -3,11 +3,11 @@ package com.xxfc.platform.vehicle;
import com.ace.cache.EnableAceCache;
import com.github.wxiaoqi.security.api.vo.config.HeaderConfig;
import com.github.wxiaoqi.security.auth.client.EnableAceAuthClient;
import com.github.wxiaoqi.security.common.annotation.AddBasicConfiguration;
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.scheduling.annotation.EnableScheduling;
@SpringBootApplication(scanBasePackages = {
......@@ -21,6 +21,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAceAuthClient
@EnableFeignClients(value = {"com.github.wxiaoqi.security","com.xxfc.platform.vehicle.feign"},defaultConfiguration = HeaderConfig.class)
@EnableAceCache
@AddBasicConfiguration
@tk.mybatis.spring.annotation.MapperScan(basePackages = "com.xxfc.platform.vehicle.mapper")
public class VehicleApplication {
......
......@@ -5,9 +5,7 @@ import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
......@@ -60,7 +58,7 @@ import static com.github.wxiaoqi.security.auth.common.constatns.CommonConstants.
@Service
@Slf4j
public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> implements UserRestInterface {
public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> {
public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
......@@ -85,9 +83,7 @@ public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> implements UserR
@Autowired
private VehicleBookHourInfoBiz vehicleBookHourInfoBiz;
@Autowired
UserFeign userFeign;
@Override
public UserFeign getUserFeign() {return userFeign;}
AdminInfoFeign adminInfoFeign;
@Value("${vehicle.baseUploadPath}")
private String baseUploadPath ;
@Value("${vehicle.fristMileage}")
......@@ -414,7 +410,7 @@ public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> implements UserR
for(Map.Entry<String,List<String>> entry:yearMonthAndDate.entrySet()){
Boolean rsEach = applyVehicle4EmployeePerMonth(bookVehicleVo.getVehicleId(),entry.getValue(),entry.getKey());
if(Boolean.FALSE.equals(rsEach)){
throw new BaseException(ResultCode.FAILED_CODE);
throw new BaseException(ResultCode.VEHICLE_IS_BOOKED);
}
}
......@@ -451,7 +447,7 @@ public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> implements UserR
//修改相关车辆预定记录
Boolean hasSuc = bookedVehicle(bookVehicleVo);
if(!hasSuc){
throw new BaseException(ResultCode.FAILED_CODE);
throw new BaseException("车辆预定失败");
}
//添加随车物品
......@@ -1269,10 +1265,12 @@ public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> implements UserR
Integer limit = vehiclePlanDto.getLimit() == null ? 10 : vehiclePlanDto.getLimit();
vehiclePlanDto.setPage(page);
vehiclePlanDto.setLimit(limit);
UserDTO userDTO = getAdminUserInfo();
UserDTO userDTO = adminInfoFeign.getAdminUserInfo();
if(userDTO == null) {
return ObjectRestResponse.createFailedResult(235, "token失效");
}
List<String> zoneList = null;
List<String> companyList = null;
if(vehiclePlanDto.getZoneId() == null) { //默认查出所有权限内的数据
if(DATA_ALL_FALSE.equals(userDTO.getDataAll())) { //不能获取全部数据
String zoneId = null;
......@@ -1281,16 +1279,24 @@ public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> implements UserR
} else {
zoneId = userDTO.getZoneId() + ",";
}
vehiclePlanDto.setZoneIds(zoneId.split(","));
zoneList = new ArrayList<>(Arrays.asList(zoneId.split(",")));
String companyId = null;
if(StringUtils.isNotBlank(userDTO.getDataCompany())) {
companyId = userDTO.getDataCompany();
} else {
companyId = userDTO.getCompanyId() + ",";
}
vehiclePlanDto.setCompanyIds(companyId.split(","));
companyList = new ArrayList<>(Arrays.asList(companyId.split(",")));
}
}
if(vehiclePlanDto.getParkBranchCompanyId() != null) {
if (companyList == null) {
companyList = Lists.newArrayList();
}
companyList.add(vehiclePlanDto.getParkBranchCompanyId() + "");
}
vehiclePlanDto.setCompanyIds(companyList);
vehiclePlanDto.setZoneIds(zoneList);
Query query = new Query(vehiclePlanDto);
PageDataVO<VehicleAndModelInfoVo> pageDataVO = PageDataVO.pageInfo(query, () -> mapper.getVehicle(query.getSuper()));
return ObjectRestResponse.succ(pageDataVO);
......@@ -1327,4 +1333,7 @@ public class VehicleBiz extends BaseBiz<VehicleMapper, Vehicle> implements UserR
return list;
}
public List<String> findExistVehicleIds() {
return mapper.findExistVehicleIds();
}
}
......@@ -29,6 +29,7 @@ public class VehicleBookInfoBiz extends BaseBiz<VehicleBookInfoMapper, VehicleBo
public static final DateTimeFormatter YEARMONTH_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM");
public static final Integer DEL_BATCH_SIZE = 1000;
public static final Integer COPY_BATCH_SIZE = 100;
public static final int MONTH_INTERVAL=2;
@Autowired
private RedisTemplate customRedisTemplate;
......@@ -127,4 +128,7 @@ public class VehicleBookInfoBiz extends BaseBiz<VehicleBookInfoMapper, VehicleBo
mapper.createTbIfNotExists(tbName);
}
public void InsertBatch(List<VehicleBookInfo> bookInfos) {
mapper.insertBatch(bookInfos);
}
}
package com.xxfc.platform.vehicle.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Slf4j
@Configuration
public class XxlJobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.executor.appname}")
private String appName;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean(initMethod = "start", destroyMethod = "destroy")
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppName(appName);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
*
* 1、引入依赖:
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
\ No newline at end of file
package com.xxfc.platform.vehicle.jobhandler;
import com.xxfc.platform.vehicle.biz.VehicleBiz;
import com.xxfc.platform.vehicle.biz.VehicleBookInfoBiz;
import com.xxfc.platform.vehicle.entity.VehicleBookInfo;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/8/1 11:28
*/
@JobHandler(value = "vehicle_job_handler")
@Component("vehicle_job_handler")
public class VehicleJobHandler extends IJobHandler {
@Autowired
private VehicleBiz vehicleBiz;
@Autowired
private VehicleBookInfoBiz vehicleBookInfoBiz;
@Override
public ReturnT<String> execute(String s) throws Exception {
try {
List<String> existVehicleIds = vehicleBiz.findExistVehicleIds();
LocalDate date = LocalDate.now();
int year = date.getYear();
int nowMonth = date.getMonthValue();
int month = nowMonth + VehicleBookInfoBiz.MONTH_INTERVAL > 12 ? (VehicleBookInfoBiz.MONTH_INTERVAL + nowMonth) - 12 : nowMonth + VehicleBookInfoBiz.MONTH_INTERVAL;
year = month > nowMonth ? year : year + 1;
String yearAndMonth = String.format("%d-%d", year, month);
XxlJobLogger.log("----查询到的车型ids:【{}】",existVehicleIds);
if (CollectionUtils.isNotEmpty(existVehicleIds)) {
List<VehicleBookInfo> bookInfos = existVehicleIds.stream().map(vehicleId -> {
VehicleBookInfo vehicleBookInfo = new VehicleBookInfo();
vehicleBookInfo.setVehicle(vehicleId);
vehicleBookInfo.setYearMonth(yearAndMonth);
return vehicleBookInfo;
}).collect(Collectors.toList());
vehicleBookInfoBiz.InsertBatch(bookInfos);
XxlJobLogger.log("----插入车型对象:【{}】",bookInfos);
}
ReturnT returnT = new ReturnT();
returnT.setCode(100);
returnT.setMsg("成功");
return returnT;
} catch (Exception ex) {
XxlJobLogger.log(ex);
return FAIL;
}
}
}
package com.xxfc.platform.vehicle.mapper;
import com.xxfc.platform.vehicle.entity.VehicleBookInfo;
import org.apache.ibatis.annotations.Param;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
......@@ -43,4 +44,5 @@ public interface VehicleBookInfoMapper extends Mapper<VehicleBookInfo> {
public Integer del4YearMoth(Map<String, Object> params);
void insertBatch(@Param("vbfs") List<VehicleBookInfo> bookInfos);
}
\ No newline at end of file
......@@ -3,6 +3,7 @@ package com.xxfc.platform.vehicle.mapper;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.pojo.*;
import com.xxfc.platform.vehicle.pojo.dto.VehiclePlanDto;
import org.apache.ibatis.annotations.Select;
import org.springframework.data.repository.query.Param;
import tk.mybatis.mapper.common.Mapper;
......@@ -46,5 +47,6 @@ public interface VehicleMapper extends Mapper<Vehicle> {
int upMileageByIdAndStatus(@Param("vehicleId") String vehicleId, @Param("status") Integer status,
@Param("lastStatus") Integer lastStatus,@Param("mileage") Integer mileage);
@Select("select `id` from `vehicle` where `is_del`=0")
List<String> findExistVehicleIds();
}
\ No newline at end of file
......@@ -11,6 +11,7 @@
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss}){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}}"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!--1. 输出到控制台-->
<filter class="com.github.wxiaoqi.security.common.filter.NacosLogFilter"></filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
......@@ -24,7 +25,7 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
......@@ -35,20 +36,10 @@
<MaxHistory>30</MaxHistory><!--日志文件保留天数 -->
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
</encoder>
</appender>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.0.181:5044</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" >
<!--"appname":"springboot21-log-elk" 的作用是指定创建索引的名字时用,并且在生成的文档中会多了这个字段
在logstashindex中引入 index => "%{[appname]}-%{+YYYY.MM.dd}"-->
<customFields>{"appName":"elk-log-service-gateway-dev"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
......
......@@ -87,5 +87,10 @@
</insert>
<insert id="insertBatch">
INSERT IGNORE INTO vehicle_book_info(`vehicle`,`year_month`,`booked_date`)VALUES
<foreach collection="vbfs" item="vbf" separator=",">
(#{vbf.vehicle} ,#{vbf.yearMonth} ,0)
</foreach>
</insert>
</mapper>
\ No newline at end of file
......@@ -376,9 +376,8 @@
</select>
<select id="getBookRecord" resultMap="searchBookRecord" parameterType="com.xxfc.platform.vehicle.pojo.VehicleBookRecordQueryVo">
select bc3.name parkCompanyName,bc4.name subordinateBranchName, conv(v2.booked_date,10,2) book_date, conv(v4.booked_hour,10,2) startHour,conv(v5.booked_hour,10,2) endHour, bc1.`name` lift_company_name, bc2.`name` ret_company_name, v3.number_plate,v1.*
select bc3.name parkCompanyName,bc4.name subordinateBranchName, conv(v4.booked_hour,10,2) startHour,conv(v5.booked_hour,10,2) endHour, bc1.`name` lift_company_name, bc2.`name` ret_company_name, v3.number_plate,v1.*
from vehicle_book_record v1
LEFT JOIN vehicle_book_info v2 on v1.vehicle_id = v2.vehicle and v2.year_month = CONCAT(YEAR(v1.book_start_date),"-",IF(MONTH(v1.book_start_date) > 10,MONTH(v1.book_start_date),CONCAT("0",MONTH(v1.book_start_date))))
LEFT JOIN vehicle_book_hour_info v4 on v4.book_record_id = v1.id and YEAR(v4.year_month_day) = YEAR(v1.book_start_date) AND MONTH(v4.year_month_day) = MONTH(v1.book_start_date) AND DAY(v4.year_month_day) =DAY(v1.book_start_date)
LEFT JOIN vehicle_book_hour_info v5 on v5.book_record_id = v1.id and YEAR(v5.year_month_day) = YEAR(v1.book_end_date) AND MONTH(v5.year_month_day) = MONTH(v1.book_end_date) AND DAY(v5.year_month_day) =DAY(v1.book_end_date)
LEFT JOIN branch_company bc1 ON v1.lift_company = bc1.id
......@@ -388,7 +387,7 @@
LEFT JOIN branch_company bc4 on v3.subordinate_branch = bc4.id
<where>
<if test="selectedMonth != null">
and v2.year_month = #{selectedMonth}
and (v1.book_start_date like CONCAT(#{selectedMonth}, "%") or v1.book_start_date like CONCAT(#{selectedMonth}, "%"))
</if>
<if test="numberPlate != null">
and v3.number_plate = #{numberPlate}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment