package com.ruoyi.erp.request; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.utils.http.HttpUtils; import lombok.Setter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * ERP请求基类(支持开放平台签名规范) */ public abstract class ERPRequestBase { private static final Logger log = LoggerFactory.getLogger(ERPRequestBase.class); protected String url; protected String sign; protected IERPAccount erpAccount; @Setter protected JSONObject requestBody; protected long timestamp; // 统一时间戳字段 public ERPRequestBase(String url, IERPAccount erpAccount) { this.url = url; this.erpAccount = erpAccount; } /** * 生成MD5签名(兼容官方示例) * @param str 需要签名的原始字符串 * @return 十六进制小写MD5值 */ public String genMd5(String str) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8)); StringBuilder result = new StringBuilder(); for (byte b : digest) { result.append(String.format("%02x", b & 0xff)); // 保证小写十六进制 } return result.toString(); } catch (NoSuchAlgorithmException e) { log.error("MD5算法初始化失败", e); throw new RuntimeException("MD5算法初始化失败", e); } } /** * 生成请求签名(与官方示例保持完全一致的拼接逻辑) */ public void genSign(long timestamp) { this.timestamp = timestamp; String jsonStr = getRequestBody(); // 使用getRequestBody()方法 String data = erpAccount.getApiKey() + "," + genMd5(jsonStr) + "," + timestamp + "," + erpAccount.getApiKeySecret(); this.sign = genMd5(data); } /** * 获取带签名的请求URL * @return 包含签名参数的完整URL */ public String getRequestUrl() { return url + "?appid=" + erpAccount.getApiKey() + "×tamp=" + timestamp + "&sign=" + sign; } /** * 获取请求体内容(空时返回空对象) * @return JSON字符串格式的请求体 */ public String getRequestBody() { return requestBody != null ? requestBody.toJSONString() : "{}"; } /** * 执行HTTP请求并获取响应 * @return 接口返回的原始JSON字符串 */ public String getResponseBody() { try { long timestamp = System.currentTimeMillis() / 1000; genSign(timestamp); String requestUrl = getRequestUrl(); String body = getRequestBody(); System.out.println("请求地址: " + requestUrl); System.out.println("请求体: " + body); // 统一通过自定义 SSL 通道发起请求,提升与开放平台的 TLS 兼容性 return HttpUtils.sendSSLPost(requestUrl, body, org.springframework.http.MediaType.APPLICATION_JSON_VALUE); } catch (Exception e) { log.error("HTTP请求失败: {}", e.getMessage(), e); throw new RuntimeException("ERP接口调用失败: " + e.getMessage(), e); } } }