物料导入繁体解析1
This commit is contained in:
+35
-23
@@ -435,12 +435,6 @@ public class MaterialBaseInfoApplicationService {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
|
||||
row.setOrganizationId(loginOrgId);
|
||||
}
|
||||
if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
|
||||
row.setTopOrganizationId(loginTopOrgId);
|
||||
}
|
||||
if (row.getNullify() == null) {
|
||||
row.setNullify(2);
|
||||
}
|
||||
@@ -450,11 +444,16 @@ public class MaterialBaseInfoApplicationService {
|
||||
if (StringUtils.isBlank(row.getHsCode()) && StringUtils.isNotBlank(row.getHsCodeImport())) {
|
||||
row.setHsCode(row.getHsCodeImport().trim());
|
||||
}
|
||||
// Excel 表头错位或重复时,HS 可能被读入「物料条形码」列;与 HS 完全相同时视为误填,保留 hsCode、清空条码
|
||||
normalizeImportBarCodeWhenDuplicateOfHs(row);
|
||||
// 先解析货主并补全组织,再做重复/存在性校验(组织维度依赖 organizationId)
|
||||
// 客户模板通常只有「货主名称」无「货主id」:须先按名称解析货主,再回填组织;勿提前写入登录组织以免组织校验拦截货主匹配
|
||||
fillIdsFromExistingMasterData(row);
|
||||
fillOrganizationFromShipperIfNeeded(row);
|
||||
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
|
||||
row.setOrganizationId(loginOrgId);
|
||||
}
|
||||
if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
|
||||
row.setTopOrganizationId(loginTopOrgId);
|
||||
}
|
||||
fillOrganizationName(row, loginUser);
|
||||
|
||||
String shipperCode = StringUtils.defaultString(row.getShipperCode(), "");
|
||||
@@ -677,15 +676,28 @@ public class MaterialBaseInfoApplicationService {
|
||||
String shipperName = StringUtils.isNotBlank(row.getShipperName()) ? row.getShipperName().trim() : null;
|
||||
String shipperCode = StringUtils.isNotBlank(row.getShipperCode()) ? row.getShipperCode().trim() : null;
|
||||
|
||||
UserPo matched = resolveShipperUserForImport(shipperName, shipperCode, importOrgId, true);
|
||||
if (matched == null) {
|
||||
matched = resolveShipperUserForImport(shipperName, shipperCode, importOrgId, false);
|
||||
}
|
||||
if (matched != null) {
|
||||
applyUserPoToMaterialImportRow(row, matched);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enforceOrganization true=货主 organizationId 须与 importOrgId 一致;false=跨组织也接受并回填货主所属组织
|
||||
*/
|
||||
private UserPo resolveShipperUserForImport(String shipperName, String shipperCode, Long importOrgId,
|
||||
boolean enforceOrganization) {
|
||||
if (StringUtils.isNotBlank(shipperName)) {
|
||||
for (String nameVariant : ZhTextNormalizeUtil.nameLookupVariants(shipperName)) {
|
||||
try {
|
||||
AjaxResult ajaxResult = userServiceFeign.getInfoByName(nameVariant);
|
||||
if ("200".equals(String.valueOf(ajaxResult.get("code"))) && ajaxResult.get("data") != null) {
|
||||
UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
|
||||
if (userPo != null && shipperUserMatchesImportOrganization(userPo, importOrgId)) {
|
||||
applyUserPoToMaterialImportRow(row, userPo);
|
||||
return;
|
||||
if (userPo != null && shipperUserMatchesImportOrganization(userPo, importOrgId, enforceOrganization)) {
|
||||
return userPo;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -697,7 +709,7 @@ public class MaterialBaseInfoApplicationService {
|
||||
try {
|
||||
AjaxResult shipperListResult = userServiceFeign.userShipperListAll();
|
||||
if (!"200".equals(String.valueOf(shipperListResult.get("code"))) || shipperListResult.get("data") == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
Object data = shipperListResult.get("data");
|
||||
List<Map<String, Object>> shipperList;
|
||||
@@ -719,7 +731,7 @@ public class MaterialBaseInfoApplicationService {
|
||||
shipperList = JSON.parseObject(JSONObject.toJSONString(data), new TypeReference<List<Map<String, Object>>>() { });
|
||||
}
|
||||
if (shipperList == null || shipperList.isEmpty()) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
for (Map<String, Object> shipper : shipperList) {
|
||||
if (shipper == null) {
|
||||
@@ -738,15 +750,15 @@ public class MaterialBaseInfoApplicationService {
|
||||
}
|
||||
String normalizedName = StringUtils.isNotBlank(shipperName) ? shipperName : "";
|
||||
String normalizedCode = StringUtils.isNotBlank(shipperCode) ? shipperCode : "";
|
||||
boolean matched = false;
|
||||
boolean nameMatched = false;
|
||||
if (StringUtils.isNotEmpty(normalizedCode)) {
|
||||
String c1 = userCode != null ? String.valueOf(userCode).trim() : "";
|
||||
String c2 = userMemberCode != null ? String.valueOf(userMemberCode).trim() : "";
|
||||
if (normalizedCode.equals(c1) || normalizedCode.equals(c2)) {
|
||||
matched = true;
|
||||
nameMatched = true;
|
||||
}
|
||||
}
|
||||
if (!matched && StringUtils.isNotEmpty(normalizedName)) {
|
||||
if (!nameMatched && StringUtils.isNotEmpty(normalizedName)) {
|
||||
for (Object cand : new Object[] { userName, entName }) {
|
||||
if (cand == null) {
|
||||
continue;
|
||||
@@ -754,12 +766,12 @@ public class MaterialBaseInfoApplicationService {
|
||||
String s = String.valueOf(cand).trim();
|
||||
if (ZhTextNormalizeUtil.textEquals(normalizedName, s)
|
||||
|| ZhTextNormalizeUtil.textContains(s, normalizedName)) {
|
||||
matched = true;
|
||||
nameMatched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matched && userId != null) {
|
||||
if (nameMatched && userId != null) {
|
||||
try {
|
||||
Long candidateId = Long.valueOf(String.valueOf(userId));
|
||||
AjaxResult infoRes = userServiceFeign.getInfo(candidateId);
|
||||
@@ -767,9 +779,8 @@ public class MaterialBaseInfoApplicationService {
|
||||
continue;
|
||||
}
|
||||
UserPo up = JSON.parseObject(JSONObject.toJSONString(infoRes.get("data")), UserPo.class);
|
||||
if (shipperUserMatchesImportOrganization(up, importOrgId)) {
|
||||
applyUserPoToMaterialImportRow(row, up);
|
||||
return;
|
||||
if (shipperUserMatchesImportOrganization(up, importOrgId, enforceOrganization)) {
|
||||
return up;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.debug("物料导入: 从货主列表解析用户失败: {}", ex.getMessage());
|
||||
@@ -779,6 +790,7 @@ public class MaterialBaseInfoApplicationService {
|
||||
} catch (Exception e) {
|
||||
log.debug("物料导入: userShipperListAll 失败: {}", e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void applyUserPoToMaterialImportRow(MaterialBaseInfoDTO row, UserPo userPo) {
|
||||
@@ -826,8 +838,8 @@ public class MaterialBaseInfoApplicationService {
|
||||
return organizationId != null && organizationId > 0;
|
||||
}
|
||||
|
||||
private boolean shipperUserMatchesImportOrganization(UserPo userPo, Long importOrganizationId) {
|
||||
if (importOrganizationId == null) {
|
||||
private boolean shipperUserMatchesImportOrganization(UserPo userPo, Long importOrganizationId, boolean enforceOrganization) {
|
||||
if (!enforceOrganization || importOrganizationId == null) {
|
||||
return true;
|
||||
}
|
||||
if (userPo == null) {
|
||||
|
||||
@@ -13,7 +13,9 @@ import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 物料主数据导入:支持繁体中文表头的 Excel 解析。
|
||||
@@ -23,6 +25,19 @@ public final class MaterialBaseInfoImportExcelUtil {
|
||||
private MaterialBaseInfoImportExcelUtil() {
|
||||
}
|
||||
|
||||
/** 客户模板常见表头别名 → 系统 @Excel 标准表头 */
|
||||
private static final Map<String, String> HEADER_ALIASES = new HashMap<>();
|
||||
|
||||
static {
|
||||
HEADER_ALIASES.put("条形码", "物料条形码");
|
||||
HEADER_ALIASES.put("保質期(天)", "保质期 单位:天");
|
||||
HEADER_ALIASES.put("保质期(天)", "保质期 单位:天");
|
||||
HEADER_ALIASES.put("净重(kg)", "净重 单位:千克");
|
||||
HEADER_ALIASES.put("淨重(kg)", "净重 单位:千克");
|
||||
HEADER_ALIASES.put("体积(m³)", "体积 单位:立方米");
|
||||
HEADER_ALIASES.put("體積(m³)", "体积 单位:立方米");
|
||||
}
|
||||
|
||||
public static List<MaterialBaseInfoDTO> importRows(InputStream is) throws Exception {
|
||||
Workbook workbook = WorkbookFactory.create(is);
|
||||
try {
|
||||
@@ -54,7 +69,9 @@ public final class MaterialBaseInfoImportExcelUtil {
|
||||
if (StringUtils.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
cell.setCellValue(ZhTextNormalizeUtil.normalizeExcelHeader(value));
|
||||
String normalized = ZhTextNormalizeUtil.normalizeExcelHeader(value);
|
||||
String alias = HEADER_ALIASES.get(normalized);
|
||||
cell.setCellValue(alias != null ? alias : normalized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,14 +49,25 @@ public final class ZhTextNormalizeUtil {
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
return toSimple(a).equals(toSimple(b));
|
||||
return normalizeNameKey(a).equals(normalizeNameKey(b));
|
||||
}
|
||||
|
||||
public static boolean textContains(String haystack, String needle) {
|
||||
if (StringUtils.isBlank(haystack) || StringUtils.isBlank(needle)) {
|
||||
return false;
|
||||
}
|
||||
return toSimple(haystack).contains(toSimple(needle));
|
||||
return normalizeNameKey(haystack).contains(normalizeNameKey(needle));
|
||||
}
|
||||
|
||||
/** 简繁体 + 全角括号等常见差异归一化,便于货主/分类名称匹配。 */
|
||||
public static String normalizeNameKey(String text) {
|
||||
if (StringUtils.isBlank(text)) {
|
||||
return text;
|
||||
}
|
||||
String s = toSimple(text.trim());
|
||||
s = s.replace('(', '(').replace(')', ')');
|
||||
s = s.replace(' ', ' ');
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user