当计算海运价格时,会包含始发地到始发港、始发港都目的港、目的港到目的地的这三段路程。当系统中已经维护了始发地到始发港的字典数据,始发港都目的港的字典数据,目的港到目的地的字典数据后,当要查询1:门到门、2:门到港、3:港到门、4:港到港的最低价格,并且给出各段的分别价格时,用到如下方法
注释:
1:门到门包含:始发地到始发港+始发港到目的港+目的港到目的地
2:门到港包含:始发地到始发港+始发港到目的港
3:港到门:始发港到目的港+目的港到目的地
4:港到港:始发港到目的港
上代码
/**
* 查询最低价格
*
* @param dto
* @return
*/
public SearchPriceResult getSearchPriceResult(SearchPriceDTO dto) {
SearchPriceResult searchPriceResult = new SearchPriceResult();
// 创建价格信息字典
Map<String, List<PriceInfo>> priceMap = new HashMap<>();
//集港价格集合
//List<TSeaFreightConsolidationPrice> tSeaFreightConsolidationPriceList = tSeaFreightConsolidationPriceService.list();
List<TSeaFreightConsolidationPrice> tSeaFreightConsolidationPriceList = myCache.getAllTSeaFreightConsolidationPrice();
// 添加集港价格信息,达到类似下面效果
if (EmptyUtil.isNotEmpty(tSeaFreightConsolidationPriceList)) {
for (TSeaFreightConsolidationPrice price : tSeaFreightConsolidationPriceList) {
String originatingDetailAddress = price.getNvcOrginatingDetailAddress();
String loadingPort = price.getNvcDestinationPortAddress();
Double priceValue = price.getDContainerTrailerFee();
PriceInfo priceInfo = new PriceInfo("集港", originatingDetailAddress, loadingPort, priceValue);
// 检查priceMap中是否已经有该始发地的列表
List<PriceInfo> priceInfoList = priceMap.getOrDefault(originatingDetailAddress, new ArrayList<>());
// 添加新的PriceInfo到列表中
priceInfoList.add(priceInfo);
// 将列表放回priceMap中
priceMap.put(originatingDetailAddress, priceInfoList);
}
}
// 添加集港价格信息
/*
priceMap.put("始发地A", Arrays.asList(
new PriceInfo("集港", "始发地A", "始发港1", 100.0),
new PriceInfo("集港", "始发地A", "始发港2", 120.0)
));
priceMap.put("始发地B", Collections.singletonList(
new PriceInfo("集港", "始发地B", "始发港3", 90.0)
));
*/
//海运价格集合
//List<TOceanfreightPrice> oceanFreightPrices = tOceanfreightPriceService.list();
List<TOceanfreightPrice> oceanFreightPrices = myCache.getAllTOceanfreightPrice();
// 遍历查询结果
for (TOceanfreightPrice price : oceanFreightPrices) {
// 假设 OceanFreightPrice 类有相应的 getter 方法来获取字段值
String originatingPort = price.getNvcOriginatingPortAddress(); // 始发港
String destinationPort = price.getNvcDestinationPortAddress(); // 目的港
double freightPrice = price.getDOceanFreight() + price.getDOriginatingExtras(); // 海运费
// 检查 priceMap 中是否已经有该始发港的列表
List<PriceInfo> priceInfoList = priceMap.getOrDefault(originatingPort, new ArrayList<>());
// 创建 PriceInfo 对象并添加到列表中
PriceInfo priceInfo = new PriceInfo("海运", originatingPort, destinationPort, freightPrice);
priceInfoList.add(priceInfo);
// 将列表放回 priceMap 中
priceMap.put(originatingPort, priceInfoList);
}
// 添加海运价格信息
/*
priceMap.put("始发港1", Collections.singletonList(
new PriceInfo("海运", "始发港1", "目的港1", 500.0)
));
priceMap.put("始发港2", Arrays.asList(
new PriceInfo("海运", "始发港2", "目的港1", 480.0),
new PriceInfo("海运", "始发港2", "目的港2", 490.0)
));
priceMap.put("始发港3", Collections.singletonList(
new PriceInfo("海运", "始发港3", "目的港2", 510.0)
));
*/
//送货价格集合
//List<TSeaFreightDeliveryPrice> tSeaFreightDeliveryPrices = tSeaFreightDeliveryPriceService.list();
List<TSeaFreightDeliveryPrice> tSeaFreightDeliveryPrices = myCache.getAllTSeaFreightDeliveryPrice();
// 遍历查询结果
for (TSeaFreightDeliveryPrice price : tSeaFreightDeliveryPrices) {
// 假设 OceanFreightPrice 类有相应的 getter 方法来获取字段值
String destinationPort = price.getNvcDestinationPortAddress(); // 目的港
String destinationDetailAddress = price.getNvcDestinationDetailAddress(); // 目的地
double freightPrice = price.getDDestinationExtras() + price.getDDeliveryTrailerFee(); // 海运费
// 检查 priceMap 中是否已经有该始发港的列表
List<PriceInfo> priceInfoList = priceMap.getOrDefault(destinationPort, new ArrayList<>());
// 创建 PriceInfo 对象并添加到列表中
PriceInfo priceInfo = new PriceInfo("送货", destinationPort, destinationDetailAddress, freightPrice);
priceInfoList.add(priceInfo);
// 将列表放回 priceMap 中
priceMap.put(destinationPort, priceInfoList);
}
// 添加送货价格信息
/*
priceMap.put("目的港1", Arrays.asList(
new PriceInfo("送货", "目的港1", "目的地X", 150.0),
new PriceInfo("送货", "目的港1", "目的地Y", 160.0)
));
priceMap.put("目的港2", Collections.singletonList(
new PriceInfo("送货", "目的港2", "目的地Y", 140.0)
));
*/
// 创建海运价格计算器实例
SeaFreightCalculator calculator = new SeaFreightCalculator(priceMap);
LowestPriceResult result = new LowestPriceResult();
if (dto.getIType() == 1) {
result = calculator.calculateLowestPrice(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());
}
if (dto.getIType() == 2) {
result = calculator.calculateLowestPriceFromOriginToPort(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());
}
if (dto.getIType() == 3) {
result = calculator.calculateLowestPriceFromPortToDestination(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());
}
if (dto.getIType() == 4) {
result = calculator.calculateLowestPriceFromPortToPort(dto.getNvcOrginatingDetailAddress(), dto.getNvcDestinationDetailAddress());
}
searchPriceResult.setLowestTotalPrice(result.getLowestTotalPrice());
// if (result.getPortPrice()==null) result.getSeaPrice().setPrice() = 0.0;
searchPriceResult.setPortPrice(result.getPortPrice() == null ? null : result.getPortPrice().getPrice());
searchPriceResult.setSeaPrice(result.getSeaPrice() == null ? null : result.getSeaPrice().getPrice());
searchPriceResult.setDeliveryPrice(result.getDeliveryPrice() == null ? null : result.getDeliveryPrice().getPrice());
/*
// 计算从始发地A到目的港的最低价格 门到港
LowestPriceResult result1 = calculator.calculateLowestPriceFromOriginToPort("始发地A", "目的港2");
System.out.println(result1);
// 计算从始发港1到目的港的最低价格 港到港
LowestPriceResult result2 = calculator.calculateLowestPriceFromPortToPort("始发港1", "目的港1");
System.out.println(result2);
// 计算从始发港2到目的地的最低价格 港到门
LowestPriceResult result3 = calculator.calculateLowestPriceFromPortToDestination("始发港2", "目的地Y");
System.out.println(result3);
// 计算从始发地A到目的地Y的最低价格 门到门
LowestPriceResult result = calculator.calculateLowestPrice("始发地A", "目的地Y");
System.out.println(result);*/
return searchPriceResult;
}
下面是计算价格的核心方法
public class SeaFreightCalculator {
private Map<String, List<PriceInfo>> priceMap;
public SeaFreightCalculator(Map<String, List<PriceInfo>> priceMap) {
this.priceMap = priceMap;
}
// 公共方法:获取特定类型的价格信息
private List<PriceInfo> getPrices(String from, String type) {
return priceMap.getOrDefault(from, Collections.emptyList()).stream()
.filter(price -> price.getType().equals(type))
.collect(Collectors.toList());
}
// 计算从始发港到目的港的最低价格(港到港)
public LowestPriceResult calculateLowestPriceFromPortToPort(String from, String to) {
LowestPriceResult result = new LowestPriceResult();
result.setFrom(from);
result.setTo(to);
double lowestTotalPrice = Double.MAX_VALUE;
PriceInfo lowestPrice = null;
for (PriceInfo price : getPrices(from, "海运")) {
if (price.getTo().equals(to) && lowestTotalPrice > price.getPrice()) {
lowestTotalPrice = price.getPrice();
lowestPrice = price;
}
}
if (lowestPrice != null) {
result.setLowestTotalPrice(lowestTotalPrice);
result.setSeaPrice(lowestPrice);
}
return result;
}
// 计算从始发地到目的港的最低价格(需要集港和海运两段)(门到港)
public LowestPriceResult calculateLowestPriceFromOriginToPort(String from, String to) {
LowestPriceResult result = new LowestPriceResult();
result.setFrom(from);
result.setTo(to);
double lowestTotalPrice = Double.MAX_VALUE;
PriceInfo lowestPortPrice = null, lowestSeaPrice = null;
// 遍历所有集港价格
for (PriceInfo collectionPrice : getPrices(from, "集港")) {
String intermediatePort = collectionPrice.getTo(); // 中间港口
// 对于每个中间港口,找到到目的港的海运价格
for (PriceInfo seaPrice : getPrices(intermediatePort, "海运")) {
if (seaPrice.getTo().equals(to)) {
double totalPrice = collectionPrice.getPrice() + seaPrice.getPrice();
if (totalPrice < lowestTotalPrice) {
lowestTotalPrice = totalPrice;
lowestPortPrice = collectionPrice;
lowestSeaPrice = seaPrice;
}
}
}
}
if (lowestPortPrice != null && lowestSeaPrice != null) {
result.setLowestTotalPrice(lowestTotalPrice);
result.setPortPrice(lowestPortPrice);
result.setSeaPrice(lowestSeaPrice);
}
return result;
}
// 计算从始发港到目的地的最低价格(需要海运和送货两段)(港到门)
public LowestPriceResult calculateLowestPriceFromPortToDestination(String fromPort, String toDestination) {
LowestPriceResult result = new LowestPriceResult();
result.setFrom(fromPort);
result.setTo(toDestination);
double lowestTotalPrice = Double.MAX_VALUE;
PriceInfo lowestSeaPrice = null, lowestDeliveryPrice = null;
for (PriceInfo seaPrice : getPrices(fromPort, "海运")) {
for (PriceInfo deliveryPrice : getPrices(seaPrice.getTo(), "送货")) {
if (deliveryPrice.getTo().equals(toDestination)) {
double totalPrice = seaPrice.getPrice() + deliveryPrice.getPrice();
if (totalPrice < lowestTotalPrice) {
lowestTotalPrice = totalPrice;
lowestSeaPrice = seaPrice;
lowestDeliveryPrice = deliveryPrice;
}
}
}
}
if (lowestSeaPrice != null && lowestDeliveryPrice != null) {
result.setLowestTotalPrice(lowestTotalPrice);
result.setSeaPrice(lowestSeaPrice);
result.setDeliveryPrice(lowestDeliveryPrice);
}
return result;
}
// 计算最低价格的方法 (计算从始发地到目的地的最低价格需要集港、海运、送货三段,门到门)
public LowestPriceResult calculateLowestPrice(String from, String to) {
LowestPriceResult lowestPriceResult = new LowestPriceResult();
lowestPriceResult.setFrom(from);
lowestPriceResult.setTo(to);
double lowestTotalPrice = Double.MAX_VALUE;
PriceInfo lowestPortPrice = null, lowestSeaPrice = null, lowestDeliveryPrice = null;
// 遍历所有可能的路径
for (PriceInfo portPrice : priceMap.getOrDefault(from, Collections.emptyList())) {
if ("集港".equals(portPrice.getType())) {
for (PriceInfo seaPrice : priceMap.getOrDefault(portPrice.getTo(), Collections.emptyList())) {
if ("海运".equals(seaPrice.getType())) {
for (PriceInfo deliveryPrice : priceMap.getOrDefault(seaPrice.getTo(), Collections.emptyList())) {
if ("送货".equals(deliveryPrice.getType()) && deliveryPrice.getTo().equals(to)) {
double totalPrice = portPrice.getPrice() + seaPrice.getPrice() + deliveryPrice.getPrice();
if (totalPrice < lowestTotalPrice) {
lowestTotalPrice = totalPrice;
lowestPortPrice = portPrice;
lowestSeaPrice = seaPrice;
lowestDeliveryPrice = deliveryPrice;
}
}
}
}
}
}
}
// 设置最低价格和各段价格
if (lowestTotalPrice != Double.MAX_VALUE) {
lowestPriceResult.setLowestTotalPrice(lowestTotalPrice);
lowestPriceResult.setPortPrice(lowestPortPrice);
lowestPriceResult.setSeaPrice(lowestSeaPrice);
lowestPriceResult.setDeliveryPrice(lowestDeliveryPrice);
}
return lowestPriceResult;
}
}