| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- package com.malk.taisen.service.impl;
- import cn.hutool.http.HttpUtil;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.malk.server.aliwork.YDConf;
- import com.malk.server.aliwork.YDParam;
- import com.malk.server.dingtalk.DDR_New;
- import com.malk.service.aliwork.YDClient;
- import com.malk.service.dingtalk.DDClient;
- import com.malk.service.dingtalk.DDClient_Notice;
- import com.malk.service.dingtalk.DDClient_NoticeResult;
- import com.malk.taisen.dto.ArNotifyRecord;
- import com.malk.taisen.service.ArNotifyService;
- import com.malk.utils.UtilList;
- import com.malk.utils.UtilMap;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- @Slf4j
- @Service
- public class ArNotifyServiceImpl implements ArNotifyService {
- private static final String APP_TYPE = "APP_N9NPHVTQLPBPO8MR6WFG";
- private static final String FORM_UUID = "FORM-A7AA1BE41C354D5C879925006D3A3F06K6ZY";
- private static final int MAX_ATTEMPTS = 6;
- @Autowired
- private YDClient ydClient;
- @Autowired
- private DDClient ddClient;
- @Autowired
- private DDClient_Notice ddClientNotice;
- @Autowired
- private DDClient_NoticeResult ddClientNoticeResult;
- @Value("${ar.notify.user-ids:}")
- private String notifyUserIds;
- /**
- * Persist an AR batch and send one DingTalk work notification.
- *
- * @param records AR automatic posting records
- * @return true only after DingTalk confirms delivery and Yida is updated
- */
- @Override
- public boolean notify(List<ArNotifyRecord> records) {
- try {
- for (ArNotifyRecord record : records) {
- validate(record);
- }
- final String instanceId = createRecord(records);
- if (instanceId == null) {
- return false;
- }
- List<String> recipients = recipients();
- if (UtilList.isEmpty(recipients)) {
- markFailure(instanceId, 0, "未配置AR_NOTIFY_USER_IDS");
- return false;
- }
- return sendAndConfirm(records, instanceId, recipients);
- } catch (Exception e) {
- log.error("AR自动入账通知执行失败", e);
- return false;
- }
- }
- private String createRecord(List<ArNotifyRecord> records) {
- Map formData = UtilMap.map("tableField_3ycv10yjn", detailRows(records));
- formData.put("selectField_89a55tbg2", "处理中");
- formData.put("numberField_89a56h485", 0);
- Object result = retry("创建宜搭实例", new Action() {
- @Override
- public Object execute() {
- return ydClient.createData(YDParam.builder().appType(APP_TYPE).formUuid(FORM_UUID)
- .formDataJson(JSON.toJSONString(formData)).build());
- }
- });
- return instanceId(result);
- }
- private boolean sendAndConfirm(List<ArNotifyRecord> records, String instanceId, List<String> recipients) {
- String lastError = "";
- String taskId = null;
- for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
- try {
- if (StringUtils.isBlank(taskId)) {
- taskId = ddClientNotice.sendNotification(ddClient.getAccessToken(), recipients, null, false,
- notificationMessage(records, instanceId));
- if (StringUtils.isBlank(taskId)) {
- throw new IllegalStateException("钉钉未返回工作通知任务编号");
- }
- update(instanceId, UtilMap.map("textField_89a545m8z, numberField_89a56h485",
- taskId, attempt - 1));
- }
- Map result = ddClientNoticeResult.getSendResult(ddClient.getAccessToken(), taskId);
- if (!isSent(result)) {
- throw new IllegalStateException("钉钉工作通知尚未发送成功: " + JSON.toJSONString(result));
- }
- Date now = new Date();
- update(instanceId, UtilMap.map(
- "textField_89a41cak4, dateField_89a42ww2f, textField_89a53tgha, selectField_89a55tbg2, numberField_89a56h485, textareaField_89a575hku",
- "X", now.getTime(), new SimpleDateFormat("HHmmss").format(now), "成功", attempt - 1, "钉钉工作通知发送成功"));
- return true;
- } catch (Exception e) {
- lastError = e.getMessage();
- log.warn("AR自动入账通知第{}次尝试失败, instanceId={}, taskId={}, error={}",
- attempt, instanceId, taskId, lastError);
- if (attempt < MAX_ATTEMPTS) {
- sleep(attempt);
- }
- }
- }
- log.error("AR自动入账通知重试耗尽, instanceId={}, error={}", instanceId, lastError);
- markFailure(instanceId, MAX_ATTEMPTS - 1, lastError);
- return false;
- }
- private void markFailure(final String instanceId, final int retryCount, final String message) {
- retry("回写宜搭失败状态", new Action() {
- @Override
- public Object execute() {
- update(instanceId, UtilMap.map("selectField_89a55tbg2, numberField_89a56h485, textareaField_89a575hku",
- "失败", retryCount, StringUtils.abbreviate(message, 1900)));
- return Boolean.TRUE;
- }
- });
- }
- private void update(String instanceId, Map formData) {
- ydClient.operateData(YDParam.builder().appType(APP_TYPE).formInstanceId(instanceId)
- .updateFormDataJson(JSON.toJSONString(formData)).build(), YDConf.FORM_OPERATION.update);
- }
- private Object retry(String actionName, Action action) {
- for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
- try {
- return action.execute();
- } catch (Exception e) {
- log.warn("{}第{}次尝试失败: {}", actionName, attempt, e.getMessage());
- if (attempt < MAX_ATTEMPTS) {
- sleep(attempt);
- }
- }
- }
- log.error("{}重试耗尽", actionName);
- return null;
- }
- private void sleep(int retryNumber) {
- try {
- Thread.sleep((1L << (retryNumber - 1)) * 1000L);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new IllegalStateException("重试等待被中断", e);
- }
- }
- private Map notificationMessage(List<ArNotifyRecord> records, String instanceId) {
- String detailUrl = "https://www.aliwork.com/" + APP_TYPE + "/formDetail/" + FORM_UUID
- + "?formInstId=" + instanceId + "&corpid=dinge61fe69900ea236b35c2f4657eb6378f";
- ArNotifyRecord first = records.get(0);
- String text = "本次自动入账记录数:" + records.size() + "\n公司代码:" + first.getBUKRS()
- + "\n首条客户:" + first.getKUNNR() + " " + StringUtils.defaultString(first.getZNAME())
- + "\n首条凭证:" + first.getBELNR() + "\n请点击查看明细。";
- Map<String, Object> link = new HashMap<>();
- link.put("picUrl", "@lALOACZwe2Rk");
- link.put("title", "AR自动入账通知");
- link.put("text", text);
- link.put("messageUrl", detailUrl);
- Map<String, Object> message = new HashMap<>();
- message.put("msgtype", "link");
- message.put("link", link);
- return message;
- }
- private boolean isSent(Map result) {
- if (result == null) {
- return false;
- }
- return !hasFailure(result, "invalid_user_id_list")
- && !hasFailure(result, "forbidden_list")
- && !hasFailure(result, "failed_user_id_list")
- && !hasFailure(result, "invalid_dept_id_list")
- && !hasFailure(result, "forbidden_dept_id_list")
- && !hasFailure(result, "failed_dept_id_list");
- }
- private boolean hasFailure(Map result, String key) {
- Object value = result.get(key);
- if (value == null) {
- return false;
- }
- if (value instanceof Collection) {
- return !((Collection) value).isEmpty();
- }
- if (value.getClass().isArray()) {
- return java.lang.reflect.Array.getLength(value) > 0;
- }
- return StringUtils.isNotBlank(String.valueOf(value));
- }
- private String instanceId(Object result) {
- if (result instanceof DDR_New) {
- DDR_New response = (DDR_New) result;
- if (StringUtils.isNotBlank(response.getFormInstId())) {
- return response.getFormInstId();
- }
- if (StringUtils.isNotBlank(response.getInstanceId())) {
- return response.getInstanceId();
- }
- result = response.getResult();
- }
- if (result instanceof String && StringUtils.isNotBlank((String) result)) {
- return (String) result;
- }
- if (!(result instanceof Map)) {
- log.error("宜搭创建响应未包含实例ID, response={}", JSON.toJSONString(result));
- return null;
- }
- Map map = (Map) result;
- Object id = map.get("formInstId");
- if (id == null) {
- id = map.get("formInstanceId");
- }
- if (id == null) {
- id = map.get("instanceId");
- }
- return id == null ? null : String.valueOf(id);
- }
- private List<String> recipients() {
- List<String> result = new ArrayList<>();
- String[] userIds = StringUtils.split(StringUtils.defaultString(notifyUserIds), ',');
- if (userIds == null) {
- return result;
- }
- for (String userId : userIds) {
- if (StringUtils.isNotBlank(userId)) {
- result.add(userId.trim());
- }
- }
- return result;
- }
- private List<Map> detailRows(List<ArNotifyRecord> records) {
- List<Map> rows = new ArrayList<>();
- for (ArNotifyRecord record : records) {
- rows.add(UtilMap.map(
- "textField_3ycw2w508, textField_3ycw3wu79, textField_3ycw4j3ot, textField_3ycw539ws, textField_3ycw6yohj, dateField_3ycw7ql0n, dateField_3ycw8qqry, dateField_3ycw9wnsf, numberField_3ycwa25z7, textField_3ycwbocwu, textField_3ycwcntzu, dateField_3ycwdnk73, textField_3ycwes8k4, textField_3ycwfk3zf, textField_3ycwgmpib, textField_3ycwhz5dp",
- record.getBUKRS(), record.getKUNNR(), record.getZNAME(), record.getBELNR(), record.getGJAHR(),
- dateMillis(record.getBUDAT()), dateMillis(record.getBLDAT()), dateMillis(record.getCPUDT()), record.getWRBTR(),
- record.getWAERS(), "", null, "", "", "", ""));
- }
- return rows;
- }
- private static long dateMillis(String date) {
- try {
- SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
- formatter.setLenient(false);
- return formatter.parse(date).getTime();
- } catch (ParseException e) {
- throw new IllegalArgumentException("日期必须为yyyyMMdd格式: " + date, e);
- }
- }
- private void validate(ArNotifyRecord record) {
- if (record == null || StringUtils.isAnyBlank(record.getBUKRS(), record.getKUNNR(), record.getBELNR(),
- record.getGJAHR(), record.getBUDAT(), record.getBLDAT(), record.getCPUDT()) || record.getWRBTR() == null) {
- throw new IllegalArgumentException("BUKRS、KUNNR、BELNR、GJAHR、BUDAT、BLDAT、CPUDT、WRBTR不能为空");
- }
- }
- private interface Action {
- Object execute();
- }
- public static void main(String[] args) {
- String url = "https://etl-nonprod-tasks.tysondt.com:443/api/1/rest/feed/run/task/TysonNonProd/projects/10-QA-team-cash-to-order/tk_dingtalk_to_sap_otc_inquiry?bearer_token=Rs8eIy614To-g4UAQTsYTt@G9bRMhQrl";
- // String url2 = "https://etl-nonprod-tasks.tysondt.com:443/api/1/rest/feed/run/task/TysonNonProd/projects/00-STG-team-cash-to-order/tk_dingtalk_to_sap_otc_unlocked_orders_inquiry?bearer_token=i2AZ93FBOD42aPNLyWACGxXRyK0LdY8U";
- String result= HttpUtil.createPost(url).body(JSONObject.toJSONString(UtilMap.map("CUSTOMER_NUMBER","3000045"))).form(JSONObject.toJSONString(UtilMap.map("requestID, interface_no","12345, OTC002"))).execute().body();
- System.out.println(result);
- // String result2= HttpUtil.createPost(url2).body(JSONObject.toJSONString(UtilMap.map("CUSTOMER_NUMBER","1000253"))).form(JSONObject.toJSONString(UtilMap.map("requestID","1234"))).execute().body();
- // System.out.println(result2);
- }
- }
|