Browse Source

feat(订单表单): 新增导入物料前自动保存订单功能

yz 2 weeks ago
parent
commit
c985d2cf4d

+ 27 - 2
src/components/order-form/material-detail-mixin.js

@@ -120,6 +120,16 @@ export default {
     showTemplateImportActions: {
       type: Boolean,
       default: true
+    },
+
+    /**
+     * 确保已获取订单ID(用于新增态导入前自动保存)
+     * @description 当 orderId 为空时,上传前会调用该函数尝试先保存订单并返回订单ID
+     * @type {import('vue').PropOptions<null | (() => Promise<string|number|null|undefined>)>}
+     */
+    ensureOrderId: {
+      type: Function,
+      default: null
     }
   },
 
@@ -669,7 +679,22 @@ export default {
      * @this {MaterialDetailTableComponent & Vue}
      */
     async uploadSalesOrderFile(file) {
-      if (!this.orderId) {
+      /** @type {string|number|null|undefined} */
+      let targetOrderId = this.orderId
+      if (!targetOrderId && typeof this.ensureOrderId === 'function') {
+        try {
+          this.$message && this.$message.info('新增订单导入前需要先保存订单,正在保存...')
+          const ensured = await this.ensureOrderId()
+          targetOrderId = ensured || this.orderId
+        } catch (e) {
+          // 保存失败或被取消
+          console.error('导入前保存订单失败:', e)
+          this.$message && this.$message.error('保存订单失败,无法导入,请先手动保存后重试')
+          return
+        }
+      }
+
+      if (!targetOrderId) {
         this.$message && this.$message.warning('请先保存订单获取订单ID后再上传')
         return
       }
@@ -682,7 +707,7 @@ export default {
 
       try {
         this.uploadLoading = true
-        const response = await importSalesOrderById(this.orderId, file)
+        const response = await importSalesOrderById(targetOrderId, file)
         const success = response?.data?.success
         const data = response?.data?.data
         const message = response?.data?.msg || response?.data?.message

+ 31 - 11
src/components/order-form/order-form-mixin.js

@@ -937,14 +937,14 @@ export default {
      */
     async handleSave() {
       if (this.saveLoading) {
-        return // 防止重复提交
+        return null // 防止重复提交
       }
 
       try {
         // 表单验证
         const isValid = await this.validateForm()
         if (!isValid) {
-          return
+          return null
         }
 
         // 库存校验:订单数量不得超过可用数量(可用数量=storeInventory 映射而来)
@@ -985,6 +985,15 @@ export default {
         const successMessage = this.isEdit ? '订单更新成功' : '订单创建成功'
         this.$message.success(successMessage)
 
+        // 尽早同步ID到本地表单,便于新增态后续操作(如导入)使用
+        const responseData = response && response.data ? response.data.data : null
+        const savedId = (typeof responseData === 'string' || typeof responseData === 'number')
+          ? responseData
+          : (responseData && responseData.id)
+        if (savedId) {
+          this.formData.id = String(savedId)
+        }
+
         /**
          * 保存成功事件
          * @event typeof ORDER_FORM_EVENTS.SAVE_SUCCESS
@@ -1001,23 +1010,21 @@ export default {
         // 新增模式:保存成功后使用返回的订单ID加载订单详情并切换到编辑模式
         // 编辑模式:保存成功后刷新订单详情,已保存的物料置为不可删除
         if (this.isEdit) {
-          const savedId = (response && response.data && response.data.data && response.data.data.id) || this.orderId || (this.formData && this.formData.id)
-          if (savedId) {
-            await this.loadOrderDetail(String(savedId))
+          const targetId = savedId || this.orderId || (this.formData && this.formData.id)
+          if (targetId) {
+            await this.loadOrderDetail(String(targetId))
           }
         } else {
           // 新增模式:使用接口返回的订单ID加载订单详情并切换到编辑模式
-          const newOrderId = response && response.data && response.data.data
-          if (newOrderId) {
-            // 设置订单ID,触发编辑模式
-            this.orderId = String(newOrderId)
-            // 加载订单详情数据
-            await this.loadOrderDetail(String(newOrderId))
+          if (savedId) {
+            // 加载订单详情数据(父组件会基于 save-success 切换到编辑模式并回传 orderId)
+            await this.loadOrderDetail(String(savedId))
             // 可选:显示成功提示,告知用户已切换到编辑模式
             this.$message.success('订单创建成功,已自动切换到编辑模式')
           }
         }
 
+        return savedId ? String(savedId) : null
       } catch (error) {
         const errorMessage = this.isEdit ? '订单更新失败,请重试' : '订单创建失败,请重试'
         this.$message.error(errorMessage)
@@ -1028,6 +1035,19 @@ export default {
     },
 
     /**
+     * 确保已获取订单ID(用于新增态导入前自动保存)
+     * @returns {Promise<string|number|null>}
+     * @this {import('./types').OrderFormMixinComponent}
+     */
+    async ensureOrderIdForImport() {
+      const existing = this.orderId || (this.formData && this.formData.id)
+      if (existing) return existing
+
+      const createdId = await this.handleSave()
+      return createdId || this.orderId || (this.formData && this.formData.id) || null
+    },
+
+    /**
      * 判断订单是否可以提交到U9
      * @description 仅草稿(0)和未提交(1)状态允许提交
      * @param {import('./types').OrderFormModel | any} row - 订单数据对象

+ 2 - 1
src/components/order-form/order-form.vue

@@ -55,10 +55,11 @@
       <!-- 物料明细区域 -->
       <div class="material-detail-section">
         <material-detail-table
-          :order-id="orderId"
+          :order-id="orderId || (formData && formData.id)"
           :edit-mode="true"
           :material-details="materialDetails"
           :is-draft="isDraft"
+          :ensure-order-id="ensureOrderIdForImport"
           @refresh="handleMaterialChange"
           @material-import="handleMaterialImport"
           @material-delete="handleMaterialDelete"

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

@@ -224,7 +224,9 @@ export interface OrderFormMixinMethods {
   /** 处理返回 */
   handleBack(): void;
   /** 处理保存 */
-  handleSave(): Promise<void>;
+  handleSave(): Promise<string | null>;
+  /** 新增态导入前确保订单ID */
+  ensureOrderIdForImport(): Promise<string | number | null>;
   /** 提交订单数据 */
   submitOrderData(submitData: OrderFormData): Promise<import("@/api/types/order").SalesOrderCreateResponse>;
   /** 准备销售订单数据 */
@@ -453,7 +455,9 @@ export interface OrderFormMethods {
   /** 处理返回操作 */
   handleBack(): void;
   /** 处理保存操作 */
-  handleSave(): Promise<void>;
+  handleSave(): Promise<string | null>;
+  /** 新增态导入前确保订单ID */
+  ensureOrderIdForImport(): Promise<string | number | null>;
   /** 提交订单数据 */
   submitOrderData(submitData: any): Promise<ApiResponse>;
   /** 验证表单 */
@@ -639,6 +643,8 @@ export interface MaterialDetailTableComponent extends Vue {
   editMode: boolean;
   showTemplateImportActions: boolean;
   orderId: string | number | null;
+  /** 新增态导入前用于自动保存并返回订单ID */
+  ensureOrderId?: () => Promise<string | number | null | undefined>;
   materialDetails: MaterialDetailRecord[];
   isDraft: boolean;