Files
quote_price/src/main/java/lingtao/net/Factory/CardPricingStrategy.java
T
2025-04-13 01:36:45 +08:00

399 lines
20 KiB
Java

package lingtao.net.Factory;
import lingtao.net.bean.Product;
import lingtao.net.vo.PricingListVo;
import lingtao.net.vo.ProductVo;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
public class CardPricingStrategy implements PricingStrategy {
@Override
public PricingListVo calculatePrice(Product dto, String role) {
String plantName = dto.getPlantName();
String kindValue = dto.getProTypeLabel();
if ("菜单".equals(kindValue)) {
//return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
// String size = dto.getUi_menu_size();
// dto.setLength(Double.valueOf(size.substring(0, size.indexOf("*"))));
// if (size.contains(",")) {
// size = size.split(",")[0];
// }
// if (size.indexOf(("*"), size.indexOf("*") + 1) == -1) {
// dto.setWidth(Double.valueOf(size.substring(size.indexOf("*") + 1)));
// } else {
// dto.setWidth(Double.valueOf(size.substring(size.indexOf("*") + 1, size.indexOf(("*"), size.indexOf("*") + 1))));
// dto.setLength(Math.abs(Double.parseDouble(size.substring(size.indexOf(("*"), size.indexOf("*") + 1) + 1))));
// }
}
double width = dto.getWidth();
double length = dto.getLength();
int count = dto.getCount();
int number = dto.getNumber();
// 定义纸张尺寸(单位:毫米)
double paperLength = 280; // 纸张长度
double paperWidth = 420; // 纸张宽度
String basePrice = "0"; // 基础价格
BigDecimal price = new BigDecimal(0); // 最终价格
BigDecimal weight = BigDecimal.ZERO;
length = convertToMillimetersWithMargin(length);
width = convertToMillimetersWithMargin(width);
String material = "1";
if ("婚礼报纸".equals(kindValue)) {
material = "2";//157g铜版纸
} else if ("特种纸名片".equals(kindValue)) {
material = dto.getKindValue6();
} else if ("菜单".equals(kindValue) && "2".equals(dto.getKindValue5())) {
material = "pvc";
}
String ggSize = dto.getSize1();//刮刮膜
List<ProductVo> resultList = new ArrayList<>();
List<String> craft_list = dto.getCraft() != null ? Arrays.asList(dto.getCraft()) : new ArrayList<>();
if ("艾印".equals(plantName) && !"种子纸".equals(kindValue) && !"菜单".equals(kindValue)) {
if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
return new PricingListVo(100, "车间无烫金工艺"); // 返回空列表表示不适用
}
Map<String, Map<String, String>> kindValuePrice = new HashMap<>();
// 统一键的类型为字符串
kindValuePrice.put("1", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
kindValuePrice.put("2", createPriceMap("1", "1.8", "2", "2.4"));//157g铜版纸
kindValuePrice.put("皙贝", createPriceMap("1", "2.1", "2", "3.1"));//白卡
kindValuePrice.put("琮纹", createPriceMap("1", "2.5", "2", "3.7"));//刚古
kindValuePrice.put("玉蕊", createPriceMap("1", "2.7", "2", "3.8"));//蛋壳
kindValuePrice.put("睿狐", createPriceMap("1", "2.7", "2", "3.8"));//莱尼
kindValuePrice.put("溪雪", createPriceMap("1", "3.2", "2", "3.2"));//珠光
if (!kindValuePrice.containsKey(material)) {
return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
}
// 检查是否超出纸张尺寸限制
if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
}
// 计算一张纸能容纳的最大金属标数量
double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);
// 计算所需纸张数量
int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
//单双面单价不一致
Map<String, String> prices = kindValuePrice.get(material);
if ("双面印刷".equals(dto.getCraftShua())) {
basePrice = prices.get("2");
} else {
basePrice = prices.get("1");
}
price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);
if ("刮刮卡".equals(kindValue)) {
Map<String, Map<String, String>> ggmPrices = new HashMap<String, Map<String, String>>();
ggmPrices.put("60*25", createPriceMap("50", "3", "100", "5"));
ggmPrices.put("48*15", createPriceMap("50", "2", "100", "3"));
ggmPrices.put("8*30", createPriceMap("50", "1", "100", "2"));
ggmPrices.put("6*22", createPriceMap("50", "0.8", "100", "1.6"));
if (!ggmPrices.containsKey(ggSize)) {
return new PricingListVo(100, "无该尺寸刮刮膜"); // 返回空列表表示不适用
}
Map<String, String> ggmPrice = ggmPrices.get(ggSize);
if (count <= 50) {
price = price.add(new BigDecimal(ggmPrice.get("50"))).setScale(2, RoundingMode.HALF_UP);
} else {
price = price.add(new BigDecimal(ggmPrice.get("100"))).setScale(2, RoundingMode.HALF_UP);
}
}
}
if ("即客".equals(plantName) && !"种子纸".equals(kindValue) && !"菜单".equals(kindValue)) {
if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
return new PricingListVo(100, "车间无烫金工艺"); // 返回空列表表示不适用
}
Map<String, Map<String, String>> kindValuePrice = new HashMap<>();
// 统一键的类型为字符串
kindValuePrice.put("1", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
kindValuePrice.put("2", createPriceMap("1", "1.8", "2", "2.4"));//157g铜版纸
kindValuePrice.put("萱姿", createPriceMap("1", "3", "2", "3"));//雅柔
kindValuePrice.put("芳怡", createPriceMap("1", "3", "2", "3"));//草香
if (!kindValuePrice.containsKey(material)) {
return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
}
// 检查是否超出纸张尺寸限制
if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
}
// 计算一张纸能容纳的最大金属标数量
double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);
// 计算所需纸张数量
int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
//单双面单价不一致
Map<String, String> prices = kindValuePrice.get(material);
if ("双面印刷".equals(dto.getCraftShua())) {
basePrice = prices.get("2");
} else {
basePrice = prices.get("1");
}
price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);
if ("刮刮卡".equals(kindValue)) {
Map<String, Map<String, String>> ggmPrices = new HashMap<String, Map<String, String>>();
ggmPrices.put("60*25", createPriceMap("50", "3", "100", "6"));
ggmPrices.put("48*15", createPriceMap("50", "2", "100", "4"));
ggmPrices.put("8*30", createPriceMap("50", "1", "100", "2"));
ggmPrices.put("6*22", createPriceMap("50", "0.8", "100", "1.6"));
if (!ggmPrices.containsKey(ggSize)) {
return new PricingListVo(100, "无该尺寸刮刮膜"); // 返回空列表表示不适用
}
Map<String, String> ggmPrice = ggmPrices.get(ggSize);
if (count <= 50) {
price = price.add(new BigDecimal(ggmPrice.get("50"))).setScale(2, RoundingMode.HALF_UP);
} else {
price = price.add(new BigDecimal(ggmPrice.get("100"))).setScale(2, RoundingMode.HALF_UP);
}
}
}
if ("欣海信".equals(plantName) && !"种子纸".equals(kindValue)) {
paperLength = 272; // 纸张长度
paperWidth = 390; // 纸张宽度
Map<String, Map<String, String>> kindValuePrice = new HashMap<>();
// 统一键的类型为字符串
kindValuePrice.put("1", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
kindValuePrice.put("pvc", createPriceMap("1", "3", "2", "3.3"));//300g铜版纸
kindValuePrice.put("2", createPriceMap("1", "1.8", "2", "2.4"));//157g铜版纸
kindValuePrice.put("溪雪", createPriceMap("1", "4", "2", "6"));//珠光
kindValuePrice.put("琮纹", createPriceMap("1", "4", "2", "6"));//刚古
kindValuePrice.put("睿狐", createPriceMap("1", "4", "2", "6"));//莱尼
kindValuePrice.put("玉蕊", createPriceMap("1", "4", "2", "6"));//蛋壳
if (!kindValuePrice.containsKey(material)) {
return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
}
// 检查是否超出纸张尺寸限制
if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
}
// 计算一张纸能容纳的最大金属标数量
double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);
// 计算所需纸张数量
int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
//单双面单价不一致
Map<String, String> prices = kindValuePrice.get(material);
if ("双面印刷".equals(dto.getCraftShua())) {
basePrice = prices.get("2");
if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
basePrice = new BigDecimal(basePrice).add(new BigDecimal(prices.get("18"))).setScale(2, RoundingMode.HALF_UP).toString();
}
} else {
basePrice = prices.get("1");
if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
basePrice = new BigDecimal(basePrice).add(new BigDecimal(prices.get("9"))).setScale(2, RoundingMode.HALF_UP).toString();
}
}
price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);
if ("刮刮卡".equals(kindValue)) {
price = price.add(new BigDecimal(0.3).multiply(new BigDecimal(count))).setScale(2, RoundingMode.HALF_UP);
}
}
if ("彩印通".equals(plantName) && !"种子纸".equals(kindValue) && !"菜单".equals(kindValue)) {
paperLength = 297;
paperWidth = 420;
if (craft_list.contains("烫金") || craft_list.contains("彩色印刷+烫金")) {
return new PricingListVo(100, "车间无烫金工艺"); // 返回空列表表示不适用
}
Map<String, Map<String, String>> kindValuePrice = new HashMap<>();
// 统一键的类型为字符串
kindValuePrice.put("1", createPriceMap("1", "2.5", "2", "3"));//300g铜版纸
kindValuePrice.put("芳怡", createPriceMap("1", "5.5", "2", "5.5"));//草香
kindValuePrice.put("溪雪", createPriceMap("1", "3.5", "2", "3.5"));//珠光
kindValuePrice.put("萱姿", createPriceMap("1", "5", "2", "5"));//雅柔
if (!kindValuePrice.containsKey(material)) {
return new PricingListVo(100, "暂无报价"); // 返回空列表表示不适用
}
// 检查是否超出纸张尺寸限制
if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
}
// 计算一张纸能容纳的最大金属标数量
double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);
// 计算所需纸张数量
int requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
//单双面单价不一致
Map<String, String> prices = kindValuePrice.get(material);
if ("双面印刷".equals(dto.getCraftShua())) {
basePrice = prices.get("2");
} else {
basePrice = prices.get("1");
}
if (craft_list.contains("异形")) {
basePrice = new BigDecimal(basePrice).add(new BigDecimal("0.5")).setScale(2, RoundingMode.HALF_UP).toString();
}
price = new BigDecimal(basePrice).multiply(new BigDecimal(requiredSheets)).setScale(2, RoundingMode.HALF_UP);
if ("刮刮卡".equals(kindValue)) {
BigDecimal ggPrice = new BigDecimal("0.02").multiply(new BigDecimal(count));
price = price.add(ggPrice.compareTo(new BigDecimal("30")) > 0 ? ggPrice : new BigDecimal("30")).setScale(2, RoundingMode.HALF_UP);
}
}
if ("种子纸".equals(kindValue) && "鸿晟".equals(plantName)) {
if (!StringUtils.isEmpty(dto.getSwitchz3Size()) || "2".equals(dto.getZ3type())) {
count = Math.max(count, 300);
}
price = BigDecimal.valueOf((length * width * count * 70) / 1000000).setScale(2, RoundingMode.HALF_UP);//价格计算尺寸*数量*200/10000
if (craft_list.contains("编码")) {//起步价10
price = price.add(max(new BigDecimal(count * 0.4), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
if (craft_list.contains("打孔")) {
price = price.add(max(new BigDecimal(count * 0.1), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
if (craft_list.contains("手撕线")) {
price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
if (craft_list.contains("压痕")) {
price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
price = price.multiply(new BigDecimal(number));//款数翻倍
price = max(price, new BigDecimal(80)).setScale(2, RoundingMode.HALF_UP);
if (!StringUtils.isEmpty(dto.getSwitchz3Size())) {
price = price.add(new BigDecimal(100)).add(new BigDecimal(count * 0.1)).setScale(2, RoundingMode.HALF_UP);
}
if (craft_list.size() > 0 && craft_list.contains("绳子")) {
price = price.add(max(new BigDecimal(0.1 * number * count), new BigDecimal(5))).setScale(2, RoundingMode.HALF_UP);
}
}
if ("种子纸".equals(kindValue) && "驰远".equals(plantName)) {
if (!StringUtils.isEmpty(dto.getSwitchz3Size()) || "2".equals(dto.getZ3type())) {
count = Math.max(count, 300);
}
basePrice = "45";
if (!StringUtils.isEmpty(dto.getSwitchz3Size())) {
basePrice = "65";
if (length > 12 || width > 12) {
return new PricingListVo(100, "纸张尺寸超出");
}
}
price = BigDecimal.valueOf((length * width * count) / 1000000).multiply(new BigDecimal(basePrice)).setScale(2, RoundingMode.HALF_UP);//价格计算尺寸*数量*200/10000
if (craft_list.contains("编码")) {//起步价10
price = price.add(max(new BigDecimal(count * 0.4), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
if (craft_list.contains("打孔")) {
price = price.add(max(new BigDecimal(count * 0.1), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
if (craft_list.contains("手撕线")) {
price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
if (craft_list.contains("压痕")) {
price = price.add(max(new BigDecimal(count * 0.2), new BigDecimal(10))).setScale(2, RoundingMode.HALF_UP);
}
price = price.multiply(new BigDecimal(number));//款数翻倍
price = max(price, new BigDecimal(80)).setScale(2, RoundingMode.HALF_UP);
if (craft_list.size() > 0 && craft_list.contains("绳子")) {
price = price.add(max(new BigDecimal(0.1 * number * count), new BigDecimal(5))).setScale(2, RoundingMode.HALF_UP);
}
}
weight = BigDecimal.valueOf(number * (length) / 1000 * (width) / 1000 * count * 0.25 * 1.15);
// 创建产品对象并添加到结果列表
ProductVo pro = new ProductVo();
pro.setPrice(price.doubleValue());
pro.setCount(count);
pro.setWeight(weight.toString());
resultList.add(pro);
return new PricingListVo(resultList);
}
public static BigDecimal max(BigDecimal a, BigDecimal b) {
if (a == null) {
return b;
}
if (b == null) {
return a;
}
return a.compareTo(b) >= 0 ? a : b;
}
/**
* 创建价格映射
*
* @param keysAndValues 键值对数组
* @return 初始化后的价格映射
*/
private Map<String, String> createPriceMap(String... keysAndValues) {
if (keysAndValues.length % 2 != 0) {
throw new IllegalArgumentException("键值对数量必须为偶数");
}
Map<String, String> priceMap = new HashMap<>();
for (int i = 0; i < keysAndValues.length; i += 2) {
priceMap.put(keysAndValues[i], keysAndValues[i + 1]);
}
return priceMap;
}
/**
* 将给定的尺寸转换为毫米,并在每边增加3毫米的边距
*
* @param size 需要转换的原始尺寸
* @return 转换后的尺寸,单位为毫米,包括边距
*/
private double convertToMillimetersWithMargin(double size) {
return size * 10 + 2 * 2; // 换成毫米,每边+2
}
/**
* 检查给定的长度和宽度是否在纸张尺寸范围内
*
* @param length 需要检查的长度
* @param width 需要检查的宽度
* @param paperLength 纸张的长度
* @param paperWidth 纸张的宽度
* @return 如果给定尺寸在纸张尺寸范围内,则返回true;否则返回false
*/
private boolean isWithinPaperSize(double length, double width, double paperLength, double paperWidth) {
return (length <= paperLength && width <= paperWidth) || (length <= paperWidth && width <= paperLength);
}
/**
* 计算每张纸最多可以容纳的物品数量
*
* @param length 物品的长度
* @param width 物品的宽度
* @param paperLength 纸张的长度
* @param paperWidth 纸张的宽度
* @return 每张纸最多可以容纳的物品数量
*/
private double calculateMaxItemsPerSheet(double length, double width, double paperLength, double paperWidth) {
return Math.max(
Math.floor(paperLength / length) * Math.floor(paperWidth / width),
Math.floor(paperLength / width) * Math.floor(paperWidth / length)
);
}
/**
* 计算完成指定数量的物品所需的纸张数量
*
* @param count 物品的总数量
* @param number 每个物品需要的数量
* @param maxItemsPerSheet 每张纸最多可以容纳的物品数量
* @return 完成指定数量的物品所需的纸张数量
*/
private int calculateRequiredSheets(int count, int number, double maxItemsPerSheet) {
return (int) Math.ceil((count * number) / maxItemsPerSheet);
}
}