瀏覽代碼

Bom Supporting Function

reset-do-picking-order
B.E.N.S.O.N 1 周之前
父節點
當前提交
d5f19a7057
共有 3 個文件被更改,包括 79 次插入25 次删除
  1. +7
    -0
      src/app/api/settings/bomWeighting/client.ts
  2. +20
    -1
      src/components/BomWeightingScoreTable/BomWeightingScoreTable.tsx
  3. +52
    -24
      src/components/BomWeightingTabs/BomWeightingTabs.tsx

+ 7
- 0
src/app/api/settings/bomWeighting/client.ts 查看文件

@@ -12,6 +12,13 @@ export interface UpdateBomWeightingScoreInputs {
remarks?: string; remarks?: string;
} }


export const fetchBomWeightingScoresClient = async (): Promise<BomWeightingScoreResult[]> => {
const response = await axiosInstance.get<BomWeightingScoreResult[]>(
`${NEXT_PUBLIC_API_URL}/bomWeightingScores`
);
return response.data;
};

export const updateBomWeightingScoreClient = async ( export const updateBomWeightingScoreClient = async (
data: UpdateBomWeightingScoreInputs data: UpdateBomWeightingScoreInputs
): Promise<BomWeightingScoreResult> => { ): Promise<BomWeightingScoreResult> => {


+ 20
- 1
src/components/BomWeightingScoreTable/BomWeightingScoreTable.tsx 查看文件

@@ -16,9 +16,10 @@ import Stack from "@mui/material/Stack";


interface Props { interface Props {
bomWeightingScores: BomWeightingScoreResult[]; bomWeightingScores: BomWeightingScoreResult[];
onWeightingUpdated?: () => void;
} }


const BomWeightingScoreTable: React.FC<Props> & { Loading?: React.FC } = ({ bomWeightingScores: initialBomWeightingScores }) => {
const BomWeightingScoreTable: React.FC<Props> & { Loading?: React.FC } = ({ bomWeightingScores: initialBomWeightingScores, onWeightingUpdated }) => {
const { t } = useTranslation("common"); const { t } = useTranslation("common");
const [bomWeightingScores, setBomWeightingScores] = useState(initialBomWeightingScores); const [bomWeightingScores, setBomWeightingScores] = useState(initialBomWeightingScores);
const [isEditMode, setIsEditMode] = useState(false); const [isEditMode, setIsEditMode] = useState(false);
@@ -120,10 +121,28 @@ const BomWeightingScoreTable: React.FC<Props> & { Loading?: React.FC } = ({ bomW
prev.map((r) => updatedById.get(r.id) ?? r), prev.map((r) => updatedById.get(r.id) ?? r),
); );


// Wait a bit to ensure all weighting updates are committed to database
// before recalculating base scores
console.log("Waiting for weighting updates to commit...");
await new Promise(resolve => setTimeout(resolve, 200));

// After weighting changes, trigger BOM baseScore recalculation on the server // After weighting changes, trigger BOM baseScore recalculation on the server
try { try {
console.log("Triggering BOM base score recalculation...");
const result = await recalcBomScoresClient(); const result = await recalcBomScoresClient();
updatedCount = result?.updatedCount ?? null; updatedCount = result?.updatedCount ?? null;
console.log(`BOM base scores recalculated: ${updatedCount} BOMs updated`);
// Wait a bit more to ensure recalculation transaction is committed
// before refreshing the frontend
await new Promise(resolve => setTimeout(resolve, 300));
// Notify parent component to refresh BOM scores if needed
if (onWeightingUpdated) {
console.log("Refreshing BOM scores in frontend...");
await onWeightingUpdated();
console.log("BOM scores refreshed");
}
} catch (recalcError) { } catch (recalcError) {
console.error("Failed to recalculate BOM base scores:", recalcError); console.error("Failed to recalculate BOM base scores:", recalcError);
// We don't block the main save flow if recalculation fails // We don't block the main save flow if recalculation fails


+ 52
- 24
src/components/BomWeightingTabs/BomWeightingTabs.tsx 查看文件

@@ -3,6 +3,7 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { BomWeightingScoreResult } from "@/app/api/settings/bomWeighting"; import { BomWeightingScoreResult } from "@/app/api/settings/bomWeighting";
import { fetchBomWeightingScoresClient } from "@/app/api/settings/bomWeighting/client";
import type { BomScoreResult } from "@/app/api/bom"; import type { BomScoreResult } from "@/app/api/bom";
import { fetchBomScoresClient } from "@/app/api/bom/client"; import { fetchBomScoresClient } from "@/app/api/bom/client";
import BomWeightingScoreTable from "@/components/BomWeightingScoreTable"; import BomWeightingScoreTable from "@/components/BomWeightingScoreTable";
@@ -16,37 +17,61 @@ interface Props {
bomWeightingScores: BomWeightingScoreResult[]; bomWeightingScores: BomWeightingScoreResult[];
} }


const BomWeightingTabs: React.FC<Props> = ({ bomWeightingScores }) => {
const BomWeightingTabs: React.FC<Props> = ({ bomWeightingScores: initialBomWeightingScores }) => {
const { t } = useTranslation("common"); const { t } = useTranslation("common");
const [tab, setTab] = useState(0); const [tab, setTab] = useState(0);
const [bomWeightingScores, setBomWeightingScores] = useState<BomWeightingScoreResult[]>(initialBomWeightingScores);
const [bomScores, setBomScores] = useState<BomScoreResult[] | null>(null); const [bomScores, setBomScores] = useState<BomScoreResult[] | null>(null);
const [loadingScores, setLoadingScores] = useState(false); const [loadingScores, setLoadingScores] = useState(false);
const [loadError, setLoadError] = useState<string | null>(null); const [loadError, setLoadError] = useState<string | null>(null);


useEffect(() => {
if (tab !== 1) return;
const loadBomScores = React.useCallback(async () => {
try {
setLoadingScores(true);
setLoadError(null);
console.log("Fetching BOM scores from /bom/scores...");
const data = await fetchBomScoresClient();
console.log("BOM scores received:", data);
setBomScores(data || []);
} catch (err: any) {
console.error("Failed to load BOM scores:", err);
const errorMsg =
err?.response?.data?.message || err?.message || t("Update Failed") || "Load failed";
setLoadError(errorMsg);
setBomScores([]);
} finally {
setLoadingScores(false);
}
}, [t]);

const loadBomWeightingScores = React.useCallback(async () => {
try {
console.log("Fetching BOM weighting scores...");
const data = await fetchBomWeightingScoresClient();
console.log("BOM weighting scores received:", data);
setBomWeightingScores(data || []);
} catch (err: any) {
console.error("Failed to load BOM weighting scores:", err);
}
}, []);

const handleWeightingUpdated = React.useCallback(async () => {
// Refresh both weighting scores and BOM scores
await Promise.all([
loadBomWeightingScores(),
loadBomScores()
]);
}, [loadBomWeightingScores, loadBomScores]);


const load = async () => {
try {
setLoadingScores(true);
setLoadError(null);
console.log("Fetching BOM scores from /bom/scores...");
const data = await fetchBomScoresClient();
console.log("BOM scores received:", data);
setBomScores(data || []);
} catch (err: any) {
console.error("Failed to load BOM scores:", err);
const errorMsg =
err?.response?.data?.message || err?.message || t("Update Failed") || "Load failed";
setLoadError(errorMsg);
setBomScores([]);
} finally {
setLoadingScores(false);
}
};
// Sync initial prop values
useEffect(() => {
setBomWeightingScores(initialBomWeightingScores);
}, [initialBomWeightingScores]);


void load();
}, [tab, t]);
useEffect(() => {
if (tab !== 1) return;
void loadBomScores();
}, [tab, loadBomScores]);


return ( return (
<> <>
@@ -83,7 +108,10 @@ const BomWeightingTabs: React.FC<Props> = ({ bomWeightingScores }) => {


<Box> <Box>
{tab === 0 && ( {tab === 0 && (
<BomWeightingScoreTable bomWeightingScores={bomWeightingScores} />
<BomWeightingScoreTable
bomWeightingScores={bomWeightingScores}
onWeightingUpdated={handleWeightingUpdated}
/>
)} )}
{tab === 1 && ( {tab === 1 && (
loadingScores ? ( loadingScores ? (


Loading…
取消
儲存