lfx 3 hónapja%!(EXTRA string=óta)
szülő
commit
e2aaaaee6e

+ 1 - 1
pom.xml

@@ -38,7 +38,7 @@
         <dependency>
             <groupId>com.malk</groupId>
             <artifactId>base</artifactId>
-            <version>1.3</version>
+            <version>2.0</version>
         </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>

+ 26 - 0
src/main/java/com/malk/eastar/LtcEastarApplication.java

@@ -0,0 +1,26 @@
+package com.malk.eastar;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * corp项目: 扫描公共模块
+ * -
+ * 若是无需数据库模块, 配置无效地址也可启动, 引入mjava不支持直接 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 配置
+ * 需要配置 jpa.hibernate.ddl-auto 为 none. 标识对表没有任何操作. 若不设置为 none, flyway.enabled 配置会无效, 在没有数库连接情况下程序无法启动
+ */
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+@EnableScheduling
+public class LtcEastarApplication {
+
+    public static void main(String... args) {
+
+        try {
+            SpringApplication.run(LtcEastarApplication.class, args);
+        }catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 32 - 0
src/main/java/com/malk/eastar/conf/CfsToStageEnum.java

@@ -0,0 +1,32 @@
+package com.malk.eastar.conf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum CfsToStageEnum {
+    STEPA("白样", "样品阶段"),
+    STEPB("制版", "样品阶段"),
+    STEPC("产前样", "样品阶段"),
+    STEPAD("大货", "生产阶段"),
+    STEPE("包装", "包装阶段"),
+    STEPF("出货", "出货阶段"),
+    STEPG("已完成", "收尾阶段");
+
+    private final String key;
+    private final String value;
+
+    private static final Map<String, String> CACHE = new HashMap<>();
+    static {
+        // 初始化缓存
+        for (CfsToStageEnum entry : CfsToStageEnum.values()) {
+            CACHE.put(entry.key, entry.value);
+        }
+    }
+    CfsToStageEnum(String key, String value) {
+        this.key = key;
+        this.value = value;
+    }
+    public static String getValueByKey(String key) {
+        return CACHE.get(key);
+    }
+}

+ 30 - 0
src/main/java/com/malk/eastar/conf/EastarParam.java

@@ -0,0 +1,30 @@
+package com.malk.eastar.conf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EastarParam {
+    public static Map<String,String> CUSTFIELD_ACCE=new HashMap<>();
+    public static Map<String,String> CUSTFIELD_DOLL=new HashMap<>();
+    public static String YD_FORMUUID_PROJECT="FORM-D8DFF1F8C07A4869BCC850090F3A3B4EE0AV"; // 立项流程
+    public static String YD_FORMUUID_RECOD="FORM-64A758B8173341879B24D612E180BE997E0B"; // TB项目档案
+    public static String YD_FORMUUID_ORDER="FORM-A731443BE0F04467A5D7FC1A82431D6AL2JO"; // 订单表
+    public static String YD_FORMUUID_SONCONF="FORM-760F4001E1C743BA8527721F7217E068534G"; // 子任务拆分配置表
+
+    public static String TB_PROJECT_TEMP="68b4fa329ae5c6b2af2d8e18";
+
+    static {
+        CUSTFIELD_ACCE.put("配件名","textField_me2f7tvo");
+        CUSTFIELD_ACCE.put("系列名称","selectField_me2f7tw4");
+//        CUSTFIELD_ACCE.put("语言","selectField_me2f7tvj"); //调整为子表拆分传输
+        CUSTFIELD_ACCE.put("配件品类","selectField_me2f7tvk");
+        CUSTFIELD_ACCE.put("工厂(供应商)","textField_me2f7tvz");
+//        CUSTFIELD_ACCE.put("订单数量","numberField_me2f7tvl"); //调整为子表拆分传输
+        CUSTFIELD_DOLL.put("配件名","textField_me2f7tw6");
+        CUSTFIELD_DOLL.put("系列名称","selectField_me2f7tw3");
+//        CUSTFIELD_DOLL.put("配件品类","selectField_me2f7tvk");
+        CUSTFIELD_DOLL.put("工厂(供应商)","textField_mec5w62j");
+        CUSTFIELD_DOLL.put("订单数量","numberField_mec5w621");
+    }
+
+}

+ 47 - 0
src/main/java/com/malk/eastar/controller/EastarTbController.java

@@ -0,0 +1,47 @@
+package com.malk.eastar.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.server.common.McException;
+import com.malk.server.common.McR;
+import com.malk.utils.UtilMap;
+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 com.malk.eastar.service.EastarTbService;
+
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping("/tb/")
+public class EastarTbController {
+
+    @Autowired
+    private EastarTbService eastarTbService;
+
+    /**
+     * 保存任务,如无项目自动创建
+     */
+    @PostMapping("task/save")
+    McR createProject(@RequestBody JSONObject data) {
+        log.info("通过模板创建项目, {}", data);
+        McException.assertParamException_Null(data, "formInstId");
+        String formInstId = UtilMap.getString(data, "formInstId");
+        Map result=eastarTbService.createTask(formInstId);
+        return McR.success(result);
+    }
+
+    /**
+     * 变更任务状态
+     */
+    @PostMapping("task/stateChange")
+    McR taskStateChange(@RequestBody JSONObject data) {
+        log.info("变更任务状态, {}", data);
+        McException.assertParamException_Null(data, "taskIds","tfsName");
+        Map result=eastarTbService.taskStateChange(data.getString("taskIds"),data.getString("tfsName"));
+        return McR.success(result);
+    }
+}

+ 12 - 0
src/main/java/com/malk/eastar/service/EastarTbService.java

@@ -0,0 +1,12 @@
+package com.malk.eastar.service;
+
+import java.util.Map;
+
+public interface EastarTbService {
+
+    Map createProject(String projectCode, String templateId, String tbProjectId);
+
+    Map createTask(String formInstId);
+
+    Map taskStateChange(String taskIds,String tfsName);
+}

+ 64 - 0
src/main/java/com/malk/eastar/service/impl/EastarTBEventImpl.java

@@ -0,0 +1,64 @@
+package com.malk.eastar.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.delegate.TBEvent;
+import com.malk.eastar.conf.CfsToStageEnum;
+import com.malk.server.teambition.TBConf;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.teambition.TBClient;
+import com.malk.service.teambition.TBClient_Project;
+import com.malk.service.teambition.TBClient_Task;
+import com.malk.utils.UtilList;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Slf4j
+@Primary
+public class EastarTBEventImpl implements TBEvent {
+
+    @Autowired
+    private TBClient_Task tbTaskClient;
+    @Autowired
+    private TBClient_Project tbProjectClient;
+    @Autowired
+    private TBConf tbConf;
+
+    @Override
+    public void callBackTask(JSONObject eventJson) {
+        String eventName = eventJson.getString("event");
+        if (eventName.equals("v3.task.taskflowstatus.update")){
+            log.info("任务状态更新");
+            JSONObject data=eventJson.getJSONObject("data");
+            String taskId=data.getString("taskId"); // 任务编号
+            String tfsId=data.getString("tfsId"); // 任务状态编号
+            List<Map> taskList=tbTaskClient.queryTaskDetail(taskId,"","");
+            Map task=taskList.get(0);
+            String projectId= UtilMap.getString(task,"projectId"); //
+            String tasklistId=UtilMap.getString(task,"tasklistId"); //
+            tfsId=UtilMap.getString(task,"tfsId");
+            Map tfs= UtilList.findFirstMap(tbProjectClient.queryProjectCustomFlowStatus(projectId,tfsId,"",null));
+            String tfsName=UtilMap.getString(tfs,"name");
+            String stageId= tbTaskClient.queryTaskStage(projectId,tasklistId, CfsToStageEnum.getValueByKey(tfsName));
+            log.info("任务{}更新任务列表为:【{}】{}",taskId,CfsToStageEnum.getValueByKey(tfsName),stageId);
+            tbTaskClient.updateTaskStage(taskId,tbConf.getOperatorId(),stageId);
+        }
+    }
+
+    @Override
+    public void callBackProject(JSONObject eventJson) {
+
+    }
+
+    @Override
+    public void callBackWorktime(JSONObject eventJson) {
+
+    }
+
+}

+ 336 - 0
src/main/java/com/malk/eastar/service/impl/EastarTbServiceImpl.java

@@ -0,0 +1,336 @@
+package com.malk.eastar.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.eastar.conf.EastarParam;
+import com.malk.eastar.util.ConfigDataProcessor;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.aliwork.YDSearch;
+import com.malk.server.common.McException;
+import com.malk.server.teambition.TBConf;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.service.teambition.TBClient_Project;
+import com.malk.service.teambition.TBClient_Task;
+import com.malk.service.teambition.TBClient_User;
+import com.malk.utils.PublicUtil;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.malk.eastar.service.EastarTbService;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class EastarTbServiceImpl  implements EastarTbService {
+
+    @Autowired
+    private TBClient_Project  tbProject;
+    @Autowired
+    private TBClient_Task tbTask;
+    @Autowired
+    private TBClient_User tbUser;
+    @Autowired
+    private TBConf tbConf;
+    @Autowired
+    private YDClient ydClient;
+    @Autowired
+    private YDService ydService;
+
+    @Override
+    public Map createProject(String projectCode, String templateId, String tbProjectId) {
+        if(PublicUtil.isNull(tbProjectId)){
+            Map result = tbProject.projectCreateWithTemplate(projectCode, templateId, tbConf.getOperatorId());
+            tbProjectId = UtilMap.getString(result, "id");
+        }
+        return UtilMap.map("tbProjectId",tbProjectId);
+    }
+
+
+    @Override
+    public Map createTask(String formInstId) {
+        Map data=ydClient.queryData(YDParam.builder().formInstId(formInstId).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+        String merName= UtilMap.getString(data,"textField_me87x1o0");// 客户名称
+        String pMainName= UtilMap.getString(data,"textField_me9n24kq"); // 主项目名称
+        String pMainId= UtilMap.getString(data,"textField_me2hyldb");// 主项目编号
+        String pName= UtilMap.getString(data,"textField_me87x1nz"); // 项目名称
+        String pId= UtilMap.getString(data,"textField_me2hyldc");// 项目编号
+        String orderType= UtilMap.getString(data,"selectField_mdf997wp"); // 订单类型 大货 打样
+        String pTaskType= UtilMap.getAssFieldValue(data,"associationFormField_me9n24kk_id").get(0).title; // 项目任务类型
+        List<Map> recodList = (List<Map>) ydClient.queryData(YDParam.builder().formUuid(EastarParam.YD_FORMUUID_RECOD).searchCondition(
+                JSONObject.toJSONString(Arrays.asList(new YDSearch("textField_me2hyldb",pMainId,"主项目编号", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ)))
+        ).build(), YDConf.FORM_QUERY.retrieve_list).getData();
+        // 项目创建
+        String tbProjectId;
+        if(recodList == null || recodList.size()<1){
+            Map result = tbProject.projectCreateWithTemplate(pMainName, EastarParam.TB_PROJECT_TEMP, tbConf.getOperatorId());
+            tbProjectId = UtilMap.getString(result, "id");
+        }else {
+            tbProjectId = UtilMap.getString(UtilMap.getMap(recodList.get(0),"formData"),"textField_mecmytpo");
+        }
+        // 订单数据
+        String orderFid= UtilMap.getAssFieldValue(data,"associationFormField_me2hylda_id").get(0).instanceId; // 项目任务类型
+        Map orderData=ydClient.queryData(YDParam.builder().formInstId(orderFid).build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+        List<Map> orderLangConf=UtilMap.getList(orderData,"tableField_meqqj4we");// 语言配置
+        List<Map> orderTypeConfALl=UtilMap.getList(orderData,"tableField_mesc7nvp");// 类型源配置
+        List<Map> orderTypeAndLangConf=new ArrayList<>();// 语言+类型配置
+        List<Map> orderTypeConf=new ArrayList<>();// 纯类型配置
+        for(Map map:orderTypeConfALl){
+            if(PublicUtil.isNull(map.get("textField_mesc7nvm"))){ // 根据语言为空判断
+                orderTypeConf.add(map);
+            }else {
+                orderTypeAndLangConf.add(map);
+            }
+        }
+        // 子任务拆分数据
+        List<Map> sonConfData= ydService.queryDetails(YDParam.builder().formInstanceId("FINST-X1B66Y81IUFY9U417XIUE99I8YV93HGMJ8WEMF").formUuid(EastarParam.YD_FORMUUID_SONCONF).tableFieldId("tableField_mew7d9f3").build());// 全品类配件表
+        Map<String,Map<String,List<String>>>  sonConf= ConfigDataProcessor.processConfigData(sonConfData);
+        // 同步项目集
+        List<Map> programList = tbProject.queryProgramList("", merName);
+        String programId = ""; // LEV项目管理
+        if (programList.size() > 0) {
+            programId=UtilMap.getString(programList.get(0), "id");
+        }else{
+            Map program=tbProject.createProgramList(merName,"");
+            programId=UtilMap.getString(program,"id");
+        }
+        tbProject.upsertProgramProject(programId, Arrays.asList(tbProjectId), tbConf.getOperatorId());
+        // 成员处理
+        List<String> pmUserId = (List<String>) UtilMap.getList(data, "employeeField_me2hyld8_id");// 项目经理
+        List<String> ssUserId = (List<String>) UtilMap.getList(data, "employeeField_me2hyld9_id");// 业务
+        List<String> qeUserId = (List<String>) UtilMap.getList(data, "employeeField_me9n24ka_id");// QE
+        pmUserId=tbUser.getUserIds(pmUserId, false);
+        ssUserId=tbUser.getUserIds(ssUserId, false);
+        qeUserId=tbUser.getUserIds(qeUserId, false);
+        List<Map> mchTable= UtilMap.getList(data,"tableField_mec6juik");// 跟单
+        List<String> mchList=new ArrayList<>();
+        Map<String,String> mchMap=new HashMap<>();
+        Map<String,String> userIdMap=new HashMap<>();
+        for (Map map:mchTable){
+            String ddId=String.valueOf(UtilMap.getList(map,"employeeField_me9n24kl_id").get(0));
+            if(!mchList.contains(ddId)){
+                mchList.add(ddId);
+                userIdMap.put(ddId,tbUser.getUserId(ddId,false));
+            }
+            mchMap.put(UtilMap.getString(map,"textField_mec6juil"),userIdMap.get(ddId));
+        }
+        mchList=tbUser.getUserIds(mchList, false);
+        mchList.remove(tbConf.getOperatorId());
+        List<String> userList = new ArrayList<>();
+        userList.addAll(pmUserId); // 添加 list1 的所有元素
+        userList.addAll(ssUserId);
+        userList.addAll(qeUserId);
+        userList.addAll(mchList);
+        Set<String> set = new HashSet<>(userList);
+        userList = new ArrayList<>(set);
+        tbProject.createProjectMember(tbProjectId, userList, tbConf.getOperatorId());
+        if (!mchList.isEmpty()) {
+            String roleId = _getProjectRoleId(tbProjectId, "跟单(MCH)");
+            tbProject.updateProjectMember(mchList, Arrays.asList(roleId), tbProjectId);
+        }
+        if (!qeUserId.isEmpty()) {
+            String roleId = _getProjectRoleId(tbProjectId, "质控(QE)");
+            tbProject.updateProjectMember(qeUserId, Arrays.asList(roleId), tbProjectId);
+        }
+        // 指定项目经理为编辑权限
+        if (!pmUserId.isEmpty()) {
+            String roleId = _getProjectRoleId(tbProjectId, "项目拥有者");
+            tbProject.updateProjectMember(pmUserId, Arrays.asList(roleId), tbProjectId);
+        }
+        // 任务公用字段
+        List maincustomfields=new ArrayList();
+        maincustomfields.add(tbConf.assembleCustomFieldName("项目编号",pId));
+        maincustomfields.add(tbConf.assembleCustomFieldName("项目名称",pName));
+        maincustomfields.add(tbConf.assembleCustomFieldName("产品阶段",orderType));
+        maincustomfields.add(tbConf.assembleCustomFieldName("客户",merName));
+        maincustomfields.add(tbConf.assembleCustomField("业务(Sales)",getCustFiledValueId(ssUserId)));
+        maincustomfields.add(tbConf.assembleCustomField("项目经理(PM)",getCustFiledValueId(pmUserId)));
+        maincustomfields.add(tbConf.assembleCustomField("品控(QE)",getCustFiledValueId(qeUserId)));
+
+        // 任务类型
+        String scenariofieldconfigId=_getTaskType(tbProjectId,pTaskType);
+        String sonScenariofieldconfigId=_getTaskType(tbProjectId,"配件-子任务");
+        String tasklistId=_getTaskList(tbProjectId,orderType+"项目");
+        String stageId= tbTask.queryTaskStage(tbProjectId,tasklistId,"启动阶段");
+        // 全品类任务生成
+        List<Map> table= ydService.queryDetails(YDParam.builder().formInstanceId(formInstId).formUuid(EastarParam.YD_FORMUUID_PROJECT).tableFieldId("tableField_mdy8x198").build());// 全品类配件表
+        List<Map> recodTable = new ArrayList<>();
+        List<String> jds=UtilMap.getList(data,"checkboxField_me9n37rs");
+        for(Map map:table){
+            Map taskMap=UtilMap.map("projectId, tasklistId, scenariofieldconfigId, stageId",tbProjectId,tasklistId,scenariofieldconfigId,stageId);
+            taskMap.put("content",String.valueOf(map.get("selectField_me2f7tw4"))+"-"+String.valueOf(map.get("textField_me2f7tvo"))); //系列 配件
+            taskMap.put("executorId",mchMap.get(UtilMap.getString(map,"textField_me2f7tvz"))); // 通过供应商确定执行人
+            List<Map> customfields=getCustomfields(EastarParam.CUSTFIELD_ACCE,map);
+            customfields.addAll(maincustomfields);
+            List<Map> resulr=null;
+            boolean isLang="是".equals(UtilMap.getString(map,"radioField_me2f7tvx"));
+            boolean isType="是".equals(UtilMap.getString(map,"radioField_metn23go"));
+            String type=UtilMap.getString(map,"selectField_me2f7tvk"); // 配件大类
+            Map<String,List<String>> sonconfs=sonConf.get(type);
+            List<String> sonconf=new ArrayList<>();
+            if(sonconfs!=null&&sonconfs.size()>0){
+                for(String str:jds){
+                    if(sonconfs.containsKey(str)){
+                        List<String> list=sonconfs.get(str);
+                        for (String s: list) {
+                            sonconf.add(type+" / "+s);
+                        }
+                    }
+                }
+            }
+            if(isType){// 区分工艺
+                if(isLang){ // 区分语言  通过工艺拆分
+                    resulr=saveTbTask(taskMap,orderTypeAndLangConf,UtilMap.getString(map,"selectField_me2f7tw4"),customfields,isLang,isType,sonconf,sonScenariofieldconfigId);
+                }else{// 不区分语言  通过工艺没有
+                    resulr=saveTbTask(taskMap,orderTypeConf,UtilMap.getString(map,"selectField_me2f7tw4"),customfields,isLang,isType,sonconf,sonScenariofieldconfigId);
+                }
+            }else{// 不区分工艺
+                if(isLang){ // 区分语言
+                    resulr=saveTbTask(taskMap,orderLangConf,UtilMap.getString(map,"selectField_me2f7tw4"),customfields,isLang,isType,sonconf,sonScenariofieldconfigId);
+                }else{
+                    resulr=saveTbTask(taskMap,Arrays.asList(UtilMap.map("textField_meqqj4wa, textField_mesc7nvm, numberField_mesc7nvo",
+                            map.get("selectField_me2f7tw4"),map.get("selectField_me2f7tvj"),map.get("numberField_me2f7tvl"))),
+                            UtilMap.getString(map,"selectField_me2f7tw4"),customfields,isLang,isType,sonconf,sonScenariofieldconfigId);
+                }
+            }
+            recodTable.addAll(resulr);
+        }
+        // 公仔任务生成
+        List<Map> recodTable2 = new ArrayList<>();
+        boolean isNeedDoll="是".equals(UtilMap.getString(data,"selectField_mdf997xg"));
+        if(isNeedDoll){
+            List<Map> table2= ydService.queryDetails(YDParam.builder().formInstanceId(formInstId).formUuid(EastarParam.YD_FORMUUID_PROJECT).tableFieldId("tableField_me2f7tw1").build());// 公仔配件表
+            maincustomfields.add(tbConf.assembleCustomFieldName("配件品类","公仔类"));
+            for(Map map: table2){
+                Map taskMap=UtilMap.map("projectId, tasklistId, scenariofieldconfigId, stageId",tbProjectId,tasklistId,scenariofieldconfigId,stageId);
+                taskMap.put("content",String.valueOf(map.get("selectField_me2f7tw3"))+"-"+String.valueOf(map.get("textField_mec5w62c")));
+                taskMap.put("executorId",mchMap.get(UtilMap.getString(map,"textField_mec5w62j"))); // 通过供应商确定执行人
+                List<Map> customfields=getCustomfields(EastarParam.CUSTFIELD_DOLL,map);
+                customfields.addAll(maincustomfields);
+                taskMap.put("customfields",customfields);
+                Map result=tbTask.createTask(tbConf.getOperatorId(), taskMap);
+                recodTable2.add(UtilMap.map("textField_mecmytpu, textField_mecmytpv, textField_mecmytpw",result.get("content"),result.get("taskId"),"未开始"));
+            }
+        }
+        saveRecod(data,tbProjectId,recodTable,recodTable2);
+        return Collections.emptyMap();
+    }
+
+    private List<Map> saveTbTask(Map taskMap,List<Map> orderConf,String series,List<Map> customfields,boolean isLang,boolean isType,List<String> sonconf,String sonScenariofieldconfigId){
+        log.info("创建任务:{},是否区分语言{},是否区分工艺{}",taskMap.get("content"),isLang,isType);
+        List<Map> recodTable=new ArrayList<>();
+        for(Map map: orderConf){
+            Map tMap=new HashMap();
+            tMap.putAll(taskMap);
+            String confSeries=UtilMap.getString_first(map,"textField_meqqj4wa","textField_mesc7nvl");// 系列
+            if(!series.equals(confSeries)){
+                continue;
+            }
+            if(isLang){
+                String lang=UtilMap.getString_first(map,"textField_mesc7nvm","textField_meqqj4wb"); // 语言
+                if(PublicUtil.isNull(lang)){
+                    lang="不区分";
+                }
+                tMap.put("content",tMap.get("content")+"-"+lang);
+                customfields.add(tbConf.assembleCustomFieldName("语言",lang));
+            }
+            if(isType){
+                String type=UtilMap.getString(map,"textField_mesc7nvn");// 工艺区别
+                if(!PublicUtil.isNull(type)){
+                    tMap.put("content",tMap.get("content")+"-"+type);
+                }
+            }
+            String value=String.valueOf(UtilMap.get_first(map,"numberField_mesc7nvo","numberField_meqqj4wd")); // 数量
+            customfields.add(tbConf.assembleCustomFieldName("订单数量",value));
+            tMap.put("customfields",customfields);
+            log.info("最终任务名称:{}",tMap.get("content"));
+            Map result=tbTask.createTask(tbConf.getOperatorId(), tMap);// 更新任务所属任务列表
+            recodTable.add(UtilMap.map("textField_mecmytpr, textField_mecmytps, textField_mecmytpt",result.get("content"),result.get("taskId"),"未开始"));
+            for (String son:sonconf){
+                Map sonMap=new HashMap();
+                sonMap.put("content",tMap.get("content")+"/"+son.replace("/","-"));
+                sonMap.put("executorId",taskMap.get("executorId"));
+                sonMap.put("stageId",taskMap.get("stageId"));
+                sonMap.put("tasklistId",taskMap.get("tasklistId"));
+                sonMap.put("scenariofieldconfigId",sonScenariofieldconfigId);
+                sonMap.put("parentTaskId",result.get("taskId"));
+                List soncustomfields=new ArrayList();
+                soncustomfields.add(tbConf.assembleCustomFieldName("SKU类型",son));
+                sonMap.put("customfields",soncustomfields);
+                sonMap.put("projectId",taskMap.get("projectId"));
+                Map sonResult=tbTask.createTask(tbConf.getOperatorId(), sonMap);
+                log.info("子任务名称:{}",sonResult.get("content"));
+            }
+        }
+        if(recodTable.size()<1){
+            log.info("该任务未匹配上区分规则:{}",taskMap.get("content"));
+        }
+        return recodTable;
+    }
+
+    @Override
+    public Map taskStateChange(String taskIds,String tfsName) {
+        String[] tasks=taskIds.split(",");
+        for(String taskId:tasks){
+            tbTask.updateTaskFlowStatusByName(taskId,tbConf.getOperatorId(),tfsName,"");
+        }
+        return Collections.emptyMap();
+    }
+
+    private void saveRecod(Map formData,String tbProjectId,List<Map> recodTable,List<Map> recodTable2){
+        Map map=new HashMap();
+        map.put("textField_me87x1nz",formData.get("textField_me87x1nz"));
+        map.put("textField_me2hyldc",formData.get("textField_me2hyldc"));
+        map.put("textField_me9n24kq",formData.get("textField_me9n24kq"));
+        map.put("textField_me2hyldb",formData.get("textField_me2hyldb"));
+        map.put("selectField_mdf997wp",formData.get("selectField_mdf997wp"));
+        map.put("selectField_me2hylde",formData.get("selectField_me2hylde"));
+        map.put("checkboxField_me9n37rs",formData.get("checkboxField_me9n37rs"));
+        map.put("associationFormField_me9n24kk",UtilMap.getAssFieldValue(formData,"associationFormField_me9n24kk_id"));
+        map.put("textField_mecmytpo",tbProjectId);
+        map.put("tableField_mecmytpp",recodTable);
+        map.put("tableField_mecmytpq",recodTable2);
+        ydClient.operateData(YDParam.builder().formUuid(EastarParam.YD_FORMUUID_RECOD).formDataJson(JSONObject.toJSONString(map)).build(), YDConf.FORM_OPERATION.create);
+    }
+
+    private List<Map> getCustomfields(Map<String,String> CUSTFIELD_TEXT,Map tableItem){
+        List<Map> customfields=new ArrayList<>();
+        for (String key : CUSTFIELD_TEXT.keySet()) {
+            customfields.add(tbConf.assembleCustomFieldName(key,UtilMap.getString(tableItem,CUSTFIELD_TEXT.get(key))));
+        }
+        return customfields;
+    }
+    private String _getProjectRoleId(String projectId, String roleName) {
+        List<Map> roles = tbProject.queryProjectRoles(projectId);
+        Optional optional = roles.stream().filter(item -> roleName.equals(item.get("name"))).findAny();
+        McException.assertAccessException(!optional.isPresent(), roleName + ": 项目角色不存在");
+        return UtilMap.getString((Map) optional.get(), "id");
+    }
+    private static List<Map> getCustFiledValueId(List<String> ssUserId){
+        return ssUserId.stream().map(item->{
+            return UtilMap.map("id, title",item,item);
+        }).collect(Collectors.toList());
+    }
+
+    String _getTaskType(String projectId, String taskTypeName) {
+
+        List<Map> customFlowStatus = tbProject.queryProjectTaskType(projectId, UtilMap.map("q", taskTypeName));
+        // 7.10 避免模糊匹配
+        customFlowStatus = customFlowStatus.stream().filter(item -> taskTypeName.equals(UtilMap.getString(item, "name"))).collect(Collectors.toList());
+        McException.assertAccessException(customFlowStatus.isEmpty(), "工作流名称未匹配");
+        return String.valueOf(customFlowStatus.get(0).get("id"));
+    }
+
+    String _getTaskList(String projectId, String taskListName) {
+
+        List<Map> customFlowStatus = tbProject.queryProjectTaskList(projectId, UtilMap.map("q", taskListName));
+        // 7.10 避免模糊匹配
+        customFlowStatus = customFlowStatus.stream().filter(item -> taskListName.equals(UtilMap.getString(item, "title"))).collect(Collectors.toList());
+        McException.assertAccessException(customFlowStatus.isEmpty(), "任务分组名称未匹配");
+        return String.valueOf(customFlowStatus.get(0).get("id"));
+    }
+
+}

+ 41 - 0
src/main/java/com/malk/eastar/util/ConfigDataProcessor.java

@@ -0,0 +1,41 @@
+package com.malk.eastar.util;
+
+import com.malk.utils.UtilMap;
+
+import java.util.*;
+
+public class ConfigDataProcessor {
+    
+    public static Map<String, Map<String, List<String>>> processConfigData(List<Map> rawData) {
+        Map<String, Map<String, List<String>>> result = new HashMap<>();
+        
+        for (Map<String, Object> data : rawData) {
+            processSingleRecord(data, result);
+        }
+        
+        return result;
+    }
+    
+    private static void processSingleRecord(Map<String, Object> data, 
+                                          Map<String, Map<String, List<String>>> result) {
+        List<String> types = UtilMap.getList(data, "multiSelectField_mew7d9fi");
+        String jd = UtilMap.getString(data, "selectField_mew7d9f5");
+        String value = UtilMap.getString(data, "textField_mew7d9f6");
+        
+        for (String type : types) {
+            result.computeIfAbsent(type, k -> new HashMap<>())
+                 .computeIfAbsent(jd, k -> new ArrayList<>())
+                 .add(value);
+        }
+    }
+
+    public static List<String> getValues(String type, String jd,Map<String, Map<String, List<String>>> conf) {
+        if (type == null || jd == null || conf == null) {
+            return Collections.emptyList();
+        }
+        return Optional.ofNullable(conf.get(type))
+                .map(jdMap -> jdMap.get(jd))
+                .map(ArrayList::new) // 创建副本
+                .orElseGet(ArrayList::new);
+    }
+}

+ 30 - 0
src/main/resources/application-dev.yml

@@ -0,0 +1,30 @@
+server:
+  port: 9001
+  servlet:
+    context-path: /api/eastar
+enable:
+  scheduling: false
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/eastar/log/
+  level:
+    com.malk.*: info
+
+# dingtalk
+dingtalk:
+  agentId: 2691784047
+  appKey: dinghbynhnd2dbgypmsa
+  appSecret: Kl5Xw8x0TlEIlvcJuUkYZD18UTTShJmfdKrAIpY8oX-Q_tazyUKA28nQh7dG5-mq
+  corpId: dingcc1b1ffad0d5ca1d
+  aesKey:
+  token:
+# teambition
+teambition:
+  AppID: 68919e490c35df13db800269
+  AppSecret: mbifWR33zSavdzHNAAkExP0lpE8fH9Z0
+  TenantId: 62cb89730b5f5274193dbb0d
+  OperatorId: 6864f3edd93b62a08c01c827    # 公共账号, 需要有操作权限 [牧语]
+# aliwork
+aliwork:
+  appType: APP_GM7D1NW6XCD0ZJBPVH51
+  systemToken: I0D66I71GCWWUP7XAUV8757S5B7N3V2OZGSCMTFD

+ 30 - 0
src/main/resources/application-prod.yml

@@ -0,0 +1,30 @@
+server:
+  port: 9900
+  servlet:
+    context-path: /api/eastar
+enable:
+  scheduling: true
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/eastar/log/
+  level:
+    com.malk.*: info
+
+# dingtalk
+dingtalk:
+  agentId: 2691784047
+  appKey: dinghbynhnd2dbgypmsa
+  appSecret: Kl5Xw8x0TlEIlvcJuUkYZD18UTTShJmfdKrAIpY8oX-Q_tazyUKA28nQh7dG5-mq
+  corpId: dingcc1b1ffad0d5ca1d
+  aesKey:
+  token:
+# teambition
+teambition:
+  AppID: 68919e490c35df13db800269
+  AppSecret: mbifWR33zSavdzHNAAkExP0lpE8fH9Z0
+  TenantId: 62cb89730b5f5274193dbb0d
+  OperatorId: 6864f3edd93b62a08c01c827    # 公共账号, 需要有操作权限 [牧语]
+# aliwork
+aliwork:
+  appType: APP_GM7D1NW6XCD0ZJBPVH51
+  systemToken: I0D66I71GCWWUP7XAUV8757S5B7N3V2OZGSCMTFD

+ 9 - 0
src/main/resources/application.yml

@@ -0,0 +1,9 @@
+spring:
+  profiles:
+    active: dev
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 100MB
+  http:
+    enabled: false

+ 61 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false" scan="false" scanPeriod="60 seconds">
+    <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="/home/server/log/"/>
+    <property name="FileNamePattern" value="${LOG_HOME}%d{yyyyMM}/%d{dd}"/>
+
+    <!-- 定义控制台输出 -->
+    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - [%thread] - %-5level - %logger{50} - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <!--<file>${FileNamePattern}/info.log</file>-->
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${FileNamePattern}/info-%i.log</fileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <MaxFileSize>30MB</MaxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator>
+            <Key>processid</Key>
+            <DefaultValue>sys</DefaultValue>
+        </discriminator>
+        <sift>
+            <appender name="FILE-${processid}"
+                      class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <FileNamePattern>
+                        ${FileNamePattern}/${processid}.log
+                    </FileNamePattern>
+                </rollingPolicy>
+                <layout class="ch.qos.logback.classic.PatternLayout">
+                    <Pattern>
+                        %d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n
+                    </Pattern>
+                </layout>
+            </appender>
+        </sift>
+    </appender>
+
+
+    <!-- 日志输出级别 -->
+    <logger name="org.springframework" level="debug"  additivity="false"/>
+    <logger name="com.zitoo.connecter" level="debug"/>
+    <root level="INFO">
+        <appender-ref ref="stdout"/>
+        <appender-ref ref="appLogAppender"/>
+        <appender-ref ref="SIFT"/>
+    </root>
+</configuration>

+ 61 - 0
src/test/java/TbTest.java

@@ -0,0 +1,61 @@
+import com.alibaba.fastjson.JSONObject;
+import com.malk.eastar.LtcEastarApplication;
+import com.malk.eastar.conf.CfsToStageEnum;
+import com.malk.eastar.conf.EastarParam;
+import com.malk.eastar.service.EastarTbService;
+import com.malk.eastar.util.ConfigDataProcessor;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.service.teambition.TBClient_Project;
+import com.malk.service.teambition.TBClient_Task;
+import com.malk.utils.UtilList;
+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.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@SpringBootTest(classes = LtcEastarApplication.class)
+@RunWith(SpringRunner.class)
+public class TbTest {
+
+    @Autowired
+    private EastarTbService eastarTbService;
+    @Autowired
+    private TBClient_Task tbTask;
+
+    String tempId="689edfd6ee73c95fe1438e24";
+    String projectId = "";
+
+    @Test
+    public void createProject() {
+        Map map=eastarTbService.createProject("8.5测试项目",tempId,"");
+        System.out.println(map);
+    }
+
+    @Test
+    public void createTask() {
+        Map map=eastarTbService.createTask("93cd379b-cc9c-4060-a7fa-77cbc4f14af1");
+    }
+
+    @Autowired
+    private YDService ydService;
+
+    @Test
+    public void testYd(){
+        List<Map> sonConfData= ydService.queryDetails(YDParam.builder().formInstanceId("FINST-X1B66Y81IUFY9U417XIUE99I8YV93HGMJ8WEMF").formUuid(EastarParam.YD_FORMUUID_SONCONF).tableFieldId("tableField_mew7d9f3").build());// 全品类配件表
+        Map<String,Map<String,List<String>>>  map= ConfigDataProcessor.processConfigData(sonConfData);
+        log.info("map:{}",map);
+    }
+}