|
|
@@ -1,22 +1,16 @@
|
|
|
package com.fs.erp.service.impl;
|
|
|
|
|
|
-import cn.hutool.core.map.MapUtil;
|
|
|
import cn.hutool.http.HttpResponse;
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
|
|
-import com.fs.erp.dto.CommonResponse;
|
|
|
import com.fs.erp.dto.tl.JstLogisticsPushRequest;
|
|
|
import com.fs.erp.dto.tl.TlCreateOrderRequest;
|
|
|
-import com.fs.erp.dto.tl.TlCreateOrderResponse;
|
|
|
import com.fs.erp.service.TlErpOrderService;
|
|
|
-import com.fs.erp.utils.SignUtil;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.codec.digest.DigestUtils;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.http.*;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.web.client.RestTemplate;
|
|
|
|
|
|
import java.time.Instant;
|
|
|
import java.util.*;
|
|
|
@@ -33,63 +27,65 @@ public class TlErpOrderServiceImpl implements TlErpOrderService {
|
|
|
@Value("${jst.secret.key:xysync_dLsSaheCzK7RU9gd}")
|
|
|
private String secretKey;
|
|
|
|
|
|
- private final RestTemplate restTemplate = new RestTemplate();
|
|
|
private final ObjectMapper objectMapper = new ObjectMapper()
|
|
|
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
|
|
|
|
|
|
@Override
|
|
|
- public ResponseEntity<TlCreateOrderResponse> syncOrderToJst(TlCreateOrderRequest request) {
|
|
|
+ public HttpResponse syncOrderToJst(TlCreateOrderRequest request) {
|
|
|
try {
|
|
|
- String corpId = request.getCorpId();
|
|
|
- List<?> rawData = request.getData();
|
|
|
-
|
|
|
-// if (rawData == null || rawData.isEmpty()) {
|
|
|
-// return new CommonResponse<TlCreateOrderResponse>()
|
|
|
-// .setCode(-1)
|
|
|
-// .setMsg("订单数据不能为空")
|
|
|
-// .setData(null);
|
|
|
-// }
|
|
|
-
|
|
|
- List<Map<String, Object>> dataAsMaps = new ArrayList<>();
|
|
|
- for (Object item : rawData) {
|
|
|
- Map<String, Object> map = objectMapper.convertValue(item, Map.class);
|
|
|
- dataAsMaps.add(map);
|
|
|
- }
|
|
|
-
|
|
|
- long timestamp = Instant.now().getEpochSecond();
|
|
|
- String sortedDataJson = sortAndSerializeData(dataAsMaps);
|
|
|
-
|
|
|
- String signSource = secretKey + corpId + sortedDataJson + timestamp;
|
|
|
- String sign = DigestUtils.md5Hex(signSource).toLowerCase();
|
|
|
-
|
|
|
- String url = jstApiBaseUrl + "/v1/mp/sync/order/jst/create?sign=" + sign + "&t=" + timestamp;
|
|
|
- String requestBody = objectMapper.writeValueAsString(request);
|
|
|
-
|
|
|
- log.info("请求URL: {}", url);
|
|
|
- log.info("请求Body: {}", requestBody);
|
|
|
- log.info("sign = MD5({})", signSource);
|
|
|
- log.info("最终 sign: {}, t: {}", sign, timestamp);
|
|
|
-
|
|
|
- HttpHeaders headers = new HttpHeaders();
|
|
|
- headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
- HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
|
|
|
-
|
|
|
- ResponseEntity<TlCreateOrderResponse> response = restTemplate.exchange(
|
|
|
- url,
|
|
|
- HttpMethod.POST,
|
|
|
- entity,
|
|
|
- TlCreateOrderResponse.class
|
|
|
- );
|
|
|
+ String corpId = request.getCorpId();
|
|
|
+ List<?> rawData = request.getData();
|
|
|
+
|
|
|
+ List<Map<String, Object>> dataAsMaps = new ArrayList<>();
|
|
|
+ for (Object item : rawData) {
|
|
|
+ Map<String, Object> map = objectMapper.convertValue(item, Map.class);
|
|
|
+ dataAsMaps.add(map);
|
|
|
+ }
|
|
|
+
|
|
|
+ long timestamp = Instant.now().getEpochSecond();
|
|
|
+ String sortedDataJson = sortAndSerializeData(dataAsMaps);
|
|
|
+
|
|
|
+ String signSource = secretKey + corpId + sortedDataJson + timestamp;
|
|
|
+ String sign = DigestUtils.md5Hex(signSource).toLowerCase();
|
|
|
+
|
|
|
+ String url = jstApiBaseUrl + "/v1/mp/sync/order/jst/create?sign=" + sign + "&t=" + timestamp;
|
|
|
+ String requestBody = objectMapper.writeValueAsString(request);
|
|
|
+
|
|
|
+ log.info("请求URL: {}", url);
|
|
|
+ log.info("请求Body: {}", requestBody);
|
|
|
+ //log.info("sign = MD5({})", signSource);
|
|
|
+ log.info("最终 sign: {}, t: {}", sign, timestamp);
|
|
|
+ // 使用 Hutool HttpRequest 发送 POST 请求
|
|
|
+ HttpResponse response = cn.hutool.http.HttpRequest.post(url)
|
|
|
+ .header("Content-Type", "application/json;charset=UTF-8")
|
|
|
+ .body(requestBody)
|
|
|
+ .timeout(10000) // 可选:设置超时(毫秒)
|
|
|
+ .execute();
|
|
|
+
|
|
|
+ if (!response.isOk()) {
|
|
|
+ log.error("HTTP 请求失败,状态码: {}", response.getStatus());
|
|
|
+ throw new RuntimeException("调用聚水潭接口失败,HTTP 状态码: " + response.getStatus());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析响应体
|
|
|
+ String responseBody = response.body();
|
|
|
+ Map<String, Object> result;
|
|
|
+ try {
|
|
|
+ result = objectMapper.readValue(responseBody, Map.class);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("无法解析聚水潭响应体: {}", responseBody, e);
|
|
|
+ throw new RuntimeException("聚水潭返回非 JSON 响应", e);
|
|
|
+ }
|
|
|
+ // 判断业务状态是否为 "ok"
|
|
|
+ String status = (String) result.get("status");
|
|
|
+ if (!"ok".equals(status)) {
|
|
|
+ String errmsg = (String) result.get("errmsg");
|
|
|
+ log.error("聚水潭业务处理失败,status: {}, errmsg: {}", status, errmsg);
|
|
|
+ throw new RuntimeException("聚水潭同步订单失败: " + (errmsg != null ? errmsg : "未知错误"));
|
|
|
+ }
|
|
|
+ log.info("订单同步到聚水潭成功!");
|
|
|
return response;
|
|
|
-// Map<String, String> headers = MapUtil.builder(new HashMap<String, String>())
|
|
|
-// .put("Content-Type", "application/json;charset=UTF-8")
|
|
|
-// .build();
|
|
|
-// HttpResponse response = cn.hutool.http.HttpRequest.post(url)
|
|
|
-// .headerMap(headers, true)
|
|
|
-// .body(requestBody)
|
|
|
-// .execute();
|
|
|
-// return response;
|
|
|
- } catch (JsonProcessingException e) {
|
|
|
+ } catch (Exception e) {
|
|
|
throw new RuntimeException(e);
|
|
|
}
|
|
|
|