From 03a05815d7ea5612206b6cfe5d6537b4d4cedc0a Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 九月 2026 11:41:32 +0800
Subject: [PATCH] 天津潜宇塑胶app 1.添加采购需求、库存盘点、计件单价配置、产量统计、材料消耗核算、成本核算分析页面

---
 src/pages/productionDesign/bom/index.vue |  279 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 273 insertions(+), 6 deletions(-)

diff --git a/src/pages/productionDesign/bom/index.vue b/src/pages/productionDesign/bom/index.vue
index 97ba5f6..ea79eba 100644
--- a/src/pages/productionDesign/bom/index.vue
+++ b/src/pages/productionDesign/bom/index.vue
@@ -33,9 +33,14 @@
             </view>
             <text class="item-id">{{ item.bomNo || "-" }}</text>
           </view>
-          <up-tag :text="'V' + (item.version || '1.0')"
-                  type="primary"
-                  size="mini" />
+          <view class="item-right">
+            <up-tag :text="'V' + (item.version || '1.0')"
+                    type="primary"
+                    size="mini" />
+            <up-tag :text="isEnabled(item) ? '鍚敤' : '鍋滅敤'"
+                    :type="isEnabled(item) ? 'success' : 'info'"
+                    size="mini" />
+          </view>
         </view>
         <up-divider></up-divider>
         <view class="item-details">
@@ -57,6 +62,15 @@
                      size="small"
                      type="primary"
                      @click="goStructure(item)">鏌ョ湅璇︽儏</up-button>
+          <up-button class="action-btn"
+                     size="small"
+                     :type="isEnabled(item) ? 'warning' : 'success'"
+                     @click="toggleStatus(item)">{{ isEnabled(item) ? "鍋滅敤" : "鍚敤" }}</up-button>
+          <up-button class="action-btn"
+                     size="small"
+                     type="primary"
+                     plain
+                     @click="openKitCheck(item)">榻愬鍒嗘瀽</up-button>
         </view>
       </view>
       <up-loadmore :status="pageStatus" />
@@ -66,13 +80,92 @@
       <up-empty text="鏆傛棤BOM鏁版嵁"
                 mode="list"></up-empty>
     </view>
+
+    <!-- 榻愬鍒嗘瀽寮圭獥 -->
+    <up-popup :show="showKitPopup"
+              mode="bottom"
+              round="10"
+              @close="showKitPopup = false">
+      <view class="kit-popup">
+        <view class="popup-header">
+          <text class="popup-title">榻愬鍒嗘瀽 - {{ currentBom.bomNo || "" }}</text>
+        </view>
+        <view class="kit-form">
+          <text class="kit-form-label">闇�姹傛暟閲�</text>
+          <view class="kit-form-input">
+            <up-number-box v-model="demandQty"
+                           :min="0"
+                           :step="1"></up-number-box>
+          </view>
+          <up-button type="primary"
+                     size="small"
+                     :loading="kitLoading"
+                     text="鍒嗘瀽"
+                     @click="handleKitCheck"></up-button>
+        </view>
+        <scroll-view scroll-y
+                     class="kit-result">
+          <view v-if="kitResult.length > 0">
+            <view v-for="(row, index) in kitResult"
+                  :key="index"
+                  class="kit-item">
+              <view class="kit-item-header">
+                <text class="kit-name">{{ row.productName || "-" }}</text>
+                <text class="kit-model">{{ row.model || "-" }}</text>
+                <up-tag v-if="num(row.shortageQty) > 0"
+                        text="缂哄彛"
+                        type="error"
+                        size="mini" />
+              </view>
+              <view class="kit-grid">
+                <view class="kit-cell">
+                  <text class="kit-label">鍗曚綅</text>
+                  <text class="kit-value">{{ row.unit || "-" }}</text>
+                </view>
+                <view class="kit-cell">
+                  <text class="kit-label">闇�姹傛暟閲�</text>
+                  <text class="kit-value">{{ num(row.requiredQty) }}</text>
+                </view>
+                <view class="kit-cell">
+                  <text class="kit-label">鍙敤搴撳瓨</text>
+                  <text class="kit-value">{{ num(row.availableQty) }}</text>
+                </view>
+                <view class="kit-cell">
+                  <text class="kit-label">缂哄彛鏁伴噺</text>
+                  <text class="kit-value"
+                        :class="{ danger: num(row.shortageQty) > 0 }">{{ num(row.shortageQty) }}</text>
+                </view>
+              </view>
+            </view>
+          </view>
+          <view v-else
+                class="kit-empty">
+            <up-empty mode="data"
+                      :text="kitDone ? '搴撳瓨榻愬锛屾棤缂哄彛' : '璇疯緭鍏ラ渶姹傛暟閲忓悗鐐瑰嚮鍒嗘瀽'"></up-empty>
+          </view>
+        </scroll-view>
+        <view class="filter-actions">
+          <up-button type="primary"
+                     size="default"
+                     :disabled="!kitDone"
+                     text="鐢熸垚閲囪喘闇�姹�"
+                     @click="handleGenerateDemand"></up-button>
+        </view>
+      </view>
+    </up-popup>
   </view>
 </template>
 
 <script setup>
   import { reactive, ref } from "vue";
   import { onReachBottom, onShow } from "@dcloudio/uni-app";
-  import { listPage } from "@/api/productionManagement/bom";
+  import {
+    listPage,
+    changeStatus,
+    kitCheck,
+    generateDemand,
+  } from "@/api/productionManagement/bom";
+  import PageHeader from "@/components/PageHeader.vue";
 
   const queryParams = reactive({
     productName: "",
@@ -85,6 +178,15 @@
     size: 3,
     total: 0,
   });
+
+  // 鍚庣涓嶈繑鍥� status 鏃舵寜鍚敤灞曠ず锛堝吋瀹硅�佹暟鎹級
+  const isEnabled = item =>
+    item.status === undefined ||
+    item.status === null ||
+    Number(item.status) === 1;
+
+  // decimal 鍙兘鏄瓧绗︿覆锛岀粺涓�杞暟瀛楀厹搴�
+  const num = val => Number(val) || 0;
 
   const goBack = () => {
     uni.navigateBack();
@@ -125,7 +227,7 @@
         }
       })
       .catch(() => {
-        uni.showToast({ title: "鏌ヨ澶辫触", icon: "error" });
+        // 閿欒鎻愮ず鐢� request 缁熶竴澶勭悊
         pageStatus.value = "loadmore";
       });
   };
@@ -142,6 +244,87 @@
         item.remark || ""
       )}&version=${encodeURIComponent(item.version || 1)}`,
     });
+  };
+
+  // 鍚敤/鍋滅敤锛宻tatus=1 鏃跺悗绔嚜鍔ㄥ仠鐢ㄥ悓瑙勬牸鍏跺畠鐗堟湰
+  const toggleStatus = item => {
+    const enabled = isEnabled(item);
+    const nextStatus = enabled ? 0 : 1;
+    const actionText = enabled ? "鍋滅敤" : "鍚敤";
+    uni.showModal({
+      title: "鎻愮ず",
+      content: `纭畾${actionText}璇OM鐗堟湰鍚楋紵`,
+      success: res => {
+        if (!res.confirm) return;
+        uni.showLoading({ title: "澶勭悊涓�...", mask: true });
+        changeStatus({ id: item.id, status: nextStatus })
+          .then(() => {
+            uni.hideLoading();
+            uni.showToast({ title: `${actionText}鎴愬姛`, icon: "none" });
+            handleSearch();
+          })
+          .catch(() => {
+            uni.hideLoading();
+          });
+      },
+    });
+  };
+
+  // --- 榻愬鍒嗘瀽 ---
+  const showKitPopup = ref(false);
+  const kitLoading = ref(false);
+  const kitDone = ref(false);
+  const currentBom = ref({});
+  const demandQty = ref(1);
+  const kitResult = ref([]);
+
+  const openKitCheck = item => {
+    currentBom.value = item;
+    demandQty.value = 1;
+    kitResult.value = [];
+    kitDone.value = false;
+    showKitPopup.value = true;
+  };
+
+  const handleKitCheck = () => {
+    const qty = Number(demandQty.value);
+    if (!Number.isFinite(qty) || qty <= 0) {
+      uni.showToast({ title: "闇�姹傛暟閲忓繀椤诲ぇ浜�0", icon: "none" });
+      return;
+    }
+    kitLoading.value = true;
+    kitCheck({ bomId: currentBom.value.id, demandQty: qty })
+      .then(res => {
+        kitResult.value = res?.data || [];
+        kitDone.value = true;
+      })
+      .catch(() => {
+        // 閿欒鎻愮ず鐢� request 缁熶竴澶勭悊
+        kitResult.value = [];
+        kitDone.value = false;
+      })
+      .finally(() => {
+        kitLoading.value = false;
+      });
+  };
+
+  const handleGenerateDemand = () => {
+    uni.showLoading({ title: "澶勭悊涓�...", mask: true });
+    generateDemand({
+      bomId: currentBom.value.id,
+      demandQty: Number(demandQty.value),
+    })
+      .then(res => {
+        uni.hideLoading();
+        uni.showModal({
+          title: "鎻愮ず",
+          content: String(res?.data ?? "閲囪喘闇�姹傜敓鎴愬畬鎴�"),
+          showCancel: false,
+        });
+      })
+      .catch(() => {
+        uni.hideLoading();
+      });
   };
 
   onReachBottom(() => {
@@ -172,8 +355,92 @@
   }
 
   .action-btn {
-    width: calc(50% - 15rpx);
+    width: calc(33.33% - 10rpx);
     margin: 0 !important;
     margin-bottom: 15rpx !important;
   }
+
+  // --- 榻愬鍒嗘瀽寮圭獥 ---
+  .kit-popup {
+    padding-bottom: 20rpx;
+  }
+
+  .kit-form {
+    display: flex;
+    align-items: center;
+    gap: 16rpx;
+    padding: 20rpx 30rpx;
+
+    .kit-form-label {
+      font-size: 28rpx;
+      color: #333;
+    }
+
+    .kit-form-input {
+      flex: 1;
+    }
+  }
+
+  .kit-result {
+    height: 600rpx;
+    padding: 0 30rpx;
+  }
+
+  .kit-item {
+    border: 1rpx solid #f0f0f0;
+    border-radius: 12rpx;
+    padding: 16rpx;
+    margin-bottom: 16rpx;
+  }
+
+  .kit-item-header {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+    margin-bottom: 12rpx;
+
+    .kit-name {
+      font-size: 28rpx;
+      color: #333;
+      font-weight: 500;
+    }
+
+    .kit-model {
+      font-size: 24rpx;
+      color: #999;
+      flex: 1;
+    }
+  }
+
+  .kit-grid {
+    display: flex;
+    flex-wrap: wrap;
+
+    .kit-cell {
+      width: 50%;
+      display: flex;
+      align-items: center;
+      margin-bottom: 8rpx;
+
+      .kit-label {
+        font-size: 24rpx;
+        color: #777;
+        min-width: 110rpx;
+      }
+
+      .kit-value {
+        font-size: 24rpx;
+        color: #333;
+
+        &.danger {
+          color: #ee0a24;
+          font-weight: 500;
+        }
+      }
+    }
+  }
+
+  .kit-empty {
+    padding: 40rpx 0;
+  }
 </style>

--
Gitblit v1.9.3