fix(wms): 完善单据状态保护与金额精度处理

- 后端补充商品、往来企业唯一性校验
- 单据更新改为按草稿状态条件更新,避免覆盖已完成单据
- 补充 WMS 金额、规格精度迁移 SQL 与测试表结构
- 前端统一明细金额兜底计算,优化完成/作废取消处理
pull/878/head
YunaiV 2026-05-15 19:48:33 +08:00
parent 50cfbfe58b
commit b3bb1114ba
10 changed files with 29 additions and 42 deletions

View File

@ -628,6 +628,8 @@ const handleComplete = async () => {
message.success('盘库成功') message.success('盘库成功')
dialogVisible.value = false dialogVisible.value = false
emit('success') emit('success')
} catch {
//
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
@ -642,6 +644,8 @@ const handleCancel = async () => {
message.success('作废成功') message.success('作废成功')
dialogVisible.value = false dialogVisible.value = false
emit('success') emit('success')
} catch {
//
} finally { } finally {
formLoading.value = false formLoading.value = false
} }

View File

@ -86,7 +86,8 @@ import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
formatSumPrice, formatSumPrice,
formatSumQuantity formatSumQuantity,
multiplyPrice
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
/** WMS 移库单详情 */ /** WMS 移库单详情 */
@ -103,11 +104,7 @@ interface DetailRow extends MovementOrderDetailVO {
const detailRows = computed<DetailRow[]>(() => const detailRows = computed<DetailRow[]>(() =>
(detailData.value.details || []).map((detail) => ({ (detailData.value.details || []).map((detail) => ({
...detail, ...detail,
totalPrice: totalPrice: detail.totalPrice ?? multiplyPrice(detail.quantity, detail.price)
detail.totalPrice ??
(detail.price != null && detail.quantity
? Number(detail.price) * Number(detail.quantity)
: undefined)
})) }))
) )

View File

@ -466,6 +466,8 @@ const handleComplete = async () => {
message.success('移库成功') message.success('移库成功')
dialogVisible.value = false dialogVisible.value = false
emit('success') emit('success')
} catch {
//
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
@ -480,6 +482,8 @@ const handleCancel = async () => {
message.success('作废成功') message.success('作废成功')
dialogVisible.value = false dialogVisible.value = false
emit('success') emit('success')
} catch {
//
} finally { } finally {
formLoading.value = false formLoading.value = false
} }

View File

@ -367,6 +367,7 @@ import {
import { import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
multiplyPrice,
PRICE_PRECISION, PRICE_PRECISION,
QUANTITY_PRECISION QUANTITY_PRECISION
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
@ -502,10 +503,7 @@ const getDetailTotalPrice = (detail: MovementOrderDetailVO) => {
if (detail.totalPrice !== undefined && detail.totalPrice !== null) { if (detail.totalPrice !== undefined && detail.totalPrice !== null) {
return detail.totalPrice return detail.totalPrice
} }
if (!detail.quantity || detail.price === undefined || detail.price === null) { return multiplyPrice(detail.quantity, detail.price)
return undefined
}
return Number(detail.quantity) * Number(detail.price)
} }
/** 展开明细 */ /** 展开明细 */

View File

@ -104,7 +104,8 @@ import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
formatSumPrice, formatSumPrice,
formatSumQuantity formatSumQuantity,
multiplyPrice
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
/** WMS 入库单详情 */ /** WMS 入库单详情 */
@ -120,11 +121,7 @@ const detailData = ref<ReceiptOrderVO>({}) // 详情数据
const detailRows = computed<DetailRow[]>(() => const detailRows = computed<DetailRow[]>(() =>
(detailData.value.details || []).map((detail) => ({ (detailData.value.details || []).map((detail) => ({
...detail, ...detail,
totalPrice: totalPrice: detail.totalPrice ?? multiplyPrice(detail.quantity, detail.price)
detail.totalPrice ??
(detail.price != null && detail.quantity
? Number(detail.price) * Number(detail.quantity)
: undefined)
})) }))
) )

View File

@ -103,7 +103,8 @@ import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
formatSumPrice, formatSumPrice,
formatSumQuantity formatSumQuantity,
multiplyPrice
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
import Barcode from '@/views/mes/wm/barcode/components/Barcode.vue' import Barcode from '@/views/mes/wm/barcode/components/Barcode.vue'
import { BarcodeFormatEnum } from '@/views/mes/utils/constants' import { BarcodeFormatEnum } from '@/views/mes/utils/constants'
@ -129,11 +130,7 @@ interface PrintRow extends ReceiptOrderDetailVO {
const printRows = computed<PrintRow[]>(() => const printRows = computed<PrintRow[]>(() =>
(printData.value.details || []).map((detail) => ({ (printData.value.details || []).map((detail) => ({
...detail, ...detail,
totalPrice: totalPrice: detail.totalPrice ?? multiplyPrice(detail.quantity, detail.price)
detail.totalPrice ??
(detail.price != null && detail.quantity
? Number((Number(detail.price) * Number(detail.quantity)).toFixed(2))
: undefined)
})) }))
) )

View File

@ -414,6 +414,7 @@ import {
import { import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
multiplyPrice,
PRICE_PRECISION, PRICE_PRECISION,
QUANTITY_PRECISION QUANTITY_PRECISION
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
@ -559,10 +560,7 @@ const getDetailTotalPrice = (detail: ReceiptOrderDetailVO) => {
if (detail.totalPrice !== undefined && detail.totalPrice !== null) { if (detail.totalPrice !== undefined && detail.totalPrice !== null) {
return detail.totalPrice return detail.totalPrice
} }
if (!detail.quantity || detail.price === undefined || detail.price === null) { return multiplyPrice(detail.quantity, detail.price)
return undefined
}
return Number(detail.quantity) * Number(detail.price)
} }
/** 展开明细 */ /** 展开明细 */

View File

@ -104,7 +104,8 @@ import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
formatSumPrice, formatSumPrice,
formatSumQuantity formatSumQuantity,
multiplyPrice
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
/** WMS 出库单详情 */ /** WMS 出库单详情 */
@ -120,11 +121,7 @@ const detailData = ref<ShipmentOrderVO>({}) // 详情数据
const detailRows = computed<DetailRow[]>(() => const detailRows = computed<DetailRow[]>(() =>
(detailData.value.details || []).map((detail) => ({ (detailData.value.details || []).map((detail) => ({
...detail, ...detail,
totalPrice: totalPrice: detail.totalPrice ?? multiplyPrice(detail.quantity, detail.price)
detail.totalPrice ??
(detail.price != null && detail.quantity
? Number(detail.price) * Number(detail.quantity)
: undefined)
})) }))
) )

View File

@ -103,7 +103,8 @@ import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
formatSumPrice, formatSumPrice,
formatSumQuantity formatSumQuantity,
multiplyPrice
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
import Barcode from '@/views/mes/wm/barcode/components/Barcode.vue' import Barcode from '@/views/mes/wm/barcode/components/Barcode.vue'
import { BarcodeFormatEnum } from '@/views/mes/utils/constants' import { BarcodeFormatEnum } from '@/views/mes/utils/constants'
@ -129,11 +130,7 @@ interface PrintRow extends ShipmentOrderDetailVO {
const printRows = computed<PrintRow[]>(() => const printRows = computed<PrintRow[]>(() =>
(printData.value.details || []).map((detail) => ({ (printData.value.details || []).map((detail) => ({
...detail, ...detail,
totalPrice: totalPrice: detail.totalPrice ?? multiplyPrice(detail.quantity, detail.price)
detail.totalPrice ??
(detail.price != null && detail.quantity
? Number((Number(detail.price) * Number(detail.quantity)).toFixed(2))
: undefined)
})) }))
) )

View File

@ -414,6 +414,7 @@ import {
import { import {
formatPrice, formatPrice,
formatQuantity, formatQuantity,
multiplyPrice,
PRICE_PRECISION, PRICE_PRECISION,
QUANTITY_PRECISION QUANTITY_PRECISION
} from '@/views/wms/utils/format' } from '@/views/wms/utils/format'
@ -559,10 +560,7 @@ const getDetailTotalPrice = (detail: ShipmentOrderDetailVO) => {
if (detail.totalPrice !== undefined && detail.totalPrice !== null) { if (detail.totalPrice !== undefined && detail.totalPrice !== null) {
return detail.totalPrice return detail.totalPrice
} }
if (!detail.quantity || detail.price === undefined || detail.price === null) { return multiplyPrice(detail.quantity, detail.price)
return undefined
}
return Number(detail.quantity) * Number(detail.price)
} }
/** 展开明细 */ /** 展开明细 */