From 4b9403d9f405d11342290a02a0c5148d01a033b3 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期二, 17 三月 2026 16:06:23 +0800
Subject: [PATCH] fix: 库存报表页面未做页码分页(仓储物流的入库管理也没有分页)

---
 src/views/inventoryManagement/stockManagement/New.vue       |    8 ++
 src/views/basicData/product/ProductSelectDialog.vue         |   29 ++++++++-
 src/views/consumablesLogistics/stockManagement/Subtract.vue |   20 ++++++
 src/views/consumablesLogistics/stockReport/index.vue        |   39 ++++++++++++
 src/views/consumablesLogistics/stockManagement/New.vue      |    1 
 src/views/inventoryManagement/stockManagement/Subtract.vue  |   20 ++++++
 src/views/inventoryManagement/stockReport/index.vue         |   42 ++++++++++++-
 7 files changed, 144 insertions(+), 15 deletions(-)

diff --git a/src/views/basicData/product/ProductSelectDialog.vue b/src/views/basicData/product/ProductSelectDialog.vue
index 229cf87..6a30381 100644
--- a/src/views/basicData/product/ProductSelectDialog.vue
+++ b/src/views/basicData/product/ProductSelectDialog.vue
@@ -2,7 +2,13 @@
   <el-dialog v-model="visible" title="閫夋嫨浜у搧" width="900px" destroy-on-close :close-on-click-modal="false">
     <el-form :inline="true" :model="query" class="mb-2">
       <el-form-item label="浜у搧澶х被">
-        <el-input v-model="query.productName" placeholder="杈撳叆浜у搧澶х被" clearable @keyup.enter="onSearch" />
+        <el-input
+          v-model="query.productName"
+          placeholder="杈撳叆浜у搧澶х被"
+          clearable
+          :disabled="Boolean(props.fixedProductName)"
+          @keyup.enter="onSearch"
+        />
       </el-form-item>
 
       <el-form-item label="鍨嬪彿鍚嶇О">
@@ -44,7 +50,7 @@
 <script setup lang="ts">
 import { computed, onMounted, reactive, ref, watch, nextTick } from "vue";
 import { ElMessage } from "element-plus";
-import { productModelList } from '@/api/basicData/productModel'
+import { productModelList } from "../../../api/basicData/productModel.js";
 
 export type ProductRow = {
   id: number;
@@ -56,6 +62,8 @@
 const props = defineProps<{
   modelValue: boolean;
   single?: boolean; // 鏄惁鍙兘閫夋嫨涓�涓紝榛樿false锛堝彲閫夋嫨澶氫釜锛�
+  fixedProductName?: string; // 鍥哄畾鈥滀骇鍝佸ぇ绫烩�濈瓫閫夛紙渚嬪锛氳�楁潗锛夛紝浼犲叆鍚庝笉鍙紪杈戜笖閲嶇疆涓嶆竻绌�
+  excludeParentNames?: string[]; // 鎺掗櫎鈥滅被鍨嬧��(parentName)锛屼緥濡傦細['鑰楁潗']锛堜粎浼犲叆鏃剁敓鏁堬級
 }>();
 
 const emit = defineEmits(['update:modelValue', 'confirm']);
@@ -128,7 +136,7 @@
 }
 
 function onReset() {
-  query.productName = "";
+  query.productName = props.fixedProductName ? props.fixedProductName : "";
   query.model = "";
   page.pageNum = 1;
   loadData();
@@ -161,8 +169,13 @@
       current: page.pageNum,
       size: page.pageSize,
     });
-    tableData.value = res.records;
-    total.value = res.total;
+    const records = (res?.records || []) as any[];
+    const exclude = (props.excludeParentNames || []).filter(Boolean);
+    const filtered = exclude.length
+      ? records.filter((r) => !exclude.includes(String(r?.parentName ?? "")))
+      : records;
+    tableData.value = filtered;
+    total.value = exclude.length ? filtered.length : res.total;
   } finally {
     loading.value = false;
   }
@@ -172,6 +185,12 @@
 watch(() => props.modelValue, (visible) => {
   if (visible) {
     multipleSelection.value = [];
+    // 鍙湁浼犱簡 fixedProductName 鎵嶅惎鐢ㄢ�滃浐瀹氬ぇ绫荤瓫閫夆�濈殑鐗规畩閫昏緫锛屽叾瀹冨満鏅繚鎸佸師琛屼负涓嶅彉
+    if (props.fixedProductName) {
+      query.productName = props.fixedProductName;
+      page.pageNum = 1;
+      loadData();
+    }
   }
 });
 
diff --git a/src/views/consumablesLogistics/stockManagement/New.vue b/src/views/consumablesLogistics/stockManagement/New.vue
index 2100186..30191f8 100644
--- a/src/views/consumablesLogistics/stockManagement/New.vue
+++ b/src/views/consumablesLogistics/stockManagement/New.vue
@@ -120,6 +120,7 @@
       <!-- 浜у搧閫夋嫨寮圭獥 -->
       <ProductSelectDialog
           v-model="showProductSelectDialog"
+          fixedProductName="鑰楁潗"
           @confirm="handleProductSelect"
           single
       />
diff --git a/src/views/consumablesLogistics/stockManagement/Subtract.vue b/src/views/consumablesLogistics/stockManagement/Subtract.vue
index 5598000..8e7961d 100644
--- a/src/views/consumablesLogistics/stockManagement/Subtract.vue
+++ b/src/views/consumablesLogistics/stockManagement/Subtract.vue
@@ -158,6 +158,11 @@
   return props.record.parentName === '鍘熸潗鏂�';
 })
 
+const ledgerNetWeight = computed(() => {
+  const n = Number(props.record?.netWeight ?? 0);
+  return Number.isFinite(n) ? n : 0;
+});
+
 const initFormData = () => {
   if (props.record) {
     formState.value = {
@@ -221,7 +226,14 @@
   if (grossWeight != null && tareWeight != null) {
     const net = Number(grossWeight) - Number(tareWeight);
     const safeNet = Number(net.toFixed(2));
-    formState.value.netWeight = safeNet > 0 ? safeNet : 0;
+    const computedNet = safeNet > 0 ? safeNet : 0;
+    const maxNet = ledgerNetWeight.value;
+    if (Number.isFinite(maxNet) && maxNet > 0 && computedNet > maxNet) {
+      formState.value.netWeight = Number(maxNet.toFixed(2));
+      proxy?.$modal?.msgWarning?.(`棰嗙敤鍑�閲嶄笉鑳借秴杩囧彴璐﹀噣閲嶏紙${maxNet.toFixed(2)} 鍚級`);
+      return;
+    }
+    formState.value.netWeight = computedNet;
   } else {
     formState.value.netWeight = undefined;
   }
@@ -255,6 +267,12 @@
         proxy.$modal.msgError("璇烽�夋嫨瑙勬牸");
         return;
       }
+      const maxNet = ledgerNetWeight.value;
+      const usedNet = Number(formState.value.netWeight ?? 0);
+      if (Number.isFinite(maxNet) && maxNet > 0 && Number.isFinite(usedNet) && usedNet > maxNet) {
+        proxy.$modal.msgError(`棰嗙敤鍑�閲嶄笉鑳借秴杩囧彴璐﹀噣閲嶏紙${maxNet.toFixed(2)} 鍚級`);
+        return;
+      }
       if (props.type === 'qualified') {
         subtractConsumablesIn(formState.value).then(res => {
           // 鍏抽棴妯℃�佹
diff --git a/src/views/consumablesLogistics/stockReport/index.vue b/src/views/consumablesLogistics/stockReport/index.vue
index 0305289..3daddfc 100644
--- a/src/views/consumablesLogistics/stockReport/index.vue
+++ b/src/views/consumablesLogistics/stockReport/index.vue
@@ -235,6 +235,19 @@
              show-overflow-tooltip
            />
         </el-table>
+
+        <div style="margin-top: 12px; display: flex; justify-content: flex-end;">
+          <el-pagination
+            background
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="page.total"
+            v-model:page-size="page.size"
+            v-model:current-page="page.current"
+            :page-sizes="[10, 20, 50, 100]"
+            @size-change="handlePageChange"
+            @current-change="handlePageChange"
+          />
+        </div>
       </el-card>
     </div>
   </div>
@@ -272,6 +285,16 @@
   tableData: []
 })
 
+const page = reactive({
+  current: 1,
+  size: 10,
+  total: 0,
+})
+
+const handlePageChange = () => {
+  fetchList()
+}
+
 const stockRecordTypeOptions = ref([])
 
 const getRecordType = (recordType) => {
@@ -306,7 +329,7 @@
 }
 
 // 鏌ヨ鏁版嵁
-const handleQuery = async () => {
+const fetchList = async () => {
   if (!validateSearchForm()) {
     return
   }
@@ -323,6 +346,7 @@
     }
     if (response.code === 200) {
       reportData.value.tableData = response.data.records
+      page.total = Number(response.data.total ?? 0) || 0
       // reportData.value.summary = response.data.summary
       // reportData.value.chartData = response.data.chartData
       // nextTick(() => {
@@ -335,6 +359,12 @@
   } finally {
     tableLoading.value = false
   }
+}
+
+// 鏌ヨ鏁版嵁锛堟寜閽Е鍙戯細鍥炲埌绗竴椤碉級
+const handleQuery = () => {
+  page.current = 1
+  fetchList()
 }
 // // 鐢熸垚鍋囨暟鎹�
 // const generateMockData = () => {
@@ -396,7 +426,9 @@
     startMonth: "",
     endMonth: "",
     startDate: "",
-    endDate: ""
+    endDate: "",
+    current: page.current,
+    size: page.size,
   }
   
   if (searchForm.reportType === 'daily') {
@@ -418,6 +450,9 @@
   searchForm.singleDate = ''
   searchForm.dateRange = []
   searchForm.monthRange = []
+  page.current = 1
+  page.size = 10
+  page.total = 0
   reportData.value = {
     summary: null,
     chartData: null,
diff --git a/src/views/inventoryManagement/stockManagement/New.vue b/src/views/inventoryManagement/stockManagement/New.vue
index 22b8a3e..22e73ac 100644
--- a/src/views/inventoryManagement/stockManagement/New.vue
+++ b/src/views/inventoryManagement/stockManagement/New.vue
@@ -37,9 +37,9 @@
           <el-input v-model="formState.unit"  disabled />
         </el-form-item>
 
-        <!-- productType === 1锛氬崐鎴愬搧锛堝厑璁告墜鍔ㄥ~鍐欐暟閲忓叆搴擄級 -->
+        <!-- 鍗婃垚鍝侊細鍏佽鎵嬪姩濉啓鏁伴噺鍏ュ簱 -->
         <el-form-item
-            v-if="type === 'qualified' && formState.productType === 1"
+            v-if="type === 'qualified' && (formState.parentName === '鍗婃垚鍝�' || formState.productType === 1)"
             label="鏁伴噺"
             prop="qualitity"
             :rules="[
@@ -140,6 +140,7 @@
       <!-- 浜у搧閫夋嫨寮圭獥 -->
       <ProductSelectDialog
           v-model="showProductSelectDialog"
+          :excludeParentNames="['鑰楁潗']"
           @confirm="handleProductSelect"
           single
       />
@@ -182,6 +183,7 @@
   productModelName: "",
   unit: "",
   productType: undefined,
+  parentName: "",
   // 搴撳瓨鏁伴噺锛堝崐鎴愬搧鍚堟牸鍏ュ簱鍙墜鍔ㄥ~鍐欙級
   qualitity: undefined,
   // 杩囩鐩稿叧瀛楁锛堜粎鍘熸潗鏂欏悎鏍煎搧浣跨敤锛�
@@ -216,6 +218,7 @@
     productModelName: "",
     unit: "",
     productType: undefined,
+    parentName: "",
     qualitity: undefined,
     licensePlateNo: "",
     grossWeight: undefined,
@@ -243,6 +246,7 @@
     formState.value.productModelId = product.id;
     formState.value.unit = product.unit;
     formState.value.productType = product.productType;
+    formState.value.parentName = product.parentName || "";
     showProductSelectDialog.value = false;
     // 瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
     proxy.$refs["formRef"]?.validateField('productModelId');
diff --git a/src/views/inventoryManagement/stockManagement/Subtract.vue b/src/views/inventoryManagement/stockManagement/Subtract.vue
index d23c974..88cfad3 100644
--- a/src/views/inventoryManagement/stockManagement/Subtract.vue
+++ b/src/views/inventoryManagement/stockManagement/Subtract.vue
@@ -158,6 +158,11 @@
   return props.record.parentName === '鍘熸潗鏂�';
 })
 
+const ledgerNetWeight = computed(() => {
+  const n = Number(props.record?.netWeight ?? 0);
+  return Number.isFinite(n) ? n : 0;
+});
+
 const initFormData = () => {
   if (props.record) {
     formState.value = {
@@ -221,7 +226,14 @@
   if (grossWeight != null && tareWeight != null) {
     const net = Number(grossWeight) - Number(tareWeight);
     const safeNet = Number(net.toFixed(2));
-    formState.value.netWeight = safeNet > 0 ? safeNet : 0;
+    const computedNet = safeNet > 0 ? safeNet : 0;
+    const maxNet = ledgerNetWeight.value;
+    if (Number.isFinite(maxNet) && maxNet > 0 && computedNet > maxNet) {
+      formState.value.netWeight = Number(maxNet.toFixed(2));
+      proxy?.$modal?.msgWarning?.(`棰嗙敤鍑�閲嶄笉鑳借秴杩囧彴璐﹀噣閲嶏紙${maxNet.toFixed(2)} 鍚級`);
+      return;
+    }
+    formState.value.netWeight = computedNet;
   } else {
     formState.value.netWeight = undefined;
   }
@@ -255,6 +267,12 @@
         proxy.$modal.msgError("璇烽�夋嫨瑙勬牸");
         return;
       }
+      const maxNet = ledgerNetWeight.value;
+      const usedNet = Number(formState.value.netWeight ?? 0);
+      if (Number.isFinite(maxNet) && maxNet > 0 && Number.isFinite(usedNet) && usedNet > maxNet) {
+        proxy.$modal.msgError(`棰嗙敤鍑�閲嶄笉鑳借秴杩囧彴璐﹀噣閲嶏紙${maxNet.toFixed(2)} 鍚級`);
+        return;
+      }
       if (props.type === 'qualified') {
         subtractStockInventory(formState.value).then(res => {
           // 鍏抽棴妯℃�佹
diff --git a/src/views/inventoryManagement/stockReport/index.vue b/src/views/inventoryManagement/stockReport/index.vue
index 5e9dfb5..61196e4 100644
--- a/src/views/inventoryManagement/stockReport/index.vue
+++ b/src/views/inventoryManagement/stockReport/index.vue
@@ -235,13 +235,26 @@
              show-overflow-tooltip
            />
         </el-table>
+
+        <div style="margin-top: 12px; display: flex; justify-content: flex-end;">
+          <el-pagination
+            background
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="page.total"
+            v-model:page-size="page.size"
+            v-model:current-page="page.current"
+            :page-sizes="[10, 20, 50, 100]"
+            @size-change="handlePageChange"
+            @current-change="handlePageChange"
+          />
+        </div>
       </el-card>
     </div>
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, nextTick } from 'vue'
+import { ref, reactive, onMounted, nextTick, getCurrentInstance } from 'vue'
 import { ElMessage } from 'element-plus'
 import * as echarts from 'echarts'
 import {
@@ -271,6 +284,16 @@
   chartData: null,
   tableData: []
 })
+
+const page = reactive({
+  current: 1,
+  size: 10,
+  total: 0,
+})
+
+const handlePageChange = () => {
+  fetchList()
+}
 
 const stockRecordTypeOptions = ref([])
 
@@ -305,8 +328,7 @@
   }
 }
 
-// 鏌ヨ鏁版嵁
-const handleQuery = async () => {
+const fetchList = async () => {
   if (!validateSearchForm()) {
     return
   }
@@ -323,6 +345,7 @@
     }
     if (response.code === 200) {
       reportData.value.tableData = response.data.records
+      page.total = Number(response.data.total ?? 0) || 0
       // reportData.value.summary = response.data.summary
       // reportData.value.chartData = response.data.chartData
       // nextTick(() => {
@@ -335,6 +358,12 @@
   } finally {
     tableLoading.value = false
   }
+}
+
+// 鏌ヨ鏁版嵁锛堟寜閽Е鍙戯細鍥炲埌绗竴椤碉級
+const handleQuery = () => {
+  page.current = 1
+  fetchList()
 }
 // // 鐢熸垚鍋囨暟鎹�
 // const generateMockData = () => {
@@ -396,7 +425,9 @@
     startMonth: "",
     endMonth: "",
     startDate: "",
-    endDate: ""
+    endDate: "",
+    current: page.current,
+    size: page.size,
   }
   
   if (searchForm.reportType === 'daily') {
@@ -418,6 +449,9 @@
   searchForm.singleDate = ''
   searchForm.dateRange = []
   searchForm.monthRange = []
+  page.current = 1
+  page.size = 10
+  page.total = 0
   reportData.value = {
     summary: null,
     chartData: null,

--
Gitblit v1.9.3