src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -812,6 +812,13 @@
        if (CollectionUtils.isEmpty(idList)) {
            return 0;
        }
        // 校验:已审核的订单不能删除
        List<SalesLedger> ledgers = salesLedgerMapper.selectBatchIds(idList);
        for (SalesLedger ledger : ledgers) {
            if (ledger.getReviewStatus() != null && ledger.getReviewStatus() == 1) {
                throw new ServiceException("已审核的订单不能删除:" + ledger.getSalesContractNo());
            }
        }
        // 删除销售管理数据
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList).select(SalesLedgerProduct::getId);
@@ -906,11 +913,25 @@
                if (salesLedger.getDeliveryStatus() == 5) {
                    throw new ServiceException("订单已发货,禁止编辑");
                }
                // 查询数据库中的原始记录用于校验
                SalesLedger existingLedger = salesLedgerMapper.selectById(salesLedger.getId());
                if (salesLedger.getReviewStatus() != null && salesLedger.getReviewStatus() == 1) {
                    // 审核操作:校验审核人不能是录入人(仅对未审核→已审核的转换)
                    if (existingLedger != null && existingLedger.getReviewStatus() != null && existingLedger.getReviewStatus() == 0) {
                        Long currentUserId = SecurityUtils.getUserId();
                        String entryPerson = existingLedger.getEntryPerson();
                        if (entryPerson != null && entryPerson.equals(String.valueOf(currentUserId))) {
                            throw new ServiceException("不能审核本人录入的订单");
                        }
                    }
                    salesLedger.setReviewStatus(salesLedgerDto.getReviewStatus());
                } else if (salesLedger.getReviewStatus() != null && salesLedger.getReviewStatus() == 2) {
                    handleCounterReview(salesLedger);
                } else {
                    // 未审核状态的编辑操作:校验已审核的订单不能编辑
                    if (existingLedger != null && existingLedger.getReviewStatus() != null && existingLedger.getReviewStatus() == 1) {
                        throw new ServiceException("已审核的订单不能编辑");
                    }
                    salesLedger.setReviewStatus(0);
                }
                salesLedgerMapper.updateById(salesLedger);
@@ -3336,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();
@@ -3402,7 +3514,7 @@
        clearShippingAndApprovalRecords(originalSalesLedgerId);
        
        // 9. 取消原订单相关的审批流程
        cancelApproveProcesses(originalSalesLedgerId);
        cancelApproveProcesses(originalSalesLedgerId, originalLedger.getSalesContractNo());
    }
    /**
@@ -3450,7 +3562,7 @@
    /**
     * 取消原订单相关的审批流程
     */
    private void cancelApproveProcesses(Long originalSalesLedgerId) {
    private void cancelApproveProcesses(Long originalSalesLedgerId, String originalSalesContractNo) {
        // 取消入库审批流程
        List<ApproveProcess> stockInApproveProcesses = approveProcessService.list(
            new LambdaQueryWrapper<ApproveProcess>()
@@ -3469,7 +3581,7 @@
        List<ApproveProcess> deliveryApproveProcesses = approveProcessService.list(
            new LambdaQueryWrapper<ApproveProcess>()
                .eq(ApproveProcess::getApproveType, 7) // 发货审批类型
                .like(ApproveProcess::getApproveRemark, "{\"ledgerId\":" + originalSalesLedgerId)
                .like(ApproveProcess::getApproveReason, "发货审批:" + originalSalesContractNo)
                .eq(ApproveProcess::getApproveDelete, 0)
        );