Sfoglia il codice sorgente

forecast-form: add row selection and batch delete; bind table events; guard inputs/buttons by canEditCurrentForm; update types

yz 2 mesi fa
parent
commit
be093b2e3e

+ 60 - 1
src/components/forecast-form/forecast-form-mixin.js

@@ -285,7 +285,10 @@ export default {
       selectedStockId: null,
 
       /** 当前库存 */
-      currentInventory: null
+      currentInventory: null,
+      // 批量选择的行集合
+      /** @type {Array<import('@/api/types/order').PjpfStockDesc & { forecastQuantity: number, brandCode?: string }>} */
+      selectedRows: []
     }
   },
 
@@ -305,6 +308,17 @@ export default {
         return this.title
       }
       return this.isEdit ? '编辑销售预测' : '新增销售预测'
+    },
+    /**
+     * 当前表单是否允许编辑(用于控制选择与批量删除)
+     * @returns {boolean}
+     */
+    canEditCurrentForm() {
+      try {
+        return canEdit(Number(this.formData.approvalStatus ?? 0))
+      } catch (e) {
+        return false
+      }
     }
   },
 
@@ -1283,6 +1297,51 @@ export default {
       }
     },
 
+    // 表格选择与批量删除相关方法
+    getRowKey(row) {
+      const keyId = row && (row.id != null ? row.id : row.goodsId)
+      return keyId != null ? String(keyId) : String(row.code || Math.random())
+    },
+    isRowSelectable(row, index) {
+      return this.canEditCurrentForm
+    },
+    handleSelectionChange(selection) {
+      this.selectedRows = Array.isArray(selection) ? selection.slice() : []
+    },
+    async handleBatchDelete() {
+      try {
+        if (!this.selectedRows || this.selectedRows.length === 0) {
+          this.$message && this.$message.warning('请先选择要删除的物料')
+          return
+        }
+        if (!this.canEditCurrentForm) {
+          this.$message && this.$message.warning('当前审批状态不允许编辑')
+          return
+        }
+        await this.$confirm(`确认删除所选的 ${this.selectedRows.length} 条物料吗?`, '提示', {
+          type: 'warning',
+          confirmButtonText: '删除',
+          cancelButtonText: '取消'
+        })
+        const keys = new Set(this.selectedRows.map(r => {
+          const id = r && (r.id != null ? r.id : r.goodsId)
+          return id != null ? String(id) : String(r.code)
+        }))
+        this.stockTableData = this.stockTableData.filter(r => {
+          const id = r && (r.id != null ? r.id : r.goodsId)
+          const key = id != null ? String(id) : String(r.code)
+          return !keys.has(key)
+        })
+        this.selectedRows = []
+        this.$message && this.$message.success('已删除所选物料')
+      } catch (e) {
+        if (e && e !== 'cancel') {
+          console.error('批量删除失败:', e)
+          this.$message && this.$message.error('批量删除失败,请稍后重试')
+        }
+      }
+    },
+
     /**
      * 品牌变更处理
      * @param {number} brandId - 品牌ID

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

@@ -79,6 +79,12 @@
               style="margin-left: 8px"
               @click="handleImportSelectedStock"
             >添加物料</el-button>
+<el-button
+  type="danger"
+  :disabled="selectedRows.length === 0 || !canEditCurrentForm"
+  style="margin-left: 8px"
+  @click="handleBatchDelete"
+>批量删除</el-button>
           </div>
 
           <el-table
@@ -87,7 +93,10 @@
             stripe
             height="360"
             v-loading="tableLoading"
+            @selection-change="handleSelectionChange"
+            :row-key="getRowKey"
           >
+            <el-table-column type="selection" width="44" :selectable="isRowSelectable" />
             <el-table-column prop="code" label="物料编码" min-width="140" show-overflow-tooltip />
             <el-table-column prop="cname" label="物料名称" min-width="160" show-overflow-tooltip />
             <el-table-column prop="brandName" label="品牌名称" min-width="120" show-overflow-tooltip />
@@ -107,6 +116,7 @@
                   :step="1"
                   controls-position="right"
                   style="width: 120px"
+                  :disabled="!canEditCurrentForm"
                 />
               </template>
             </el-table-column>
@@ -117,6 +127,7 @@
                   type="text"
                   size="small"
                   icon="el-icon-delete"
+                  :disabled="!canEditCurrentForm"
                   @click="handleDelete(row, $index)"
                 >删除</el-button>
               </template>

+ 12 - 0
src/components/forecast-form/types.d.ts

@@ -169,6 +169,8 @@ export interface ForecastFormMixinData {
   stockSelectOptions: Array<SelectOption<string>>;
   /** 当前选择待导入的物料ID */
   selectedStockId: string | null;
+  /** 已选择的表格行(用于批量删除) */
+  selectedRows: Array<Partial<import('@/api/types/order').PjpfStockDesc> & { forecastQuantity: number; brandCode?: string; storeInventory?: string }>;
 }
 
 /**
@@ -234,6 +236,8 @@ export interface ForecastFormProps {
 export interface ForecastFormComputed {
   /** 表单标题 */
   formTitle: string;
+  /** 当前表单是否可编辑(根据审批状态) */
+  canEditCurrentForm: boolean;
 }
 
 /**
@@ -258,6 +262,14 @@ export interface ForecastFormMethods {
   handleCustomerChange(customerId: string | number): void;
   /** 物料选择变化处理 */
   handleItemChange(itemId: string | number): void;
+  /** 表格行唯一键函数 */
+  getRowKey(row: Partial<import('@/api/types/order').PjpfStockDesc> & { forecastQuantity: number; brandCode?: string; storeInventory?: string }): string;
+  /** 行是否可选择(基于表单是否可编辑) */
+  isRowSelectable(row: Partial<import('@/api/types/order').PjpfStockDesc> & { forecastQuantity: number; brandCode?: string; storeInventory?: string }, index: number): boolean;
+  /** 选择变更事件处理 */
+  handleSelectionChange(selection: Array<Partial<import('@/api/types/order').PjpfStockDesc> & { forecastQuantity: number; brandCode?: string; storeInventory?: string }>): void;
+  /** 批量删除选中行 */
+  handleBatchDelete(): Promise<void>;
   /** 初始化表单配置 */
   initFormOption(): void;
   /** 初始化表单数据 */