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