lfx 1 ヶ月 前
コミット
aa816d6656
共有37 個のファイルを変更した5149 個の追加4 個の削除を含む
  1. 54 0
      mjava-poc/pom.xml
  2. 32 0
      mjava-poc/src/main/java/com/malk/poc/Boot.java
  3. 72 0
      mjava-poc/src/main/java/com/malk/poc/controller/PLController.java
  4. 21 0
      mjava-poc/src/main/java/com/malk/poc/controller/TBController.java
  5. 641 0
      mjava-poc/src/main/java/com/malk/poc/controller/TBxYDController.java
  6. 53 0
      mjava-poc/src/main/java/com/malk/poc/delegate/TBDelegate.java
  7. 87 0
      mjava-poc/src/main/java/com/malk/poc/schedule/AWScheduleTask.java
  8. 71 0
      mjava-poc/src/main/java/com/malk/poc/server/AWServer.java
  9. 88 0
      mjava-poc/src/main/java/com/malk/poc/server/YDSearch.java
  10. 132 0
      mjava-poc/src/main/java/com/malk/poc/service/AWClint.java
  11. 59 0
      mjava-poc/src/main/java/com/malk/poc/service/AWYDClient.java
  12. 9 0
      mjava-poc/src/main/java/com/malk/poc/service/AwDingService.java
  13. 13 0
      mjava-poc/src/main/java/com/malk/poc/service/GZT_PN.java
  14. 2166 0
      mjava-poc/src/main/java/com/malk/poc/service/impl/AWImplClient.java
  15. 1018 0
      mjava-poc/src/main/java/com/malk/poc/service/impl/AWYDImplClient.java
  16. 79 0
      mjava-poc/src/main/java/com/malk/poc/service/impl/AwDingServiceImpl.java
  17. 120 0
      mjava-poc/src/main/java/com/malk/poc/service/impl/GZT_PNImpl.java
  18. 70 0
      mjava-poc/src/main/resources/application-dev.yml
  19. 45 0
      mjava-poc/src/main/resources/application-prod.yml
  20. BIN
      mjava-poc/src/main/resources/templates/templates_checked_list.xlsx
  21. BIN
      mjava-poc/src/main/resources/templates/templates_project_requirements.xlsx
  22. BIN
      mjava-poc/src/main/resources/templates/templates_project_requirements_exception.xlsx
  23. BIN
      mjava-poc/src/main/resources/templates/templates_project_requirements_test.xlsx
  24. BIN
      mjava-poc/src/main/resources/templates/templates_project_specification.xlsx
  25. BIN
      mjava-poc/src/main/resources/templates/templates_project_specification_exception.xlsx
  26. BIN
      mjava-poc/src/main/resources/templates/templates_test_specification.xlsx
  27. BIN
      mjava-poc/src/main/resources/templates/templates_test_specification_exception.xlsx
  28. BIN
      mjava-poc/src/main/resources/templates/templates_xqrk.xlsx
  29. BIN
      mjava-poc/src/main/resources/templates/templates_xqwh.xlsx
  30. BIN
      mjava-poc/src/main/resources/templates/templates_xqwh_result.xlsx
  31. 91 0
      mjava-poc/src/test/java/com/malk/poc/AwTbTest.java
  32. 87 0
      mjava-poc/src/test/java/com/malk/poc/DataHandingTest.java
  33. 58 0
      mjava-poc/src/test/java/testLocal.java
  34. 35 0
      mjava-poc/src/test/resources/server.sh
  35. 19 0
      mjava/src/main/java/com/malk/service/teambition/TBClient.java
  36. 28 4
      mjava/src/main/java/com/malk/service/teambition/impl/TBClientImpl.java
  37. 1 0
      pom.xml

+ 54 - 0
mjava-poc/pom.xml

@@ -0,0 +1,54 @@
+<?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-ipd</artifactId>
+        <groupId>com.malk</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>mjava-poc</artifactId>
+    <description>poc, TBx宜搭</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>
+    </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>

+ 32 - 0
mjava-poc/src/main/java/com/malk/poc/Boot.java

@@ -0,0 +1,32 @@
+package com.malk.poc;
+
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+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"})
+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);
+    }
+}

+ 72 - 0
mjava-poc/src/main/java/com/malk/poc/controller/PLController.java

@@ -0,0 +1,72 @@
+package com.malk.poc.controller;
+
+
+import com.malk.poc.service.GZT_PN;
+import com.malk.server.common.McException;
+import com.malk.server.common.McR;
+import com.malk.utils.UtilServlet;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping("pl")
+public class PLController {
+
+    @Autowired
+    private GZT_PN gzt_pn;
+
+    /**
+     * jsApi 注册
+     */
+    @PostMapping("register")
+    McR register(@RequestBody Map<String, String> data) {
+
+        McException.assertParamException_Null(data, "url", "nonceStr");
+        return McR.success(gzt_pn.register(data));
+    }
+
+    /**
+     * 工作台数据 - 资讯中心
+     */
+    @PostMapping("portal/ZXZX")
+    List<Map> portal_ZXZZ(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("工作台数据, {}", data);
+        return gzt_pn.getPortalList("派能资讯");
+    }
+
+    @PostMapping("portal/NLPS")
+    List<Map> portal_NLPS(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("工作台数据, {}", data);
+        return gzt_pn.getPortalList("能量派送");
+    }
+
+    @PostMapping("portal/RZZX")
+    List<Map> portal_RZZX(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("工作台数据, {}", data);
+        return gzt_pn.getPortalList("人资资讯");
+    }
+
+    @PostMapping("portal/NBZX")
+    List<Map> portal_NBZX(HttpServletRequest request) {
+
+        Map data = UtilServlet.getParamMap(request);
+        log.info("工作台数据, {}", data);
+        return gzt_pn.getPortalList("内部资讯");
+    }
+
+}

+ 21 - 0
mjava-poc/src/main/java/com/malk/poc/controller/TBController.java

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

File diff suppressed because it is too large
+ 641 - 0
mjava-poc/src/main/java/com/malk/poc/controller/TBxYDController.java


+ 53 - 0
mjava-poc/src/main/java/com/malk/poc/delegate/TBDelegate.java

@@ -0,0 +1,53 @@
+package com.malk.poc.delegate;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.poc.service.AWClint;
+import com.malk.delegate.TBEvent;
+import lombok.SneakyThrows;
+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 TBDelegate implements TBEvent {
+
+    @Autowired
+    private AWClint awClint;
+
+    @Async
+    @Override
+    @SneakyThrows
+    public void callBackTask(JSONObject eventJson) {
+        String eventName = eventJson.getString("event");
+        log.info("callBackTask, {}, {}", eventName, eventJson);
+
+        if ("v3.task.taskflowstatus.update".equals(eventName)) {
+            JSONObject data = eventJson.getJSONObject("data");
+            awClint.taskLevelValidate(data);
+            awClint.doApprove(data, false);
+        } else if ("v3.task.customfield.update".equals(eventName)) {
+            JSONObject data = eventJson.getJSONObject("data");
+            System.out.println("1" + JSONObject.toJSONString(data));
+            awClint.custFieldUpdate(data);
+        }
+    }
+
+    @Async
+    @Override
+    @SneakyThrows
+    public void callBackProject(JSONObject eventJson) {
+        String eventName = eventJson.getString("event");
+        log.info("callBackProject, {}", eventJson);
+    }
+
+}

+ 87 - 0
mjava-poc/src/main/java/com/malk/poc/schedule/AWScheduleTask.java

@@ -0,0 +1,87 @@
+//package com.malk.poc.schedule;
+//
+//import com.malk.poc.service.AWClint;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.scheduling.annotation.EnableScheduling;
+//import org.springframework.scheduling.annotation.Scheduled;
+//
+///**
+// * @EnableScheduling 开启定时任务 [配置参考McScheduleTask]
+// */
+//@Slf4j
+//@Configuration
+//@EnableScheduling
+//@ConditionalOnProperty(name = {"spel.scheduling"})
+//public class AWScheduleTask {
+//
+//    @Autowired
+//    private AWClint awClint;
+//
+//    /**
+//     * 每天12.30,00.30点同步, 项目主数据
+//     */
+//    @Scheduled(cron = "0 30 0,12 * * ? ")
+//    public void sync_4() {
+//        try {
+//            awClint.syncProject(null);
+//        } catch (Exception e) {
+//            // 记录错误信息
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    /**
+//     * 每天凌晨1点同步, 预检项
+//     */
+//    @Scheduled(cron = "0 0 1 * * ? ")
+//    public void sync_1() {
+//        try {
+//            awClint.syncCheckList(0);
+//        } catch (Exception e) {
+//            // 记录错误信息
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    /**
+//     * 每天凌晨1.30点同步. 预检项
+//     */
+//    @Scheduled(cron = "0 30 1 * * ? ")
+//    public void sync_2() {
+//        try {
+//            awClint.syncCheckList(1);
+//        } catch (Exception e) {
+//            // 记录错误信息
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    /**
+//     * 每天凌晨2点同步, 预检项
+//     */
+//    @Scheduled(cron = "0 0 2 * * ? ")
+//    public void sync_3() {
+//        try {
+//            awClint.syncCheckList(2);
+//        } catch (Exception e) {
+//            // 记录错误信息
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    /**
+//     * 每天20点同步, 全量同步CRM
+//     */
+//    @Scheduled(cron = "0 0 20 * * ? ")
+//    public void sync_5() {
+//        try {
+//            awClint.syncBaseLineForCRM();
+//        } catch (Exception e) {
+//            // 记录错误信息
+//            e.printStackTrace();
+//        }
+//    }
+//}

+ 71 - 0
mjava-poc/src/main/java/com/malk/poc/server/AWServer.java

@@ -0,0 +1,71 @@
+package com.malk.poc.server;
+
+import com.alibaba.fastjson.JSON;
+import com.malk.utils.UtilHttp;
+import com.malk.utils.UtilMap;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AWServer {
+
+    /**
+     * 任务卡片字段名称
+     */
+    public static final String TASK_ROLE = "PDT代表"; // 资源名称
+    public static final String TASK_CODE = "任务编号";
+    public static final String TASK_STAGE = "项目阶段";
+    public static final String TASK_STAGE_BLANK = "无TR评审节点";
+    public static final String TASK_PRODUCT = "产品型号";
+    public static final String TASK_PRODUCT_VERSION = "产品版本";
+    public static final String TASK_WAFER = "wafer";
+
+    public static final String TASK_TRANSMIT = "下达状态";
+
+    // prd 23.02.29 字段从 预检项 变更为 技术检查项
+    public static final String TASK_CHECK_LINK = "技术检查项";
+    public static final String TASK_CHECK_STATUS = "技术检查项检查状态";
+
+    // prd 7.17 技术检查项确认状态
+    public static final String TASK_CHECK_LINK_OK = "技术检查确认";
+
+    public static final String TASK_APPROVE_ATTACHMENT = "交付件";
+    public static final String TASK_APPROVE_VERSION = "交付件版本";
+    public static final String TASK_APPROVE_LINK = "交付件审批流程";
+    public static final String TASK_APPROVE_STATE = "变更状态";
+    public static final String TASK_APPROVE_DESC = "交付件描述";
+
+    // prd 8.6 产品型号、版本选择添加字段
+    public static final String SELECT_TASK_PRODUCT = "选择产品型号";
+    public static final String SELECT_TASK_PRODUCT_VERSION = "选择产品版本";
+
+    // ppExt: 注意不同任务类型名称唯一性, 如通用已完成不要使用
+    public static final String WORKFLOW_APPROVE = "已提交";
+    public static final List<String> WORKFLOW_INITIAL = Arrays.asList("未开始");
+
+    public static final String PROJECT_PM_ROLE = "项目管理员";
+    public static final String PROJECT_PM_NAME = "项目经理";
+
+    // 预检项不加载白名单 [项目模板/供复制项目]
+    public static final List<String> PROJECT_IGNORE_ID = Arrays.asList(
+            "65fac2fc386eb113f1adac83", // ak类正式模板
+            "65fac3af386eb113f1adacc0", // ak类迁移模板
+            "65f269605a2065ad7ad65d18"  // ak类复制项目
+    );
+
+    /**
+     * 艾为网关接口
+     */
+    private static final String appKey = "AW394034j";
+    private static final String secret = "RJbH7RMH3vllt4KDri303Mlw@df3434k";
+
+    public static String getToken() {
+
+        Map body = UtilMap.map("appKey, secret", appKey, secret);
+        String rsp = UtilHttp.doPost("https://apigateway.awinic.com/token/getToken", null, body, new HashMap());
+        Map result = (Map) JSON.parse(rsp);
+        return UtilMap.getString(result, "token");
+    }
+}

+ 88 - 0
mjava-poc/src/main/java/com/malk/poc/server/YDSearch.java

@@ -0,0 +1,88 @@
+package com.malk.poc.server;
+
+import lombok.Data;
+
+@Data
+public class YDSearch {
+
+    // YidaSearch yidaSearch=new YidaSearch("textField_lk7v5k5f",contract.getContractNo(),"同步合同档案台账", YidaSearch.Type.TEXT_FIELD,YidaSearch.Operator.EQ);
+
+
+    private String key;
+    private Object value;
+    // 组件值类型
+    private String type;
+    // 操作符
+    private String operator;
+    // 组件名称
+    private String componentName;
+    // 查询子表使用
+    private String parentId;
+
+    public YDSearch(String key, Object value, String type, String operator, String componentName){
+        this.key=key;
+        this.value=value;
+        this.type=type;
+        this.operator=operator;
+        this.componentName=componentName;
+    }
+
+    public YDSearch(String key, Object value, Type type, Operator operator, String componentName, String parentId) {
+        this.key = key;
+        this.value = value;
+        this.type = type.type;
+        this.operator = operator.operator;
+        this.componentName = componentName;
+        this.parentId = parentId;
+    }
+
+    public YDSearch(String key, Object value, String componentName, Type type, Operator operator){
+        this.key=key;
+        this.value=value;
+        this.type=type.type;
+        this.operator=operator.operator;
+        this.componentName=componentName;
+    }
+
+    // 缺少来这里找 https://open.dingtalk.com/document/orgapp-server/use-the-filter-conditions-in-the-form-data-management-for
+    public enum Type{
+        TEXT_FIELD("TEXT"),
+        TEXTAREA_FIELD("TEXT"),
+        NUMBER_FIELD("DOUBLE"),
+        RATE_FIELD("DOUBLE"),
+        RADIO_FIELD("ARRAY"),
+        CHECKBOX_FIELD("ARRAY"),
+        MULTISELECT_FIELD("ARRAY"),
+        CASCADESELECT_FIELD("STRING"),
+        DATE_FIELD("DOUBLE"),
+        CASCADEDATE_FIELD("DOUBLE"),
+        IMAGE_FIELD("TEXT"),
+        ATTACHMENT_FIELD("TEXT"),
+        EMPLOYEE_FIELD("STRING"),
+        DEPARTMENTSELECT_FIELD("ARRAY");
+
+        public final String type;
+
+        Type(String type){
+            this.type=type;
+        }
+    }
+
+    public enum Operator{
+        EQ("eq"),
+        LIKE("like"),
+        GT("gt"),
+        GE("ge"),
+        LT("lt"),
+        LE("le"),
+        BETWEEN("between"),
+        CONTAINS("contains");
+
+        public final String operator;
+
+        Operator(String operator){
+            this.operator=operator;
+        }
+    }
+
+}

+ 132 - 0
mjava-poc/src/main/java/com/malk/poc/service/AWClint.java

@@ -0,0 +1,132 @@
+package com.malk.poc.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.server.aliwork.YDParam;
+
+import java.util.List;
+import java.util.Map;
+
+public interface AWClint {
+
+    /**
+     * 交付物审批
+     */
+    Map doApprove(Map data, boolean isChange);
+
+    /**
+     * 交付物审批变更发起
+     */
+    void changeApprove(String taskId, String instanceId, String title);
+
+    /**
+     * 交付物审批回调
+     */
+    void approved(Map data);
+
+    /**
+     * 检查项check
+     */
+    Map doCheck(String taskId, boolean isTask);
+
+    /**
+     * 检查项回调
+     */
+    void checked(Map data);
+
+    /**
+     * 同步项目主数据
+     */
+    Map syncProject(String projectCode);
+
+    /**
+     * 通过模板创建项目 [templateId 为空, 触发项目类型匹配]
+     */
+    void createProject(String projectCode, String templateId);
+
+    /**
+     * 项目主数据增量更新
+     */
+    void updateProject(String projectCode);
+
+    /**
+     * 分配项目角色 prd 若是一人直接指定, 多人情况下忽略
+     */
+    void updateProjectRole(String projectId, List<String> trNode, String production, String version);
+
+    void createTask(String formInstId);
+
+    /**
+     * 项目迁移: 删除依赖项
+     */
+    void removeDependencies(String projectId, List<String> trNode);
+
+    /**
+     * 增量同步crm基线
+     */
+    void syncBaseLineForCRM(String projectId);
+
+    /**
+     * 全量同步crm基线
+     */
+    void syncBaseLineForCRM();
+
+    /**
+     * 修改任务自定义字段内容
+     *
+     * @param projectId 1. 若为空, 触发全量修改; 2. 仅修改非未完成任务
+     */
+    void batchUpdate(String fieldName, String preName, String modifyName, String projectId);
+
+    /**
+     * 同步预检项 [实现]
+     *
+     * @param srcParam          [appType, formUuid, systemToken]
+     * @param compIds           映射表: 当前组件, 来源组件
+     * @param taskCompId        任务号, 忽略为空记录
+     * @param codeCompId        来源表唯一标识
+     * @param checkType         预检项分类(TR评审要素表、经验库、IC技术检查表)
+     * @param associationCompId 预检项分类对应关联组件
+     */
+    void syncCheckList(YDParam srcParam, Map<String, ?> compIds, String taskCompId, String codeCompId, String checkType, String associationCompId);
+
+    /**
+     * 同步预检项 [通用]
+     *
+     * @param type 预检项分类(0-经验库、1-IC技术检查表, 2-TR评审要素表)
+     */
+    void syncCheckList(int type);
+
+    /**
+     * 知识库版本管理
+     */
+    void approveVersion(String taskId, String pCode);
+
+    /**
+     * 获取主数据中产品列表
+     */
+    List<Map> getProductList(String projectId, String q);
+
+    /**
+     * 获取主数据中产品版本
+     */
+    List<Map> getProductList(String projectId, String q, String taskId);
+
+    /**
+     * 选择产品\版本后, 回调更新对应原文本字段, 兼容之前字段逻辑
+     */
+    void custFieldUpdate(JSONObject data);
+
+    /**
+     * 检查项导出, 全部检查项左关联已提交数据
+     */
+    List<Map> exportCheckList(String pCode, String proType);
+
+    /**
+     * 任务NA校验, 一二级不允许NA
+     */
+    void taskLevelValidate(Map data);
+
+    void test();
+
+    void tmp();
+}

+ 59 - 0
mjava-poc/src/main/java/com/malk/poc/service/AWYDClient.java

@@ -0,0 +1,59 @@
+package com.malk.poc.service;
+
+import java.util.List;
+import java.util.Map;
+
+public interface AWYDClient {
+
+
+    /**
+     * 提供verifier数据读取服务
+     */
+    Map syncVerifier(String projectCode, String productCode, String productVersion);
+
+    /**
+     * 提供verifier数据回传服务
+     */
+    void backVerifier(Map data);
+
+    /**
+     * 项目需求导入校验
+     */
+    Map checkImportData_projectRequirements(String charter, List<Map> dataList, boolean isSubmit);
+
+    /**
+     * 项目需求审批通过后, 回写需求编号与关联表单, ppExt 并覆盖项目需求档案需求列表
+     */
+    void dealApprovedData_projectRequirements(String pCode, String instanceId, Map data);
+
+    /**
+     * tmp 覆盖项目需求档案需求列表, 兼容 dealApprovedData_projectRequirements
+     */
+    void archiveProjectRequirements(String pCode, String instanceId);
+
+    /**
+     * 项目规格导入校验
+     */
+    Map checkImportData_projectSpecification(String charter, List<Map> dataList, List<String> prList, boolean isSubmit);
+
+    /**
+     * 项目规格审批通过后, 回写规格编号与关联表单
+     */
+    void dealApprovedData_projectSpecification(String instanceId, Map data);
+
+    /**
+     * 测试规格导入校验
+     */
+    Map checkImportData_testSpecification(String charter, List<Map> dataList, List<String> prList, boolean isSubmit);
+
+    /**
+     * 测试规格审批通过后, 回写规格编号与关联表单
+     */
+    void dealApprovedData_testSpecification(String instanceId, Map data);
+
+    
+    void test();
+
+    // 0906 项目需求导入逻辑变更, 弃用保留
+    Map checkImportData(Map data);
+}

+ 9 - 0
mjava-poc/src/main/java/com/malk/poc/service/AwDingService.java

@@ -0,0 +1,9 @@
+package com.malk.poc.service;
+
+import java.util.Map;
+
+public interface AwDingService {
+
+    void saveGroup(Map upMap,Map formData);
+
+}

+ 13 - 0
mjava-poc/src/main/java/com/malk/poc/service/GZT_PN.java

@@ -0,0 +1,13 @@
+package com.malk.poc.service;
+
+import java.util.List;
+import java.util.Map;
+
+public interface GZT_PN {
+
+    List<Map> getPortalList(String section);
+
+    void getDataList();
+
+    Map register(Map<String, String> data);
+}

File diff suppressed because it is too large
+ 2166 - 0
mjava-poc/src/main/java/com/malk/poc/service/impl/AWImplClient.java


File diff suppressed because it is too large
+ 1018 - 0
mjava-poc/src/main/java/com/malk/poc/service/impl/AWYDImplClient.java


+ 79 - 0
mjava-poc/src/main/java/com/malk/poc/service/impl/AwDingServiceImpl.java

@@ -0,0 +1,79 @@
+package com.malk.poc.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.malk.poc.service.AwDingService;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Group;
+import com.malk.utils.UtilEnv;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.formula.functions.T;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Slf4j
+@Service
+public class AwDingServiceImpl implements AwDingService {
+
+    @Autowired
+    private DDClient_Group ddClient_group;
+    @Autowired
+    private DDClient ddClient;
+
+    String _matchFormData(String code) {
+        Map<String, String> formUuid = UtilMap.empty();
+        if (true || UtilEnv.getActiveProfile().equals(UtilEnv.ENV_PROD)) {
+            formUuid.put("OWNER_USER_ID", "153620324221442254");// todo 需要替换艾为tbmanager userId
+            formUuid.put("TEMPLATE_ID", "17d5c0fc-79f8-43bf-86ab-bad1e254ec2d");// todo 需要在艾为组织创建场景群模板,并替换模板ID
+        } else {
+            formUuid.put("OWNER_USER_ID", "153620324221442254");
+            formUuid.put("TEMPLATE_ID", "17d5c0fc-79f8-43bf-86ab-bad1e254ec2d");
+        }
+        return formUuid.get(code);
+    }
+
+    @Override
+    public void saveGroup(Map upMap, Map formData) {
+        try {
+            String ddGroupId=String.valueOf(formData.get("textField_luqvxhec"));// 群ID
+            List<Map> list= (List<Map>) formData.get("tableField_lqxtykcf");// 项目角色子表单
+            String newUsers="";
+            for (Map map:list){
+                newUsers=newUsers.concat(String.join(",",UtilMap.getList(map,"employeeField_lqxtykch_id"))).concat(",");
+            }
+            newUsers=newUsers.substring(0,newUsers.length()-1);
+            if(StrUtil.isBlank(ddGroupId)){
+                String name=String.valueOf(formData.get("textField_lqxtykcd")).concat("项目群");// todo 这里是群名称
+                ddGroupId=ddClient_group.createGroupByTemp(ddClient.getAccessToken(),name,_matchFormData("TEMPLATE_ID"),_matchFormData("OWNER_USER_ID"),newUsers);
+                // 创建群
+                upMap.put("textField_luqvxhec",ddGroupId);// 群ID
+                upMap.put("textField_luqvxhed",newUsers);// 群成员ID
+            }else{
+                // 判断并更新群成员
+                String oldUsers=String.valueOf(formData.get("textField_luqvxhed"));
+                // 删除群成员
+                List delList=findDifferentElements(Arrays.asList(oldUsers.split(",")),Arrays.asList(newUsers.split(",")));
+                if(delList.size()>0){
+                    ddClient_group.delGroupUser(ddClient.getAccessToken(),ddGroupId,String.join(",",delList));
+                }
+                // 新增群成员
+                List addList=findDifferentElements(Arrays.asList(newUsers.split(",")),Arrays.asList(oldUsers.split(",")));
+                if(addList.size()>0){
+                    ddClient_group.addGroupUser(ddClient.getAccessToken(),ddGroupId,String.join(",",addList));
+                }
+                upMap.put("textField_luqvxhed",newUsers);// 群成员ID
+            }
+        }catch (Exception e){
+            log.error("创建钉钉项目群异常了,{}",e);
+            e.printStackTrace();
+        }
+    }
+
+    private List findDifferentElements(List firstArray,List secondArray){
+        Set<T> set1 = new HashSet<>(firstArray);
+        set1.removeAll(secondArray);
+        return new ArrayList<>(set1);
+    }
+}

+ 120 - 0
mjava-poc/src/main/java/com/malk/poc/service/impl/GZT_PNImpl.java

@@ -0,0 +1,120 @@
+package com.malk.poc.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.poc.service.GZT_PN;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+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.DDService;
+import com.malk.utils.UtilDateTime;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@EnableScheduling
+@Service
+@Slf4j
+public class GZT_PNImpl implements GZT_PN {
+
+    private Map portal_cache = new HashMap();
+    @Autowired
+    private YDClient ydClient;
+
+    @Override
+    public List<Map> getPortalList(String section) {
+        return _portalList(section);
+    }
+
+    @Override
+    public void getDataList() {
+        try {
+
+            portal_cache = new HashMap();
+            getPortalList("派能资讯");
+            getPortalList("能量派送");
+            getPortalList("人资资讯");
+            getPortalList("内部资讯");
+
+        } catch (Exception e) {
+            // 记录错误信息
+            e.printStackTrace();
+        }
+    }
+
+    private List<Map> _portalList(String type) {
+        List<Map> pList = UtilMap.getList(portal_cache, type);
+        try {
+            if (pList.isEmpty()) {
+                List<Map> dataList = (List<Map>) ydClient.queryData(YDParam.builder()
+                        .appType("APP_OM7HTYCXYQYCKJ046D9V")
+                        .systemToken("BN766KC1CS9Q2LJQDAKIN82VVUHT2J07ALF3M7R2")
+                        .formUuid("FORM-918FE77C2E8248069B7CA497C6B2E4C6XD4B")
+                        .pageSize(5)
+                        .searchFieldJson(JSONObject.toJSONString(UtilMap.map("selectField_m17kv4an", type)))
+                        .build(), YDConf.FORM_QUERY.retrieve_search_form).getData();
+
+                dataList.sort(Comparator.comparingInt(item -> UtilMap.getInt(item, "numberField_m3s6swzt"))); // 排序
+                pList = dataList.stream().map(item -> {
+                    Map formData = UtilMap.getMap(item, "formData");
+
+                    Map row = UtilMap.map("title, source, link", UtilMap.getString(formData, "textField_m17kv4aq"), UtilMap.getString(formData, "textField_m17kv4as"), UtilMap.getString(formData, "textField_m17kv4at"));
+                    long date = UtilMap.getLong(formData, "dateField_m17kv4ar");
+                    if (date > 0L) {
+                        row.put("dateTime", UtilDateTime.format(new Date(date), "yyyy-MM-dd HH:mm"));
+                    }
+                    // 图片免登处理
+                    String image = UtilMap.getString(formData, "imageField_m1abjxl0");
+                    if (StringUtils.isNotBlank(image)) {
+                        List<Map> attas = (List<Map>) JSON.parse(image);
+                        row.put("image", convertTemporaryUrl_PN(UtilMap.getString(attas.get(0), "url")));
+                        Object image1 = row.get("image");
+                        //   System.out.println("image=========" + UtilMap.getString(attas.get(0), "url"));
+//                    System.out.println("image1========="+image1);
+                    }
+                    return row;
+                }).collect(Collectors.toList());
+                portal_cache.put(type, pList);
+            }
+        } catch (Exception e) {
+
+        }
+        log.info("type: {},list:{}", type, pList);
+        return pList;
+    }
+
+    @Autowired
+    private DDClient ddClient;
+
+    /**
+     * 派能
+     */
+    public String convertTemporaryUrl_PN(String url) {
+        String ddapptonken = ddClient.getAccessToken("dingmpxci8bolc3jpima", "Y_k3jpKNHbGvb9S9As2Y61ZaUFNglm7SCqquIkcowLBRoc4ZpH7DG0ZTn8LyHMwI");
+        Map param = new HashMap();
+        param.put("systemToken", "BN766KC1CS9Q2LJQDAKIN82VVUHT2J07ALF3M7R2");
+        param.put("userId", YDConf.PUB_ACCOUNT);
+        param.put("fileUrl", url);          // URL在param上时, 需要编码 [UtilHttp已经做了编码] - URLEncoder.encode(url, "UTF-8")
+        param.put("timeout", 60000);      // 默认1分钟, 最大24小时 [毫秒]
+        // System.out.println("ssss:"+(String) DDR_New.doGet("https://api.dingtalk.com/v1.0/yida/apps/temporaryUrls/APP_G951QZ32AUJNJUE4G127" , ddClient.initTokenHeader_PN(), param).getResult());
+        return (String) DDR_New.doGet("https://api.dingtalk.com/v1.0/yida/apps/temporaryUrls/APP_OM7HTYCXYQYCKJ046D9V", DDConf.initTokenHeader(ddapptonken), param).getResult();
+    }
+
+    @Autowired
+    private DDService ddService;
+
+    @Override
+    public Map register(Map<String, String> data) {
+        String ddapptonken = ddClient.getAccessToken("dingmpxci8bolc3jpima", "Y_k3jpKNHbGvb9S9As2Y61ZaUFNglm7SCqquIkcowLBRoc4ZpH7DG0ZTn8LyHMwI");
+        return ddService.registerJsApi(ddapptonken, data.get("url"), data.get("nonceStr"));
+    }
+}

+ 70 - 0
mjava-poc/src/main/resources/application-dev.yml

@@ -0,0 +1,70 @@
+# 环境配置
+server:
+  port: 9001
+  servlet:
+    context-path: /api/paineng
+
+# 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: root
+    password: mu123
+    url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+    # 主库
+    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: 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: 3288641544
+  appKey: dingqbryerfateuj6ody
+  appSecret: FVyZxdRxBiulGMSZeFzZVAzKtBYFMWXpHW6nmfLzk4cCEcotyewRrihk7_Okpsl0
+  corpId: ding6d0de5f5de58a80c35c2f4657eb6378f
+  aesKey:
+  token:
+  operator: "0953580166844866"   # OA管理员账号
+
+# teambition
+teambition:
+  AppID: 6800a99731585ad0dc02e73e
+  AppSecret: n7L8Zz1g4Ss6eprjTDqORRDhVtOUpREK
+  TenantId: 5e448b27e9642b000154a48d        # 管理后台 - 企业xx - 企业ID
+  OperatorId: 5e698cca21f5ad70dfba7d2b      # 公共账号, 需要有操作权限 [牧语]
+
+#
+aliwork:
+  appType: "APP_QDJP8Y2EK6PJ602502TR"
+  systemToken: "CRD66J71IPNU4PBHFUS2T73H5UXJ3CRJX1L9MIA"

+ 45 - 0
mjava-poc/src/main/resources/application-prod.yml

@@ -0,0 +1,45 @@
+# 环境配置
+server:
+  port: 9001
+  servlet:
+    context-path: /api/paineng
+
+# 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: root
+    password: mu123
+    url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    database: MYSQL
+    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+# dingtalk
+dingtalk:
+  agentId: 3288641544
+  appKey: dingqbryerfateuj6ody
+  appSecret: FVyZxdRxBiulGMSZeFzZVAzKtBYFMWXpHW6nmfLzk4cCEcotyewRrihk7_Okpsl0
+  corpId: ding6d0de5f5de58a80c35c2f4657eb6378f
+  aesKey:
+  token:
+  operator: "0953580166844866"   # OA管理员账号
+
+# teambition
+teambition:
+  AppID: 6800a99731585ad0dc02e73e
+  AppSecret: n7L8Zz1g4Ss6eprjTDqORRDhVtOUpREK
+  TenantId: 5e448b27e9642b000154a48d        # 管理后台 - 企业xx - 企业ID
+  OperatorId: 5e698cca21f5ad70dfba7d2b      # 公共账号, 需要有操作权限 [牧语]
+
+#
+aliwork:
+  appType: "APP_QDJP8Y2EK6PJ602502TR"
+  systemToken: "CRD66J71IPNU4PBHFUS2T73H5UXJ3CRJX1L9MIA"

BIN
mjava-poc/src/main/resources/templates/templates_checked_list.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_project_requirements.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_project_requirements_exception.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_project_requirements_test.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_project_specification.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_project_specification_exception.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_test_specification.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_test_specification_exception.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_xqrk.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_xqwh.xlsx


BIN
mjava-poc/src/main/resources/templates/templates_xqwh_result.xlsx


+ 91 - 0
mjava-poc/src/test/java/com/malk/poc/AwTbTest.java

@@ -0,0 +1,91 @@
+package com.malk.poc;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.poc.service.AWClint;
+import com.malk.server.teambition.TBConf;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.teambition.TBClient;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class AwTbTest {
+
+    @Autowired
+    private TBClient tbClient;
+    @Autowired
+    private TBConf tbConf;
+
+    @Test
+    public void test() {
+        List<String> users = Arrays.asList("5f3a250040ce230ba377bf3c", "5e698cca21f5ad70dfba7d2b", "616fb6f78ad4104a10515809");
+        String programId = "662a69aceda740b4e63d3976";
+//        tbClient.createProgramMember(programId,tbConf.getOperatorId(),users);
+        List addUsers = new ArrayList();
+        for (String userId : users) {
+            List resut = tbClient.queryProgramMember(programId, tbConf.getOperatorId(), UtilMap.map("userIds", userId));
+            if (resut.size() < 1) addUsers.add(userId);
+        }
+        log.info("需要添加到项目集的userId:{}", tbClient);
+        if (addUsers.size() > 0) tbClient.createProgramMember(programId, tbConf.getOperatorId(), addUsers);
+    }
+
+    @Autowired
+    private YDClient ydClient;
+
+    // this.initOptions("FORM-IQ8666B1PL275QG5BSSDG6ZD9X3Q29X881HCL4", JSON.stringify({'textField_ljsd7bjn':value}), //
+    //    "8F966HB12J27MQJM6V4IQDYHYTPA2G4GTZGCLN1", "APP_QBWQITQBSPJNYTUTNPDK",
+    //    'yida_pub_account', "selectField_lchafcgt", "selectField_lchafcgt", "selectField_lywdbrk1", 100);
+
+
+    @Test
+    public void adad() {
+//        YDSearch ydSearch=new YDSearch("textField_lha7mqbs","G","物料子类", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ);
+//        YDSearch ydSearch2=new YDSearch("textField_lha7mqbn","A2443","项目号", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ);
+//        List<Map> list =(List<Map>) ydClient.queryData(YDParam.builder().formUuid("FORM-4W8667D17CAAGFXI9VO0J9J7RFNL2QDFL7AHLJ")
+//                .appType("APP_QBWQITQBSPJNYTUTNPDK").systemToken("8F966HB12J27MQJM6V4IQDYHYTPA2G4GTZGCLN1")
+//                .searchCondition(JSONObject.toJSONString(Arrays.asList(ydSearch,ydSearch2)))
+//                .pageSize(100).build(), YDConf.FORM_QUERY.retrieve_list).getData();
+//        List<Map> result=new ArrayList<>();
+//        Map<String,String> keyMap=new HashMap<>();
+//        for (Map map:list){
+//            String data=UtilMap.getString(UtilMap.getMap(map,"formData"),("textField_lhsxurnt"));
+//            if(!StringUtils.isBlank(data)&&!keyMap.containsKey(data)){
+//                result.add(UtilMap.map("title",data));
+//            }
+//        }
+//        print(result);
+//        DDR_New ddr_new = ydClient.queryData(YDParam.builder()
+//                .appType("APP_QBWQITQBSPJNYTUTNPDK").systemToken("8F966HB12J27MQJM6V4IQDYHYTPA2G4GTZGCLN1")
+//                .pageSize(100)
+//                .build(), YDConf.FORM_QUERY.retrieve_forms);
+//        print(ddr_new);
+    }
+
+    private void print(Object o) {
+        System.out.println(JSONObject.toJSONString(o));
+    }
+
+    @Autowired
+    private AWClint awClint;
+
+    @Test
+    public void test1() {
+//        String id=tbClient.getUserId("5e698cca21f5ad70dfba7d2b",true);
+//        System.out.println(id);
+//        System.out.println(tbClient.idMapQuery("5e698cca21f5ad70dfba7d2b",true));
+        awClint.createTask("6800e9aad52ec8c669c757b0");
+    }
+
+}

+ 87 - 0
mjava-poc/src/test/java/com/malk/poc/DataHandingTest.java

@@ -0,0 +1,87 @@
+package com.malk.poc;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.teambition.TBConf;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.service.teambition.TBClient;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.platform.commons.util.StringUtils;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.*;
+
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class DataHandingTest {
+
+    @Autowired
+    private TBClient tbClient;
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private YDService ydService;
+
+    // 处理数据
+    @Test
+    public void test(){
+        List<Map> data = ydService.queryFormData_all(YDParam.builder().formUuid("FORM-6E2C0D1197264B8AA23EB3FECAE7344B00BN").build());
+        List<Map> errorList = new ArrayList<>();
+        for (Map item:data){
+            String instanceId=UtilMap.getString(item,("instanceId"));
+            String tbTaskId=UtilMap.getString(item,("textField_lr3dlwsa"));
+            if(StringUtils.isBlank(tbTaskId)){
+                continue;
+            }
+            try {
+                Map taskData = _getTaskFieldMap(tbTaskId, "wafer");
+                Map rTask = UtilMap.getMap(taskData, "task");
+                Map updateMap=new HashMap();
+                updateMap.put("textField_m0yo7tsj",taskData.get("wafer"));
+                updateMap.put("textField_m0yo7tsk",_getWorkFlowStatusList(UtilMap.getString(rTask,"projectId"),UtilMap.getString(rTask,"tfsId"))); // 任务状态
+                ydClient.operateData(YDParam.builder().formInstId(instanceId).updateFormDataJson(JSONObject.toJSONString(updateMap)).build(), YDConf.FORM_OPERATION.update);
+            }catch (Exception e){
+                e.printStackTrace();
+                errorList.add(UtilMap.map("instanceId, tbTaskId",instanceId,tbTaskId));
+            }
+        }
+        System.out.println(JSONObject.toJSONString(errorList));
+    }
+
+    private Map _getTaskFieldMap(String taskId, String... fieldNames) {
+        // 查询任务详情
+        Map rTask = tbClient.queryTaskDetail(taskId, null, null).get(0);
+        // 查询项目任务ID
+        List<Map> customField = tbClient.queryProjectCustomField(String.valueOf(rTask.get("projectId")), null);
+        return __getTaskMap(rTask, customField, fieldNames);
+    }
+
+    // 组装任务数据
+    private Map __getTaskMap(Map task, List<Map> projectCustomField, String... fieldNames) {
+        Map result = UtilMap.map("task", task);
+        List<Map> taskCustomField = (List<Map>) task.get("customfields");
+        for (String filed : fieldNames) {
+            Optional optional = projectCustomField.stream().filter(item -> filed.equals(item.get("name"))).findAny();
+            if (optional.isPresent()) {
+                Map map = (Map) optional.get();
+                result.put(filed, TBConf.getTaskFieldValue_First(taskCustomField, String.valueOf(map.get("id"))));
+                result.put(filed + "_id", map.get("id")); // ppExt: 返回字段ID
+            }
+        }
+        return result;
+    }
+
+    private String _getWorkFlowStatusList(String projectId,String tfsId) {
+        List<Map> customFlowStatus = tbClient.queryProjectCustomFlowStatus(projectId, UtilMap.map("tfsIds",tfsId));
+        return UtilMap.getString(customFlowStatus.get(0),"name");
+    }
+
+}

+ 58 - 0
mjava-poc/src/test/java/testLocal.java

@@ -0,0 +1,58 @@
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.poc.Boot;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+/**
+ * @author floe
+ * @date 2024/7/22 22:29
+ */
+@Slf4j
+@SpringBootTest(classes = Boot.class)
+@RunWith(SpringRunner.class)
+public class testLocal {
+
+    @Autowired
+    private YDClient ydClient;
+
+
+
+    @Test
+    public void test(){
+        String token="Bearer ".concat(getToken());
+        List<String> ids= FileUtil.readLines("/home/ids.txt","utf-8");
+//        List<String> ids= Arrays.asList("66697d643f7c5aef23f3a326###FINST-TM966BD1ISXM7XLDC9AGM4N92MDV325WL1YYLV9B","6699cef58e173e99e22d8de4###FINST-MBC668915E4NNTTUAFIFSDQZTPYT2T3WIV0ZLBF6");
+        for (int i = 0; i < ids.size(); i++) {
+            String result=HttpUtil.createPost("https://apigateway.awinic.com/sys/teambition/api/aiwei/do-check?taskId="+ids.get(i).split("###")[0])
+                    .header("authorization",token).execute().body();
+            System.out.println(result);
+            JSONObject resultObj=JSONObject.parseObject(result);
+            if(!resultObj.getBoolean("success")){
+                continue;
+            }
+            JSONObject data=resultObj.getJSONObject("data");
+            data.remove("tableField_lqxxgj4s");
+            data.remove("userId");
+            ydClient.operateData(YDParam.builder().updateFormDataJson(JSONObject.toJSONString(data)).formInstanceId(ids.get(i).split("###")[1]).build()
+             , YDConf.FORM_OPERATION.update);
+        }
+    }
+
+    private String getToken(){
+        String a=HttpUtil.post("https://apigateway.awinic.com/token/getToken", JSONObject.toJSONString(UtilMap.map("appKey, secret","AW394034j","RJbH7RMH3vllt4KDri303Mlw@df3434k")));
+        System.out.println(a);
+        return JSONObject.parseObject(a).getJSONObject("data").getString("token");
+    }
+}

+ 35 - 0
mjava-poc/src/test/resources/server.sh

@@ -0,0 +1,35 @@
+#!/bin/bash
+appname='mjava-aiwei'
+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"
+  else
+    if [ "$1" == "test" ]; then
+      nohup java -Xms256m -Xmx256m -jar $appname.jar --spring.profiles.active=test &
+      echo "server test is starting"
+    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

+ 19 - 0
mjava/src/main/java/com/malk/service/teambition/TBClient.java

@@ -37,6 +37,8 @@ public interface TBClient {
 
     List<Map> idMapQuery(String userId, boolean isTbID);
 
+    String getUserId(String id,Boolean isTB);
+
     /**
      * 更新企业成员
      *
@@ -210,6 +212,14 @@ public interface TBClient {
      */
     List<Map> queryProjectCustomFlow(String projectId, Map body);
 
+    /**
+     * 搜索项目任务类型
+     *
+     * @apiNote https://open.teambition.com/docs/apis/6321c6d1912d20d3b5a49cc4
+     */
+    List<Map> queryProjectTaskType(String projectId, Map body);
+
+
     /**
      * 获取依赖项
      *
@@ -302,6 +312,13 @@ public interface TBClient {
      */
     List<Map> queryProgramMember(String programId, String operatorId, Map body);
 
+    /**
+     * 创建任务
+     *
+     * @apiNote https://open.teambition.com/docs/apis/66693d96912d20d3b5ee5737
+     */
+    Map createTask(String operatorId, Map body);
+
     /**
      * 查询全部数据 [函数回调]
      * - ppExt
@@ -313,4 +330,6 @@ public interface TBClient {
     interface QueryAll {
         boolean dataList(List<Map> list);
     }
+
+
 }

+ 28 - 4
mjava/src/main/java/com/malk/service/teambition/impl/TBClientImpl.java

@@ -1,6 +1,9 @@
 package com.malk.service.teambition.impl;
 
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.auth0.jwt.algorithms.Algorithm;
 import com.malk.server.common.McException;
 import com.malk.server.dingtalk.DDConf;
@@ -17,10 +20,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 @Slf4j
 @Service
@@ -176,6 +176,17 @@ public class TBClientImpl implements TBClient {
         return (List<Map>) tbr.getResult();
     }
 
+    @Override
+    public String getUserId(String id,Boolean isTB){
+        if(StringUtils.isBlank(id)){
+            return "";
+        }
+        String resultStr=UtilHttp.doGet(tbConf.getApiHost() + "/idmap/dingtalk/"+(isTB?"getDingUserId?tbUserIds=":"getTbUserId?dingUserIds=")+id, initHeaderToken_Bearer(), null);
+        System.out.println(resultStr);
+        JSONObject result=JSONObject.parseObject(resultStr);
+        return result.getJSONArray("result").getJSONObject(0).getString(isTB?"dingtalkUserId":"tbUserId");
+    }
+
     @Override
     public Map updateUser(String operatorId, List<Map> members) {
         Map body = new HashMap();
@@ -308,6 +319,13 @@ public class TBClientImpl implements TBClient {
         return (List<Map>) tbr.getResult();
     }
 
+    @Override
+    public List<Map> queryProjectTaskType(String projectId, Map body) {
+        body = UtilMap.put(body, "pageSize", TBConf.PAGE_SIZE_LIMIT);
+        TBR tbr = (TBR) UtilHttp.doGet(tbConf.getApiHost() + "/v3/project/" + projectId + "/scenariofieldconfig/search", initHeaderToken(), body, TBR.class);
+        return (List<Map>) tbr.getResult();
+    }
+
     @Override
     public List<Map> queryTaskDependency(String taskId, Map body) {
         body = UtilMap.put(body, "pageSize", TBConf.PAGE_SIZE_LIMIT);
@@ -405,4 +423,10 @@ public class TBClientImpl implements TBClient {
         TBR tbr = (TBR) UtilHttp.doGet(tbConf.getApiHost() + "v3/program/" + programId + "/member", initHeaderToken(operatorId), body, TBR.class);
         return (List<Map>) tbr.getResult();
     }
+
+    @Override
+    public Map createTask(String operatorId, Map body) {
+        TBR tbr = (TBR) UtilHttp.doPost(tbConf.getApiHost() + "/v3/task/create", initHeaderToken(operatorId), body, TBR.class);
+        return (Map) tbr.getResult();
+    }
 }

+ 1 - 0
pom.xml

@@ -11,6 +11,7 @@
     <modules>
         <module>mjava</module>
         <module>mjava-aiwei</module>
+        <module>mjava-poc</module>
     </modules>
     <packaging>pom</packaging>