liu
2 天以前 b490500184a57b740c016bb281765fe29731eab5
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
@@ -21,11 +21,16 @@
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi;
import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsCreateReqDTO;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
@@ -43,7 +48,7 @@
/**
 * ERP 销售订单 Service 实现类
 *
 * @author 芋道源码
 * @author 超级管理员
 */
@Service
@Validated
@@ -73,6 +78,25 @@
    @Resource
    private MesProMpsApi mpsApi;
    @Resource
    private PlatformTransactionManager transactionManager;
    /**
     * MPS 创建使用独立事务(REQUIRES_NEW):
     * 审核时自动创建 MPS 属于尽力而为的联动,失败仅记录日志并回滚自身,
     * 不能污染销售订单审核事务(否则内层异常会把外层事务标记为 rollback-only,导致整个审核被回滚)
     */
    private TransactionTemplate mpsTransactionTemplate;
    @PostConstruct
    public void initMpsTransactionTemplate() {
        mpsTransactionTemplate = new TransactionTemplate(transactionManager);
        mpsTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    }
    @Resource
    private StorageAttachmentApi storageAttachmentApi;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createSaleOrder(ErpSaleOrderSaveReqVO createReqVO) {
@@ -97,12 +121,16 @@
        // 2.1 插入订单
        ErpSaleOrderDO saleOrder = BeanUtils.toBean(createReqVO, ErpSaleOrderDO.class, in -> in
                .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
                .setDepositPrice(ObjectUtil.defaultIfNull(createReqVO.getDepositPrice(), BigDecimal.ZERO))
                .setOutCount(BigDecimal.ZERO).setOutStatus(ErpSaleOrderOutStatusEnum.NOT_OUT.getStatus()));
        calculateTotalPrice(saleOrder, saleOrderItems);
        saleOrderMapper.insert(saleOrder);
        // 2.2 插入订单项
        saleOrderItems.forEach(o -> o.setOrderId(saleOrder.getId()));
        saleOrderItemMapper.insertBatch(saleOrderItems);
        // 2.3 绑定附件
        storageAttachmentApi.bindAttachments("file", "erp_sale_order",
                saleOrder.getId(), createReqVO.getBlobIds());
        return saleOrder.getId();
    }
@@ -129,10 +157,13 @@
        // 2.1 更新订单
        ErpSaleOrderDO updateObj = BeanUtils.toBean(updateReqVO, ErpSaleOrderDO.class);
        updateObj.setDepositPrice(ObjectUtil.defaultIfNull(updateReqVO.getDepositPrice(), BigDecimal.ZERO));
        calculateTotalPrice(updateObj, saleOrderItems);
        saleOrderMapper.updateById(updateObj);
        // 2.2 更新订单项
        updateSaleOrderItemList(updateReqVO.getId(), saleOrderItems);
        // 2.3 更新附件
        storageAttachmentApi.updateAttachments("file", "erp_sale_order", updateReqVO.getId(), updateReqVO.getBlobIds());
    }
    private void calculateTotalPrice(ErpSaleOrderDO saleOrder, List<ErpSaleOrderItemDO> saleOrderItems) {
@@ -195,13 +226,19 @@
                continue;
            }
            try {
                Long mpsId = createMpsForSaleOrderItem(saleOrder, item);
                // 独立事务创建 MPS:失败只回滚 MPS 自身,不影响审核事务
                Long mpsId = mpsTransactionTemplate.execute(txStatus -> {
                    Long newMpsId = createMpsForSaleOrderItem(saleOrder, item);
                    if (newMpsId != null) {
                        // 更新销售订单明细的 MPS 关联
                        saleOrderItemMapper.updateById(new ErpSaleOrderItemDO()
                                .setId(item.getId())
                                .setMpsId(newMpsId));
                    }
                    return newMpsId;
                });
                if (mpsId != null) {
                    mpsCount++;
                    // 更新销售订单明细的 MPS 关联
                    saleOrderItemMapper.updateById(new ErpSaleOrderItemDO()
                            .setId(item.getId())
                            .setMpsId(mpsId));
                }
            } catch (Exception e) {
                log.error("[createMpsForSaleOrder] 创建 MPS 失败,saleOrderItemId={}", item.getId(), e);
@@ -370,9 +407,11 @@
        // 2. 遍历删除,并记录操作日志
        saleOrders.forEach(saleOrder -> {
            // 2.1 删除订单
            // 2.1 删除附件
            storageAttachmentApi.deleteAttachmentsByRecord("erp_sale_order", saleOrder.getId());
            // 2.2 删除订单
            saleOrderMapper.deleteById(saleOrder.getId());
            // 2.2 删除订单项
            // 2.3 删除订单项
            saleOrderItemMapper.deleteByOrderId(saleOrder.getId());
        });
    }
@@ -467,4 +506,4 @@
        }
    }
}
}