xmy 2 hete%!(EXTRA string=óta)
szülő
commit
4dc05b5738
37 módosított fájl, 2946 hozzáadás és 0 törlés
  1. 70 0
      mjava-ounuo/src/main/java/com/malk/tuosi/controller/TBController.java
  2. 179 0
      mjava-ounuo/src/main/java/com/malk/tuosi/controller/TaskController.java
  3. 25 0
      mjava-ounuo/src/main/java/com/malk/tuosi/entity/AnnualSeasonalSample.java
  4. 27 0
      mjava-ounuo/src/main/java/com/malk/tuosi/entity/ConfirmDesignYear.java
  5. 27 0
      mjava-ounuo/src/main/java/com/malk/tuosi/entity/DesigndeparttMonthConfirm.java
  6. 29 0
      mjava-ounuo/src/main/java/com/malk/tuosi/entity/EmployeeWeeklyTasks.java
  7. 25 0
      mjava-ounuo/src/main/java/com/malk/tuosi/entity/NewprocessImplementation.java
  8. 31 0
      mjava-ounuo/src/main/java/com/malk/tuosi/entity/Task.java
  9. 30 0
      mjava-ounuo/src/main/java/com/malk/tuosi/entity/YearPersonalConfirm.java
  10. 9 0
      mjava-ounuo/src/main/java/com/malk/tuosi/mapper/AnnualSeasonalSampleMapper.java
  11. 13 0
      mjava-ounuo/src/main/java/com/malk/tuosi/mapper/ConfirmDesignYearMapper.java
  12. 9 0
      mjava-ounuo/src/main/java/com/malk/tuosi/mapper/DesigndeparttMonthConfirmMapper.java
  13. 13 0
      mjava-ounuo/src/main/java/com/malk/tuosi/mapper/EmployeeWeeklyTasksMapper.java
  14. 9 0
      mjava-ounuo/src/main/java/com/malk/tuosi/mapper/NewprocessImplementationMapper.java
  15. 16 0
      mjava-ounuo/src/main/java/com/malk/tuosi/mapper/TaskMapper.java
  16. 13 0
      mjava-ounuo/src/main/java/com/malk/tuosi/mapper/YearPersonalConfirmMapper.java
  17. 958 0
      mjava-ounuo/src/main/java/com/malk/tuosi/schedule/ScheduleTask.java
  18. 7 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/AnnualSeasonalSampleService.java
  19. 7 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/ConfirmDesignYearService.java
  20. 8 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/DesigndeparttMonthConfirmService.java
  21. 7 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/EmployeeWeeklyTasksService.java
  22. 7 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/NewprocessImplementationService.java
  23. 32 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/TBService.java
  24. 10 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/TaskService.java
  25. 7 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/YearPersonalConfirmService.java
  26. 13 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/AnnualSeasonalSampleServiceImpl.java
  27. 14 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/ConfirmDesignYearServiceImpl.java
  28. 13 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/DesigndeparttMonthConfirmServiceImpl.java
  29. 12 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/EmployeeWeeklyTasksServiceImpl.java
  30. 14 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/NewprocessImplementationServiceImpl.java
  31. 18 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/TaskServiceImpl.java
  32. 806 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/TbServiceImpl.java
  33. 9 0
      mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/YearPersonalConfirmServiceImpl.java
  34. 263 0
      mjava-ounuo/src/main/java/com/malk/tuosi/test/test.java
  35. 114 0
      mjava-ounuo/src/main/resources/application-dev.yml
  36. 99 0
      mjava-ounuo/src/main/resources/application-prod.yml
  37. 3 0
      mjava-ounuo/src/main/resources/application.yml

+ 70 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/controller/TBController.java

@@ -0,0 +1,70 @@
+package com.malk.tuosi.controller;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.malk.server.common.McR;
+import com.malk.tuosi.service.TBService;
+import com.malk.tuosi.service.impl.TbServiceImpl;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping("/TBConstructionLog")
+public class TBController {
+    @Autowired
+    private TBService tbService;
+
+    /*TODO:TB获取应用授权token*/
+    @SneakyThrows
+    @PostMapping("/GetAppToken")
+    McR AppAccessToken() throws JsonProcessingException {
+        log.info("---------获取到token---------");
+        return tbService.AppAccessToken();
+    }
+
+    /*TODO:钉钉获取应用token*/
+    @PostMapping("/GetDingToken")
+    McR AccessToken() throws JsonProcessingException{
+        log.info("---------获取到dingtoken-------");
+        return tbService.Accesstoken();
+    }
+
+    /*TODO:TB事件订阅接口*/
+    @PostMapping("/tbTaskUpdate")
+    McR tbTaskUpdate(@RequestBody Map body) throws JsonProcessingException{
+        return McR.success(tbService.tbTaskUpdate(body));
+    }
+
+    /*TODO:钉盘文件上传*/
+    @PostMapping("/uploadKnowledge")
+    McR uploadKnowledge(@RequestParam  String pathName, @RequestParam String fileName,@RequestParam String fileType) throws JsonProcessingException{
+        return McR.success(tbService.uploadKnowledge(pathName,fileName,fileType));
+    }
+
+    /*TODO:版线组位置附件上传CRM*/
+    @PostMapping("/tbCallbackCRM")
+    McR tbCallbackCRM(@RequestBody Map body) throws JsonProcessingException{
+        return McR.success(tbService.tbCallbackCRM(body));
+    }
+
+    /*TODO:OA回传TB*/
+    @PostMapping("/oaCallbackTB")
+    McR oaCallbackTB(@RequestBody Map body) throws  JsonProcessingException{
+        return McR.success(tbService.oaCallbackTB(body));
+    }
+
+    /*TODO:Teambition userId 查询钉钉 userId*/
+
+    @PostMapping("/TBtoDinguserId")
+    McR TBtoDinguserId(@RequestParam List list) throws JsonProcessingException{
+        return McR.success(tbService.TBtoDinguserId(list));
+    }
+
+
+
+}

+ 179 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/controller/TaskController.java

@@ -0,0 +1,179 @@
+package com.malk.tuosi.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.malk.server.common.McR;
+import com.malk.tuosi.entity.Task;
+import com.malk.tuosi.mapper.TaskMapper;
+import com.malk.tuosi.service.TBService;
+import com.malk.tuosi.service.TaskService;
+import com.malk.utils.UtilHttp;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.StreamSupport;
+
+@Slf4j
+@RestController
+@RequestMapping("/datasync")
+public class TaskController {
+    @Autowired
+    private TaskMapper taskMapper;
+    @Autowired
+    private TBService tbService;
+
+    @SneakyThrows
+    @PostMapping("/addTask")
+    McR addTask(){
+        /*todo:查询任务详情*/
+        //1、计数项目任务
+        HashMap header = new HashMap();
+        header.put("x-operator-id","622ee3450cf3bb5e1a486f1f");
+        McR Token = tbService.AppAccessToken();
+        Object token = Token.getData();
+        header.put("Authorization","Bearer " + token);
+        header.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+        header.put("X-Tenant-Type","organization");
+        String projectId = "6878b323386fac7ab9dbe5e9";
+        String doGet = UtilHttp.doGet("https://open.teambition.com/api/v3/project/" + projectId + "/task/count", (Map) header, (Map) null);
+        Matcher m = Pattern.compile("\"result\":(\\d+)").matcher(doGet);
+        int result = m.find() ? Integer.parseInt(m.group(1)) : 0;//1450
+        //2、查询项目任务
+        HashMap param = new HashMap();
+        param.put("pageSize",100);
+        ArrayList list = new ArrayList();//分页标全部存在list
+
+        String pageToken = "";//初始值
+        for (int i=0;i<result/100 + 1;i++){
+            ArrayList<String> allIds = new ArrayList<>();//todo:->>>>>>>>>全部任务id存在allIds
+            param.put("pageToken",pageToken);
+            String doGet1 = UtilHttp.doGet("https://open.teambition.com/api/v3/project/" + projectId + "/task/query", header, param);
+            List<String> batchIds = extractIdsFromJson(doGet1);//提取当前批次的id
+            allIds.addAll(batchIds);//添加到总列表
+            ObjectMapper mapper = new ObjectMapper();
+            String nextPageToken = mapper.readTree(doGet1).get("nextPageToken").asText();
+            if (nextPageToken != null && !nextPageToken.trim().isEmpty()) {
+                // 不为空,使用nextPageToken
+                list.add(nextPageToken);
+                pageToken = nextPageToken;
+            }else {
+                // 为空,不进行处理
+            }
+
+            /*todo:100条数据处理*/
+            //3、查询任务详情
+            int k =0;
+            ArrayList errorList = new ArrayList();
+            for (int j = 0; j < allIds.size(); j++) {
+                k++;
+                HashMap params = new HashMap();
+                params.put("taskId", allIds.get(j));
+                String doGet2 = UtilHttp.doGet("https://open.teambition.com/api/v3/task/query", header, params);
+                String crmId = "";            //CRM编码--->343513
+                String renWuName = "";        //品名--->530GX16迎凤富贵--河南盈乐
+                String company = "";          // 客户名称--->华美食品(河北)有限公司
+                String draftStatus = "";      // 设计类别--->确认稿
+                String customerType = "";     // 文件来源(公司)--->客户
+                String levelOneDesign = "";   // 设计等级--->一级设计
+                String tfsId = new ObjectMapper().readTree(doGet2).get("result").get(0).get("tfsId").asText();//任务状态ID
+                renWuName = new ObjectMapper().readTree(doGet2).get("result").get(0).get("content").asText();//任务名称--->品名
+                String title = StreamSupport.stream(new ObjectMapper().readTree(doGet2)
+                                .get("result").get(0).get("customfields").spliterator(), false)
+                        .filter(field -> "689d4ebf343c05fe73700c93".equals(field.get("cfId").asText()))
+                        .findFirst()
+                        .map(field -> field.get("value").get(0).get("title").asText())
+                        .orElse(null);//CRM单据ID--->CRM编码
+                JSONArray customfields = JSON.parseObject(doGet2).getJSONArray("result").getJSONObject(0).getJSONArray("customfields");
+                for (int p = 0; p < customfields.size(); p++) {
+                    JSONObject field = customfields.getJSONObject(p);
+                    String cfId = field.getString("cfId");
+                    JSONArray valueArray = field.getJSONArray("value");
+                    if (valueArray != null && !valueArray.isEmpty()) {
+                        String value = valueArray.getJSONObject(0).getString("title");
+                        //根据cfId匹配
+                        switch (cfId){
+                            case "687df3b60ae1530fa2704499":
+                                company = value;
+                                break;
+                            case "687e0308e3f7ce8174a19cfc":
+                                draftStatus = value;
+                                break;
+                            case "687df8813d5081f8c81cf375":
+                                customerType = value;
+                                break;
+                            case "691c29c1f8cbae320a1c8e75":
+                                levelOneDesign = value;
+                                break;
+                            case "68f980e6a24e799a9c7a226a":
+                                crmId = value;
+                                break;
+                        }
+                    }
+                }
+                /*todo:给实体赋值*/
+                /*打印进度*/
+                log.info("进度:{}/{}",k,result);
+                Task task = new Task();
+                task.setTaskId(crmId);//CRM编码
+                task.setTaskName(renWuName);//任务名称
+                task.setCustomerName(company);//客户名称
+                task.setDesignCategory(draftStatus);//设计类别
+                task.setFileSource(customerType);//文件来源(公司)
+                task.setDesignLevel(levelOneDesign);//设计等级
+                /*todo:插入数据库*/
+                int insert = taskMapper.insert(task);
+                Map<String, Object> response = new HashMap<>();
+                if(insert > 0){
+                    response.put("success", true);
+                    response.put("message", "用户创建成功");
+                    response.put("data", "");
+                    log.info("任务创建成功,任务ID:{},任务名称:{}", task.getTaskId(),task.getTaskName());
+                }else {
+                    log.info("任务创建失败,任务ID:{},任务名称:{}",task.getTaskId(),task.getTaskName());
+                    errorList.add(task.getTaskId() + "---" + task.getTaskName());//插入数据失败的统计
+                }
+            }
+
+            if(errorList.size() >0){
+                System.out.println("插入任务列表失败集合:" + errorList);
+            }
+        }
+
+        return McR.success();
+    }
+
+    /*额外方法:从项目任务查询的100条任务提取result中所有的id*/
+    private static List<String> extractIdsFromJson(String jsonString) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode rootNode = mapper.readTree(jsonString);
+        JsonNode resultArray = rootNode.get("result");
+
+        // 预分配100容量(每批大约100条数据)
+        List<String> ids = new ArrayList<>(100);
+
+        if (resultArray != null && resultArray.isArray()) {
+            for (JsonNode item : resultArray) {
+                if (item.has("id")) {
+                    String id = item.get("id").asText();
+                    ids.add(id);
+                }
+            }
+        }
+        return ids;
+    }
+
+
+}

+ 25 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/entity/AnnualSeasonalSample.java

@@ -0,0 +1,25 @@
+package com.malk.tuosi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户实体类
+ * 注意:实体类使用驼峰命名,对应数据库的下划线命名
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AnnualSeasonalSample {
+    /*任务id*/
+    private String taskId;
+    /*任务名称*/
+    private String taskName;
+    /*客户*/
+    private String customer;
+    /*设计等级*/
+    private String designLevel;
+    /*设计类别*/
+    private String designType;
+}

+ 27 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/entity/ConfirmDesignYear.java

@@ -0,0 +1,27 @@
+package com.malk.tuosi.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户实体类
+ * 注意:实体类使用驼峰命名,对应数据库的下划线命名
+ */
+@Data
+//@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+//@TableName("ConfirmDesignYear")
+public class ConfirmDesignYear {
+    /*任务id*/
+    private String taskId;
+    /*任务名称*/
+    private String taskName;
+    /*设计等级*/
+    private String designLevel;
+    /*任务类型*/
+    private String taskType;
+}

+ 27 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/entity/DesigndeparttMonthConfirm.java

@@ -0,0 +1,27 @@
+package com.malk.tuosi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户实体类
+ * 注意:实体类使用驼峰命名,对应数据库的下划线命名
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DesigndeparttMonthConfirm {
+    /*任务id*/
+    private String taskId;
+    /*任务名称*/
+    private String taskName;
+    /*客户*/
+    private String customer;
+    /*设计等级*/
+    private String designLevel;
+    /*设计类别*/
+    private String designType;
+    /*截止时间*/
+    private String dateLineEnd;
+}

+ 29 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/entity/EmployeeWeeklyTasks.java

@@ -0,0 +1,29 @@
+package com.malk.tuosi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户实体类
+ * 注意:实体类使用驼峰命名,对应数据库的下划线命名
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class EmployeeWeeklyTasks {
+    /*任务id*/
+    private String taskId;
+    /*任务名称*/
+    private String taskName;
+    /*负责人*/
+    private String manager;
+    /*开始时间*/
+    private String timeStart;
+    /*结束时间*/
+    private String timeEnd;
+    /*任务类型*/
+    private String taskType;
+    /*任务状态*/
+    private String status;
+}

+ 25 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/entity/NewprocessImplementation.java

@@ -0,0 +1,25 @@
+package com.malk.tuosi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户实体类
+ * 注意:实体类使用驼峰命名,对应数据库的下划线命名
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class NewprocessImplementation {
+    /*任务id*/
+    private String taskId;
+    /*任务名称*/
+    private String taskName;
+    /*客户*/
+    private String customer;
+    /*设计等级*/
+    private String designLevel;
+    /*设计类别*/
+    private String designType;
+}

+ 31 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/entity/Task.java

@@ -0,0 +1,31 @@
+package com.malk.tuosi.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 用户实体类
+ * 注意:实体类使用驼峰命名,对应数据库的下划线命名
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("task_total")
+public class Task {
+    /*CRM编码-对应数据库 task_id*/
+    private String taskId;
+    /*品名-对应数据库 task_name*/
+    private String taskName;
+    /*客户名称-对应数据库 customer_name*/
+    private String customerName;
+    /*设计类别-对应数据库 design_category*/
+    private String designCategory;
+    /*文件来源(公司)-对应数据库 file_source*/
+    private String  fileSource;
+    /*设计等级-对应数据库 design_level*/
+    private String designLevel;
+}

+ 30 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/entity/YearPersonalConfirm.java

@@ -0,0 +1,30 @@
+package com.malk.tuosi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.xmlbeans.impl.tool.StreamInstanceValidator;
+
+/**
+ * 用户实体类
+ * 注意:实体类使用驼峰命名,对应数据库的下划线命名
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class YearPersonalConfirm {
+    /*任务id*/
+    private String taskId;
+    /*任务名称(品名)*/
+    private String taskName;
+    /*设计人员*/
+    private String designPerson;
+    /*系数*/
+    private Integer coefficient;
+    /*客户名称*/
+    private String customerName;
+    /*设计等级*/
+    private String designLevel;
+    /*完成时间*/
+    private String deadline;
+}

+ 9 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/mapper/AnnualSeasonalSampleMapper.java

@@ -0,0 +1,9 @@
+package com.malk.tuosi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.tuosi.entity.AnnualSeasonalSample;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface AnnualSeasonalSampleMapper extends BaseMapper<AnnualSeasonalSample> {
+}

+ 13 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/mapper/ConfirmDesignYearMapper.java

@@ -0,0 +1,13 @@
+package com.malk.tuosi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.tuosi.entity.ConfirmDesignYear;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户数据访问接口
+ * 注意:使用@Mapper注解,Spring Boot会自动扫描
+ */
+@Mapper
+public interface ConfirmDesignYearMapper extends BaseMapper<ConfirmDesignYear> {
+}

+ 9 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/mapper/DesigndeparttMonthConfirmMapper.java

@@ -0,0 +1,9 @@
+package com.malk.tuosi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.tuosi.entity.DesigndeparttMonthConfirm;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface DesigndeparttMonthConfirmMapper extends BaseMapper<DesigndeparttMonthConfirm> {
+}

+ 13 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/mapper/EmployeeWeeklyTasksMapper.java

@@ -0,0 +1,13 @@
+package com.malk.tuosi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.tuosi.entity.EmployeeWeeklyTasks;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户数据访问接口
+ * 注意:使用@Mapper注解,Spring Boot会自动扫描
+ */
+@Mapper
+public interface EmployeeWeeklyTasksMapper extends BaseMapper<EmployeeWeeklyTasks> {
+}

+ 9 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/mapper/NewprocessImplementationMapper.java

@@ -0,0 +1,9 @@
+package com.malk.tuosi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.tuosi.entity.NewprocessImplementation;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface NewprocessImplementationMapper extends BaseMapper<NewprocessImplementation> {
+}

+ 16 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/mapper/TaskMapper.java

@@ -0,0 +1,16 @@
+package com.malk.tuosi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.tuosi.entity.Task;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 用户数据访问接口
+ * 注意:使用@Mapper注解,Spring Boot会自动扫描
+ */
+@Mapper
+public interface TaskMapper extends BaseMapper<Task> {
+}

+ 13 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/mapper/YearPersonalConfirmMapper.java

@@ -0,0 +1,13 @@
+package com.malk.tuosi.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.malk.tuosi.entity.YearPersonalConfirm;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户数据访问接口
+ * 注意:使用@Mapper注解,Spring Boot会自动扫描
+ */
+@Mapper
+public interface YearPersonalConfirmMapper extends BaseMapper<YearPersonalConfirm> {
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 958 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/schedule/ScheduleTask.java


+ 7 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/AnnualSeasonalSampleService.java

@@ -0,0 +1,7 @@
+package com.malk.tuosi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.tuosi.entity.AnnualSeasonalSample;
+
+public interface AnnualSeasonalSampleService extends IService<AnnualSeasonalSample> {
+}

+ 7 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/ConfirmDesignYearService.java

@@ -0,0 +1,7 @@
+package com.malk.tuosi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.tuosi.entity.ConfirmDesignYear;
+
+public interface ConfirmDesignYearService extends IService<ConfirmDesignYear> {
+}

+ 8 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/DesigndeparttMonthConfirmService.java

@@ -0,0 +1,8 @@
+package com.malk.tuosi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.tuosi.entity.DesigndeparttMonthConfirm;
+
+public interface DesigndeparttMonthConfirmService extends IService<DesigndeparttMonthConfirm> {
+
+}

+ 7 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/EmployeeWeeklyTasksService.java

@@ -0,0 +1,7 @@
+package com.malk.tuosi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.tuosi.entity.EmployeeWeeklyTasks;
+
+public interface EmployeeWeeklyTasksService extends IService<EmployeeWeeklyTasks> {
+}

+ 7 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/NewprocessImplementationService.java

@@ -0,0 +1,7 @@
+package com.malk.tuosi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.tuosi.entity.NewprocessImplementation;
+
+public interface NewprocessImplementationService extends IService<NewprocessImplementation> {
+}

+ 32 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/TBService.java

@@ -0,0 +1,32 @@
+package com.malk.tuosi.service;
+
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.malk.server.common.McR;
+
+import java.util.List;
+import java.util.Map;
+
+public interface TBService {
+    /*TODO:获取apptoken*/
+    McR AppAccessToken() throws JsonProcessingException;
+
+    /*TODO:获取dingtoken*/
+    McR Accesstoken() throws JsonProcessingException;
+
+   /*TODO:接收TB推送的数据*/
+    McR tbTaskUpdate(Map body) throws JsonProcessingException;
+
+    /*TODO:钉盘文件上传接口*/
+    McR uploadKnowledge(String pathName,String fileName,String fileType) throws JsonProcessingException;
+
+    /*TODO:TB回传CRM*/
+    McR tbCallbackCRM(Map body) throws JsonProcessingException;
+
+    /*TODO:OA回传TB*/
+    McR oaCallbackTB(Map body) throws  JsonProcessingException;
+
+    /*TODO:Teambition userId 查询钉钉 userId*/
+    String TBtoDinguserId(List list) throws JsonProcessingException;
+
+}

+ 10 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/TaskService.java

@@ -0,0 +1,10 @@
+package com.malk.tuosi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.tuosi.entity.Task;
+
+import java.util.List;
+
+public interface TaskService extends IService<Task> {
+
+}

+ 7 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/YearPersonalConfirmService.java

@@ -0,0 +1,7 @@
+package com.malk.tuosi.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.malk.tuosi.entity.YearPersonalConfirm;
+
+public interface YearPersonalConfirmService extends IService<YearPersonalConfirm> {
+}

+ 13 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/AnnualSeasonalSampleServiceImpl.java

@@ -0,0 +1,13 @@
+package com.malk.tuosi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.tuosi.entity.AnnualSeasonalSample;
+import com.malk.tuosi.mapper.AnnualSeasonalSampleMapper;
+import com.malk.tuosi.service.AnnualSeasonalSampleService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class AnnualSeasonalSampleServiceImpl extends ServiceImpl<AnnualSeasonalSampleMapper, AnnualSeasonalSample> implements AnnualSeasonalSampleService {
+}

+ 14 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/ConfirmDesignYearServiceImpl.java

@@ -0,0 +1,14 @@
+package com.malk.tuosi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.tuosi.entity.ConfirmDesignYear;
+import com.malk.tuosi.mapper.ConfirmDesignYearMapper;
+import com.malk.tuosi.service.ConfirmDesignYearService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class ConfirmDesignYearServiceImpl extends ServiceImpl<ConfirmDesignYearMapper, ConfirmDesignYear> implements ConfirmDesignYearService {
+
+}

+ 13 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/DesigndeparttMonthConfirmServiceImpl.java

@@ -0,0 +1,13 @@
+package com.malk.tuosi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.tuosi.entity.DesigndeparttMonthConfirm;
+import com.malk.tuosi.mapper.DesigndeparttMonthConfirmMapper;
+import com.malk.tuosi.service.DesigndeparttMonthConfirmService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class DesigndeparttMonthConfirmServiceImpl extends ServiceImpl<DesigndeparttMonthConfirmMapper, DesigndeparttMonthConfirm> implements DesigndeparttMonthConfirmService {
+}

+ 12 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/EmployeeWeeklyTasksServiceImpl.java

@@ -0,0 +1,12 @@
+package com.malk.tuosi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.tuosi.entity.EmployeeWeeklyTasks;
+import com.malk.tuosi.mapper.EmployeeWeeklyTasksMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class EmployeeWeeklyTasksServiceImpl extends ServiceImpl<EmployeeWeeklyTasksMapper,EmployeeWeeklyTasks> {
+}

+ 14 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/NewprocessImplementationServiceImpl.java

@@ -0,0 +1,14 @@
+package com.malk.tuosi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.tuosi.mapper.NewprocessImplementationMapper;
+import com.malk.tuosi.service.NewprocessImplementationService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import com.malk.tuosi.entity.NewprocessImplementation;
+
+@Slf4j
+@Service
+public class NewprocessImplementationServiceImpl extends ServiceImpl<NewprocessImplementationMapper,NewprocessImplementation> implements NewprocessImplementationService {
+
+}

+ 18 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/TaskServiceImpl.java

@@ -0,0 +1,18 @@
+package com.malk.tuosi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.tuosi.entity.Task;
+import com.malk.tuosi.mapper.TaskMapper;
+import com.malk.tuosi.service.TaskService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class TaskServiceImpl extends ServiceImpl<TaskMapper,Task> implements TaskService {
+}
+
+

+ 806 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/TbServiceImpl.java

@@ -0,0 +1,806 @@
+package com.malk.tuosi.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.malk.server.common.McException;
+import com.malk.server.common.McR;
+import com.malk.server.common.VenR;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.server.dingtalk.DDR_New;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Extension;
+import com.malk.tuosi.service.TBService;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+import com.sun.crypto.provider.PBEWithMD5AndDESCipher;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import lombok.var;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.io.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.net.URL;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class TbServiceImpl implements TBService {
+
+
+    /*TODO:TB获取应用token*/
+    @Override
+    public McR AppAccessToken() throws JsonProcessingException {
+        HashMap body = new HashMap();
+        body.put("appId","6874ba11d22c73565fd8af9d");
+        body.put("appSecret","4JBgPwpctG27SuZrVVeCrXoiVCjie9ID");
+        String doPost = UtilHttp.doPost("https://open.teambition.com/api/appToken",null,null,body);
+        // 使用 Fastjson 解析 JSON
+        JSONObject jsonObject = JSONObject.parseObject(doPost);
+        String appToken = jsonObject.getString("appToken");
+        log.info("Toke:{}",appToken);
+        return McR.success(appToken);
+    }
+
+    /*TODO:钉钉获取应用token*/
+    public McR Accesstoken() throws JsonProcessingException{
+        HashMap params = new HashMap();
+        params.put("appkey","dingtjgevp4t9vnlmpbj");
+        params.put("appsecret","Q3CzrNIj4HjON8buv4zClgpf-A0cW5uDRB5UtMHJHAHuQDj-g1nmq-h7EeYe_i5a");
+        String doGet = UtilHttp.doGet("https://oapi.dingtalk.com/gettoken", null, params);
+        JSONObject jsonObject = JSONObject.parseObject(doGet);
+        String accessToken = jsonObject.getString("access_token");
+        log.info("accessToken:{}",accessToken);
+        return McR.success(accessToken);
+    }
+
+    /*TODO:接收TB推送的数据*/
+    @SneakyThrows
+    @Override
+    public McR tbTaskUpdate(Map body) throws JsonProcessingException {
+        String s = JSON.toJSONString(body);
+        JSONObject jsonObject = JSON.parseObject(s);
+        String event = jsonObject.getString("event");
+        //一层过滤:过滤事件[任务自定义字段更新事件]
+        if (event.equals("v3.task.customfield.update")){
+            JSONObject data = jsonObject.getJSONObject("data");
+            System.out.println(data);
+            //二层过滤:过滤任务字段[只允许work类型字段类型生效]】
+            String customfieldId = data.getString("customfieldId");//自定义字段ID
+            // 1、版线组附件:6889f02fc74205217edfa65b 2、3D效果图:689d9834591915184b095e5f  3、白盒视频:6889c49443cbd3a23c9dc55f
+            //todo:版线组附件回传CRM
+            if(customfieldId.equals("6889f02fc74205217edfa65b") && data.getString("customfieldOldValue").equals("[]")){
+                log.info("第一次上传,版线组附件为空");
+                tbCallbackCRM(data);
+            }
+            String customfieldType = data.getString("customfieldType");//自定义字段类型
+            String taskId = data.getString("taskId");//任务id
+            if(customfieldType.equals("work")){
+                /*TODO:查询任务详情,字段值,获取metaString*/
+                HashMap head = new HashMap();
+                McR accessToken = AppAccessToken();
+                Object tokenData = accessToken.getData();
+                head.put("Authorization","Bearer " + tokenData);
+                head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+                head.put("X-Tenant-Type","organization");
+
+                HashMap param = new HashMap();
+                param.put("taskId",taskId);
+                String doGet = UtilHttp.doGet("https://open.teambition.com/api/v3/task/query", head, param);//查询任务详情
+                ObjectMapper objectMapper = new ObjectMapper();
+                JsonNode rootNode = objectMapper.readTree(doGet);
+                for(JsonNode resultNode : rootNode.path("result")){
+                    String content = resultNode.path("content").asText();//任务名称
+                    String customerName = "";//客户简称
+                    String manager = "";//节点负责人
+                    String designTime = "";//设计完成时间
+                    for(JsonNode customField : resultNode.path("customfields")) {
+                        String cfId = customField.path("cfId").asText();
+                        if ("68c23d6fee5aa63b8da58878".equals(cfId)) {
+                            JsonNode valueArray = customField.path("value");
+                            if (valueArray.isArray() && valueArray.size() > 0) {
+                                String dateTimeStr = valueArray.get(0).path("title").asText();
+                                // 解析UTC时间
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+                                sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+                                Date date = sdf.parse(dateTimeStr);
+                                // 直接格式化为本地时间(不需要加8小时)
+                                SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+                                designTime = outputFormat.format(date);
+                            }
+                        }
+                    }
+                    for(JsonNode customField : resultNode.path("customfields")){
+                        String cfId = customField.path("cfId").asText();
+                        if ("687df3b60ae1530fa2704499".equals(cfId)) {
+                            // 获取 value 数组中的第一个元素的 title
+                            JsonNode valueArray = customField.path("value");
+                            if (valueArray.isArray() && valueArray.size() > 0) {
+                                customerName = valueArray.get(0).path("title").asText();//客户简称
+                            }
+                        }else if ("66bb1a56f7e230ed6843796e".equals(cfId)){
+                            JsonNode valueArray = customField.path("value");
+                            if (valueArray.isArray() && valueArray.size() > 0) {
+                                manager = valueArray.get(0).path("title").asText();//节点负责人
+                            }
+                        } else if ("68c23d6fee5aa63b8da58878".equals(cfId)) {
+                            JsonNode valueArray = customField.path("value");
+                            if (valueArray.isArray() && valueArray.size() > 0) {
+                                String dateTimeStr = valueArray.get(0).path("title").asText();
+                                // 解析UTC时间
+                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+                                sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+                                Date date = sdf.parse(dateTimeStr);
+                                // 加上8小时(转换为北京时间)
+                                Calendar calendar = Calendar.getInstance();
+                                calendar.setTime(date);
+                                calendar.add(Calendar.HOUR_OF_DAY, 8);
+                                // 格式化为 "yyyy-MM-dd HH:mm"
+                                SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+                                designTime = outputFormat.format(calendar.getTime());//设计完成时间
+                            }
+                        }
+                        if(customfieldId.equals(cfId)){
+                            String writeValueAsString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(customField);
+                            //解析metaString中的resourceId(附件可能会上传多个,所以得遍历customfield里面的值)
+                            ObjectMapper mapper = new ObjectMapper();
+                            JsonNode node = mapper.readTree(writeValueAsString);
+                            JsonNode valueArray =  node.path("value");
+                            //检查value数组是否存在&不为空
+                            if(valueArray.isArray() && valueArray.size() > 0){
+                                List<String> allResourceIds = new ArrayList<>();
+                                List<String> allFileNames = new ArrayList<>();
+                                //遍历所有的value节点,收集resourceId和文件名title
+                                String resourceId = "";
+                                for (int i=0;i<valueArray.size();i++){
+                                    JsonNode valueNode = valueArray.get(i);
+                                    String metaString = valueNode.path("metaString").asText();
+                                    String title = valueNode.path("title").asText();
+
+                                    JsonNode metaJson = objectMapper.readTree(metaString);
+                                    resourceId = metaJson.path("resourceId").asText();
+                                    allResourceIds.add(resourceId);
+                                    allFileNames.add(title);
+                                }
+                                if(!allResourceIds.isEmpty()){
+                                    //根据resourceId获取文件详情 POST https://open.teambition.com/api/v3/file/query/by-resource-ids
+                                    HashMap haader = new HashMap();
+                                    haader.put("Content-Type", "application/json");
+                                    haader.put("Authorization", "Bearer " + tokenData);
+                                    haader.put("x-operator-id", "622ee3450cf3bb5e1a486f1f");
+                                    haader.put("X-Tenant-Id", "61a8c26719c3b5ffe9c4cffb");
+                                    haader.put("X-Tenant-Type", "organization");
+
+                                    HashMap boody = new HashMap();
+                                    boody.put("resourceIds",allResourceIds);
+                                    boody.put("needSign",true);
+
+                                    String fileDownloadResponse = UtilHttp.doPost("https://open.teambition.com/api/v3/file/query/by-resource-ids", haader, null, boody);
+
+                                    JSONObject response = JSON.parseObject(fileDownloadResponse);
+                                    JSONArray resultArray = response.getJSONArray("result");
+
+                                    if(resultArray != null && resultArray.size() > 0){
+                                        //todo:3D效果图放在新图案  白盒视频放在白盒库
+                                        String basedir = "";
+                                        String fileType = "";//附件类型:新图案(199256463063)、白盒(199256765924)
+                                        if(customfieldId.equals("689d9834591915184b095e5f")){
+                                            basedir = "C:/downloads/附件存储/新图案";
+                                            fileType = "199256463063";
+                                        }else if(customfieldId.equals("6889c49443cbd3a23c9dc55f")){
+                                            basedir = "C:/downloads/附件存储/白盒库";
+                                            fileType = "199256765924";
+                                        }else {
+                                            basedir = "C:/downloads/附件存储/其它";
+                                        }
+                                        List<String> successDownloads = new ArrayList<>();
+                                        List<String> failedDownloads = new ArrayList<>();
+                                        //遍历所有结果,下载每个文件(只需要拿到最新的内容即可)
+                                        for (int i=0;i< resultArray.size();i++) {
+                                            JSONObject fileObject = resultArray.getJSONObject(i);
+                                            String downloadUrl = fileObject.getString("downloadUrl");
+                                            //文件名称:设计完成时间-任务名称-客户简称-节点负责人-附件名称
+                                            String fileName = designTime + "_" + content + "_" + customerName + "_" + manager + "_" + fileObject.getString("fileName");
+                                                try {
+                                                    String savePath = downloadFile(downloadUrl, basedir, fileName);
+                                                    successDownloads.add(fileName + "->" + savePath);
+                                                    System.out.println("[文件本地存储成功][" + i + "]=====>" + fileName + "保存路径:" + savePath);
+                                                    /*TODO:钉盘文件存储一份*/
+                                                    System.out.println("[开始上传文件到钉盘]");
+                                                    uploadKnowledge(savePath, fileName,fileType);
+                                                } catch (IOException e) {
+                                                    failedDownloads.add(fileName + "->" + e.getMessage());
+                                                    System.out.println("[文件下载失败][" + i + "]=====>" + fileName + "错误信息:" + e.getMessage());
+                                                }
+                                        }
+
+                                    }else {
+                                        System.out.println("[警告]未找到任何文件下载信息");
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } else if (event.equals("v3.task.create")) {
+            JSONObject data = jsonObject.getJSONObject("data");
+            String sfcId = data.getString("sfcId");
+            if (sfcId.equals("6878b3c0669d175c3c6bc679") || sfcId.equals("6878b3ceb5ffcf500365d17a") || sfcId.equals("6878b3d8f40485da4c5f99a2")
+                || sfcId.equals("6878b39a27ae5f3cac355fb9") || sfcId.equals("6878b3a4090e6872fd6b78c6") || sfcId.equals("6878b3ad9e17ac8a027c6d37")
+                || sfcId.equals("68999dc2d1cb63e672e0b503") || sfcId.equals("68999dcf3071884859cacb87") || sfcId.equals("6878b3b60d49d89e7955726f")
+                || sfcId.equals("68999dd990de390188d8bee6")){
+                String taskId = data.getString("taskId");
+                HashMap header = new HashMap();
+                header.put("x-operator-id","622ee3450cf3bb5e1a486f1f");//xmy
+                McR Token = AppAccessToken();
+                Object token = Token.getData();
+                header.put("Authorization","Bearer " + token);
+                header.put("X-Tenant-type","organization");
+                header.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+                HashMap body_AAA = new HashMap();
+                String nodeId = null;
+                switch (sfcId){
+                    case "6878b3c0669d175c3c6bc679" :
+                        nodeId = "6875ba31ff8968791e009dad";
+                        break;
+                    case "6878b3ceb5ffcf500365d17a" :
+                        nodeId = "6875c12442b4476582041a90";
+                        break;
+                    case "6878b3d8f40485da4c5f99a2" :
+                        nodeId = "6875c736476bc6384b458cfa";
+                        break;
+                    case "6878b39a27ae5f3cac355fb9" :
+                        nodeId = "6875f3cf4b7eb5199098892c";
+                        break;
+                    case "6878b3a4090e6872fd6b78c6" :
+                        nodeId = "6875f5e40a12fb0d64feb1e2";
+                        break;
+                    case "6878b3ad9e17ac8a027c6d37" :
+                        nodeId = "6875f78e43d815a435aa9308";
+                        break;
+                    case "68999dc2d1cb63e672e0b503" :
+                        nodeId = "6880881feac3a8e8f6e3aead";
+                        break;
+                    case "68999dcf3071884859cacb87" :
+                        nodeId = "68808b96767bd365b1b7b6f5";
+                        break;
+                    case "6878b3b60d49d89e7955726f" :
+                        nodeId = "6874c857ad8265662925a6ae";
+                        break;
+                    case "68999dd990de390188d8bee6":
+                        nodeId = "6880912c9c778244636507f8";
+                        break;
+                }
+                body_AAA.put("nodeId",nodeId);
+                String doPut = UtilHttp.doPut(
+                        "https://open.teambition.com/api/v3/task/" + taskId + "/node/complete",
+                        header,
+                        null,
+                        body_AAA);
+                log.info("[创建任务自动更新确认流程]");
+            }
+        }else if (event.equals("v3.task.node.status.update")) {
+            /*群卡片推送*/
+            JSONObject data = jsonObject.getJSONObject("data");
+            String nodeId = data.get("nodeId").toString();
+            String taskId = data.get("taskId").toString();
+            if(("6875f58cf512415e5944c64c".equals(nodeId) || "6878a073eaa6f6ff736a5575".equals(nodeId)) && data.get("status").equals("finish")){//主管确认(1)  6875f58cf512415e5944c64c   主管确认(2)6878a073eaa6f6ff736a5575
+                /*设计单主管确认节点*/
+                List<String> allResourceIds = new ArrayList<>();//存储文件的ids
+                List<String>  downloadUrls= new ArrayList<>();//存储文件下载地址(原来的)
+                List<String> newdownloadUrls = new ArrayList<>();//卡片存储文件地址(新的)
+                /*所有的字段信息定义*/
+                String content = "";//todo:任务名称
+                List<String> involveMembers = new ArrayList<>();//todo:负责人
+                String businessManager = "";//todo:业务经理
+                String businessPerson = "";//todo:业务人员
+                String customerName = "";//todo:客户名称
+                String downloadUrl = "";
+                String valueAsString = "";//todo:文件下载地址(jsonString)
+
+                HashMap head = new HashMap();
+                McR accessToken = AppAccessToken();
+                Object tokenData = accessToken.getData();
+                head.put("Authorization","Bearer " + tokenData);
+                head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+                head.put("X-Tenant-Type","organization");
+                HashMap param = new HashMap();
+                param.put("taskId",taskId);
+                String doGet = UtilHttp.doGet("https://open.teambition.com/api/v3/task/query", head, param);//查询任务详情
+                ObjectMapper objectMapper = new ObjectMapper();
+                JsonNode rootNode = objectMapper.readTree(doGet);
+                JsonNode result = rootNode.path("result");
+                for(JsonNode resultNode : rootNode.path("result")){
+                    content = resultNode.path("content").asText();//todo:任务名称
+
+                    JsonNode customFields = resultNode.path("customfields");
+                    if (customFields.isArray()) {
+                        for (JsonNode field : customFields) {
+                            String cfId = field.path("cfId").asText();
+                            // 检查是否有 value 数组
+                            JsonNode valueArray = field.path("value");
+                            if (!valueArray.isArray() || valueArray.size() == 0) {
+                                continue;
+                            }
+                            // 获取第一个 value 对象
+                            JsonNode firstValue = valueArray.get(0);
+                            switch (cfId) {
+                                case "687df458b9c2f9f90865c13b": // todo:业务经理
+                                    businessManager = firstValue.path("title").asText();
+                                    System.out.println("业务经理: " + businessManager);
+                                    break;
+
+                                case "688191972ab6c4f412ea2bb9": // todo:业务人员
+                                    businessPerson = firstValue.path("title").asText();
+                                    System.out.println("业务人员: " + businessPerson);
+                                    break;
+
+                                case "687df3b60ae1530fa2704499": // todo:客户名称
+                                    customerName = firstValue.path("title").asText();
+                                    System.out.println("客户名称: " + customerName);
+                                    break;
+
+                                case "689d9834591915184b095e5f": // todo:附件 metaString
+                                    JsonNode valueArray1 = field.path("value");
+                                    if (valueArray1.isArray()) {
+                                        for (JsonNode attachment : valueArray) {
+                                            String metaString = attachment.path("metaString").asText();
+                                            String title = attachment.path("title").asText();
+                                            String director = title.substring(title.lastIndexOf("-") + 1, title.lastIndexOf("."));
+                                            involveMembers.add(director);
+                                            if (!metaString.isEmpty()) {
+                                                ObjectMapper mapper = new ObjectMapper();
+                                                JsonNode metaJson = mapper.readTree(metaString);
+                                                String resourceId = metaJson.path("resourceId").asText();
+                                                allResourceIds.add(resourceId);
+                                            }
+                                        }
+                                    }
+                                    HashMap haader = new HashMap();
+                                    haader.put("Content-Type", "application/json");
+                                    haader.put("Authorization", "Bearer " + tokenData);
+                                    haader.put("x-operator-id", "622ee3450cf3bb5e1a486f1f");
+                                    haader.put("X-Tenant-Id", "61a8c26719c3b5ffe9c4cffb");
+                                    haader.put("X-Tenant-Type", "organization");
+
+                                    HashMap boody = new HashMap();
+                                    boody.put("resourceIds",allResourceIds);
+                                    boody.put("needSign",true);
+
+                                    String fileDownloadResponse = UtilHttp.doPost("https://open.teambition.com/api/v3/file/query/by-resource-ids", haader, null, boody);
+                                    JSONObject response = JSON.parseObject(fileDownloadResponse);
+                                    JSONArray resultArray = response.getJSONArray("result");
+                                    for (int i=0;i< resultArray.size();i++) {
+                                        JSONObject fileObject = resultArray.getJSONObject(i);
+                                        downloadUrl = fileObject.getString("downloadUrl");
+                                        downloadUrls.add(downloadUrl);
+                                    }
+                                    System.out.println("下载地址" + downloadUrls);//原下载地址
+
+                                    //todo:把照片存在file目录下
+
+                                    if(resultArray != null && resultArray.size()>0){
+                                        String basedir = "file";
+                                        ArrayList successDownloads = new ArrayList();
+                                        ArrayList faileDownloads = new ArrayList();
+                                        for (int i=0;i<resultArray.size();i++){
+                                            JSONObject fileObject = resultArray.getJSONObject(i);//新下载地址
+                                            String downloadUrl1 = fileObject.getString("downloadUrl");
+                                            long millisTimestamp = System.currentTimeMillis();//当前时间戳
+                                            String fileName = millisTimestamp + "_" + fileObject.getString("fileName");
+                                            try{
+                                                String savePath = downloadFile(downloadUrl1,basedir,fileName);//TODO;存储图片至file目录下
+                                                successDownloads.add(fileName + "->" + savePath);
+                                                System.out.println("文件存储成功["+i+"]=====>"+fileName+"保存路径:"+savePath);
+                                                String newsavepath = "http://ounuo.raresoft.net:7880/file/"+fileName;
+                                                newdownloadUrls.add(newsavepath);
+                                            }catch (IOException e){
+                                                faileDownloads.add(fileName+"->"+e.getMessage());
+                                                System.out.println("文件下载失败["+i+"]=====>"+fileName+"错误信息:"+e.getMessage());
+                                            }
+                                        }
+                                    }
+
+                                    ObjectMapper mapper = new ObjectMapper();
+                                    // 使用Stream API创建List<Map<String, String>>
+                                    List<Map<String, String>> res = newdownloadUrls.stream()
+                                            .map(url -> {
+                                                Map<String, String> map = new LinkedHashMap<>(); // 保持顺序
+                                                map.put("arr", url);
+                                                return map;
+                                            })
+                                            .collect(Collectors.toList());
+                                    valueAsString = mapper.writeValueAsString(res);
+                                    System.out.println("格式化后的下载地址:" + valueAsString);
+                                    break;
+                            }
+                        }
+                    }
+                    System.out.println(); // 空行分隔
+                }
+                //组装数据卡片推送
+                // 业务经理=宁学刚推送至“郝总—节令—设计对接”cid2niI2sTPksK5PHpfrLgCPQ==   业务经理=姜华推送至“姜华—流通—设计对接”cid+J9H07847VNwIYiLpNay0Q==  业务经理=谷晨丹推送至“谷晨丹—烘焙—设计对接”cidqXtqGAN+Es7L/5m3uaZzSg==  业务经理=赵宇娟推送至"赵宇娟—烘焙—设计对接"cidaUtMTIjDHM60UXFfHegKtg==
+                JSONObject cardData = new JSONObject();
+                cardData.put("name_task", content);
+                cardData.put("designer", String.join(",", involveMembers));
+                cardData.put("name_person", businessManager + "," + businessPerson);
+                cardData.put("name_customer", customerName);
+                cardData.put("arr_picture", valueAsString);//todo:里面的每个需要转成jsonString类型
+                cardData.put("link","https://www.teambition.com/project/6878b323386fac7ab9dbe5e9/tasks/view/6878b323cc336006f34d1d22/task/"+taskId);
+                JSONObject message = new JSONObject();
+                message.put("cardData", cardData);
+                message.put("outTrackId", String.valueOf(System.currentTimeMillis()));
+                if("宁学刚".equals(businessManager)){
+                    message.put("openSpaceId", "dtv1.card//IM_GROUP.cid2niI2sTPksK5PHpfrLgCPQ==");
+                } else if ("姜华".equals(businessManager)) {
+                    message.put("openSpaceId", "dtv1.card//IM_GROUP.cid+J9H07847VNwIYiLpNay0Q==");
+                }else if ("赵宇娟".equals(businessManager)) {
+                    message.put("openSpaceId", "dtv1.card//IM_GROUP.cidaUtMTIjDHM60UXFfHegKtg==");
+                } else if ("陈晶".equals(businessManager) || "郝俊秀".equals(businessManager)) {
+                    message.put("openSpaceId", "dtv1.card//IM_GROUP.cidTppONwRCrkshRlCt28O+NA==");
+                }
+//                message.put("openSpaceId", "dtv1.card//IM_GROUP.cidTppONwRCrkshRlCt28O+NA==");//正式群id:cidTppONwRCrkshRlCt28O+NA==   测试群id:cidKoVDKhvynnj+73h0uxSJBA==
+                message.put("cardTemplateId", "160b26bf-d699-49fc-a6dc-9cd20eed7750.schema");
+                message.put("robotCode", "dinghhozexm92tupobfo");
+//                message.put("link","https://www.teambition.com/project/6878b323386fac7ab9dbe5e9/tasks/view/6878b323cc336006f34d1d22/task/" + taskId);
+                createAndDeliverCard(message);//调用卡片推送
+            }
+        }
+         return McR.success();
+    }
+
+    /*TODO:钉盘文件上传*/
+    @SneakyThrows
+    @Override
+    public McR uploadKnowledge(String pathName,String fileName,String fileType) throws JsonProcessingException {
+        /*TODO:step1:获取上传文件需要的resourceUrls和headers参数值*/
+        HashMap head = new HashMap();
+        McR accessToken = Accesstoken();
+        Object tokenData = accessToken.getData();
+        head.put("x-acs-dingtalk-access-token",tokenData);
+
+        HashMap params = new HashMap();
+        params.put("unionId","Vwt6seFpRYYCh1yj2BBTCwiEiE");
+
+        HashMap body = new HashMap();
+        body.put("protocol","HEADER_SIGNATURE");//默认
+        body.put("multipart",false);//5G以下文件,设为false
+        DDR_New deptDDR  = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/27116552652/files/uploadInfos/query", head, params, body, DDR_New.class);
+        Map headerSignatureInfo = deptDDR.getHeaderSignatureInfo();
+        /*TODO:step2:使用OSS的header加签方式上传文件*/
+        List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
+        //从接口中获取到resourceUrl
+        String resourceUrl = resourceUrls.get(0);
+        //从接口中获取到headers
+        Map<String, String> headers = (Map<String, String>) headerSignatureInfo.get("headers");
+        URL url = new URL(resourceUrl);
+        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+        if (headers != null) {
+            for (Map.Entry<String, String> entry : headers.entrySet()) {
+                connection.setRequestProperty(entry.getKey(), entry.getValue());
+            }
+        }
+        connection.setDoOutput(true);
+        connection.setRequestMethod("PUT");
+        connection.setUseCaches(false);
+        connection.setReadTimeout(10000);
+        connection.setConnectTimeout(10000);
+        connection.connect();
+        OutputStream out = connection.getOutputStream();
+        InputStream is = new FileInputStream(new File(pathName));
+        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("上传失败");
+        }
+        /*TODO:step3:调用提交文件接口,完成文件上传*/
+        HashMap param = new HashMap();
+        param.put("unionId","Vwt6seFpRYYCh1yj2BBTCwiEiE");
+
+        HashMap boddy = new HashMap();
+        String uploadKey = deptDDR.getUploadKey();
+        boddy.put("uploadKey",uploadKey);//添加文件唯一标识uploadKey
+        boddy.put("name",fileName);//文件的名称,带后缀
+        boddy.put("parentId",fileType);//父目录Id====> 白盒库:199256765924    新图案:199256463063
+
+        HashMap header = new HashMap();
+        header.put("x-acs-dingtalk-access-token",tokenData);
+        String post = UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/27116552652/files/commit", header, param, boddy);
+        return McR.success(post);
+    }
+
+    /*TODO:版线组位置附件上传CRM*/
+    @Override
+    public McR tbCallbackCRM(Map body) throws JsonProcessingException {
+        String s = JSON.toJSONString(body);
+        //解析参数拿到taskIda
+        JSONObject object = JSON.parseObject(s);
+        String taskId = object.getString("taskId");//任务id
+        String customfieldId = object.getString("customfieldId");//自定义字段id
+        //获取回传CRM中的crmid  metaString(若有)
+        HashMap head = new HashMap();
+        McR accessToken = AppAccessToken();
+        Object tokenData = accessToken.getData();
+        head.put("Authorization","Bearer " + tokenData);
+        head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+        head.put("X-Tenant-Type","organization");
+        HashMap param = new HashMap();
+        param.put("taskId",taskId);
+        String doGet = UtilHttp.doGet("https://open.teambition.com/api/v3/task/query", head, param);
+        JSONObject responseJson = JSON.parseObject(doGet);
+        JSONArray resultArray = responseJson.getJSONArray("result");
+        String crmid = null;
+        String metaString = null;
+        String resourceId = null;
+        List<String> resourceIds_AAA = new ArrayList<>();
+        if(resultArray != null && !resultArray.isEmpty()){
+            JSONObject task = resultArray.getJSONObject(0);
+            JSONArray customFields = task.getJSONArray("customfields");
+            if(customFields != null){
+                for (int i = 0; i < customFields.size(); i++) {
+                    JSONObject field = customFields.getJSONObject(i);
+                    String cfId = field.getString("cfId");
+                    if("689d4ebf343c05fe73700c93".equals(cfId)){//CRM单据ID
+                        JSONArray valueArray = field.getJSONArray("value");
+                        if(valueArray != null && !valueArray.isEmpty()){
+                            JSONObject firstValue = valueArray.getJSONObject(0);
+                            crmid = firstValue.getString("title");
+                        }
+                    }
+
+                    if("6889f02fc74205217edfa65b".equals(cfId)){//版线位置附件
+                        JSONArray array = field.getJSONArray("value");
+                        if(array != null && !array.isEmpty()){
+                            for (int j = 0; j < array.size(); j++) {
+                                JSONObject firstValue1 = array.getJSONObject(j);
+                                metaString =firstValue1.getString("metaString");
+                                JSONObject jsonObject = JSON.parseObject(metaString);
+                                resourceId  = jsonObject.getString("resourceId");
+                            }
+                            resourceIds_AAA.add(resourceId);
+                        }
+                    }
+
+                }
+            }
+        }
+        //获取当前变更时间 202x-0x-xx xx:xx:xx
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String jssj = now.format(formatter);
+        //获取文件downloadurl(若有) 1、查询任务详情(拿到metaString)  2、获取文件下载URL
+        String done = null;
+        if(!metaString.isEmpty()){
+            HashMap header = new HashMap();
+            McR Token = AppAccessToken();
+            Object token = Token.getData();
+            header.put("Authorization","Bearer " + token);
+            header.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+            header.put("X-Tenant-Type","organization");
+            HashMap bodyy = new HashMap();
+            bodyy.put("needSign",true);
+            bodyy.put("resourceIds",resourceIds_AAA);
+            String post = UtilHttp.doPost("https://open.teambition.com/api/v3/file/query/by-resource-ids", header, null, bodyy);
+            String downloadURL = JSON.parseObject(post).getJSONArray("result").getJSONObject(0).getString("downloadUrl");
+            //获取文件名称
+            String fileName = JSON.parseObject(post).getJSONArray("result").getJSONObject(0).getString("fileName");
+            //TODO:调用TB回传CRM接口
+            //构建请求头
+            HashMap headers = new HashMap();
+            headers.put("crmuserid","620131c2fe8d7eb6b8dfbf76");//tb的userid(固定是张昆)
+            headers.put("TargetSystem","CRM");//固定值
+            //构建params参数
+            HashMap params = new HashMap();
+            params.put("crmid",crmid);
+            params.put("jssj",jssj);
+            params.put("bxwz",downloadURL);
+            params.put("bxwzsname",fileName);
+            //构建body参数
+            HashMap bodys = new HashMap();
+            bodys.put("params",params);
+            done = UtilHttp.doPost("http://ounuo.ip.raresoft.net:8888/api/dd/selfchange", headers, null, bodys);
+        }
+
+        return McR.success(done);
+    }
+
+    @Autowired
+    private DDConf ddConf;
+    @Autowired
+    private DDClient ddClient;
+
+    @Override
+    public McR oaCallbackTB(Map body) throws JsonProcessingException {
+        //获取单个审批实例详情
+        HashMap params_AAA = new HashMap();
+        params_AAA.put("appkey","dingi61ncsi1zjo7eosp");
+        params_AAA.put("appsecret","unvpxWgDeYEokuUlD-4iyDh0NdRH3NRKE1OkDF8VPQwyYi0Nuo_uXTWBYxnKYJaI");
+        String doGet = UtilHttp.doGet("https://oapi.dingtalk.com/gettoken", null, params_AAA);
+        JSONObject jsonObject_AAA = JSONObject.parseObject(doGet);
+        String accessToken = jsonObject_AAA.getString("access_token");
+
+        HashMap head_AAA = new HashMap();
+        head_AAA.put("x-acs-dingtalk-access-token",accessToken);
+        HashMap params = new HashMap();
+        String InstanceId = body.get("InstanceId").toString();
+        params.put("processInstanceId",InstanceId);
+        String s = UtilHttp.doGet("https://api.dingtalk.com/v1.0/workflow/processInstances", head_AAA, params);
+        JSONObject jsonObject = JSON.parseObject(s);
+        JSONObject jsonObject1 = jsonObject.getJSONObject("result");
+        JSONArray jsonArray = jsonObject1.getJSONArray("operationRecords");
+        String remark = "";
+        for (int i = 0; i < jsonArray.size(); i++) {
+            JSONObject jsonObject2 = jsonArray.getJSONObject(i);
+            String type = jsonObject2.getString("type");
+            String s1 = jsonObject2.getString("remark");
+            if (type.equals("ADD_REMARK") && s1.contains("发起审批的 Teambition 任务")){
+                remark = jsonObject2.getString("remark");
+            }
+        }
+        //截取remark中()的内容
+        String remarkStr111 = remark.substring(remark.indexOf("(") + 1, remark.indexOf(")"));
+        String remarkStr222 = "";
+        try {
+            remarkStr222 = URLDecoder.decode(remarkStr111, "UTF-8");
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        String remarkStr333 = "";
+        try {
+            remarkStr333 = URLDecoder.decode(remarkStr222, "UTF-8");
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        //获取链接中的tasks/后?前的参数
+        String strStart = "tasks/";
+        String endStart = "?isDingtalkHeaderHidden";
+        String taskId = remarkStr333.substring(remarkStr333.indexOf(strStart) + 6, remarkStr333.lastIndexOf(endStart));
+        //更新任务
+        double value = 0;
+        String name = "";
+        JSONArray array = jsonObject1.getJSONArray("formComponentValues");
+        for (int j=0;j<array.size();j++){
+            JSONObject object = array.getJSONObject(j);
+            name = object.getString("name");
+            if(name.equals("版费总价")){
+                value = object.getDoubleValue("value");
+            }
+        }
+        HashMap head = new HashMap();
+        head.put("x-operator-id","622ee3450cf3bb5e1a486f1f");
+        McR Token = AppAccessToken();
+        Object tok = Token.getData();
+        head.put("Authorization","Bearer " + tok);
+        head.put("X-Tenant-type","organization");
+        head.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+        String finalName = name;
+        double finalValue = value;
+        HashMap<String,Object> bodyy =  new HashMap<String,Object>(){{
+           put("customfieldName", finalName);
+           put("value",Collections.singletonList(
+                   new HashMap<String,String>() {{
+                       put("title", String.valueOf(finalValue));
+                   }}
+           ));
+        }};
+        String s1 = UtilHttp.doPost("https://open.teambition.com/api/v3/task/" + taskId + "/customfield/update", head, null, bodyy);
+        return McR.success(s1);
+    }
+
+    @Override
+    public String TBtoDinguserId(List list) throws JsonProcessingException {
+        System.out.println(list);
+        HashMap header = new HashMap();
+        McR accessToken = AppAccessToken();
+        Object tokenData = accessToken.getData();
+        header.put("Authorization","Bearer " + tokenData);
+        header.put("X-Tenant-type","organization");
+        header.put("X-Tenant-Id","61a8c26719c3b5ffe9c4cffb");
+        HashMap param = new HashMap();
+        param.put("tbUserIds",list);
+        String s = UtilHttp.doGet("https://open.teambition.com/api/idmap/dingtalk/getDingUserId", header, param);
+        ObjectMapper objectMapper = new ObjectMapper();
+        var rootNode = objectMapper.readTree(s);
+        List<String> userIdList  = objectMapper.convertValue(
+                        rootNode.get("result"),
+                        new TypeReference<List<Map<String, String>>>() {
+                        }
+                )
+                .stream()
+                .map(map -> map.get("dingtalkUserId"))
+                .collect(Collectors.toList());
+        //开始处理userid查询用户名称
+        HashMap params = new HashMap();
+        McR Token = Accesstoken();
+        Object Data = Token.getData();
+        params.put("access_token",Data);
+        HashMap body = new HashMap();
+        List<String> nameList  = new ArrayList<>();
+        String result = "";
+        for (String str : userIdList){
+            body.put("userid",str);
+            String doPost = UtilHttp.doPost("https://oapi.dingtalk.com/topapi/v2/user/get", null, params, body);
+            ObjectMapper objectmapper = new ObjectMapper();
+            String username = objectMapper.readTree(doPost)
+                    .path("result")
+                    .path("name")
+                    .asText();
+            nameList.add(username);
+            result = nameList.stream()
+                    .collect(Collectors.joining(","));
+        }
+        return result;
+    }
+
+    //文件存储方法
+    /**
+     * 下载文件到本地(自定义文件名)
+     * param fileUrl 文件下载URL
+     * param baseDir 基础存储目录
+     * param customFileName 自定义文件名(不含扩展名)
+     * return 下载后的文件绝对路径
+*/    public static String downloadFile(String fileUrl,String baseDir,String customFileName) throws IOException{
+        // 创建基础目录
+        File baseDirectory = new File(baseDir);
+        if (!baseDirectory.exists()) {
+            baseDirectory.mkdirs();
+        }
+
+        // 完整的保存路径
+        String savePath = new File(baseDir, customFileName).getAbsolutePath();
+
+        // 下载文件
+        URL url = new URL(fileUrl);
+        URLConnection connection = url.openConnection();
+        try (InputStream in = connection.getInputStream();
+             FileOutputStream out = new FileOutputStream(savePath)) {
+
+            byte[] buffer = new byte[4096];
+            int bytesRead;
+            while ((bytesRead = in.read(buffer)) != -1) {
+                out.write(buffer, 0, bytesRead);
+            }
+        }
+        return savePath;
+    }
+
+
+    @Autowired
+    private DDClient_Extension ddClientExtension;
+    /*群消息卡片推送*/
+    public McR createAndDeliverCard(@RequestBody JSONObject param){
+        log.info("推送消息:{}",param);
+        McException.assertParamException_Null(param,"cardData","outTrackId","openSpaceId","robotCode","cardTemplateId");
+        Map<String,Object> data = new HashMap();
+        data.put("imGroupOpenDeliverModel", UtilMap.map("robotCode",param.getString("robotCode")));
+        data.put("imGroupOpenSpaceModel",UtilMap.map("supportForward",true));
+        if(param.containsKey("extInfo")){
+            data.putAll(param.getJSONObject("extInfo"));
+        }
+        Map map = ddClientExtension.createAndDeliverCards(ddClient.getAccessToken(),param.getString("cardTemplateId"),param.getString("outTrackId"),
+                UtilMap.map("cardParamMap",param.getJSONObject("cardData")),param.getString("openSpaceId"),data);
+        return McR.success(map);
+    }
+
+}

+ 9 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/service/impl/YearPersonalConfirmServiceImpl.java

@@ -0,0 +1,9 @@
+package com.malk.tuosi.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.malk.tuosi.entity.YearPersonalConfirm;
+import com.malk.tuosi.mapper.YearPersonalConfirmMapper;
+import com.malk.tuosi.service.YearPersonalConfirmService;
+
+public class YearPersonalConfirmServiceImpl extends ServiceImpl<YearPersonalConfirmMapper, YearPersonalConfirm> implements YearPersonalConfirmService {
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 263 - 0
mjava-ounuo/src/main/java/com/malk/tuosi/test/test.java


+ 114 - 0
mjava-ounuo/src/main/resources/application-dev.yml

@@ -0,0 +1,114 @@
+# 环境配置
+server:
+  port: 8082
+  servlet:
+    context-path: /api/ounuo
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+#spring:
+#  # database
+#  datasource:
+##      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+#    driver-class-name: com.mysql.cj.jdbc.Driver
+#    username: ounuo_user
+#    password: OUNUO123!
+#    url: jdbc:mysql://ounuo.raresoft.net:33306/TASK
+#  jpa:
+#    hibernate:
+#      ddl-auto: none
+#    show-sql: true
+#    database: oracle
+#  hikari:
+#    pool-name: DateHikariCP
+#    minimum-idle: 0
+#    maximum-pool-size: 10
+#    idle-timeout: 30000
+#    max-lifetime: 120000          # 小于数据库超时大于业务执行返回时间[hikari默认30m, mysql默认10m]
+#    connection-timeout: 30000     # 数据库连接超时时间,默认30秒,即30000
+
+spring:
+  datasource:
+    url: jdbc:mysql://47.110.74.198:3306/ounuo?useSSL=false&serverTimezone=Asia/Shanghai
+    username: root
+    password: cp-root@2022++
+    hikari:
+      # 检测连接是否有效的 SQL(每次从连接池获取连接时执行)
+      connection-test-query: SELECT 1
+      # 或使用更标准的 JDBC4 isValid()(推荐)
+      # connection-test-query 不需要设置,Hikari 默认用 isValid()
+
+      # 连接最大存活时间(必须 < MySQL 的 wait_timeout,建议 30 分钟)
+      max-lifetime: 1800000  # 30分钟
+
+      # 空闲连接超时(小于 max-lifetime)
+      idle-timeout: 600000   # 10分钟
+
+      # 从连接池获取连接的超时时间
+      connection-timeout: 30000 # 30秒
+
+      # 最小空闲连接数
+      minimum-idle: 5
+
+
+
+  #    # 主库
+#    primary:
+#      username: root
+#      password: mu123
+#      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#    # 从库
+#    slave:
+#      username: root
+#      password: mu123
+#      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava_slave?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+#  jpa:
+#    hibernate:
+#      ddl-auto: none      # JPA对表没有任何操作
+#    show-sql: true
+#    database: ORACLE
+#    database-platform: org.hibernate.dialect.Oracle12cDialect
+
+# 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
+  level:
+    com.malk.*: debug
+
+# dingtalk 钉钉
+dingtalk:
+  agentId: 4115325431
+  appKey: dinghhozexm92tupobfo
+  appSecret: -zYNwc4j9hssiP0mTNbSe0D9v9ejh4OIaHnx_EhVZWJbwnatvgtNiSFPIwAg9AGb
+  corpId: ding2af339267563330e4ac5d6980864d335
+  aesKey:
+  token:
+  operator: 332051151139376769   # OA管理员账号:鲜明阳 [0开头需要转一下字符串]
+
+# aliwork 宜搭
+aliwork:
+  appType: APP_VCTRP6227CC8368NDOID
+  systemToken: 5H9662C1X8XJLFFCE841M5VBEBQ73DM5IBPULPI3
+
+# MyBatisplus配置
+mybatis-plus:
+  mapper-locations: classpath:mapper/*.xml  # mapper.xml存放路径
+  type-aliases-package: com.malk.tuosi.entity  # 实体类包路径
+  configuration:
+    # 开启下划线转驼峰(默认就是true,但明确配置一下)
+    map-underscore-to-camel-case: true
+
+#定时器
+enable:
+  scheduling: true

+ 99 - 0
mjava-ounuo/src/main/resources/application-prod.yml

@@ -0,0 +1,99 @@
+# 环境配置
+server:
+  port: 7879
+  servlet:
+    context-path: /api/ounuo
+
+# 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: ounuo_user
+#    password: OUNUO123!
+#    url: jdbc:mysql://ounuo.raresoft.net:33306/TASK
+
+spring:
+  datasource:
+    url: jdbc:mysql://47.110.74.198:3306/ounuo?useSSL=false&serverTimezone=Asia/Shanghai
+    username: root
+    password: cp-root@2022++
+    hikari:
+      # 检测连接是否有效的 SQL(每次从连接池获取连接时执行)
+      connection-test-query: SELECT 1
+      # 或使用更标准的 JDBC4 isValid()(推荐)
+      # connection-test-query 不需要设置,Hikari 默认用 isValid()
+
+      # 连接最大存活时间(必须 < MySQL 的 wait_timeout,建议 30 分钟)
+      max-lifetime: 1800000  # 30分钟
+
+      # 空闲连接超时(小于 max-lifetime)
+      idle-timeout: 600000   # 10分钟
+
+      # 从连接池获取连接的超时时间
+      connection-timeout: 30000 # 30秒
+
+      # 最小空闲连接数
+      minimum-idle: 5
+
+
+  #    # 主库
+  #    primary:
+  #      username: root
+  #      password: mu123
+  #      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  #    # 从库
+  #    slave:
+  #      username: root
+  #      password: mu123
+  #      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava_slave?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    hibernate:
+      ddl-auto: none      # JPA对表没有任何操作
+    show-sql: true
+    database: ORACLE
+    database-platform: org.hibernate.dialect.Oracle12cDialect
+
+# 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: 4115325431
+  appKey: dinghhozexm92tupobfo
+  appSecret: -zYNwc4j9hssiP0mTNbSe0D9v9ejh4OIaHnx_EhVZWJbwnatvgtNiSFPIwAg9AGb
+  corpId: ding2af339267563330e4ac5d6980864d335
+  aesKey:
+  token:
+  operator: 332051151139376769   # OA管理员账号:鲜明阳 [0开头需要转一下字符串]
+
+# aliwork 宜搭
+aliwork:
+  appType: APP_VCTRP6227CC8368NDOID
+  systemToken: 5H9662C1X8XJLFFCE841M5VBEBQ73DM5IBPULPI3
+
+# MyBatisplus配置
+mybatis-plus:
+  mapper-locations: classpath:mapper/*.xml  # mapper.xml存放路径
+  type-aliases-package: com.malk.tuosi.entity  # 实体类包路径
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印SQL日志(可选)
+
+#定时器
+enable:
+  scheduling: true

+ 3 - 0
mjava-ounuo/src/main/resources/application.yml

@@ -0,0 +1,3 @@
+spring:
+  profiles:
+    active: dev