mlchen 2 giorni fa
parent
commit
c09c699146

+ 12 - 0
src/views/warehouseManagement/stockBatchChangeRecord/components/BatchChangeRecord.vue

@@ -0,0 +1,12 @@
+<template>
+  <BatchChangeDialog standalone />
+</template>
+
+<script>
+  import BatchChangeDialog from '@/views/warehouseManagement/stockLedger/components/BatchChangeDialog.vue';
+
+  export default {
+    name: 'BatchChangeRecord',
+    components: { BatchChangeDialog }
+  };
+</script>

+ 20 - 0
src/views/warehouseManagement/stockBatchChangeRecord/index.vue

@@ -0,0 +1,20 @@
+<template>
+  <el-card shadow="never" class="stock-batch-change-record">
+    <BatchChangeRecord />
+  </el-card>
+</template>
+
+<script>
+  import BatchChangeRecord from './components/BatchChangeRecord.vue';
+
+  export default {
+    name: 'StockBatchChangeRecord',
+    components: { BatchChangeRecord }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .stock-batch-change-record {
+    min-height: calc(100vh - 116px);
+  }
+</style>

+ 156 - 19
src/views/warehouseManagement/stockLedger/components/BatchChangeDialog.vue

@@ -1,5 +1,7 @@
 <template>
-  <el-dialog
+  <component
+    :is="standalone ? 'div' : 'el-dialog'"
+    class="batch-change-dialog"
     :title="dialogTitle"
     :visible.sync="visible"
     width="92%"
@@ -9,12 +11,12 @@
     <template v-if="mode === 'records'">
       <el-form
         size="mini"
-        label-width="72px"
-        class="record-search"
+        label-width="78px"
+        class="record-search ele-form-search"
         @submit.native.prevent="searchRecords"
       >
         <el-row :gutter="16">
-          <el-col :xs="24" :md="12" :lg="5">
+          <el-col :xs="24" :sm="12" :md="8" :lg="6">
             <el-form-item label="审核代码">
               <el-input
                 v-model="recordQuery.changeNo"
@@ -23,7 +25,7 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :md="12" :lg="5">
+          <el-col :xs="24" :sm="12" :md="8" :lg="6">
             <el-form-item label="审批人">
               <el-input
                 v-model="recordQuery.approverName"
@@ -32,7 +34,7 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :md="12" :lg="5">
+          <el-col :xs="24" :sm="12" :md="8" :lg="6">
             <el-form-item label="仓库名称">
               <el-input
                 v-model="recordQuery.warehouseName"
@@ -41,7 +43,7 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :md="12" :lg="5">
+          <el-col :xs="24" :sm="12" :md="8" :lg="6">
             <el-form-item label="批次号">
               <el-input
                 v-model="recordQuery.batchNo"
@@ -50,7 +52,7 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :md="12" :lg="5">
+          <el-col :xs="24" :sm="12" :md="8" :lg="6">
             <el-form-item label="物品编码">
               <el-input
                 v-model="recordQuery.categoryCode"
@@ -59,7 +61,7 @@
               />
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :md="12" :lg="5">
+          <el-col :xs="24" :sm="12" :md="8" :lg="6">
             <el-form-item label="类型">
               <el-select
                 v-model="recordQuery.changeType"
@@ -71,7 +73,7 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :md="12" :lg="5">
+          <el-col :xs="24" :sm="12" :md="8" :lg="6">
             <el-form-item label="审批状态">
               <el-select
                 v-model="recordQuery.verifyStatus"
@@ -87,9 +89,29 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :xs="24" :lg="4" class="record-search-actions">
-            <el-button type="primary" @click="searchRecords">查询</el-button>
-            <el-button @click="resetRecordQuery">重置</el-button>
+          <el-col
+            :xs="24"
+            :sm="12"
+            :md="8"
+            :lg="6"
+            :sm-offset="0"
+            :md-offset="16"
+            :lg-offset="18"
+            class="record-search-actions"
+          >
+            <el-button
+              type="primary"
+              icon="el-icon-search"
+              class="ele-btn-icon"
+              @click="searchRecords"
+              >查询</el-button
+            >
+            <el-button
+              type="primary"
+              icon="el-icon-refresh-left"
+              @click="resetRecordQuery"
+              >重置</el-button
+            >
           </el-col>
         </el-row>
       </el-form>
@@ -129,13 +151,14 @@
       <el-alert
         v-if="mode === 'merge'"
         title="仅允许同仓库、批次号、物品属性、供应商和价格完全一致的库存合批,审批通过后生成新系统批次。"
-        style="color: red"
+        style="color:red"
         type="info"
         :closable="false"
       />
       <el-alert
         v-else
         title="包装明细必须整行分配;锁定明细按锁定单分配,关联包装时自动跟随包装目标。"
+        style="color:red"
         type="info"
         :closable="false"
       />
@@ -261,6 +284,18 @@
             @click="assignSelectedPackingTarget"
             >批量分配</el-button
           >
+          <el-button
+            size="mini"
+            :disabled="Boolean(pendingApproveId)"
+            @click="assignAllPackingTargets"
+            >一键分配</el-button
+          >
+          <el-button
+            size="mini"
+            :disabled="Boolean(pendingApproveId)"
+            @click="clearPackingTargets"
+            >清空分配</el-button
+          >
         </div>
         <el-table
           ref="packingTable"
@@ -274,6 +309,8 @@
             v-if="mode === 'split'"
             type="selection"
             width="45"
+            align="center"
+            header-align="center"
             :selectable="packingRowSelectable"
           />
           <el-table-column
@@ -354,7 +391,7 @@
       />
     </div>
 
-    <span slot="footer">
+    <span v-if="!standalone" slot="footer">
       <el-button @click="visible = false">取 消</el-button>
       <el-button
         v-if="mode !== 'records'"
@@ -542,7 +579,7 @@
         </el-tab-pane>
       </el-tabs>
     </el-dialog>
-  </el-dialog>
+  </component>
 </template>
 
 <script>
@@ -579,6 +616,12 @@
 
   export default {
     components: { bpmDetail },
+    props: {
+      standalone: {
+        type: Boolean,
+        default: false
+      }
+    },
     data() {
       return {
         visible: false,
@@ -607,6 +650,9 @@
         }
       };
     },
+    mounted() {
+      if (this.standalone) this.open('records');
+    },
     computed: {
       detailProcessInstanceId() {
         return (
@@ -965,6 +1011,87 @@
           });
         });
       },
+      /** 按所有目标子批次的计量数量依次匹配整包装。 */
+      assignAllPackingTargets() {
+        if (this.pendingApproveId) return;
+        const availableRows = this.packingRows.filter(
+          (row) => !row.targetDetailId
+        );
+        const assignments = [];
+        for (const target of this.targets) {
+          const assignedMeasureQuantity = this.packingRows
+            .filter((row) => row.targetDetailId === target.targetDetailId)
+            .reduce(
+              (sum, row) => sum.plus(decimal(row.measureQuantity)),
+              new BigNumber(0)
+            );
+          const remainingMeasureQuantity = decimal(
+            target.measureQuantity
+          ).minus(assignedMeasureQuantity);
+          if (remainingMeasureQuantity.lte(0)) continue;
+
+          const selectedRows = this.findPackingCombination(
+            availableRows,
+            remainingMeasureQuantity
+          );
+          if (!selectedRows.length) {
+            return this.$message.warning(
+              `${this.targetLabel(
+                target.targetDetailId
+              )}没有可按计量数量分配的整包装`
+            );
+          }
+          assignments.push({
+            target,
+            selectedRows
+          });
+          selectedRows.forEach((packing) => {
+            availableRows.splice(availableRows.indexOf(packing), 1);
+          });
+        }
+
+        assignments.forEach(({ target, selectedRows }) => {
+          selectedRows.forEach((packing) => {
+            packing.targetDetailId = target.targetDetailId;
+            this.assignPackingTarget(packing, target.targetDetailId, false);
+          });
+        });
+        this.syncTargetPackingMinimums();
+        this.selectedPackingRows = [];
+        if (this.$refs.packingTable) this.$refs.packingTable.clearSelection();
+        if (assignments.some(({ selectedRows }) => selectedRows.length)) {
+          this.$message.success('已按所有目标计量数量自动分配整包装');
+        }
+      },
+      /** 清除所有包装和锁定单的目标分配,保留目标数量输入。 */
+      clearPackingTargets() {
+        if (this.pendingApproveId) return;
+        this.packingRows.forEach((packing) => {
+          packing.targetDetailId = null;
+        });
+        this.lockRows.forEach((lock) => {
+          lock.targetDetailId = null;
+          lock.targetConflict = false;
+        });
+        this.selectedPackingRows = [];
+        if (this.$refs.packingTable) this.$refs.packingTable.clearSelection();
+        this.$message.success('已清空全部分配');
+      },
+      findPackingCombination(rows, targetQuantity) {
+        const selected = [];
+        const search = (start, quantity) => {
+          if (quantity.eq(0)) return true;
+          for (let index = start; index < rows.length; index += 1) {
+            const packingQuantity = decimal(rows[index].measureQuantity);
+            if (packingQuantity.gt(quantity)) continue;
+            selected.push(rows[index]);
+            if (search(index + 1, quantity.minus(packingQuantity))) return true;
+            selected.pop();
+          }
+          return false;
+        };
+        return search(0, targetQuantity) ? selected.slice() : [];
+      },
       /** 包装分配变化时,同步其关联锁定单的全部明细和包装。 */
       assignPackingTarget(packing, targetDetailId, shouldSync = true) {
         const relatedLocks = this.lockRows.filter((lock) =>
@@ -1439,7 +1566,7 @@
 
 <style scoped>
   .record-search {
-    padding: 14px 16px 2px;
+    padding: 12px 14px 2px;
     margin-bottom: 12px;
     background-color: #f5f7fa;
     border: 1px solid #ebeef5;
@@ -1448,17 +1575,27 @@
   .record-search :deep(.el-select) {
     width: 100%;
   }
+  .record-search :deep(.el-form-item) {
+    margin-bottom: 12px;
+  }
   .record-search-actions {
     display: flex;
     justify-content: flex-end;
-    padding-top: 1px;
+    align-items: flex-start;
+    gap: 8px;
+    padding-top: 0;
   }
   @media (max-width: 1199px) {
     .record-search-actions {
-      justify-content: flex-start;
+      justify-content: flex-end;
       padding: 0 8px 12px;
     }
   }
+  @media (max-width: 767px) {
+    .record-search-actions {
+      justify-content: flex-start;
+    }
+  }
   .section-title {
     margin: 14px 0 8px;
     font-weight: 600;

+ 0 - 7
src/views/warehouseManagement/stockLedger/components/item-list.vue

@@ -95,13 +95,6 @@
             @click="openBatchChange('merge')"
             >合批申请</el-button
           >
-          <el-button
-            v-if="selectedDime == 2"
-            size="small"
-            icon="el-icon-document"
-            @click="openBatchChange('records')"
-            >批次变更记录</el-button
-          >
         </div>
 
         <!-- <el-button