9 天以前 56b8b84689ccf5389ee02814bcb8bfe407f05a87
Merge remote-tracking branch 'origin/dev_New_pro' into dev_New_pro
已添加1个文件
已修改11个文件
360 ■■■■■ 文件已修改
src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickRecordDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickRecordVo.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionOrderPickRecordController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionOrderPickRecordMapper.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionOrderPick.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionOrderPickRecord.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionOrderPickRecordService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickRecordServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionOrderPickMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionOrderPickRecordMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickDto.java
@@ -33,6 +33,12 @@
    @Schema(description = "备注")
    private String remark;
    @Schema(description = "补料原因")
    private String feedingReason;
    @Schema(description = "本次补料数量")
    private BigDecimal feedingQuantity;
    @Schema(description = "领料明细列表")
    @JsonAlias({"dto", "productionOrderPickDto"})
    private List<ProductionOrderPickDto> pickList;
src/main/java/com/ruoyi/production/bean/dto/ProductionOrderPickRecordDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.ruoyi.production.bean.dto;
import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(name = "ProductionOrderPickRecordDto", description = "领料记录查询参数")
public class ProductionOrderPickRecordDto extends ProductionOrderPickRecord {
}
src/main/java/com/ruoyi/production/bean/vo/ProductionOrderPickRecordVo.java
@@ -1,9 +1,12 @@
package com.ruoyi.production.bean.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = true)
@@ -21,5 +24,11 @@
    @Schema(description = "单位")
    private String unit;
}
    @Schema(description = "补料人")
    private String supplementUserName;
    @Schema(description = "补料日期")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime supplementTime;
}
src/main/java/com/ruoyi/production/controller/ProductionOrderPickRecordController.java
@@ -1,7 +1,17 @@
package com.ruoyi.production.controller;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.bean.dto.ProductionOrderPickRecordDto;
import com.ruoyi.production.bean.vo.ProductionOrderPickRecordVo;
import com.ruoyi.production.service.ProductionOrderPickRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * <p>
@@ -13,6 +23,15 @@
 */
@RestController
@RequestMapping("/productionOrderPickRecord")
@Tag(name = "生产订单领料记录")
@RequiredArgsConstructor
public class ProductionOrderPickRecordController {
    private final ProductionOrderPickRecordService productionOrderPickRecordService;
    @GetMapping("/feeding")
    @Operation(summary = "查询补料记录")
    public R<List<ProductionOrderPickRecordVo>> listFeedingRecord(ProductionOrderPickRecordDto dto) {
        return R.ok(productionOrderPickRecordService.listFeedingRecord(dto));
    }
}
src/main/java/com/ruoyi/production/mapper/ProductionOrderPickRecordMapper.java
@@ -1,6 +1,8 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.production.bean.dto.ProductionOrderPickRecordDto;
import com.ruoyi.production.bean.vo.ProductionOrderPickRecordVo;
import com.ruoyi.production.bean.vo.ProductionOrderPickVo;
import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import org.apache.ibatis.annotations.Mapper;
@@ -20,5 +22,6 @@
public interface ProductionOrderPickRecordMapper extends BaseMapper<ProductionOrderPickRecord> {
    List<ProductionOrderPickVo> listPickedDetailByOrderId(@Param("productionOrderId") Long productionOrderId);
}
    List<ProductionOrderPickRecordVo> listFeedingRecord(ProductionOrderPickRecordDto dto);
}
src/main/java/com/ruoyi/production/pojo/ProductionOrderPick.java
@@ -66,6 +66,19 @@
    @Schema(description = "需求数量")
    private BigDecimal demandedQuantity;
    @Schema(description = "补料总量")
    private BigDecimal  feedingQty;
    @Schema(description = "退料数量")
    private BigDecimal  returnQty;
    @Schema(description = "实际数量")
    private BigDecimal  actualQty;
    @Schema(description = "是否已退料")
    @TableField("is_returned")
    private Boolean returned;
    @Schema(description = "是否bom领料")
    @TableField("is_bom")
    private Boolean bom;
src/main/java/com/ruoyi/production/pojo/ProductionOrderPickRecord.java
@@ -57,6 +57,9 @@
    @Schema(description = "备注")
    private String remark;
    @Schema(description = "补料原因")
    private String feedingReason;
    @Schema(description = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
src/main/java/com/ruoyi/production/service/ProductionOrderPickRecordService.java
@@ -1,7 +1,11 @@
package com.ruoyi.production.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.bean.dto.ProductionOrderPickRecordDto;
import com.ruoyi.production.bean.vo.ProductionOrderPickRecordVo;
import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import java.util.List;
/**
 * <p>
@@ -13,4 +17,5 @@
 */
public interface ProductionOrderPickRecordService extends IService<ProductionOrderPickRecord> {
    List<ProductionOrderPickRecordVo> listFeedingRecord(ProductionOrderPickRecordDto dto);
}
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickRecordServiceImpl.java
@@ -1,10 +1,15 @@
package com.ruoyi.production.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.production.bean.dto.ProductionOrderPickRecordDto;
import com.ruoyi.production.bean.vo.ProductionOrderPickRecordVo;
import com.ruoyi.production.mapper.ProductionOrderPickRecordMapper;
import com.ruoyi.production.pojo.ProductionOrderPickRecord;
import com.ruoyi.production.service.ProductionOrderPickRecordService;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/**
 * <p>
@@ -17,4 +22,11 @@
@Service
public class ProductionOrderPickRecordServiceImpl extends ServiceImpl<ProductionOrderPickRecordMapper, ProductionOrderPickRecord> implements ProductionOrderPickRecordService {
    @Override
    public List<ProductionOrderPickRecordVo> listFeedingRecord(ProductionOrderPickRecordDto dto) {
        if (dto == null || dto.getProductionOrderId() == null || dto.getPickId() == null) {
            return Collections.emptyList();
        }
        return baseMapper.listFeedingRecord(dto);
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
@@ -39,6 +39,9 @@
@RequiredArgsConstructor
public class ProductionOrderPickServiceImpl extends ServiceImpl<ProductionOrderPickMapper, ProductionOrderPick> implements ProductionOrderPickService {
    private static final byte PICK_TYPE_NORMAL = 1;
    private static final byte PICK_TYPE_FEEDING = 2;
    private final ProductionOrderMapper productionOrderMapper;
    private final ProductionOperationTaskMapper productionOperationTaskMapper;
    private final ProductionOrderPickRecordMapper productionOrderPickRecordMapper;
@@ -68,6 +71,7 @@
            orderPick.setTechnologyOperationId(resolvedDto.getTechnologyOperationId());
            orderPick.setDemandedQuantity(resolvedDto.getDemandedQuantity());
            orderPick.setBom(resolvedDto.getBom());
            orderPick.setReturned(false);
            baseMapper.insert(orderPick);
            insertPickRecord(orderPick.getId(),
@@ -79,7 +83,8 @@
                    BigDecimal.ZERO,
                    resolvedDto.getPickQuantity(),
                    resolvedDto.getPickType(),
                    resolvedDto.getRemark());
                    resolvedDto.getRemark(),
                    resolvedDto.getFeedingReason());
        }
        return true;
    }
@@ -105,6 +110,15 @@
        Map<Long, ProductionOrderPick> existingPickMap = existingPickList.stream()
                .filter(item -> item.getId() != null)
                .collect(Collectors.toMap(ProductionOrderPick::getId, Function.identity(), (a, b) -> a));
        if (isFeedingRequest(dto)) {
            processFeedingPickItems(dto, existingPickMap, productionOrderId);
            return true;
        }
        if (isReturnRequest(dto)) {
            processReturnPickItems(dto, existingPickMap, productionOrderId);
            return true;
        }
        processDeletePickIds(dto, existingPickMap, productionOrderId);
@@ -174,7 +188,8 @@
                    oldQuantity,
                    BigDecimal.ZERO,
                    rootDto.getPickType(),
                    rootDto.getRemark());
                    rootDto.getRemark(),
                    rootDto.getFeedingReason());
            existingPickMap.remove(deleteId);
        }
    }
@@ -191,7 +206,7 @@
                .filter(item -> item.getId() != null)
                .filter(item -> Objects.equals(item.getProductionOrderId(), productionOrderId))
                .filter(item -> !keepPickIdSet.contains(item.getId()))
                .collect(Collectors.toList());
                .toList();
        for (ProductionOrderPick missingPick : missingPickList) {
            String oldBatchNo = resolveInventoryBatchNoFromStored(missingPick.getBatchNo());
            BigDecimal oldQuantity = defaultDecimal(missingPick.getQuantity());
@@ -209,7 +224,8 @@
                    oldQuantity,
                    BigDecimal.ZERO,
                    rootDto.getPickType(),
                    rootDto.getRemark());
                    rootDto.getRemark(),
                    rootDto.getFeedingReason());
            existingPickMap.remove(missingPick.getId());
        }
    }
@@ -230,6 +246,7 @@
        orderPick.setTechnologyOperationId(dto.getTechnologyOperationId());
        orderPick.setDemandedQuantity(dto.getDemandedQuantity());
        orderPick.setBom(dto.getBom());
        orderPick.setReturned(false);
        baseMapper.insert(orderPick);
        insertPickRecord(orderPick.getId(),
@@ -241,7 +258,111 @@
                BigDecimal.ZERO,
                dto.getPickQuantity(),
                dto.getPickType(),
                dto.getRemark());
                dto.getRemark(),
                dto.getFeedingReason());
    }
    private void processFeedingPickItems(ProductionOrderPickDto rootDto,
                                         Map<Long, ProductionOrderPick> existingPickMap,
                                         Long productionOrderId) {
        List<ProductionOrderPickDto> pickItems = resolveUpdateItems(rootDto);
        for (int i = 0; i < pickItems.size(); i++) {
            int rowNo = i + 1;
            ProductionOrderPickDto resolvedDto = mergeDto(rootDto, pickItems.get(i));
            if (isEmptyUpdateItem(resolvedDto)) {
                continue;
            }
            if (!isFeedingPick(resolvedDto)) {
                throw new ServiceException("补料请求中的领料类型必须全部为2");
            }
            if (resolvedDto.getProductionOrderId() == null) {
                resolvedDto.setProductionOrderId(productionOrderId);
            }
            validateFeedingParam(resolvedDto, rowNo);
            ProductionOrderPick oldPick = existingPickMap.get(resolvedDto.getId());
            if (oldPick == null || !Objects.equals(oldPick.getProductionOrderId(), productionOrderId)) {
                throw new ServiceException("第" + rowNo + "条领料记录不存在或不属于当前订单");
            }
            addFeedingPick(resolvedDto, oldPick, rowNo);
        }
    }
    private void addFeedingPick(ProductionOrderPickDto dto, ProductionOrderPick oldPick, int rowNo) {
        if (dto.getProductModelId() != null && !Objects.equals(dto.getProductModelId(), oldPick.getProductModelId())) {
            throw new ServiceException("第" + rowNo + "条补料产品规格与领料记录不一致");
        }
        Long productModelId = oldPick.getProductModelId();
        List<String> batchNoList = resolveBatchNoList(dto);
        String inventoryBatchNo = batchNoList.isEmpty()
                ? resolveInventoryBatchNoFromStored(oldPick.getBatchNo())
                : pickInventoryBatchNo(batchNoList);
        BigDecimal feedingQuantity = dto.getFeedingQuantity();
        subtractInventory(productModelId, inventoryBatchNo, feedingQuantity, rowNo);
        BigDecimal beforeFeedingQty = sumFeedingQuantity(dto.getProductionOrderId(), oldPick.getId());
        BigDecimal afterFeedingQty = beforeFeedingQty.add(feedingQuantity);
        insertPickRecord(oldPick.getId(),
                dto.getProductionOrderId(),
                dto.getProductionOperationTaskId(),
                productModelId,
                inventoryBatchNo,
                feedingQuantity,
                beforeFeedingQty,
                afterFeedingQty,
                PICK_TYPE_FEEDING,
                dto.getRemark(),
                dto.getFeedingReason());
        ProductionOrderPick updatePick = new ProductionOrderPick();
        updatePick.setId(oldPick.getId());
        updatePick.setFeedingQty(afterFeedingQty);
        updatePick.setActualQty(calculateActualQty(oldPick, afterFeedingQty));
        int affected = baseMapper.updateById(updatePick);
        if (affected <= 0) {
            throw new ServiceException("第" + rowNo + "条补料总量更新失败");
        }
        oldPick.setFeedingQty(afterFeedingQty);
        oldPick.setActualQty(updatePick.getActualQty());
    }
    private void processReturnPickItems(ProductionOrderPickDto rootDto,
                                        Map<Long, ProductionOrderPick> existingPickMap,
                                        Long productionOrderId) {
        List<ProductionOrderPickDto> pickItems = resolveUpdateItems(rootDto);
        for (int i = 0; i < pickItems.size(); i++) {
            int rowNo = i + 1;
            ProductionOrderPickDto resolvedDto = mergeDto(rootDto, pickItems.get(i));
            if (isEmptyUpdateItem(resolvedDto)) {
                continue;
            }
            if (resolvedDto.getProductionOrderId() == null) {
                resolvedDto.setProductionOrderId(productionOrderId);
            }
            validateReturnParam(resolvedDto, rowNo);
            ProductionOrderPick oldPick = existingPickMap.get(resolvedDto.getId());
            if (oldPick == null || !Objects.equals(oldPick.getProductionOrderId(), productionOrderId)) {
                throw new ServiceException("第" + rowNo + "条领料记录不存在或不属于当前订单");
            }
            updateReturnPick(resolvedDto, oldPick, rowNo);
        }
    }
    private void updateReturnPick(ProductionOrderPickDto dto, ProductionOrderPick oldPick, int rowNo) {
        ProductionOrderPick updatePick = new ProductionOrderPick();
        updatePick.setId(oldPick.getId());
        updatePick.setReturnQty(dto.getReturnQty());
        updatePick.setActualQty(dto.getActualQty());
        updatePick.setReturned(true);
        int affected = baseMapper.updateById(updatePick);
        if (affected <= 0) {
            throw new ServiceException("第" + rowNo + "条退料信息更新失败");
        }
        oldPick.setReturnQty(updatePick.getReturnQty());
        oldPick.setActualQty(updatePick.getActualQty());
        oldPick.setReturned(true);
    }
    private void updateExistingPick(ProductionOrderPickDto dto,
@@ -304,7 +425,8 @@
                    oldQuantity,
                    newQuantity,
                    dto.getPickType(),
                    dto.getRemark());
                    dto.getRemark(),
                    dto.getFeedingReason());
        }
    }
@@ -317,7 +439,8 @@
                                  BigDecimal beforeQuantity,
                                  BigDecimal afterQuantity,
                                  Byte pickType,
                                  String remark) {
                                  String remark,
                                  String feedingReason) {
        ProductionOrderPickRecord pickRecord = new ProductionOrderPickRecord();
        pickRecord.setPickId(pickId);
        pickRecord.setProductionOrderId(productionOrderId);
@@ -327,8 +450,9 @@
        pickRecord.setPickQuantity(defaultDecimal(pickQuantity));
        pickRecord.setBeforeQuantity(defaultDecimal(beforeQuantity));
        pickRecord.setAfterQuantity(defaultDecimal(afterQuantity));
        pickRecord.setPickType(pickType == null ? (byte) 1 : pickType);
        pickRecord.setPickType(pickType == null ? PICK_TYPE_NORMAL : pickType);
        pickRecord.setRemark(remark);
        pickRecord.setFeedingReason(feedingReason);
        productionOrderPickRecordMapper.insert(pickRecord);
    }
@@ -405,6 +529,11 @@
                && StringUtils.isEmpty(dto.getBatchNo())
                && (dto.getBatchNoList() == null || dto.getBatchNoList().isEmpty())
                && dto.getPickType() == null
                && dto.getFeedingQuantity() == null
                && StringUtils.isEmpty(dto.getFeedingReason())
                && dto.getReturnQty() == null
                && dto.getActualQty() == null
                && dto.getReturned() == null
                && dto.getProductionOperationTaskId() == null
                && dto.getTechnologyOperationId() == null
                && StringUtils.isEmpty(dto.getOperationName())
@@ -440,10 +569,15 @@
            merged.setPickQuantity(itemDto.getPickQuantity());
            merged.setPickType(itemDto.getPickType());
            merged.setRemark(itemDto.getRemark());
            merged.setFeedingReason(itemDto.getFeedingReason());
            merged.setFeedingQuantity(itemDto.getFeedingQuantity());
            merged.setTechnologyOperationId(itemDto.getTechnologyOperationId());
            merged.setOperationName(itemDto.getOperationName());
            merged.setDemandedQuantity(itemDto.getDemandedQuantity());
            merged.setBom(itemDto.getBom());
            merged.setReturnQty(itemDto.getReturnQty());
            merged.setActualQty(itemDto.getActualQty());
            merged.setReturned(itemDto.getReturned());
        }
        if (merged.getId() == null) {
            merged.setId(rootDto.getId());
@@ -472,6 +606,12 @@
        if (merged.getRemark() == null) {
            merged.setRemark(rootDto.getRemark());
        }
        if (merged.getFeedingReason() == null) {
            merged.setFeedingReason(rootDto.getFeedingReason());
        }
        if (merged.getFeedingQuantity() == null) {
            merged.setFeedingQuantity(rootDto.getFeedingQuantity());
        }
        if (merged.getTechnologyOperationId() == null) {
            merged.setTechnologyOperationId(rootDto.getTechnologyOperationId());
        }
@@ -483,6 +623,15 @@
        }
        if (merged.getBom() == null) {
            merged.setBom(rootDto.getBom());
        }
        if (merged.getReturnQty() == null) {
            merged.setReturnQty(rootDto.getReturnQty());
        }
        if (merged.getActualQty() == null) {
            merged.setActualQty(rootDto.getActualQty());
        }
        if (merged.getReturned() == null) {
            merged.setReturned(rootDto.getReturned());
        }
        return merged;
    }
@@ -497,9 +646,89 @@
        if (dto.getPickQuantity() == null || dto.getPickQuantity().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("第" + rowNo + "条领料数量必须大于0");
        }
        if (dto.getPickType() != null && dto.getPickType() != 1 && dto.getPickType() != 2) {
        if (dto.getPickType() != null && dto.getPickType() != PICK_TYPE_NORMAL && dto.getPickType() != PICK_TYPE_FEEDING) {
            throw new ServiceException("第" + rowNo + "条领料类型只能是1或2");
        }
    }
    private void validateFeedingParam(ProductionOrderPickDto dto, int rowNo) {
        if (dto.getProductionOrderId() == null) {
            throw new ServiceException("第" + rowNo + "条生产订单ID不能为空");
        }
        if (dto.getId() == null) {
            throw new ServiceException("第" + rowNo + "条领料ID不能为空");
        }
        if (dto.getFeedingQuantity() == null || dto.getFeedingQuantity().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("第" + rowNo + "条本次补料数量必须大于0");
        }
        if (!isFeedingPick(dto)) {
            throw new ServiceException("第" + rowNo + "条补料类型必须为2");
        }
    }
    private void validateReturnParam(ProductionOrderPickDto dto, int rowNo) {
        if (dto.getProductionOrderId() == null) {
            throw new ServiceException("第" + rowNo + "条生产订单ID不能为空");
        }
        if (dto.getId() == null) {
            throw new ServiceException("第" + rowNo + "条领料ID不能为空");
        }
        if (dto.getReturnQty() == null || dto.getReturnQty().compareTo(BigDecimal.ZERO) < 0) {
            throw new ServiceException("第" + rowNo + "条退料数量不能为空且不能小于0");
        }
        if (dto.getActualQty() == null || dto.getActualQty().compareTo(BigDecimal.ZERO) < 0) {
            throw new ServiceException("第" + rowNo + "条实际数量不能为空且不能小于0");
        }
    }
    private boolean isFeedingRequest(ProductionOrderPickDto dto) {
        if (isFeedingPick(dto)) {
            return true;
        }
        if (dto.getPickList() == null || dto.getPickList().isEmpty()) {
            return false;
        }
        return dto.getPickList().stream()
                .filter(Objects::nonNull)
                .anyMatch(this::isFeedingPick);
    }
    private boolean isFeedingPick(ProductionOrderPickDto dto) {
        return dto != null && Objects.equals(dto.getPickType(), PICK_TYPE_FEEDING);
    }
    private boolean isReturnRequest(ProductionOrderPickDto dto) {
        if (isReturnPick(dto)) {
            return true;
        }
        if (dto.getPickList() == null || dto.getPickList().isEmpty()) {
            return false;
        }
        return dto.getPickList().stream()
                .filter(Objects::nonNull)
                .anyMatch(this::isReturnPick);
    }
    private boolean isReturnPick(ProductionOrderPickDto dto) {
        return dto != null && Boolean.TRUE.equals(dto.getReturned());
    }
    private BigDecimal sumFeedingQuantity(Long productionOrderId, Long pickId) {
        List<ProductionOrderPickRecord> feedingRecords = productionOrderPickRecordMapper.selectList(
                Wrappers.<ProductionOrderPickRecord>lambdaQuery()
                        .eq(ProductionOrderPickRecord::getProductionOrderId, productionOrderId)
                        .eq(ProductionOrderPickRecord::getPickId, pickId)
                        .eq(ProductionOrderPickRecord::getPickType, PICK_TYPE_FEEDING));
        return feedingRecords.stream()
                .map(ProductionOrderPickRecord::getPickQuantity)
                .map(this::defaultDecimal)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    private BigDecimal calculateActualQty(ProductionOrderPick pick, BigDecimal feedingQty) {
        return defaultDecimal(pick.getQuantity())
                .add(defaultDecimal(feedingQty))
                .subtract(defaultDecimal(pick.getReturnQty()));
    }
    private String normalizeBatchNo(String batchNo) {
@@ -654,4 +883,3 @@
        return value == null ? BigDecimal.ZERO : value;
    }
}
src/main/resources/mapper/production/ProductionOrderPickMapper.xml
@@ -17,12 +17,17 @@
        <result column="operation_name" property="operationName" />
        <result column="technology_operation_id" property="technologyOperationId" />
        <result column="demanded_quantity" property="demandedQuantity" />
        <result column="feeding_qty" property="feedingQty" />
        <result column="return_qty" property="returnQty" />
        <result column="actual_qty" property="actualQty" />
        <result column="is_returned" property="returned" />
        <result column="is_bom" property="bom" />
    </resultMap>
    <select id="listPickedDetailByOrderId" resultType="com.ruoyi.production.bean.vo.ProductionOrderPickVo">
        select pop.*,
               pop.is_bom as bom,
               pop.is_returned as returned,
               pop.quantity as pickQuantity,
               p.product_name as productName,
               pm.model as model,
src/main/resources/mapper/production/ProductionOrderPickRecordMapper.xml
@@ -15,6 +15,7 @@
        <result column="after_quantity" property="afterQuantity" />
        <result column="pick_type" property="pickType" />
        <result column="remark" property="remark" />
        <result column="feeding_reason" property="feedingReason" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="create_user" property="createUser" />
@@ -36,4 +37,24 @@
        order by popr.create_time desc, popr.id desc
    </select>
    <select id="listFeedingRecord" resultType="com.ruoyi.production.bean.vo.ProductionOrderPickRecordVo">
        select popr.*,
               poro.operation_name as operationName,
               p.product_name as productName,
               pm.model as model,
               pm.unit as unit,
               coalesce(su.nick_name, su.user_name) as supplementUserName,
               popr.create_time as supplementTime
        from production_order_pick_record popr
                 left join production_operation_task pot on popr.production_operation_task_id = pot.id
                 left join production_order_routing_operation poro on pot.technology_routing_operation_id = poro.id
                 left join product_model pm on popr.product_model_id = pm.id
                 left join product p on pm.product_id = p.id
                 left join sys_user su on popr.create_user = su.user_id
        where popr.production_order_id = #{productionOrderId}
          and popr.pick_id = #{pickId}
          and popr.pick_type = 2
        order by popr.create_time desc, popr.id desc
    </select>
</mapper>