13 小时以前 6b2e46f69c234aa1d18fe8f3a77ede2baa674ce4
feat(mes): 更新种子质量检验功能

- 集成物料选择组件替换原有的物料ID输入框
- 添加不合格结果提交前的二次确认弹窗
- 在表单加载时禁用所有输入控件防止重复提交
- 更新验证提示信息将"物料ID"改为"选择物料"
- 优化库存流转说明展示不合格品处理逻辑
- 为表单项添加加载状态禁用属性提升用户体验
已修改1个文件
41 ■■■■ 文件已修改
src/views/mes/qc/seedQuality/index.vue 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/seedQuality/index.vue
@@ -1,9 +1,11 @@
<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue';
import { message } from 'ant-design-vue';
import { message, Modal } from 'ant-design-vue';
import { IconifyIcon } from '@vben/icons';
import { gsap } from 'gsap';
import MdItemSelect from '#/views/mes/md/item/components/select.vue';
import {
  submitSeedQuality,
@@ -61,7 +63,7 @@
async function submit() {
  if (!code.value.trim() || !itemId.value) {
    message.warning('请填写袋码和物料 ID');
    message.warning('请填写袋码并选择物料');
    return;
  }
  if (!allEntered.value) {
@@ -75,6 +77,21 @@
  if (!overallPassed.value && !reason.value.trim()) {
    message.warning('检验不合格时必须填写不合格原因');
    return;
  }
  if (!overallPassed.value) {
    const confirmed = await new Promise<boolean>((resolve) => {
      Modal.confirm({
        title: '确认提交不合格结果?',
        content: '不合格品将由后端从暂存库存中清除,并保留不合格原因用于质量分析。',
        okText: '确认提交',
        cancelText: '返回修改',
        okButtonProps: { danger: true },
        onOk: () => resolve(true),
        onCancel: () => resolve(false),
      });
    });
    if (!confirmed) return;
  }
  loading.value = true;
@@ -144,26 +161,28 @@
        <template #title><div class="card-title"><IconifyIcon icon="ep:edit-pen" />质检信息</div></template>
        <a-form layout="vertical">
          <div class="base-grid">
            <a-form-item label="袋码" required><a-input v-model:value="code" size="large" placeholder="请输入或扫描袋码" /></a-form-item>
            <a-form-item label="物料 ID" required><a-input-number v-model:value="itemId" class="full-width" size="large" :min="1" placeholder="请输入物料编号" /></a-form-item>
            <a-form-item label="生产批次"><a-input v-model:value="batchCode" size="large" placeholder="请输入批次号(选填)" /></a-form-item>
            <a-form-item label="袋码" required><a-input v-model:value="code" size="large" :disabled="loading" placeholder="请输入或扫描袋码" /></a-form-item>
            <a-form-item label="物料" required>
              <MdItemSelect v-model="itemId" :disabled="loading" size="large" placeholder="请选择物料" />
            </a-form-item>
            <a-form-item label="生产批次"><a-input v-model:value="batchCode" size="large" :disabled="loading" placeholder="请输入批次号(选填)" /></a-form-item>
          </div>
          <a-divider orientation="left">指标结果</a-divider>
          <div class="indicator-list">
            <div v-for="item in indicators" :key="item.code" class="indicator-row" :class="{ failed: !isPassed(item) }">
              <div class="indicator-name"><span class="indicator-dot" :class="isPassed(item) ? 'pass' : 'fail'" /><strong>{{ item.label }}</strong><small>{{ item.unit }}</small></div>
              <a-input-number v-model:value="item.value" class="indicator-input" :min="0" :precision="3" placeholder="实测值" />
              <a-input-number v-model:value="item.value" class="indicator-input" :disabled="loading" :min="0" :precision="3" placeholder="实测值" />
              <span class="range-separator">范围</span>
              <a-input-number v-model:value="item.minValue" class="range-input" :min="0" :precision="3" placeholder="下限" />
              <a-input-number v-model:value="item.minValue" class="range-input" :disabled="loading" :min="0" :precision="3" placeholder="下限" />
              <span>—</span>
              <a-input-number v-model:value="item.maxValue" class="range-input" :min="0" :precision="3" placeholder="上限" />
              <a-input-number v-model:value="item.maxValue" class="range-input" :disabled="loading" :min="0" :precision="3" placeholder="上限" />
              <a-tag :color="isPassed(item) ? 'success' : 'error'">{{ isPassed(item) ? '合格' : '超出范围' }}</a-tag>
            </div>
          </div>
          <a-form-item label="不合格原因" :required="!overallPassed" class="reason-item"><a-textarea v-model:value="reason" :rows="3" :maxlength="500" show-count :placeholder="overallPassed ? '合格结果无需填写' : '请说明不合格原因'" /></a-form-item>
          <div class="form-actions"><a-button @click="resetForm">重置</a-button><a-button type="primary" size="large" :loading="loading" @click="submit"><IconifyIcon icon="ep:upload-filled" />提交质检</a-button></div>
          <a-form-item label="不合格原因" :required="!overallPassed" class="reason-item"><a-textarea v-model:value="reason" :disabled="loading" :rows="3" :maxlength="500" show-count :placeholder="overallPassed ? '合格结果无需填写' : '请说明不合格原因'" /></a-form-item>
          <div class="form-actions"><a-button :disabled="loading" @click="resetForm">重置</a-button><a-button type="primary" size="large" :loading="loading" @click="submit"><IconifyIcon icon="ep:upload-filled" />提交质检</a-button></div>
        </a-form>
      </a-card>
@@ -171,7 +190,7 @@
        <template #title><div class="card-title"><IconifyIcon icon="ep:data-analysis" />判定说明</div></template>
        <div class="result-hero" :class="overallPassed ? 'passed' : allEntered ? 'failed-result' : 'pending-result'"><IconifyIcon :icon="overallPassed ? 'ep:circle-check-filled' : allEntered ? 'ep:warning-filled' : 'ep:edit-pen'" /><strong>{{ overallPassed ? '当前结果合格' : allEntered ? '当前存在不合格项' : '等待录入指标' }}</strong><span>{{ allEntered ? '实测值需处于最小值与最大值之间' : `已录入 ${enteredCount} / 4 项实测值` }}</span></div>
        <div class="rule-list"><div><IconifyIcon icon="ep:check" /><span>四项指标必须全部提交</span></div><div><IconifyIcon icon="ep:check" /><span>边界值按合格处理</span></div><div><IconifyIcon icon="ep:check" /><span>不合格结果需保留原因</span></div><div><IconifyIcon icon="ep:check" /><span>质检员与检验时间由服务端记录</span></div></div>
        <a-alert message="库存位置由后台配置解析" description="本页面只提交袋码、物料、批次和检验指标,不允许前端选择仓库、库区或库位。" type="info" show-icon />
        <a-alert message="库存流转由后端处理" description="合格品将从暂存库转入正式库存;不合格品将直接清除暂存库存并保留不合格原因。质检员和检验时间由服务端记录,本页面不选择仓库、库区或库位。" type="info" show-icon />
        <div v-if="submittedId" class="success-note"><IconifyIcon icon="ep:success-filled" /><span>最近提交质检编号:<strong>{{ submittedId }}</strong></span></div>
      </a-card>
    </section>