refactor(uapbd): 优化物料 PLM 下载功能

- 重构了单个和多个物料文件下载的逻辑
-增加了异常处理和错误反馈机制
This commit is contained in:
mzr 2025-08-13 19:31:48 +08:00
parent fe004487e2
commit 803e7c9205
1 changed files with 143 additions and 78 deletions

View File

@ -7,10 +7,12 @@ 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.ml.NCLangRes4VoTransl;
import nc.vo.pub.BusinessException;
import nccloud.baseapp.core.log.NCCForUAPLogger;
import nccloud.baseapp.core.log.NCCForPrintLogger;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.io.WebFile;
import nccloud.framework.core.io.WebFileDisposition;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import org.apache.http.client.config.CookieSpecs;
@ -20,13 +22,10 @@ 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 org.owasp.esapi.ESAPI;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -58,17 +57,31 @@ public class MaterialPlmDownloadAction implements ICommonAction {
WebFile files = null;
try {
Map<String, String[]> params_1 = request.readParameters();
String[] materialCodeArr = params_1.get("materialCode"); // 获取所有 pk
String[] materialCodeArr = params_1.get("materialCode"); // 获取所有物料编码
if (materialCodeArr == null || materialCodeArr.length == 0) {
ExceptionUtils.wrapBusinessException("物料编码不能为空");
}
NCCForUAPLogger.debug("MaterialPlmDownloadAction-pk = " + Arrays.toString(materialCodeArr));
// NCCForUAPLogger.debug("MaterialPlmDownloadAction-pk = " + Arrays.toString(materialCodeArr));
// String materialCode = "101092250323,101092250321,101092250322";
// String[] materialCodeArr = materialCode.split(",", -1);
files = this.getPlmFiles(materialCodeArr);
} catch (Exception e) {
logger.error("MaterialPlmDownloadAction-exp:" + e.getMessage());
ExceptionUtils.wrapException(e);
} catch (Exception ex) {
logger.error("MaterialPlmDownloadAction-exp:" + ex.getMessage());
// 将异常转换为WebFile的形式返回以便前端展示报错
NCCForPrintLogger.error(ex);
Throwable e = org.apache.commons.lang3.exception.ExceptionUtils.getRootCause(ex);
String mess = ESAPI.encoder().encodeForHTML(NCLangRes4VoTransl.getNCLangRes().getStrByID("1501003_0", "01501003-0121")) + ESAPI.encoder().encodeForHTML(e.getMessage());
if (e.getMessage() == null || "".equals(e.getMessage())) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
mess = ESAPI.encoder().encodeForHTML(NCLangRes4VoTransl.getNCLangRes().getStrByID("1501003_0", "01501003-0122")) + ESAPI.encoder().encodeForHTML(sw.toString());
mess = "<span style= \"color:red \">" + mess + "</span>";
}
InputStream in = new ByteArrayInputStream(mess.getBytes());
WebFile errorFile = new WebFile("print_error.html", in);
errorFile.setDisposition(WebFileDisposition.Inline);
files = errorFile;
}
return files;
}
@ -88,55 +101,116 @@ public class MaterialPlmDownloadAction implements ICommonAction {
token = getToken();
if (materialCodeArr.length == 1) {
String materialCode = materialCodeArr[0];
JSONObject plmFileJson = this.getPlmFile(materialCode);
String materialId = getMaterialId(materialCode);
if (StringUtils.isEmpty(materialId)) {
throw new BusinessException("物料编码:" + materialCode + ",获取PLM物料id失败,请检查PLM是否存在对应的物料");
}
String fileRes = this.getFileId(materialId);
JSONObject fileJson = JSONObject.parseObject(fileRes);
String list = fileJson.getString("list");
JSONArray jsonArray = JSONObject.parseArray(list);
if (jsonArray == null || jsonArray.isEmpty()) {
throw new BusinessException("物料编码:" + materialCode + ",获取PLM物料的文件信息失败");
}
JSONObject plmFileJson = jsonArray.getJSONObject(0);
String objId = plmFileJson.getString("objId");
if (objId == null || objId.isEmpty()) {
throw new BusinessException("物料编码:" + materialCode + ",获取PLM物料的文件信息失败");
}
String fname = plmFileJson.getString("fname");
byte[] fileBytes = this.doDownloadPlmFile(objId);
if (fileBytes.length == 0) {
throw new BusinessException("未查询到PLM的文件");
throw new BusinessException("物料编码:" + materialCode + ",未查询到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 (int i = 0; i < materialCodeArr.length; i++) {
String materialCode = materialCodeArr[i];
JSONObject plmFileJson = this.getPlmFile(materialCode);
String objId = plmFileJson.getString("objId");
// String fname = plmFileJson.getString("fname"); // 二维图档.pdf
String name = plmFileJson.getString("name");
String suffix = plmFileJson.getString("suffix");
byte[] fileBytes = this.doDownloadPlmFile(objId);
if (fileBytes.length == 0) {
continue;
}
String fname = name + "_" + materialCode + "_" + i + "." + suffix;
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);
file = processMultipleFiles(materialCodeArr);
}
return file;
}
public JSONObject getPlmFile(String materialCode) throws Exception {
/**
* 处理多个文件并打包
*
* @param materialCodeArr 物料编码数组
* @return 打包后的zip文件WebFile对象
* @throws Exception 异常
*/
private WebFile processMultipleFiles(String[] materialCodeArr) throws Exception {
// 在内存中的 ZIP 输出流
ByteArrayOutputStream zipOut = new ByteArrayOutputStream();
ZipOutputStream zipStream = new ZipOutputStream(zipOut);
int successCount = 0; // 成功处理的文件数
try {
for (int i = 0; i < materialCodeArr.length; i++) {
String materialCode = materialCodeArr[i];
try {
boolean success = processSingleMaterialToZip(materialCode, i, zipStream);
if (success) {
successCount++;
}
} catch (BusinessException e) {
logger.error("处理物料编码 " + materialCode + " 时出现异常: " + e.getMessage());
// 继续处理下一个
}
}
zipStream.finish();
} finally {
zipStream.close();
}
// 如果没有任何文件成功处理
if (successCount == 0) {
throw new BusinessException("没有有效的文件可以打包");
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String zipName = "图纸文档打包_" + sdf.format(new Date());
// 创建 WebFile 对象用于 ZIP 文件
InputStream ins = new ByteArrayInputStream(zipOut.toByteArray());
return new WebFile(zipName + ".zip", ins);
}
/**
* 将单个物料文件添加到ZIP流中
*
* @param materialCode 物料编码
* @param index 索引
* @param zipStream ZIP输出流
* @return boolean 是否成功处理
* @throws Exception 异常
*/
private boolean processSingleMaterialToZip(String materialCode, int index, ZipOutputStream zipStream) throws Exception {
String materialId = getMaterialId(materialCode);
return getFileId(materialId);
if (StringUtils.isEmpty(materialId)) {
return false;
}
String fileRes = this.getFileId(materialId);
JSONObject fileJson = JSONObject.parseObject(fileRes);
String list = fileJson.getString("list");
JSONArray jsonArray = JSONObject.parseArray(list);
if (jsonArray == null || jsonArray.isEmpty()) {
return false;
}
JSONObject plmFileJson = jsonArray.getJSONObject(0);
String objId = plmFileJson.getString("objId");
if (objId == null || objId.isEmpty()) {
return false;
}
String name = plmFileJson.getString("name");
String suffix = plmFileJson.getString("suffix");
byte[] fileBytes = this.doDownloadPlmFile(objId);
if (fileBytes.length == 0) {
return false;
}
String fname = name + "_" + materialCode + "_" + index + "." + suffix;
zipStream.putNextEntry(new ZipEntry(fname));
zipStream.write(fileBytes);
zipStream.closeEntry();
return true;
}
@ -148,7 +222,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
tokenMap.put("uname", plmUser);
tokenMap.put("f", "true");
String tokenStr = doGet(plmBaseUrl + tokenUrl, tokenMap);
logger.error("GetPlmFileUtil-getToken-tokenStr = " + tokenStr);
// logger.error("GetPlmFileUtil-getToken-tokenStr = " + tokenStr);
JSONObject jsonObject = JSONObject.parseObject(tokenStr);
String token = jsonObject.getString("errmsg");
if (token == null || token.isEmpty()) {
@ -175,12 +249,12 @@ public class MaterialPlmDownloadAction implements ICommonAction {
String list = jsonObject.getString("list");
JSONArray jsonArray = JSONObject.parseArray(list);
if (jsonArray == null || jsonArray.isEmpty()) {
throw new BusinessException("获取PLM物料id失败");
return "";
}
JSONObject listJson = jsonArray.getJSONObject(0);
String objId = listJson.getString("objId");
if (objId == null || objId.isEmpty()) {
throw new BusinessException("获取PLM物料id失败");
return "";
}
return objId;
}
@ -188,7 +262,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
/**
* 根据零部件ID获取文件ID
*/
private JSONObject getFileId(String materialId) throws IOException, BusinessException {
private String getFileId(String materialId) throws IOException, BusinessException {
String fileUrl = plmBaseUrl + materialFileIdUrl;
fileUrl = fileUrl.replace("{rid}", token);
// 对象表名 MPART零部件
@ -201,18 +275,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
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;
return result;
}
/**
@ -259,17 +322,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
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;
String url = buildUrlWithParams(requestUrl, paramMap);
HttpGet get = new HttpGet(url);
String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity()));
get.releaseConnection();
@ -294,8 +347,23 @@ public class MaterialPlmDownloadAction implements ICommonAction {
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
.setDefaultRequestConfig(globalConfig).build();
String url = buildUrlWithParams(requestUrl, paramMap);
HttpGet get = new HttpGet(url);
byte[] responseString = httpClient.execute(get, response -> EntityUtils.toByteArray(response.getEntity()));
get.releaseConnection();
return responseString;
}
/**
* 构建带参数的URL
*
* @param baseUrl 基础URL
* @param paramMap 参数Map
* @return 完整URL
*/
private String buildUrlWithParams(String baseUrl, Map<String, String> paramMap) {
StringBuilder param = new StringBuilder("?");
if (paramMap != null) {
if (paramMap != null && !paramMap.isEmpty()) {
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
param.append(entry.getKey());
param.append("=");
@ -304,10 +372,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
}
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;
return baseUrl + param;
}
}