贴皮新增面积计算、贴皮排单新增面积统计

This commit is contained in:
gaoqr
2026-07-29 14:09:07 +08:00
parent 45ef5b9c6a
commit b0a46d6f37
9 changed files with 66 additions and 40 deletions
@@ -211,6 +211,7 @@ public class ErrorCodeConstants {
public static final ErrorCode VENEER_PLAN_PLATE_SOURCE_MISMATCH = new ErrorCode(1_003_009_049, "veneer.plan.plate.source.mismatch");
public static final ErrorCode VENEER_PLAN_PLATE_STATUS_CHANGED = new ErrorCode(1_003_009_050, "veneer.plan.plate.status.changed");
public static final ErrorCode VENEER_DECOMPOSE_RECORD_INSERT_FAILED = new ErrorCode(1_003_009_051, "veneer.decompose.record.insert.failed");
public static final ErrorCode VENEER_DECOMPOSE_PLATE_SIZE_INVALID = new ErrorCode(1_003_009_052, "veneer.decompose.plate.size.invalid");
//=========== 部件管理 1-003-010-000 ============
public static final ErrorCode ORDER_COMPONENT_NOT_EXIST = new ErrorCode(1_003_010_000, "order.component.not.exist");
@@ -59,12 +59,12 @@ public class OrderPlateVeneerDO extends BaseDO {
private String plateName;
/**
* 原板件长度,单位:mm。
* 贴皮最终长度,已包含两侧外扩余量,单位:mm。
*/
private BigDecimal plateLength;
/**
* 原板件宽度,单位:mm。
* 贴皮最终宽度,已包含两侧外扩余量,单位:mm。
*/
private BigDecimal plateWidth;
@@ -98,6 +98,11 @@ public class OrderPlateVeneerDO extends BaseDO {
*/
private BigDecimal outerMargin;
/**
* 贴皮面积,单位:平方米。
*/
private BigDecimal veneerArea;
/**
* 贴皮排单ID,0表示未排单。
*/
@@ -38,6 +38,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -51,6 +52,7 @@ import static com.cf.imes.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.GOODS_PLATE_UPDATE_CONCURRENCY_ERROR;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_PLATE_UPDATE_CONCURRENCY_ERROR;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_PLATE_STATUS_CHANGED;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_PLATE_SIZE_INVALID;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_RECORD_INSERT_FAILED;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_SCOPE_REQUIRED;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_SIDE_REQUIRED;
@@ -72,6 +74,22 @@ public class VeneerDecomposeServiceImpl implements VeneerDecomposeService {
*/
private static final int DECOMPOSE_STAT_BATCH_SIZE = 100;
/**
* 外扩余量需要向板件长、宽的两侧分别增加。
*/
private static final BigDecimal OUTER_MARGIN_DOUBLE = new BigDecimal("2");
/**
* 平方毫米转换为平方米的除数。
*/
private static final BigDecimal SQUARE_MILLIMETER_PER_SQUARE_METER =
new BigDecimal("1000000");
/**
* 单张贴皮面积保留的小数位数。
*/
private static final int VENEER_AREA_SCALE = 3;
@Resource
private VeneerDecomposeMapper veneerDecomposeMapper;
@@ -423,6 +441,25 @@ public class VeneerDecomposeServiceImpl implements VeneerDecomposeService {
*/
private OrderPlateVeneerDO buildPlateVeneer(PlateDO plate, VeneerDO sourceVeneer,
VeneerSideEnum veneerSide, BigDecimal outerMargin) {
BigDecimal actualOuterMargin = ObjectUtil.defaultIfNull(outerMargin, BigDecimal.TEN);
BigDecimal sourceLength = plate.getHeight();
BigDecimal sourceWidth = plate.getWidth();
if (sourceLength == null || sourceWidth == null
|| sourceLength.signum() <= 0 || sourceWidth.signum() <= 0
|| actualOuterMargin.signum() < 0) {
throw new ServiceException(VENEER_DECOMPOSE_PLATE_SIZE_INVALID, plate.getPlateNo());
}
// 外扩余量作用于板件四周,长、宽分别增加两倍余量后作为贴皮最终尺寸。
BigDecimal veneerLength = sourceLength.add(
actualOuterMargin.multiply(OUTER_MARGIN_DOUBLE));
BigDecimal veneerWidth = sourceWidth.add(
actualOuterMargin.multiply(OUTER_MARGIN_DOUBLE));
BigDecimal veneerArea = veneerLength.multiply(veneerWidth).divide(
SQUARE_MILLIMETER_PER_SQUARE_METER,
VENEER_AREA_SCALE,
RoundingMode.HALF_UP);
int plateSurface = resolvePlateSurface(plate.getHoleArrange(), veneerSide);
return OrderPlateVeneerDO.builder()
.organId(plate.getOrganId())
@@ -431,14 +468,15 @@ public class VeneerDecomposeServiceImpl implements VeneerDecomposeService {
.orderPlateId(plate.getId())
.plateNo(plate.getPlateNo())
.plateName(plate.getName())
.plateLength(plate.getHeight())
.plateWidth(plate.getWidth())
.plateLength(veneerLength)
.plateWidth(veneerWidth)
.plateThickness(plate.getThickness())
.holeArrange(plate.getHoleArrange())
.veneerSide(veneerSide.getSide())
.plateSurface(plateSurface)
.veneerNo(plate.getPlateNo() + veneerSide.getSide())
.outerMargin(outerMargin)
.outerMargin(actualOuterMargin)
.veneerArea(veneerArea)
.planId(0L)
.sourceVeneerId(sourceVeneer.getId())
.sourceVeneerNo(sourceVeneer.getVeneerNo())
@@ -124,16 +124,6 @@ public class VeneerPlanServiceImpl implements VeneerPlanService {
VeneerPlanStatusEnum.NOCUTTING.getStatus(),
VeneerPlanStatusEnum.OPTIMIZED.getStatus());
/**
* 平方毫米转换为平方米的除数。
*/
private static final BigDecimal SQUARE_MILLIMETER_PER_SQUARE_METER = new BigDecimal("1000000");
/**
* 外扩余量需要向长、宽的两侧分别增加。
*/
private static final BigDecimal OUTER_MARGIN_DOUBLE = new BigDecimal("2");
@Resource
private VeneerPlanMapper veneerPlanMapper;
@@ -877,27 +867,21 @@ public class VeneerPlanServiceImpl implements VeneerPlanService {
}
/**
* 根据原板尺寸和外扩余量计算当前贴皮排单的面积。
* 汇总当前贴皮排单的贴皮面积。
* A/B面作为两条贴皮记录分别累计,结果单位为平方米。
*
* @param veneers 同一贴皮商品编号下的贴皮记录
* @return 保留位小数的贴皮总面积
* @return 保留位小数的贴皮总面积
*/
private BigDecimal calculateVeneerArea(List<OrderPlateVeneerDO> veneers) {
BigDecimal totalSquareMillimeter = BigDecimal.ZERO;
BigDecimal totalArea = BigDecimal.ZERO;
for (OrderPlateVeneerDO veneer : veneers) {
BigDecimal length = veneer.getPlateLength();
BigDecimal width = veneer.getPlateWidth();
BigDecimal outerMargin = Objects.requireNonNullElse(veneer.getOuterMargin(), BigDecimal.ZERO);
if (length == null || width == null || length.signum() <= 0 || width.signum() <= 0
|| outerMargin.signum() < 0) {
BigDecimal veneerArea = veneer.getVeneerArea();
if (veneerArea == null || veneerArea.signum() <= 0) {
throw new ServiceException(VENEER_PLAN_AREA_DATA_INVALID, veneer.getId());
}
BigDecimal finalLength = length.add(outerMargin.multiply(OUTER_MARGIN_DOUBLE));
BigDecimal finalWidth = width.add(outerMargin.multiply(OUTER_MARGIN_DOUBLE));
totalSquareMillimeter = totalSquareMillimeter.add(finalLength.multiply(finalWidth));
totalArea = totalArea.add(veneerArea);
}
return totalSquareMillimeter.divide(
SQUARE_MILLIMETER_PER_SQUARE_METER, 4, RoundingMode.HALF_UP);
return totalArea.setScale(3, RoundingMode.HALF_UP);
}
}
@@ -384,8 +384,8 @@
og.brand,
og.material,
op.height,
op.height AS length,
op.width,
opv.plate_length AS length,
opv.plate_width AS width,
op.thickness,
op.split_width AS splitWidth,
op.split_height AS splitHeight,
@@ -116,10 +116,7 @@
<select id="selectPlanStatistics"
resultType="com.cf.imes.module.executor.dal.dataobject.veneer.VeneerPlanStatisticsDO">
SELECT COUNT(*) AS veneerNum,
COALESCE(ROUND(SUM(
(opv.plate_length + opv.outer_margin * 2)
* (opv.plate_width + opv.outer_margin * 2) / 1000000
), 4), 0) AS veneerArea
COALESCE(ROUND(SUM(opv.veneer_area), 3), 0) AS veneerArea
FROM order_plate_veneer opv
WHERE opv.deleted = false
AND opv.plan_id = #{planId}
@@ -168,9 +165,7 @@
opv.order_goods_id AS orderGoodsId,
opv.order_plate_id AS orderPlateId,
opv.plate_no AS plateNo,
opv.plate_length AS plateLength,
opv.plate_width AS plateWidth,
opv.outer_margin AS outerMargin,
opv.veneer_area AS veneerArea,
opv.source_veneer_id AS sourceVeneerId,
opv.source_veneer_no AS sourceVeneerNo
FROM order_plate_veneer opv
@@ -74,6 +74,7 @@ veneer.decompose.scope.required=訂單ID列表和板材商品編碼不能同時
veneer.decompose.side.required=A面和B面貼皮至少選擇一個
veneer.decompose.plate.status.changed=板件分解狀態已變更,請重新整理後再試
veneer.decompose.record.insert.failed=貼皮分解記錄生成失敗,請重新整理後再試
veneer.decompose.plate.size.invalid=板件{0}的長寬或外擴餘量異常,無法生成貼皮
veneer.decompose.plate.no.required=板件編號不能為空
veneer.decompose.outer.margin.min=外擴餘量不能小於0
veneer.reselect.record.required=請選擇需要重選貼皮的資料
@@ -84,7 +85,7 @@ veneer.remove.record.status.changed=所選貼皮資料已刪除、已排單或
veneer.unplanned.scope.invalid=訂單ID列表和板材商品編碼列表必須且只能傳入一項
veneer.plan.record.required=請選擇需要排單的貼皮資料
veneer.plan.record.status.changed=所選貼皮資料已排單、已刪除或狀態發生變化,請重新整理後再試
veneer.plan.area.data.invalid=貼皮記錄{0}的板件尺寸或外擴餘量異常,無法計算貼皮面積
veneer.plan.area.data.invalid=貼皮記錄{0}的面積資料異常,無法建立貼皮排單
veneer.plan.create.failed=貼皮排單建立失敗,請稍後再試
veneer.plan.group.required=請提交需要建立的貼皮排單分組
veneer.plan.group.source.no.required=貼皮排單分組的貼皮商品編號不能為空
@@ -74,6 +74,7 @@ veneer.decompose.scope.required=Order ID list and goods code cannot both be empt
veneer.decompose.side.required=At least one veneer must be selected for side A or B
veneer.decompose.plate.status.changed=Plate decomposition status has changed. Please refresh and retry
veneer.decompose.record.insert.failed=Failed to create veneer decomposition records. Please refresh and retry
veneer.decompose.plate.size.invalid=Plate {0} has invalid dimensions or outer margin and cannot generate veneer
veneer.decompose.plate.no.required=Plate numbers cannot be empty
veneer.decompose.outer.margin.min=Outer margin cannot be less than 0
veneer.reselect.record.required=Please select records for veneer reselection
@@ -84,7 +85,7 @@ veneer.remove.record.status.changed=The selected veneer data has been removed, s
veneer.unplanned.scope.invalid=Exactly one of the order ID list and goods code list must be provided
veneer.plan.record.required=Please select veneer records to schedule
veneer.plan.record.status.changed=The selected veneer data has been scheduled, removed, or changed. Please refresh and retry
veneer.plan.area.data.invalid=Veneer record {0} has invalid plate dimensions or outer margin
veneer.plan.area.data.invalid=Veneer record {0} has invalid area data and cannot create a veneer plan
veneer.plan.create.failed=Failed to create the veneer plan. Please retry later
veneer.plan.group.required=Please submit at least one veneer plan group
veneer.plan.group.source.no.required=The veneer product number of a plan group is required
@@ -74,6 +74,7 @@ veneer.decompose.scope.required=订单ID列表和板材商品编码不能同时
veneer.decompose.side.required=A面和B面贴皮至少选择一个
veneer.decompose.plate.status.changed=板件分解状态已变更,请刷新后重试
veneer.decompose.record.insert.failed=贴皮分解记录生成失败,请刷新后重试
veneer.decompose.plate.size.invalid=板件{0}的长宽或外扩余量异常,无法生成贴皮
veneer.decompose.plate.no.required=板件编号不能为空
veneer.decompose.outer.margin.min=外扩余量不能小于0
veneer.reselect.record.required=请选择需要重选贴皮的数据
@@ -84,7 +85,7 @@ veneer.remove.record.status.changed=所选贴皮数据已删除、已排单或
veneer.unplanned.scope.invalid=订单ID列表和板材商品编码列表必须且只能传入一项
veneer.plan.record.required=请选择需要排单的贴皮数据
veneer.plan.record.status.changed=所选贴皮数据已排单、已删除或状态发生变化,请刷新后重试
veneer.plan.area.data.invalid=贴皮记录{0}的板件尺寸或外扩余量异常,无法计算贴皮面积
veneer.plan.area.data.invalid=贴皮记录{0}的面积数据异常,无法创建贴皮排单
veneer.plan.create.failed=贴皮排单创建失败,请稍后重试
veneer.plan.group.required=请提交需要创建的贴皮排单分组
veneer.plan.group.source.no.required=贴皮排单分组的贴皮商品编号不能为空