399 lines
20 KiB
Java
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);
|
|
}
|
|
}
|