Merge remote-tracking branch 'origin/develop-hlq20260421mpm' into develop

This commit is contained in:
10001392 2026-05-20 16:24:36 +08:00
commit 849ac75f54
4 changed files with 203 additions and 25 deletions

View File

@ -1,6 +1,7 @@
package com.nflg.wms.admin.controller;
import com.nflg.wms.admin.service.MaterialControllerService;
import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.constant.UserType;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
@ -19,6 +20,7 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -31,6 +33,7 @@ import java.util.Set;
/**
* 图纸管理
*/
@Slf4j
@RestController
@RequestMapping("/material")
public class MaterialController extends BaseController {
@ -182,7 +185,28 @@ public class MaterialController extends BaseController {
*/
@PostMapping("/mpm/syncFromMpmBatch")
public ApiResult<Void> syncFromMpmBatch(/*@Valid */@RequestBody @NotEmpty List<MaterialAddQO> requests) {
materialControllerService.syncFromMpmBatch(requests);
return ApiResult.success();
StringBuilder errorMessages = new StringBuilder();
int successCount = 0;
int failCount = 0;
for (MaterialAddQO request : requests) {
try {
materialControllerService.syncFromMpm(request);
successCount++;
} catch (Exception e) {
failCount++;
String errorMsg = String.format("[%s] %s; ", request.getNo(), e.getMessage());
errorMessages.append(errorMsg);
log.error("同步图纸失败: {}, 错误: {}", request.getNo(), e.getMessage(), e);
}
}
if (failCount > 0) {
String resultMsg = String.format("批量同步完成,成功%d条失败%d条。失败详情: %s",
successCount, failCount, errorMessages.toString());
return ApiResult.error(STATE.BusinessError, resultMsg);
} else {
return ApiResult.success();
}
}
}

View File

@ -1,6 +1,7 @@
package com.nflg.wms.admin.controller;
import com.nflg.wms.admin.service.StructuralPackageControllerService;
import com.nflg.wms.common.constant.STATE;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.PackageMaterialDTO;
@ -13,6 +14,7 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -23,6 +25,7 @@ import java.util.List;
/**
* 钢构包管理
*/
@Slf4j
@RestController
@RequestMapping("/package")
public class StructuralPackageController extends BaseController {
@ -144,8 +147,13 @@ public class StructuralPackageController extends BaseController {
*/
@PostMapping("/mpm/syncFromMpm")
public ApiResult<Void> syncFromMpm(/*@Valid */@RequestBody PackageAddQO request) {
packageControllerService.syncFromMpm(request);
return ApiResult.success();
try {
packageControllerService.syncFromMpm(request);
return ApiResult.success();
} catch (Exception e) {
log.error("从MPM系统同步钢构包数据失败: {}, 错误: {}", request.getNo(), e.getMessage(), e);
return ApiResult.error(STATE.BusinessError, "同步失败: " + e.getMessage());
}
}
/**
@ -153,8 +161,29 @@ public class StructuralPackageController extends BaseController {
*/
@PostMapping("/mpm/syncFromMpmBatch")
public ApiResult<Void> syncFromMpmBatch(/*@Valid */@RequestBody @NotEmpty List<PackageAddQO> requests) {
packageControllerService.syncFromMpmBatch(requests);
return ApiResult.success();
StringBuilder errorMessages = new StringBuilder();
int successCount = 0;
int failCount = 0;
for (PackageAddQO request : requests) {
try {
packageControllerService.syncFromMpm(request);
successCount++;
} catch (Exception e) {
failCount++;
String errorMsg = String.format("[%s] %s; ", request.getNo(), e.getMessage());
errorMessages.append(errorMsg);
log.error("同步钢构包失败: {}, 错误: {}", request.getNo(), e.getMessage(), e);
}
}
if (failCount > 0) {
String resultMsg = String.format("批量同步完成,成功%d条失败%d条。失败详情: %s",
successCount, failCount, errorMessages.toString());
return ApiResult.error(STATE.BusinessError, resultMsg);
} else {
return ApiResult.success();
}
}
//
// /**

View File

@ -32,10 +32,16 @@ import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.ttzero.excel.entity.ListSheet;
import org.ttzero.excel.entity.Workbook;
@ -56,6 +62,7 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@ -81,6 +88,12 @@ public class MaterialControllerService {
@Resource
private IUserSupplierService userSupplierService;
@Resource
private RestTemplate restTemplate;
@Value("${mpm.download.url}")
private String mpmDownloadUrl;
public void add(@Valid MaterialAddQO request) {
WmsMaterial old = materialService.getCurrent(request.getNo());
VUtil.trueThrowBusinessError(Objects.nonNull(old) && !old.getComplete())
@ -415,33 +428,141 @@ public class MaterialControllerService {
}
/**
* 批量从MPM系统同步图纸数据
* 从MPM系统同步图纸数据单个
* 每次推送都是新版本直接新增
*/
@Transactional
public void syncFromMpmBatch(@Valid @NotEmpty List<MaterialAddQO> requests) {
log.info("开始批量从MPM系统同步图纸数据共{}条", requests.size());
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void syncFromMpm(@Valid MaterialAddQO request) {
log.info("开始从MPM系统同步图纸数据: {}", request.getNo());
for (MaterialAddQO request : requests) {
WmsMaterial wmsMaterial = Convert.convert(WmsMaterial.class, request);
wmsMaterial.setCreateBy("MPM_SYNC");
wmsMaterial.setCreateTime(LocalDateTime.now());
wmsMaterial.setFromMpm(true); // 标记为来自MPM
// 如果fileindex和filename都不为空则从MPM下载文件并上传到本系统
if (StrUtil.isNotBlank(request.getFileindex()) && StrUtil.isNotBlank(request.getFilename())) {
try {
log.info("开始从MPM系统同步图纸数据: {}", request.getNo());
WmsMaterial wmsMaterial = Convert.convert(WmsMaterial.class, request);
wmsMaterial.setCreateBy("MPM_SYNC");
wmsMaterial.setCreateTime(LocalDateTime.now());
wmsMaterial.setFromMpm(true); // 标记为来自MPM
materialService.add(wmsMaterial);
log.info("成功从MPM系统同步图纸数据: {}, 版本: {}", request.getNo(), wmsMaterial.getVersion());
String fileUrl = downloadAndUploadFileFromMpm(request.getFileindex(), request.getFilename());
if (StrUtil.isNotBlank(fileUrl)) {
wmsMaterial.setImage(fileUrl);
log.info("成功从MPM下载并上传文件: {}, 文件URL: {}", request.getNo(), fileUrl);
} else {
log.warn("从MPM下载文件失败但继续同步图纸数据: {}", request.getNo());
}
} catch (Exception e) {
log.error("同步图纸失败: {}, 错误: {}", request.getNo(), e.getMessage(), e);
// 继续处理下一条不中断整个批量同步
log.error("从MPM下载并上传文件失败: {}, 错误: {}", request.getNo(), e.getMessage(), e);
// 文件下载失败不影响主流程继续同步其他数据
}
}
log.info("批量从MPM系统同步图纸数据完成");
materialService.add(wmsMaterial);
log.info("成功从MPM系统同步图纸数据: {}, 版本: {}", request.getNo(), wmsMaterial.getVersion());
}
/**
* 从MPM系统下载文件并上传到本系统
*
* @param fileindex 文件索引
* @param filename 文件名
* @return 上传后的文件URL
*/
private String downloadAndUploadFileFromMpm(String fileindex, String filename) {
try {
// 构建MPM下载请求URL
String mpmRequestUrl = mpmDownloadUrl + "/" + filename + "," + fileindex;
log.info("请求MPM文件下载地址: {}", mpmRequestUrl);
// 发送GET请求获取文件下载地址
ResponseEntity<Map<String, Object>> response = restTemplate.exchange(
mpmRequestUrl,
HttpMethod.GET,
null,
new ParameterizedTypeReference<Map<String, Object>>() {}
);
Map<String, Object> responseBody = response.getBody();
if (responseBody != null && Boolean.TRUE.equals(responseBody.get("success"))) {
Map<String, String> data = (Map<String, String>) responseBody.get("data");
if (data != null && data.containsKey(filename)) {
String downloadUrl = data.get(filename);
log.info("获取到MPM文件下载地址: {}", downloadUrl);
// 下载文件内容
ResponseEntity<byte[]> fileResponse = restTemplate.exchange(
downloadUrl,
HttpMethod.GET,
null,
byte[].class
);
if (fileResponse.getStatusCode().is2xxSuccessful() && fileResponse.getBody() != null) {
byte[] fileContent = fileResponse.getBody();
// 生成文件路径
String filePath = buildFilePathForMpm(filename);
// 上传到本系统
String uploadUrl = fileUploadService.upload(
filePath,
new java.io.ByteArrayInputStream(fileContent),
getContentType(filename)
);
log.info("文件上传成功URL: {}", uploadUrl);
return uploadUrl;
} else {
log.error("从MPM下载文件失败状态码: {}", fileResponse.getStatusCode());
}
} else {
log.error("MPM响应中未找到文件下载地址: {}", filename);
}
} else {
log.error("MPM请求失败: {}", responseBody != null ? responseBody.get("message") : "未知错误");
}
} catch (Exception e) {
log.error("从MPM下载并上传文件异常: fileindex={}, filename={}, 错误: {}", fileindex, filename, e.getMessage(), e);
}
return null;
}
/**
* 根据文件名生成文件路径
*
* @param fileName 文件名
* @return 文件路径
*/
private String buildFilePathForMpm(String fileName) {
String fileType = "." + FilenameUtils.getExtension(fileName);
return StrUtil.format("admin/{}/{}/{}/{}{}",
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")),
"MPM_SYNC",
RandomUtil.randomString(4),
IdUtil.fastUUID(),
fileType);
}
/**
* 根据文件扩展名获取Content-Type
*
* @param fileName 文件名
* @return Content-Type
*/
private String getContentType(String fileName) {
String extension = FilenameUtils.getExtension(fileName).toLowerCase();
return switch (extension) {
case "pdf" -> "application/pdf";
case "jpg", "jpeg" -> "image/jpeg";
case "png" -> "image/png";
case "gif" -> "image/gif";
case "doc" -> "application/msword";
case "docx" -> "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
case "xls" -> "application/vnd.ms-excel";
case "xlsx" -> "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
default -> "application/octet-stream";
};
}
/**

View File

@ -76,4 +76,8 @@ public class MaterialAddQO {
* 版本号
*/
private String version;
private String filename;
private String fileindex;
}