package com.malk.huagao.controller; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.malk.huagao.service.IKdYdCustomerService; import com.malk.huagao.service.IKdYdZpService; import com.malk.huagao.service.YdHuaGaoService; 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.common.McR; import com.malk.server.dingtalk.DDConf; import com.malk.server.dingtalk.DDR_New; import com.malk.service.aliwork.YDClient; import com.malk.service.aliwork.YDService; import com.malk.service.dingtalk.DDClient; import com.malk.service.dingtalk.DDClient_Contacts; import com.malk.service.dingtalk.DDClient_Extension; import com.malk.service.dingtalk.DDClient_Workflow; import com.malk.utils.UtilHttp; import com.malk.utils.UtilMap; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.MDC; 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.stereotype.Controller; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; import java.time.ZoneId; import java.util.*; import java.util.stream.Collectors; /** *

* 前端控制器 *

* * @author LQY * @since 2025-10-09 */ @RestController @Slf4j @RequestMapping("/hg") public class KdYdCustomerController { @Autowired private IKdYdCustomerService kdYdCustomerService; @Autowired private YdHuaGaoService ydHuaGaoService; @Autowired private IKdYdZpService kdYdZpService; @Autowired private DDClient_Contacts ddClient_contacts; @Autowired private DDClient ddClient; @Autowired private DDClient_Extension ddClientExtension; @Autowired private YDClient ydClient; @Autowired private DDConf ddConf; @Autowired private YDService ydService; @PostMapping("/test") public McR sendGroupMsg(@RequestBody JSONObject param) { log.info("推送消息:{}", param); McException.assertParamException_Null(param, "msgParam", "msgKey", "openConversationId", "robotCode", "coolAppCode"); Map map = ddClientExtension.sendGroupMessages(ddClient.getAccessToken(), param.getJSONObject("msgParam"), param.getString("msgKey"), param.getString("openConversationId") , param.getString("robotCode"), param.getString("coolAppCode")); return McR.success(map); } @PostMapping("/test33") public McR test18(@RequestBody Map data) { MDC.put("MDC_KEY_PID", "1003"); String formUuid = "FORM-F79B680547674A6BBD11C0D511E3C14B28FY"; long now = System.currentTimeMillis(); long dayMillis = 24L * 60 * 60 * 1000; ZoneId zoneId = ZoneId.of("Asia/Shanghai"); long startTime = LocalDate.now(zoneId).atStartOfDay(zoneId).toInstant().toEpochMilli(); long endTime = LocalDate.now(zoneId).plusDays(15).atStartOfDay(zoneId).toInstant().toEpochMilli() - 1; List list = null; // 查询重试(您已有的逻辑保留) for (int attempt = 1; attempt <= 3; attempt++) { try { list = ydService.queryFormData_all( YDParam.builder() .formUuid(formUuid) .searchFieldJson(JSONObject.toJSONString(Arrays.asList( new YDSearch("dateField_mjm9k35l", Arrays.asList(startTime, endTime), "DateField", YDSearch.Type.DATE_FIELD, YDSearch.Operator.BETWEEN), // // 如果需要过滤 textField_mjm9k35n = "666",保留;否则删除 // new YDSearch("textField_mjm9k35n", "666", // "TextField", YDSearch.Type.TEXT_FIELD, YDSearch.Operator.EQ), new YDSearch("radioField_mru0o7u6", "是", "RadioField", YDSearch.Type.RADIO_FIELD, YDSearch.Operator.EQ) ))) .build() ); break; } catch (Exception e) { log.warn("查询宜搭数据第 {} 次失败:{}", attempt, e.getMessage(), e); if (attempt == 3) return McR.errorParam("查询宜搭数据失败:" + e.getMessage()); try { Thread.sleep(2000L); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); return McR.errorParam("查询被中断"); } } } if (list == null || list.isEmpty()) { log.info("没有找到需要处理的单据"); return McR.success("无待处理数据"); } String accessToken; try { accessToken = ddClient.getAccessToken(); } catch (Exception e) { log.warn("获取钉钉 accessToken 失败:{}", e.getMessage(), e); return McR.errorParam("获取钉钉 accessToken 失败:" + e.getMessage()); } Number agentId = ddConf.getAgentId(); List releaseIds = new ArrayList<>(); log.info("共查询到 {} 条待处理单据", list.size()); for (Map item : list) { long releaseTime = UtilMap.getLong(item, "dateField_mjm9k35l"); if (releaseTime <= 0) { log.warn("释放日期为空,跳过:{}", item); continue; } Object idObj = item.get("textField_ms2nby3g"); if (idObj == null) idObj = item.get("formInstId"); String formInstanceId = idObj == null ? null : String.valueOf(idObj); if (StringUtils.isBlank(formInstanceId) || "null".equals(formInstanceId)) { log.warn("formInstanceId 为空,跳过:{}", item); continue; } // 到期释放 if (releaseTime <= now) { releaseIds.add(formInstanceId); continue; } // 提取申请人 String sqr = null; Object sqrObj = item.get("employeeField_mjm9k35m_id"); if (sqrObj instanceof List) { List sqrList = (List) sqrObj; if (!sqrList.isEmpty()) sqr = String.valueOf(sqrList.get(0)); } else if (sqrObj != null) { String sqrText = String.valueOf(sqrObj); try { JSONArray sqrArray = JSON.parseArray(sqrText); if (sqrArray != null && !sqrArray.isEmpty()) sqr = sqrArray.getString(0); } catch (Exception e) { sqr = sqrText; } } if (StringUtils.isBlank(sqr) || "null".equals(sqr)) { log.warn("申请人为空,跳过提醒:{}", formInstanceId); continue; } String type = String.valueOf(item.get("selectField_l3nrjuq0")); String khmc = String.valueOf(item.get("textField_mjm9k35o")); long days = (releaseTime - now + dayMillis - 1) / dayMillis; String msg = null; if ("未成交".equals(type)) { msg = khmc + " 客户近三个月内未成交,还剩 " + days + " 天即将释放到公海"; } else if ("半年金额不足".equals(type)) { msg = khmc + " 客户近半年内成交未达到7.5w,还剩 " + days + " 天即将释放到公海"; } else if ("一年金额不足".equals(type)) { msg = khmc + " 客户近一年内成交未达到15w,还剩 " + days + " 天即将释放到公海"; } if (msg != null) { try { sendDdMsg(accessToken, agentId, sqr, msg); } catch (Exception e) { log.warn("发送钉钉提醒失败,formInstanceId={},原因:{}", formInstanceId, e.getMessage()); } } } // ========== 批量释放(微调:增加批次间隔) ========== int totalSuccess = 0; if (!releaseIds.isEmpty()) { Map formData = new HashMap<>(); formData.put("employeeField_lqanqe6n", Arrays.asList()); formData.put("employeeField_lqanqe6o", Arrays.asList()); formData.put("selectField_megi74y7", "公司分配"); formData.put("employeeField_megi74yl", Arrays.asList()); int batchSize = 50; int maxRetry = 5; // 如果3次不够,改成10或20 int totalBatch = (releaseIds.size() + batchSize - 1) / batchSize; for (int i = 0; i < releaseIds.size(); i += batchSize) { int end = Math.min(i + batchSize, releaseIds.size()); List batch = releaseIds.subList(i, end); int batchNo = (i / batchSize) + 1; for (int attempt = 1; attempt <= maxRetry; attempt++) { try { ydClient.operateData( YDParam.builder() .formUuid("FORM-68154CC0A7054BF0B1C933752CD3881FB0SR") .formInstanceIdList(batch) .useLatestVersion(true) .updateFormDataJson(JSON.toJSONString(formData)) .build(), YDConf.FORM_OPERATION.multi_update ); totalSuccess += batch.size(); log.info("释放批次 {}/{} 成功,数量 {}", batchNo, totalBatch, batch.size()); break; } catch (Exception e) { log.warn("释放批次 {}/{} 第 {} 次失败:{}", batchNo, totalBatch, attempt, e.getMessage(), e); if (attempt < maxRetry) { try { Thread.sleep(2000L); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); return McR.errorParam("批量释放被中断"); } } else { log.error("释放批次 {}/{} 最终失败", batchNo, totalBatch); } } } // ========== 新增:批次间隔1秒 ========== if (i + batchSize < releaseIds.size()) { try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } log.info("处理完成,查询 {} 条,到期释放 {} 条", list.size(), totalSuccess); return McR.success("处理完成,查询 " + list.size() + " 条,到期释放 " + totalSuccess + " 条"); } @PostMapping("/test32") McR test13(@RequestBody Map data) { MDC.put("MDC_KEY_PID", "1003"); //当前时间戳 long endTime = System.currentTimeMillis(); long ndTime = endTime + 365L * 24 * 60 * 60 * 1000; long lcTime = endTime + 90L * 24 * 60 * 60 * 1000; // long startTime = endTime - 14L * 24 * 60 * 60 * 1000; List list = ydService.queryFormData_all( YDParam.builder() .formUuid("FORM-F79B680547674A6BBD11C0D511E3C14B28FY") .searchFieldJson(JSONObject.toJSONString(Arrays.asList( new YDSearch( "dateField_mjz31qkm", endTime, "DateField", YDSearch.Type.DATE_FIELD, YDSearch.Operator.LE ) // new YDSearch( // "radioField_mru0o7u6", // "是", // "RadioField", // YDSearch.Type.RADIO_FIELD, // YDSearch.Operator.EQ // ) ))) .build() ); log.info("查询结果:{}", list); List allIds = list.stream() .map(item -> String.valueOf(item.get("formInstanceId"))) .filter(StringUtils::isNotBlank) .collect(Collectors.toList()); Map upData = new HashMap<>(); upData.put("dateField_mjm9k35j", endTime); upData.put("dateField_mjqkkcsg", endTime); upData.put("numberField_mjm9k35k", 0); upData.put("selectField_l3nrjuq0", "未成交"); upData.put("dateField_mjz31qkm", ndTime); upData.put("dateField_mjm9k35l", lcTime); int batchSize = 50; int totalSuccess = 0; for (int i = 0; i < allIds.size(); i += batchSize) { int end = Math.min(i + batchSize, allIds.size()); List batch = allIds.subList(i, end); for (int attempt = 1; attempt <= 30; attempt++) { try { ydClient.operateData(YDParam.builder() .formInstanceIdList(batch) .formUuid("FORM-F79B680547674A6BBD11C0D511E3C14B28FY") .useLatestVersion(true) .updateFormDataJson(JSON.toJSONString(upData)) .build(), YDConf.FORM_OPERATION.multi_update); totalSuccess += batch.size(); log.info("批次 {}/{} 成功", (i / batchSize) + 1, (allIds.size() + batchSize - 1) / batchSize); break; } catch (Exception e) { log.warn("批次 {}/{} 第 {} 次失败", (i / batchSize) + 1, attempt, e.getMessage()); if (attempt < 2000) { try { Thread.sleep(2000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } } } } return McR.success("处理完成,成功 " + totalSuccess + "/" + allIds.size() + " 条"); } @PostMapping("/test31") public McR test15(@RequestBody Map data) { MDC.put("MDC_KEY_PID", "1003"); List list = ydService.queryFormData_all(YDParam.builder() .formUuid("FORM-68154CC0A7054BF0B1C933752CD3881FB0SR").build()); if (list == null || list.isEmpty()) { return McR.success("无待处理数据"); } List allIds = list.stream() .map(item -> String.valueOf(item.get("formInstanceId"))) .filter(StringUtils::isNotBlank) .collect(Collectors.toList()); Map formData = new HashMap<>(); formData.put("radioField_mru0o7u6", "是"); int batchSize = 50; int totalSuccess = 0; for (int i = 0; i < allIds.size(); i += batchSize) { int end = Math.min(i + batchSize, allIds.size()); List batch = allIds.subList(i, end); for (int attempt = 1; attempt <= 50; attempt++) { try { ydClient.operateData(YDParam.builder() .formInstanceIdList(batch) .formUuid("FORM-68154CC0A7054BF0B1C933752CD3881FB0SR") .useLatestVersion(true) .updateFormDataJson(JSON.toJSONString(formData)) .build(), YDConf.FORM_OPERATION.multi_update); totalSuccess += batch.size(); log.info("批次 {}/{} 成功", (i / batchSize) + 1, (allIds.size() + batchSize - 1) / batchSize); break; } catch (Exception e) { log.warn("批次 {}/{} 第 {} 次失败", (i / batchSize) + 1, attempt, e.getMessage()); if (attempt < 2000) { try { Thread.sleep(2000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } } } } return McR.success("处理完成,成功 " + totalSuccess + "/" + allIds.size() + " 条"); } @PostMapping("/test30") McR test16(@RequestBody Map data) { MDC.put("MDC_KEY_PID", "1003"); //当前时间戳 long endTime = System.currentTimeMillis(); long startTime = endTime - 14L * 24 * 60 * 60 * 1000; // List list = ydService.queryFormData_all( // YDParam.builder() // .formUuid("FORM-F79B680547674A6BBD11C0D511E3C14B28FY") // .searchFieldJson(JSONObject.toJSONString(Arrays.asList( // new YDSearch( // "dateField_mjz31qkm", // endTime, // "DateField", // YDSearch.Type.DATE_FIELD, // YDSearch.Operator.GE // ), // new YDSearch( // "radioField_mru0o7u6", // "是", // "RadioField", // YDSearch.Type.RADIO_FIELD, // YDSearch.Operator.EQ // ) // ))) // .build() // ); List list = ydService.queryFormData_all( YDParam.builder() .formUuid("FORM-F79B680547674A6BBD11C0D511E3C14B28FY") .searchFieldJson(JSONObject.toJSONString(Arrays.asList( // new YDSearch( // "dateField_mjm9k35l", // Arrays.asList(startTime, endTime), // "DateField", // YDSearch.Type.DATE_FIELD, // YDSearch.Operator.BETWEEN // ), new YDSearch( "textField_ms2nby3g", "666", "TextField", YDSearch.Type.TEXT_FIELD, YDSearch.Operator.EQ ), new YDSearch( "radioField_mru0o7u6", "是", "RadioField", YDSearch.Type.RADIO_FIELD, YDSearch.Operator.EQ ) ))) .build() ); if (list == null || list.isEmpty()) { log.info("没有找到需要处理的单据"); return McR.success("无待处理数据"); } log.info("共查询到 {} 条待处理单据", list.size()); for (Map item : list) { // String glbdjson = String.valueOf(item.get("associationFormField_me2kiw8j_id")); String sqr = String.valueOf(item.get("employeeField_mjm9k35m_id")); String sqrid = sqr.substring(2, sqr.length() - 2); String formInstanceId = String.valueOf(item.get("textField_ms2nby3g")); String sfghcdate = String.valueOf(UtilMap.getLong(item, "dateField_mjm9k35l")); long days = DateUtil.between(new Date(), DateUtil.parse(sfghcdate), DateUnit.DAY); String type = String.valueOf(item.get("selectField_l3nrjuq0")); if ("未成交".equals(type)) { sendDdMsg(ddClient.getAccessToken(), ddConf.getAgentId(), sqrid, "客户近三个月内未成交,还剩 " + days + " 天即将释放到公海"); } else if ("半年金额不足".equals(type)) { sendDdMsg(ddClient.getAccessToken(), ddConf.getAgentId(), sqrid, "客户近半年内成交未达到7.5w,还剩 " + days + " 天即将释放到公海"); } else if ("一年金额不足".equals(type)) { sendDdMsg(ddClient.getAccessToken(), ddConf.getAgentId(), sqrid, "客户近一年内成交未达到15w,还剩 " + days + " 天即将释放到公海"); } if (days <= 0){ Map formData = new HashMap<>(); formData.put("employeeField_lqanqe6n", Arrays.asList()); formData.put("employeeField_lqanqe6o", Arrays.asList()); formData.put("selectField_megi74y7", "公司分配"); formData.put("employeeField_megi74yl", Arrays.asList()); ydClient.operateData(YDParam.builder() .formInstId("9f9b8d6e-9d88-4233-81a6-34bd559376b3") // .useLatestVersion(true) .updateFormDataJson(JSON.toJSONString(formData)) .build(), YDConf.FORM_OPERATION.update); // } } // String zssj = String.valueOf(item.get("employeeField_mmsna3tm_id")); //// String zt = String.valueOf(item.get("selectField_mewmhnwj")); //// String fhtzd = String.valueOf(item.get("serialNumberField_mheazm7w")); // // // 解析关联字段 JSON // List sealjsonlist = parseJsonList(glbdjson); // HashMap updateMap = new HashMap<>(); // for (Object obj : item.entrySet()) { // Map.Entry formEntry = (Map.Entry) obj; // String key = formEntry.getKey(); // Object value = formEntry.getValue(); // // // 跳过需要特殊处理的主表关联字段 // if (key.equals("associationFormField_me2kiw8j_id") || // key.equals("employeeField_mdya1lol_id") || // key.equals("employeeField_mmsna3tn_id") || // key.equals("employeeField_mmsna3tm_id")) { // continue; // } // // // 复制其他字段 // updateMap.put(key, value); // } // // // 2. 添加需要特殊处理的主表字段 // updateMap.put("associationFormField_me2kiw8j", sealjsonlist); // updateMap.put("employeeField_mdya1lol", sqr); // updateMap.put("employeeField_mmsna3tn", xszg); // updateMap.put("employeeField_mmsna3tm", zssj); // // 3. 添加处理后的子表数据 // String sqrid = sqr.substring(2, sqr.length() - 2); // String xszgid = xszg.substring(2, xszg.length() - 2); // String finalId = (sqrid == null || sqrid.trim().isEmpty()) ? xszgid : sqrid; // ydClient.operateData( // YDParam.builder() // .formUuid("FORM-54F26858BF574AF0838AEF4086C35FD5VDXJ") // .processCode("TPROC--1VF66Z61YYX6RD04NCTOPAF5EFMD2DKJV8UQM2") // .formDataJson(JSON.toJSONString(updateMap)) // .userId(finalId) // .build(), // YDConf.FORM_OPERATION.start // ); // Map formData = new HashMap<>(); // formData.put("radioField_mru0o7u6", "是"); // ydClient.operateData(YDParam.builder() // .formInstId(formInstanceId) // .useLatestVersion(true) // .updateFormDataJson(JSON.toJSONString(formData)) // .build(), YDConf.FORM_OPERATION.update); // } // } // System.out.println("list=="+list); // for (Map item : list) { // String formInstanceId = String.valueOf(item.get("formInstanceId")); // Map formData =new HashMap<>(); // formData.put("textField_mfxbtce5", "无"); // formData.put("dateField_ml4ikfa1", "4073040000000"); // ydClient.operateData(YDParam.builder() // .formInstId(formInstanceId) // .updateFormDataJson(JSON.toJSONString(formData)) // .build(), YDConf.FORM_OPERATION.update); // } // Map userInfoByMobile1 = ddClient_contacts.getUserInfoById(ddClient.getAccessToken(), "yzsyzid2"); // if (userInfoByMobile1 != null && userInfoByMobile1.containsKey("mobile")) { // mobile = String.valueOf(userInfoByMobile1.get("mobile")); // } // String ins = String.valueOf(data.get("formInstId")); // // // DDR_New ddrNew = ydClient.queryData(YDParam.builder() // .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90") // .build(), YDConf.FORM_QUERY.retrieve_search_form_id); // // System.out.println(ddrNew.getTotalCount()); // // ydClient.operateData(YDParam.builder() // .formUuid("FORM-E64114E9F2C9426E91F92886EDFFA2C08Q90") // .asynchronousExecution(true) // .formInstanceIdList((List) ddrNew.getData()) // .build(), YDConf.FORM_OPERATION.delete_batch); // DDR_New ddrNew = ydClient.queryData(YDParam.builder() // .formInstId("FINST-DZ966471VB228QLYJ6WXG6I7YGV631VYLW0KMBQE") // .build(), YDConf.FORM_QUERY.retrieve_id); //// //// if (ddrNew == null || ddrNew.getFormData() == null) { //// throw new RuntimeException("未找到订单信息"); //// } //// // Map formData1 = ddrNew.getFormData(); // System.out.println("======"+formData1); // String ddje = UtilMap.getString(formData1, "numberField_mjm9k35k"); // String dddate = UtilMap.getString(formData1, "dateField_mjm9k35j"); // // System.out.println(dddate); // System.out.println(ddje); // ydClient.operateData(YDParam.builder() // .formInstanceId(ins) // .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("numberField_mhirg0kz","156")))//xz04 //// .updateFormDataJson(JSONObject.toJSONString(UtilMap.map(employ,id)))//xz04 // .useLatestVersion(true) // .build(), YDConf.FORM_OPERATION.update); // ydHuaGaoService.synckdYdMaterial(); // ydHuaGaoService.synckdYdPayment(); // ydHuaGaoService.synckdYdTRANSFER(); // ydHuaGaoService.syncKdYdReceivable(); // kdYdZpService.insertkdYdZp(data); // ydHuaGaoService.synckdYdOutbound(); } return McR.success(); } public void sendDdMsg(String access_token, Number agent_id, String userid_list, String content) { if (Objects.nonNull(userid_list)) { Map param2 = new HashMap(); param2.put("access_token", access_token); Map body3 = new HashMap(); body3.put("agent_id", agent_id); body3.put("userid_list", userid_list); Map msg = new HashMap(); msg.put("msgtype", "text"); //获取当前时间 精确到秒 String time = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"); msg.put("text", UtilMap.map("content, aa", content, "")); body3.put("msg", msg); UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2", null, param2, body3); } } public void searchDdMsg(String access_token, Number agent_id, Number task_id) { if (Objects.nonNull(task_id)) { Map param2 = new HashMap(); param2.put("access_token", access_token); Map body3 = new HashMap(); body3.put("agent_id", agent_id); body3.put("task_id", task_id); // Map msg = new HashMap(); // msg.put("msgtype", "text"); //获取当前时间 精确到秒 // String time = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"); // msg.put("text", UtilMap.map("content, aa", content, "")); // body3.put("msg", msg); UtilHttp.doPost("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2", null, param2, body3); } } private List parseJsonList(String jsonStr) { if (jsonStr == null || "null".equals(jsonStr) || jsonStr.isEmpty()) { return Collections.emptyList(); } try { // 宜搭有时返回的是 "\"[{...}]\"",需先 unescape String clean = StringEscapeUtils.unescapeJava(jsonStr); // 如果首尾是双引号,去掉 if (clean.startsWith("\"") && clean.endsWith("\"")) { clean = clean.substring(1, clean.length() - 1); } return (List) JSONArray.parse(clean); } catch (Exception e) { return Collections.emptyList(); } } @PostMapping("/kdYdCustomer") Map insertCustomer(@RequestBody Map map) { Map stringObjectMap = kdYdCustomerService.insertCustomer(map); return stringObjectMap; } }