电力电器流程生产订单与MES对接接口-张鑫-代码同步

This commit is contained in:
mzr 2025-10-24 09:14:34 +08:00
parent 585471ac75
commit 3c913ba2a2
6 changed files with 2262 additions and 0 deletions

View File

@ -0,0 +1,10 @@
<?xml version='1.0' encoding='gb2312'?>
<module name="mmpac">
<public>
<!-- 调用mes新增删除接口 -->
<component priority="0" singleton="true" remote="false" tx="NONE" supportAlias="true">
<interface>nccloud.api.mmpac.service.MesDataService</interface>
<implementation>nc.bs.mmpac.pmo.pac0002.Impl.MesDataServiceImpl</implementation>
</component>
</public>
</module>

View File

@ -0,0 +1,93 @@
package nc.bs.mmpac.pmo.pac0002.Impl;
import com.alibaba.fastjson.JSONObject;
import nc.bd.itf.util.MesApiSignatureUtil;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nccloud.api.mmpac.service.MesDataService;
import org.apache.commons.httpclient.HttpStatus;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
/**
* MES新增接口数据组装服务实现类
*/
public class MesDataServiceImpl implements MesDataService {
public static final String mes = "http://172.18.6.3:8282/SD_TKDLDQ_SD_TKDLDQ/Api/Public/Pushsoft.Data/Import";
// 单例HttpClient避免重复创建
private static final HttpClient httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
private static final int TIMEOUT = 60000; // 超时时间设置为60秒
@Override
public Map<String, String> assembleAndSaveProductionOrder(PMOAggVO[] pmoAggVOS, String UNIQUE_ID, List<String> jsonObjects) {
Map<String, String> map = new HashMap<>();
try {
for (String jsonObject : jsonObjects) {
JSONObject jsonObject2 = new JSONObject();
jsonObject2.put("data", jsonObject);
jsonObject2.put("uniqueId", UNIQUE_ID);
String header = MesApiSignatureUtil.buldeRequestHeader(jsonObject2);
String body = this.doPost(jsonObject, header, UNIQUE_ID);
JSONObject jsonObject1 = JSONObject.parseObject(body);
String mesDocEntry = jsonObject1.getJSONObject("Data").getJSONObject("Key").getString("DocEntry");
if (UNIQUE_ID.equals("ff3f024bc1")){
map.put(JSONObject.parseObject(jsonObject).get("Z_cmoid").toString(), mesDocEntry);
}
if (UNIQUE_ID.equals("ff3f024d12")){
// map.put("10070","10070");
map.put(mesDocEntry, mesDocEntry);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return map;
}
private String doPost(String jsonData, String header, String uniqueId) {
// 构造表单数据
try {
// 关键修复手动对表单参数进行URLEncoder编码确保与签名原始数据的对应关系
String encodedData = URLEncoder.encode(jsonData, StandardCharsets.UTF_8.name());
String encodedUniqueId = URLEncoder.encode(uniqueId, StandardCharsets.UTF_8.name());
// 构建正确的表单请求体application/x-www-form-urlencoded格式
String formBody = "data=" + encodedData + "&uniqueId=" + encodedUniqueId;
// 构造请求
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(mes))
.header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
.header("Accept", "application/json").header("X-PushApi-User", "ERP")
.header("X-PushApi-Digest", header).POST(HttpRequest.BodyPublishers.ofString(formBody.toString()))
.build();
// 执行请求
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != HttpStatus.SC_OK){
throw new RuntimeException(response.body());
}
return response.body();
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,81 @@
package nc.bs.mmpac.pmo.pac0002.bp.rule;
import com.alibaba.fastjson.JSONObject;
import nc.bs.framework.common.NCLocator;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.pubitf.bd.accessor.GeneralAccessorFactory;
import nc.pubitf.bd.accessor.IGeneralAccessor;
import nc.vo.bd.accessor.IBDData;
import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO;
import nc.vo.pub.BusinessException;
import nccloud.api.mmpac.service.MesDataService;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 修改的时候调用mes的修改接口
*/
public class UpdateAfterToMesRule implements IRule<PMOAggVO> {
@Override
public void process(PMOAggVO[] pmoAggVOS) {
MesDataService lookup = NCLocator.getInstance().lookup(MesDataService.class);
String UNIQUE_ID = "ff3f024d18";
List<String> jsonObjects = null;
try {
jsonObjects = this.buildParams(pmoAggVOS);
} catch (BusinessException e) {
throw new RuntimeException(e);
}
if (jsonObjects.size()>0){
Map<String, String> map = lookup.assembleAndSaveProductionOrder(pmoAggVOS, UNIQUE_ID, jsonObjects);
}
}
/**
* 组装参数
*/
private List<String> buildParams(PMOAggVO[] pmoAggVOS) throws BusinessException {
IGeneralAccessor accessor = GeneralAccessorFactory.getAccessor("2ee58f9b-781b-469f-b1d8-1816842515c3");
List<String> maps = new ArrayList<>();
for (PMOAggVO pmoAggVO : pmoAggVOS) {
PMOItemVO[] childrenVO = pmoAggVO.getChildrenVO();
for (PMOItemVO childrenVO1 : childrenVO) {
boolean b = this.checkOrg(pmoAggVO);
if (!b)continue;
if (childrenVO1.getVdef41() == null||childrenVO1.getVdef41().equals("")||childrenVO1.getVdef40().equals("")||childrenVO1.getVdef40()==null) continue;
JSONObject params = new JSONObject();
//增加表体备注
BigDecimal qty = childrenVO1.getNplanputnum() != null ?
childrenVO1.getNplanputnum().toBigDecimal() : BigDecimal.ZERO;
params.put("DocEntry", childrenVO1.getVdef41());
params.put("Qty", qty);
params.put("Remarks",childrenVO1.getVnote()==null?"":childrenVO1.getVnote());//备注
params.put("SchedStart", childrenVO1.getTplanstarttime()==null?"":childrenVO1.getTplanstarttime().toString());
params.put("SchedEnd", childrenVO1.getTplanendtime()==null?"":childrenVO1.getTplanendtime().toString());
IBDData docByPk = accessor.getDocByPk(childrenVO1.getCprojectid());
params.put("ProjectID", docByPk==null?"":docByPk.getCode());
maps.add( params.toJSONString());
}
}
return maps;
}
/**
* 校验组织是否是C023
*/
private boolean checkOrg(PMOAggVO pmoAggVO) {
IGeneralAccessor accessorOrg = GeneralAccessorFactory.getAccessor("985be8a4-3a36-4778-8afe-2d8ed3902659");
String pkOrg = pmoAggVO.getParentVO().getPk_org();
IBDData docByPk = accessorOrg.getDocByPk(pkOrg);
if (docByPk.getCode().equals("C023")) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,239 @@
package nc.bd.itf.util;
import com.alibaba.fastjson.JSONObject;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* MES系统API签名工具类
* 用于生成符合MES系统要求的请求摘要
*/
public class MesApiSignatureUtil {
private static final String Url = "http://192.168.110.62:8282/AIO8/Api//Public/";
private static final String AppID = "ERP";
private static final String AppVersion = "v250930";
private static final String AppSecret = "2e13b8dc412b42968abbe105360155af";
private static final String UserID = "ERP";
/**
* API请求参数键值对
*/
public static class ApiKeyValue {
private String key;
private String value;
public ApiKeyValue(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
/**
* 计算当前时间戳秒级
* @return 时间戳
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis() / 1000;
}
/**
* 对请求参数进行排序
* @param params 参数列表
* @return 排序后的参数列表
*/
public static List<ApiKeyValue> sortParams(List<ApiKeyValue> params) {
if (params == null || params.isEmpty()) {
return new ArrayList<>();
}
// 按参数名称进行升序排序
return params.stream()
.sorted(Comparator.comparing(ApiKeyValue::getKey))
.collect(Collectors.toList());
}
/**
* 合并参数为字符串
* @param sortedParams 排序后的参数列表
* @return 合并后的参数字符串
*/
public static String mergeParams(List<ApiKeyValue> sortedParams) {
if (sortedParams == null || sortedParams.isEmpty()) {
return "";
}
StringBuilder paramString = new StringBuilder();
for (ApiKeyValue kv : sortedParams) {
paramString.append(kv.getKey()).append(kv.getValue());
}
return paramString.toString();
}
/**
* 计算摘要
* @param paramString 合并后的参数字符串
* @param timeStamp 时间戳
* @return 计算后的的摘要
*/
public static String calcDigestDigest(String paramString, long timeStamp) {
try {
// 参数字符串 + 时间戳 + 密钥
String content = paramString + timeStamp + AppSecret;
// 创建MD5消息摘要
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 计算摘要
byte[] digestBytes = md5.digest(content.getBytes(StandardCharsets.UTF_8));
// 转为十六进制字符串
StringBuilder result = new StringBuilder();
for (byte b : digestBytes) {
result.append(String.format("%02x", b));
}
return result.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5算法不可用", e);
}
}
/**
* 生成完整的摘要请求头
* @param timeStamp 时间戳
* @param digest 摘要
* @return 请求头内容
*/
public static String generateDigestHeader(long timeStamp, String digest) {
return String.format("AppID=%s, AppVersion=%s, Timestamp=%d, Digest=%s",
AppID, AppVersion, timeStamp, digest);
}
/**
* 生成完整的摘要请求头自动计算时间戳
* @param params 请求参数
* @param secret 密钥
* @return 请求头内容
*/
public static String generateDigestHeader(List<ApiKeyValue> params, String secret) {
// 计算时间戳
long timeStamp = getCurrentTimestamp();
// 排序参数
List<ApiKeyValue> sortedParams = sortParams(params);
// 合并参数
String paramString = mergeParams(sortedParams);
// 计算摘要
String digest = calcDigestDigest(paramString, timeStamp);
// 生成请求头
return generateDigestHeader(timeStamp, digest);
}
/**
* 生成完整的摘要请求头自动计算时间戳
* @param paramMap 请求参数Map
* @param secret 密钥
* @return 请求头内容
*/
public static String generateDigestHeader(Map<String, String> paramMap, String secret) {
if (paramMap == null || paramMap.isEmpty()) {
return generateDigestHeader(new ArrayList<>(), secret);
}
List<ApiKeyValue> params = paramMap.entrySet().stream()
.map(entry -> new ApiKeyValue(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
return generateDigestHeader(params, secret);
}
public static String buldeRequestHeader(JSONObject paramsJson) {
// 创建测试参数
List<ApiKeyValue> params = new ArrayList<>();
for (String key : paramsJson.keySet()) {
params.add(new ApiKeyValue(key, paramsJson.getString(key)));
}
// 方法1分步处理
System.out.println("=== 方法1分步处理 ===");
long timeStamp = getCurrentTimestamp();
System.out.println("时间戳: " + timeStamp);
List<ApiKeyValue> sortedParams = sortParams(params);
System.out.println("排序后参数:");
sortedParams.forEach(kv -> System.out.println(kv.getKey() + "=" + kv.getValue()));
String paramString = mergeParams(sortedParams);
System.out.println("合并后参数: " + paramString);
String digest = calcDigestDigest(paramString, timeStamp);
System.out.println("计算的摘要: " + digest);
String header = generateDigestHeader(timeStamp, digest);
return header;
}
/**
* 主方法用于测试
*/
public static void main(String[] args) {
try {
/* 创建测试参数
List<ApiKeyValue> params = new ArrayList<>();
params.add(new ApiKeyValue("参数名3", "参数值3"));
params.add(new ApiKeyValue("参数名1", "参数值1"));
params.add(new ApiKeyValue("参数名2", "参数值2"));
// 方法1分步处理
System.out.println("=== 方法1分步处理 ===");
long timeStamp = getCurrentTimestamp();
System.out.println("时间戳: " + timeStamp);
List<ApiKeyValue> sortedParams = sortParams(params);
System.out.println("排序后参数:");
sortedParams.forEach(kv -> System.out.println(kv.getKey() + "=" + kv.getValue()));
String paramString = mergeParams(sortedParams);
System.out.println("合并后参数: " + paramString);
String digest = calcDigestDigest(paramString, timeStamp);
System.out.println("计算的摘要: " + digest);
String header = generateDigestHeader(timeStamp, digest);
System.out.println("请求头: " + header);*/
JSONObject paramsJson = new JSONObject();
paramsJson.put("code","0001");
paramsJson.put("name","张三");
String header = MesApiSignatureUtil.buldeRequestHeader(paramsJson);
System.out.println("请求头: " + header);
} catch (Exception e) {
e.printStackTrace();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
package nccloud.api.mmpac.service;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO;
import nc.vo.pub.BusinessException;
/**
* MES新增接口数据组装服务
*/
public interface MesDataService {
/**
* 组装并保存MES生产订单数据
* @param pmoAggVOS 生产订单数据
* @return 处理结果
* @throws BusinessException 业务异常
*/
Map<String, String> assembleAndSaveProductionOrder(PMOAggVO[] pmoAggVOS,String UNIQUE_ID,List<String> jsonObjects);
}