refactor(uapbd): 优化物料 PLM 下载功能
- 重构了单个和多个物料文件下载的逻辑 -增加了异常处理和错误反馈机制
This commit is contained in:
parent
fe004487e2
commit
803e7c9205
|
@ -7,10 +7,12 @@ import nc.bs.logging.Log;
|
||||||
import nc.bs.trade.business.HYSuperDMO;
|
import nc.bs.trade.business.HYSuperDMO;
|
||||||
import nc.vo.bd.defdoc.DefdocVO;
|
import nc.vo.bd.defdoc.DefdocVO;
|
||||||
import nc.vo.cmp.util.StringUtils;
|
import nc.vo.cmp.util.StringUtils;
|
||||||
|
import nc.vo.ml.NCLangRes4VoTransl;
|
||||||
import nc.vo.pub.BusinessException;
|
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.exception.ExceptionUtils;
|
||||||
import nccloud.framework.core.io.WebFile;
|
import nccloud.framework.core.io.WebFile;
|
||||||
|
import nccloud.framework.core.io.WebFileDisposition;
|
||||||
import nccloud.framework.web.action.itf.ICommonAction;
|
import nccloud.framework.web.action.itf.ICommonAction;
|
||||||
import nccloud.framework.web.container.IRequest;
|
import nccloud.framework.web.container.IRequest;
|
||||||
import org.apache.http.client.config.CookieSpecs;
|
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.client.HttpClients;
|
||||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.owasp.esapi.ESAPI;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -58,17 +57,31 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
WebFile files = null;
|
WebFile files = null;
|
||||||
try {
|
try {
|
||||||
Map<String, String[]> params_1 = request.readParameters();
|
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) {
|
if (materialCodeArr == null || materialCodeArr.length == 0) {
|
||||||
ExceptionUtils.wrapBusinessException("物料编码不能为空");
|
ExceptionUtils.wrapBusinessException("物料编码不能为空");
|
||||||
}
|
}
|
||||||
NCCForUAPLogger.debug("MaterialPlmDownloadAction-pk = " + Arrays.toString(materialCodeArr));
|
// NCCForUAPLogger.debug("MaterialPlmDownloadAction-pk = " + Arrays.toString(materialCodeArr));
|
||||||
// String materialCode = "101092250323,101092250321,101092250322";
|
// String materialCode = "101092250323,101092250321,101092250322";
|
||||||
// String[] materialCodeArr = materialCode.split(",", -1);
|
// String[] materialCodeArr = materialCode.split(",", -1);
|
||||||
files = this.getPlmFiles(materialCodeArr);
|
files = this.getPlmFiles(materialCodeArr);
|
||||||
} catch (Exception e) {
|
} catch (Exception ex) {
|
||||||
logger.error("MaterialPlmDownloadAction-exp:" + e.getMessage());
|
logger.error("MaterialPlmDownloadAction-exp:" + ex.getMessage());
|
||||||
ExceptionUtils.wrapException(e);
|
// 将异常转换为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;
|
return files;
|
||||||
}
|
}
|
||||||
|
@ -88,55 +101,116 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
token = getToken();
|
token = getToken();
|
||||||
if (materialCodeArr.length == 1) {
|
if (materialCodeArr.length == 1) {
|
||||||
String materialCode = materialCodeArr[0];
|
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");
|
String objId = plmFileJson.getString("objId");
|
||||||
|
if (objId == null || objId.isEmpty()) {
|
||||||
|
throw new BusinessException("物料编码:" + materialCode + ",获取PLM物料的文件信息失败");
|
||||||
|
}
|
||||||
String fname = plmFileJson.getString("fname");
|
String fname = plmFileJson.getString("fname");
|
||||||
|
|
||||||
byte[] fileBytes = this.doDownloadPlmFile(objId);
|
byte[] fileBytes = this.doDownloadPlmFile(objId);
|
||||||
if (fileBytes.length == 0) {
|
if (fileBytes.length == 0) {
|
||||||
throw new BusinessException("未查询到PLM的文件");
|
throw new BusinessException("物料编码:" + materialCode + ",未查询到PLM文件");
|
||||||
}
|
}
|
||||||
InputStream ins = new ByteArrayInputStream(fileBytes);
|
InputStream ins = new ByteArrayInputStream(fileBytes);
|
||||||
file = new WebFile(fname, ins);
|
file = new WebFile(fname, ins);
|
||||||
} else {
|
} else {
|
||||||
// 多个物料合并成zip文件输出文件流
|
file = processMultipleFiles(materialCodeArr);
|
||||||
// 创建内存中的 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
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);
|
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("uname", plmUser);
|
||||||
tokenMap.put("f", "true");
|
tokenMap.put("f", "true");
|
||||||
String tokenStr = doGet(plmBaseUrl + tokenUrl, tokenMap);
|
String tokenStr = doGet(plmBaseUrl + tokenUrl, tokenMap);
|
||||||
logger.error("GetPlmFileUtil-getToken-tokenStr = " + tokenStr);
|
// logger.error("GetPlmFileUtil-getToken-tokenStr = " + tokenStr);
|
||||||
JSONObject jsonObject = JSONObject.parseObject(tokenStr);
|
JSONObject jsonObject = JSONObject.parseObject(tokenStr);
|
||||||
String token = jsonObject.getString("errmsg");
|
String token = jsonObject.getString("errmsg");
|
||||||
if (token == null || token.isEmpty()) {
|
if (token == null || token.isEmpty()) {
|
||||||
|
@ -175,12 +249,12 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
String list = jsonObject.getString("list");
|
String list = jsonObject.getString("list");
|
||||||
JSONArray jsonArray = JSONObject.parseArray(list);
|
JSONArray jsonArray = JSONObject.parseArray(list);
|
||||||
if (jsonArray == null || jsonArray.isEmpty()) {
|
if (jsonArray == null || jsonArray.isEmpty()) {
|
||||||
throw new BusinessException("获取PLM物料id失败");
|
return "";
|
||||||
}
|
}
|
||||||
JSONObject listJson = jsonArray.getJSONObject(0);
|
JSONObject listJson = jsonArray.getJSONObject(0);
|
||||||
String objId = listJson.getString("objId");
|
String objId = listJson.getString("objId");
|
||||||
if (objId == null || objId.isEmpty()) {
|
if (objId == null || objId.isEmpty()) {
|
||||||
throw new BusinessException("获取PLM物料id失败");
|
return "";
|
||||||
}
|
}
|
||||||
return objId;
|
return objId;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +262,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
/**
|
/**
|
||||||
* 根据零部件ID获取文件ID
|
* 根据零部件ID获取文件ID
|
||||||
*/
|
*/
|
||||||
private JSONObject getFileId(String materialId) throws IOException, BusinessException {
|
private String getFileId(String materialId) throws IOException, BusinessException {
|
||||||
String fileUrl = plmBaseUrl + materialFileIdUrl;
|
String fileUrl = plmBaseUrl + materialFileIdUrl;
|
||||||
fileUrl = fileUrl.replace("{rid}", token);
|
fileUrl = fileUrl.replace("{rid}", token);
|
||||||
// 对象表名 MPART(零部件)
|
// 对象表名 MPART(零部件)
|
||||||
|
@ -201,18 +275,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
map.put("item", "SIPM1");// 关联对象表名
|
map.put("item", "SIPM1");// 关联对象表名
|
||||||
String result = doGet(fileUrl, map);
|
String result = doGet(fileUrl, map);
|
||||||
logger.error("GetPlmFileUtil-getFileId-result = " + result);
|
logger.error("GetPlmFileUtil-getFileId-result = " + result);
|
||||||
JSONObject jsonObject = JSONObject.parseObject(result);
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -259,17 +322,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
|
|
||||||
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
|
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
|
||||||
.setDefaultRequestConfig(globalConfig).build();
|
.setDefaultRequestConfig(globalConfig).build();
|
||||||
StringBuilder param = new StringBuilder("?");
|
String url = buildUrlWithParams(requestUrl, paramMap);
|
||||||
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);
|
HttpGet get = new HttpGet(url);
|
||||||
String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity()));
|
String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity()));
|
||||||
get.releaseConnection();
|
get.releaseConnection();
|
||||||
|
@ -294,8 +347,23 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
|
|
||||||
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
|
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
|
||||||
.setDefaultRequestConfig(globalConfig).build();
|
.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("?");
|
StringBuilder param = new StringBuilder("?");
|
||||||
if (paramMap != null) {
|
if (paramMap != null && !paramMap.isEmpty()) {
|
||||||
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
|
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
|
||||||
param.append(entry.getKey());
|
param.append(entry.getKey());
|
||||||
param.append("=");
|
param.append("=");
|
||||||
|
@ -304,10 +372,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
||||||
}
|
}
|
||||||
param.deleteCharAt(param.length() - 1);
|
param.deleteCharAt(param.length() - 1);
|
||||||
}
|
}
|
||||||
String url = requestUrl + param;
|
return baseUrl + param;
|
||||||
HttpGet get = new HttpGet(url);
|
|
||||||
byte[] responseString = httpClient.execute(get, response -> EntityUtils.toByteArray(response.getEntity()));
|
|
||||||
get.releaseConnection();
|
|
||||||
return responseString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue