新增 初步获取优化算法参数接口

This commit is contained in:
yangsb
2024-03-20 17:31:27 +08:00
parent 7fc795747a
commit 872b8ac3c3
9 changed files with 280 additions and 6 deletions
@@ -62,7 +62,7 @@ public class OptimizePlanController {
}
@GetMapping("/getOptimizeParam")
@Operation(summary = "获取优化算法参数")
@Operation(summary = "获取优化算法参数 (未完成)")
@PreAuthorize("@ss.hasPermission('executor:optimize-plate:create')")
public CommonResult<OptimizeParamResVO> getOptimizeParam(@RequestParam @Valid @NotNull(message = "排单id不能空") Long planId) {
return CommonResult.success(optimizePlanService.getOptimizeParam(planId));
@@ -2,6 +2,7 @@ package com.cf.imes.module.executor.controller.admin.plan.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
@@ -12,6 +13,7 @@ import java.util.List;
*/
@Data
@Schema(description = "优化算法入参")
@Builder
public class OptimizeParamResVO {
@Schema(description = "小板列表")
@@ -19,7 +21,7 @@ public class OptimizeParamResVO {
@Schema(description = "原料板规格列表")
private List<RawSize> rawSizes;
@Schema(description = "余料板数量")
private Integer remainPlateCount;
private List<Integer> remainPlateCount;
@Schema(description = "优化次数")
private Integer optimizeCount;
@Schema(description = "双面加工的小板是否优先排入")
@@ -35,6 +37,7 @@ public class OptimizeParamResVO {
@Data
@Schema(description = "原料板规格")
@Builder
public static class RawSize {
@Schema(description = "")
private BigDecimal length;
@@ -0,0 +1,76 @@
package com.cf.imes.module.executor.dal.dataobject.orderBody;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
/**
* 生产单柜体 DO
*
* @author 晨丰科技
*/
@TableName("order_body")
@KeySequence("order_body_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderBodyDO extends BaseDO {
/**
* 模块 ID
*/
@TableId
private Long id;
/**
* 生产单号
*/
private Long orderId;
/**
* 房间ID,后端生成
*/
private Long roomId;
/**
* 房间名称
*/
private String roomName;
/**
* 模块名称
*/
private String name;
/**
* 模块宽度
*/
private Double width;
/**
* 模块高度
*/
private Double height;
/**
* 模块深度
*/
private Double depth;
/**
* 模块复制数量
*/
private Short multiNum;
/**
* 板材数量
*/
private Short plateNum;
/**
* 异型数量
*/
private Short unregularNum;
/**
* 文件名
*/
private String filename;
/**
* 备注
*/
private String remark;
}
@@ -0,0 +1,22 @@
package com.cf.imes.module.executor.dal.dataobject.remainplaten;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.List;
/**
* @author Beal
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OutlineDTO {
private List<PointDTO> list;
private BigDecimal length;
private BigDecimal width;
}
@@ -0,0 +1,15 @@
package com.cf.imes.module.executor.dal.dataobject.remainplaten;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author Beal
*/
@Data
public class PointDTO {
private int x;
private int y;
private int curve;
}
@@ -0,0 +1,17 @@
package com.cf.imes.module.executor.dal.mysql.orderBody;
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
import com.cf.imes.module.executor.dal.dataobject.orderBody.OrderBodyDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 生产单柜体 Mapper
*
* @author 晨丰科技
*/
@Mapper
public interface OrderBodyMapper extends BaseMapperX<OrderBodyDO> {
}
@@ -1,21 +1,37 @@
package com.cf.imes.module.executor.service.optimizeplan;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.cf.imes.module.executor.controller.admin.plan.vo.*;
import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO;
import com.cf.imes.module.executor.dal.dataobject.orderItem.OrderItemDO;
import com.cf.imes.module.executor.dal.dataobject.plan.PlanDO;
import com.cf.imes.module.executor.dal.dataobject.planitem.PlanItemDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO;
import com.cf.imes.module.executor.dal.dataobject.remainplaten.OutlineDTO;
import com.cf.imes.module.executor.dal.dataobject.remainplaten.PointDTO;
import com.cf.imes.module.executor.dal.dataobject.remainplaten.RemainPlateDO;
import com.cf.imes.module.executor.dal.mysql.goods.GoodsMapper;
import com.cf.imes.module.executor.dal.mysql.plan.PlanMapper;
import com.cf.imes.module.executor.dal.mysql.plate.PlateMapper;
import com.cf.imes.module.executor.dal.mysql.remainplaten.RemainPlateMapper;
import com.cf.imes.module.executor.util.RectangleChecker;
import com.cf.imes.module.infra.api.file.FileApi;
import com.cf.imes.module.infra.api.file.dto.FileCreateReqDTO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.UNKNOWN;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -39,6 +55,9 @@ public class OptimizePlanServiceImpl implements OptimizePlanService {
@Resource
private PlateMapper plateMapper;
@Resource
private GoodsMapper goodsMapper;
@Override
public List<PlateOptimize> getPlateListByPlanId(Long planId) {
return planMapper.selectPlateListByPlanId(planId);
@@ -121,13 +140,64 @@ public class OptimizePlanServiceImpl implements OptimizePlanService {
//小板列表
List<PlateParam> plates = plateMapper.selectPlateList(planId);
//余料规格列表
List<RemainPlateDO> remainPlateDOS = remainPlateMapper.selectList(new LambdaQueryWrapperX<RemainPlateDO>().eq(RemainPlateDO::getPlanId, planId));
//余料板规格
List<OptimizeParamResVO.RawSize> rawSizes = new ArrayList<>();
List<Integer> remainPlateCount = new ArrayList<>();
if(CollectionUtil.isNotEmpty(remainPlateDOS)) {
Map<String, List<OutlineDTO>> map = remainPlateDOS.stream()
.map(e -> OutlineDTO.builder()
.list(JsonUtils.parseArray(e.getOutline(), PointDTO.class))
.length(e.getLength())
.width(e.getWidth())
.build()
)
.filter(e -> e.getList().size() == 4 && RectangleChecker.checkRectangle(e.getList()))
.collect(Collectors.groupingBy(e -> e.getLength() + "," + e.getWidth()));
map.entrySet().forEach(e-> {
String[] split = e.getKey().split(",");
BigDecimal length = new BigDecimal(split[0]);
BigDecimal width = new BigDecimal(split[1]);
List<OutlineDTO> outlines = e.getValue();
rawSizes.add(OptimizeParamResVO.RawSize.builder()
.length(length)
.width(width)
.x(new BigDecimal(outlines.get(0).getList().get(0).getX()))
.y(new BigDecimal(outlines.get(0).getList().get(0).getY()))
.build());
remainPlateCount.add(outlines.size());
});
}
//大板规格
/**
* select * from order_goods a
* left join order_plate b on a.goods_id = b.goods_id
* left join order_item c on b.id = c.plate_id
* left join order_plan_item d on c.id = d.item_id
* where d.plan_id = 1769638780093857792
*/
MPJLambdaWrapper<GoodsDO> wrapper = new MPJLambdaWrapperX<GoodsDO>()
.distinct()
.select(GoodsDO::getId ,GoodsDO::getWidth, GoodsDO::getHeight)
.leftJoin(PlateDO.class, PlateDO::getGoodsId, GoodsDO::getGoodsId)
.leftJoin(OrderItemDO.class, OrderItemDO::getPlanId, PlateDO::getPlateNo)
.leftJoin(PlanItemDO.class, PlanItemDO::getItemId, OrderItemDO::getId);
//余料板数量
GoodsDO goodsDO = goodsMapper.selectJoinOne(GoodsDO.class, wrapper);
rawSizes.add(OptimizeParamResVO.RawSize.builder()
.width(goodsDO.getWidth())
.length(goodsDO.getHeight())
.x(new BigDecimal("0"))
.y(new BigDecimal("0"))
.build());
return OptimizeParamResVO.builder()
.plates(plates)
.rawSizes(rawSizes)
.remainPlateCount(remainPlateCount)
.build();
return null;
}
}
@@ -15,12 +15,14 @@ import com.cf.imes.framework.mybatis.core.query.QueryWrapperX;
import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO;
import com.cf.imes.module.executor.dal.dataobject.module.ModuleDO;
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
import com.cf.imes.module.executor.dal.dataobject.orderBody.OrderBodyDO;
import com.cf.imes.module.executor.dal.dataobject.orderItem.OrderItemDO;
import com.cf.imes.module.executor.dal.dataobject.planitem.PlanItemDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO;
import com.cf.imes.module.executor.dal.mysql.goods.GoodsMapper;
import com.cf.imes.module.executor.dal.mysql.module.ModuleMapper;
import com.cf.imes.module.executor.dal.mysql.order.OrderMapper;
import com.cf.imes.module.executor.dal.mysql.orderBody.OrderBodyMapper;
import com.cf.imes.module.executor.dal.mysql.orderItem.OrderItemMapper;
import com.cf.imes.module.executor.dal.mysql.planitem.PlanItemMapper;
import com.cf.imes.module.executor.dal.mysql.plate.PlateMapper;
@@ -83,6 +85,8 @@ public class PlanServiceImpl implements PlanService {
@Resource
private ModuleMapper moduleMapper;
@Resource
private OrderBodyMapper orderBodyMapper;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -341,6 +345,13 @@ public class PlanServiceImpl implements PlanService {
List<PlateResList> list = plateMapper.selectPlateByPlanId(queryWrapperX);
Set<Long> bodyIds = list.stream().map(PlateResList::getBodyId).collect(Collectors.toSet());
Set<Long> roomIds = list.stream().map(PlateResList::getRoomId).collect(Collectors.toSet());
if(CollectionUtil.isNotEmpty(bodyIds)) {
List<OrderBodyDO> orderBodyDOS = orderBodyMapper.selectBatchIds(bodyIds);
for (PlateResList resList : list) {
resList.setBodyName(orderBodyDOS.stream().filter(e -> Objects.equals(e.getId(), resList.getBodyId())).map(OrderBodyDO::getName).findAny().orElse(null));
resList.setRoomName(orderBodyDOS.stream().filter(e -> Objects.equals(e.getId(), resList.getRoomId())).map(OrderBodyDO::getRoomName).findAny().orElse(null));
}
}
//todo 获取柜体名称,房间名称
/* List<ModuleDO> moduleDOS = moduleMapper.selectList(new LambdaQueryWrapperX<ModuleDO>().in(ModuleDO::getId, bodyIds).eq(ModuleDO::getType, 2)
.or().in(ModuleDO::getId, roomIds).eq(ModuleDO::getType, 1)
@@ -0,0 +1,60 @@
package com.cf.imes.module.executor.util;
import com.cf.imes.module.executor.dal.dataobject.remainplaten.PointDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
/**
* @author Beal
*/
public class RectangleChecker {
/**
* 获取两个点之间直线距离
* @param x1 点1的x
* @param y1 点1的y
* @param x2 点2的x
* @param y2 点2的y
* @return 距离
*/
public static double getDistance(int x1,int y1, int x2, int y2){
return Math.sqrt(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
/**
* 检查4个点的形状是否为长方形
* @param x1
* @param y1
* @param x2
* @param y2
* @param x3
* @param y3
* @param x4
* @param y4
* @return
*/
public static boolean checkRectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 ) {
return (x1 == x2 || y1==y2 ) && (x2 == x3 || y2==y3 ) && (x3 == x4 || y3==y4 ) && (x4 == x1 || y4==y1 );
}
public static boolean checkRectangle(List<PointDTO> list) {
if(list.size()!=4) {
return false;
}
PointDTO p1 = list.get(0);
PointDTO p2 = list.get(1);
PointDTO p3 = list.get(2);
PointDTO p4 = list.get(3);
return (p1.getX() == p2.getX() || p1.getY()==p1.getY() ) && (p2.getX() == p3.getX() || p2.getY()==p3.getY() )
&& (p3.getX() == p4.getX() || p3.getY()==p4.getY() ) && (p4.getX() == p1.getX() || p4.getY()==p1.getY() );
}
public static void main(String[] args) {
//System.out.println(checkRectangle(new Point(6, 5), new Point(10, 5), new Point(10, 15), new Point(5, 15)));
System.out.println(checkRectangle(5,5,10,5,11,15,5,15));
}
}