"use client"; import { ReactNode, createContext, useCallback, useContext, useEffect, useState, } from "react"; import { useQrCodeScannerContext } from "./QrCodeScannerProvider"; export interface TestQrCodeContext { enableTestMode: boolean; setEnableTestMode: (enabled: boolean) => void; testScanLotByIndex: (index: number) => void; testScanAllLots: () => void; getActiveLots: () => any[]; onTestScan?: (data: TestScanData) => Promise; } export interface TestScanData { type: "single" | "all"; lotIndex?: number; lots: any[]; } interface TestQrCodeProviderProps { children: ReactNode; lotData: any[]; // 当前页面的批次数据 onScanLot?: (lotNo: string) => Promise; // 扫描单个批次的回调 filterActive?: (lot: any) => boolean; // 过滤活跃批次的函数 onBatchScan?: () => Promise; } export const TestQrCodeContext = createContext( undefined ); const TestQrCodeProvider: React.FC = ({ children, lotData, onScanLot, filterActive, onBatchScan, }) => { const [enableTestMode, setEnableTestMode] = useState(true); const { values: qrValues, resetScan } = useQrCodeScannerContext(); // 默认的活跃批次过滤器 const defaultFilterActive = useCallback((lot: any) => { return ( lot.lotAvailability !== 'rejected' && lot.stockOutLineStatus !== 'rejected' && lot.stockOutLineStatus !== 'completed' && lot.processingStatus !== 'completed' && lot.matchStatus !== 'completed' && lot.noLot !== true ); }, []); // 获取活跃批次 const getActiveLots = useCallback(() => { const filter = filterActive || defaultFilterActive; return lotData.filter(filter); }, [lotData, filterActive, defaultFilterActive]); // 测试扫描单个批次 const testScanLotByIndex = useCallback(async (index: number) => { const activeLots = getActiveLots(); if (index < 1 || index > activeLots.length) { console.error( `❌ TEST: Invalid lot index ${index}. Valid range: 1-${activeLots.length}` ); return; } const targetLot = activeLots[index - 1]; // 转换为0-based索引 console.log( `%c TEST: Scanning lot #${index}/${activeLots.length}: ${targetLot.lotNo}`, "color: blue; font-weight: bold" ); if (onScanLot) { await onScanLot(targetLot.lotNo); } }, [getActiveLots, onScanLot]); const testScanAllLots = useCallback(async () => { const activeLots = getActiveLots(); if (activeLots.length === 0) { console.error("❌ TEST: No active lots to scan"); return; } // ✅ 优化:如果有批量扫描回调,使用它(高效批量处理) if (onBatchScan) { console.log( `%c TEST: Batch scanning ALL ${activeLots.length} lots...`, "color: orange; font-weight: bold" ); try { await onBatchScan(); console.log( `%c TEST: Completed batch scan for all ${activeLots.length} lots`, "color: green; font-weight: bold" ); } catch (error) { console.error("❌ TEST: Error in batch scan:", error); } return; } // 回退到原来的逐个扫描方式(如果没有提供批量回调) console.log( `%c TEST: Scanning ALL ${activeLots.length} lots (one by one)...`, "color: orange; font-weight: bold" ); for (let i = 0; i < activeLots.length; i++) { const lot = activeLots[i]; console.log( `%c TEST: Scanning lot ${i + 1}/${activeLots.length}: ${lot.lotNo}`, "color: blue" ); if (onScanLot) { await onScanLot(lot.lotNo); // 添加延迟避免并发冲突 await new Promise(resolve => setTimeout(resolve, 300)); } } console.log( `%c TEST: Completed scanning all ${activeLots.length} lots`, "color: green; font-weight: bold" ); }, [getActiveLots, onScanLot, onBatchScan]); // 监听 QR 扫描值,处理测试格式 useEffect(() => { if (!enableTestMode || qrValues.length === 0) { return; } const latestQr = qrValues[qrValues.length - 1]; let processed = false; // 处理 {2fitestall} if (latestQr === "{2fitestall}") { console.log( "%c TEST QR: Detected {2fitestall}", "color: purple; font-weight: bold" ); testScanAllLots(); processed = true; } // 处理 {2fitest[number]} else if (latestQr.startsWith("{2fitest") && latestQr.endsWith("}")) { const content = latestQr.substring(8, latestQr.length - 1); if (/^\d+$/.test(content)) { const lotIndex = parseInt(content, 10); console.log( `%c TEST QR: Detected {2fitest${lotIndex}}`, "color: purple; font-weight: bold" ); testScanLotByIndex(lotIndex); processed = true; } } // 如果处理了测试格式,重置扫描器 if (processed) { setTimeout(() => { resetScan(); }, 100); } }, [qrValues, enableTestMode, testScanAllLots, testScanLotByIndex, resetScan]); return ( {children} ); }; export const useTestQrCode = (): TestQrCodeContext => { const context = useContext(TestQrCodeContext); if (!context) { throw new Error( "useTestQrCode must be used within a TestQrCodeProvider" ); } return context; }; export default TestQrCodeProvider;