ソースを参照

创建模拟环境项目

Scott 3 年 前
コミット
39daf96427

+ 154 - 0
analog-api/build.gradle

@@ -0,0 +1,154 @@
+
+apply plugin: 'java'
+apply plugin: 'org.springframework.boot'
+apply plugin: 'io.spring.dependency-management'
+
+// 部署为外部服务器时, 配置为war包
+apply plugin: 'war'
+
+war {
+	archiveBaseName = 'analog-api'
+}
+
+
+// Task type of JavaCompile
+tasks.withType(JavaCompile, {
+	//enable compilation in a separate daemon process
+	sourceCompatibility = 8
+	targetCompatibility = 8
+	// default to true
+	options.incremental = true
+	// default to true
+	options.failOnError = false
+	// default to false
+	options.fork = true
+	options.encoding = "UTF-8"
+	// default to true
+	options.debug = true
+})
+
+repositories {
+	// 本地仓库
+	mavenLocal()
+	// ali 代理的central仓
+	maven {url 'https://maven.aliyun.com/repository/central'}
+	// ali 代理的central仓和jcenter仓的聚合仓
+	maven {url 'https://maven.aliyun.com/repository/public'}
+	maven {url 'https://maven.aliyun.com/repository/google'}
+	maven {url 'https://maven.aliyun.com/repository/gradle-plugin'}
+	maven {url 'https://maven.aliyun.com/repository/spring'}
+	maven {url 'https://maven.aliyun.com/repository/spring-plugin'}
+	maven {url 'https://maven.aliyun.com/repository/grails-core'}
+	// 远程中央仓库
+	mavenCentral()
+	maven {url 'https://repo1.maven.org/maven2/'}
+	// maven {url 'https://maven.google.com/'}
+	maven {url 'https://plugins.gradle.org/m2/'}
+	maven {url 'https://repo.spring.io/libs-milestone/'}
+	maven {url 'https://repo.spring.io/plugins-release/'}
+	maven {url 'https://repo.grails.org/grails/core/'}
+	maven {url 'https://repository.apache.org/content/groups/public/'}
+	maven {url 'https://repository.jboss.org/nexus/content/repositories/releases/'}
+
+	// 配置使用其它nexus 私服
+	maven {
+		// 非https需要增加对不安全协议的信任
+		allowInsecureProtocol true
+		url 'http://nexus.ds-bay.com/content/groups/public/'
+		credentials {
+			username 'admin'
+			password 'admin123'
+		}
+	}
+}
+
+ext {
+	lombok = '1.18.22'
+	junit = '4.13'
+	slf4j = '1.7.25'
+
+	javax_annotation_api = '1.3.2'
+	javax_servlet = '4.0.1'
+
+	spring_boot = '2.6.3'
+	spring = '5.3.13'
+
+	// logback对spring的支持
+	logback_ext_spring = '0.1.4'
+
+	jackson = '2.11.2'
+
+	// 工具类
+	google_guava = '29.0-jre'
+
+	// Java工具包类库,各种Util工具类
+	hutool = '5.6.2'
+
+	// (推荐)Forest,Java HTTP 客户端框架
+	forest = '1.5.0-RC5'
+
+	// alibaba 出品 excel 工具类, 需要 lombok 支持
+	easyexcel = '3.0.5'
+
+}
+
+
+// tag::dependencies[]
+dependencies {
+	compileOnly "org.projectlombok:lombok:${lombok}"
+	annotationProcessor "org.projectlombok:lombok:${lombok}"
+
+	testImplementation('org.springframework.boot:spring-boot-starter-test') {
+		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
+	}
+
+	implementation "javax.annotation:javax.annotation-api:${javax_annotation_api}"
+
+	// 内置Tomcat部署, 同时不需要编译, 使用 runtimeOnly
+	//runtimeOnly 'org.springframework.boot:spring-boot-starter-tomcat'
+	// 内置Tomcat部署, 同时需要编译, 使用 implementation
+	implementation 'org.springframework.boot:spring-boot-starter-tomcat'
+	// 外部Tomcat部署, 同时需要编译, 使用 compileOnly
+	//compileOnly 'org.springframework.boot:spring-boot-starter-tomcat'
+
+	//处理Properties 配置文件
+	//Gradle 4.5 and earlier
+	//compileOnly 'org.springframework.boot:spring-boot-configuration-processor'
+	//Gradle 4.6 and later
+	annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
+
+	implementation 'org.springframework.boot:spring-boot-starter-web'
+	implementation 'org.springframework.boot:spring-boot-starter-aop'
+
+
+	// logback对spring的支持
+	implementation "org.logback-extensions:logback-ext-spring:${logback_ext_spring}"
+
+	// 数据序列化
+	// 为保证引入 jackson包版本一致性,不使用到其它低版本包, 引入如下三个依赖
+	implementation "com.fasterxml.jackson.core:jackson-databind:${jackson}"
+	implementation "com.fasterxml.jackson.core:jackson-core:${jackson}"
+	implementation "com.fasterxml.jackson.core:jackson-annotations:${jackson}"
+	// jackson 支持格式化LocalDateTime
+	implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${jackson}"
+	implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson}"
+	implementation "com.fasterxml.jackson.module:jackson-module-afterburner:${jackson}"
+	// jackson 支持格式化XML
+	implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson}"
+
+	// 工具类
+	implementation "com.google.guava:guava:${google_guava}"
+
+	// Java工具包类库,各种Util工具类
+	implementation "cn.hutool:hutool-all:${hutool}"
+
+	// (推荐)Forest,Java HTTP 客户端框架
+	implementation "com.dtflys.forest:spring-boot-starter-forest:${forest}"
+
+
+	// alibaba 出品 excel 工具类, 需要 lombok 支持
+	implementation "com.alibaba:easyexcel:${easyexcel}"
+
+
+}
+// end::dependencies[]

+ 2 - 0
analog-api/setting.gradle

@@ -0,0 +1,2 @@
+rootProject.name = 'analog-api'
+

+ 13 - 0
analog-api/src/main/java/com/songmao/analog/api/AnalogApiApplication.java

@@ -0,0 +1,13 @@
+package com.songmao.analog.api;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class AnalogApiApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(AnalogApiApplication.class, args);
+	}
+
+}

+ 13 - 0
analog-api/src/main/java/com/songmao/analog/api/ServletInitializer.java

@@ -0,0 +1,13 @@
+package com.songmao.analog.api;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+public class ServletInitializer extends SpringBootServletInitializer {
+
+	@Override
+	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+		return application.sources(AnalogApiApplication.class);
+	}
+
+}

+ 5 - 0
analog-api/src/main/java/com/songmao/analog/api/wmsyibuda/README.MD

@@ -0,0 +1,5 @@
+# 一步达WMS模拟接口
+
+## 库存查询接口(多商品)
+1. 2021-12-09新增
+2. 模拟对接一步达WMS库存查询接口

+ 34 - 0
analog-api/src/main/java/com/songmao/analog/api/wmsyibuda/controller/WmsYibudaController.java

@@ -0,0 +1,34 @@
+package com.songmao.analog.api.wmsyibuda.controller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@Controller
+public class WmsYibudaController {
+    private static final Logger logger = LoggerFactory.getLogger(WmsYibudaController.class);
+
+    /**
+     * 海控项目,一步达WMS库存查询接口模拟
+     * @param requestParams
+     * @param responseParams
+     * @return
+     */
+    @ResponseBody
+    @RequestMapping(value="/esbcenter/api/esb/", produces = MediaType.APPLICATION_XML_VALUE)
+    public String list(@RequestParam(value = "requestParams", required = false) String requestParams,
+                     @RequestParam(value = "responseParams", required = false) String responseParams)  {
+        logger.info("---------- 一步达WMS::库存查询接口,模拟回执请求 ----------------------------------------");
+
+        logger.info("---------- 接收请求参数:{}", requestParams);
+
+        logger.info("---------- 接收到的回执参数:{}", responseParams);
+
+        return responseParams;
+    }
+
+}

+ 25 - 0
analog-api/src/main/java/com/songmao/analog/api/wmsyibuda/vo/ExtendProps.java

@@ -0,0 +1,25 @@
+package com.songmao.analog.api.wmsyibuda.vo;
+
+import java.io.Serializable;
+
+public class ExtendProps implements Serializable {
+    private static final long serialVersionUID = -1010285449684182191L;
+    public String value1;
+    public String value2;
+
+    public String getValue1() {
+        return value1;
+    }
+
+    public void setValue1(String value1) {
+        this.value1 = value1;
+    }
+
+    public String getValue2() {
+        return value2;
+    }
+
+    public void setValue2(String value2) {
+        this.value2 = value2;
+    }
+}

+ 121 - 0
analog-api/src/main/java/com/songmao/analog/api/wmsyibuda/vo/Item.java

@@ -0,0 +1,121 @@
+package com.songmao.analog.api.wmsyibuda.vo;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import java.io.Serializable;
+
+public class Item implements Serializable {
+    private static final long serialVersionUID = -2010285449684182190L;
+
+    public String warehouseCode;
+    public String itemCode;
+    public String itemId;
+    public String inventoryType;
+    public String imperfectGrade;
+    public String quantity;
+    public String lockQuantity;
+    public String batchCode;
+    public String productDate;
+    public String expireDate;
+    public String produceCode;
+
+    @XmlElementWrapper(name = "extendProps")
+    @XmlElement(name = "extendProp")
+    public String extendProps;
+
+    public String getWarehouseCode() {
+        return warehouseCode;
+    }
+
+    public void setWarehouseCode(String warehouseCode) {
+        this.warehouseCode = warehouseCode;
+    }
+
+    public String getItemCode() {
+        return itemCode;
+    }
+
+    public void setItemCode(String itemCode) {
+        this.itemCode = itemCode;
+    }
+
+    public String getItemId() {
+        return itemId;
+    }
+
+    public void setItemId(String itemId) {
+        this.itemId = itemId;
+    }
+
+    public String getInventoryType() {
+        return inventoryType;
+    }
+
+    public void setInventoryType(String inventoryType) {
+        this.inventoryType = inventoryType;
+    }
+
+    public String getImperfectGrade() {
+        return imperfectGrade;
+    }
+
+    public void setImperfectGrade(String imperfectGrade) {
+        this.imperfectGrade = imperfectGrade;
+    }
+
+    public String getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(String quantity) {
+        this.quantity = quantity;
+    }
+
+    public String getLockQuantity() {
+        return lockQuantity;
+    }
+
+    public void setLockQuantity(String lockQuantity) {
+        this.lockQuantity = lockQuantity;
+    }
+
+    public String getBatchCode() {
+        return batchCode;
+    }
+
+    public void setBatchCode(String batchCode) {
+        this.batchCode = batchCode;
+    }
+
+    public String getProductDate() {
+        return productDate;
+    }
+
+    public void setProductDate(String productDate) {
+        this.productDate = productDate;
+    }
+
+    public String getExpireDate() {
+        return expireDate;
+    }
+
+    public void setExpireDate(String expireDate) {
+        this.expireDate = expireDate;
+    }
+
+    public String getProduceCode() {
+        return produceCode;
+    }
+
+    public void setProduceCode(String produceCode) {
+        this.produceCode = produceCode;
+    }
+
+    public String getExtendProps() {
+        return extendProps;
+    }
+
+    public void setExtendProps(String extendProps) {
+        this.extendProps = extendProps;
+    }
+}

+ 52 - 0
analog-api/src/main/java/com/songmao/analog/api/wmsyibuda/vo/WmsResponse.java

@@ -0,0 +1,52 @@
+package com.songmao.analog.api.wmsyibuda.vo;
+
+
+import javax.xml.bind.annotation.*;
+import java.io.Serializable;
+import java.util.List;
+
+@XmlRootElement(name = "response")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class WmsResponse implements Serializable {
+    private static final long serialVersionUID = -2140285112234182103L;
+
+    private String flag;
+    private String code;
+    private String message;
+
+    @XmlElementWrapper(name = "items")
+    @XmlElement(name = "item")
+    private List<Item> items;
+
+    public String getFlag() {
+        return flag;
+    }
+
+    public void setFlag(String flag) {
+        this.flag = flag;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public List<Item> getItems() {
+        return items;
+    }
+
+    public void setItems(List<Item> items) {
+        this.items = items;
+    }
+}

+ 10 - 0
analog-api/src/main/resources/application-dev.yml

@@ -0,0 +1,10 @@
+#---------- analog 模拟系统 ----------#
+
+
+# 当前环境
+spring:
+    config:
+        activate:
+            on-profile: dev
+
+

+ 9 - 0
analog-api/src/main/resources/application-test.yml

@@ -0,0 +1,9 @@
+#---------- analog 模拟系统 ----------#
+
+
+# 当前环境
+spring:
+    config:
+        activate:
+            on-profile: test
+

+ 30 - 0
analog-api/src/main/resources/application.yml

@@ -0,0 +1,30 @@
+#---------- analog 模拟系统 ----------#
+
+
+# 项目配置
+app:
+    name: analog pangu
+    description: ${app.name} is a Spring Boot application
+
+# 服务配置
+server:
+    address: 127.0.0.1
+    port: 9999
+    servlet:
+        context-path: /
+
+#-------------------- 集中配置 begin --------------------#
+
+
+#-------------------- 集中配置 end --------------------#
+
+spring:
+    profiles:
+        active: dev
+    aop:
+        proxy-target-class: true
+
+    mvc:
+        throw-exception-if-no-handler-found: true
+
+

+ 232 - 0
analog-api/src/main/resources/logback.xml

@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
+scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
+debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
+-->
+<configuration scan="false" scanPeriod="60 seconds" debug="false">
+
+    <property name="LOG_HOME" value="/data/logs/analog/analog-api/"/>
+    <!-- 定义日志的根目录 -->
+    <property name="TRACE_DIR" value="trace" />
+    <property name="DEBUG_DIR" value="debug" />
+    <property name="INFO_DIR" value="info" />
+    <property name="WARN_DIR" value="warn" />
+    <property name="ERROR_DIR" value="error" />
+    <!-- 定义日志文件名称 -->
+    <property name="TRACE_FILE_NAME" value="analog-api-trace"></property>
+    <property name="DEBUG_FILE_NAME" value="analog-api-debug"></property>
+    <property name="INFO_FILE_NAME" value="analog-api-info"></property>
+    <property name="WARN_FILE_NAME" value="analog-api-warn"></property>
+    <property name="ERROR_FILE_NAME" value="analog-api-error"></property>
+
+    <!-- 定义日志级别颜色 -->
+    <!-- 控制台显示 -->
+    <property name="STD_CONSOLE_LOG_PATTERN"
+              value="%d{yyyy-MM-dd HH:mm:ss.SSS}[%yellow(%thread)]-[%highlight(%-5level)][%green(%logger{70}):%cyan(%line)] - %msg%n"/>
+
+    <!-- 日志文件打印 -->
+    <property name="CONSOLE_LOG_PATTERN"
+              value="%d{yyyy-MM-dd HH:mm:ss.SSS}[%thread]-[%-5level][%logger{70}:%line] - %msg%n"/>
+
+    <!-- ConsoleAppender 控制台输出 appender -->
+    <appender name="stdoutAppender" class="ch.qos.logback.core.ConsoleAppender">
+        <!--
+        日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度
+        %logger{70} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,%n是换行符
+        -->
+        <encoder>
+            <pattern>${STD_CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+
+    <!-- TRACE 日志 appender  -->
+    <appender name="traceAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${TRACE_DIR}/${TRACE_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${TRACE_DIR}/${TRACE_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>TRACE</level>
+            <!--<onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
+    </appender>
+
+
+    <!-- DEBUG 日志 appender  -->
+    <appender name="debugAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${DEBUG_DIR}/${DEBUG_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${DEBUG_DIR}/${DEBUG_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <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>
+
+
+    <!-- phrase 日志 appender  -->
+    <appender name="infoAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${INFO_DIR}/${INFO_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${INFO_DIR}/${INFO_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <!--<onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
+    </appender>
+
+
+    <!-- WARN 日志 appender  -->
+    <appender name="warnAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${WARN_DIR}/${WARN_FILE_NAME}.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_HOME}/${WARN_DIR}/${WARN_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <MaxHistory>365</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <!--<onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
+    </appender>
+
+
+    <!-- ERROR 日志 appender  -->
+    <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <file>${LOG_HOME}/${ERROR_DIR}/${ERROR_FILE_NAME}.log</file>
+        <!--
+        当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
+        TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
+        -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--
+            滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
+            %i:当文件大小超过maxFileSize时,按照i进行文件滚动
+            -->
+            <fileNamePattern>${LOG_HOME}/${ERROR_DIR}/${ERROR_FILE_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <!--
+            可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
+            且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,
+            那些为了归档而创建的目录也会被删除。
+            -->
+            <MaxHistory>365</MaxHistory>
+            <!--
+            当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy
+            -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <!--
+        日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %logger{70} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,%n是换行符
+        -->
+        <encoder>
+            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <!--
+        过滤器返回枚举:DENY,NEUTRAL,ACCEPT。
+        返回DENY,日志将立即被抛弃不再经过其他过滤器;返回NEUTRAL,有序列表里的下个过滤器过接着处理日志;返回ACCEPT,日志会被立即处理不再经过剩余过滤器。
+        LevelFilter: 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。节点:level,onMatch,onMismatch
+        -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
+            <!-- 设置过滤级别 -->
+            <level>ERROR</level>
+            <!-- 配置符合过滤条件的操作
+            <onMatch>ACCEPT</onMatch>
+            &lt;!&ndash; 配置不符合过滤条件的操作 &ndash;&gt;
+            <onMismatch>DENY</onMismatch>-->
+        </filter>
+    </appender>
+
+    <!--
+        logger主要用于存放日志对象,也可以定义日志类型、级别
+        name:表示匹配的logger类型前缀,也就是包的前半部分
+        level:要记录的日志级别,大小写无关,包括 TRACE,DEBUG,INFO,WARN,ERROR,ALL 和 OFF。
+        additivity:是否向上级loger传递打印信息。默认是true。 作用在于children-logger是否向上级root-logger配置的appender传递打印信息,false:不传递,true:传递
+    -->
+    <!--
+        没设置level,继承他的上级<root>的日志级别;
+        没有设置additivity,默认为true,将此loger的打印信息向上级<root>传递;
+        没有设置appender,此loger本身不打印任何信息;
+        子<logger>向<root>传递信息后,日志level 完全由子级别的level 决定;
+    -->
+
+    <logger name="org.apache.shiro" level="DEBUG" additivity="false" />
+    <logger name="com.zaxxer.hikari" level="ERROR" additivity="false" />
+    <logger name="org.apache" level="ERROR" />
+    <logger name="org.springframework.context.annotation.ClassPathBeanDefinitionScanner" level="INFO" />
+    <logger name="org.springframework.beans.factory.support.DefaultListableBeanFactory" level="INFO" />
+    <logger name="org.springframework.data.convert.CustomConversions" level="INFO"/>
+    <logger name="org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener" level="INFO" />
+    <logger name="org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping" level="INFO" />
+    <logger name="org.springframework" level="DEBUG" />
+    <logger name="io.netty" level="INFO" />
+    <logger name="org.mybatis" level="INFO" />
+    <logger name="org.hibernate" level="INFO" />
+    <logger name="io.lettuce" level="INFO" />
+    <logger name="springfox.documentation" level="INFO" />
+
+    <logger name="com.netflix.discovery" level="ERROR" />
+    <logger name="com.netflix.eureka" level="ERROR" />
+    <logger name="org.springframework.security" level="ERROR" />
+
+    <logger name="com.songmao" level="DEBUG"/>
+
+    <!--
+        logger优先,如果没有,则使用root,任何一个类只会匹配logger或root二者之一,
+        找到这个logger或root后,再logger的level和appender。
+    -->
+    <root level="DEBUG" >
+        <appender-ref ref="stdoutAppender" />
+        <!--<appender-ref ref="traceAppender" />-->
+        <appender-ref ref="debugAppender" />
+        <!--<appender-ref ref="infoAppender" />-->
+        <!--<appender-ref ref="warnAppender" />-->
+        <!--<appender-ref ref="errorAppender" />-->
+    </root>
+</configuration>

+ 144 - 0
build.gradle

@@ -0,0 +1,144 @@
+plugins {
+    id 'org.springframework.boot' version '2.6.1' apply(false)
+    id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply(false)
+    id 'java'
+    id 'war'
+}
+
+
+// 所有子项目通用配置
+subprojects {
+    group = 'com.songmao'
+    version = '1.0.0'
+
+    apply plugin: 'java'
+    apply plugin: 'war'
+
+    project (':analog-api', {
+        apply plugin: 'org.springframework.boot'
+        //提供类似Maven dependencyManagement依赖管理功能
+        apply plugin: 'io.spring.dependency-management'
+    })
+
+    // 指定子项目配置
+    /*configure (subprojects.findAll({
+        // 满足条件的子模块应用配置
+        it.name == 'analog-api'
+    }), {
+        apply plugin: 'org.springframework.boot'
+        //提供类似Maven dependencyManagement依赖管理功能
+        apply plugin: 'io.spring.dependency-management'
+    })*/
+
+
+    // 指定子项目配置
+    /*configure (subprojects.findAll(){
+        // 满足条件的子模块应用配置
+        it.name == 'songmao-common'
+    }) {
+        bootJar {
+            // 符合条件的子项目不使用bootJar打包方式
+            enabled = false
+        }
+    }*/
+
+    // Task type of JavaCompile
+    tasks.withType(JavaCompile, {
+        //enable compilation in a separate daemon process
+        sourceCompatibility = 8
+        targetCompatibility = 8
+        //options.release = 8
+        // default to true
+        options.incremental = true
+        // default to true
+        options.failOnError = false
+        // default to false
+        options.fork = true
+        options.encoding = "UTF-8"
+        // default to true
+        options.debug = true
+    })
+
+    // tag::repositories[]
+    repositories {
+        // 本地仓库
+        mavenLocal()
+        // ali 代理的central仓
+        maven {url 'https://maven.aliyun.com/repository/central'}
+        // ali 代理的central仓和jcenter仓的聚合仓
+        maven {url 'https://maven.aliyun.com/repository/public'}
+        maven {url 'https://maven.aliyun.com/repository/google'}
+        maven {url 'https://maven.aliyun.com/repository/gradle-plugin'}
+        maven {url 'https://maven.aliyun.com/repository/spring'}
+        maven {url 'https://maven.aliyun.com/repository/spring-plugin'}
+        maven {url 'https://maven.aliyun.com/repository/grails-core'}
+        // 远程中央仓库
+        mavenCentral()
+        maven {url 'https://repo1.maven.org/maven2/'}
+        maven {url 'https://plugins.gradle.org/m2/'}
+        maven {url 'https://repo.spring.io/libs-milestone/'}
+        maven {url 'https://repo.spring.io/plugins-release/'}
+        maven {url 'https://repo.grails.org/grails/core/'}
+        maven {url 'https://repository.apache.org/content/groups/public/'}
+        maven {url 'https://repository.jboss.org/nexus/content/repositories/releases/'}
+
+        // 配置使用本机nexus 私服
+        /*maven {
+            // 非https需要增加对不安全协议的信任
+            allowInsecureProtocol true
+            url 'http://127.0.0.1:8081/repository/local-maven-public/'
+            credentials {
+                username 'admin'
+                password 'admin123'
+            }
+        }*/
+        // 配置使用其它nexus 私服
+        maven {
+            // 非https需要增加对不安全协议的信任
+            allowInsecureProtocol true
+            url 'http://nexus.ds-bay.com/content/groups/public/'
+            credentials {
+                username 'admin'
+                password 'admin123'
+            }
+        }
+        //maven {url 'others url'}
+    }
+    // end::repositories[]
+
+    ext {
+        lombok = '1.18.22'
+
+        javax_annotation_api = '1.3.2'
+        javax_servlet = '4.0.1'
+
+        spring_boot = '2.6.1'
+        spring = '5.3.13'
+
+        // logback对spring的支持
+        logback_ext_spring = '0.1.4'
+
+        jackson = '2.11.2'
+
+        // 工具类
+        google_guava = '29.0-jre'
+
+        // Java工具包类库,各种Util工具类
+        hutool = '5.6.2'
+
+        // (推荐)Forest,Java HTTP 客户端框架
+        forest = '1.5.0-RC5'
+
+        // alibaba 出品 excel 工具类, 需要 lombok 支持
+        easyexcel = '3.0.5'
+
+
+    }
+
+}
+
+
+// others project() {}
+
+
+

+ 185 - 0
gradlew

@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MSYS* | MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"

+ 89 - 0
gradlew.bat

@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 3 - 0
settings.gradle

@@ -0,0 +1,3 @@
+rootProject.name = 'analog'
+include 'analog-api'
+