物料导入分类问题解决

This commit is contained in:
秦鸿展
2026-04-22 22:44:39 +08:00
parent 87f64f0efa
commit 60874e7322
7 changed files with 126 additions and 0 deletions
@@ -369,4 +369,12 @@ public interface SystemServiceFeign {
@GetMapping("/LeaseApi/wholeRentSynchronization")
public AjaxResult wholeRentSynchronization();
/**
* 物料主数据导入:按组织与关键词匹配物料分类,返回体含物料分类的 code 字段,供写入 material_base_info.material_classify_code。
* 使用 basicApi 前缀,与 WMS 其他 Feign 调 system 的惯例一致(避免仅重启 WMS 时 system 上无 materialClassifyApi 新路由导致 404)。
*/
@GetMapping("/basicApi/matchMaterialClassifyForImport")
public AjaxResult matchForMaterialImport(@RequestParam("keyword") String keyword,
@RequestParam("organizationId") Long organizationId);
}
@@ -298,6 +298,11 @@ public class RemoteSystemFeignFallbackFactory implements FallbackFactory<SystemS
public AjaxResult wholeRentSynchronization() {
return AjaxResult.error("查询失败");
}
@Override
public AjaxResult matchForMaterialImport(String keyword, Long organizationId) {
return AjaxResult.error("物料分类匹配失败");
}
};
}
}
@@ -138,4 +138,11 @@ public class MaterialClassifyApplicationService {
public Boolean nullifyByIds(Long[] materialClassifyIds){
return materialClassifyDomainService.nullifyByIds(materialClassifyIds);
}
/**
* 物料主数据导入:按组织+关键词(分类编码/名称/名称路径)匹配分类,供 WMS Feign 调用。
*/
public MaterialClassifyPO matchByKeywordForImport(String keyword, Long organizationId) {
return materialClassifyDomainService.matchByKeywordForImport(keyword, organizationId);
}
}
@@ -1,6 +1,7 @@
package com.mhd.basic.domain.materialClassify.service;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mhd.basic.domain.materialClassify.entity.MaterialClassify;
@@ -12,6 +13,7 @@ import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -157,5 +159,29 @@ public class MaterialClassifyDomainService {
.in(MaterialClassify::getMaterialClassifyId, Arrays.asList(materialClassifyIds)));
}
/**
* 物料主数据导入:在指定组织下按分类编码/名称/名称路径精确匹配一条有效分类,用于回填物料分类编码。
*/
public MaterialClassifyPO matchByKeywordForImport(String keyword, Long organizationId) {
if (StringUtils.isEmpty(keyword) || organizationId == null) {
return null;
}
String kw = keyword.trim();
List<MaterialClassify> list = materialClassifyService.list(new LambdaQueryWrapper<MaterialClassify>()
.eq(MaterialClassify::getOrganizationId, organizationId)
.eq(MaterialClassify::getDelFlag, 1)
.and(n -> n.isNull(MaterialClassify::getNullify).or().eq(MaterialClassify::getNullify, 1))
.and(w -> w.eq(MaterialClassify::getCode, kw)
.or().eq(MaterialClassify::getName, kw)
.or().eq(MaterialClassify::getNamePath, kw))
.orderByDesc(MaterialClassify::getLevel)
.last("limit 1"));
if (list == null || list.isEmpty()) {
return null;
}
MaterialClassifyPO po = new MaterialClassifyPO();
BeanUtils.copyProperties(list.get(0), po);
return po;
}
}
@@ -8,6 +8,7 @@ import com.mhd.basic.interfaces.assember.*;
import com.mhd.basic.interfaces.dto.*;
import com.mhd.basic.interfaces.facade.vo.SysAreaVO;
import com.mhd.basic.application.service.common.CommonApplicationService;
import com.mhd.basic.application.service.materialClassify.MaterialClassifyApplicationService;
import com.mhd.basic.domain.areaAggregate.repository.po.SysAreaPO;
import com.mhd.basic.domain.areaAggregate.repository.todo.SysProvinceCityCountyDO;
import com.mhd.basic.domain.common.entity.DataPermission;
@@ -60,6 +61,8 @@ public class BasicAPI extends BaseController {
private SysAppVersionManageApplicationService sysAppVersionManageApplicationService;
@Resource
private CommonApplicationService commonApplicationService;
@Resource
private MaterialClassifyApplicationService materialClassifyApplicationService;
@ApiOperation("查询系统协议列表")
@GetMapping("/basicAgreemenList")
@@ -555,4 +558,11 @@ public class BasicAPI extends BaseController {
sysMultistageDictDo.setTopParentDictCode(topCode);
return AjaxResult.success(sysMultistageDictApplicationService.selectSysMultistageDictList(sysMultistageDictDo));
}
@ApiOperation("物料主数据导入-按关键词匹配一条物料分类(返回 material_classify.code 供 WMS 写入)")
@GetMapping("/matchMaterialClassifyForImport")
public AjaxResult matchMaterialClassifyForImport(@RequestParam("keyword") String keyword,
@RequestParam("organizationId") Long organizationId) {
return AjaxResult.success(materialClassifyApplicationService.matchByKeywordForImport(keyword, organizationId));
}
}
@@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mhd.basic.interfaces.dto.materialClassify.MaterialClassifyDTO;
@@ -108,6 +109,17 @@ public class MaterialClassifyApi extends BaseController{
{
return toAjax(materialClassifyApplicationService.nullifyByIds(materialClassifyIds));
}
/**
* 物料主数据导入:按组织与关键词匹配一条物料分类,用于回填分类编码
*/
@ApiOperation("物料主数据导入-匹配物料分类")
@GetMapping("/matchForMaterialImport")
public AjaxResult matchForMaterialImport(
@RequestParam("keyword") String keyword,
@RequestParam("organizationId") Long organizationId) {
return AjaxResult.success(materialClassifyApplicationService.matchByKeywordForImport(keyword, organizationId));
}
@@ -597,6 +597,8 @@ public class MaterialBaseInfoApplicationService {
names.add(row.getMaterialClassifyImport().trim());
row.setMaterialClassifyName(names);
}
// 按组织从 system 主数据反查分类编码,与名称列表对齐
fillMaterialClassifyCodesFromSystem(row);
// 物料种类:可传编码或名称,统一回填编码+名称
if ((StringUtils.isBlank(row.getMaterialType()) || StringUtils.isBlank(row.getMaterialTypeName()))
@@ -668,6 +670,62 @@ public class MaterialBaseInfoApplicationService {
}
}
/**
* 导入时已有分类名称但缺少分类编码时,走 system 接口按组织+名称/编码/名称路径匹配并回填.
* Excel 已填写的编码列优先保留。
*/
private void fillMaterialClassifyCodesFromSystem(MaterialBaseInfoDTO row) {
if (CollectionUtils.isEmpty(row.getMaterialClassifyName()) || row.getOrganizationId() == null) {
return;
}
List<String> names = row.getMaterialClassifyName();
List<String> existing = row.getMaterialClassifyCode();
List<String> newCodes = new ArrayList<>();
for (int i = 0; i < names.size(); i++) {
String fromExcel = (existing != null && i < existing.size()) ? existing.get(i) : null;
if (StringUtils.isNotBlank(fromExcel)) {
newCodes.add(fromExcel.trim());
continue;
}
String n = StringUtils.trimToNull(names.get(i));
if (n == null) {
newCodes.add(null);
} else {
newCodes.add(resolveClassifyCodeByFeign(n, row.getOrganizationId()));
}
}
row.setMaterialClassifyCode(newCodes);
}
/** 取 system 返回的 material_classify.code,写入本表 MATERIAL_CLASSIFY_CODEList 中一项) */
private String resolveClassifyCodeByFeign(String keyword, Long organizationId) {
if (StringUtils.isBlank(keyword) || organizationId == null) {
return null;
}
try {
AjaxResult r = systemServiceFeign.matchForMaterialImport(keyword.trim(), organizationId);
if (r == null || !"200".equals(String.valueOf(r.get("code"))) || r.get("data") == null) {
return null;
}
Map<String, Object> map = JSON.parseObject(JSONObject.toJSONString(r.get("data")),
new TypeReference<Map<String, Object>>() {});
if (map == null) {
return null;
}
Object code = map.get("code");
if (code == null) {
code = map.get("Code");
}
if (code == null) {
return null;
}
return StringUtils.trimToNull(String.valueOf(code));
} catch (Exception e) {
log.warn("导入解析物料分类编码失败 keyword={} orgId={} err={}", keyword, organizationId, e.getMessage());
return null;
}
}
private List<MaterialBarCodeDO> buildImportBarCodeList(MaterialBaseInfoDTO row) {
if (StringUtils.isBlank(row.getBarCode())) {
return null;