浏览代码

refactor(order-form): 将组件逻辑迁移至mixin并完善类型定义

yz 3 月之前
父节点
当前提交
c0f344a72b
共有 3 个文件被更改,包括 549 次插入240 次删除
  1. 286 20
      src/components/order-form/order-form-mixin.js
  2. 6 218
      src/components/order-form/order-form.vue
  3. 257 2
      src/components/order-form/types.d.ts

+ 286 - 20
src/components/order-form/order-form-mixin.js

@@ -48,6 +48,20 @@ import {
 
 /**
  * @typedef {import('./types').OrderFormModel} OrderFormModel
+ * @description 订单表单数据模型类型
+ */
+
+/**
+ * @typedef {import('./types').OrderFormRules} OrderFormRules
+ * @description 订单表单验证规则类型
+ */
+
+/**
+ * @typedef {import('./types').OrderFormMethods} OrderFormMethods
+ * @description 订单表单方法类型
+ */
+
+/**
  * @typedef {import('smallwei__avue/form').AvueFormOption<OrderFormModel>} AvueFormOption
  * @typedef {import('smallwei__avue/form').AvueFormColumn<OrderFormModel>} AvueFormColumn
  * @typedef {import('smallwei__avue/form').AvueFormGroup<OrderFormModel>} AvueFormGroup
@@ -72,11 +86,6 @@ import {
  */
 
 /**
- * @typedef {import('./types').OrderFormMixinData} OrderFormMixinData
- * @description 订单表单混入数据类型
- */
-
-/**
  * @typedef {import('@/api/types/order').SalesOrderCreateForm} SalesOrderCreateForm
  * @description 销售订单创建表单类型
  */
@@ -105,7 +114,8 @@ export default {
   /**
    * 组件响应式数据
    * @description 定义组件的响应式数据状态
-   * @returns {OrderFormMixinData} 组件数据对象
+   * @returns {import('./types').OrderFormMixinData} 组件数据对象
+   * @this {import('./types').OrderFormMixin}
    */
   data() {
     return {
@@ -124,6 +134,20 @@ export default {
       saveLoading: false,
 
       /**
+       * 表单加载状态
+       * @description 控制表单整体的加载状态,用于数据获取时的UI反馈
+       * @type {boolean}
+       */
+      formLoading: false,
+
+      /**
+       * 物料明细列表
+       * @description 存储当前订单的物料明细数据,包含数据来源和删除权限标识
+       * @type {MaterialDetailRecord[]}
+       */
+      materialDetails: [],
+
+      /**
        * 订单类型选项列表
        * @description 订单类型下拉选择器的选项数据
        * @type {typeof ORDER_TYPE_OPTIONS}
@@ -135,7 +159,12 @@ export default {
        * @description 订单状态下拉选择器的选项数据
        * @type {typeof ORDER_STATUS_OPTIONS}
        */
-      orderStatusOptions: ORDER_STATUS_OPTIONS
+      orderStatusOptions: ORDER_STATUS_OPTIONS,
+
+      // 事件常量,用于模板中的动态事件绑定
+      CUSTOMER_SELECT_EVENTS: ORDER_FORM_EVENTS.CUSTOMER_SELECT,
+      ADDRESS_SELECT_EVENTS: ORDER_FORM_EVENTS.ADDRESS_SELECT,
+      MATERIAL_DETAIL_EVENTS: ORDER_FORM_EVENTS.MATERIAL_DETAIL
     }
   },
 
@@ -148,6 +177,7 @@ export default {
      * 订单表单验证规则
      * @description 定义订单表单各字段的验证规则,支持必填、长度、格式等验证
      * @returns {OrderFormRules} 完整的表单验证规则对象
+     * @this {import('./types').OrderFormMixin}
      */
     formRules() {
       return {
@@ -329,6 +359,67 @@ export default {
           }
         ]
       }
+    },
+
+    /**
+     * 表单标题
+     * @description 根据编辑模式动态显示表单标题
+     * @returns {string} 表单标题文本
+     * @this {import('./types').OrderFormMixin}
+     */
+    formTitle() {
+      return this.isEdit ? '编辑订单' : '新增订单'
+    },
+
+    /**
+     * 物料明细表格配置
+     * @description 获取物料明细表格的配置选项
+     * @returns {Object} 表格配置对象
+     * @this {import('./types').OrderFormMixin}
+     */
+    materialDetailTableOption() {
+      return {
+        border: true,
+        stripe: true,
+        menuAlign: 'center',
+        align: 'center',
+        addBtn: false,
+        editBtn: false,
+        delBtn: true,
+        viewBtn: false,
+        column: [
+          {
+            label: '物料编码',
+            prop: 'itemCode',
+            width: 120
+          },
+          {
+            label: '物料名称',
+            prop: 'itemName',
+            width: 150
+          },
+          {
+            label: '规格型号',
+            prop: 'specs',
+            width: 120
+          },
+          {
+            label: '订单数量',
+            prop: 'orderQuantity',
+            width: 100
+          },
+          {
+            label: '单价',
+            prop: 'unitPrice',
+            width: 100
+          },
+          {
+            label: '总金额',
+            prop: 'totalAmount',
+            width: 120
+          }
+        ]
+      }
     }
   },
 
@@ -342,6 +433,7 @@ export default {
      * @description 创建订单表单的初始数据结构
      * @returns {OrderFormModel} 初始化的表单数据对象
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     createInitialFormData() {
       return {
@@ -371,6 +463,7 @@ export default {
      * @returns {Promise<void>}
      * @throws {Error} 当初始化过程中发生错误时抛出异常
      * @public
+     * @this {import('./types').OrderFormMixin}
      */
     async initForm() {
       try {
@@ -395,6 +488,7 @@ export default {
      * @returns {Promise<void>}
      * @throws {Error} 当重置过程中发生严重错误时抛出异常
      * @public
+     * @this {import('./types').OrderFormMixin}
      */
     async resetForm() {
       try {
@@ -430,6 +524,7 @@ export default {
      * @returns {Promise<void>}
      * @throws {Error} 当订单ID无效、API调用失败或数据格式错误时抛出异常
      * @public
+     * @this {import('./types').OrderFormMixin}
      */
     async loadOrderDetail(orderId) {
       // 参数验证
@@ -439,9 +534,6 @@ export default {
 
       try {
         // 并行加载订单详情和物料明细数据以提高性能
-        /**
-         * @type {[import('axios').AxiosResponse<ApiResponse<import('@/api/types/order').OrderRecord>>, MaterialDetailRecord[]]}
-         */
         const [orderResponse, materialResponse] = await Promise.all([
           getDetail(orderId),
           this.loadMaterialDetails(orderId)
@@ -482,6 +574,7 @@ export default {
      * @returns {Promise<MaterialDetailRecord[]>} 格式化后的物料明细数组,数值字段已进行精度处理
      * @throws {Error} 当订单ID无效或API调用失败时抛出异常
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     async loadMaterialDetails(orderId) {
       // 参数验证
@@ -573,6 +666,7 @@ export default {
      * @param {import('@/api/types/order').OrderRecord} orderData - 从API获取的原始订单数据
      * @returns {OrderFormModel} 格式化后的表单数据
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     mapOrderDataToForm(orderData) {
       // 验证和格式化数字字段
@@ -608,6 +702,7 @@ export default {
      * @returns {void}
      * @public
      * @emits back 返回列表事件
+     * @this {import('./types').OrderFormMixin}
      */
     handleBack() {
       /**
@@ -626,6 +721,7 @@ export default {
      * @throws {Error} 当表单验证失败或API调用失败时抛出异常
      * @public
      * @emits save-success 保存成功事件
+     * @this {import('./types').OrderFormMixin}
      */
     async handleSave() {
       if (this.saveLoading) {
@@ -682,6 +778,7 @@ export default {
      * @param {OrderFormModel} submitData - 要提交的订单数据
      * @returns {Promise<import('axios').AxiosResponse<ApiResponse<import('@/api/types/order').OrderRecord>>>} API响应结果
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     async submitOrderData(submitData) {
       if (this.isEdit) {
@@ -699,6 +796,7 @@ export default {
      * @param {OrderFormModel} formData - 表单数据
      * @returns {SalesOrderCreateForm} 销售订单创建数据
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     prepareSalesOrderData(formData) {
       // 转换物料明细数据为API所需格式
@@ -747,6 +845,7 @@ export default {
      * @description 使用AvueJS表单的验证功能验证所有字段
      * @returns {Promise<boolean>} 验证结果,true表示验证通过,false表示验证失败
      * @public
+     * @this {import('./types').OrderFormMixin}
      */
     async validateForm() {
       if (!this.$refs.orderForm) {
@@ -773,10 +872,11 @@ export default {
      * @description 验证AvueJS表单的所有字段,确保数据有效性
      * @returns {Promise<boolean>} 验证结果
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     async validateFormFields() {
       return new Promise((resolve) => {
-        this.$refs.orderForm.validate((valid) => {
+        this.$refs?.orderForm?.validate((valid) => {
           resolve(Boolean(valid))
         })
       })
@@ -787,6 +887,7 @@ export default {
      * @description 复制表单数据并进行清理和格式化处理
      * @returns {OrderFormModel} 准备好的提交数据
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     prepareSubmitData() {
       const submitData = { ...this.formData }
@@ -801,6 +902,7 @@ export default {
      * @param {OrderFormModel} data - 原始表单数据
      * @returns {OrderFormModel} 清理后的数据对象
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     cleanAndFormatSubmitData(data) {
       const cleanedData = {}
@@ -841,6 +943,7 @@ export default {
      * @returns {Promise<void>}
      * @throws {Error} 当物料明细保存失败时抛出异常
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     async saveMaterialDetails() {
       if (!this.materialDetails || this.materialDetails.length === 0) {
@@ -890,6 +993,7 @@ export default {
      * @param {MaterialDetailRecord} material - 物料明细数据
      * @returns {SalesOrderItemCreateForm} 格式化后的物料明细数据
      * @private
+     * @this {import('./types').OrderFormMixin}
      */
     prepareMaterialItemData(material) {
       return {
@@ -915,15 +1019,16 @@ export default {
     },
 
     /**
-      * 处理物料删除事件
-       * @description 从物料明细列表中删除指定的物料记录,仅允许删除可删除的物料
-       * @param {MaterialDeleteEventData} deleteData - 删除数据对象
-       * @param {MaterialDetailRecord} deleteData.row - 要删除的物料记录
-       * @param {number} deleteData.index - 记录在当前页的索引
-       * @returns {void}
-       * @public
-       */
-     handleMaterialDelete({ row, index }) {
+     * 处理物料删除事件
+     * @description 从物料明细列表中删除指定的物料记录,仅允许删除可删除的物料
+     * @param {MaterialDeleteEventData} deleteData - 删除数据对象
+     * @param {MaterialDetailRecord} deleteData.row - 要删除的物料记录
+     * @param {number} deleteData.index - 记录在当前页的索引
+     * @returns {void}
+     * @public
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleMaterialDelete({ row, index }) {
        if (!row) {
          this.$message.warning('删除数据无效')
          return
@@ -960,6 +1065,7 @@ export default {
      * @param {MaterialDetailRecord[]} importedMaterials - 导入的物料数据数组
      * @returns {void}
      * @public
+     * @this {import('./types').OrderFormMixin}
      */
     handleMaterialImport(importedMaterials) {
       if (!Array.isArray(importedMaterials) || importedMaterials.length === 0) {
@@ -1000,6 +1106,166 @@ export default {
         this.$message.error('导入物料失败,请重试')
         console.error('导入物料失败:', error)
       }
+    },
+
+    /**
+     * 处理表单提交事件
+     * @description AvueJS表单提交时的回调处理
+     * @param {OrderFormModel} formData - 表单数据
+     * @param {Function} done - 完成回调函数
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleFormSubmit(formData, done) {
+      this.handleSave().finally(() => {
+        if (typeof done === 'function') {
+          done()
+        }
+      })
+    },
+
+    /**
+     * 处理表单重置事件
+     * @description AvueJS表单重置时的回调处理
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleFormReset() {
+      this.resetForm()
+    },
+
+    /**
+     * 处理物料明细数据变化
+     * @description 当物料明细表格数据发生变化时的回调处理,自动重新计算订单总金额和总数量
+     * @param {MaterialDetailRecord[]} materialDetails - 更新后的物料明细列表
+     * @returns {void}
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleMaterialChange(materialDetails) {
+      this.materialDetails = materialDetails
+      // 可以在这里添加其他业务逻辑,如计算订单总金额等
+      this.calculateOrderTotal()
+    },
+
+    /**
+     * 处理物料明细更新事件
+     * @description 当物料明细表格中的数据被编辑时的回调处理,自动重新计算订单总金额和总数量
+     * @param {MaterialUpdateEventData} updateData - 更新数据对象
+     * @returns {void}
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleMaterialUpdate({ row, index }) {
+      // 如果有有效的索引,更新物料明细列表中对应的记录
+      if (index >= 0 && index < this.materialDetails.length) {
+        this.$set(this.materialDetails, index, { ...row })
+      }
+
+      // 无论索引是否有效,都重新计算订单总金额
+      this.calculateOrderTotal()
+    },
+
+    /**
+     * 计算订单总金额和总数量
+     * @description 根据物料明细计算订单总金额、总数量、总税额并更新表单数据
+     * @returns {void}
+     * @this {import('./types').OrderFormMixin}
+     */
+    calculateOrderTotal() {
+      // 计算订单总金额
+      const totalAmount = this.materialDetails.reduce((sum, item) => {
+        return sum + (Number(item.totalAmount) || 0)
+      }, 0)
+
+      // 计算订单总数量
+      const totalQuantity = this.materialDetails.reduce((sum, item) => {
+        return sum + (Number(item.orderQuantity) || 0)
+      }, 0)
+
+      // 计算总税额
+      const totalTaxAmount = this.materialDetails.reduce((sum, item) => {
+        return sum + (Number(item.taxAmount) || 0)
+      }, 0)
+
+      // 更新表单中的总金额、总数量和税额字段
+      if (this.formData) {
+        this.$set(this.formData, 'totalAmount', Math.round(totalAmount * 100) / 100)
+        this.$set(this.formData, 'totalQuantity', Math.round(totalQuantity))
+        this.$set(this.formData, 'totalTaxAmount', Math.round(totalTaxAmount * 100) / 100)
+      }
+    },
+
+    /**
+     * 处理客户选择事件
+     * @description 当客户选择组件选择客户时的回调处理,自动填充客户编码和客户名称,并清空地址相关字段
+     * @param {Object} customerData - 客户数据对象
+     * @param {string|number} customerData.customerId - 客户ID
+     * @param {string} customerData.customerCode - 客户编码
+     * @param {string} customerData.customerName - 客户名称
+     * @returns {void}
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleCustomerSelected(customerData) {
+      if (this.formData) {
+        // 更新客户相关字段
+        this.$set(this.formData, 'customerId', customerData.customerId)
+        this.$set(this.formData, 'customerCode', customerData.customerCode)
+        this.$set(this.formData, 'customerName', customerData.customerName)
+
+        // 清空地址相关字段
+        this.$set(this.formData, 'addressId', '')
+        this.$set(this.formData, 'receiverName', '')
+        this.$set(this.formData, 'receiverPhone', '')
+        this.$set(this.formData, 'receiverRegion', '')
+        this.$set(this.formData, 'receiverAddress', '')
+      }
+    },
+
+    /**
+     * 处理地址选择事件
+     * @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 - 邮政编码
+     * @returns {void}
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleAddressSelected(addressData) {
+      if (this.formData) {
+        // 更新地址相关字段
+        this.$set(this.formData, 'addressId', addressData.addressId)
+        this.$set(this.formData, 'receiverName', addressData.receiverName || '')
+        this.$set(this.formData, 'receiverPhone', addressData.receiverPhone || '')
+        this.$set(this.formData, 'receiverRegion', addressData.regionName || '')
+        this.$set(this.formData, 'receiverAddress', addressData.detailAddress || '')
+      }
+    },
+
+    /**
+     * 处理地址回显
+     * @description 在编辑模式下,根据表单中的地址信息在地址选择组件中进行回显
+     * @returns {void}
+     * @this {import('./types').OrderFormMixin}
+     */
+    handleAddressEcho() {
+      // 查找地址选择组件的引用
+      const addressSelectRefs = this.$refs.orderForm?.$refs?.addressId
+      const addressSelectComponent = Array.isArray(addressSelectRefs) ? addressSelectRefs[0] : addressSelectRefs
+
+      if (addressSelectComponent && typeof addressSelectComponent.setEchoValue === 'function') {
+        // 构建地址信息对象用于匹配
+        const addressInfo = {
+          receiverName: this.formData.receiverName,
+          receiverPhone: this.formData.receiverPhone,
+          regionName: this.formData.receiverRegion,
+          detailAddress: this.formData.receiverAddress
+        }
+
+        // 调用地址选择组件的回显方法
+        addressSelectComponent.setEchoValue(addressInfo)
+      }
     }
   }
 }

+ 6 - 218
src/components/order-form/order-form.vue

@@ -77,18 +77,21 @@
 </template>
 
 <script>
+// @ts-check
 import orderFormMixin from './order-form-mixin'
-import { getFormOption } from './form-option'
 import MaterialDetailTable from './material-detail-table.vue'
 import CustomerSelect from './customer-select.vue'
 import AddressSelect from './address-select.vue'
-import { CUSTOMER_SELECT_EVENTS, ADDRESS_SELECT_EVENTS, MATERIAL_DETAIL_EVENTS } from './events'
 
 /**
+ * 订单表单组件类型定义
  * @typedef {import('./types').OrderFormModel} OrderFormModel
  * @typedef {import('./types').MaterialDetailRecord} MaterialDetailRecord
  * @typedef {import('./types').MaterialUpdateEventData} MaterialUpdateEventData
  * @typedef {import('./types').MaterialDeleteEventData} MaterialDeleteEventData
+ * @typedef {import('./types').CustomerSelectData} CustomerSelectData
+ * @typedef {import('./types').AddressSelectData} AddressSelectData
+ * @typedef {import('./types').OrderFormComponent} OrderFormComponent
  * @typedef {import('smallwei__avue/form').AvueFormOption<OrderFormModel>} AvueFormOption
  * @typedef {import('smallwei__avue/form').AvueFormColumn<OrderFormModel>} AvueFormColumn
  * @typedef {import('smallwei__avue/form').AvueFormGroup<OrderFormModel>} AvueFormGroup
@@ -97,6 +100,7 @@ import { CUSTOMER_SELECT_EVENTS, ADDRESS_SELECT_EVENTS, MATERIAL_DETAIL_EVENTS }
 /**
  * 订单表单组件
  * @description 基于AvueJS的订单表单组件,支持新增和编辑订单功能,包含物料明细管理和自动计算功能
+ * @this {import('./types').OrderFormComponent}
  */
 export default {
   name: 'OrderForm',
@@ -112,49 +116,6 @@ export default {
   },
 
   /**
-   * 组件数据
-   */
-  data() {
-    return {
-      /**
-     * 物料明细列表
-     * @type {MaterialDetailRecord[]}
-     * @description 存储当前订单的物料明细数据,包含数据来源和删除权限标识
-     */
-      materialDetails: [],
-
-      // 事件常量,用于模板中的动态事件绑定
-      CUSTOMER_SELECT_EVENTS,
-      ADDRESS_SELECT_EVENTS,
-      MATERIAL_DETAIL_EVENTS
-    }
-  },
-
-  /**
-   * 计算属性
-   * @description 组件的响应式计算属性
-   */
-  computed: {
-    /**
-     * 获取表单配置选项
-     * @description 根据编辑模式动态生成AvueJS表单配置
-     * @returns {AvueFormOption} AvueJS表单配置对象
-     */
-    formOption() {
-      return getFormOption(this.isEdit)
-    },
-
-    /**
-     * 表单标题
-     * @description 根据编辑模式动态显示表单标题
-     * @returns {string} 表单标题文本
-     */
-    formTitle() {
-      return this.isEdit ? '编辑订单' : '新增订单'
-    }
-  },
-
-  /**
    * 组件属性定义
    * @description 定义组件接收的外部属性及其类型约束
    */
@@ -249,179 +210,6 @@ export default {
         }
       }
     }
-  },
-
-  /**
-   * 组件方法
-   * @description 组件的业务逻辑方法
-   */
-  methods: {
-    /**
-     * 处理表单提交事件
-     * @description AvueJS表单提交时的回调处理
-     * @param {OrderFormData} formData - 表单数据
-     * @param {Function} done - 完成回调函数
-     */
-    handleFormSubmit(formData, done) {
-      this.handleSave().finally(() => {
-        if (typeof done === 'function') {
-          done()
-        }
-      })
-    },
-
-    /**
-     * 处理表单重置事件
-     * @description AvueJS表单重置时的回调处理
-     */
-    handleFormReset() {
-      this.resetForm()
-    },
-
-    /**
-     * 处理物料明细数据变化
-     * @description 当物料明细表格数据发生变化时的回调处理,自动重新计算订单总金额和总数量
-     * @param {MaterialDetailRecord[]} materialDetails - 更新后的物料明细列表
-     * @returns {void}
-     */
-    handleMaterialChange(materialDetails) {
-      this.materialDetails = materialDetails
-      // 可以在这里添加其他业务逻辑,如计算订单总金额等
-      this.calculateOrderTotal()
-    },
-
-    /**
-     * 处理物料导入事件
-     * @description 当从物料导入弹窗确认导入物料时的回调处理,自动重新计算订单总金额和总数量
-     * @param {MaterialDetailRecord[]} importedMaterials - 导入的物料列表
-     * @returns {void}
-     */
-    handleMaterialImport(importedMaterials) {
-      // 调用mixin中的方法来正确处理导入物料(设置数据来源和删除权限)
-      // mixin中的方法会直接更新this.materialDetails并显示成功消息
-      this.$options.mixins[0].methods.handleMaterialImport.call(this, importedMaterials)
-
-      // 重新计算订单总金额
-      this.calculateOrderTotal()
-    },
-
-    /**
-     * 处理物料明细更新事件
-     * @description 当物料明细表格中的数据被编辑时的回调处理,自动重新计算订单总金额和总数量
-     * @param {MaterialUpdateEventData} updateData - 更新数据对象
-     * @returns {void}
-     */
-    handleMaterialUpdate({ row, index }) {
-      // 如果有有效的索引,更新物料明细列表中对应的记录
-      if (index >= 0 && index < this.materialDetails.length) {
-        this.$set(this.materialDetails, index, { ...row })
-      }
-
-      // 无论索引是否有效,都重新计算订单总金额
-      this.calculateOrderTotal()
-    },
-
-    /**
-     * 计算订单总金额和总数量
-     * @description 根据物料明细计算订单总金额、总数量、总税额并更新表单数据
-     * @returns {void}
-     */
-    calculateOrderTotal() {
-      // 计算订单总金额
-      const totalAmount = this.materialDetails.reduce((sum, item) => {
-        return sum + (Number(item.totalAmount) || 0)
-      }, 0)
-
-      // 计算订单总数量
-      const totalQuantity = this.materialDetails.reduce((sum, item) => {
-        return sum + (Number(item.orderQuantity) || 0)
-      }, 0)
-
-      // 计算总税额
-      const totalTaxAmount = this.materialDetails.reduce((sum, item) => {
-        return sum + (Number(item.taxAmount) || 0)
-      }, 0)
-
-      // 更新表单中的总金额、总数量和税额字段
-      if (this.formData) {
-        this.$set(this.formData, 'totalAmount', Math.round(totalAmount * 100) / 100)
-        this.$set(this.formData, 'totalQuantity', Math.round(totalQuantity))
-        this.$set(this.formData, 'totalTaxAmount', Math.round(totalTaxAmount * 100) / 100)
-      }
-    },
-
-    /**
-     * 处理客户选择事件
-     * @description 当客户选择组件选择客户时的回调处理,自动填充客户编码和客户名称,并清空地址相关字段
-     * @param {Object} customerData - 客户数据对象
-     * @param {string|number} customerData.customerId - 客户ID
-     * @param {string} customerData.customerCode - 客户编码
-     * @param {string} customerData.customerName - 客户名称
-     * @returns {void}
-     */
-    handleCustomerSelected(customerData) {
-      if (this.formData) {
-        // 更新客户相关字段
-        this.$set(this.formData, 'customerId', customerData.customerId)
-        this.$set(this.formData, 'customerCode', customerData.customerCode)
-        this.$set(this.formData, 'customerName', customerData.customerName)
-
-        // 清空地址相关字段
-        this.$set(this.formData, 'addressId', '')
-        this.$set(this.formData, 'receiverName', '')
-        this.$set(this.formData, 'receiverPhone', '')
-        this.$set(this.formData, 'receiverRegion', '')
-        this.$set(this.formData, 'receiverAddress', '')
-      }
-    },
-
-    /**
-     * 处理地址选择事件
-     * @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 - 邮政编码
-     * @returns {void}
-     */
-    handleAddressSelected(addressData) {
-      if (this.formData) {
-        // 更新地址相关字段
-        this.$set(this.formData, 'addressId', addressData.addressId)
-        this.$set(this.formData, 'receiverName', addressData.receiverName || '')
-        this.$set(this.formData, 'receiverPhone', addressData.receiverPhone || '')
-        this.$set(this.formData, 'receiverRegion', addressData.regionName || '')
-        this.$set(this.formData, 'receiverAddress', addressData.detailAddress || '')
-      }
-    },
-
-    /**
-     * 处理地址回显
-     * @description 在编辑模式下,根据表单中的地址信息在地址选择组件中进行回显
-     * @returns {void}
-     */
-    handleAddressEcho() {
-      // 查找地址选择组件的引用
-      const addressSelectRefs = this.$refs.orderForm?.$refs?.addressId
-      const addressSelectComponent = Array.isArray(addressSelectRefs) ? addressSelectRefs[0] : addressSelectRefs
-
-      if (addressSelectComponent && typeof addressSelectComponent.setEchoValue === 'function') {
-        // 构建地址信息对象用于匹配
-        const addressInfo = {
-          receiverName: this.formData.receiverName,
-          receiverPhone: this.formData.receiverPhone,
-          regionName: this.formData.receiverRegion,
-          detailAddress: this.formData.receiverAddress
-        }
-
-        // 调用地址选择组件的回显方法
-        addressSelectComponent.setEchoValue(addressInfo)
-      }
-    }
   }
 }
 </script>

+ 257 - 2
src/components/order-form/types.d.ts

@@ -160,10 +160,165 @@ export interface OrderFormMixinData {
   formData: OrderFormModel;
   /** 保存操作加载状态 */
   saveLoading: boolean;
+  /** 表单加载状态 */
+  formLoading: boolean;
+  /** 物料明细列表 */
+  materialDetails: MaterialDetailRecord[];
   /** 订单类型选项列表 */
-  orderTypeOptions: SelectOption<OrderType>[];
+  orderTypeOptions: OrderTypeOption[];
   /** 订单状态选项列表 */
-  orderStatusOptions: SelectOption<OrderStatus>[];
+  orderStatusOptions: OrderStatusOption[];
+  /** 客户选择事件常量 */
+  CUSTOMER_SELECT_EVENTS: any;
+  /** 地址选择事件常量 */
+  ADDRESS_SELECT_EVENTS: any;
+  /** 物料明细事件常量 */
+  MATERIAL_DETAIL_EVENTS: any;
+}
+
+/**
+ * 订单表单混入计算属性类型
+ * @description 定义订单表单混入组件的计算属性结构
+ */
+export interface OrderFormMixinComputed {
+  /** 订单表单验证规则 */
+  formRules: OrderFormRules;
+  /** 表单配置选项 */
+  formOption: AvueFormOption;
+  /** 表单标题 */
+  formTitle: string;
+  /** 物料明细表格配置 */
+  materialDetailTableOption: any;
+}
+
+/**
+ * 订单表单混入方法类型
+ * @description 定义订单表单混入组件的方法结构
+ */
+export interface OrderFormMixinMethods {
+  /** 创建初始表单数据 */
+  createInitialFormData(): OrderFormModel;
+  /** 初始化表单 */
+  initForm(): Promise<void>;
+  /** 重置表单 */
+  resetForm(): Promise<void>;
+  /** 加载订单详情 */
+  loadOrderDetail(orderId: string | number): Promise<void>;
+  /** 加载物料明细 */
+  loadMaterialDetails(orderId: string | number): Promise<MaterialDetailRecord[]>;
+  /** 映射订单数据到表单 */
+  mapOrderDataToForm(orderData: any): void;
+  /** 处理返回 */
+  handleBack(): void;
+  /** 处理保存 */
+  handleSave(): Promise<void>;
+  /** 提交订单数据 */
+  submitOrderData(submitData: any): Promise<any>;
+  /** 准备销售订单数据 */
+  prepareSalesOrderData(formData: OrderFormModel): any;
+  /** 验证表单 */
+  validateForm(): Promise<boolean>;
+  /** 验证表单字段 */
+  validateFormFields(): Promise<boolean>;
+  /** 准备提交数据 */
+  prepareSubmitData(): any;
+  /** 清理和格式化提交数据 */
+  cleanAndFormatSubmitData(data: any): any;
+  /** 保存物料明细 */
+  saveMaterialDetails(): Promise<void>;
+  /** 准备物料项数据 */
+  prepareMaterialItemData(material: MaterialDetailRecord): any;
+  /** 处理物料删除 */
+  handleMaterialDelete(data: MaterialDeleteEventData): void;
+  /** 处理物料导入 */
+  handleMaterialImport(importedMaterials: MaterialDetailRecord[]): void;
+  /** 处理表单提交事件 */
+  handleFormSubmit(formData: OrderFormModel, done: Function): void;
+  /** 处理表单重置事件 */
+  handleFormReset(): void;
+  /** 处理物料明细数据变化 */
+  handleMaterialChange(materialDetails: MaterialDetailRecord[]): void;
+  /** 处理物料明细更新事件 */
+  handleMaterialUpdate(updateData: MaterialUpdateEventData): void;
+  /** 计算订单总金额和总数量 */
+  calculateOrderTotal(): void;
+  /** 处理客户选择事件 */
+  handleCustomerSelected(customerData: CustomerSelectData): void;
+  /** 处理地址选择事件 */
+  handleAddressSelected(addressData: AddressSelectData): void;
+  /** 处理地址回显 */
+  handleAddressEcho(): void;
+}
+
+/**
+ * 订单表单组件数据类型
+ * @description 定义订单表单组件的数据结构,现在大部分逻辑已移到mixin中
+ */
+export interface OrderFormComponentData {
+  // 组件本身不再需要额外的data,所有逻辑都在mixin中
+}
+
+/**
+ * 订单表单组件计算属性类型
+ * @description 定义订单表单组件的计算属性结构,现在大部分逻辑已移到mixin中
+ */
+export interface OrderFormComponentComputed {
+  // 组件本身不再需要额外的computed,所有逻辑都在mixin中
+}
+
+/**
+ * 客户选择数据接口
+ * @description 客户选择组件返回的数据结构
+ */
+export interface CustomerSelectData {
+  /** 客户ID */
+  customerId: string | number;
+  /** 客户编码 */
+  customerCode: string;
+  /** 客户名称 */
+  customerName: string;
+}
+
+/**
+ * 地址选择数据接口
+ * @description 地址选择组件返回的数据结构
+ */
+export interface AddressSelectData {
+  /** 地址ID */
+  addressId: string | number;
+  /** 收货人姓名 */
+  receiverName: string;
+  /** 收货人电话 */
+  receiverPhone: string;
+  /** 地区编码 */
+  regionCode: string;
+  /** 地区名称 */
+  regionName: string;
+  /** 详细地址 */
+  detailAddress: string;
+  /** 邮政编码 */
+  postalCode?: string;
+}
+
+/**
+ * 订单表单组件方法类型
+ * @description 定义订单表单组件的方法结构,现在大部分逻辑已移到mixin中
+ */
+export interface OrderFormComponentMethods {
+  // 组件本身不再需要额外的methods,所有逻辑都在mixin中
+}
+
+/**
+ * 订单表单组件属性类型
+ * @description 定义订单表单组件的属性结构
+ */
+export interface OrderFormComponentProps {
+  /** 表单可见性控制 */
+  visible: boolean;
+  /** 编辑模式标识 */
+  isEdit: boolean;
+  /** 订单唯一标识 */
+  orderId: string | number | null;
 }
 
 /**
@@ -449,6 +604,53 @@ export interface MaterialDeleteEventData {
 }
 
 /**
+ * 物料更新事件数据接口
+ * @description 定义物料更新事件传递的数据结构
+ */
+export interface MaterialUpdateEventData {
+  /** 更新的物料索引 */
+  index: number;
+  /** 更新的物料数据 */
+  material: MaterialDetailRecord;
+  /** 更新的字段名 */
+  field?: string;
+  /** 更新的值 */
+  value?: any;
+}
+
+/**
+ * 客户选择事件数据接口
+ * @description 定义客户选择事件传递的数据结构
+ */
+export interface CustomerSelectData {
+  /** 客户ID */
+  customerId: string | number;
+  /** 客户编码 */
+  customerCode: string;
+  /** 客户名称 */
+  customerName: string;
+  /** 客户其他信息 */
+  [key: string]: any;
+}
+
+/**
+ * 地址选择事件数据接口
+ * @description 定义地址选择事件传递的数据结构
+ */
+export interface AddressSelectData {
+  /** 地址ID */
+  addressId: string | number;
+  /** 地址详情 */
+  address: string;
+  /** 收货人 */
+  consignee?: string;
+  /** 联系电话 */
+  phone?: string;
+  /** 地址其他信息 */
+  [key: string]: any;
+}
+
+/**
  * 物料明细查询参数
  * @description 物料明细表格查询和筛选使用的参数
  */
@@ -530,3 +732,56 @@ export interface PaginationConfig {
   /** 总条数 */
   total: number;
 }
+
+/**
+ * 订单表单混入完整接口
+ * @description 订单表单混入组件的完整类型定义
+ */
+export interface OrderFormMixin extends OrderFormMixinData, OrderFormMixinComputed, OrderFormMixinMethods, OrderFormComponentProps {
+  /** Vue实例引用 */
+  $refs: {
+    [key: string]: any;
+  };
+  /** 事件发射器 */
+  $emit: (event: string, ...args: any[]) => void;
+  /** 消息提示 */
+  $message: {
+    success(message: string): void;
+    error(message: string): void;
+    warning(message: string): void;
+    info(message: string): void;
+  };
+  /** 下一个tick */
+  $nextTick(): Promise<void>;
+  /** Vue设置响应式属性 */
+  $set: (target: any, key: string | number, value: any) => any;
+}
+
+/**
+ * 订单表单组件完整接口
+ * @description 订单表单组件的完整类型定义
+ */
+export interface OrderFormComponent extends OrderFormComponentData, OrderFormComponentComputed, OrderFormComponentMethods, OrderFormComponentProps {
+  /** Vue实例引用 */
+  $refs: {
+    orderForm?: any;
+    [key: string]: any;
+  };
+  /** 事件发射器 */
+  $emit: (event: string, ...args: any[]) => void;
+  /** 消息提示 */
+  $message: {
+    success(message: string): void;
+    error(message: string): void;
+    warning(message: string): void;
+    info(message: string): void;
+  };
+  /** 下一个tick */
+  $nextTick(): Promise<void>;
+  /** Vue设置响应式属性 */
+  $set: (target: any, key: string | number, value: any) => any;
+  /** 混入的方法和属性 */
+  $options: {
+    mixins: OrderFormMixin[];
+  };
+}