117 lines
3.1 KiB
TypeScript
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
|
|
}
|
|
}
|