From a40c47699ceee859ea2fadf9b5500161bad63e6d Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 16 Apr 2026 11:23:23 +0900 Subject: [PATCH] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=9D=B4=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/step/StepUp.jsx | 150 ++++++++++++------ 1 file changed, 98 insertions(+), 52 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index 14f6aa03..da6ea213 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -134,9 +134,7 @@ export default function StepUp(props) { const moduleIds = targetSurface.modules.map((module) => module.id) /** 기존 모듈 텍스트 삭제 */ - canvas - .getObjects() - .filter((obj) => moduleIds.includes(obj.parentId)) + ;[...canvas.getObjects().filter((obj) => moduleIds.includes(obj.parentId))] .forEach((text) => canvas.remove(text)) /** 새로운 모듈 회로 정보 추가 */ @@ -410,61 +408,100 @@ export default function StepUp(props) { * 주어진 stepUpListData 를 기준으로 캔버스의 모든 module circuit 텍스트를 다시 그린다. * 모든 pcsItem 의 selected serQty 를 순회해 적용한다. */ - const applyCircuitsToCanvas = (stepUpListSrc) => { + /** + * 모듈에 circuit 텍스트를 추가하는 공통 함수 + */ + const addCircuitTextToModule = (module) => { + const targetModule = canvas.getObjects().find((obj) => obj.id === module.uniqueId) + if (targetModule && module.circuit !== '' && module.circuit !== null) { + const moduleCircuitText = new fabric.Text(module.circuit, { + left: targetModule.left + targetModule.width / 2, + top: targetModule.top + targetModule.height / 2, + fontFamily: circuitNumberText.fontFamily.value, + fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', + fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontSize: circuitNumberText.fontSize.value, + fill: circuitNumberText.fontColor.value, + width: targetModule.width, + height: targetModule.height, + textAlign: 'center', + originX: 'center', + originY: 'center', + name: 'circuitNumber', + parentId: targetModule.id, + circuitInfo: module.pcsItemId, + visible: isDisplayCircuitNumber, + }) + targetModule.circuit = moduleCircuitText + targetModule.pcsItemId = module.pcsItemId + targetModule.circuitNumber = module.circuit + canvas.add(moduleCircuitText) + } + } + + const applyCircuitsToCanvas = (stepUpListSrc, mainIdx, subIdx) => { if (!stepUpListSrc?.[0]?.pcsItemList) return - /** 모든 모듈 circuit 데이터 초기화 */ - canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE) - .forEach((module) => { + if (mainIdx >= 1) { + /** + * 우측 PCS (mainIdx >= 1) 클릭 시: + * 해당 pcsItem 의 selected serQty 를 찾아서 moduleList 의 circuit 만 갱신한다. + * 좌측 PCS 의 circuit 은 그대로 유지. + */ + const pcsItem = stepUpListSrc[0].pcsItemList[mainIdx] + const sel = pcsItem?.serQtyList?.find((sq) => sq.selected) + if (!sel) return + + // 해당 pcsItem 의 moduleList 에 포함된 모듈의 기존 circuit 텍스트만 제거 + const moduleUniqueIds = new Set() + sel.roofSurfaceList.forEach((rs) => { + rs.moduleList.forEach((m) => moduleUniqueIds.add(m.uniqueId)) + }) + + // 해당 모듈의 circuit 데이터 초기화 + 기존 텍스트 제거 + const targetModuleObjs = canvas.getObjects().filter( + (obj) => obj.name === POLYGON_TYPE.MODULE && moduleUniqueIds.has(obj.id), + ) + targetModuleObjs.forEach((module) => { module.circuit = null module.circuitNumber = null module.pcsItemId = null }) - /** 기존 circuit 텍스트 객체 모두 제거 */ - canvas - .getObjects() - .filter((obj) => obj.name === 'circuitNumber') - .forEach((text) => canvas.remove(text)) + const textsToRemove = [...canvas.getObjects().filter( + (obj) => obj.name === 'circuitNumber' && moduleUniqueIds.has(obj.parentId), + )] + textsToRemove.forEach((text) => canvas.remove(text)) - stepUpListSrc[0].pcsItemList.forEach((pcsItem) => { - const sel = pcsItem.serQtyList?.find((sq) => sq.selected) - if (!sel) return + // 새 circuit 적용 sel.roofSurfaceList.forEach((roofSurface) => { - const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0] - if (!targetSurface) return + roofSurface.moduleList.forEach((module) => addCircuitTextToModule(module)) + }) + } else { + /** + * 좌측 PCS (mainIdx === 0) 클릭 시: + * 전체 모듈 circuit 초기화 후 모든 pcsItem 의 selected 를 적용 + */ + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE) + .forEach((module) => { + module.circuit = null + module.circuitNumber = null + module.pcsItemId = null + }) - roofSurface.moduleList.forEach((module) => { - const targetModule = canvas.getObjects().find((obj) => obj.id === module.uniqueId) - if (targetModule && module.circuit !== '' && module.circuit !== null) { - const moduleCircuitText = new fabric.Text(module.circuit, { - left: targetModule.left + targetModule.width / 2, - top: targetModule.top + targetModule.height / 2, - fontFamily: circuitNumberText.fontFamily.value, - fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', - fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontSize: circuitNumberText.fontSize.value, - fill: circuitNumberText.fontColor.value, - width: targetModule.width, - height: targetModule.height, - textAlign: 'center', - originX: 'center', - originY: 'center', - name: 'circuitNumber', - parentId: targetModule.id, - circuitInfo: module.pcsItemId, - visible: isDisplayCircuitNumber, - }) - targetModule.circuit = moduleCircuitText - targetModule.pcsItemId = module.pcsItemId - targetModule.circuitNumber = module.circuit - canvas.add(moduleCircuitText) - } + const circuitTexts = [...canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')] + circuitTexts.forEach((text) => canvas.remove(text)) + + stepUpListSrc[0].pcsItemList.forEach((pcsItem) => { + const sel = pcsItem.serQtyList?.find((sq) => sq.selected) + if (!sel) return + sel.roofSurfaceList.forEach((roofSurface) => { + roofSurface.moduleList.forEach((module) => addCircuitTextToModule(module)) }) }) - }) + } canvas.renderAll() setModuleStatisticsData() @@ -483,8 +520,7 @@ export default function StepUp(props) { setStepUpListData(tempStepUpListData) /** PCS 2개 이상 또는 첫번째 PCS 선택 시에만 실행 */ - const needsRefetch = - tempStepUpListData[0].pcsItemList.length > 1 && mainIdx === 0 + const needsRefetch = tempStepUpListData[0].pcsItemList.length > 1 && mainIdx === 0 if (needsRefetch) { /** 파워컨디셔너 옵션 조회 요청 파라미터 */ @@ -522,10 +558,10 @@ export default function StepUp(props) { const dataArray = Array.isArray(res.data) ? res.data : [res.data] const newStepUpListData = formatStepUpListData(dataArray) setStepUpListData(newStepUpListData) - applyCircuitsToCanvas(newStepUpListData) + applyCircuitsToCanvas(newStepUpListData, mainIdx, subIdx) } else { swalFire({ text: getMessage('common.message.send.error') }) - applyCircuitsToCanvas(tempStepUpListData) + applyCircuitsToCanvas(tempStepUpListData, mainIdx, subIdx) } }) return @@ -533,7 +569,7 @@ export default function StepUp(props) { } /** API 재조회가 없는 경로: 현재 tempStepUpListData 로 즉시 캔버스 갱신 */ - applyCircuitsToCanvas(tempStepUpListData) + applyCircuitsToCanvas(tempStepUpListData, mainIdx, subIdx) } /** @@ -551,7 +587,17 @@ export default function StepUp(props) { paralQty: serQty.paralQty, // 접속함 중복 체크: 동일 itemId는 1개만, 다르면 각각 올림 connections: item.connList?.length - ? [...new Map(item.connList.map((conn) => [conn.itemId, { connItemId: conn.itemId, connMaxParalCnt: conn.connMaxParalCnt }])).values()] + ? [ + ...new Map( + item.connList.map((conn) => [ + conn.itemId, + { + connItemId: conn.itemId, + connMaxParalCnt: conn.connMaxParalCnt, + }, + ]), + ).values(), + ] : [], } })