Files
client-web/src/modules/first-leg/components/ChargeableWeightDialog.vue
T
2026-10-20 11:54:44 +08:00

56 lines
2.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { onBeforeUnmount, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { getChargeableWeights, confirmChargeableWeight, type ChargeableWeight } from '../api/chargeableWeights'
const props = defineProps<{ orderId: string; canConfirm: boolean }>()
const emit = defineEmits<{ close: []; confirmed: [] }>()
const rows = ref<ChargeableWeight[]>([])
const loading = ref(false)
const saving = ref('')
const error = ref('')
const commands = new Map<string, string>()
let sequence = 0
let confirmationSequence = 0
async function load() {
const ticket = ++sequence
loading.value = true; error.value = ''; rows.value = []
try { const data = await getChargeableWeights(props.orderId); if (ticket === sequence) rows.value = data }
catch (e) { if (ticket === sequence) error.value = e instanceof Error ? e.message : '计费重加载失败' }
finally { if (ticket === sequence) loading.value = false }
}
async function confirm(row: ChargeableWeight) {
if (saving.value || !props.canConfirm) return
const ticket = sequence
const attempt = ++confirmationSequence
const fingerprint = `${row.inboundId}:${row.fingerprint}`
const key = commands.get(fingerprint) ?? `weight-${crypto.randomUUID()}`
commands.set(fingerprint, key); saving.value = row.inboundId; error.value = ''
try {
await confirmChargeableWeight(row, key)
if (ticket !== sequence) return
ElMessage.success('计费重已确认'); emit('confirmed'); await load()
} catch (e) { if (ticket === sequence) error.value = e instanceof Error ? e.message : '确认失败,请刷新后重试' }
finally { if (attempt === confirmationSequence) saving.value = '' }
}
watch(() => props.orderId, () => { confirmationSequence++; saving.value = ''; commands.clear(); void load() }, { immediate: true })
onBeforeUnmount(() => { sequence++; confirmationSequence++ })
</script>
<template>
<el-dialog :model-value="true" title="确认计费重" width="560px" :close-on-click-modal="false" @close="emit('close')">
<el-alert v-if="error" :title="error" type="error" :closable="false" />
<el-button v-if="error" :disabled="!!saving" @click="load">重新加载</el-button>
<div v-loading="loading">
<el-empty v-if="!loading && !error && !rows.length" description="暂无已审核的计费重" />
<div v-for="row in rows" :key="row.inboundId" class="weight-row">
<span>来源入仓单:{{ row.inboundId }}<br>计费重:{{ row.chargeableWeightKg }} kg</span>
<el-tag v-if="row.confirmed" type="success">已确认</el-tag>
<el-button v-else-if="canConfirm" type="primary" :disabled="!!saving" :loading="saving === row.inboundId" @click="confirm(row)">确认计费重</el-button>
<span v-else>待确认</span>
</div>
</div>
</el-dialog>
</template>
<style scoped>
.weight-row { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 12px 0; }
</style>