package com.vincent.rsf.openApi.service.phyz.impl;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.cfg.CoercionAction;
|
import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
|
import com.vincent.rsf.framework.exception.CoolException;
|
import com.vincent.rsf.openApi.config.PlatformProperties;
|
import com.vincent.rsf.openApi.entity.constant.WmsConstant;
|
import com.vincent.rsf.openApi.entity.dto.CommonResponse;
|
import com.vincent.rsf.openApi.entity.phyz.ErpReportParams;
|
import com.vincent.rsf.openApi.entity.phyz.Order;
|
import com.vincent.rsf.openApi.service.WmsErpService;
|
import com.vincent.rsf.openApi.service.phyz.ErpReportService;
|
import com.vincent.rsf.openApi.utils.ParamsMapUtils;
|
import com.vincent.rsf.openApi.utils.SslUtils;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.entity.StringEntity;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.HttpClients;
|
import org.apache.http.util.EntityUtils;
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
import org.apache.http.client.config.RequestConfig;
|
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpMethod;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.client.ClientHttpResponse;
|
import org.springframework.stereotype.Service;
|
import org.springframework.web.client.RestTemplate;
|
|
import javax.annotation.PostConstruct;
|
import javax.annotation.Resource;
|
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
import java.lang.reflect.Field;
|
import java.security.cert.X509Certificate;
|
import java.io.IOException;
|
import java.io.UnsupportedEncodingException;
|
import java.security.MessageDigest;
|
import java.security.NoSuchAlgorithmException;
|
import java.util.*;
|
|
@Slf4j
|
@Service
|
public class ErpReportServiceImpl implements ErpReportService {
|
|
private static String ERP_REPORT_URL;
|
|
private CloseableHttpClient httpClient;
|
|
@Resource
|
private PlatformProperties.ErpApi erpApi;
|
@Resource
|
private PlatformProperties.WmsApi wmsApi;
|
@Resource
|
private WmsErpService wmsErpService;
|
@Resource
|
private RestTemplate restTemplate;
|
|
|
@PostConstruct
|
public void init() {
|
ERP_REPORT_URL = erpApi.getErpUrl();
|
}
|
|
|
|
public int addOrderToServer(Order order) {
|
if (Objects.isNull(order.getOrderNo()) || order.getOrderNo().isEmpty()) {
|
throw new CoolException("订单号不能为空!!");
|
}
|
/**WMS基础配置链接*/
|
String wmsUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.MODIFY_ORDER_DETLS;
|
HttpHeaders headers = new HttpHeaders();
|
headers.add("Content-Type", "application/json");
|
headers.add("api-version", "v2.0");
|
|
List<Map<String, Object>> maps = new ArrayList<>();
|
Map<String, Object> mapParams = new HashMap<>();
|
// mapParams.put("orderNo", params.getOrderNo());
|
// mapParams.put("anfme", params.getAnfme());
|
// mapParams.put("type", params.getType());
|
// mapParams.put("wkType", params.getWkType());
|
// mapParams.put("exceStatus", params.getExceStatus());
|
// mapParams.put("orderItems", params.getOrderItems());
|
// maps.add(mapParams);
|
|
JSONObject params = JSONObject.parseObject(JSON.toJSONString(order));
|
JSONObject mappedData = ParamsMapUtils.apiMaps("erp", "orderId", params);
|
mapParams = objectToMap(mappedData);
|
maps.add(mapParams);
|
log.info("修改订单信息及状态: {}, 请求参数: {}", wmsUrl, JSONArray.toJSONString(maps));
|
HttpEntity<List<Map<String, Object>>> httpEntity = new HttpEntity<>(maps, headers);
|
// asnOrder/items/save
|
ResponseEntity<String> exchange = restTemplate.exchange(wmsUrl, HttpMethod.POST, httpEntity, String.class);
|
log.info("订单修改返回结果: {}", exchange);
|
if (Objects.isNull(exchange.getBody())) {
|
throw new CoolException("查询失败!!");
|
} else {
|
ObjectMapper objectMapper = new ObjectMapper();
|
objectMapper.coercionConfigDefaults().setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
|
try {
|
CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class);
|
if (result.getCode() == 200) {
|
// JSONObject object = JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
|
return 1;
|
} else {
|
return 0;
|
// throw new CoolException("查询失败!!");
|
}
|
} catch (JsonProcessingException e) {
|
return 0;
|
// throw new CoolException(e.getMessage());
|
}
|
}
|
|
|
// ErpOpParams erpOpParams = new ErpOpParams();
|
// erpOpParams.set
|
//
|
// wmsErpService.updateOrderDetl(ErpOpParams params);
|
|
// CommonResponse updateOrderDetl()
|
//
|
// asnOrderService.saveOrderAndItems(params, getLoginUserId());
|
}
|
|
public static Map<String, Object> objectToMap(Object obj) {
|
Map<String, Object> map = new HashMap<>();
|
Field[] fields = obj.getClass().getDeclaredFields();
|
for (Field field : fields) {
|
field.setAccessible(true); // 设置私有字段也可以访问
|
try {
|
map.put(field.getName(), field.get(obj));
|
} catch (IllegalAccessException e) {
|
e.printStackTrace();
|
}
|
}
|
return map;
|
}
|
|
|
|
/**
|
* 入/出库任务完成上报
|
*
|
* @param params
|
* @return
|
*/
|
public CommonResponse reportInOrOutBound(Object params) {
|
if (Objects.isNull(params)) {
|
throw new CoolException("入/出库任务信息参数不能为空!!");
|
}
|
|
// TODO:参数转换
|
ErpReportParams erpReportParams = new ErpReportParams();
|
if (params instanceof ErpReportParams) {
|
erpReportParams = (ErpReportParams) params;
|
} else if (params instanceof java.util.Map) {
|
java.util.Map<String, Object> paramMap = (java.util.Map<String, Object>) params;
|
|
// 设置基本属性
|
erpReportParams.setFDate((String) paramMap.get("FDate"));
|
erpReportParams.setF_OHDL_BillnoType((String) paramMap.get("F_OHDL_BillnoType"));
|
erpReportParams.setFStockOrgId(paramMap.get("FStockOrgId"));
|
erpReportParams.setFPrdOrgId(paramMap.get("FPrdOrgId"));
|
erpReportParams.setF_OHDL_ProPlan((String) paramMap.get("F_OHDL_ProPlan"));
|
|
// 处理FEntity列表
|
Object fEntityObj = paramMap.get("FEntity");
|
if (fEntityObj instanceof java.util.List) {
|
java.util.List<?> fEntityList = (java.util.List<?>) fEntityObj;
|
java.util.List<ErpReportParams.FEntityItem> entityItems = new java.util.ArrayList<>();
|
|
for (Object item : fEntityList) {
|
if (item instanceof java.util.Map) {
|
java.util.Map<String, Object> itemMap = (java.util.Map<String, Object>) item;
|
ErpReportParams.FEntityItem entityItem = new ErpReportParams.FEntityItem();
|
|
// 使用反射设置属性值
|
try {
|
// 使用反射直接访问字段并设置值
|
java.lang.reflect.Field field;
|
|
field = entityItem.getClass().getDeclaredField("FMaterialId");
|
field.setAccessible(true);
|
field.set(entityItem, itemMap.get("FMaterialId"));
|
|
field = entityItem.getClass().getDeclaredField("FUnitID");
|
field.setAccessible(true);
|
field.set(entityItem, itemMap.get("FUnitID"));
|
|
// 处理数值类型
|
Object fAppQty = itemMap.get("FAppQty");
|
if (fAppQty instanceof Number) {
|
field = entityItem.getClass().getDeclaredField("FAppQty");
|
field.setAccessible(true);
|
field.set(entityItem, ((Number) fAppQty).doubleValue());
|
} else if (fAppQty != null) {
|
field = entityItem.getClass().getDeclaredField("FAppQty");
|
field.setAccessible(true);
|
field.set(entityItem, Double.parseDouble(fAppQty.toString()));
|
}
|
|
Object fActualQty = itemMap.get("FActualQty");
|
if (fActualQty instanceof Number) {
|
field = entityItem.getClass().getDeclaredField("FActualQty");
|
field.setAccessible(true);
|
field.set(entityItem, ((Number) fActualQty).doubleValue());
|
} else if (fActualQty != null) {
|
field = entityItem.getClass().getDeclaredField("FActualQty");
|
field.setAccessible(true);
|
field.set(entityItem, Double.parseDouble(fActualQty.toString()));
|
}
|
|
field = entityItem.getClass().getDeclaredField("FStockId");
|
field.setAccessible(true);
|
field.set(entityItem, itemMap.get("FStockId"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_BworkShop");
|
field.setAccessible(true);
|
field.set(entityItem, itemMap.get("F_OHDL_BworkShop"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_Pallet");
|
field.setAccessible(true);
|
field.set(entityItem, (String) itemMap.get("F_OHDL_Pallet"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_ConPoint");
|
field.setAccessible(true);
|
field.set(entityItem, (String) itemMap.get("F_OHDL_ConPoint"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_PlanNo");
|
field.setAccessible(true);
|
field.set(entityItem, (String) itemMap.get("F_OHDL_PlanNo"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_MONo");
|
field.setAccessible(true);
|
field.set(entityItem, (String) itemMap.get("F_OHDL_MONo"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_MOId");
|
field.setAccessible(true);
|
field.set(entityItem, (String) itemMap.get("F_OHDL_MOId"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_MOLine");
|
field.setAccessible(true);
|
field.set(entityItem, (String) itemMap.get("F_OHDL_MOLine"));
|
|
field = entityItem.getClass().getDeclaredField("F_OHDL_MOLineId");
|
field.setAccessible(true);
|
field.set(entityItem, (String) itemMap.get("F_OHDL_MOLineId"));
|
} catch (Exception e) {
|
log.error("设置FEntityItem属性时发生错误: " + e.getMessage());
|
throw new CoolException("设置FEntityItem属性失败: " + e.getMessage());
|
}
|
|
entityItems.add(entityItem);
|
} else if (item instanceof ErpReportParams.FEntityItem) {
|
entityItems.add((ErpReportParams.FEntityItem) item);
|
}
|
}
|
erpReportParams.setFEntity(entityItems);
|
}
|
} else {
|
throw new CoolException("无法处理的参数类型: " + params.getClass().getName());
|
}
|
|
JSONObject model = new JSONObject();
|
model.put("Model", erpReportParams);
|
JSONObject data = new JSONObject();
|
data.put("data", model);
|
data.put("formid", "ke3d5adc0bbe64eceafd5891400adf40e");
|
|
try {
|
JSONObject loginResult = loginBySign();
|
if (loginResult.getInteger("LoginResultType") == 1) {
|
String erpUrl = ERP_REPORT_URL + "/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc";
|
log.info("Erp入/出库任务完成上报: {}, 请求参数: {}", erpUrl, JSONObject.toJSONString(data));
|
|
String result2 = httpPostExample(erpUrl, data.toJSONString());
|
JSONObject jsonObject = JSONObject.parseObject(result2);
|
log.info("Erp入/出库任务完成上报返回" + jsonObject.toJSONString());
|
boolean sendSuccess = jsonObject.getJSONObject("Result").getJSONObject("ResponseStatus").getBoolean("IsSuccess");
|
|
// TODO:转换后返回
|
if (sendSuccess) {
|
return CommonResponse.ok();
|
} else {
|
JSONArray errors = jsonObject.getJSONObject("Result").getJSONObject("ResponseStatus").getJSONArray("Errors");
|
String errorMsg = "";
|
for (int i = 0; i < errors.size(); i++) {
|
errorMsg += errors.getJSONObject(i).getString("Message") + " ";
|
}
|
return CommonResponse.error(errorMsg);
|
}
|
}
|
} catch (Exception e) {
|
log.error("loginBySign", e);
|
}
|
|
|
// try {
|
// JSONObject jsonObject = postRequest(erpUrl, data, true);
|
// log.info(jsonObject.toJSONString());
|
// boolean sendSuccess = jsonObject.getJSONObject("Result").getJSONObject("ResponseStatus").getBoolean("IsSuccess");
|
//
|
// // TODO:转换后返回
|
// if (sendSuccess) {
|
// return CommonResponse.ok();
|
// } else {
|
// JSONArray errors = jsonObject.getJSONObject("Result").getJSONObject("ResponseStatus").getJSONArray("Errors");
|
// String errorMsg = "";
|
// for (int i = 0; i < errors.size(); i++) {
|
// errorMsg += errors.getJSONObject(i).getString("Message") + " ";
|
// }
|
// return CommonResponse.error(errorMsg);
|
// }
|
// } catch (Exception e) {
|
// log.error("Erp入/出库任务上报响应失败", e);
|
// throw new CoolException("Erp解析响应失败:" + e.getMessage());
|
// }
|
|
return null;
|
}
|
|
|
// 其他入/出库主动上报
|
|
|
// 盘点结果上报
|
|
|
// region 登录
|
/**
|
* 登录,登录参数依次为账套ID、用户名、应用ID、时间戳、签名信息、语言ID
|
*
|
* @throws UnsupportedEncodingException
|
* @throws NoSuchAlgorithmException
|
*/
|
public JSONObject loginBySign() throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
String url = ERP_REPORT_URL + "/Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginBySign.common.kdsvc";
|
JSONObject params = new JSONObject();
|
params.put("parameters", loginParams());
|
String result = httpPostExample(url, params.toJSONString());
|
return JSONObject.parseObject(result);
|
}
|
|
/**
|
* 登录参数整理
|
*
|
* @return
|
* @throws UnsupportedEncodingException
|
* @throws NoSuchAlgorithmException
|
*/
|
private Object[] loginParams() throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
//时间戳
|
long timestamp = System.currentTimeMillis() / 1000;
|
//数据中心ID
|
String dbId = "69368c1051a322";
|
//用户名称
|
String userName = "楼坚伟";
|
//第三方系统应用Id
|
String appId = "330678_w2eBwdkp0oCW2XxuW16D4w/NRhTaTPKp";
|
//第三方系统应用秘钥
|
String appSecret = "31c9e5da6472456193e0c8a7dd2160d9";
|
//将账套ID、用户名、应用ID、应用秘钥、时间戳 放到数组里面
|
String[] arr = new String[] { dbId, userName, appId, appSecret, String.valueOf(timestamp) };
|
//生成签名信息
|
String sign = getSha256(arr);
|
|
return new Object[] { dbId, userName, appId, String.valueOf(timestamp), sign, 2052};
|
}
|
|
public static String getSha256(String[] input) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchAlgorithmException {
|
Arrays.sort(input);
|
//SHA1加密的话改成MessageDigest.getInstance("SHA-1");
|
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
for (String str : input) {
|
sha256.update(str.getBytes("UTF-8"));
|
}
|
byte[] hashBytes = sha256.digest();
|
StringBuilder hashString = new StringBuilder();
|
for (byte b : hashBytes) {
|
String hex = Integer.toHexString(0xff & b);
|
if (hex.length() == 1) {
|
hashString.append('0');
|
}
|
hashString.append(hex);
|
}
|
return hashString.toString();
|
}
|
// endregion
|
|
/**
|
* 通用HTTP POST请求方法
|
*
|
* @param url 请求URL
|
* @param params 请求参数
|
* @return 响应结果
|
*/
|
public JSONObject postRequest(String url, Object params) {
|
if (StringUtils.isBlank(url)) {
|
throw new CoolException("请求URL不能为空!!");
|
}
|
if (Objects.isNull(params)) {
|
throw new CoolException("请求参数不能为空!!");
|
}
|
|
log.info("Erp POST请求: {}, 请求参数: {}", url, JSONObject.toJSONString(params));
|
|
HttpHeaders headers = new HttpHeaders();
|
headers.add("Content-Type", "application/json;charset=utf-8");
|
|
HttpEntity<Object> httpEntity = new HttpEntity<>(params, headers);
|
|
// 创建支持忽略SSL证书验证的RestTemplate
|
RestTemplate sslRestTemplate = SslUtils.createIgnoreSSLRestTemplate();
|
|
// 设置错误处理器,不抛出异常,而是返回响应体
|
sslRestTemplate.setErrorHandler(new org.springframework.web.client.DefaultResponseErrorHandler() {
|
@Override
|
public boolean hasError(ClientHttpResponse response) throws IOException {
|
// 不管状态码如何,都不视为错误
|
return false;
|
}
|
});
|
|
ResponseEntity<String> exchange = sslRestTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
|
log.info("Erp POST请求响应结果: {}", exchange);
|
|
if (Objects.isNull(exchange.getBody())) {
|
throw new CoolException("请求失败!!");
|
}
|
|
try {
|
ObjectMapper objectMapper = new ObjectMapper();
|
objectMapper.coercionConfigDefaults().setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
|
return objectMapper.readValue(exchange.getBody(), JSONObject.class);
|
} catch (JsonProcessingException e) {
|
log.error("Erp解析响应失败", e);
|
throw new CoolException("Erp解析响应失败:" + e.getMessage());
|
}
|
}
|
|
|
|
/**
|
* HTTP POST请求示例 - 支持HTTPS
|
*
|
* @param url 请求URL
|
* @param params 请求参数
|
* @return 响应结果
|
*/
|
public String httpPostExample(String url, String params) {
|
if (httpClient == null) {
|
httpClient = createHttpsClient();
|
}
|
HttpPost httpPost = new HttpPost(url);
|
try {
|
StringEntity entity = new StringEntity(params, "UTF-8");
|
httpPost.setEntity(entity);
|
httpPost.setHeader("Content-type", "application/json;charset=utf-8");
|
httpPost.setHeader("Accept", "application/json");
|
return EntityUtils.toString(httpClient.execute(httpPost).getEntity());
|
} catch (Exception e) {
|
log.error("HTTP POST请求失败: {}", e.getMessage(), e);
|
throw new CoolException("HTTP POST请求失败: " + e.getMessage());
|
}
|
}
|
|
/**
|
* 使用RestTemplate的HTTPS POST请求示例
|
*
|
* @param url 请求URL
|
* @param params 请求参数
|
* @return 响应结果
|
*/
|
public String httpsPostWithRestTemplate(String url, String params) {
|
try {
|
log.info("HTTPS POST请求: {}, 请求参数: {}", url, params);
|
|
HttpHeaders headers = new HttpHeaders();
|
headers.add("Content-Type", "application/json;charset=utf-8");
|
headers.add("Accept", "application/json");
|
|
HttpEntity<String> httpEntity = new HttpEntity<>(params, headers);
|
|
// 使用项目中已有的SSL工具类创建忽略SSL证书验证的RestTemplate
|
RestTemplate sslRestTemplate = SslUtils.createIgnoreSSLRestTemplate();
|
|
// 设置错误处理器,不抛出异常,而是返回响应体
|
sslRestTemplate.setErrorHandler(new org.springframework.web.client.DefaultResponseErrorHandler() {
|
@Override
|
public boolean hasError(ClientHttpResponse response) throws IOException {
|
// 不管状态码如何,都不视为错误
|
return false;
|
}
|
});
|
|
ResponseEntity<String> exchange = sslRestTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
|
log.info("HTTPS POST请求响应结果: {}", exchange);
|
|
if (Objects.isNull(exchange.getBody())) {
|
throw new CoolException("请求失败!!");
|
}
|
|
return exchange.getBody();
|
} catch (Exception e) {
|
log.error("HTTPS POST请求失败: {}", e.getMessage(), e);
|
throw new CoolException("HTTPS POST请求失败: " + e.getMessage());
|
}
|
}
|
|
/**
|
* 创建支持HTTPS的HttpClient
|
*
|
* @return CloseableHttpClient实例
|
*/
|
private CloseableHttpClient createHttpsClient() {
|
try {
|
// 创建信任所有证书的TrustManager
|
TrustManager[] trustAllCerts = new TrustManager[] {
|
new X509TrustManager() {
|
public X509Certificate[] getAcceptedIssuers() { return null; }
|
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
|
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
|
}
|
};
|
|
// 初始化SSLContext
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
|
// 创建SSL连接管理器
|
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
|
sslContext,
|
(hostname, session) -> true // 允许所有主机名
|
);
|
|
// 创建HttpClientBuilder并设置SSL配置
|
RequestConfig config = RequestConfig.custom()
|
.setConnectTimeout(30000) // 连接超时时间
|
.setSocketTimeout(60000) // 读取超时时间
|
.build();
|
|
return HttpClients.custom()
|
.setSSLSocketFactory(sslsf)
|
.setDefaultRequestConfig(config)
|
.build();
|
} catch (Exception e) {
|
log.error("创建HTTPS客户端失败: {}", e.getMessage(), e);
|
return HttpClients.createDefault(); // 回退到默认客户端
|
}
|
}
|
|
// /**
|
// * 示例:如何使用HTTPS POST方法
|
// *
|
// * @param url 目标URL
|
// * @param jsonData JSON数据
|
// * @return 响应结果
|
// */
|
// public String exampleUsage(String url, String jsonData) {
|
// log.info("开始调用HTTPS POST请求示例");
|
//
|
// try {
|
// // 方法1: 使用Apache HttpClient
|
// String result1 = httpPostExample(url, jsonData);
|
// log.info("使用HttpClient的POST请求结果: {}", result1);
|
//
|
// // 方法2: 使用RestTemplate
|
// String result2 = httpsPostWithRestTemplate(url, jsonData);
|
// log.info("使用RestTemplate的POST请求结果: {}", result2);
|
//
|
// // 根据实际需要选择返回结果
|
// return result1;
|
// } catch (Exception e) {
|
// log.error("HTTPS POST请求示例执行失败: {}", e.getMessage(), e);
|
// throw e;
|
// }
|
// }
|
|
}
|