Files
shanxia2.0/web-admin/src/composables/usePlFreightCalc.ts
T
2026-08-27 14:23:18 +08:00

117 lines
3.1 KiB
TypeScript

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<FreightCalcProductRow[]>
hasFreight: Ref<number>
freightType: Ref<string>
}) {
const transportQty = ref<number | null>(null)
const transportQtyTouched = ref(false)
const freightAmount = ref<number | null>(null)
const freightAmountTouched = ref(false)
const freightPrice = ref<number | null>(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
}
}