修改公共配置字典

This commit is contained in:
wuweihua
2026-09-08 10:51:20 +08:00
parent 647be14d66
commit 38796d8683
25 changed files with 389 additions and 80 deletions
@@ -25,9 +25,15 @@ public class BmsProduct extends BaseEntity
private String taxMode;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date effectiveDate;
/** 0启用(按日期展示已生效/待生效) 1已失效 */
private String status;
private String sourceSheet;
private Long tmsId;
private Integer countryCount;
private List<BmsProductCountry> countries;
/**
* 查询用:ACTIVE已生效 / PENDING待生效 / EXPIRED已失效
* (非表字段,由生效日期+status 推导)
*/
private String effectStatus;
}
@@ -25,8 +25,13 @@ public class BmsProductCountry implements Serializable
private String leadTime;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date effectiveDate;
/** null=open; closed to next import effective_date */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date expireDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdAt;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updatedAt;
/** query only: true = expire_date is null */
private Boolean openOnly;
}
@@ -21,9 +21,22 @@ public interface BmsProductCountryMapper
public int deleteByProductCodes(String[] productCodes);
/** Max open (expire_date is null) effective_date for product */
public Date selectMaxOpenEffectiveDate(@Param("productCode") String productCode);
/** Close open versions: set expire_date = newEffectiveDate where effective_date &lt; newEffectiveDate */
public int expireOpenByProductCode(
@Param("productCode") String productCode,
@Param("newEffectiveDate") Date newEffectiveDate);
/** Replace same-day version only */
public int deleteOpenByProductCodeAndEffectiveDate(
@Param("productCode") String productCode,
@Param("effectiveDate") Date effectiveDate);
/**
* 按产品 + 国家 + 重量落入重量段 + 计数时间过滤,匹配一条默认价
* 只取 effective_date <= bizDate 的已生效明细,多匹配时按 effective_date desc 取最新。
* Match by product + country + weight + bizDate.
* effective_date &lt;= bizDate and (expire_date is null or expire_date &gt; bizDate).
*/
public BmsProductCountry selectMatchByProductCountryWeight(
@Param("productCode") String productCode,
@@ -185,26 +185,21 @@ public class BmsProductServiceImpl implements IBmsProductService
{
product.setStatus("0");
productMapper.insertBmsProduct(product);
saveCountries(product.getProductCode(), countries);
countryNum += saveCountriesVersioned(product.getProductCode(), countries);
successNum++;
countryNum += countries.size();
}
else if (updateSupport)
{
product.setProductId(existing.getProductId());
productMapper.updateBmsProduct(product);
countryMapper.deleteByProductCode(product.getProductCode());
saveCountries(product.getProductCode(), countries);
countryNum += saveCountriesVersioned(product.getProductCode(), countries);
updateNum++;
countryNum += countries.size();
}
else if (!countries.isEmpty())
{
// Product already exists and "update" unchecked: still refresh country/fee rows from Excel.
countryMapper.deleteByProductCode(product.getProductCode());
saveCountries(product.getProductCode(), countries);
// Keep product master; version country rows by effective_date
countryNum += saveCountriesVersioned(product.getProductCode(), countries);
updateNum++;
countryNum += countries.size();
}
else
{
@@ -224,6 +219,7 @@ public class BmsProductServiceImpl implements IBmsProductService
}
String msg = "\u5bfc\u5165\u6210\u529f\uff1a\u65b0\u589e " + successNum + " \u4e2a\u4ea7\u54c1\uff0c\u66f4\u65b0 " + updateNum + " \u4e2a\uff0c\u8df3\u8fc7 "
+ skipNum + " \u4e2a\uff1b\u5199\u5165\u56fd\u5bb6/\u91cd\u91cf\u6bb5\u660e\u7ec6 " + countryNum + " \u884c\u3002"
+ "<br/>\u56fd\u5bb6\u660e\u7ec6\uff1a\u82e5\u65b0\u751f\u6548\u65e5\u665a\u4e8e\u4e0a\u6b21\uff0c\u4fdd\u7559\u5386\u53f2\u7248\u4e14\u4e0a\u6b21\u5931\u6548\u65e5=\u672c\u6b21\u751f\u6548\u65e5\uff1b\u540c\u65e5\u5219\u66ff\u6362\u5f53\u524d\u5f00\u653e\u7248\u3002"
+ "<br/>\u8303\u56f4\uff1a\u4ea7\u54c1\u76ee\u5f55 + \u91cd\u91cf\u6bb5 + \u8fd0\u8d39/\u6302\u53f7\u8d39 + \u5c3a\u5bf8/\u5c3e\u7a0b/\u65f6\u6548\uff1b\u56fd\u5bb6\u7801\u6765\u81ea bms_region\u3002";
if (!unmatchedCountries.isEmpty())
{
@@ -233,11 +229,47 @@ public class BmsProductServiceImpl implements IBmsProductService
}
}
private void saveCountries(String productCode, List<BmsProductCountry> countries)
/**
* Versioned country save:
* - newEff &gt; last open eff: close old (expire_date = newEff), insert new (keep history)
* - newEff equals last open: replace that open version only
* - newEff &lt; last open: reject
*/
private int saveCountriesVersioned(String productCode, List<BmsProductCountry> countries)
{
if (countries == null || countries.isEmpty())
{
return 0;
}
Date newEff = resolveImportEffectiveDate(countries);
Date lastOpenEff = countryMapper.selectMaxOpenEffectiveDate(productCode);
if (lastOpenEff != null && newEff != null && newEff.before(lastOpenEff))
{
throw new ServiceException("\u751f\u6548\u65e5\u671f "
+ formatDate(newEff) + " \u65e9\u4e8e\u5f53\u524d\u5f00\u653e\u7248 "
+ formatDate(lastOpenEff) + "\uff0c\u8bf7\u4f7f\u7528\u66f4\u665a\u7684\u751f\u6548\u65e5\u671f\u5bfc\u5165");
}
if (lastOpenEff != null && newEff != null && newEff.after(lastOpenEff))
{
// Previous open version expire_date = this effective_date; keep old rows
countryMapper.expireOpenByProductCode(productCode, newEff);
}
else if (lastOpenEff != null)
{
// Same effective day (or both null): replace current open version only
countryMapper.deleteOpenByProductCodeAndEffectiveDate(productCode, newEff);
}
for (BmsProductCountry c : countries)
{
c.setProductCode(productCode);
c.setExpireDate(null);
if (c.getEffectiveDate() == null)
{
c.setEffectiveDate(newEff);
}
try
{
countryMapper.insertBmsProductCountry(c);
@@ -250,9 +282,46 @@ public class BmsProductServiceImpl implements IBmsProductService
throw new ServiceException(
"\u8bf7\u5148\u6267\u884c SQL\uff1abms-back/sql/price/product_country_fee_alter.sql\uff08\u7f3a\u5c11\u8fd0\u8d39/\u6302\u53f7\u8d39\u5b57\u6bb5\uff09");
}
if (tip.contains("expire_date") || tip.contains("uk_product_country_weight"))
{
throw new ServiceException(
"\u8bf7\u5148\u6267\u884c SQL\uff1abms-back/sql/price/product_country_expire_alter.sql\uff08\u7f3a\u5c11\u5931\u6548\u65e5\u671f/\u7248\u672c\u552f\u4e00\u952e\uff09");
}
throw e;
}
}
return countries.size();
}
private Date resolveImportEffectiveDate(List<BmsProductCountry> countries)
{
Date max = null;
for (BmsProductCountry c : countries)
{
if (c.getEffectiveDate() == null)
{
continue;
}
if (max == null || c.getEffectiveDate().after(max))
{
max = c.getEffectiveDate();
}
}
return max;
}
private String formatDate(Date d)
{
if (d == null)
{
return "-";
}
return new SimpleDateFormat("yyyy-MM-dd").format(d);
}
private void saveCountries(String productCode, List<BmsProductCountry> countries)
{
saveCountriesVersioned(productCode, countries);
}
private List<BmsProduct> parseCatalog(Sheet sheet)
@@ -671,6 +671,10 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
for (BmsProductCountry row : rows)
{
if (row.getExpireDate() != null)
{
continue;
}
if (!matchDetailCountry(detail, row))
{
continue;
@@ -1,6 +1,7 @@
package com.ruoyi.system.service;
import java.util.List;
import java.util.Map;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
@@ -34,6 +35,13 @@ public interface ISysDictTypeService
*/
public List<SysDictData> selectDictDataByType(String dictType);
/**
* 查询全部正常状态字典数据(按字典类型分组)
*
* @return key=dictType, value=字典数据列表
*/
public Map<String, List<SysDictData>> selectDictDataAllMap();
/**
* 根据字典类型ID查询信息
*
@@ -1,6 +1,7 @@
package com.ruoyi.system.service.impl;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -87,6 +88,28 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService
return null;
}
/**
* 查询全部正常状态字典数据(按字典类型分组)
*/
@Override
public Map<String, List<SysDictData>> selectDictDataAllMap()
{
SysDictData query = new SysDictData();
query.setStatus("0");
Map<String, List<SysDictData>> dictDataMap = dictDataMapper.selectDictDataList(query).stream()
.collect(Collectors.groupingBy(SysDictData::getDictType));
Map<String, List<SysDictData>> result = new HashMap<>();
for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet())
{
List<SysDictData> sorted = entry.getValue().stream()
.sorted(Comparator.comparing(SysDictData::getDictSort))
.collect(Collectors.toList());
result.put(entry.getKey(), sorted);
DictUtils.setDictCache(entry.getKey(), sorted);
}
return result;
}
/**
* 根据字典类型ID查询信息
*