| | |
| | | import { |
| | | resolveSeedQuality, |
| | | submitSeedQualityGroup, |
| | | getSeedIndicatorRanges, |
| | | } from '#/api/mes/qc/seedQuality'; |
| | | import { getWarehouseSimpleList } from '#/api/mes/wm/warehouse'; |
| | | |
| | |
| | | { code: 'germination_rate', label: '发芽率', unit: '%' }, |
| | | { code: 'moisture', label: '水分', unit: '%' }, |
| | | ]); |
| | | const rangesReady = computed(() => indicators.value.every((item) => |
| | | item.minValue !== undefined && item.maxValue !== undefined)); |
| | | |
| | | async function loadRanges() { |
| | | const ranges = await getSeedIndicatorRanges(); |
| | | for (const item of indicators.value) { |
| | | const range = ranges.find((row) => row.indicatorCode === item.code); |
| | | item.minValue = range?.minValue === undefined ? undefined : Number(range.minValue); |
| | | item.maxValue = range?.maxValue === undefined ? undefined : Number(range.maxValue); |
| | | } |
| | | } |
| | | |
| | | const pendingCount = computed(() => target.value?.pendingBagIds?.length ?? 0); |
| | | const completedCount = computed(() => target.value?.completedBagIds?.length ?? 0); |
| | |
| | | reason.value = ''; |
| | | indicators.value.forEach((item) => { |
| | | item.value = undefined; |
| | | item.minValue = undefined; |
| | | item.maxValue = undefined; |
| | | }); |
| | | } |
| | | |
| | |
| | | resolving.value = true; |
| | | submittedCount.value = undefined; |
| | | try { |
| | | await loadRanges().catch(() => undefined); |
| | | const data = await resolveSeedQuality(value, scanType.value); |
| | | if (data.canceled) { |
| | | target.value = undefined; |
| | |
| | | return; |
| | | } |
| | | if (!allEntered.value) { |
| | | message.warning('请填写四项指标的实测值及合格上下限'); |
| | | message.warning('请填写四项指标的实测值和本次合格上下限'); |
| | | return; |
| | | } |
| | | if (indicators.value.some((item) => item.minValue === undefined || item.maxValue === undefined || item.minValue > item.maxValue)) { |
| | |
| | | Modal.confirm({ |
| | | title: overallPassed.value ? '确认提交合格结果?' : '确认提交不合格结果?', |
| | | content: overallPassed.value |
| | | ? `本次 ${count} 袋将统一记录为初检合格,待加工部和公司质检审批后才转入合格库。${scopeNote}` |
| | | : `本次 ${count} 袋将记录为初检不合格,保留暂存库存并等待复检。${scopeNote}`, |
| | | ? `本次 ${count} 袋将统一记录为初检合格,待初检审核通过后复检;复检审核通过后才转入合格库。${scopeNote}` |
| | | : `本次 ${count} 袋将记录为初检不合格,保留暂存库存;初检审核后决定是否进入复检。${scopeNote}`, |
| | | okText: '确认提交', |
| | | cancelText: '返回修改', |
| | | okButtonProps: { danger: !overallPassed.value }, |
| | |
| | | })), |
| | | }); |
| | | submittedCount.value = result.processedCount; |
| | | message.success(`本次 ${result.processedCount} 袋已提交:${passed ? '初检合格,待两级审批' : '初检不合格,待复检'}`); |
| | | message.success(`本次 ${result.processedCount} 袋已提交初检,待初检审核`); |
| | | if (pageRoot.value && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) { |
| | | gsap.fromTo('.result-card', { scale: 0.97, autoAlpha: 0.5 }, { scale: 1, autoAlpha: 1, duration: 0.35, ease: 'power2.out' }); |
| | | } |
| | |
| | | } |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | await loadRanges(); |
| | | } catch (error) { |
| | | message.error(errorText(error)); |
| | | } |
| | | try { |
| | | const warehouses = await getWarehouseSimpleList(); |
| | | qualifiedWarehouses.value = (warehouses ?? []).filter( |
| | |
| | | <div> |
| | | <div class="eyebrow">MES / 质量管理</div> |
| | | <h1>种子质检</h1> |
| | | <p>识别待检范围并录入四项指标;合格经加工部与公司质检审批后入库,不合格先复检</p> |
| | | <p>识别待检范围并录入四项指标;初检审核后复检,复检审核后入库或处置</p> |
| | | </div> |
| | | <div class="header-badge"><IconifyIcon icon="ep:checked" /> 袋码 / 托盘码 / 批次码</div> |
| | | </header> |
| | |
| | | </a-form-item> |
| | | </div> |
| | | <p v-if="!qualifiedWarehouses.length" class="target-warning">暂无可用合格库,请联系管理员配置后再提交质检。</p> |
| | | <a-alert v-if="!rangesReady" class="target-empty" type="info" show-icon message="本次请手动填写合格范围" description="管理员尚未配置完整默认范围;仍可手动填写四项指标的合格上下限。" /> |
| | | |
| | | <a-divider orientation="left">指标结果</a-divider> |
| | | <div class="indicator-list"> |
| | |
| | | <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" :disabled="loading" :min="0" :precision="3" placeholder="实测值" /> |
| | | <span class="range-separator">范围</span> |
| | | <a-input-number v-model:value="item.minValue" class="range-input" :disabled="loading" :min="0" :precision="3" placeholder="下限" /> |
| | | <a-input-number v-model:value="item.minValue" class="range-input" :disabled="loading" :min="0" :max="100" :precision="3" placeholder="下限" /> |
| | | <span>—</span> |
| | | <a-input-number v-model:value="item.maxValue" class="range-input" :disabled="loading" :min="0" :precision="3" placeholder="上限" /> |
| | | <a-input-number v-model:value="item.maxValue" class="range-input" :disabled="loading" :min="0" :max="100" :precision="3" placeholder="上限" /> |
| | | <a-tag :color="!allEntered ? 'default' : isPassed(item) ? 'success' : 'error'">{{ !allEntered ? '待录入' : isPassed(item) ? '合格' : '超出范围' }}</a-tag> |
| | | </div> |
| | | </div> |
| | |
| | | <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><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="submittedCount" class="success-note"><IconifyIcon icon="ep:success-filled" /><span>最近提交质检:<strong>{{ submittedCount }} 袋</strong></span></div> |
| | | </a-card> |
| | | </section> |