CANCERYS\kw093 14 часов назад
Родитель
Сommit
b006a1115c
7 измененных файлов: 61 добавлений и 51 удалений
  1. +1
    -1
      src/app/api/jo/actions.ts
  2. +1
    -1
      src/app/api/po/index.ts
  3. +1
    -0
      src/app/api/stockIn/index.ts
  4. +1
    -1
      src/components/ProductionProcess/JobProcessStatus.tsx
  5. +14
    -10
      src/components/ProductionProcess/ProductionProcessList.tsx
  6. +22
    -33
      src/components/PutAwayScan/PutAwayModal.tsx
  7. +21
    -5
      src/components/Qc/QcStockInModal.tsx

+ 1
- 1
src/app/api/jo/actions.ts Просмотреть файл

@@ -1211,7 +1211,7 @@ export const fetchMaterialPickStatus = cache(async (): Promise<MaterialPickStatu
})
export interface ProcessStatusInfo {
processName?: string | null;
equipmentDescription?: string | null;
equipmentName?: string | null;
equipmentDetailName?: string | null;
startTime?: string | null;
endTime?: string | null;


+ 1
- 1
src/app/api/po/index.ts Просмотреть файл

@@ -33,7 +33,7 @@ export interface PoResult {
status: string;
pol?: PurchaseOrderLine[];
}
export type { StockInLine } from "../stockIn";
export interface PurchaseOrderLine {
id: number;
purchaseOrderId: number;


+ 1
- 0
src/app/api/stockIn/index.ts Просмотреть файл

@@ -127,6 +127,7 @@ export interface StockInLine {
joCode?: string;
warehouseCode?: string;
defaultWarehouseId: number; // id for now
locationCode?: string;
dnNo?: string;
dnDate?: number[];
stockQty?: number;


+ 1
- 1
src/components/ProductionProcess/JobProcessStatus.tsx Просмотреть файл

@@ -285,7 +285,7 @@ const JobProcessStatus: React.FC = () => {
}
const label = [
process.processName,
process.equipmentDescription,
process.equipmentName,
process.equipmentDetailName ? `-${process.equipmentDetailName}` : "",
].filter(Boolean).join(" ");
// 如果工序是必需的,显示三行(Start、Finish、Wait Time)


+ 14
- 10
src/components/ProductionProcess/ProductionProcessList.tsx Просмотреть файл

@@ -20,6 +20,8 @@ import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import dayjs from "dayjs";
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";


import {
fetchAllJoborderProductProcessInfo,
AllJoborderProductProcessInfoResponse,
@@ -50,6 +52,7 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ onSelectProcess
const [openModal, setOpenModal] = useState<boolean>(false);
const [modalInfo, setModalInfo] = useState<StockInLineInput>();
const currentUserId = session?.id ? parseInt(session.id) : undefined;

const [suggestedLocationCode, setSuggestedLocationCode] = useState<string | null>(null);
const handleAssignPickOrder = useCallback(async (pickOrderId: number, jobOrderId?: number, productProcessId?: number) => {
if (!currentUserId) {
@@ -87,17 +90,17 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ onSelectProcess
alert(t(`Unknown error: ${error?.message || "Unknown error"}。Please try again later.`));
}
}, [currentUserId, t, onSelectMatchingStock]);

const handleViewStockIn = useCallback((process: AllJoborderProductProcessInfoResponse) => {
if (!process.stockInLineId) {
alert(t("Invalid Stock In Line Id"));
return;
}
setModalInfo({
id: process.stockInLineId,
//itemId: process.itemId, // 如果 process 中有 itemId,添加这一行
//expiryDate: dayjs().add(1, "month").format(OUTPUT_DATE_FORMAT),
// 视需要补 itemId、jobOrderId 等
});
setOpenModal(true);
}, [t]);
@@ -316,13 +319,14 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ onSelectProcess
})}
</Grid>
<QcStockInModal
session={sessionToken}
open={openModal}
onClose={closeNewModal}
inputDetail={modalInfo}
printerCombo={printerCombo}
printSource="productionProcess"
/>
session={sessionToken}
open={openModal}
onClose={closeNewModal}
inputDetail={modalInfo}
printerCombo={printerCombo}
warehouse={[]}
printSource="productionProcess"
/>
{processes.length > 0 && (
<TablePagination
component="div"


+ 22
- 33
src/components/PutAwayScan/PutAwayModal.tsx Просмотреть файл

@@ -174,42 +174,31 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId

// 根据 item 的 locationCode 设置默认 warehouseId
useEffect(() => {
const fetchItemAndSetDefaultWarehouse = async () => {
if (itemDetail?.itemId && warehouse.length > 0 && firstWarehouseId === null) {
// 只在第一次上架时设置默认值
try {
const itemResult = await fetchItemForPutAway(itemDetail.itemId);
const item = itemResult.item;
// 获取 item 的 locationCode(处理大小写问题)
const locationCode = item.LocationCode || item.locationCode;
if (locationCode) {
// 根据 locationCode 查找对应的 warehouse(通过 code 匹配)
const matchedWarehouse = warehouse.find(
(w) => w.code === locationCode || w.code?.toLowerCase() === locationCode?.toLowerCase()
);
if (matchedWarehouse) {
// 只设置用于显示的默认值,不通知父组件
setItemDefaultWarehouseId(matchedWarehouse.id);
console.log("%c Set default warehouse from item locationCode (display only):", "color:green", {
locationCode,
warehouseId: matchedWarehouse.id,
warehouseCode: matchedWarehouse.code
});
}
}
} catch (error) {
console.error("Error fetching item to get default warehouse:", error);
// 直接使用 fetchStockInLineInfo 返回的 locationCode
// 只在第一次上架时(firstWarehouseId === null)设置默认值
if (itemDetail?.locationCode && warehouse.length > 0 && firstWarehouseId === null) {
const locationCode = itemDetail.locationCode;
if (locationCode) {
// 根据 locationCode 查找对应的 warehouse(通过 code 匹配)
const matchedWarehouse = warehouse.find(
(w) => w.code === locationCode || w.code?.toLowerCase() === locationCode?.toLowerCase()
);
if (matchedWarehouse) {
// 只设置用于显示的默认值,不通知父组件
setItemDefaultWarehouseId(matchedWarehouse.id);
console.log("%c Set default warehouse from item locationCode (from API, display only):", "color:green", {
locationCode,
warehouseId: matchedWarehouse.id,
warehouseCode: matchedWarehouse.code
});
} else {
console.log("%c No warehouse found for locationCode:", "color:yellow", locationCode);
}
}
};
if (itemDetail && itemDetail.status === "received") {
fetchItemAndSetDefaultWarehouse();
}
}, [itemDetail, warehouse, firstWarehouseId]);
}, [itemDetail?.locationCode, warehouse, firstWarehouseId]);

useEffect(() => {
// 只使用实际扫描的 warehouseId,不使用默认值进行验证


+ 21
- 5
src/components/Qc/QcStockInModal.tsx Просмотреть файл

@@ -119,12 +119,20 @@ const QcStockInModal: React.FC<Props> = ({
const res = await fetchStockInLineInfo(stockInLineId);
if (res) {
console.log("%c Fetched Stock In Line: ", "color:orange", res);
console.log("%c [QC] itemId in response:", "color:yellow", res.itemId);
console.log("%c [QC] locationCode in response:", "color:yellow", res.locationCode);
// 如果 res 中没有 itemId,检查是否有其他方式获取
if (!res.itemId) {
console.warn("%c [QC] Warning: itemId is missing in response!", "color:red");
}
setStockInLineInfo({...inputDetail, ...res, expiryDate: res.expiryDate});
// fetchQcResultData(stockInLineId);
} else throw("Result is undefined");
} catch (e) {
console.log("%c Error when fetching Stock In Line: ", "color:red", e);
console.log("%c Error details: ", "color:red", {
message: e instanceof Error ? e.message : String(e),
stack: e instanceof Error ? e.stack : undefined
});
alert("Something went wrong, please retry");
closeHandler({}, "backdropClick");
}
@@ -144,16 +152,24 @@ const QcStockInModal: React.FC<Props> = ({
}
}, [open]);
useEffect(() => {
// 如果后端已经在 StockInLine 中返回了 locationCode,直接使用
if (stockInLineInfo?.locationCode) {
setItemLocationCode(stockInLineInfo.locationCode);
console.log("%c [QC] item LocationCode from API:", "color:cyan", stockInLineInfo.locationCode);
return;
}
// 如果没有 locationCode,尝试从 itemId 获取(向后兼容)
const loadItemLocationCode = async () => {
if (!stockInLineInfo?.itemId) return;
try {
const itemResult = await fetchItemForPutAway(stockInLineInfo.itemId);
const item = itemResult.item;
const locationCode = item.LocationCode || item.locationCode || null;
setItemLocationCode(locationCode);
console.log("%c [QC] item LocationCode:", "color:cyan", locationCode);
console.log("%c [QC] item LocationCode from fetchItemForPutAway:", "color:cyan", locationCode);
} catch (error) {
console.error("Error fetching item to get LocationCode in QC:", error);
setItemLocationCode(null);


Загрузка…
Отмена
Сохранить