From cc3001ab9e0ab8ce673b812a22ebea1edd332f2a Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期六, 14 三月 2026 15:38:33 +0800
Subject: [PATCH] fix: 完成仓储物流的功能开发

---
 src/pages/index.vue                                        |   85 +
 src/pages/inventoryManagement/receiptManagement/index.vue  |  576 ++++-----
 src/pages/inventoryManagement/stockReport/view.vue         |  173 ++
 src/api/basicData/enum.js                                  |   33 
 src/pages.json                                             |   65 +
 src/pages/inventoryManagement/stockReport/index.vue        |  274 ++++
 src/api/inventoryManagement/stockUninventory.js            |   46 
 src/pages/inventoryManagement/dispatchLog/view.vue         |  259 ++++
 src/pages/inventoryManagement/stockManagement/add.vue      |  426 +++++++
 src/api/inventoryManagement/stockInRecord.js               |   27 
 src/api/inventoryManagement/stockOutRecord.js              |   19 
 src/pages/inventoryManagement/stockManagement/index.vue    |  456 +++++++
 src/pages/inventoryManagement/receiptManagement/view.vue   |  260 ++++
 src/api/inventoryManagement/stockInventory.js              |   64 +
 src/pages/inventoryManagement/stockManagement/subtract.vue |  268 ++++
 src/api/basicData/productModel.js                          |   11 
 src/pages/inventoryManagement/stockManagement/view.vue     |  193 +++
 src/pages/inventoryManagement/dispatchLog/index.vue        |  333 +++++
 18 files changed, 3,254 insertions(+), 314 deletions(-)

diff --git a/src/api/basicData/enum.js b/src/api/basicData/enum.js
new file mode 100644
index 0000000..3f71b87
--- /dev/null
+++ b/src/api/basicData/enum.js
@@ -0,0 +1,33 @@
+import request from '@/utils/request'
+
+// 鍚堟牸鍏ュ簱鏉ユ簮绫诲瀷
+export function findAllQualifiedStockInRecordTypeOptions() {
+  return request({
+    url: '/basic/enum/StockInQualifiedRecordTypeEnum',
+    method: 'GET'
+  })
+}
+
+// 涓嶅悎鏍煎叆搴撴潵婧愮被鍨�
+export function findAllUnQualifiedStockInRecordTypeOptions() {
+  return request({
+    url: '/basic/enum/StockInUnQualifiedRecordTypeEnum',
+    method: 'GET'
+  })
+}
+
+// 鍚堟牸鍑哄簱鏉ユ簮绫诲瀷
+export function findAllQualifiedStockOutRecordTypeOptions() {
+  return request({
+    url: '/basic/enum/StockOutQualifiedRecordTypeEnum',
+    method: 'GET'
+  })
+}
+
+// 涓嶅悎鏍煎嚭搴撴潵婧愮被鍨�
+export function findAllUnQualifiedStockOutRecordTypeOptions() {
+  return request({
+    url: '/basic/enum/StockOutUnQualifiedRecordTypeEnum',
+    method: 'GET'
+  })
+}
diff --git a/src/api/basicData/productModel.js b/src/api/basicData/productModel.js
new file mode 100644
index 0000000..6dbd327
--- /dev/null
+++ b/src/api/basicData/productModel.js
@@ -0,0 +1,11 @@
+import request from '@/utils/request'
+
+// 浜у搧鍨嬪彿鍒嗛〉鍒楄〃锛堢敤浜庨�夋嫨浜у搧锛�
+export const productModelList = (params) => {
+  return request({
+    url: '/basic/product/pageModel',
+    method: 'GET',
+    params
+  })
+}
+
diff --git a/src/api/inventoryManagement/stockInRecord.js b/src/api/inventoryManagement/stockInRecord.js
new file mode 100644
index 0000000..a2e6535
--- /dev/null
+++ b/src/api/inventoryManagement/stockInRecord.js
@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 鍏ュ簱绠$悊-鍒嗛〉鏌ヨ鍏ュ簱璁板綍锛堝悎鏍�/涓嶅悎鏍硷級
+export const getStockInRecordListPage = (params) => {
+  return request({
+    url: '/stockInRecord/listPage',
+    method: 'GET',
+    params
+  })
+}
+
+// 鏍规嵁 id 鏌ヨ鍏ュ簱璁板綍璇︽儏
+export const getStockInRecordById = (id) => {
+  return request({
+    url: '/stockInRecord/' + id,
+    method: 'GET'
+  })
+}
+
+// 鎵归噺鍒犻櫎鍏ュ簱璁板綍
+export const batchDeleteStockInRecords = (ids) => {
+  return request({
+    url: '/stockInRecord',
+    method: 'DELETE',
+    data: ids
+  })
+}
diff --git a/src/api/inventoryManagement/stockInventory.js b/src/api/inventoryManagement/stockInventory.js
new file mode 100644
index 0000000..d9743f6
--- /dev/null
+++ b/src/api/inventoryManagement/stockInventory.js
@@ -0,0 +1,64 @@
+import request from '@/utils/request'
+
+// 鍚堟牸搴撳瓨-鍒嗛〉鏌ヨ
+export const getStockInventoryListPage = (params) => {
+  return request({
+    url: '/stockInventory/pagestockInventory',
+    method: 'GET',
+    params
+  })
+}
+
+// 鏂板鍚堟牸搴撳瓨
+export const createStockInventory = (data) => {
+  return request({
+    url: '/stockInventory/addstockInventory',
+    method: 'POST',
+    data
+  })
+}
+
+// 鍑哄簱锛堝噺灏戝簱瀛橈級
+export const subtractStockInventory = (data) => {
+  return request({
+    url: '/stockInventory/subtractStockInventory',
+    method: 'POST',
+    data
+  })
+}
+
+// 鍐荤粨搴撳瓨
+export const frozenStockInventory = (data) => {
+  return request({
+    url: '/stockInventory/frozenStock',
+    method: 'POST',
+    data
+  })
+}
+
+// 瑙e喕搴撳瓨
+export const thawStockInventory = (data) => {
+  return request({
+    url: '/stockInventory/thawStock',
+    method: 'POST',
+    data
+  })
+}
+
+// 搴撳瓨鎶ヨ〃-鏃ユ姤/鏈堟姤
+export const getStockInventoryReportList = (params) => {
+  return request({
+    url: '/stockInventory/stockInventoryPage',
+    method: 'GET',
+    params
+  })
+}
+
+// 搴撳瓨鎶ヨ〃-杩涘嚭瀛�
+export const getStockInventoryInAndOutReportList = (params) => {
+  return request({
+    url: '/stockInventory/stockInAndOutRecord',
+    method: 'GET',
+    params
+  })
+}
diff --git a/src/api/inventoryManagement/stockOutRecord.js b/src/api/inventoryManagement/stockOutRecord.js
new file mode 100644
index 0000000..362d838
--- /dev/null
+++ b/src/api/inventoryManagement/stockOutRecord.js
@@ -0,0 +1,19 @@
+import request from '@/utils/request'
+
+// 鍑哄簱鍙拌处-鍒嗛〉鏌ヨ鍑哄簱璁板綍锛堝悎鏍�/涓嶅悎鏍硷級
+export const getStockOutPage = (params) => {
+  return request({
+    url: '/stockOutRecord/listPage',
+    method: 'GET',
+    params
+  })
+}
+
+// 鍒犻櫎鍑哄簱璁板綍
+export const delStockOut = (ids) => {
+  return request({
+    url: '/stockOutRecord',
+    method: 'DELETE',
+    data: ids
+  })
+}
diff --git a/src/api/inventoryManagement/stockUninventory.js b/src/api/inventoryManagement/stockUninventory.js
new file mode 100644
index 0000000..ec42cdd
--- /dev/null
+++ b/src/api/inventoryManagement/stockUninventory.js
@@ -0,0 +1,46 @@
+import request from '@/utils/request'
+
+// 涓嶅悎鏍煎簱瀛�-鍒嗛〉鏌ヨ
+export const getStockUninventoryListPage = (params) => {
+  return request({
+    url: '/stockUninventory/pagestockUninventory',
+    method: 'GET',
+    params
+  })
+}
+
+// 鏂板涓嶅悎鏍煎簱瀛�
+export const createStockUnInventory = (data) => {
+  return request({
+    url: '/stockUninventory/addstockUninventory',
+    method: 'POST',
+    data
+  })
+}
+
+// 棰嗙敤锛堝噺灏戜笉鍚堟牸搴撳瓨锛�
+export const subtractStockUnInventory = (data) => {
+  return request({
+    url: '/stockUninventory/subtractstockUninventory',
+    method: 'POST',
+    data
+  })
+}
+
+// 鍐荤粨涓嶅悎鏍煎簱瀛�
+export const frozenStockUninventory = (data) => {
+  return request({
+    url: '/stockUninventory/frozenStock',
+    method: 'POST',
+    data
+  })
+}
+
+// 瑙e喕涓嶅悎鏍煎簱瀛�
+export const thawStockUninventory = (data) => {
+  return request({
+    url: '/stockUninventory/thawStock',
+    method: 'POST',
+    data
+  })
+}
diff --git a/src/pages.json b/src/pages.json
index d11cdea..ac70378 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -675,7 +675,7 @@
     {
       "path": "pages/inventoryManagement/receiptManagement/index",
       "style": {
-        "navigationBarTitleText": "鑷畾涔夊叆搴�",
+        "navigationBarTitleText": "鍏ュ簱绠$悊",
         "navigationStyle": "custom"
       }
     },
@@ -687,6 +687,13 @@
       }
     },
     {
+      "path": "pages/inventoryManagement/receiptManagement/view",
+      "style": {
+        "navigationBarTitleText": "鍏ュ簱璇︽儏",
+        "navigationStyle": "custom"
+      }
+    },
+    {
       "path": "pages/inventoryManagement/issueManagement/index",
       "style": {
         "navigationBarTitleText": "鑷畾涔夊嚭搴�",
@@ -694,6 +701,62 @@
       }
     },
     {
+      "path": "pages/inventoryManagement/dispatchLog/index",
+      "style": {
+        "navigationBarTitleText": "鍑哄簱鍙拌处",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/inventoryManagement/dispatchLog/view",
+      "style": {
+        "navigationBarTitleText": "鍑哄簱璇︽儏",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/inventoryManagement/stockManagement/index",
+      "style": {
+        "navigationBarTitleText": "搴撳瓨绠$悊",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/inventoryManagement/stockManagement/add",
+      "style": {
+        "navigationBarTitleText": "鏂板搴撳瓨",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/inventoryManagement/stockManagement/subtract",
+      "style": {
+        "navigationBarTitleText": "搴撳瓨鍑哄簱",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/inventoryManagement/stockManagement/view",
+      "style": {
+        "navigationBarTitleText": "搴撳瓨璇︽儏",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/inventoryManagement/stockReport/index",
+      "style": {
+        "navigationBarTitleText": "搴撳瓨鎶ヨ〃",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/inventoryManagement/stockReport/view",
+      "style": {
+        "navigationBarTitleText": "搴撳瓨鎶ヨ〃璇︽儏",
+        "navigationStyle": "custom"
+      }
+    },
+    {
       "path": "pages/safeProduction/safeQualifications/index",
       "style": {
         "navigationBarTitleText": "瑙勭▼涓庤祫璐�",
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 00f37cd..f4bc2c3 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -212,6 +212,31 @@
         </up-grid>
       </view>
     </view>
+    <!-- 浠撳偍鐗╂祦妯″潡 -->
+    <view class="common-module warehouse-logistics-module"
+          v-if="hasWarehouseLogisticsItems">
+      <view class="module-header">
+        <view class="module-title-container">
+          <text class="module-title">浠撳偍鐗╂祦</text>
+        </view>
+      </view>
+      <view class="module-content">
+        <up-grid :border="false"
+                 col="4">
+          <up-grid-item v-for="(item, index) in warehouseLogisticsItems"
+                        :key="index"
+                        @click="handleCommonItemClick(item)">
+            <view class="icon-container"
+                  :style="{ background: item.bgColor }">
+              <up-icon :name="item.icon"
+                       :size="58"
+                       color="#ffffff"></up-icon>
+            </view>
+            <text class="item-label">{{item.label}}</text>
+          </up-grid-item>
+        </up-grid>
+      </view>
+    </view>
   </view>
 </template>
 
@@ -439,7 +464,26 @@
       icon: "/static/images/icon/xunjianshangchuan@2x.png",
       label: "宸℃绠$悊",
     },
-    
+  ]);
+
+  // 浠撳偍鐗╂祦鍔熻兘鏁版嵁
+  const warehouseLogisticsItems = reactive([
+    {
+      icon: "/static/images/icon/caigoutaizhang@2x.png",
+      label: "鍏ュ簱绠$悊",
+    },
+    {
+      icon: "/static/images/icon/caigoutaizhang@2x.png",
+      label: "鍑哄簱鍙拌处",
+    },
+    {
+      icon: "/static/images/icon/caigoutaizhang@2x.png",
+      label: "搴撳瓨绠$悊",
+    },
+    {
+      icon: "/static/images/icon/caigoutaizhang@2x.png",
+      label: "搴撳瓨鎶ヨ〃",
+    },
   ]);
 
   // 澶勭悊甯哥敤鍔熻兘鐐瑰嚮
@@ -747,6 +791,26 @@
       case "鍚堝悓绠$悊":
         uni.navigateTo({
           url: "/pages/humanResources/contractManagement/index",
+        });
+        break;
+      case "鍏ュ簱绠$悊":
+        uni.navigateTo({
+          url: "/pages/inventoryManagement/receiptManagement/index",
+        });
+        break;
+      case "鍑哄簱鍙拌处":
+        uni.navigateTo({
+          url: "/pages/inventoryManagement/dispatchLog/index",
+        });
+        break;
+      case "搴撳瓨绠$悊":
+        uni.navigateTo({
+          url: "/pages/inventoryManagement/stockManagement/index",
+        });
+        break;
+      case "搴撳瓨鎶ヨ〃":
+        uni.navigateTo({
+          url: "/pages/inventoryManagement/stockReport/index",
         });
         break;
       default:
@@ -1069,6 +1133,22 @@
       }
     }
     equipmentItems.splice(0, equipmentItems.length, ...filteredEquipment);
+
+    // 杩囨护浠撳偍鐗╂祦鑿滃崟
+    const originalWarehouseLogistics = [
+      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "鍏ュ簱绠$悊" },
+      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "鍑哄簱鍙拌处" },
+      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "搴撳瓨绠$悊" },
+      { icon: "/static/images/icon/caigoutaizhang@2x.png", label: "搴撳瓨鎶ヨ〃" },
+    ];
+    const filteredWarehouseLogistics = originalWarehouseLogistics.filter(
+      item => allowedMenuTitles.has(item.label)
+    );
+    warehouseLogisticsItems.splice(
+      0,
+      warehouseLogisticsItems.length,
+      ...filteredWarehouseLogistics
+    );
   };
 
   // 妫�鏌ユā鍧楁槸鍚︽湁鑿滃崟椤归渶瑕佹樉绀�
@@ -1079,6 +1159,9 @@
   const hasHumanResourcesItems = computed(() => humanResourcesItems.length > 0);
   const hasProductionItems = computed(() => productionItems.length > 0);
   const hasEquipmentItems = computed(() => equipmentItems.length > 0);
+  const hasWarehouseLogisticsItems = computed(
+    () => warehouseLogisticsItems.length > 0
+  );
 
   onMounted(() => {
     // 姣忔杩涘叆棣栭〉閮藉己鍒跺埛鏂扮敤鎴蜂俊鎭拰璺敱鏉冮檺锛屼笉鍋氭湰鍦扮紦瀛樺垽鏂�
diff --git a/src/pages/inventoryManagement/dispatchLog/index.vue b/src/pages/inventoryManagement/dispatchLog/index.vue
new file mode 100644
index 0000000..1ab16fe
--- /dev/null
+++ b/src/pages/inventoryManagement/dispatchLog/index.vue
@@ -0,0 +1,333 @@
+<template>
+  <view class="dispatch-page">
+    <PageHeader title="鍑哄簱鍙拌处" @back="goBack" />
+
+    <!-- 鏍囩锛氬悎鏍煎嚭搴� / 涓嶅悎鏍煎嚭搴� -->
+    <view class="tabs-wrap">
+      <view
+        v-for="tab in tabs"
+        :key="tab.name"
+        class="tab-item"
+        :class="{ active: activeTab === tab.name }"
+        @click="activeTab = tab.name"
+      >
+        <text>{{ tab.label }}</text>
+      </view>
+    </view>
+
+    <!-- 鎼滅储鍖哄煙 -->
+    <view class="search-section">
+      <view class="search-row">
+        <view class="search-input-wrap">
+          <up-input
+            v-model="searchForm.productName"
+            placeholder="浜у搧澶х被"
+            clearable
+          />
+        </view>
+        <view class="btn-search" @click="handleQuery">
+          <view class="btn-search-inner">
+            <up-icon name="search" size="22" color="#fff"></up-icon>
+            <text>鎼滅储</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 鍒楄〃 -->
+    <view class="list-section">
+      <view v-if="tableData.length > 0">
+        <view
+          v-for="(item, index) in tableData"
+          :key="item.id || index"
+          class="card-item"
+        >
+          <view class="card-click" @click="goDetail(item)">
+            <view class="card-header">
+              <view class="header-main">
+                <text class="product-name">{{ item.productName }}</text>
+                <text class="outbound-date">{{ item.createTime }}</text>
+              </view>
+            </view>
+            <up-divider />
+            <view class="card-body">
+              <view class="row"><text class="l">瑙勬牸鍨嬪彿</text><text class="r">{{ item.model }}</text></view>
+              <view class="row"><text class="l">鍗曚綅</text><text class="r">{{ item.unit }}</text></view>
+              <view class="row"><text class="l">鍑哄簱鏁伴噺</text><text class="r highlight">{{ item.stockOutNum }}</text></view>
+              <view class="row"><text class="l">鍑哄簱浜�</text><text class="r">{{ item.createBy }}</text></view>
+              <view class="row" v-if="item.recordType !== undefined"><text class="l">鏉ユ簮</text><text class="r">{{ getRecordType(item.recordType) || item.recordType }}</text></view>
+              <view class="row"><text class="l">姣涢噸(鍚�)</text><text class="r">{{ item.grossWeight ?? '-' }}</text></view>
+              <view class="row"><text class="l">鐨噸(鍚�)</text><text class="r">{{ item.tareWeight ?? '-' }}</text></view>
+              <view class="row"><text class="l">鍑�閲�(鍚�)</text><text class="r">{{ item.netWeight ?? '-' }}</text></view>
+              <view class="row"><text class="l">杩囩鏃ユ湡</text><text class="r">{{ item.weighingDate || '-' }}</text></view>
+              <view class="row"><text class="l">杩囩鍛�</text><text class="r">{{ item.weighingOperator || '-' }}</text></view>
+            </view>
+          </view>
+          <view class="card-actions">
+            <view class="btn-delete" @click.stop="handleDeleteSingle(item)">鍒犻櫎</view>
+          </view>
+        </view>
+      </view>
+      <view v-else class="no-data">鏆傛棤鏁版嵁</view>
+    </view>
+    <!-- 鍔犺浇鏇村 -->
+    <view class="load-more-wrap" v-if="tableData.length > 0">
+      <u-loadmore :status="loadStatus" @loadmore="loadMore" />
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch } from 'vue'
+import { onShow, onReachBottom } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+import { getStockOutPage, delStockOut } from '@/api/inventoryManagement/stockOutRecord.js'
+import {
+  findAllQualifiedStockOutRecordTypeOptions,
+  findAllUnQualifiedStockOutRecordTypeOptions
+} from '@/api/basicData/enum.js'
+
+const activeTab = ref('qualified')
+const stockRecordTypeOptions = ref([])
+const tabs = [
+  { label: '鍚堟牸鍑哄簱', name: 'qualified', type: '0' },
+  { label: '涓嶅悎鏍煎嚭搴�', name: 'unqualified', type: '1' }
+]
+const tableData = ref([])
+const total = ref(0)
+const loadStatus = ref('loadmore')
+const page = reactive({ current: 1, size: 20 })
+const data = reactive({
+  searchForm: {
+    productName: ''
+  }
+})
+const { searchForm } = toRefs(data)
+
+const currentType = () => tabs.find(t => t.name === activeTab.value)?.type || '0'
+
+function getRecordType(recordType) {
+  if (recordType == null || recordType === '') return ''
+  return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || ''
+}
+
+function fetchRecordTypeOptions() {
+  const api = currentType() === '1'
+    ? findAllUnQualifiedStockOutRecordTypeOptions
+    : findAllQualifiedStockOutRecordTypeOptions
+  api()
+    .then(res => {
+      const list = res.data != null ? res.data : res
+      stockRecordTypeOptions.value = Array.isArray(list) ? list : []
+    })
+    .catch(() => {
+      stockRecordTypeOptions.value = []
+    })
+}
+
+const getList = () => {
+  const isFirstPage = page.current === 1
+  if (isFirstPage) {
+    uni.showLoading({ title: '鍔犺浇涓�...', mask: true })
+  }
+  getStockOutPage({
+    ...page,
+    type: currentType(),
+    productName: searchForm.value.productName
+  })
+    .then(res => {
+      uni.hideLoading()
+      const records = res.data?.records || []
+      const totalCount = res.data?.total || 0
+      if (isFirstPage) {
+        tableData.value = records
+        fetchRecordTypeOptions()
+      } else {
+        tableData.value = [...tableData.value, ...records]
+      }
+      total.value = totalCount
+      if (tableData.value.length >= totalCount || totalCount === 0) {
+        loadStatus.value = 'nomore'
+      } else {
+        loadStatus.value = 'loadmore'
+      }
+    })
+    .catch(() => {
+      uni.hideLoading()
+      loadStatus.value = 'error'
+      if (isFirstPage) {
+        uni.showToast({ title: '鍔犺浇澶辫触', icon: 'none' })
+      }
+    })
+}
+
+const loadMore = () => {
+  if (loadStatus.value === 'nomore' || loadStatus.value === 'loading') return
+  loadStatus.value = 'loading'
+  page.current++
+  getList()
+}
+
+watch(activeTab, () => {
+  page.current = 1
+  loadStatus.value = 'loadmore'
+  stockRecordTypeOptions.value = []
+  getList()
+})
+
+const handleQuery = () => {
+  page.current = 1
+  loadStatus.value = 'loadmore'
+  getList()
+}
+
+const goDetail = (item) => {
+  if (!item.id) return
+  try {
+    uni.setStorageSync('dispatchDetailItem', JSON.stringify({
+      item,
+      type: currentType()
+    }))
+  } catch (e) {}
+  uni.navigateTo({
+    url: '/pages/inventoryManagement/dispatchLog/view?id=' + item.id
+  })
+}
+
+const handleDeleteSingle = (item) => {
+  uni.showModal({
+    title: '鍒犻櫎',
+    content: '纭鍒犻櫎璇ユ潯鍑哄簱璁板綍锛�',
+    success: res => {
+      if (res.confirm) {
+        delStockOut([item.id])
+          .then(() => {
+            uni.showToast({ title: '鍒犻櫎鎴愬姛', icon: 'success' })
+            getList()
+          })
+          .catch(() => {
+            uni.showToast({ title: '鍒犻櫎澶辫触', icon: 'none' })
+          })
+      }
+    }
+  })
+}
+
+const goBack = () => uni.navigateBack()
+
+onShow(() => getList())
+onReachBottom(() => loadMore())
+</script>
+
+<style lang="scss" scoped>
+.dispatch-page {
+  min-height: 100vh;
+  background: #f5f5f5;
+  padding-bottom: 40rpx;
+}
+.tabs-wrap {
+  display: flex;
+  background: #fff;
+  padding: 24rpx;
+  gap: 24rpx;
+}
+.tab-item {
+  flex: 1;
+  text-align: center;
+  padding: 20rpx;
+  border-radius: 12rpx;
+  background: #f0f0f0;
+  font-size: 28rpx;
+  color: #666;
+}
+.tab-item.active {
+  background: #2979ff;
+  color: #fff;
+}
+.search-section {
+  background: #fff;
+  margin: 24rpx;
+  padding: 24rpx;
+  border-radius: 16rpx;
+}
+.search-row {
+  display: flex;
+  align-items: center;
+}
+.search-input-wrap { flex: 1; margin-right: 20rpx; min-width: 0; }
+.btn-search {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 180rpx;
+  min-height: 72rpx;
+  flex-shrink: 0;
+  padding: 20rpx 24rpx;
+  background: #2979ff;
+  color: #fff;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+  box-sizing: border-box;
+  text-align: center;
+}
+.btn-search-inner {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  gap: 8rpx;
+}
+.btn-search text { line-height: 1; vertical-align: middle; }
+:deep(.btn-search-inner > *),
+:deep(.btn-search > *) {
+  flex-shrink: 0;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+}
+.list-section { padding: 0 24rpx; }
+.card-item {
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 24rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+.card-header { padding: 8rpx 0; }
+.header-main {
+  display: flex;
+  flex-direction: column;
+  gap: 8rpx;
+}
+.product-name { font-size: 30rpx; font-weight: 500; color: #333; }
+.outbound-date { font-size: 24rpx; color: #999; }
+.card-body .row {
+  display: flex;
+  justify-content: space-between;
+  padding: 12rpx 0;
+  font-size: 26rpx;
+}
+.card-body .l { color: #666; }
+.card-body .r { color: #333; }
+.card-body .r.highlight { color: #2979ff; font-weight: 500; }
+.card-actions {
+  margin-top: 16rpx;
+  padding-top: 16rpx;
+  border-top: 1rpx solid #eee;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.btn-delete {
+  font-size: 28rpx;
+  color: #f56c6c;
+  padding: 12rpx 32rpx;
+}
+.no-data {
+  text-align: center;
+  padding: 80rpx 0;
+  color: #999;
+  font-size: 28rpx;
+}
+.load-more-wrap { padding: 24rpx 0 40rpx; }
+</style>
diff --git a/src/pages/inventoryManagement/dispatchLog/view.vue b/src/pages/inventoryManagement/dispatchLog/view.vue
new file mode 100644
index 0000000..ea41965
--- /dev/null
+++ b/src/pages/inventoryManagement/dispatchLog/view.vue
@@ -0,0 +1,259 @@
+<template>
+  <view class="detail-page">
+    <PageHeader title="鍑哄簱璇︽儏" @back="goBack" />
+    <view v-if="loading" class="loading-wrap">
+      <text class="loading-text">鍔犺浇涓�...</text>
+    </view>
+    <view v-else-if="detail" class="detail-wrap">
+      <!-- 鍩虹淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">鍩虹淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row">
+            <text class="label">搴忓彿</text>
+            <text class="value">{{ detail.index ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍑哄簱鎵规</text>
+            <text class="value value-strong">{{ detail.outboundBatches || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍑哄簱鏃堕棿</text>
+            <text class="value">{{ detail.createTime || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">浜у搧澶х被</text>
+            <text class="value value-strong">{{ detail.productName || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">瑙勬牸鍨嬪彿</text>
+            <text class="value">{{ detail.model || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍗曚綅</text>
+            <text class="value">{{ detail.unit || '-' }}</text>
+          </view>
+          <view class="detail-row detail-row-highlight">
+            <text class="label">鍑哄簱鏁伴噺</text>
+            <text class="value value-num">{{ detail.stockOutNum ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍑哄簱浜�</text>
+            <text class="value">{{ detail.createBy || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鏉ユ簮</text>
+            <text class="value">{{ getRecordType(detail.recordType) || '-' }}</text>
+          </view>
+        </view>
+      </view>
+      <!-- 鍑哄簱淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">鍑哄簱淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row">
+            <text class="label">杞︾墝鍙�</text>
+            <text class="value">{{ detail.licensePlateNo || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">姣涢噸(鍚�)</text>
+            <text class="value">{{ detail.grossWeight ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鐨噸(鍚�)</text>
+            <text class="value">{{ detail.tareWeight ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍑�閲�(鍚�)</text>
+            <text class="value">{{ detail.netWeight ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">杩囩鏃ユ湡</text>
+            <text class="value">{{ detail.weighingDate || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">杩囩鍛�</text>
+            <text class="value">{{ detail.weighingOperator || '-' }}</text>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view v-else class="empty">
+      <text class="empty-text">鏆傛棤璇︽儏鏁版嵁</text>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+import {
+  findAllQualifiedStockOutRecordTypeOptions,
+  findAllUnQualifiedStockOutRecordTypeOptions
+} from '@/api/basicData/enum.js'
+
+const detail = ref(null)
+const loading = ref(true)
+const stockRecordTypeOptions = ref([])
+
+function normalizeDetail(raw) {
+  if (!raw) return null
+  const d = typeof raw === 'object' ? raw : {}
+  return {
+    index: d.index ?? 1,
+    outboundBatches: d.outboundBatches,
+    createTime: d.createTime,
+    productName: d.productName,
+    model: d.model,
+    unit: d.unit,
+    stockOutNum: d.stockOutNum,
+    createBy: d.createBy,
+    recordType: d.recordType,
+    licensePlateNo: d.licensePlateNo,
+    grossWeight: d.grossWeight,
+    tareWeight: d.tareWeight,
+    netWeight: d.netWeight,
+    weighingDate: d.weighingDate,
+    weighingOperator: d.weighingOperator
+  }
+}
+
+function getRecordType(recordType) {
+  if (recordType == null || recordType === '') return ''
+  return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || ''
+}
+
+function fetchRecordTypeOptions(type) {
+  const api = type === '1'
+    ? findAllUnQualifiedStockOutRecordTypeOptions
+    : findAllQualifiedStockOutRecordTypeOptions
+  api()
+    .then(res => {
+      const data = res.data != null ? res.data : res
+      stockRecordTypeOptions.value = Array.isArray(data) ? data : []
+    })
+    .catch(() => {
+      stockRecordTypeOptions.value = []
+    })
+}
+
+onLoad(() => {
+  const cached = uni.getStorageSync('dispatchDetailItem')
+  if (cached) {
+    try {
+      const payload = typeof cached === 'string' ? JSON.parse(cached) : cached
+      const item = payload && payload.item != null ? payload.item : payload
+      const type = payload && payload.type != null ? payload.type : '0'
+      detail.value = normalizeDetail({ ...item, index: 1 })
+      fetchRecordTypeOptions(type)
+      uni.removeStorageSync('dispatchDetailItem')
+    } catch (e) {
+      uni.removeStorageSync('dispatchDetailItem')
+    }
+  }
+  loading.value = false
+})
+
+const goBack = () => uni.navigateBack()
+</script>
+
+<style lang="scss" scoped>
+.detail-page {
+  min-height: 100vh;
+  background: linear-gradient(180deg, #e8eef7 0%, #f2f5fa 100%);
+  padding-bottom: 48rpx;
+}
+.loading-wrap {
+  padding: 120rpx 48rpx;
+  text-align: center;
+}
+.loading-text {
+  color: #8c9aa8;
+  font-size: 28rpx;
+}
+.empty {
+  padding: 120rpx 48rpx;
+  text-align: center;
+}
+.empty-text {
+  color: #8c9aa8;
+  font-size: 28rpx;
+}
+.detail-wrap {
+  padding: 24rpx 24rpx 32rpx;
+}
+.section-card {
+  background: #fff;
+  border-radius: 24rpx;
+  overflow: hidden;
+  margin-bottom: 28rpx;
+  box-shadow: 0 8rpx 32rpx rgba(41, 121, 255, 0.06);
+  border: 1rpx solid rgba(41, 121, 255, 0.06);
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  padding: 28rpx 32rpx;
+  background: linear-gradient(135deg, #f8fbff 0%, #f0f6ff 100%);
+  border-bottom: 1rpx solid #eef3fa;
+}
+.section-dot {
+  width: 8rpx;
+  height: 8rpx;
+  border-radius: 50%;
+  background: #2979ff;
+  margin-right: 16rpx;
+}
+.section-title {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #1e3a5f;
+  letter-spacing: 0.5rpx;
+}
+.section-body {
+  padding: 8rpx 32rpx 24rpx;
+}
+.detail-row {
+  display: flex;
+  align-items: center;
+  min-height: 96rpx;
+  padding: 0 16rpx;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+  margin-bottom: 4rpx;
+}
+.detail-row .label {
+  width: 200rpx;
+  flex-shrink: 0;
+  color: #6b7c93;
+  font-size: 26rpx;
+}
+.detail-row .value {
+  flex: 1;
+  color: #2c3e50;
+  text-align: right;
+  word-break: break-all;
+  font-size: 28rpx;
+}
+.detail-row .value-strong {
+  color: #1e3a5f;
+  font-weight: 500;
+}
+.detail-row .value-num {
+  color: #2979ff;
+  font-weight: 600;
+  font-size: 32rpx;
+}
+.detail-row-highlight {
+  background: linear-gradient(90deg, rgba(41, 121, 255, 0.06) 0%, transparent 100%);
+  margin: 12rpx -16rpx 4rpx;
+  padding: 20rpx 16rpx;
+}
+</style>
diff --git a/src/pages/inventoryManagement/receiptManagement/index.vue b/src/pages/inventoryManagement/receiptManagement/index.vue
index 257ea3e..60a3ccc 100644
--- a/src/pages/inventoryManagement/receiptManagement/index.vue
+++ b/src/pages/inventoryManagement/receiptManagement/index.vue
@@ -1,406 +1,358 @@
 <template>
-  <view class="stock-in-page">
-    <PageHeader title="鑷畾涔夊叆搴�" @back="goBack" />
-    
+  <view class="receipt-page">
+    <PageHeader title="鍏ュ簱绠$悊" @back="goBack" />
+
+    <!-- 鏍囩锛氬悎鏍煎叆搴� / 涓嶅悎鏍煎叆搴� -->
+    <view class="tabs-wrap">
+      <view
+        v-for="tab in tabs"
+        :key="tab.name"
+        class="tab-item"
+        :class="{ active: activeTab === tab.name }"
+        @click="activeTab = tab.name"
+      >
+        <text>{{ tab.label }}</text>
+      </view>
+    </view>
+
     <!-- 鎼滅储鍖哄煙 -->
     <view class="search-section">
-      <view class="search-bar">
-        <view class="search-input">
+      <view class="search-row">
+        <view class="search-input-wrap">
           <up-input
-            v-model="searchForm.supplierName"
-            placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О"
+            v-model="searchForm.productName"
+            placeholder="浜у搧澶х被"
             clearable
           />
         </view>
-        <view class="search-button" @click="handleQuery">
-          <up-icon name="search" size="24" color="#999"></up-icon>
+        <view class="btn-search" @click="handleQuery">
+          <view class="btn-search-inner">
+            <up-icon name="search" size="22" color="#fff"></up-icon>
+            <text>鎼滅储</text>
+          </view>
         </view>
       </view>
-      <view class="date-filter" @click="openDatePickerHandler">
-        <text class="date-text">{{ searchForm.timeStr || '閫夋嫨鏃ユ湡' }}</text>
-        <up-icon name="calendar" size="18" color="#999"></up-icon>
-      </view>
     </view>
-    
-    <!-- 鍒楄〃 -->
-    <view class="stock-list" v-if="tableData.length > 0">
-      <view v-for="(item, index) in tableData" :key="index" class="stock-item">
-        <view class="item-header">
-          <view class="item-left">
-            <view class="batch-icon">
-              <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+
+    <!-- 鍒楄〃锛堝悎鏍�/涓嶅悎鏍煎叡鐢ㄦ帴鍙� type 鍖哄垎锛� -->
+    <view class="list-section" v-if="activeTab !== 'custom'">
+      <view v-if="tableData.length > 0">
+        <view
+          v-for="(item, index) in tableData"
+          :key="item.id || index"
+          class="card-item"
+        >
+          <view class="card-click" @click="goDetail(item)">
+            <view class="card-header">
+              <view class="header-main">
+                <text class="product-name">{{ item.productName }}</text>
+                <text class="inbound-date">{{ item.createTime || item.inboundDate }}</text>
+              </view>
             </view>
-            <text class="batch-text">{{ item.inboundBatches }}</text>
+            <up-divider />
+            <view class="card-body">
+              <view class="row"><text class="l">瑙勬牸鍨嬪彿</text><text class="r">{{ item.model }}</text></view>
+              <view class="row"><text class="l">鍗曚綅</text><text class="r">{{ item.unit }}</text></view>
+              <view class="row"><text class="l">鍏ュ簱鏁伴噺</text><text class="r highlight">{{ item.stockInNum }}</text></view>
+              <view class="row"><text class="l">鍏ュ簱浜�</text><text class="r">{{ item.createBy }}</text></view>
+              <view class="row" v-if="item.recordType !== undefined"><text class="l">鏉ユ簮</text><text class="r">{{ getRecordType(item.recordType) || item.recordType }}</text></view>
+            </view>
           </view>
-          <view class="item-right">
-            <text class="time-text">{{ item.inboundDate }}</text>
+          <view class="card-actions">
+            <view class="btn-delete" @click.stop="handleDeleteSingle(item)">鍒犻櫎</view>
           </view>
-        </view>
-        <up-divider></up-divider>
-        
-        <view class="item-details">
-          <view class="detail-row">
-            <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
-            <text class="detail-value">{{ item.supplierName }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">浜у搧澶х被</text>
-            <text class="detail-value">{{ item.productCategory }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">瑙勬牸鍨嬪彿</text>
-            <text class="detail-value">{{ item.specificationModel }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鐗╁搧绫诲瀷</text>
-            <text class="detail-value">{{ item.itemType }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍏ュ簱鏁伴噺</text>
-            <text class="detail-value highlight">{{ item.inboundNum }} {{ item.unit }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍚◣鍗曚环</text>
-            <text class="detail-value">楼{{ item.taxInclusiveUnitPrice }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍚◣鎬讳环</text>
-            <text class="detail-value price">楼{{ item.taxInclusiveTotalPrice }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">绋庣巼</text>
-            <text class="detail-value">{{ item.taxRate }}%</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">鍏ュ簱浜�</text>
-            <text class="detail-value">{{ item.createBy }}</text>
-          </view>
-        </view>
-        
-        <view class="item-actions">
-          <u-button type="primary" size="small" @click="handleEdit(item)">缂栬緫</u-button>
-          <u-button type="error" size="small" plain @click="handleDeleteSingle(item)">鍒犻櫎</u-button>
         </view>
       </view>
+      <view v-else class="no-data">鏆傛棤鏁版嵁</view>
     </view>
-    
-    <view v-else class="no-data">
-      <text>鏆傛棤鏁版嵁</text>
+    <!-- 鍔犺浇鏇村 -->
+    <view class="load-more-wrap" v-if="tableData.length > 0">
+      <u-loadmore :status="loadStatus" @loadmore="loadMore" />
     </view>
-    
-    <!-- 娴姩鎿嶄綔鎸夐挳 -->
-    <view class="fab-button" @click="handleAdd">
-      <up-icon name="plus" size="24" color="#ffffff"></up-icon>
-    </view>
-    
-    <!-- 鏃ユ湡閫夋嫨鍣� -->
-    <up-popup :show="showDatePicker" mode="bottom" @close="showDatePicker = false">
-      <up-datetime-picker
-        :show="true"
-        v-model="dateValue"
-        @confirm="onDateConfirm"
-        @cancel="showDatePicker = false"
-        mode="date"
-      />
-    </up-popup>
-    
-    <!-- 琛ㄥ崟寮圭獥 -->
-    <form-dia-manual ref="formDiaManual" @close="getList" @success="getList" />
   </view>
 </template>
 
 <script setup>
-import { ref, reactive, toRefs, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import dayjs from 'dayjs'
+import { ref, reactive, toRefs, watch } from 'vue'
+import { onShow, onReachBottom } from '@dcloudio/uni-app'
 import PageHeader from '@/components/PageHeader.vue'
-import FormDiaManual from './components/formDiaManual.vue'
-import useUserStore from '@/store/modules/user'
-import { formatDateToYMD } from '@/utils/ruoyi'
 import {
-  getInPageByCustom,
-  delStockInCustom
-} from "@/api/inventoryManagement/stockIn.js"
+  getStockInRecordListPage,
+  batchDeleteStockInRecords
+} from '@/api/inventoryManagement/stockInRecord.js'
+import {
+  findAllQualifiedStockInRecordTypeOptions,
+  findAllUnQualifiedStockInRecordTypeOptions
+} from '@/api/basicData/enum.js'
 
-const userStore = useUserStore()
+const activeTab = ref('qualified')
+const stockRecordTypeOptions = ref([])
+const tabs = [
+  { label: '鍚堟牸鍏ュ簱', name: 'qualified', type: '0' },
+  { label: '涓嶅悎鏍煎叆搴�', name: 'unqualified', type: '1' }
+]
 
 const tableData = ref([])
-const showDatePicker = ref(false)
-const dateValue = ref(new Date().getTime())
-const formDiaManual = ref(null)
-
-const page = reactive({
-  current: 1,
-  size: 20,
-})
 const total = ref(0)
+const loadStatus = ref('loadmore') // loadmore | loading | nomore | error
 
+const page = reactive({ current: 1, size: 4 })
 const data = reactive({
   searchForm: {
-    supplierName: '',
-    timeStr: '',
-  },
+    productName: ''
+  }
 })
 const { searchForm } = toRefs(data)
 
-// 缁熶竴鐢� dayjs 杈撳嚭 YYYY-MM-DD
-const formatYMDLocal = (ts) => dayjs(Number(ts)).format('YYYY-MM-DD')
+const currentType = () => tabs.find(t => t.name === activeTab.value)?.type || '0'
 
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
-  uni.navigateBack()
+function getRecordType(recordType) {
+  if (recordType == null || recordType === '') return ''
+  return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || ''
 }
 
-// 鏌ヨ鍒楄〃
-const handleQuery = () => {
-  page.current = 1
-  getList()
+function fetchRecordTypeOptions() {
+  const api = currentType() === '1'
+    ? findAllUnQualifiedStockInRecordTypeOptions
+    : findAllQualifiedStockInRecordTypeOptions
+  api()
+    .then(res => {
+      const data = res.data != null ? res.data : res
+      stockRecordTypeOptions.value = Array.isArray(data) ? data : []
+    })
+    .catch(() => {
+      stockRecordTypeOptions.value = []
+    })
 }
 
 const getList = () => {
-  uni.showLoading({
-    title: '鍔犺浇涓�...',
-    mask: true
-  })
-  
+  if (activeTab.value === 'custom') return
+  const isFirstPage = page.current === 1
+  if (isFirstPage) {
+    uni.showLoading({ title: '鍔犺浇涓�...', mask: true })
+  }
   const params = {
     ...page,
-    supplierName: searchForm.value.supplierName,
-    timeStr: searchForm.value.timeStr
+    type: currentType(),
+    productName: searchForm.value.productName
   }
-  
-  getInPageByCustom(params).then(res => {
-    uni.hideLoading()
-    tableData.value = res.data.records || []
-    total.value = res.data.total || 0
-  }).catch(() => {
-    uni.hideLoading()
-    uni.showToast({
-      title: '鍔犺浇澶辫触',
-      icon: 'none'
+  getStockInRecordListPage(params)
+    .then(res => {
+      uni.hideLoading()
+      const records = res.data?.records || []
+      const totalCount = res.data?.total || 0
+      if (isFirstPage) {
+        tableData.value = records
+        fetchRecordTypeOptions()
+      } else {
+        tableData.value = [...tableData.value, ...records]
+      }
+      total.value = totalCount
+      if (tableData.value.length >= totalCount || totalCount === 0) {
+        loadStatus.value = 'nomore'
+      } else {
+        loadStatus.value = 'loadmore'
+      }
     })
+    .catch(() => {
+      uni.hideLoading()
+      loadStatus.value = 'error'
+      if (isFirstPage) {
+        uni.showToast({ title: '鍔犺浇澶辫触', icon: 'none' })
+      }
+    })
+}
+
+const loadMore = () => {
+  if (loadStatus.value === 'nomore' || loadStatus.value === 'loading') return
+  loadStatus.value = 'loading'
+  page.current++
+  getList()
+}
+
+watch(activeTab, () => {
+  page.current = 1
+  loadStatus.value = 'loadmore'
+  stockRecordTypeOptions.value = []
+  getList()
+})
+
+const handleQuery = () => {
+  page.current = 1
+  loadStatus.value = 'loadmore'
+  getList()
+}
+
+const goDetail = (item) => {
+  if (!item.id) return
+  try {
+    uni.setStorageSync('receiptDetailItem', JSON.stringify({
+      item,
+      type: currentType()
+    }))
+  } catch (e) {}
+  uni.navigateTo({
+    url: '/pages/inventoryManagement/receiptManagement/view?id=' + item.id
   })
 }
 
-// 鎵撳紑鏃ユ湡閫夋嫨鍣紙绠�鍗曞彲闈狅級
-const openDatePickerHandler = () => {
-  // 鑻ュ凡鏈夐�変腑鏃ユ湡锛岀敤瀹冨垵濮嬪寲锛涘惁鍒欑敤浠婂ぉ
-  dateValue.value = searchForm.value.timeStr
-    ? dayjs(searchForm.value.timeStr, 'YYYY-MM-DD').valueOf()
-    : Date.now()
-  showDatePicker.value = true
-}
-
-// 鏃ユ湡閫夋嫨纭锛堜笌鍏朵粬椤典竴鑷达細鎷挎椂闂存埑 -> YYYY-MM-DD锛�
-const onDateConfirm = (e) => {
-  searchForm.value.timeStr = formatDateToYMD(e.value)
-  showDatePicker.value = false
-  handleQuery()
-}
-
-// 鏂板鍏ュ簱
-const handleAdd = () => {
-  formDiaManual.value?.openDialog('add')
-}
-
-// 缂栬緫
-const handleEdit = (item) => {
-  formDiaManual.value?.openDialog('edit', item)
-}
-
-// 鍒犻櫎鍗曟潯
 const handleDeleteSingle = (item) => {
-  // 妫�鏌ユ槸鍚︽槸鏈汉鍒涘缓
-  if (item.createBy !== userStore.nickName) {
-    uni.showToast({
-      title: '涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�',
-      icon: 'none'
-    })
-    return
-  }
-  
   uni.showModal({
     title: '鍒犻櫎',
-    content: '纭鍒犻櫎璇ュ叆搴撹褰曞悧锛�',
-    success: (res) => {
+    content: '纭鍒犻櫎璇ユ潯鍏ュ簱璁板綍锛�',
+    success: res => {
       if (res.confirm) {
-        delStockInCustom({ ids: [item.id] }).then(() => {
-          uni.showToast({
-            title: '鍒犻櫎鎴愬姛',
-            icon: 'success'
+        batchDeleteStockInRecords([item.id])
+          .then(() => {
+            uni.showToast({ title: '鍒犻櫎鎴愬姛', icon: 'success' })
+            getList()
           })
-          getList()
-        }).catch(() => {
-          uni.showToast({
-            title: '鍒犻櫎澶辫触',
-            icon: 'none'
+          .catch(() => {
+            uni.showToast({ title: '鍒犻櫎澶辫触', icon: 'none' })
           })
-        })
       }
     }
   })
 }
 
+const goBack = () => uni.navigateBack()
+
 onShow(() => {
-  getList()
+  if (activeTab.value !== 'custom') getList()
+})
+
+onReachBottom(() => {
+  loadMore()
 })
 </script>
 
-<style scoped lang="scss">
-.stock-in-page {
+<style lang="scss" scoped>
+.receipt-page {
   min-height: 100vh;
   background: #f5f5f5;
-  padding-bottom: 80px;
+  padding-bottom: 40rpx;
 }
-
+.tabs-wrap {
+  display: flex;
+  background: #fff;
+  padding: 24rpx;
+  gap: 24rpx;
+}
+.tab-item {
+  flex: 1;
+  text-align: center;
+  padding: 20rpx;
+  border-radius: 12rpx;
+  background: #f0f0f0;
+  font-size: 28rpx;
+  color: #666;
+}
+.tab-item.active {
+  background: #2979ff;
+  color: #fff;
+}
 .search-section {
   background: #fff;
-  padding: 16px;
-  margin-bottom: 12px;
+  margin: 24rpx;
+  padding: 24rpx;
+  border-radius: 16rpx;
 }
-
-.search-bar {
+.search-row {
   display: flex;
   align-items: center;
-  gap: 12px;
-  margin-bottom: 12px;
+  margin-bottom: 20rpx;
 }
-
-.search-input {
-  flex: 1;
-}
-
-.search-button {
-  width: 44px;
-  height: 44px;
+.search-input-wrap { flex: 1; margin-right: 20rpx; min-width: 0; }
+.btn-search {
   display: flex;
   align-items: center;
   justify-content: center;
-  background: #f5f5f5;
-  border-radius: 8px;
-}
-
-.date-filter {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: 12px 16px;
-  background: #f5f5f5;
-  border-radius: 8px;
-}
-
-.date-text {
-  font-size: 14px;
-  color: #666;
-}
-
-.stock-list {
-  padding: 0 16px;
-}
-
-.stock-item {
-  background: #fff;
-  border-radius: 12px;
-  padding: 16px;
-  margin-bottom: 12px;
-  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
-}
-
-.item-header {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  margin-bottom: 12px;
-}
-
-.item-left {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
-.batch-icon {
-  width: 32px;
-  height: 32px;
+  width: 180rpx;
+  min-height: 72rpx;
+  flex-shrink: 0;
+  padding: 20rpx 24rpx;
   background: #2979ff;
-  border-radius: 8px;
+  color: #fff;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+  box-sizing: border-box;
+  text-align: center;
+}
+.btn-search-inner {
   display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  gap: 8rpx;
+}
+.btn-search text {
+  line-height: 1;
+  vertical-align: middle;
+}
+/* 鎸夐挳鍐呭浘鏍囦笌鏂囧瓧鍨傜洿姘村钩閮藉眳涓� */
+:deep(.btn-search-inner > *),
+:deep(.btn-search > *) {
+  flex-shrink: 0;
+  display: inline-flex;
   align-items: center;
   justify-content: center;
 }
-
-.batch-text {
-  font-size: 14px;
+.list-section {
+  padding: 0 24rpx;
+}
+.card-item {
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 24rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+.card-header {
+  padding: 8rpx 0;
+}
+.header-main {
+  display: flex;
+  flex-direction: column;
+  gap: 8rpx;
+}
+.product-name {
+  font-size: 30rpx;
   font-weight: 500;
   color: #333;
 }
-
-.time-text {
-  font-size: 12px;
+.inbound-date {
+  font-size: 24rpx;
   color: #999;
 }
-
-.item-details {
-  margin: 12px 0;
-}
-
-.detail-row {
+.card-body .row {
   display: flex;
-  align-items: center;
   justify-content: space-between;
-  padding: 8px 0;
+  padding: 12rpx 0;
+  font-size: 26rpx;
 }
-
-.detail-label {
-  font-size: 14px;
-  color: #666;
-}
-
-.detail-value {
-  font-size: 14px;
-  color: #333;
-  text-align: right;
-  flex: 1;
-  margin-left: 12px;
-}
-
-.detail-value.highlight {
-  color: #2979ff;
-  font-weight: 500;
-}
-
-.detail-value.price {
-  color: #ff6b00;
-  font-weight: 500;
-}
-
-.item-actions {
+.card-body .l { color: #666; }
+.card-body .r { color: #333; }
+.card-body .r.highlight { color: #2979ff; font-weight: 500; }
+.card-actions {
+  margin-top: 16rpx;
+  padding-top: 16rpx;
+  border-top: 1rpx solid #eee;
   display: flex;
-  gap: 12px;
-  margin-top: 12px;
-  padding-top: 12px;
-  border-top: 1px solid #f5f5f5;
+  justify-content: center;
+  align-items: center;
 }
-
+.btn-delete {
+  font-size: 28rpx;
+  color: #f56c6c;
+  padding: 12rpx 32rpx;
+}
 .no-data {
   text-align: center;
-  padding: 60px 0;
+  padding: 80rpx 0;
   color: #999;
-  font-size: 14px;
+  font-size: 28rpx;
 }
-
-.fab-button {
-  position: fixed;
-  right: 20px;
-  bottom: 80px;
-  width: 56px;
-  height: 56px;
-  background: #2979ff;
-  border-radius: 50%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  box-shadow: 0 4px 12px rgba(41, 121, 255, 0.4);
-  z-index: 999;
+.load-more-wrap {
+  padding: 24rpx 0 40rpx;
 }
 </style>
diff --git a/src/pages/inventoryManagement/receiptManagement/view.vue b/src/pages/inventoryManagement/receiptManagement/view.vue
new file mode 100644
index 0000000..e5daea9
--- /dev/null
+++ b/src/pages/inventoryManagement/receiptManagement/view.vue
@@ -0,0 +1,260 @@
+<template>
+  <view class="detail-page">
+    <PageHeader title="鍏ュ簱璇︽儏" @back="goBack" />
+    <view v-if="loading" class="loading-wrap">
+      <text class="loading-text">鍔犺浇涓�...</text>
+    </view>
+    <view v-else-if="detail" class="detail-wrap">
+      <!-- 鍩虹淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">鍩虹淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row">
+            <text class="label">搴忓彿</text>
+            <text class="value">{{ detail.index ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍏ュ簱鎵规</text>
+            <text class="value value-strong">{{ detail.inboundBatches || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍏ュ簱鏃堕棿</text>
+            <text class="value">{{ detail.createTime || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">浜у搧澶х被</text>
+            <text class="value value-strong">{{ detail.productName || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">瑙勬牸鍨嬪彿</text>
+            <text class="value">{{ detail.model || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍗曚綅</text>
+            <text class="value">{{ detail.unit || '-' }}</text>
+          </view>
+          <view class="detail-row detail-row-highlight">
+            <text class="label">鍏ュ簱鏁伴噺</text>
+            <text class="value value-num">{{ detail.stockInNum ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍏ュ簱浜�</text>
+            <text class="value">{{ detail.createBy || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鏉ユ簮</text>
+            <text class="value">{{ getRecordType(detail.recordType) || '-' }}</text>
+          </view>
+        </view>
+      </view>
+      <!-- 鍏ュ簱淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">鍏ュ簱淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row">
+            <text class="label">杞︾墝鍙�</text>
+            <text class="value">{{ detail.licensePlateNo || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">姣涢噸(鍚�)</text>
+            <text class="value">{{ detail.grossWeight ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鐨噸(鍚�)</text>
+            <text class="value">{{ detail.tareWeight ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍑�閲�(鍚�)</text>
+            <text class="value">{{ detail.netWeight ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">杩囩鏃ユ湡</text>
+            <text class="value">{{ detail.weighingDate || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">杩囩鍛�</text>
+            <text class="value">{{ detail.weighingOperator || '-' }}</text>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view v-else class="empty">
+      <text class="empty-text">鏆傛棤璇︽儏鏁版嵁</text>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+import {
+  findAllQualifiedStockInRecordTypeOptions,
+  findAllUnQualifiedStockInRecordTypeOptions
+} from '@/api/basicData/enum.js'
+
+const detail = ref(null)
+const loading = ref(true)
+const stockRecordTypeOptions = ref([])
+
+// 涓庡弬鑰� el-table-column 鐨� prop 淇濇寔涓�鑷达細inboundBatches, createTime, productName, model, unit, stockInNum, licensePlateNo, grossWeight, tareWeight, netWeight, createBy, recordType, weighingDate, weighingOperator
+function normalizeDetail(raw) {
+  if (!raw) return null
+  const d = typeof raw === 'object' ? raw : {}
+  return {
+    index: d.index ?? 1,
+    inboundBatches: d.inboundBatches,
+    createTime: d.createTime,
+    productName: d.productName,
+    model: d.model,
+    unit: d.unit,
+    stockInNum: d.stockInNum,
+    createBy: d.createBy,
+    recordType: d.recordType,
+    licensePlateNo: d.licensePlateNo,
+    grossWeight: d.grossWeight,
+    tareWeight: d.tareWeight,
+    netWeight: d.netWeight,
+    weighingDate: d.weighingDate,
+    weighingOperator: d.weighingOperator
+  }
+}
+
+function getRecordType(recordType) {
+  if (recordType == null || recordType === '') return ''
+  return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || ''
+}
+
+function fetchRecordTypeOptions(type) {
+  const api = type === '1'
+    ? findAllUnQualifiedStockInRecordTypeOptions
+    : findAllQualifiedStockInRecordTypeOptions
+  api()
+    .then(res => {
+      const data = res.data != null ? res.data : res
+      stockRecordTypeOptions.value = Array.isArray(data) ? data : []
+    })
+    .catch(() => {
+      stockRecordTypeOptions.value = []
+    })
+}
+
+onLoad(() => {
+  const cached = uni.getStorageSync('receiptDetailItem')
+  if (cached) {
+    try {
+      const payload = typeof cached === 'string' ? JSON.parse(cached) : cached
+      const item = payload && payload.item != null ? payload.item : payload
+      const type = payload && payload.type != null ? payload.type : '0'
+      detail.value = normalizeDetail({ ...item, index: 1 })
+      fetchRecordTypeOptions(type)
+      uni.removeStorageSync('receiptDetailItem')
+    } catch (e) {
+      uni.removeStorageSync('receiptDetailItem')
+    }
+  }
+  loading.value = false
+})
+
+const goBack = () => uni.navigateBack()
+</script>
+
+<style lang="scss" scoped>
+.detail-page {
+  min-height: 100vh;
+  background: linear-gradient(180deg, #e8eef7 0%, #f2f5fa 100%);
+  padding-bottom: 48rpx;
+}
+.loading-wrap {
+  padding: 120rpx 48rpx;
+  text-align: center;
+}
+.loading-text {
+  color: #8c9aa8;
+  font-size: 28rpx;
+}
+.empty {
+  padding: 120rpx 48rpx;
+  text-align: center;
+}
+.empty-text {
+  color: #8c9aa8;
+  font-size: 28rpx;
+}
+.detail-wrap {
+  padding: 24rpx 24rpx 32rpx;
+}
+.section-card {
+  background: #fff;
+  border-radius: 24rpx;
+  overflow: hidden;
+  margin-bottom: 28rpx;
+  box-shadow: 0 8rpx 32rpx rgba(41, 121, 255, 0.06);
+  border: 1rpx solid rgba(41, 121, 255, 0.06);
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  padding: 28rpx 32rpx;
+  background: linear-gradient(135deg, #f8fbff 0%, #f0f6ff 100%);
+  border-bottom: 1rpx solid #eef3fa;
+}
+.section-dot {
+  width: 8rpx;
+  height: 8rpx;
+  border-radius: 50%;
+  background: #2979ff;
+  margin-right: 16rpx;
+}
+.section-title {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #1e3a5f;
+  letter-spacing: 0.5rpx;
+}
+.section-body {
+  padding: 8rpx 32rpx 24rpx;
+}
+.detail-row {
+  display: flex;
+  align-items: center;
+  min-height: 96rpx;
+  padding: 0 16rpx;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+  margin-bottom: 4rpx;
+}
+.detail-row .label {
+  width: 200rpx;
+  flex-shrink: 0;
+  color: #6b7c93;
+  font-size: 26rpx;
+}
+.detail-row .value {
+  flex: 1;
+  color: #2c3e50;
+  text-align: right;
+  word-break: break-all;
+  font-size: 28rpx;
+}
+.detail-row .value-strong {
+  color: #1e3a5f;
+  font-weight: 500;
+}
+.detail-row .value-num {
+  color: #2979ff;
+  font-weight: 600;
+  font-size: 32rpx;
+}
+.detail-row-highlight {
+  background: linear-gradient(90deg, rgba(41, 121, 255, 0.06) 0%, transparent 100%);
+  margin: 12rpx -16rpx 4rpx;
+  padding: 20rpx 16rpx;
+}
+</style>
diff --git a/src/pages/inventoryManagement/stockManagement/add.vue b/src/pages/inventoryManagement/stockManagement/add.vue
new file mode 100644
index 0000000..6c69d85
--- /dev/null
+++ b/src/pages/inventoryManagement/stockManagement/add.vue
@@ -0,0 +1,426 @@
+<template>
+  <view class="add-stock-page">
+    <PageHeader title="鏂板搴撳瓨" @back="goBack" />
+
+    <scroll-view scroll-y class="content-scroll">
+      <view class="form-section">
+        <view class="form-row">
+          <text class="form-label required">浜у搧鍚嶇О</text>
+          <view class="selector-trigger" @click="openProductSelector">
+            <text class="selector-text" :class="{ placeholder: !form.productName }">
+              {{ form.productName || '璇烽�夋嫨浜у搧' }}
+            </text>
+            <up-icon name="arrow-right" size="16" color="#999"></up-icon>
+          </view>
+        </view>
+        <view class="form-row">
+          <text class="form-label">瑙勬牸</text>
+          <up-input v-model="form.productModelName" disabled placeholder="璇烽�夋嫨浜у搧鍚庤嚜鍔ㄥ甫鍑�" />
+        </view>
+        <view class="form-row">
+          <text class="form-label">鍗曚綅</text>
+          <up-input v-model="form.unit" disabled placeholder="璇烽�夋嫨浜у搧鍚庤嚜鍔ㄥ甫鍑�" />
+        </view>
+      </view>
+
+      <!-- 鍚堟牸搴撳瓨鏃舵樉绀鸿繃纾呯浉鍏冲瓧娈� -->
+      <view v-if="isQualified" class="form-section">
+        <view class="section-title">杩囩淇℃伅</view>
+        <view class="form-row">
+          <text class="form-label">杞︾墝鍙�</text>
+          <up-input v-model="form.licensePlateNo" placeholder="璇疯緭鍏ヨ溅鐗屽彿" />
+        </view>
+        <view class="form-row">
+          <text class="form-label">姣涢噸(鍚�)</text>
+          <up-input
+            v-model="form.grossWeight"
+            type="number"
+            placeholder="璇疯緭鍏ユ瘺閲�"
+          />
+        </view>
+        <view class="form-row">
+          <text class="form-label">鐨噸(鍚�)</text>
+          <up-input
+            v-model="form.tareWeight"
+            type="number"
+            placeholder="璇疯緭鍏ョ毊閲�"
+          />
+        </view>
+        <view class="form-row">
+          <text class="form-label">鍑�閲�(鍚�)</text>
+          <up-input
+            v-model="form.netWeight"
+            type="number"
+            disabled
+            placeholder="鑷姩璁$畻"
+          />
+        </view>
+        <view class="form-row">
+          <text class="form-label">杩囩鏃ユ湡</text>
+          <view class="selector-trigger" @click="openWeighingDatePicker">
+            <text class="selector-text" :class="{ placeholder: !form.weighingDate }">
+              {{ form.weighingDate || '璇烽�夋嫨杩囩鏃ユ湡' }}
+            </text>
+            <up-icon name="calendar" size="16" color="#999"></up-icon>
+          </view>
+        </view>
+        <view class="form-row">
+          <text class="form-label">杩囩鍛�</text>
+          <up-input v-model="form.weighingOperator" placeholder="璇疯緭鍏ヨ繃纾呭憳" />
+        </view>
+      </view>
+
+      <view class="form-section">
+        <!-- <view class="form-row">
+          <text class="form-label required">鏁伴噺</text>
+          <up-input v-model="form.qualitity" type="number" placeholder="璇疯緭鍏ユ暟閲�" />
+        </view> -->
+        <view class="form-row">
+          <text class="form-label">澶囨敞</text>
+          <up-input v-model="form.remark" type="textarea" placeholder="閫夊~" />
+        </view>
+      </view>
+    </scroll-view>
+
+    <!-- 鎻愪氦鎸夐挳 -->
+    <view class="bottom-bar">
+      <view class="btn-submit" @click="handleSubmit">鎻愪氦</view>
+    </view>
+
+    <!-- 浜у搧閫夋嫨寮圭獥锛堢畝鍖栫増 ProductSelectDialog锛� -->
+    <up-popup :show="showProductPopup" mode="bottom" @close="showProductPopup = false">
+      <view class="product-popup">
+        <view class="popup-header">
+          <text class="popup-title">閫夋嫨浜у搧</text>
+        </view>
+        <view class="popup-search">
+          <up-input
+            v-model="productQuery.productName"
+            placeholder="浜у搧澶х被"
+            clearable
+          />
+          <up-input
+            v-model="productQuery.model"
+            placeholder="鍨嬪彿鍚嶇О"
+            clearable
+          />
+          <view class="popup-search-btn" @click="loadProductList">鎼滅储</view>
+        </view>
+        <scroll-view scroll-y class="product-list">
+          <view
+            v-for="item in productList"
+            :key="item.id"
+            class="product-item"
+            @click="selectProduct(item)"
+          >
+            <view class="product-name-row">
+              <text class="product-name">{{ item.productName }}</text>
+              <text class="product-unit">{{ item.unit }}</text>
+            </view>
+            <view class="product-model">鍨嬪彿锛歿{ item.model }}</view>
+          </view>
+          <view v-if="!productLoading && productList.length === 0" class="no-data">
+            鏆傛棤鏁版嵁
+          </view>
+        </scroll-view>
+      </view>
+    </up-popup>
+
+    <!-- 杩囩鏃ユ湡閫夋嫨鍣� -->
+    <up-popup :show="showWeighingDatePicker" mode="bottom" @close="showWeighingDatePicker = false">
+      <up-datetime-picker
+        :show="true"
+        v-model="weighingDateValue"
+        mode="datetime"
+        @confirm="onWeighingDateConfirm"
+        @cancel="showWeighingDatePicker = false"
+      />
+    </up-popup>
+  </view>
+</template>
+
+<script setup>
+import { ref, reactive, computed, watch } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import dayjs from 'dayjs'
+import PageHeader from '@/components/PageHeader.vue'
+import { createStockInventory } from '@/api/inventoryManagement/stockInventory.js'
+import { createStockUnInventory } from '@/api/inventoryManagement/stockUninventory.js'
+import { productModelList } from '@/api/basicData/productModel.js'
+
+const form = reactive({
+  productId: undefined,
+  productModelId: undefined,
+  productName: '',
+  productModelName: '',
+  unit: '',
+  productType: undefined,
+  licensePlateNo: '',
+  grossWeight: '',
+  tareWeight: '',
+  netWeight: '',
+  weighingDate: '',
+  weighingOperator: '',
+  qualitity: '',
+  remark: ''
+})
+
+const type = ref('0') // 0 鍚堟牸搴撳瓨锛�1 涓嶅悎鏍煎簱瀛�
+const isQualified = computed(() => type.value === '0')
+
+const showProductPopup = ref(false)
+const productQuery = reactive({
+  productName: '',
+  model: ''
+})
+const productList = ref([])
+const productLoading = ref(false)
+
+const showWeighingDatePicker = ref(false)
+const weighingDateValue = ref(Date.now())
+
+onLoad((options) => {
+  if (options && options.type != null) {
+    type.value = options.type
+  }
+})
+
+const openProductSelector = () => {
+  showProductPopup.value = true
+  if (productList.value.length === 0) {
+    loadProductList()
+  }
+}
+
+const loadProductList = () => {
+  productLoading.value = true
+  productModelList({
+    productName: productQuery.productName || '',
+    model: productQuery.model || '',
+    current: 1,
+    size: 20
+  })
+    .then(res => {
+      const data = res?.records || res?.data?.records || []
+      productList.value = Array.isArray(data) ? data : []
+    })
+    .finally(() => {
+      productLoading.value = false
+    })
+}
+
+const selectProduct = (item) => {
+  form.productId = item.productId || item.id
+  form.productModelId = item.id
+  form.productName = item.productName
+  form.productModelName = item.model
+  form.unit = item.unit
+  form.productType = item.productType
+  showProductPopup.value = false
+}
+
+// 鍑�閲� = 姣涢噸 - 鐨噸
+const computeNetWeight = () => {
+  const gross = Number(form.grossWeight)
+  const tare = Number(form.tareWeight)
+  if (!isNaN(gross) && !isNaN(tare)) {
+    const net = Number((gross - tare).toFixed(2))
+    form.netWeight = net > 0 ? net : 0
+  } else {
+    form.netWeight = ''
+  }
+}
+
+// 鐩戝惉姣涢噸銆佺毊閲嶅彉鍖栵紝鑷姩璁$畻鍑�閲�
+watch(
+  () => [form.grossWeight, form.tareWeight],
+  () => {
+    computeNetWeight()
+  }
+)
+
+const openWeighingDatePicker = () => {
+  weighingDateValue.value = form.weighingDate
+    ? dayjs(form.weighingDate, 'YYYY-MM-DD HH:mm:ss').valueOf()
+    : Date.now()
+  showWeighingDatePicker.value = true
+}
+
+const onWeighingDateConfirm = (e) => {
+  const ts = e?.value ?? weighingDateValue.value
+  form.weighingDate = dayjs(ts).format('YYYY-MM-DD HH:mm:ss')
+  showWeighingDatePicker.value = false
+}
+
+const handleSubmit = () => {
+  if (!form.productName || !form.productModelId) {
+    uni.showToast({ title: '璇烽�夋嫨浜у搧', icon: 'none' })
+    return
+  }
+  // if (!form.qualitity || Number(form.qualitity) <= 0) {
+  //   uni.showToast({ title: '璇疯緭鍏ユ暟閲�', icon: 'none' })
+  //   return
+  // }
+  const payload = {
+    productId: form.productId,
+    productModelId: form.productModelId,
+    productName: form.productName,
+    productModelName: form.productModelName,
+    unit: form.unit,
+    productType: form.productType,
+    licensePlateNo: form.licensePlateNo,
+    grossWeight: form.grossWeight,
+    tareWeight: form.tareWeight,
+    netWeight: form.netWeight,
+    weighingDate: form.weighingDate,
+    weighingOperator: form.weighingOperator,
+    remark: form.remark
+  }
+  const api = isQualified.value ? createStockInventory : createStockUnInventory
+  api(payload)
+    .then(() => {
+      uni.showToast({ title: '鏂板鎴愬姛', icon: 'success' })
+      setTimeout(() => {
+        uni.navigateBack()
+      }, 400)
+    })
+    .catch(() => {
+      uni.showToast({ title: '鏂板澶辫触', icon: 'none' })
+    })
+}
+
+const goBack = () => uni.navigateBack()
+</script>
+
+<style lang="scss" scoped>
+.add-stock-page {
+  min-height: 100vh;
+  background: #f5f5f5;
+  padding-bottom: 100rpx;
+}
+.content-scroll {
+  height: calc(100vh - 100rpx);
+}
+.form-section {
+  background: #fff;
+  margin: 24rpx;
+  padding: 24rpx;
+  border-radius: 16rpx;
+}
+.section-title {
+  font-size: 28rpx;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 12rpx;
+}
+.form-row {
+  margin-bottom: 24rpx;
+}
+.form-label {
+  display: block;
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 12rpx;
+}
+.form-label.required::after {
+  content: '*';
+  color: #f56c6c;
+  margin-left: 6rpx;
+}
+.selector-trigger {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20rpx 24rpx;
+  background: #f5f5f5;
+  border-radius: 12rpx;
+}
+.selector-text {
+  font-size: 28rpx;
+  color: #333;
+}
+.selector-text.placeholder {
+  color: #999;
+}
+.bottom-bar {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
+  background: #fff;
+  box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.04);
+}
+.btn-submit {
+  height: 88rpx;
+  border-radius: 999rpx;
+  background: #2979ff;
+  color: #fff;
+  font-size: 30rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.product-popup {
+  background: #fff;
+  border-radius: 24rpx 24rpx 0 0;
+  padding-bottom: env(safe-area-inset-bottom);
+}
+.popup-header {
+  padding: 24rpx;
+  border-bottom: 1rpx solid #eee;
+}
+.popup-title {
+  font-size: 30rpx;
+  font-weight: 500;
+  color: #333;
+}
+.popup-search {
+  padding: 16rpx 24rpx;
+  display: flex;
+  flex-direction: column;
+  gap: 12rpx;
+}
+.popup-search-btn {
+  margin-top: 8rpx;
+  align-self: flex-end;
+  padding: 12rpx 32rpx;
+  border-radius: 999rpx;
+  background: #2979ff;
+  color: #fff;
+  font-size: 26rpx;
+}
+.product-list {
+  max-height: 600rpx;
+  padding: 0 24rpx 24rpx;
+}
+.product-item {
+  padding: 20rpx 0;
+  border-bottom: 1rpx solid #f0f0f0;
+}
+.product-name-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8rpx;
+}
+.product-name {
+  font-size: 28rpx;
+  color: #333;
+}
+.product-unit {
+  font-size: 24rpx;
+  color: #999;
+}
+.product-model {
+  font-size: 24rpx;
+  color: #666;
+}
+.no-data {
+  text-align: center;
+  padding: 40rpx 0;
+  color: #999;
+  font-size: 26rpx;
+}
+</style>
+
diff --git a/src/pages/inventoryManagement/stockManagement/index.vue b/src/pages/inventoryManagement/stockManagement/index.vue
new file mode 100644
index 0000000..e36fac0
--- /dev/null
+++ b/src/pages/inventoryManagement/stockManagement/index.vue
@@ -0,0 +1,456 @@
+<template>
+  <view class="stock-mgmt-page">
+    <PageHeader title="搴撳瓨绠$悊" @back="goBack" />
+
+    <!-- 鏍囩锛氬悎鏍煎簱瀛� / 涓嶅悎鏍煎簱瀛� -->
+    <view class="tabs-wrap">
+      <view
+        v-for="tab in tabs"
+        :key="tab.name"
+        class="tab-item"
+        :class="{ active: activeTab === tab.name }"
+        @click="activeTab = tab.name"
+      >
+        <text>{{ tab.label }}</text>
+      </view>
+    </view>
+
+    <!-- 鎼滅储鍖哄煙 -->
+    <view class="search-section">
+      <view class="search-row">
+        <view class="search-input-wrap">
+          <up-input
+            v-model="searchForm.productName"
+            placeholder="浜у搧澶х被"
+            clearable
+          />
+        </view>
+        <view class="btn-search" @click="handleQuery">
+          <view class="btn-search-inner">
+            <up-icon name="search" size="22" color="#fff"></up-icon>
+            <text>鎼滅储</text>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 鍒楄〃 + 婊氬姩鍒嗛〉 -->
+    <view class="list-section">
+      <view v-if="tableData.length > 0">
+        <view
+          v-for="(item, index) in tableData"
+          :key="item.id || index"
+          class="card-item"
+        >
+          <view class="card-click" @click="goDetail(item)">
+            <view class="card-header">
+              <view class="header-main">
+                <text class="product-name">{{ item.productName }}</text>
+                <text class="sub-title">{{ item.model || item.updateTime }}</text>
+              </view>
+            </view>
+            <up-divider />
+            <view class="card-body">
+              <view class="row"><text class="l">瑙勬牸鍨嬪彿</text><text class="r">{{ item.model }}</text></view>
+              <view class="row"><text class="l">鍗曚綅</text><text class="r">{{ item.unit }}</text></view>
+              <view class="row"><text class="l">鎬诲簱瀛樻暟</text><text class="r highlight">{{ item.qualitity }}</text></view>
+              <view class="row"><text class="l">鍐荤粨鏁伴噺</text><text class="r">{{ item.lockedQuantity || 0 }}</text></view>
+              <view class="row"><text class="l">鍙敤搴撳瓨</text><text class="r">{{ item.unLockedQuantity ?? (item.qualitity - (item.lockedQuantity || 0)) }}</text></view>
+              <view class="row"><text class="l">鏈�杩戞洿鏂版椂闂�</text><text class="r">{{ item.updateTime }}</text></view>
+            </view>
+          </view>
+          <view class="card-actions">
+            <view
+              class="btn-link btn-link-primary"
+              :class="{ disabled: !(item.unLockedQuantity > 0) }"
+              @click="openSubtract(item)"
+            >鍑哄簱</view>
+            <view
+              class="btn-link btn-link-warn"
+              v-if="item.unLockedQuantity > 0"
+              @click="openFrozen(item)"
+            >鍐荤粨</view>
+            <view
+              class="btn-link btn-link-plain"
+              v-if="(item.lockedQuantity || 0) > 0"
+              @click="openThaw(item)"
+            >瑙e喕</view>
+          </view>
+        </view>
+        <view class="load-more-wrap">
+          <u-loadmore :status="loadStatus" @loadmore="loadMore" />
+        </view>
+      </view>
+      <view v-else class="no-data">鏆傛棤鏁版嵁</view>
+    </view>
+
+    <!-- 鍑哄簱/鍐荤粨/瑙e喕寮圭獥 -->
+    <up-popup :show="showQuantityPopup" mode="center" round="16" @close="closeQuantityPopup">
+      <view class="popup-inner">
+        <view class="popup-title">{{ quantityTitle }}</view>
+        <view class="form-row">
+          <text class="form-label">鏁伴噺</text>
+          <up-input v-model="quantityForm.num" type="number" :placeholder="'鏈�澶�' + maxQuantity" />
+        </view>
+        <view class="popup-footer">
+          <view class="btn-cancel" @click="closeQuantityPopup">鍙栨秷</view>
+          <view class="btn-ok" @click="submitQuantity">纭畾</view>
+        </view>
+      </view>
+    </up-popup>
+
+    <!-- 鍙充笅瑙掓柊澧炴寜閽細杩涘叆鏂板搴撳瓨椤甸潰 -->
+    <view class="fab-button" @click="goAdd">
+      <up-icon name="plus" size="24" color="#ffffff"></up-icon>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, watch, computed } from 'vue'
+import { onShow, onReachBottom } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+import {
+  getStockInventoryListPage,
+  createStockInventory,
+  subtractStockInventory,
+  frozenStockInventory,
+  thawStockInventory
+} from '@/api/inventoryManagement/stockInventory.js'
+import {
+  getStockUninventoryListPage,
+  createStockUnInventory,
+  subtractStockUnInventory,
+  frozenStockUninventory,
+  thawStockUninventory
+} from '@/api/inventoryManagement/stockUninventory.js'
+
+const activeTab = ref('qualified')
+const tabs = [
+  { label: '鍚堟牸搴撳瓨', name: 'qualified' },
+  { label: '涓嶅悎鏍煎簱瀛�', name: 'unqualified' }
+]
+const tableData = ref([])
+const total = ref(0)
+const loadStatus = ref('loadmore') // loadmore | loading | nomore | error
+const showQuantityPopup = ref(false)
+const quantityOp = ref('') // subtract | frozen | thaw
+const currentRecord = ref(null)
+const page = reactive({ current: 1, size: 20 })
+const data = reactive({
+  searchForm: { productName: '' },
+  quantityForm: { num: '' }
+})
+const { searchForm, quantityForm } = toRefs(data)
+
+const isQualified = () => activeTab.value === 'qualified'
+const getList = () => {
+  const isFirstPage = page.current === 1
+  if (isFirstPage) {
+    uni.showLoading({ title: '鍔犺浇涓�...', mask: true })
+  }
+  const params = { ...page, productName: searchForm.value.productName }
+  const api = isQualified() ? getStockInventoryListPage : getStockUninventoryListPage
+  api(params)
+    .then(res => {
+      uni.hideLoading()
+      const records = res.data?.records || []
+      const totalCount = res.data?.total || 0
+      if (isFirstPage) {
+        tableData.value = records
+      } else {
+        tableData.value = [...tableData.value, ...records]
+      }
+      total.value = totalCount
+      if (tableData.value.length >= totalCount || totalCount === 0) {
+        loadStatus.value = 'nomore'
+      } else {
+        loadStatus.value = 'loadmore'
+      }
+    })
+    .catch(() => {
+      uni.hideLoading()
+      loadStatus.value = 'error'
+      if (isFirstPage) {
+        uni.showToast({ title: '鍔犺浇澶辫触', icon: 'none' })
+      }
+    })
+}
+
+const loadMore = () => {
+  if (loadStatus.value === 'nomore' || loadStatus.value === 'loading') return
+  loadStatus.value = 'loading'
+  page.current++
+  getList()
+}
+
+watch(activeTab, () => {
+  page.current = 1
+  loadStatus.value = 'loadmore'
+  getList()
+})
+
+const handleQuery = () => {
+  page.current = 1
+  loadStatus.value = 'loadmore'
+  getList()
+}
+
+const goAdd = () => {
+  const type = isQualified() ? '0' : '1'
+  uni.navigateTo({
+    url: `/pages/inventoryManagement/stockManagement/add?type=${type}`
+  })
+}
+
+const quantityTitle = computed(() => {
+  if (quantityOp.value === 'frozen') return '鍐荤粨搴撳瓨'
+  if (quantityOp.value === 'thaw') return '瑙e喕搴撳瓨'
+  return ''
+})
+const maxQuantity = computed(() => {
+  if (!currentRecord.value) return 0
+  if (quantityOp.value === 'frozen') return currentRecord.value.unLockedQuantity || 0
+  if (quantityOp.value === 'thaw') return currentRecord.value.lockedQuantity || 0
+  return 0
+})
+
+const openSubtract = (row) => {
+  if (!(row.unLockedQuantity > 0)) return
+  try {
+    uni.setStorageSync('stockSubtractRecord', JSON.stringify({
+      item: row,
+      type: isQualified() ? '0' : '1'
+    }))
+  } catch (e) {}
+  const typeParam = isQualified() ? '0' : '1'
+  uni.navigateTo({
+    url: `/pages/inventoryManagement/stockManagement/subtract?type=${typeParam}&id=${row.id}`
+  })
+}
+const openFrozen = (row) => {
+  quantityOp.value = 'frozen'
+  currentRecord.value = row
+  quantityForm.value.num = ''
+  showQuantityPopup.value = true
+}
+const openThaw = (row) => {
+  quantityOp.value = 'thaw'
+  currentRecord.value = row
+  quantityForm.value.num = ''
+  showQuantityPopup.value = true
+}
+const closeQuantityPopup = () => {
+  showQuantityPopup.value = false
+  currentRecord.value = null
+  quantityOp.value = ''
+}
+const submitQuantity = () => {
+  const num = Number(quantityForm.value.num)
+  if (!num || num <= 0 || num > maxQuantity.value) {
+    uni.showToast({ title: `璇疯緭鍏� 1~${maxQuantity.value} 涔嬮棿鐨勬暟閲廯, icon: 'none' })
+    return
+  }
+  const id = currentRecord.value?.id
+  if (!id) return
+  const base = { id, lockedQuantity: num }
+  let promise
+  if (quantityOp.value === 'frozen') {
+    promise = isQualified() ? frozenStockInventory(base) : frozenStockUninventory(base)
+  } else {
+    promise = isQualified() ? thawStockInventory(base) : thawStockUninventory(base)
+  }
+  promise.then(() => {
+    uni.showToast({ title: '鎿嶄綔鎴愬姛', icon: 'success' })
+    closeQuantityPopup()
+    getList()
+  }).catch(() => uni.showToast({ title: '鎿嶄綔澶辫触', icon: 'none' }))
+}
+
+const goDetail = (item) => {
+  if (!item) return
+  try {
+    uni.setStorageSync('stockDetailItem', JSON.stringify({
+      item,
+      type: isQualified() ? '0' : '1'
+    }))
+  } catch (e) {}
+  if (!item.id) {
+    uni.navigateTo({ url: '/pages/inventoryManagement/stockManagement/view' })
+  } else {
+    uni.navigateTo({ url: '/pages/inventoryManagement/stockManagement/view?id=' + item.id })
+  }
+}
+
+const goBack = () => uni.navigateBack()
+onShow(() => getList())
+onReachBottom(() => {
+  loadMore()
+})
+</script>
+
+<style lang="scss" scoped>
+.stock-mgmt-page {
+  min-height: 100vh;
+  background: #f5f5f5;
+  padding-bottom: 120rpx;
+}
+.tabs-wrap {
+  display: flex;
+  background: #fff;
+  padding: 24rpx;
+  gap: 24rpx;
+}
+.tab-item {
+  flex: 1;
+  text-align: center;
+  padding: 20rpx;
+  border-radius: 12rpx;
+  background: #f0f0f0;
+  font-size: 28rpx;
+  color: #666;
+}
+.tab-item.active {
+  background: #2979ff;
+  color: #fff;
+}
+.search-section {
+  background: #fff;
+  margin: 24rpx;
+  padding: 24rpx;
+  border-radius: 16rpx;
+}
+.search-row {
+  display: flex;
+  align-items: center;
+}
+.search-input-wrap { flex: 1; margin-right: 20rpx; min-width: 0; }
+.btn-search {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 180rpx;
+  min-height: 72rpx;
+  flex-shrink: 0;
+  padding: 20rpx 24rpx;
+  background: #2979ff;
+  color: #fff;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+  box-sizing: border-box;
+  text-align: center;
+}
+.btn-search-inner {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  gap: 8rpx;
+}
+.btn-search text { line-height: 1; vertical-align: middle; }
+:deep(.btn-search-inner > *),
+:deep(.btn-search > *) {
+  flex-shrink: 0;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+}
+.list-section { padding: 0 24rpx; }
+.card-item {
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 24rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+.card-header { padding: 8rpx 0; }
+.header-main {
+  display: flex;
+  flex-direction: column;
+  gap: 8rpx;
+}
+.product-name { font-size: 30rpx; font-weight: 500; color: #333; }
+.sub-title { font-size: 24rpx; color: #999; }
+.card-body .row {
+  display: flex;
+  justify-content: space-between;
+  padding: 12rpx 0;
+  font-size: 26rpx;
+}
+.card-body .l { color: #666; }
+.card-body .r { color: #333; }
+.card-body .r.highlight { color: #2979ff; font-weight: 500; }
+.card-actions {
+  display: flex;
+  gap: 16rpx;
+  margin-top: 16rpx;
+  padding-top: 16rpx;
+  border-top: 1rpx solid #eee;
+  justify-content: flex-end;
+}
+.btn-link {
+  min-width: 120rpx;
+  padding: 10rpx 20rpx;
+  border-radius: 24rpx;
+  font-size: 26rpx;
+  text-align: center;
+  border-width: 1rpx;
+  border-style: solid;
+}
+.btn-link-primary {
+  color: #ffffff;
+  background: #2979ff;
+  border-color: #2979ff;
+}
+.btn-link-warn {
+  color: #ff9f1a;
+  background: rgba(255, 159, 26, 0.08);
+  border-color: rgba(255, 159, 26, 0.6);
+}
+.btn-link-plain {
+  color: #666666;
+  background: #f5f5f5;
+  border-color: #e0e0e0;
+}
+.btn-link.disabled {
+  color: #cccccc;
+  background: #f5f5f5;
+  border-color: #e0e0e0;
+}
+.no-data { text-align: center; padding: 80rpx 0; color: #999; font-size: 28rpx; }
+
+/* 鍙充笅瑙掓诞鍔ㄦ柊澧炴寜閽� */
+.fab-button {
+  position: fixed;
+  bottom: calc(30px + env(safe-area-inset-bottom));
+  right: 30px;
+  width: 56px;
+  height: 56px;
+  background: #2979ff;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 4px 16px rgba(41, 121, 255, 0.3);
+  z-index: 1000;
+}
+
+.popup-inner { padding: 40rpx; min-width: 560rpx; background: #fff; }
+.popup-title { font-size: 32rpx; font-weight: 500; margin-bottom: 32rpx; }
+.form-row { margin-bottom: 24rpx; }
+.form-row .form-label { display: block; font-size: 26rpx; color: #666; margin-bottom: 12rpx; }
+.date-picker-trigger {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20rpx 24rpx;
+  background: #f5f5f5;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+}
+.date-picker-text { color: #333; }
+.date-picker-text.placeholder { color: #999; }
+.popup-footer { display: flex; gap: 24rpx; margin-top: 40rpx; }
+.btn-cancel { flex: 1; text-align: center; padding: 24rpx; background: #f0f0f0; border-radius: 12rpx; }
+.btn-ok { flex: 1; text-align: center; padding: 24rpx; background: #2979ff; color: #fff; border-radius: 12rpx; }
+</style>
diff --git a/src/pages/inventoryManagement/stockManagement/subtract.vue b/src/pages/inventoryManagement/stockManagement/subtract.vue
new file mode 100644
index 0000000..4970275
--- /dev/null
+++ b/src/pages/inventoryManagement/stockManagement/subtract.vue
@@ -0,0 +1,268 @@
+<template>
+  <view class="subtract-page">
+    <PageHeader title="搴撳瓨鍑哄簱" @back="goBack" />
+
+    <scroll-view scroll-y class="content-scroll">
+      <view class="form-section">
+        <view class="form-row">
+          <text class="form-label">浜у搧鍚嶇О</text>
+          <up-input v-model="form.productName" disabled />
+        </view>
+        <view class="form-row">
+          <text class="form-label">瑙勬牸</text>
+          <up-input v-model="form.model" disabled />
+        </view>
+        <view class="form-row">
+          <text class="form-label">鍗曚綅</text>
+          <up-input v-model="form.unit" disabled />
+        </view>
+      </view>
+
+      <view class="form-section">
+        <view class="section-title">鍑哄簱/杩囩淇℃伅</view>
+        <view class="form-row">
+          <text class="form-label">杞︾墝鍙�</text>
+          <up-input v-model="form.licensePlateNo" placeholder="璇疯緭鍏ヨ溅鐗屽彿" />
+        </view>
+        <view class="form-row">
+          <text class="form-label">姣涢噸(鍚�)</text>
+          <up-input
+            v-model="form.grossWeight"
+            type="number"
+            placeholder="璇疯緭鍏ユ瘺閲�"
+          />
+        </view>
+        <view class="form-row">
+          <text class="form-label">鐨噸(鍚�)</text>
+          <up-input
+            v-model="form.tareWeight"
+            type="number"
+            placeholder="璇疯緭鍏ョ毊閲�"
+          />
+        </view>
+        <view class="form-row">
+          <text class="form-label">鍑�閲�(鍚�)</text>
+          <up-input
+            v-model="form.netWeight"
+            type="number"
+            disabled
+            placeholder="鑷姩璁$畻"
+          />
+        </view>
+        <view class="form-row">
+          <text class="form-label">杩囩鏃ユ湡</text>
+          <view class="selector-trigger" @click="openWeighingDatePicker">
+            <text class="selector-text" :class="{ placeholder: !form.weighingDate }">
+              {{ form.weighingDate || '璇烽�夋嫨杩囩鏃ユ湡' }}
+            </text>
+            <up-icon name="calendar" size="16" color="#999"></up-icon>
+          </view>
+        </view>
+        <view class="form-row">
+          <text class="form-label">杩囩鍛�</text>
+          <up-input v-model="form.weighingOperator" placeholder="璇疯緭鍏ヨ繃纾呭憳" />
+        </view>
+        <view class="form-row">
+          <text class="form-label">澶囨敞</text>
+          <up-input v-model="form.remark" type="textarea" placeholder="閫夊~" />
+        </view>
+      </view>
+    </scroll-view>
+
+    <view class="bottom-bar">
+      <view class="btn-submit" @click="handleSubmit">鍑哄簱</view>
+    </view>
+
+    <!-- 杩囩鏃ユ湡閫夋嫨鍣� -->
+    <up-popup :show="showWeighingDatePicker" mode="bottom" @close="showWeighingDatePicker = false">
+      <up-datetime-picker
+        :show="true"
+        v-model="weighingDateValue"
+        mode="datetime"
+        @confirm="onWeighingDateConfirm"
+        @cancel="showWeighingDatePicker = false"
+      />
+    </up-popup>
+  </view>
+</template>
+
+<script setup>
+import { ref, reactive, watch } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import dayjs from 'dayjs'
+import PageHeader from '@/components/PageHeader.vue'
+import { subtractStockInventory } from '@/api/inventoryManagement/stockInventory.js'
+import { subtractStockUnInventory } from '@/api/inventoryManagement/stockUninventory.js'
+
+const form = reactive({
+  id: undefined,
+  // 浜у搧鍙婂簱瀛樺熀纭�淇℃伅锛堟潵鑷垪琛ㄨ褰曪級
+  productId: undefined,
+  productModelId: undefined,
+  parentId: undefined,
+  parentName: '',
+  productName: '',
+  model: '',
+  unit: '',
+  qualitity: undefined,
+  lockedQuantity: undefined,
+  unLockedQuantity: undefined,
+  warnNum: undefined,
+  currentStock: undefined,
+  totalStockIn: undefined,
+  totalStockOut: undefined,
+  createTime: '',
+  updateTime: '',
+  version: undefined,
+  // 鍑哄簱/杩囩淇℃伅
+  licensePlateNo: '',
+  grossWeight: '',
+  tareWeight: '',
+  netWeight: '',
+  weighingDate: '',
+  weighingOperator: '',
+  remark: ''
+})
+
+const type = ref('0') // 0 鍚堟牸搴撳瓨锛�1 涓嶅悎鏍煎簱瀛�
+const showWeighingDatePicker = ref(false)
+const weighingDateValue = ref(Date.now())
+
+onLoad((options) => {
+  if (options && options.type != null) {
+    type.value = options.type
+  }
+  const cached = uni.getStorageSync('stockSubtractRecord')
+  if (cached) {
+    try {
+      const payload = typeof cached === 'string' ? JSON.parse(cached) : cached
+      const item = payload && payload.item ? payload.item : payload
+      // 灏嗗垪琛ㄨ褰曠殑瀹屾暣瀛楁鎷疯礉鍒拌〃鍗曚腑锛屼繚鎸佷笌 PC 绔� Subtract.vue 涓�鑷�
+      Object.assign(form, item)
+      uni.removeStorageSync('stockSubtractRecord')
+    } catch (e) {
+      uni.removeStorageSync('stockSubtractRecord')
+    }
+  }
+})
+
+// 鍑�閲� = 姣涢噸 - 鐨噸
+const computeNetWeight = () => {
+  const gross = Number(form.grossWeight)
+  const tare = Number(form.tareWeight)
+  if (!isNaN(gross) && !isNaN(tare)) {
+    const net = Number((gross - tare).toFixed(2))
+    form.netWeight = net > 0 ? net : 0
+  } else {
+    form.netWeight = ''
+  }
+}
+
+watch(
+  () => [form.grossWeight, form.tareWeight],
+  () => {
+    computeNetWeight()
+  }
+)
+
+const openWeighingDatePicker = () => {
+  weighingDateValue.value = form.weighingDate
+    ? dayjs(form.weighingDate, 'YYYY-MM-DD HH:mm:ss').valueOf()
+    : Date.now()
+  showWeighingDatePicker.value = true
+}
+
+const onWeighingDateConfirm = (e) => {
+  const ts = e?.value ?? weighingDateValue.value
+  form.weighingDate = dayjs(ts).format('YYYY-MM-DD HH:mm:ss')
+  showWeighingDatePicker.value = false
+}
+
+const handleSubmit = () => {
+  if (!form.id) {
+    uni.showToast({ title: '璁板綍淇℃伅缂哄け锛屾棤娉曞嚭搴�', icon: 'none' })
+    return
+  }
+  const payload = { ...form }
+  const api = type.value === '0' ? subtractStockInventory : subtractStockUnInventory
+  api(payload)
+    .then(() => {
+      uni.showToast({ title: '鍑哄簱鎴愬姛', icon: 'success' })
+      setTimeout(() => {
+        uni.navigateBack()
+      }, 400)
+    })
+    .catch(() => {
+      uni.showToast({ title: '鍑哄簱澶辫触', icon: 'none' })
+    })
+}
+
+const goBack = () => uni.navigateBack()
+</script>
+
+<style lang="scss" scoped>
+.subtract-page {
+  min-height: 100vh;
+  background: #f5f5f5;
+  padding-bottom: 100rpx;
+}
+.content-scroll {
+  height: calc(100vh - 100rpx);
+}
+.form-section {
+  background: #fff;
+  margin: 24rpx;
+  padding: 24rpx;
+  border-radius: 16rpx;
+}
+.section-title {
+  font-size: 28rpx;
+  font-weight: 500;
+  color: #333;
+  margin-bottom: 12rpx;
+}
+.form-row {
+  margin-bottom: 24rpx;
+}
+.form-label {
+  display: block;
+  font-size: 26rpx;
+  color: #666;
+  margin-bottom: 12rpx;
+}
+.selector-trigger {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20rpx 24rpx;
+  background: #f5f5f5;
+  border-radius: 12rpx;
+}
+.selector-text {
+  font-size: 28rpx;
+  color: #333;
+}
+.selector-text.placeholder {
+  color: #999;
+}
+.bottom-bar {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
+  background: #fff;
+  box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.04);
+}
+.btn-submit {
+  height: 88rpx;
+  border-radius: 999rpx;
+  background: #2979ff;
+  color: #fff;
+  font-size: 30rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>
+
diff --git a/src/pages/inventoryManagement/stockManagement/view.vue b/src/pages/inventoryManagement/stockManagement/view.vue
new file mode 100644
index 0000000..8f26078
--- /dev/null
+++ b/src/pages/inventoryManagement/stockManagement/view.vue
@@ -0,0 +1,193 @@
+<template>
+  <view class="detail-page">
+    <PageHeader title="搴撳瓨璇︽儏" @back="goBack" />
+    <view v-if="loading" class="loading-wrap">
+      <text class="loading-text">鍔犺浇涓�...</text>
+    </view>
+    <view v-else-if="detail" class="detail-wrap">
+      <!-- 鍩虹淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">鍩虹淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row">
+            <text class="label">搴忓彿</text>
+            <text class="value">{{ detail.index ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">浜у搧澶х被</text>
+            <text class="value value-strong">{{ detail.productName || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">瑙勬牸鍨嬪彿</text>
+            <text class="value">{{ detail.model || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍗曚綅</text>
+            <text class="value">{{ detail.unit || '-' }}</text>
+          </view>
+        </view>
+      </view>
+      <!-- 搴撳瓨淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">搴撳瓨淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row">
+            <text class="label">鎬诲簱瀛樻暟</text>
+            <text class="value value-num">{{ detail.qualitity ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍐荤粨鏁伴噺</text>
+            <text class="value">{{ detail.lockedQuantity ?? 0 }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍙敤搴撳瓨</text>
+            <text class="value">{{ detail.unLockedQuantity ?? (detail.qualitity - (detail.lockedQuantity || 0)) }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鏈�杩戞洿鏂版椂闂�</text>
+            <text class="value">{{ detail.updateTime || '-' }}</text>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view v-else class="empty">
+      <text class="empty-text">鏆傛棤璇︽儏鏁版嵁</text>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+
+const detail = ref(null)
+const loading = ref(true)
+
+function normalizeDetail(raw) {
+  if (!raw) return null
+  const d = typeof raw === 'object' ? raw : {}
+  return {
+    index: d.index ?? 1,
+    productName: d.productName,
+    model: d.model,
+    unit: d.unit,
+    qualitity: d.qualitity,
+    lockedQuantity: d.lockedQuantity,
+    unLockedQuantity: d.unLockedQuantity,
+    updateTime: d.updateTime
+  }
+}
+
+onLoad(() => {
+  const cached = uni.getStorageSync('stockDetailItem')
+  if (cached) {
+    try {
+      const payload = typeof cached === 'string' ? JSON.parse(cached) : cached
+      const item = payload && payload.item != null ? payload.item : payload
+      detail.value = normalizeDetail({ ...item, index: 1 })
+      uni.removeStorageSync('stockDetailItem')
+    } catch (e) {
+      uni.removeStorageSync('stockDetailItem')
+    }
+  }
+  loading.value = false
+})
+
+const goBack = () => uni.navigateBack()
+</script>
+
+<style lang="scss" scoped>
+.detail-page {
+  min-height: 100vh;
+  background: linear-gradient(180deg, #e8eef7 0%, #f2f5fa 100%);
+  padding-bottom: 48rpx;
+}
+.loading-wrap {
+  padding: 120rpx 48rpx;
+  text-align: center;
+}
+.loading-text {
+  color: #8c9aa8;
+  font-size: 28rpx;
+}
+.empty {
+  padding: 120rpx 48rpx;
+  text-align: center;
+}
+.empty-text {
+  color: #8c9aa8;
+  font-size: 28rpx;
+}
+.detail-wrap {
+  padding: 24rpx 24rpx 32rpx;
+}
+.section-card {
+  background: #fff;
+  border-radius: 24rpx;
+  overflow: hidden;
+  margin-bottom: 28rpx;
+  box-shadow: 0 8rpx 32rpx rgba(41, 121, 255, 0.06);
+  border: 1rpx solid rgba(41, 121, 255, 0.06);
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  padding: 28rpx 32rpx;
+  background: linear-gradient(135deg, #f8fbff 0%, #f0f6ff 100%);
+  border-bottom: 1rpx solid #eef3fa;
+}
+.section-dot {
+  width: 8rpx;
+  height: 8rpx;
+  border-radius: 50%;
+  background: #2979ff;
+  margin-right: 16rpx;
+}
+.section-title {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #1e3a5f;
+  letter-spacing: 0.5rpx;
+}
+.section-body {
+  padding: 8rpx 32rpx 24rpx;
+}
+.detail-row {
+  display: flex;
+  align-items: center;
+  min-height: 96rpx;
+  padding: 0 16rpx;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+  margin-bottom: 4rpx;
+}
+.detail-row .label {
+  width: 220rpx;
+  flex-shrink: 0;
+  color: #6b7c93;
+  font-size: 26rpx;
+}
+.detail-row .value {
+  flex: 1;
+  color: #2c3e50;
+  text-align: right;
+  word-break: break-all;
+  font-size: 28rpx;
+}
+.detail-row .value-strong {
+  color: #1e3a5f;
+  font-weight: 500;
+}
+.detail-row .value-num {
+  color: #2979ff;
+  font-weight: 600;
+  font-size: 32rpx;
+}
+</style>
diff --git a/src/pages/inventoryManagement/stockReport/index.vue b/src/pages/inventoryManagement/stockReport/index.vue
new file mode 100644
index 0000000..1eba7a4
--- /dev/null
+++ b/src/pages/inventoryManagement/stockReport/index.vue
@@ -0,0 +1,274 @@
+<template>
+  <view class="report-page">
+    <PageHeader title="搴撳瓨鎶ヨ〃" @back="goBack" />
+
+    <!-- 鎶ヨ〃绫诲瀷 -->
+    <view class="tabs-wrap">
+      <view
+        v-for="t in reportTypes"
+        :key="t.value"
+        class="tab-item"
+        :class="{ active: searchForm.reportType === t.value }"
+        @click="searchForm.reportType = t.value"
+      >
+        <text>{{ t.label }}</text>
+      </view>
+    </view>
+
+    <!-- 鏃堕棿閫夋嫨鍖哄煙宸插幓闄わ紝浣跨敤榛樿鏃ユ湡閫昏緫 -->
+
+    <!-- 鍒楄〃 + 婊氬姩鍒嗛〉 -->
+    <view class="list-section">
+      <view class="section-header">
+        <text class="table-title">{{ tableTitle }}</text>
+      </view>
+      <view v-if="tableData.length > 0">
+        <view v-for="(item, index) in tableData" :key="index" class="card-item">
+          <view class="card-header">
+            <view class="header-main">
+              <text class="product-name">{{ item.productName }}</text>
+              <text class="sub-title">{{ item.model }}</text>
+            </view>
+          </view>
+          <up-divider />
+          <view class="card-body">
+            <view class="row"><text class="l">鍗曚綅</text><text class="r">{{ item.unit }}</text></view>
+            <view class="row" v-if="searchForm.reportType !== 'inout'"><text class="l">鍏ュ簱鏃堕棿</text><text class="r">{{ item.createTime }}</text></view>
+            <view class="row" v-if="searchForm.reportType !== 'inout'"><text class="l">鍏ュ簱鎵规</text><text class="r">{{ item.inboundBatches }}</text></view>
+            <view class="row"><text class="l">鍏ュ簱鏁伴噺</text><text class="r">{{ item.totalStockIn ?? item.stockInNum }}</text></view>
+            <view class="row" v-if="searchForm.reportType === 'inout'"><text class="l">鍑哄簱鏁伴噺</text><text class="r">{{ item.totalStockOut }}</text></view>
+            <view class="row"><text class="l">鐜板湪搴撳瓨</text><text class="r highlight">{{ item.currentStock }}</text></view>
+            <view class="row" v-if="item.createBy"><text class="l">鍏ュ簱浜�</text><text class="r">{{ item.createBy }}</text></view>
+          </view>
+        </view>
+        <view class="load-more-wrap">
+          <u-loadmore :status="loadStatus" @loadmore="loadMore" />
+        </view>
+      </view>
+      <view v-else class="no-data">鏆傛棤鏁版嵁</view>
+    </view>
+
+    <up-popup :show="showDatePicker" mode="bottom" @close="showDatePicker = false">
+      <up-datetime-picker
+        v-model="dateValue"
+        :mode="datePickerMode"
+        @confirm="onDateConfirm"
+        @cancel="showDatePicker = false"
+      />
+    </up-popup>
+  </view>
+</template>
+
+<script setup>
+import { ref, reactive, toRefs, computed, watch } from 'vue'
+import dayjs from 'dayjs'
+import PageHeader from '@/components/PageHeader.vue'
+import { formatDateToYMD } from '@/utils/ruoyi'
+import { onShow, onReachBottom } from '@dcloudio/uni-app'
+import {
+  getStockInventoryReportList,
+  getStockInventoryInAndOutReportList
+} from '@/api/inventoryManagement/stockInventory.js'
+
+const reportTypes = [
+  { label: '鏃ユ姤', value: 'daily' },
+  { label: '鏈堟姤', value: 'monthly' },
+  { label: '杩涘嚭瀛樻姤琛�', value: 'inout' }
+]
+const tableData = ref([])
+const showDatePicker = ref(false)
+const dateValue = ref(Date.now())
+const datePickerTarget = ref('') // single | startMonth | endMonth
+const loadStatus = ref('loadmore') // loadmore | loading | nomore | error
+const page = reactive({ current: 1, size: 20 })
+const data = reactive({
+  searchForm: {
+    reportType: 'daily',
+    singleDate: '',
+    startMonth: '',
+    endMonth: '',
+    startDate: '',
+    endDate: ''
+  }
+})
+const { searchForm } = toRefs(data)
+
+const datePickerMode = computed(() => {
+  if (datePickerTarget.value === 'startMonth' || datePickerTarget.value === 'endMonth') return 'month'
+  return 'date'
+})
+
+const tableTitle = computed(() => {
+  const m = { daily: '鏃ユ姤璇︾粏鏁版嵁', monthly: '鏈堟姤璇︾粏鏁版嵁', inout: '杩涘嚭瀛樻姤琛ㄨ缁嗘暟鎹�' }
+  return m[searchForm.value.reportType] || '鎶ヨ〃鏁版嵁'
+})
+
+const getQueryParams = () => {
+  const p = {
+    reportType: searchForm.value.reportType,
+    current: page.current,
+    size: page.size
+  }
+  if (searchForm.value.reportType === 'daily') {
+    p.reportDate = searchForm.value.singleDate
+  } else if (searchForm.value.reportType === 'monthly') {
+    p.startMonth = searchForm.value.startMonth
+    p.endMonth = searchForm.value.endMonth
+  } else if (searchForm.value.reportType === 'monthly') {
+    p.startMonth = searchForm.value.startMonth
+    p.endMonth = searchForm.value.endMonth
+  } else {
+    p.startDate = searchForm.value.startDate
+    p.endDate = searchForm.value.endDate
+  }
+  return p
+}
+
+const getList = () => {
+  const isFirstPage = page.current === 1
+  if (isFirstPage) {
+    uni.showLoading({ title: '鏌ヨ涓�...', mask: true })
+  }
+  const params = getQueryParams()
+  const isInout = searchForm.value.reportType === 'inout'
+  const api = isInout ? getStockInventoryInAndOutReportList : getStockInventoryReportList
+  api(params)
+    .then(res => {
+      uni.hideLoading()
+      const records = res.data?.records || []
+      const total = res.data?.total || records.length
+      if (isFirstPage) {
+        tableData.value = records
+      } else {
+        tableData.value = [...tableData.value, ...records]
+      }
+      if (tableData.value.length >= total || total === 0) {
+        loadStatus.value = 'nomore'
+      } else {
+        loadStatus.value = 'loadmore'
+      }
+    })
+    .catch(() => {
+      uni.hideLoading()
+      loadStatus.value = 'error'
+      if (isFirstPage) {
+        uni.showToast({ title: '鏌ヨ澶辫触', icon: 'none' })
+      }
+    })
+}
+
+const handleQuery = () => {
+  page.current = 1
+  loadStatus.value = 'loadmore'
+  getList()
+}
+
+const loadMore = () => {
+  if (loadStatus.value === 'nomore' || loadStatus.value === 'loading') return
+  loadStatus.value = 'loading'
+  page.current++
+  getList()
+}
+
+const openDatePicker = (target) => {
+  datePickerTarget.value = target
+  let val = ''
+  if (target === 'single') val = searchForm.value.singleDate
+  else if (target === 'startMonth') val = searchForm.value.startMonth
+  else if (target === 'endMonth') val = searchForm.value.endMonth
+  dateValue.value = val ? new Date(val).getTime() : Date.now()
+  showDatePicker.value = true
+}
+
+const onDateConfirm = (e) => {
+  const isMonth = datePickerTarget.value === 'startMonth' || datePickerTarget.value === 'endMonth'
+  const str = isMonth ? dayjs(e.value).format('YYYY-MM') : formatDateToYMD(e.value)
+  if (datePickerTarget.value === 'single') searchForm.value.singleDate = str
+  else if (datePickerTarget.value === 'startMonth') searchForm.value.startMonth = str
+  else if (datePickerTarget.value === 'endMonth') searchForm.value.endMonth = str
+  showDatePicker.value = false
+  handleQuery()
+}
+
+// 鍒濆鍖栵細鏃ユ姤榛樿浠婂ぉ锛屾湀鎶ラ粯璁ゆ湰鏈堬紝杩涘嚭瀛橀粯璁ゆ渶杩�7澶�
+const initDefaultDates = () => {
+  const today = dayjs()
+  if (!searchForm.value.singleDate) {
+    searchForm.value.singleDate = today.format('YYYY-MM-DD')
+  }
+  if (!searchForm.value.startMonth || !searchForm.value.endMonth) {
+    const startOfMonth = today.startOf('month').format('YYYY-MM-DD')
+    const endOfMonth = today.endOf('month').format('YYYY-MM-DD')
+    searchForm.value.startMonth = startOfMonth
+    searchForm.value.endMonth = endOfMonth
+  }
+  if (!searchForm.value.startDate || !searchForm.value.endDate) {
+    searchForm.value.endDate = today.format('YYYY-MM-DD')
+    searchForm.value.startDate = today.subtract(6, 'day').format('YYYY-MM-DD')
+  }
+}
+
+watch(
+  () => searchForm.value.reportType,
+  () => {
+    // 鍒囨崲鎶ヨ〃绫诲瀷鏃朵繚鐣欏凡绠楀ソ鐨勯粯璁ゆ椂闂达紝鍙噸鏌�
+    handleQuery()
+  }
+)
+
+onShow(() => {
+  initDefaultDates()
+  handleQuery()
+})
+
+const goBack = () => uni.navigateBack()
+</script>
+
+<style lang="scss" scoped>
+.report-page { min-height: 100vh; background: #f5f5f5; padding-bottom: 40rpx; }
+.tabs-wrap { display: flex; background: #fff; padding: 24rpx; gap: 24rpx; }
+.tab-item { flex: 1; text-align: center; padding: 20rpx; border-radius: 12rpx; background: #f0f0f0; font-size: 28rpx; color: #666; }
+.tab-item.active { background: #2979ff; color: #fff; }
+.search-section { background: #fff; margin: 24rpx; padding: 24rpx; border-radius: 16rpx; }
+.search-row { display: flex; align-items: center; margin-bottom: 0; flex-wrap: wrap; }
+.search-row .label { width: 140rpx; font-size: 26rpx; color: #666; }
+.search-row .label.end { margin-left: 24rpx; }
+.date-picker { flex: 1; min-width: 200rpx; padding: 20rpx; background: #f5f5f5; border-radius: 12rpx; font-size: 28rpx; }
+.btn-row { display: flex; gap: 24rpx; margin-top: 24rpx; }
+.btn-query { flex: 1; text-align: center; padding: 24rpx; background: #2979ff; color: #fff; border-radius: 12rpx; }
+.btn-reset { flex: 1; text-align: center; padding: 24rpx; background: #e0e0e0; border-radius: 12rpx; }
+.list-section { margin: 24rpx; }
+.section-header {
+  margin-bottom: 16rpx;
+  padding: 16rpx 20rpx;
+}
+.table-title { font-size: 30rpx; font-weight: 500; color: #333; }
+.card-item {
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 20rpx 24rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+}
+.card-header {
+  padding: 4rpx 0 12rpx;
+}
+.header-main {
+  display: flex;
+  flex-direction: column;
+  gap: 6rpx;
+}
+.product-name {
+  font-size: 30rpx;
+  font-weight: 500;
+  color: #333;
+}
+.sub-title {
+  font-size: 24rpx;
+  color: #999;
+}
+.card-body .row { display: flex; justify-content: space-between; padding: 6rpx 0; font-size: 26rpx; }
+.card-body .l { color: #666; } .card-body .r { color: #333; } .card-body .r.highlight { color: #2979ff; font-weight: 500; }
+.no-data { text-align: center; padding: 60rpx 0; color: #999; font-size: 28rpx; }
+.load-more-wrap { padding: 24rpx 0 8rpx; }
+</style>
diff --git a/src/pages/inventoryManagement/stockReport/view.vue b/src/pages/inventoryManagement/stockReport/view.vue
new file mode 100644
index 0000000..e2d3870
--- /dev/null
+++ b/src/pages/inventoryManagement/stockReport/view.vue
@@ -0,0 +1,173 @@
+<template>
+  <view class="detail-page">
+    <PageHeader title="搴撳瓨鎶ヨ〃璇︽儏" @back="goBack" />
+    <view v-if="detail" class="detail-wrap">
+      <!-- 鍩虹淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">鍩虹淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row">
+            <text class="label">搴忓彿</text>
+            <text class="value">{{ detail.index ?? '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">浜у搧澶х被</text>
+            <text class="value value-strong">{{ detail.productName || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">瑙勬牸鍨嬪彿</text>
+            <text class="value">{{ detail.model || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍗曚綅</text>
+            <text class="value">{{ detail.unit || '-' }}</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 鎶ヨ〃淇℃伅 -->
+      <view class="section-card">
+        <view class="section-head">
+          <view class="section-dot"></view>
+          <text class="section-title">鎶ヨ〃淇℃伅</text>
+        </view>
+        <view class="section-body">
+          <view class="detail-row" v-if="type !== 'inout'">
+            <text class="label">鍏ュ簱鏃堕棿</text>
+            <text class="value">{{ detail.createTime || '-' }}</text>
+          </view>
+          <view class="detail-row" v-if="type !== 'inout'">
+            <text class="label">鍏ュ簱鎵规</text>
+            <text class="value">{{ detail.inboundBatches || '-' }}</text>
+          </view>
+          <view class="detail-row">
+            <text class="label">鍏ュ簱鏁伴噺</text>
+            <text class="value">{{ detail.totalStockIn ?? detail.stockInNum ?? '-' }}</text>
+          </view>
+          <view class="detail-row" v-if="type === 'inout'">
+            <text class="label">鍑哄簱鏁伴噺</text>
+            <text class="value">{{ detail.totalStockOut ?? '-' }}</text>
+          </view>
+          <view class="detail-row detail-row-highlight">
+            <text class="label">鐜板湪搴撳瓨</text>
+            <text class="value value-num">{{ detail.currentStock ?? '-' }}</text>
+          </view>
+          <view class="detail-row" v-if="detail.createBy">
+            <text class="label">鍏ュ簱浜�</text>
+            <text class="value">{{ detail.createBy }}</text>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view v-else class="empty">
+      <text class="empty-text">鏆傛棤璇︽儏鏁版嵁</text>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import PageHeader from '@/components/PageHeader.vue'
+
+const detail = ref(null)
+const type = ref('daily')
+
+onLoad(() => {
+  const cached = uni.getStorageSync('stockReportDetail')
+  if (cached) {
+    try {
+      const payload = typeof cached === 'string' ? JSON.parse(cached) : cached
+      type.value = payload?.type || 'daily'
+      detail.value = payload?.item || null
+      uni.removeStorageSync('stockReportDetail')
+    } catch (e) {
+      uni.removeStorageSync('stockReportDetail')
+    }
+  }
+})
+
+const goBack = () => uni.navigateBack()
+</script>
+
+<style lang="scss" scoped>
+.detail-page {
+  min-height: 100vh;
+  background: #f5f5f5;
+  padding-bottom: 40rpx;
+}
+.detail-wrap {
+  padding: 24rpx;
+}
+.empty {
+  padding: 120rpx 48rpx;
+  text-align: center;
+}
+.empty-text {
+  color: #8c9aa8;
+  font-size: 28rpx;
+}
+.section-card {
+  background: #fff;
+  border-radius: 16rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
+  overflow: hidden;
+}
+.section-head {
+  display: flex;
+  align-items: center;
+  padding: 20rpx 24rpx;
+  border-bottom: 1rpx solid #eee;
+}
+.section-dot {
+  width: 8rpx;
+  height: 8rpx;
+  border-radius: 50%;
+  background: #2979ff;
+  margin-right: 12rpx;
+}
+.section-title {
+  font-size: 30rpx;
+  font-weight: 500;
+  color: #333;
+}
+.section-body {
+  padding: 12rpx 24rpx 20rpx;
+}
+.detail-row {
+  display: flex;
+  align-items: center;
+  min-height: 80rpx;
+  font-size: 28rpx;
+}
+.detail-row .label {
+  width: 200rpx;
+  flex-shrink: 0;
+  color: #6b7c93;
+  font-size: 26rpx;
+}
+.detail-row .value {
+  flex: 1;
+  color: #2c3e50;
+  text-align: right;
+  word-break: break-all;
+  font-size: 28rpx;
+}
+.detail-row .value-strong {
+  color: #1e3a5f;
+  font-weight: 500;
+}
+.detail-row .value-num {
+  color: #2979ff;
+  font-weight: 600;
+  font-size: 32rpx;
+}
+.detail-row-highlight {
+  margin-top: 8rpx;
+}
+</style>
+

--
Gitblit v1.9.3