<script setup lang="ts">
|
import type { TraceResult } from '#/utils/traceLookup';
|
|
import { computed, ref } from 'vue';
|
|
import { Button } from 'ant-design-vue';
|
|
import { lookupTrace } from '#/utils/traceLookup';
|
|
import TraceScanInput from './TraceScanInput.vue';
|
|
/**
|
* 追溯二维码扫码核对面板。
|
*
|
* 扫码后只解析对象并展示核对信息,点击「确认带入」才由页面执行写入。
|
*/
|
const props = withDefaults(
|
defineProps<{
|
disabled?: boolean;
|
title?: string;
|
}>(),
|
{
|
disabled: false,
|
title: '扫码带出',
|
},
|
);
|
|
const emit = defineEmits<{ confirm: [trace: TraceResult] }>();
|
|
const busy = ref(false);
|
const error = ref('');
|
const trace = ref<TraceResult>();
|
|
const typeLabel = computed(() =>
|
trace.value
|
? ({ bag: '袋码', batch: '批次码', pallet: '托盘码' } as const)[
|
trace.value.type
|
]
|
: '',
|
);
|
|
const quantity = computed(() => {
|
if (!trace.value) return '';
|
if (trace.value.type === 'bag') return '1';
|
if (trace.value.type === 'pallet') return trace.value.data.bagCount ?? '';
|
return trace.value.data.bagQuantity ?? '';
|
});
|
|
async function identify(code: string) {
|
if (props.disabled || busy.value) return;
|
busy.value = true;
|
error.value = '';
|
trace.value = undefined;
|
try {
|
trace.value = await lookupTrace(code);
|
} catch (e) {
|
error.value = e instanceof Error ? e.message : '追溯码识别失败';
|
} finally {
|
busy.value = false;
|
}
|
}
|
|
function confirm() {
|
if (!trace.value) return;
|
emit('confirm', trace.value);
|
trace.value = undefined;
|
}
|
|
function cancel() {
|
trace.value = undefined;
|
error.value = '';
|
}
|
</script>
|
|
<template>
|
<section class="mb-3 rounded-lg border border-border p-3">
|
<h3 class="mb-2 text-sm font-semibold">{{ title }}</h3>
|
<TraceScanInput
|
v-if="!trace"
|
:disabled="disabled || busy"
|
@code="identify"
|
/>
|
<div v-else class="space-y-1 text-sm">
|
<p>
|
<span class="text-muted-foreground">码类型:</span>{{ typeLabel }}
|
<span class="ml-4 text-muted-foreground">码值:</span>{{ trace.code }}
|
</p>
|
<p>
|
<span class="text-muted-foreground">品种:</span
|
>{{ trace.data.itemName || '未录入' }}
|
<span class="ml-4 text-muted-foreground">批次:</span
|
>{{ trace.data.batchCode || '未绑定' }}
|
</p>
|
<p>
|
<span class="text-muted-foreground">可带入数量:</span
|
>{{ quantity || '—' }}
|
</p>
|
<div class="flex gap-2 pt-1">
|
<Button type="primary" :disabled="disabled || busy" @click="confirm">
|
确认带入
|
</Button>
|
<Button :disabled="busy" @click="cancel">取消本次扫码</Button>
|
</div>
|
</div>
|
<p v-if="error" class="mt-1 text-red-600" role="alert">{{ error }}</p>
|
</section>
|
</template>
|