package com.ruoyi.lsfx.client; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.lsfx.domain.CallerContext; import com.ruoyi.lsfx.domain.response.XinhuaEnterpriseQueryResult; import com.ruoyi.lsfx.exception.LsfxApiException; import com.ruoyi.lsfx.util.HttpUtil; import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import java.util.LinkedHashMap; import java.util.Map; /** 新华社工商信息同步接口客户端。 */ @Component public class XinhuaEnterpriseClient { private static final int PLATFORM_SUCCESS_CODE = 10000; private static final int BUSINESS_SUCCESS_STATUS = 1; private static final int BUSINESS_SUCCESS_REASON_CODE = 200; @Resource private HttpUtil httpUtil; @Resource private ObjectMapper objectMapper; @Value("${xinhua-enterprise.api.url}") private String apiUrl; @Value("${xinhua-enterprise.api.org-code:999000}") private String orgCode; @Value("${xinhua-enterprise.api.run-type:1}") private String runType; public XinhuaEnterpriseQueryResult query(CallerContext caller, String enterpriseName) { String normalizedName = normalize(enterpriseName); if (!StringUtils.hasText(normalizedName)) { throw new IllegalArgumentException("企业名称不能为空"); } Map params = new LinkedHashMap<>(); params.put("entName", normalizedName); params.put("serialNum", buildSerialNum()); params.put("runType", runType); params.put("orgCode", orgCode); String rawJson = httpUtil.postUrlEncodedFormForString(caller, apiUrl, params, null); JsonNode root = parse(rawJson); JsonNode data = requireSuccess(root); JsonNode profile = data.path("mappingOutputFields"); if (!profile.isObject() || profile.isEmpty()) { throw new LsfxApiException("新华社工商接口返回工商信息为空"); } String responseName = normalize(profile.path("enterpriseName").asText(null)); if (!normalizedName.equals(responseName)) { throw new LsfxApiException("新华社工商接口返回企业名称与查询名称不一致"); } if (!StringUtils.hasText(normalize(profile.path("creditCode").asText(null)))) { throw new LsfxApiException("新华社工商接口未返回统一社会信用代码"); } return new XinhuaEnterpriseQueryResult(rawJson, profile); } private JsonNode parse(String rawJson) { try { return objectMapper.readTree(rawJson); } catch (Exception e) { throw new LsfxApiException("新华社工商接口响应不是合法JSON", e); } } private JsonNode requireSuccess(JsonNode root) { if (!root.path("success").asBoolean(false)) { throw new LsfxApiException(message(root, "新华社工商接口平台调用失败")); } if (root.path("code").asInt(Integer.MIN_VALUE) != PLATFORM_SUCCESS_CODE) { throw new LsfxApiException("新华社工商接口平台状态码异常: " + root.path("code").asText()); } JsonNode data = root.path("data"); if (!data.isObject()) { throw new LsfxApiException("新华社工商接口返回data为空"); } if (data.path("status").asInt(Integer.MIN_VALUE) != BUSINESS_SUCCESS_STATUS) { throw new LsfxApiException(message(root, "新华社工商接口业务状态异常")); } if (data.path("reasonCode").asInt(Integer.MIN_VALUE) != BUSINESS_SUCCESS_REASON_CODE) { throw new LsfxApiException(message(root, "新华社工商接口业务原因码异常")); } return data; } private String message(JsonNode root, String defaultMessage) { String reason = normalize(root.path("data").path("reasonMessage").asText(null)); return StringUtils.hasText(reason) ? reason : defaultMessage; } private String buildSerialNum() { return "CCDI_GS_" + System.currentTimeMillis() + "_" + IdUtils.fastSimpleUUID(); } private String normalize(String value) { return value == null ? null : value.trim(); } }