From c1db5c5fd141602683ce015683bdcede50f1562d Mon Sep 17 00:00:00 2001 From: Marcos Reifonas Date: Sun, 20 Sep 2026 01:07:33 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Auto-deploy:=20TrackSteelAPP=20a?= =?UTF-8?q?tualizado=20em=2020/09/2026=2001:07:33?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/viewer3d/ModelViewer3D.tsx | 11 +++++- src/pages/Visualizador3D.tsx | 43 ++++++++++++++++------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/components/viewer3d/ModelViewer3D.tsx b/src/components/viewer3d/ModelViewer3D.tsx index 7a81c96..8c9b224 100644 --- a/src/components/viewer3d/ModelViewer3D.tsx +++ b/src/components/viewer3d/ModelViewer3D.tsx @@ -237,7 +237,16 @@ export const ModelViewer3D: React.FC = ({ if (colorMode === 'production' && productionData) { // Look up production pointing status - const prod = productionData.get(pmark); + let prod = productionData.get(pmark); + if (!prod) { + // Fallback lookup: IFC marks sometimes have prefixes like B135-1-V1 or suffixes. + for (const [key, val] of productionData.entries()) { + if (pmark === key || pmark.endsWith(`-${key}`) || key.endsWith(`-${pmark}`) || pmark.includes(key)) { + prod = val; + break; + } + } + } if (prod && prod.pointedQtd > 0) { // Apply stage color (e.g., Light Green #4ade80 for pointed) const stageHex = prod.processColor || '#4ade80'; diff --git a/src/pages/Visualizador3D.tsx b/src/pages/Visualizador3D.tsx index 751074f..674d056 100644 --- a/src/pages/Visualizador3D.tsx +++ b/src/pages/Visualizador3D.tsx @@ -48,6 +48,7 @@ export default function Visualizador3D() { const [totalPecasBD, setTotalPecasBD] = useState(0); const [totalApontadasBD, setTotalApontadasBD] = useState(0); const [pesoTotalBD, setPesoTotalBD] = useState(0); + const [progressoOF, setProgressoOF] = useState(0); // 3D Model and Quality State const [modelData, setModelData] = useState(null); @@ -126,8 +127,7 @@ export default function Visualizador3D() { totalPecas += Number(p.quantidade || 0); totalPeso += Number(p.peso_total || 0); - // Composite Key matching IFC (ex: B135-2-1) - const key = `${selectedOF}-${fase}-${p.marca}`; + const key = p.marca; prodMap.set(key, { pecaId: p.id, marca: p.marca, @@ -135,37 +135,53 @@ export default function Visualizador3D() { totalQtd: Number(p.quantidade || 1), pointedQtd: 0, currentProcessName: 'Pendente', - processColor: '#64748b' + processColor: '#64748b', + processOrdem: 0 }); }); } - let pointedTotal = 0; if (apontamentosData) { + // Ordenar apontamentos do menor processo para o maior (assim o processo mais avançado sobressai por último) + apontamentosData.sort((a: any, b: any) => (a.processo?.ordem || 0) - (b.processo?.ordem || 0)); + apontamentosData.forEach((ap: any) => { const marca = ap.peca?.marca; - const fase = String(ap.peca?.etapa_fase || '1'); if (marca) { - const key = `${selectedOF}-${fase}-${marca}`; + const key = marca; const existing = prodMap.get(key); if (existing) { const qty = Number(ap.quantidade_produzida || 0); - existing.pointedQtd += qty; - pointedTotal += qty; - if (ap.processo?.nome) { - existing.currentProcessName = ap.processo.nome; - existing.processColor = ap.processo.cor || PROCESS_COLORS[ap.processo.nome] || '#10b981'; + if (qty > 0) { + // Atualiza a peça para o estágio mais avançado alcançado + existing.pointedQtd = Math.max(existing.pointedQtd, qty); // Evita duplicar apontamentos de processos anteriores + existing.currentProcessName = ap.processo?.nome || existing.currentProcessName; + existing.processColor = ap.processo?.cor || PROCESS_COLORS[ap.processo?.nome || ''] || '#10b981'; + existing.processOrdem = ap.processo?.ordem || existing.processOrdem; } } } }); } + let pointedTotal = 0; + let sumProgress = 0; // Para evolução da OF + + prodMap.forEach((val) => { + pointedTotal += val.pointedQtd; + // Considerando maxOrdem = 5 como final para cálculo de %. Ajuste conforme necessário. + const pecaProgress = val.pointedQtd > 0 ? Math.min(val.processOrdem / 5, 1) * (val.pointedQtd / val.totalQtd) : 0; + sumProgress += pecaProgress * val.totalQtd; + }); + + const progressoGeralPercent = totalPecas > 0 ? Math.min(Math.round((sumProgress / totalPecas) * 100), 100) : 0; + setPhasesList(Array.from(phases).sort()); setProductionMap(prodMap); setTotalPecasBD(totalPecas); setTotalApontadasBD(pointedTotal); setPesoTotalBD(totalPeso); + setProgressoOF(progressoGeralPercent); } catch (err) { console.error('Erro ao carregar dados de produção da OF:', err); } @@ -201,7 +217,8 @@ export default function Visualizador3D() { } }; - const progressPercent = totalPecasBD > 0 ? Math.min(Math.round((totalApontadasBD / totalPecasBD) * 100), 100) : 0; + const progressPercent = totalPecasBD > 0 ? Math.min(Math.round((totalApontadasBD / totalPecasBD) * 100), 100) : 0; // Será substituido pelo state local caso quisermos, mas o totalApontadasBD já não vai estourar. + return (
@@ -346,7 +363,7 @@ export default function Visualizador3D() { Evolução da OF - {progressPercent}% concluído + {progressoOF}% concluído