src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -3357,6 +3357,97 @@
     * 2. 复制原销售台账及产品数据,生成新的台账
     * 3. 对原台账的库存数据进行反向操作
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Long> counterReview(CounterReviewDto dto) {
        if (dto == null || CollectionUtils.isEmpty(dto.getIds())) {
            throw new ServiceException("请选择要反审核的订单");
        }
        if (dto.getCounterReviewType() == null || (dto.getCounterReviewType() != 1 && dto.getCounterReviewType() != 2)) {
            throw new ServiceException("请选择反审核类型:作废或重新生成");
        }
        if (dto.getCounterReviewDesc() == null || dto.getCounterReviewDesc().trim().isEmpty()) {
            throw new ServiceException("请输入反审核描述");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<Long> newLedgerIds = new ArrayList<>();
        for (Long id : dto.getIds()) {
            SalesLedger originalLedger = salesLedgerMapper.selectById(id);
            if (originalLedger == null) {
                throw new ServiceException("订单不存在,无法反审核");
            }
            if (originalLedger.getReviewStatus() == null || originalLedger.getReviewStatus() != 1) {
                throw new ServiceException("订单" + originalLedger.getSalesContractNo() + "不是已审核状态,无法反审核");
            }
            // 1. 标记原订单为已反审
            originalLedger.setReviewStatus(2);
            originalLedger.setCounterReviewTime(LocalDateTime.now());
            originalLedger.setCounterReviewPerson(loginUser.getUser().getNickName());
            originalLedger.setCounterReviewPersonId(loginUser.getUserId());
            originalLedger.setCounterReviewType(dto.getCounterReviewType());
            originalLedger.setCounterReviewDesc(dto.getCounterReviewDesc());
            salesLedgerMapper.updateById(originalLedger);
            // 2. 作废库存:入库扣减、出库增加、删除记录
            processOriginalOrderStock(id);
            // 3. 清除质检记录
            clearQualityInspectRecords(id);
            // 4. 清除发货信息和发货审批记录
            clearShippingAndApprovalRecords(id);
            // 5. 取消审批流程
            cancelApproveProcesses(id, originalLedger.getSalesContractNo());
            // 6. 重新生成:创建新台账副本
            if (dto.getCounterReviewType() == 2) {
                SalesLedger newLedger = new SalesLedger();
                BeanUtils.copyProperties(originalLedger, newLedger);
                newLedger.setId(null);
                newLedger.setSalesContractNo(generateSalesContractNo());
                newLedger.setDeliveryStatus(1);
                newLedger.setStockStatus(0);
                newLedger.setReviewStatus(0);
                newLedger.setCounterReviewTime(null);
                newLedger.setCounterReviewPerson(null);
                newLedger.setCounterReviewPersonId(null);
                newLedger.setCounterReviewType(null);
                newLedger.setCounterReviewDesc(null);
                salesLedgerMapper.insert(newLedger);
                // 复制产品到新台账
                List<SalesLedgerProduct> originalProducts = salesLedgerProductMapper.selectList(
                    Wrappers.<SalesLedgerProduct>lambdaQuery()
                        .eq(SalesLedgerProduct::getSalesLedgerId, id)
                );
                for (SalesLedgerProduct originalProduct : originalProducts) {
                    SalesLedgerProduct newProduct = new SalesLedgerProduct();
                    BeanUtils.copyProperties(originalProduct, newProduct);
                    newProduct.setId(null);
                    newProduct.setSalesLedgerId(newLedger.getId());
                    newProduct.setStockedQuantity(BigDecimal.ZERO);
                    newProduct.setShippedQuantity(BigDecimal.ZERO);
                    newProduct.setUnqualifiedStockedQuantity(BigDecimal.ZERO);
                    newProduct.setUnqualifiedShippedQuantity(BigDecimal.ZERO);
                    newProduct.setReturnQuality(BigDecimal.ZERO);
                    newProduct.setAvailableQuality(newProduct.getQuantity().subtract(newProduct.getReturnQuality()));
                    newProduct.setProductStockStatus(0);
                    newProduct.fillRemainingQuantity();
                    salesLedgerProductMapper.insert(newProduct);
                }
                newLedgerIds.add(newLedger.getId());
            }
        }
        return newLedgerIds;
    }
    /**
     * 旧版反审处理(兼容 addOrUpdateSalesLedger 中 reviewStatus=2 的调用)
     */
    private void handleCounterReview(SalesLedger salesLedger) {
        // 1. 设置反审相关信息
        LoginUser loginUser = SecurityUtils.getLoginUser();