昨天 684e4306a08feeae188070f264148e6765da8dcf
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -36,6 +36,8 @@
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
@@ -47,6 +49,10 @@
@RequiredArgsConstructor
public class ShippingInfoServiceImpl extends ServiceImpl<ShippingInfoMapper, ShippingInfo> implements ShippingInfoService {
    /**
     * listPage 的行来源标记:shipping=发货单,oilOut=销售类油品出库
     */
    private static final String SOURCE_OIL_OUT = "oilOut";
    private final ShippingInfoMapper shippingInfoMapper;
@@ -68,8 +74,24 @@
        IPage<ShippingInfoDto> listPage = shippingInfoMapper.listPage(page, req);
        listPage.getRecords().forEach(item -> {
            item.setStorageBlobVOs(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.IMAGE, RecordTypeEnum.SHIPPING_INFO, item.getId()));
            // 油品出库行没有 shipping_product_detail,批号明细只能由出库记录自身字段构造
            if (SOURCE_OIL_OUT.equals(item.getSource())) {
                item.setBatchNoList(buildOilOutBatchNoList(item));
            }
        });
        return listPage;
    }
    /**
     * 油品出库行的批号明细,供发货台账详情弹框的「批号」明细表展示
     */
    private List<ShippingProductDetailDto> buildOilOutBatchNoList(ShippingInfoDto item) {
        ShippingProductDetailDto detail = new ShippingProductDetailDto();
        detail.setBatchNo(item.getOutBatchNo());
        detail.setProductName(item.getProductName());
        detail.setSpecificationModel(item.getSpecificationModel());
        detail.setDeliveryQuantity(item.getTotalQuantity());
        return Collections.singletonList(detail);
    }
    @Override
@@ -171,7 +193,6 @@
    @Override
    public boolean addReq(ShippingInfoDto req) {
        // 校验该产品是否已有待审核/审核中的发货记录,防止重复提交
        Long salesLedgerProductId = req.getSalesLedgerProductId();
        if (salesLedgerProductId != null) {
@@ -216,4 +237,31 @@
        this.updateById(req);
        return true;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addShippedFromOutbound(ShippingInfoDto req) {
        // 仓储物流出库即发货:不发起发货审批,直接落为已发货,库存由 add 内部扣减
        req.setShippingNo(OrderUtils.countTodayByCreateTime(
                shippingInfoMapper, "SH", "shipping_no", LocalDateTime.now()));
        req.setStatus("已发货");
        if (req.getShippingDate() == null) {
            req.setShippingDate(new Date());
        }
        this.add(req);
        return req.getId();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelByOutbound(Long shippingInfoId) {
        if (shippingInfoId == null) {
            return;
        }
        // 回滚该发货单占用的库存
        stockUtils.deleteStockOutRecord(shippingInfoId, StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode());
        shippingProductDetailMapper.delete(new LambdaQueryWrapper<ShippingProductDetail>()
                .eq(ShippingProductDetail::getShippingInfoId, shippingInfoId));
        this.removeById(shippingInfoId);
    }
}