Browse Source

update

master
CANCERYS\kw093 1 week ago
parent
commit
02e2cb03f3
5 changed files with 421 additions and 46 deletions
  1. +42
    -1
      src/app/api/do/actions.tsx
  2. +15
    -0
      src/app/api/do/index.tsx
  3. +53
    -2
      src/app/api/pickOrder/actions.ts
  4. +97
    -0
      src/components/FinishedGoodSearch/GoodPickExecution.tsx
  5. +214
    -43
      src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx

+ 42
- 1
src/app/api/do/actions.tsx View File

@@ -10,7 +10,7 @@ import { DoResult } from ".";
import { GridRowId, GridRowSelectionModel } from "@mui/x-data-grid";
import { GET } from "../auth/[...nextauth]/route";
import { stringify } from "querystring";
import { convertObjToURLSearchParams } from "@/app/utils/commonUtil";
export interface CreateConsoDoInput {
ids: GridRowSelectionModel;
}
@@ -131,7 +131,48 @@ export interface getTicketReleaseTable {
handlerName: string | null;
numberOfFGItems: number;
}
export interface SearchDeliveryOrderInfoRequest {
code: string;
shopName: string;
status: string;
orderStartDate: string;
orderEndDate: string;
estArrStartDate: string;
estArrEndDate: string;
pageSize: number;
pageNum: number;
}
export interface SearchDeliveryOrderInfoResponse {
records: DeliveryOrderInfo[];
total: number;
}
export interface DeliveryOrderInfo {
id: number;
code: string;
shopName: string;
supplierName: string; // 改为必需字段
status: string;
orderDate: string;
estimatedArrivalDate: string;
deliveryOrderLines: DoDetailLine[];
}
export const fetchDoRecordByPage = cache(async (data?: SearchDeliveryOrderInfoRequest) => {
const queryStr = convertObjToURLSearchParams(data)
console.log("queryStr", queryStr)
const response = serverFetchJson<SearchDeliveryOrderInfoResponse>(
`${BASE_API_URL}/jo/getRecordByPage?${queryStr}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
next: {
tags: ["jos"]
}
}
)

return response
})
export const fetchTicketReleaseTable = cache(async ()=> {
return await serverFetchJson<getTicketReleaseTable[]>(
`${BASE_API_URL}/doPickOrder/ticket-release-table`,


+ 15
- 0
src/app/api/do/index.tsx View File

@@ -13,6 +13,21 @@ export interface DoResult {
shopName: string;
}

export interface DoOrder {
id: number;
code: string;
supplierName: string;
shopName: string;
currencyCode: string;
orderDate: string;
estimatedArrivalDate: string;
estArrStartDate: string;
estArrEndDate: string;
completeDate: string;
status: string;
// deliveryOrderLines: DoDetailLine[];

}
export interface DoDetailLine {
id: number;
itemNo: string;


+ 53
- 2
src/app/api/pickOrder/actions.ts View File

@@ -453,8 +453,59 @@ export interface LaneBtn {
total: number;
}



export interface QrPickBatchSubmitRequest {
userId: number;
lines: QrPickSubmitLineRequest[];
}
export interface QrPickSubmitLineRequest {
stockOutLineId: number;
pickOrderLineId: number;
inventoryLotLineId: number | null; // ✅ 修复:应该是 nullable
requiredQty: number | null; // ✅ 修复:添加 requiredQty
actualPickQty: number | null; // ✅ 修复:添加 actualPickQty
stockOutLineStatus: string | null; // ✅ 修复:添加 stockOutLineStatus
pickOrderConsoCode: string | null; // ✅ 修复:添加 pickOrderConsoCode
noLot: boolean; // ✅ 修复:添加 noLot
}
export interface UpdateStockOutLineStatusByQRCodeAndLotNoRequest {
pickOrderLineId: number,
inventoryLotNo: string,
stockOutLineId: number,
itemId: number,
status: string
}
export const updateStockOutLineStatusByQRCodeAndLotNo = async (data: UpdateStockOutLineStatusByQRCodeAndLotNoRequest) => {
console.log("🚀 Frontend: Calling updateStockOutLineStatusByQRCodeAndLotNo with data:", data);
try {
const response = await serverFetchJson<PostPickOrderResponse<UpdateStockOutLineStatusByQRCodeAndLotNoRequest>>(
`${BASE_API_URL}/stockOutLine/updateStatusByQRCodeAndLotNo`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
},
);
console.log("✅ Frontend: API call successful, response:", response);
return response;
} catch (error) {
console.error("❌ Frontend: API call failed:", error);
throw error;
}
};
export const batchQrSubmit = async (data: QrPickBatchSubmitRequest) => {
const response = await serverFetchJson<PostPickOrderResponse<QrPickBatchSubmitRequest>>(
`${BASE_API_URL}/stockOutLine/batchQrSubmit`,
{
method: "POST",
body: JSON.stringify(data),
},
);
return response;
};
export const fetchDoPickOrderDetail = async (
doPickOrderId: number,


+ 97
- 0
src/components/FinishedGoodSearch/GoodPickExecution.tsx View File

@@ -35,6 +35,7 @@ import {
checkAndCompletePickOrderByConsoCode,
fetchDoPickOrderDetail,
DoPickOrderDetail,
batchQrSubmit,
} from "@/app/api/pickOrder/actions";
import { fetchNameList, NameList } from "@/app/api/user/actions";
import {
@@ -488,6 +489,7 @@ const fetchFgPickOrdersData = useCallback(async () => {

// Handle QR code submission for matched lot (external scanning)
// Handle QR code submission for matched lot (external scanning)
/*
const handleQrCodeSubmit = useCallback(async (lotNo: string) => {
console.log(` Processing QR Code for lot: ${lotNo}`);
@@ -583,6 +585,101 @@ const fetchFgPickOrdersData = useCallback(async () => {
}, 3000);
}
}, [combinedLotData, fetchAllCombinedLotData]);
*/ const handleQrCodeSubmit = useCallback(async (lotNo: string) => {
console.log(` Processing QR Code for lot: ${lotNo}`);
// Use current data without refreshing to avoid infinite loop
const currentLotData = combinedLotData;
console.log(`🔍 Available lots:`, currentLotData.map(lot => lot.lotNo));
const matchingLots = currentLotData.filter(lot =>
lot.lotNo === lotNo ||
lot.lotNo?.toLowerCase() === lotNo.toLowerCase()
);
if (matchingLots.length === 0) {
console.error(`❌ Lot not found: ${lotNo}`);
setQrScanError(true);
setQrScanSuccess(false);
return;
}
console.log(` Found ${matchingLots.length} matching lots:`, matchingLots);
setQrScanError(false);
try {
let successCount = 0;
let existsCount = 0;
let errorCount = 0;
for (const matchingLot of matchingLots) {
console.log(`🔄 Processing pick order line ${matchingLot.pickOrderLineId} for lot ${lotNo}`);
if (matchingLot.stockOutLineId) {
console.log(` Stock out line already exists for line ${matchingLot.pickOrderLineId}`);
existsCount++;
} else {
const stockOutLineData: CreateStockOutLine = {
consoCode: matchingLot.pickOrderConsoCode,
pickOrderLineId: matchingLot.pickOrderLineId,
inventoryLotLineId: matchingLot.lotId,
qty: 0.0
};
console.log(`Creating stock out line for pick order line ${matchingLot.pickOrderLineId}:`, stockOutLineData);
const result = await createStockOutLine(stockOutLineData);
console.log(`Create stock out line result for line ${matchingLot.pickOrderLineId}:`, result);
if (result && result.code === "EXISTS") {
console.log(` Stock out line already exists for line ${matchingLot.pickOrderLineId}`);
existsCount++;
} else if (result && result.code === "SUCCESS") {
console.log(` Stock out line created successfully for line ${matchingLot.pickOrderLineId}`);
successCount++;
} else {
console.error(`❌ Failed to create stock out line for line ${matchingLot.pickOrderLineId}:`, result);
errorCount++;
}
}
}
// Always refresh data after processing (success or failure)
console.log("🔄 Refreshing data after QR code processing...");
await fetchAllCombinedLotData();
if (successCount > 0 || existsCount > 0) {
console.log(` QR Code processing completed: ${successCount} created, ${existsCount} already existed`);
setQrScanSuccess(true);
setQrScanInput(''); // Clear input after successful processing
// Clear success state after a delay
setTimeout(() => {
setQrScanSuccess(false);
}, 2000);
} else {
console.error(`❌ QR Code processing failed: ${errorCount} errors`);
setQrScanError(true);
setQrScanSuccess(false);
// Clear error state after a delay
setTimeout(() => {
setQrScanError(false);
}, 3000);
}
} catch (error) {
console.error("❌ Error processing QR code:", error);
setQrScanError(true);
setQrScanSuccess(false);
// Still refresh data even on error
await fetchAllCombinedLotData();
// Clear error state after a delay
setTimeout(() => {
setQrScanError(false);
}, 3000);
}
}, [combinedLotData, fetchAllCombinedLotData]);

const handleManualInputSubmit = useCallback(() => {
if (qrScanInput.trim() !== '') {


+ 214
- 43
src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx View File

@@ -41,10 +41,12 @@ import {
PickOrderCompletionResponse,
checkAndCompletePickOrderByConsoCode,
updateSuggestedLotLineId,
updateStockOutLineStatusByQRCodeAndLotNo,
confirmLotSubstitution,
fetchDoPickOrderDetail, // 必须添加
DoPickOrderDetail, // 必须添加
fetchFGPickOrdersByUserId
fetchFGPickOrdersByUserId ,
batchQrSubmit
} from "@/app/api/pickOrder/actions";

import FGPickOrderInfoCard from "./FGPickOrderInfoCard";
@@ -124,7 +126,7 @@ const QrCodeModal: React.FC<{
onClose();
resetScan();
} else {
console.log(` QR Code mismatch. Expected: ${lot.lotNo}, Got: ${stockInLineInfo.lotNo}`);
console.log(` QR Code mismatch. Expected: ${lot.lotNo}, Got: ${stockInLineInfo.lotNo}`);
setQrScanFailed(true);
setManualInputError(true);
setManualInputSubmitted(true);
@@ -498,7 +500,7 @@ const fgOrder: FGPickOrderResponse = {
console.log("🔍 DEBUG fgOrder.lineCountsPerPickOrder:", fgOrder.lineCountsPerPickOrder);
console.log("🔍 DEBUG fgOrder.pickOrderCodes:", fgOrder.pickOrderCodes);
console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
// 移除:不需要 doPickOrderDetail 和 switcher 逻辑
// 移除:不需要 doPickOrderDetail 和 switcher 逻辑
// if (hierarchicalData.pickOrders.length > 1) { ... }
// 直接使用合并后的 pickOrderLines
@@ -629,14 +631,14 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
checkAllLotsCompleted(flatLotData);
} catch (error) {
console.error(" Error fetching combined lot data:", error);
console.error(" Error fetching combined lot data:", error);
setCombinedLotData([]);
setOriginalCombinedData([]);
setAllLotsCompleted(false);
} finally {
setCombinedDataLoading(false);
}
}, [currentUserId, checkAllLotsCompleted]); // 移除 selectedPickOrderId 依赖
}, [currentUserId, checkAllLotsCompleted]); // 移除 selectedPickOrderId 依赖
// Add effect to check completion when lot data changes
useEffect(() => {
if (combinedLotData.length > 0) {
@@ -714,7 +716,7 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
// 检查 lotNo 是否为 null 或 undefined(包括字符串 "null")
if (!lotNo || lotNo === 'null' || lotNo.trim() === '') {
console.error(" Invalid lotNo: null, undefined, or empty");
console.error(" Invalid lotNo: null, undefined, or empty");
return;
}
@@ -730,11 +732,11 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
});
if (matchingLots.length === 0) {
console.error(` Lot not found: ${lotNo}`);
console.error(` Lot not found: ${lotNo}`);
setQrScanError(true);
setQrScanSuccess(false);
const availableLotNos = currentLotData.map(lot => lot.lotNo).join(', ');
console.log(` QR Code "${lotNo}" does not match any expected lots. Available lots: ${availableLotNos}`);
console.log(` QR Code "${lotNo}" does not match any expected lots. Available lots: ${availableLotNos}`);
return;
}
@@ -832,7 +834,7 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
//setQrScanSuccess(false);
//}, 2000);
} else {
console.error(` QR Code processing failed: ${errorCount} errors`);
console.error(` QR Code processing failed: ${errorCount} errors`);
setQrScanError(true);
setQrScanSuccess(false);
@@ -842,14 +844,11 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
//}, 3000);
}
} catch (error) {
console.error(" Error processing QR code:", error);
console.error(" Error processing QR code:", error);
setQrScanError(true);
setQrScanSuccess(false);
// Still refresh data even on error
setIsRefreshingData(true);
await fetchAllCombinedLotData();
// Clear error state after a delay
setTimeout(() => {
setQrScanError(false);
@@ -860,7 +859,88 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
setIsRefreshingData(false);
}, 1000);
}
}, [combinedLotData, fetchAllCombinedLotData]);
}, [combinedLotData]);
const handleFastQrScan = useCallback(async (lotNo: string) => {
const startTime = performance.now();
console.log(`⏱️ [FAST SCAN START] Lot: ${lotNo}`);
console.log(`⏰ Start time: ${new Date().toISOString()}`);
// 从 combinedLotData 中找到对应的 lot
const findStartTime = performance.now();
const matchingLot = combinedLotData.find(lot =>
lot.lotNo && lot.lotNo === lotNo
);
const findTime = performance.now() - findStartTime;
console.log(`⏱️ Find lot time: ${findTime.toFixed(2)}ms`);
if (!matchingLot || !matchingLot.stockOutLineId) {
const totalTime = performance.now() - startTime;
console.warn(`⚠️ Fast scan: Lot ${lotNo} not found or no stockOutLineId`);
console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms`);
return;
}
try {
// ✅ 使用快速 API
const apiStartTime = performance.now();
const res = await updateStockOutLineStatusByQRCodeAndLotNo({
pickOrderLineId: matchingLot.pickOrderLineId,
inventoryLotNo: lotNo,
stockOutLineId: matchingLot.stockOutLineId,
itemId: matchingLot.itemId,
status: "checked",
});
const apiTime = performance.now() - apiStartTime;
console.log(`⏱️ API call time: ${apiTime.toFixed(2)}ms`);
if (res.code === "checked" || res.code === "SUCCESS") {
// ✅ 只更新本地状态,不调用 fetchAllCombinedLotData
const updateStartTime = performance.now();
const entity = res.entity as any;
setCombinedLotData(prev => prev.map(lot => {
if (lot.stockOutLineId === matchingLot.stockOutLineId &&
lot.pickOrderLineId === matchingLot.pickOrderLineId) {
return {
...lot,
stockOutLineStatus: 'checked',
stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
};
}
return lot;
}));
setOriginalCombinedData(prev => prev.map(lot => {
if (lot.stockOutLineId === matchingLot.stockOutLineId &&
lot.pickOrderLineId === matchingLot.pickOrderLineId) {
return {
...lot,
stockOutLineStatus: 'checked',
stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
};
}
return lot;
}));
const updateTime = performance.now() - updateStartTime;
console.log(`⏱️ State update time: ${updateTime.toFixed(2)}ms`);
const totalTime = performance.now() - startTime;
console.log(`✅ [FAST SCAN END] Lot: ${lotNo}`);
console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
console.log(`⏰ End time: ${new Date().toISOString()}`);
} else {
const totalTime = performance.now() - startTime;
console.warn(`⚠️ Fast scan failed for ${lotNo}:`, res.code);
console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms`);
}
} catch (error) {
const totalTime = performance.now() - startTime;
console.error(` Fast scan error for ${lotNo}:`, error);
console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms`);
}
}, [combinedLotData, updateStockOutLineStatusByQRCodeAndLotNo]);


const processOutsideQrCode = useCallback(async (latestQr: string) => {
// 1) Parse JSON safely
let qrData: any = null;
@@ -916,7 +996,7 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
return;
}
// FIXED: Find the ACTIVE suggested lot (not rejected lots)
// FIXED: Find the ACTIVE suggested lot (not rejected lots)
const activeSuggestedLots = sameItemLotsInExpected.filter(lot =>
lot.lotAvailability !== 'rejected' &&
lot.stockOutLineStatus !== 'rejected' &&
@@ -937,14 +1017,85 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
);
if (exactLotMatch && scanned?.lotNo) {
// Case 1: Normal case - item matches AND lot matches -> proceed
console.log(`Exact lot match found for ${scanned.lotNo}, submitting QR`);
handleQrCodeSubmit(scanned.lotNo);
return;
// ✅ Case 1: 使用 updateStockOutLineStatusByQRCodeAndLotNo API(更快)
console.log(`✅ Exact lot match found for ${scanned.lotNo}, using fast API`);
if (!exactLotMatch.stockOutLineId) {
console.warn("No stockOutLineId on exactLotMatch, cannot update status by QR.");
setQrScanError(true);
setQrScanSuccess(false);
return;
}
try {
// ✅ 直接调用后端 API,后端会处理所有匹配逻辑
const res = await updateStockOutLineStatusByQRCodeAndLotNo({
pickOrderLineId: exactLotMatch.pickOrderLineId,
inventoryLotNo: scanned.lotNo,
stockOutLineId: exactLotMatch.stockOutLineId,
itemId: exactLotMatch.itemId,
status: "checked",
});
console.log("updateStockOutLineStatusByQRCodeAndLotNo result:", res);
// 后端返回三种 code:checked / LOT_NUMBER_MISMATCH / ITEM_MISMATCH
if (res.code === "checked" || res.code === "SUCCESS") {
// ✅ 完全匹配 - 只更新本地状态,不调用 fetchAllCombinedLotData
setQrScanError(false);
setQrScanSuccess(true);
// ✅ 更新本地状态
const entity = res.entity as any;
setCombinedLotData(prev => prev.map(lot => {
if (lot.stockOutLineId === exactLotMatch.stockOutLineId &&
lot.pickOrderLineId === exactLotMatch.pickOrderLineId) {
return {
...lot,
stockOutLineStatus: 'checked',
stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
};
}
return lot;
}));
setOriginalCombinedData(prev => prev.map(lot => {
if (lot.stockOutLineId === exactLotMatch.stockOutLineId &&
lot.pickOrderLineId === exactLotMatch.pickOrderLineId) {
return {
...lot,
stockOutLineStatus: 'checked',
stockOutLineQty: entity?.qty ? Number(entity.qty) : lot.stockOutLineQty,
};
}
return lot;
}));
console.log("✅ Status updated locally, no full data refresh needed");
} else if (res.code === "LOT_NUMBER_MISMATCH") {
console.warn("Backend reported LOT_NUMBER_MISMATCH:", res.message);
setQrScanError(true);
setQrScanSuccess(false);
} else if (res.code === "ITEM_MISMATCH") {
console.warn("Backend reported ITEM_MISMATCH:", res.message);
setQrScanError(true);
setQrScanSuccess(false);
} else {
console.warn("Unexpected response code from backend:", res.code);
setQrScanError(true);
setQrScanSuccess(false);
}
} catch (e) {
console.error("Error calling updateStockOutLineStatusByQRCodeAndLotNo:", e);
setQrScanError(true);
setQrScanSuccess(false);
}
return; // ✅ 直接返回,不再调用 handleQrCodeSubmit
}
// Case 2: Item matches but lot number differs -> open confirmation modal
// FIXED: Use the first ACTIVE suggested lot, not just any lot
const expectedLot = activeSuggestedLots[0];
if (!expectedLot) {
console.error("Could not determine expected lot for confirmation");
@@ -953,7 +1104,7 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
return;
}
// Check if the expected lot is already the scanned lot (after substitution)
// Check if the expected lot is already the scanned lot (after substitution)
if (expectedLot.lotNo === scanned?.lotNo) {
console.log(`Lot already substituted, proceeding with ${scanned.lotNo}`);
handleQrCodeSubmit(scanned.lotNo);
@@ -982,7 +1133,7 @@ console.log("🔍 DEBUG fgOrder.deliveryNos:", fgOrder.deliveryNos);
setQrScanSuccess(false);
return;
}
}, [combinedLotData, handleQrCodeSubmit, handleLotMismatch]);
}, [combinedLotData, handleQrCodeSubmit, handleLotMismatch]);
// Update the outside QR scanning effect to use enhanced processing
// Update the outside QR scanning effect to use enhanced processing
useEffect(() => {
@@ -1073,13 +1224,12 @@ useEffect(() => {
console.log(` Auto-set pick quantity to ${requiredQty} for lot ${lotNo}`);
}, 500);
// Refresh data
await fetchAllCombinedLotData();
} catch (error) {
console.error("Error creating stock out line:", error);
}
}
}, [selectedLotForQr, fetchAllCombinedLotData]);
}, [selectedLotForQr]);


const handlePickQtyChange = useCallback((lotKey: string, value: number | string) => {
@@ -1190,7 +1340,7 @@ useEffect(() => {
} else if (completionResponse.message === "not completed") {
console.log(`⏳ Pick order not completed yet, more lines remaining`);
} else {
console.error(` Error checking completion: ${completionResponse.message}`);
console.error(` Error checking completion: ${completionResponse.message}`);
}
} catch (error) {
console.error("Error checking pick order completion:", error);
@@ -1268,7 +1418,7 @@ useEffect(() => {
if (result && result.code === "SUCCESS") {
console.log(" Pick execution issue recorded successfully");
} else {
console.error(" Failed to record pick execution issue:", result);
console.error(" Failed to record pick execution issue:", result);
}
setPickExecutionFormOpen(false);
@@ -1452,7 +1602,7 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
} else if (completionResponse.message === "not completed") {
console.log(`⏳ Pick order not completed yet, more lines remaining`);
} else {
console.error(` Error checking completion: ${completionResponse.message}`);
console.error(` Error checking completion: ${completionResponse.message}`);
}
} catch (error) {
console.error("Error checking pick order completion:", error);
@@ -1513,7 +1663,7 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
const stockOutLineId = lot.stockOutLineId;
if (!stockOutLineId) {
console.error(" No stockOutLineId found for lot:", lot);
console.error(" No stockOutLineId found for lot:", lot);
return;
}
@@ -1558,17 +1708,20 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
if (result && result.code === "SUCCESS") {
console.log(" No-lot item handled and issue recorded successfully");
} else {
console.error(" Failed to record pick execution issue:", result);
console.error(" Failed to record pick execution issue:", result);
}
// Step 3: Refresh data
await fetchAllCombinedLotData();
} catch (error) {
console.error(" Error in handlelotnull:", error);
console.error(" Error in handlelotnull:", error);
}
}, [fetchAllCombinedLotData, session, currentUserId, fgPickOrders]);
// ... existing code ...
const handleSubmitAllScanned = useCallback(async () => {
const startTime = performance.now();
console.log(`⏱️ [BATCH SUBMIT START]`);
console.log(`⏰ Start time: ${new Date().toISOString()}`);
const scannedLots = combinedLotData.filter(lot => {
// 如果是 noLot 情况,检查状态是否为 pending 或 partially_complete
if (lot.noLot === true) {
@@ -1667,14 +1820,31 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
});
// Wait for all submissions to complete
const results = await Promise.all(submitPromises);
const successCount = results.filter(r => r.success).length;
const submitStartTime = performance.now();
const submitResults = await Promise.all(submitPromises);
const submitSuccessCount = submitResults.filter(r => r.success).length;
console.log(` Batch submit completed: ${successCount}/${scannedLots.length} items submitted`);
// Refresh data once after all submissions
await fetchAllCombinedLotData();
console.log(` Batch submit completed: ${submitSuccessCount}/${scannedLots.length} items submitted`);
// Wait for all submissions to complete
const results = await Promise.all(submitPromises);
const submitTime = performance.now() - submitStartTime;
const successCount = results.filter(r => r.success).length;
console.log(`⏱️ All submissions completed in ${submitTime.toFixed(2)}ms (${(submitTime / 1000).toFixed(3)}s)`);
console.log(`⏱️ Average time per item: ${(submitTime / scannedLots.length).toFixed(2)}ms`);
console.log(` Batch submit completed: ${successCount}/${scannedLots.length} items submitted`);
// Refresh data once after all submissions
const refreshStartTime = performance.now();
await fetchAllCombinedLotData();
const refreshTime = performance.now() - refreshStartTime;
console.log(`⏱️ Data refresh time: ${refreshTime.toFixed(2)}ms (${(refreshTime / 1000).toFixed(3)}s)`);
const totalTime = performance.now() - startTime;
console.log(`⏱️ [BATCH SUBMIT END]`);
console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
console.log(`⏰ End time: ${new Date().toISOString()}`);
if (successCount > 0) {
setQrScanSuccess(true);
setTimeout(() => {
@@ -1961,10 +2131,10 @@ paginatedData.map((lot, index) => {
}}
>
<TableCell>
<Typography variant="body2" fontWeight="bold">
{index + 1}
</Typography>
</TableCell>
<Typography variant="body2" fontWeight="bold">
{paginationController.pageNum * paginationController.pageSize + index + 1}
</Typography>
</TableCell>
<TableCell>
<Typography variant="body2">
{lot.routerRoute || '-'}
@@ -2218,7 +2388,8 @@ paginatedData.map((lot, index) => {
uomDesc: selectedLotForExecutionForm.uomDesc || '',
pickedQty: selectedLotForExecutionForm.actualPickQty || 0,
uomShortDesc: selectedLotForExecutionForm.uomShortDesc || '',
suggestedList: []
suggestedList: [],
noLotLines: [],
}}
pickOrderId={selectedLotForExecutionForm.pickOrderId}
pickOrderCreateDate={new Date()}


Loading…
Cancel
Save