feat(material):优化物料PLM文件下载功能
- 增加物料编码去重逻辑,避免重复下载- 为每个物料生成独立压缩包,再统一打包成ZIP文件 - 新增物料名称查询功能,用于构建更清晰的文件名 - 优化文件命名规则,包含物料编码和名称信息 - 增强PLM接口鉴权错误处理机制
This commit is contained in:
parent
8503c03d6a
commit
20520fe986
|
|
@ -2,9 +2,11 @@ package nccloud.web.uapbd.material.action;
|
|||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import nc.bs.dao.BaseDAO;
|
||||
import nc.bs.dao.DAOException;
|
||||
import nc.bs.logging.Log;
|
||||
import nc.bs.trade.business.HYSuperDMO;
|
||||
import nc.jdbc.framework.processor.ColumnProcessor;
|
||||
import nc.vo.bd.defdoc.DefdocVO;
|
||||
import nc.vo.cmp.util.StringUtils;
|
||||
import nc.vo.ml.NCLangRes4VoTransl;
|
||||
|
|
@ -26,9 +28,7 @@ import org.owasp.esapi.ESAPI;
|
|||
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
|
|
@ -39,6 +39,7 @@ import java.util.zip.ZipOutputStream;
|
|||
* @date 2025/8/4
|
||||
*/
|
||||
public class MaterialPlmDownloadAction implements ICommonAction {
|
||||
private static final BaseDAO dao = new BaseDAO();
|
||||
private static final String LOG_INFO_NAME = "dldzlog";
|
||||
private static final Log logger = Log.getInstance(LOG_INFO_NAME);
|
||||
private String plmBaseUrl = "";
|
||||
|
|
@ -52,6 +53,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
|||
private String materialFileIdUrl = "/sipmweb/api/{rid}/relation/{t}/{id}/data";
|
||||
// 下载文件
|
||||
private String downlownUrl = "/sipmweb/web/download";
|
||||
private Map<String, String> materialMap = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Object doAction(IRequest request) {
|
||||
|
|
@ -97,54 +99,119 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
|||
plmUser = configParams.get("plmUser");
|
||||
passwd = configParams.getOrDefault("passwd", "");
|
||||
token = getToken();
|
||||
|
||||
// 无论单个还是多个物料,均打包为ZIP(原单个物料返回单文件,无法同时返回两类文件)
|
||||
return processMultipleFiles(materialCodeArr);
|
||||
// 去重物料编码
|
||||
Set<String> materialCodeSet = new HashSet<>(Arrays.asList(materialCodeArr));
|
||||
getMaterialMapInfo(materialCodeSet);
|
||||
// 无论单个还是多个物料,均打包为ZIP
|
||||
return processMultipleFiles(materialCodeSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理多个文件并打包(同时包含SIPM1和SIPM2)
|
||||
* 获取物料的名称
|
||||
*
|
||||
* @param materialCodeArr 物料编码数组
|
||||
* @return 打包后的zip文件WebFile对象
|
||||
* @param materialCodeSet
|
||||
* @return
|
||||
*/
|
||||
private void getMaterialMapInfo(Set<String> materialCodeSet) throws DAOException {
|
||||
for (String code : materialCodeSet) {
|
||||
String sql = "select name from bd_material where code = '" + code + "'";
|
||||
String materialName = (String) dao.executeQuery(sql, new ColumnProcessor("name"));
|
||||
materialMap.put(code, materialName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理多个物料文件,为每个物料创建单独的压缩包,然后将所有压缩包打包成一个大压缩包
|
||||
*
|
||||
* @param materialCodeSet 物料编码数组
|
||||
* @return 包含所有物料压缩包的WebFile对象
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
private WebFile processMultipleFiles(String[] materialCodeArr) throws Exception {
|
||||
// 在内存中的 ZIP 输出流
|
||||
ByteArrayOutputStream zipOut = new ByteArrayOutputStream();
|
||||
ZipOutputStream zipStream = new ZipOutputStream(zipOut);
|
||||
int successCount = 0; // 成功处理的文件数
|
||||
private WebFile processMultipleFiles(Set<String> materialCodeSet) throws Exception {
|
||||
// 创建总的ZIP输出流
|
||||
ByteArrayOutputStream mainZipOut = new ByteArrayOutputStream();
|
||||
ZipOutputStream mainZipStream = new ZipOutputStream(mainZipOut);
|
||||
|
||||
int successCount = 0; // 成功处理的物料数
|
||||
|
||||
try {
|
||||
for (int i = 0; i < materialCodeArr.length; i++) {
|
||||
String materialCode = materialCodeArr[i];
|
||||
for (String materialCode : materialCodeSet) {
|
||||
try {
|
||||
// 同时处理当前物料的SIPM1和SIPM2
|
||||
boolean success1 = processSingleMaterialToZip(materialCode, i, "SIPM1", zipStream);
|
||||
boolean success2 = processSingleMaterialToZip(materialCode, i, "SIPM2", zipStream);
|
||||
if (success1) successCount++;
|
||||
if (success2) successCount++;
|
||||
// 为每个物料创建独立的压缩包
|
||||
WebFile singleMaterialZip = createSingleMaterialZip(materialCode);
|
||||
if (singleMaterialZip != null) {
|
||||
// 将单个物料的压缩包添加到总压缩包中
|
||||
mainZipStream.putNextEntry(new ZipEntry(singleMaterialZip.getFileName()));
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
InputStream inputStream = singleMaterialZip.getInputStream();
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
mainZipStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
inputStream.close();
|
||||
mainZipStream.closeEntry();
|
||||
successCount++;
|
||||
}
|
||||
} catch (BusinessException e) {
|
||||
logger.error("处理物料编码 " + materialCode + " 时出现异常: " + e.getMessage(), e);
|
||||
// 继续处理下一个
|
||||
// 继续处理下一个物料
|
||||
}
|
||||
}
|
||||
zipStream.finish();
|
||||
|
||||
mainZipStream.finish();
|
||||
} finally {
|
||||
zipStream.close();
|
||||
mainZipStream.close();
|
||||
}
|
||||
|
||||
// 如果没有任何文件成功处理
|
||||
// 如果没有任何物料成功处理
|
||||
if (successCount == 0) {
|
||||
throw new BusinessException("没有有效的文件可以打包");
|
||||
throw new BusinessException("没有有效的文件可下载");
|
||||
}
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||
String zipName = "图纸文档打包_" + sdf.format(new Date());
|
||||
// 创建 WebFile 对象用于 ZIP 文件
|
||||
InputStream ins = new ByteArrayInputStream(zipOut.toByteArray());
|
||||
String zipName = "物料文档打包_" + sdf.format(new Date());
|
||||
|
||||
// 创建返回的WebFile对象
|
||||
InputStream ins = new ByteArrayInputStream(mainZipOut.toByteArray());
|
||||
return new WebFile(zipName + ".zip", ins);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为单个物料创建压缩包
|
||||
*
|
||||
* @param materialCode 物料编码
|
||||
* @return 单个物料的压缩包WebFile对象
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
private WebFile createSingleMaterialZip(String materialCode) throws Exception {
|
||||
// 创建单个物料的ZIP输出流
|
||||
ByteArrayOutputStream singleZipOut = new ByteArrayOutputStream();
|
||||
ZipOutputStream singleZipStream = new ZipOutputStream(singleZipOut);
|
||||
|
||||
boolean hasFiles = false;
|
||||
try {
|
||||
// 处理SIPM1类型的文件(图纸)
|
||||
boolean success1 = processSingleMaterialToZip(materialCode, 0, "SIPM1", singleZipStream);
|
||||
// 处理SIPM2类型的文件(文件)
|
||||
boolean success2 = processSingleMaterialToZip(materialCode, 0, "SIPM2", singleZipStream);
|
||||
|
||||
hasFiles = success1 || success2;
|
||||
|
||||
singleZipStream.finish();
|
||||
} finally {
|
||||
singleZipStream.close();
|
||||
}
|
||||
// 如果该物料没有任何文件,则返回null
|
||||
if (!hasFiles) {
|
||||
return null;
|
||||
}
|
||||
// 创建单个物料的压缩包文件名
|
||||
String fileName = materialCode + "_" + materialMap.get(materialCode) + ".zip";
|
||||
// 创建WebFile对象
|
||||
InputStream ins = new ByteArrayInputStream(singleZipOut.toByteArray());
|
||||
return new WebFile(fileName, ins);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将单个物料文件添加到ZIP流中
|
||||
*
|
||||
|
|
@ -187,7 +254,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
|||
}
|
||||
|
||||
// 生成带类型标识的文件名,避免重复
|
||||
String fname = name + "_" + materialCode + "_" + getTypeName(fileType) + "_" + (index + i) + "." + suffix;
|
||||
String fname = materialCode + "_" + materialMap.get(materialCode) + "_" + name + "_" + (index + i) + "." + suffix;
|
||||
zipStream.putNextEntry(new ZipEntry(fname));
|
||||
zipStream.write(fileBytes);
|
||||
zipStream.closeEntry();
|
||||
|
|
@ -201,13 +268,15 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
|||
private String getToken() throws IOException, BusinessException {
|
||||
Map<String, String> tokenMap = new HashMap<>();
|
||||
tokenMap.put("uname", plmUser);
|
||||
if (!"passwd".equals(passwd) && !"null".equals(passwd) && !"~".equals(passwd)) {
|
||||
tokenMap.put("passwd", passwd);
|
||||
}
|
||||
tokenMap.put("passwd", passwd);
|
||||
tokenMap.put("f", "true");
|
||||
String tokenStr = doGet(plmBaseUrl + tokenUrl, tokenMap);
|
||||
JSONObject jsonObject = JSONObject.parseObject(tokenStr);
|
||||
String token = jsonObject.getString("errmsg");
|
||||
if (!"0".equals(jsonObject.get("errcode") + "")) {
|
||||
// 抛出错误信息
|
||||
throw new BusinessException(token);
|
||||
}
|
||||
if (token == null || token.isEmpty()) {
|
||||
throw new BusinessException("PLM鉴权失败");
|
||||
}
|
||||
|
|
@ -300,8 +369,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
|||
.setSocketTimeout(200000) // 等待响应超时
|
||||
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
|
||||
|
||||
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
|
||||
.setDefaultRequestConfig(globalConfig).build();
|
||||
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(globalConfig).build();
|
||||
String url = buildUrlWithParams(requestUrl, paramMap);
|
||||
HttpGet get = new HttpGet(url);
|
||||
String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity()));
|
||||
|
|
@ -325,8 +393,7 @@ public class MaterialPlmDownloadAction implements ICommonAction {
|
|||
.setSocketTimeout(200000) // 等待响应超时
|
||||
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
|
||||
|
||||
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
|
||||
.setDefaultRequestConfig(globalConfig).build();
|
||||
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()));
|
||||
|
|
|
|||
Loading…
Reference in New Issue