From 7a93a85f75bcfc8001ea1d3b921860806a8209ac Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 29 十月 2026 12:28:48 +0800
Subject: [PATCH] feat(mobile): 新增多个移动端功能模块并优化扫码流程

---
 src/views/wls/returnsales/modules/line-list.vue |   77 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/src/views/wls/returnsales/modules/line-list.vue b/src/views/wls/returnsales/modules/line-list.vue
index eac0e37..2e78bf0 100644
--- a/src/views/wls/returnsales/modules/line-list.vue
+++ b/src/views/wls/returnsales/modules/line-list.vue
@@ -5,6 +5,8 @@
 import type { MesWmReturnSalesDetailApi } from '#/api/mes/wm/returnsales/detail';
 import type { MesWmReturnSalesLineApi } from '#/api/mes/wm/returnsales/line';
 
+import type { TraceResult } from '#/utils/traceLookup';
+
 import { computed, reactive } from 'vue';
 
 import { useVbenModal } from '@vben/common-ui';
@@ -13,11 +15,15 @@
 
 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
 import { getReturnSalesDetailListByLineId } from '#/api/mes/wm/returnsales/detail';
+import { getBatchPage } from '#/api/mes/wm/batch';
+import { getReturnableProductSalesLineList } from '#/api/mes/wm/returnsales';
 import {
   deleteReturnSalesLine,
   getReturnSalesLinePage,
 } from '#/api/mes/wm/returnsales/line';
+import TraceScanPanel from '#/components/TraceScanPanel.vue';
 import { $t } from '#/locales';
+import { traceQuantity } from '#/utils/traceLookup';
 import { PrinterLabel } from '#/views/wls/barcode/components';
 
 import { useLineGridColumns } from '../data';
@@ -68,6 +74,72 @@
       returnId: props.returnId,
     })
     .open();
+}
+
+/** 鎵爜甯﹀嚭锛氬叧鑱斿嚭搴撳崟鏃跺尮閰嶅彲閫�鍑哄簱琛岋紝鍚﹀垯鎸夋壒娆″甫鍑虹墿鏂欎笌鏁伴噺 */
+async function handleTraceConfirm(trace: TraceResult) {
+  const { batchCode, itemId } = trace.data;
+  if (!itemId || !batchCode) {
+    message.warning('璇ヨ拷婧爜鏈粦瀹氱墿鏂欐垨鎵规');
+    return;
+  }
+  try {
+    if (props.productSalesId) {
+      const lines = await getReturnableProductSalesLineList(
+        props.productSalesId,
+      );
+      const matched = lines.find(
+        (line) => line.itemId === itemId && line.batchCode === batchCode,
+      );
+      if (!matched) {
+        message.warning('璇ヨ拷婧爜瀵瑰簲鐨勬壒娆′笉鍦ㄦ湰鍗曞彲閫�鑼冨洿鍐�');
+        return;
+      }
+      const returnable = Number(matched.returnableQuantity ?? 0);
+      const quantity = Math.min(traceQuantity(trace) ?? returnable, returnable);
+      lineFormModalApi
+        .setData({
+          clientId: props.clientId,
+          defaults: {
+            batchCode: matched.batchCode,
+            itemId: matched.itemId,
+            productSalesLineId: matched.productSalesLineId,
+            quantity,
+            returnableQuantity: returnable,
+          },
+          productSalesId: props.productSalesId,
+          returnId: props.returnId,
+        })
+        .open();
+      return;
+    }
+    const batches = await getBatchPage({
+      code: batchCode,
+      itemId,
+      pageNo: 1,
+      pageSize: 20,
+    });
+    const batch = batches.list.find((item) => item.code === batchCode);
+    if (!batch?.id) {
+      message.warning('鏈壘鍒拌杩芥函鐮佸搴旂殑鍏ュ簱鎵规');
+      return;
+    }
+    lineFormModalApi
+      .setData({
+        clientId: props.clientId,
+        defaults: {
+          batchCode,
+          batchId: batch.id,
+          itemId,
+          quantity: traceQuantity(trace),
+        },
+        productSalesId: props.productSalesId,
+        returnId: props.returnId,
+      })
+      .open();
+  } catch (e) {
+    message.error(e instanceof Error ? e.message : '鎵爜甯﹀嚭澶辫触');
+  }
 }
 
 /** 缂栬緫鐗╂枡 */
@@ -188,6 +260,11 @@
   <div>
     <LineFormModal @success="handleRefresh" />
     <DetailFormModal @success="handleDetailSuccess" />
+    <TraceScanPanel
+      v-if="isEditable"
+      title="鎵爜甯﹀嚭閫�璐ф槑缁�"
+      @confirm="handleTraceConfirm"
+    />
     <Grid table-title="鐗╂枡淇℃伅">
       <template v-if="isEditable" #toolbar-tools>
         <TableAction

--
Gitblit v1.9.3