Merge remote-tracking branch 'origin/dev-ty1.2' into dev-ty1.2

This commit is contained in:
hjx
2026-08-05 09:55:47 +08:00
50 changed files with 2428 additions and 187 deletions
@@ -7,12 +7,14 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableRyFeignClients
@EnableDiscoveryClient
@MapperScan("com.mhd.wms.domain.**.mapper")
@EnableMethodCache(basePackages = "com.mhd.platform.domain.**.cache")
@EnableAsync
@ComponentScan(basePackages = {
"com.mhd.wms",
"com.mhd.system.api.factory"
@@ -49,12 +49,15 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
@@ -100,6 +103,10 @@ public class MaterialBaseInfoApplicationService {
@Resource
private MaterialBaseInfoMapper materialBaseInfoMapper;
@Autowired
private MaterialBaseInfoAsyncService materialBaseInfoAsyncService;
/**
* 分页查询物料基础信息列表
*/
@@ -436,8 +443,47 @@ public class MaterialBaseInfoApplicationService {
return materialBaseInfoDomainService.getInfoByNoOrderReceipt(materialBaseInfoDO);
}
/**
* 导入物料主数据(仅导入主表字段
* 导入物料主数据(异步入口
*
* <p>接口层调用此方法,将文件保存到临时目录后立即返回"异步处理中",
* 实际导入由 {@link #doImportData(File, String, LoginUser)} 异步执行,
* 避免大数据量时接口超时。</p>
*/
public AjaxResult importDataAsync(MultipartFile file) {
if (file == null || file.isEmpty()) {
throw new ServiceException("上传文件不能为空");
}
String fileName = file.getOriginalFilename();
if (org.apache.commons.lang3.StringUtils.isBlank(fileName)
|| (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))) {
throw new ServiceException("请上传xls或xlsx格式文件");
}
// 流式写入临时文件,避免大文件 getBytes() 导致内存溢出和接口超时
String tmpDir = System.getProperty("java.io.tmpdir") + File.separator + "material_import";
File dir = new File(tmpDir);
if (!dir.exists()) {
dir.mkdirs();
}
String tmpFileName = System.currentTimeMillis() + "_" + fileName;
File tmpFile = new File(dir, tmpFileName);
try {
file.transferTo(tmpFile);
} catch (Exception e) {
throw new ServiceException("文件保存失败:" + e.getMessage());
}
LoginUser loginUser = SecurityUtils.getLoginUser();
// 通过独立的异步 Service 执行导入(避免类内部 self-invocation 导致 @Async 失效)
materialBaseInfoAsyncService.doImportData(tmpFile, fileName, loginUser);
return AjaxResult.success("导入任务已提交,正在后台异步处理,请稍后查看导入结果日志");
}
/**
* 导入物料主数据(仅导入主表字段)- 原同步方法保留,供其他场景调用
*/
@Transactional(rollbackFor = Exception.class)
public AjaxResult importData(MultipartFile file) {
@@ -496,7 +542,6 @@ public class MaterialBaseInfoApplicationService {
row.setHsCode(row.getHsCodeImport().trim());
}
normalizeImportBarCodeWhenDuplicateOfHs(row);
// 客户模板通常只有「货主名称」无「货主id」:须先按名称解析货主,再回填组织;勿提前写入登录组织以免组织校验拦截货主匹配
fillIdsFromExistingMasterData(row);
fillOrganizationFromShipperIfNeeded(row);
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
@@ -567,25 +612,20 @@ public class MaterialBaseInfoApplicationService {
materialBaseInfoDO.setMaterialCommon(null);
materialBaseInfoDO.setMaterialWarehouseControl(null);
materialBaseInfoDO.setMaterialBarCodeList(buildImportBarCodeList(row));
// 商品规则由 buildImportMaterialGoodsRule + insert() 统一写入,勿再单独 insert,避免 MATERIAL_GOODS_RULE 重复
insert(materialBaseInfoDO);
Long materialBaseInfoId = materialBaseInfoDO.getMaterialBaseInfoId();
//公共信息
MaterialCommonDO materialCommonDO = materialBaseInfoDO.getMaterialCommon();
if (materialCommonDO != null) {
materialCommonDO.setMaterialBaseInfoId(materialBaseInfoId);
materialCommonDomainService.insert(materialCommonDO);
}
//仓库控制信息
MaterialWarehouseControlDO materialWarehouseControlDO = materialBaseInfoDO.getMaterialWarehouseControl();
if (materialWarehouseControlDO != null) {
materialWarehouseControlDO.setMaterialBaseInfoId(materialBaseInfoId);
materialWarehouseControlDomainService.insert(materialWarehouseControlDO);
}
//库存预警
materialInventoryWarningDomainService.batchInsertOrUpdate(materialBaseInfoDO);
//条码信息
materialBarCodeDomainService.batchInsertOrUpdate(materialBaseInfoDO);
successCount++;
}
@@ -596,10 +636,11 @@ public class MaterialBaseInfoApplicationService {
return AjaxResult.success("导入成功,共" + successCount + "");
}
/**
* 使用已存在主数据按名称/编码反查并回填ID
*/
private void fillIdsFromExistingMasterData(MaterialBaseInfoDTO row) {
public void fillIdsFromExistingMasterData(MaterialBaseInfoDTO row) {
if (StringUtils.isBlank(row.getPackName()) && StringUtils.isNotBlank(row.getPackImport())) {
row.setPackName(row.getPackImport().trim());
}
@@ -818,10 +859,14 @@ public class MaterialBaseInfoApplicationService {
Object userCode = shipper.get("userCode");
Object userMemberCode = shipper.get("userMemberCode");
Object entName = shipper.get("shipperEnterpriseName");
if (userName == null) {
// userName 可能为空字符串而非 null,需同时判断空字符串
if (userName == null || String.valueOf(userName).trim().isEmpty()) {
userName = shipper.get("userNameShipper");
}
if (userName == null || String.valueOf(userName).trim().isEmpty()) {
userName = shipper.get("name");
}
if (userName == null) {
if (userName == null || String.valueOf(userName).trim().isEmpty()) {
userName = shipper.get("shipperName");
}
String normalizedName = StringUtils.isNotBlank(shipperName) ? shipperName : "";
@@ -919,7 +964,7 @@ public class MaterialBaseInfoApplicationService {
/**
* Excel 已填货主 ID、但未填组织时,从货主用户补全组织信息。
*/
private void fillOrganizationFromShipperIfNeeded(MaterialBaseInfoDTO row) {
public void fillOrganizationFromShipperIfNeeded(MaterialBaseInfoDTO row) {
if (isValidOrgId(row.getOrganizationId()) || row.getShipperId() == null) {
return;
}
@@ -978,7 +1023,7 @@ public class MaterialBaseInfoApplicationService {
}
}
private void fillOrganizationName(MaterialBaseInfoDTO row, LoginUser loginUser) {
public void fillOrganizationName(MaterialBaseInfoDTO row, LoginUser loginUser) {
if (StringUtils.isNotBlank(row.getOrganizationName())) {
return;
}
@@ -998,7 +1043,7 @@ public class MaterialBaseInfoApplicationService {
}
}
private void fillClassifyTypeAndUnit(MaterialBaseInfoDTO row) {
public void fillClassifyTypeAndUnit(MaterialBaseInfoDTO row) {
normalizeMaterialClassifyImportFields(row);
// 按组织从 system 主数据反查分类编码,与名称列表对齐
fillMaterialClassifyCodesFromSystem(row);
@@ -1179,7 +1224,7 @@ public class MaterialBaseInfoApplicationService {
* 导入约定:「HS码/HS编码」与「物料条形码」为不同列。模板表头错位或两列误填相同 HS 时,
* barCode 会与 hsCode 相同;此时保留 hsCode,清空主表/子表条码,避免 HS 写入 bar_code。
*/
private void normalizeImportBarCodeWhenDuplicateOfHs(MaterialBaseInfoDTO row) {
public void normalizeImportBarCodeWhenDuplicateOfHs(MaterialBaseInfoDTO row) {
if (row == null) {
return;
}
@@ -1194,7 +1239,7 @@ public class MaterialBaseInfoApplicationService {
}
}
private List<MaterialBarCodeDO> buildImportBarCodeList(MaterialBaseInfoDTO row) {
public List<MaterialBarCodeDO> buildImportBarCodeList(MaterialBaseInfoDTO row) {
if (StringUtils.isBlank(row.getBarCode())) {
return null;
}
@@ -1234,7 +1279,7 @@ public class MaterialBaseInfoApplicationService {
return idObj == null ? null : Long.valueOf(String.valueOf(idObj));
}
private MaterialGoodsRuleDO buildImportMaterialGoodsRule(MaterialBaseInfoDTO row) {
public MaterialGoodsRuleDO buildImportMaterialGoodsRule(MaterialBaseInfoDTO row) {
String batchName = StringUtils.isNotBlank(row.getBatchRuleNameImport())
? row.getBatchRuleNameImport().trim()
: (StringUtils.isNotBlank(row.getBatchName())
@@ -1309,7 +1354,7 @@ public class MaterialBaseInfoApplicationService {
.trim();
}
private List<Map<String, Object>> extractTableDataRows(Map<String, Object> resultMap) {
public List<Map<String, Object>> extractTableDataRows(Map<String, Object> resultMap) {
if (resultMap == null) {
return new ArrayList<>();
}
@@ -0,0 +1,274 @@
package com.mhd.wms.application.service.materialBaseInfo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mhd.common.core.domain.po.UserPo;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.UserServiceFeign;
import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.materialBarCode.service.MaterialBarCodeDomainService;
import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo;
import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService;
import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper;
import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO;
import com.mhd.wms.domain.materialBaseInfo.service.MaterialBaseInfoDomainService;
import com.mhd.wms.domain.materialGoodsRule.service.MaterialGoodsRuleDomainService;
import com.mhd.wms.domain.materialCommon.service.MaterialCommonDomainService;
import com.mhd.wms.domain.materialCommon.repository.todo.MaterialCommonDO;
import com.mhd.wms.domain.materialInventoryWarning.service.MaterialInventoryWarningDomainService;
import com.mhd.wms.domain.materialWarehouseControl.service.MaterialWarehouseControlDomainService;
import com.mhd.wms.domain.materialWarehouseControl.repository.todo.MaterialWarehouseControlDO;
import com.mhd.wms.interfaces.dto.materialBaseInfo.MaterialBaseInfoDTO;
import com.mhd.wms.util.MaterialBaseInfoImportExcelUtil;
import com.mhd.wms.util.ZhTextNormalizeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
/**
* 物料主数据异步导入服务
*/
@Slf4j
@Service
public class MaterialBaseInfoAsyncService {
@Autowired
private IMaterialBaseInfoService materialBaseInfoService;
@Autowired
private MaterialBaseInfoMapper materialBaseInfoMapper;
@Autowired
private SystemServiceFeign systemServiceFeign;
@Autowired
private UserServiceFeign userServiceFeign;
@Autowired
private MaterialCommonDomainService materialCommonDomainService;
@Autowired
private MaterialWarehouseControlDomainService materialWarehouseControlDomainService;
@Autowired
private MaterialInventoryWarningDomainService materialInventoryWarningDomainService;
@Autowired
private MaterialBarCodeDomainService materialBarCodeDomainService;
@Autowired
private MaterialBaseInfoDomainService materialBaseInfoDomainService;
@Autowired
private com.mhd.wms.domain.materialGoodsRule.service.MaterialGoodsRuleDomainService materialGoodsRuleDomainService;
@org.springframework.context.annotation.Lazy
@Autowired
private MaterialBaseInfoApplicationService materialBaseInfoApplicationService;
@Async
public void doImportData(File tmpFile, String fileName, LoginUser loginUser) {
long startTime = System.currentTimeMillis();
log.info("=== 物料主数据异步导入开始,文件:{},大小:{}KB ===", fileName, tmpFile.length() / 1024);
try {
List<MaterialBaseInfoDTO> rows;
try (InputStream is = new FileInputStream(tmpFile)) {
rows = MaterialBaseInfoImportExcelUtil.importRows(is);
} catch (Exception e) {
log.error("物料主数据异步导入失败 - 文件解析异常:{}", e.getMessage(), e);
return;
}
if (CollectionUtils.isEmpty(rows)) {
log.warn("物料主数据异步导入结束 - 导入数据为空");
return;
}
Long loginOrgId = null;
Long loginTopOrgId = null;
if (loginUser != null && loginUser.getUserPo() != null) {
loginOrgId = loginUser.getUserPo().getOrganizationId();
loginTopOrgId = loginUser.getUserPo().getTopOrganizationId();
}
StringBuilder errors = new StringBuilder();
Set<String> duplicateInFile = new HashSet<>();
int successCount = 0;
int totalCount = rows.size();
Map<String, Map<String, Object>> packCache = new HashMap<>();
for (int i = 0; i < rows.size(); i++) {
MaterialBaseInfoDTO row = rows.get(i);
int rowNum = i + 2;
if (row == null) {
continue;
}
try {
if (StringUtils.isBlank(row.getMaterialCode())) {
errors.append("").append(rowNum).append("行:物料编码不能为空;");
continue;
}
if (StringUtils.isBlank(row.getMaterialName())) {
errors.append("").append(rowNum).append("行:物料名称不能为空;");
continue;
}
if (row.getNullify() == null) {
row.setNullify(2);
}
if (row.getCommon() == null) {
row.setCommon(2);
}
if (StringUtils.isBlank(row.getHsCode()) && StringUtils.isNotBlank(row.getHsCodeImport())) {
row.setHsCode(row.getHsCodeImport().trim());
}
materialBaseInfoApplicationService.normalizeImportBarCodeWhenDuplicateOfHs(row);
materialBaseInfoApplicationService.fillIdsFromExistingMasterData(row);
materialBaseInfoApplicationService.fillOrganizationFromShipperIfNeeded(row);
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
row.setOrganizationId(loginOrgId);
}
if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
row.setTopOrganizationId(loginTopOrgId);
}
materialBaseInfoApplicationService.fillOrganizationName(row, loginUser);
String shipperCode = StringUtils.defaultString(row.getShipperCode(), "");
String duplicateKey = row.getOrganizationId() + "|" + shipperCode + "|" + row.getMaterialCode();
if (!duplicateInFile.add(duplicateKey)) {
errors.append("").append(rowNum).append("行:文件内存在重复物料;");
continue;
}
LambdaQueryWrapper<MaterialBaseInfo> wrapper = new LambdaQueryWrapper<MaterialBaseInfo>()
.eq(MaterialBaseInfo::getDelFlag, 1)
.eq(MaterialBaseInfo::getOrganizationId, row.getOrganizationId())
.eq(MaterialBaseInfo::getMaterialCode, row.getMaterialCode());
if (StringUtils.isBlank(row.getShipperCode())) {
wrapper.and(w -> w.isNull(MaterialBaseInfo::getShipperCode).or().eq(MaterialBaseInfo::getShipperCode, ""));
} else {
wrapper.eq(MaterialBaseInfo::getShipperCode, row.getShipperCode());
}
if (materialBaseInfoService.count(wrapper) > 0) {
errors.append("").append(rowNum).append("行:物料已存在;");
continue;
}
materialBaseInfoApplicationService.fillClassifyTypeAndUnit(row);
// 包装规格查询(带缓存)
String packCacheKey = row.getOrganizationId() + "|" + StringUtils.defaultString(row.getPackName());
Map<String, Object> cachedPack = packCache.get(packCacheKey);
if (cachedPack == null) {
Object result = systemServiceFeign.getPackList(null, row.getPackName(), row.getOrganizationId());
if (result == null) {
packCache.put(packCacheKey, Collections.emptyMap());
errors.append("").append(rowNum).append("行:包装规格查询无返回;");
continue;
}
Map<String, Object> resultMap = JSON.parseObject(JSONObject.toJSONString(result), new TypeReference<Map<String, Object>>() {});
List<Map<String, Object>> rowsPack = extractTableDataRows(resultMap);
if (CollectionUtils.isEmpty(rowsPack)) {
packCache.put(packCacheKey, Collections.emptyMap());
errors.append("").append(rowNum).append("行:包装规格不存在;");
continue;
}
cachedPack = rowsPack.get(0);
packCache.put(packCacheKey, cachedPack);
}
if (cachedPack.isEmpty()) {
errors.append("").append(rowNum).append("行:包装规格不存在(缓存);");
continue;
}
String packCode = cachedPack.get("packCode") == null ? "" : String.valueOf(cachedPack.get("packCode"));
row.setPackCode(packCode);
String packId = cachedPack.get("packId") == null ? "" : String.valueOf(cachedPack.get("packId"));
if (StringUtils.isBlank(packId) || !StringUtils.isNumeric(packId)) {
errors.append("").append(rowNum).append("行:包装规格数据异常;");
continue;
}
row.setPackId(Long.valueOf(packId));
String unitName = cachedPack.get("unitName") == null ? "" : String.valueOf(cachedPack.get("unitName"));
row.setUnitCode("EA");
row.setUnitName(unitName);
MaterialBaseInfoDO materialBaseInfoDO = new MaterialBaseInfoDO();
BeanUtils.copyProperties(row, materialBaseInfoDO);
materialBaseInfoDO.setMaterialGoodsRule(materialBaseInfoApplicationService.buildImportMaterialGoodsRule(row));
materialBaseInfoDO.setMaterialCommon(null);
materialBaseInfoDO.setMaterialWarehouseControl(null);
materialBaseInfoDO.setMaterialBarCodeList(materialBaseInfoApplicationService.buildImportBarCodeList(row));
// 补全创建人信息(异步线程没有 SecurityContext,用 loginUser
if (loginUser != null) {
materialBaseInfoDO.setCreateBy(loginUser.getUserid());
materialBaseInfoDO.setCreateByName(loginUser.getUsername());
}
materialBaseInfoDO.setCreateTime(new Date());
// 调用原 ApplicationService 的 insert,走完整的插入逻辑(含商品规则、公共信息、NC编码等)
materialBaseInfoApplicationService.insert(materialBaseInfoDO);
successCount++;
} catch (Exception e) {
log.error("物料主数据异步导入 - 第{}行处理异常", rowNum, e);
errors.append("").append(rowNum).append("行:处理异常-").append(e.getMessage()).append("");
}
}
long costTime = System.currentTimeMillis() - startTime;
if (errors.length() > 0) {
log.warn("=== 物料主数据异步导入完成,文件:{},总数:{},成功:{},失败:{},耗时:{}ms,失败原因:{} ===",
fileName, totalCount, successCount, totalCount - successCount, costTime, errors);
} else {
log.info("=== 物料主数据异步导入完成,文件:{},总数:{},成功:{},耗时:{}ms ===",
fileName, totalCount, successCount, costTime);
}
} finally {
try {
if (tmpFile.exists()) {
tmpFile.delete();
}
} catch (Exception e) {
log.warn("物料主数据异步导入 - 临时文件清理失败:{}", e.getMessage());
}
}
}
// ====== 以下工具方法 ======
private List<Map<String, Object>> extractTableDataRows(Map<String, Object> resultMap) {
if (resultMap == null) {
return Collections.emptyList();
}
Object data = resultMap.get("data");
if (data == null) {
data = resultMap.get("rows");
}
if (data instanceof List) {
@SuppressWarnings("unchecked")
List<Map<String, Object>> list = (List<Map<String, Object>>) data;
return list;
}
if (data instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> dataMap = (Map<String, Object>) data;
Object innerData = dataMap.get("data");
if (innerData instanceof List) {
@SuppressWarnings("unchecked")
List<Map<String, Object>> list = (List<Map<String, Object>>) innerData;
return list;
}
Object rows = dataMap.get("rows");
if (rows instanceof List) {
@SuppressWarnings("unchecked")
List<Map<String, Object>> list = (List<Map<String, Object>>) rows;
return list;
}
}
return Collections.emptyList();
}
private boolean isValidOrgId(Long id) {
return id != null && id > 0;
}
}
@@ -545,9 +545,71 @@ public class StockInOrderApplicationService {
info.setKhdm(userNcCode);
List<InMaterialDetailPO> materialDetailList = info.getMaterialDetailList();
if (materialDetailList != null && !materialDetailList.isEmpty()) {
for (InMaterialDetailPO inMaterialDetailPO : materialDetailList) {
// TODO: 设置物料详情信息
inMaterialDetailPO.setKhdm(userNcCode);
// 收集所有有效的物料基础信息ID
Set<Long> materialBaseInfoIdSet = new HashSet<>();
for (InMaterialDetailPO detail : materialDetailList) {
if (detail.getMaterialBaseInfoId() != null && detail.getMaterialBaseInfoId() > 0) {
materialBaseInfoIdSet.add(detail.getMaterialBaseInfoId());
}
}
// 批量查询物料基础信息,try-catch保护,防止没有ID时NPE
Map<Long, MaterialBaseInfoPO> materialBaseInfoMap = new HashMap<>();
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
try {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoService.getInfo(materialBaseInfoId);
if (materialBaseInfoPO != null) {
materialBaseInfoMap.put(materialBaseInfoId, materialBaseInfoPO);
}
} catch (Exception e) {
log.warn("获取物料基础信息失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage());
}
}
// 填充明细的物料字段(物料编码、抄码、条码、单位等)
Long shipperId = info.getShipperId();
for (InMaterialDetailPO detail : materialDetailList) {
detail.setKhdm(userNcCode);
Long materialBaseInfoId = detail.getMaterialBaseInfoId();
MaterialBaseInfoPO materialBaseInfoPO = null;
if (materialBaseInfoId != null && materialBaseInfoId > 0) {
materialBaseInfoPO = materialBaseInfoMap.get(materialBaseInfoId);
}
// 兜底:ID=0时用物料名称反查
if (materialBaseInfoPO == null && StringUtils.isNotBlank(detail.getMaterialName())) {
try {
MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO();
queryDO.setMaterialName(detail.getMaterialName().trim());
if (shipperId != null && shipperId > 0) {
queryDO.setShipperId(shipperId);
}
List<MaterialBaseInfoPO> list = materialBaseInfoService.queryList(queryDO);
if (list != null && !list.isEmpty()) {
materialBaseInfoPO = list.get(0);
}
} catch (Exception e) {
log.warn("兜底反查物料失败,物料名:{}", detail.getMaterialName());
}
}
if (materialBaseInfoPO != null) {
if (StringUtils.isBlank(detail.getMaterialCode())) {
detail.setMaterialCode(materialBaseInfoPO.getMaterialCode());
}
if (StringUtils.isBlank(detail.getBarCode())) {
detail.setBarCode(materialBaseInfoPO.getBarCode());
}
if (StringUtils.isBlank(detail.getUnitCode())) {
detail.setUnitCode(materialBaseInfoPO.getUnitCode());
}
if (StringUtils.isBlank(detail.getUnitName())) {
detail.setUnitName(materialBaseInfoPO.getUnitName());
}
detail.setPackId(materialBaseInfoPO.getPackId());
detail.setPackCode(materialBaseInfoPO.getPackCode());
detail.setPackName(materialBaseInfoPO.getPackName());
}
}
info.setMaterialDetailList(materialDetailList);
}
@@ -282,9 +282,6 @@ public class StockOutOrderApplicationService {
stockOutOrderPO.setMaterialQuantity(cnt);
}
BigDecimal checkSum = (mag != null && mag.getCheckQuantitySum() != null)
? mag.getCheckQuantitySum() : BigDecimal.ZERO;
stockOutOrderPO.setCheckQuantity(checkSum);
stockOutOrderPO.setReceiptOrderAccountList(
accountByOrderId.getOrDefault(stockOutOrderPO.getOutOrderId(), Collections.emptyList()));
}
@@ -233,7 +233,9 @@ public class StockReceiptOrderApplicationService {
}
for (ReceiptMaterialDetailPO receiptMaterialDetailPO : receiptMaterialDetailPOList) {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoMap.get(receiptMaterialDetailPO.getMaterialBaseInfoId());
receiptMaterialDetailPO.setCopyCode(materialBaseInfoPO.getCopyCode());
if (materialBaseInfoPO != null) {
receiptMaterialDetailPO.setCopyCode(materialBaseInfoPO.getCopyCode());
}
}
// 4.2 批量查询包装规格信息单位代码为EA的单位名称
@@ -819,7 +819,12 @@ public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper,
materialInventory.setNetWeight(netWeight);
materialInventory.setMaterialBaseInfoId(materialInventoryParamDO.getMaterialBaseInfoId());
materialInventory.setInOrderNumber(materialInventoryParamDO.getInOrderNumber());
if (materialBaseInfo != null) {
// 优先使用上游传入的货主信息如来自上架单否则再从物料基础信息兜底
if (materialInventoryParamDO.getShipperId() != null) {
materialInventory.setShipperId(materialInventoryParamDO.getShipperId());
materialInventory.setShipperName(materialInventoryParamDO.getShipperName());
materialInventory.setShipperCode(materialInventoryParamDO.getShipperCode());
} else if (materialBaseInfo != null) {
materialInventory.setShipperId(materialBaseInfo.getShipperId());
materialInventory.setShipperName(materialBaseInfo.getShipperName());
materialInventory.setShipperCode(materialBaseInfo.getShipperCode());
@@ -106,12 +106,16 @@ public class MaterialBaseInfoApi extends BaseController {
}
/**
* 导入物料主数据
* 导入物料主数据异步执行
*
* <p>数据量大时同步导入会导致接口超时改为异步模式
* 接口立即返回"已提交异步处理"后台线程执行实际导入
* 导入结果通过日志输出</p>
*/
@ApiOperation("导入物料主数据")
@ApiOperation("导入物料主数据(异步)")
@PostMapping("/importData")
public AjaxResult importData(@RequestParam("file") MultipartFile file) {
return materialBaseInfoApplicationService.importData(file);
return materialBaseInfoApplicationService.importDataAsync(file);
}
@ApiOperation("物料管理更新推送信息")
@@ -36,6 +36,11 @@ public final class MaterialBaseInfoImportExcelUtil {
HEADER_ALIASES.put("淨重(kg)", "净重 单位:千克");
HEADER_ALIASES.put("体积(m³)", "体积 单位:立方米");
HEADER_ALIASES.put("體積(m³)", "体积 单位:立方米");
HEADER_ALIASES.put("", "物料大小-长 单位:米");
HEADER_ALIASES.put("", "物料大小-宽 单位:米");
HEADER_ALIASES.put("", "物料大小-高 单位:米");
HEADER_ALIASES.put("公司名称", "货主名称");
HEADER_ALIASES.put("公司名稱", "货主名称");
}
public static List<MaterialBaseInfoDTO> importRows(InputStream is) throws Exception {