From da583971227d237848ea28d54641dd20428f3da6 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期一, 29 九月 2025 11:04:35 +0800
Subject: [PATCH] 绞线报工:二维码领用单丝,一层领完之后就自动切换层(从里到外),PDA:领用时需要选中层数,然后进行领用。PC端需要分层展示各层单丝领用情况。

---
 src/pages/production/twist/components/StatisticsModal.vue |  262 ++++++++++++++++++++++++++++++++
 src/api/product/twist.ts                                  |    9 +
 src/pages/production/twist/receive/monofil.vue            |  186 ++++++++++++++++++++---
 3 files changed, 432 insertions(+), 25 deletions(-)

diff --git a/src/api/product/twist.ts b/src/api/product/twist.ts
index 900e4a9..5bca559 100644
--- a/src/api/product/twist.ts
+++ b/src/api/product/twist.ts
@@ -44,6 +44,15 @@
       data: data,
     });
   },
+
+  // 鑾峰彇鏍瑰彿
+  getRootNumber(params: { wireId: number }) {
+    return request<BaseResult<any>>({
+      url: "/app/getStrandedWireDishTypeByWire",
+      method: "GET",
+      data: params,
+    });
+  },
 };
 
 export default TwistApi;
diff --git a/src/pages/production/twist/components/StatisticsModal.vue b/src/pages/production/twist/components/StatisticsModal.vue
new file mode 100644
index 0000000..4c1f988
--- /dev/null
+++ b/src/pages/production/twist/components/StatisticsModal.vue
@@ -0,0 +1,262 @@
+<template>
+  <!-- 浣跨敤鍘熺敓瀹炵幇鏇夸唬 wd-popup -->
+  <view
+    v-if="visible"
+    style="
+      position: fixed;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background: rgba(0, 0, 0, 0.5);
+      z-index: 10000;
+    "
+  >
+    <view
+      class="statistics-modal"
+      style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)"
+    >
+      <view class="modal-header">
+        <text class="title">鍗曚笣棰嗙敤缁熻</text>
+        <wd-icon name="close" @click="handleClose" />
+      </view>
+
+      <view class="modal-content">
+        <view class="summary-section">
+          <view class="summary-item">
+            <text class="label">鎬荤洏鏁帮細</text>
+            <text class="value">{{ totalCount }} 鐩�</text>
+          </view>
+          <view class="summary-item">
+            <text class="label">鎬婚噸閲忥細</text>
+            <text class="value">{{ totalWeight.toFixed(2) }} kg</text>
+          </view>
+          <view class="summary-item">
+            <text class="label">鎬婚暱搴︼細</text>
+            <text class="value">{{ totalLength.toFixed(2) }} M</text>
+          </view>
+        </view>
+
+        <view class="layer-section">
+          <text class="section-title">鍚勫眰缁熻</text>
+          <view class="layer-list">
+            <view v-for="layer in layerStatistics" :key="layer.twistedLayer" class="layer-item">
+              <view class="layer-header">
+                <text class="layer-name">{{ layer.twistedLayer }}</text>
+                <text class="layer-count">{{ layer.count }} 鐩�</text>
+              </view>
+              <view class="layer-details">
+                <text class="detail-text">閲嶉噺锛歿{ layer.weight.toFixed(2) }} kg</text>
+                <text class="detail-text">闀垮害锛歿{ layer.length.toFixed(2) }} M</text>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <view class="modal-footer">
+        <wd-button @click="handleClose" type="default">鍙栨秷</wd-button>
+        <wd-button type="primary" @click="handleConfirm" custom-class="confirm-btn">
+          纭淇濆瓨
+        </wd-button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup lang="ts">
+interface LayerStatistic {
+  twistedLayer: string;
+  count: number;
+  weight: number;
+  length: number;
+}
+
+const props = defineProps<{
+  visible: boolean;
+  nodeList: any[];
+}>();
+
+// 鐩戝惉 visible 鍙樺寲
+watch(
+  () => props.visible,
+  () => {
+    // 鍙互鍦ㄨ繖閲屾坊鍔犻渶瑕佺殑閫昏緫
+  }
+);
+
+const emit = defineEmits<{
+  "update:visible": [value: boolean];
+  confirm: [];
+}>();
+
+// 璁$畻缁熻鏁版嵁
+const layerStatistics = computed<LayerStatistic[]>(() => {
+  const stats: { [key: string]: LayerStatistic } = {};
+
+  // 閬嶅巻姣忓眰鐨勫崟涓濇暟鎹�
+  props.nodeList.forEach((node) => {
+    const layerName = node.twistedLayer;
+    if (!stats[layerName]) {
+      stats[layerName] = {
+        twistedLayer: layerName,
+        count: 0,
+        weight: 0,
+        length: 0,
+      };
+    }
+
+    // 缁熻璇ュ眰鐨勫崟涓濇暟鎹�
+    if (node.strandedWireDish && Array.isArray(node.strandedWireDish)) {
+      node.strandedWireDish.forEach((item: any) => {
+        stats[layerName].count++;
+        stats[layerName].weight += parseFloat(item.actuallyWeight || 0);
+        stats[layerName].length += parseFloat(item.amount || 0);
+      });
+    }
+  });
+
+  return Object.values(stats);
+});
+
+// 璁$畻鎬绘暟鎹�
+const totalCount = computed(() => {
+  return layerStatistics.value.reduce((sum, layer) => sum + layer.count, 0);
+});
+
+const totalWeight = computed(() => {
+  return layerStatistics.value.reduce((sum, layer) => sum + layer.weight, 0);
+});
+
+const totalLength = computed(() => {
+  return layerStatistics.value.reduce((sum, layer) => sum + layer.length, 0);
+});
+
+const handleClose = () => {
+  emit("update:visible", false);
+};
+
+const handleConfirm = () => {
+  emit("confirm");
+  emit("update:visible", false);
+};
+</script>
+
+<style lang="scss" scoped>
+.statistics-modal {
+  width: 320px;
+  background: #fff;
+  border-radius: 12px;
+  overflow: hidden;
+}
+
+.modal-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 16px 20px;
+  border-bottom: 1px solid #f0f0f0;
+
+  .title {
+    font-size: 18px;
+    font-weight: 600;
+    color: #333;
+  }
+}
+
+.modal-content {
+  padding: 20px;
+}
+
+.summary-section {
+  margin-bottom: 20px;
+
+  .summary-item {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 8px;
+
+    .label {
+      font-size: 16px;
+      color: #666;
+    }
+
+    .value {
+      font-size: 16px;
+      font-weight: 600;
+      color: #0d867f;
+    }
+  }
+}
+
+.layer-section {
+  .section-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333;
+    margin-bottom: 12px;
+    display: block;
+  }
+
+  .layer-list {
+    .layer-item {
+      background: #f8f9fa;
+      border-radius: 8px;
+      padding: 12px;
+      margin-bottom: 8px;
+
+      .layer-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 4px;
+
+        .layer-name {
+          font-size: 14px;
+          font-weight: 500;
+          color: #333;
+        }
+
+        .layer-count {
+          font-size: 14px;
+          color: #0d867f;
+          font-weight: 600;
+        }
+      }
+
+      .layer-details {
+        .detail-text {
+          font-size: 12px;
+          color: #666;
+        }
+      }
+    }
+  }
+}
+
+.modal-footer {
+  display: flex;
+  gap: 12px;
+  padding: 16px 20px;
+  border-top: 1px solid #f0f0f0;
+
+  .cancel-btn {
+    flex: 1;
+  }
+
+  .confirm-btn {
+    flex: 1;
+  }
+}
+
+// 纭鎸夐挳鏍峰紡
+:deep(.confirm-btn) {
+  background-color: #0d867f !important;
+  border-color: #0d867f !important;
+}
+
+:deep(.confirm-btn .wd-button__content) {
+  color: #fff !important;
+}
+</style>
diff --git a/src/pages/production/twist/receive/monofil.vue b/src/pages/production/twist/receive/monofil.vue
index 35c416d..d5cc002 100644
--- a/src/pages/production/twist/receive/monofil.vue
+++ b/src/pages/production/twist/receive/monofil.vue
@@ -2,7 +2,6 @@
   <view class="list_box">
     <z-paging
       ref="pagingRef"
-      v-model="cardList"
       :fixed="false"
       :auto-show-back-to-top="true"
       :loading-more-enabled="false"
@@ -15,7 +14,16 @@
           </template>
         </CardTitle>
       </template>
-      <MonofilCard v-for="(item, index) in cardList" :key="index" :data="item" />
+      <!-- <MonofilCard v-for="(item, index) in cardList" :key="index" :data="item" /> -->
+      <wd-tabs v-model="tab" slidable="always">
+        <block v-for="item in nodeList" :key="item">
+          <wd-tab :title="item.twistedLayer" :name="item.twistedLayer">
+            <view class="content">
+              <MonofilCard v-for="(m, i) in item.strandedWireDish" :key="i" :data="m" />
+            </view>
+          </wd-tab>
+        </block>
+      </wd-tabs>
       <template #bottom>
         <view class="flex justify-center items-center">
           <wd-button block @click="save">
@@ -25,6 +33,11 @@
       </template>
     </z-paging>
     <Scan ref="scanRef" emitName="scanMono" />
+    <StatisticsModal
+      v-model:visible="showStatisticsModal"
+      :nodeList="nodeList"
+      @confirm="handleConfirmSave"
+    />
     <wd-toast />
   </view>
 </template>
@@ -32,6 +45,7 @@
 <script setup lang="ts">
 import CardTitle from "@/components/card-title/index.vue";
 import MonofilCard from "../components/MonofilCard.vue";
+import StatisticsModal from "../components/StatisticsModal.vue";
 import { useToast } from "wot-design-uni";
 import { onLoad, onUnload } from "@dcloudio/uni-app";
 import Scan from "@/components/scan/index.vue";
@@ -44,8 +58,17 @@
 const paramsId = ref();
 const pagingRef = ref();
 const scanRef = ref();
-const cardList = ref<any[]>([]);
 const toast = useToast();
+const tab = ref("");
+const showStatisticsModal = ref(false);
+
+// 鐩戝惉鏍囩鍒囨崲
+watch(tab, () => {
+  if (tab.value) {
+    console.log("tab.value:===========1", tab.value);
+    getList();
+  }
+});
 
 const getScanCode = async (code: any) => {
   console.log("鑷畾涔夋壂鎻忕殑缁撴灉鍥炶皟鍑芥暟:", code);
@@ -55,24 +78,43 @@
   const { data } = await TwistApi.getScarn({
     outPutId: JSON.parse(code.code).id,
   });
-  const exists = cardList.value.some((item) => item.monofilamentNumber === data.monofilamentNumber);
+
+  // 妫�鏌ユ槸鍚﹀凡閫夋嫨鏍囩
+  if (!tab.value) {
+    toast.error("璇峰厛閫夋嫨涓�涓眰");
+    return;
+  }
+
+  // 鎵惧埌褰撳墠閫変腑鐨勫眰
+  console.log("tab.value:===========2", tab.value);
+  const currentLayer = nodeList.value.find((node) => node.twistedLayer === tab.value);
+  if (!currentLayer) {
+    toast.error("鏈壘鍒板綋鍓嶉�変腑鐨勫眰");
+    return;
+  }
+
+  // 妫�鏌ュ綋鍓嶅眰鏄惁宸插瓨鍦ㄨ鍗曚笣
+  const exists = currentLayer.strandedWireDish?.some(
+    (item: any) => item.monofilamentNumber === data.monofilamentNumber
+  );
   if (!exists) {
     const { id, outPutId, wireId, oneLength, ...rest } = data;
-    console.log("sb", {
+    const newItem = {
       wireId: paramsId.value,
       outputId: id,
       amount: oneLength,
       ongLength: oneLength,
       ...rest,
-    });
-    cardList.value.push({
-      wireId: paramsId.value,
-      outputId: id,
-      amount: oneLength,
-      ongLength: oneLength,
-      ...rest,
-    });
-    pagingRef.value.complete(cardList.value);
+    };
+
+    // 娣诲姞鍒板綋鍓嶅眰鐨� strandedWireDish 涓�
+    if (!currentLayer.strandedWireDish) {
+      currentLayer.strandedWireDish = [];
+    }
+    currentLayer.strandedWireDish.push(newItem);
+
+    // 鍒锋柊褰撳墠灞傜殑鏁版嵁鏄剧ず
+    getList();
   } else {
     toast.error("璇ュ崟涓濆凡棰嗙敤锛岃鍕块噸澶嶆壂鐮�");
   }
@@ -83,22 +125,100 @@
 };
 
 const getList = async () => {
-  const { code, data } = await ManageApi.getStrandedWireDish({
-    wireId: paramsId.value,
-    type: "鍗曚笣",
-  });
-  if (code == 200) {
-    pagingRef.value.complete(data);
+  // 浠庡綋鍓嶉�変腑灞傜殑 strandedWireDish 涓幏鍙栨暟鎹�
+  const currentLayer = nodeList.value.find((node) => node.twistedLayer === tab.value);
+  if (currentLayer && currentLayer.strandedWireDish) {
+    pagingRef.value.complete(currentLayer.strandedWireDish);
+  } else {
+    pagingRef.value.complete([]);
   }
 };
 
-const save = async () => {
-  const value = cardList.value.filter((item: { id?: number }) => item.id === undefined || item.id === null);
+let nodeList = ref<any[]>([]);
+// 鑾峰彇鏍瑰彿
+const getRootNumber = async (wireId: number) => {
+  const { code, data, msg } = await TwistApi.getRootNumber({ wireId });
+  if (code === 200) {
+    nodeList.value = data.nodeList;
+    if (data.otherStrandedWireDish && data.otherStrandedWireDish.length > 0) {
+      nodeList.value.push({
+        strandedWireDish: data.otherStrandedWireDish,
+        twistedLayer: "鍏朵粬",
+        twistId: null,
+      });
+    }
+    // 璁剧疆榛樿绗竴灞�
+    if (nodeList.value && nodeList.value.length > 0 && !tab.value) {
+      tab.value = nodeList.value[0].twistedLayer;
+      console.log("璁剧疆榛樿绗竴灞�:", tab.value);
+      // 璁剧疆榛樿鏍囩鍚庯紝鍔犺浇绗竴灞傜殑鏁版嵁
+      getList();
+    }
+  } else {
+    toast.error(msg || "鑾峰彇鏍瑰彿澶辫触");
+  }
+};
 
-  const { code,msg } = await TwistApi.addStrandedWireDish(value);
+const save = () => {
+  // 妫�鏌� nodeList 涓槸鍚︽湁鏂扮殑鍗曚笣鏁版嵁闇�瑕佷繚瀛�
+  let hasNewData = false;
+
+  nodeList.value.forEach((node) => {
+    if (node.strandedWireDish && Array.isArray(node.strandedWireDish)) {
+      const hasNewInLayer = node.strandedWireDish.some(
+        (item: { id?: number }) => item.id === undefined || item.id === null
+      );
+      if (hasNewInLayer) {
+        hasNewData = true;
+      }
+    }
+  });
+
+  if (!hasNewData) {
+    toast.error("娌℃湁鏂扮殑鍗曚笣鏁版嵁闇�瑕佷繚瀛�");
+    return;
+  }
+
+  // 鏄剧ず缁熻寮规
+  showStatisticsModal.value = true;
+};
+
+const handleConfirmSave = async () => {
+  // 浠� nodeList 涓敹闆嗘墍鏈夐渶瑕佷繚瀛樼殑鏂板崟涓濇暟鎹�
+  const newData: any[] = [];
+
+  nodeList.value.forEach((node) => {
+    node.strandedWireDish.forEach((item: any) => {
+      item.twistId = node.twistId;
+    });
+    if (node.strandedWireDish && Array.isArray(node.strandedWireDish)) {
+      const layerNewData = node.strandedWireDish.filter(
+        (item: { id?: number }) => item.id === undefined || item.id === null
+      );
+      newData.push(...layerNewData);
+    }
+  });
+
+  if (newData.length === 0) {
+    toast.error("娌℃湁鏂扮殑鍗曚笣鏁版嵁闇�瑕佷繚瀛�");
+    return;
+  }
+
+  const { code, msg } = await TwistApi.addStrandedWireDish(newData);
   if (code == 200) {
     toast.success(msg);
-    cardList.value = [];
+
+    // 娓呯┖鎵�鏈夊眰涓凡淇濆瓨鐨勬暟鎹紙缁欏凡淇濆瓨鐨勬暟鎹坊鍔� id锛�
+    nodeList.value.forEach((node) => {
+      if (node.strandedWireDish && Array.isArray(node.strandedWireDish)) {
+        node.strandedWireDish.forEach((item: any) => {
+          if (item.id === undefined || item.id === null) {
+            item.id = Date.now(); // 涓存椂鏍囪涓哄凡淇濆瓨
+          }
+        });
+      }
+    });
+
     pagingRef.value.refresh();
     getList();
   } else {
@@ -106,10 +226,14 @@
   }
 };
 
-onLoad((options: any) => {
+onLoad(async (options: any) => {
   // 寮�鍚箍鎾洃鍚簨浠�
   uni.$on("scanMono", getScanCode);
   paramsId.value = options.id;
+
+  // 璋冪敤鑾峰彇鏍瑰彿鎺ュ彛
+  getRootNumber(options.id);
+  // getRootNumber(118);
 });
 onUnload(() => {
   // 寮�鍚箍鎾洃鍚簨浠�
@@ -125,4 +249,16 @@
 :deep(.wd-button__content) {
   color: #0d867f;
 }
+:deep(.zp-paging-container) {
+  background: transparent !important;
+}
+:deep(.zp-paging-container-content) {
+  background: transparent !important;
+}
+:deep(.wd-tabs) {
+  background: transparent !important;
+}
+:deep(.wd-tabs__nav) {
+  margin-bottom: 10px;
+}
 </style>

--
Gitblit v1.9.3