MetalTargetStrategy.java 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package lingtao.net.Factory;
  2. import lingtao.net.bean.Product;
  3. import lingtao.net.util.PriceUtils;
  4. import lingtao.net.vo.PricingListVo;
  5. import lingtao.net.vo.ProductVo;
  6. import java.math.BigDecimal;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. public class MetalTargetStrategy implements PricingStrategy {
  10. @Override
  11. public PricingListVo calculatePrice(Product dto, String role) {
  12. String plantName = dto.getPlantName();
  13. double width = dto.getWidth();
  14. double length = dto.getLength();
  15. int count = dto.getCount();
  16. int number = dto.getNumber();
  17. List<ProductVo> resultList = new ArrayList<>();
  18. // 定义纸张尺寸(单位:毫米)
  19. double paperLength = 295; // 纸张长度
  20. double paperWidth = 195; // 纸张宽度
  21. double basePrice = 0; // 基础价格
  22. double minPrice = 0; // 起步价
  23. double price = 0; // 最终价格
  24. double colorPrice = 0; // 颜色附加费
  25. double moreColorPrice = 0; // 多颜色附加费
  26. int requiredSheets = 0;
  27. BigDecimal weight = BigDecimal.ZERO;
  28. // 转换尺寸为毫米并增加边距
  29. length = convertToMillimetersWithMargin(length);
  30. width = convertToMillimetersWithMargin(width);
  31. if ("金大".equals(plantName) || "鑫灿".equals(plantName)) {
  32. // 检查是否超出纸张尺寸限制
  33. if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
  34. return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
  35. }
  36. // 计算一张纸能容纳的最大金属标数量
  37. double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);
  38. // 计算所需纸张数量
  39. requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
  40. // 计算颜色附加费
  41. if (!"金色".equals(dto.getTcolor()) && !"银色".equals(dto.getTcolor()) && !"玫瑰金色".equals(dto.getTcolor())) {
  42. colorPrice = 1;
  43. }
  44. if ("金大".equals(plantName)) {
  45. // 设置起步价
  46. minPrice = 45;
  47. if ("双色".equals(dto.getCraftMo())) {
  48. minPrice = 70;
  49. moreColorPrice = 10;
  50. }
  51. if ("彩色(三色)".equals(dto.getCraftMo())) {
  52. minPrice = 105;
  53. moreColorPrice = 20;
  54. }
  55. colorPrice += moreColorPrice;
  56. // 根据数量计算基础价格
  57. if (requiredSheets <= 2) {
  58. price = minPrice + colorPrice;
  59. } else if (requiredSheets <= 9) {
  60. price = minPrice + (requiredSheets - 2) * (12 + colorPrice);
  61. } else if (requiredSheets <= 19) {
  62. price = Math.ceil((13 + colorPrice) * requiredSheets);
  63. } else if (requiredSheets <= 29) {
  64. price = Math.ceil((12 + colorPrice) * requiredSheets);
  65. } else if (requiredSheets <= 39) {
  66. price = Math.ceil((11 + colorPrice) * requiredSheets);
  67. } else if (requiredSheets <= 49) {
  68. price = Math.ceil((10 + colorPrice) * requiredSheets);
  69. } else {
  70. price = Math.ceil((9 + colorPrice) * requiredSheets);
  71. }
  72. }
  73. if ("鑫灿".equals(plantName)) {
  74. // 设置起步价
  75. minPrice = 45;
  76. if ("双色".equals(dto.getCraftMo())) {
  77. minPrice = 55;
  78. moreColorPrice = 10;
  79. }
  80. if ("彩色(三色)".equals(dto.getCraftMo())) {
  81. minPrice = 105;
  82. moreColorPrice = 20;
  83. }
  84. colorPrice += moreColorPrice;
  85. // 根据数量计算基础价格
  86. if (requiredSheets <= 2) {
  87. price = minPrice + colorPrice;
  88. } else if (requiredSheets <= 9) {
  89. price = minPrice + (requiredSheets - 2) * (10 + colorPrice);
  90. } else if (requiredSheets <= 19) {
  91. price = Math.ceil((13 + colorPrice) * requiredSheets);
  92. } else if (requiredSheets <= 29) {
  93. price = Math.ceil((12 + colorPrice) * requiredSheets);
  94. } else if (requiredSheets <= 39) {
  95. price = Math.ceil((11 + colorPrice) * requiredSheets);
  96. } else if (requiredSheets <= 49) {
  97. price = Math.ceil((10 + colorPrice) * requiredSheets);
  98. } else if (requiredSheets <= 100) {
  99. price = Math.ceil((9 + colorPrice) * requiredSheets);
  100. } else {
  101. price = Math.ceil((8 + colorPrice) * requiredSheets);
  102. }
  103. }
  104. }
  105. if ("紫瑶".equals(plantName)) {
  106. paperLength = 170;
  107. paperWidth = 300;
  108. // 检查是否超出纸张尺寸限制
  109. if (!isWithinPaperSize(length, width, paperLength, paperWidth)) {
  110. return new PricingListVo(100, "出纸张尺寸限制"); // 返回空列表表示不适用
  111. }
  112. // 计算一张纸能容纳的最大金属标数量
  113. double maxItemsPerSheet = calculateMaxItemsPerSheet(length, width, paperLength, paperWidth);
  114. // 计算所需纸张数量
  115. requiredSheets = calculateRequiredSheets(count, number, maxItemsPerSheet);
  116. // 计算颜色附加费
  117. if (!"银色".equals(dto.getTcolor())) {
  118. colorPrice = 1;
  119. }
  120. // 设置起步价
  121. minPrice = 40;
  122. if ("单色".equals(dto.getCraftMo())) {
  123. if (requiredSheets == 1) {
  124. price = colorPrice == 1 ? 45 : 40;
  125. } else if (requiredSheets == 2) {
  126. price = colorPrice == 1 ? 55 : 50;
  127. } else if (requiredSheets == 3) {
  128. price = colorPrice == 1 ? 65 : 55;
  129. } else if (requiredSheets == 4) {
  130. price = colorPrice == 1 ? 70 : 60;
  131. } else if (requiredSheets == 5) {
  132. price = colorPrice == 1 ? 75 : 65;
  133. } else if (requiredSheets == 6) {
  134. price = colorPrice == 1 ? 80 : 70;
  135. } else {
  136. price = colorPrice == 1 ? 80 + (requiredSheets - 6) * 9 : 70 + (requiredSheets - 6) * 8;
  137. }
  138. }
  139. if ("双色".equals(dto.getCraftMo())) {
  140. minPrice = 60;
  141. moreColorPrice = 30;
  142. }
  143. if ("彩色(三色)".equals(dto.getCraftMo())) {
  144. minPrice = 70;
  145. moreColorPrice = 40;
  146. }
  147. if (price == 0) {
  148. price = Math.ceil(minPrice + moreColorPrice * (requiredSheets - 1));
  149. }
  150. }
  151. // 创建产品对象并添加到结果列表
  152. ProductVo pro = new ProductVo();
  153. pro.setPrice(price);
  154. pro.setCount(count);
  155. pro.setWeight(BigDecimal.valueOf(requiredSheets / 30).setScale(2, BigDecimal.ROUND_HALF_UP).toString());
  156. resultList.add(pro);
  157. return new PricingListVo(resultList);
  158. }
  159. /**
  160. * 将给定的尺寸转换为毫米,并在每边增加3毫米的边距
  161. *
  162. * @param size 需要转换的原始尺寸
  163. * @return 转换后的尺寸,单位为毫米,包括边距
  164. */
  165. private double convertToMillimetersWithMargin(double size) {
  166. return size * 10 + 2 * 1.5; // 换成毫米,每边+3
  167. }
  168. /**
  169. * 检查给定的长度和宽度是否在纸张尺寸范围内
  170. *
  171. * @param length 需要检查的长度
  172. * @param width 需要检查的宽度
  173. * @param paperLength 纸张的长度
  174. * @param paperWidth 纸张的宽度
  175. * @return 如果给定尺寸在纸张尺寸范围内,则返回true;否则返回false
  176. */
  177. private boolean isWithinPaperSize(double length, double width, double paperLength, double paperWidth) {
  178. return (length <= paperLength && width <= paperWidth) || (length <= paperWidth && width <= paperLength);
  179. }
  180. /**
  181. * 计算每张纸最多可以容纳的物品数量
  182. *
  183. * @param length 物品的长度
  184. * @param width 物品的宽度
  185. * @param paperLength 纸张的长度
  186. * @param paperWidth 纸张的宽度
  187. * @return 每张纸最多可以容纳的物品数量
  188. */
  189. private double calculateMaxItemsPerSheet(double length, double width, double paperLength, double paperWidth) {
  190. return Math.max(
  191. Math.floor(paperLength / length) * Math.floor(paperWidth / width),
  192. Math.floor(paperLength / width) * Math.floor(paperWidth / length)
  193. );
  194. }
  195. /**
  196. * 计算完成指定数量的物品所需的纸张数量
  197. *
  198. * @param count 物品的总数量
  199. * @param number 每个物品需要的数量
  200. * @param maxItemsPerSheet 每张纸最多可以容纳的物品数量
  201. * @return 完成指定数量的物品所需的纸张数量
  202. */
  203. private int calculateRequiredSheets(int count, int number, double maxItemsPerSheet) {
  204. return (int) Math.ceil((count * number) / maxItemsPerSheet);
  205. }
  206. }