Forráskód Böngészése

refactor(order-form): 优化类型定义和表单数据处理逻辑

yz 3 hete
szülő
commit
5405866036

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

@@ -46,7 +46,7 @@ export const add = async (row) => {
 
 /**
  * 更新订单
- * @param {OrderForm} row - 订单表单数据
+ * @param {import('@/components/order-form/types').OrderFormModel} row - 订单表单数据
  * @returns {Promise<OrderOperationResponse>}
  */
 export const update = async (row) => {
@@ -83,4 +83,4 @@ export const getCustomerAddressList = async (customerCode) => {
       size: 100
     }
   })
-}
+}

+ 3 - 3
src/api/types/order-item.d.ts

@@ -2,8 +2,8 @@ import { ORDER_ITEM_STATUS } from '@/constants';
 import { AxiosResponse } from 'axios';
 import { BaseEntity, BaseQueryParams, PageResult, ApiResponseData } from './order';
 
-// export type OrderItemStatus = keyof typeof ORDER_ITEM_STATUS;
-export type OrderItemStatus = 'PENDING' | 'CONFIRMED' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED';
+export type OrderItemStatus = (typeof ORDER_ITEM_STATUS)[keyof typeof ORDER_ITEM_STATUS];
+// export type OrderItemStatus = 'PENDING' | 'CONFIRMED' | 'SHIPPED' | 'DELIVERED' | 'CANCELLED';
 
 export interface OrderItemQueryParams extends BaseQueryParams {
   orderId: string | number;
@@ -66,4 +66,4 @@ export type OrderItemListResponse = AxiosResponse<ApiResponseData<PageResult<Ord
 
 export type OrderItemDetailResponse = AxiosResponse<ApiResponseData<OrderItemRecord>>;
 
-export type OrderItemOperationResponse = AxiosResponse<ApiResponseData<boolean>>;
+export type OrderItemOperationResponse = AxiosResponse<ApiResponseData<boolean>>;

+ 77 - 54
src/components/order-form/order-form-mixin.js

@@ -13,7 +13,8 @@ import {
   ORDER_TYPES,
   ORDER_STATUS,
   ORDER_TYPE_OPTIONS,
-  ORDER_STATUS_OPTIONS
+  ORDER_STATUS_OPTIONS,
+  ORDER_ITEM_STATUS
 } from '@/constants/order'
 
 // 本地常量定义导入
@@ -442,17 +443,19 @@ export default {
    */
   createInitialFormData() {
       return {
-        id: null,
+        id: undefined,
         orderCode: '',
+        orgId: undefined,
         orgCode: '',
         orgName: '',
-        customerId: undefined,
+        customerId: null,
         customerCode: '',
         customerName: '',
         orderType: ORDER_TYPES.NORMAL,
+        orderQuantity: 0,
         totalAmount: null,
         totalQuantity: null,
-        addressId: '',
+        addressId: null,
         receiverName: '',
         receiverPhone: '',
         receiverRegion: '',
@@ -619,13 +622,16 @@ export default {
             const taxRateValidation = validateNumber(material.taxRate)
             const taxAmountValidation = validateNumber(material.taxAmount)
             const totalAmountValidation = validateNumber(material.totalAmount)
+            const availableQuantityValidation = validateNumber(material.availableQuantity)
+            const confirmQuantityValidation = validateNumber(material.confirmQuantity)
 
-            /** @type MaterialDetailRecord */
             const detailData =  {
               ...material,
-              id: material.id || '',
-              itemId: material.itemId || '',
-              warehouseId: material.warehouseId || '',
+              id: String(material.id || ''),
+              itemId: String(material.itemId || ''),
+              warehouseId: String(material.warehouseId || ''),
+              mainCategoryId: String(material.mainItemCategoryId) || '',
+              mainItemCategoryId: material.mainItemCategoryId ? String(material.mainItemCategoryId) : undefined,
               createTime: material.createTime || new Date().toISOString(),
               updateTime: material.updateTime || new Date().toISOString(),
               dataSource: MaterialDetailDataSource.REMOTE,
@@ -636,10 +642,12 @@ export default {
               taxRate: taxRateValidation.isValid ? preciseRound(taxRateValidation.value, 4) : 0,
               taxAmount: taxAmountValidation.isValid ? preciseRound(taxAmountValidation.value, 2) : 0,
               totalAmount: totalAmountValidation.isValid ? preciseRound(totalAmountValidation.value, 2) : 0,
+              availableQuantity: availableQuantityValidation.isValid ? preciseRound(availableQuantityValidation.value, 0) : 0,
+              confirmQuantity: confirmQuantityValidation.isValid ? preciseRound(confirmQuantityValidation.value, 0) : 0,
               // 确保必要的字段存在
               itemCode: material.itemCode || '',
               itemName: material.itemName || '',
-              specs: material.specs || '',
+              specs: material.specs || ''
             }
             return detailData;
           } catch (itemError) {
@@ -661,8 +669,7 @@ export default {
               totalAmount: 0,
               itemCode: material.itemCode || '',
               itemName: material.itemName || '',
-              specs: material.specs || '',
-              unit: material.unit || ''
+              specs: material.specs || ''
             }
           }
         })
@@ -688,18 +695,19 @@ export default {
       const orderQuantityValidation = validateNumber(orderData.orderQuantity)
 
       return {
-        id: orderData.id || null,
+        id: orderData.id ? Number(orderData.id) : undefined,
         orderCode: String(orderData.orderCode || ''),
+        orgId: orderData.orgId ? Number(orderData.orgId) : undefined,
         orgCode: String(orderData.orgCode || ''),
         orgName: String(orderData.orgName || ''),
         customerId: Number(orderData.customerId) || null,
         customerCode: String(orderData.customerCode || ''),
         customerName: String(orderData.customerName || ''),
         orderType: Number(orderData.orderType) || ORDER_TYPES.NORMAL,
-        orderQuantity: orderQuantityValidation.isValid ? parseInt(orderQuantityValidation.value.toString()) : null,
+        orderQuantity: orderQuantityValidation.isValid ? parseInt(orderQuantityValidation.value.toString()) : 0,
         totalAmount: totalAmountValidation.isValid ? preciseRound(totalAmountValidation.value, 2) : null,
         totalQuantity: totalQuantityValidation.isValid ? preciseRound(totalQuantityValidation.value, 4) : null,
-        addressId: String(orderData.addressId || ''),
+        addressId: orderData.addressId ? Number(orderData.addressId) : null,
         receiverName: String(orderData.receiverName || ''),
         receiverPhone: String(orderData.receiverPhone || ''),
         receiverRegion: String(orderData.receiverRegion || ''),
@@ -829,25 +837,26 @@ export default {
         taxRate: Number(material.taxRate) || 0,
         taxAmount: Number(material.taxAmount) || 0,
         totalAmount: Number(material.totalAmount) || 0,
-        itemStatus: Number(material.itemStatus) || Number(material.status) || 0
+        itemStatus: material.itemStatus || ORDER_ITEM_STATUS.UNCONFIRMED,
       }))
 
-      // 创建销售订单数据对象,不包含orderCode字段
+      // 创建销售订单数据对象
       const salesOrderData = {
         ...formData,
-        orgId: Number(formData.orgId) || 0,
-        customerId: Number(formData.customerId) || 0,
+        orgId: formData.orgId ? Number(formData.orgId) : 0,
+        customerId: formData.customerId ? Number(formData.customerId) : 0,
         orderType: Number(formData.orderType) || 0,
         totalAmount: Number(formData.totalAmount) || 0,
         totalQuantity: Number(formData.totalQuantity) || 0,
-        addressId: Number(formData.addressId) || 0,
-        status: Number(formData.status) || 0,
+        addressId: formData.addressId ? Number(formData.addressId) : 0,
+        status: formData.status,
         pcBladeOrderItemList
       }
 
       // 新增模式下,移除orderCode字段
-      if (!this.isEdit && salesOrderData.orderCode) {
-        delete salesOrderData.orderCode
+      if (!this.isEdit) {
+        const { orderCode, ...dataWithoutOrderCode } = salesOrderData
+        return dataWithoutOrderCode
       }
 
       return salesOrderData
@@ -889,7 +898,7 @@ export default {
      */
     async validateFormFields() {
       return new Promise((resolve) => {
-        this.$refs?.orderForm?.validate((valid) => {
+        this.$refs?.orderForm?.validate(/** @param {boolean} valid */ (valid) => {
           resolve(Boolean(valid))
         })
       })
@@ -918,10 +927,11 @@ export default {
      * @this {import('./types').OrderFormMixinComponent}
      */
     cleanAndFormatSubmitData(data) {
+      /** @type {Record<string, any>} */
       const cleanedData = {}
 
       Object.keys(data).forEach(key => {
-        const value = data[key]
+        const value = /** @type {Record<string, any>} */(data)[key]
 
         // 新增模式下,移除orderCode字段
         if (!this.isEdit && key === 'orderCode') {
@@ -947,7 +957,7 @@ export default {
         }
       })
 
-      return cleanedData
+      return /** @type {any} */ (cleanedData)
     },
 
     /**
@@ -974,6 +984,7 @@ export default {
 
       const { add: addOrderItem } = await import('@/api/order/order-item')
       const savePromises = []
+      /** @type {Array<{ index: number, itemCode: string, error: Error }>} */
       const failedItems = []
 
       // 准备所有导入物料明细的保存请求
@@ -1027,21 +1038,19 @@ export default {
         taxRate: Number(material.taxRate) || 0,
         taxAmount: Number(material.taxAmount) || 0,
         totalAmount: Number(material.totalAmount) || 0,
-        itemStatus: Number(material.itemStatus) || Number(material.status) || 0
+        itemStatus: ORDER_ITEM_STATUS.UNCONFIRMED,
       }
     },
 
     /**
      * 处理物料删除事件
      * @description 从物料明细列表中删除指定的物料记录,仅允许删除可删除的物料
-     * @param {MaterialDeleteEventData} deleteData - 删除数据对象
-     * @param {MaterialDetailRecord} deleteData.row - 要删除的物料记录
-     * @param {number} deleteData.index - 记录在当前页的索引
+     * @param {import('./types').MaterialDetailRecord} row - 要删除的物料记录
      * @returns {void}
      * @public
      * @this {import('./types').OrderFormMixinComponent}
      */
-    handleMaterialDelete({ row, index }) {
+    handleMaterialDelete(/** @type {{ row: import('./types').MaterialDetailRecord, index: number }} */ { row, index }) {
        if (!row) {
          this.$message.warning('删除数据无效')
          return
@@ -1128,7 +1137,7 @@ export default {
      * @param {Function} done - 完成回调函数
      * @this {import('./types').OrderFormMixinComponent}
      */
-    handleFormSubmit(formData, done) {
+    handleFormSubmit(/** @type {import('./types').OrderFormModel} */ formData, /** @type {Function} */ done) {
       this.handleSave().finally(() => {
         if (typeof done === 'function') {
           done()
@@ -1161,19 +1170,43 @@ export default {
     /**
      * 处理物料明细更新事件
      * @description 当物料明细表格中的数据被编辑时的回调处理,自动重新计算订单总金额和总数量
-     * @param {MaterialUpdateEventData} updateData - 更新数据对象
+     * @param {import('./types').MaterialUpdateEventData} eventData - 更新事件数据对象
      * @returns {void}
      * @this {import('./types').OrderFormMixinComponent}
      */
-    handleMaterialUpdate({ row, index }) {
-      // 如果有有效的索引,更新物料明细列表中对应的记录
-      if (index >= 0 && index < this.materialDetails.length) {
-        this.$set(this.materialDetails, index, { ...row })
-      }
+    handleMaterialUpdate(eventData) {
+       if (!eventData || typeof eventData !== 'object') {
+         console.warn('Invalid material update event data:', eventData)
+         return
+       }
 
-      // 无论索引是否有效,都重新计算订单总金额
-      this.calculateOrderTotal()
-    },
+       const { index, row } = eventData
+       if (typeof index !== 'number' || index < 0) {
+         console.warn('Invalid material update index:', index)
+         return
+       }
+
+       if (!row || typeof row !== 'object') {
+         console.warn('Invalid material update data:', row)
+         return
+       }
+
+       // 验证索引是否在有效范围内
+       if (index >= this.materialDetails.length) {
+         console.warn('Material update index out of range:', index, 'length:', this.materialDetails.length)
+         return
+       }
+
+       // 更新物料明细数据
+       this.$set(this.materialDetails, index, {
+         ...this.materialDetails[index],
+         ...row,
+         updateTime: new Date().toISOString()
+       })
+
+       // 重新计算订单总计
+       this.calculateOrderTotal()
+     },
 
     /**
      * 计算订单总金额和总数量
@@ -1208,14 +1241,11 @@ export default {
     /**
      * 处理客户选择事件
      * @description 当客户选择组件选择客户时的回调处理,自动填充客户编码和客户名称,并清空地址相关字段
-     * @param {Object} customerData - 客户数据对象
-     * @param {string|number} customerData.customerId - 客户ID
-     * @param {string} customerData.customerCode - 客户编码
-     * @param {string} customerData.customerName - 客户名称
+     * @param {import('./types').CustomerSelectData} customerData - 客户数据对象
      * @returns {void}
      * @this {import('./types').OrderFormMixinComponent}
      */
-    handleCustomerSelected(customerData) {
+    handleCustomerSelected(/** @type {import('./types').CustomerSelectData} */ customerData) {
       if (this.formData) {
         // 更新客户相关字段
         this.$set(this.formData, 'customerId', customerData.customerId)
@@ -1234,18 +1264,11 @@ export default {
     /**
      * 处理地址选择事件
      * @description 当地址选择组件选择地址时的回调处理,自动填充收货人相关信息
-     * @param {Object} addressData - 地址数据对象
-     * @param {string|number} addressData.addressId - 地址ID
-     * @param {string} addressData.receiverName - 收货人姓名
-     * @param {string} addressData.receiverPhone - 收货人电话
-     * @param {string} addressData.regionCode - 地区编码
-     * @param {string} addressData.regionName - 地区名称
-     * @param {string} addressData.detailAddress - 详细地址
-     * @param {string} addressData.postalCode - 邮政编码
+     * @param {import('./types').AddressSelectData} addressData - 地址数据对象
      * @returns {void}
      * @this {import('./types').OrderFormMixinComponent}
      */
-    handleAddressSelected(addressData) {
+    handleAddressSelected(/** @type {import('./types').AddressSelectData} */ addressData) {
       if (this.formData) {
         // 更新地址相关字段
         this.$set(this.formData, 'addressId', addressData.addressId)

+ 4 - 3
src/components/order-form/types.d.ts

@@ -138,6 +138,7 @@ import { DicItem, DicProps } from '@types/smallwei__avue/dic';
 // Vue相关类型导入
 import Vue, { VNode } from 'vue';
 import { NormalizedScopedSlot } from 'vue/types/vnode';
+import { OrderItemStatus } from '@/api/types/order';
 
 // 为了兼容现有代码,定义一些类型别名
 type AvueDicData = DicItem;
@@ -544,7 +545,7 @@ export interface MaterialDetailItem {
   /** 规格型号 */
   specification?: string;
   /** 规格描述 */
-  specs?: string | number | null;
+  specs?: string | null;
   /** 单位 */
   unit?: string;
   /** 主物料分类ID */
@@ -554,7 +555,7 @@ export interface MaterialDetailItem {
   /** 主物料分类ID */
   mainItemCategoryId?: string;
   /** 主物料分类名称 */
-  mainItemCategoryName?: string | number;
+  mainItemCategoryName?: string;
   /** 仓库ID */
   warehouseId: string;
   /** 仓库名称 */
@@ -576,7 +577,7 @@ export interface MaterialDetailItem {
   /** 明细状态 */
   status: typeof MaterialDetailStatus[keyof typeof MaterialDetailStatus];
   /** 物料状态 */
-  itemStatus?: number;
+  itemStatus?: OrderItemStatus;
   /** 是否可删除 */
   isDeletable?: boolean;
   /** 创建时间,ISO 8601格式 */