소스 검색

项目迁移

zhang-kan-kan 2 년 전
커밋
a73fa62ef2
24개의 변경된 파일3092개의 추가작업 그리고 0개의 파일을 삭제
  1. 37 0
      .gitignore
  2. 353 0
      pom.xml
  3. 23 0
      src/main/java/com/muzhi/meixi/MeiXiApplication.java
  4. 129 0
      src/main/java/com/muzhi/meixi/api/WdtClient.java
  5. 77 0
      src/main/java/com/muzhi/meixi/common/R.java
  6. 12 0
      src/main/java/com/muzhi/meixi/common/ResultCode.java
  7. 34 0
      src/main/java/com/muzhi/meixi/controller/AccessTokenController.java
  8. 57 0
      src/main/java/com/muzhi/meixi/controller/DingOaController.java
  9. 63 0
      src/main/java/com/muzhi/meixi/entity/Stocks.java
  10. 160 0
      src/main/java/com/muzhi/meixi/entity/StocksCopy.java
  11. 12 0
      src/main/java/com/muzhi/meixi/mapper/StocksCopyMapper.java
  12. 12 0
      src/main/java/com/muzhi/meixi/mapper/StocksMapper.java
  13. 5 0
      src/main/java/com/muzhi/meixi/mapper/xml/StocksCopyMapper.xml
  14. 5 0
      src/main/java/com/muzhi/meixi/mapper/xml/StocksMapper.xml
  15. 11 0
      src/main/java/com/muzhi/meixi/service/AccessTokenService.java
  16. 27 0
      src/main/java/com/muzhi/meixi/service/DingOaService.java
  17. 46 0
      src/main/java/com/muzhi/meixi/service/impl/AccessTokenServiceImpl.java
  18. 867 0
      src/main/java/com/muzhi/meixi/service/impl/DingOaServiceImpl.java
  19. 150 0
      src/main/java/com/muzhi/meixi/utils/FileItem.java
  20. 129 0
      src/main/java/com/muzhi/meixi/utils/StringUtils.java
  21. 572 0
      src/main/java/com/muzhi/meixi/utils/WebUtils.java
  22. 57 0
      src/main/resources/application.properties
  23. 241 0
      src/test/java/com/muzhi/meixi/APITest/Test1.java
  24. 13 0
      src/test/java/com/muzhi/meixi/TestApplicationTests.java

+ 37 - 0
.gitignore

@@ -0,0 +1,37 @@
+# IntelliJ project files
+.idea
+*.iml
+out
+gen
+### Java template
+# Compiled class file
+*.class
+
+# Log file
+*.log
+/log/
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+mvnw
+mvnw.cmd
+
+# tmp file
+.tmp
+/tmp/

+ 353 - 0
pom.xml

@@ -0,0 +1,353 @@
+<?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>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.3.3.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.muzhi.meixi</groupId>
+    <artifactId>meixi</artifactId>
+<!--    <packaging>jar</packaging>-->
+    <version>1.0-SNAPSHOT</version>
+    <name>meixi</name>
+    <description>Demo project for Spring Boot</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <fastjson.version>1.2.33</fastjson.version>
+        <gson.version>2.8.2</gson.version>
+        <json.version>20170516</json.version>
+        <poi.version>3.17</poi.version>
+        <jodatime.version>2.10.1</jodatime.version>
+        <swagger.version>2.7.0</swagger.version>
+        <commons-fileupload.version>1.3.1</commons-fileupload.version>
+        <!--        <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>-->
+        <!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本-->
+        <!--        <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>-->
+    </properties>
+
+    <repositories>
+        <repository>
+            <id>sonatype-nexus-staging</id>
+            <name>Sonatype Nexus Staging</name>
+            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.4.0</version>
+        </dependency>
+
+        <!-- httpClient -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.13</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-httpclient</groupId>
+            <artifactId>commons-httpclient</artifactId>
+            <version>3.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.4.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.konghq</groupId>
+            <artifactId>unirest-java</artifactId>
+            <version>2.3.17</version>
+        </dependency>
+
+<!--        <dependency>-->
+<!--            <groupId>org.slf4j</groupId>-->
+<!--            <artifactId>slf4j-api</artifactId>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>commons-io</groupId>-->
+<!--            <artifactId>commons-io</artifactId>-->
+<!--        </dependency>-->
+
+        <!--json 组件 -->
+<!--        <dependency>-->
+<!--            <groupId>com.alibaba</groupId>-->
+<!--            <artifactId>fastjson</artifactId>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+
+        <!--        <dependency>-->
+        <!--            <groupId>org.apache.cxf</groupId>-->
+        <!--            <artifactId>cxf-spring-boot-starter-jaxws</artifactId>-->
+        <!--            <version>3.3.1</version>-->
+        <!--        </dependency>-->
+
+        <!--        <dependency>-->
+        <!--            <groupId>org.springframework.boot</groupId>-->
+        <!--            <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
+        <!--&lt;!&ndash;            <version>2.3.3.RELEASE</version>&ndash;&gt;-->
+        <!--        </dependency>-->
+
+        <!--钉钉相关-->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>alibaba-dingtalk-service-sdk</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>dingtalk</artifactId>
+            <version>1.4.35</version>
+        </dependency>
+
+        <!--json相关-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>${json.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>${gson.version}</version>
+        </dependency>
+
+        <!--        <dependency>-->
+        <!--            <groupId>net.sf.json-lib</groupId>-->
+        <!--            <artifactId>json-lib</artifactId>-->
+        <!--            <version>2.4</version>-->
+        <!--        </dependency>-->
+
+
+        <!-- JSONObject对象依赖的jar包 -->
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.9.3</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+            <version>3.2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.ezmorph</groupId>
+            <artifactId>ezmorph</artifactId>
+            <version>1.0.6</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.json-lib</groupId>
+            <artifactId>json-lib</artifactId>
+            <version>2.2.3</version>
+            <classifier>jdk15</classifier><!-- 指定jdk版本 -->
+        </dependency>
+
+
+        <!--xls-->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <!--xlsx-->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <!--文件上传-->
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>${commons-fileupload.version}</version>
+        </dependency>
+
+        <!--        <dependency>-->
+        <!--            <groupId>org.springframework.boot</groupId>-->
+        <!--            <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
+        <!--        </dependency>-->
+
+        <!--引入web模块-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <version>2.3.3.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+            <version>1.18.10</version>
+        </dependency>
+
+        <!--mybatis-plus数据库连接-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+        <!--引入mysql:数据库驱动-->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <!--引入druid数据源-->
+        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.9</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.1.9</version>
+        </dependency>
+
+        <!--引入jpa模块-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+
+        <!--日期时间工具-->
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>${jodatime.version}</version>
+        </dependency>
+
+        <!--日期工具-->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>4.6.8</version>
+        </dependency>
+
+        <!--log4j-->
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+
+        <!--swagger-->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>${swagger.version}</version>
+        </dependency>
+        <!--swagger ui-->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>${swagger.version}</version>
+        </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>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <fork>true</fork>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.3.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>utf8</encoding>
+                </configuration>
+            </plugin>
+
+            <!--打包跳过测试-->
+<!--            <plugin>-->
+<!--                <groupId>org.apache.maven.plugins</groupId>-->
+<!--                <artifactId>maven-surefire-plugin</artifactId>-->
+<!--                <version>2.4.2</version>-->
+<!--                <configuration>-->
+<!--                    <skipTests>true</skipTests>-->
+<!--                </configuration>-->
+<!--            </plugin>-->
+        </plugins>
+
+        <!--映射mapper中对应的xml配置文件,如果没有mapper.xml文件则将下列注释-->
+<!--        <resources>-->
+<!--            <resource>-->
+<!--                <directory>src/main/java</directory>-->
+<!--                <includes>-->
+<!--                    <include>**/*.xml</include>-->
+
+<!--                    <include>**/*.properties</include>-->
+<!--                    <include>**/*.tld</include>-->
+<!--                    <include>**/*.xls</include>-->
+<!--                    <include>**/*.xlsx</include>-->
+<!--                </includes>-->
+<!--                <filtering>false</filtering>-->
+<!--            </resource>-->
+<!--        </resources>-->
+    </build>
+
+</project>

+ 23 - 0
src/main/java/com/muzhi/meixi/MeiXiApplication.java

@@ -0,0 +1,23 @@
+package com.muzhi.meixi;
+
+//import org.mybatis.spring.annotation.MapperScan;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+
+@MapperScan("com.muzhi.meixi.mapper")
+@EnableAsync//开启异步注解
+@SpringBootApplication//启动时不加载数据库(exclude= DataSourceAutoConfiguration.class)
+@EnableScheduling//开启定时任务
+//@ComponentScan(basePackages = {"com.muzhi"})
+public class MeiXiApplication {
+
+    public static void main(String[] args){
+        SpringApplication.run(MeiXiApplication.class, args);
+    }
+
+}

+ 129 - 0
src/main/java/com/muzhi/meixi/api/WdtClient.java

@@ -0,0 +1,129 @@
+package com.muzhi.meixi.api;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.Map;
+
+import com.muzhi.meixi.utils.WebUtils;
+
+public class WdtClient {
+	
+	private String appkey;
+	private String appsecret;
+	private String sid;
+	private String baseUrl;
+	
+	private int connectTimeout = 3000;//3秒
+	private int readTimeout = 15000;//15秒
+	
+	public WdtClient(String sid, String appkey, String appsecret, String baseUrl)
+	{
+		this.sid = sid;
+		this.appkey = appkey;
+		this.appsecret = appsecret;
+		this.baseUrl = baseUrl;
+		
+		if(!this.baseUrl.endsWith("/")) 
+			this.baseUrl = this.baseUrl+"/";
+	}
+	
+	public void setTimeout(int connectTimeout, int readTimeout)
+	{
+		this.connectTimeout = connectTimeout;
+		this.readTimeout = readTimeout;
+	}
+	
+	private static String getStringFromException(Throwable e) {
+		String result = "";
+		ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		PrintStream ps = new PrintStream(bos);
+		e.printStackTrace(ps);
+		try {
+			result = bos.toString("UTF-8");
+		} catch (IOException ioe) {
+		}
+		return result;
+	}
+	
+	private static byte[] encryptMD5(String data) throws IOException {
+		byte[] bytes = null;
+		try {
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			bytes = md.digest(data.getBytes("UTF-8"));
+		} catch (GeneralSecurityException gse) {
+			String msg = getStringFromException(gse);
+			throw new IOException(msg);
+		}
+		return bytes;
+	}
+	
+	private static String byte2hex(byte[] bytes) {
+		StringBuilder sign = new StringBuilder();
+		for (int i = 0; i < bytes.length; i++) {
+			String hex = Integer.toHexString(bytes[i] & 0xFF);
+			if (hex.length() == 1) {
+				//保证所有的16进制都是两位:00-ff,其中[80~ff]代表[-128,-1]
+				sign.append("0");
+			}
+			sign.append(hex);
+		}
+		return sign.toString();
+	}
+	
+	/**
+	 * 给TOP请求签名。
+	 * 
+	 * @param params 所有字符型的TOP请求参数
+	 * @param appsecret 签名密钥
+	 * @return 签名
+	 * @throws IOException 
+	 */
+	public static String signRequest(Map<String, String> params, String appsecret) throws IOException {
+		// 第一步:检查参数是否已经排序
+		String[] keys = params.keySet().toArray(new String[0]);
+		Arrays.sort(keys);
+
+		// 第二步:把所有参数名和参数值串在一起
+		StringBuilder query = new StringBuilder();
+		for (String key : keys) {
+			if("sign".equals(key))
+				continue;
+			
+			if(query.length() > 0)
+				query.append(';');
+			
+			int len = key.length();
+			query.append(String.format("%02d", len)).append('-').append(key).append(':');
+			
+			String value = params.get(key);
+			
+			len = value.length();
+			query.append(String.format("%04d", len)).append('-').append(value);
+			
+		}
+		
+		query.append(appsecret);
+		
+		// 第三步:使用MD5加密
+		byte[] bytes = encryptMD5(query.toString());
+
+		// 第四步:把二进制转化为大写的十六进制
+		return byte2hex(bytes);
+	}
+	
+	public String execute(String relativeUrl, Map<String, String> params) throws IOException {
+		
+		params.put("appkey", this.appkey);
+		params.put("sid", this.sid);
+		params.put("timestamp", Long.toString(System.currentTimeMillis()/1000));
+		
+		params.put("sign", signRequest(params, this.appsecret));
+		
+		return WebUtils.doPost(this.baseUrl + relativeUrl, params, "UTF-8", connectTimeout, readTimeout, null);
+		
+	}
+}

+ 77 - 0
src/main/java/com/muzhi/meixi/common/R.java

@@ -0,0 +1,77 @@
+package com.muzhi.meixi.common;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author ZhangKan
+ * @Data 11:20
+ */
+
+//统一返回结果类
+@Data
+public class R {
+
+    @ApiModelProperty(value = "是否成功")
+    private Boolean success;
+
+    @ApiModelProperty(value = "返回码")
+    private Integer code;
+
+    @ApiModelProperty(value = "返回消息")
+    private String message;
+
+    @ApiModelProperty(value = "返回数据")
+    private Map<String, Object> data = new HashMap<String, Object>();
+
+    //把构造方法私有
+    private R(){}
+
+    //成功静态方法
+    public static R ok(){
+
+        R r = new R();
+        r.setSuccess(true);
+        r.setCode(ResultCode.SUCCESS);
+        r.setMessage("成功");
+        return r;
+    }
+
+    //失败静态方法
+    public static R error(){
+
+        R r = new R();
+        r.setSuccess(false);
+        r.setCode(ResultCode.ERROR);
+        r.setMessage("失败");
+        return r;
+    }
+
+    public R message(String message){
+        this.setMessage(message);
+        return this;
+    }
+
+    public R code(Integer code){
+        this.setCode(code);
+        return this;
+    }
+
+    public R data(String key, Object value){
+        this.data.put(key, value);
+        return this;
+    }
+
+    public R data(String key, String value){
+        this.data.put(key, value);
+        return this;
+    }
+
+    public R data(Map<String, Object> map){
+        this.setData(map);
+        return this;
+    }
+}

+ 12 - 0
src/main/java/com/muzhi/meixi/common/ResultCode.java

@@ -0,0 +1,12 @@
+package com.muzhi.meixi.common;
+
+/**
+ * @Author ZhangKan
+ * @Data 11:15
+ */
+public interface ResultCode {
+
+    public static Integer SUCCESS = 200;//成功
+
+    public static Integer ERROR = 201;//失败
+}

+ 34 - 0
src/main/java/com/muzhi/meixi/controller/AccessTokenController.java

@@ -0,0 +1,34 @@
+package com.muzhi.meixi.controller;
+
+import com.muzhi.meixi.service.AccessTokenService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author ZhangKan
+ * @Data 15:03
+ */
+
+@Api(description = "钉钉授权AccessToken")
+@RestController
+@RequestMapping("/dingservice")
+@CrossOrigin//解决跨域问题
+public class AccessTokenController {
+
+    @Autowired
+    private AccessTokenService AccessTokenService;
+
+    //获取钉钉中的access_token(美犀架构)
+    @ApiOperation(value = "获取钉钉中的access_token")
+    @GetMapping("getAccessToken")
+    public String getAccessToken(){
+
+        String accessToken = AccessTokenService.getAccessToken();
+        return accessToken;
+    }
+}

+ 57 - 0
src/main/java/com/muzhi/meixi/controller/DingOaController.java

@@ -0,0 +1,57 @@
+package com.muzhi.meixi.controller;
+
+import com.muzhi.meixi.common.R;
+import com.muzhi.meixi.service.DingOaService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+
+@Api(description = "钉钉")
+@RestController
+@RequestMapping("/dingservice")
+@CrossOrigin//解决跨域问题
+public class DingOaController {
+
+    @Autowired
+    private DingOaService dingOaService;
+
+    //获取旺店通库存信息
+    @ApiOperation(value = "获取旺店通库存信息")
+    @GetMapping("getWangdiantongStocks")
+//    @Scheduled(cron = "0 10 0 * * ?")//每天00:10触发(也就是凌晨0点10分触发)
+//    @Scheduled(cron = "0 0/10 * * * ?")//每10分钟执行一次
+    @Scheduled(cron = "0 */10 * * * ?")//每隔10分钟执行一次
+    public String getWangdiantongStocks(){
+        //先删除清空Stocks表
+        dingOaService.removeStocks();
+
+        String wangdiantongStocks = dingOaService.getWangdiantongStocks();
+        return wangdiantongStocks;
+    }
+
+    //旺店通库存信息表同步展示表
+//    @ApiOperation(value = "获取旺店通库存信息")
+//    @GetMapping("setStocksCopy")
+//    @Scheduled(cron = "0 35 0 * * ?")//每天00:35触发(也就是凌晨0点35分触发)
+//    public String setStocksCopy(){
+//
+//        String setStocksCopy = dingOaService.setStocksCopy();
+//        return setStocksCopy;
+//    }
+
+    //获取旺店通库存信息,并同步至宜搭
+//    @ApiOperation(value = "获取旺店通库存信息,并同步至宜搭")
+//    @PostMapping("createWangdiantongStocks")
+//    @Scheduled(cron = "0 5 1 * * ?")//每天01:05触发(也就是凌晨1点05分触发)
+//    public String createWangdiantongStocks(){
+//
+//        String wangdiantongStocks = dingOaService.createWangdiantongStocks();
+//        return wangdiantongStocks;
+//    }
+}

+ 63 - 0
src/main/java/com/muzhi/meixi/entity/Stocks.java

@@ -0,0 +1,63 @@
+package com.muzhi.meixi.entity;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "库存信息", description = "美犀旺店通库存信息")
+public class Stocks {
+
+    @ApiModelProperty(value = "条形码")
+    private String barcode;
+
+    @ApiModelProperty(value = "货品编码")
+    private String goodsNo;
+
+    @ApiModelProperty(value = "货品名称")
+    private String goodsName;
+
+    @ApiModelProperty(value = "仓库主键id")
+    private String warehouseId;
+
+    @ApiModelProperty(value = "仓库编码")
+    private String warehouseNo;
+
+    @ApiModelProperty(value = "仓库名称")
+    private String warehouseName;
+
+    @ApiModelProperty(value = "库存量")
+    private float stockNum;
+
+    @ApiModelProperty(value = "产品编码")
+    private String cpbm;
+
+    @ApiModelProperty(value = "通用小名")
+    private String tyxm;
+
+    @ApiModelProperty(value = "国内加总")
+    private float gnjz;
+
+    @ApiModelProperty(value = "日销")
+    private float rx;
+
+    @ApiModelProperty(value = "剩余售卖天数")
+    private float sysmts;
+
+    @ApiModelProperty(value = "当前剩余库存")
+    private float dqsykc;
+
+    @ApiModelProperty(value = "下月剩余库存")
+    private float xysykc;
+
+    @ApiModelProperty(value = "预估断货日")
+    private Date ygdhr;
+}

+ 160 - 0
src/main/java/com/muzhi/meixi/entity/StocksCopy.java

@@ -0,0 +1,160 @@
+package com.muzhi.meixi.entity;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "库存信息", description = "美犀旺店通库存展示信息")
+public class StocksCopy {
+
+    @ApiModelProperty(value = "条形码")
+    private String barcode;
+
+    @ApiModelProperty(value = "货品编码")
+    private String goodsNo;
+
+    @ApiModelProperty(value = "货品名称")
+    private String goodsName;
+
+
+    /*======仓库======*/
+    @ApiModelProperty(value = "奇门菜鸟仓编码048")
+    private String qmcncNo;
+
+    @ApiModelProperty(value = "奇门菜鸟仓名称")
+    private String qmcncName;
+
+    @ApiModelProperty(value = "奇门菜鸟仓存量")
+    private float qmcncNum;
+
+    @ApiModelProperty(value = "天猫仓编码020")
+    private String tmcNo;
+
+    @ApiModelProperty(value = "天猫仓名称")
+    private String tmcName;
+
+    @ApiModelProperty(value = "天猫仓库存量")
+    private float tmcNum;
+
+    @ApiModelProperty(value = "网红仓编码021")
+    private String whcNo;
+
+    @ApiModelProperty(value = "网红仓名称")
+    private String whcName;
+
+    @ApiModelProperty(value = "网红仓库存量")
+    private float whcNum;
+
+    @ApiModelProperty(value = "分销仓编码022")
+    private String fxcNo;
+
+    @ApiModelProperty(value = "分销仓名称")
+    private String fxcName;
+
+    @ApiModelProperty(value = "分销仓库存量")
+    private float fxcNum;
+
+    @ApiModelProperty(value = "备用仓编码023")
+    private String bycNo;
+
+    @ApiModelProperty(value = "备用仓名称")
+    private String bycName;
+
+    @ApiModelProperty(value = "备用仓库存量")
+    private float bycNum;
+
+    @ApiModelProperty(value = "次品仓编码024")
+    private String cpcNo;
+
+    @ApiModelProperty(value = "次品仓名称")
+    private String cpcName;
+
+    @ApiModelProperty(value = "次品仓库存量")
+    private float cpcNum;
+
+    @ApiModelProperty(value = "徐汇仓编码025")
+    private String xhcNo;
+
+    @ApiModelProperty(value = "徐汇仓名称")
+    private String xhcName;
+
+    @ApiModelProperty(value = "徐汇仓库存量")
+    private float xhcNum;
+
+    @ApiModelProperty(value = "广州仓编码026")
+    private String gzcNo;
+
+    @ApiModelProperty(value = "广州仓名称")
+    private String gzcName;
+
+    @ApiModelProperty(value = "广州仓库存量")
+    private float gzcNum;
+
+    @ApiModelProperty(value = "直营仓编码033")
+    private String zycNo;
+
+    @ApiModelProperty(value = "直营仓名称")
+    private String zycName;
+
+    @ApiModelProperty(value = "直营仓库存量")
+    private float zycNum;
+
+    @ApiModelProperty(value = "广州次品仓编码059")
+    private String gzcpcNo;
+
+    @ApiModelProperty(value = "广州次品仓名称")
+    private String gzcpcName;
+
+    @ApiModelProperty(value = "广州次品仓库存量")
+    private float gzcpcNum;
+
+    @ApiModelProperty(value = "暂存仓编码060")
+    private String zccNo;
+
+    @ApiModelProperty(value = "暂存仓名称")
+    private String zccName;
+
+    @ApiModelProperty(value = "暂存仓库存量")
+    private float zccNum;
+    /*======仓库======*/
+
+
+    @ApiModelProperty(value = "产品编码")
+    private String cpbm;
+
+    @ApiModelProperty(value = "通用小名")
+    private String tyxm;
+
+    @ApiModelProperty(value = "国内加总")
+    private float gnjz;
+
+    @ApiModelProperty(value = "日销")
+    private float rx;
+
+    @ApiModelProperty(value = "剩余售卖天数")
+    private float sysmts;
+
+    @ApiModelProperty(value = "当前剩余库存")
+    private float dqsykc;
+
+    @ApiModelProperty(value = "下月剩余库存")
+    private float xysykc;
+
+    @ApiModelProperty(value = "预估断货日")
+    private Date ygdhr;
+
+    @ApiModelProperty(value = "本月剩余天数")
+    private int bysyts;
+
+    @ApiModelProperty(value = "下月总天数")
+    private int xyzts;
+}

+ 12 - 0
src/main/java/com/muzhi/meixi/mapper/StocksCopyMapper.java

@@ -0,0 +1,12 @@
+package com.muzhi.meixi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muzhi.meixi.entity.Stocks;
+import com.muzhi.meixi.entity.StocksCopy;
+import org.springframework.stereotype.Repository;
+
+//在对应的Mapper上面继承基本的类BaseMapper
+@Repository//代表持久层,或者加入@Mapper注解
+public interface StocksCopyMapper extends BaseMapper<StocksCopy> {
+    //所有的CRUD操作都已经编写完成了
+}

+ 12 - 0
src/main/java/com/muzhi/meixi/mapper/StocksMapper.java

@@ -0,0 +1,12 @@
+package com.muzhi.meixi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.muzhi.meixi.entity.Stocks;
+import com.muzhi.meixi.entity.StocksCopy;
+import org.springframework.stereotype.Repository;
+
+//在对应的Mapper上面继承基本的类BaseMapper
+@Repository//代表持久层,或者加入@Mapper注解
+public interface StocksMapper extends BaseMapper<Stocks> {
+    //所有的CRUD操作都已经编写完成了
+}

+ 5 - 0
src/main/java/com/muzhi/meixi/mapper/xml/StocksCopyMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.muzhi.meixi.mapper.StocksCopyMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/muzhi/meixi/mapper/xml/StocksMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.muzhi.meixi.mapper.StocksMapper">
+
+</mapper>

+ 11 - 0
src/main/java/com/muzhi/meixi/service/AccessTokenService.java

@@ -0,0 +1,11 @@
+package com.muzhi.meixi.service;
+
+/**
+ * @Author ZhangKan
+ * @Data 15:34
+ */
+public interface AccessTokenService {
+
+    //获取access_token的方法(美邸艾架构)
+    String getAccessToken();
+}

+ 27 - 0
src/main/java/com/muzhi/meixi/service/DingOaService.java

@@ -0,0 +1,27 @@
+package com.muzhi.meixi.service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author ZhangKan
+ * @Data 15:34
+ */
+public interface DingOaService {
+
+    //删除旺店通同步库存表中的所有数据
+    String removeStocks();
+
+    //删除宜搭展示库存表
+//    String removeStocksCopy();
+
+
+    //获取旺店通库存信息
+    String getWangdiantongStocks();
+
+    //旺店通库存信息表同步展示表
+    String setStocksCopy();
+
+    //获取旺店通库存信息,并同步至宜搭
+    String createWangdiantongStocks();
+}

+ 46 - 0
src/main/java/com/muzhi/meixi/service/impl/AccessTokenServiceImpl.java

@@ -0,0 +1,46 @@
+package com.muzhi.meixi.service.impl;
+
+import com.dingtalk.api.DefaultDingTalkClient;
+import com.dingtalk.api.request.OapiGettokenRequest;
+import com.dingtalk.api.response.OapiGettokenResponse;
+import com.muzhi.meixi.service.AccessTokenService;
+import com.taobao.api.ApiException;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * @Author ZhangKan
+ * @Data 15:39
+ */
+
+@Service
+public class AccessTokenServiceImpl implements AccessTokenService {
+
+    //美犀
+    //APPKEY
+    private static String APPKEY = "dingfzex4b8uyuvgo0ap";
+    //APPSECRET
+    private static String APPSECRET = "GAO61byMYd5EjMQT9zoLMn-3e4qWMJBcxzwBrXa5Z8cGn_BJUr3KntW1dbgbS_jY";
+    //AgenthId:2184795806
+
+    public static String accessToken = null;
+
+
+    //获取access_token的方法(美犀架构)
+    @Override
+    public String getAccessToken() {
+        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+        OapiGettokenRequest request = new OapiGettokenRequest();
+        request.setAppkey(APPKEY);
+        request.setAppsecret(APPSECRET);
+        request.setHttpMethod("GET");
+        try {
+            OapiGettokenResponse response = client.execute(request);
+            accessToken = response.getAccessToken();
+            System.out.println("AccessToken:" + accessToken);
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+        return accessToken;
+    }
+}

+ 867 - 0
src/main/java/com/muzhi/meixi/service/impl/DingOaServiceImpl.java

@@ -0,0 +1,867 @@
+package com.muzhi.meixi.service.impl;
+
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponse;
+import com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsResponse;
+import com.aliyun.dingtalkyida_1_0.models.SearchFormDatasResponse;
+import com.aliyun.tea.TeaException;
+import com.aliyun.teautil.models.RuntimeOptions;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.muzhi.meixi.api.WdtClient;
+import com.muzhi.meixi.entity.Stocks;
+import com.muzhi.meixi.entity.StocksCopy;
+import com.muzhi.meixi.mapper.StocksCopyMapper;
+import com.muzhi.meixi.mapper.StocksMapper;
+import com.muzhi.meixi.service.AccessTokenService;
+import com.muzhi.meixi.service.DingOaService;
+import lombok.extern.log4j.Log4j;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+@Service
+@Slf4j
+public class DingOaServiceImpl implements DingOaService {
+
+    @Autowired
+    private AccessTokenService accessTokenService;
+
+    //旺店通同步库存
+    @Autowired
+    private StocksMapper stocksMapper;
+
+    //宜搭展示库存表
+    @Autowired
+    private StocksCopyMapper stocksCopyMapper;
+
+
+
+    //删除旺店通同步库存表中的所有数据
+    @Override
+    public String removeStocks(){
+        stocksMapper.delete(null);
+        return "清空旺店通同步库存数据成功!";
+    }
+
+    //删除宜搭展示库存表
+//    @Override
+//    public String removeStocksCopy(){
+//        stocksCopyMapper.delete(null);
+//        return "清空旺店通同步库存数据成功!";
+//    }
+
+
+
+    //获取旺店通库存信息
+    @Override
+    public String getWangdiantongStocks(){
+//        //卖家账号
+//        String sidTest = "apidevnew2";
+//        //接口账号
+//        String appkeyTest = "xindi2-test";
+//        //接口秘钥
+//        String appsecretTest = "bff3980d2";
+//        //测试环境
+//        String baseUrlTest = "https://sandbox.wangdian.cn/openapi2/";
+
+//        //测试
+//        WdtClient client = new WdtClient(sidTest, appkeyTest, appsecretTest, baseUrlTest);
+
+        //卖家账号
+        String sid = "xindi2";
+        //接口账号
+        String appkey = "xindi2-ot";
+        //接口秘钥
+        String appsecret = "7aaa92c1cb4b8c00d42082b5d430c55a";
+        //正式环境
+        String baseUrl = "https://api.wangdian.cn/openapi2/";
+
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        //获取当前时间时分秒
+        Date Date = new Date(System.currentTimeMillis());
+        System.out.println("当前时间:" + Date);
+        String dateNowString = simpleDateFormat.format(Date);
+        System.out.println("当前时间(时间样式):" + dateNowString);
+
+        //获取前一天的零点零分零秒
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(Date);
+        //前一天
+        calendar.add(Calendar.DAY_OF_MONTH,-1);
+        calendar.set(Calendar.HOUR_OF_DAY,0);
+        calendar.set(Calendar.MINUTE,0);
+        calendar.set(Calendar.SECOND,0);
+        calendar.set(Calendar.MILLISECOND,0);
+        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
+        System.out.println("前一天零点(时间样式):" + time);
+
+        List list = new ArrayList();
+        list.add("048");//奇门菜鸟仓
+        list.add("020");//天猫仓
+        list.add("021");//网红仓
+        list.add("022");//分销仓
+        list.add("023");//备用仓
+//        list.add("024");//次品仓
+//        list.add("025");//徐汇仓
+        list.add("026");//广州仓
+        list.add("033");//直营仓
+//        list.add("059");//广州次品仓
+//        list.add("060");//暂存仓
+        for (int a = 0; a < list.size(); a++) {
+            String warehouseId = list.get(a).toString();
+            log.info("=========当前查询仓库编号=========:" + warehouseId);
+            System.out.println("=========当前仓库编号=========:" + warehouseId);
+
+            //休眠时间
+            final long timeInterval = 800;
+
+            String page_no = "0";
+            String page_size = "100";
+
+            JSONArray stocksArray = null;
+            try {
+                do {
+                    //正式
+                    WdtClient client = new WdtClient(sid, appkey, appsecret, baseUrl);
+
+                    //测试环境sid、appkey、密钥请到旺店通开放平台-自助对接-申请测试环境内查看,测试环境url=https://sandbox.wangdian.cn/openapi2/
+                    //调用正式环境时请将sid、appkey、appsecret切换为实际参数,参数在旺店通开放平台-自助对接-应用管理内应用状态为已上线的应用中查看,调用正式环境注意切换正式环境url=https://api.wangdian.cn/openapi2/
+
+                    System.out.println("当前分页数:" + page_no);
+
+                    Map<String, String> params = new HashMap<>();
+                    //【全量查询库存接口】
+//                    params.put("warehouse_no", warehouseId);
+////                    params.put("start_time","2022-11-01 00:00:00");
+////                    params.put("end_time","2022-11-29 00:00:00");
+//                    params.put("page_no", page_no);
+//                    params.put("page_size", page_size);
+//
+//                    JSONObject jsonObject = null;
+//                    try {
+//                        String response = client.execute("vip_stock_query_all.php", params);
+//                        System.out.println("分页【" + page_no + "】调用返回数据" + response);
+//
+//                        jsonObject = JSON.parseObject(response);
+//
+//                    } catch (IOException e) {
+//                        e.printStackTrace();
+//                    }
+
+                    //【增量查询库存接口】
+                    //仓库编号
+                    params.put("warehouse_no", warehouseId);
+                    //商家编码
+//                    params.put("spec_no","xindi2");
+                    //已删除货品库存信息(1代表查询未删除库存,不传或者传0查询所有库存)
+                    params.put("is_deleted","1");
+//                    params.put("start_time","2020-07-01 00:00:00");
+//                    params.put("end_time","2020-07-31 00:00:00");
+                    //开始时间(前一天时间)
+                    params.put("start_time",time);
+                    //结束时间(当前时间)
+                    params.put("end_time",dateNowString);
+                    params.put("page_no", page_no);
+                    params.put("page_size", page_size);
+
+                    JSONObject jsonObject = null;
+                    try {
+                        String response = client.execute("stock_query.php", params);
+                        System.out.println("分页【" + page_no + "】调用返回数据" + response);
+
+                        jsonObject = JSON.parseObject(response);
+
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+
+//            String total_count = jsonObject.getString("total_count");
+//            int total_countAll = Integer.parseInt(total_count);
+//            System.out.println("总数:" + total_countAll);
+//            int page_noAll = total_countAll/100;
+//            System.out.println("总页数:" + page_noAll);
+
+                    Stocks stocks = new Stocks();
+                    stocksArray = jsonObject.getJSONArray("stocks");
+                for (int i = 0; i < stocksArray.size(); i++) {
+                    JSONObject jsonObject1 = stocksArray.getJSONObject(i);
+                    //条形码
+                    String barcode = jsonObject1.getString("barcode");
+                    stocks.setBarcode(barcode);
+                    //货品编码
+                    String goods_no = jsonObject1.getString("goods_no");
+                    stocks.setGoodsNo(goods_no);
+                    //货品名称
+                    String goods_name = jsonObject1.getString("goods_name");
+                    stocks.setGoodsName(goods_name);
+                    //仓库主键id
+                    String warehouse_id = jsonObject1.getString("warehouse_id");
+                    stocks.setWarehouseId(warehouse_id);
+                    //仓库编码
+                    String warehouse_no = jsonObject1.getString("warehouse_no");
+                    stocks.setWarehouseNo(warehouse_no);
+                    //仓库名称
+                    String warehouse_name = jsonObject1.getString("warehouse_name");
+                    stocks.setWarehouseName(warehouse_name);
+//                    //库存量
+//                    Float stock_num = jsonObject1.getFloat("stock_num");
+//                    stocks.setStockNum(stock_num);
+                    //可发库存
+                    Float stock_num = jsonObject1.getFloat("avaliable_num");
+                    stocks.setStockNum(stock_num);
+
+                    stocksMapper.insert(stocks);
+                }
+
+                    int page_noINT = Integer.parseInt(page_no);
+                    page_noINT = page_noINT + 1;
+                    page_no = String.valueOf(page_noINT);
+
+                    //休眠3秒钟再次调用:由于旺店通接口1分钟只能调用60次接口
+                    Thread.sleep(timeInterval);
+                    log.info("休眠中......");
+
+                }while (!stocksArray.isEmpty() & stocksArray.size() == 100);
+
+            }catch (InterruptedException e){
+                e.printStackTrace();
+            }
+        }
+//        log.info("======&&&&&&******【旺店通库存表数据同步结束】******&&&&&&======");
+//        return "旺店通库存信息同步至数据库成功!";
+
+        /*旺店通库存同步完成后调用该方法同步至展示表*/
+        log.info("开始调用同步展示表方法......");
+        setStocksCopy();
+        log.info("===同步展示表方法结束===");
+
+        /*更新宜搭库存表*/
+        log.info("开始调用更新宜搭库存表方法......");
+        createWangdiantongStocks();
+        log.info("===同步宜搭库存表方法结束===");
+
+        log.info("======&&&&&&******【旺店通库存表同步宜搭结束】******&&&&&&======");
+        return "旺店通库存表同步宜搭结束!";
+    }
+
+    //旺店通库存信息表同步展示表
+    @Override
+    public String setStocksCopy(){
+
+//        //本月剩余天数
+//        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:OO"));
+//        int days = calendar.get(Calendar.DAY_OF_MONTH);
+//        System.out.println("本月当前天数:" + days);
+//        int MaxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+//        System.out.println("本月最大天数:" + MaxDays);
+//        //+1的目的是为了将当天也包含在本月剩余天数中
+//        int bysyts = MaxDays - days + 1;
+//        System.out.println("本月剩余天数:" + bysyts);
+//
+//        //下月总天数
+//        calendar.add(Calendar.MONTH,+1);//下个月
+//        int xyzts = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+//        System.out.println("下月总天数:" + xyzts);
+
+        //TODO test
+//        QueryWrapper<Stocks> queryWrapperTest = new QueryWrapper<>();
+//        queryWrapperTest.eq("goods_no", "LC106CN");
+
+
+        //抓取旺店通库存表数据
+        List<Stocks> stocksList = stocksMapper.selectList(null);
+        System.out.println("旺店通数据表总数:" + stocksList.size());
+
+        //循环获取旺店通库存表数据
+        for (int x = 0; x < stocksList.size(); x++) {
+            //创建展示表
+            StocksCopy stocksCopy = new StocksCopy();
+
+//            log.info("******当前条数======:" + x);
+            //条形码
+            String barcode = stocksList.get(x).getBarcode();
+//            log.info("******条形码======:" + barcode);
+            //货品编码
+            String goodsNo = stocksList.get(x).getGoodsNo();
+//            log.info("******货品编码======:" + goodsNo);
+            //货品名称
+            String goodsName = stocksList.get(x).getGoodsName();
+//            log.info("******货品名称======:" + goodsName);
+            //仓库编码
+            String warehouseNo = stocksList.get(x).getWarehouseNo();
+//            log.info("******仓库编码======:" + warehouseNo);
+            //仓库名称
+            String warehouseName = stocksList.get(x).getWarehouseName();
+//            log.info("******仓库名称======:" + warehouseName);
+            //仓库数量
+            float stockNum = stocksList.get(x).getStockNum();
+//            log.info("******仓库数量======:" + stockNum);
+
+            /*查询数据库中Copy表是否存在物品的id*/
+            String wpid = null;
+            QueryWrapper<StocksCopy> queryWrapper = new QueryWrapper<>();
+            try {
+                queryWrapper.eq("goods_no", goodsNo);
+
+                wpid = stocksCopyMapper.selectOne(queryWrapper).getGoodsNo();
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+            System.out.println("查询数据库中Copy表是否存在物品的id:" + wpid);
+            /*查询数据库中Copy表是否存在物品的id*/
+
+            //判断展示表中是否存在当前物品编码
+            if (wpid == null){
+                log.info("展示表当前物品为空,开始执行插入......");
+
+                //条形码
+                stocksCopy.setBarcode(barcode);
+                System.out.println("插入条码:" + barcode);
+                //货品编码
+                stocksCopy.setGoodsNo(goodsNo);
+                System.out.println("插入货品编码:" + goodsNo);
+                //货品名称
+                stocksCopy.setGoodsName(goodsName);
+                System.out.println("插入货品名称:" + goodsName);
+
+//                //本月剩余天数
+//                stocksCopy.setBysyts(bysyts);
+//                System.out.println("插入本月剩余天数:" + bysyts);
+//                //下月总天数
+//                stocksCopy.setXyzts(xyzts);
+//                System.out.println("插入下月总天数:" + xyzts);
+
+                System.out.println("仓库编码:" + warehouseNo);
+                //仓库编码/仓库名称/仓库数量
+                if (warehouseNo.equals("048")){//奇门菜鸟仓
+                    stocksCopy.setQmcncNo(warehouseNo);
+                    stocksCopy.setQmcncName(warehouseName);
+                    stocksCopy.setQmcncNum(stockNum);
+
+                    //国内加总
+                    stocksCopy.setGnjz(stockNum);
+                    System.out.println("048仓库数量:" + stockNum);
+                }
+                else if (warehouseNo.equals("020")){//天猫仓
+                    stocksCopy.setTmcNo(warehouseNo);
+                    stocksCopy.setTmcName(warehouseName);
+                    stocksCopy.setTmcNum(stockNum);
+
+                    //国内加总
+                    stocksCopy.setGnjz(stockNum);
+                    System.out.println("020仓库数量:" + stockNum);
+                }
+                else if (warehouseNo.equals("021")){//网红仓
+                    stocksCopy.setWhcNo(warehouseNo);
+                    stocksCopy.setWhcName(warehouseName);
+                    stocksCopy.setWhcNum(stockNum);
+
+                    //国内加总
+                    stocksCopy.setGnjz(stockNum);
+                    System.out.println("021仓库数量:" + stockNum);
+                }
+                else if (warehouseNo.equals("022")){//分销仓
+                    stocksCopy.setFxcNo(warehouseNo);
+                    stocksCopy.setFxcName(warehouseName);
+                    stocksCopy.setFxcNum(stockNum);
+
+                    //国内加总
+                    stocksCopy.setGnjz(stockNum);
+                    System.out.println("022仓库数量:" + stockNum);
+                }
+                else if (warehouseNo.equals("023")){//备用仓
+                    stocksCopy.setBycNo(warehouseNo);
+                    stocksCopy.setBycName(warehouseName);
+                    stocksCopy.setBycNum(stockNum);
+
+                    //国内加总
+                    stocksCopy.setGnjz(stockNum);
+                    System.out.println("023仓库数量:" + stockNum);
+                }
+//                else if (warehouseNo.equals("024")){//次品仓
+//                    stocksCopy.setCpcNo(warehouseNo);
+//                    stocksCopy.setCpcName(warehouseName);
+//                    stocksCopy.setCpcNum(stockNum);
+//
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNum);
+//                    System.out.println("024仓库数量:" + stockNum);
+//                }
+//                else if (warehouseNo.equals("025")){//徐汇仓
+//                    stocksCopy.setXhcNo(warehouseNo);
+//                    stocksCopy.setXhcName(warehouseName);
+//                    stocksCopy.setXhcNum(stockNum);
+//
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNum);
+//                    System.out.println("025仓库数量:" + stockNum);
+//                }
+                else if (warehouseNo.equals("026")){//广州仓
+                    stocksCopy.setGzcNo(warehouseNo);
+                    stocksCopy.setGzcName(warehouseName);
+                    stocksCopy.setGzcNum(stockNum);
+
+                    //国内加总
+                    stocksCopy.setGnjz(stockNum);
+                    System.out.println("026仓库数量:" + stockNum);
+                }
+                else if (warehouseNo.equals("033")){//直营仓
+                    stocksCopy.setZycNo(warehouseNo);
+                    stocksCopy.setZycName(warehouseName);
+                    stocksCopy.setZycNum(stockNum);
+
+                    //国内加总
+                    stocksCopy.setGnjz(stockNum);
+                    System.out.println("033仓库数量:" + stockNum);
+                }
+//                else if (warehouseNo.equals("059")){//广州次品仓
+//                    stocksCopy.setGzcpcNo(warehouseNo);
+//                    stocksCopy.setGzcpcName(warehouseName);
+//                    stocksCopy.setGzcpcNum(stockNum);
+//
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNum);
+//                    System.out.println("059仓库数量:" + stockNum);
+//                }
+//                else if (warehouseNo.equals("060")){//暂存仓
+//                    stocksCopy.setZccNo(warehouseNo);
+//                    stocksCopy.setZccName(warehouseName);
+//                    stocksCopy.setZccNum(stockNum);
+//
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNum);
+//                    System.out.println("060仓库数量:" + stockNum);
+//                }
+                //展示表不存在该物品则新增一条
+                stocksCopyMapper.insert(stocksCopy);
+            }
+            else if (wpid != null){
+                log.info("展示表当前物品不为空,开始执行更新......");
+
+                log.info("******当前条数======:" + x);
+                //条形码
+//                String barcode = stocksList.get(x).getBarcode();
+                log.info("******条形码======:" + barcode);
+                //货品编码
+//                String goodsNo = stocksList.get(x).getGoodsNo();
+                log.info("******货品编码======:" + goodsNo);
+                //货品名称
+//                String goodsName = stocksList.get(x).getGoodsName();
+                log.info("******货品名称======:" + goodsName);
+                //仓库编码
+//                String warehouseNo = stocksList.get(x).getWarehouseNo();
+                log.info("******仓库编码======:" + warehouseNo);
+                //仓库名称
+//                String warehouseName = stocksList.get(x).getWarehouseName();
+                log.info("******仓库名称======:" + warehouseName);
+                //仓库数量
+//                float stockNum = stocksList.get(x).getStockNum();
+                log.info("******仓库数量======:" + stockNum);
+
+                UpdateWrapper<StocksCopy> updateWrapper = new UpdateWrapper<>();
+                updateWrapper.eq("goods_no",wpid);
+
+//                //本月剩余天数
+//                updateWrapper.set("bysyts",bysyts);
+//                System.out.println("更新本月剩余天数:" + bysyts);
+//                //下月总天数
+//                updateWrapper.set("xyzts",xyzts);
+//                System.out.println("更新下月总天数:" + xyzts);
+
+                //仓库编码/仓库名称/仓库数量
+                if (warehouseNo.equals("048")){//奇门菜鸟仓
+                    stocksCopy.setQmcncNo(warehouseNo);
+                    stocksCopy.setQmcncName(warehouseName);
+                    stocksCopy.setQmcncNum(stockNum);
+
+                    updateWrapper.set("qmcnc_no",warehouseNo);
+                    updateWrapper.set("qmcnc_name",warehouseName);
+                    updateWrapper.set("qmcnc_num",stockNum);
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNumAll);
+                    log.info("***【048奇门菜鸟仓】数据到这!***");
+                }
+                else if (warehouseNo.equals("020")){//天猫仓
+                    stocksCopy.setTmcNo(warehouseNo);
+                    stocksCopy.setTmcName(warehouseName);
+                    stocksCopy.setTmcNum(stockNum);
+
+                    updateWrapper.set("tmc_no",warehouseNo);
+                    updateWrapper.set("tmc_name",warehouseName);
+                    updateWrapper.set("tmc_num",stockNum);
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNumAll);
+                    log.info("***【020天猫仓】数据到这!***");
+                }
+                else if (warehouseNo.equals("021")){//网红仓
+                    stocksCopy.setWhcNo(warehouseNo);
+                    stocksCopy.setWhcName(warehouseName);
+                    stocksCopy.setWhcNum(stockNum);
+
+                    updateWrapper.set("whc_no",warehouseNo);
+                    updateWrapper.set("whc_name",warehouseName);
+                    updateWrapper.set("whc_num",stockNum);
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNumAll);
+                    log.info("***【021网红仓】数据到这!***");
+                }
+                else if (warehouseNo.equals("022")){//分销仓
+                    stocksCopy.setFxcNo(warehouseNo);
+                    stocksCopy.setFxcName(warehouseName);
+                    stocksCopy.setFxcNum(stockNum);
+
+                    updateWrapper.set("fxc_no",warehouseNo);
+                    updateWrapper.set("fxc_name",warehouseName);
+                    updateWrapper.set("fxc_num",stockNum);
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNumAll);
+                    log.info("***【022分销仓】数据到这!***");
+                }
+                else if (warehouseNo.equals("023")){//备用仓
+                    stocksCopy.setBycNo(warehouseNo);
+                    stocksCopy.setBycName(warehouseName);
+                    stocksCopy.setBycNum(stockNum);
+
+                    updateWrapper.set("byc_no",warehouseNo);
+                    updateWrapper.set("byc_name",warehouseName);
+                    updateWrapper.set("byc_num",stockNum);
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNumAll);
+                    log.info("***【023备用仓】数据到这!***");
+                }
+//                else if (warehouseNo.equals("024")){//次品仓
+//                    stocksCopy.setCpcNo(warehouseNo);
+//                    stocksCopy.setCpcName(warehouseName);
+//                    stocksCopy.setCpcNum(stockNum);
+//
+//                    updateWrapper.set("cpc_no",warehouseNo);
+//                    updateWrapper.set("cpc_name",warehouseName);
+//                    updateWrapper.set("cpc_num",stockNum);
+////                    //国内加总
+////                    stocksCopy.setGnjz(stockNumAll);
+//                    log.info("***【024次品仓】数据到这!***");
+//                }
+//                else if (warehouseNo.equals("025")){//徐汇仓
+//                    stocksCopy.setXhcNo(warehouseNo);
+//                    stocksCopy.setXhcName(warehouseName);
+//                    stocksCopy.setXhcNum(stockNum);
+//
+//                    updateWrapper.set("xhc_no",warehouseNo);
+//                    updateWrapper.set("xhc_name",warehouseName);
+//                    updateWrapper.set("xhc_num",stockNum);
+////                    //国内加总
+////                    stocksCopy.setGnjz(stockNumAll);
+//                    log.info("***【025徐汇仓】数据到这!***");
+//                }
+                else if (warehouseNo.equals("026")){//广州仓
+                    stocksCopy.setGzcNo(warehouseNo);
+                    stocksCopy.setGzcName(warehouseName);
+                    stocksCopy.setGzcNum(stockNum);
+
+                    updateWrapper.set("gzc_no",warehouseNo);
+                    updateWrapper.set("gzc_name",warehouseName);
+                    updateWrapper.set("gzc_num",stockNum);
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNumAll);
+                    log.info("***【026广州仓】数据到这!***");
+                }
+                else if (warehouseNo.equals("033")){//直营仓
+                    stocksCopy.setZycNo(warehouseNo);
+                    stocksCopy.setZycName(warehouseName);
+                    stocksCopy.setZycNum(stockNum);
+
+                    updateWrapper.set("zyc_no",warehouseNo);
+                    updateWrapper.set("zyc_name",warehouseName);
+                    updateWrapper.set("zyc_num",stockNum);
+//                    //国内加总
+//                    stocksCopy.setGnjz(stockNumAll);
+                    log.info("***【033直营仓】数据到这!***");
+                }
+//                else if (warehouseNo.equals("059")){//广州次品仓
+//                    stocksCopy.setGzcpcNo(warehouseNo);
+//                    stocksCopy.setGzcpcName(warehouseName);
+//                    stocksCopy.setGzcpcNum(stockNum);
+//
+//                    updateWrapper.set("gzcpc_no",warehouseNo);
+//                    updateWrapper.set("gzcpc_name",warehouseName);
+//                    updateWrapper.set("gzcpc_num",stockNum);
+////                    //国内加总
+////                    stocksCopy.setGnjz(stockNumAll);
+//                    log.info("***【059广州次品仓】数据到这!***");
+//                }
+//                else if (warehouseNo.equals("060")){//暂存仓
+//                    stocksCopy.setZccNo(warehouseNo);
+//                    stocksCopy.setZccName(warehouseName);
+//                    stocksCopy.setZccNum(stockNum);
+//
+//                    updateWrapper.set("zcc_no",warehouseNo);
+//                    updateWrapper.set("zcc_name",warehouseName);
+//                    updateWrapper.set("zcc_num",stockNum);
+////                    //国内加总
+////                    stocksCopy.setGnjz(stockNumAll);
+//                    log.info("***【060暂存仓】数据到这!***");
+//                }
+
+                stocksCopyMapper.update(null,updateWrapper);
+
+                QueryWrapper queryWrapperUP = new QueryWrapper();
+                queryWrapperUP.eq("goods_no",wpid);
+
+                //查询展示表中该物品的所有库存数量
+                //奇门菜鸟仓数量
+                float qmcncNum = stocksCopyMapper.selectOne(queryWrapperUP).getQmcncNum();
+                System.out.println("奇门菜鸟仓数量:" + qmcncNum);
+                //天猫仓数量
+                float tmcNum = stocksCopyMapper.selectOne(queryWrapperUP).getTmcNum();
+                System.out.println("天猫仓数量:" + tmcNum);
+                //网红仓数量
+                float whcNum = stocksCopyMapper.selectOne(queryWrapperUP).getWhcNum();
+                System.out.println("网红仓数量:" + whcNum);
+                //分销仓数量
+                float fxcNum = stocksCopyMapper.selectOne(queryWrapperUP).getFxcNum();
+                System.out.println("分销仓数量:" + fxcNum);
+                //备用仓数量
+                float bycNum = stocksCopyMapper.selectOne(queryWrapperUP).getBycNum();
+                System.out.println("备用仓数量:" + bycNum);
+//                //次品仓数量
+//                float cpcNum = stocksCopyMapper.selectOne(queryWrapperUP).getCpcNum();
+//                System.out.println("次品仓数量:" + cpcNum);
+//                //徐汇仓数量
+//                float xhcNum = stocksCopyMapper.selectOne(queryWrapperUP).getXhcNum();
+//                System.out.println("徐汇仓数量:" + xhcNum);
+                //广州仓数量
+                float gzcNum = stocksCopyMapper.selectOne(queryWrapperUP).getGzcNum();
+                System.out.println("广州仓数量:" + gzcNum);
+                //直营仓数量
+                float zycNum = stocksCopyMapper.selectOne(queryWrapperUP).getZycNum();
+                System.out.println("直营仓数量:" + zycNum);
+//                //广州次品仓数量
+//                float gzcpcNum = stocksCopyMapper.selectOne(queryWrapperUP).getGzcpcNum();
+//                System.out.println("广州次品仓数量:" + gzcpcNum);
+//                //暂存仓数量
+//                float zccNum = stocksCopyMapper.selectOne(queryWrapperUP).getZccNum();
+//                System.out.println("暂存仓数量:" + zccNum);
+
+                //展示表已存在该物品时,插入库存前查询展示表各仓库总数
+                float stockNumAll = qmcncNum + tmcNum + whcNum + fxcNum + bycNum + gzcNum + zycNum;
+                System.out.println("展示表已存在该物品时,插入库存前查询展示表各仓库总数:" + stockNumAll);
+
+                //国内加总
+                updateWrapper.set("gnjz",stockNumAll);
+                stocksCopyMapper.update(null,updateWrapper);
+            }
+
+        }
+
+        log.info("======&&&&&&******【展示表数据同步结束】******&&&&&&======");
+        return "旺店通库存信息表同步展示表成功!";
+    }
+
+    //获取旺店通库存信息,并同步至宜搭
+    public static com.aliyun.dingtalkyida_1_0.Client createClient() throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
+        config.protocol = "https";
+        config.regionId = "central";
+        return new com.aliyun.dingtalkyida_1_0.Client(config);
+    }
+
+    @Override
+    public String createWangdiantongStocks(){
+
+        //本月剩余天数
+        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:OO"));
+        int days = calendar.get(Calendar.DAY_OF_MONTH);
+        System.out.println("本月当前天数:" + days);
+        int MaxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        System.out.println("本月最大天数:" + MaxDays);
+        //+1的目的是为了将当天也包含在本月剩余天数中
+        int bysyts = MaxDays - days + 1;
+        System.out.println("本月剩余天数:" + bysyts);
+
+        //下月总天数
+        calendar.add(Calendar.MONTH,+1);//下个月
+        int xyzts = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+        System.out.println("下月总天数:" + xyzts);
+
+        //当前时间的时间戳
+        long timeMillis = System.currentTimeMillis();
+
+        //展示表
+        List<StocksCopy> stocksCopyList = stocksCopyMapper.selectList(null);
+        System.out.println("展示表总数:" + stocksCopyList.size());
+
+        for (int i = 0; i < stocksCopyList.size(); i++) {
+            //条形码
+            String barcode = stocksCopyList.get(i).getBarcode();
+            //产品编号
+            String goodsNo = stocksCopyList.get(i).getGoodsNo();
+            //商品名称
+            String goodsName = stocksCopyList.get(i).getGoodsName();
+            //国内加总
+            float gnjz = stocksCopyList.get(i).getGnjz();
+            //奇门菜鸟仓048
+            float qmcncNum = stocksCopyList.get(i).getQmcncNum();
+            //天猫仓020
+            float tmcNum = stocksCopyList.get(i).getTmcNum();
+            //网红仓021
+            float whcNum = stocksCopyList.get(i).getWhcNum();
+            //分销仓022
+            float fxcNum = stocksCopyList.get(i).getFxcNum();
+            //备用仓023
+            float bycNum = stocksCopyList.get(i).getBycNum();
+//            //次品仓024
+//            float cpcNum = stocksCopyList.get(i).getCpcNum();
+//            //徐汇仓025
+//            float xhcNum = stocksCopyList.get(i).getXhcNum();
+            //广州仓026
+            float gzcNum = stocksCopyList.get(i).getGzcNum();
+            //直营仓033
+            float zycNum = stocksCopyList.get(i).getZycNum();
+//            //广州次品仓059
+//            float gzcpcNum = stocksCopyList.get(i).getGzcpcNum();
+//            //暂存仓060
+//            float zccNum = stocksCopyList.get(i).getZccNum();
+
+//            //本月剩余天数(包含今日)
+//            int bysyts = stocksCopyList.get(i).getBysyts();
+//            //下月总天数
+//            int xyzts = stocksCopyList.get(i).getXyzts();
+
+            /*同步至宜搭*/
+            Map map = new HashMap();
+            //条形码
+            map.put("textField_lbajxvt9", barcode);
+            //产品编码
+            map.put("textField_lbd4c51m", goodsNo);
+            //商品名称
+            map.put("textField_lbd4c51n", goodsName);
+            //国内加总
+            map.put("numberField_lbd9y20d", gnjz);
+
+            //奇门菜鸟仓048
+            map.put("numberField_lco5yzqv", qmcncNum);
+            //天猫仓020
+            map.put("numberField_lbd9y20g", tmcNum);
+            //网红仓021
+            map.put("numberField_lbd9y20i", whcNum);
+            //分销仓022
+            map.put("numberField_lbd9y20j", fxcNum);
+            //备用仓023
+            map.put("numberField_lbd9y20k", bycNum);
+//            //次品仓024
+//            map.put("numberField_lbd9y20l", cpcNum);
+//            //徐汇仓025
+//            map.put("numberField_lbd9y20f", xhcNum);
+            //广州仓026
+            map.put("numberField_lbd9y20m", gzcNum);
+            //直营仓033
+            map.put("numberField_lbd9y20h", zycNum);
+//            //广州次品仓059
+//            map.put("numberField_lbg9y9zx", gzcpcNum);
+//            //暂存仓060
+//            map.put("numberField_lbg9ya00", zccNum);
+
+            //数据更新日期(时间戳)
+            map.put("dateField_lbg3bsyh", timeMillis);
+            //本月剩余天数(包含今日)
+            map.put("numberField_lbg3bsyf", bysyts);
+            //下月总天数
+            map.put("numberField_lbg3bsyg", xyzts);
+
+            String mapJson = JSON.toJSONString(map);
+            System.out.println("mapJson:" + mapJson);
+
+            //宜搭表单判断查询条件
+            Map map1 = new HashMap();
+            //产品编号
+            map1.put("key","textField_lbd4c51m");
+            //产品编号查询匹配值
+            map1.put("value",goodsNo);
+            //控件编号(文本)
+            map1.put("type","TEXT");
+            //逻辑判断符
+            map1.put("operator","eq");
+            //控件类型(文本)
+            map1.put("componentName","TextField");
+            List list = new ArrayList();
+            list.add(map1);
+
+            String listJson = JSON.toJSONString(list);
+            System.out.println("查询条件listJson:" + listJson);
+
+
+            //新增或更新表单实例【宜搭】
+            try {
+                com.aliyun.dingtalkyida_1_0.Client client = createClient();
+                com.aliyun.dingtalkyida_1_0.models.CreateOrUpdateFormDataHeaders createOrUpdateFormDataHeaders = new com.aliyun.dingtalkyida_1_0.models.CreateOrUpdateFormDataHeaders();
+                createOrUpdateFormDataHeaders.xAcsDingtalkAccessToken = accessTokenService.getAccessToken();
+                com.aliyun.dingtalkyida_1_0.models.CreateOrUpdateFormDataRequest createOrUpdateFormDataRequest = new com.aliyun.dingtalkyida_1_0.models.CreateOrUpdateFormDataRequest()
+                        .setSystemToken("DJ966581GT76IWY6660IB9E1MIP62BYAXJABL1OB")
+                        .setFormUuid("FORM-BH766Y61VAO5U4ZV775ZG679JWIQ2A6MXJABLQ3")
+                        .setUserId("yida_pub_account")
+                        .setSearchCondition(listJson)
+                        .setAppType("APP_R1OQTHQK87Q5S5ZSSYC1")
+                        .setFormDataJson(mapJson);
+
+                client.createOrUpdateFormDataWithOptions(createOrUpdateFormDataRequest, createOrUpdateFormDataHeaders, new com.aliyun.teautil.models.RuntimeOptions());
+            } catch (TeaException err) {
+                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+                    // err 中含有 code 和 message 属性,可帮助开发定位问题
+                }
+
+            } catch (Exception _err) {
+                TeaException err = new TeaException(_err.getMessage(), _err);
+                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+                    // err 中含有 code 和 message 属性,可帮助开发定位问题
+                }
+
+            }
+
+            //创建宜搭表单数据
+//            try {
+//                com.aliyun.dingtalkyida_1_0.Client client = createClient();
+//                com.aliyun.dingtalkyida_1_0.models.SaveFormDataHeaders saveFormDataHeaders = new com.aliyun.dingtalkyida_1_0.models.SaveFormDataHeaders();
+//                saveFormDataHeaders.xAcsDingtalkAccessToken = accessTokenService.getAccessToken();
+//                com.aliyun.dingtalkyida_1_0.models.SaveFormDataRequest saveFormDataRequest = new com.aliyun.dingtalkyida_1_0.models.SaveFormDataRequest()
+//                        //宜搭应用秘钥
+//                        .setSystemToken("DJ966581GT76IWY6660IB9E1MIP62BYAXJABL1OB")
+//                        //宜搭表单ID
+//                        .setFormUuid("FORM-BH766Y61VAO5U4ZV775ZG679JWIQ2A6MXJABLQ3")
+//                        //创建人id
+//                        .setUserId("yida_pub_account")
+//                        //宜搭应用编码
+//                        .setAppType("APP_R1OQTHQK87Q5S5ZSSYC1")
+//                        .setFormDataJson(mapJson);
+//
+//                client.saveFormDataWithOptions(saveFormDataRequest, saveFormDataHeaders, new com.aliyun.teautil.models.RuntimeOptions());
+//            } catch (TeaException err) {
+//                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+//                    // err 中含有 code 和 message 属性,可帮助开发定位问题
+//                }
+//
+//            } catch (Exception _err) {
+//                TeaException err = new TeaException(_err.getMessage(), _err);
+//                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+//                    // err 中含有 code 和 message 属性,可帮助开发定位问题
+//                }
+//
+//            }
+        }
+
+
+        log.info("======数据同步结束======");
+        return "同步至宜搭库存信息表成功!";
+    }
+}

+ 150 - 0
src/main/java/com/muzhi/meixi/utils/FileItem.java

@@ -0,0 +1,150 @@
+package com.muzhi.meixi.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * 文件元数据。
+ * 
+ */
+public class FileItem {
+
+	private String fileName;
+	private String mimeType;
+	private byte[] content;
+	private File file;
+
+	/**
+	 * 基于本地文件的构造器。
+	 * 
+	 * @param file 本地文件
+	 */
+	public FileItem(File file) {
+		this.file = file;
+	}
+
+	/**
+	 * 基于文件绝对路径的构造器。
+	 * 
+	 * @param filePath 文件绝对路径
+	 */
+	public FileItem(String filePath) {
+		this(new File(filePath));
+	}
+
+	/**
+	 * 基于文件名和字节流的构造器。
+	 * 
+	 * @param fileName 文件名
+	 * @param content 文件字节流
+	 */
+	public FileItem(String fileName, byte[] content) {
+		this.fileName = fileName;
+		this.content = content;
+	}
+
+	/**
+	 * 基于文件名、字节流和媒体类型的构造器。
+	 * 
+	 * @param fileName 文件名
+	 * @param content 文件字节流
+	 * @param mimeType 媒体类型
+	 */
+	public FileItem(String fileName, byte[] content, String mimeType) {
+		this(fileName, content);
+		this.mimeType = mimeType;
+	}
+
+	public String getFileName() {
+		if (this.fileName == null && this.file != null && this.file.exists()) {
+			this.fileName = file.getName();
+		}
+		return this.fileName;
+	}
+
+	public String getMimeType() throws IOException {
+		if (this.mimeType == null) {
+			this.mimeType = getMimeType(getContent());
+		}
+		return this.mimeType;
+	}
+
+	/**
+	 * 获取文件的真实后缀名。目前只支持JPG, GIF, PNG, BMP四种图片文件。
+	 * 
+	 * @param bytes 文件字节流
+	 * @return JPG, GIF, PNG or null
+	 */
+	public static String getFileSuffix(byte[] bytes) {
+		if (bytes == null || bytes.length < 10) {
+			return null;
+		}
+
+		if (bytes[0] == 'G' && bytes[1] == 'I' && bytes[2] == 'F') {
+			return "GIF";
+		} else if (bytes[1] == 'P' && bytes[2] == 'N' && bytes[3] == 'G') {
+			return "PNG";
+		} else if (bytes[6] == 'J' && bytes[7] == 'F' && bytes[8] == 'I' && bytes[9] == 'F') {
+			return "JPG";
+		} else if (bytes[0] == 'B' && bytes[1] == 'M') {
+			return "BMP";
+		} else {
+			return null;
+		}
+	}
+	
+	/**
+	 * 获取文件的真实媒体类型。目前只支持JPG, GIF, PNG, BMP四种图片文件。
+	 * 
+	 * @param bytes 文件字节流
+	 * @return 媒体类型(MEME-TYPE)
+	 */
+	public static String getMimeType(byte[] bytes) {
+		String suffix = getFileSuffix(bytes);
+		String mimeType;
+
+		if ("JPG".equals(suffix)) {
+			mimeType = "image/jpeg";
+		} else if ("GIF".equals(suffix)) {
+			mimeType = "image/gif";
+		} else if ("PNG".equals(suffix)) {
+			mimeType = "image/png";
+		} else if ("BMP".equals(suffix)) {
+			mimeType = "image/bmp";
+		}else {
+			mimeType = "application/octet-stream";
+		}
+
+		return mimeType;
+	}
+	
+	public byte[] getContent() throws IOException {
+		if (this.content == null && this.file != null && this.file.exists()) {
+			InputStream in = null;
+			ByteArrayOutputStream out = null;
+
+			try {
+				in = new FileInputStream(this.file);
+				out = new ByteArrayOutputStream();
+				int ch;
+				while ((ch = in.read()) != -1) {
+					out.write(ch);
+				}
+				this.content = out.toByteArray();
+			} finally {
+				if (out != null) {
+					out.close();
+				}
+				if (in != null) {
+					in.close();
+				}
+			}
+		}
+		return this.content;
+	}
+
+}

+ 129 - 0
src/main/java/com/muzhi/meixi/utils/StringUtils.java

@@ -0,0 +1,129 @@
+package com.muzhi.meixi.utils;
+
+
+/**
+ * 字符串工具类。
+ * 
+ */
+public abstract class StringUtils {
+
+	private StringUtils() {}
+
+	/**
+	 * 检查指定的字符串是否为空。
+	 * <ul>
+	 * <li>SysUtils.isEmpty(null) = true</li>
+	 * <li>SysUtils.isEmpty("") = true</li>
+	 * <li>SysUtils.isEmpty("   ") = true</li>
+	 * <li>SysUtils.isEmpty("abc") = false</li>
+	 * </ul>
+	 * 
+	 * @param value 待检查的字符串
+	 * @return true/false
+	 */
+	public static boolean isEmpty(String value) {
+		int strLen;
+		if (value == null || (strLen = value.length()) == 0) {
+			return true;
+		}
+		for (int i = 0; i < strLen; i++) {
+			if ((Character.isWhitespace(value.charAt(i)) == false)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * 检查对象是否为数字型字符串,包含负数开头的。
+	 */
+	public static boolean isNumeric(Object obj) {
+		if (obj == null) {
+			return false;
+		}
+		char[] chars = obj.toString().toCharArray();
+		int length = chars.length;
+		if(length < 1)
+			return false;
+		
+		int i = 0;
+		if(length > 1 && chars[0] == '-')
+			i = 1;
+		
+		for (; i < length; i++) {
+			if (!Character.isDigit(chars[i])) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * 检查指定的字符串列表是否不为空。
+	 */
+	public static boolean areNotEmpty(String... values) {
+		boolean result = true;
+		if (values == null || values.length == 0) {
+			result = false;
+		} else {
+			for (String value : values) {
+				result &= !isEmpty(value);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 把通用字符编码的字符串转化为汉字编码。
+	 */
+	public static String unicodeToChinese(String unicode) {
+		StringBuilder out = new StringBuilder();
+		if (!isEmpty(unicode)) {
+			for (int i = 0; i < unicode.length(); i++) {
+				out.append(unicode.charAt(i));
+			}
+		}
+		return out.toString();
+	}
+
+	public static String toUnderlineStyle(String name) {
+		StringBuilder newName = new StringBuilder();
+		for (int i = 0; i < name.length(); i++) {
+			char c = name.charAt(i);
+			if (Character.isUpperCase(c)) {
+				if (i > 0) {
+					newName.append("_");
+				}
+				newName.append(Character.toLowerCase(c));
+			} else {
+				newName.append(c);
+			}
+		}
+		return newName.toString();
+	}
+
+	public static String convertString(byte[] data, int offset, int length) {
+		if (data == null) {
+			return null;
+		} else {
+			try {
+				return new String(data, offset, length, "UTF-8");
+			} catch (Exception e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+
+	public static byte[] convertBytes(String data) {
+		if (data == null) {
+			return null;
+		} else {
+			try {
+				return data.getBytes("UTF-8");
+			} catch (Exception e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+
+}

+ 572 - 0
src/main/java/com/muzhi/meixi/utils/WebUtils.java

@@ -0,0 +1,572 @@
+package com.muzhi.meixi.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+//import java.security.SecureRandom;
+//import java.security.cert.Certificate;
+//import java.security.cert.CertificateException;
+//import java.security.cert.CertificateFactory;
+//import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+//import javax.net.ssl.HostnameVerifier;
+//import javax.net.ssl.HttpsURLConnection;
+//import javax.net.ssl.SSLContext;
+//import javax.net.ssl.SSLSession;
+//import javax.net.ssl.TrustManager;
+//import javax.net.ssl.X509TrustManager;
+
+
+/**
+ * 网络工具类。
+ * 
+ */
+public abstract class WebUtils {
+
+	private static final String DEFAULT_CHARSET = "UTF-8";
+	private static final String METHOD_POST = "POST";
+	private static final String METHOD_GET = "GET";
+	//private static final Certificate verisign; // 根证书
+	//private static boolean ignoreSSLCheck; // 忽略SSL检查
+
+//	static {
+//		InputStream input = null;
+//		try {
+//			CertificateFactory cf = CertificateFactory.getInstance("X.509");
+//			input = WebUtils.class.getResourceAsStream("/verisign.crt");
+//			verisign = cf.generateCertificate(input);
+//		} catch (Exception e) {
+//			throw new RuntimeException(e);
+//		} finally {
+//			if (input != null) {
+//				try {
+//					input.close();
+//				} catch (IOException e) {
+//				}
+//			}
+//		}
+//	}
+
+//	public static class VerisignTrustManager implements X509TrustManager {
+//		public X509Certificate[] getAcceptedIssuers() {
+//			return null;
+//		}
+//
+//		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+//		}
+//
+//		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+//			Exception exp = null;
+//
+//			for (X509Certificate cert : chain) {
+//				cert.checkValidity(); // 验证证书有效期
+//				try {
+//					cert.verify(verisign.getPublicKey());// 验证签名
+//					exp = null;
+//					break;
+//				} catch (Exception e) {
+//					exp = e;
+//				}
+//			}
+//
+//			if (exp != null) {
+//				throw new CertificateException(exp);
+//			}
+//		}
+//	}
+//
+//	public static class TrustAllTrustManager implements X509TrustManager {
+//		public X509Certificate[] getAcceptedIssuers() {
+//			return null;
+//		}
+//
+//		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+//		}
+//
+//		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+//		}
+//	}
+
+	private WebUtils() {
+	}
+
+//	public static void setIgnoreSSLCheck(boolean ignoreSSLCheck) {
+//		WebUtils.ignoreSSLCheck = ignoreSSLCheck;
+//	}
+
+	/**
+	 * 执行HTTP POST请求。
+	 * 
+	 * @param url 请求地址
+	 * @param params 请求参数
+	 * @return 响应字符串
+	 */
+	public static String doPost(String url, Map<String, String> params, int connectTimeout, int readTimeout) throws IOException {
+		return doPost(url, params, DEFAULT_CHARSET, connectTimeout, readTimeout);
+	}
+
+	/**
+	 * 执行HTTP POST请求。
+	 * 
+	 * @param url 请求地址
+	 * @param params 请求参数
+	 * @param charset 字符集,如UTF-8, GBK, GB2312
+	 * @return 响应字符串
+	 */
+	public static String doPost(String url, Map<String, String> params, String charset, int connectTimeout, int readTimeout) throws IOException {
+		return doPost(url, params, charset, connectTimeout, readTimeout, null);
+	}
+
+	public static String doPost(String url, Map<String, String> params, String charset, int connectTimeout, int readTimeout, Map<String, String> headerMap) throws IOException {
+		String ctype = "application/x-www-form-urlencoded;charset=" + charset;
+		String query = buildQuery(params, charset);
+		byte[] content = {};
+		if (query != null) {
+			content = query.getBytes(charset);
+		}
+		return _doPost(url, ctype, content, connectTimeout, readTimeout, headerMap);
+	}
+
+	/**
+	 * 执行HTTP POST请求。
+	 * 
+	 * @param url 请求地址
+	 * @param ctype 请求类型
+	 * @param content 请求字节数组
+	 * @return 响应字符串
+	 */
+	public static String doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout) throws IOException {
+		return _doPost(url, ctype, content, connectTimeout, readTimeout, null);
+	}
+
+	private static String _doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout, Map<String, String> headerMap) throws IOException {
+		HttpURLConnection conn = null;
+		OutputStream out = null;
+		String rsp = null;
+		try {
+			conn = getConnection(new URL(url), METHOD_POST, ctype, headerMap);
+			conn.setConnectTimeout(connectTimeout);
+			conn.setReadTimeout(readTimeout);
+			
+			out = conn.getOutputStream();
+			out.write(content);
+			
+			rsp = getResponseAsString(conn);
+		} finally {
+			if (out != null) {
+				out.close();
+			}
+			if (conn != null) {
+				conn.disconnect();
+			}
+		}
+
+		return rsp;
+	}
+
+	/**
+	 * 执行带文件上传的HTTP POST请求。
+	 * 
+	 * @param url 请求地址
+	 * @param params 文本请求参数
+	 * @param fileParams 文件请求参数
+	 * @return 响应字符串
+	 */
+	public static String doPost(String url, Map<String, String> params, Map<String, FileItem> fileParams, int connectTimeout, int readTimeout) throws IOException {
+		if (fileParams == null || fileParams.isEmpty()) {
+			return doPost(url, params, DEFAULT_CHARSET, connectTimeout, readTimeout);
+		} else {
+			return doPost(url, params, fileParams, DEFAULT_CHARSET, connectTimeout, readTimeout);
+		}
+	}
+
+	public static String doPost(String url, Map<String, String> params, Map<String, FileItem> fileParams, String charset, int connectTimeout, int readTimeout) throws IOException {
+		return doPost(url, params, fileParams, charset, connectTimeout, readTimeout, null);
+	}
+
+	/**
+	 * 执行带文件上传的HTTP POST请求。
+	 * 
+	 * @param url 请求地址
+	 * @param params 文本请求参数
+	 * @param fileParams 文件请求参数
+	 * @param charset 字符集,如UTF-8, GBK, GB2312
+	 * @param headerMap 需要传递的header头,可以为空
+	 * @return 响应字符串
+	 */
+	public static String doPost(String url, Map<String, String> params, Map<String, FileItem> fileParams, String charset,
+			int connectTimeout, int readTimeout, Map<String, String> headerMap) throws IOException {
+		if (fileParams == null || fileParams.isEmpty()) {
+			return doPost(url, params, charset, connectTimeout, readTimeout, headerMap);
+		} else {
+			return _doPostWithFile(url, params, fileParams, charset, connectTimeout, readTimeout, headerMap);
+		}
+	}
+
+	private static String _doPostWithFile(String url, Map<String, String> params, Map<String, FileItem> fileParams,
+			String charset, int connectTimeout, int readTimeout, Map<String, String> headerMap) throws IOException {
+		String boundary = String.valueOf(System.nanoTime()); // 随机分隔线
+		HttpURLConnection conn = null;
+		OutputStream out = null;
+		String rsp = null;
+		try {
+			String ctype = "multipart/form-data;charset=" + charset + ";boundary=" + boundary;
+			conn = getConnection(new URL(url), METHOD_POST, ctype, headerMap);
+			conn.setConnectTimeout(connectTimeout);
+			conn.setReadTimeout(readTimeout);
+
+			out = conn.getOutputStream();
+			byte[] entryBoundaryBytes = ("\r\n--" + boundary + "\r\n").getBytes(charset);
+
+			// 组装文本请求参数
+			Set<Entry<String, String>> textEntrySet = params.entrySet();
+			for (Entry<String, String> textEntry : textEntrySet) {
+				byte[] textBytes = getTextEntry(textEntry.getKey(), textEntry.getValue(), charset);
+				out.write(entryBoundaryBytes);
+				out.write(textBytes);
+			}
+
+			// 组装文件请求参数
+			Set<Entry<String, FileItem>> fileEntrySet = fileParams.entrySet();
+			for (Entry<String, FileItem> fileEntry : fileEntrySet) {
+				FileItem fileItem = fileEntry.getValue();
+				if (fileItem.getContent() == null) {
+					continue;
+				}
+				byte[] fileBytes = getFileEntry(fileEntry.getKey(), fileItem.getFileName(), fileItem.getMimeType(), charset);
+				out.write(entryBoundaryBytes);
+				out.write(fileBytes);
+				out.write(fileItem.getContent());
+			}
+
+			// 添加请求结束标志
+			byte[] endBoundaryBytes = ("\r\n--" + boundary + "--\r\n").getBytes(charset);
+			out.write(endBoundaryBytes);
+			rsp = getResponseAsString(conn);
+
+		} finally {
+			if (out != null) {
+				out.close();
+			}
+			if (conn != null) {
+				conn.disconnect();
+			}
+		}
+
+		return rsp;
+	}
+
+	private static byte[] getTextEntry(String fieldName, String fieldValue, String charset) throws IOException {
+		StringBuilder entry = new StringBuilder();
+		entry.append("Content-Disposition:form-data;name=\"");
+		entry.append(fieldName);
+		entry.append("\"\r\nContent-Type:text/plain\r\n\r\n");
+		entry.append(fieldValue);
+		return entry.toString().getBytes(charset);
+	}
+
+	private static byte[] getFileEntry(String fieldName, String fileName, String mimeType, String charset) throws IOException {
+		StringBuilder entry = new StringBuilder();
+		entry.append("Content-Disposition:form-data;name=\"");
+		entry.append(fieldName);
+		entry.append("\";filename=\"");
+		entry.append(fileName);
+		entry.append("\"\r\nContent-Type:");
+		entry.append(mimeType);
+		entry.append("\r\n\r\n");
+		return entry.toString().getBytes(charset);
+	}
+
+	/**
+	 * 执行HTTP GET请求。
+	 * 
+	 * @param url 请求地址
+	 * @param params 请求参数
+	 * @return 响应字符串
+	 */
+	public static String doGet(String url, Map<String, String> params) throws IOException {
+		return doGet(url, params, DEFAULT_CHARSET);
+	}
+
+	/**
+	 * 执行HTTP GET请求。
+	 * 
+	 * @param url 请求地址
+	 * @param params 请求参数
+	 * @param charset 字符集,如UTF-8, GBK, GB2312
+	 * @return 响应字符串
+	 */
+	public static String doGet(String url, Map<String, String> params, String charset) throws IOException {
+		HttpURLConnection conn = null;
+		String rsp = null;
+
+		try {
+			String ctype = "application/x-www-form-urlencoded;charset=" + charset;
+			String query = buildQuery(params, charset);
+			
+			conn = getConnection(buildGetUrl(url, query), METHOD_GET, ctype, null);
+
+			rsp = getResponseAsString(conn);
+
+		} finally {
+			if (conn != null) {
+				conn.disconnect();
+			}
+		}
+
+		return rsp;
+	}
+
+	private static HttpURLConnection getConnection(URL url, String method, String ctype, Map<String, String> headerMap) throws IOException {
+		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+//		if (conn instanceof HttpsURLConnection) {
+//			HttpsURLConnection connHttps = (HttpsURLConnection) conn;
+//			if (ignoreSSLCheck) {
+//				try {
+//					SSLContext ctx = SSLContext.getInstance("TLS");
+//					ctx.init(null, new TrustManager[] { new TrustAllTrustManager() }, new SecureRandom());
+//					connHttps.setSSLSocketFactory(ctx.getSocketFactory());
+//					connHttps.setHostnameVerifier(new HostnameVerifier() {
+//						public boolean verify(String hostname, SSLSession session) {
+//							return true;
+//						}
+//					});
+//				} catch (Exception e) {
+//					throw new IOException(e);
+//				}
+//			} else {
+//				try {
+//					SSLContext ctx = SSLContext.getInstance("TLS");
+//					ctx.init(null, new TrustManager[] { new VerisignTrustManager() }, new SecureRandom());
+//					connHttps.setSSLSocketFactory(ctx.getSocketFactory());
+//				} catch (Exception e) {
+//					throw new IOException(e);
+//				}
+//			}
+//			conn = connHttps;
+//		}
+
+		conn.setRequestMethod(method);
+		conn.setDoInput(true);
+		conn.setDoOutput(true);
+		conn.setRequestProperty("Accept", "*/*");
+		conn.setRequestProperty("User-Agent", "wdt-java-sdk");
+		conn.setRequestProperty("Content-Type", ctype);
+		if (headerMap != null) {
+			for (Entry<String, String> entry : headerMap.entrySet()) {
+				conn.setRequestProperty(entry.getKey(), entry.getValue());
+			}
+		}
+		return conn;
+	}
+
+	private static URL buildGetUrl(String strUrl, String query) throws IOException {
+		URL url = new URL(strUrl);
+		if (StringUtils.isEmpty(query)) {
+			return url;
+		}
+
+		if (StringUtils.isEmpty(url.getQuery())) {
+			if (strUrl.endsWith("?")) {
+				strUrl = strUrl + query;
+			} else {
+				strUrl = strUrl + "?" + query;
+			}
+		} else {
+			if (strUrl.endsWith("&")) {
+				strUrl = strUrl + query;
+			} else {
+				strUrl = strUrl + "&" + query;
+			}
+		}
+
+		return new URL(strUrl);
+	}
+
+	public static String buildQuery(Map<String, String> params, String charset) throws IOException {
+		if (params == null || params.isEmpty()) {
+			return null;
+		}
+
+		StringBuilder query = new StringBuilder();
+		Set<Entry<String, String>> entries = params.entrySet();
+		boolean hasParam = false;
+
+		for (Entry<String, String> entry : entries) {
+			String name = entry.getKey();
+			String value = entry.getValue();
+			// 忽略参数名或参数值为空的参数
+			if (StringUtils.areNotEmpty(name, value)) {
+				if (hasParam) {
+					query.append("&");
+				} else {
+					hasParam = true;
+				}
+
+				query.append(name).append("=").append(URLEncoder.encode(value, charset));
+			}
+		}
+
+		return query.toString();
+	}
+
+	protected static String getResponseAsString(HttpURLConnection conn) throws IOException {
+		String charset = getResponseCharset(conn.getContentType());
+		InputStream es = conn.getErrorStream();
+		if (es == null) {
+			return getStreamAsString(conn.getInputStream(), charset);
+		} else {
+			String msg = getStreamAsString(es, charset);
+			if (StringUtils.isEmpty(msg)) {
+				throw new IOException(conn.getResponseCode() + ":" + conn.getResponseMessage());
+			} else {
+				throw new IOException(msg);
+			}
+		}
+	}
+
+	private static String getStreamAsString(InputStream stream, String charset) throws IOException {
+		try {
+			Reader reader = new InputStreamReader(stream, charset);
+			StringBuilder response = new StringBuilder();
+
+			final char[] buff = new char[1024];
+			int read = 0;
+			while ((read = reader.read(buff)) > 0) {
+				// 一次读取1024个字符
+				response.append(buff, 0, read);
+			}
+
+			return response.toString();
+		} finally {
+			if (stream != null) {
+				stream.close();
+			}
+		}
+	}
+
+	private static String getResponseCharset(String ctype) {
+		String charset = DEFAULT_CHARSET;
+
+		if (!StringUtils.isEmpty(ctype)) {
+			String[] params = ctype.split(";");
+			for (String param : params) {
+				param = param.trim();
+				if (param.startsWith("charset")) {
+					String[] pair = param.split("=", 2);
+					if (pair.length == 2) {
+						if (!StringUtils.isEmpty(pair[1])) {
+							charset = pair[1].trim();
+						}
+					}
+					break;
+				}
+			}
+		}
+
+		return charset;
+	}
+
+	/**
+	 * 使用默认的UTF-8字符集反编码请求参数值。
+	 * 
+	 * @param value 参数值
+	 * @return 反编码后的参数值
+	 */
+	public static String decode(String value) {
+		return decode(value, DEFAULT_CHARSET);
+	}
+
+	/**
+	 * 使用默认的UTF-8字符集编码请求参数值。
+	 * 
+	 * @param value 参数值
+	 * @return 编码后的参数值
+	 */
+	public static String encode(String value) {
+		return encode(value, DEFAULT_CHARSET);
+	}
+
+	/**
+	 * 使用指定的字符集反编码请求参数值。
+	 * 
+	 * @param value 参数值
+	 * @param charset 字符集
+	 * @return 反编码后的参数值
+	 */
+	public static String decode(String value, String charset) {
+		String result = null;
+		if (!StringUtils.isEmpty(value)) {
+			try {
+				result = URLDecoder.decode(value, charset);
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 使用指定的字符集编码请求参数值。
+	 * 
+	 * @param value 参数值
+	 * @param charset 字符集
+	 * @return 编码后的参数值
+	 */
+	public static String encode(String value, String charset) {
+		String result = null;
+		if (!StringUtils.isEmpty(value)) {
+			try {
+				result = URLEncoder.encode(value, charset);
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		return result;
+	}
+
+	public static Map<String, String> getParamsFromUrl(String url) {
+		Map<String, String> map = null;
+		if (url != null && url.indexOf('?') != -1) {
+			map = splitUrlQuery(url.substring(url.indexOf('?') + 1));
+		}
+		if (map == null) {
+			map = new HashMap<String, String>();
+		}
+		return map;
+	}
+
+	/**
+	 * 从URL中提取所有的参数。
+	 * 
+	 * @param query URL地址
+	 * @return 参数映射
+	 */
+	public static Map<String, String> splitUrlQuery(String query) {
+		Map<String, String> result = new HashMap<String, String>();
+
+		String[] pairs = query.split("&");
+		if (pairs != null && pairs.length > 0) {
+			for (String pair : pairs) {
+				String[] param = pair.split("=", 2);
+				if (param != null && param.length == 2) {
+					result.put(param[0], param[1]);
+				}
+			}
+		}
+
+		return result;
+	}
+
+}

+ 57 - 0
src/main/resources/application.properties

@@ -0,0 +1,57 @@
+server.port=8098
+server.servlet.context-path=/meixi
+
+server.tomcat.uri-encoding=UTF-8
+
+## 服务名
+#spring.application.name=meixi-yd
+## 环境设置:dev、test、prod(开发环境、测试环境、生产环境)
+#spring.profiles.active=dev
+
+# mysql数据库连接
+# 本地测试数据库
+#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+#spring.datasource.url=jdbc:mysql://localhost:3306/dingtalk?serverTimezone=GMT%2B8
+#spring.datasource.username=root
+#spring.datasource.password=123456
+
+# 云璞【47.98.130.40服务器】测试数据库
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.url=jdbc:mysql://47.97.181.40:3306/dingtalk?serverTimezone=GMT%2B8
+spring.datasource.username=root
+spring.datasource.password=cp-root@2022++
+
+#定时同步
+
+#配置日志,当前为默认的控制台输出,也可以用log4j
+#mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
+
+#控制台显示sql
+#spring.jpa.show-sql=true
+#更新或者创建数据表结构
+#spring.jpa.hibernate.ddl-auto=update
+
+#返回json的全局时间格式
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+#配置mapper xml文件的路径
+#mybatis-plus.mapper-locations=classpath:com/muzhi/lz/mapper/xml/*.xml
+
+#mybatis-plus.config-location=classpath:mybatis/mybatis-config.xml
+
+#禁用缓存
+spring.thymeleaf.cache=false
+#spring.thymeleaf.mode= LEGACYHTML5
+#spring.resources.chain.strategy.content.enabled=true
+#spring.resources.chain.strategy.content.paths=/**
+#spring.thymeleaf.check-template = true
+#spring.thymeleaf.servlet.content-type=text/html
+#spring.thymeleaf.enabled = true
+#spring.thymeleaf.encoding = UTF-8
+#spring.thymeleaf.prefix = classpath:/static/
+#spring.thymeleaf.suffix = .html
+
+#定义日期提交的格式(日期的格式化):SpingMVC将页面提交的值需要转换为指定类型;默认的是yyyy/MM/dd
+#spring.mvc.date-format=yyyy-MM-dd
+
+spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/templates/

+ 241 - 0
src/test/java/com/muzhi/meixi/APITest/Test1.java

@@ -0,0 +1,241 @@
+package com.muzhi.meixi.APITest;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.muzhi.meixi.api.WdtClient;
+import com.muzhi.meixi.service.AccessTokenService;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@SpringBootTest
+public class Test1 {
+
+    @Autowired
+    private AccessTokenService accessTokenService;
+
+    @Test
+    public void panduan(){
+        //判断日期是否为周六周日
+        String date = "2022-10-08 00:00:00";
+        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+        Date date1 = null;
+        try {
+            date1 = format.parse(date);
+            System.out.println("date1:" + date1);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date1);
+
+        if (calendar.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||calendar.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){
+            System.out.println("当前日期为周六周日!");
+        }else {
+            System.out.println("当前日期为工作日");
+        }
+    }
+
+    @Test
+    public void date(){
+        int dkcs = 5;
+        int ccts = 0;
+
+        dkcs = dkcs/2;
+        int dkcsLast = (int)dkcs;
+
+
+        if (dkcs > 0){
+            //实际出差天数
+            ccts = ccts + dkcsLast;
+            System.out.println("实际出差天数:" + ccts);
+        }
+
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        long startLong = new Long("1670342400000");
+        //将时间戳转换为时间
+        Date startDate = new Date(startLong);
+        System.out.println("出差开始时间(时间型):" + startDate);
+        //将时间调整为yyyy-MM-dd HH:mm:ss时间样式
+        String startString = simpleDateFormat.format(startDate);
+        System.out.println("出差开始时间(时间样式):" + startString);
+
+        long endLong = new Long("1670428800000");
+        //将时间戳转换为时间
+        Date endDate = new Date(endLong);
+        System.out.println("出差结束时间(时间型):" + endDate);
+        //将时间调整为yyyy-MM-dd HH:mm:ss时间样式
+        String endString = simpleDateFormat.format(endDate);
+        System.out.println("出差结束时间(时间样式):" + endString);
+
+        Calendar calendar1 = Calendar.getInstance();
+        calendar1.setTime(endDate);
+        //后面一天
+        calendar1.add(Calendar.DAY_OF_MONTH,1);
+        calendar1.set(Calendar.HOUR_OF_DAY,0);
+        calendar1.set(Calendar.MINUTE,0);
+        calendar1.set(Calendar.SECOND,0);
+        calendar1.set(Calendar.MILLISECOND,0);
+        String time1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar1.getTime());
+        System.out.println("出差结束时间后面一天零点:" + time1);
+
+        DateTime lastDateTime = DateUtil.parse(time1);
+        System.out.println("出差结束时间后面一天(时间型):" + lastDateTime);
+
+        //获取当天前一天的零点零分零秒
+        Date Date = new Date(System.currentTimeMillis());
+        System.out.println("当前时间:" + Date);
+        String dateNowString = simpleDateFormat.format(Date);
+        System.out.println("当前时间(时间样式):" + dateNowString);
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(Date);
+        //前一天
+        calendar.add(Calendar.DAY_OF_MONTH,-1);
+        calendar.set(Calendar.HOUR_OF_DAY,0);
+        calendar.set(Calendar.MINUTE,0);
+        calendar.set(Calendar.SECOND,0);
+        calendar.set(Calendar.MILLISECOND,0);
+        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
+        System.out.println("前一天零点:" + time);
+
+        Calendar calendar111 = Calendar.getInstance();
+        calendar111.setTime(Date);
+        //前一个月第一天
+        calendar111.add(Calendar.MONTH,-1);
+        calendar111.set(Calendar.DAY_OF_MONTH,1);
+        calendar111.set(Calendar.HOUR_OF_DAY,0);
+        calendar111.set(Calendar.MINUTE,0);
+        calendar111.set(Calendar.SECOND,0);
+        calendar111.set(Calendar.MILLISECOND,0);
+        String FORMtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar111.getTime());
+        System.out.println("前一个月第一天零点:" + FORMtime);
+
+        Calendar calendar222 = Calendar.getInstance();
+        int month222 = calendar222.get(Calendar.MONTH);
+        //前一个月最后一天
+        calendar222.set(Calendar.MONTH,month222-1);
+        calendar222.set(Calendar.DAY_OF_MONTH,calendar222.getActualMaximum(Calendar.DAY_OF_MONTH));
+        calendar222.set(Calendar.HOUR_OF_DAY,0);
+        calendar222.set(Calendar.MINUTE,0);
+        calendar222.set(Calendar.SECOND,0);
+        calendar222.set(Calendar.MILLISECOND,0);
+        String TOtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar222.getTime());
+        System.out.println("前一个月最后一天零点:" + TOtime);
+    }
+
+    @Test
+    public void wangdiantong(){
+
+        //卖家账号
+        String sid = "xindi2";
+        //接口账号
+        String appkey = "xindi2-ot";
+        //接口秘钥
+        String appsecret = "7aaa92c1cb4b8c00d42082b5d430c55a";
+        //正式环境
+        String baseUrl = "https://api.wangdian.cn/openapi2/";
+
+
+        //卖家账号
+        String sidTest = "apidevnew2";
+        //接口账号
+        String appkeyTest = "xindi2-test";
+        //接口秘钥
+        String appsecretTest = "bff3980d2";
+        //测试环境
+        String baseUrlTest = "https://sandbox.wangdian.cn/openapi2/";
+
+        //正式
+        WdtClient client = new WdtClient(sid, appkey, appsecret, baseUrl);
+
+        //测试
+//        WdtClient client = new WdtClient(sidTest, appkeyTest, appsecretTest, baseUrlTest);
+
+        //测试环境sid、appkey、密钥请到旺店通开放平台-自助对接-申请测试环境内查看,测试环境url=https://sandbox.wangdian.cn/openapi2/
+        //调用正式环境时请将sid、appkey、appsecret切换为实际参数,参数在旺店通开放平台-自助对接-应用管理内应用状态为已上线的应用中查看,调用正式环境注意切换正式环境url=https://api.wangdian.cn/openapi2/
+
+        Map<String, String> params = new HashMap<>();
+        //CANGK
+//        params.put("warehouse_no", "WARE1");
+//        params.put("start_time","2022-11-01 00:00:00");
+//        params.put("end_time","2022-11-29 00:00:00");
+        params.put("page_no", "0");
+        params.put("page_size", "100");
+
+
+        //【全量查询库存接口】
+//        JSONObject jsonObject = null;
+//        try {
+//            String response = client.execute("vip_stock_query_all.php", params);
+//            System.out.println(response);
+//
+//            jsonObject = JSON.parseObject(response);
+//
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+
+        //【增量查询库存接口】
+        params.put("start_time", "2022-12-01 00:00:00");
+        params.put("end_time", "2022-12-13 00:00:00");
+//        params.put("spec_no","6930285735967");
+        params.put("is_deleted","1");
+//        params.put("spec_is_deleted","1");
+
+        JSONObject jsonObject = null;
+        try {
+            String response = client.execute("stock_query.php", params);
+            System.out.println(response);
+
+            jsonObject = JSON.parseObject(response);
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        System.out.println("旺店通接口返回数据:" + jsonObject);
+
+//        //unicode转中文
+//        int start = 0;
+//        int end = 0;
+//        final StringBuffer buffer = new StringBuffer();
+//        while (start > -1) {
+//            end = message.indexOf("\\u", start + 2);
+//            String charStr = "";
+//            if (end == -1) {
+//                charStr = message.substring(start, message.length());
+//            } else {
+//                charStr = message.substring(start, end);
+//            }
+//            char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整型字符串。
+//            buffer.append(new Character(letter).toString());
+//            start = end;
+//        }
+//        String messageStr = buffer.toString();
+//        System.out.println("unicode转中文:" + messageStr);
+
+//        JSONArray stocks = jsonObject.getJSONArray("stocks");
+//        for (int i = 0; i < stocks.size(); i++) {
+//            JSONObject jsonObject1 = stocks.getJSONObject(i);
+//            //条形码
+//            String barcode = jsonObject1.getString("barcode");
+//            //货物名称
+//            String goods_name = jsonObject1.getString("goods_name");
+//            //仓库名称
+//            String warehouse_name = jsonObject1.getString("warehouse_name");
+//            //库存量
+//            String stock_num = jsonObject1.getString("stock_num");
+//        }
+    }
+}

+ 13 - 0
src/test/java/com/muzhi/meixi/TestApplicationTests.java

@@ -0,0 +1,13 @@
+package com.muzhi.meixi;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class TestApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}