|
|
@@ -1,7 +1,12 @@
|
|
|
package com.ruoyi.logistics.service.impl;
|
|
|
|
|
|
-import java.util.List;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import com.ruoyi.common.core.exception.ServiceException;
|
|
|
import com.ruoyi.common.core.utils.DateUtils;
|
|
|
+import com.ruoyi.common.security.utils.SecurityUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import com.ruoyi.logistics.mapper.SysDeptRateMapper;
|
|
|
@@ -41,20 +46,62 @@ public class SysDeptRateServiceImpl implements ISysDeptRateService
|
|
|
@Override
|
|
|
public List<SysDeptRate> selectSysDeptRateList(SysDeptRate sysDeptRate)
|
|
|
{
|
|
|
- return sysDeptRateMapper.selectSysDeptRateList(sysDeptRate);
|
|
|
+ List<SysDeptRate> sysDeptRates = sysDeptRateMapper.selectSysDeptRateList(sysDeptRate);
|
|
|
+
|
|
|
+ // 根据 companyType 和 productType 分组后,再根据 intervalBegins 正序排列
|
|
|
+ return sysDeptRates.stream()
|
|
|
+ .sorted(
|
|
|
+ Comparator.comparing(SysDeptRate::getCompanyType)
|
|
|
+ .thenComparing(SysDeptRate::getProductType)
|
|
|
+ .thenComparing(SysDeptRate::getIntervalBegins)
|
|
|
+ )
|
|
|
+ .collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 新增供应商费率配置
|
|
|
*
|
|
|
- * @param sysDeptRate 供应商费率配置
|
|
|
+ * @param sysDeptRates 供应商费率配置
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@Override
|
|
|
- public int insertSysDeptRate(SysDeptRate sysDeptRate)
|
|
|
+ public int insertSysDeptRate(List<SysDeptRate> sysDeptRates)
|
|
|
{
|
|
|
- sysDeptRate.setCreateTime(DateUtils.getNowDate());
|
|
|
- return sysDeptRateMapper.insertSysDeptRate(sysDeptRate);
|
|
|
+ if (sysDeptRates == null || sysDeptRates.isEmpty()) {
|
|
|
+ throw new ServiceException("批量插入的费率配置列表不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按 companyType + productType 分组校验区间重叠
|
|
|
+ Map<String, List<SysDeptRate>> groupedRates = new HashMap<>();
|
|
|
+
|
|
|
+ for (SysDeptRate rate : sysDeptRates) {
|
|
|
+ // 构建分组 key: companyType_productType
|
|
|
+ String groupKey = rate.getCompanyType() + "_" + rate.getProductType();
|
|
|
+ groupedRates.computeIfAbsent(groupKey, k -> new ArrayList<>()).add(rate);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 对每个分组进行区间重叠校验
|
|
|
+ for (Map.Entry<String, List<SysDeptRate>> entry : groupedRates.entrySet()) {
|
|
|
+ List<SysDeptRate> rates = entry.getValue();
|
|
|
+ validateIntervalOverlap(rates);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置创建时间并批量插入
|
|
|
+ for (SysDeptRate rate : sysDeptRates) {
|
|
|
+ if (null == rate.getRateId()) {
|
|
|
+ rate.setCreateTime(DateUtils.getNowDate());
|
|
|
+ rate.setCreateBy(SecurityUtils.getUsername());
|
|
|
+ rate.setUserId(SecurityUtils.getUserId());
|
|
|
+ sysDeptRateMapper.insertSysDeptRate(rate);
|
|
|
+ } else {
|
|
|
+ rate.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ rate.setUpdateBy(SecurityUtils.getUsername());
|
|
|
+ rate.setUserId(SecurityUtils.getUserId());
|
|
|
+ sysDeptRateMapper.updateSysDeptRate(rate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return sysDeptRates.size();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -93,4 +140,99 @@ public class SysDeptRateServiceImpl implements ISysDeptRateService
|
|
|
{
|
|
|
return sysDeptRateMapper.deleteSysDeptRateByRateId(rateId);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验同一物流公司和产品类型的区间是否重叠
|
|
|
+ * 区间规则:(intervalBegins, intervalEnds] 左开右闭
|
|
|
+ *
|
|
|
+ * @param rates 费率配置列表
|
|
|
+ * @throws ServiceException 如果存在区间重叠
|
|
|
+ */
|
|
|
+ private static void validateIntervalOverlap(List<SysDeptRate> rates) {
|
|
|
+ if (rates.size() <= 1) {
|
|
|
+ return; // 单个或空列表无需校验
|
|
|
+ }
|
|
|
+
|
|
|
+ // 两两比较所有区间
|
|
|
+ for (int i = 0; i < rates.size(); i++) {
|
|
|
+ for (int j = i + 1; j < rates.size(); j++) {
|
|
|
+ SysDeptRate rate1 = rates.get(i);
|
|
|
+ SysDeptRate rate2 = rates.get(j);
|
|
|
+
|
|
|
+ Long begins1 = rate1.getIntervalBegins();
|
|
|
+ Long ends1 = rate1.getIntervalEnds();
|
|
|
+ Long begins2 = rate2.getIntervalBegins();
|
|
|
+ Long ends2 = rate2.getIntervalEnds();
|
|
|
+
|
|
|
+ // 检查区间有效性
|
|
|
+ if (begins1 == null || ends1 == null || begins2 == null || ends2 == null) {
|
|
|
+ throw new ServiceException("区间开始和结束值不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (begins1 >= ends1) {
|
|
|
+ throw new ServiceException(String.format(
|
|
|
+ "第%d条配置的区间开始值必须小于结束值", i + 1));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (begins2 >= ends2) {
|
|
|
+ throw new ServiceException(String.format(
|
|
|
+ "第%d条配置的区间开始值必须小于结束值", j + 1));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断两个区间是否重叠
|
|
|
+ // 区间 1: (begins1, ends1]
|
|
|
+ // 区间 2: (begins2, ends2]
|
|
|
+ // 不重叠的条件:ends1 <= begins2 或 ends2 <= begins1
|
|
|
+ // 重叠的条件:!(ends1 <= begins2 || ends2 <= begins1)
|
|
|
+ boolean isOverlap = !(ends1 <= begins2 || ends2 <= begins1);
|
|
|
+
|
|
|
+ if (isOverlap) {
|
|
|
+ throw new ServiceException(String.format(
|
|
|
+ "物流公司%s、产品类型%s的区间配置存在重叠:区间%d(%d,%d] 与区间%d(%d,%d]",
|
|
|
+ rates.get(i).getCompanyType(),
|
|
|
+ rates.get(i).getProductType(),
|
|
|
+ i + 1, begins1, ends1,
|
|
|
+ j + 1, begins2, ends2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ List<SysDeptRate> rates = new ArrayList<>();
|
|
|
+ SysDeptRate a = new SysDeptRate();
|
|
|
+ SysDeptRate b = new SysDeptRate();
|
|
|
+ SysDeptRate c = new SysDeptRate();
|
|
|
+
|
|
|
+ a.setCompanyType("JD");
|
|
|
+ a.setProductType("ed-m-0001");
|
|
|
+ a.setIntervalBegins(0L);
|
|
|
+ a.setIntervalEnds(100L);
|
|
|
+ a.setRate(new BigDecimal("0.1"));
|
|
|
+
|
|
|
+ b.setCompanyType("JD");
|
|
|
+ b.setProductType("ed-m-0001");
|
|
|
+ b.setIntervalBegins(100L);
|
|
|
+ b.setIntervalEnds(200L);
|
|
|
+ b.setRate(new BigDecimal("0.2"));
|
|
|
+
|
|
|
+ c.setCompanyType("JD");
|
|
|
+ c.setProductType("ed-m-0002");
|
|
|
+ c.setIntervalBegins(200L);
|
|
|
+ c.setIntervalEnds(300L);
|
|
|
+ c.setRate(new BigDecimal("0.3"));
|
|
|
+
|
|
|
+ rates.add(c);
|
|
|
+ rates.add(b);
|
|
|
+ rates.add(a);
|
|
|
+
|
|
|
+ List<SysDeptRate> collect = rates.stream()
|
|
|
+ .sorted(
|
|
|
+ Comparator.comparing(SysDeptRate::getCompanyType)
|
|
|
+ .thenComparing(SysDeptRate::getProductType)
|
|
|
+ .thenComparing(SysDeptRate::getIntervalBegins)
|
|
|
+ )
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ System.out.println(1);
|
|
|
+ }
|
|
|
}
|