Ver código fonte

项目迁移

zhang-kan-kan 2 anos atrás
commit
db009b7f57
23 arquivos alterados com 3334 adições e 0 exclusões
  1. 37 0
      .gitignore
  2. 353 0
      pom.xml
  3. 22 0
      src/main/java/com/muzhi/zhizhong/ZhiZhongApplication.java
  4. 77 0
      src/main/java/com/muzhi/zhizhong/common/R.java
  5. 12 0
      src/main/java/com/muzhi/zhizhong/common/ResultCode.java
  6. 43 0
      src/main/java/com/muzhi/zhizhong/controller/AccessTokenController.java
  7. 117 0
      src/main/java/com/muzhi/zhizhong/controller/DingOaController.java
  8. 42 0
      src/main/java/com/muzhi/zhizhong/controller/TongbuController.java
  9. 28 0
      src/main/java/com/muzhi/zhizhong/entity/EmpZhizhong.java
  10. 34 0
      src/main/java/com/muzhi/zhizhong/entity/StateZhizhong.java
  11. 11 0
      src/main/java/com/muzhi/zhizhong/mapper/EmpZhizhongMapper.java
  12. 12 0
      src/main/java/com/muzhi/zhizhong/mapper/StateZhizhongMapper.java
  13. 5 0
      src/main/java/com/muzhi/zhizhong/mapper/xml/EmpZhizhongMapper.xml
  14. 5 0
      src/main/java/com/muzhi/zhizhong/mapper/xml/StateZhizhongMapper.xml
  15. 14 0
      src/main/java/com/muzhi/zhizhong/service/AccessTokenService.java
  16. 35 0
      src/main/java/com/muzhi/zhizhong/service/DingOaService.java
  17. 10 0
      src/main/java/com/muzhi/zhizhong/service/TongbuService.java
  18. 72 0
      src/main/java/com/muzhi/zhizhong/service/impl/AccessTokenServiceImpl.java
  19. 1469 0
      src/main/java/com/muzhi/zhizhong/service/impl/DingOaServiceImpl.java
  20. 195 0
      src/main/java/com/muzhi/zhizhong/service/impl/TongbuServiceImpl.java
  21. 60 0
      src/main/resources/application.properties
  22. 668 0
      src/test/java/com/muzhi/zhizhong/APITest/Test1.java
  23. 13 0
      src/test/java/com/muzhi/zhizhong/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.zhizhong</groupId>
+    <artifactId>zhizhong</artifactId>
+<!--    <packaging>jar</packaging>-->
+    <version>1.0-SNAPSHOT</version>
+    <name>zhizhong</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>

+ 22 - 0
src/main/java/com/muzhi/zhizhong/ZhiZhongApplication.java

@@ -0,0 +1,22 @@
+package com.muzhi.zhizhong;
+
+//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.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+
+@MapperScan("com.muzhi.zhizhong.mapper")
+@EnableAsync//开启异步注解
+@SpringBootApplication//(exclude= DataSourceAutoConfiguration.class)启动时不加载数据库
+@EnableScheduling//开启定时任务
+//@ComponentScan(basePackages = {"com.muzhi"})
+public class ZhiZhongApplication {
+
+    public static void main(String[] args){
+        SpringApplication.run(ZhiZhongApplication.class, args);
+    }
+
+}

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

@@ -0,0 +1,77 @@
+package com.muzhi.zhizhong.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/zhizhong/common/ResultCode.java

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

+ 43 - 0
src/main/java/com/muzhi/zhizhong/controller/AccessTokenController.java

@@ -0,0 +1,43 @@
+package com.muzhi.zhizhong.controller;
+
+import com.muzhi.zhizhong.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;
+    }
+
+    //获取钉钉中的access_token(牧之测试架构4)
+    @ApiOperation(value = "获取钉钉中的access_token")
+    @GetMapping("getMuZhiAccessToken")
+    public String getMuZhiAccessToken(){
+
+        String muZhiAccessToken = AccessTokenService.getMuZhiAccessToken();
+        return muZhiAccessToken;
+    }
+}

+ 117 - 0
src/main/java/com/muzhi/zhizhong/controller/DingOaController.java

@@ -0,0 +1,117 @@
+package com.muzhi.zhizhong.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.muzhi.zhizhong.common.R;
+import com.muzhi.zhizhong.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.*;
+
+
+@Api(description = "钉钉人事")
+@RestController
+@RequestMapping("/dingservice")
+@CrossOrigin//解决跨域问题
+public class DingOaController {
+
+    @Autowired
+    private DingOaService dingOaService;
+
+    //获取map集合参数
+    @ApiOperation(value = "获取map集合参数")
+    @GetMapping("getJsonStr")
+    public String getJsonStr(){
+
+        String jsonStr = dingOaService.getJsonStr();
+        System.out.println(jsonStr);
+
+        return jsonStr;
+    }
+
+    //创建钉钉OA审批:采购订单【传json格式参数】
+    @ApiOperation(value = "创建钉钉OA审批:采购订单")
+    @PostMapping("createPuOrder")
+    @ResponseBody
+    public R createPuOrder(@RequestBody JSONObject body) throws Exception{
+
+        R puOrder = dingOaService.createPuOrder(body);
+        System.out.println(puOrder);
+
+        return puOrder;
+    }
+
+//    //创建钉钉OA审批:采购订单【传jsonStr格式参数】
+//    @ApiOperation(value = "创建钉钉OA审批:采购订单")
+//    @PostMapping("createPuOrder")
+//    public R createPuOrder(String jsonStr) throws Exception{
+//
+//        R puOrder = dingOaService.createPuOrder(jsonStr);
+//        System.out.println(puOrder);
+//
+//        return puOrder;
+//    }
+
+    //创建钉钉OA审批:销售订单【传json格式参数】
+    @ApiOperation(value = "创建钉钉OA审批:销售订单")
+    @PostMapping("createSaOrder")
+    public R createSaOrder(@RequestBody JSONObject body) throws Exception{
+
+        R saOrder = dingOaService.createSaOrder(body);
+        System.out.println(saOrder);
+
+        return saOrder;
+    }
+
+//    //创建钉钉OA审批:销售订单【传jsonStr格式参数】
+//    @ApiOperation(value = "创建钉钉OA审批:销售订单")
+//    @PostMapping("createSaOrder")
+//    public R createSaOrder(String jsonStr) throws Exception{
+//
+//        R saOrder = dingOaService.createSaOrder(jsonStr);
+//        System.out.println(saOrder);
+//
+//        return saOrder;
+//    }
+
+    //附件上传
+    @ApiOperation(value = "附件上传")
+    @PostMapping("addFile")
+    public R addFile(String download_url,String userid) throws Exception{
+
+        R s = dingOaService.addFile(download_url,userid);
+        System.out.println(s);
+
+        return s;
+    }
+
+    //定时同步钉钉审批单状态至U8C
+    @ApiOperation(value = "定时同步钉钉审批单状态至U8C")
+    @PostMapping("timerStatus")
+//    @Scheduled(cron = "0 10 0 * * ?")//每天00:10触发(也就是凌晨0点10分触发)
+//    @Scheduled(cron = "0/30 * * * * ?")//每30秒触发一次
+//    @Scheduled(cron = "0 0/1 * * * ?")//每1分钟触发一次
+    public R timerStatus(){
+
+        R s = dingOaService.timerStatus();
+        R r = dingOaService.timerStatusPDF();
+        System.out.println(r);
+
+        return r;
+    }
+
+    //定时同步钉钉审批单合同附件签署状态至U8C
+    @ApiOperation(value = "定时同步钉钉审批单合同附件签署状态至U8C")
+    @PostMapping("timerStatusPDF")
+//    @Scheduled(cron = "0 10 0 * * ?")//每天00:10触发(也就是凌晨0点10分触发)
+//    @Scheduled(cron = "0/30 * * * * ?")//每30秒触发一次
+//    @Scheduled(cron = "0 0/1 * * * ?")//每1分钟触发一次
+    public R timerStatusPDF(){
+
+        R s = dingOaService.timerStatusPDF();
+        System.out.println(s);
+
+        return s;
+    }
+}

+ 42 - 0
src/main/java/com/muzhi/zhizhong/controller/TongbuController.java

@@ -0,0 +1,42 @@
+package com.muzhi.zhizhong.controller;
+
+
+import com.muzhi.zhizhong.common.R;
+import com.muzhi.zhizhong.service.TongbuService;
+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.*;
+
+@Api(description = "同步数据至数据库")
+@RestController
+@RequestMapping("/tongbuservice")
+@CrossOrigin//解决跨域问题
+public class TongbuController {
+
+    @Autowired
+    private TongbuService tongbuService;
+
+    //删除employee表中的所有数据
+    @ApiOperation(value = "删除employee表中的所有数据")
+    @PostMapping("removeEmployee")
+    public R removeEmployee(){
+        String result = tongbuService.removeEmployee();
+        return R.ok().data("result", result);
+    }
+
+    //同步花名册数据至数据库
+    @ApiOperation(value = "同步花名册数据至数据库")
+    @PostMapping("addHuamingce")
+//    @Scheduled(cron = "0 1 15 * * ?")//每天下午15:01触发(也就是下午3点触发)
+    @Scheduled(cron = "0 0 0 * * ?")//每天00:00触发(也就是凌晨0点整触发)
+    public R addHuamingce(){
+        //先删除清空employee表中的所有数据
+        tongbuService.removeEmployee();
+
+        //再执行插入花名册数据库表的接口
+        String result = tongbuService.addHuamingce();
+        return R.ok().data("result", result);
+    }
+}

+ 28 - 0
src/main/java/com/muzhi/zhizhong/entity/EmpZhizhong.java

@@ -0,0 +1,28 @@
+package com.muzhi.zhizhong.entity;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "人员信息", description = "人员信息")
+public class EmpZhizhong {
+
+    @ApiModelProperty(value = "人员id")
+    private String userid;
+
+    @ApiModelProperty(value = "人员姓名")
+    private String name;
+
+    @ApiModelProperty(value = "部门id")
+    private String deptid;
+
+    @ApiModelProperty(value = "部门")
+    private String deptname;
+}

+ 34 - 0
src/main/java/com/muzhi/zhizhong/entity/StateZhizhong.java

@@ -0,0 +1,34 @@
+package com.muzhi.zhizhong.entity;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "同步记录", description = "同步记录")
+public class StateZhizhong {
+
+    @ApiModelProperty(value = "订单类型")
+    private String type;
+
+    @ApiModelProperty(value = "唯一编码")
+    private String pk;
+
+    @ApiModelProperty(value = "审批实例id")
+    private String processid;
+
+    @ApiModelProperty(value = "订单编号")
+    private String orderid;
+
+    @ApiModelProperty(value = "U8C同步钉钉状态")
+    private String state;
+
+    @ApiModelProperty(value = "钉钉审批/签署状态回传")
+    private String status;
+}

+ 11 - 0
src/main/java/com/muzhi/zhizhong/mapper/EmpZhizhongMapper.java

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

+ 12 - 0
src/main/java/com/muzhi/zhizhong/mapper/StateZhizhongMapper.java

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

+ 5 - 0
src/main/java/com/muzhi/zhizhong/mapper/xml/EmpZhizhongMapper.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.zhizhong.mapper.EmpZhizhongMapper">
+
+</mapper>

+ 5 - 0
src/main/java/com/muzhi/zhizhong/mapper/xml/StateZhizhongMapper.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.zhizhong.mapper.StateZhizhongMapper">
+
+</mapper>

+ 14 - 0
src/main/java/com/muzhi/zhizhong/service/AccessTokenService.java

@@ -0,0 +1,14 @@
+package com.muzhi.zhizhong.service;
+
+/**
+ * @Author ZhangKan
+ * @Data 15:34
+ */
+public interface AccessTokenService {
+
+    //获取access_token的方法(智众架构)
+    String getAccessToken();
+
+    //获取access_token的方法(牧之测试架构4)
+    String getMuZhiAccessToken();
+}

+ 35 - 0
src/main/java/com/muzhi/zhizhong/service/DingOaService.java

@@ -0,0 +1,35 @@
+package com.muzhi.zhizhong.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.muzhi.zhizhong.common.R;
+import org.springframework.web.bind.annotation.RequestBody;
+
+/**
+ * @Author ZhangKan
+ * @Data 15:34
+ */
+public interface DingOaService {
+    //获取map集合参数
+    String getJsonStr();
+
+    //创建钉钉OA审批:采购订单【传json格式参数】
+    R createPuOrder(JSONObject body) throws Exception;
+
+//    //创建钉钉OA审批:采购订单【传jsonStr格式参数】
+//    R createPuOrder(String jsonStr) throws Exception;
+
+    //创建钉钉OA审批:销售订单【传json格式参数】
+    R createSaOrder(JSONObject body) throws Exception;
+
+//    //创建钉钉OA审批:销售订单【传jsonStr格式参数】
+//    R createSaOrder(String jsonStr) throws Exception;
+
+    //附件上传
+    R addFile(String download_url,String userid) throws Exception;
+
+    //定时同步钉钉审批单状态至U8C
+    R timerStatus();
+
+    //定时同步钉钉审批单合同附件签署状态至U8C
+    R timerStatusPDF();
+}

+ 10 - 0
src/main/java/com/muzhi/zhizhong/service/TongbuService.java

@@ -0,0 +1,10 @@
+package com.muzhi.zhizhong.service;
+
+public interface TongbuService {
+
+    //删除employee表中的所有数据
+    String removeEmployee();
+
+    //同步花名册数据至数据库
+    String addHuamingce();
+}

+ 72 - 0
src/main/java/com/muzhi/zhizhong/service/impl/AccessTokenServiceImpl.java

@@ -0,0 +1,72 @@
+package com.muzhi.zhizhong.service.impl;
+
+import com.dingtalk.api.DefaultDingTalkClient;
+import com.dingtalk.api.request.OapiGettokenRequest;
+import com.dingtalk.api.response.OapiGettokenResponse;
+import com.muzhi.zhizhong.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 = "dingavm4s3mj6h9vqhcv";
+    //APPSECRET
+    private static String APPSECRET = "lj_AUdLCwk8ixkF24hQ5EqasE6osd0IXHb8Vl-QRyFQionSJeBbYgtE65zk6v2k3";
+    //AgenthId:2121466878
+
+    public static String accessToken = null;
+
+    //牧之测试架构4
+    //APPKEY
+    private static String APPKEY1 = "ding2katvzyqvlkunqtb";
+    //APPSECRET
+    private static String APPSECRET1 = "vSctQrVm5cGos0X6K86NN0A8Vv6-SmN4W_VRXjsqPqZRhZtbG6xfPATOZhPi3VBE";
+
+    public static String accessToken1 = 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;
+    }
+
+    //获取access_token的方法(牧之测试架构4)
+    @Override
+    public String getMuZhiAccessToken() {
+        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+        OapiGettokenRequest request = new OapiGettokenRequest();
+        request.setAppkey(APPKEY1);
+        request.setAppsecret(APPSECRET1);
+        request.setHttpMethod("GET");
+        try {
+            OapiGettokenResponse response = client.execute(request);
+            accessToken1 = response.getAccessToken();
+            System.out.println("牧之测试架构4的AccessToken:" + accessToken1);
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+        return accessToken1;
+    }
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 1469 - 0
src/main/java/com/muzhi/zhizhong/service/impl/DingOaServiceImpl.java


Diferenças do arquivo suprimidas por serem muito extensas
+ 195 - 0
src/main/java/com/muzhi/zhizhong/service/impl/TongbuServiceImpl.java


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

@@ -0,0 +1,60 @@
+#我方服务器部署端口
+server.port=8081
+#智众方服务器部署端口
+#server.port=8088
+server.servlet.context-path=/zhizhong
+
+server.tomcat.uri-encoding=UTF-8
+
+## 服务名
+#spring.application.name=zhizhong-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/

+ 668 - 0
src/test/java/com/muzhi/zhizhong/APITest/Test1.java

@@ -0,0 +1,668 @@
+package com.muzhi.zhizhong.APITest;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.aliyun.dingtalkstorage_1_0.models.CommitFileResponse;
+import com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoResponse;
+import com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceResponse;
+import com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsResponse;
+import com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceResponse;
+import com.aliyun.tea.TeaException;
+import com.aliyun.teautil.models.RuntimeOptions;
+import com.dingtalk.api.DefaultDingTalkClient;
+import com.dingtalk.api.DingTalkClient;
+import com.dingtalk.api.request.OapiCspaceAddRequest;
+import com.dingtalk.api.request.OapiProcessinstanceCreateRequest;
+import com.dingtalk.api.request.OapiProcessinstanceCspaceInfoRequest;
+import com.dingtalk.api.request.OapiV2UserGetRequest;
+import com.dingtalk.api.response.OapiCspaceAddResponse;
+import com.dingtalk.api.response.OapiProcessinstanceCreateResponse;
+import com.dingtalk.api.response.OapiProcessinstanceCspaceInfoResponse;
+import com.dingtalk.api.response.OapiV2UserGetResponse;
+import com.muzhi.zhizhong.service.AccessTokenService;
+import com.taobao.api.ApiException;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@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(){
+        //获取当天前一天的零点零分零秒
+        Date Date = new Date(System.currentTimeMillis());
+        System.out.println("当前时间:" + Date);
+        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);
+    }
+
+    //新版创建OA审批
+    public static com.aliyun.dingtalkworkflow_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.dingtalkworkflow_1_0.Client(config);
+    }
+
+    @Test
+    public void creatOAnew() throws Exception{
+
+        JSONObject jsonObject = null;
+        com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
+        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceHeaders startProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceHeaders();
+        startProcessInstanceHeaders.xAcsDingtalkAccessToken = accessTokenService.getAccessToken();
+        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues formComponentValues0 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues()
+                .setName("供应商名称")
+                .setComponentType("TextField")
+                .setId("TextField_18SNO8NGT59FK")
+                .setValue("随便是什么222333");
+        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers approvers0 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers()
+                .setActionType("NONE")
+                .setUserIds(java.util.Arrays.asList(
+                        "3956393642753968"
+                ));
+        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest startProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest()
+                .setApprovers(java.util.Arrays.asList(
+                        approvers0
+                ))
+                .setOriginatorUserId("3956393642753968")
+                .setProcessCode("PROC-C897D925-5856-4200-BB0E-2AC03A1CBD60")
+                .setFormComponentValues(java.util.Arrays.asList(
+                        formComponentValues0
+                ));
+        try {
+            StartProcessInstanceResponse startProcessInstanceResponse = client.startProcessInstanceWithOptions(startProcessInstanceRequest, startProcessInstanceHeaders, new RuntimeOptions());
+            System.out.println("*************" + JSON.toJSONString(startProcessInstanceResponse.getBody()));
+            String s = JSON.toJSONString(startProcessInstanceResponse.getBody());
+            jsonObject = JSON.parseObject(s);
+            System.out.println("创建审批实例接口object对象:" + jsonObject);
+        } 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 属性,可帮助开发定位问题
+            }
+
+        }
+
+        System.out.println("创建审批实例接口object对象:" + jsonObject);
+    }
+
+    @Test
+    public void creatOA() throws Exception{
+
+        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/create");
+        OapiProcessinstanceCreateRequest req = new OapiProcessinstanceCreateRequest();
+        req.setAgentId(2121466878L);
+        req.setProcessCode("PROC-C897D925-5856-4200-BB0E-2AC03A1CBD60");
+        req.setOriginatorUserId("3956393642753968");
+        req.setDeptId(-1L);
+//        req.setCcList("4525xxxxxxxx77041");
+//        req.setCcPosition("FINISH");
+
+        //单行输入框
+        List<OapiProcessinstanceCreateRequest.FormComponentValueVo> formComponentValueVoList = new ArrayList<>();
+        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+        formComponentValueVoList.add(formComponentValueVo);
+        formComponentValueVo.setName("供应商名称");
+        formComponentValueVo.setValue("这是一个测试供应商");
+
+//        //多行输入框
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo1 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo1);
+//        formComponentValueVo1.setName("多行输入框");
+//        formComponentValueVo1.setValue("测试多行输入框");
+//
+//        //金额输入框
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo2 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo2);
+//        formComponentValueVo2.setName("金额(元)大写");
+//        formComponentValueVo2.setValue("1");
+//
+//        //数字输入框
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo3 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo3);
+//        formComponentValueVo3.setName("数字输入框");
+//        formComponentValueVo3.setValue("100");
+//
+//        //单选框组件
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo5 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo5);
+//        formComponentValueVo5.setName("单选框");
+//        formComponentValueVo5.setValue("a");
+//
+//        //多选框组件
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo6 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo6);
+//        formComponentValueVo6.setName("多选框");
+//        formComponentValueVo6.setValue("[\"a\",\"b\"]");
+//
+//        //日期组件
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo7 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo7);
+//        formComponentValueVo7.setName("日期");
+//        formComponentValueVo7.setValue("2021-08-17");
+//
+//        //日期区间组件
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo8 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo8);
+//        formComponentValueVo8.setName("[\"开始时间\",\"结束时间\"]");
+//        formComponentValueVo8.setValue("[\"2019-02-19\",\"2019-02-25\"]");
+//
+//        //上传图片
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo9 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo9);
+//        formComponentValueVo9.setName("图片");
+//        formComponentValueVo9.setValue(JSON.toJSONString(new String[]{"https://xxxxxxxx", "https://xxxxxxxxx"}));
+//
+//        //上传审批附件
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo10 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo10);
+//        JSONObject jsonObject = new JSONObject();
+//        jsonObject.put("spaceId", "163xxxx658");
+//        jsonObject.put("fileName", "IMG_2322.PNG");
+//        jsonObject.put("fileSize", "276297");
+//        jsonObject.put("fileType", "png");
+//        jsonObject.put("fileId", "405xxxxx777");
+//        Object o[] = new Object[]{jsonObject};
+//        String s = JSON.toJSONString(o);
+//        formComponentValueVo10.setName("附件");
+//        formComponentValueVo10.setValue(s);
+//
+//        //联系人
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo11 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo11);
+//        formComponentValueVo11.setName("联系人");
+//        formComponentValueVo11.setValue("[\"4525xxxxxxxx77041\"]");
+//
+//        //明细
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo12 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo Item1 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        Item1.setName("单行输入框");
+//        Item1.setValue("明细单行输入框");
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo Item2 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        Item2.setName("数字输入框");
+//        Item2.setValue("100");
+//        formComponentValueVo12.setName("明细");
+//        formComponentValueVo12.setValue(JSON.toJSONString(Arrays.asList(Arrays.asList(Item1, Item2))));
+//        formComponentValueVoList.add(formComponentValueVo12);
+//
+//        //关联审批单
+//        OapiProcessinstanceCreateRequest.FormComponentValueVo formComponentValueVo13 = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
+//        formComponentValueVoList.add(formComponentValueVo13);
+//        formComponentValueVo13.setName("关联审批单");
+//        formComponentValueVo13.setValue(JSON.toJSONString(Arrays.asList("fa2aa864-xxxx-xxxx-xxxx-75572c0e2cdf")));
+//
+//        //设置审批人,会签、或签设置的审批人必须大于等于2个人
+//        List<OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo> processInstanceApproverVoList = new ArrayList<OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo>();
+//        OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo processInstanceApproverVo = new OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo();
+//        processInstanceApproverVoList.add(processInstanceApproverVo);
+//        processInstanceApproverVo.setTaskActionType("AND");
+//        processInstanceApproverVo.setUserIds(Arrays.asList("4525xxxxxxxx77041","2643xxxxxxx69379"));
+//        OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo processInstanceApproverVo1 = new OapiProcessinstanceCreateRequest.ProcessInstanceApproverVo();
+//        processInstanceApproverVoList.add(processInstanceApproverVo1);
+//        processInstanceApproverVo1.setTaskActionType("OR");
+//        processInstanceApproverVo1.setUserIds(Arrays.asList("4525xxxxxxxx77041","2643xxxxxxx69379"));
+//        req.setApproversV2(processInstanceApproverVoList);
+
+        req.setFormComponentValues(formComponentValueVoList);
+        OapiProcessinstanceCreateResponse rsp = client.execute(req, accessTokenService.getAccessToken());
+        System.out.println(JSON.toJSONString(rsp));
+    }
+
+    //审批附件id
+    public static String fileId = null;
+    //审批附件名称
+    public static String fileName = null;
+    //审批附件长度
+    public static Long fileSize = 0L;
+    //审批附件类型
+    public static String fileType = null;
+    //审批钉盘空间id
+    public static String spaceId = null;
+
+    //文件下载保存方法
+    @SuppressWarnings("finally")
+    public static File downloadFile(String urlPath, String downloadDir) {
+        File file = null;
+        try {
+
+            URL url = new URL(urlPath);
+
+            URLConnection urlConnection = url.openConnection();
+
+            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;// http的连接类
+
+            //String contentType = httpURLConnection.getContentType();//请求类型,可用来过滤请求,
+
+            httpURLConnection.setConnectTimeout(1000*5);//设置超时
+
+            httpURLConnection.setRequestMethod("GET");//设置请求方式,默认是GET
+
+            httpURLConnection.setRequestProperty("Charset", "UTF-8");// 设置字符编码
+
+
+            httpURLConnection.connect();// 打开连接
+
+            BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream());
+
+            //TODO 修改成动态文件名称:当前审批单的文件名称
+//            String fileName = "ceshi.pdf";// 指定文件名称
+
+            String path = downloadDir + File.separatorChar + fileName;// 指定存放位置,此处使用的是全局变量的文件名称
+            file = new File(path);
+            // 校验文件夹目录是否存在,不存在就创建一个目录
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+            }
+
+            OutputStream out = new FileOutputStream(file);
+            int size = 0;
+
+            byte[] b = new byte[2048];
+            //把输入流的文件读取到字节数据b中,然后输出到指定目录的文件
+            while ((size = bin.read(b)) != -1) {
+                out.write(b, 0, size);
+            }
+            // 关闭资源
+            bin.close();
+            out.close();
+            System.out.println("文件下载成功!");
+        } catch (MalformedURLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            System.out.println("文件下载失败!");
+        } finally {
+            return file;
+        }
+
+    }
+
+    public static com.aliyun.dingtalkstorage_1_0.Client createClient1() throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
+        config.protocol = "https";
+        config.regionId = "central";
+        return new com.aliyun.dingtalkstorage_1_0.Client(config);
+    }
+
+    @Test
+    public void getSpaceId(){
+
+        //文件下载地址
+        String download_url = "https://mc.cloudpure.cn/portal/aliwork/love.pdf";
+
+        //获取当前日期,用于创建文件保存目录中增加当前日期的文件夹作区分
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式 yyyy-MM-dd HH:mm:ss
+        String format = df.format(new Date());
+        System.out.println(format);// new Date()为获取当前系统时间
+
+        //参数1:文件下载地址;
+        //参数2:文件下载后保存地址;
+        //【windows端下载文件保存路径】
+        File file = downloadFile(download_url, "D:\\pdf\\" + format);
+        System.out.println("&&&&&&&&&&&&&&&&&" + file);
+        if (file != null){
+            fileSize = file.length();
+            System.out.println("文件长度:" + fileSize);
+            fileName = file.getName();
+            System.out.println("文件名称:" + fileName);
+            //截取文件全名最后一个小数点后面的文件后缀(文件类型)
+            fileType = fileName.substring(fileName.lastIndexOf(".") + 1,fileName.length());
+            System.out.println("文件类型:" + fileType);
+        }else {
+            System.out.println("文件下载地址有误!");
+        }
+        //【Linux端下载文件保存路径】
+        //downloadFile(download_uri,format);
+
+        //【Linux下面的路径】
+        //原始文件路径
+        String strFile = format + File.separator + fileName;
+
+        //【windows下面的路径】
+        //原始文件路径
+        String a = "D:\\pdf\\" + format + "\\" + fileName;
+
+        System.out.println("#################" + a);
+
+        //***获取审批钉盘空间信息(企业审批附件钉盘空间,需通过获取审批钉盘空间信息接口进行【授权】)***
+        String space_XX = null;
+
+        try {
+            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/cspace/info");
+            OapiProcessinstanceCspaceInfoRequest req = new OapiProcessinstanceCspaceInfoRequest();
+            //用户id
+            req.setUserId("3956393642753968");
+            //企业应用标识,此处可以不传
+//            req.setAgentId(2121466878L);
+            OapiProcessinstanceCspaceInfoResponse rsp = client.execute(req, accessTokenService.getAccessToken());
+            space_XX = rsp.getBody();
+            System.out.println(rsp.getBody());
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+
+        JSONObject jsonObject_space = JSON.parseObject(space_XX);
+        JSONObject result_space = jsonObject_space.getJSONObject("result");
+        spaceId = result_space.getString("space_id");
+        System.out.println("审批钉盘空间id:" + spaceId);
+
+        //获取当前人员的unionid
+        String unionid = null;
+        try {
+            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
+            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
+            //待查询的人员userid
+            req.setUserid("3956393642753968");
+            OapiV2UserGetResponse rsp = client.execute(req, accessTokenService.getAccessToken());
+            String result = rsp.getBody();
+            System.out.println(result);
+            unionid = JSON.parseObject(result).getJSONObject("result").getString("unionid");
+            System.out.println("获取的人员unionid:" + unionid);
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+
+        //获取文件上传信息
+        JSONObject jsonObject = null;
+        try {
+            com.aliyun.dingtalkstorage_1_0.Client client = createClient1();
+            com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoHeaders getFileUploadInfoHeaders = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoHeaders();
+            getFileUploadInfoHeaders.xAcsDingtalkAccessToken = accessTokenService.getAccessToken();
+
+            com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest getFileUploadInfoRequest = new com.aliyun.dingtalkstorage_1_0.models.GetFileUploadInfoRequest()
+                    .setUnionId(unionid)
+                    .setProtocol("HEADER_SIGNATURE")
+                    .setMultipart(false);
+
+            GetFileUploadInfoResponse fileUploadInfoWithOptions = client.getFileUploadInfoWithOptions(spaceId, getFileUploadInfoRequest, getFileUploadInfoHeaders, new RuntimeOptions());
+            System.out.println("*************" + JSON.toJSONString(fileUploadInfoWithOptions.getBody()));
+            String s = JSON.toJSONString(fileUploadInfoWithOptions.getBody());
+            jsonObject = JSON.parseObject(s);
+            System.out.println("获取文件上传信息接口object对象:" + jsonObject);
+        } 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 属性,可帮助开发定位问题
+            }
+
+        }
+        JSONObject headerSignatureInfo = jsonObject.getJSONObject("headerSignatureInfo");
+
+        //uploadKey
+        String uploadKey = jsonObject.getString("uploadKey");
+        System.out.println("uploadKey:" + uploadKey);
+
+        //headers
+        JSONObject headersA = headerSignatureInfo.getJSONObject("headers");
+        String authorization = headersA.getString("Authorization");
+        String xossdate = headersA.getString("x-oss-date");
+        Map map = new HashMap();
+        map.put("Authorization",authorization);
+        map.put("x-oss-date",xossdate);
+        System.out.println("headers:" + map);
+
+        //resourceUrl
+        JSONArray resourceUrls = headerSignatureInfo.getJSONArray("resourceUrls");
+        String resourceUrlsString = resourceUrls.getString(0);
+        System.out.println("resourceUrl:" + resourceUrlsString);
+
+        // 从接口返回信息中拿到url
+        String resourceUrl = resourceUrlsString;
+        // 从接口返回信息中拿到headers
+        Map<String, String> headers = map;
+        try {
+            URL url = new URL(resourceUrl);
+            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+            if (headers != null) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                }
+            }
+            connection.setDoOutput(true);
+            connection.setRequestMethod("PUT");
+            connection.setUseCaches(false);
+            connection.setReadTimeout(10000);
+            connection.setConnectTimeout(10000);
+            connection.connect();
+            OutputStream out = connection.getOutputStream();
+
+            //本地上传文件路径
+            InputStream is = new FileInputStream(new File(a));
+
+            byte[] b =new byte[1024];
+            int temp;
+            while ((temp=is.read(b))!=-1){
+                out.write(b,0,temp);
+            }
+            out.flush();
+            out.close();
+            int responseCode = connection.getResponseCode();
+            connection.disconnect();
+            if (responseCode == 200) {
+                System.out.println("上传成功");
+            } else {
+                System.out.println("上传失败");
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+    }
+
+    public static com.aliyun.dingtalkstorage_1_0.Client createClientFile() throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
+        config.protocol = "https";
+        config.regionId = "central";
+        return new com.aliyun.dingtalkstorage_1_0.Client(config);
+    }
+
+    //提交文件
+    @Test
+    public void commit(){
+
+        /*提交文件,并获取文件id*/
+        JSONObject jsonObjectTJ = null;
+        try {
+            com.aliyun.dingtalkstorage_1_0.Client client = createClientFile();
+            com.aliyun.dingtalkstorage_1_0.models.CommitFileHeaders commitFileHeaders = new com.aliyun.dingtalkstorage_1_0.models.CommitFileHeaders();
+            commitFileHeaders.xAcsDingtalkAccessToken = accessTokenService.getAccessToken();
+            com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOptionAppProperties optionAppProperties0 = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOptionAppProperties()
+                    //属性名。
+                    .setName("123.pdf")
+                    //属性可见性。
+                    //PUBLIC:所有应用都可见
+                    //PRIVATE:仅限当前应用可见
+                    .setVisibility("PUBLIC")
+                    //属性值。
+                    .setValue("合同附件");
+            com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOption option = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest.CommitFileRequestOption()
+                    .setAppProperties(java.util.Arrays.asList(
+                            optionAppProperties0
+                    ));
+            com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest commitFileRequest = new com.aliyun.dingtalkstorage_1_0.models.CommitFileRequest()
+                    .setUnionId("WdWZ8N96r257fu4N33YJcgiEiE")
+                    //文件的名称,带后缀。
+                    .setName("123.pdf")
+                    //添加文件唯一标识。
+                    .setUploadKey("hgHOI6ZojQLPAAAAFUPLNPUDAQShNwXaADkjaUFFSEFxUm1hV3hsQTZoNWRXNWthWE5yTUFUT0lVYWl5UVhOQnBnR3pJb0h6bU9PRm1vSXpRSjEGqERJTkdUQUxL")
+                    //父目录Id。根目录时,该参数是0
+                    .setParentId("0")
+                    .setOption(option);
+
+            CommitFileResponse commitFileResponse = client.commitFileWithOptions("598108301", commitFileRequest, commitFileHeaders, new RuntimeOptions());
+            System.out.println("*************" + JSON.toJSONString(commitFileResponse.getBody()));
+            String s = JSON.toJSONString(commitFileResponse.getBody());
+            jsonObjectTJ = JSON.parseObject(s);
+            System.out.println("提交文件接口object对象:" + jsonObjectTJ);
+        } 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 {
+            JSONObject dentry = jsonObjectTJ.getJSONObject("dentry");
+            fileId = dentry.getString("id");
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        System.out.println("获取的文件id:" + fileId);
+        /*提交文件,并获取文件id*/
+    }
+
+    //获取审批实例ID列表
+    @Test
+    public void getShenpiID(){
+
+        JSONObject jsonObject = null;
+        try {
+            com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
+            com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsHeaders listProcessInstanceIdsHeaders = new com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsHeaders();
+            listProcessInstanceIdsHeaders.xAcsDingtalkAccessToken = accessTokenService.getAccessToken();
+            com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsRequest listProcessInstanceIdsRequest = new com.aliyun.dingtalkworkflow_1_0.models.ListProcessInstanceIdsRequest()
+                    .setStartTime(1671087622000L)
+                    .setEndTime(1671091222000L)
+                    .setProcessCode("PROC-67912B9E-E328-469E-BF1A-0578297B49B1")
+                    .setNextToken(0L)
+                    .setMaxResults(20L);
+
+            ListProcessInstanceIdsResponse listProcessInstanceIdsResponse = client.listProcessInstanceIdsWithOptions(listProcessInstanceIdsRequest, listProcessInstanceIdsHeaders, new RuntimeOptions());
+            System.out.println("*************" + JSON.toJSONString(listProcessInstanceIdsResponse.getBody()));
+            String s = JSON.toJSONString(listProcessInstanceIdsResponse.getBody());
+            jsonObject = JSON.parseObject(s);
+            System.out.println("提交文件接口object对象:" + jsonObject);
+        } 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 属性,可帮助开发定位问题
+            }
+
+        }
+
+        JSONObject jsonObject1 = null;
+        try {
+            com.aliyun.dingtalkworkflow_1_0.Client client = createClient();
+            com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders getProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders();
+            getProcessInstanceHeaders.xAcsDingtalkAccessToken = accessTokenService.getAccessToken();
+            com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest getProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest()
+                    .setProcessInstanceId("pTA0ccsyS_O0L-g5Hym27w05291671089519");
+
+            GetProcessInstanceResponse processInstanceWithOptions = client.getProcessInstanceWithOptions(getProcessInstanceRequest, getProcessInstanceHeaders, new RuntimeOptions());
+            System.out.println("*************" + JSON.toJSONString(processInstanceWithOptions.getBody()));
+            String s = JSON.toJSONString(processInstanceWithOptions.getBody());
+            jsonObject1 = JSON.parseObject(s);
+            System.out.println("提交文件接口object对象:" + jsonObject1);
+        } 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 属性,可帮助开发定位问题
+            }
+
+        }
+    }
+
+    //测试U8C回传状态接口
+    @Test
+    public void setState(){
+
+
+    }
+}

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

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