Merge remote-tracking branch 'origin/main'

This commit is contained in:
lihao 2025-08-11 18:26:46 +08:00
commit 994bfbb60b
8 changed files with 778 additions and 62 deletions

View File

@ -0,0 +1,431 @@
package nccloud.wmssync.ml.m45;
import nc.bs.businessevent.IBusinessEvent;
import nc.bs.businessevent.IBusinessListener;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.ic.general.businessevent.ICGeneralCommonEvent;
import nc.bs.logging.Log;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.stordoc.StordocVO;
import nc.vo.bd.supplier.SupplierVO;
import nc.vo.ic.m45.entity.PurchaseInBodyVO;
import nc.vo.ic.m45.entity.PurchaseInHeadVO;
import nc.vo.ic.m45.entity.PurchaseInVO;
import nc.vo.org.StockOrgVO;
import nc.vo.pmpub.project.ProjectHeadVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDateTime;
import nccloud.api.uapbd.wms.utils.IWmsSyncUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 采购入库下发WMS
*/
public class WmsSyncPurchaseInListener implements IBusinessListener {
private static final String WAREHOUSE_PREFIX = "CK";
private static final String WAREHOUSE_SUFFIX = "001";
public static final IWmsSyncUtils WMS_SYNC_UTILS = NCLocator.getInstance().lookup(IWmsSyncUtils.class);
public static final BaseDAO dao = new BaseDAO();
private static final Log log = Log.getInstance("wmslog");
@Override
public void doAction(IBusinessEvent iBusinessEvent) throws BusinessException {
// 先检查是否是BDCommonEvent类型
if (iBusinessEvent instanceof ICGeneralCommonEvent event) {
PurchaseInVO[] purchaseInVOs = (PurchaseInVO[]) event.getOldObjs();
if (purchaseInVOs != null) {
log.info("采购入库单下发WMS开始");
for (PurchaseInVO purchaseInVO : purchaseInVOs) {
try {
sendToWMS(purchaseInVO);
} catch (BusinessException e) {
throw new BusinessException("采购入库单下发WMS失败:" + e.getMessage(), e);
}
}
}
}
}
private void sendToWMS(PurchaseInVO purchaseInVO) throws BusinessException {
String pkOrg = purchaseInVO.getHead().getPk_org();
String orgCode = WMS_SYNC_UTILS.transferCodeByPk(StockOrgVO.getDefaultTableName(), StockOrgVO.CODE, StockOrgVO.PK_STOCKORG, pkOrg);
if (WMS_SYNC_UTILS.checkIfIncludeOrg(orgCode)) {
log.info("采购入库单下发WMS开始组织code" + orgCode);
// 构造WMS请求数据
Map<String, Object> requestData = buildWMSRequestData(purchaseInVO, orgCode);
// 调用WMS接口
WMS_SYNC_UTILS.sendToExternalSystem("putASN", requestData);
log.info("采购入库单下发WMS完成单据号" + purchaseInVO.getHead().getVbillcode());
} else {
log.info("采购入库单下发: 当前组织" + orgCode + "不是指定组织不同步WMS");
}
}
/**
* 构造WMS putASN接口请求数据
*
* @param purchaseInVO 采购入库单VO - ERP: PurchaseInVO
* @param orgCode 组织编码
* @return WMS请求数据
* @throws BusinessException
*/
private Map<String, Object> buildWMSRequestData(PurchaseInVO purchaseInVO, String orgCode) throws BusinessException {
Map<String, Object> requestData = new HashMap<>();
Map<String, Object> data = new HashMap<>();
PurchaseInHeadVO head = purchaseInVO.getHead();
PurchaseInBodyVO[] bodies = purchaseInVO.getBodys();
// 构造headlist
Map<String, Object> headlist = buildHeadList(head, bodies, orgCode);
// 构造details
List<Map<String, Object>> detailsList = new ArrayList<>();
if (bodies != null) {
for (PurchaseInBodyVO body : bodies) {
Map<String, Object> detail = buildDetailItem(body, head);
detailsList.add(detail);
}
}
headlist.put("details", detailsList);
data.put("header", List.of(headlist));
requestData.put("data", data);
return requestData;
}
/**
* 构造WMS表头数据
*
* @param head 采购入库单表头VO - ERP: PurchaseInHeadVO
* @param bodies 采购入库单表体VO数组 - ERP: PurchaseInBodyVO[]
* @param orgCode 组织编码
* @return WMS表头数据
* @throws BusinessException
*/
private Map<String, Object> buildHeadList(PurchaseInHeadVO head, PurchaseInBodyVO[] bodies, String orgCode) throws BusinessException {
Map<String, Object> headlist = new HashMap<>();
// warehouseId - 所属仓库 - ERP: cwarehouseid -> WMS: warehouseId
headlist.put("warehouseId", WAREHOUSE_PREFIX + orgCode + WAREHOUSE_SUFFIX);
// customerId - 货主ID - ERP: 默认固定值 -> WMS: customerId
headlist.put("customerId", "TKJT");
// asnType - 订单类型 - ERP: 根据业务类型判断 -> WMS: asnType
headlist.put("asnType", "CGRK"); // 采购入库订单
// docNo - ERP单据号 - ERP: vbillcode -> WMS: docNo
headlist.put("docNo", head.getVbillcode());
// asnReferenceA - SRM单号 - ERP: 暂无对应字段 -> WMS: asnReferenceA
// headlist.put("asnReferenceA", "");
// asnReferenceB - ASN参考信息B - ERP: 暂无对应字段 -> WMS: asnReferenceB
// headlist.put("asnReferenceB", "");
// asnReferenceC - ASN参考信息C - ERP: 暂无对应字段 -> WMS: asnReferenceC
// headlist.put("asnReferenceC", "");
// asnReferenceD - ASN参考信息D - ERP: 暂无对应字段 -> WMS: asnReferenceD
// headlist.put("asnReferenceD", "");
// asnCreationTime - ASN创建时间 - ERP: creationtime -> WMS: asnCreationTime
UFDateTime creationTime = head.getCreationtime();
if (creationTime != null) {
headlist.put("asnCreationTime", creationTime.toString());
}
// expectedArriveTime1 - 预期到货时间段从 - ERP: 暂无对应字段 -> WMS: expectedArriveTime1
// headlist.put("expectedArriveTime1", "");
// expectedArriveTime2 - 预期到货时间段到 - ERP: 暂无对应字段 -> WMS: expectedArriveTime2
// headlist.put("expectedArriveTime2", "");
// supplierId - 供应商ID - ERP: cvendorid -> WMS: supplierId
String supplierCode = WMS_SYNC_UTILS.transferCodeByPk(SupplierVO.getDefaultTableName(),
SupplierVO.CODE, SupplierVO.PK_SUPPLIER, head.getCvendorid());
headlist.put("supplierId", supplierCode);
// supplierName - 供应商名称 - ERP: 通过供应商ID查询名称 -> WMS: supplierName
String supplierName = WMS_SYNC_UTILS.transferCodeByPk(SupplierVO.getDefaultTableName(),
SupplierVO.NAME, SupplierVO.PK_SUPPLIER, head.getCvendorid());
headlist.put("supplierName", supplierName);
// supplierAddress1 - 供应商地址 - ERP: 通过供应商ID查询地址 -> WMS: supplierAddress1
String supplierAddress = WMS_SYNC_UTILS.transferCodeByPk(SupplierVO.getDefaultTableName(), SupplierVO.CORPADDRESS, SupplierVO.PK_SUPPLIER, head.getCvendorid());
headlist.put("supplierAddress1", supplierAddress != null ? supplierAddress : "");
// supplierAddress2~4 - 供应商地址2~4 - ERP: 暂无对应字段 -> WMS: supplierAddress2~4
// headlist.put("supplierAddress2", "");
// headlist.put("supplierAddress3", "");
// headlist.put("supplierAddress4", "");
// 供应商国家省份等信息 - ERP: 暂无对应字段 -> WMS: supplierCountry等
// headlist.put("supplierCountry", "");
// headlist.put("supplierProvince", "");
// headlist.put("supplierCity", "");
// headlist.put("supplierDistrict", "");
// headlist.put("supplierStreet", "");
// supplierContact - 供应商联系人 - ERP: 暂无对应字段 -> WMS: supplierContact
// String supplierContact = WMS_SYNC_UTILS.transferFieldByPkAllowNull(SupplierVO.getDefaultTableName(),
// SupplierVO.LINKMAN, SupplierVO.PK_SUPPLIER, head.getCvendorid());
// headlist.put("supplierContact", supplierContact != null ? supplierContact : "");
// supplierFax - 供应商传真 - ERP: 暂无对应字段 -> WMS: supplierFax
// headlist.put("supplierFax", "");
// supplierMail - 供应商电子邮件 - ERP: 暂无对应字段 -> WMS: supplierMail
// headlist.put("supplierMail", "");
// supplierTel1 - 供应商移动电话 - ERP: 通过供应商ID查询电话 -> WMS: supplierTel1
String supplierTel = WMS_SYNC_UTILS.transferFieldByPkAllowNull(SupplierVO.getDefaultTableName(),
SupplierVO.TEL1, SupplierVO.PK_SUPPLIER, head.getCvendorid());
headlist.put("supplierTel1", supplierTel != null ? supplierTel : "");
// supplierTel2 - 供应商固定电话 - ERP: 暂无对应字段 -> WMS: supplierTel2
// headlist.put("supplierTel2", "");
// supplierZip - 供应商邮政编码 - ERP: 暂无对应字段 -> WMS: supplierZip
// headlist.put("supplierZip", "");
// carrierId - 承运人ID - ERP: 暂无对应字段 -> WMS: carrierId
// headlist.put("carrierId", "");
// carrierName - 承运人名称 - ERP: 暂无对应字段 -> WMS: carrierName
// headlist.put("carrierName", "");
// issuePartyId - 下单方ID - ERP: 暂无对应字段 -> WMS: issuePartyId
// headlist.put("issuePartyId", "");
// issuePartyName - 下单方名称 - ERP: 暂无对应字段 -> WMS: issuePartyName
// headlist.put("issuePartyName", "");
// countryOfDestination - 目的国 - ERP: crececountryid -> WMS: countryOfDestination
// headlist.put("countryOfDestination", "");
// countryOfOrigin - 原产国 - ERP: csendcountryid -> WMS: countryOfOrigin
// headlist.put("countryOfOrigin", "");
// followUp - 业务担当 - ERP: cbizid -> WMS: followUp
// headlist.put("followUp", "");
// hedi01 - EDI相关信息01 - ERP: 自定义字段 -> WMS: hedi01
// headlist.put("hedi01", "");
// hedi02 - 是否为负数 - 根据expectedQty决定 -> WMS: hedi02
// 先计算所有表体的expectedQty总和来判断正负
boolean hasNegativeQty = false;
if (bodies != null) {
for (PurchaseInBodyVO body : bodies) {
if (body.getNshouldnum() != null && body.getNshouldnum().doubleValue() < 0) {
hasNegativeQty = true;
break;
}
}
}
String isNegative = hasNegativeQty ? "Y" : "N";
headlist.put("hedi02", isNegative);
// 表头自定义项使用
// 获取来源/源头单据信息从表体第一个记录中获取
String sourceBillHid = "";
String firstBillHid = "";
String sourceTranstype = "";
String firstTranstype = "";
if (bodies != null && bodies.length > 0) {
PurchaseInBodyVO firstBody = bodies[0];
sourceBillHid = firstBody.getCsourcebillhid() != null ? firstBody.getCsourcebillhid() : "";
firstBillHid = firstBody.getCfirstbillhid() != null ? firstBody.getCfirstbillhid() : "";
sourceTranstype = firstBody.getCsourcetranstype() != null ? firstBody.getCsourcetranstype() : "";
firstTranstype = firstBody.getCfirsttranstype() != null ? firstBody.getCfirsttranstype() : "";
}
// hedi03 - 来源单据表头主键 - ERP: csourcebillhid -> WMS: hedi03
headlist.put("hedi03", sourceBillHid);
// hedi04 - 源头单据表头主键 - ERP: cfirstbillhid -> WMS: hedi04
headlist.put("hedi04", firstBillHid);
// hedi05 - 来源单据交易类型 - ERP: csourcetranstype -> WMS: hedi05
headlist.put("hedi05", sourceTranstype);
// hedi06 - 源头单据交易类型 - ERP: cfirsttranstype -> WMS: hedi06
headlist.put("hedi06", firstTranstype);
// hedi07 - 当前单据表头主键 - ERP: cgeneralhid -> WMS: hedi07
headlist.put("hedi07", head.getCgeneralhid());
// hedi08~10 - EDI相关信息08~10 - ERP: 自定义字段 -> WMS: hedi08~10
// headlist.put("hedi08", "");
headlist.put("hedi09", 0);
headlist.put("hedi10", 0);
// 装卸货地信息 - ERP: 暂无对应字段 -> WMS: placeOf系列
// headlist.put("placeOfDischarge", "");
// headlist.put("placeOfLoading", "");
// headlist.put("placeOfDelivery", "");
// priority - 优先级 - ERP: 暂无对应字段 -> WMS: priority
// headlist.put("priority", "");
// userDefine1~6 - 用户自定义1~6 - ERP: 自定义字段 -> WMS: userDefine1~6
// headlist.put("userDefine1", "");
// headlist.put("userDefine2", "");
// headlist.put("userDefine3", "");
// headlist.put("userDefine4", "");
// headlist.put("userDefine5", "");
// headlist.put("userDefine6", "");
// notes - 备注 - ERP: vnote -> WMS: notes
headlist.put("notes", head.getVnote() != null ? head.getVnote() : "");
// createSource - 创建来源 - ERP: 固定值 -> WMS: createSource
headlist.put("createSource", "ERP");
// crossdockFlag - 越库标记 - ERP: 暂无对应字段 -> WMS: crossdockFlag
// headlist.put("crossdockFlag", "");
return headlist;
}
/**
* 构造WMS表体明细数据
*
* @param body 采购入库单表体VO - ERP: PurchaseInBodyVO
* @param head 采购入库单表头VO - ERP: PurchaseInHeadVO
* @return WMS表体明细数据
* @throws BusinessException
*/
private Map<String, Object> buildDetailItem(PurchaseInBodyVO body, PurchaseInHeadVO head) throws BusinessException {
Map<String, Object> detail = new HashMap<>();
// lineNo - ERP行号 - ERP: crowno -> WMS: lineNo
detail.put("lineNo", body.getCrowno());
// sku - 产品编码 - ERP: cmaterialvid -> WMS: sku
String materialCode = WMS_SYNC_UTILS.transferCodeByPk(MaterialVO.getDefaultTableName(),
MaterialVO.CODE, MaterialVO.PK_MATERIAL, body.getCmaterialvid());
detail.put("sku", materialCode);
// expectedQty - 应收数量 - ERP: nshouldnum -> WMS: expectedQty (确保为正数)
double expectedQty = body.getNshouldnum() != null ? body.getNshouldnum().doubleValue() : 0;
detail.put("expectedQty", Math.abs(expectedQty)); // 取绝对值确保为正数
// totalPrice - 总价 - ERP: 暂无直接对应字段 -> WMS: totalPrice
detail.put("totalPrice", 0);
// packUom - 单位 - ERP: castunitid -> WMS: packUom (仅可选择EA/IP/CS/PL)
// String unitCode = WMS_SYNC_UTILS.transferCodeByPk("bd_measdoc",
// "code", "pk_measdoc", body.getCastunitid());
// detail.put("packUom", convertToWMSUnit(unitCode));
detail.put("packUom", "EA"); // 默认EA
// lotAtt01 - 生产日期 - ERP: dproducedate -> WMS: lotAtt01
detail.put("lotAtt01", body.getDproducedate() != null ? body.getDproducedate().toString() : "");
// lotAtt02 - 失效日期 - ERP: dvalidate -> WMS: lotAtt02
detail.put("lotAtt02", body.getDvalidate() != null ? body.getDvalidate().toString() : "");
// lotAtt03 - 入库日期 - ERP: dbizdate -> WMS: lotAtt03
detail.put("lotAtt03", body.getDbizdate() != null ? body.getDbizdate().toString() : "");
// lotAtt04 - ERP批次号 - ERP: vbatchcode -> WMS: lotAtt04
detail.put("lotAtt04", body.getVbatchcode() != null ? body.getVbatchcode() : "");
// lotAtt05 - ERP仓库 - ERP: cbodywarehouseid -> WMS: lotAtt05
String bodyWarehouseCode = WMS_SYNC_UTILS.transferCodeByPk(StordocVO.getDefaultTableName(),
StordocVO.CODE, StordocVO.PK_STORDOC, body.getCbodywarehouseid());
detail.put("lotAtt05", bodyWarehouseCode);
// lotAtt06 - 供应商 - ERP: cvendorid -> WMS: lotAtt06
String bodySupplierCode = WMS_SYNC_UTILS.transferCodeByPk(SupplierVO.getDefaultTableName(),
SupplierVO.CODE, SupplierVO.PK_SUPPLIER, body.getCvendorid());
detail.put("lotAtt06", bodySupplierCode);
// lotAtt07 - 生产厂商 - ERP: -> WMS: lotAtt07
detail.put("lotAtt07", ""); // 采购入库无生产厂商
// lotAtt08 - 质量状态 - ERP: 默认合格 -> WMS: lotAtt08
detail.put("lotAtt08", "HG");
// lotAtt09 - 项目号 - ERP: cprojectid -> WMS: lotAtt09
String projectCode = WMS_SYNC_UTILS.transferCodeByPk(ProjectHeadVO.getDefaultTableName(),
ProjectHeadVO.PROJECT_CODE, ProjectHeadVO.PK_PROJECT, body.getCprojectid());
detail.put("lotAtt09", projectCode != null ? projectCode : "");
// lotAtt10~24 - 批次属性10~24 - ERP: 暂无对应字段 -> WMS: lotAtt10~24
// for (int i = 10; i <= 24; i++) {
// detail.put("lotAtt" + String.format("%02d", i), "");
// }
// dedi04 - 来源单据表体行主键 - ERP: csourcebillbid -> WMS: dedi04
detail.put("dedi04", body.getCsourcebillbid() != null ? body.getCsourcebillbid() : "");
// dedi05 - 源头单据表体主键 - ERP: cfirstbillbid -> WMS: dedi05
detail.put("dedi05", body.getCfirstbillbid() != null ? body.getCfirstbillbid() : "");
// dedi06 - 当前单据表体行主键 - ERP: cgeneralbid -> WMS: dedi06
detail.put("dedi06", body.getCgeneralbid() != null ? body.getCgeneralbid() : "");
// dedi07 - 源头单据号 - ERP: vfirstbillcode -> WMS: dedi07
// detail.put("dedi07", body.getVfirstbillcode() != null ? body.getVfirstbillcode() : "");
// dedi08 - 来源单据行号 - ERP: vsourcerowno -> WMS: dedi08
// detail.put("dedi08", body.getVsourcerowno() != null ? body.getVsourcerowno() : "");
// dedi09 - 避免使用 只能存数字
// detail.put("dedi09", "");
// dedi10 - 避免使用 只能存数字
// detail.put("dedi10", "");
// dedi11 - 当前单据表体主键 - ERP: cgeneralbid -> WMS: dedi11
// detail.put("dedi11", ""); // 字段移至userDefine6
// dedi12 - 当前单据号 - ERP: vbillcode -> WMS: dedi12
// detail.put("dedi12", head.getVbillcode() != null ? head.getVbillcode() : "");
// dedi13 - 当前单据行号 - ERP: crowno -> WMS: dedi13
// detail.put("dedi13", body.getCrowno() != null ? body.getCrowno() : "");
// dedi14~16 - 保留为扩展字段
// detail.put("dedi14", "");
// detail.put("dedi15", "");
// detail.put("dedi16", "");
// userDefine1~6 - 用户自定义字段 - 停用
// userDefine1 -
// detail.put("userDefine1", "");
// userDefine2 -
// detail.put("userDefine2", "");
// userDefine3 -
// detail.put("userDefine3", "");
// userDefine4 - 来源单据表体行主键
// detail.put("userDefine4", body.getCsourcebillbid() != null ? body.getCsourcebillbid() : "");
// userDefine5 - 源头单据表体行主键
// detail.put("userDefine5", body.getCfirstbillbid() != null ? body.getCfirstbillbid() : "");
// userDefine6 - 当前单据表体行主键
// detail.put("userDefine6", body.getCgeneralbid() != null ? body.getCgeneralbid() : "");
// notes - 备注 - ERP: vnotebody -> WMS: notes
detail.put("notes", body.getVnotebody() != null ? body.getVnotebody() : "");
return detail;
}
}

View File

@ -0,0 +1,39 @@
package nccloud.wmssync.ml.m4a;
import nc.bs.businessevent.IBusinessEvent;
import nc.bs.businessevent.IBusinessListener;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.ic.general.businessevent.ICGeneralCommonEvent;
import nc.bs.logging.Log;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.stordoc.StordocVO;
import nc.vo.bd.supplier.SupplierVO;
import nc.vo.ic.m4a.entity.GeneralInBodyVO;
import nc.vo.ic.m4a.entity.GeneralInHeadVO;
import nc.vo.ic.m4a.entity.GeneralInVO;
import nc.vo.org.StockOrgVO;
import nc.vo.pmpub.project.ProjectHeadVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDateTime;
import nccloud.api.uapbd.wms.utils.IWmsSyncUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* ÆäËûÈë¿âµ¥Ï·¢WMS
*/
public class WmsSyncGeneralInListener implements IBusinessListener {
@Override
public void doAction(IBusinessEvent iBusinessEvent) throws BusinessException {
}
}

View File

@ -3,6 +3,7 @@ package nc.bs.mmpac.pmo.pac0002.bp;
import java.util.ArrayList;
import java.util.List;
import nc.bs.mmpac.pmo.pac0002.bp.rule.AfterApproveSyncEpicMesRule;
import nc.bs.mmpac.pmo.pac0002.bp.rule.AfterApprovingSynchronizeRuleRZ;
import nc.bs.mmpac.pmo.pac0002.pluginpoint.PMOPluginPoint;
import nc.bs.mmpac.pmo.pac0002.rule.PMOATPUpdateRule;
@ -251,6 +252,8 @@ public class PMOAdjustBP {
//变更推送生产订单至锐制MES
IRule<PMOAggVO> pushRZRule = new AfterApprovingSynchronizeRuleRZ(Boolean.FALSE);
processer.addAfterFinalRule(pushRZRule);
// 变更后推送流程生产订单到艾普MES
processer.addAfterRule(new AfterApproveSyncEpicMesRule());
}
// 挪退料建议

View File

@ -1,5 +1,6 @@
package nccloud.api.impl.so.m30;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import nc.bd.itf.tools.BFPubTools;
@ -1345,7 +1346,9 @@ public class APISaleOrderMaitainImpl implements IAPISaleOrderMaitain {
updateJson.put("contractOrdersList", l_map_f);
// BIPºÏͬÏúÊÛ©µ¥¸üРÖ÷±íid
updateJson.put("id", soMap.get("vdef9"));
bodyJson.put("HTXSDD", updateJson);
JSONArray array = new JSONArray();
array.add(updateJson);
bodyJson.put("HTXSDD", array);
NCCForUAPLogger.debug("updateBipFlagSo-bodyJson:" + bodyJson);
Logger.error("updateBipFlagSo-bodyJson:" + bodyJson);
String resultString = doSendHttp(updateUrl, "POST", tokenParam, "", headers, bodyJson.toJSONString());

View File

@ -1,11 +1,37 @@
package nccloud.web.uapbd.material.action;
import nc.bs.uapbd.util.GetPlmFileUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import nc.bs.dao.DAOException;
import nc.bs.logging.Log;
import nc.bs.trade.business.HYSuperDMO;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.cmp.util.StringUtils;
import nc.vo.pub.BusinessException;
import nccloud.baseapp.core.log.NCCForUAPLogger;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.io.WebFile;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* »ñÈ¡ÎïÁÏPLMÎļþ
@ -14,20 +40,270 @@ import java.util.Map;
* @date 2025/8/4
*/
public class MaterialPlmDownloadAction implements ICommonAction {
private static final String LOG_INFO_NAME = "dldzlog";
private static final Log logger = Log.getInstance(LOG_INFO_NAME);
private String plmBaseUrl = "";
private String plmUser = "";
private String token = "";
private static final String tokenUrl = "/sipmweb/api/oauth";
// 根据物料编码获取零部件ID
private String materialIdUrl = "/sipmweb/api/{rid}/search/{t}";
// 根据零部件ID获取二维图档ID及信息
private String materialFileIdUrl = "/sipmweb/api/{rid}/relation/{t}/{id}/data";
// 下载文件
private String downlownUrl = "/sipmweb/web/download";
@Override
public Object doAction(IRequest request) {
WebFile files = null;
try {
Map<String, String[]> params_1 = request.readParameters();
String[] pks = params_1.get("materialCode"); // »ñÈ¡ËùÓÐ pk
String materialCode = "101092250323,101092250323";
String[] materialCodeArr = materialCode.split(",", -1);
GetPlmFileUtil fileUtil = new GetPlmFileUtil();
files = fileUtil.getPlmFiles(materialCodeArr);
String[] materialCodeArr = params_1.get("materialCode"); // 获取所有 pk
if (materialCodeArr == null || materialCodeArr.length == 0) {
ExceptionUtils.wrapBusinessException("物料编码不能为空");
}
NCCForUAPLogger.debug("MaterialPlmDownloadAction-pk = " + Arrays.toString(materialCodeArr));
// String materialCode = "101092250323,101092250321,101092250322";
// String[] materialCodeArr = materialCode.split(",", -1);
files = this.getPlmFiles(materialCodeArr);
} catch (Exception e) {
throw new RuntimeException(e);
logger.error("MaterialPlmDownloadAction-exp:" + e.getMessage());
ExceptionUtils.wrapException(e);
}
return files;
}
public WebFile getPlmFiles(String[] materialCodeArr) throws Exception {
WebFile file = null;
if (materialCodeArr == null || materialCodeArr.length == 0) {
return file;
}
// 获取PLM的参数
Map<String, String> configParams = getConfigParams("Dldz-config");
if (configParams == null || configParams.isEmpty()) {
throw new BusinessException("未配置PLM参数");
}
plmBaseUrl = configParams.get("plmBaseUrl");
plmUser = configParams.get("plmUser");
token = getToken();
if (materialCodeArr.length == 1) {
String materialCode = materialCodeArr[0];
JSONObject plmFileJson = this.getPlmFile(materialCode);
String objId = plmFileJson.getString("objId");
String fname = plmFileJson.getString("fname");
byte[] fileBytes = this.doDownloadPlmFile(objId);
if (fileBytes.length == 0) {
throw new BusinessException("未查询到PLM的文件");
}
InputStream ins = new ByteArrayInputStream(fileBytes);
file = new WebFile(fname, ins);
} else {
// 多个物料合并成zip文件输出文件流
// 创建内存中的 ZIP 输出流
ByteArrayOutputStream zipOut = new ByteArrayOutputStream();
ZipOutputStream zipStream = new ZipOutputStream(zipOut);
try {
for (String materialCode : materialCodeArr) {
JSONObject plmFileJson = this.getPlmFile(materialCode);
String objId = plmFileJson.getString("objId");
String fname = plmFileJson.getString("fname");
byte[] fileBytes = this.doDownloadPlmFile(objId);
if (fileBytes.length == 0) {
continue;
}
zipStream.putNextEntry(new ZipEntry(fname));
zipStream.write(fileBytes);
zipStream.closeEntry();
}
zipStream.finish();
} finally {
zipStream.close();
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String zipName = "物料图纸下载_" + sdf.format(new Date());
// 构造 WebFile 返回 ZIP 文件
InputStream ins = new ByteArrayInputStream(zipOut.toByteArray());
file = new WebFile(zipName + ".zip", ins);
}
return file;
}
public JSONObject getPlmFile(String materialCode) throws Exception {
String materialId = getMaterialId(materialCode);
return getFileId(materialId);
}
/**
* 获取token
*/
private String getToken() throws IOException, BusinessException {
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("uname", plmUser);
tokenMap.put("f", "true");
String tokenStr = doGet(plmBaseUrl + tokenUrl, tokenMap);
logger.error("GetPlmFileUtil-getToken-tokenStr = " + tokenStr);
JSONObject jsonObject = JSONObject.parseObject(tokenStr);
String token = jsonObject.getString("errmsg");
if (token == null || token.isEmpty()) {
throw new BusinessException("PLM鉴权失败");
}
return token;
}
/**
* 根据物料编码获取零部件ID
*/
private String getMaterialId(String materialCode) throws IOException, BusinessException {
String fileUrl = plmBaseUrl + materialIdUrl;
fileUrl = fileUrl.replace("{rid}", token);
// 对象表名 MPART零部件
fileUrl = fileUrl.replace("{t}", "MPART");
Map<String, String> map = new HashMap<>();
map.put("key", materialCode);// 搜索关键字
map.put("start", "0");// 偏移量
map.put("size", "10");// 数量
String result = doGet(fileUrl, map);
logger.error("GetPlmFileUtil-getMaterialId-result = " + result);
JSONObject jsonObject = JSONObject.parseObject(result);
String list = jsonObject.getString("list");
JSONArray jsonArray = JSONObject.parseArray(list);
if (jsonArray == null || jsonArray.isEmpty()) {
throw new BusinessException("获取PLM物料id失败");
}
JSONObject listJson = jsonArray.getJSONObject(0);
String objId = listJson.getString("objId");
if (objId == null || objId.isEmpty()) {
throw new BusinessException("获取PLM物料id失败");
}
return objId;
}
/**
* 根据零部件ID获取文件ID
*/
private JSONObject getFileId(String materialId) throws IOException, BusinessException {
String fileUrl = plmBaseUrl + materialFileIdUrl;
fileUrl = fileUrl.replace("{rid}", token);
// 对象表名 MPART零部件
fileUrl = fileUrl.replace("{t}", "MPART");
// 对象id
fileUrl = fileUrl.replace("{id}", materialId);
Map<String, String> map = new HashMap<>();
map.put("re", "MPART_SIPM1");// 关系ID 二维图档MPART_SIPM1
map.put("start", "0");// 偏移量
map.put("item", "SIPM1");// 关联对象表名
String result = doGet(fileUrl, map);
logger.error("GetPlmFileUtil-getFileId-result = " + result);
JSONObject jsonObject = JSONObject.parseObject(result);
String list = jsonObject.getString("list");
JSONArray jsonArray = JSONObject.parseArray(list);
if (jsonArray == null || jsonArray.isEmpty()) {
throw new BusinessException("获取PLM物料的文件信息失败");
}
JSONObject listJson = jsonArray.getJSONObject(0);
String objId = listJson.getString("objId");
if (objId == null || objId.isEmpty()) {
throw new BusinessException("获取PLM物料的文件信息失败");
}
return listJson;
}
/**
* 调用PLM的下载文件接口
*/
private byte[] doDownloadPlmFile(String fileId) throws IOException {
String fileUrl = plmBaseUrl + downlownUrl;
Map<String, String> map = new HashMap<>();
map.put("rid", token);
map.put("id", fileId);// 对象id
map.put("t", "SIPM1");// 对象表名
map.put("type", "D");// 文件类别BD,DD是文件本身的文件BD是PDF图
return getFileFromPlm(fileUrl, map);
}
public Map<String, String> getConfigParams(String code) {
Map<String, String> map = new HashMap<>();
String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='[code]' and dr=0 ) and dr=0";
strWhere = strWhere.replace("[code]", code);
try {
DefdocVO[] defdocVOs = (DefdocVO[]) new HYSuperDMO().queryByWhereClause(DefdocVO.class, strWhere);
if (defdocVOs != null) {
for (DefdocVO defdocVO : defdocVOs) {
String value = StringUtils.isEmpty(defdocVO.getMemo()) ? defdocVO.getName() : defdocVO.getMemo();
map.put(defdocVO.getCode().trim(), value);
}
}
} catch (DAOException e) {
logger.error("Failed to get config parameters for code: " + code, e);
}
return map;
}
private String doGet(String requestUrl, Map<String, String> paramMap) throws IOException {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(5000);
cm.setDefaultMaxPerRoute(500);
RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(50000) // 连接池获取连接超时
.setConnectTimeout(50000) // 连接建立超时
.setSocketTimeout(200000) // 等待响应超时
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
.setDefaultRequestConfig(globalConfig).build();
StringBuilder param = new StringBuilder("?");
if (paramMap != null) {
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
param.append(entry.getKey());
param.append("=");
param.append(entry.getValue());
param.append("&");
}
param.deleteCharAt(param.length() - 1);
}
String url = requestUrl + param;
HttpGet get = new HttpGet(url);
String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity()));
get.releaseConnection();
return responseString;
}
/**
* 调用第三方文件接口并接收文件流
*
* @param requestUrl 文件接口URL
* @return 文件流
*/
private byte[] getFileFromPlm(String requestUrl, Map<String, String> paramMap) throws IOException {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(5000);
cm.setDefaultMaxPerRoute(500);
RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(50000) // 连接池获取连接超时
.setConnectTimeout(50000) // 连接建立超时
.setSocketTimeout(200000) // 等待响应超时
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
.setDefaultRequestConfig(globalConfig).build();
StringBuilder param = new StringBuilder("?");
if (paramMap != null) {
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
param.append(entry.getKey());
param.append("=");
param.append(entry.getValue());
param.append("&");
}
param.deleteCharAt(param.length() - 1);
}
String url = requestUrl + param;
HttpGet get = new HttpGet(url);
byte[] responseString = httpClient.execute(get, response -> EntityUtils.toByteArray(response.getEntity()));
get.releaseConnection();
return responseString;
}
}

View File

@ -1,6 +1,7 @@
package nc.bs.uapbd.bip.workplugin;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.yonyou.cloud.utils.StringUtils;
@ -198,8 +199,9 @@ public class ErpSaleOrderToBIPBackgroupWorkPlugin implements IBackgroundWorkPlug
js_apct.put("contractOrdersList", l_map_f);
js_apct.put("id", hid);
js_apct_detail.put("HTXSDD", js_apct);
JSONArray array = new JSONArray();
array.add(js_apct);
js_apct_detail.put("HTXSDD", array);
logger.error("ErpSaleOrderToBIPBackgroupWorkPlugin-param = " + js_apct_detail.toJSONString());
String resultString = doSendHttp(custUpdateUrl, "POST", tokenParam, "", headers, js_apct_detail.toJSONString());
logger.error("ErpSaleOrderToBIPBackgroupWorkPlugin-res = " + resultString);

View File

@ -17,7 +17,6 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -88,9 +87,11 @@ public class GetPlmFileUtil {
String objId = plmFileJson.getString("objId");
String fname = plmFileJson.getString("fname");
byte[] pdfBytes = this.doDownloadPlmFile(objId);
InputStream ins = new ByteArrayInputStream(pdfBytes);
byte[] fileBytes = this.doDownloadPlmFile(objId);
if (fileBytes.length == 0) {
throw new BusinessException("δ²éѯµ½PLMµÄÎļþ");
}
InputStream ins = new ByteArrayInputStream(fileBytes);
file = new WebFile(fname, ins);
} else {
// 多个物料合并成zip文件输出文件流
@ -98,29 +99,17 @@ public class GetPlmFileUtil {
ByteArrayOutputStream zipOut = new ByteArrayOutputStream();
ZipOutputStream zipStream = new ZipOutputStream(zipOut);
try {
// int i=0;
for (String materialCode : materialCodeArr) {
JSONObject plmFileJson = this.getPlmFile(materialCode);
String objId = plmFileJson.getString("objId");
String fname = plmFileJson.getString("fname");
byte[] pdfBytes =this.doDownloadPlmFile(objId);
InputStream ins = new ByteArrayInputStream(pdfBytes);
// InputStream ins = this.doDownloadPlmFile(objId);
try {
byte[] bytes = parseFileStream(ins);
zipStream.putNextEntry(new ZipEntry(fname+""));
// i++;
zipStream.write(bytes);
byte[] fileBytes = this.doDownloadPlmFile(objId);
if (fileBytes.length == 0) {
continue;
}
zipStream.putNextEntry(new ZipEntry(fname));
zipStream.write(fileBytes);
zipStream.closeEntry();
} finally {
if (ins != null) {
try {
ins.close();
} catch (IOException e) {
logger.error("Failed to close input stream: " + e.getMessage());
}
}
}
}
zipStream.finish();
} finally {
@ -289,34 +278,6 @@ public class GetPlmFileUtil {
byte[] responseString = httpClient.execute(get, response -> EntityUtils.toByteArray(response.getEntity()));
get.releaseConnection();
return responseString;
// // 执行请求并返回文件流
// return httpClient.execute(httpGet, response -> {
// // 检查响应状态
// int statusCode = response.getStatusLine().getStatusCode();
// if (statusCode >= 200 && statusCode < 300) {
// return response.getEntity().getContent();
// } else {
// throw new IOException("HTTP request failed with status code: " + statusCode);
// }
// });
}
/**
* 解析文件流
*
* @param inputStream 文件流
* @return 解析结果
*/
private byte[] parseFileStream(InputStream inputStream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
byte[] byteArray = buffer.toByteArray();
buffer.close();
return byteArray;
}
}

View File

@ -39,9 +39,10 @@ public class MyHelper {
sqlBuilder.append(pkField, pk);
Object o = dao.executeQuery(sqlBuilder.toString(), new ColumnProcessor());
if (o == null) {
throw new BusinessException("未查询到编码信息sql【" + sqlBuilder + "");
Logger.info("未查询到编码信息sql【" + sqlBuilder + "");
// throw new BusinessException("未查询到编码信息sql【" + sqlBuilder + "");
}
return o.toString();
return String.valueOf(o);
}
/**