物料导入繁体解析
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.exception.ServiceException;
|
||||
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.page.TableDataInfo;
|
||||
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.service.MaterialWarehouseControlDomainService;
|
||||
import com.mhd.wms.interfaces.dto.materialBaseInfo.MaterialBaseInfoDTO;
|
||||
import com.mhd.wms.util.MaterialBaseInfoImportExcelUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -54,6 +55,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -398,8 +400,7 @@ public class MaterialBaseInfoApplicationService {
|
||||
|
||||
final List<MaterialBaseInfoDTO> rows;
|
||||
try (InputStream is = file.getInputStream()) {
|
||||
ExcelUtil<MaterialBaseInfoDTO> util = new ExcelUtil<>(MaterialBaseInfoDTO.class);
|
||||
rows = util.importExcel(is);
|
||||
rows = MaterialBaseInfoImportExcelUtil.importRows(is);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("导入模板解析失败:" + e.getMessage());
|
||||
}
|
||||
@@ -434,10 +435,10 @@ public class MaterialBaseInfoApplicationService {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (row.getOrganizationId() == null && loginOrgId != null) {
|
||||
if (!isValidOrgId(row.getOrganizationId()) && isValidOrgId(loginOrgId)) {
|
||||
row.setOrganizationId(loginOrgId);
|
||||
}
|
||||
if (row.getTopOrganizationId() == null && loginTopOrgId != null) {
|
||||
if (row.getTopOrganizationId() == null && isValidOrgId(loginTopOrgId)) {
|
||||
row.setTopOrganizationId(loginTopOrgId);
|
||||
}
|
||||
if (row.getNullify() == null) {
|
||||
@@ -451,6 +452,9 @@ public class MaterialBaseInfoApplicationService {
|
||||
}
|
||||
// Excel 表头错位或重复时,HS 可能被读入「物料条形码」列;与 HS 完全相同时视为误填,保留 hsCode、清空条码
|
||||
normalizeImportBarCodeWhenDuplicateOfHs(row);
|
||||
// 先解析货主并补全组织,再做重复/存在性校验(组织维度依赖 organizationId)
|
||||
fillIdsFromExistingMasterData(row);
|
||||
fillOrganizationFromShipperIfNeeded(row);
|
||||
fillOrganizationName(row, loginUser);
|
||||
|
||||
String shipperCode = StringUtils.defaultString(row.getShipperCode(), "");
|
||||
@@ -473,8 +477,6 @@ public class MaterialBaseInfoApplicationService {
|
||||
errors.append("第").append(rowNum).append("行:物料已存在(组织+货主编码+物料编码);");
|
||||
continue;
|
||||
}
|
||||
// 根据导入的名称/编码回填现有ID,避免要求模板传ID
|
||||
fillIdsFromExistingMasterData(row);
|
||||
fillClassifyTypeAndUnit(row);
|
||||
|
||||
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())) {
|
||||
row.setPackName(row.getPackImport().trim());
|
||||
}
|
||||
// 货主:先按本组织已有物料反查,再用用户中心按「货主编码/货主名称」解析 userId(与入库单 import 一致;纯数字也可作名称,例如「1449」)
|
||||
// 货主:先按本组织已有物料反查,再用用户中心按「货主编码/货主名称」解析 userId(支持繁体名称)
|
||||
if (row.getShipperId() == null && (StringUtils.isNotBlank(row.getShipperCode()) || StringUtils.isNotBlank(row.getShipperName()))) {
|
||||
MaterialBaseInfo matched = materialBaseInfoService.getOne(new LambdaQueryWrapper<MaterialBaseInfo>()
|
||||
.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"));
|
||||
MaterialBaseInfo matched = findExistingMaterialByShipper(row);
|
||||
if (matched != null) {
|
||||
row.setShipperId(matched.getShipperId());
|
||||
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或主键,避免与业务上以数字作为企业简称/名称的货主(如「1449」)冲突。
|
||||
@@ -658,17 +678,19 @@ public class MaterialBaseInfoApplicationService {
|
||||
String shipperCode = StringUtils.isNotBlank(row.getShipperCode()) ? row.getShipperCode().trim() : null;
|
||||
|
||||
if (StringUtils.isNotBlank(shipperName)) {
|
||||
try {
|
||||
AjaxResult ajaxResult = userServiceFeign.getInfoByName(shipperName);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
String s = String.valueOf(cand).trim();
|
||||
if (normalizedName.equals(s) || s.contains(normalizedName)) {
|
||||
if (ZhTextNormalizeUtil.textEquals(normalizedName, s)
|
||||
|| ZhTextNormalizeUtil.textContains(s, normalizedName)) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
@@ -763,6 +786,15 @@ public class MaterialBaseInfoApplicationService {
|
||||
return;
|
||||
}
|
||||
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())) {
|
||||
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) {
|
||||
if (importOrganizationId == null) {
|
||||
return true;
|
||||
@@ -831,12 +886,7 @@ public class MaterialBaseInfoApplicationService {
|
||||
}
|
||||
|
||||
private void fillClassifyTypeAndUnit(MaterialBaseInfoDTO row) {
|
||||
// 物料分类:模板常用“物料分类”单列,回填到名称列表
|
||||
if (CollectionUtils.isEmpty(row.getMaterialClassifyName()) && StringUtils.isNotBlank(row.getMaterialClassifyImport())) {
|
||||
List<String> names = new ArrayList<>();
|
||||
names.add(row.getMaterialClassifyImport().trim());
|
||||
row.setMaterialClassifyName(names);
|
||||
}
|
||||
normalizeMaterialClassifyImportFields(row);
|
||||
// 按组织从 system 主数据反查分类编码,与名称列表对齐
|
||||
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 接口按组织+名称/编码/名称路径匹配并回填.
|
||||
* Excel 已填写的编码列优先保留。
|
||||
*/
|
||||
private void fillMaterialClassifyCodesFromSystem(MaterialBaseInfoDTO row) {
|
||||
if (CollectionUtils.isEmpty(row.getMaterialClassifyName()) || row.getOrganizationId() == null) {
|
||||
if (row.getOrganizationId() == null) {
|
||||
return;
|
||||
}
|
||||
List<String> names = row.getMaterialClassifyName();
|
||||
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<>();
|
||||
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;
|
||||
if (StringUtils.isNotBlank(fromExcel)) {
|
||||
newCodes.add(fromExcel.trim());
|
||||
continue;
|
||||
}
|
||||
String n = StringUtils.trimToNull(names.get(i));
|
||||
String n = (names != null && i < names.size()) ? StringUtils.trimToNull(names.get(i)) : null;
|
||||
if (n == null) {
|
||||
newCodes.add(null);
|
||||
} else {
|
||||
newCodes.add(resolveClassifyCodeByFeign(n, row.getOrganizationId()));
|
||||
continue;
|
||||
}
|
||||
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 中一项) */
|
||||
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) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+11
-5
@@ -31,7 +31,7 @@ public class MaterialBaseInfoDTO extends BaseVOEntity {
|
||||
private Long materialBaseInfoId;
|
||||
|
||||
@ApiModelProperty("组织表ID")
|
||||
@Excel(name = "组织表ID")
|
||||
@Excel(name = "组织表id")
|
||||
private Long organizationId;
|
||||
|
||||
@ApiModelProperty("组织名称")
|
||||
@@ -39,7 +39,7 @@ public class MaterialBaseInfoDTO extends BaseVOEntity {
|
||||
private String organizationName;
|
||||
|
||||
@ApiModelProperty("一级组织表ID")
|
||||
@Excel(name = "一级组织表ID")
|
||||
@Excel(name = "一级组织表id")
|
||||
private Long topOrganizationId;
|
||||
|
||||
@ApiModelProperty("货主id")
|
||||
@@ -67,16 +67,22 @@ public class MaterialBaseInfoDTO extends BaseVOEntity {
|
||||
private String barCode;
|
||||
|
||||
@ApiModelProperty("物料分类编码")
|
||||
@Excel(name = "物料分类编码")
|
||||
@Excel(name = "物料分类编码", type = Excel.Type.EXPORT)
|
||||
@TableField(typeHandler = ListTypeHandler.class)
|
||||
private List<String> materialClassifyCode;
|
||||
|
||||
@ApiModelProperty("物料分类名称")
|
||||
@Excel(name = "物料分类名称")
|
||||
@Excel(name = "物料分类名称", type = Excel.Type.EXPORT)
|
||||
@TableField(typeHandler = ListTypeHandler.class)
|
||||
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("物料分类(导入)")
|
||||
@Excel(name = "物料分类")
|
||||
@Excel(name = "物料分类", type = Excel.Type.IMPORT)
|
||||
private String materialClassifyImport;
|
||||
|
||||
@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