22 lines
1.8 KiB
Vue
22 lines
1.8 KiB
Vue
<script setup lang="ts">
|
||
import { ref, watch, onBeforeUnmount } from 'vue'
|
||
import { listTripDispatchCandidates, type DispatchCandidate } from '../api/trips'
|
||
import { getApiErrorDetails } from '@/shared/api/http'
|
||
const value = defineModel<string>({ default: '' })
|
||
const props = defineProps<{ tripNo: string; disabled?: boolean }>()
|
||
const rows = ref<DispatchCandidate[]>([]), loading = ref(false), error = ref(''), total = ref(0)
|
||
let sequence = 0, timer: ReturnType<typeof setTimeout> | undefined
|
||
function search(keyword = '') {
|
||
clearTimeout(timer); const current = ++sequence
|
||
timer = setTimeout(async () => {
|
||
loading.value = true; error.value = ''
|
||
try { const result = await listTripDispatchCandidates(props.tripNo, keyword.trim() || undefined); if (current === sequence) { rows.value = result.records; total.value = result.total } }
|
||
catch (cause) { if (current === sequence) { rows.value = []; error.value = getApiErrorDetails(cause, '待运货物加载失败').message } }
|
||
finally { if (current === sequence) loading.value = false }
|
||
}, 250)
|
||
}
|
||
watch(() => props.tripNo, () => { sequence++; clearTimeout(timer); rows.value = []; value.value = ''; loading.value = false })
|
||
onBeforeUnmount(() => { sequence++; clearTimeout(timer) })
|
||
</script>
|
||
<template><div><el-select v-model="value" aria-label="选择本仓待运排车单" filterable remote :remote-method="search" :loading="loading" :disabled="disabled" placeholder="按排车单号或目的地搜索" @focus="search()"><el-option v-for="row in rows" :key="row.dispatchNo" :label="`${row.dispatchNo} · ${row.route || '路线待核对'} · ${row.packageCount}箱`" :value="row.dispatchNo" /></el-select><p v-if="error" role="alert">{{ error }} <el-button link @click="search()">重试</el-button></p><small v-if="total > rows.length">候选较多,请输入排车单号缩小范围。</small></div></template>
|