乱码注释调整

This commit is contained in:
liuminghui
2026-10-27 10:17:53 +08:00
parent f80af4a2f6
commit be0b067516
132 changed files with 440 additions and 440 deletions
@@ -9,7 +9,7 @@ import com.bms.price.domain.BmsProductImportTask;
import com.bms.price.domain.CatalogPreviewApplyRequest;
/**
* Product list service
* 产品列表服务
*
* @author bms
*/
@@ -9,7 +9,7 @@ import com.bms.price.domain.BmsRedlineProductImportTask;
import com.bms.price.domain.RedlineCatalogPreviewApplyRequest;
/**
* redline product list service
* 红线价产品列表服务
*
* @author bms
*/
@@ -19,7 +19,7 @@ import com.bms.price.domain.vo.TmsPriceBillRequest;
import com.bms.price.domain.vo.TmsPriceQuoteResult;
import com.bms.price.domain.vo.TmsOrderBillStatusResult;
/** Order billing: persist prc_order_bill + prc_income_bill/+fee. Payable (prc_pay_bill/+fee) skipped for now. */
/** 订单计费:写入 prc_order_bill 与 prc_income_bill 及其费用。应付(prc_pay_bill 及其费用)暂不处理。 */
public interface IPrcOrderBillService
{
TmsPriceQuoteResult bill(TmsPriceBillRequest request);
@@ -5,7 +5,7 @@ import java.util.List;
import com.bms.price.domain.PrcPriceExcelFile;
/**
* Import quote Excel attachment service
* 导入报价 Excel 附件服务
*/
public interface IPrcPriceExcelFileService
{
@@ -8,14 +8,14 @@ import java.util.Date;
import java.util.List;
/**
* TMS freight quote / bill calc service (shared by console trial and upstream bill).
* TMS 运费试算 / 计费计算服务(控制台试算与上游计费共用)。
*
* Match order:
* 1) Customer binds (package not stopped), bind_priority ASC; bind date range is not used for billing
* 2) Active package version at bill datetime (version effective_time / expire_time)
* 3) FIXED detail override, else DISCOUNT on that version
* 4) Else product default only when a version existed but detail missed
* Package hit uses version surcharge snapshot when present; else product library.
* 匹配顺序:
* 1) 客户绑定(套餐未停用),bind_priority 升序;绑定日期范围不参与计费时间判断
* 2) 计费时刻生效的套餐版本(version effective_time / expire_time)
* 3) 优先 FIXED 明细覆盖,否则用该版本的 DISCOUNT
* 4) 仅当版本存在但明细未命中时,才用产品默认价
* 命中套餐时,有版本附加费快照则用快照,否则用产品库。
*
* @author bms
*/
@@ -27,8 +27,8 @@ import com.bms.price.mapper.PrcOrderBillMapper;
import com.bms.system.service.IBmsProductCodeMappingService;
/**
* Compare local order-bill product codes against customer bound package SALES products.
* Also accepts product_code_mapping (upstream -> BMS).
* 把本地订单账单的产品代码与客户绑定套餐的 SALES 产品比对。
* 同时接受 product_code_mapping(上游代码 -> BMS)。
*/
@Service
public class OrderBillProductCheckService
@@ -61,7 +61,7 @@ import com.bms.system.domain.BmsRegion;
import com.bms.system.mapper.BmsRegionMapper;
/**
* Product service with Weishi Excel import (catalog + country weight bands)
* 产品服务,含威狮 Excel 导入(目录 + 国家重量段)
*
* @author bms
*/
@@ -70,18 +70,18 @@ public class BmsProductServiceImpl implements IBmsProductService
{
private static final Logger log = LoggerFactory.getLogger(BmsProductServiceImpl.class);
private static final String CATALOG_SHEET = "\u4ea7\u54c1\u76ee\u5f55";
private static final String CATALOG_SHEET = "产品目录";
private static final Set<String> SKIP_SHEETS = new HashSet<>(Arrays.asList(
CATALOG_SHEET, "\u9000\u4ef6\u91cd\u6d3e", "\u7533\u62a5\u8bf4\u660e", "\u8d54\u507f\u6807\u51c6"));
CATALOG_SHEET, "退件重派", "申报说明", "赔偿标准"));
private static final Pattern EFFECTIVE_DATE_PATTERN = Pattern.compile(
"\u751f\u6548\u65e5\u671f[\uff1a:]\\s*(\\d{4})[/.-](\\d{1,2})[/.-](\\d{1,2})");
"生效日期[::]\\s*(\\d{4})[/.-](\\d{1,2})[/.-](\\d{1,2})");
private static final Pattern EFFECTIVE_DATE_YMD = Pattern.compile(
"(\\d{4})[/.-](\\d{1,2})[/.-](\\d{1,2})");
private static final Pattern EFFECTIVE_DATE_CN = Pattern.compile(
"(\\d{4})\\s*\u5e74\\s*(\\d{1,2})\\s*\u6708\\s*(\\d{1,2})");
"(\\d{4})\\s*年\\s*(\\d{1,2})\\s*月\\s*(\\d{1,2})");
/** Parse 0.01\u2264W\u22640.3 / 0.3<W\u22641 */
/** Parse 0.01≤W≤0.3 / 0.3<W≤1 */
private static final Pattern WEIGHT_RANGE_PATTERN = Pattern.compile(
"(\\d+(?:\\.\\d+)?)\\s*[<\\u2264]=?\\s*W\\s*[<\\u2264]=?\\s*(\\d+(?:\\.\\d+)?)",
Pattern.CASE_INSENSITIVE);
@@ -178,7 +178,7 @@ public class BmsProductServiceImpl implements IBmsProductService
{
if (country == null || country.getDetailId() == null)
{
throw new ServiceException("\u660e\u7ec6\u884c\u4e3b\u952e\u7f3a\u5931\uff0c\u65e0\u6cd5\u4fee\u6539");
throw new ServiceException("明细行主键缺失,无法修改");
}
PrcPriceSetDetail old = detailMapper.selectPrcPriceSetDetailById(country.getDetailId());
int rows = countryMapper.updateBmsProductCountry(country);
@@ -257,7 +257,7 @@ public class BmsProductServiceImpl implements IBmsProductService
if (!notPendingTips.isEmpty())
{
throw new ServiceException(MessageUtils.message("price.product.delete.pendingOnly",
String.join("\u3001", notPendingTips)));
String.join("、", notPendingTips)));
}
if (deletableIds.isEmpty())
{
@@ -434,7 +434,7 @@ public class BmsProductServiceImpl implements IBmsProductService
{
tip = e.getClass().getSimpleName();
}
failureMsg.append("<br/>").append(product.getProductCode()).append("\uff1a").append(tip);
failureMsg.append("<br/>").append(product.getProductCode()).append(":").append(tip);
}
}
@@ -450,7 +450,7 @@ public class BmsProductServiceImpl implements IBmsProductService
+ "<br/>" + MessageUtils.message("price.product.import.success.detail2");
if (!unmatchedCountries.isEmpty())
{
msg += "<br/>" + MessageUtils.message("price.product.import.success.unmatched", String.join("\u3001", unmatchedCountries));
msg += "<br/>" + MessageUtils.message("price.product.import.success.unmatched", String.join("、", unmatchedCountries));
}
return msg;
}
@@ -576,7 +576,7 @@ public class BmsProductServiceImpl implements IBmsProductService
{
tip = e.getClass().getSimpleName();
}
failureMsg.append("<br/>").append(product.getProductCode()).append("\uff1a").append(tip);
failureMsg.append("<br/>").append(product.getProductCode()).append(":").append(tip);
}
}
@@ -717,7 +717,7 @@ public class BmsProductServiceImpl implements IBmsProductService
continue;
}
Sheet sheet = workbook.getSheetAt(i);
if (sheet == null || findHeaderCell(sheet, "\u56fd\u5bb6") == null)
if (sheet == null || findHeaderCell(sheet, "国家") == null)
{
continue;
}
@@ -918,7 +918,7 @@ public class BmsProductServiceImpl implements IBmsProductService
}
if (files.size() > com.bms.price.service.support.UploadFileBatch.MAX_FILES)
{
throw new ServiceException("\u5355\u6b21\u6700\u591a\u5bfc\u5165 5 \u4e2a\u6587\u4ef6");
throw new ServiceException("单次最多导入 5 个文件");
}
for (MultipartFile file : files)
{
@@ -1666,9 +1666,9 @@ public class BmsProductServiceImpl implements IBmsProductService
private List<BmsProduct> parseCatalog(Sheet sheet)
{
List<BmsProduct> list = new ArrayList<>();
// Header is "\u5bf9\u63a5\u4ee3\u7801" or legacy "\u4ea7\u54c1\u5bf9\u63a5\u4ee3\u7801". Column A is often empty.
// 20260928 layout inserts "\u8ba1\u6ce1\u89c4\u5219" before country, so map by header name.
int[] header = findHeaderCell(sheet, "\u5bf9\u63a5\u4ee3\u7801");
// Header is "对接代码" or legacy "产品对接代码". Column A is often empty.
// 20260928 layout inserts "计泡规则" before country, so map by header name.
int[] header = findHeaderCell(sheet, "对接代码");
if (header == null)
{
throw new ServiceException(MessageUtils.message("price.product.import.catalogHeaderMissing"));
@@ -1676,20 +1676,20 @@ public class BmsProductServiceImpl implements IBmsProductService
int headerRowIdx = header[0];
int colCode = header[1];
Row head = sheet.getRow(headerRowIdx);
int colName = catalogColumn(head, "\u4ea7\u54c1\u540d\u79f0", colCode + 1);
int colLevel = catalogColumn(head, "\u65f6\u6548", colCode + 2);
int colCargo = catalogColumn(head, "\u8d70\u8d27\u5c5e\u6027", colCode + 3);
int colDest = findColByHeader(head, "\u56fd\u5bb6", colCode);
int colName = catalogColumn(head, "产品名称", colCode + 1);
int colLevel = catalogColumn(head, "时效", colCode + 2);
int colCargo = catalogColumn(head, "走货属性", colCode + 3);
int colDest = findColByHeader(head, "国家", colCode);
if (colDest < 0)
{
colDest = findColByHeader(head, "\u76ee\u7684", colCode);
colDest = findColByHeader(head, "目的", colCode);
}
if (colDest < 0)
{
colDest = colCode + 4;
}
int colNote = catalogColumn(head, "\u66f4\u65b0\u5185\u5bb9", colCode + 5);
int colDate = catalogColumn(head, "\u751f\u6548", colCode + 6);
int colNote = catalogColumn(head, "更新内容", colCode + 5);
int colDate = catalogColumn(head, "生效", colCode + 6);
int lastRow = sheet.getLastRowNum();
for (int i = headerRowIdx + 1; i <= lastRow; i++)
{
@@ -1699,7 +1699,7 @@ public class BmsProductServiceImpl implements IBmsProductService
continue;
}
String code = cellString(row.getCell(colCode));
if (StringUtils.isEmpty(code) || code.contains("\u5bf9\u63a5\u4ee3\u7801"))
if (StringUtils.isEmpty(code) || code.contains("对接代码"))
{
continue;
}
@@ -1822,8 +1822,8 @@ public class BmsProductServiceImpl implements IBmsProductService
return "";
}
String out = s.trim().toLowerCase(Locale.ROOT);
// unify dash variants: - \u2013 \u2014 \uff0d
out = out.replace('\u2013', '-').replace('\u2014', '-').replace('\uff0d', '-');
// unify dash variants: - – — -
out = out.replace('–', '-').replace('—', '-').replace('-', '-');
out = out.replace(" ", "").replace("\u3000", "");
return out;
}
@@ -1879,10 +1879,10 @@ public class BmsProductServiceImpl implements IBmsProductService
return false;
}
String n = name.trim();
return "\u6b27\u76df".equals(n)
return "欧盟".equals(n)
|| "EU".equalsIgnoreCase(n)
|| "\u6b27\u6d32\u8054\u76df".equals(n)
|| "\u6b27\u76df\u56fd\u5bb6".equals(n);
|| "欧洲联盟".equals(n)
|| "欧盟国家".equals(n);
}
private List<BmsProductCountry> parseProductSheet(Sheet sheet, BmsProduct product,
@@ -1896,7 +1896,7 @@ public class BmsProductServiceImpl implements IBmsProductService
Date sheetEffective = parseSheetEffectiveDate(sheet);
List<BmsProductCountry> list = new ArrayList<>();
int[] countryHeader = findHeaderCell(sheet, "\u56fd\u5bb6");
int[] countryHeader = findHeaderCell(sheet, "国家");
if (countryHeader == null)
{
return list;
@@ -1904,12 +1904,12 @@ public class BmsProductServiceImpl implements IBmsProductService
int headerRowIdx = countryHeader[0];
Row headerRow = sheet.getRow(headerRowIdx);
int colCountry = countryHeader[1];
int colWeight = findColByHeader(headerRow, "\u91cd\u91cf", colCountry + 1);
int colFreight = findColByHeader(headerRow, "\u8fd0\u8d39", colCountry + 1);
int colRegister = findColByHeader(headerRow, "\u6302\u53f7", colCountry + 1);
int colSize = findColByHeader(headerRow, "\u5c3a\u5bf8", colCountry + 1);
int colLastMile = findColByHeader(headerRow, "\u5c3e\u7a0b", colCountry + 1);
int colLeadTime = findColByHeader(headerRow, "\u65f6\u6548", colCountry + 1);
int colWeight = findColByHeader(headerRow, "重量", colCountry + 1);
int colFreight = findColByHeader(headerRow, "运费", colCountry + 1);
int colRegister = findColByHeader(headerRow, "挂号", colCountry + 1);
int colSize = findColByHeader(headerRow, "尺寸", colCountry + 1);
int colLastMile = findColByHeader(headerRow, "尾程", colCountry + 1);
int colLeadTime = findColByHeader(headerRow, "时效", colCountry + 1);
if (colWeight < 0)
{
colWeight = colCountry + 1;
@@ -1949,7 +1949,7 @@ public class BmsProductServiceImpl implements IBmsProductService
}
String countryCell = cellString(row.getCell(colCountry));
String weightLabel = cellString(row.getCell(colWeight));
if ("\u56fd\u5bb6".equals(countryCell) || weightLabel.contains("\u91cd\u91cf\u6bb5"))
if ("国家".equals(countryCell) || weightLabel.contains("重量段"))
{
continue;
}
@@ -2232,7 +2232,7 @@ public class BmsProductServiceImpl implements IBmsProductService
{
return parseYmd(cn.group(1), cn.group(2), cn.group(3));
}
if (text.contains("\u751f\u6548"))
if (text.contains("生效"))
{
Matcher ymd = EFFECTIVE_DATE_YMD.matcher(text);
if (ymd.find())
@@ -2262,11 +2262,11 @@ public class BmsProductServiceImpl implements IBmsProductService
private static String resolveTaxMode(String productName)
{
if (productName != null && productName.contains("\u5305\u7a0e"))
if (productName != null && productName.contains("包税"))
{
return "TAX_INCLUDED";
}
if (productName != null && productName.contains("\u4e0d\u5305\u7a0e"))
if (productName != null && productName.contains("不包税"))
{
return "TAX_EXCLUDED";
}
@@ -2407,13 +2407,13 @@ public class BmsProductServiceImpl implements IBmsProductService
}
s = s.trim();
// Excel NA markers: / 、- 、— 、N/A
if ("/".equals(s) || "-".equals(s) || "\u2014".equals(s) || "\uff0d".equals(s)
if ("/".equals(s) || "-".equals(s) || "—".equals(s) || "-".equals(s)
|| "N/A".equalsIgnoreCase(s) || "NA".equalsIgnoreCase(s))
{
return null;
}
// strip currency / unit suffixes: 56、56元、56 RMB
s = s.replace(",", "").replace("\uffe5", "").replace("\u5143", "")
s = s.replace(",", "").replace("¥", "").replace("元", "")
.replace("RMB", "").replace("rmb", "").trim();
if (s.isEmpty() || "/".equals(s))
{
@@ -2448,22 +2448,22 @@ public class BmsProductServiceImpl implements IBmsProductService
private List<BmsProduct> parseCountryCatalog(Sheet sheet)
{
List<BmsProduct> list = new ArrayList<>();
int[] header = findHeaderCell(sheet, "\u4ea7\u54c1\u540d\u79f0");
int[] header = findHeaderCell(sheet, "产品名称");
if (header == null)
{
header = findHeaderCell(sheet, "\u4ea7\u54c1ID");
header = findHeaderCell(sheet, "产品ID");
}
if (header == null)
{
throw new ServiceException(MessageUtils.message("price.product.import.countryCatalogHeaderMissing"));
}
Row head = sheet.getRow(header[0]);
int colCode = firstCol(head, "\u4ea7\u54c1ID", "\u4ea7\u54c1\u5bf9\u63a5\u4ee3\u7801", "\u4ea7\u54c1\u4ee3\u7801");
int colName = findColByHeader(head, "\u4ea7\u54c1\u540d\u79f0", 0);
int colService = firstCol(head, "\u670d\u52a1", "\u65f6\u6548\u7b49\u7ea7");
int colCargo = findColByHeader(head, "\u8d70\u8d27\u5c5e\u6027", 0);
int colNote = firstCol(head, "\u5907\u6ce8", "\u66f4\u65b0\u5185\u5bb9");
int colDate = firstCol(head, "\u66f4\u65b0\u65f6\u95f4", "\u751f\u6548\u65e5\u671f");
int colCode = firstCol(head, "产品ID", "产品对接代码", "产品代码");
int colName = findColByHeader(head, "产品名称", 0);
int colService = firstCol(head, "服务", "时效等级");
int colCargo = findColByHeader(head, "走货属性", 0);
int colNote = firstCol(head, "备注", "更新内容");
int colDate = firstCol(head, "更新时间", "生效日期");
if (colCode < 0 || colName < 0)
{
return list;
@@ -2531,23 +2531,23 @@ public class BmsProductServiceImpl implements IBmsProductService
continue;
}
Sheet sheet = workbook.getSheetAt(i);
int[] header = findHeaderCell(sheet, "\u4ea7\u54c1\u540d\u79f0");
int[] header = findHeaderCell(sheet, "产品名称");
if (header == null)
{
continue;
}
Row headerRow = sheet.getRow(header[0]);
int colName = header[1];
int colWeight = findColByHeader(headerRow, "\u91cd\u91cf", 0);
int colWeight = findColByHeader(headerRow, "重量", 0);
if (colWeight < 0)
{
continue;
}
int colFreight = findColByHeader(headerRow, "\u8fd0\u8d39", 0);
int colRegister = findColByHeader(headerRow, "\u6302\u53f7", 0);
int colSize = findColByHeader(headerRow, "\u5c3a\u5bf8", 0);
int colLastMile = findColByHeader(headerRow, "\u5c3e\u7a0b", 0);
int colLeadTime = findColByHeader(headerRow, "\u65f6\u6548", 0);
int colFreight = findColByHeader(headerRow, "运费", 0);
int colRegister = findColByHeader(headerRow, "挂号", 0);
int colSize = findColByHeader(headerRow, "尺寸", 0);
int colLastMile = findColByHeader(headerRow, "尾程", 0);
int colLeadTime = findColByHeader(headerRow, "时效", 0);
String currentName = null;
String currentSize = null;
@@ -2627,7 +2627,7 @@ public class BmsProductServiceImpl implements IBmsProductService
{
return true;
}
return name.contains("\u90ae\u7f16") || name.contains("\u8d54\u507f");
return name.contains("邮编") || name.contains("赔偿");
}
private static boolean isSectionTitle(String name)
@@ -2637,9 +2637,9 @@ public class BmsProductServiceImpl implements IBmsProductService
return false;
}
String n = name.trim();
return n.startsWith("\u4e00\u3001") || n.startsWith("\u4e8c\u3001") || n.startsWith("\u4e09\u3001")
|| n.startsWith("\u56db\u3001") || n.startsWith("\u4e94\u3001") || n.startsWith("\u516d\u3001")
|| n.startsWith("\u7279\u522b");
return n.startsWith("一、") || n.startsWith("二、") || n.startsWith("三、")
|| n.startsWith("四、") || n.startsWith("五、") || n.startsWith("六、")
|| n.startsWith("特别");
}
private PriceBlock findPriceBlock(String productName, Map<String, PriceBlock> blocks)
@@ -2654,7 +2654,7 @@ public class BmsProductServiceImpl implements IBmsProductService
{
return exact;
}
String stripped = name.replace("\u6807\u51c6", "").trim();
String stripped = name.replace("标准", "").trim();
exact = blocks.get(stripped);
if (exact != null)
{
@@ -2682,7 +2682,7 @@ public class BmsProductServiceImpl implements IBmsProductService
return "";
}
return s.trim().replace(" ", "").replace("\u3000", "")
.replace("-", "").replace("\u2013", "").replace("\u2014", "").replace("\uff0d", "");
.replace("-", "").replace("–", "").replace("—", "").replace("-", "");
}
private List<BmsProductCountry> stampSelectedCountry(List<BmsProductCountry> rows, BmsRegion region, Date eff)
@@ -2797,7 +2797,7 @@ public class BmsProductServiceImpl implements IBmsProductService
continue;
}
Sheet sheet = workbook.getSheetAt(i);
if (sheet == null || findHeaderCell(sheet, "\u56fd\u5bb6") == null)
if (sheet == null || findHeaderCell(sheet, "国家") == null)
{
continue;
}
@@ -2881,7 +2881,7 @@ public class BmsProductServiceImpl implements IBmsProductService
String name = product == null || StringUtils.isEmpty(product.getProductName())
? "-" : product.getProductName();
return MessageUtils.message("price.product.import.dupCountry.item",
code, name, String.join("\u3001", dups));
code, name, String.join("、", dups));
}
private List<String> findDuplicateCountryWeightLabels(List<BmsProductCountry> rows)
@@ -60,25 +60,25 @@ import com.bms.system.domain.BmsRegion;
import com.bms.system.mapper.BmsRegionMapper;
/**
* Product service with Weishi Excel import (catalog + country weight bands)
* 产品服务,含威狮 Excel 导入(目录 + 国家重量段)
*
* @author bms
*/
@Service
public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
{
private static final String CATALOG_SHEET = "\u4ea7\u54c1\u76ee\u5f55";
private static final String CATALOG_SHEET = "产品目录";
private static final Set<String> SKIP_SHEETS = new HashSet<>(Arrays.asList(
CATALOG_SHEET, "\u9000\u4ef6\u91cd\u6d3e", "\u7533\u62a5\u8bf4\u660e", "\u8d54\u507f\u6807\u51c6"));
CATALOG_SHEET, "退件重派", "申报说明", "赔偿标准"));
private static final Pattern EFFECTIVE_DATE_PATTERN = Pattern.compile(
"\u751f\u6548\u65e5\u671f[\uff1a:]\\s*(\\d{4})[/.-](\\d{1,2})[/.-](\\d{1,2})");
"生效日期[::]\\s*(\\d{4})[/.-](\\d{1,2})[/.-](\\d{1,2})");
private static final Pattern EFFECTIVE_DATE_YMD = Pattern.compile(
"(\\d{4})[/.-](\\d{1,2})[/.-](\\d{1,2})");
private static final Pattern EFFECTIVE_DATE_CN = Pattern.compile(
"(\\d{4})\\s*\u5e74\\s*(\\d{1,2})\\s*\u6708\\s*(\\d{1,2})");
"(\\d{4})\\s*年\\s*(\\d{1,2})\\s*月\\s*(\\d{1,2})");
/** Parse 0.01\u2264W\u22640.3 / 0.3<W\u22641 */
/** Parse 0.01≤W≤0.3 / 0.3<W≤1 */
private static final Pattern WEIGHT_RANGE_PATTERN = Pattern.compile(
"(\\d+(?:\\.\\d+)?)\\s*[<\\u2264]=?\\s*W\\s*[<\\u2264]=?\\s*(\\d+(?:\\.\\d+)?)",
Pattern.CASE_INSENSITIVE);
@@ -175,7 +175,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
{
if (country == null || country.getDetailId() == null)
{
throw new ServiceException("\u660e\u7ec6\u884c\u4e3b\u952e\u7f3a\u5931\uff0c\u65e0\u6cd5\u4fee\u6539");
throw new ServiceException("明细行主键缺失,无法修改");
}
PrcPriceSetDetail old = detailMapper.selectPrcPriceSetDetailById(country.getDetailId());
int rows = countryMapper.updateBmsRedlineProductCountry(country);
@@ -254,7 +254,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
if (!notPendingTips.isEmpty())
{
throw new ServiceException(MessageUtils.message("price.redline.delete.pendingOnly",
String.join("\u3001", notPendingTips)));
String.join("、", notPendingTips)));
}
if (deletableIds.isEmpty())
{
@@ -432,7 +432,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
{
tip = e.getClass().getSimpleName();
}
failureMsg.append("<br/>").append(product.getProductCode()).append("\uff1a").append(tip);
failureMsg.append("<br/>").append(product.getProductCode()).append(":").append(tip);
}
}
@@ -448,7 +448,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
+ "<br/>" + MessageUtils.message("price.product.import.success.detail2");
if (!unmatchedCountries.isEmpty())
{
msg += "<br/>" + MessageUtils.message("price.product.import.success.unmatched", String.join("\u3001", unmatchedCountries));
msg += "<br/>" + MessageUtils.message("price.product.import.success.unmatched", String.join("、", unmatchedCountries));
}
return msg;
}
@@ -574,7 +574,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
{
tip = e.getClass().getSimpleName();
}
failureMsg.append("<br/>").append(product.getProductCode()).append("\uff1a").append(tip);
failureMsg.append("<br/>").append(product.getProductCode()).append(":").append(tip);
}
}
@@ -769,7 +769,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
}
if (files.size() > com.bms.price.service.support.UploadFileBatch.MAX_FILES)
{
throw new ServiceException("\u5355\u6b21\u6700\u591a\u5bfc\u5165 5 \u4e2a\u6587\u4ef6");
throw new ServiceException("单次最多导入 5 个文件");
}
for (MultipartFile file : files)
{
@@ -1497,9 +1497,9 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
private List<BmsRedlineProduct> parseCatalog(Sheet sheet)
{
List<BmsRedlineProduct> list = new ArrayList<>();
// Header is "\u5bf9\u63a5\u4ee3\u7801" or legacy "\u4ea7\u54c1\u5bf9\u63a5\u4ee3\u7801". Column A is often empty.
// 20260928 layout inserts "\u8ba1\u6ce1\u89c4\u5219" before country, so map by header name.
int[] header = findHeaderCell(sheet, "\u5bf9\u63a5\u4ee3\u7801");
// Header is "对接代码" or legacy "产品对接代码". Column A is often empty.
// 20260928 layout inserts "计泡规则" before country, so map by header name.
int[] header = findHeaderCell(sheet, "对接代码");
if (header == null)
{
throw new ServiceException(MessageUtils.message("price.product.import.catalogHeaderMissing"));
@@ -1507,20 +1507,20 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
int headerRowIdx = header[0];
int colCode = header[1];
Row head = sheet.getRow(headerRowIdx);
int colName = catalogColumn(head, "\u4ea7\u54c1\u540d\u79f0", colCode + 1);
int colLevel = catalogColumn(head, "\u65f6\u6548", colCode + 2);
int colCargo = catalogColumn(head, "\u8d70\u8d27\u5c5e\u6027", colCode + 3);
int colDest = findColByHeader(head, "\u56fd\u5bb6", colCode);
int colName = catalogColumn(head, "产品名称", colCode + 1);
int colLevel = catalogColumn(head, "时效", colCode + 2);
int colCargo = catalogColumn(head, "走货属性", colCode + 3);
int colDest = findColByHeader(head, "国家", colCode);
if (colDest < 0)
{
colDest = findColByHeader(head, "\u76ee\u7684", colCode);
colDest = findColByHeader(head, "目的", colCode);
}
if (colDest < 0)
{
colDest = colCode + 4;
}
int colNote = catalogColumn(head, "\u66f4\u65b0\u5185\u5bb9", colCode + 5);
int colDate = catalogColumn(head, "\u751f\u6548", colCode + 6);
int colNote = catalogColumn(head, "更新内容", colCode + 5);
int colDate = catalogColumn(head, "生效", colCode + 6);
int lastRow = sheet.getLastRowNum();
for (int i = headerRowIdx + 1; i <= lastRow; i++)
{
@@ -1530,7 +1530,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
continue;
}
String code = cellString(row.getCell(colCode));
if (StringUtils.isEmpty(code) || code.contains("\u5bf9\u63a5\u4ee3\u7801"))
if (StringUtils.isEmpty(code) || code.contains("对接代码"))
{
continue;
}
@@ -1647,8 +1647,8 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
return "";
}
String out = s.trim().toLowerCase(Locale.ROOT);
// unify dash variants: - \u2013 \u2014 \uff0d
out = out.replace('\u2013', '-').replace('\u2014', '-').replace('\uff0d', '-');
// unify dash variants: - – — -
out = out.replace('–', '-').replace('—', '-').replace('-', '-');
out = out.replace(" ", "").replace("\u3000", "");
return out;
}
@@ -1689,10 +1689,10 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
return false;
}
String n = name.trim();
return "\u6b27\u76df".equals(n)
return "欧盟".equals(n)
|| "EU".equalsIgnoreCase(n)
|| "\u6b27\u6d32\u8054\u76df".equals(n)
|| "\u6b27\u76df\u56fd\u5bb6".equals(n);
|| "欧洲联盟".equals(n)
|| "欧盟国家".equals(n);
}
private List<BmsRedlineProductCountry> parseProductSheet(Sheet sheet, BmsRedlineProduct product,
@@ -1706,7 +1706,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
Date sheetEffective = parseSheetEffectiveDate(sheet);
List<BmsRedlineProductCountry> list = new ArrayList<>();
int[] countryHeader = findHeaderCell(sheet, "\u56fd\u5bb6");
int[] countryHeader = findHeaderCell(sheet, "国家");
if (countryHeader == null)
{
return list;
@@ -1714,12 +1714,12 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
int headerRowIdx = countryHeader[0];
Row headerRow = sheet.getRow(headerRowIdx);
int colCountry = countryHeader[1];
int colWeight = findColByHeader(headerRow, "\u91cd\u91cf", colCountry + 1);
int colFreight = findColByHeader(headerRow, "\u8fd0\u8d39", colCountry + 1);
int colRegister = findColByHeader(headerRow, "\u6302\u53f7", colCountry + 1);
int colSize = findColByHeader(headerRow, "\u5c3a\u5bf8", colCountry + 1);
int colLastMile = findColByHeader(headerRow, "\u5c3e\u7a0b", colCountry + 1);
int colLeadTime = findColByHeader(headerRow, "\u65f6\u6548", colCountry + 1);
int colWeight = findColByHeader(headerRow, "重量", colCountry + 1);
int colFreight = findColByHeader(headerRow, "运费", colCountry + 1);
int colRegister = findColByHeader(headerRow, "挂号", colCountry + 1);
int colSize = findColByHeader(headerRow, "尺寸", colCountry + 1);
int colLastMile = findColByHeader(headerRow, "尾程", colCountry + 1);
int colLeadTime = findColByHeader(headerRow, "时效", colCountry + 1);
if (colWeight < 0)
{
colWeight = colCountry + 1;
@@ -1759,7 +1759,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
}
String countryCell = cellString(row.getCell(colCountry));
String weightLabel = cellString(row.getCell(colWeight));
if ("\u56fd\u5bb6".equals(countryCell) || weightLabel.contains("\u91cd\u91cf\u6bb5"))
if ("国家".equals(countryCell) || weightLabel.contains("重量段"))
{
continue;
}
@@ -2042,7 +2042,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
{
return parseYmd(cn.group(1), cn.group(2), cn.group(3));
}
if (text.contains("\u751f\u6548"))
if (text.contains("生效"))
{
Matcher ymd = EFFECTIVE_DATE_YMD.matcher(text);
if (ymd.find())
@@ -2072,11 +2072,11 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
private static String resolveTaxMode(String productName)
{
if (productName != null && productName.contains("\u5305\u7a0e"))
if (productName != null && productName.contains("包税"))
{
return "TAX_INCLUDED";
}
if (productName != null && productName.contains("\u4e0d\u5305\u7a0e"))
if (productName != null && productName.contains("不包税"))
{
return "TAX_EXCLUDED";
}
@@ -2217,13 +2217,13 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
}
s = s.trim();
// Excel NA markers: / 、- 、— 、N/A
if ("/".equals(s) || "-".equals(s) || "\u2014".equals(s) || "\uff0d".equals(s)
if ("/".equals(s) || "-".equals(s) || "—".equals(s) || "-".equals(s)
|| "N/A".equalsIgnoreCase(s) || "NA".equalsIgnoreCase(s))
{
return null;
}
// strip currency / unit suffixes: 56、56元、56 RMB
s = s.replace(",", "").replace("\uffe5", "").replace("\u5143", "")
s = s.replace(",", "").replace("¥", "").replace("元", "")
.replace("RMB", "").replace("rmb", "").trim();
if (s.isEmpty() || "/".equals(s))
{
@@ -2258,22 +2258,22 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
private List<BmsRedlineProduct> parseCountryCatalog(Sheet sheet)
{
List<BmsRedlineProduct> list = new ArrayList<>();
int[] header = findHeaderCell(sheet, "\u4ea7\u54c1\u540d\u79f0");
int[] header = findHeaderCell(sheet, "产品名称");
if (header == null)
{
header = findHeaderCell(sheet, "\u4ea7\u54c1ID");
header = findHeaderCell(sheet, "产品ID");
}
if (header == null)
{
throw new ServiceException(MessageUtils.message("price.product.import.countryCatalogHeaderMissing"));
}
Row head = sheet.getRow(header[0]);
int colCode = firstCol(head, "\u4ea7\u54c1ID", "\u4ea7\u54c1\u5bf9\u63a5\u4ee3\u7801", "\u4ea7\u54c1\u4ee3\u7801");
int colName = findColByHeader(head, "\u4ea7\u54c1\u540d\u79f0", 0);
int colService = firstCol(head, "\u670d\u52a1", "\u65f6\u6548\u7b49\u7ea7");
int colCargo = findColByHeader(head, "\u8d70\u8d27\u5c5e\u6027", 0);
int colNote = firstCol(head, "\u5907\u6ce8", "\u66f4\u65b0\u5185\u5bb9");
int colDate = firstCol(head, "\u66f4\u65b0\u65f6\u95f4", "\u751f\u6548\u65e5\u671f");
int colCode = firstCol(head, "产品ID", "产品对接代码", "产品代码");
int colName = findColByHeader(head, "产品名称", 0);
int colService = firstCol(head, "服务", "时效等级");
int colCargo = findColByHeader(head, "走货属性", 0);
int colNote = firstCol(head, "备注", "更新内容");
int colDate = firstCol(head, "更新时间", "生效日期");
if (colCode < 0 || colName < 0)
{
return list;
@@ -2341,23 +2341,23 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
continue;
}
Sheet sheet = workbook.getSheetAt(i);
int[] header = findHeaderCell(sheet, "\u4ea7\u54c1\u540d\u79f0");
int[] header = findHeaderCell(sheet, "产品名称");
if (header == null)
{
continue;
}
Row headerRow = sheet.getRow(header[0]);
int colName = header[1];
int colWeight = findColByHeader(headerRow, "\u91cd\u91cf", 0);
int colWeight = findColByHeader(headerRow, "重量", 0);
if (colWeight < 0)
{
continue;
}
int colFreight = findColByHeader(headerRow, "\u8fd0\u8d39", 0);
int colRegister = findColByHeader(headerRow, "\u6302\u53f7", 0);
int colSize = findColByHeader(headerRow, "\u5c3a\u5bf8", 0);
int colLastMile = findColByHeader(headerRow, "\u5c3e\u7a0b", 0);
int colLeadTime = findColByHeader(headerRow, "\u65f6\u6548", 0);
int colFreight = findColByHeader(headerRow, "运费", 0);
int colRegister = findColByHeader(headerRow, "挂号", 0);
int colSize = findColByHeader(headerRow, "尺寸", 0);
int colLastMile = findColByHeader(headerRow, "尾程", 0);
int colLeadTime = findColByHeader(headerRow, "时效", 0);
String currentName = null;
String currentSize = null;
@@ -2437,7 +2437,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
{
return true;
}
return name.contains("\u90ae\u7f16") || name.contains("\u8d54\u507f");
return name.contains("邮编") || name.contains("赔偿");
}
private static boolean isSectionTitle(String name)
@@ -2447,9 +2447,9 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
return false;
}
String n = name.trim();
return n.startsWith("\u4e00\u3001") || n.startsWith("\u4e8c\u3001") || n.startsWith("\u4e09\u3001")
|| n.startsWith("\u56db\u3001") || n.startsWith("\u4e94\u3001") || n.startsWith("\u516d\u3001")
|| n.startsWith("\u7279\u522b");
return n.startsWith("一、") || n.startsWith("二、") || n.startsWith("三、")
|| n.startsWith("四、") || n.startsWith("五、") || n.startsWith("六、")
|| n.startsWith("特别");
}
private PriceBlock findPriceBlock(String productName, Map<String, PriceBlock> blocks)
@@ -2464,7 +2464,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
{
return exact;
}
String stripped = name.replace("\u6807\u51c6", "").trim();
String stripped = name.replace("标准", "").trim();
exact = blocks.get(stripped);
if (exact != null)
{
@@ -2492,7 +2492,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
return "";
}
return s.trim().replace(" ", "").replace("\u3000", "")
.replace("-", "").replace("\u2013", "").replace("\u2014", "").replace("\uff0d", "");
.replace("-", "").replace("–", "").replace("—", "").replace("-", "");
}
private List<BmsRedlineProductCountry> stampSelectedCountry(List<BmsRedlineProductCountry> rows, BmsRegion region, Date eff)
@@ -2646,7 +2646,7 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
String name = product == null || StringUtils.isEmpty(product.getProductName())
? "-" : product.getProductName();
return MessageUtils.message("price.product.import.dupCountry.item",
code, name, String.join("\u3001", dups));
code, name, String.join("、", dups));
}
private List<String> findDuplicateCountryWeightLabels(List<BmsRedlineProductCountry> rows)
@@ -265,7 +265,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
{
if (row != null && FEE_TYPE_REFUND.equalsIgnoreCase(row.getFeeType()))
{
throw new ServiceException("\u8ba2\u5355\u5df2\u9000\u8d39\uff0c\u4e0d\u53ef\u91cd\u590d\u9000\u8d39");
throw new ServiceException("订单已退费,不可重复退费");
}
}
@@ -993,8 +993,8 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
Integer.valueOf(ORDER_BILL_EXPORT_MAX)));
}
String prefix = PrcOrderBillExportTask.TYPE_BILLING.equals(type)
? "\u8ba1\u8d39\u5217\u8868"
: "\u8ba2\u5355\u5217\u8868";
? "计费列表"
: "订单列表";
String fileName = prefix + "_" + DateUtils.dateTimeNow() + ".xlsx";
String taskId = IdUtils.fastSimpleUUID();
orderBillExportAsyncRunner.put(taskId, PrcOrderBillExportTask.STATUS_PENDING, 0, "queued", null,
@@ -2730,7 +2730,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
|| StringUtils.isNotEmpty(endBizDate);
if (!hasFilter)
{
throw new ServiceException("\u8bf7\u5148\u8bbe\u7f6e\u5217\u8868\u7b5b\u9009\u6761\u4ef6");
throw new ServiceException("请先设置列表筛选条件");
}
PrcOrderBill query = new PrcOrderBill();
query.setOrderNos(orderNos);
@@ -2751,12 +2751,12 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
List<PrcOrderBill> list = self.selectBillList(query);
if (list == null || list.isEmpty())
{
throw new ServiceException("\u5f53\u524d\u7b5b\u9009\u6761\u4ef6\u4e0b\u6ca1\u6709\u53ef\u5bfc\u51fa\u7684\u8ba2\u5355");
throw new ServiceException("当前筛选条件下没有可导出的订单");
}
if (list.size() > CHARGE_WEIGHT_IMPORT_MAX)
{
throw new ServiceException("\u7b5b\u9009\u7ed3\u679c\u8d85\u8fc7 "
+ CHARGE_WEIGHT_IMPORT_MAX + " \u6761\uff0c\u8bf7\u7f29\u5c0f\u7b5b\u9009\u8303\u56f4");
throw new ServiceException("筛选结果超过 "
+ CHARGE_WEIGHT_IMPORT_MAX + " 条,请缩小筛选范围");
}
List<ChargeWeightImportRow> rows = new ArrayList<ChargeWeightImportRow>(list.size());
for (PrcOrderBill bill : list)
@@ -2776,7 +2776,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService
}
if (rows.isEmpty())
{
throw new ServiceException("\u5f53\u524d\u7b5b\u9009\u6761\u4ef6\u4e0b\u6ca1\u6709\u53ef\u5bfc\u51fa\u7684\u8ba2\u5355");
throw new ServiceException("当前筛选条件下没有可导出的订单");
}
return rows;
}
@@ -19,7 +19,7 @@ import com.bms.price.mapper.PrcPriceExcelFileMapper;
import com.bms.price.service.IPrcPriceExcelFileService;
/**
* Persist import Excel bytes and metadata (OSS, same pattern as AR bill export).
* 保存导入 Excel 的字节和元数据(OSS,与应收账单导出同一方式)。
*/
@Service
public class PrcPriceExcelFileServiceImpl implements IPrcPriceExcelFileService
@@ -714,16 +714,16 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
if (details.isEmpty())
{
items.add(new PrcPriceSetCheckItem("FIXED \u660e\u7ec6\u5b8c\u6574\u6027", "FAIL",
"\u65e0\u5957\u9910\u660e\u7ec6\uff1a\u56fa\u5b9a\u4ef7\u987b\u5148\u62c9\u53d6\u4ea7\u54c1\u5217\u8868\u6216\u5bfc\u5165 Excel \u5efa\u4ef7"));
items.add(new PrcPriceSetCheckItem("FIXED 明细完整性", "FAIL",
"无套餐明细:固定价须先拉取产品列表或导入 Excel 建价"));
}
else if (incomplete > 0)
{
items.add(new PrcPriceSetCheckItem("FIXED \u660e\u7ec6\u5b8c\u6574\u6027", "FAIL", incomplete + " \u6761\u660e\u7ec6\u7f3a\u5c11\u4ea7\u54c1/\u56fd\u5bb6/\u91cd\u91cf\u6bb5"));
items.add(new PrcPriceSetCheckItem("FIXED 明细完整性", "FAIL", incomplete + " 条明细缺少产品/国家/重量段"));
}
else
{
items.add(new PrcPriceSetCheckItem("FIXED \u660e\u7ec6\u5b8c\u6574\u6027", "PASS", details.size() + " \u6761\u5957\u9910\u9500\u552e\u4ef7\u660e\u7ec6\uff08\u4e0d\u56de\u9000 product_country\uff09"));
items.add(new PrcPriceSetCheckItem("FIXED 明细完整性", "PASS", details.size() + " 条套餐销售价明细(不回退 product_country)"));
}
}
else
@@ -784,33 +784,33 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
if (dupInSet || bound > 0)
{
items.add(new PrcPriceSetCheckItem("\u4e00\u4e2a\u5ba2\u6237\u53ea\u80fd\u7ed1\u5b9a\u4e00\u4e2a\u5957\u9910", "FAIL",
items.add(new PrcPriceSetCheckItem("一个客户只能绑定一个套餐", "FAIL",
MessageUtils.message("price.set.customer.alreadyBound")));
}
else if (customers.isEmpty())
{
items.add(new PrcPriceSetCheckItem("\u4e00\u4e2a\u5ba2\u6237\u53ea\u80fd\u7ed1\u5b9a\u4e00\u4e2a\u5957\u9910", "INFO",
"\u6682\u672a\u7ed1\u5b9a\u5ba2\u6237\uff0c\u53ef\u540e\u7eed\u8865\u5145"));
items.add(new PrcPriceSetCheckItem("一个客户只能绑定一个套餐", "INFO",
"暂未绑定客户,可后续补充"));
}
else
{
items.add(new PrcPriceSetCheckItem("\u4e00\u4e2a\u5ba2\u6237\u53ea\u80fd\u7ed1\u5b9a\u4e00\u4e2a\u5957\u9910", "PASS",
"\u5ba2\u6237\u672a\u7ed1\u5b9a\u5176\u4ed6\u5957\u9910"));
items.add(new PrcPriceSetCheckItem("一个客户只能绑定一个套餐", "PASS",
"客户未绑定其他套餐"));
}
if (TYPE_FIXED.equals(setType) && !details.isEmpty())
{
items.add(new PrcPriceSetCheckItem("\u8fd0\u8d39\u5355\u4ef7 vs \u9ed8\u8ba4\u7b49\u7ea7\u4ef7\u504f\u5dee", "INFO",
"\u56fa\u5b9a\u4ef7\u4ec5\u4f7f\u7528\u5957\u9910\u660e\u7ec6\uff1b\u672a\u547d\u4e2d\u5219\u4e0d\u8ba1\u8d39\uff08\u4e0d\u56de\u9000 product_country\uff09"));
items.add(new PrcPriceSetCheckItem("运费单价 vs 默认等级价偏差", "INFO",
"固定价仅使用套餐明细;未命中则不计费(不回退 product_country)"));
}
else if (TYPE_FIXED.equals(setType))
{
items.add(new PrcPriceSetCheckItem("\u8fd0\u8d39\u5355\u4ef7 vs \u9ed8\u8ba4\u7b49\u7ea7\u4ef7\u504f\u5dee", "INFO",
"\u65e0\u5957\u9910\u660e\u7ec6\u65f6\u56fa\u5b9a\u4ef7\u4e0d\u8ba1\u8d39\uff0c\u8bf7\u5148\u62c9\u53d6\u6216\u5bfc\u5165\u5efa\u4ef7"));
items.add(new PrcPriceSetCheckItem("运费单价 vs 默认等级价偏差", "INFO",
"无套餐明细时固定价不计费,请先拉取或导入建价"));
}
else if (TYPE_DISCOUNT.equals(setType))
{
items.add(new PrcPriceSetCheckItem("\u8fd0\u8d39\u5355\u4ef7 vs \u9ed8\u8ba4\u7b49\u7ea7\u4ef7\u504f\u5dee", "INFO", "\u6298\u6263\u6a21\u5f0f\u6309\u4e0b\u5355\u65f6\u9ed8\u8ba4\u7b49\u7ea7\u4ef7 \u00d7 \u6298\u6263\u8ba1\u8d39"));
items.add(new PrcPriceSetCheckItem("运费单价 vs 默认等级价偏差", "INFO", "折扣模式按下单时默认等级价 × 折扣计费"));
}
return items;
@@ -1006,7 +1006,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
if (files.size() > com.bms.price.service.support.UploadFileBatch.MAX_FILES)
{
throw new ServiceException("\u5355\u6b21\u6700\u591a\u5bfc\u5165 5 \u4e2a\u6587\u4ef6");
throw new ServiceException("单次最多导入 5 个文件");
}
List<byte[]> bytesList = new ArrayList<byte[]>();
List<String> names = new ArrayList<String>();
@@ -1318,7 +1318,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
if (bytesList.size() > com.bms.price.service.support.UploadFileBatch.MAX_FILES)
{
throw new ServiceException("\u5355\u6b21\u6700\u591a\u5bfc\u5165 5 \u4e2a\u6587\u4ef6");
throw new ServiceException("单次最多导入 5 个文件");
}
List<PrcPriceSetDetail> existing = existingDetails;
Map<String, Object> last = null;
@@ -2931,7 +2931,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
private static String formatWeightLabel(BigDecimal min, BigDecimal max)
{
return stripTrailingZeros(min) + "<W\u2264" + stripTrailingZeros(max);
return stripTrailingZeros(min) + "<W≤" + stripTrailingZeros(max);
}
private static String stripTrailingZeros(BigDecimal v)
@@ -36,14 +36,14 @@ import com.bms.system.domain.BmsRegion;
import com.bms.system.mapper.BmsRegionMapper;
/**
* Zone management: region -> prc_zone -> postcode detail
* 分区管理:国家(region) -> prc_zone -> 邮编明细
*/
@Service
public class PrcZoneServiceImpl implements IPrcZoneService
{
private static final String SHEET_SUFFIX = "\u5206\u533a";
private static final String COL_POSTCODE = "\u90ae\u7f16";
private static final String COL_ZONE = "\u5206\u533a";
private static final String SHEET_SUFFIX = "分区";
private static final String COL_POSTCODE = "邮编";
private static final String COL_ZONE = "分区";
private static final Pattern ZONE_NUM = Pattern.compile("(\\d+)");
private static final int BATCH_SIZE = 500;
private static final DataFormatter CELL_FMT = new DataFormatter(Locale.ROOT);
@@ -405,10 +405,10 @@ public class PrcZoneServiceImpl implements IPrcZoneService
}
// strip common suffixes: remote surcharge / surcharge / postcode
String[] suffixes = {
"\u504f\u8fdc\u9644\u52a0\u8d39",
"\u9644\u52a0\u8d39",
"MR\u90ae\u7f16",
"\u90ae\u7f16"
"偏远附加费",
"附加费",
"MR邮编",
"邮编"
};
for (String suffix : suffixes)
{
@@ -417,25 +417,25 @@ public class PrcZoneServiceImpl implements IPrcZoneService
return StringUtils.trim(name.substring(0, name.length() - suffix.length()));
}
}
if (name.contains("\u52a0\u62ff\u5927"))
if (name.contains("加拿大"))
{
return "\u52a0\u62ff\u5927";
return "加拿大";
}
if (name.contains("\u6fb3\u5927\u5229\u4e9a"))
if (name.contains("澳大利亚"))
{
return "\u6fb3\u5927\u5229\u4e9a";
return "澳大利亚";
}
if (name.contains("\u82f1\u56fd"))
if (name.contains("英国"))
{
return "\u82f1\u56fd";
return "英国";
}
if (name.contains("\u65e5\u672c"))
if (name.contains("日本"))
{
return "\u65e5\u672c";
return "日本";
}
if (name.contains("\u6cd5\u56fd"))
if (name.contains("法国"))
{
return "\u6cd5\u56fd";
return "法国";
}
return null;
}
@@ -446,19 +446,19 @@ public class PrcZoneServiceImpl implements IPrcZoneService
{
return parseZonePostcodes(sheet);
}
if (sheetName.contains("\u52a0\u62ff\u5927"))
if (sheetName.contains("加拿大"))
{
return parseRemoteZonePostcodes(sheet);
}
if (sheetName.contains("\u6cd5\u56fd") && sheetName.contains("\u90ae\u7f16"))
if (sheetName.contains("法国") && sheetName.contains("邮编"))
{
return parseCoveragePostcodes(sheet);
}
if (sheetName.contains("\u65e5\u672c"))
if (sheetName.contains("日本"))
{
return parseProvincePostcodes(sheet);
}
if (sheetName.contains("\u82f1\u56fd"))
if (sheetName.contains("英国"))
{
return parseUkSurchargePostcodes(sheet);
}
@@ -499,13 +499,13 @@ public class PrcZoneServiceImpl implements IPrcZoneService
for (int c = 0; c < row.getLastCellNum(); c++)
{
String val = cellText(row.getCell(c));
if (val.contains("\u90ae\u7f16") && postcodeCol < 0)
if (val.contains("邮编") && postcodeCol < 0)
{
postcodeCol = c;
headerRow = r;
}
if ((val.equals("\u504f\u8fdc\u5206\u533a") || val.equals(COL_ZONE) || val.contains("\u5206\u533a"))
&& !val.contains("\u9644\u52a0") && zoneCol < 0)
if ((val.equals("偏远分区") || val.equals(COL_ZONE) || val.contains("分区"))
&& !val.contains("附加") && zoneCol < 0)
{
zoneCol = c;
headerRow = r;
@@ -542,12 +542,12 @@ public class PrcZoneServiceImpl implements IPrcZoneService
for (int c = 0; c < row.getLastCellNum(); c++)
{
String val = cellText(row.getCell(c));
if ((val.contains("\u5dde") || val.contains("\u7701") || "\u5dde\u7701".equals(val)) && provinceCol < 0)
if ((val.contains("州") || val.contains("省") || "州省".equals(val)) && provinceCol < 0)
{
provinceCol = c;
headerRow = r;
}
if (COL_POSTCODE.equals(val) || val.equals("\u90ae\u7f16"))
if (COL_POSTCODE.equals(val) || val.equals("邮编"))
{
postcodeCol = c;
headerRow = r;
@@ -599,12 +599,12 @@ public class PrcZoneServiceImpl implements IPrcZoneService
for (int c = 0; c < row.getLastCellNum(); c++)
{
String val = cellText(row.getCell(c));
if (val.contains("\u8986\u76d6\u90ae\u7f16") || val.equals(COL_POSTCODE))
if (val.contains("覆盖邮编") || val.equals(COL_POSTCODE))
{
postcodeCol = c;
headerRow = r;
}
if (val.contains("\u5c3e\u7a0b") || val.contains("\u81ea\u63d0"))
if (val.contains("尾程") || val.contains("自提"))
{
zoneCol = c;
headerRow = r;
@@ -665,8 +665,8 @@ public class PrcZoneServiceImpl implements IPrcZoneService
}
for (int c = 0; c < row.getLastCellNum(); c++)
{
if (cellText(row.getCell(c)).contains("\u90ae\u7f16\u5f00\u5934")
|| cellText(row.getCell(c)).contains("\u7a7a\u6c14\u51cf\u6392"))
if (cellText(row.getCell(c)).contains("邮编开头")
|| cellText(row.getCell(c)).contains("空气减排"))
{
headerRow = r;
break;
@@ -62,12 +62,12 @@ import com.bms.price.service.ITmsPriceQuoteService;
import com.bms.system.service.IBmsProductCodeMappingService;
/**
* Shared quote/bill calc: customer bind + package version by bizDate (version effective_time).
* Bind pr_begindate/pr_enddate is not used for billing time gate.
* Sales price comes from package snapshot only (FIXED detail / DISCOUNT on catalog base).
* No bind / no active version: quote and bill both fail hard (no PRODUCT_DEFAULT).
* Bill sync soft-fails for product/country/weight miss (billing_fail_status 1/2/3, zero amounts).
* product_country is only for product_amount/cost and DISCOUNT freight base.
* 共用的试算/计费计算:按 bizDate 取客户绑定和套餐版本(版本 effective_time)。
* 绑定的 pr_begindate/pr_enddate 不作为计费时间门槛。
* 销售价只来自套餐快照(FIXED 明细 / 按目录底价 DISCOUNT)。
* 无绑定或无生效版本:试算和计费都直接失败(不用 PRODUCT_DEFAULT)。
* 账单同步时,产品/国家/重量段未命中为软失败(billing_fail_status 1/2/3,金额为 0)。
* product_country 只用于 product_amount/cost 以及 DISCOUNT 的运费底价。
*
* @author bms
*/
@@ -1554,7 +1554,7 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
}
String name = fee.getFeeName() == null ? "" : fee.getFeeName().trim();
if (name.isEmpty() || "SURCHARGE".equalsIgnoreCase(name)
|| "\u9644\u52a0\u8d39".equals(name))
|| "附加费".equals(name))
{
return true;
}
@@ -1791,15 +1791,15 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
{
if (FEE_BASIC.equals(feeType))
{
return "\u57fa\u7840\u8fd0\u8d39";
return "基础运费";
}
if (FEE_REG.equals(feeType))
{
return "\u6302\u53f7\u8d39";
return "挂号费";
}
if (FEE_SUR.equals(feeType))
{
return "\u9644\u52a0\u8d39";
return "附加费";
}
return feeType;
}
@@ -1938,7 +1938,7 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
private static String formatWeightLabel(BigDecimal min, BigDecimal max)
{
return strip(min) + "<W\u2264" + strip(max);
return strip(min) + "<W≤" + strip(max);
}
private static String strip(BigDecimal v)
@@ -15,7 +15,7 @@ import com.bms.price.mapper.PrcPriceSetVersionMapper;
import com.bms.price.mapper.PrcSurchargeRelMapper;
/**
* Resolve / create global PRODUCT or REDLINE versions (price_set_id null).
* 解析或创建全局 PRODUCT / REDLINE 版本(price_set_id 为空)。
*/
@Component
public class CatalogVersionSupport
@@ -201,12 +201,12 @@ public class CatalogVersionSupport
PrcPriceSetVersion ver = versionMapper.selectPrcPriceSetVersionById(psvId);
if (ver == null)
{
throw new ServiceException("\u7248\u672c\u4e0d\u5b58\u5728");
throw new ServiceException("版本不存在");
}
assertCatalogType(ver.getPriceType());
if (!STATUS_DRAFT.equals(ver.getStatus()) && !STATUS_PENDING.equals(ver.getStatus()))
{
throw new ServiceException("\u4ec5\u8349\u7a3f\u6216\u5f85\u751f\u6548\u7248\u672c\u53ef\u4ee5\u5220\u9664");
throw new ServiceException("仅草稿或待生效版本可以删除");
}
surchargeRelMapper.physicalDeleteByPsvId(psvId);
detailMapper.physicalDeleteByPsvId(psvId);
@@ -228,16 +228,16 @@ public class CatalogVersionSupport
PrcPriceSetVersion ver = versionMapper.selectPrcPriceSetVersionById(psvId);
if (ver == null)
{
throw new ServiceException("\u7248\u672c\u4e0d\u5b58\u5728");
throw new ServiceException("版本不存在");
}
assertCatalogType(ver.getPriceType());
if (StringUtils.isNotEmpty(priceType) && !priceType.equals(ver.getPriceType()))
{
throw new ServiceException("\u7248\u672c\u7c7b\u578b\u4e0d\u5339\u914d");
throw new ServiceException("版本类型不匹配");
}
if (!STATUS_DRAFT.equals(ver.getStatus()) && !STATUS_PENDING.equals(ver.getStatus()))
{
throw new ServiceException("\u4ec5\u8349\u7a3f\u6216\u5f85\u751f\u6548\u7248\u672c\u53ef\u4ee5\u7f16\u8f91");
throw new ServiceException("仅草稿或待生效版本可以编辑");
}
return ver;
}
@@ -259,7 +259,7 @@ public class CatalogVersionSupport
PrcPriceSetVersion src = findEffectVersion(priceType);
if (src == null)
{
throw new ServiceException("\u5f53\u524d\u6ca1\u6709\u5df2\u751f\u6548\u7248\u672c\u53ef\u4ee5\u6cbf\u7528");
throw new ServiceException("当前没有已生效版本可以沿用");
}
}
draft = ensureDraftVersion(priceType, null, copyFromLatest);
@@ -275,7 +275,7 @@ public class CatalogVersionSupport
PrcPriceSetVersion src = findEffectVersion(priceType);
if (src == null)
{
throw new ServiceException("\u5f53\u524d\u6ca1\u6709\u5df2\u751f\u6548\u7248\u672c\u53ef\u4ee5\u6cbf\u7528");
throw new ServiceException("当前没有已生效版本可以沿用");
}
if (!src.getPsvId().equals(draft.getPsvId()))
{
@@ -10,7 +10,7 @@ import com.bms.price.domain.PrcOrderBill;
import com.bms.price.domain.vo.PrcBillingBillListExportRow;
import com.bms.price.domain.vo.PrcOrderBillListExportRow;
/** Map PrcOrderBill rows to Excel export VOs and write response. */
/** 把 PrcOrderBill 行映射为 Excel 导出 VO 并写入响应。 */
public final class OrderBillExportSupport
{
private OrderBillExportSupport()
@@ -113,13 +113,13 @@ public final class OrderBillExportSupport
/** Export order-list Excel by current query result. */
public static void exportOrderList(HttpServletResponse response, List<PrcOrderBill> list)
{
ExcelUtil.export(response, toOrderListRows(list), PrcOrderBillListExportRow.class, "\u8ba2\u5355\u5217\u8868");
ExcelUtil.export(response, toOrderListRows(list), PrcOrderBillListExportRow.class, "订单列表");
}
/** Export billing-list Excel by current query result. */
public static void exportBillingList(HttpServletResponse response, List<PrcOrderBill> list)
{
ExcelUtil.export(response, toBillingListRows(list), PrcBillingBillListExportRow.class, "\u8ba1\u8d39\u5217\u8868");
ExcelUtil.export(response, toBillingListRows(list), PrcBillingBillListExportRow.class, "计费列表");
}
public static List<PrcOrderBillListExportRow> toOrderListRows(List<PrcOrderBill> list)
@@ -5,7 +5,7 @@ import java.util.List;
import org.springframework.web.multipart.MultipartFile;
import com.bms.common.exception.ServiceException;
/** Collect multipart parts named files and/or file. At most 5. */
/** 收集名为 files 和/或 file 的上传分片。最多 5 个。 */
public final class UploadFileBatch
{
public static final int MAX_FILES = 5;
@@ -37,7 +37,7 @@ public final class UploadFileBatch
}
if (list.size() > MAX_FILES)
{
throw new ServiceException("\u5355\u6b21\u6700\u591a\u5bfc\u5165 5 \u4e2a\u6587\u4ef6");
throw new ServiceException("单次最多导入 5 个文件");
}
return list;
}