物料导入繁体解析
This commit is contained in:
+142
-46
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.mhd.common.core.domain.po.UserPo;
|
import com.mhd.common.core.domain.po.UserPo;
|
||||||
import com.mhd.common.core.exception.ServiceException;
|
import com.mhd.common.core.exception.ServiceException;
|
||||||
import com.mhd.common.core.enums.DictCode;
|
import com.mhd.common.core.enums.DictCode;
|
||||||
import com.mhd.common.core.utils.poi.ExcelUtil;
|
import com.mhd.wms.util.ZhTextNormalizeUtil;
|
||||||
import com.mhd.common.core.web.domain.AjaxResult;
|
import com.mhd.common.core.web.domain.AjaxResult;
|
||||||
import com.mhd.common.core.web.page.TableDataInfo;
|
import com.mhd.common.core.web.page.TableDataInfo;
|
||||||
import com.mhd.common.security.utils.SecurityUtils;
|
import com.mhd.common.security.utils.SecurityUtils;
|
||||||
@@ -42,6 +42,7 @@ import com.mhd.wms.domain.materialWarehouseControl.repository.po.MaterialWarehou
|
|||||||
import com.mhd.wms.domain.materialWarehouseControl.repository.todo.MaterialWarehouseControlDO;
|
import com.mhd.wms.domain.materialWarehouseControl.repository.todo.MaterialWarehouseControlDO;
|
||||||
import com.mhd.wms.domain.materialWarehouseControl.service.MaterialWarehouseControlDomainService;
|
import com.mhd.wms.domain.materialWarehouseControl.service.MaterialWarehouseControlDomainService;
|
||||||
import com.mhd.wms.interfaces.dto.materialBaseInfo.MaterialBaseInfoDTO;
|
import com.mhd.wms.interfaces.dto.materialBaseInfo.MaterialBaseInfoDTO;
|
||||||
|
import com.mhd.wms.util.MaterialBaseInfoImportExcelUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
@@ -54,6 +55,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -398,8 +400,7 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
|
|
||||||
final List<MaterialBaseInfoDTO> rows;
|
final List<MaterialBaseInfoDTO> rows;
|
||||||
try (InputStream is = file.getInputStream()) {
|
try (InputStream is = file.getInputStream()) {
|
||||||
ExcelUtil<MaterialBaseInfoDTO> util = new ExcelUtil<>(MaterialBaseInfoDTO.class);
|
rows = MaterialBaseInfoImportExcelUtil.importRows(is);
|
||||||
rows = util.importExcel(is);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ServiceException("导入模板解析失败:" + e.getMessage());
|
throw new ServiceException("导入模板解析失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -434,10 +435,10 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row.getOrganizationId() == null && loginOrgId != null) {
|
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
|
||||||
row.setOrganizationId(loginOrgId);
|
row.setOrganizationId(loginOrgId);
|
||||||
}
|
}
|
||||||
if (row.getTopOrganizationId() == null && loginTopOrgId != null) {
|
if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
|
||||||
row.setTopOrganizationId(loginTopOrgId);
|
row.setTopOrganizationId(loginTopOrgId);
|
||||||
}
|
}
|
||||||
if (row.getNullify() == null) {
|
if (row.getNullify() == null) {
|
||||||
@@ -451,6 +452,9 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
}
|
}
|
||||||
// Excel 表头错位或重复时,HS 可能被读入「物料条形码」列;与 HS 完全相同时视为误填,保留 hsCode、清空条码
|
// Excel 表头错位或重复时,HS 可能被读入「物料条形码」列;与 HS 完全相同时视为误填,保留 hsCode、清空条码
|
||||||
normalizeImportBarCodeWhenDuplicateOfHs(row);
|
normalizeImportBarCodeWhenDuplicateOfHs(row);
|
||||||
|
// 先解析货主并补全组织,再做重复/存在性校验(组织维度依赖 organizationId)
|
||||||
|
fillIdsFromExistingMasterData(row);
|
||||||
|
fillOrganizationFromShipperIfNeeded(row);
|
||||||
fillOrganizationName(row, loginUser);
|
fillOrganizationName(row, loginUser);
|
||||||
|
|
||||||
String shipperCode = StringUtils.defaultString(row.getShipperCode(), "");
|
String shipperCode = StringUtils.defaultString(row.getShipperCode(), "");
|
||||||
@@ -473,8 +477,6 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
errors.append("第").append(rowNum).append("行:物料已存在(组织+货主编码+物料编码);");
|
errors.append("第").append(rowNum).append("行:物料已存在(组织+货主编码+物料编码);");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 根据导入的名称/编码回填现有ID,避免要求模板传ID
|
|
||||||
fillIdsFromExistingMasterData(row);
|
|
||||||
fillClassifyTypeAndUnit(row);
|
fillClassifyTypeAndUnit(row);
|
||||||
|
|
||||||
Object result = systemServiceFeign.getPackList(null, row.getPackName(), row.getOrganizationId());
|
Object result = systemServiceFeign.getPackList(null, row.getPackName(), row.getOrganizationId());
|
||||||
@@ -551,23 +553,9 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
if (StringUtils.isBlank(row.getPackName()) && StringUtils.isNotBlank(row.getPackImport())) {
|
if (StringUtils.isBlank(row.getPackName()) && StringUtils.isNotBlank(row.getPackImport())) {
|
||||||
row.setPackName(row.getPackImport().trim());
|
row.setPackName(row.getPackImport().trim());
|
||||||
}
|
}
|
||||||
// 货主:先按本组织已有物料反查,再用用户中心按「货主编码/货主名称」解析 userId(与入库单 import 一致;纯数字也可作名称,例如「1449」)
|
// 货主:先按本组织已有物料反查,再用用户中心按「货主编码/货主名称」解析 userId(支持繁体名称)
|
||||||
if (row.getShipperId() == null && (StringUtils.isNotBlank(row.getShipperCode()) || StringUtils.isNotBlank(row.getShipperName()))) {
|
if (row.getShipperId() == null && (StringUtils.isNotBlank(row.getShipperCode()) || StringUtils.isNotBlank(row.getShipperName()))) {
|
||||||
MaterialBaseInfo matched = materialBaseInfoService.getOne(new LambdaQueryWrapper<MaterialBaseInfo>()
|
MaterialBaseInfo matched = findExistingMaterialByShipper(row);
|
||||||
.eq(MaterialBaseInfo::getDelFlag, 1)
|
|
||||||
.eq(MaterialBaseInfo::getOrganizationId, row.getOrganizationId())
|
|
||||||
.and(w -> {
|
|
||||||
if (StringUtils.isNotBlank(row.getShipperCode())) {
|
|
||||||
w.eq(MaterialBaseInfo::getShipperCode, row.getShipperCode());
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotBlank(row.getShipperName())) {
|
|
||||||
if (StringUtils.isNotBlank(row.getShipperCode())) {
|
|
||||||
w.or();
|
|
||||||
}
|
|
||||||
w.eq(MaterialBaseInfo::getShipperName, row.getShipperName());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.last("limit 1"));
|
|
||||||
if (matched != null) {
|
if (matched != null) {
|
||||||
row.setShipperId(matched.getShipperId());
|
row.setShipperId(matched.getShipperId());
|
||||||
if (StringUtils.isBlank(row.getShipperCode())) {
|
if (StringUtils.isBlank(row.getShipperCode())) {
|
||||||
@@ -642,6 +630,38 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按货主编码/名称在本组织已有物料中反查(名称支持简繁体归一化匹配)。
|
||||||
|
*/
|
||||||
|
private MaterialBaseInfo findExistingMaterialByShipper(MaterialBaseInfoDTO row) {
|
||||||
|
if (row.getOrganizationId() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(row.getShipperCode())) {
|
||||||
|
MaterialBaseInfo byCode = materialBaseInfoService.getOne(new LambdaQueryWrapper<MaterialBaseInfo>()
|
||||||
|
.eq(MaterialBaseInfo::getDelFlag, 1)
|
||||||
|
.eq(MaterialBaseInfo::getOrganizationId, row.getOrganizationId())
|
||||||
|
.eq(MaterialBaseInfo::getShipperCode, row.getShipperCode().trim())
|
||||||
|
.last("limit 1"));
|
||||||
|
if (byCode != null) {
|
||||||
|
return byCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(row.getShipperName())) {
|
||||||
|
for (String nameVariant : ZhTextNormalizeUtil.nameLookupVariants(row.getShipperName())) {
|
||||||
|
MaterialBaseInfo byName = materialBaseInfoService.getOne(new LambdaQueryWrapper<MaterialBaseInfo>()
|
||||||
|
.eq(MaterialBaseInfo::getDelFlag, 1)
|
||||||
|
.eq(MaterialBaseInfo::getOrganizationId, row.getOrganizationId())
|
||||||
|
.eq(MaterialBaseInfo::getShipperName, nameVariant)
|
||||||
|
.last("limit 1"));
|
||||||
|
if (byName != null) {
|
||||||
|
return byName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入时按货主名称/编号从用户中心解析货主ID(与 {@link com.mhd.wms.application.service.stockInOrder.StockInOrderApplicationService#getShipperIdByNameOrCode} 一致)。
|
* 导入时按货主名称/编号从用户中心解析货主ID(与 {@link com.mhd.wms.application.service.stockInOrder.StockInOrderApplicationService#getShipperIdByNameOrCode} 一致)。
|
||||||
* 不将纯数字的「货主名称」当作用户ID或主键,避免与业务上以数字作为企业简称/名称的货主(如「1449」)冲突。
|
* 不将纯数字的「货主名称」当作用户ID或主键,避免与业务上以数字作为企业简称/名称的货主(如「1449」)冲突。
|
||||||
@@ -658,17 +678,19 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
String shipperCode = StringUtils.isNotBlank(row.getShipperCode()) ? row.getShipperCode().trim() : null;
|
String shipperCode = StringUtils.isNotBlank(row.getShipperCode()) ? row.getShipperCode().trim() : null;
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(shipperName)) {
|
if (StringUtils.isNotBlank(shipperName)) {
|
||||||
try {
|
for (String nameVariant : ZhTextNormalizeUtil.nameLookupVariants(shipperName)) {
|
||||||
AjaxResult ajaxResult = userServiceFeign.getInfoByName(shipperName);
|
try {
|
||||||
if ("200".equals(String.valueOf(ajaxResult.get("code"))) && ajaxResult.get("data") != null) {
|
AjaxResult ajaxResult = userServiceFeign.getInfoByName(nameVariant);
|
||||||
UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
|
if ("200".equals(String.valueOf(ajaxResult.get("code"))) && ajaxResult.get("data") != null) {
|
||||||
if (userPo != null && shipperUserMatchesImportOrganization(userPo, importOrgId)) {
|
UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
|
||||||
applyUserPoToMaterialImportRow(row, userPo);
|
if (userPo != null && shipperUserMatchesImportOrganization(userPo, importOrgId)) {
|
||||||
return;
|
applyUserPoToMaterialImportRow(row, userPo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("物料导入: getInfoByName 货主失败 name={}: {}", nameVariant, e.getMessage());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.debug("物料导入: getInfoByName 货主失败: {}", e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,7 +752,8 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String s = String.valueOf(cand).trim();
|
String s = String.valueOf(cand).trim();
|
||||||
if (normalizedName.equals(s) || s.contains(normalizedName)) {
|
if (ZhTextNormalizeUtil.textEquals(normalizedName, s)
|
||||||
|
|| ZhTextNormalizeUtil.textContains(s, normalizedName)) {
|
||||||
matched = true;
|
matched = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -763,6 +786,15 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
row.setShipperId(userPo.getUserId());
|
row.setShipperId(userPo.getUserId());
|
||||||
|
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(userPo.getOrganizationId())) {
|
||||||
|
row.setOrganizationId(userPo.getOrganizationId());
|
||||||
|
}
|
||||||
|
if (row.getTopOrganizationId() == null && isValidOrgId(userPo.getTopOrganizationId())) {
|
||||||
|
row.setTopOrganizationId(userPo.getTopOrganizationId());
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(row.getOrganizationName()) && StringUtils.isNotBlank(userPo.getOrganizationName())) {
|
||||||
|
row.setOrganizationName(userPo.getOrganizationName());
|
||||||
|
}
|
||||||
if (StringUtils.isBlank(row.getShipperCode()) && StringUtils.isNotBlank(userPo.getUserMemberCode())) {
|
if (StringUtils.isBlank(row.getShipperCode()) && StringUtils.isNotBlank(userPo.getUserMemberCode())) {
|
||||||
row.setShipperCode(userPo.getUserMemberCode());
|
row.setShipperCode(userPo.getUserMemberCode());
|
||||||
}
|
}
|
||||||
@@ -771,6 +803,29 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel 已填货主 ID、但未填组织时,从货主用户补全组织信息。
|
||||||
|
*/
|
||||||
|
private void fillOrganizationFromShipperIfNeeded(MaterialBaseInfoDTO row) {
|
||||||
|
if (isValidOrgId(row.getOrganizationId()) || row.getShipperId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
AjaxResult infoRes = userServiceFeign.getInfo(row.getShipperId());
|
||||||
|
if (!"200".equals(String.valueOf(infoRes.get("code"))) || infoRes.get("data") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UserPo userPo = JSON.parseObject(JSONObject.toJSONString(infoRes.get("data")), UserPo.class);
|
||||||
|
applyUserPoToMaterialImportRow(row, userPo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("物料导入: 按货主ID补全组织失败 shipperId={}: {}", row.getShipperId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidOrgId(Long organizationId) {
|
||||||
|
return organizationId != null && organizationId > 0;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean shipperUserMatchesImportOrganization(UserPo userPo, Long importOrganizationId) {
|
private boolean shipperUserMatchesImportOrganization(UserPo userPo, Long importOrganizationId) {
|
||||||
if (importOrganizationId == null) {
|
if (importOrganizationId == null) {
|
||||||
return true;
|
return true;
|
||||||
@@ -831,12 +886,7 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fillClassifyTypeAndUnit(MaterialBaseInfoDTO row) {
|
private void fillClassifyTypeAndUnit(MaterialBaseInfoDTO row) {
|
||||||
// 物料分类:模板常用“物料分类”单列,回填到名称列表
|
normalizeMaterialClassifyImportFields(row);
|
||||||
if (CollectionUtils.isEmpty(row.getMaterialClassifyName()) && StringUtils.isNotBlank(row.getMaterialClassifyImport())) {
|
|
||||||
List<String> names = new ArrayList<>();
|
|
||||||
names.add(row.getMaterialClassifyImport().trim());
|
|
||||||
row.setMaterialClassifyName(names);
|
|
||||||
}
|
|
||||||
// 按组织从 system 主数据反查分类编码,与名称列表对齐
|
// 按组织从 system 主数据反查分类编码,与名称列表对齐
|
||||||
fillMaterialClassifyCodesFromSystem(row);
|
fillMaterialClassifyCodesFromSystem(row);
|
||||||
|
|
||||||
@@ -910,35 +960,81 @@ public class MaterialBaseInfoApplicationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excel 导入列绑定 String 字段,再转为 List(List 字段仅用于导出/持久化)。
|
||||||
|
*/
|
||||||
|
private void normalizeMaterialClassifyImportFields(MaterialBaseInfoDTO row) {
|
||||||
|
if (CollectionUtils.isEmpty(row.getMaterialClassifyCode())
|
||||||
|
&& StringUtils.isNotBlank(row.getMaterialClassifyCodeImport())) {
|
||||||
|
row.setMaterialClassifyCode(splitImportList(row.getMaterialClassifyCodeImport()));
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isEmpty(row.getMaterialClassifyName())) {
|
||||||
|
if (StringUtils.isNotBlank(row.getMaterialClassifyNameImport())) {
|
||||||
|
row.setMaterialClassifyName(splitImportList(row.getMaterialClassifyNameImport()));
|
||||||
|
} else if (StringUtils.isNotBlank(row.getMaterialClassifyImport())) {
|
||||||
|
row.setMaterialClassifyName(splitImportList(row.getMaterialClassifyImport()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> splitImportList(String raw) {
|
||||||
|
if (StringUtils.isBlank(raw)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Arrays.stream(raw.split("[,,]"))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(StringUtils::isNotBlank)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入时已有分类名称但缺少分类编码时,走 system 接口按组织+名称/编码/名称路径匹配并回填.
|
* 导入时已有分类名称但缺少分类编码时,走 system 接口按组织+名称/编码/名称路径匹配并回填.
|
||||||
* Excel 已填写的编码列优先保留。
|
* Excel 已填写的编码列优先保留。
|
||||||
*/
|
*/
|
||||||
private void fillMaterialClassifyCodesFromSystem(MaterialBaseInfoDTO row) {
|
private void fillMaterialClassifyCodesFromSystem(MaterialBaseInfoDTO row) {
|
||||||
if (CollectionUtils.isEmpty(row.getMaterialClassifyName()) || row.getOrganizationId() == null) {
|
if (row.getOrganizationId() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<String> names = row.getMaterialClassifyName();
|
List<String> names = row.getMaterialClassifyName();
|
||||||
List<String> existing = row.getMaterialClassifyCode();
|
List<String> existing = row.getMaterialClassifyCode();
|
||||||
|
if (CollectionUtils.isEmpty(names) && CollectionUtils.isEmpty(existing)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int size = Math.max(names != null ? names.size() : 0, existing != null ? existing.size() : 0);
|
||||||
List<String> newCodes = new ArrayList<>();
|
List<String> newCodes = new ArrayList<>();
|
||||||
for (int i = 0; i < names.size(); i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
String fromExcel = (existing != null && i < existing.size()) ? existing.get(i) : null;
|
String fromExcel = (existing != null && i < existing.size()) ? existing.get(i) : null;
|
||||||
if (StringUtils.isNotBlank(fromExcel)) {
|
if (StringUtils.isNotBlank(fromExcel)) {
|
||||||
newCodes.add(fromExcel.trim());
|
newCodes.add(fromExcel.trim());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String n = StringUtils.trimToNull(names.get(i));
|
String n = (names != null && i < names.size()) ? StringUtils.trimToNull(names.get(i)) : null;
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
newCodes.add(null);
|
continue;
|
||||||
} else {
|
}
|
||||||
newCodes.add(resolveClassifyCodeByFeign(n, row.getOrganizationId()));
|
String resolved = resolveClassifyCodeByFeign(n, row.getOrganizationId());
|
||||||
|
if (StringUtils.isNotBlank(resolved)) {
|
||||||
|
newCodes.add(resolved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row.setMaterialClassifyCode(newCodes);
|
row.setMaterialClassifyCode(CollectionUtils.isEmpty(newCodes) ? null : newCodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 取 system 返回的 material_classify.code,写入本表 MATERIAL_CLASSIFY_CODE(List 中一项) */
|
/** 取 system 返回的 material_classify.code,写入本表 MATERIAL_CLASSIFY_CODE(List 中一项) */
|
||||||
private String resolveClassifyCodeByFeign(String keyword, Long organizationId) {
|
private String resolveClassifyCodeByFeign(String keyword, Long organizationId) {
|
||||||
|
if (StringUtils.isBlank(keyword) || organizationId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (String variant : ZhTextNormalizeUtil.nameLookupVariants(keyword)) {
|
||||||
|
String code = resolveClassifyCodeByFeignOnce(variant, organizationId);
|
||||||
|
if (StringUtils.isNotBlank(code)) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveClassifyCodeByFeignOnce(String keyword, Long organizationId) {
|
||||||
if (StringUtils.isBlank(keyword) || organizationId == null) {
|
if (StringUtils.isBlank(keyword) || organizationId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-5
@@ -31,7 +31,7 @@ public class MaterialBaseInfoDTO extends BaseVOEntity {
|
|||||||
private Long materialBaseInfoId;
|
private Long materialBaseInfoId;
|
||||||
|
|
||||||
@ApiModelProperty("组织表ID")
|
@ApiModelProperty("组织表ID")
|
||||||
@Excel(name = "组织表ID")
|
@Excel(name = "组织表id")
|
||||||
private Long organizationId;
|
private Long organizationId;
|
||||||
|
|
||||||
@ApiModelProperty("组织名称")
|
@ApiModelProperty("组织名称")
|
||||||
@@ -39,7 +39,7 @@ public class MaterialBaseInfoDTO extends BaseVOEntity {
|
|||||||
private String organizationName;
|
private String organizationName;
|
||||||
|
|
||||||
@ApiModelProperty("一级组织表ID")
|
@ApiModelProperty("一级组织表ID")
|
||||||
@Excel(name = "一级组织表ID")
|
@Excel(name = "一级组织表id")
|
||||||
private Long topOrganizationId;
|
private Long topOrganizationId;
|
||||||
|
|
||||||
@ApiModelProperty("货主id")
|
@ApiModelProperty("货主id")
|
||||||
@@ -67,16 +67,22 @@ public class MaterialBaseInfoDTO extends BaseVOEntity {
|
|||||||
private String barCode;
|
private String barCode;
|
||||||
|
|
||||||
@ApiModelProperty("物料分类编码")
|
@ApiModelProperty("物料分类编码")
|
||||||
@Excel(name = "物料分类编码")
|
@Excel(name = "物料分类编码", type = Excel.Type.EXPORT)
|
||||||
@TableField(typeHandler = ListTypeHandler.class)
|
@TableField(typeHandler = ListTypeHandler.class)
|
||||||
private List<String> materialClassifyCode;
|
private List<String> materialClassifyCode;
|
||||||
|
|
||||||
@ApiModelProperty("物料分类名称")
|
@ApiModelProperty("物料分类名称")
|
||||||
@Excel(name = "物料分类名称")
|
@Excel(name = "物料分类名称", type = Excel.Type.EXPORT)
|
||||||
@TableField(typeHandler = ListTypeHandler.class)
|
@TableField(typeHandler = ListTypeHandler.class)
|
||||||
private List<String> materialClassifyName;
|
private List<String> materialClassifyName;
|
||||||
|
@ApiModelProperty("物料分类编码(导入)")
|
||||||
|
@Excel(name = "物料分类编码", type = Excel.Type.IMPORT)
|
||||||
|
private String materialClassifyCodeImport;
|
||||||
|
@ApiModelProperty("物料分类名称(导入)")
|
||||||
|
@Excel(name = "物料分类名称", type = Excel.Type.IMPORT)
|
||||||
|
private String materialClassifyNameImport;
|
||||||
@ApiModelProperty("物料分类(导入)")
|
@ApiModelProperty("物料分类(导入)")
|
||||||
@Excel(name = "物料分类")
|
@Excel(name = "物料分类", type = Excel.Type.IMPORT)
|
||||||
private String materialClassifyImport;
|
private String materialClassifyImport;
|
||||||
|
|
||||||
@ApiModelProperty("物料种类编码 数据字典")
|
@ApiModelProperty("物料种类编码 数据字典")
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.mhd.wms.util;
|
||||||
|
|
||||||
|
import com.mhd.common.core.utils.poi.ExcelUtil;
|
||||||
|
import com.mhd.wms.interfaces.dto.materialBaseInfo.MaterialBaseInfoDTO;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.DataFormatter;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物料主数据导入:支持繁体中文表头的 Excel 解析。
|
||||||
|
*/
|
||||||
|
public final class MaterialBaseInfoImportExcelUtil {
|
||||||
|
|
||||||
|
private MaterialBaseInfoImportExcelUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<MaterialBaseInfoDTO> importRows(InputStream is) throws Exception {
|
||||||
|
Workbook workbook = WorkbookFactory.create(is);
|
||||||
|
try {
|
||||||
|
normalizeHeaderRow(workbook.getSheetAt(0), 0);
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
workbook.write(bos);
|
||||||
|
ExcelUtil<MaterialBaseInfoDTO> util = new ExcelUtil<>(MaterialBaseInfoDTO.class);
|
||||||
|
return util.importExcel(new ByteArrayInputStream(bos.toByteArray()));
|
||||||
|
} finally {
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void normalizeHeaderRow(Sheet sheet, int titleNum) {
|
||||||
|
if (sheet == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Row headerRow = sheet.getRow(titleNum);
|
||||||
|
if (headerRow == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DataFormatter formatter = new DataFormatter();
|
||||||
|
for (int i = 0; i < headerRow.getLastCellNum(); i++) {
|
||||||
|
Cell cell = headerRow.getCell(i);
|
||||||
|
if (cell == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String value = formatter.formatCellValue(cell);
|
||||||
|
if (StringUtils.isBlank(value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cell.setCellValue(ZhTextNormalizeUtil.normalizeExcelHeader(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.mhd.wms.util;
|
||||||
|
|
||||||
|
import com.github.houbb.opencc4j.util.ZhConverterUtil;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简繁体文本归一化,用于 Excel 导入表头及货主名称匹配。
|
||||||
|
*/
|
||||||
|
public final class ZhTextNormalizeUtil {
|
||||||
|
|
||||||
|
private ZhTextNormalizeUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toSimple(String text) {
|
||||||
|
if (StringUtils.isBlank(text)) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return ZhConverterUtil.toSimple(text.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toTraditional(String text) {
|
||||||
|
if (StringUtils.isBlank(text)) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return ZhConverterUtil.toTraditional(text.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入表头:繁体转简体,并将末尾 ID 统一为小写 id(与 @Excel name 一致)。
|
||||||
|
*/
|
||||||
|
public static String normalizeExcelHeader(String header) {
|
||||||
|
if (StringUtils.isBlank(header)) {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
String simple = toSimple(header.trim());
|
||||||
|
if (simple.endsWith("ID")) {
|
||||||
|
return simple.substring(0, simple.length() - 2) + "id";
|
||||||
|
}
|
||||||
|
return simple;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean textEquals(String a, String b) {
|
||||||
|
if (a == null && b == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a == null || b == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return toSimple(a).equals(toSimple(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean textContains(String haystack, String needle) {
|
||||||
|
if (StringUtils.isBlank(haystack) || StringUtils.isBlank(needle)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return toSimple(haystack).contains(toSimple(needle));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称查询候选:原文、简体、繁体(去重,保持顺序)。
|
||||||
|
*/
|
||||||
|
public static Set<String> nameLookupVariants(String name) {
|
||||||
|
Set<String> variants = new LinkedHashSet<>();
|
||||||
|
if (StringUtils.isBlank(name)) {
|
||||||
|
return variants;
|
||||||
|
}
|
||||||
|
String trimmed = name.trim();
|
||||||
|
variants.add(trimmed);
|
||||||
|
String simple = toSimple(trimmed);
|
||||||
|
if (StringUtils.isNotBlank(simple)) {
|
||||||
|
variants.add(simple);
|
||||||
|
}
|
||||||
|
String traditional = toTraditional(trimmed);
|
||||||
|
if (StringUtils.isNotBlank(traditional)) {
|
||||||
|
variants.add(traditional);
|
||||||
|
}
|
||||||
|
return variants;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user