fyz 13 saat önce
işleme
ea457321f7
25 değiştirilmiş dosya ile 2388 ekleme ve 0 silme
  1. 61 0
      mjava-gd/pom.xml
  2. 33 0
      mjava-gd/src/main/java/com/malk/guangdian/Boot.java
  3. 22 0
      mjava-gd/src/main/java/com/malk/guangdian/controller/DDController.java
  4. 52 0
      mjava-gd/src/main/java/com/malk/guangdian/controller/DLController.java
  5. 69 0
      mjava-gd/src/main/java/com/malk/guangdian/delegate/DDDelegate.java
  6. 63 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Income/fct_ar.java
  7. 12 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Income/fct_ar_b.java
  8. 17 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Income/fct_ar_plan.java
  9. 59 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Payment/fct_ap.java
  10. 12 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Payment/fct_ap_b.java
  11. 13 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Payment/fct_ap_plan.java
  12. 11 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ContentDTO.java
  13. 15 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ContentFile.java
  14. 15 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/Content/Parties.java
  15. 41 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ZhiYuanDTO.java
  16. 38 0
      mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ZhiYuanVO.java
  17. 718 0
      mjava-gd/src/main/java/com/malk/guangdian/service/Impl/PayServiceImpl.java
  18. 43 0
      mjava-gd/src/main/java/com/malk/guangdian/service/PayService.java
  19. 57 0
      mjava-gd/src/main/resources/application-dev.yml
  20. 48 0
      mjava-gd/src/main/resources/application-prod.yml
  21. 152 0
      mjava-gd/src/main/resources/json/form.json
  22. 151 0
      mjava-gd/src/main/resources/json/formtest.json
  23. 199 0
      mjava-gd/src/test/java/test.java
  24. 39 0
      mjava-gd/src/test/resource/server.sh
  25. 448 0
      pom.xml

+ 61 - 0
mjava-gd/pom.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>java-mcli</artifactId>
+        <groupId>com.malk</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>mjava-guangdian</artifactId>
+    <description>广电集团</description>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <!-- 核心模块-->
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>mjava</artifactId>
+            <version>${mjava.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.41.2.1</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.1.RELEASE</version>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <!-- 如果没有该配置,devtools不会生效: 打包时关闭 -->
+                    <fork>false</fork>
+                    <!-- 避免中文乱码 -->
+                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
+                </configuration>
+                <!-- 允许生成可运行jar -->
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <finalName>${project.artifactId}</finalName>
+    </build>
+</project>

+ 33 - 0
mjava-gd/src/main/java/com/malk/guangdian/Boot.java

@@ -0,0 +1,33 @@
+package com.malk.guangdian;
+
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+import javax.persistence.EntityManager;
+
+/**
+ * corp项目: 扫描公共模块
+ * -
+ * 若是无需数据库模块, 配置无效地址也可启动, 引入mjava不支持直接 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 配置
+ * 需要配置 jpa.hibernate.ddl-auto 为 none. 标识对表没有任何操作. 若不设置为 none, flyway.enabled 配置会无效, 在没有数库连接情况下程序无法启动
+ */
+@EnableJpaAuditing
+@SpringBootApplication(scanBasePackages = {"com.malk"},exclude={DataSourceAutoConfiguration.class})
+public class Boot {
+
+    public static void main(String... args) {
+        SpringApplication.run(Boot.class, args);
+    }
+
+    /**
+     * 让Spring管理JPAQueryFactory [不使用Qualifier详见mjava-Boot]
+     */
+    @Bean
+    public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) {
+        return new JPAQueryFactory(entityManager);
+    }
+}

+ 22 - 0
mjava-gd/src/main/java/com/malk/guangdian/controller/DDController.java

@@ -0,0 +1,22 @@
+package com.malk.guangdian.controller;
+
+import com.malk.controller.DDCallbackController;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 钉钉事件回调 3_1
+ * -
+ * [子项目直接继承即可有调用, 无需实现]
+ * -
+ * 注解 @RequestMapping 路径不能重复 [主子项目属同一个项目];
+ * 获取项目回调请求地址, https://mc.cloudpure.cn/frp/xxx/dd/callback [调试代理: frp + nginx]
+ */
+@Slf4j
+@RestController
+@RequestMapping("/dd")
+public class DDController extends DDCallbackController {
+
+
+}

+ 52 - 0
mjava-gd/src/main/java/com/malk/guangdian/controller/DLController.java

@@ -0,0 +1,52 @@
+package com.malk.guangdian.controller;
+
+/**
+ * 错误抛出与拦截详见 CatchException
+ */
+
+import com.malk.guangdian.entity.Content.ZhiYuanDTO;
+import com.malk.guangdian.service.PayService;
+import com.malk.server.common.McR;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.service.dingtalk.DDService;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping
+public class DLController {
+
+    @Autowired
+    private YDService ydService;
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private PayService payService;
+
+    @PostMapping(value = "test")
+    McR testToken() {
+        return McR.success();
+    }
+
+    @PostMapping(value = "createContract")
+    McR testGet(@RequestBody ZhiYuanDTO data) throws Exception {
+        String contract = payService.createContract(data);
+//        payService.testupload();
+        return McR.success(contract);
+//        return McR.success();
+    }
+
+    @PostMapping(value = "startProcess")
+    McR startProcess(@RequestBody Map data,@RequestParam String code){
+        Map<String, Object> stringObjectMap = payService.startProcess(code, data);
+//        payService.testupload();
+        return McR.success(stringObjectMap);
+//        return McR.success();
+    }
+}

+ 69 - 0
mjava-gd/src/main/java/com/malk/guangdian/delegate/DDDelegate.java

@@ -0,0 +1,69 @@
+package com.malk.guangdian.delegate;
+
+import com.malk.guangdian.service.PayService;
+import com.malk.delegate.DDEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+/**
+ * OA审批事件 [主项目也有实现, 添加 @Primary 优先注入主项目实现]
+ * -
+ * 取消方案: 撤销和拒绝流程不继续执行连接器, 因此不使用连接器与轮询审批记录方案 [低效而且占用较高钉钉api调次数];
+ * 优化方案: 通过事件订阅实现实时同步所有审批状态, 定时查询钉钉回调失败记录 [配置钉钉事件Delegate, 添加定时任务]
+ */
+@Slf4j
+@Service
+@Primary
+public class DDDelegate implements DDEvent {
+
+    private static final String PAYMENT_CONTRACT = "PROC-DAB53435-D2A5-467F-910E-8AEEEFC4B0EA";
+    private static final String INCOME_CONTRACT = "PROC-8BD93A79-5907-4D59-82C7-F75AE6A79419";
+
+    @Autowired
+    PayService payService;
+    // 审批任务回调执行业务逻辑
+    @Async
+    @Override
+    public void executeEvent_Task_Finish(String processInstanceId, String processCode, boolean isAgree, String remark) {
+        log.info("executeEvent_Task_Finish");
+    }
+
+    @Async
+    @Override
+    public void executeEvent_Task_Start(String processInstanceId, String processCode) {
+        log.info("executeEvent_Task_Start");
+    }
+
+    @Async
+    @Override
+    public void executeEvent_Task_Redirect(String processInstanceId, String processCode) {
+        log.info("executeEvent_Task_Redirect");
+    }
+
+    @Async
+    @Override
+    public void executeEvent_Instance_Start(String processInstanceId, String processCode) {
+        log.info("executeEvent_Instance_Start");
+    }
+
+
+    // 审批实例回调执行业务逻辑
+    @Async
+    @Override
+    public void executeEvent_Instance_Finish(String processInstanceId, String processCode, boolean isAgree, boolean isTerminate, String staffId) {
+        log.info("executeEvent_Instance_Finish");
+        String approveResult = isAgree ? "agree" : "refuse";
+//        if (isTerminate) approveResult = "terminated";
+        if  (isAgree){
+            if (processCode.equals(PAYMENT_CONTRACT)){
+
+            } else if (processCode.equals(INCOME_CONTRACT)) {
+
+            }
+        }
+        log.info("审批实例回调执行业务逻辑, {}", approveResult);
+    }
+}

+ 63 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Income/fct_ar.java

@@ -0,0 +1,63 @@
+package com.malk.guangdian.entity.BIP.Income;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class fct_ar implements Serializable {
+    private static final long serialVersionUID = -8311118627395331518L;
+    private String actualinvalidate;	//否	实际终止日期
+    private String actualvalidate;	//否	实际生效日期
+    private String billmaker;	//否	制单人
+    private String blatest;	//否	是否最新版本
+    private String btriatradeflag;	//否	三角贸易
+    private String cbilltypecode;	//否	单据类型
+    private String ccurrencyid;	//否	本位币
+    private String corigcurrencyid;	//是	币种
+    private String cprojectid;	//否	项目
+    private String ctname;	//是	合同名称
+    private String ctrantypeid;	//否	合同类型
+    private String dbilldate;	//否	单据日期
+    private String dmakedate;	//否	制单日期
+    private String fstatusflag;	//否	合同状态
+    private String invallidate;	//否	计划终止日期
+    private String nexchangerate;	//是	折本汇率
+    private String nglobalexchgrate;	//否	全局本位币汇率
+    private String ngroupexchgrate;	//否	集团本位币汇率
+    private String norigcopamount;	//否	累计原币开票金额
+    private String norigplanamount;	//否	累计原币预收款金额
+    private String norigpshamount;	//否	累计原币收款金额
+    private String ntotalastnum;	//否	总数量
+    private String ntotalcopamount;	//否	累计本币开票金额
+    private String ntotalgpamount;	//否	累计本币收款金额
+    private String ntotalorigmny;	//是	原币价税合计
+    private String ntotaltaxmny;	//否	本币价税合计
+    private String organizer;	//是	承办组织
+    private String overrate;	//是	超合同收款比例
+    private String pk_customer; //	是	客户(传统一社会信用代码)
+    private String pk_fct_ar;	//否	收款合同主键
+    private String pk_group;	//否	集团
+    private String pk_org;	//是	财务组织
+    private String pk_org_v;	//否	财务组织版本
+    private String pk_payterm;	//否	收款协议
+    private String subscribedate;	//是	签字盖章日期
+    private String valdate;	//是	计划生效日期
+    private String vbillcode;	//是	合同编码
+    private String version;	//否	版本号
+    private String vtrantypecode;	//是	合同类型编码
+    private String openct;	//是	敞口合同
+    private String mountcalculation;	//否	计算
+    private String earlysign;	//否	期初标志
+    private String signorg;	//否	签字组织
+    private String Vallidate;	//是	计划终止日期
+    private String pk_ratetype;	//否	组织汇率类型
+    private String ratedate;	//否	组织汇率来源日期
+    private String personnelid;	//是	承办人员
+    private String depid;	//是	承办部门
+    private String bankaccount;	//是	本方银行账号
+    private List<fct_ar_b> fct_ar_b;//	否	Array	合同基本
+    private List<fct_ar_plan> fct_ar_plan; //收款计划
+
+}

+ 12 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Income/fct_ar_b.java

@@ -0,0 +1,12 @@
+package com.malk.guangdian.entity.BIP.Income;
+
+import lombok.Data;
+
+@Data
+public class fct_ar_b {
+    private String crowno;	//是	行号
+    private String inoutcome;	//否	收支项目
+    private String norigtaxmny;	//是	累计原币价税金额
+    private String ntaxmny;	//是	累计本币价税金额
+    private String pk_financeorg;	//是	财务组织
+}

+ 17 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Income/fct_ar_plan.java

@@ -0,0 +1,17 @@
+package com.malk.guangdian.entity.BIP.Income;
+
+import lombok.Data;
+
+@Data
+public class fct_ar_plan {
+   private String planrate;	//是	计划比例
+   private String begindate;	//是	起算日期
+   private String accountdate;	//是	账期天数
+   private String accountnum;	//是	账期号
+   private String enddate;	//是	计划到期日
+   private String planmoney;	//是	计划金额
+   private String receivetype;	//是	预收款
+   private String moneytype;	//是	收支项目
+   private String reymontype;	//是	收款类型
+   private String pk_financeorg;	//是	财务组织
+}

+ 59 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Payment/fct_ap.java

@@ -0,0 +1,59 @@
+package com.malk.guangdian.entity.BIP.Payment;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class fct_ap {
+    private String actualinvalidate;	//否	实际终止日期
+    private String actualvalidate;	//否	实际生效日期
+    private String billmaker;	//否	制单人
+    private String blatest;	//否	是否最新版本
+    private String btriatradeflag;	//否	三角贸易
+    private String cbilltypecode;	//否	单据类型
+    private String ccurrencyid;	//否	本位币
+    private String corigcurrencyid;	//是	币种
+    private String cprojectid;	//否	项目
+    private String ctname;	//是	合同名称
+    private String ctrantypeid;	//否	合同类型
+    private String dbilldate;	//否	单据日期
+    private String dmakedate;	//否	制单日期
+    private String fstatusflag;	//否	合同状态
+    private String nexchangerate;	//是	折本汇率
+    private String nglobalexchgrate;	//否	全局本位币汇率
+    private String ngroupexchgrate;	//否	集团本位币汇率
+    private String norigcopamount;	//否	累计原币开票金额
+    private String ntotalastnum;	//否	总数量
+    private String ntotalcopamount;	//否	累计本币开票金额
+    private String ntotalorigmny;	//是	原币价税合计
+    private String ntotaltaxmny;	//否	本币价税合计
+    private String organizer;	//是	承办组织
+    private String overrate;	//是	超合同收款比例
+    private String cvendorid;	//是	供应商(传统一社会信用代码)
+    private String pk_group;	//否	集团
+    private String pk_org;	//是	财务组织
+    private String pk_org_v;	//否	财务组织版本
+    private String pk_payterm;	//否	付款协议
+    private String subscribedate;	//是	签字盖章日期
+    private String valdate;	//是	计划生效日期
+    private String vbillcode;	//否	合同编码
+    private String version;	//否	版本号
+    private String vtrantypecode;	//是	合同类型编码
+    private String paymontype;	//是	付款类型
+    private String openct;	//是	敞口合同
+    private String mountcalculation;	//否	计算
+    private String earlysign;	//否	期初标志
+    private String invallidate;	//是	计划终止日期
+    private String signorg;	//是	签约组织
+    private String pk_ratetype;	//否	组织汇率类型
+    private String ratedate;	//否	组织汇率来源日期
+    private String vdef30;	//是	签约供应商
+    private String personnelid;	//是	承办人员
+    private String depid;	//是	承办部门
+    private String ourbankaccount;	//是	本方银行账号
+    private String bankaccount;	//是	收款银行账号
+    private String ctaxcodeid;	//是	税目
+    private List<fct_ap_b> fct_ap_b;	 //否	合同基本
+    private List<fct_ap_plan> fct_ap_plan;	//否	付款计划
+}

+ 12 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Payment/fct_ap_b.java

@@ -0,0 +1,12 @@
+package com.malk.guangdian.entity.BIP.Payment;
+
+public class fct_ap_b {
+    private String pk_financeorg;	//是	财务组织
+    private String crowno;	//是	行号
+    private String inoutcome;	//否	收支项目
+    private String norigtaxmny;	//是	累计原币价税金额
+    private String ntaxmny;	//是	累计本币价税金额
+    private String ntax;	//是	税额
+    private String norigtax;	//是	原币税额
+    private String norigmny;	//是	无税金额
+}

+ 13 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/BIP/Payment/fct_ap_plan.java

@@ -0,0 +1,13 @@
+package com.malk.guangdian.entity.BIP.Payment;
+
+public class fct_ap_plan {
+    private String pk_financeorg;	//是	财务组织
+    private String planrate;	//是	计划比例
+    private String begindate;	//是	起算日期
+    private String accountdate;	//是	账期
+    private String enddate;	//是	计划到期日
+    private String planmoney;	//是	计划金额
+    private String paytype;	//是	预付款
+    private String moneytype;	//是	收支项目
+    private String accountnum;	//是	账期号
+}

+ 11 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ContentDTO.java

@@ -0,0 +1,11 @@
+package com.malk.guangdian.entity.Content;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ContentDTO implements Serializable {
+    private static final long serialVersionUID = -8311118627395331518L;
+    private ZhiYuanVO ImportContractInfoRequest;//钉盘空间id
+}

+ 15 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ContentFile.java

@@ -0,0 +1,15 @@
+package com.malk.guangdian.entity.Content;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ContentFile implements Serializable {
+    private static final long serialVersionUID = -8311118627395331518L;
+    private String spaceId;//钉盘空间id
+    private String fileId;//钉盘文件id
+    private String fileName;//文件名
+    private String fileType;//文件种类
+    private String fileSize;//文件大小
+}

+ 15 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/Content/Parties.java

@@ -0,0 +1,15 @@
+package com.malk.guangdian.entity.Content;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+@Data
+public class Parties implements Serializable {
+    private static final long serialVersionUID = 4820142670157009063L;
+    private String name;//主体名称
+    private String responsiblePerson;//负责人
+
+
+}

+ 41 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ZhiYuanDTO.java

@@ -0,0 +1,41 @@
+package com.malk.guangdian.entity.Content;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class ZhiYuanDTO implements Serializable {
+    private static final long serialVersionUID = 4820142670157009063L;
+//    @NotBlank
+//    private String contractId;//合同编号
+    @NotBlank
+    private String contractName;//合同名称
+    @NotBlank
+    private String downloadUrl;//文件下载地址
+    @NotBlank
+    private String type;//文件下载地址
+//    @NotBlank
+//    private String amountType;//金额类型
+//    @NotBlank
+//    private String ownerStaffId;//所属人工号
+//    @NotBlank
+//    private String amount;//金额
+//    @NotBlank
+//    private String signTime;//签署时间Unix毫秒级时间戳
+//    @NotBlank
+//    private String ownerDeptNo;//所属人部门编号
+//    private String ownerDeptName;//所属人部门名称
+//    @NotBlank
+//    private String effectiveStatus;//履约状态
+//    @NotBlank
+//    private String startDate;//Unix毫秒级时间戳
+//    @NotBlank
+//    private String endDate;//Unix毫秒级时间戳
+//    private List<Parties> ourParties;//我方主体
+//    private List<Parties> otherParties;//他方主体
+
+
+}

+ 38 - 0
mjava-gd/src/main/java/com/malk/guangdian/entity/Content/ZhiYuanVO.java

@@ -0,0 +1,38 @@
+package com.malk.guangdian.entity.Content;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class ZhiYuanVO implements Serializable {
+    private static final long serialVersionUID = 4820142670157009063L;
+    @NotBlank
+    private String contractId;//合同编号
+    @NotBlank
+    private String contractName;//合同名称
+    @NotBlank
+    private String amountType;//金额类型
+    @NotBlank
+    private String ownerStaffId;//所属人工号
+    @NotBlank
+    private String amount;//金额
+    @NotBlank
+    private Long signTime;//签署时间Unix毫秒级时间戳
+    @NotBlank
+    private String ownerDeptNo;//所属人部门编号
+    private String ownerDeptName;//所属人部门名称
+    @NotBlank
+    private String effectiveStatus;//履约状态
+    @NotBlank
+    private String startDate;//Unix毫秒级时间戳
+    @NotBlank
+    private String endDate;//Unix毫秒级时间戳
+    private List<String> ourParties;//我方主体
+    private List<String> otherParties;//他方主体
+    private List<String> contentFiles;//他方主体
+
+
+}

+ 718 - 0
mjava-gd/src/main/java/com/malk/guangdian/service/Impl/PayServiceImpl.java

@@ -0,0 +1,718 @@
+package com.malk.guangdian.service.Impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.guangdian.entity.Content.ContentFile;
+import com.malk.guangdian.entity.Content.ZhiYuanDTO;
+import com.malk.guangdian.service.PayService;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.server.dingtalk.DDR_New;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Personnel;
+import com.malk.service.dingtalk.DDClient_Workflow;
+import com.malk.service.dingtalk.DDService;
+import com.malk.utils.UtilFile;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+@Slf4j
+public class PayServiceImpl implements PayService {
+
+    @Autowired
+    private DDClient ddClient;
+    @Autowired
+    private DDClient_Workflow ddClient_workflow;
+    @Autowired
+    private DDClient_Personnel ddClientPersonnel;
+    @Value(value = "${dingtalk.appKey}")
+    private String APP_EKY;
+    @Value(value = "${dingtalk.appSecret}")
+    private String APP_SECRET;
+    @Value(value = "${dingtalk.agentId}")
+    private Long agentId;
+    @Value(value = "${dingtalk.unionId}")
+    private String unionId;
+    @Value(value = "${dingtalk.spaceId}")
+    private String spaceId;
+    @Value(value = "${dingtalk.parentId}")
+    private String parentId;
+    @Value(value = "${saveFile.path}")
+    private String saveFilePath;
+    @Value(value = "${dingtalk.parentUuid}")
+    private String parentDentryUuid;
+    @Autowired
+    private DDConf ddConf;
+    @Autowired
+    DDService ddService;
+
+    @Autowired
+    private YDClient ydClient;
+
+    private static final String API_TOKEN = "/common/unAuth/tokens/generate";
+    private static final String POST_DATA_URL = "/common/document";
+    private static final String FIND_BY_CODES = "/common/users/v2/findByCodes";
+    private static final String FIND_COMPANY = "/common/departments/v2/findByCode";
+    private ConcurrentHashMap<String, LocalDateTime> tokenStore = new ConcurrentHashMap<>();
+    //出差类型枚举
+    private static final Map<String, String> BUSINESS_TYPE = new HashMap<>();
+
+    static {
+        BUSINESS_TYPE.put("境内", "01");
+        BUSINESS_TYPE.put("境外", "02");
+        BUSINESS_TYPE.put("短期培训", "03");
+    }
+    private static final Map<String, String> ATTACHMENT_ENUM = new HashMap<>();
+    static {
+        ATTACHMENT_ENUM.put("attachmentUrl","附件");
+        ATTACHMENT_ENUM.put("contractTextUrl","合同正文");
+        ATTACHMENT_ENUM.put("contractScanUrl","上传生效的合同扫描件");
+        ATTACHMENT_ENUM.put("contractPreApprovalFlow","合同前置审批流程");
+        ATTACHMENT_ENUM.put("procurementResult","oa请示、采购结果");
+        ATTACHMENT_ENUM.put("decisionDocument","决策文件、会议纪要、中标通知书等");
+    }
+    //所有的枚举
+    private static final Map<String, String> ALLENUM = new HashMap<>();
+
+    static {
+        //签署法人实体
+        ALLENUM.put("option_aoscience_bio_nantong_co_l__c", "澳斯康生物(南通)股份有限公司");
+        ALLENUM.put("option_gansu_jianshun_biotech_co__c", "甘肃健顺生物科技有限公司");
+        ALLENUM.put("option_jianshun_bio_tech_nantong__c", "健顺生物科技(南通)有限公司");
+        ALLENUM.put("option_shanghai_aoskang_bio_pharm__c", "上海澳斯康生物制药有限公司");
+        ALLENUM.put("option_shanghai_jianshiba_biotech__c", "上海健士拜生物科技有限公司");
+        ALLENUM.put("option_group_research_center__c", "集团研发中心");
+        ALLENUM.put("i5r85d5r8", "集团部门");
+        //区域
+        ALLENUM.put("option_international__c", "国际");
+        ALLENUM.put("cD2b3f", "国内");
+        //合同事宜
+        ALLENUM.put("x8luwTHo7", "合同签订");
+        ALLENUM.put("kptFZ7XFr", "合同变更");
+        ALLENUM.put("8D36ieItP", "合同解除");
+        //是否设计法人章、是否涉密
+        ALLENUM.put("option_yes__c", "是");
+        ALLENUM.put("option_no__c", "否");
+        //合同总价是否为固定金额、客户是否需求赔偿
+        ALLENUM.put("true", "是");
+        ALLENUM.put("false", "否");
+        //原币类型
+        ALLENUM.put("option_example_options__c", "欧元EUR");
+        ALLENUM.put("option_usd_currency__c", "美元USD");
+        ALLENUM.put("option_cny__c", "人民币CNY");
+        //是否加盖公章
+        ALLENUM.put("wSZ3tbp4m", "否");
+        ALLENUM.put("option1", "是");
+        //投诉等级
+        ALLENUM.put("option_B__c", "一般质量投诉");
+        ALLENUM.put("option_A__c", "重大质量投诉");
+        //申请类型
+        ALLENUM.put("1kRYAt2So", "细胞株");
+        ALLENUM.put("9V9fvk5j1", "原材料");
+        ALLENUM.put("5U6yt12hf", "耗材");
+        ALLENUM.put("evF26O4He", "产品");
+        ALLENUM.put("other", "其他");
+
+    }
+
+    //所有的枚举
+    private static final Map<String, String> AFTER_SALE = new HashMap<>();
+
+    static {
+        //售后管理
+        AFTER_SALE.put("option_example_options__c", "投诉处理(非质量投诉)");
+        AFTER_SALE.put("option_quality_complaint_handling__c", "投诉处理(质量投诉)");
+    }
+    /**
+     * 从Content-Disposition头获取文件名
+     */
+    private static String getFileNameFromConnection(HttpURLConnection connection) {
+        String contentDisposition = connection.getHeaderField("Content-Disposition");
+        if (contentDisposition != null) {
+            // 查找filename=后面的内容
+            String[] parts = contentDisposition.split(";");
+            for (String part : parts) {
+                if (part.trim().startsWith("filename=")) {
+                    String fileName = part.substring(part.indexOf('=') + 1).trim();
+                    // 去除引号并解码URL编码
+                    fileName = fileName.replace("\"", "");
+                    try {
+                        return URLDecoder.decode(fileName, StandardCharsets.UTF_8.name());
+                    } catch (UnsupportedEncodingException e) {
+                        return fileName;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    //下载宜搭附件
+    private String downloadFile(String fileURL, String contractName, String type, String savePath) throws IOException {
+        //若是宜搭附件url 则需获得附件临时免登地址
+//        fileURL = ydClient.convertTemporaryUrl(fileURL);
+
+        URL url = new URL(fileURL);
+        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
+        httpConn.setRequestMethod("GET");
+        httpConn.setInstanceFollowRedirects(true); // 强制跟随重定向(必加!)
+        httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
+        httpConn.setConnectTimeout(10000);
+        httpConn.setReadTimeout(20000);
+        httpConn.setDoInput(true);
+        httpConn.setDoOutput(false);
+        int responseCode = httpConn.getResponseCode();
+
+        // 获取文件名
+//        String fileName = getFileNameFromConnection(httpConn);
+        String fileName = contractName + "." + type;
+        // 检查HTTP响应代码是否为200
+        if (responseCode == HttpURLConnection.HTTP_OK) {
+            InputStream inputStream = httpConn.getInputStream();
+            FileOutputStream outputStream = new FileOutputStream(savePath + fileName);
+
+            byte[] buffer = new byte[8192];
+            int bytesRead = -1;
+
+            while ((bytesRead = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, bytesRead);
+            }
+
+            outputStream.close();
+            inputStream.close();
+        } else {
+            System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
+        }
+        httpConn.disconnect();
+        return fileName;
+    }
+
+    /**
+     * 上传文件至钉盘
+     * @param filePath 文件存储地址
+     * @param conflictStrategy 覆盖或其他上传方式
+     * @return
+     */
+    private Map uploadToDingTalk(String filePath,String conflictStrategy) {
+        //获取当前时间戳
+        long beginTimestamp = System.currentTimeMillis();
+        System.out.println("开始上传附件:" + DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));
+
+        //文件
+        File file = new File(filePath);
+
+        //获取文件上传信息
+        Map param = new HashMap();
+        param.put("unionId",unionId);
+        Map body = new HashMap();
+        body.put("protocol","HEADER_SIGNATURE");
+        body.put("multipart",false);
+
+        DDR_New ddr = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + spaceId + "/files/uploadInfos/query", ddConf.initTokenHeader(ddClient.getAccessToken()), param, body, DDR_New.class);
+        String uploadKey = ddr.getUploadKey();
+        Map headerSignatureInfo = ddr.getHeaderSignatureInfo();
+        Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
+        List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
+        String resourceUrl = resourceUrls.get(0);
+
+        Map dentry = new HashMap();
+        //使用OSS的header加签方式上传文件
+        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(file);
+            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("上传失败");
+            }
+            //提交文件
+            Map body2 = new HashMap();
+            Map option = new HashMap();
+            option.put("conflictStrategy",conflictStrategy);
+            body2.put("uploadKey",uploadKey);
+            body2.put("name",file.getName());
+            body2.put("option",option);
+            DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/files/"+parentDentryUuid+"/commit", ddClient.initTokenHeader(), param, body2, DDR_New.class);
+            dentry = ddrNew.getDentry();
+
+        }catch (IOException e){
+            log.info("上传文件异常:{}",e);
+        }
+
+        long endTimestamp = System.currentTimeMillis();
+        System.out.println("上传文件结束:" + DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
+        System.out.println("上传文件耗时:" + (endTimestamp - beginTimestamp)/1000.0 + "s");
+        return dentry;
+    }
+
+    private Map<String, Object> convert(Object object) throws Exception {
+        Map<String, Object> map = new HashMap<>();
+        Class<?> clazz = object.getClass();
+        for (Field field : clazz.getDeclaredFields()) {
+            field.setAccessible(true);
+            String value = field.get(object) != null ? field.get(object).toString() : "";
+            map.put(field.getName(), value);
+        }
+        return map;
+    }
+
+    @Override
+    public void testGet(String filePath,String parentId,String conflictStrategy) {
+    }
+
+    @Override
+    public String createContract(ZhiYuanDTO zhiYuanDTO) throws Exception {
+        String downloadUrl = zhiYuanDTO.getDownloadUrl();
+        List<Map<String, Object>> resultList = new ArrayList<>();
+
+        List<ContentFile> contentFileList = new ArrayList<>();
+        List<Map> formValue = new ArrayList<>();
+        //遍历入参所有文件下载地址进行下载文件
+//        downloadUrls.forEach(e->{
+/*        String fileName = null;
+        try {
+            fileName = downloadFile(downloadUrl, zhiYuanDTO.getContractName(), zhiYuanDTO.getType(), saveFilePath);
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }*/
+/*        Map overwrite = uploadToDingTalk(saveFilePath + fileName, "OVERWRITE");
+        log.info("附件回参:{}",overwrite);
+        ContentFile contentFile = new ContentFile();
+        contentFile.setSpaceId(spaceId);
+        contentFile.setFileId(overwrite.get("uuid").toString());
+        contentFile.setFileName(fileName);
+        contentFile.setFileType(overwrite.get("extension").toString());
+        contentFile.setFileSize(overwrite.get("size").toString());
+
+        contentFileList.add(contentFile);*/
+        Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), "603864663125953014", downloadUrl, zhiYuanDTO.getContractName(), zhiYuanDTO.getType());
+        Map<String, Object> result = UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(map, "spaceId"), zhiYuanDTO.getContractName(),
+                UtilMap.getString(map, "size"), UtilMap.getString(map, "extension"), UtilMap.getString(map, "id"));
+        resultList.add(result);
+        formValue.add(UtilMap.map("name, value","合同正文",JSON.toJSONString(resultList)));
+        List<Object> objects = new ArrayList<>();
+        formValue.add(UtilMap.map("name, value","合同名称, 测试合同"));
+        formValue.add(UtilMap.map("name, value","合同期限类型, 固定期限"));
+        formValue.add(UtilMap.map("name, value","签署方式, 纸质签署"));
+        formValue.add(UtilMap.map("name, value","金额类型, 无金额"));
+//        formValue.add(UtilMap.map("name, value","合同名称, 测试接口"));
+        formValue.add(UtilMap.map("name, value","合同编号生成方式, 选择已有合同编号"));
+        formValue.add(UtilMap.map("name, value","合同编号规则, 测试合同编号"));
+        Map<String, String> map11 = UtilMap.map("name, value, bizAlias", "我方主体名称, 待补充, contract_mine_company_name");
+        Map<String, String> map12 = UtilMap.map("name, value", "我方负责人, 待补充");
+        List<Map<String,String>> mapList1 = new ArrayList<>();
+        mapList1.add(map11);
+        mapList1.add(map12);
+        objects.add(mapList1);
+        formValue.add(UtilMap.map("name, value","我方信息",JSON.toJSONString(objects)));
+
+        objects.clear();
+
+        Map<String, String> map21 = UtilMap.map("name, value, bizAlias", "对方主体名称, 待补充, contract_opposite_company_name");
+        Map<String, String> map22 = UtilMap.map("name, value", "对方负责人, 待补充");
+        List<Map<String,String>> mapList2 = new ArrayList<>();
+        mapList2.add(map21);
+        mapList2.add(map22);
+        objects.add(mapList2);
+        formValue.add(UtilMap.map("name, value","对方信息",JSON.toJSONString(objects)));
+
+        List<String> workingEmployeeIds = new ArrayList<>();
+        workingEmployeeIds.add("603864663125953014");
+        List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
+
+//        formValue.add(UtilMap.map("name, value","我方信息, [[{\"name\":\"我方主体名称\",\"value\":\"测试我方主体名称1\",\"bizAlias\":\"contract mine company_name\"},{\"name\":\"我方负责人\",\"value\":\"林晔1\"}]]"));
+//        formValue.add(UtilMap.map("name, value","对方信息, [[\"name\":\"对方主体名称\",\"value\":\"测试对方主体名称1\",\"bizAlias\":\"contract opposite company name\"},{\"name\":\"对方负责人\",\"value\":\"方1\"}]]"));
+//        PROC-B5E48D42-87FA-4C4E-9CD8-9178EEF1F0D3
+//        PROC-51DCBCDA-1F51-4C5A-80E7-FFDDACEAD6A9
+        ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), "603864663125953014", "PROC-B5E48D42-87FA-4C4E-9CD8-9178EEF1F0D3", formValue, deptIdByUserId.get(0));
+//        });
+        return null;
+    }
+    /**
+     * 获取钉钉员工手机号
+     * @param workingEmployeeIds 钉钉人员id
+     * @return
+     */
+    public List<String> getDeptIdByUserId(List<String> workingEmployeeIds) {
+        log.info("根据钉钉人员id获取员工部门id:{}",workingEmployeeIds.toString());
+        List<String> filterList = new ArrayList<>();
+        filterList.add("sys00-mainDeptId");
+        List<Map> employeeInfos = ddClientPersonnel.getEmployeeInfos(ddClient.getAccessToken(), workingEmployeeIds, agentId, filterList);
+        List<String> personList = new ArrayList<>();
+        employeeInfos.forEach(e -> {
+            List<Map> mapList = (List<Map>) e.get("field_data_list");
+            mapList.forEach(m -> {
+                List<Map> valueList = (List<Map>) m.get("field_value_list");
+                String value = valueList.get(0).get("value").toString();
+                personList.add(value);
+            });
+        });
+        return personList;
+    }
+
+    @Override
+    public void testupload() {
+        uploadToDingTalk(saveFilePath  + "合印强制验收.jpg","OVERWRITE");
+    }
+
+    @Override
+    public Map<String, Object> startProcessContract(String code, Map data) {
+        Map overwrite = uploadToDingTalk(saveFilePath + "合印强制验收.jpg", "OVERWRITE");
+        System.out.println(overwrite);
+        List<Map> formValue = new ArrayList<>();
+        log.info("code:{} ",code);
+        formValue.add(UtilMap.map("name, value","合同名称, 测试合同"));
+        formValue.add(UtilMap.map("name, value","合同期限类型, 固定期限"));
+        formValue.add(UtilMap.map("name, value","签署方式, 纸质签署"));
+        formValue.add(UtilMap.map("name, value","金额类型, 收入"));
+        formValue.add(UtilMap.map("name, value","合同正文",overwrite));
+        formValue.add(UtilMap.map("name, value","我方信息, [[{\"name\":\"我方主体名称\",\"value\":\"测试我方主体名称1\",\"bizAlias\":\"contract mine company_name\"},{\"name\":\"我方负责人\",\"value\":\"林晔1\"}]]"));
+        formValue.add(UtilMap.map("name, value","对方信息, [[\"name\":\"对方主体名称\",\"value\":\"测试对方主体名称1\",\"bizAlias\":\"contract opposite company name\"},{\"name\":\"对方负责人\",\"value\":\"方1\"}]]"));
+        List<String> workingEmployeeIds = new ArrayList<>();
+        workingEmployeeIds.add("603864663125953014");
+        List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
+        ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), "603864663125953014", "PROC-51DCBCDA-1F51-4C5A-80E7-FFDDACEAD6A9", formValue, deptIdByUserId.get(0));
+        return null;
+    }
+
+    @Override
+    public void sendToU8Payment(String processInstanceId) {
+        log.info("开始向用友推送付款合同台账");
+        String token = ddClient.getAccessToken(APP_EKY, APP_SECRET);
+        Map processData = ddClient_workflow.getProcessInstanceId(token, processInstanceId);
+
+    }
+
+    @Override
+    public void sendToU8Income(String processInstanceId) {
+        log.info("开始向用友推送收款合同台账");
+        String token = ddClient.getAccessToken(APP_EKY, APP_SECRET);
+        Map processData = ddClient_workflow.getProcessInstanceId(token, processInstanceId);
+    }
+
+    private Map MATE;
+
+    /**
+     * 加载json
+     */
+    private Map _getMeta() {
+        if (ObjectUtil.isNull(MATE)) {
+            MATE = (Map) UtilFile.readJsonObjectFromResource("json/form.json"); // 本地匹配宜搭组件ID
+//            MATE = (Map) UtilFile.readJsonObjectFromResource("static/json/formtest.json"); // 本地匹配宜搭组件ID
+        }
+        return MATE;
+    }
+    /**
+     * 整合传参数据为OA审批 name - value 数据格式
+     * @param code 单据类型
+     * @param data 传参
+     * @param meta json
+     * @param formValue OA审批数据格式
+     */
+    private void IntegrationData(String code, Map data, Map meta, List<Map> formValue) {
+        log.info("开始处理接口参数数据转为OA审批接口数据格式");
+        //json数据列
+        Map<String, ?> component = (Map) ((Map) meta.get(code)).get("compIds");
+        for (String key : component.keySet()) {
+            Map formData = UtilMap.empty();
+            if (key.startsWith("tableField_")) {
+                String[] split = key.split("_");
+                List<Map> rows = UtilMap.getList(data,split[1]);
+                List<List<Map>> lastList = new ArrayList<>();
+                Map<String, String> compIds = (Map) component.get(key);
+                if (rows.size() > 0 ){
+                    for (Map row : rows) {
+                        List<Map> details = new ArrayList<>();
+                        for (String prop : compIds.keySet()) {
+                            Map detail = UtilMap.empty();
+                            detail.put("value", row.get(compIds.get(prop)));
+                            detail.put("name", prop);
+                            if (prop.contains("我方主体名称")){
+                                detail.put("bizAlias","contract_mine_company_name");
+                            } else if (prop.contains("对方主体名称")) {
+                                detail.put("bizAlias","contract_opposite_company_name");
+                            }
+                            details.add(detail);
+                        }
+                        lastList.add(details);
+                    }
+                    formData.put( "value", JSON.toJSONString(lastList));
+                    formData.put( "name",((Map) meta.get(code)).get(split[1]).toString());
+                }else {
+                    List<Map> details = new ArrayList<>();
+                    for (String prop : compIds.keySet()) {
+                        Map detail = UtilMap.empty();
+                        if ("quantity".equals(compIds.get(prop))){
+                            detail.put("value", "0");
+                            detail.put("name", prop);
+                        }else {
+                            detail.put("value", "无");
+                            detail.put("name", prop);
+                        }
+                        details.add(detail);
+                    }
+                    lastList.add(details);
+                    formData.put( "value", JSON.toJSONString(lastList));
+                    formData.put( "name",((Map) meta.get(code)).get(split[1]).toString());
+                }
+            } else {
+                if (data.containsKey(component.get(key))){
+                    if (ObjectUtil.isNotNull(data.get(component.get(key)))){
+                        Object value = data.get(component.get(key));
+                        formData.put("name", key);
+                        formData.put("value",value.toString());
+                        if ("RelatedReceipt".equals(component.get(key))){
+                            List<String> ids = new ArrayList<>();
+                            ids.add(value.toString());
+                            formData.put("name", key);
+                            formData.put("value",JSON.toJSONString(ids));
+                        }
+                        if (ALLENUM.containsKey(value.toString())){
+                            formData.put("value",ALLENUM.get(value.toString()));
+                        }
+                        if (AFTER_SALE.containsKey(value.toString()) && "KS".equals(code) && "售后管理".equals(key)) {
+                            formData.put("value",AFTER_SALE.get(value.toString()));
+                        }
+                    }
+                }
+            }
+            if (formData.size()>0){
+                formValue.add(formData);
+            }
+        }
+        final String[] token = {""};
+        final boolean[] isHave = {false};
+        ATTACHMENT_ENUM.forEach((k,v)->{
+            if (data.containsKey(k) && hasValid(data,k)){
+                tokenStore.forEach((k1, v1) -> {
+                    if (validateToken(k1)) {
+                        token[0] = k1;
+                        isHave[0] = true;
+                    }
+                });
+                if (!isHave[0]) {
+                    token[0] = getOAToken();
+                }
+                log.info("开始处理附件上传");
+                List<Map> attachment = (List<Map>) data.get(k);
+                List<Map<String, Object>> resultList = new ArrayList<>();
+                attachment.forEach(e->{
+                    String[] split = UtilMap.getString(e, "name").split("\\.");
+                    String fileName = split[0];
+                    if (split.length > 2){
+                        for (int i = 1; i < split.length -1; i++) {
+                            fileName = fileName + "." + split[i];
+                        }
+                    }
+                    String fileType = split[split.length-1];
+                    Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), "603864663125953014", e.get("downloadUrl").toString() + "?token=" + token[0], fileName, fileType);
+//                    Map map = ddService.uploadFileFormUrlForOverflow(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), e.get("downloadUrl").toString() + "?token=" + token[0], fileName, fileType);
+                    Map<String, Object> result = UtilMap.map("spaceId, fileName, fileSize, fileType, fileId", UtilMap.getString(map, "spaceId"), fileName,
+                            UtilMap.getString(map, "size"), UtilMap.getString(map, "extension"), UtilMap.getString(map, "id"));
+                    resultList.add(result);
+                });
+                formValue.add(UtilMap.map("name, value",v,JSON.toJSONString(resultList)));
+            }
+        });
+
+    }
+    /**
+     * 整合传参及OA数据格式
+     * @param code 单据类型
+     * @param data 传参
+     * @return 流程实例id
+     */
+    private String dataProcessing(String code, Map data){
+        //加载json映射
+        Map meta = _getMeta();
+        //表单字段映射
+        List<Map> formValue = new ArrayList<>();
+        log.info("code:{} ",code);
+        IntegrationData(code, data, meta, formValue);
+        List<String> workingEmployeeIds = new ArrayList<>();
+        workingEmployeeIds.add(data.get(((Map) meta.get(code)).get("creator")).toString());
+        List<String> deptIdByUserId = getDeptIdByUserId(workingEmployeeIds);
+        if (code.startsWith("HTSPD")){
+            formValue.add(UtilMap.map("name, value","发起部门",deptIdByUserId.get(0)));
+            formValue.add(UtilMap.map("name, value","合同编号生成方式, 选择已有合同编号"));
+//            formValue.add(UtilMap.map("name, value","合同编号规则, 测试合同编号"));
+            return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(),((Map) meta.get(code)).get("processCode").toString(), formValue, deptIdByUserId.get(0));
+//            return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), "PROC-B5E48D42-87FA-4C4E-9CD8-9178EEF1F0D3", formValue, deptIdByUserId.get(0));
+        }
+        return ddClient_workflow.doProcessInstancesNew(ddClient.getAccessToken(), data.get(((Map) meta.get(code)).get("creator")).toString(), ((Map) meta.get(code)).get("processCode").toString(), formValue, deptIdByUserId.get(0));
+//        return code;
+    }
+
+    /**
+     * 发起流程审批
+     * @param code
+     * @param data
+     * @return 流程实例id和地址
+     */
+    @Override
+    public Map<String, Object> startProcess(String code, Map data) {
+        String instanceId = dataProcessing(code, data);
+        JSONObject jsonObject = JSONObject.parseObject(instanceId);
+        if (!ObjectUtil.isNotNull(jsonObject.get("instanceId"))){
+            return UtilMap.map("ddProcessId, dtUrl, reqMsg",  jsonObject.get("instanceId"), "error", instanceId);
+        }
+        String url = "https://applink.dingtalk.com/approval/detail?corpId=ding226da4276814d290a1320dcb25e91351&instanceId=" + jsonObject.get("instanceId");
+        return UtilMap.map("ddProcessId, dtUrl, reqMsg",  jsonObject.get("instanceId"),  url, instanceId);
+    }
+
+    /**
+     * object附件判空
+     * @param data
+     * @param key
+     * @return
+     */
+    public boolean hasValid(Map data,String key) {
+
+        Object flowObj = data.get(key);
+        if (ObjectUtil.isNull(flowObj)) {
+            return false;
+        }
+        if (!(flowObj instanceof List)) {
+            return false;
+        }
+        List<?> flowList = (List<?>) flowObj;
+        if (flowList.isEmpty()) {
+            return false;
+        }
+        for (Object item : flowList) {
+            if (item instanceof Map) {
+                Map<?, ?> itemMap = (Map<?, ?>) item;
+                Object url = itemMap.get("downloadUrl");
+                if (url != null && !url.toString().trim().isEmpty()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String getOAToken(){
+        String urlStr = "https://oa.cbyun.com.cn/seeyon/rest/token";
+        String jsonInput = "{\"userName\":\"restDing\",\"password\":\"507228d7-8768-4a2d-a1c3-5b49af9b30de\"}";
+
+        HttpURLConnection connection = null;
+        try {
+            // 1. 创建连接
+            URL url = new URL(urlStr);
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty("Content-Type", "application/json");
+            connection.setDoOutput(true); // 允许输出
+            connection.setDoInput(true);  // 允许输入
+            connection.setConnectTimeout(5000);
+            connection.setReadTimeout(5000);
+
+            // 2. 写入请求体
+            try (OutputStream os = connection.getOutputStream()) {
+                byte[] input = jsonInput.getBytes(StandardCharsets.UTF_8);
+                os.write(input, 0, input.length);
+            }
+
+            // 3. 获取响应码
+            int responseCode = connection.getResponseCode();
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                // 4. 读取响应内容
+                StringBuilder response = new StringBuilder();
+                try (BufferedReader br = new BufferedReader(
+                        new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
+                    String line;
+                    while ((line = br.readLine()) != null) {
+                        response.append(line);
+                    }
+                }
+                String jsonResponse = response.toString();
+                System.out.println("响应原始内容: " + jsonResponse);
+                JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
+
+                // 5. 解析 id 字段(手动提取,避免依赖 JSON 库)
+                String id = jsonObject.getString("id");
+                if (id != null) {
+                    log.info("获取到的 id:{} ",id);
+                    addToken(id, 14);
+                    return id;
+                } else {
+                    log.info("未找到 id 字段");
+                    return null;
+                }
+            } else {
+               log.error("请求失败,HTTP 状态码:{} " , responseCode);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * token存储
+     * @param token
+     * @param expireMinutes
+     */
+    public void addToken(String token, int expireMinutes) {
+        LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(expireMinutes);
+        tokenStore.put(token, expirationTime);
+    }
+
+    /**
+     * 清理过期token
+     * @param token
+     * @return
+     */
+    public boolean validateToken(String token) {
+        LocalDateTime expirationTime = tokenStore.get(token);
+        if (expirationTime == null || expirationTime.isBefore(LocalDateTime.now())) {
+            tokenStore.remove(token); // 清理过期 Token
+            return false;
+        }
+        return true;
+    }
+}

+ 43 - 0
mjava-gd/src/main/java/com/malk/guangdian/service/PayService.java

@@ -0,0 +1,43 @@
+package com.malk.guangdian.service;
+
+import com.malk.guangdian.entity.BIP.Income.fct_ar;
+import com.malk.guangdian.entity.BIP.Payment.fct_ap;
+import com.malk.guangdian.entity.Content.ZhiYuanDTO;
+import com.malk.server.common.McR;
+
+import java.util.Map;
+
+public interface PayService {
+
+    void testGet(String filePath,String parentId,String conflictStrategy);
+
+    /**
+     * 创建智能合同台账
+     */
+    String createContract(ZhiYuanDTO zhiYuanDTO) throws Exception;
+
+
+    void testupload();
+
+
+    /**
+     * 通用流程发起
+     */
+    Map<String, Object> startProcess(String code, Map data);
+
+    Map<String, Object> startProcessContract(String code, Map data);
+
+    /**
+     * 推送用友付款合同
+     * @param processInstanceId
+     */
+    void sendToU8Payment(String processInstanceId);
+
+    /**
+     * 推送用友收款合同
+     * @param processInstanceId
+     */
+    void sendToU8Income(String processInstanceId);
+
+    String getOAToken();
+}

+ 57 - 0
mjava-gd/src/main/resources/application-dev.yml

@@ -0,0 +1,57 @@
+# 环境配置
+server:
+  port: 8108
+  servlet:
+    context-path: /api/guangdian
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: test
+    password: test123
+    url: jdbc:mysql://47.110.74.198:3306?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    hibernate:
+      ddl-auto: none      # JPA对表没有任何操作
+    show-sql: true
+    database: MYSQL
+    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+# filepath
+#file:
+#  path:
+#    file: /Users/malk/server/_Tool/var/mjava/tmp/file/
+#    image: /Users/malk/server/_Tool/var/mjava/tmp/image/
+#    tmp: /Users/malk/server/_Tool/var/mjava/tmp/
+#  source:
+#    fonts: /Users/malk/server/_Tool/fonts/simsun.ttc
+#logging:
+#  file:
+#    path: /Users/malk/server/_Tool/var/mjava/log
+
+# dingtalk
+dingtalk:
+  agentId: 4001069821
+  appKey: dingyfonlp1uc4zfrrqu
+  appSecret: h-ppTpBZpOgBY3OVQQIJJmaCNvCT-2bjQPgm9NnOqjYH0n_tkSJlVmbu44tJ7FJr
+  corpId:
+  aesKey:
+  token:
+  unionId: ut05hb7w9kxwTKt7iSNabvgiEiE #测试unionid
+  spaceId: 851452912 #钉盘-团队文件-全员文件夹
+  operator: ""   # OA管理员账号
+  parentId: 194258821321
+  parentUuid: XPwkYGxZV3Nqqzp2IlrdvGXmWAgozOKL
+
+saveFile:
+  path: C:\Users\86137\Desktop\
+
+

+ 48 - 0
mjava-gd/src/main/resources/application-prod.yml

@@ -0,0 +1,48 @@
+# 环境配置
+server:
+  port: 8111
+  servlet:
+    context-path: /api/guangdian
+
+# condition
+spel:
+  scheduling: true        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: test
+    password: test123
+    url: jdbc:mysql://47.110.74.198:3306?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#    url: jdbc:mysql://127.0.0.1:3306?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#  jpa:
+#    hibernate:
+#      ddl-auto: none      # JPA对表没有任何操作
+#    show-sql: true
+#    database: MYSQL
+#    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+# dingtalk
+dingtalk:
+  agentId: 4001069821
+  appKey: dingyfonlp1uc4zfrrqu
+  appSecret: h-ppTpBZpOgBY3OVQQIJJmaCNvCT-2bjQPgm9NnOqjYH0n_tkSJlVmbu44tJ7FJr
+  corpId:
+  aesKey:
+  token:
+  unionId: ut05hb7w9kxwTKt7iSNabvgiEiE #测试unionid
+  spaceId: 851452912 #钉盘-团队文件-全员文件夹
+  operator: ""   # OA管理员账号
+  parentId: 194258821321
+  parentUuid: XPwkYGxZV3Nqqzp2IlrdvGXmWAgozOKL
+saveFile:
+  path: /home/server/guangdian/file/
+
+# aliwork
+#aliwork:
+#  appType: "APP_LNBUWW7ZBXRUWE29PCOV"
+#  systemToken: "WC866ZA1PI1B2L1JDNL334F44KI03GREIV1ILZ13"

+ 152 - 0
mjava-gd/src/main/resources/json/form.json

@@ -0,0 +1,152 @@
+{
+  "NSWBD": {
+    "processCode": "PROC-4685C389-FF2B-4FE2-A802-FEBB7BB9CDDE",
+    "creator": "proposerCode",
+    "attachmentUrl": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "compIds": {
+      "时间": "time",
+      "收文号": "receiveNo",
+      "紧急程度": "urgencyLevel",
+      "办文人员": "handler",
+      "批文部门": "approveDept",
+      "文件标题": "fileTitle",
+      "董事长批示": "chairmanComment",
+      "总经理批示": "managerComment",
+      "相关分管领导批示": "deputyLeaderComment",
+      "拟文部门签批": "draftDeptApproval",
+      "相关部门意见": "relatedDeptOpinion",
+      "备注": "remark"
+    }
+  },
+  "HTSPD-JT": {
+    "processCode": "PROC-7C20FBC6-5C55-41C5-8786-08DEAF6E2050",
+    "creator": "proposerCode",
+    "contractTextUrl": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "contractScanUrl": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "contractPreApprovalFlow": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "ourPartyInfo": "我方信息",
+    "counterpartyInfo": "对方信息",
+    "compIds": {
+      "发起人": "proposerName",
+      "日期": "date",
+      "合同文本预审": "contractTextPreliminaryReview",
+      "合同预审流程": "contractPreliminaryReviewFlow",
+      "合同名称": "contractName",
+      "金额类型": "amountType",
+      "合同总额(元)": "contractTotalAmount",
+      "发起方式": "initiateMethod",
+      "合同期限类型": "contractTermType",
+      "tableField_ourPartyInfo": {
+        "我方主体名称": "ourPartySubjectName"
+      },
+      "合同正文": "contractMainText",
+      "tableField_counterpartyInfo": {
+        "对方主体名称": "counterpartySubjectName"
+      },
+      "签署方式": "signMethod",
+      "是否涉及其他相关部门": "isInvolveOtherDepts",
+      "是否需王旭协同": "isNeedLandCoordination",
+      "请选择该合同的审批人": "contractApprover"
+    }
+  },
+  "HTSPD-YD": {
+    "processCode": "PROC-4BE72E7B-2862-4803-8CAD-BD2BB69C77A4",
+    "creator": "proposerCode",
+    "ourPartyInfo": "我方信息",
+    "counterpartyInfo": "对方信息",
+    "compIds": {
+      "发起人": "proposerName",
+      "合同类型": "contractType",
+      "其他合同类型": "otherContractType",
+      "合同文本预审": "contractTextPreReview",
+      "是否关联其他部门审批": "isRelateOtherDeptApproval",
+      "合同名称": "contractName",
+      "金额类型": "amountType",
+      "合同总额(元)": "contractTotalAmount",
+      "发起方式": "initiateMethod",
+      "合同期限类型": "contractTermType",
+      "合同说明": "contractRemark",
+      "tableField_ourPartyInfo": {
+        "我方主体名称": "ourPartySubjectName"
+      },
+      "合同正文": "contractMainText",
+      "tableField_counterpartyInfo": {
+        "对方主体名称": "counterpartySubjectName"
+      },
+      "签署方式": "signMethod",
+      "印章类型": "sealType",
+      "风险告知同意并勾选1": "riskTypeAgreementCheck1",
+      "风险告知1": "riskNotification1",
+      "风险告知同意并勾选2": "riskTypeAgreementCheck2",
+      "风险告知2": "riskNotification2"
+    }
+  },
+  "HTSPD-GF": {
+  "processCode": "PROC-5CF4FE9C-96F6-42BF-876B-ADA383356808",
+  "creator": "proposerCode",
+  "contractTextUrl": {
+    "downloadUrl": "downloadUrl",
+    "name": "name"
+  },
+  "contractScanUrl": {
+    "downloadUrl": "downloadUrl",
+    "name": "name"
+  },
+  "contractPreApprovalFlow": {
+    "downloadUrl": "downloadUrl",
+    "name": "name"
+  },
+  "ourPartyInfo": "我方信息",
+  "counterpartyInfo": "对方信息",
+  "compIds": {
+    "发起人": "proposerName",
+    "合同名称": "contractName",
+    "金额类型": "amountType",
+    "合同总额(元)": "contractTotalAmount",
+    "发起方式": "initiateMethod",
+    "合同期限类型": "contractTermType",
+    "签署方式": "signMethod",
+    "tableField_ourPartyInfo": {
+      "我方主体名称": "ourPartySubjectName"
+    },
+    "合同正文": "contractMainText",
+    "tableField_counterpartyInfo": {
+      "对方主体名称": "counterpartySubjectName"
+    },
+    "合同前置审批": "frontApproval",
+    "oa请示、采购结果": "procurementResult",
+    "决策文件、会议纪要、中标通知书等": "decisionDocument",
+    "合同是否需要审核": "isReview",
+    "政企类合同金额(元)": "governmentAmt",
+    "市场经营支出类合同金额(元)": "marketOperationAmt",
+    "综合服务合同金额(元)": "integratedServicesAmt",
+    "采购类合同金额(元)": "buyAmt",
+    "借款合同金额(元)": "loanAmt",
+    "对外投资项目类别": "outProjectType",
+    "战略合同项目类别": "strategyProjectType",
+    "非结构性存款类(固定资产/股权等)金额(元)": "nonStructuralAmt",
+    "结构性存款等合同金额(元)": "structuralAmt",
+    "融资担保合同金额(元)": "financingAmt",
+    "一般战略合同金额(元)": "generalStrategyAmt",
+    "赞助捐赠合同金额(元)": "sponsorshipAmt",
+    "其他合同金额(元)": "otherContractAmt",
+    "其他合同类型": "otherContractType",
+    "风险告知同意并勾选": "riskTypeAgreementCheck",
+    "风险告知": "riskNotification",
+    "合同文本预审": "contractTextPreReview",
+    "合同类型": "contractType"
+  }
+}
+}

+ 151 - 0
mjava-gd/src/main/resources/json/formtest.json

@@ -0,0 +1,151 @@
+{
+  "NSWBD": {
+    "processCode": "PROC-4685C389-FF2B-4FE2-A802-FEBB7BB9CDDE",
+    "creator": "proposerCode",
+    "attachmentUrl": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "compIds": {
+      "时间": "time",
+      "收文号": "receiveNo",
+      "紧急程度": "urgencyLevel",
+      "办文人员": "handler",
+      "批文部门": "approveDept",
+      "文件标题": "fileTitle",
+      "董事长批示": "chairmanComment",
+      "总经理批示": "managerComment",
+      "相关分管领导批示": "deputyLeaderComment",
+      "拟文部门签批": "draftDeptApproval",
+      "相关部门意见": "relatedDeptOpinion",
+      "备注": "remark"
+    }
+  },
+  "HTSPD-JT": {
+    "processCode": "PROC-7C20FBC6-5C55-41C5-8786-08DEAF6E2050",
+    "creator": "proposerCode",
+    "contractTextUrl": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "contractScanUrl": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "contractPreApprovalFlow": {
+      "downloadUrl": "downloadUrl",
+      "name": "name"
+    },
+    "ourPartyInfo": "我方信息",
+    "counterpartyInfo": "对方信息",
+    "compIds": {
+      "发起人": "proposerCode",
+      "日期": "date",
+      "合同文本预审": "contractTextPreliminaryReview",
+      "合同预审流程": "contractPreliminaryReviewFlow",
+      "合同名称": "contractName",
+      "金额类型": "amountType",
+      "合同总额(元)": "contractTotalAmount",
+      "发起方式": "initiateMethod",
+      "合同期限类型": "contractTermType",
+      "tableField_ourPartyInfo": {
+        "我方主体名称": "ourPartySubjectName"
+      },
+      "合同正文": "contractMainText",
+      "tableField_counterpartyInfo": {
+        "对方主体名称": "counterpartySubjectName"
+      },
+      "签署方式": "signMethod",
+      "是否涉及其他相关部门": "isInvolveOtherDepts",
+      "是否需王旭协同": "isNeedLandCoordination",
+      "请选择该合同的审批人": "contractApprover"
+    }
+  },
+  "HTSPD-YD": {
+    "processCode": "PROC-7C20FBC6-5C55-41C5-8786-08DEAF6E2050",
+    "creator": "proposerCode",
+    "ourPartyInfo": "我方信息",
+    "counterpartyInfo": "对方信息",
+    "paymentPlan": "账款计划",
+    "compIds": {
+      "发起人": "proposerCode",
+      "合同类型": "contractType",
+      "其他合同类型": "otherContractType",
+      "合同文本预审": "contractTextPreReview",
+      "是否关联其他部门审批": "isRelateOtherDeptApproval",
+      "合同名称": "contractName",
+      "金额类型": "amountType",
+      "合同总额(元)": "contractTotalAmount",
+      "发起方式": "initiateMethod",
+      "合同编号规则": "contractNoRule",
+      "tableField_paymentPlan": {
+        "类型": "planType",
+        "计划日期": "planDate",
+        "金额": "planAmount",
+        "备注": "remark"
+      },
+      "合同期限类型": "contractTermType",
+      "服务期限与合同有效期是否一致": "isServiceTermSameAsValidity",
+      "开始时间结束时间": "startEndTime",
+      "合同有效期": "contractValidityPeriod",
+      "合同服务期限": "contractServiceTerm",
+      "合同有效期开始时间": "contractValidityStartTime",
+      "合同有效期限开始时间": "contractValidityPeriodStartTime",
+      "合同服务期限开始时间": "contractServiceTermStartTime",
+      "tableField_ourPartyInfo": {
+        "我方主体名称": "ourPartySubjectName"
+      },
+      "合同正文": "contractMainText",
+      "tableField_counterpartyInfo": {
+        "对方主体名称": "counterpartySubjectName"
+      },
+      "签署方式": "signMethod",
+      "印章类型": "sealType",
+      "电子签信息": "eSignatureInfo",
+      "风险类型同意书勾选1": "riskTypeAgreementCheck1",
+      "风险告知1": "riskNotification1",
+      "风险类型同意书勾选2": "riskTypeAgreementCheck2",
+      "风险告知2": "riskNotification2"
+    }
+  },"HTSPD-GF": {
+  "processCode": "PROC-7C20FBC6-5C55-41C5-8786-08DEAF6E2050",
+  "creator": "proposerCode",
+  "contractTextUrl": {
+    "downloadUrl": "downloadUrl",
+    "name": "name"
+  },
+  "contractScanUrl": {
+    "downloadUrl": "downloadUrl",
+    "name": "name"
+  },
+  "contractPreApprovalFlow": {
+    "downloadUrl": "downloadUrl",
+    "name": "name"
+  },
+  "ourPartyInfo": "我方信息",
+  "counterpartyInfo": "对方信息",
+  "compIds": {
+    "发起人": "proposerCode",
+    "日期": "date",
+    "合同前置审批流程": "contractPreApprovalFlow",
+    "合同文本预审": "contractTextPreliminaryReview",
+    "合同预审流程": "contractPreliminaryReviewFlow",
+    "合同名称": "contractName",
+    "金额类型": "amountType",
+    "合同总额(元)": "contractTotalAmount",
+    "发起方式": "initiateMethod",
+    "合同期限类型": "contractTermType",
+    "tableField_ourPartyInfo": {
+      "我方主体名称": "ourPartySubjectName"
+    },
+    "合同正文": "contractMainText",
+    "tableField_counterpartyInfo": {
+      "对方主体名称": "counterpartySubjectName"
+    },
+    "签署方式": "signMethod",
+    "是否涉及其他相关部门": "isInvolveOtherDepts",
+    "是否需王旭协同": "isNeedLandCoordination",
+    "请选择该合同的审批人": "contractApprover"
+  }
+}
+}

+ 199 - 0
mjava-gd/src/test/java/test.java

@@ -0,0 +1,199 @@
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.guangdian.Boot;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McException;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.server.dingtalk.DDR;
+import com.malk.server.dingtalk.DDR_New;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Contacts;
+import com.malk.service.dingtalk.DDClient_Personnel;
+import com.malk.service.dingtalk.DDClient_Workflow;
+import com.malk.utils.UtilDateTime;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import nccloud.open.api.auto.token.cur.utils.APICurUtils;
+import nccloud.open.api.auto.token.itf.IAPIUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Boot.class)
+public class test {
+//    public static void main(String[] args) throws Exception {
+//        String ip = "127.0.0.1";
+//        String port = "8080";
+//        String biz_center = "001";
+//        String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApzpqAg5xEk6E9o7ISP0pQO1Vdg6V8GozPHrVuBh6SOADw0je6qKfgvAn/s5RabyfBGfrFZ5kybPIPyizqCoqaDN5sX6tnyo3nxvuJCywK1CVr9X01P02GOJOx9EdJDZxp9e2Q/cbj/c8+amxId8brVCAm3OT8kM9UZUzohFassJuOVlA1TJ6A+u5MZ7cGM3/UQS6QJVD6N/8PraBfsdxxsXt0M4f0Lkalaxf8rVT+VHBK8jLxp9XaUWRJG6yatMMoFCIMZ6TNjOCSJ1ZDAlJ/pU5VY79RyS5jfkd+70YzUKlZjMJ/psO+ZEVFPu/yfMfS8M16c8xrXDzFcI1wcbBXwIDAQAB";
+//        String client_id = "zdgl";
+//        String client_secret = "4b0618a08ea84ff2ac93";
+//        String username = "JT001";
+//        String password = "1234qwer@";
+//        IAPIUtils util = null;
+//        util= new APICurUtils();
+//        util.init(ip, port, biz_center, client_id, client_secret, pubKey, username, password);
+//        String token = util.getToken();
+//        String url = "nccloud/api/gl/accountrep/accountbalance";
+//        util.setApiUrl(url);
+//
+//        String json = "{\r\n" +
+//                "  \"ufinterface\": {\r\n" +
+//                "    \"billtype\": \"supbankacc\",\r\n" +
+//                "    \"sender\": \"ZDGL\",\r\n" +
+//                "    \"replace\": \"Y\",\r\n" +
+//                "    \"bill\": {\r\n" +
+//                "      \"billhead\": {\r\n" +
+//                "        \"custbankVO\": {\r\n" +
+//                "          \"pk_cust\": \"KS01000000006\",\r\n" +
+//                "          \"pk_org\": \"01\"\r\n" +
+//                "        },\r\n" +
+//                "        \"bankaccbasVO\": {\r\n" +
+//                "          \"pk_group\": \"01\",\r\n" +
+//                "          \"accopendate\": \"\",\r\n" +
+//                "          \"enablestate\": \"2\",\r\n" +
+//                "          \"orgnumber\": \"\",\r\n" +
+//                "          \"accnum\": \"6222788\",\r\n" +
+//                "          \"pk_netbankinftp\": \"\",\r\n" +
+//                "          \"city\": \"\",\r\n" +
+//                "          \"pk_bankdoc\": \"01000001\",\r\n" +
+//                "          \"pk_org\": \"01\",\r\n" +
+//                "          \"accattribute\": \"0\",\r\n" +
+//                "          \"province\": \"\",\r\n" +
+//                "          \"tel\": \"\",\r\n" +
+//                "          \"accname\": \"\",\r\n" +
+//                "          \"pk_banktype\": \"01\",\r\n" +
+//                "          \"customernumber\": \"\",\r\n" +
+//                "          \"address\": \"\",\r\n" +
+//                "          \"accstate\": \"0\",\r\n" +
+//                "          \"accclass\": \"3\",\r\n" +
+//                "          \"combinenum\": \"123123\",\r\n" +
+//                "          \"accountproperty\": \"0\",\r\n" +
+//                "          \"contactpsn\": \"\",\r\n" +
+//                "          \"bankarea\": \"\",\r\n" +
+//                "		  \"bankaccsub\": {\r\n" +
+//                "						\"item\": {\r\n" +
+//                "							\"isdefault\": \"N\",\r\n" +
+//                "							\"pk_currtype\": \"CNY\"\r\n" +
+//                "						}\r\n" +
+//                "					}\r\n" +
+//                "        }\r\n" +
+//                "      }\r\n" +
+//                "    },\r\n" +
+//                "    \"isexchange\": \"Y\",\r\n" +
+//                "    \"account\": \"001\",\r\n" +
+//                "    \"groupcode\": \"01\"\r\n" +
+//                "  }\r\n" +
+//                "}";
+//
+//        JSONObject json2 = JSONObject.parseObject(json);
+//        String result = util.getAPIRetrun(token, json2.toJSONString());
+//        System.out.println(result);
+//
+//    }
+
+
+    public static void main(String[] args) {
+        String urlStr = "https://oa.cbyun.com.cn/seeyon/rest/token";
+        String jsonInput = "{\"userName\":\"restDing\",\"password\":\"507228d7-8768-4a2d-a1c3-5b49af9b30de\"}";
+
+        HttpURLConnection connection = null;
+        try {
+            // 1. 创建连接
+            URL url = new URL(urlStr);
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setRequestMethod("POST");
+            connection.setRequestProperty("Content-Type", "application/json");
+            connection.setDoOutput(true); // 允许输出
+            connection.setDoInput(true);  // 允许输入
+            connection.setConnectTimeout(5000);
+            connection.setReadTimeout(5000);
+
+            // 2. 写入请求体
+            try (OutputStream os = connection.getOutputStream()) {
+                byte[] input = jsonInput.getBytes(StandardCharsets.UTF_8);
+                os.write(input, 0, input.length);
+            }
+
+            // 3. 获取响应码
+            int responseCode = connection.getResponseCode();
+            if (responseCode == HttpURLConnection.HTTP_OK) {
+                // 4. 读取响应内容
+                StringBuilder response = new StringBuilder();
+                try (BufferedReader br = new BufferedReader(
+                        new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
+                    String line;
+                    while ((line = br.readLine()) != null) {
+                        response.append(line);
+                    }
+                }
+                String jsonResponse = response.toString();
+                System.out.println("响应原始内容: " + jsonResponse);
+                JSONObject jsonObject = JSONObject.parseObject(jsonResponse);
+
+                // 5. 解析 id 字段(手动提取,避免依赖 JSON 库)
+                String id = jsonObject.getString("id");
+                if (id != null) {
+                    System.out.println("获取到的 id: " + id);
+                } else {
+                    System.out.println("未找到 id 字段");
+                }
+            } else {
+                System.err.println("请求失败,HTTP 状态码: " + responseCode);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+    /**
+     * 从简单的 JSON 字符串中提取 "id" 字段的值
+     * 例如输入 {"id":"xxx"} 返回 xxx(去除前后引号)
+     * @param json 响应 JSON 字符串
+     * @return id 值,未找到返回 null
+     */
+    private static String extractIdFromJson(String json) {
+        // 查找 "id":" 的位置
+        String key = "\"id\":\"";
+        int startIndex = json.indexOf(key);
+        if (startIndex == -1) {
+            return null;
+        }
+        startIndex += key.length(); // 移动到值的开始位置
+        int endIndex = json.indexOf("\"", startIndex);
+        if (endIndex == -1) {
+            return null;
+        }
+        return json.substring(startIndex, endIndex);
+    }
+}

+ 39 - 0
mjava-gd/src/test/resource/server.sh

@@ -0,0 +1,39 @@
+#!/bin/bash
+
+appname='mjava-dongfangxinhua'
+
+if [ "$1" == "dev" ]; then
+  java -Xms256m -Xmx256m -jar $appname.jar --spring.profiles.active=dev
+else
+  if [ "$1" == "start" ]; then
+    nohup java -Xms256m -Xmx256m -jar $appname.jar &
+    echo "server prod is starting"
+    tail -f log/info.log
+  else
+    if [ "$1" == "test" ]; then
+      nohup java -Xms256m -Xmx256m -jar $appname.jar --spring.profiles.active=test &
+      echo "server test is starting"
+      tail -f log/info.log
+    else
+      if [ "$1" == "stop" ]; then
+        PID=$(ps -ef | grep $appname.jar | grep -v grep | awk '{ print $2 }')
+        if [ -z "$PID" ]; then
+          echo "server is already stopped"
+        else
+          echo kill $PID
+          kill $PID
+        fi
+      else
+        if [ "$1" == "status" ]; then
+          PID=$(ps -ef | grep $appname.jar | grep -v grep | awk '{ print $2 }')
+          if [ -z "$PID" ]; then
+            echo "server is stopped"
+          else
+            echo "server is running"
+            echo $PID
+          fi
+        fi
+      fi
+    fi
+  fi
+fi

+ 448 - 0
pom.xml

@@ -0,0 +1,448 @@
+<?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>
+
+    <groupId>com.malk</groupId>
+    <artifactId>java-mcli</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <modules>
+        <module>mjava-gd</module>
+    </modules>
+    <packaging>pom</packaging>
+
+    <name>java-mcli</name>
+    <description>mjava framework</description>
+
+    <!-- 版本管理 Management -->
+    <properties>
+        <!-- mjava版本: 修改mjava pom配置 -->
+        <mjava.version>0.0.3</mjava.version>
+        <!-- 全局配置 -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <!-- 公共依赖 -->
+        <spring-boot-dependencies.version>2.2.13.RELEASE</spring-boot-dependencies.version>
+        <junit.verson>4.12</junit.verson>
+        <lombok.version>1.18.8</lombok.version>
+        <validation-api.version>2.0.1.Final</validation-api.version>
+        <fastjson.version>1.2.83</fastjson.version>
+        <commons-lang3.version>3.10</commons-lang3.version>
+        <guava.version>30.1.1-jre</guava.version>
+        <hutool-all.version>5.6.0</hutool-all.version>
+        <spring-boot-starter-data-jpa.version>2.1.3.RELEASE</spring-boot-starter-data-jpa.version>
+        <querydsl-apt.version>4.2.1</querydsl-apt.version>
+        <querydsl-jpa.version>4.2.1</querydsl-jpa.version>
+        <spring-boot-starter-jdbc.version>2.2.13.RELEASE</spring-boot-starter-jdbc.version>
+        <easyexcel.version>2.2.7</easyexcel.version>
+        <!-- 数据库连接 [仅mysql为全局依赖] -->
+        <mysql-connector-java.version>8.0.22</mysql-connector-java.version>
+        <mssql-jdbc.version>6.4.0.jre8</mssql-jdbc.version>
+        <ojdbc6.version>11.2.0.4</ojdbc6.version>
+        <mongo-java-driver.version>3.12.7</mongo-java-driver.version>
+        <spring-boot-starter-data-mongodb.version>2.2.13.RELEASE</spring-boot-starter-data-mongodb.version>
+        <!-- jsp [非全局依赖] -->
+        <tomcat-embed-jasper.version>9.0.41</tomcat-embed-jasper.version>
+        <jstl.version>1.2</jstl.version>
+        <javax.servlet-api.version>4.0.1</javax.servlet-api.version>
+        <javax.servlet.jsp-api.version>2.3.1</javax.servlet.jsp-api.version>
+        <!-- jwt [非全局依赖] -->
+        <java-jwt.version>3.4.0</java-jwt.version>
+        <!-- swagger3: todo -->
+        <springfox-boot-starter.version>3.0.0</springfox-boot-starter.version>
+        <!-- 网页转pdf [非全局依赖] -->
+        <flying-saucer-pdf-itext5.version>9.0.3</flying-saucer-pdf-itext5.version>
+        <!-- 腾讯云[发票识别] [非全局依赖] -->
+        <tencentcloud-sdk-java.version>3.1.778</tencentcloud-sdk-java.version>
+        <!-- 不执行单元测试,也不编译测试类 -->
+        <skipTests>true</skipTests>
+        <!-- 不执行单元测试,但会编译测试类,并在target/test-classes目录下生成相应的class -->
+        <maven.test.skip>true</maven.test.skip>
+        <mybatis-plus.version>3.5.1</mybatis-plus.version>
+        <durid.version>1.1.18</durid.version>
+    </properties>
+
+    <!-- 依赖声明 & 版本 -->
+    <dependencyManagement>
+        <dependencies>
+            <!-- SpringBoot 依赖 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot-dependencies.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <!-- 单元测试 -->
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>${junit.verson}</version>
+                <scope>test</scope>
+            </dependency>
+
+            <!-- lombok -->
+            <dependency>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok</artifactId>
+                <version>${lombok.version}</version>
+                <scope>provided</scope>
+            </dependency>
+
+            <!-- validation 参数校验 -->
+            <dependency>
+                <groupId>javax.validation</groupId>
+                <artifactId>validation-api</artifactId>
+                <version>${validation-api.version}</version>
+            </dependency>
+
+            <!-- 阿里巴巴 json -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>${fastjson.version}</version>
+            </dependency>
+
+            <!-- 通用的工具类集 -->
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>${commons-lang3.version}</version>
+            </dependency>
+            <!-- ppExt: 23.10.26 钉钉新方式以Steam接入, HTTP形式commonsc-codec在升级之后,其内部做了一个validateCharacter校验. 使用 guava 替代-->
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>${guava.version}</version>
+            </dependency>
+            <!-- 国产工具集 -->
+            <dependency>
+                <groupId>cn.hutool</groupId>
+                <artifactId>hutool-all</artifactId>
+                <version>${hutool-all.version}</version>
+            </dependency>
+
+            <!-- data-jpa 数据库操作 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-data-jpa</artifactId>
+                <version>${spring-boot-starter-data-jpa.version}</version>
+            </dependency>
+
+            <!-- QueryDSL 4.x 支持-->
+            <dependency>
+                <groupId>com.querydsl</groupId>
+                <artifactId>querydsl-apt</artifactId>
+                <scope>provided</scope>
+                <version>${querydsl-apt.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.querydsl</groupId>
+                <artifactId>querydsl-jpa</artifactId>
+                <version>${querydsl-jpa.version}</version>
+            </dependency>
+
+            <!-- AOP多数据源切换 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-jdbc</artifactId>
+                <version>${spring-boot-starter-jdbc.version}</version>
+            </dependency>
+
+            <!-- easyExcel 优化 poi [不影响单独引入poi, 会冲突] -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>easyexcel</artifactId>
+                <version>${easyexcel.version}</version>
+            </dependency>
+
+            <!-- mySql 驱动 -->
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${mysql-connector-java.version}</version>
+            </dependency>
+
+            <!-- sqlserver依赖 -->
+            <dependency>
+                <groupId>com.microsoft.sqlserver</groupId>
+                <artifactId>mssql-jdbc</artifactId>
+                <scope>runtime</scope>
+                <version>${mssql-jdbc.version}</version>
+            </dependency>
+
+            <!-- Oracle 依赖 -->
+            <dependency>
+                <groupId>com.oracle.database.jdbc</groupId>
+                <artifactId>ojdbc6</artifactId>
+                <version>${ojdbc6.version}</version>
+            </dependency>
+
+            <!-- MongoDB 驱动 -->
+            <dependency>
+                <groupId>org.mongodb</groupId>
+                <artifactId>mongo-java-driver</artifactId>
+                <version>${mongo-java-driver.version}</version>
+            </dependency>
+            <!-- MongoDB jpa 操作 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-data-mongodb</artifactId>
+                <version>${spring-boot-starter-data-mongodb.version}</version>
+            </dependency>
+
+            <!-- url转pdf -->
+            <dependency>
+                <groupId>org.xhtmlrenderer</groupId>
+                <artifactId>flying-saucer-pdf-itext5</artifactId>
+                <version>${flying-saucer-pdf-itext5.version}</version>
+            </dependency>
+
+            <!-- jsp: tomcat-embed-jasper 需要添加到子项目内 -->
+            <dependency>
+                <groupId>org.apache.tomcat.embed</groupId>
+                <artifactId>tomcat-embed-jasper</artifactId>
+                <version>${tomcat-embed-jasper.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>jstl</artifactId>
+                <version>${jstl.version}</version>
+            </dependency>
+            <!-- servlet -->
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>javax.servlet-api</artifactId>
+                <version>${javax.servlet-api.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet.jsp</groupId>
+                <artifactId>javax.servlet.jsp-api</artifactId>
+                <version>${javax.servlet.jsp-api.version}</version>
+            </dependency>
+
+            <!-- jwt -->
+            <dependency>
+                <groupId>com.auth0</groupId>
+                <artifactId>java-jwt</artifactId>
+                <version>${java-jwt.version}</version>
+            </dependency>
+
+            <!-- 腾讯云 -->
+            <dependency>
+                <groupId>com.tencentcloudapi</groupId>
+                <artifactId>tencentcloud-sdk-java</artifactId>
+                <version>${tencentcloud-sdk-java.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <!-- 子项目需要与 mjava 相同的依赖, 否则调试可运行, 打包后会运行报错. 为了避免重复引入 pom, 将 mjava 依赖直接在全局 pom 引入 -->
+    <dependencies>
+        <!-- spring boot -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-tomcat</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!-- spring-boot-devtools [热部署] -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <optional>true</optional> <!-- 表示依赖不会传递 -->
+        </dependency>
+        <!-- 单元测试 -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- validation 参数校验 -->
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+
+        <!-- 阿里巴巴 json -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!-- 通用的工具类集 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <!-- 国产工具集 -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
+        <!-- data-jpa 数据库操作 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+
+        <!-- QueryDSL 4.x 支持-->
+        <dependency>
+            <groupId>com.querydsl</groupId>
+            <artifactId>querydsl-apt</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.querydsl</groupId>
+            <artifactId>querydsl-jpa</artifactId>
+        </dependency>
+
+        <!-- AOP多数据源切换 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+
+        <!-- easyExcel 优化 poi [不影响单独引入poi, 会冲突] -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+        </dependency>
+
+        <!-- mySql 驱动 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <!--        引入mybatisPlus 包含了 jdbc -->
+<!--        <dependency>-->
+<!--            <groupId>com.baomidou</groupId>-->
+<!--            <artifactId>mybatis-plus-boot-starter</artifactId>-->
+<!--            <version>${mybatis-plus.version}</version>-->
+<!--        </dependency>-->
+
+        <!--        引入durid數據源-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${durid.version}</version>
+        </dependency>
+
+        <!-- Oracle 依赖 -->
+<!--                <dependency>-->
+<!--                    <groupId>com.oracle.database.jdbc</groupId>-->
+<!--                    <artifactId>ojdbc6</artifactId>-->
+<!--                </dependency>-->
+
+<!--         sqlserver 依赖 -->
+<!--                <dependency>-->
+<!--                    <groupId>com.microsoft.sqlserver</groupId>-->
+<!--                    <artifactId>mssql-jdbc</artifactId>-->
+<!--                    <scope>runtime</scope>-->
+<!--                </dependency>-->
+
+
+<!--         MongoDB 驱动 -->
+<!--                <dependency>-->
+<!--                    <groupId>org.mongodb</groupId>-->
+<!--                    <artifactId>mongo-java-driver</artifactId>-->
+<!--                </dependency>-->
+<!--         MongoDB jpa 操作 -->
+<!--                <dependency>-->
+<!--                    <groupId>org.springframework.boot</groupId>-->
+<!--                    <artifactId>spring-boot-starter-data-mongodb</artifactId>-->
+<!--                    <version>${spring-boot-starter-data-mongodb.version}</version>-->
+<!--                </dependency>-->
+
+<!--         url转pdf -->
+<!--                <dependency>-->
+<!--                    <groupId>org.xhtmlrenderer</groupId>-->
+<!--                    <artifactId>flying-saucer-pdf-itext5</artifactId>-->
+<!--                </dependency>-->
+
+<!--         jsp: tomcat-embed-jasper 需要在子项目内引用才有效 -->
+<!--                <dependency>-->
+<!--                    <groupId>javax.servlet</groupId>-->
+<!--                    <artifactId>jstl</artifactId>-->
+<!--                </dependency>-->
+<!--         servlet -->
+                <dependency>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>javax.servlet-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>javax.servlet.jsp</groupId>
+                    <artifactId>javax.servlet.jsp-api</artifactId>
+                </dependency>
+
+<!--         jwt -->
+                <dependency>
+                    <groupId>com.auth0</groupId>
+                    <artifactId>java-jwt</artifactId>
+                </dependency>
+
+<!--         腾讯云 [go to https://search.maven.org/search?q=tencentcloud-sdk-java and get the latest version.] -->
+<!--                <dependency>-->
+<!--                    <groupId>com.tencentcloudapi</groupId>-->
+<!--                    <artifactId>tencentcloud-sdk-java</artifactId>-->
+<!--                </dependency>-->
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                    <!-- jva使用了未经检查或不安全的操作,编译会有打印,通过插件显示具体报错警告位置, 如 T, Map, List 也会报警告 -->
+                    <compilerArgument>-Xlint:unchecked</compilerArgument>
+                </configuration>
+            </plugin>
+            <!-- QueryDSL 插件: 因为QueryDsl是类型安全的,所以还需要加上Maven APT plugin,使用 APT 自动生成Q类 -->
+            <plugin>
+                <groupId>com.mysema.maven</groupId>
+                <artifactId>apt-maven-plugin</artifactId>
+                <version>1.1.3</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>process</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>target/generated-sources/java</outputDirectory>
+                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>