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

refactor(forecast-form): 将表单逻辑迁移至mixin并移除重复代码

yz 1 hónapja
szülő
commit
8df91d8052

+ 229 - 33
src/components/forecast-form/forecast-form-mixin.js

@@ -20,6 +20,9 @@ import {
 // 远程搜索API
 import { getCustomerList, getItemList } from '@/api/common'
 
+// 表单配置导入
+import { getFormOption } from './form-option'
+
 /**
  * 销售预测表单事件常量
  * @readonly
@@ -94,6 +97,14 @@ export default {
     title: {
       type: String,
       default: ''
+    },
+
+    /**
+     * 编辑时的表单数据
+     */
+    editData: {
+      type: Object,
+      default: () => ({})
     }
   },
 
@@ -164,7 +175,21 @@ export default {
        * @description 表单字段的验证规则
        * @type {typeof FORECAST_FORM_RULES}
        */
-      formRules: FORECAST_FORM_RULES
+      formRules: FORECAST_FORM_RULES,
+
+      /**
+       * 表单配置
+       * @description AvueJS表单配置对象
+       * @type {Object}
+       */
+      formOption: {},
+
+      /**
+       * 当前库存
+       * @description 当前选中物料的库存数量
+       * @type {number|null}
+       */
+      currentInventory: null
     }
   },
 
@@ -223,12 +248,41 @@ export default {
      * @param {Object} val - 新的初始表单数据
      */
     initialFormData(val) {
-      if (val && this.visible) {
+      if (val) {
         this.formData = this.cleanAndFormatFormData(val)
       }
     },
 
     /**
+     * 监听编辑数据变化
+     */
+    editData: {
+      handler(newData) {
+        if (newData && this.isEdit) {
+          this.formData = { 
+            ...newData,
+            year: newData.year ? newData.year.toString() : ''
+          }
+        }
+      },
+      immediate: true,
+      deep: true
+    },
+
+    /**
+     * 监听编辑模式变化
+     */
+    isEdit: {
+      handler(newVal) {
+        this.initFormOption()
+        if (!newVal) {
+          this.initFormData()
+        }
+      },
+      immediate: true
+    },
+
+    /**
      * 监听预测ID变化
      * @param {string|number} val - 新的预测ID
      */
@@ -243,6 +297,14 @@ export default {
   },
 
   /**
+   * 组件创建时
+   */
+  created() {
+    this.initFormOption()
+    this.initFormData()
+  },
+
+  /**
    * 组件方法
    * @description 组件的业务逻辑方法集合
    */
@@ -504,33 +566,180 @@ export default {
     },
 
     /**
+     * 初始化表单配置
+     */
+    initFormOption() {
+      this.formOption = getFormOption(this.isEdit)
+    },
+
+    /**
+     * 初始化表单数据
+     */
+    initFormData() {
+      if (this.isEdit && this.editData) {
+        // 编辑模式:使用传入的数据,确保year字段为字符串格式
+        this.formData = { 
+          ...this.editData,
+          year: this.editData.year ? this.editData.year.toString() : ''
+        }
+      } else {
+        // 新增模式:使用默认数据,自动填入下个月
+        const now = new Date()
+        const currentYear = now.getFullYear()
+        const currentMonth = now.getMonth() + 1
+        
+        let nextYear, nextMonth
+        if (currentMonth === 12) {
+          // 当前是12月,下个月是明年1月
+          nextYear = currentYear + 1
+          nextMonth = 1
+        } else {
+          // 其他月份,直接 +1
+          nextYear = currentYear
+          nextMonth = currentMonth + 1
+        }
+        
+        this.formData = {
+          forecastCode: '',
+          year: nextYear.toString(),
+          month: nextMonth,
+          customerId: '',
+          customerCode: '',
+          customerName: '',
+          brandId: '',
+          brandCode: '',
+          brandName: '',
+          itemId: '',
+          itemCode: '',
+          itemName: '',
+          itemSpecs: '',
+          forecastQuantity: 1,
+          currentInventory: '',
+          approvalStatus: '',
+          approvalRemark: ''
+        }
+        
+        // 生成预测编码
+        this.generateForecastCode()
+      }
+    },
+
+    /**
      * 生成预测编码
      * @description 自动生成销售预测编码
      * @returns {void}
      */
     generateForecastCode() {
       const now = new Date()
-      const year = now.getFullYear()
-      const month = String(now.getMonth() + 1).padStart(2, '0')
-      const timestamp = now.getTime().toString().slice(-6)
-      this.formData.forecastCode = `FC-${year}-${month}-${timestamp}`
+      const year = this.formData.year || now.getFullYear()
+      const month = this.formData.month || (now.getMonth() + 1)
+      const monthStr = month.toString().padStart(2, '0')
+      const random = Math.floor(1000 + Math.random() * 9000) // 生成1000-9999之间的随机数
+      
+      this.formData.forecastCode = `FC-${year}${monthStr}-${random}`
     },
 
     /**
-     * 表单提交
-     * @description 提交表单数据,根据编辑模式调用不同的API
-     * @returns {Promise<void>}
+     * 客户选择事件处理
      */
-    async submitForm() {
-      try {
-        // 表单验证
-        await this.$refs.form.validate()
+    handleCustomerSelected(customerData) {
+      if (customerData && customerData.customerId) {
+        this.formData.customerId = customerData.customerId
+        this.formData.customerCode = customerData.customerCode
+        this.formData.customerName = customerData.customerName
+      } else {
+        this.formData.customerId = ''
+        this.formData.customerCode = ''
+        this.formData.customerName = ''
+      }
+    },
+
+    /**
+     * 品牌变更处理
+     */
+    handleBrandChange(brandId) {
+      const selectedBrand = this.brandOptions.find(brand => brand.id === brandId)
+      if (selectedBrand) {
+        this.formData.brandCode = selectedBrand.code
+        this.formData.brandName = selectedBrand.name
+      } else {
+        this.formData.brandCode = ''
+        this.formData.brandName = ''
+      }
+    },
+
+    /**
+     * 物料选择处理
+     * @description 处理MaterialSelect组件的物料选择事件
+     * @param {Object} materialData - 物料选择数据
+     * @param {string|number} materialData.itemId - 物料ID
+     * @param {string} materialData.itemCode - 物料编码
+     * @param {string} materialData.itemName - 物料名称
+     * @param {string} materialData.specification - 物料规格
+     * @param {import('@/api/types/common').ItemRecord|null} materialData.materialData - API返回的物料数据对象
+     */
+    handleMaterialSelected(materialData) {
+      if (materialData && materialData.itemId) {
+        this.formData.itemId = materialData.itemId
+        this.formData.itemCode = materialData.itemCode
+        this.formData.itemName = materialData.itemName
+        this.formData.itemSpecs = materialData.specification || ''
+        // 获取当前库存
+        this.getCurrentInventory(materialData.itemId)
+      } else {
+        this.formData.itemId = ''
+        this.formData.itemCode = ''
+        this.formData.itemName = ''
+        this.formData.itemSpecs = ''
+        this.currentInventory = null
+      }
+    },
 
-        this.saveLoading = true
+    /**
+     * 获取当前库存
+     * @param {string|number} itemId - 物料ID
+     */
+    getCurrentInventory(itemId) {
+      // 简化实现,实际应该调用API
+      setTimeout(() => {
+        // 模拟随机库存数量
+        this.currentInventory = Math.floor(Math.random() * 1000)
+      }, 300)
+    },
 
-        // 准备提交数据
-        const submitData = this.prepareSubmitData()
+    /**
+     * 表单提交处理
+     */
+    handleSubmit() {
+      // 表单验证
+      this.$refs.forecastForm.validate((valid) => {
+        if (!valid) {
+          return
+        }
+        this.submitForm()
+      })
+    },
+
+    /**
+     * 表单重置处理
+     */
+    handleReset() {
+      this.initFormData()
+      this.currentInventory = null
+      this.$emit('reset')
+    },
 
+    /**
+     * 提交表单数据
+     * @description 执行表单数据的提交操作,包括数据验证和API调用
+     * @returns {Promise<void>} 提交操作的Promise
+     * @throws {Error} 当提交失败时抛出错误
+     */
+    async submitForm() {
+      try {
+        // 提交数据
+        const submitData = { ...this.formData }
+        
         let res
         if (this.isEdit) {
           res = await updateForecast(submitData)
@@ -538,24 +747,11 @@ export default {
           res = await addForecast(submitData)
         }
 
-        if (res.data && res.data.success) {
-          // 触发提交成功事件,传递API响应数据
-          this.$emit(FORECAST_FORM_EVENTS.SUBMIT_SUCCESS, res.data)
-          
-          // 关闭表单
-          this.closeForm()
-        } else {
-          this.$message.error(res.data?.msg || (this.isEdit ? '修改失败' : '添加失败'))
-        }
+        // 触发提交成功事件,传递API响应数据
+        this.$emit('submit', res.data)
       } catch (error) {
-        if (error.fields) {
-          // 表单验证失败
-          return
-        }
-        console.error('保存失败:', error)
-        this.$message.error('保存失败,请稍后重试')
-      } finally {
-        this.saveLoading = false
+        console.error('提交表单失败:', error)
+        this.$message.error(error.message || '操作失败,请重试')
       }
     },
 

+ 0 - 304
src/components/forecast-form/index.vue

@@ -54,9 +54,6 @@
 
 <script>
 import forecastFormMixin from './forecast-form-mixin.js'
-import { getFormOption } from './form-option'
-import { getApprovalStatusLabel, getApprovalStatusType } from '@/constants/forecast'
-import { addForecast, updateForecast } from '@/api/forecast/index'
 import CustomerSelect from '@/components/common/customer-select.vue'
 import MaterialSelect from '@/components/common/material-select.vue'
 
@@ -74,307 +71,6 @@ export default {
   components: {
     CustomerSelect,
     MaterialSelect
-  },
-
-  /**
-   * 组件属性
-   */
-  props: {
-    /**
-     * 是否为编辑模式
-     */
-    isEdit: {
-      type: Boolean,
-      default: false
-    },
-    /**
-     * 编辑时的表单数据
-     */
-    editData: {
-      type: Object,
-      default: () => ({})
-    }
-  },
-
-  /**
-   * 组件数据
-   */
-  data() {
-    return {
-      // 表单配置
-      formOption: {},
-      // 当前库存
-      currentInventory: null
-    }
-  },
-
-  /**
-   * 计算属性
-   */
-  computed: {
-    /**
-     * 表单标题
-     */
-    formTitle() {
-      return this.isEdit ? '编辑销售预测' : '新增销售预测'
-    }
-  },
-
-  /**
-   * 侦听器
-   */
-  watch: {
-    /**
-     * 监听编辑数据变化
-     */
-    editData: {
-      handler(newData) {
-        if (newData && this.isEdit) {
-          this.formData = { 
-            ...newData,
-            year: newData.year ? newData.year.toString() : ''
-          }
-        }
-      },
-      immediate: true,
-      deep: true
-    },
-
-    /**
-     * 监听编辑模式变化
-     */
-    isEdit: {
-      handler(newVal) {
-        this.initFormOption()
-        if (!newVal) {
-          this.initFormData()
-        }
-      },
-      immediate: true
-    }
-  },
-
-  /**
-   * 组件创建时
-   */
-  created() {
-    this.initFormOption()
-    this.initFormData()
-  },
-
-  /**
-   * 组件方法
-   */
-  methods: {
-    /**
-     * 初始化表单配置
-     */
-    initFormOption() {
-      this.formOption = getFormOption(this.isEdit)
-    },
-
-    /**
-     * 初始化表单数据
-     */
-    initFormData() {
-        if (this.isEdit && this.editData) {
-          // 编辑模式:使用传入的数据,确保year字段为字符串格式
-          this.formData = { 
-            ...this.editData,
-            year: this.editData.year ? this.editData.year.toString() : ''
-          }
-      } else {
-        // 新增模式:使用默认数据,自动填入下个月
-        const now = new Date()
-        const currentYear = now.getFullYear()
-        const currentMonth = now.getMonth() + 1
-        
-        let nextYear, nextMonth
-        if (currentMonth === 12) {
-          // 当前是12月,下个月是明年1月
-          nextYear = currentYear + 1
-          nextMonth = 1
-        } else {
-          // 其他月份,直接 +1
-          nextYear = currentYear
-          nextMonth = currentMonth + 1
-        }
-        
-        this.formData = {
-          forecastCode: '',
-          year: nextYear.toString(),
-          month: nextMonth,
-          customerId: '',
-          customerCode: '',
-          customerName: '',
-          brandId: '',
-          brandCode: '',
-          brandName: '',
-          itemId: '',
-          itemCode: '',
-          itemName: '',
-          itemSpecs: '',
-          forecastQuantity: 1,
-          currentInventory: '',
-          approvalStatus: '',
-          approvalRemark: ''
-        }
-        
-        // 生成预测编码
-        this.generateForecastCode()
-      }
-    },
-
-    /**
-     * 生成预测编码
-     */
-    generateForecastCode() {
-      const now = new Date()
-      const year = this.formData.year || now.getFullYear()
-      const month = this.formData.month || (now.getMonth() + 1)
-      const monthStr = month.toString().padStart(2, '0')
-      const random = Math.floor(1000 + Math.random() * 9000) // 生成1000-9999之间的随机数
-      
-      this.formData.forecastCode = `FC-${year}${monthStr}-${random}`
-    },
-
-    /**
-     * 客户选择事件处理
-     */
-    handleCustomerSelected(customerData) {
-      if (customerData && customerData.customerId) {
-        this.formData.customerId = customerData.customerId
-        this.formData.customerCode = customerData.customerCode
-        this.formData.customerName = customerData.customerName
-      } else {
-        this.formData.customerId = ''
-        this.formData.customerCode = ''
-        this.formData.customerName = ''
-      }
-    },
-
-    /**
-     * 品牌变更处理
-     */
-    handleBrandChange(brandId) {
-      const selectedBrand = this.brandOptions.find(brand => brand.id === brandId)
-      if (selectedBrand) {
-        this.formData.brandCode = selectedBrand.code
-        this.formData.brandName = selectedBrand.name
-      } else {
-        this.formData.brandCode = ''
-        this.formData.brandName = ''
-      }
-    },
-
-    /**
-     * 物料变更处理
-     */
-    handleItemChange(itemId) {
-      const selectedItem = this.itemOptions.find(item => item.id === itemId)
-      if (selectedItem) {
-        this.formData.itemCode = selectedItem.code
-        this.formData.itemName = selectedItem.name
-        this.formData.itemSpecs = selectedItem.specs || ''
-        // 获取当前库存
-        this.getCurrentInventory(itemId)
-      } else {
-        this.formData.itemCode = ''
-        this.formData.itemName = ''
-        this.formData.itemSpecs = ''
-        this.currentInventory = null
-      }
-    },
-
-    /**
-     * 物料选择处理
-     * @description 处理MaterialSelect组件的物料选择事件
-     * @param {Object} materialData - 物料选择数据
-     */
-    handleMaterialSelected(materialData) {
-      if (materialData && materialData.itemId) {
-        this.formData.itemId = materialData.itemId
-        this.formData.itemCode = materialData.itemCode
-        this.formData.itemName = materialData.itemName
-        this.formData.itemSpecs = materialData.specification || ''
-        // 获取当前库存
-        this.getCurrentInventory(materialData.itemId)
-      } else {
-        this.formData.itemId = ''
-        this.formData.itemCode = ''
-        this.formData.itemName = ''
-        this.formData.itemSpecs = ''
-        this.currentInventory = null
-      }
-    },
-
-    /**
-     * 获取当前库存
-     * @param {string} itemId - 物料ID
-     */
-    getCurrentInventory(itemId) {
-      // 简化实现,实际应该调用API
-      setTimeout(() => {
-        // 模拟随机库存数量
-        this.currentInventory = Math.floor(Math.random() * 1000)
-      }, 300)
-    },
-
-    /**
-     * 表单提交处理
-     */
-    handleSubmit() {
-      // 表单验证
-      this.$refs.forecastForm.validate((valid) => {
-        if (!valid) {
-          return
-        }
-        this.submitForm()
-      })
-    },
-
-    /**
-     * 执行表单提交
-     */
-    async submitForm() {
-      try {
-
-        // 提交数据
-        const submitData = { ...this.formData }
-        
-        let res
-        if (this.isEdit) {
-          res = await updateForecast(submitData)
-        } else {
-          res = await addForecast(submitData)
-        }
-
-        // 触发提交成功事件,传递API响应数据
-        this.$emit('submit', res.data)
-      } catch (error) {
-        console.error('提交表单失败:', error)
-        this.$message.error(error.message || '操作失败,请重试')
-      }
-    },
-
-    /**
-     * 表单重置处理
-     */
-    handleReset() {
-      this.initFormData()
-      this.currentInventory = null
-      this.$emit('reset')
-    },
-
-    /**
-     * 获取审批状态标签
-     */
-    getApprovalStatusLabel,
-
-    /**
-     * 获取审批状态类型
-     */
-    getApprovalStatusType
   }
 }
 </script>