Переглянути джерело

update skip button

MergeProblem1
CANCERYS\kw093 2 тижднів тому
джерело
коміт
f903dae3c1
5 змінених файлів з 214 додано та 9 видалено
  1. +30
    -0
      src/app/api/pickOrder/actions.ts
  2. +159
    -6
      src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx
  3. +23
    -3
      src/components/QrCodeScannerProvider/TestQrCodeProvider.tsx
  4. +1
    -0
      src/i18n/zh/inventory.json
  5. +1
    -0
      src/i18n/zh/pickOrder.json

+ 30
- 0
src/app/api/pickOrder/actions.ts Переглянути файл

@@ -542,7 +542,37 @@ export const batchQrSubmit = async (data: QrPickBatchSubmitRequest) => {
);
return response;
};
export interface BatchScanRequest {
userId: number;
lines: BatchScanLineRequest[];
}
export interface BatchScanLineRequest {
pickOrderLineId: number;
inventoryLotLineId: number | null; // 如果有 lot,提供 lotId;如果没有则为 null
pickOrderConsoCode: string;
lotNo: string | null; // 用于日志和验证
itemId: number;
itemCode: string;
stockOutLineId: number | null; // ✅ 新增:如果已有 stockOutLineId,直接使用
}

export const batchScan = async (data: BatchScanRequest) => {
console.log("📤 batchScan - Request body:", JSON.stringify(data, null, 2));
const response = await serverFetchJson<PostPickOrderResponse<BatchScanRequest>>(
`${BASE_API_URL}/stockOutLine/batchScan`,
{
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
},
},
);
console.log("📥 batchScan - Response:", response);
return response;
};
export const fetchDoPickOrderDetail = async (
doPickOrderId: number,
selectedPickOrderId?: number


+ 159
- 6
src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx Переглянути файл

@@ -48,8 +48,10 @@ import {
batchQrSubmit,
batchSubmitList, // 添加:导入 batchSubmitList
batchSubmitListRequest, // 添加:导入类型
batchSubmitListLineRequest

batchSubmitListLineRequest,
batchScan,
BatchScanRequest,
BatchScanLineRequest,
} from "@/app/api/pickOrder/actions";

import FGPickOrderInfoCard from "./FGPickOrderInfoCard";
@@ -1834,6 +1836,62 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
}
try {
// Special case: If submitQty is 0 and all values are 0, mark as completed with qty: 0
if (submitQty === 0) {
console.log(`=== SUBMITTING ALL ZEROS CASE ===`);
console.log(`Lot: ${lot.lotNo}`);
console.log(`Stock Out Line ID: ${lot.stockOutLineId}`);
console.log(`Setting status to 'completed' with qty: 0`);
const updateResult = await updateStockOutLineStatus({
id: lot.stockOutLineId,
status: 'completed',
qty: 0
});
console.log('Update result:', updateResult);
const r: any = updateResult as any;
const updateOk =
r?.code === 'SUCCESS' ||
r?.type === 'completed' ||
typeof r?.id === 'number' ||
typeof r?.entity?.id === 'number' ||
(r?.message && r.message.includes('successfully'));
if (!updateResult || !updateOk) {
console.error('Failed to update stock out line status:', updateResult);
throw new Error('Failed to update stock out line status');
}
// Check if pick order is completed
if (lot.pickOrderConsoCode) {
console.log(` Lot ${lot.lotNo} completed (all zeros), checking if pick order ${lot.pickOrderConsoCode} is complete...`);
try {
const completionResponse = await checkAndCompletePickOrderByConsoCode(lot.pickOrderConsoCode);
console.log(` Pick order completion check result:`, completionResponse);
if (completionResponse.code === "SUCCESS") {
console.log(` Pick order ${lot.pickOrderConsoCode} completed successfully!`);
} else if (completionResponse.message === "not completed") {
console.log(`⏳ Pick order not completed yet, more lines remaining`);
} else {
console.error(` Error checking completion: ${completionResponse.message}`);
}
} catch (error) {
console.error("Error checking pick order completion:", error);
}
}
await fetchAllCombinedLotData();
console.log("All zeros submission completed successfully!");
setTimeout(() => {
checkAndAutoAssignNext();
}, 1000);
return;
}
// FIXED: Calculate cumulative quantity correctly
const currentActualPickQty = lot.actualPickQty || 0;
const cumulativeQty = currentActualPickQty + submitQty;
@@ -1882,7 +1940,7 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
console.log(` Pick order completion check result:`, completionResponse);
if (completionResponse.code === "SUCCESS") {
console.log(`�� Pick order ${lot.pickOrderConsoCode} completed successfully!`);
console.log(` Pick order ${lot.pickOrderConsoCode} completed successfully!`);
} else if (completionResponse.message === "not completed") {
console.log(`⏳ Pick order not completed yet, more lines remaining`);
} else {
@@ -1905,8 +1963,14 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
}
}, [fetchAllCombinedLotData, checkAndAutoAssignNext]);


// Add these functions after line 395
const handleSkip = useCallback(async (lot: any) => {
try {
console.log("Skip clicked, submit 0 qty for lot:", lot.lotNo);
await handleSubmitPickQtyWithQty(lot, 0);
} catch (err) {
console.error("Error in Skip:", err);
}
}, [handleSubmitPickQtyWithQty]);
const handleStartScan = useCallback(() => {
console.log(" Starting manual QR scan...");
setIsManualScanning(true);
@@ -2001,7 +2065,86 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe
console.error(" Error in handlelotnull:", error);
}
}, [fetchAllCombinedLotData, session, currentUserId, fgPickOrders]);
// ... existing code ...
const handleBatchScan = useCallback(async () => {
const startTime = performance.now();
console.log(`⏱️ [BATCH SCAN START]`);
console.log(`⏰ Start time: ${new Date().toISOString()}`);
// 获取所有活跃批次(未扫描的)
const activeLots = combinedLotData.filter(lot => {
return (
lot.lotAvailability !== 'rejected' &&
lot.stockOutLineStatus !== 'rejected' &&
lot.stockOutLineStatus !== 'completed' &&
lot.stockOutLineStatus !== 'checked' && // ✅ 只处理未扫描的
lot.processingStatus !== 'completed' &&
lot.noLot !== true &&
lot.lotNo // ✅ 必须有 lotNo
);
});
if (activeLots.length === 0) {
console.log("No active lots to scan");
return;
}
console.log(`📦 Batch scanning ${activeLots.length} active lots using batch API...`);
try {
// ✅ 转换为批量扫描 API 所需的格式
const lines: BatchScanLineRequest[] = activeLots.map((lot) => ({
pickOrderLineId: Number(lot.pickOrderLineId),
inventoryLotLineId: lot.lotId ? Number(lot.lotId) : null,
pickOrderConsoCode: String(lot.pickOrderConsoCode || ''),
lotNo: lot.lotNo || null,
itemId: Number(lot.itemId),
itemCode: String(lot.itemCode || ''),
stockOutLineId: lot.stockOutLineId ? Number(lot.stockOutLineId) : null, // ✅ 新增
}));
const request: BatchScanRequest = {
userId: currentUserId || 0,
lines: lines
};
console.log(`📤 Sending batch scan request with ${lines.length} lines`);
console.log(`📋 Request data:`, JSON.stringify(request, null, 2));
const scanStartTime = performance.now();
// ✅ 使用新的批量扫描 API(一次性处理所有请求)
const result = await batchScan(request);
const scanTime = performance.now() - scanStartTime;
console.log(`⏱️ Batch scan API call completed in ${scanTime.toFixed(2)}ms (${(scanTime / 1000).toFixed(3)}s)`);
console.log(`📥 Batch scan result:`, result);
// ✅ 刷新数据以获取最新的状态
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 SCAN END]`);
console.log(`⏱️ Total time: ${totalTime.toFixed(2)}ms (${(totalTime / 1000).toFixed(3)}s)`);
console.log(`⏰ End time: ${new Date().toISOString()}`);
if (result && result.code === "SUCCESS") {
setQrScanSuccess(true);
setQrScanError(false);
} else {
console.error("❌ Batch scan failed:", result);
setQrScanError(true);
setQrScanSuccess(false);
}
} catch (error) {
console.error("❌ Error in batch scan:", error);
setQrScanError(true);
setQrScanSuccess(false);
}
}, [combinedLotData, fetchAllCombinedLotData, currentUserId]);
const handleSubmitAllScanned = useCallback(async () => {
const startTime = performance.now();
console.log(`⏱️ [BATCH SUBMIT START]`);
@@ -2174,6 +2317,7 @@ const handleSubmitAllScanned = useCallback(async () => {
<TestQrCodeProvider
lotData={combinedLotData}
onScanLot={handleQrCodeSubmit}
onBatchScan={handleBatchScan}
filterActive={(lot) => (
lot.lotAvailability !== 'rejected' &&
lot.stockOutLineStatus !== 'rejected' &&
@@ -2542,6 +2686,15 @@ paginatedData.map((lot, index) => {
>
{t("Issue")}
</Button>
<Button
variant="outlined"
size="small"
onClick={() => handleSkip(lot)}
disabled={lot.stockOutLineStatus === 'completed'}
sx={{ fontSize: '0.7rem', py: 0.5, minHeight: '28px', minWidth: '60px' }}
>
{t("Skip")}
</Button>
</Stack>
);
})()}


+ 23
- 3
src/components/QrCodeScannerProvider/TestQrCodeProvider.tsx Переглянути файл

@@ -29,6 +29,7 @@ interface TestQrCodeProviderProps {
lotData: any[]; // 当前页面的批次数据
onScanLot?: (lotNo: string) => Promise<void>; // 扫描单个批次的回调
filterActive?: (lot: any) => boolean; // 过滤活跃批次的函数
onBatchScan?: () => Promise<void>;
}

export const TestQrCodeContext = createContext<TestQrCodeContext | undefined>(
@@ -40,6 +41,7 @@ const TestQrCodeProvider: React.FC<TestQrCodeProviderProps> = ({
lotData,
onScanLot,
filterActive,
onBatchScan,
}) => {
const [enableTestMode, setEnableTestMode] = useState<boolean>(true);
const { values: qrValues, resetScan } = useQrCodeScannerContext();
@@ -84,7 +86,6 @@ const TestQrCodeProvider: React.FC<TestQrCodeProviderProps> = ({
}
}, [getActiveLots, onScanLot]);

// 测试扫描所有批次
const testScanAllLots = useCallback(async () => {
const activeLots = getActiveLots();
@@ -93,8 +94,27 @@ const TestQrCodeProvider: React.FC<TestQrCodeProviderProps> = ({
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...`,
`%c TEST: Scanning ALL ${activeLots.length} lots (one by one)...`,
"color: orange; font-weight: bold"
);

@@ -116,7 +136,7 @@ const TestQrCodeProvider: React.FC<TestQrCodeProviderProps> = ({
`%c TEST: Completed scanning all ${activeLots.length} lots`,
"color: green; font-weight: bold"
);
}, [getActiveLots, onScanLot]);
}, [getActiveLots, onScanLot, onBatchScan]);

// 监听 QR 扫描值,处理测试格式
useEffect(() => {


+ 1
- 0
src/i18n/zh/inventory.json Переглянути файл

@@ -37,6 +37,7 @@
"miss": "缺貨",
"bad": "不良",
"expiry": "過期",
"open":"開倉",
"Bom Req. Qty": "需求數(BOM單位)",
"selected stock take qty": "已選擇盤點數量",
"book qty": "帳面庫存",


+ 1
- 0
src/i18n/zh/pickOrder.json Переглянути файл

@@ -12,6 +12,7 @@
"Escalated": "上報狀態",
"NotEscalated": "無上報",
"Assigned To": "已分配",
"Skip": "跳過",
"Do you want to start?": "確定開始嗎?",
"Start": "開始",
"Pick Order Code(s)": "提料單編號",


Завантаження…
Відмінити
Зберегти