supeng há 1 mês atrás
pai
commit
fb12756bd9
41 ficheiros alterados com 2174 adições e 0 exclusões
  1. 2 0
      .gitignore
  2. 15 0
      content-supply-core/pom.xml
  3. 35 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/annotation/NoRequestLog.java
  4. 19 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/CacheKeyConstant.java
  5. 40 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/CommonRequest.java
  6. 91 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/CommonResponse.java
  7. 13 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/Constant.java
  8. 85 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/AppTypeEnum.java
  9. 35 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/DataStatusEnum.java
  10. 41 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/ExceptionEnum.java
  11. 36 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/PlatformEnum.java
  12. 32 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/RecommendStatusEnum.java
  13. 62 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/VideoStatusEnum.java
  14. 11 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/CacheException.java
  15. 97 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/CommonException.java
  16. 11 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/DAOException.java
  17. 56 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/HttpServiceException.java
  18. 43 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/TimeoutException.java
  19. 78 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/handle/GlobalExceptionHandle.java
  20. 169 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/model/dto/BaseInfoDTO.java
  21. 26 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/model/dto/PageDTO.java
  22. 4 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/service/DemoService.java
  23. 8 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/service/impl/DemoServiceImpl.java
  24. 260 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/util/DateUtil.java
  25. 90 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/util/HttpClientUtil.java
  26. 198 0
      content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/util/HttpPoolClient.java
  27. 48 0
      content-supply-server/pom.xml
  28. 26 0
      content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/Application.java
  29. 15 0
      content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/controller/CircuitBreakerController.java
  30. 16 0
      content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/controller/DownGradeController.java
  31. 30 0
      content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/controller/IndexController.java
  32. 19 0
      content-supply-server/src/main/resources/application-dev.yml
  33. 20 0
      content-supply-server/src/main/resources/application-pre.yml
  34. 22 0
      content-supply-server/src/main/resources/application-prod.yml
  35. 22 0
      content-supply-server/src/main/resources/application-stress.yml
  36. 22 0
      content-supply-server/src/main/resources/application-test.yml
  37. 25 0
      content-supply-server/src/main/resources/application.yml
  38. 193 0
      content-supply-server/src/main/resources/logback-spring.xml
  39. 13 0
      content-supply-server/src/test/java/com/tzld/piaoquan/content/supply/BaseTest.java
  40. 16 0
      content-supply-server/src/test/java/com/tzld/piaoquan/content/supply/service/DemoServiceTest.java
  41. 130 0
      pom.xml

+ 2 - 0
.gitignore

@@ -11,4 +11,6 @@
 
 
 # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 hs_err_pid*
 hs_err_pid*
+.idea/
+*/target/*
 
 

+ 15 - 0
content-supply-core/pom.xml

@@ -0,0 +1,15 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.tzld.piaoquan</groupId>
+        <artifactId>content-supply</artifactId>
+        <version>1.0.0</version>
+    </parent>
+    <artifactId>content-supply-core</artifactId>
+    <name>content-supply-core</name>
+    <description>content-supply-core</description>
+
+</project>

+ 35 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/annotation/NoRequestLog.java

@@ -0,0 +1,35 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright © 2021 xrv <xrg@live.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.tzld.piaoquan.content.supply.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface NoRequestLog {
+}

+ 19 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/CacheKeyConstant.java

@@ -0,0 +1,19 @@
+package com.tzld.piaoquan.content.supply.common.base;
+
+/**
+ * 缓存Key
+ *
+ * @author supeng
+ * @date 2020/08/31
+ */
+public class CacheKeyConstant {
+    public static final long ONE_HOUR_SECOND = 3600;
+    public static final long SIX_HOUR_SECOND = 6* ONE_HOUR_SECOND;
+    public static final long ONE_HOUR_MILLS = ONE_HOUR_SECOND * 1000;
+    public static final long ONE_DAY_SECOND = ONE_HOUR_SECOND * 24;
+    public static final long ONE_DAY_MILLS = ONE_DAY_SECOND * 1000;
+    public static final long ONE_WEEK_SECOND = ONE_DAY_SECOND * 7;
+    public static final long ONE_WEEK_MILLS = ONE_WEEK_SECOND * 1000;
+    public static final long ONE_MOUTH_SECOND = ONE_DAY_SECOND * 30;
+    public static final long ONE_MOUTH_MILLS = ONE_MOUTH_SECOND * 1000;
+}

+ 40 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/CommonRequest.java

@@ -0,0 +1,40 @@
+package com.tzld.piaoquan.content.supply.common.base;
+
+import com.tzld.piaoquan.content.supply.model.dto.BaseInfoDTO;
+
+/**
+ * 请求参数
+ *
+ * @author supeng
+ */
+public class CommonRequest<T> {
+    /**
+     * 基础信息
+     */
+    BaseInfoDTO baseInfo;
+    /**
+     * 请求参数
+     */
+    T params;
+
+    public BaseInfoDTO getBaseInfo() {
+        return baseInfo;
+    }
+
+    public void setBaseInfo(BaseInfoDTO baseInfo) {
+        this.baseInfo = baseInfo;
+    }
+
+    public T getParams() {
+        return params;
+    }
+
+    public void setParams(T params) {
+        this.params = params;
+    }
+
+    @Override
+    public String toString() {
+        return "CommonRequest{" + "baseInfo=" + baseInfo + ", params=" + params + '}';
+    }
+}

+ 91 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/CommonResponse.java

@@ -0,0 +1,91 @@
+package com.tzld.piaoquan.content.supply.common.base;
+
+/**
+ * Common Response
+ */
+public class CommonResponse<T> {
+
+    private static final int SUCCESS_CODE = 0;
+    private static final String SUCCESS_MSG = "success";
+
+    /** 返回状态码,0 表示业务成功 */
+    private int code = 0;
+    /** 返回消息 */
+    private String msg = "success";
+    /** 业务成功时返回数据 */
+    private T data;
+    /** 重定向 */
+    private String redirect;
+
+    public boolean isSuccess() {
+        return this.code == SUCCESS_CODE;
+    }
+
+    public static <T> CommonResponse<T> success() {
+        CommonResponse<T> commonResponse = new CommonResponse<>();
+        commonResponse.setCode(SUCCESS_CODE);
+        commonResponse.setMsg(SUCCESS_MSG);
+        return commonResponse;
+    }
+
+    public static <T> CommonResponse<T> success(T data) {
+        CommonResponse<T> commonResponse = new CommonResponse<>();
+        commonResponse.setCode(SUCCESS_CODE);
+        commonResponse.setMsg(SUCCESS_MSG);
+        commonResponse.setData(data);
+        return commonResponse;
+    }
+
+    public static <T> CommonResponse<T> create() {
+        return create(SUCCESS_CODE, SUCCESS_MSG, null);
+    }
+    
+    public static <T> CommonResponse<T> create(T data) {
+        return create(SUCCESS_CODE, SUCCESS_MSG, data);
+    }
+
+    public static <T> CommonResponse<T> create(int code, String msg) {
+        return create(code, msg, null);
+    }
+
+    public static <T> CommonResponse<T> create(int code, String msg, T data) {
+        CommonResponse<T> commonResponse = new CommonResponse<>();
+        commonResponse.setCode(code);
+        commonResponse.setMsg(msg);
+        commonResponse.setData(data);
+        return commonResponse;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+
+    public void setRedirect(String redirect) {
+        this.redirect = redirect;
+    }
+
+}

+ 13 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/base/Constant.java

@@ -0,0 +1,13 @@
+package com.tzld.piaoquan.content.supply.common.base;
+
+/**
+ * 常量
+ *
+ * @author supeng
+ */
+public class Constant {
+    /**
+     * traceID
+     */
+    public static final String LOG_TRACE_ID = "logTraceId";
+}

+ 85 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/AppTypeEnum.java

@@ -0,0 +1,85 @@
+package com.tzld.piaoquan.content.supply.common.enums;
+
+/**
+ * AppType
+ * @author supeng
+ * @date 2020/08/19
+ */
+public enum AppTypeEnum {
+    /**
+     * vlog小程序
+     */
+    VLOG(0, "VLOG"),
+    /**
+     * 票圈视频APP
+     */
+    QINGQUAPP(1, "轻趣视频APP"),
+    SMILE(2, "搞笑视频"),
+    LOVEMOVIE(3, "爱电影"),
+    /**
+     * 票圈视频小程序
+     */
+    LOVELIVE(4, "爱生活"),
+    /**
+     * 长视频小程序
+     */
+    LONGVIDEO(5, "长视频"),
+    SHORTVIDEO(6, "短视频"),
+    SURPRISE(7, "惊奇视频"),
+    PC(8,"PC端"),
+    CIRCLEAPP(9,"票圈长视频APP"),
+    LONGVIDEOLITE(10,"票圈长视频lite"),
+    /**
+     * 票圈相册小程序
+     */
+    ALBUM(11,"票圈相册"),
+    H5(12,"H5端"),
+    /**
+     * 极速版APP
+     */
+    APPSPEED(13,"APP极速"),
+    SMALLSPEED(14,"小程序极速"),
+    SHANYINAPP(15,"闪音APP"),
+
+    LEHUOQUAN(16, "乐活圈"),
+
+    ADMIN_CRAWLER(888888,"后台-爬虫"),
+    OTHERS(999999,"其他的调用方,比如后台管理系统"),
+    COOPERATION(777777, "合作方渠道视频对接类型");
+
+    private Integer code;
+    private String desc;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    private AppTypeEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public static AppTypeEnum valueOf( Integer code ){
+        if(code == null) {
+            return null;
+        }
+        for( AppTypeEnum appTypeEnum :AppTypeEnum.values()){
+            if( appTypeEnum.getCode().intValue() == code.intValue() ){
+                return appTypeEnum;
+            }
+        }
+        return null;
+    }
+}

+ 35 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/DataStatusEnum.java

@@ -0,0 +1,35 @@
+package com.tzld.piaoquan.content.supply.common.enums;
+
+/**
+ * 数据状态
+ *
+ * @author supeng
+ * @Date 2020/7/31
+ */
+public enum DataStatusEnum {
+    INVALID(0, "无效"),
+    VALID(1, "有效");
+    private Integer value;
+    private String desc;
+
+    DataStatusEnum(int value, String desc) {
+        this.value = value;
+        this.desc = desc;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    public void setValue(Integer value) {
+        this.value = value;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}

+ 41 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/ExceptionEnum.java

@@ -0,0 +1,41 @@
+package com.tzld.piaoquan.content.supply.common.enums;
+
+/**
+ * 异常
+ *
+ * @author supeng
+ * @date 2020/08/31
+ */
+public enum ExceptionEnum {
+
+    SUCCESS(0, "成功"),
+    SYSTEM_ERROR(1, "系统错误"),
+    PARAMS_INVALID(2, "参数错误"),
+    DATA_NOT_EXIST(3, "数据不存在"),
+    DATA_ERROR(4, "数据错误"),
+    EXIST_RELATED_DATA(5, "存在关联数据"),
+    DATA_EXIST(6, "数据已存在"),
+    ILLEGAL_OPERATION (7, "非法操作"),
+    CONFIG_ERROR (8, "配置异常"),
+    FLOW_POOL_AUTO_ENTER_ERROR (9, "只能同时一个流量池打开【自动入池】开关"),
+    FLOW_POOL_1_AUTO_ENTER_HOLD (10, "流量池【id=1】,作为尾号流量池的开关切换策略,需要保持【自动入池】状态"),
+    FLOW_POOL_AUTO_ENTER_EXCEPT_SUPPLY (11, "除了供给池,只能同时一个流量池打开【自动入池】开关"),
+    ;
+
+    private int code;
+    private String msg;
+
+    public int getCode() {
+        return code;
+    }
+
+
+    public String getMsg() {
+        return msg;
+    }
+
+    ExceptionEnum(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+}

+ 36 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/PlatformEnum.java

@@ -0,0 +1,36 @@
+package com.tzld.piaoquan.content.supply.common.enums;
+
+/**
+ * 平台
+ *
+ * @author supeng
+ * @date 2020/08/28
+ */
+public enum PlatformEnum {
+    ANDROID("android", "安卓"),
+    IOS("ios", "IOS");
+
+    String value;
+    String desc;
+
+    PlatformEnum(String value, String desc) {
+        this.value = value;
+        this.desc = desc;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}

+ 32 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/RecommendStatusEnum.java

@@ -0,0 +1,32 @@
+package com.tzld.piaoquan.content.supply.common.enums;
+
+/**
+ * @author supeng
+ */
+
+public enum RecommendStatusEnum {
+
+	NOMAL(0,  "不可搜"),
+	RECOMMEND(1, "普通推荐"),
+	CUSTOMRECOMMEND(10, "编辑推荐"),
+	WAITRECOMMEND(-6,"待推荐"),
+	SEARCHECOMMEND(-7, "可搜索"),
+    REALTIMERECOMMEND(20,"实时推荐"),
+	UNCLASSIFIED(-1, "未分类/未选择");
+
+	RecommendStatusEnum(Integer value, String desc) {
+		this.value = value;
+		this.desc = desc;
+	}
+
+	private Integer value;
+	private String desc;
+
+	public Integer getValue() {
+		return value;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+}

+ 62 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/enums/VideoStatusEnum.java

@@ -0,0 +1,62 @@
+package com.tzld.piaoquan.content.supply.common.enums;
+
+public enum VideoStatusEnum {
+
+	    INVALID(0,"无效状态"),
+	    NORMAL(1,"有效(公开)"),
+	    DELETED(2,"已删除"),
+	   	FORBIDDEN(3,"已屏蔽(不可见)"),
+	   	FOLLOWED(4,"关注可见(可见)"),
+	   	SHARED(5,"分享可见(私密)"),
+	   	MYSELF(6,"自己可见");
+	   	
+	   	private Integer code;
+	   	private String desc;
+		public Integer getCode() {
+			return code;
+		}
+		public void setCode(Integer code) {
+			this.code = code;
+		}
+		public String getDesc() {
+			return desc;
+		}
+		public void setDesc(String desc) {
+			this.desc = desc;
+		}
+		private VideoStatusEnum(Integer code, String desc) {
+			this.code = code;
+			this.desc = desc;
+		}
+		
+		 public static boolean videoIsCanOperation( Integer status ) {
+	  		 if(NORMAL.getCode().equals(status)||
+	  			  FOLLOWED.getCode().equals(status)|| 
+	  			  SHARED.getCode().equals(status)||
+					 MYSELF.getCode().equals(status)) {
+	  			 return true;
+	  		 }
+	  		 return false;
+	  	 }
+		 
+		 public static boolean videoCanNotOperation( Integer status ) {
+	  		 if(INVALID.getCode().equals(status)||
+	  				DELETED.getCode().equals(status)|| 
+	  				FORBIDDEN.getCode().equals(status)) {
+	  			 return true;
+	  		 }
+	  		 return false;
+	  	 }
+
+	public static VideoStatusEnum valueOf(Integer code, VideoStatusEnum defaultValue) {
+		if (code == null) {
+			return defaultValue;
+		}
+		for (VideoStatusEnum oneEnum : VideoStatusEnum.values()) {
+			if (oneEnum.getCode().intValue() == code.intValue()) {
+				return oneEnum;
+			}
+		}
+		return defaultValue;
+	}
+}

+ 11 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/CacheException.java

@@ -0,0 +1,11 @@
+package com.tzld.piaoquan.content.supply.common.exception;
+
+/**
+ * 缓存异常
+ *
+ * @author supeng
+ * @date 2020/08/19
+ */
+public class CacheException extends RuntimeException {
+
+}

+ 97 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/CommonException.java

@@ -0,0 +1,97 @@
+package com.tzld.piaoquan.content.supply.common.exception;
+
+import com.tzld.piaoquan.content.supply.common.enums.ExceptionEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 异常
+ *
+ * @author supeng
+ * @date 2020/08/28
+ */
+public class CommonException extends RuntimeException {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CommonException.class);
+    /**
+     * 异常
+     */
+    private ExceptionEnum exceptionEnum;
+    /**
+     * 错误码
+     */
+    private int code;
+    /**
+     * 异常信息
+     */
+    private String msg;
+
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public CommonException(Throwable throwable) {
+        super(throwable);
+    }
+
+    public CommonException(int code, String msg) {
+        super(msg);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public CommonException(ExceptionEnum exceptionEnum) {
+        super(exceptionEnum.getMsg());
+        this.exceptionEnum = exceptionEnum;
+        this.code = exceptionEnum.getCode();
+        this.msg = exceptionEnum.getMsg();
+    }
+
+    public CommonException(ExceptionEnum exceptionEnum, String msg) {
+        super(msg);
+        this.exceptionEnum = exceptionEnum;
+        this.code = exceptionEnum.getCode();
+        this.msg = msg;
+    }
+
+
+    public CommonException(int code, String msg, Throwable throwable) {
+        super(msg, throwable);
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public CommonException(ExceptionEnum exceptionEnum, Throwable throwable) {
+        super(exceptionEnum.getMsg(), throwable);
+        this.exceptionEnum = exceptionEnum;
+        this.code = exceptionEnum.getCode();
+        this.msg = exceptionEnum.getMsg();
+    }
+
+
+    @Override
+    public void printStackTrace() {
+        if (exceptionEnum != null) {
+            LOGGER.info("exception code = {}, msg = {}", exceptionEnum.getCode(), exceptionEnum.getMsg());
+        }
+        LOGGER.info("exception code = {}, msg = {}", code, msg);
+    }
+}

+ 11 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/DAOException.java

@@ -0,0 +1,11 @@
+package com.tzld.piaoquan.content.supply.common.exception;
+
+/**
+ * DAO异常
+ *
+ * @author supeng
+ * @date 2020/08/19
+ */
+public class DAOException extends RuntimeException{
+
+}

+ 56 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/HttpServiceException.java

@@ -0,0 +1,56 @@
+package com.tzld.piaoquan.content.supply.common.exception;
+
+/**
+ *
+ */
+public class HttpServiceException extends RuntimeException {
+
+    private int code;
+    private String message;
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public HttpServiceException(int code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public HttpServiceException(String message, int code, String message1) {
+        super(message);
+        this.code = code;
+        this.message = message1;
+    }
+
+    public HttpServiceException(String message, Throwable cause, int code, String message1) {
+        super(message, cause);
+        this.code = code;
+        this.message = message1;
+    }
+
+    public HttpServiceException(Throwable cause, int code, String message) {
+        super(cause);
+        this.code = code;
+        this.message = message;
+    }
+
+    public HttpServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, int code, String message1) {
+        super(message, cause, enableSuppression, writableStackTrace);
+        this.code = code;
+        this.message = message1;
+    }
+}

+ 43 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/common/exception/TimeoutException.java

@@ -0,0 +1,43 @@
+package com.tzld.piaoquan.content.supply.common.exception;
+
+
+public class TimeoutException extends RuntimeException {
+
+    private String message;
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public TimeoutException() {
+    }
+
+    public TimeoutException(String message) {
+        this.message = message;
+    }
+
+    public TimeoutException(String message, String message1) {
+        super(message);
+        this.message = message1;
+    }
+
+    public TimeoutException(String message, Throwable cause, String message1) {
+        super(message, cause);
+        this.message = message1;
+    }
+
+    public TimeoutException(Throwable cause, String message) {
+        super(cause);
+        this.message = message;
+    }
+
+    public TimeoutException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, String message1) {
+        super(message, cause, enableSuppression, writableStackTrace);
+        this.message = message1;
+    }
+}

+ 78 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/handle/GlobalExceptionHandle.java

@@ -0,0 +1,78 @@
+package com.tzld.piaoquan.content.supply.handle;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.tzld.piaoquan.content.supply.common.base.CommonResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+import org.springframework.validation.BindException;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import com.tzld.piaoquan.content.supply.common.enums.ExceptionEnum;
+import com.tzld.piaoquan.content.supply.common.exception.CommonException;
+
+/**
+ * 全局异常处理器
+ * 
+ * @author liuzhiheng
+ * @date 2020年11月20日 上午11:04:48
+ * @version 1.0
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandle {
+
+    private static Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandle.class);
+
+    @ExceptionHandler
+    public Object handleException(HttpServletRequest req, Exception exception) throws Exception {
+        String uri = req.getRequestURI();
+        CommonResponse<Object> response = new CommonResponse<Object>();
+        // 业务异常
+        if (exception instanceof CommonException) {
+            CommonException e = (CommonException) exception;
+            response.setCode(e.getCode());
+            response.setMsg(e.getMsg());
+            LOGGER.warn("uri:" + uri + "\n" + "CustomException log.", exception);
+        } else if (exception instanceof MethodArgumentNotValidException) {
+            // 参数校验异常
+            MethodArgumentNotValidException e = (MethodArgumentNotValidException) exception;
+            List<ObjectError> errorList = e.getBindingResult().getAllErrors();
+            StringBuilder errorMsg = new StringBuilder();
+            errorMsg.append("|");
+            if (!CollectionUtils.isEmpty(errorList)) {
+                for (ObjectError objectError : errorList) {
+                    errorMsg.append(objectError.getDefaultMessage()).append("|");
+                }
+            }
+            response.setCode(ExceptionEnum.PARAMS_INVALID.getCode());
+            response.setMsg(errorMsg.toString());
+            LOGGER.warn("uri:" + uri + "\n" + "MethodArgumentNotValidException log.", exception);
+        } else if (exception instanceof BindException) {
+            // 参数绑定异常
+            BindException e = (BindException) exception;
+            List<ObjectError> errorList = e.getBindingResult().getAllErrors();
+            StringBuilder errorMsg = new StringBuilder();
+            errorMsg.append("|");
+            if (!CollectionUtils.isEmpty(errorList)) {
+                for (ObjectError objectError : errorList) {
+                    errorMsg.append(objectError.getDefaultMessage()).append("|");
+                }
+            }
+            response.setCode(ExceptionEnum.PARAMS_INVALID.getCode());
+            response.setMsg(errorMsg.toString());
+            LOGGER.warn("uri:" + uri + "\n" + "BindException log.", exception);
+        } else {
+            response.setCode(ExceptionEnum.SYSTEM_ERROR.getCode());
+            response.setMsg(ExceptionEnum.SYSTEM_ERROR.getMsg());
+            LOGGER.error("uri:" + uri + "\n" + "unknow exception log.", exception);
+        }
+        return response;
+    }
+
+}

+ 169 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/model/dto/BaseInfoDTO.java

@@ -0,0 +1,169 @@
+package com.tzld.piaoquan.content.supply.model.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 基础信息
+ *
+ * @author supeng
+ */
+public class BaseInfoDTO {
+    /// 用户信息
+    @ApiModelProperty(value = "公共参数-token值")
+    private String token;
+    @ApiModelProperty(value = "公共参数-登录用户ID")
+    private Long loginUid;
+
+    /// 应用信息
+    @ApiModelProperty(value = "公共参数-应用版本号")
+    private Integer appVersionCode;
+    @ApiModelProperty(value = "公共参数-产品代号")
+    private Integer appType;
+
+    /// 设备信息
+    @ApiModelProperty(value = "公共参数-手机设备的唯一码")
+    private String machineCode;
+    @ApiModelProperty(value = "公共参数-ios,android")
+    private String platform;
+    @ApiModelProperty(value = "公共参数-系统版本(例:ios10.1)")
+    private String systemVersion;
+    @ApiModelProperty(value = "公共参数-手机信息")
+    private String machineInfo;
+    @ApiModelProperty(value = "公共参数-网络类型 WI-FI 5G 4G 3G 2G")
+    private String networkType;
+    @ApiModelProperty(value = "公共参数-客户端ip")
+    private String clientIp;
+
+    // pageSource相关的参数
+    @ApiModelProperty(value = "公共参数-页面来源")
+    private String pageSource;
+
+    // 某次操作相关的参数
+    @ApiModelProperty(value = "公共参数-前端请求时间")
+    private Long clientTimestamp;
+    @ApiModelProperty(value = "公共参数-sessionId")
+    private String sessionId;
+    @ApiModelProperty(value = "公共参数-requestId,每次请求客户端生成唯一ID,不超过64位")
+    private String requestId;
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public Long getLoginUid() {
+        return loginUid;
+    }
+
+    public void setLoginUid(Long loginUid) {
+        this.loginUid = loginUid;
+    }
+
+    public Integer getAppVersionCode() {
+        return appVersionCode;
+    }
+
+    public void setAppVersionCode(Integer appVersionCode) {
+        this.appVersionCode = appVersionCode;
+    }
+
+    public Integer getAppType() {
+        return appType;
+    }
+
+    public void setAppType(Integer appType) {
+        this.appType = appType;
+    }
+
+    public String getMachineCode() {
+        return machineCode;
+    }
+
+    public void setMachineCode(String machineCode) {
+        this.machineCode = machineCode;
+    }
+
+    public String getPlatform() {
+        return platform;
+    }
+
+    public void setPlatform(String platform) {
+        this.platform = platform;
+    }
+
+    public String getSystemVersion() {
+        return systemVersion;
+    }
+
+    public void setSystemVersion(String systemVersion) {
+        this.systemVersion = systemVersion;
+    }
+
+    public String getMachineInfo() {
+        return machineInfo;
+    }
+
+    public void setMachineInfo(String machineInfo) {
+        this.machineInfo = machineInfo;
+    }
+
+    public String getNetworkType() {
+        return networkType;
+    }
+
+    public void setNetworkType(String networkType) {
+        this.networkType = networkType;
+    }
+
+    public String getClientIp() {
+        return clientIp;
+    }
+
+    public void setClientIp(String clientIp) {
+        this.clientIp = clientIp;
+    }
+
+    public String getPageSource() {
+        return pageSource;
+    }
+
+    public void setPageSource(String pageSource) {
+        this.pageSource = pageSource;
+    }
+
+    public Long getClientTimestamp() {
+        return clientTimestamp;
+    }
+
+    public void setClientTimestamp(Long clientTimestamp) {
+        this.clientTimestamp = clientTimestamp;
+    }
+
+    public String getSessionId() {
+        return sessionId;
+    }
+
+    public void setSessionId(String sessionId) {
+        this.sessionId = sessionId;
+    }
+
+    public String getRequestId() {
+        return requestId;
+    }
+
+    public void setRequestId(String requestId) {
+        this.requestId = requestId;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+            "BaseInfoDTO [token=%s, appVersionCode=%s, appType=%s, machineCode=%s, platform=%s, systemVersion=%s, machineInfo=%s, networkType=%s, clientIp=%s, pageSource=%s, clientTimestamp=%s, sessionId=%s, requestId=%s]",
+            token, appVersionCode, appType, machineCode, platform, systemVersion, machineInfo, networkType, clientIp,
+            pageSource, clientTimestamp, sessionId, requestId);
+    }
+
+}

+ 26 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/model/dto/PageDTO.java

@@ -0,0 +1,26 @@
+package com.tzld.piaoquan.content.supply.model.dto;
+
+/**
+ * @author supeng
+ */
+public class PageDTO {
+
+    private int pageNum;
+    private int pageSize;
+
+    public int getPageNum() {
+        return pageNum;
+    }
+
+    public void setPageNum(int pageNum) {
+        this.pageNum = pageNum;
+    }
+
+    public int getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(int pageSize) {
+        this.pageSize = pageSize;
+    }
+}

+ 4 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/service/DemoService.java

@@ -0,0 +1,4 @@
+package com.tzld.piaoquan.content.supply.service;
+
+public interface DemoService {
+}

+ 8 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/service/impl/DemoServiceImpl.java

@@ -0,0 +1,8 @@
+package com.tzld.piaoquan.content.supply.service.impl;
+
+import com.tzld.piaoquan.content.supply.service.DemoService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class DemoServiceImpl implements DemoService {
+}

+ 260 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/util/DateUtil.java

@@ -0,0 +1,260 @@
+package com.tzld.piaoquan.content.supply.util;
+
+import java.time.*;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * date
+ * @author supeng
+ */
+public final class DateUtil {
+
+    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+    public static final String YYYY_MM_DD = "yyyy-MM-dd";
+
+    public static final String HH_MM_SS = "HH:mm:ss";
+
+    private static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS);
+
+    private static final DateTimeFormatter DEFAULT_DATE_FORMATTER = DateTimeFormatter.ofPattern(YYYY_MM_DD);
+
+    private static final DateTimeFormatter DEFAULT_TIME_FORMATTER = DateTimeFormatter.ofPattern(HH_MM_SS);
+
+    private static final Map<String, DateTimeFormatter> PATTEN_FORMATTER_MAPPER = new HashMap<>();
+
+    static {
+        PATTEN_FORMATTER_MAPPER.put(YYYY_MM_DD_HH_MM_SS, DEFAULT_DATE_TIME_FORMATTER);
+        PATTEN_FORMATTER_MAPPER.put(YYYY_MM_DD, DEFAULT_DATE_FORMATTER);
+        PATTEN_FORMATTER_MAPPER.put(HH_MM_SS, DEFAULT_TIME_FORMATTER);
+    }
+
+    private static DateTimeFormatter cacheFormatterAndGet(String patten) {
+        DateTimeFormatter dateTimeFormatter = PATTEN_FORMATTER_MAPPER.get(patten);
+        if (dateTimeFormatter == null) {
+            dateTimeFormatter = DateTimeFormatter.ofPattern(patten);
+            PATTEN_FORMATTER_MAPPER.put(patten, dateTimeFormatter);
+        }
+        return dateTimeFormatter;
+    }
+
+    /**
+     * @param localDateTime date time
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    public static String formatLocalDateTime(LocalDateTime localDateTime) {
+        return localDateTime.format(DEFAULT_DATE_TIME_FORMATTER);
+    }
+
+    /**
+     * @param localDateTime time
+     * @param patten        yyyy-MM-dd HH:mm:ss
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    public static String formatLocalDateTime(LocalDateTime localDateTime, String patten) {
+        DateTimeFormatter dateTimeFormatter = cacheFormatterAndGet(patten);
+        return localDateTime.format(dateTimeFormatter);
+    }
+
+    /**
+     * @param localDate date
+     * @param patten    only date patten
+     * @return yyyy-MM-dd
+     */
+    public static String formatLocalDate(LocalDate localDate, String patten) {
+        DateTimeFormatter dateTimeFormatter = cacheFormatterAndGet(patten);
+        return localDate.format(dateTimeFormatter);
+    }
+
+    /**
+     * @param localDate localDate
+     * @return yyyy-MM-dd
+     */
+    public static String formatLocalDate(LocalDate localDate) {
+        return localDate.format(DEFAULT_DATE_FORMATTER);
+    }
+
+    /**
+     * @param localTime localTime
+     * @param patten    patten
+     * @return HH:mm:ss
+     */
+    public static String formatLocalTime(LocalTime localTime, String patten) {
+        DateTimeFormatter dateTimeFormatter = cacheFormatterAndGet(patten);
+        return localTime.format(dateTimeFormatter);
+    }
+
+    /**
+     * @param localTime localTime
+     * @return HH:mm:ss
+     */
+    public static String formatLocalTime(LocalTime localTime) {
+        return localTime.format(DEFAULT_TIME_FORMATTER);
+    }
+
+    /**
+     * @param date   date time
+     * @param patten patten
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    public static String format(Date date, String patten) {
+        Instant instant = date.toInstant();
+        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+        return localDateTime.format(cacheFormatterAndGet(patten));
+    }
+
+    /**
+     * @param date date
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    public static String format(Date date) {
+        return format(date, YYYY_MM_DD_HH_MM_SS);
+    }
+
+    /**
+     * @param date date
+     * @return yyyy-MM-dd
+     */
+    public static String formatDate(Date date) {
+        return format(date, YYYY_MM_DD);
+    }
+
+    /**
+     * @param date date
+     * @return HH:mm:ss
+     */
+    public static String formatTime(Date date) {
+        return format(date, HH_MM_SS);
+    }
+
+    /**
+     * @param mills mills
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    public static String formatMills(long mills, String patten) {
+        Instant instant = Instant.ofEpochMilli(mills);
+        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+        return formatLocalDateTime(localDateTime, patten);
+    }
+
+    /**
+     * @param mills mills
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    public static String formatMills(long mills) {
+        return formatMills(mills, YYYY_MM_DD_HH_MM_SS);
+    }
+
+    /**
+     * @param mills mills
+     * @return yyyy-MM-dd
+     */
+    public static String formatMillsDate(long mills) {
+        return formatMills(mills, YYYY_MM_DD);
+    }
+
+    /**
+     * @param date date
+     * @return HH:mm:ss
+     */
+    public static String formatMillsTime(long date) {
+        return formatMills(date, HH_MM_SS);
+    }
+
+    /**
+     * @param date yyyy-MM-dd HH:mm:ss
+     * @return Date
+     */
+    public static Date parse(String date) {
+        LocalDateTime localDateTime = parseToLocalDateTime(date);
+        Instant instant = localDateTime.toInstant(OffsetDateTime.now().getOffset());
+        return Date.from(instant);
+    }
+
+    /**
+     * @param date   string date
+     * @param patten formatter patten
+     * @return LocalDateTime
+     */
+    public static LocalDateTime parseToLocalDateTime(String date, String patten) {
+        return LocalDateTime.parse(date, DateTimeFormatter.ofPattern(patten));
+    }
+
+    /**
+     * @param date yyyy-MM-dd HH:mm:ss
+     * @return LocalDateTime
+     */
+    public static LocalDateTime parseToLocalDateTime(String date) {
+        return LocalDateTime.parse(date, DEFAULT_DATE_TIME_FORMATTER);
+    }
+
+    /**
+     * @param date yyyy-MM-dd
+     * @return LocalDate
+     */
+    public static LocalDate parseToLocalDate(String date) {
+        return LocalDate.parse(date, DEFAULT_DATE_FORMATTER);
+    }
+
+    /**
+     * @param date HH:mm:ss
+     * @return LocalTime
+     */
+    public static LocalTime parseToLocalTime(String date) {
+        return LocalTime.parse(date, DEFAULT_TIME_FORMATTER);
+    }
+
+    /**
+     * @param dayStart date
+     * @param dayEnd   date
+     * @return
+     */
+    public static Period betweenDays(Date dayStart, Date dayEnd) {
+        LocalDateTime localDateTimeStart = LocalDateTime.ofInstant(dayStart.toInstant(), OffsetDateTime.now().getOffset());
+        LocalDateTime localDateTimeEnd = LocalDateTime.ofInstant(dayEnd.toInstant(), OffsetDateTime.now().getOffset());
+        return Period.between(localDateTimeStart.toLocalDate(), localDateTimeEnd.toLocalDate());
+    }
+
+    /**
+     * @param dayStart date
+     * @param dayEnd   date
+     * @return
+     */
+    public static Duration betweenTimes(Date dayStart, Date dayEnd) {
+        LocalDateTime localDateTimeStart = LocalDateTime.ofInstant(dayStart.toInstant(), OffsetDateTime.now().getOffset());
+        LocalDateTime localDateTimeEnd = LocalDateTime.ofInstant(dayEnd.toInstant(), OffsetDateTime.now().getOffset());
+        return Duration.between(localDateTimeStart, localDateTimeEnd);
+    }
+
+    /**
+     * @param dayStart date
+     * @param dayEnd   date
+     * @return
+     */
+    public static Period betweenDays(String dayStart, String dayEnd) {
+        return Period.between(parseToLocalDate(dayStart), parseToLocalDate(dayEnd));
+    }
+
+    /**
+     * @param dayStart date
+     * @param dayEnd   date
+     * @return
+     */
+    public static Duration betweenTimes(String dayStart, String dayEnd) {
+        return Duration.between(parseToLocalDateTime(dayStart), parseToLocalDateTime(dayEnd));
+    }
+
+    public static void main(String[] args) {
+//        LocalDateTime localDateTime = parseToLocalDateTime("2021-11-26","yyyy-MM-dd");
+        LocalDate localDate = parseToLocalDate("2021-11-26");
+//        System.out.println(formatLocalDateTime(localDateTime));
+        LocalDateTime startDateTime = localDate.atTime(0,0,0);
+        LocalDateTime endDateTime = localDate.plusDays(1L).atTime(0,0,0);
+        System.out.println(formatLocalDateTime(startDateTime));
+        System.out.println(formatLocalDateTime(endDateTime));
+//        System.out.println(formatLocalDate(localDate));
+    }
+}

+ 90 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/util/HttpClientUtil.java

@@ -0,0 +1,90 @@
+package com.tzld.piaoquan.content.supply.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * http util
+ *
+ * @author supeng
+ */
+public class HttpClientUtil {
+
+    private static final String DEFAULT_SHARED_KEY = "DEFAULT_SHARED_KEY";
+
+    /**
+     * 链接建立的超时时间 ms
+     */
+    private static final int DEFAULT_CONNECTION_TIMEOUT = 3000;
+    /**
+     * 响应超时时间 ms
+     */
+    private static final int DEFAULT_SOCKET_TIMEOUT = 3000;
+
+    /**
+     * 每个路由的最大连接数
+     */
+    private static final int DEFAULT_DEFAULT_MAX_PER_ROUTE = 50;
+
+    /**
+     * 最大连接数
+     */
+    private static final int DEFAULT_DEFAULT_MAX_TOTAL = 200;
+
+    /**
+     * 重试次数,默认0
+     */
+    private static final int DEFAULT_RETRY_COUNT = 0;
+
+    /**
+     * 从connection pool中获得一个connection的超时时间 ms
+     */
+    private static final int DEFAULT_CONNECTION_WAIT_TIMEOUT = 300;
+
+    private static final Map<String, HttpPoolClient> CREATED_HTTP_CLIENTS = new HashMap<>();
+
+    private static final Lock LOCK = new ReentrantLock();
+
+    private HttpClientUtil() {
+    }
+
+    public static HttpPoolClient useDefault() {
+        return createCached(DEFAULT_SHARED_KEY);
+    }
+
+
+    public static HttpPoolClient createCached(String cachedKey) {
+        HttpPoolClient httpPoolClient = CREATED_HTTP_CLIENTS.get(cachedKey);
+        if (httpPoolClient != null) {
+            return httpPoolClient;
+        }
+        LOCK.lock();
+        try {
+            httpPoolClient = CREATED_HTTP_CLIENTS.get(cachedKey);
+            if (httpPoolClient == null) {
+                httpPoolClient = create(DEFAULT_CONNECTION_TIMEOUT, DEFAULT_SOCKET_TIMEOUT, DEFAULT_DEFAULT_MAX_PER_ROUTE, DEFAULT_DEFAULT_MAX_TOTAL, DEFAULT_RETRY_COUNT, DEFAULT_CONNECTION_WAIT_TIMEOUT);
+                CREATED_HTTP_CLIENTS.put(cachedKey, httpPoolClient);
+            }
+        } finally {
+            LOCK.unlock();
+        }
+        return httpPoolClient;
+    }
+
+    /**
+     * 创建httpclient
+     *
+     * @param connectTimeout        连接超时时间 ms
+     * @param socketTimeout         读超时时间(等待数据超时时间)ms
+     * @param maxPerRoute           每个路由的最大连接数
+     * @param maxTotal              最大连接数
+     * @param retryCount            重试次数
+     * @param connectionWaitTimeout 连接等待超市时间 ms
+     * @return httpclient instance
+     */
+    public static HttpPoolClient create(int connectTimeout, int socketTimeout, int maxPerRoute, int maxTotal, int retryCount, int connectionWaitTimeout) {
+        return HttpPoolClient.create(connectTimeout, socketTimeout, maxPerRoute, maxTotal, retryCount, connectionWaitTimeout);
+    }
+}

+ 198 - 0
content-supply-core/src/main/java/com/tzld/piaoquan/content/supply/util/HttpPoolClient.java

@@ -0,0 +1,198 @@
+package com.tzld.piaoquan.content.supply.util;
+
+import com.google.common.collect.Lists;
+import com.tzld.piaoquan.content.supply.common.exception.HttpServiceException;
+import com.tzld.piaoquan.content.supply.common.exception.TimeoutException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.*;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.HttpClientConnectionManager;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContexts;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+import javax.net.ssl.SSLContext;
+import java.net.SocketTimeoutException;
+import java.nio.charset.Charset;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * http client
+ * @author supeng
+ */
+public class HttpPoolClient {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(HttpPoolClient.class);
+
+    private static final ScheduledExecutorService SCHEDULED_CLOSED_EXECUTOR = new ScheduledThreadPoolExecutor(1,
+            new BasicThreadFactory.Builder().namingPattern("http conn-closed-thread-%s").priority(Thread.NORM_PRIORITY).daemon(false).build(), (r, e) -> LOGGER.error(" monitor push reject task error={}", e.toString()));
+
+    private static final List<HttpClientConnectionManager> HTTP_CLIENT_CONNECTION_MANAGERS = Lists.newArrayList();
+
+    static {
+        SCHEDULED_CLOSED_EXECUTOR.schedule(() -> HTTP_CLIENT_CONNECTION_MANAGERS.forEach(HttpClientConnectionManager::closeExpiredConnections), 5, TimeUnit.SECONDS);
+    }
+
+    private CloseableHttpClient closeableHttpClient;
+
+    private HttpPoolClient(CloseableHttpClient closeableHttpClient) {
+        this.closeableHttpClient = closeableHttpClient;
+    }
+
+    private static HttpRequestInterceptor getInterceptor() {
+        HttpRequestInterceptor requestInterceptor = (request, context) -> {
+            try {
+                String missSpanId = MDC.get("missSpanId");
+                String missTraceId = MDC.get("request-id");
+                if (missTraceId != null && !"".equals(missTraceId.trim())) {
+                    request.setHeader("request-id", missTraceId);
+                }
+                if (missSpanId != null && !"".equals(missSpanId.trim())) {
+                    request.setHeader("missSpanId", missSpanId);
+                }
+            } catch (Exception e) {
+                LOGGER.error(e.getMessage(), e);
+            }
+        };
+        return requestInterceptor;
+    }
+
+
+    public Optional<String> get(String url) {
+        HttpGet httpGet = new HttpGet(url);
+        return request(httpGet);
+    }
+
+    public Optional<String> post(String url) {
+        HttpPost httpPost = new HttpPost(url);
+        return request(httpPost);
+    }
+
+
+    public Optional<String> postJson(String url, String json) {
+        HttpPost httpPost = new HttpPost(url);
+        if (StringUtils.isBlank(json)) {
+            return request(httpPost);
+        }
+        StringEntity entity = new StringEntity(json, Charset.forName("UTF-8"));
+        entity.setContentEncoding("UTF-8");
+        entity.setContentType("application/json");
+        httpPost.setEntity(entity);
+        return request(httpPost);
+    }
+
+    public Optional<String> request(HttpRequestBase request) {
+
+        if (LOGGER.isDebugEnabled()) {
+            String path = request.getURI().toString();
+            LOGGER.debug("http request url = {} ", path);
+        }
+        HttpEntity entity = null;
+        try {
+            CloseableHttpResponse response = request((HttpUriRequest) request);
+            if (response == null) {
+                throw new RuntimeException("call api exception no response");
+            }
+            entity = response.getEntity();
+            String content = null;
+            if (entity != null) {
+                content = EntityUtils.toString(entity, "UTF-8");
+            }
+            int httpStatus = response.getStatusLine().getStatusCode();
+            if (httpStatus == HttpStatus.SC_OK) {
+                return Optional.ofNullable(content);
+            }
+            String path = request.getURI().toString();
+            LOGGER.error("http call api {} fail response status {} content {}", path, httpStatus, content);
+            throw new HttpServiceException(httpStatus, content);
+        } catch (Exception e) {
+            if (e instanceof TimeoutException) {
+                throw (TimeoutException) e;
+            }
+            if (e instanceof HttpServiceException) {
+                throw (HttpServiceException) e;
+            }
+            throw new RuntimeException(e.getMessage(), e);
+        } finally {
+            if (request != null) {
+                request.abort();
+            }
+            EntityUtils.consumeQuietly(entity);
+        }
+    }
+
+
+    public CloseableHttpResponse request(HttpUriRequest request) {
+        try {
+            CloseableHttpResponse execute = closeableHttpClient.execute(request);
+            return execute;
+        } catch (Exception e) {
+            String path = request.getURI().toString();
+            if (e instanceof SocketTimeoutException) {
+                LOGGER.error(String.format("http timeout request url = %s .", path));
+                throw new TimeoutException();
+            } else {
+            }
+            throw new RuntimeException(String.format("http exception request url = %s ", path), e);
+        }
+    }
+
+    /**
+     * @param connectTimeout 连接超时时间 ms
+     * @param socketTimeout  读超时时间(等待数据超时时间)ms
+     * @param maxPerRoute    每个路由的最大连接数
+     * @param maxTotal       最大连接数
+     * @param retryCount     重试次数
+     * @return httpclient instance
+     */
+    protected static HttpPoolClient create(int connectTimeout, int socketTimeout, int maxPerRoute, int maxTotal, int retryCount, int connectionWaitTimeout) {
+        try {
+            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).setConnectionRequestTimeout(connectionWaitTimeout).build();
+            CloseableHttpClient client = HttpClientBuilder.create()
+                    .setDefaultRequestConfig(requestConfig)
+                    .setConnectionManager(createConnectionManager(maxPerRoute, maxTotal))
+                    .setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, false)).addInterceptorFirst(getInterceptor()).build();
+            return new HttpPoolClient(client);
+        } catch (Throwable e) {
+            LOGGER.error("create HttpPoolClient exception", e);
+            throw new RuntimeException("create HttpPoolClient exception");
+        }
+    }
+
+    private static PoolingHttpClientConnectionManager createConnectionManager(int maxPerRoute, int maxTotal) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+        SSLContext sslContext = SSLContexts.custom().loadTrustMaterial((chain, authType) -> true).build();
+        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
+                .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                .register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)).build();
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
+        cm.setDefaultMaxPerRoute(maxPerRoute);
+        cm.setMaxTotal(maxTotal);
+        HTTP_CLIENT_CONNECTION_MANAGERS.add(cm);
+        return cm;
+    }
+
+}

+ 48 - 0
content-supply-server/pom.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.tzld.piaoquan</groupId>
+        <artifactId>content-supply</artifactId>
+        <version>1.0.0</version>
+    </parent>
+    <artifactId>content-supply-server</artifactId>
+    <name>content-supply-server</name>
+    <description>content-supply-server for Spring Boot</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.tzld.piaoquan</groupId>
+            <artifactId>content-supply-core</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>content-supply-server</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>com.tzld.piaoquan.content.supply.Application</mainClass>
+                    <layout>ZIP</layout>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>

+ 26 - 0
content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/Application.java

@@ -0,0 +1,26 @@
+package com.tzld.piaoquan.content.supply;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * 启动类
+ *
+ * @author supeng
+ */
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+@ServletComponentScan("com.tzld.piaoquan.content.supply")
+@EnableSwagger2
+public class Application {
+    private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+        LOGGER.info("content-supply SpringBoot Start Success");
+    }
+}

+ 15 - 0
content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/controller/CircuitBreakerController.java

@@ -0,0 +1,15 @@
+package com.tzld.piaoquan.content.supply.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 熔断
+ */
+@Slf4j
+@RestController
+@RequestMapping("/circuitbreaker")
+public class CircuitBreakerController {
+
+}

+ 16 - 0
content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/controller/DownGradeController.java

@@ -0,0 +1,16 @@
+package com.tzld.piaoquan.content.supply.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 降级
+ */
+@Slf4j
+@RestController
+@RequestMapping("/downgrade")
+public class DownGradeController {
+
+    //TODO
+}

+ 30 - 0
content-supply-server/src/main/java/com/tzld/piaoquan/content/supply/controller/IndexController.java

@@ -0,0 +1,30 @@
+package com.tzld.piaoquan.content.supply.controller;
+
+import com.tzld.piaoquan.content.supply.common.annotation.NoRequestLog;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ */
+@RestController
+@RequestMapping("/")
+public class IndexController {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(IndexController.class);
+
+    /**
+     * 探活
+     *
+     * @return
+     */
+    @NoRequestLog
+    @GetMapping("/healthcheck")
+    public String healthcheck() {
+        LOGGER.info("I'm ok");
+        return "ok";
+    }
+}

+ 19 - 0
content-supply-server/src/main/resources/application-dev.yml

@@ -0,0 +1,19 @@
+server:
+  port: 8080
+logging:
+  file:
+    path: ./datalog/weblog/${project.name}
+app:
+  id: content-supply
+apollo:
+  bootstrap:
+    enabled: true
+    namespaces: application
+  meta: http://devapolloconfig-internal.piaoquantv.com
+  cacheDir: /datalog/apollo-cache-dir
+aliyun:
+  log:
+    logstore:
+      action: action-log-test
+      request: request-log-test
+    topic:

+ 20 - 0
content-supply-server/src/main/resources/application-pre.yml

@@ -0,0 +1,20 @@
+server:
+  port: 8080
+
+logging:
+  file:
+    path: /datalog/weblog/${project.name}
+app:
+  id: content-supply
+apollo:
+  bootstrap:
+    enabled: true
+    namespaces: application
+  meta: http://preapolloconfig-internal.piaoquantv.com
+  cacheDir: /datalog/apollo-cache-dir
+aliyun:
+  log:
+    logstore:
+      action: action-log-pre
+      request: request-log-pre
+    topic:

+ 22 - 0
content-supply-server/src/main/resources/application-prod.yml

@@ -0,0 +1,22 @@
+server:
+  port: 8080
+
+logging:
+  file:
+    path: /datalog/weblog/${project.name}
+
+app:
+  id: content-supply
+apollo:
+  bootstrap:
+    enabled: true
+    namespaces: application
+  meta: http://apolloconfig-internal.piaoquantv.com
+  cacheDir: /datalog/apollo-cache-dir
+
+aliyun:
+  log:
+    logstore:
+      action: action-log
+      request: request-log
+    topic:

+ 22 - 0
content-supply-server/src/main/resources/application-stress.yml

@@ -0,0 +1,22 @@
+server:
+  port: 8080
+
+logging:
+  file:
+    path: /datalog/weblog/${project.name}
+
+app:
+  id: content-supply
+apollo:
+  bootstrap:
+    enabled: true
+    namespaces: application
+  meta: http://testapolloconfig-internal.piaoquantv.com
+  cacheDir: /datalog/apollo-cache-dir
+
+aliyun:
+  log:
+    logstore:
+      action: action-log-test
+      request: request-log-test
+    topic:

+ 22 - 0
content-supply-server/src/main/resources/application-test.yml

@@ -0,0 +1,22 @@
+server:
+  port: 8080
+
+logging:
+  file:
+    path: /datalog/weblog/${project.name}
+
+app:
+  id: content-supply
+apollo:
+  bootstrap:
+    enabled: true
+    namespaces: application
+  meta: http://testapolloconfig-internal.piaoquantv.com
+  cacheDir: /datalog/apollo-cache-dir
+
+aliyun:
+  log:
+    logstore:
+      action: action-log-test
+      request: request-log-test
+    topic:

+ 25 - 0
content-supply-server/src/main/resources/application.yml

@@ -0,0 +1,25 @@
+spring:
+  application:
+    name: content-supply
+  profiles:
+    active: dev
+
+project:
+  name: content-supply
+
+server:
+  tomcat:
+    threads:
+      max: 1000
+    uri-encoding: UTF-8
+    accept-count: 1000
+  servlet:
+    session:
+      timeout: 60
+
+aliyun:
+  log:
+    endpoint: cn-hangzhou-intranet.log.aliyuncs.com
+    accessKeyId: LTAIP6x1l3DXfSxm
+    accessKeySecret: KbTaM9ars4OX3PMS6Xm7rtxGr1FLon
+    project: content-supply

+ 193 - 0
content-supply-server/src/main/resources/logback-spring.xml

@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
+<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
+<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
+<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
+<configuration  scan="true" scanPeriod="10 seconds">
+
+    <!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
+
+    <contextName>logback</contextName>
+    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
+<!--    <property name="LOG_PATH"  value="${logging.file.path}" />-->
+    <springProperty name="LOG_PATH" source="logging.file.path"/>
+
+    <!-- 彩色日志 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+
+    <!--输出到控制台-->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>info</level>
+        </filter>
+        <encoder>
+            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+            <!-- 设置字符集 -->
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <!--输出到文件-->
+    <!-- 时间滚动输出 level为 DEBUG 日志 -->
+    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/debug.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志归档 -->
+            <fileNamePattern>${LOG_PATH}/debug/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>debug</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 时间滚动输出 level为 INFO 日志 -->
+    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/info.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 每天日志归档路径以及格式 -->
+            <fileNamePattern>${LOG_PATH}/info/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>info</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 时间滚动输出 level为 WARN 日志 -->
+    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/warn.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_PATH}/warn/warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录warn级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>warn</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+
+    <!-- 时间滚动输出 level为 ERROR 日志 -->
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/error.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{logTraceId}] %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_PATH}/error/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>100MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>15</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录ERROR级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--
+        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
+        以及指定<appender>。<logger>仅有一个name属性,
+        一个可选的level和一个可选的addtivity属性。
+        name:用来指定受此logger约束的某一个包或者具体的某一个类。
+        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+              还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
+              如果未设置此属性,那么当前logger将会继承上级的级别。
+        addtivity:是否向上级logger传递打印信息。默认是true。
+    -->
+    <!--<logger name="org.springframework.web" level="info"/>-->
+    <!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
+    <!--
+        使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
+        第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
+        第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
+     -->
+
+    <!--
+        root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
+        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+        不能设置为INHERITED或者同义词NULL。默认是DEBUG
+        可以包含零个或多个元素,标识这个appender将会添加到这个logger。
+    -->
+
+    <springProfile name="dev">
+        <logger name="com.tzld.piaoquan.content.supply" level="info"/>
+    </springProfile>
+    <springProfile name="test">
+        <logger name="com.tzld.piaoquan.content.supply" level="info"/>
+    </springProfile>
+    <springProfile name="pre">
+        <logger name="com.tzld.piaoquan.content.supply" level="info"/>
+    </springProfile>
+    <springProfile name="stress">
+        <logger name="com.tzld.piaoquan.content.supply" level="info"/>
+    </springProfile>
+    <springProfile name="prod">
+        <logger name="com.tzld.piaoquan.content.supply" level="info"/>
+    </springProfile>
+
+    <root level="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>
+
+</configuration>

+ 13 - 0
content-supply-server/src/test/java/com/tzld/piaoquan/content/supply/BaseTest.java

@@ -0,0 +1,13 @@
+package com.tzld.piaoquan.content.supply;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class BaseTest {
+
+    @Test
+    void contextLoads() {
+    }
+
+}

+ 16 - 0
content-supply-server/src/test/java/com/tzld/piaoquan/content/supply/service/DemoServiceTest.java

@@ -0,0 +1,16 @@
+package com.tzld.piaoquan.content.supply.service;
+
+import com.tzld.piaoquan.content.supply.BaseTest;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DemoServiceTest extends BaseTest {
+
+    @Autowired
+    DemoService demoService;
+
+    @Test
+    void test(){
+//        demoService
+    }
+}

+ 130 - 0
pom.xml

@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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">
+
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>pom</packaging>
+    <parent>
+        <groupId>com.tzld.commons</groupId>
+        <artifactId>supom</artifactId>
+        <version>1.0.5</version>
+    </parent>
+    <groupId>com.tzld.piaoquan</groupId>
+    <artifactId>content-supply</artifactId>
+    <version>1.0.0</version>
+    <name>content-supply</name>
+    <description>content-supply</description>
+
+    <modules>
+        <module>content-supply-core</module>
+        <module>content-supply-server</module>
+    </modules>
+
+    <properties>
+        <lombok.version>1.18.20</lombok.version>
+        <xxl.job.version>2.2.0</xxl.job.version>
+        <aviator.version>5.2.7</aviator.version>
+        <httpclient.version>4.5.13</httpclient.version>
+        <common.lang3.version>3.12.0</common.lang3.version>
+        <spring.kafka.version>2.6.4</spring.kafka.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok</artifactId>
+                <version>${lombok.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpclient</artifactId>
+                <version>${httpclient.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>${common.lang3.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.cloud</groupId>-->
+<!--            <artifactId>spring-cloud-commons</artifactId>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ctrip.framework.apollo</groupId>
+            <artifactId>apollo-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.tzld.commons</groupId>
+            <artifactId>aliyun-log-spring-boot-starter</artifactId>
+            <version>2.0.0</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>aliyun-log</artifactId>
+                    <groupId>com.aliyun.openservices</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun.openservices</groupId>
+            <artifactId>aliyun-log-logback-appender</artifactId>
+            <version>0.1.18</version>
+        </dependency>
+    </dependencies>
+</project>