import { computed, ref, watch, type Ref } from 'vue' import { useDictStore } from '@/store/modules/dict' import { getProductUnitLabel } from '@/utils/crm-product-display' export interface FreightCalcProductRow { quantity?: number | null actualQty?: number | null unit?: string | null } export function sumProductActualQuantities(products: FreightCalcProductRow[]) { return products.reduce((sum, row) => { const actual = row.actualQty if (actual != null && !Number.isNaN(Number(actual))) { return sum + Number(actual) } return sum }, 0) } /** @deprecated 使用 sumProductActualQuantities */ export function sumProductQuantities(products: FreightCalcProductRow[]) { return sumProductActualQuantities(products) } export function resolveFreightUnitLabel(products: FreightCalcProductRow[]) { const units = products.map(row => row.unit).filter(Boolean) as string[] if (!units.length) return '吨' const dictStore = useDictStore() return getProductUnitLabel(dictStore.getLabel.bind(dictStore), units[0]) } export function usePlFreightCalc(options: { products: Ref hasFreight: Ref freightType: Ref }) { const transportQty = ref(null) const transportQtyTouched = ref(false) const freightAmount = ref(null) const freightAmountTouched = ref(false) const freightPrice = ref(null) const defaultTransportQty = computed(() => sumProductActualQuantities(options.products.value)) watch( () => options.products.value, () => { if (!transportQtyTouched.value) { transportQty.value = defaultTransportQty.value || null } }, { deep: true, immediate: true } ) const calculatedFreight = computed(() => { if (!options.hasFreight.value) return 0 if (options.freightType.value === 'by_trip') { return Number(freightAmount.value || 0) } const qty = Number(transportQty.value || 0) const price = Number(freightPrice.value || 0) return qty * price }) watch(calculatedFreight, val => { if (options.freightType.value === 'by_weight' && !freightAmountTouched.value) { freightAmount.value = val > 0 ? val : null } }) watch([transportQty, freightPrice], () => { if (options.freightType.value === 'by_weight' && options.hasFreight.value) { freightAmountTouched.value = false } }) watch( () => options.freightType.value, type => { freightAmountTouched.value = false if (type === 'by_trip') { freightPrice.value = null } } ) function resetFreightCalc() { transportQty.value = null transportQtyTouched.value = false freightAmount.value = null freightAmountTouched.value = false freightPrice.value = null } function markTransportQtyTouched() { transportQtyTouched.value = true } function markFreightAmountTouched() { freightAmountTouched.value = true } return { transportQty, transportQtyTouched, freightPrice, freightAmount, freightAmountTouched, defaultTransportQty, calculatedFreight, resetFreightCalc, markTransportQtyTouched, markFreightAmountTouched } }