src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -80,12 +80,39 @@
        QualityInspect qualityInspect = new QualityInspect();
        BeanUtils.copyProperties(qualityInspectDto, qualityInspect);
        qualityInspect.setInspectState(0);//默认未提交
        // 根据 inspectRule 补全抽检比例和抽检数量默认值
        applyInspectRuleDefaults(qualityInspect);
        qualityInspectMapper.insert(qualityInspect);
        for (QualityInspectParam qualityInspectParam : qualityInspectDto.getQualityInspectParams()) {
            qualityInspectParam.setInspectId(qualityInspect.getId());
        }
        qualityInspectParamService.saveBatch(qualityInspectDto.getQualityInspectParams());
        return 0;
    }
    /**
     * 根据 inspectRule 设置抽检比例和抽检数量默认值
     * - inspectRule=0 (全检): sampleRatio=100, sampleQuantity=全部数量
     * - inspectRule=1 (抽检): sampleRatio 取传入值或0, sampleQuantity=数量×比例/100
     */
    private void applyInspectRuleDefaults(QualityInspect inspect) {
        Integer rule = inspect.getInspectRule();
        java.math.BigDecimal quantity = inspect.getQuantity();
        if (rule == null || rule == 0) {
            // 全检
            inspect.setSampleRatio(java.math.BigDecimal.valueOf(100));
            inspect.setSampleQuantity(quantity != null ? quantity : java.math.BigDecimal.ZERO);
        } else {
            // 抽检
            java.math.BigDecimal ratio = inspect.getSampleRatio() != null ? inspect.getSampleRatio() : java.math.BigDecimal.ZERO;
            inspect.setSampleRatio(ratio);
            if (quantity != null && ratio.compareTo(java.math.BigDecimal.ZERO) > 0) {
                inspect.setSampleQuantity(quantity.multiply(ratio)
                        .divide(java.math.BigDecimal.valueOf(100), 0, java.math.RoundingMode.CEILING));
            } else {
                inspect.setSampleQuantity(java.math.BigDecimal.ZERO);
            }
        }
    }
    @Override
@@ -244,7 +271,9 @@
    /**
     * 在独立事务中处理单个检验单
     * 数量、合格数量默认使用检验单自身的数量,不合格数量为0
     * 支持全检和抽检模式:
     * - 全检:数量、合格数量默认使用检验单自身的数量,不合格数量为0
     * - 抽检:使用前端传入的 sampleQuantity/qualifiedQuantity/unqualifiedQuantity
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void processSingleInspect(Long id, BatchQuickInspectRequest request,
@@ -257,17 +286,66 @@
            throw new RuntimeException("检验单已提交");
        }
        // 数量默认取检验单自身的数量,不合格数量为0
        BigDecimal qty = qualityInspect.getQuantity() != null ? qualityInspect.getQuantity() : BigDecimal.ZERO;
        BigDecimal qualified = qty;
        BigDecimal unqualified = BigDecimal.ZERO;
        // 判断检验规则:全检(0/null) 或 抽检(1)
        Integer inspectRule = qualityInspect.getInspectRule();
        boolean isFullInspect = inspectRule == null || inspectRule == 0;
        BigDecimal totalQty = qualityInspect.getQuantity() != null ? qualityInspect.getQuantity() : BigDecimal.ZERO;
        BigDecimal sampleQty;
        BigDecimal qualified;
        BigDecimal unqualified;
        if (isFullInspect) {
            // 全检模式:检验数量 = 总数量
            sampleQty = totalQty;
            // 如果前端传入了合格/不合格数量则使用,否则默认全部合格
            if (request.getQualifiedQuantity() != null && request.getUnqualifiedQuantity() != null) {
                qualified = request.getQualifiedQuantity();
                unqualified = request.getUnqualifiedQuantity();
            } else {
                qualified = totalQty;
                unqualified = BigDecimal.ZERO;
            }
        } else {
            // 抽检模式
            // 抽检数量:优先使用前端传入值,其次使用检验单已有的 sampleQuantity,最后按比例计算
            if (request.getSampleQuantity() != null && request.getSampleQuantity().compareTo(BigDecimal.ZERO) > 0) {
                sampleQty = request.getSampleQuantity();
            } else if (qualityInspect.getSampleQuantity() != null && qualityInspect.getSampleQuantity().compareTo(BigDecimal.ZERO) > 0) {
                sampleQty = qualityInspect.getSampleQuantity();
            } else {
                // 按抽检比例计算
                BigDecimal ratio = qualityInspect.getSampleRatio() != null ? qualityInspect.getSampleRatio() : BigDecimal.ZERO;
                sampleQty = totalQty.multiply(ratio)
                        .divide(BigDecimal.valueOf(100), 0, BigDecimal.ROUND_CEILING);
            }
            // 校验抽检数量不能超过总数量
            if (sampleQty.compareTo(totalQty) > 0) {
                sampleQty = totalQty;
            }
            // 合格/不合格数量:优先使用前端传入值
            if (request.getQualifiedQuantity() != null || request.getUnqualifiedQuantity() != null) {
                qualified = request.getQualifiedQuantity() != null ? request.getQualifiedQuantity() : BigDecimal.ZERO;
                unqualified = request.getUnqualifiedQuantity() != null ? request.getUnqualifiedQuantity() : BigDecimal.ZERO;
            } else {
                // 默认抽检样本全部合格
                qualified = sampleQty;
                unqualified = BigDecimal.ZERO;
            }
        }
        // 2. 更新检验单字段
        qualityInspect.setCheckResult(checkResult);
        qualityInspect.setTestStandardId(request.getTestStandardId());
        qualityInspect.setQuantity(qty);
        // 记录实际检验数量(抽检时为样本数量,全检时为总数量)
        qualityInspect.setQuantity(sampleQty);
        qualityInspect.setQualifiedQuantity(qualified);
        qualityInspect.setUnqualifiedQuantity(unqualified);
        // 更新抽检数量字段
        if (!isFullInspect) {
            qualityInspect.setSampleQuantity(sampleQty);
        }
        if (request.getCheckCompany() != null) {
            qualityInspect.setCheckCompany(request.getCheckCompany());
        }