瀏覽代碼

update qr code scan modal

master
kelvinsuen 3 月之前
父節點
當前提交
3b33e17cff
共有 3 個檔案被更改,包括 136 行新增95 行删除
  1. +2
    -1
      src/app/api/qrcode/index.ts
  2. +13
    -75
      src/components/PutAwayScan/PutAwayScan.tsx
  3. +121
    -19
      src/components/QrCodeScannerProvider/QrCodeScannerProvider.tsx

+ 2
- 1
src/app/api/qrcode/index.ts 查看文件

@@ -6,10 +6,11 @@ import { serverFetchJson } from "../../utils/fetchUtil";
import { BASE_API_URL } from "../../../config/api";

export interface QrCodeInfo {
value: string;
// warehouse qrcode
warehouseId?: number;
// item qrcode
stockInLineId?: number;
itemId: number;
itemId?: number;
lotNo?: string;
}

+ 13
- 75
src/components/PutAwayScan/PutAwayScan.tsx 查看文件

@@ -52,10 +52,8 @@ const PutAwayScan: React.FC<Props> = ({ warehouse }) => {
useEffect(() => {
if (!scanner.isScanning) {
scanner.startScan();
console.log("%c Scanning started ", "color:cyan");
} else if (scanner.isScanning) {
scanner.stopScan();
console.log("%c Scanning stopped ", "color:cyan");
}
}, []);

@@ -87,37 +85,6 @@ const PutAwayScan: React.FC<Props> = ({ warehouse }) => {
setOpenPutAwayModal(false);
}


const findIdByRoughMatch = (inputString : string, keyword : string) => {
const keywordIndex = inputString.indexOf(keyword);
if (keywordIndex === -1) {
return {
keywordFound: false,
number: null,
message: `${keyword} not found in the input`,
};
}
const substringAfterKeyword = inputString.slice(keywordIndex + keyword.length);
const numberMatch = substringAfterKeyword.match(/\d+/);
if (!numberMatch) {
return {
keywordFound: true,
number: null,
message: `No valid number found after ${keyword}`,
};
}
return {
keywordFound: true,
number: parseInt(numberMatch[0], 10),
message: `Found ${keyword} at index ${keywordIndex}, first number found after is: ${numberMatch[0]}`,
};
}

const addPutAwayHistory = (putAwayData: PutAwayRecord) => {
console.log("%c Added new data to Putaway history: ", "color:orange", putAwayData);
const newPutaway = { ...putAwayData, id: putAwayHistory.length + 1 };
@@ -133,51 +100,22 @@ const PutAwayScan: React.FC<Props> = ({ warehouse }) => {

// Get Scanned Values
useEffect(() => {
if (scanner.values.length > 0) {//} && !Boolean(itemDetail)) {
const scannedValues = scanner.values[0];
console.log("%c Scanned: ", "color:cyan", scannedValues);

if (scannedValues.substring(0, 8) == "{2fitest") { // DEBUGGING
const number = scannedValues.substring(8, scannedValues.length - 1);
if (/^\d+$/.test(number)) { // Check if number contains only digits
console.log("%c DEBUG: Testing SIL ID: ", "color:cyan", number);
if (scannedSilId === 0) {
setScannedSilId(Number(number));
} else setScannedWareHouseId(Number(number));
} else {
console.error("%c DEBUG: Invalid number format: ", "color:red", number);
resetScan();
}
return;
}
try {
const data: QrCodeInfo = JSON.parse(scannedValues);
console.log("%c Scanned with data", "color:green", data);
if (scannedSilId == 0) { // Initial State
if (data.stockInLineId !== undefined) {
setScannedSilId(Number(data.stockInLineId));
} else resetScan("Cannot read Stock In Line Id");
} else { // Processing
if (data.warehouseId !== undefined) {
setScannedWareHouseId(Number(data.warehouseId));
} else resetScan("Cannot read Warehouse Id");
}
} catch (error) { // Rought match for other scanner -- Pending Review
if (scannedSilId == 0) {
const silId = findIdByRoughMatch(scannedValues, "StockInLine").number ?? 0;
setScannedSilId(silId);

} else {
const whId = findIdByRoughMatch(scannedValues, "warehouseId").number ?? 0;
setScannedWareHouseId(whId);
}

resetScan(String(error));
if (scanner.result) {
const data = scanner.result;
if (scannedSilId == 0) { // Initial State
if (!isNaN(Number(data.value))) { setScannedSilId(Number(data.value)); }
else if (data.stockInLineId) {
setScannedSilId(Number(data.stockInLineId));
} else resetScan("Cannot read Stock In Line Id");
} else { // Processing
if (!isNaN(Number(data.value))) { setScannedWareHouseId(Number(data.value)); }
else if (data.warehouseId) {
setScannedWareHouseId(Number(data.warehouseId));
} else resetScan("Cannot read Warehouse Id");
}
scanner.resetScan();
}
}, [scanner.values]);
}, [scanner.result]);

return (<>
<Paper sx={{


+ 121
- 19
src/components/QrCodeScannerProvider/QrCodeScannerProvider.tsx 查看文件

@@ -1,4 +1,5 @@
"use client";
import { QrCodeInfo } from "@/app/api/qrcode";
import {
ReactNode,
createContext,
@@ -14,6 +15,7 @@ export interface QrCodeScanner {
startScan: () => void;
stopScan: () => void;
resetScan: () => void;
result: QrCodeInfo | undefined;
}

interface QrCodeScannerProviderProps {
@@ -32,19 +34,73 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({
const [keys, setKeys] = useState<string[]>([]);
const [leftCurlyBraceCount, setLeftCurlyBraceCount] = useState<number>(0);
const [rightCurlyBraceCount, setRightCurlyBraceCount] = useState<number>(0);
const resetQrCodeScanner = useCallback(() => {
const [scanResult, setScanResult] = useState<QrCodeInfo | undefined>()

const resetScannerInput = useCallback(() => {
setKeys(() => []);
setLeftCurlyBraceCount(() => 0);
setRightCurlyBraceCount(() => 0);
}, []);

const resetQrCodeScanner = useCallback((error : string = "") => {
setQrCodeScannerValues(() => []);
setScanResult(undefined);
resetScannerInput();

console.log("%c Scanner Reset", "color:cyan");
if (error.length > 0) {
console.log("%c Error:", "color:red", error);
}
}, []);

const startQrCodeScanner = useCallback(() => {
resetQrCodeScanner();
setIsScanning(() => true);
console.log("%c Scanning started ", "color:cyan");
}, []);

const endQrCodeScanner = useCallback(() => {
setIsScanning(() => false);
console.log("%c Scanning stopped ", "color:cyan");
}, []);

// Find by rough match, return 0 if not found
const findIdByRoughMatch = (inputString : string, keyword : string) => {
console.log(`%c Performed rough match for ${keyword} within ${inputString}`, "color:brown");
const keywordIndex = inputString.indexOf(keyword);
let result : {keywordFound: boolean; number: number | null; message: string} = {
keywordFound: false,
number: null,
message: `${keyword} not found in the input`,
};

if (keywordIndex !== -1) {
const substringAfterKeyword = inputString.slice(keywordIndex + keyword.length);
const numberMatch = substringAfterKeyword.match(/\d+/);
if (!numberMatch) {
result = {
keywordFound: true,
number: null,
message: `No valid number found after ${keyword}`,
};
} else {
result = {
keywordFound: true,
number: parseInt(numberMatch[0], 10),
message: `Found ${keyword} at index ${keywordIndex}, first number found after is: ${numberMatch[0]}`,
};
}
}

console.log(`%c ${result.message}`, "color:brown");
return result;
};

// Check the KeyDown
useEffect(() => {
if (isScanning) {
@@ -70,27 +126,72 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({

// Update Qr Code Scanner Values
useEffect(() => {
if (
leftCurlyBraceCount !== 0 &&
rightCurlyBraceCount !== 0 &&
leftCurlyBraceCount === rightCurlyBraceCount
) {
const startBrace = keys.indexOf("{");
const endBrace = keys.lastIndexOf("}");
setQrCodeScannerValues((value) => [
...value,
keys.join("").substring(startBrace, endBrace + 1),
]);
console.log(keys);
console.log("%c QR Scanner Values:", "color:cyan", qrCodeScannerValues);

// reset
setKeys(() => []);
setLeftCurlyBraceCount(() => 0);
setRightCurlyBraceCount(() => 0);
if (rightCurlyBraceCount > leftCurlyBraceCount || leftCurlyBraceCount > 1) { // Prevent multiple scan
resetQrCodeScanner("Too many scans at once");
} else {
if (leftCurlyBraceCount == 1 && keys.length == 1)
{ console.log("%c Scan detected, waiting for inputs...", "color:cyan"); }
if (
leftCurlyBraceCount !== 0 &&
rightCurlyBraceCount !== 0 &&
leftCurlyBraceCount === rightCurlyBraceCount
) {
const startBrace = keys.indexOf("{");
const endBrace = keys.lastIndexOf("}");
setQrCodeScannerValues((value) => [
...value,
keys.join("").substring(startBrace, endBrace + 1),
]);
// console.log(keys);
// console.log("%c QR Scanner Values:", "color:cyan", qrCodeScannerValues);
resetScannerInput();
}
}
}, [keys, leftCurlyBraceCount, rightCurlyBraceCount]);

useEffect(() => {
if (qrCodeScannerValues.length > 0) {
const scannedValues = qrCodeScannerValues[0];
console.log("%c Scanned Result: ", "color:cyan", scannedValues);

if (scannedValues.substring(0, 8) == "{2fitest") { // DEBUGGING
const number = scannedValues.substring(8, scannedValues.length - 1);
if (/^\d+$/.test(number)) { // Check if number contains only digits
console.log("%c DEBUG: detected ID: ", "color:pink", number);
const debugValue = {
value: number
}
setScanResult(debugValue);
} else {
resetQrCodeScanner("DEBUG -- Invalid number format: " + number);
}
return;
}

try {
const data: QrCodeInfo = JSON.parse(scannedValues);
console.log("%c Parsed scan data", "color:green", data);
const content = scannedValues.substring(1, scannedValues.length - 1);
data.value = content;
setScanResult(data);

} catch (error) { // Rought match for other scanner input -- Pending Review
const silId = findIdByRoughMatch(scannedValues, "StockInLine").number ?? 0;
if (silId == 0) {
const whId = findIdByRoughMatch(scannedValues, "warehouseId").number ?? 0;
setScanResult({...scanResult, stockInLineId: whId, value: whId.toString()});
} else { setScanResult({...scanResult, stockInLineId: silId, value: silId.toString()}); }

resetQrCodeScanner(String(error));
}

// resetQrCodeScanner();
}
}, [qrCodeScannerValues]);

return (
<QrCodeScannerContext.Provider
value={{
@@ -99,6 +200,7 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({
startScan: startQrCodeScanner,
stopScan: endQrCodeScanner,
resetScan: resetQrCodeScanner,
result: scanResult,
}}
>
{children}


Loading…
取消
儲存