|
@@ -6,7 +6,7 @@
|
|
|
// API接口导入
|
|
|
import { add, update as updateOrderHeader, getDetail } from '@/api/order/order'
|
|
|
import { getList as getOrderItemList } from '@/api/order/order-item'
|
|
|
-import { createSalesOrder, updateOrder, addOrderItem } from '@/api/order/sales-order'
|
|
|
+import { createSalesOrder, updateOrder, addOrderItem, updateOrderItem } from '@/api/order/sales-order'
|
|
|
import { getCustomerInfo } from '@/api/common/index'
|
|
|
import { getList as getAddressList } from '@/api/order/address'
|
|
|
import { submitOrderToU9 } from '@/api/order/sales-order'
|
|
@@ -158,6 +158,13 @@ export default {
|
|
|
materialDetails: [],
|
|
|
|
|
|
/**
|
|
|
+ * 远程明细原始快照映射
|
|
|
+ * @description 记录从服务器加载的远程物料明细的原始值,用于草稿状态下的变更对比
|
|
|
+ * @type {Record<string, {orderQuantity:number, confirmQuantity:number, unitPrice:number, taxRate:number}>}
|
|
|
+ */
|
|
|
+ originalRemoteDetailsById: {},
|
|
|
+
|
|
|
+ /**
|
|
|
* 订单类型选项列表
|
|
|
* @description 订单类型下拉选择器的选项数据
|
|
|
* @type {typeof ORDER_TYPE_OPTIONS}
|
|
@@ -440,6 +447,16 @@ export default {
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否为草稿状态
|
|
|
+ * @description 根据订单状态判断是否为草稿
|
|
|
+ * @returns {boolean}
|
|
|
+ */
|
|
|
+ isDraft() {
|
|
|
+ const status = Number(this.formData && this.formData.status)
|
|
|
+ return status === ORDER_STATUS.DRAFT
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -681,6 +698,9 @@ export default {
|
|
|
// 设置物料明细数据(确保是数组类型)
|
|
|
this.materialDetails = Array.isArray(materialResponse) ? materialResponse : []
|
|
|
|
|
|
+ // 新增:建立远程明细原始快照,用于后续对比并持久化更新
|
|
|
+ this.originalRemoteDetailsById = this.buildOriginalRemoteSnapshot(this.materialDetails)
|
|
|
+
|
|
|
console.log(`成功加载订单详情,订单编码: ${orderData.orderCode || orderId}`)
|
|
|
|
|
|
} catch (error) {
|
|
@@ -803,6 +823,52 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ // 构建远程明细原始快照
|
|
|
+ buildOriginalRemoteSnapshot(materials) {
|
|
|
+ const map = {}
|
|
|
+ try {
|
|
|
+ (materials || [])
|
|
|
+ .filter(m => m && m.dataSource === MaterialDetailDataSource.REMOTE)
|
|
|
+ .forEach(m => {
|
|
|
+ const key = String(m.id || m.itemId || m.itemCode || '')
|
|
|
+ if (!key) return
|
|
|
+ map[key] = {
|
|
|
+ orderQuantity: Math.round(Number(m.orderQuantity) || 0),
|
|
|
+ confirmQuantity: Math.round(Number(m.confirmQuantity) || 0),
|
|
|
+ unitPrice: preciseRound(Number(m.unitPrice) || 0, 2),
|
|
|
+ taxRate: preciseRound(Number(m.taxRate) || 0, 4)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } catch (e) {
|
|
|
+ // eslint-disable-next-line no-console
|
|
|
+ console.warn('构建原始快照失败:', e)
|
|
|
+ }
|
|
|
+ return map
|
|
|
+ },
|
|
|
+
|
|
|
+ // 判断远程明细是否发生变化(与原始快照对比)
|
|
|
+ hasRemoteMaterialChanged(currentRow) {
|
|
|
+ if (!currentRow) return false
|
|
|
+ const key = String(currentRow.id || currentRow.itemId || currentRow.itemCode || '')
|
|
|
+ if (!key) return false
|
|
|
+ const original = this.originalRemoteDetailsById && this.originalRemoteDetailsById[key]
|
|
|
+ if (!original) return false
|
|
|
+
|
|
|
+ const curr = {
|
|
|
+ orderQuantity: Math.round(Number(currentRow.orderQuantity) || 0),
|
|
|
+ confirmQuantity: Math.round(Number(currentRow.confirmQuantity) || 0),
|
|
|
+ unitPrice: preciseRound(Number(currentRow.unitPrice) || 0, 2),
|
|
|
+ taxRate: preciseRound(Number(currentRow.taxRate) || 0, 4)
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ curr.orderQuantity !== original.orderQuantity ||
|
|
|
+ curr.confirmQuantity !== original.confirmQuantity ||
|
|
|
+ curr.unitPrice !== original.unitPrice ||
|
|
|
+ curr.taxRate !== original.taxRate
|
|
|
+ )
|
|
|
+ },
|
|
|
+
|
|
|
/**
|
|
|
* 映射订单数据到表单格式
|
|
|
* @description 将API返回的订单数据安全地映射为表单数据格式,并格式化数字字段
|
|
@@ -1001,7 +1067,7 @@ export default {
|
|
|
*/
|
|
|
async submitOrderData(submitData) {
|
|
|
if (this.isEdit) {
|
|
|
- // 编辑状态下:先仅更新订单基础信息(不包含物料明细),再单独添加“导入”的物料
|
|
|
+ // 编辑状态下:先仅更新订单基础信息(不包含物料明细),再单独处理导入新增与远程变更
|
|
|
// 第一步:更新订单头
|
|
|
const headerData = this.prepareSubmitData()
|
|
|
const headerResponse = await updateOrderHeader(headerData)
|
|
@@ -1018,7 +1084,7 @@ export default {
|
|
|
const orderCode = (this.formData && this.formData.orderCode) || ''
|
|
|
|
|
|
const payloads = importedMaterials.map(material => ({
|
|
|
- orderId: String(orderId), // 以字符串传输,避免大整数精度问题
|
|
|
+ orderId: String(orderId),
|
|
|
orderCode,
|
|
|
itemId: String(material.itemId || ''),
|
|
|
itemCode: material.itemCode || '',
|
|
@@ -1045,7 +1111,48 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 两步均成功,返回头部更新的响应
|
|
|
+ // 第三步:草稿状态下,找出远程明细的变更并调用 updateOrderItem 持久化
|
|
|
+ if (this.isDraft) {
|
|
|
+ const orderId = (this.formData && this.formData.id) || this.orderId
|
|
|
+ const remoteChanged = (this.materialDetails || [])
|
|
|
+ .filter(m => m.dataSource === MaterialDetailDataSource.REMOTE)
|
|
|
+ .filter(m => this.hasRemoteMaterialChanged(m))
|
|
|
+
|
|
|
+ if (remoteChanged.length > 0) {
|
|
|
+ const updatePayloads = remoteChanged.map(material => ({
|
|
|
+ id: String(material.id || ''),
|
|
|
+ orderId: String(orderId || ''),
|
|
|
+ orderCode: (this.formData && this.formData.orderCode) || '',
|
|
|
+ itemId: String(material.itemId || ''),
|
|
|
+ itemCode: material.itemCode || '',
|
|
|
+ itemName: material.itemName || '',
|
|
|
+ specs: material.specs || '',
|
|
|
+ mainItemCategoryId: String(material.mainItemCategoryId || ''),
|
|
|
+ mainItemCategoryName: material.mainItemCategoryName || '',
|
|
|
+ warehouseId: String(material.warehouseId || ''),
|
|
|
+ warehouseName: material.warehouseName || '',
|
|
|
+ availableQuantity: Number(material.availableQuantity) || 0,
|
|
|
+ orderQuantity: Number(material.orderQuantity) || 0,
|
|
|
+ confirmQuantity: Number(material.confirmQuantity) || Number(material.orderQuantity) || 0,
|
|
|
+ unitPrice: Number(material.unitPrice) || 0,
|
|
|
+ taxRate: Number(material.taxRate) || 0,
|
|
|
+ taxAmount: Number(material.taxAmount) || 0,
|
|
|
+ totalAmount: Number(material.totalAmount) || 0,
|
|
|
+ itemStatus: material.itemStatus || ORDER_ITEM_STATUS.UNCONFIRMED
|
|
|
+ }))
|
|
|
+
|
|
|
+ const updateResults = await Promise.all(updatePayloads.map(p => updateOrderItem(p)))
|
|
|
+ const updatesOk = updateResults.every(r => r && r.data && r.data.success)
|
|
|
+ if (!updatesOk) {
|
|
|
+ throw new Error('部分物料更新失败')
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新成功后,刷新原始快照,避免后续重复提交
|
|
|
+ this.originalRemoteDetailsById = this.buildOriginalRemoteSnapshot(this.materialDetails)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回头部更新的响应
|
|
|
return headerResponse
|
|
|
} else {
|
|
|
// 新建状态下使用createSalesOrder接口,包含物料明细数据
|