24282 1 год назад
Родитель
Сommit
312f0ca7ed

+ 20 - 0
sd-business/src/main/java/com/sd/business/entity/work/constant/MaterialsConstant.java

@@ -0,0 +1,20 @@
+package com.sd.business.entity.work.constant;
+
+public interface MaterialsConstant {
+
+    /**
+     * 出血长度
+     */
+    double RESERVE = 5.5;
+
+    /**
+     * 卷材长度
+     */
+    int MASTER_LENGTH = 4300;
+
+    /**
+     * 卷材宽度
+     */
+    int MASTER_WIDTH = 163;
+
+}

+ 1 - 1
sd-business/src/main/java/com/sd/business/entity/work/enums/WorkOrderFixationSpecEnum.java

@@ -10,7 +10,7 @@ import java.math.BigDecimal;
 @AllArgsConstructor
 public enum WorkOrderFixationSpecEnum {
 
-    SKU_SPEC(new BigDecimal("30"), new BigDecimal("40"), 430),
+    SPEC_30_40(new BigDecimal("30"), new BigDecimal("40"), 430),
     ;
 
     /**

+ 0 - 10
sd-business/src/main/java/com/sd/business/entity/work/po/WorkOrder.java

@@ -26,21 +26,11 @@ public class WorkOrder extends BasePo {
     private String code;
 
     /**
-     * 生产批次号
-     */
-    private Integer productionBatchNumber;
-
-    /**
      * 1固定尺寸排版 2随机排版
      */
     private Integer type;
 
     /**
-     * 固定尺寸排版最多排版个数
-     */
-    private BigDecimal fixationMaxNum;
-
-    /**
      * 固定尺寸排版规格参数
      */
     private String fixationSpec;

+ 20 - 5
sd-business/src/main/java/com/sd/business/entity/work/po/WorkOrderDetail.java

@@ -21,11 +21,6 @@ import java.math.BigDecimal;
 public class WorkOrderDetail extends BasePo {
 
     /**
-     * 生产批次号
-     */
-    private Integer productionBatchNumber;
-
-    /**
      * 工单id
      */
     private Long workOrderId;
@@ -51,6 +46,26 @@ public class WorkOrderDetail extends BasePo {
     private BigDecimal y;
 
     /**
+     * 长(考虑旋转后的)
+     */
+    private BigDecimal length;
+
+    /**
+     * 宽(考虑旋转后的)
+     */
+    private BigDecimal width;
+
+    /**
+     * 出血长(考虑旋转后的)
+     */
+    private BigDecimal bleedingLength;
+
+    /**
+     * 出血宽(考虑旋转后的)
+     */
+    private BigDecimal bleedingWidth;
+
+    /**
      * 是否旋转
      */
     private Integer rotate;

+ 15 - 14
sd-business/src/main/java/com/sd/business/service/work/impl/WorkOrderServiceImpl.java

@@ -10,6 +10,7 @@ import com.ruoyi.common.core.domain.BaseIdPo;
 import com.ruoyi.common.exception.ServiceException;
 import com.sd.business.entity.order.po.OrderSku;
 import com.sd.business.entity.sku.po.SkuSpec;
+import com.sd.business.entity.work.constant.MaterialsConstant;
 import com.sd.business.entity.work.dto.WorkOrderSelectDto;
 import com.sd.business.entity.work.enums.WorkOrderFixationSpecEnum;
 import com.sd.business.entity.work.po.WorkOrder;
@@ -51,9 +52,6 @@ import java.util.stream.Collectors;
 public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder> implements WorkOrderService {
 
     private static final ReentrantLock schedulingLock = new ReentrantLock();
-    private static final double reserve = 5.5;
-    private static final int master_length = 4300;
-    private static final int master_width = 163;
 
     @Autowired
     private SkuSpecService skuSpecService;
@@ -235,8 +233,8 @@ public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder
             List<Item> itemList = new ArrayList<>();
             for (int i = 0; i < schedulingNum; i++) {
                 Long orderSkuId = item.getId();
-                double length = skuSpec.getLength().doubleValue() + reserve;
-                double width = skuSpec.getWidth().doubleValue() + reserve;
+                double length = skuSpec.getLength().doubleValue() + MaterialsConstant.RESERVE;
+                double width = skuSpec.getWidth().doubleValue() + MaterialsConstant.RESERVE;
 
                 itemList.add(new Item(orderSkuId, length, width));
             }
@@ -244,7 +242,7 @@ public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder
             return itemList.stream();
         }).toArray(Item[]::new);
 
-        Solution solve = GA.solve(master_length, master_width, items);
+        Solution solve = GA.solve(MaterialsConstant.MASTER_LENGTH, MaterialsConstant.MASTER_WIDTH, items);
 
         List<PlaceItem> placeItemList = solve.getPlaceItemList();
         if (placeItemList.size() == list.size()) {
@@ -257,12 +255,11 @@ public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder
         WorkOrder workOrder = new WorkOrder();
         workOrder.setId(IdWorker.getId());
         workOrder.setCode(CodeEnum.WORK_ORDER_CODE.getCode());
-        workOrder.setProductionBatchNumber(1);
         workOrder.setType(2);
         workOrder.setMasterBomSpecId(bomSpecId);
         workOrder.setPrintingPaperBomSpecId(printingPaperBomSpecId);
         workOrder.setSchedulingNum(new BigDecimal(placeItemList.size()));
-        workOrder.setUseRatio(BigDecimal.valueOf(solve.getRate() * 100));
+        workOrder.setUseRatio(BigDecimal.valueOf(solve.getUseRatio() * 100));
         workOrder.setMaxLength(BigDecimal.valueOf(solve.getMaxLength()));
         workOrder.setSyncProduction(StatusConstant.NO);
         workOrder.setIntegrity(StatusConstant.YES);
@@ -273,12 +270,15 @@ public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder
             orderSku.setSchedulingNum(orderSku.getSchedulingNum().add(BigDecimal.ONE));
 
             WorkOrderDetail workOrderDetail = new WorkOrderDetail();
-            workOrderDetail.setProductionBatchNumber(1);
             workOrderDetail.setWorkOrderId(workOrder.getId());
             workOrderDetail.setOrderInfoId(orderSku.getOrderId());
             workOrderDetail.setOrderSkuId(item.getId());
             workOrderDetail.setX(BigDecimal.valueOf(item.getX()));
             workOrderDetail.setY(BigDecimal.valueOf(item.getY()));
+            workOrderDetail.setBleedingLength(BigDecimal.valueOf(item.getLength()));
+            workOrderDetail.setBleedingWidth(BigDecimal.valueOf(item.getLength()));
+            workOrderDetail.setLength(BigDecimal.valueOf(item.getLength() - MaterialsConstant.RESERVE));
+            workOrderDetail.setWidth(BigDecimal.valueOf(item.getWidth() - MaterialsConstant.RESERVE));
             workOrderDetail.setRotate(item.isRotate() ? StatusConstant.YES : StatusConstant.NO);
             return workOrderDetail;
         }).collect(Collectors.toList());
@@ -316,13 +316,14 @@ public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder
         WorkOrder workOrder = new WorkOrder();
         workOrder.setId(IdWorker.getId());
         workOrder.setCode(CodeEnum.WORK_ORDER_CODE.getCode());
-        workOrder.setProductionBatchNumber(1);
         workOrder.setType(1);
-        workOrder.setFixationMaxNum(new BigDecimal(schedulingNum));
         workOrder.setFixationSpec(workOrderFixationSpecEnum.getLength() + "*" + workOrderFixationSpecEnum.getWidth());
         workOrder.setMasterBomSpecId(bomSpecId);
         workOrder.setPrintingPaperBomSpecId(printingPaperBomSpecId);
-        workOrder.setSchedulingNum(new BigDecimal(schedulingNum));
+
+        // todo 利用率 最大长度 排单数量赋值
+        //workOrder.setSchedulingNum(new BigDecimal(schedulingNum));
+
         workOrder.setSyncProduction(StatusConstant.NO);
         workOrder.setIntegrity(StatusConstant.YES);
 
@@ -375,14 +376,14 @@ public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder
 
     private void addWorkOrderDetail(WorkOrder workOrder, List<WorkOrderDetail> workOrderDetailList, OrderSku orderSku) {
         WorkOrderDetail workOrderDetail = new WorkOrderDetail();
-        workOrderDetail.setProductionBatchNumber(1);
         workOrderDetail.setWorkOrderId(workOrder.getId());
         workOrderDetail.setOrderInfoId(orderSku.getOrderId());
         workOrderDetail.setOrderSkuId(orderSku.getId());
 
-        // todo 赋值 x,y轴
+        // todo 赋值 x,y轴 长 宽 出血长 出现宽
 
         workOrderDetailList.add(workOrderDetail);
     }
 
+
 }

+ 25 - 0
sd-business/src/main/java/com/sd/business/service/work/impl/fixation/FixationFactory.java

@@ -0,0 +1,25 @@
+package com.sd.business.service.work.impl.fixation;
+
+import com.ruoyi.common.exception.ServiceException;
+import com.sd.business.entity.work.enums.WorkOrderFixationSpecEnum;
+import com.sd.business.service.work.impl.fixation.strategy.FixationStrategy;
+import com.sd.business.service.work.impl.fixation.strategy.Fixation_30_40;
+
+public class FixationFactory {
+
+    private FixationFactory() {
+    }
+
+    public FixationStrategy get(WorkOrderFixationSpecEnum workOrderFixationSpecEnum) {
+        switch (workOrderFixationSpecEnum) {
+
+            case SPEC_30_40:
+                return new Fixation_30_40();
+
+            default:
+                throw new ServiceException("未知排版策略");
+
+        }
+    }
+
+}

+ 77 - 0
sd-business/src/main/java/com/sd/business/service/work/impl/fixation/Test.java

@@ -0,0 +1,77 @@
+package com.sd.business.service.work.impl.fixation;
+
+import com.sd.business.entity.work.constant.MaterialsConstant;
+import com.sd.business.service.work.impl.fixation.strategy.FixationStrategy;
+import com.sd.business.service.work.impl.fixation.strategy.Fixation_30_40;
+import javafx.scene.Scene;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Button;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+
+import java.util.Random;
+
+public class Test extends javafx.application.Application {
+
+    private static final FixationStrategy fixationStrategy = new Fixation_30_40();
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    @Override
+    public void start(Stage primaryStage) throws Exception {
+        AnchorPane pane = new AnchorPane();
+        Canvas canvas = new Canvas(MaterialsConstant.MASTER_WIDTH, MaterialsConstant.MASTER_LENGTH);
+        pane.getChildren().add(canvas);
+        canvas.relocate(100, 100);
+        // 绘制最外层的矩形
+        draw(canvas, 0, 0, MaterialsConstant.MASTER_WIDTH, MaterialsConstant.MASTER_LENGTH, true);
+        // 添加按钮
+        Button nextButton = new Button("Next");
+        nextButton.setPrefSize(80, 50);
+
+        nextButton.setOnAction(actionEvent -> {
+            try {
+
+                draw(canvas,
+                        fixationStrategy.getX().doubleValue(),
+                        fixationStrategy.getY().doubleValue(),
+                        fixationStrategy.getBleedingWidth().doubleValue(),
+                        fixationStrategy.getBleedingLength().doubleValue(),
+                        false);
+
+                fixationStrategy.next();
+
+            } catch (Exception e) {
+                Alert alert = new Alert(Alert.AlertType.WARNING);
+                alert.setContentText("已经没有可以放置的矩形了!");
+                alert.showAndWait();
+            }
+        });
+        //
+        pane.getChildren().add(nextButton);
+        primaryStage.setTitle("二维矩形装箱可视化");
+        primaryStage.setScene(new Scene(pane, MaterialsConstant.MASTER_WIDTH + 200, MaterialsConstant.MASTER_LENGTH + 200, Color.AQUA));
+        primaryStage.show();
+    }
+
+    private void draw(Canvas canvas, double x, double y, double l, double w, boolean isBound) {
+        GraphicsContext gc = canvas.getGraphicsContext2D();
+        // 边框
+        gc.setStroke(Color.BLACK);
+        gc.setLineWidth(2);
+        gc.strokeRect(x, y, l, w);
+        // 填充
+        if (!isBound) {
+            gc.setFill(new Color(new Random().nextDouble(), new Random().nextDouble(), new Random().nextDouble(), new Random().nextDouble()));
+        } else {
+            gc.setFill(new Color(1, 1, 1, 1));
+        }
+        gc.fillRect(x, y, l, w);
+    }
+
+}

+ 48 - 0
sd-business/src/main/java/com/sd/business/service/work/impl/fixation/TypeSettingBo.java

@@ -0,0 +1,48 @@
+package com.sd.business.service.work.impl.fixation;
+
+import java.math.BigDecimal;
+
+public class TypeSettingBo {
+
+    /**
+     * 已使用面积
+     */
+    protected BigDecimal usedArea;
+
+    /**
+     * x轴坐标
+     */
+    protected BigDecimal x;
+
+    /**
+     * y轴坐标
+     */
+    protected BigDecimal y;
+
+    /**
+     * 排单数量
+     */
+    protected BigDecimal schedulingNum;
+
+    /**
+     * 长(考虑旋转后的)
+     */
+    protected BigDecimal length;
+
+    /**
+     * 宽(考虑旋转后的)
+     */
+    protected BigDecimal width;
+
+    /**
+     * 最大长度
+     */
+    protected BigDecimal maxLength;
+
+    /**
+     * 是否旋转
+     */
+    protected Boolean hasRotate;
+
+
+}

+ 93 - 0
sd-business/src/main/java/com/sd/business/service/work/impl/fixation/strategy/FixationStrategy.java

@@ -0,0 +1,93 @@
+package com.sd.business.service.work.impl.fixation.strategy;
+
+import com.sd.business.entity.work.constant.MaterialsConstant;
+import lombok.Getter;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+@Getter
+public abstract class FixationStrategy {
+
+    /**
+     * 卷材面积
+     */
+    protected final BigDecimal masterArea;
+    /**
+     * 已使用面积
+     */
+    protected BigDecimal usedArea;
+    /**
+     * x轴坐标
+     */
+    protected BigDecimal x;
+    /**
+     * y轴坐标
+     */
+    protected BigDecimal y;
+    /**
+     * 排单数量
+     */
+    protected BigDecimal schedulingNum;
+    /**
+     * 长(考虑旋转后的)
+     */
+    protected BigDecimal length;
+    /**
+     * 宽(考虑旋转后的)
+     */
+    protected BigDecimal width;
+    /**
+     * 最大长度
+     */
+    protected BigDecimal maxLength;
+    /**
+     * 是否旋转
+     */
+    protected Boolean hasRotate;
+    /**
+     * 是否可以继续排版
+     */
+    protected Boolean hasNext;
+
+    protected FixationStrategy(BigDecimal length, BigDecimal width, BigDecimal maxLength, boolean HasRotate) {
+        this.length = length;
+        this.width = width;
+        this.maxLength = maxLength;
+        this.hasRotate = HasRotate;
+
+        this.masterArea = new BigDecimal(MaterialsConstant.MASTER_LENGTH * MaterialsConstant.MASTER_WIDTH);
+        this.usedArea = BigDecimal.ZERO;
+        this.x = BigDecimal.ZERO;
+        this.y = BigDecimal.ZERO;
+        this.schedulingNum = BigDecimal.ONE;
+        this.hasNext = true;
+    }
+
+    /**
+     * 下一个排版信息
+     */
+    public abstract void next();
+
+    /**
+     * 获取使用率
+     */
+    public final BigDecimal getUseRatio() {
+        return usedArea.multiply(new BigDecimal(100)).divide(masterArea, 2, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 获取出血长度
+     */
+    public final BigDecimal getBleedingLength() {
+        return this.length.add(BigDecimal.valueOf((MaterialsConstant.RESERVE)));
+    }
+
+    /**
+     * 获取出血宽度
+     */
+    public final BigDecimal getBleedingWidth() {
+        return this.width.add(BigDecimal.valueOf((MaterialsConstant.RESERVE)));
+    }
+
+}

+ 148 - 0
sd-business/src/main/java/com/sd/business/service/work/impl/fixation/strategy/Fixation_30_40.java

@@ -0,0 +1,148 @@
+package com.sd.business.service.work.impl.fixation.strategy;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.exception.ServiceException;
+import com.sd.business.entity.work.constant.MaterialsConstant;
+
+import java.math.BigDecimal;
+
+public class Fixation_30_40 extends FixationStrategy {
+
+    private final BigDecimal masterLength = new BigDecimal(MaterialsConstant.MASTER_LENGTH);
+
+    /**
+     * 不考虑旋转长宽
+     */
+    private final BigDecimal l = this.length;
+    private final BigDecimal w = this.width;
+
+    /**
+     * 不考虑旋转出血长宽
+     */
+    private final BigDecimal bl = getBleedingLength();
+    private final BigDecimal bw = getBleedingWidth();
+
+    /**
+     * 第一列到第四列左边x轴坐标
+     */
+    private final BigDecimal x1 = BigDecimal.ZERO;
+    private final BigDecimal x2 = getBleedingWidth();
+    private final BigDecimal x3 = this.x2.add(getBleedingWidth());
+    private final BigDecimal x4 = this.x3.add(getBleedingLength());
+
+    /**
+     * 第一列到第四列下边y坐标
+     */
+    private BigDecimal y1 = this.bl;
+    private BigDecimal y2 = BigDecimal.ZERO;
+    private BigDecimal y3 = BigDecimal.ZERO;
+    private BigDecimal y4 = BigDecimal.ZERO;
+
+    public Fixation_30_40() {
+        super(
+                new BigDecimal("30"),
+                new BigDecimal("40"),
+                new BigDecimal("30").add(BigDecimal.valueOf((MaterialsConstant.RESERVE))),
+                false
+        );
+    }
+
+    public static void main(String[] args) {
+        Fixation_30_40 fixation3040 = new Fixation_30_40();
+
+
+        while (true) {
+            System.out.println(JSONObject.toJSONString(fixation3040));
+            fixation3040.next();
+
+
+        }
+    }
+
+    @Override
+    public void next() {
+
+        if (!this.hasNext) {
+            throw new ServiceException("卷材排满,无法继续排版了");
+        }
+
+        // 排版个数为偶数时,排第二列或者第四列
+        if (schedulingNum.add(BigDecimal.ONE).intValue() % 2 == 0) {
+            // 如果第一列和第二列轴相等,排第四列
+            if (this.y1.compareTo(this.y2) == 0) {
+                this.x = this.x4;
+                this.y = this.y4;
+                this.length = this.w;
+                this.width = this.l;
+                this.hasRotate = true;
+
+                this.y4 = this.y4.add(this.bw);
+            }
+            // 否则排第二列
+            else {
+                this.x = this.x2;
+                this.y = this.y2;
+                this.length = this.l;
+                this.width = this.w;
+                this.hasRotate = false;
+
+                this.y2 = this.y2.add(this.bl);
+            }
+
+            // 查看是否还能排版
+            if (this.y1.add(this.bl).compareTo(masterLength) > 0
+                    && this.y3.add(this.bw).compareTo(masterLength) > 0
+                    && this.y3.add(this.bl).compareTo(masterLength) > 0) {
+                this.hasNext = false;
+            }
+
+        }
+
+        // 排版个数为奇数时,排第一列或者第三列
+        else {
+            // 对比排第一列最大高度小还是第三列最大高度小
+            BigDecimal tempY1 = this.y1.add(this.bl);
+            BigDecimal tempY3 = this.y3.add(this.bw);
+
+            // 如果第一列最大高度大,排第三列
+            if (tempY1.compareTo(tempY3) > 0) {
+
+                this.x = this.x3;
+                this.y = this.y3;
+
+                // 无法继续旋转排版
+                if (tempY3.compareTo(masterLength) > 0) {
+                    this.length = this.l;
+                    this.width = this.w;
+                    this.hasRotate = false;
+                    this.y3 = this.y3.add(this.bl);
+                    this.hasNext = false;
+                }
+                // 旋转排版
+                else {
+                    this.length = this.w;
+                    this.width = this.l;
+                    this.hasRotate = true;
+                    this.y3 = tempY3;
+                }
+
+            }
+            // 否则排第一列
+            else {
+                this.x = this.x1;
+                this.y = this.y1;
+                this.length = this.l;
+                this.width = this.w;
+                this.hasRotate = false;
+
+                this.y1 = tempY1;
+            }
+
+        }
+
+        this.schedulingNum = this.schedulingNum.add(BigDecimal.ONE);
+        this.maxLength = this.y1.compareTo(this.y3) > 0 ? this.y1 : this.y3;
+        this.usedArea = this.usedArea.add(getBleedingWidth().multiply(getBleedingLength()));
+    }
+
+}

+ 2 - 2
sd-business/src/main/java/com/sd/business/util/packing/GA.java

@@ -229,7 +229,7 @@ public class GA {
                 bestGenome = copyGenome(genome);
             }
         }
-        System.out.println("初始解为:" + bestGenome.getSolution().getRate());
+        System.out.println("初始解为:" + bestGenome.getSolution().getUseRatio());
     }
 
     /**
@@ -246,7 +246,7 @@ public class GA {
         if (compareDouble(tempBest.getFitness(), bestGenome.getFitness()) == 1) {
             bestGenome = copyGenome(tempBest);
             // 最佳迭代次数
-            System.out.println("当前代数: " + t + " : " + bestGenome.getSolution().getRate());
+            System.out.println("当前代数: " + t + " : " + bestGenome.getSolution().getUseRatio());
         }
         for (int i = 0; i < cloneNumOfBestIndividual; i++) {
             newPopulation.add(copyGenome(tempBest));

+ 1 - 1
sd-business/src/main/java/com/sd/business/util/packing/entity/Solution.java

@@ -31,6 +31,6 @@ public class Solution {
     /**
      * 利用率
      */
-    private double rate;
+    private double useRatio;
 
 }

+ 1 - 1
sd-business/src/main/java/com/sd/business/util/packing/model/Genome.java

@@ -69,7 +69,7 @@ public class Genome {
             items[i] = this.items[genomeArray[i]];
         }
         solution = new SkyLinePacking(isRotateEnable, length, width, items).packing();
-        fitness = solution.getRate();
+        fitness = solution.getUseRatio();
     }
 
 }