Jelajahi Sumber

feat(订单表单): 优化编辑模式下订单更新逻辑

yz 1 bulan lalu
induk
melakukan
02c5bcd443

+ 5 - 2
src/api/order/sales-order.js

@@ -4,8 +4,11 @@ import request from '@/router/axios'
 /**
  * @typedef {import('@/api/types/order').SalesOrderItemCreateForm} SalesOrderItemCreateForm
  * @typedef {import('@/api/types/order').SalesOrderCreateForm} SalesOrderCreateForm
+ * @typedef {import('@/api/types/order').SalesOrderUpdateForm} SalesOrderUpdateForm
+ * @typedef {import('@/api/types/order').SalesOrderItemUpdateForm} SalesOrderItemUpdateForm
  * @typedef {import('@/api/types/order').OrderOperationResponse} OrderOperationResponse
  * @typedef {import('@/api/types/order').SalesOrderCreateResponse} SalesOrderCreateResponse
+ * @typedef {import('@/api/types/order').SalesOrderUpdateResponse} SalesOrderUpdateResponse
  * @typedef {import('@/api/types/order').SubmitOrderToU9Request} SubmitOrderToU9Request
  * @typedef {import('@/api/types/order').SubmitOrderToU9Response} SubmitOrderToU9Response
  * @typedef {import('@/api/types/order').SalesOrderListQueryParams} SalesOrderListQueryParams
@@ -114,8 +117,8 @@ export const updateOrderItem = async (row) => {
 
 /**
  * 更新订单
- * @param {SalesOrderCreateForm} row - 订单数据
- * @returns {Promise<OrderOperationResponse>} 更新结果
+ * @param {SalesOrderUpdateForm} row - 订单数据
+ * @returns {Promise<SalesOrderUpdateResponse>} 更新结果
  */
 export const updateOrder = async (row) => {
   return request({

+ 22 - 0
src/api/types/order.d.ts

@@ -202,6 +202,28 @@ export type CustomerAddressListResponse = AxiosResponse<ApiResponseData<Customer
 export type SalesOrderCreateResponse = AxiosResponse<ApiResponseData<boolean>>;
 
 /**
+ * 销售订单更新表单接口(基于SalesOrderCreateForm,修正字段类型)
+ */
+export type SalesOrderUpdateForm = Omit<SalesOrderCreateForm, 'addressId' | 'customerId' | 'pcBladeOrderItemList'> & {
+  id: number;
+  addressId: number;
+  customerId: string;
+  pcBladeOrderItemList: SalesOrderItemUpdateForm[];
+};
+
+/**
+ * 销售订单明细更新表单接口(基于SalesOrderItemCreateForm,修正字段类型)
+ */
+export type SalesOrderItemUpdateForm = Omit<SalesOrderItemCreateForm, 'orderId'> & {
+  orderId: number;
+};
+
+/**
+ * 销售订单更新响应类型
+ */
+export type SalesOrderUpdateResponse = AxiosResponse<ApiResponseData<null>>;
+
+/**
  * 提交订单到U9系统请求参数接口
  */
 export interface SubmitOrderToU9Request {

+ 64 - 89
src/components/order-form/order-form-mixin.js

@@ -6,7 +6,7 @@
 // API接口导入
 import { add, update, getDetail } from '@/api/order/order'
 import { getList as getOrderItemList } from '@/api/order/order-item'
-import { createSalesOrder } from '@/api/order/sales-order'
+import { createSalesOrder, updateOrder } from '@/api/order/sales-order'
 import { getCustomerInfo } from '@/api/common/index'
 import { getList as getAddressList } from '@/api/order/address'
 
@@ -855,7 +855,7 @@ export default {
     /**
      * 处理表单保存操作
      * @description 验证表单数据并提交到服务器,支持新增和编辑模式
-     * 编辑模式下先保存订单数据,再批量保存物料明细数据
+     * 编辑模式下使用updateOrder方法一次性保存订单和物料明细数据
      * @returns {Promise<void>}
      * @throws {Error} 当表单验证失败或API调用失败时抛出异常
      * @public
@@ -882,11 +882,6 @@ export default {
         // 调用相应的API
         const response = await this.submitOrderData(submitData)
 
-        // 编辑模式下,保存订单数据后再批量保存物料明细
-        if (this.isEdit) {
-          await this.saveMaterialDetails()
-        }
-
         // 显示成功提示
         const successMessage = this.isEdit ? '订单更新成功' : '订单创建成功'
         this.$message.success(successMessage)
@@ -913,7 +908,7 @@ export default {
 
     /**
      * 提交订单数据到服务器
-     * @description 根据编辑模式调用相应的API接口,新建状态下使用createSalesOrder包含物料明细
+     * @description 根据编辑模式调用相应的API接口,编辑模式下使用updateOrder包含物料明细,新建状态下使用createSalesOrder包含物料明细
      * @param {OrderFormModel} submitData - 要提交的订单数据
      * @returns {Promise<import("@/api/types/order").SalesOrderCreateResponse>} API响应结果
      * @private
@@ -921,7 +916,9 @@ export default {
    */
   async submitOrderData(submitData) {
       if (this.isEdit) {
-        return await update(submitData)
+        // 编辑状态下使用updateOrder接口,包含物料明细数据
+        const salesOrderData = this.prepareSalesOrderUpdateData(submitData)
+        return await updateOrder(salesOrderData)
       } else {
         // 新建状态下使用createSalesOrder接口,包含物料明细数据
         const salesOrderData = this.prepareSalesOrderData(submitData)
@@ -982,6 +979,64 @@ export default {
     },
 
     /**
+     * 准备销售订单更新数据
+     * @description 将表单数据和物料明细数据组合为updateOrder接口所需的格式
+     * @param {OrderFormModel} formData - 表单数据
+     * @returns {import('@/api/types/order').SalesOrderUpdateForm} 销售订单更新数据
+     * @private
+     * @this {import('./types').OrderFormMixinComponent}
+     */
+    prepareSalesOrderUpdateData(formData) {
+      // 转换所有物料明细数据为API所需格式
+      const pcBladeOrderItemList = this.materialDetails.map(material => ({
+        id: material.id ? material.id : undefined, // 保持为字符串类型
+        orderId: formData.id || '', // 保持为字符串类型,避免大整数精度丢失
+        itemId: Number(material.itemId) || 0,
+        itemCode: material.itemCode || '',
+        itemName: material.itemName || '',
+        specs: material.specs || '',
+        mainItemCategoryId: Number(material.mainItemCategoryId) || Number(material.mainCategoryId) || 0,
+        mainItemCategoryName: material.mainItemCategoryName || material.mainCategoryName || '',
+        warehouseId: Number(material.warehouseId) || 0,
+        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 salesOrderUpdateData = {
+        id: formData.id, // 保持为字符串类型,避免大整数精度丢失
+        orderCode: formData.orderCode || '',
+        orgId: formData.orgId ? Number(formData.orgId) : 0,
+        orgCode: formData.orgCode || '',
+        orgName: formData.orgName || '',
+        customerId: Number(formData.customerId) || 0,
+        customerCode: formData.customerCode || '',
+        customerName: formData.customerName || '',
+        orderType: Number(formData.orderType) || 0,
+        orderQuantity: Number(formData.orderQuantity) || 0,
+        totalAmount: Number(formData.totalAmount) || 0,
+        totalQuantity: Number(formData.totalQuantity) || 0,
+        addressId: Number(formData.addressId) || 0,
+        receiverName: formData.receiverName || '',
+        receiverPhone: formData.receiverPhone || '',
+        receiverRegion: formData.receiverRegion || '',
+        receiverAddress: formData.receiverAddress || '',
+        status: formData.status,
+        remark: formData.remark || '',
+        pcBladeOrderItemList
+      }
+
+      return salesOrderUpdateData
+    },
+
+    /**
      * 验证表单数据
      * @description 使用AvueJS表单的验证功能验证所有字段
      * @returns {Promise<boolean>} 验证结果,true表示验证通过,false表示验证失败
@@ -1085,87 +1140,7 @@ export default {
       return /** @type {any} */ (cleanedData)
     },
 
-    /**
-     * 批量保存物料明细数据
-     * @description 编辑模式下,只保存通过导入获取的物料数据,使用新增接口
-     * @returns {Promise<void>}
-     * @throws {Error} 当物料明细保存失败时抛出异常
-     * @private
-     * @this {import('./types').OrderFormMixinComponent}
-     */
-    async saveMaterialDetails() {
-      if (!this.materialDetails || this.materialDetails.length === 0) {
-        return
-      }
-
-      // 过滤出通过导入获取的物料数据
-      const importedMaterials = this.materialDetails.filter(material =>
-        material.dataSource === MaterialDetailDataSource.IMPORTED
-      )
-
-      if (importedMaterials.length === 0) {
-        return
-      }
-
-      const { add: addOrderItem } = await import('@/api/order/order-item')
-      const savePromises = []
-      /** @type {Array<{ index: number, itemCode: string, error: Error }>} */
-      const failedItems = []
-
-      // 准备所有导入物料明细的保存请求
-      for (let i = 0; i < importedMaterials.length; i++) {
-        const material = importedMaterials[i]
-        const materialData = this.prepareMaterialItemData(material)
 
-        const savePromise = addOrderItem(materialData)
-          .catch(error => {
-            failedItems.push({ index: i + 1, itemCode: material.itemCode, error })
-            return null
-          })
-
-        savePromises.push(savePromise)
-      }
-
-      // 等待所有保存操作完成
-      await Promise.all(savePromises)
-
-      // 检查是否有失败的项目
-      if (failedItems.length > 0) {
-        const errorMessage = `导入物料明细保存失败:${failedItems.map(item => `第${item.index}条(${item.itemCode})`).join('、')}`
-        throw new Error(errorMessage)
-      }
-    },
-
-    /**
-     * 准备物料明细数据
-     * @description 将物料明细数据转换为API接口所需的格式,用于新增物料明细
-     * @param {MaterialDetailRecord} material - 物料明细数据
-     * @returns {SalesOrderItemCreateForm} 格式化后的物料明细数据
-     * @private
-     * @this {import('./types').OrderFormMixinComponent}
-     */
-    prepareMaterialItemData(material) {
-      return {
-        orderId: this.formData.id,
-        orderCode: this.formData.orderCode || '',
-        itemId: Number(material.itemId) || 0,
-        itemCode: material.itemCode || '',
-        itemName: material.itemName || '',
-        specs: material.specs || material.specification || '',
-        mainItemCategoryId: Number(material.mainItemCategoryId) || Number(material.mainCategoryId) || 0,
-        mainItemCategoryName: material.mainItemCategoryName || material.mainCategoryName || '',
-        warehouseId: Number(material.warehouseId) || 0,
-        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: ORDER_ITEM_STATUS.UNCONFIRMED,
-      }
-    },
 
     /**
      * 处理物料删除事件