Quellcode durchsuchen

供应商推送字段调整

fyz vor 2 Wochen
Ursprung
Commit
786cf8d23c

+ 112 - 2
mjava-sdzl/src/main/java/com/malk/sdzl/service/Impl/YqbOrderPushServiceImpl.java

@@ -26,8 +26,10 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /** 宜搭采购合同表单推送易企报单据服务。 */
 @Slf4j
@@ -41,6 +43,7 @@ public class YqbOrderPushServiceImpl implements YqbOrderPushService {
     private static final String AMOUNT_FIELD_ID = "numberField_mpgp9h5c";
     private static final String APPROVAL_USER_FIELD_ID = "employeeField_mt2q233g";
     private static final String DATE_FIELD_PREFIX = "dateField";
+    private static final String CASCADE_DATE_FIELD_PREFIX = "cascadeDateField";
     private static final String ATTACHMENT_FIELD_PREFIX = "attachmentField";
     private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter
             .ofPattern("yyyy-MM-dd")
@@ -152,8 +155,14 @@ public class YqbOrderPushServiceImpl implements YqbOrderPushService {
         YqbApiResponse<Object> response = yqbApiClient.post(
                 CREATE_ORDER_PATH, createRequest.toRequestBody(), "生成单据");
         if (!response.isSuccess()) {
-            throw new IllegalStateException("易企报生成单据失败:result=" + response.getResult()
-                    + ",message=" + response.getMessage());
+            String failReason = extractFailReason(response.getData());
+            String errorMessage = "易企报生成单据失败:result=" + response.getResult()
+                    + ",message=" + response.getMessage();
+            if (!isBlank(failReason)) {
+                errorMessage += ",failReason=" + failReason;
+            }
+            log.error("{},formInstanceId={}", errorMessage, formInstanceId);
+            throw new IllegalStateException(errorMessage);
         }
 
         YqbOrderPushResult result = new YqbOrderPushResult();
@@ -167,6 +176,70 @@ public class YqbOrderPushServiceImpl implements YqbOrderPushService {
         return result;
     }
 
+    /**
+     * 提取易企报生成单据失败明细中的 failReason。
+     * data 可能是 JSONObject / Map,也可能被反序列化为 JSON 字符串;
+     * failList 兼容直接数组或 {"failList": [...]} 两种形式。
+     */
+    @SuppressWarnings("unchecked")
+    private String extractFailReason(Object data) {
+        if (data == null) {
+            return null;
+        }
+        Object parsedData = data;
+        if (data instanceof String) {
+            String dataText = ((String) data).trim();
+            if (dataText.startsWith("{") || dataText.startsWith("[")) {
+                try {
+                    parsedData = JSON.parse(dataText);
+                } catch (Exception e) {
+                    log.warn("易企报生成单据失败响应 data 不是有效 JSON:{}", dataText);
+                    return null;
+                }
+            }
+        }
+
+        Object failListValue = parsedData;
+        if (parsedData instanceof Map) {
+            failListValue = ((Map<?, ?>) parsedData).get("failList");
+        }
+        if (failListValue instanceof String) {
+            String failListText = ((String) failListValue).trim();
+            if (failListText.startsWith("[")) {
+                try {
+                    failListValue = JSON.parseArray(failListText);
+                } catch (Exception e) {
+                    log.warn("易企报生成单据失败响应 failList 不是有效 JSON:{}", failListText);
+                    return null;
+                }
+            }
+        }
+        if (!(failListValue instanceof Collection)) {
+            return null;
+        }
+
+        Set<String> reasons = new LinkedHashSet<>();
+        for (Object failItem : (Collection<?>) failListValue) {
+            Object reason = null;
+            if (failItem instanceof Map) {
+                reason = ((Map<?, ?>) failItem).get("failReason");
+            } else if (failItem instanceof String) {
+                try {
+                    Object parsedItem = JSON.parse((String) failItem);
+                    if (parsedItem instanceof Map) {
+                        reason = ((Map<?, ?>) parsedItem).get("failReason");
+                    }
+                } catch (Exception ignored) {
+                    // 单条失败信息不是 JSON 时忽略,继续读取其他条目。
+                }
+            }
+            if (reason != null && !String.valueOf(reason).trim().isEmpty()) {
+                reasons.add(String.valueOf(reason).trim());
+            }
+        }
+        return reasons.isEmpty() ? null : String.join(";", reasons);
+    }
+
     private List<YqbOrderComponent> buildOrderComponents(Map<String, Object> formData) {
         List<YqbOrderComponent> components = new ArrayList<>();
         for (FieldMapping mapping : FIELD_MAPPINGS) {
@@ -262,6 +335,9 @@ public class YqbOrderPushServiceImpl implements YqbOrderPushService {
                 return DATE_FORMATTER.format(Instant.ofEpochMilli(epochMillis));
             }
         }
+        if (mapping.fieldId.startsWith(CASCADE_DATE_FIELD_PREFIX)) {
+            return formatCascadeDateValue(mapping.fieldId, value);
+        }
         if (mapping.fieldId.startsWith(ATTACHMENT_FIELD_PREFIX)) {
             return getAttachmentTemporaryUrls(mapping.fieldId, value);
         }
@@ -271,6 +347,40 @@ public class YqbOrderPushServiceImpl implements YqbOrderPushService {
         return String.valueOf(value);
     }
 
+    /**
+     * 级联日期组件返回数组,例如 ["1760457600000", "1760544000000"]。
+     * 将每个可识别的毫秒时间戳转换为 yyyy-MM-dd,并保留数组结构后转成 JSON 字符串。
+     */
+    private String formatCascadeDateValue(String fieldId, Object value) {
+        Object cascadeDateValue = value;
+        if (value instanceof String) {
+            String text = ((String) value).trim();
+            if (text.startsWith("[") && text.endsWith("]")) {
+                try {
+                    cascadeDateValue = JSON.parseArray(text);
+                } catch (Exception e) {
+                    log.warn("宜搭级联日期字段值不是有效 JSON 数组,按原值推送,fieldId={},value={}", fieldId, text);
+                    return text;
+                }
+            }
+        }
+        if (!(cascadeDateValue instanceof Collection)) {
+            return String.valueOf(value);
+        }
+
+        List<Object> formattedValues = new ArrayList<>();
+        for (Object item : (Collection<?>) cascadeDateValue) {
+            Long epochMillis = getEpochMillis(item);
+            if (epochMillis == null) {
+                formattedValues.add(item);
+                log.warn("宜搭级联日期字段中存在非毫秒时间戳值,按原值推送,fieldId={},value={}", fieldId, item);
+            } else {
+                formattedValues.add(DATE_FORMATTER.format(Instant.ofEpochMilli(epochMillis)));
+            }
+        }
+        return JSON.toJSONString(formattedValues);
+    }
+
     private List<String> getAttachmentTemporaryUrls(String fieldId, Object value) {
         Object attachmentValue = value;
         if (value instanceof String) {

+ 19 - 5
mjava-sdzl/src/main/java/com/malk/sdzl/service/Impl/YqbSupplierFormPushServiceImpl.java

@@ -38,10 +38,10 @@ public class YqbSupplierFormPushServiceImpl implements YqbSupplierFormPushServic
     private static final String FIELD_BANK_FULL_NAME = "textField_mpfb5onx";
     private static final String FIELD_BANK_ACCOUNT = "textField_mpfb5ony";
     private static final String FIELD_ADDRESS = "textField_mpdskkg3";
-    private static final String FIELD_BANK_NAME = "selectField_mpfb5oo1";
-    private static final String FIELD_CITY = "textField_mrlpiibu";
+    private static final String FIELD_BANK_NAME = "textField_mvapyji4";
+    private static final String FIELD_CITY = "addressField_mpfb5oo0_id";
     private static final String FIELD_PHONE = "textField_mpfb5oo3";
-    private static final String FIELD_SUPPLIER_CODE = "textField_mrleu14h";
+    private static final String FIELD_SUPPLIER_CODE = "serialNumberField_mrleswm7";
 
     @Autowired
     private YDClient ydClient;
@@ -88,7 +88,8 @@ public class YqbSupplierFormPushServiceImpl implements YqbSupplierFormPushServic
 
         YqbApiResponse<Object> invoiceResponse = yqbInvoiceTitleService.addOrUpdateInvoiceTitle(invoiceRequest);
         ensureSuccess(invoiceResponse, "新增发票抬头");
-        String invoiceTitleId = extractResponseId(invoiceResponse.getData(), "新增发票抬头");
+        // 发票抬头新增接口成功时直接返回 data=发票抬头ID,例如 data: 131309。
+        String invoiceTitleId = extractDirectResponseId(invoiceResponse.getData(), "新增发票抬头");
 
         supplierRequest.setPayAccountIds(payAccountId);
         supplierRequest.setInvoiceTitleIds(invoiceTitleId);
@@ -116,7 +117,9 @@ public class YqbSupplierFormPushServiceImpl implements YqbSupplierFormPushServic
         request.setBankCardNum(requiredField(formData, FIELD_BANK_ACCOUNT, "银行账号"));
         request.setBankName(requiredField(formData, FIELD_BANK_NAME, "法人收款银行"));
         request.setBankFullName(valueOf(formData.get(FIELD_BANK_FULL_NAME)));
-        request.setCity(valueOf(formData.get(FIELD_CITY)));
+        String[] split = valueOf(formData.get(FIELD_CITY)).replace("\"", "").split("/");
+        request.setProvince(split[0]);
+        request.setCity(split[1]);
         request.setType(YqbReceiptAccountRequest.TYPE_CORPORATE);
         request.setVisible(YqbReceiptAccountRequest.VISIBLE_ALL);
         request.setSourceType(YqbReceiptAccountRequest.SOURCE_TYPE_IMPORT);
@@ -158,6 +161,17 @@ public class YqbSupplierFormPushServiceImpl implements YqbSupplierFormPushServic
         return id;
     }
 
+    /**
+     * 发票抬头新增接口的 data 直接就是 ID,例如:{"data":131309,"result":100}。
+     */
+    private String extractDirectResponseId(Object data, String operation) {
+        String id = valueOf(data);
+        if (isBlank(id)) {
+            throw new IllegalStateException(operation + "成功响应 data 中缺少 ID");
+        }
+        return id;
+    }
+
     @SuppressWarnings("unchecked")
     private String extractId(Object value) {
         if (value == null) {