编辑 | blame | 历史 | 原始文档

质检快速检验抽检功能前端联调文档

扩展批量快速检验接口,支持全检和抽检两种检验模式,自动填充抽检数量。

涉及页面

  • 质量管理 / 检验单列表 - 批量快速检验弹窗
  • 质量管理 / 原材料检验 / 过程检验 / 出厂检验 - 快速检验操作

API

方法 路径 说明
POST /qualityInspect/batchQuickInspect 批量快速检验 (扩展参数)

请求参数:

参数 类型 必填 说明
ids List<Long> 检验单ID列表
checkResult String 检测结果:合格/不合格/部分合格
testStandardId Long 指标标准ID
checkCompany String 检测单位
checkName String 检验员姓名
checkTime String 检测日期,格式:YYYY-MM-DD
paramList List 检验参数列表
sampleQuantity BigDecimal 抽检数量(新增)
qualifiedQuantity BigDecimal 合格数量(新增)
unqualifiedQuantity BigDecimal 不合格数量(新增)

响应:

{
  "code": 200,
  "msg": "快速检验完成:成功 3 条"
}

业务规则说明

检验模式判断

根据检验单的 inspectRule 字段判断检验模式:

inspectRule 检验模式 处理逻辑
0 或 null 全检 检验数量 = 总数量,默认全部合格
1 抽检 检验数量 = 抽检样本数量

抽检数量来源优先级

当检验单为抽检模式时,抽检数量按以下优先级确定:

  1. 前端传入 sampleQuantity(最高优先级)
  2. 检验单已有 sampleQuantity
  3. 按抽检比例计算总数量 × sampleRatio / 100(向上取整)
  4. 校验:抽检数量不能超过总数量,超过则自动修正为总数量

合格/不合格数量

场景 处理逻辑
前端传入了 qualifiedQuantity/unqualifiedQuantity 使用前端传入值
前端未传入 默认全部合格(合格数=检验数量,不合格数=0)

入库处理

  • 入库数量 = 合格数量 × 入库比例 / 100
  • 入库比例默认 100%,可通过 stockInRatio 字段调整

前端修改点

1. 快速检验弹窗增加抽检字段

<el-dialog title="批量快速检验" v-model="quickInspectVisible">
  <el-form :model="quickInspectForm" label-width="100px">
    <!-- 基础字段 -->
    <el-form-item label="检测结果" required>
      <el-select v-model="quickInspectForm.checkResult">
        <el-option label="合格" value="合格" />
        <el-option label="不合格" value="不合格" />
        <el-option label="部分合格" value="部分合格" />
      </el-select>
    </el-form-item>

    <el-form-item label="指标标准" required>
      <el-select v-model="quickInspectForm.testStandardId">
        <!-- 指标标准列表 -->
      </el-select>
    </el-form-item>

    <el-form-item label="检验员">
      <el-input v-model="quickInspectForm.checkName" />
    </el-form-item>

    <el-form-item label="检测日期">
      <el-date-picker v-model="quickInspectForm.checkTime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
    </el-form-item>

    <!-- 抽检相关字段(根据检验单模式动态显示) -->
    <el-form-item label="检验模式">
      <el-tag :type="inspectModeTag">{{ inspectModeLabel }}</el-tag>
    </el-form-item>

    <!-- 抽检模式下显示 -->
    <el-form-item label="抽检数量" v-if="showSampleFields">
      <el-input-number
        v-model="quickInspectForm.sampleQuantity"
        :min="1"
        :max="maxSampleQuantity"
        :precision="0"
      />
      <span class="tip">最大可抽检数量:{{ maxSampleQuantity }}</span>
    </el-form-item>

    <!-- 部分合格或不合格时显示 -->
    <el-form-item label="合格数量" v-if="showQuantityFields">
      <el-input-number
        v-model="quickInspectForm.qualifiedQuantity"
        :min="0"
        :max="quickInspectForm.sampleQuantity || totalQuantity"
        :precision="0"
      />
    </el-form-item>

    <el-form-item label="不合格数量" v-if="showQuantityFields">
      <el-input-number
        v-model="quickInspectForm.unqualifiedQuantity"
        :min="0"
        :max="quickInspectForm.sampleQuantity || totalQuantity"
        :precision="0"
      />
    </el-form-item>
  </el-form>

  <template #footer>
    <el-button @click="quickInspectVisible = false">取消</el-button>
    <el-button type="primary" @click="submitQuickInspect">确认检验</el-button>
  </template>
</el-dialog>

2. data 数据

data() {
  return {
    quickInspectVisible: false,
    quickInspectForm: {
      ids: [],
      checkResult: '合格',
      testStandardId: null,
      checkCompany: '',
      checkName: '',
      checkTime: '',
      paramList: [],
      sampleQuantity: null,
      qualifiedQuantity: null,
      unqualifiedQuantity: null,
    },
    // 选中的检验单列表
    selectedInspects: [],
    // 当前检验单信息(用于单条快速检验)
    currentInspect: null,
  }
}

3. computed 计算属性

computed: {
  // 检验模式标签
  inspectModeLabel() {
    if (!this.currentInspect) return '未知';
    return this.currentInspect.inspectRule === 1 ? '抽检' : '全检';
  },
  inspectModeTag() {
    if (!this.currentInspect) return 'info';
    return this.currentInspect.inspectRule === 1 ? 'warning' : 'success';
  },
  // 是否显示抽检字段
  showSampleFields() {
    return this.currentInspect && this.currentInspect.inspectRule === 1;
  },
  // 是否显示合格/不合格数量输入(部分合格或不合格时)
  showQuantityFields() {
    return this.quickInspectForm.checkResult === '部分合格' ||
           this.quickInspectForm.checkResult === '不合格';
  },
  // 总数量
  totalQuantity() {
    return this.currentInspect?.quantity || 0;
  },
  // 最大抽检数量
  maxSampleQuantity() {
    return this.totalQuantity;
  },
  // 默认抽检数量(从检验单获取或按比例计算)
  defaultSampleQuantity() {
    if (!this.currentInspect) return 0;
    if (this.currentInspect.sampleQuantity) {
      return this.currentInspect.sampleQuantity;
    }
    if (this.currentInspect.sampleRatio) {
      return Math.ceil(this.totalQuantity * this.currentInspect.sampleRatio / 100);
    }
    return this.totalQuantity;
  },
}

4. methods 方法

methods: {
  // 打开快速检验弹窗
  openQuickInspectDialog(row) {
    // 单条快速检验
    this.currentInspect = row;
    this.quickInspectForm.ids = [row.id];
    // 抽检模式下自动填充抽检数量
    if (row.inspectRule === 1) {
      this.quickInspectForm.sampleQuantity = this.defaultSampleQuantity;
    }
    // 其他字段初始化
    this.quickInspectForm.checkResult = '合格';
    this.quickInspectForm.testStandardId = row.testStandardId;
    this.quickInspectForm.checkTime = new Date().toISOString().slice(0, 10);
    this.quickInspectForm.qualifiedQuantity = null;
    this.quickInspectForm.unqualifiedQuantity = null;
    this.quickInspectVisible = true;
  },

  // 批量快速检验
  openBatchQuickInspectDialog(selection) {
    this.selectedInspects = selection;
    this.quickInspectForm.ids = selection.map(s => s.id);
    // 批量检验时,取第一条检验单的信息作为参考
    this.currentInspect = selection[0];
    // 抽检模式下自动填充
    if (this.currentInspect?.inspectRule === 1) {
      this.quickInspectForm.sampleQuantity = this.defaultSampleQuantity;
    }
    this.quickInspectVisible = true;
  },

  // 检测结果变化时自动调整数量
  onCheckResultChange(val) {
    if (val === '合格') {
      // 合格时,清空手动输入的数量
      this.quickInspectForm.qualifiedQuantity = null;
      this.quickInspectForm.unqualifiedQuantity = null;
    } else if (val === '不合格') {
      // 不合格时,默认全部不合格
      const qty = this.showSampleFields ? this.quickInspectForm.sampleQuantity : this.totalQuantity;
      this.quickInspectForm.qualifiedQuantity = 0;
      this.quickInspectForm.unqualifiedQuantity = qty;
    } else if (val === '部分合格') {
      // 部分合格时,需要用户手动输入
      this.quickInspectForm.qualifiedQuantity = null;
      this.quickInspectForm.unqualifiedQuantity = null;
    }
  },

  // 提交快速检验
  async submitQuickInspect() {
    // 校验必填字段
    if (!this.quickInspectForm.checkResult) {
      this.$message.warning('请选择检测结果');
      return;
    }
    if (!this.quickInspectForm.testStandardId) {
      this.$message.warning('请选择指标标准');
      return;
    }

    // 抽检模式下校验抽检数量
    if (this.showSampleFields && !this.quickInspectForm.sampleQuantity) {
      this.$message.warning('请输入抽检数量');
      return;
    }

    // 部分合格时校验数量
    if (this.quickInspectForm.checkResult === '部分合格') {
      if (!this.quickInspectForm.qualifiedQuantity && !this.quickInspectForm.unqualifiedQuantity) {
        this.$message.warning('请输入合格数量和不合格数量');
        return;
      }
      const total = this.showSampleFields
        ? this.quickInspectForm.sampleQuantity
        : this.totalQuantity;
      const sum = (this.quickInspectForm.qualifiedQuantity || 0) +
                  (this.quickInspectForm.unqualifiedQuantity || 0);
      if (sum > total) {
        this.$message.warning('合格数量+不合格数量不能超过检验数量');
        return;
      }
    }

    try {
      const res = await axios.post('/qualityInspect/batchQuickInspect', this.quickInspectForm);
      if (res.code === 200) {
        this.$message.success(res.msg);
        this.quickInspectVisible = false;
        this.refreshList();
      } else {
        this.$message.error(res.msg);
      }
    } catch (e) {
      this.$message.error('快速检验失败');
    }
  },
}

5. 检验单列表显示抽检信息

建议在检验单列表中增加以下列:

<el-table-column label="检验规则" width="100">
  <template #default="{ row }">
    <el-tag :type="row.inspectRule === 1 ? 'warning' : 'success'" size="small">
      {{ row.inspectRule === 1 ? '抽检' : '全检' }}
    </el-tag>
  </template>
</el-table-column>

<el-table-column label="抽检比例" width="100">
  <template #default="{ row }">
    {{ row.inspectRule === 1 ? (row.sampleRatio || 0) + '%' : '-' }}
  </template>
</el-table-column>

<el-table-column label="抽检数量" width="100">
  <template #default="{ row }">
    {{ row.inspectRule === 1 ? (row.sampleQuantity || '-') : row.quantity }}
  </template>
</el-table-column>

请求示例

全检模式

{
  "ids": [1, 2, 3],
  "checkResult": "合格",
  "testStandardId": 100,
  "checkName": "张三",
  "checkTime": "2026-06-18"
}

抽检模式 - 全部合格

{
  "ids": [4],
  "checkResult": "合格",
  "testStandardId": 100,
  "checkName": "张三",
  "checkTime": "2026-06-18",
  "sampleQuantity": 50
}

抽检模式 - 部分合格

{
  "ids": [5],
  "checkResult": "部分合格",
  "testStandardId": 100,
  "checkName": "张三",
  "checkTime": "2026-06-18",
  "sampleQuantity": 50,
  "qualifiedQuantity": 45,
  "unqualifiedQuantity": 5
}

注意事项

  • 批量快速检验时,如果选中的检验单有不同的检验规则(全检/抽检),建议提示用户分开处理,或前端按第一条检验单的模式统一处理。
  • 抽检数量由前端传入时,后端会校验不超过总数量,超出自动修正。
  • 抽检模式下,入库数量按抽检样本的合格数量计算,而非推算总量。
  • 如需在抽检模式下根据样本合格率推算总量入库比例,请另行提出需求。
  • 前端在打开弹窗时,应自动填充检验单已有的 sampleQuantity 或按比例计算的默认值,减少用户输入负担。