package com.malk.aiwei.service.impl; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.malk.aiwei.server.AWServer; import com.malk.aiwei.service.AWClint; import com.malk.aiwei.service.AwDingService; import com.malk.server.aliwork.YDConf; import com.malk.server.aliwork.YDParam; import com.malk.server.common.McException; import com.malk.server.dingtalk.DDConf; import com.malk.server.teambition.TBConf; import com.malk.service.aliwork.YDClient; import com.malk.service.aliwork.YDService; import com.malk.service.teambition.TBClient; import com.malk.utils.*; import lombok.Synchronized; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; @Service @Slf4j public class AWImplClient implements AWClint { @Autowired private YDClient ydClient; @Autowired private YDService ydService; @Autowired private YDConf ydConf; @Autowired private AwDingService awDingService; // 项目主数据表 String _matchFormUuid(String code) { Map formUuid = UtilMap.empty(); if (true || UtilEnv.getActiveProfile().equals(UtilEnv.ENV_PROD)) { formUuid.put("REVIEW", "FORM-812FD46AF391449A8F206EDB3221B38840UQ"); // 交付物审批记录 formUuid.put("REVIEW_PROCESS", "TPROC--RJC66SC1NEFHXJ0H770K0CF4WN1K21HQ706RL5"); // 交付物审批记录 formUuid.put("PROJECT", "FORM-141E21DF183846028E21727CE43CD1C75CLZ"); // 项目主数据 formUuid.put("APPROVE", "FORM-A25299893F614A6EAA672514D3A76BB0QDBF"); // 交付物审批矩阵 formUuid.put("CHECK", "FORM-1A5D4D7FBF88409B956EBE51F9342A6BKOLP"); // 预检项 formUuid.put("RECORD", "FORM-6E2C0D1197264B8AA23EB3FECAE7344B00BN"); // 预检项记录 formUuid.put("ROLE", "FORM-3C7396A12ADB48A8833EBD90089C93833R21"); // 项目角色 formUuid.put("ROLE_PDT", "FORM-69B6A8151F3346DCA20B0ED54F5380675LJX"); // PDT角色 formUuid.put("CRM_LOG", "FORM-16DD578308E64763AE1539D8176CCCD0GX6F"); // crm推送日志 formUuid.put("TEMPLATE", "FORM-24EFE5C1BCE54E7192E53B33ADFBF1C52NS3"); // TB模板与项目类型映射表 formUuid.put("DOMAIN", "https://yida.awinic.com/"); // 宜搭域名 } else { // [ fixme: 测试环境添加主数据, 匹配不同架构下企业成员 ] formUuid.put("REVIEW", "FORM-FBC1A390B4C348089020C763938A6F54RUNY"); formUuid.put("REVIEW_PROCESS", "TPROC--YU966T91PIDH4XDR82OJC8GVOP7Z19PODTXQL6"); formUuid.put("PROJECT", "FORM-84EF78C7DBA047E58A8C8511106F91D5WNVI"); formUuid.put("APPROVE", "FORM-AB7263D2A12F4E01A871656F0D995BC96PR1"); formUuid.put("CHECK", "FORM-E6CB042D7929448888AE5E2B27631E57IVPM"); formUuid.put("RECORD", "FORM-7B63BB056145452F8BC0A2C52492DE00QVBH"); formUuid.put("ROLE", "FORM-5BE21392886E46DF955D1EBC100ADA429NON"); formUuid.put("CRM_LOG", "FORM-7F40E85D4FA8487C8E00C9156B76A953CBMG"); formUuid.put("TEMPLATE", "FORM-C864290977A64FC4A061434DF21D5871JA04"); formUuid.put("DOMAIN", "https://kabom7.aliwork.com/"); } return formUuid.get(code); } /** * 交付物审批 [ppExt: 宜搭附件传递 downloadUrl 和 name 即可实现在线预览] */ @Override public void doApprove(Map data) { String projectId = UtilMap.getString(data, "projectId"); String workFlowApprove = _getWorkFlowStatus(projectId, AWServer.WORKFLOW_APPROVE); if (!data.get("tfsId").equals(workFlowApprove)) { return; } log.info("交付物审批, {}", data); String pCode = UtilMap.getString(data, "projectId"); String creatorId = UtilMap.getString(data, "creatorId"); String taskId = UtilMap.getString(data, "taskId"); Map taskData = _getTaskFieldMap(UtilMap.getString(data, "taskId"), AWServer.TASK_CODE, AWServer.TASK_APPROVE_ATTACHMENT, AWServer.TASK_APPROVE_DESC); String tCode = UtilMap.getString(taskData, AWServer.TASK_CODE); // 工作流tb虽然配置了流转逻辑, 冗余稳定性 List formList = (List) ydClient.queryData(YDParam.builder() .formUuid(_matchFormUuid("REVIEW")) .searchFieldJson(JSON.toJSONString(UtilMap.map("selectField_lqxuswzd, textField_lrncs2fu", tCode, pCode))) .instanceStatus("RUNNING") .build(), YDConf.FORM_QUERY.retrieve_search_process).getData(); if (formList.size() > 0 && formList.stream().filter(item -> tCode.equals(((Map) item.get("data")).get("selectField_lqxuswzd"))).findAny().isPresent()) { return; } String result = ""; List tList = null; Map rProject = null; if (StringUtils.isBlank(tCode)) { result = "无任务编码"; } else { List pList = ydService.queryDataList_FormData(_matchFormUuid("PROJECT"), UtilMap.map("textField_lqxtykce", pCode)); pList = pList.stream().filter(item -> pCode.equals(item.get("textField_lqxtykce"))).collect(Collectors.toList()); if (pList.size() == 0) { result = "未匹配到项目主数据"; } else { rProject = pList.get(0); // prd 多模板适配: [任务号 + 项目类型] String proType = UtilMap.getString(rProject, "textField_ltwcq7s6"); tList = ydService.queryDataList_FormData(_matchFormUuid("APPROVE"), UtilMap.map("selectField_lrncf4hk, radioField_lrnddfq6", tCode, "启用")); tList = tList.stream().filter(item -> tCode.equals(item.get("selectField_lrncf4hk")) && UtilMap.getList(item, "multiSelectField_ltwjre9s").contains(proType)).collect(Collectors.toList()); if (tList.size() == 0) { result = "未配置交付物审批"; } } /// 发起评审 if (StringUtils.isBlank(result)) { List roles = (List) rProject.get("tableField_lqxtykcf"); Map formData = UtilMap.map("selectField_lqxuswzd, textField_lrncs2fu", tCode, pCode); formData.put("attachmentField_lqxtebtq", _getDocs(taskData)); formData.put("selectField_lqxuswze", UtilMap.getString(rProject, "textField_lrj7vnxb")); // 项目编号 formData.put("textField_lqxuc9m4", UtilMap.getString(rProject, "textareaField_lrj7vnxl")); // 项目描述 formData.put("employeeField_ltzn872j", UtilMap.getString(rProject, "employeeField_ltzn872j_id")); // 项目经理 0402 控制矩阵角色为空, 流转到PM formData.put("textField_ltwcq7s6", UtilMap.getString(rProject, "textField_ltwcq7s6")); // 项目类型 formData.put("textareaField_lw0nmvko", UtilMap.getString(taskData, AWServer.TASK_APPROVE_DESC)); // 交付件描述 // 匹配任务编码与项目角色 List> compIds = Arrays.asList( // 任务表角色, 交付物评审表: 角色, 审批人 UtilMap.map("tsRole, prRole, prEmp", "multiSelectField_lrokzlo7, multiSelectField_lrokzlo7, employeeField_lqxtebtw"), UtilMap.map("tsRole, prRole, prEmp", "multiSelectField_lrokzlo8, multiSelectField_lrokzlo8, employeeField_lqxtebtx"), UtilMap.map("tsRole, prRole, prEmp", "multiSelectField_lrokzlo9, multiSelectField_lrokzlo9, employeeField_lqxtebty")); Map rCondition = tList.get(0); for (Map compId : compIds) { // ppExt: 宜搭多选若无值则不返回字段 [prd 角色多选, 会签逻辑] if (!rCondition.containsKey(compId.get("tsRole"))) { continue; } List namesCondition = (List) rCondition.get(compId.get("tsRole")); List namesApproveRole = new ArrayList<>(); List namesApprover = new ArrayList<>(); for (String name : namesCondition) { Optional optional = roles.stream().filter(item -> UtilString.equal(name, item.get("selectField_lqxu6bgf"))).findAny(); if (optional.isPresent()) { Map detail = (Map) optional.get(); if (ObjectUtil.isNotNull(detail.get("selectField_lqxu6bgf"))) { namesApproveRole.add(String.valueOf(detail.get("selectField_lqxu6bgf"))); } if (ObjectUtil.isNotNull(detail.get("employeeField_lqxtykch_id"))) { namesApprover.addAll((List) detail.get("employeeField_lqxtykch_id")); } } } formData.put(compId.get("prRole"), namesApproveRole); formData.put(compId.get("prEmp"), namesApprover); } // 组装数据 Map extra = (Map) tbClient.idMapQuery(creatorId, "dingTalk-user", ddConf.getCorpId()).get(0).get("extra"); UtilMap.putAll(formData, UtilMap.map("textField_lr3dlwsa, textField_lr3er4qb", taskId, creatorId)); formData.put("employeeField_lui5fu7z", Arrays.asList(extra.get("userId"))); // 0402 指定发起人, 用于结构化数据子流程发起人 String instanceId = (String) ydClient.operateData(YDParam.builder() .formUuid(_matchFormUuid("REVIEW")) .processCode(_matchFormUuid("REVIEW_PROCESS")) .formDataJson(JSON.toJSONString(formData)) .userId(extra.get("userId")) .build(), YDConf.FORM_OPERATION.start); result = _matchFormUuid("DOMAIN") + ydConf.getAppType() + "/processDetail?procInsId=" + instanceId; } } log.info("交付物结果, {}", result); Map body = TBConf.assembleCustomFieldName(AWServer.TASK_APPROVE_LINK, result); tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body); } /** * 交付物审批回调 */ @Override public void approved(Map data) { log.info("交付物审批回调, {}", data); String result = String.valueOf(data.get("approve")); String workFlowId = _getWorkFlowStatus(String.valueOf(data.get("projectId")), result); tbClient.updateTaskFlowStatus(String.valueOf(data.get("taskId")), tbConf.getOperatorId(), workFlowId, String.valueOf(data.get("approve"))); } @Autowired private TBClient tbClient; @Autowired private DDConf ddConf; // 获取任务详情 fixme 提取到 tbservice private Map _getTaskFieldMap(Map task, List projectCustomField, String... fieldNames) { return __getTaskMap(task, projectCustomField, fieldNames); } // 组装任务数据 private Map __getTaskMap(Map task, List projectCustomField, String... fieldNames) { Map result = UtilMap.map("task", task); List taskCustomField = (List) 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; } // 获取任务详情 fixme 提取到 tbservice private Map _getTaskFieldMap(String taskId, String... fieldNames) { // 查询任务详情 Map rTask = tbClient.queryTaskDetail(taskId, null, null).get(0); // 查询项目任务ID List customField = tbClient.queryProjectCustomField(String.valueOf(rTask.get("projectId")), null); return __getTaskMap(rTask, customField, fieldNames); } // 匹配工作流名称, 获取ID @Deprecated String _getWorkFlowStatus(String projectId, String workFlowStatusName) { List customFlowStatus = tbClient.queryProjectCustomFlowStatus(projectId, UtilMap.map("q", workFlowStatusName)); McException.assertAccessException(customFlowStatus.isEmpty(), "工作流名称未匹配"); return String.valueOf(customFlowStatus.get(0).get("id")); } // 前置过滤 fixme 提取方法 List _getWorkFlowStatusList(String projectId, String... workFlowStatusNames) { List workFlowStatusList = new ArrayList<>(); for (String name : workFlowStatusNames) { List customFlowStatus = tbClient.queryProjectCustomFlowStatus(projectId, UtilMap.map("q", name)); workFlowStatusList.addAll(customFlowStatus.stream().map(item -> UtilMap.getString(item, "id")).collect(Collectors.toList())); } return workFlowStatusList; } // 后置过滤 fixme 提取方法 List _getWorkFlowStatusList(String projectId, List workFlowStatusNames) { //List names = Arrays.stream(workFlowStatusNames).collect(Collectors.toList()); List customFlowStatus = tbClient.queryProjectCustomFlowStatus(projectId, null); List workFlowStatusList = customFlowStatus.stream().filter(item -> workFlowStatusNames.contains(item.get("name"))).collect(Collectors.toList()); return workFlowStatusList.stream().map(item -> UtilMap.getString(item, "id")).collect(Collectors.toList()); } /** * 获取知识库附件传递到宜搭 * - ppExt - * 1. 宜搭附件传递 downloadUrl 和 name 即可实现在线预览 * 2. 知识库绑定没有文件后缀, 宜搭识别目前仅能点击下载跳转预览, 添加统一docx后缀, 文档会自行区分 */ List _getDocs(Map taskData) { Map rTask = UtilMap.getMap(taskData, "task"); List customfields = UtilMap.getList(rTask, "customfields"); String deliverable = String.valueOf(taskData.get(AWServer.TASK_APPROVE_ATTACHMENT + "_id")); // 交付物任务字段ID List attachments = TBConf.getTaskFieldValue(customfields, deliverable).stream().map(item -> { Map link = (Map) JSON.parse(String.valueOf(item.get("metaString"))); return UtilMap.map("downloadUrl, name", link.get("url"), link.get("title") + ".docx"); }).collect(Collectors.toList()); return attachments; } /** * 检查项check * * @param isTask 服务于任务自定义详情卡片, 否则为宜搭发起: 抛出错误信息 */ @Override public Map doCheck(String taskId, boolean isTask) { log.info("检查项check, {}", taskId); Map taskData = _getTaskFieldMap(taskId, AWServer.TASK_CODE, AWServer.TASK_CHECK_LINK, AWServer.TASK_ROLE, AWServer.TASK_STAGE, AWServer.TASK_CHECK_STATUS, AWServer.TASK_PRODUCT, AWServer.TASK_PRODUCT_VERSION); Map rTask = UtilMap.getMap(taskData, "task"); String pCode = UtilMap.getString(rTask, "projectId"); if (AWServer.PROJECT_IGNORE_ID.contains(pCode)) { return UtilMap.map("result", "模板/复用项目"); } String checkLink = UtilMap.getString(taskData, AWServer.TASK_CHECK_LINK); /// prd 预检项持续维护需要重新匹配, 任务号和主数据判定为非法, 无需重新刷新 if (isTask && (StringUtils.isNotBlank(checkLink) && !"未配置预检项".equals(checkLink))) { return UtilMap.map("result", "链接已加载"); } // prd 非未完成任务若是未配置预检项状态, 忽略更新 if (isTask && !_getWorkFlowStatusList(pCode, AWServer.WORKFLOW_INITIAL).contains(rTask.get("tfsId"))) { return UtilMap.map("result", "任务已执行"); } String creatorId = UtilMap.getString(rTask, "creatorId"); String tCode = UtilMap.getString(taskData, AWServer.TASK_CODE); String result = ""; List tList = null; Map rProject = null; if (StringUtils.isBlank(tCode)) { result = "无任务编码"; } else { List pList = ydService.queryDataList_FormData(_matchFormUuid("PROJECT"), UtilMap.map("textField_lqxtykce", pCode)); pList = pList.stream().filter(item -> pCode.equals(item.get("textField_lqxtykce"))).collect(Collectors.toList()); if (pList.size() == 0) { result = "未匹配到项目主数据"; } else { rProject = pList.get(0); String proType = UtilMap.getString(rProject, "textField_ltwcq7s6"); tList = ydService.queryFormData_all(YDParam.builder() .formUuid(_matchFormUuid("CHECK")) .searchFieldJson(JSON.toJSONString(UtilMap.map("selectField_lrncf4hk, radioField_lrnddfq6", tCode, "启用"))) .build()); // prd 多模板适配: [任务号 + 项目类型] tList = tList.stream().filter(item -> tCode.equals(item.get("selectField_lrncf4hk")) && UtilMap.getList(item, "multiSelectField_ltwjre9s").contains(proType)).collect(Collectors.toList()); if (tList.size() == 0) { result = "未配置预检项"; } else { result = _matchFormUuid("DOMAIN") + ydConf.getAppType() + "/workbench/" + _matchFormUuid("RECORD") + "?taskId=" + taskId; } } } log.info("检查项结果, {}", result); if (isTask) { if (!checkLink.equals(result)) { Map body = TBConf.assembleCustomFieldName(AWServer.TASK_CHECK_LINK, result); tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body); } // prd 未配置预检项更新为已检查, 避免完成任务完成触发必填校验 [ppExt 避免重复写入, 重复写入TB会重复记录日志 if (!result.startsWith("http") && !taskData.get(AWServer.TASK_CHECK_STATUS).equals("已检查")) { Map body = TBConf.assembleCustomFieldName(AWServer.TASK_CHECK_STATUS, "已检查"); tbClient.updateTaskCustomField(taskId, tbConf.getOperatorId(), body); } return UtilMap.map("result", result); } McException.assertAccessException(!result.startsWith("https://"), result); Map formData = UtilMap.map("selectField_lqxuswzd, textField_lrndwu00, textField_lr3dlwsa, textField_lr3er4qb", tCode, pCode, taskId, creatorId); // 项目信息 formData.putAll(UtilMap.map("selectField_lqxuswze, textField_lrndwu07, textField_lqxuc9m4", UtilMap.getString(rProject, "textField_lrj7vnxb"), UtilMap.getString(rProject, "textareaField_lrj7vnxl"), UtilMap.getString(rProject, "textField_lqxtykcd"))); // 任务信息 [TBManager 操作] Map extra = (Map) tbClient.idMapQuery(creatorId, "dingTalk-user", ddConf.getCorpId()).get(0).get("extra"); // ppExt: TB映射钉钉信息仅返回 userId, 人员组件返回前端展示需要 name. 通过页面公式临时自动加载, 可通过TB接口或钉钉用户接口查询 formData.putAll(UtilMap.map("textField_lrndwu09, textField_lrndwu0a, textField_lrndwu0b, employeeField_lrndwu0e, textField_lvbrueqs, textField_lvbrueqt", rTask.get("content"), taskData.get(AWServer.TASK_STAGE), taskData.get(AWServer.TASK_ROLE), Arrays.asList(UtilMap.map("value, name", extra.get("userId"), extra.get("userId"))), taskData.get(AWServer.TASK_PRODUCT), taskData.get(AWServer.TASK_PRODUCT_VERSION))); // 返回检查项 formData.put("tableField_lqxxgj4s", tList.stream().map(item -> { item.put("associationFormField_lrrnem5r", YDConf.associationForm(ydConf.getAppType(), _matchFormUuid("CHECK"), UtilMap.getString(item, "instanceId"), UtilMap.getString(item, "textField_lrnd3h0r"), "", false)); return item; }).collect(Collectors.toList())); return formData; } /** * 检查项回调 */ @Override public void checked(Map data) { log.info("检查项回调, {}", data); Map body = TBConf.assembleCustomFieldName(AWServer.TASK_CHECK_STATUS, "已检查"); tbClient.updateTaskCustomField(String.valueOf(data.get("taskId")), tbConf.getOperatorId(), body); String result = _matchFormUuid("DOMAIN") + ydConf.getAppType() + "/formDetail?formInstId=" + data.get("formInstId"); Map body2 = TBConf.assembleCustomFieldName(AWServer.TASK_CHECK_LINK, result); tbClient.updateTaskCustomField(String.valueOf(data.get("taskId")), tbConf.getOperatorId(), body2); } /** * 同步项目主数据 [兼容新增] */ @Synchronized @Override public Map syncProject(String projectCode) { // 新增场景下, 提供实例ID回写TB项目编号 Map formData = null; // 查询项目主数据 [艾为应用] YDParam ydParam = YDParam.builder() .appType("APP_QBWQITQBSPJNYTUTNPDK") .systemToken("8F966HB12J27MQJM6V4IQDYHYTPA2G4GTZGCLN1") .formUuid("FORM-Q4A664A1V158R81L662N9507PLND288T7O6ELN") .build(); if (StringUtils.isNotBlank(projectCode)) { ydParam.setSearchFieldJson(JSON.toJSONString(UtilMap.map("textField_le6o88w0", projectCode))); } // prd 客户系统主数据, 是全量定时从mdm更新, 因此不能增量 List mapBaseList = ydService.queryFormData_all(ydParam); if (StringUtils.isNotBlank(projectCode)) { mapBaseList = mapBaseList.stream().filter(item -> projectCode.equals(item.get("textField_le6o88w0"))).collect(Collectors.toList()); } log.info("项目主数据, {}", mapBaseList.size()); McException.assertAccessException(mapBaseList.isEmpty(), "未匹配项目主数据"); // 查询项目角色 YDParam ydParam1 = YDParam.builder() .formUuid(_matchFormUuid("ROLE")) .build(); List mapRole = (List) ydClient.queryData(ydParam1, YDConf.FORM_QUERY.retrieve_search_form).getData(); // prd 5.14 C类项目成员同步PDT成员主数据 ydParam1.setFormUuid(_matchFormUuid("ROLE_PDT")); List rolePDT = (List) ydClient.queryData(ydParam1, YDConf.FORM_QUERY.retrieve_search_form).getData(); // 匹配数据组件ID for (Map baseFormData : mapBaseList) { // 项目主数据 formData = new HashMap(); formData.put("textField_lqxtykcd", baseFormData.get("textField_lo2c1f0l")); // 项目名称 formData.put("textField_lrj7vnxb", baseFormData.get("textField_le6o88w0")); // 项目号 formData.put("textField_lrj7vnxc", baseFormData.get("textField_le6o88w1")); // 项目简称 formData.put("textareaField_lrj7vnxl", baseFormData.get("textField_le6o88w2")); // 项目描述 formData.put("textField_lrj7vnxf", baseFormData.get("formInstanceId")); // 项目实例ID formData.put("textField_ltsdsti6", baseFormData.get("textField_libg2ea8")); // PDT (项目分组) formData.put("textField_ltsdsti7", baseFormData.get("textField_llouhiyf")); // 项目状态 formData.put("textField_ltsdsti8", baseFormData.get("textField_lo2c1f0r")); // mPDT formData.put("textField_ltsdsti9", baseFormData.get("textField_lki3egzn")); // Charter子类 formData.put("textField_ltwcq7s5", baseFormData.get("textField_lki3egzm")); // Charter formData.put("textField_ltwcq7s6", baseFormData.get("textField_lnjqpeie")); // 项目类型 (TB项目模板) List details = new ArrayList<>(); List roleMap = mapRole; Map projectMembers = baseFormData; // 项目角色详情 [prd 5.14 C类项目成员同步PDT成员主数据] if ("Charter开发项目".equals(formData.get("textField_ltwcq7s6"))) { roleMap = rolePDT; String charter = String.valueOf(formData.get("textField_ltsdsti6")); YDParam ydParam2 = YDParam.builder() .appType("APP_LH2TJTIT3EWHCG084TGL") .systemToken("QYC66KA1F4ZG5RQV8HR9WBHYW03S3CQAJKDQLZ1") .formUuid("FORM-90E23DE1BBEB43759ED9517F98BA4938P61C") .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_lr0dvhqh", charter))) .build(); List listPDT = (List) ydClient.queryData(ydParam2, YDConf.FORM_QUERY.retrieve_search_form).getData(); listPDT = listPDT.stream().filter(item -> charter.equals(((Map) item.get("formData")).get("textField_lr0dvhqh"))).collect(Collectors.toList()); if (listPDT.size() == 0) { continue; } projectMembers = (Map) listPDT.get(0).get("formData"); } for (Map roleData : roleMap) { Map roleFormData = (Map) roleData.get("formData"); // 创建详情的角色名称和成员组件Map Object roleMember = projectMembers.get(roleFormData.get("textField_lr7bgi76")); String roleName = UtilMap.getString(roleFormData, "textField_lqxu439g"); if (roleMember != null && roleName != null) { // prd 提交代表标识, 用于同步项目角色 details.add(UtilMap.map("employeeField_lqxtykch, selectField_lqxu6bgf, radioField_lu8li5ie", roleMember, roleName, roleFormData.get("radioField_lu8li5ie"))); // prd 添加项目经理, 用于数据权限控制 if (AWServer.PROJECT_PM_NAME.equals(roleName)) { formData.put("employeeField_ltzn872j", roleMember); } } } formData.put("tableField_lqxtykcf", details); // 通过项目号获取项目是否已存在 List projectMaps = ydService.queryDataList_FormData(_matchFormUuid("PROJECT"), UtilMap.map("textField_lrj7vnxb", baseFormData.get("textField_le6o88w0"))); projectMaps = projectMaps.stream().filter(sub -> baseFormData.get("textField_le6o88w0").equals(sub.get("textField_lrj7vnxb"))).collect(Collectors.toList()); YDParam ydParam2 = YDParam.builder() .formUuid(_matchFormUuid("PROJECT")) .formDataJson(JSON.toJSONString(formData)) .updateFormDataJson(JSON.toJSONString(formData)) .useLatestVersion(true) .build(); if (projectMaps.size() > 0) { ydParam2.setFormInstanceId(String.valueOf(projectMaps.get(0).get("instanceId"))); ydClient.operateData(ydParam2, YDConf.FORM_OPERATION.update); // 主表为增量更新 // 保留tb项目号, 避免冲重复通过模板参加项目 [供新增用] formData.put("textField_lqxtykce", UtilMap.getString(projectMaps.get(0), "textField_lqxtykce")); formData.put("formInstanceId", projectMaps.get(0).get("instanceId")); } else { String formInstId = (String) ydClient.operateData(ydParam2, YDConf.FORM_OPERATION.create); formData.put("formInstanceId", formInstId); } // 全量兼容: tb项目成员更新 [兼容存量创建项目, 被删除后执行异常] String projectId = UtilMap.getString(formData, "textField_lqxtykce"); if (StringUtils.isNotBlank(projectId) && StringUtils.isBlank(projectCode)) { try { _syncProjectRole(formData, projectId, false); } catch (Exception e) { // 记录错误信息 e.printStackTrace(); } } log.info("同步项目主数据, code = {}, id = {}", projectCode, projectCode); } return formData; } @Autowired private TBConf tbConf; /** * 通过模板创建项目 [ppExt: 过滤宜搭项目档案\TB项目, 避免重复创建, 若判定为更新下执行项目成员更新] */ @Override @Synchronized public void createProject(String projectCode, String templateId) { log.info("通过模板创建项目, {}, {}", projectCode, templateId); // 虽然先创建TB, 可以一次性同步项目数据, 但避免执行异常, 因此成功创建TB项目再回写 Map formData = syncProject(projectCode); String projectId = UtilMap.getString(formData, "textField_lqxtykce"); log.info("项目主数据, {}, {}", projectId, formData); boolean isCreate = StringUtils.isBlank(projectId); if (isCreate) { //awDingService.saveGroup(upMap,formData); // prd 多模板适配: [templateId 为空, 触发项目类型匹配] if (StringUtils.isBlank(templateId)) { List dataList = ydService.queryDataList_FormData(_matchFormUuid("TEMPLATE"), null); Optional optional = dataList.stream().filter(item -> item.get("selectField_ltwcsr8w").equals(formData.get("textField_ltwcq7s6"))).findAny(); McException.assertAccessException(!optional.isPresent(), projectCode + ": TB项目模板未维护!"); templateId = UtilMap.getString((Map) optional.get(), "textField_ltwcybz1"); McException.assertAccessException(templateId.length() <= 1, projectCode + ": TB项目模板未匹配!"); } // 通过模板创建项目, 创建项目并更新项目TB项目ID Map result = tbClient.projectCreateWithTemplate(projectCode, templateId, tbConf.getOperatorId()); projectId = UtilMap.getString(result, "id"); ydClient.operateData(YDParam.builder() .formInstanceId(UtilMap.getString(formData, "formInstanceId")) .updateFormDataJson(JSON.toJSONString(UtilMap.map("textField_lqxtykce", projectId))) .build(), YDConf.FORM_OPERATION.update); log.info("TB项目号更新, {}, {}", projectCode, UtilMap.getString(formData, "formInstanceId"), projectId); } _syncProjectRole(formData, projectId, isCreate); } /** * 项目主数据增量更新 */ @Override public void updateProject(String projectCode) { Map formData = syncProject(projectCode); log.info("项目主数据增量更新, {}", formData); String projectId = UtilMap.getString(formData, "textField_lqxtykce"); if (StringUtils.isNotBlank(projectId)) { // 屏蔽未创建项目, 出现新增 _syncProjectRole(formData, projectId, false); } } // 同步TB项目成员/项目分组 todo 群成员 void _syncProjectRole(Map formData, String projectId, boolean isCreate) { // prd TB项目成员, 项目经理设置为管理者 List pmUserId = new ArrayList<>(); List roleIds = new ArrayList<>(); List representativeIds = new ArrayList<>(); String representative = _getProjectRoleId(projectId, "项目各代表"); String pmRoleId = _getProjectRoleId(projectId, AWServer.PROJECT_PM_ROLE); String staffRoleId = _getProjectRoleId(projectId, "项目成员"); List details = (List) formData.get("tableField_lqxtykcf"); for (Map row : details) { // 同步项目主数据, 会重新匹配项目成员, 因此无需 employeeField_xxx_id 取值 List userIds = (List) UtilMap.getList(row, "employeeField_lqxtykch"); if (userIds.isEmpty()) { continue; } String roleName = UtilMap.getString(row, "selectField_lqxu6bgf"); if (AWServer.PROJECT_PM_NAME.equals(roleName)) { pmUserId.addAll(userIds); } // prd 项目各代表, 可独立N/A任务, 添加角色控制权限 if ("是".equals(row.get("radioField_lu8li5ie"))) { representativeIds.addAll(userIds); } roleIds.addAll(userIds); } // 钉钉人员ID转TB人员ID roleIds = _convertUserId(roleIds, false); tbClient.createProjectMember(projectId, roleIds, tbConf.getOperatorId()); if (!representativeIds.isEmpty()) { tbClient.updateProjectMember(_convertUserId(representativeIds, false), Arrays.asList(staffRoleId, representative), projectId); } // prd 不做删除, 离职自动退出, 避免临时交接不可见的问题. 但需要移除项目经理权限 List roleList = tbClient.queryProjectMember(projectId, UtilMap.map("projectRoleId", pmRoleId)); for (Map role : roleList) { List tRoleIds = UtilMap.getList(role, "roleIds"); tRoleIds.remove(pmRoleId); if (tRoleIds.isEmpty()) { tRoleIds.add(staffRoleId); } tbClient.updateProjectMember(Arrays.asList(UtilMap.getString(role, "userId")), tRoleIds, projectId); } // 指定项目经理为编辑权限 if (!pmUserId.isEmpty()) { tbClient.updateProjectMember(_convertUserId(pmUserId, false), Arrays.asList(pmRoleId), projectId); } // 同步项目分组 [prd 主数据建立产品与分组对照表,绑定末级分类接口,若未匹配则不添加] String groupName = UtilMap.getString(formData, "textField_ltsdsti6"); if (StringUtils.isNotBlank(groupName)) { List tagList = tbClient.queryTagList(UtilMap.map("q", groupName)); if (tagList.size() > 0) { tbClient.updateProjectTag(projectId, Arrays.asList(UtilMap.getString(tagList.get(0), "id"), staffRoleId), tbConf.getOperatorId()); } } // prd 人员变更, 自动同步更新执行人: 仅触发存在执行人 & 未完成场景 [5.10 新增项目不执行, TB任务号宜搭回写有延迟, 避免异常] if (!isCreate) { updateProjectRole(projectId, Arrays.asList("全部", "自动更新")); } log.info("TB项目信息, {}, {}", projectId, roleIds.size()); } // fixme 提取方法, 参考 getProjectCFID 实现 private String _getProjectRoleId(String projectId, String roleName) { List roles = tbClient.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"); } /** * 分配项目角色 prd 若是一人直接指定, 多人情况下忽略 */ @Synchronized @Override public void updateProjectRole(String projectId, List trNode) { // 项目档案 [tb项目号查询, 避免模糊匹配] List pList = ydService.queryDataList_FormData(_matchFormUuid("PROJECT"), UtilMap.map("textField_lqxtykce", projectId)); McException.assertAccessException(pList.isEmpty(), "未匹配到项目主数据"); List rList = (List) pList.get(0).get("tableField_lqxtykcf"); log.info("分配项目角色 projectId = {}, 项目数量 = {}, 角色列表 = {}", projectId, pList.size(), rList); // 任务编码字段ID List customField = tbClient.queryProjectCustomField(projectId, null); // prd 非未完成任务, 不执行人员匹配更新 List workFlowStatusList = _getWorkFlowStatusList(projectId, AWServer.WORKFLOW_INITIAL); //List taskList = tbClient.queryProjectTaskList(projectId, UtilMap.map("pageSize", 10), null); tbClient.queryProjectTaskList(projectId, null, taskList -> { for (Map task : taskList) { if (!workFlowStatusList.contains(task.get("tfsId"))) { continue; } // 获取资源名称对应的项目角色 Optional optional = customField.stream().filter(item -> AWServer.TASK_ROLE.equals(item.get("name"))).findAny(); if (!optional.isPresent()) { continue; } List customfields = (List) task.get("customfields"); // prd 按照tr节点分配成员, 若是含有全部则忽略 if (!trNode.contains("全部")) { Optional optional2 = customField.stream().filter(item -> AWServer.TASK_STAGE.equals(item.get("name"))).findAny(); if (!optional2.isPresent()) { continue; } // prd 传递无TR评审节点值, 匹配空值, 作为分配条件 String trName = TBConf.getTaskFieldValue_First(customfields, UtilMap.getString((Map) optional2.get(), "id")); if (StringUtils.isBlank(trName)) { if (!trNode.contains(AWServer.TASK_STAGE_BLANK)) { continue; } } else { if (!trNode.contains(trName)) { continue; } } log.info("tr节点控制, {}, {}", trName, trNode); } // prd 人员变更, 自动同步更新执行人: 仅触发存在执行人 & 未完成场景 if (trNode.contains("自动更新")) { if (StringUtils.isBlank(UtilMap.getString(task, "executorId"))) { continue; } } String roleName = TBConf.getTaskFieldValue_First(customfields, UtilMap.getString((Map) optional.get(), "id")); // 获取角色在项目主数据对应成员 optional = rList.stream().filter(item -> roleName.equals(item.get("selectField_lqxu6bgf"))).findAny(); if (!optional.isPresent()) { continue; } log.info("分配项目角色 taskId = {}, 资源名称 = {}, 角色信息 = {}", UtilMap.getString(task, "id"), roleName, optional.get()); List roleIds = (List) UtilMap.getList((Map) optional.get(), "employeeField_lqxtykch_id"); if (roleIds.size() == 1) { String tbUserId = _convertUserId(roleIds.get(0), false); if (StringUtils.isNotBlank(tbUserId)) { tbClient.updateTaskExecutor(UtilMap.getString(task, "id"), tbConf.getOperatorId(), tbUserId, false, false); } } } return true; }); } /** * 项目迁移: 删除依赖项 */ @Synchronized @Override public void removeDependencies(String projectId, List trNode) { // 任务编码字段ID List customField = tbClient.queryProjectCustomField(projectId, null); tbClient.queryProjectTaskList(projectId, null, taskList -> { for (Map task : taskList) { Optional optional = customField.stream().filter(item -> AWServer.TASK_STAGE.equals(item.get("name"))).findAny(); if (!optional.isPresent()) { continue; } List customfields = (List) task.get("customfields"); String trName = TBConf.getTaskFieldValue_First(customfields, UtilMap.getString((Map) optional.get(), "id")); // prd 传递无TR评审节点值, 匹配空值, 作为删除条件 if (trNode.contains(trName) || (StringUtils.isBlank(trName) && trNode.contains(AWServer.TASK_STAGE_BLANK))) { String taskId = UtilMap.getString(task, "id"); List dependencies = tbClient.queryTaskDependency(taskId, null); log.info("taskID = {}, trNode, {}, 依赖数量: {}", taskId, trName, dependencies.size()); for (Map dependency : dependencies) { tbClient.removeTaskDependency(UtilMap.getString(dependency, "id"), tbConf.getOperatorId()); } } } return true; }); } // TB与宜搭userId转换 fixme 提取 tbService private String _convertUserId(String userId, boolean isTBID) { List tbMap = tbClient.idMapQuery(userId, isTBID); // 过滤未匹配人员信息 [ppExt: TB人员未匹配, 不执行修改也无报错] if (tbMap.isEmpty()) { log.warn("TB与宜搭userId转换为空, userId = {}, tbID = {}", userId, isTBID); return ""; } if (!isTBID) { return UtilMap.getString(tbMap.get(0), "tbId"); } else { Map extra = UtilMap.getMap(tbMap.get(0), "extra"); return UtilMap.getString(extra, "userId"); } } // TB与宜搭userId转换 fixme 提取 tbService private List _convertUserId(List userIds, boolean isTBID) { return userIds.stream().distinct() .map(id -> _convertUserId(id, isTBID)) .filter(id -> StringUtils.isNotBlank(id)) .collect(Collectors.toList()); } /** * 同步crm基线 */ @Override public void syncBaseLineForCRM(String projectId) { String C_TR5_03_13 = "TR5-03-13"; String C_TR6_01_11 = "TR6-01-11"; // prd 推CRM的逻辑, 完成时间晚于2024/3/29的就更新,否则不更新 Date dlDate = UtilDateTime.parseDateTime("2024-03-29 23:59:59"); // 7. 产品型号 (Name) : 以上计划时间对应的产品型号 / 取产品型号字段 List customField = tbClient.queryProjectCustomField(projectId, null); // 基线同步需求 List baseLines = tbClient.queryGanttBaselineList(projectId, null).stream() .filter(item -> UtilMap.getString(item, "title").toUpperCase().contains("PDCP")).collect(Collectors.toList()); log.info("PDCP基线, {}, {}", projectId, baseLines.size()); List baseLineTaskList = new ArrayList(); if (baseLines.size() > 0) { // prd 若存在多个同名, 取最新基线 [返回值创建时间升序] tbClient.queryGanttBaselineTask(UtilMap.getString(baseLines.get(baseLines.size() - 1), "id"), null, taskList -> { baseLineTaskList.addAll(taskList); return true; }); } log.info("基线任务, {}", baseLineTaskList.size()); // 最新同步需求 Map proData = getProjectCFID(projectId, Arrays.asList(AWServer.TASK_CODE, AWServer.TASK_PRODUCT)); String tql = "cf:" + proData.get(AWServer.TASK_CODE) + " = " + C_TR5_03_13 + " AND (cf:" + proData.get(AWServer.TASK_PRODUCT) + " != null)" + " ORDER BY startDate DESC"; List taskList = tbClient.queryProjectTaskList(projectId, UtilMap.map("q", tql), null); log.info("项目计划: {}, {}", C_TR5_03_13, taskList.size()); List dataList = new ArrayList<>(); for (Map task : taskList) { String name = _getTaskFieldMap(task, customField, AWServer.TASK_PRODUCT).get(AWServer.TASK_PRODUCT); // 多料号兼容 if (dataList.stream().filter(item -> name.equals(item.get("Name"))).findAny().isPresent()) { continue; } Map tData = UtilMap.map("Name", name); // 2. 预计α推广 (AlphaDate): 最新项目计划(非基线)里的ADCPα任务对应的计划完成时间 / TR5-03-13任务号 取最新版本 String date = UtilMap.getString(task, "dueDate"); if (UtilString.isNotBlankCompatNull(date)) { Date tDate = UtilDateTime.parse(date, UtilDateTime.DATE_MSEL_ISO); if (tDate.after(dlDate)) { tData.put("AlphaDate", UtilDateTime.formatDate(tDate)); } } // 3. α推广 (AlphaDate2): 【ADCPα】对应的实际完成时间 / TR5-03-13任务号 取最新版本 date = UtilMap.getString(task, "accomplishTime"); if (UtilString.isNotBlankCompatNull(date)) { Date tDate = UtilDateTime.parse(date, UtilDateTime.DATE_MSEL_ISO); if (tDate.after(dlDate)) { tData.put("AlphaDate2", UtilDateTime.formatDate(tDate)); } } // 1. α推广基线 (AlphaBaseline): PDCP basseline 基线下的ADCPα任务的计划完成时间 / PDCP basseline 基线 TR5-03-13任务号 Optional optional = baseLineTaskList.stream().filter(item -> task.get("id").equals(item.get("id"))).findAny(); if (optional.isPresent()) { date = UtilMap.getString((Map) optional.get(), "planDueDate"); if (StringUtils.isNotBlank(date)) { Date tDate = UtilDateTime.parse(date, UtilDateTime.DATE_MSEL_ISO); if (tDate.after(dlDate)) { tData.put("AlphaBaseline", UtilDateTime.formatDate(tDate)); } } } if (tData.keySet().size() >= 2) { dataList.add(tData); _pushCRM(projectId, tData); } } tql = "cf:" + proData.get(AWServer.TASK_CODE) + " = " + C_TR6_01_11 + " AND (cf:" + proData.get(AWServer.TASK_PRODUCT) + " != null)" + " ORDER BY startDate ASC"; taskList = tbClient.queryProjectTaskList(projectId, UtilMap.map("q", tql), null); log.info("项目计划: {}, {}", C_TR6_01_11, taskList.size()); dataList = new ArrayList<>(); for (Map task : taskList) { String name = _getTaskFieldMap(task, customField, AWServer.TASK_PRODUCT).get(AWServer.TASK_PRODUCT); // 多料号兼容 if (dataList.stream().filter(item -> name.equals(item.get("Name"))).findAny().isPresent()) { continue; } Map tData = UtilMap.map("Name", name); // 5. 预计正式发布 (AgentSampleDate): 最新项目计划(非基线),取最早那个产品版本的计划完成时间 / TR6-01-11任务号 最早版本 String date = UtilMap.getString(task, "dueDate"); if (UtilString.isNotBlankCompatNull(date)) { Date tDate = UtilDateTime.parse(date, UtilDateTime.DATE_MSEL_ISO); if (tDate.after(dlDate)) { tData.put("AgentSampleDate", UtilDateTime.formatDate(tDate)); } } // 6. 正式发布 (ProductSendDate): 【ADCP】对应的取最早那个产品版本的实际完成时间 / TR6-01-11任务号 最早版本 date = UtilMap.getString(task, "accomplishTime"); if (UtilString.isNotBlankCompatNull(date)) { Date tDate = UtilDateTime.parse(date, UtilDateTime.DATE_MSEL_ISO); if (tDate.after(dlDate)) { tData.put("ProductSendDate", UtilDateTime.formatDate(tDate)); } } // 4. 正式发布基线 (ReleaseBaseline): 取PDCPbasseline基线里的ADCP的计划完成时间,取最早那个产品版本的计划完成时间 / PDCP basseline 基线 TR6-01-11任务号 Optional optional = baseLineTaskList.stream().filter(item -> task.get("id").equals(item.get("id"))).findAny(); if (optional.isPresent()) { date = UtilMap.getString((Map) optional.get(), "planDueDate"); if (StringUtils.isNotBlank(date)) { Date tDate = UtilDateTime.parse(date, UtilDateTime.DATE_MSEL_ISO); if (tDate.after(dlDate)) { tData.put("ReleaseBaseline", UtilDateTime.formatDate(tDate)); } } } if (tData.keySet().size() >= 2) { dataList.add(tData); _pushCRM(projectId, tData); } } } // 推送crm: prd 单次推送必须为相同料号 void _pushCRM(String projectId, Map record) { log.info("推送crm, {}", record); //Map param = UtilMap.map("username, password, client_id, client_secret, grant_type", "interface@awinic.com.cn.uat", "welcome12", "3MVG959Nd8JMmavT2IGqAtf_hIbxepsElGbOpno6AO8KdQJSpSNqY9bnLRU2exuAEh3qIXb1oTn98S9h0WWZk", "3C9FC7427866D69586964F65A16D288EBBB1544335DD9FF3A03DE21DF14A7C6A", "password"); Map param = UtilMap.map("username, password, client_id, client_secret, grant_type", "interface@awinic.com.cn", "welcome12", "3MVG9d8..z.hDcPKSaWop76C8GRQarYhn0LpBnP_U2S3VJaT8a6l05e2pDkdk5oE4MInQYwyLMpqWM7bLDzqm", "26A90098BDBE8C356817938986472730BAE5D9536DA9096AC7C45A4973867100", "password"); //String rsp = UtilHttp.doPost("https://test.salesforce.com/services/oauth2/token", null, param, UtilMap.empty()); String rsp = UtilHttp.doPost("https://login.salesforce.com/services/oauth2/token", null, param, UtilMap.empty()); Map result = (Map) JSON.parse(rsp); Map header = UtilMap.map("Authorization", "OAuth " + result.get("access_token")); rsp = UtilHttp.doPost(UtilMap.getString(result, "instance_url") + "/services/apexrest/TBProductStageTimeRest", header, null, Arrays.asList(record), null); ydClient.operateData(YDParam.builder() .formUuid(_matchFormUuid("CRM_LOG")) .formDataJson(JSON.toJSONString(UtilMap.map("textareaField_lu8kinep, textareaField_lu8kineu, textField_lu8kinew", Arrays.asList(record), rsp, projectId))) .build(), YDConf.FORM_OPERATION.create); } /** * 全量同步crm基线 */ @Override public void syncBaseLineForCRM() { // prd 同步CRM: 项目状态为执行 & TB项目号不为空 YDParam ydParam = YDParam.builder() .formUuid(_matchFormUuid("PROJECT")) .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llouhiyf", "执行"))) .build(); List proList = ydService.queryFormData_all(ydParam); for (Map pro : proList) { String projectId = UtilMap.getString(pro, "textField_lqxtykce"); if (StringUtils.isBlank(projectId)) { continue; } syncBaseLineForCRM(projectId); } } // 获取项目自定义字段ID, 格式 { 名称: id } fixme 提取 Map getProjectCFID(String projectId, List names) { List customField = tbClient.queryProjectCustomField(projectId, null); List tList = customField.stream().filter(item -> names.contains(item.get("name"))).collect(Collectors.toList()); return (Map) tList.stream().reduce(UtilMap.empty(), (acc, cur) -> { ((Map) acc).put(((Map) cur).get("name"), ((Map) cur).get("id")); return acc; }); } /** * 修改任务自定义字段内容 * * @param projectId 1. 若为空, 触发全量修改; 2. 仅修改非未完成任务 */ @Override public void batchUpdate(String fieldName, String preName, String modifyName, String projectId) { if (StringUtils.isBlank(projectId)) { // prd 同步修改: 项目状态为执行 & TB项目号不为空 YDParam ydParam = YDParam.builder() .formUuid(_matchFormUuid("PROJECT")) .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llouhiyf", "执行"))) .build(); List proList = ydService.queryFormData_all(ydParam); for (Map pro : proList) { String _projectId = UtilMap.getString(pro, "textField_lqxtykce"); if (StringUtils.isBlank(_projectId)) { continue; } _batchUpdate(fieldName, preName, modifyName, _projectId); } } else { _batchUpdate(fieldName, preName, modifyName, projectId); } } /// 修改任务自定义字段 void _batchUpdate(String fieldName, String preName, String modifyName, String projectId) { // prd 非未完成任务字段ID List workFlowStatusList = _getWorkFlowStatusList(projectId, AWServer.WORKFLOW_INITIAL); Map proData = getProjectCFID(projectId, Arrays.asList(fieldName)); String tql = "cf:" + proData.get(fieldName) + " = " + preName + " AND tfsId IN (" + String.join(", ", workFlowStatusList) + ")"; List taskList = tbClient.queryProjectTaskList(projectId, UtilMap.put(UtilMap.empty(), "q", tql), null); for (Map task : taskList) { Map body = TBConf.assembleCustomFieldName(fieldName, modifyName); tbClient.updateTaskCustomField(UtilMap.getString(task, "id"), tbConf.getOperatorId(), body); } } /** * 同步预检项 [全量同步, 忽略任务号为空记录] */ @Synchronized @Override public void syncCheckList(YDParam srcParam, Map compIds, String taskCompId, String codeCompId, String checkType, String associationCompId) { String curFormUuid = _matchFormUuid("CHECK"); // 数据来源表 List srcList = ydService.queryFormData_all(srcParam); // 当前记录表 List curList = ydService.queryFormData_all(YDParam.builder() .formUuid(curFormUuid) .searchFieldJson(JSON.toJSONString(UtilMap.map("selectField_lrnd3h0s", checkType))) .build()); log.info("全量同步 ##, srcList = {}, curList = {}", srcList.size(), curList.size()); for (Map item : srcList) { if (StringUtils.isBlank(UtilMap.getString(item, taskCompId))) { continue; } Map formData = UtilMap.map(associationCompId, YDConf.associationForm(srcParam.getAppType(), srcParam.getFormUuid(), UtilMap.getString(item, "formInstanceId"), UtilMap.getString(item, codeCompId), "", false)); formData.put("radioField_lrnddfq6", "启用"); formData.put("selectField_lrnd3h0s", checkType); for (String compId : compIds.keySet()) { formData.put(compId, item.get(compIds.get(compId))); } YDConf.FORM_OPERATION operate = YDConf.FORM_OPERATION.create; YDParam ydParam = YDParam.builder() .formUuid(curFormUuid) .formDataJson(JSON.toJSONString(formData)) .updateFormDataJson(JSON.toJSONString(formData)) .useLatestVersion(true) .build(); // 避免循坏内查询, 也避免了模糊匹配 Optional optional = curList.stream().filter(cur -> cur.get("textField_lrnd3h0r").equals(item.get(codeCompId))).findAny(); if (optional.isPresent()) { ydParam.setFormInstanceId(UtilMap.getString((Map) optional.get(), "formInstanceId")); operate = YDConf.FORM_OPERATION.update; // prd 0402 兼容删除场景, 标记状态为停用, 不做实际删除 ((Map) optional.get()).put("status", true); } ydClient.operateData(ydParam, operate); } List dataList = curList.stream().filter(item -> "启用".equals(item.get("radioField_lrnddfq6")) && !item.containsKey("status")).collect(Collectors.toList()); log.info(" 兼容删除场景, 标记状态为停用, {}", dataList.size()); dataList.forEach(item -> { ydClient.operateData(YDParam.builder() .formInstanceId(UtilMap.getString(item, "formInstanceId")) .updateFormDataJson(JSON.toJSONString(UtilMap.map("radioField_lrnddfq6", "停用"))) .build(), YDConf.FORM_OPERATION.update); }); } /** * 同步预检项 [通用] */ @Synchronized @Override public void syncCheckList(int type) { log.info("## 同步预检项, {}", type); switch (type) { case 0: // 经验库 YDParam ydParam1 = YDParam.builder() .appType("APP_D4NPOH9J3KCG5VE1RVN6") .systemToken("6J8668A1B59FA7SAFTAF89PTKKGP2HY3FP3OLV1") .formUuid("FORM-D47CCA076DA54F969DF7442D81E4B5A8PC6Q") .build(); // 任务号, 描述, ID(标题), 任务名称, 适用项目类型 Map compIds1 = UtilMap.map("selectField_lrncf4hk, textField_lrrnqz7w, textField_lrnd3h0r, textField_ltzl9mpc, multiSelectField_ltwjre9s", "selectField_ls9yctsd, textareaField_lo5eakcv, serialNumberField_lo5dmyfb, textField_ls9xvxvk, multiSelectField_ltwjre9s"); syncCheckList(ydParam1, compIds1, "selectField_ls9yctsd", "serialNumberField_lo5dmyfb", "经验库", "associationFormField_lrrn5csf"); break; case 1: // IC技术检查表 YDParam ydParam2 = YDParam.builder() .appType("APP_NOSSCZQ8FFZKHDQOIIDA") .systemToken("UM6660D1BFTFLFAP7NPJDBJEEAB737FAR1SOLD4") .formUuid("FORM-B40420AFCDB84AD69FE78D82D6D5CFD2C2D2") .build(); // 任务号, 描述, ID(标题), 任务名称, 适用项目类型 Map compIds2 = UtilMap.map("selectField_lrncf4hk, textField_lrrnqz7w, textField_lrnd3h0r, textField_ltzl9mpc, multiSelectField_ltwjre9s", "selectField_bclg9y5, textField_k1e08ji, textField_96ikaoh, textField_lsa0d856, multiSelectField_ltwjre9s"); syncCheckList(ydParam2, compIds2, "selectField_bclg9y5", "textField_96ikaoh", "IC技术检查表", "associationFormField_lrrn5csg"); break; case 2: // TR评审要素表 YDParam ydParam3 = YDParam.builder() .formUuid("FORM-5436DC75BC8347D498DFF2617925BA70O066") .build(); // 任务号, 描述, ID(标题), 验收标准, 等级, 任务名称, 适用项目类型 Map compIds3 = UtilMap.map("selectField_lrncf4hk, textField_lrrnqz7w, textField_lrnd3h0r, textField_cd4f65l, textField_267kho2, textField_ltzl9mpc, multiSelectField_ltwjre9s", "selectField_4gwjfa5, textField_lryetn3g, textField_9x1yps6, textField_cd4f65l, textField_267kho2, textField_ls9xvxvk, multiSelectField_ltwjre9s"); syncCheckList(ydParam3, compIds3, "selectField_4gwjfa5", "textField_9x1yps6", "TR评审要素表", "associationFormField_lrrn5csa"); break; } log.info("同步预检项 ##, {}", type); } /** * 提供verifier数据读取服务 */ @Override public List syncVerifier(String projectCode) { List dataList = ydService.queryFormData_all(YDParam.builder() .formUuid("FORM-23B67983E91C4ED3B063F9B629D6E964SGHH") .searchCondition(JSON.toJSONString(UtilMap.map("textField_lt6xd8lm", projectCode))) .build()); return dataList.stream().map(item -> { return item; }).collect(Collectors.toList()); } @Override public void test() { } /// tmp: 5.22 处理检查项重复数据 private void _test() { List dataList = ydService.queryFormData_all(YDParam.builder() .formUuid("FORM-6E2C0D1197264B8AA23EB3FECAE7344B00BN") .searchFieldJson(JSON.toJSONString(UtilMap.map("selectField_lqxuswze", "A2328"))) .build()); dataList.forEach(item -> { List details = (List) item.get("tableField_lqxxgj4s"); String formInstanceId = String.valueOf(item.get("formInstanceId")); if (details.size() == 50) { YDParam ydParam = YDParam.builder().formUuid("FORM-6E2C0D1197264B8AA23EB3FECAE7344B00BN").formInstanceId(formInstanceId).tableFieldId("tableField_lqxxgj4s").build(); details = ydService.queryDetails(ydParam); } if (!details.stream().filter(row -> "技术评审要素表".equals(row.get("selectField_lrnd3h0s"))).findAny().isPresent()) { return; } details = details.stream().filter(row -> !"IC技术检查表".equals(row.get("selectField_lrnd3h0s"))).collect(Collectors.toList()); details.forEach(record -> { // String tmp = ((List>) JSON.parse(String.valueOf(JSON.parse(String.valueOf(record.get("associationFormField_lrrnem5r_id")))))).get(0).get("title"); // if (tmp.startsWith("TR")) { // record.put("selectField_lrnd3h0s", "TR评审要素表"); // } else if (tmp.contains("-")) { // record.put("selectField_lrnd3h0s", "IC技术检查表"); // } else { // record.put("selectField_lrnd3h0s", "经验库"); // } if ("技术评审要素表".equals(record.get("selectField_lrnd3h0s"))) { record.put("selectField_lrnd3h0s", "IC技术检查表"); } record.put("associationFormField_lrrnem5r", JSON.parse(String.valueOf(record.get("associationFormField_lrrnem5r_id")))); }); log.info("------, {}, {}, {}", details.size(), formInstanceId, details); ydClient.operateData(YDParam.builder() .formInstanceId(String.valueOf(item.get("formInstanceId"))) .updateFormDataJson(JSON.toJSONString(UtilMap.map("tableField_lqxxgj4s", details))) .build(), YDConf.FORM_OPERATION.update); }); } }