import WithDraggable from '@/components/common/draggable/WithDraggable' import { useContext, useEffect, useRef, useState } from 'react' import PowerConditionalSelect from '@/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect' import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp' import { useMessage } from '@/hooks/useMessage' import { usePopup } from '@/hooks/usePopup' import PassivityCircuitAllocation from './step/type/PassivityCircuitAllocation' import BasicSetting from '@/components/floor-plan/modal/basic/BasicSetting' import { useMasterController } from '@/hooks/common/useMasterController' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { GlobalDataContext } from '@/app/GlobalDataProvider' import { POLYGON_TYPE, MENU } from '@/common/common' import { useSwal } from '@/hooks/useSwal' import { canvasState, canvasZoomState, currentMenuState } from '@/store/canvasAtom' import { useTrestle } from '@/hooks/module/useTrestle' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { v4 as uuidv4 } from 'uuid' import { useEstimate } from '@/hooks/useEstimate' import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' import { useImgLoader } from '@/hooks/floorPlan/useImgLoader' import { QcastContext } from '@/app/QcastProvider' import { fontSelector } from '@/store/fontAtom' import { fabric } from 'fabric' const ALLOCATION_TYPE = { AUTO: 'auto', PASSIVITY: 'passivity', } export default function CircuitTrestleSetting({ id }) { const { getMessage } = useMessage() const { closePopup, addPopup } = usePopup() const { apply, setViewCircuitNumberTexts, getEstimateData, clear: clearTrestle, setAllModuleSurfaceIsComplete } = useTrestle() const { swalFire } = useSwal() const { saveEstimate } = useEstimate() const canvas = useRecoilValue(canvasState) const setCurrentMenu = useSetRecoilState(currentMenuState) const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const [tabNum, setTabNum] = useState(1) const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO) const [circuitAllocationType, setCircuitAllocationType] = useState(1) const { managementState, setManagementState } = useContext(GlobalDataContext) const selectedModules = useRecoilValue(selectedModuleState) const { getPcsAutoRecommendList, getPcsVoltageChk, getPcsVoltageStepUpList, getPcsManualConfChk } = useMasterController() const flowText = useRecoilValue(fontSelector('flowText')) const lengthText = useRecoilValue(fontSelector('lengthText')) const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText')) // 회로할당(승합설정)에서 선택된 값들을 저장할 상태 추가 const [selectedStepUpValues, setSelectedStepUpValues] = useState({}) const [getStepUpSelections, setGetStepUpSelections] = useState(null) // const { trigger: setCircuitData } = useCanvasPopupStatusController(4) // const [stepUpListData, setStepUpListData] = useRecoilState(stepUpListDataState) const [stepUpListData, setStepUpListData] = useState([]) const [seletedMainOption, setSeletedMainOption] = useState(null) const [seletedSubOption, setSeletedSubOption] = useState(null) const { setModuleStatisticsData } = useCircuitTrestle() const { handleCanvasToPng } = useImgLoader() const moduleSelectionData = useRecoilValue(moduleSelectionDataState) const passivityCircuitAllocationRef = useRef() const { setIsGlobalLoading } = useContext(QcastContext) const originCanvasViewPortTransform = useRef([]) const [isFold, setIsFold] = useState(false) const { makers, setMakers, selectedMaker, setSelectedMaker, series, setSeries, models, setModels, selectedModels, setSelectedModels, pcsCheck, setPcsCheck, getOptYn, getPcsItemList, getSelectedPcsItemList, getUseModuleItemList, getRoofSurfaceList, getModuleList, removeNotAllocationModules, resetCircuits, } = useCircuitTrestle() // const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) useEffect(() => { originCanvasViewPortTransform.current = [...canvas.viewportTransform] if (!managementState) { } // setCircuitData({ // makers, // selectedMaker, // series, // models, // selectedModels, // pcsCheck, // }) return () => { const moduleSetupSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) if (moduleSetupSurfaces.some((surface) => !surface.isComplete)) { resetCircuits() } } }, []) // 모듈이 설치된 경우 rack설치 여부에 따라 설치 된 모듈 아래에 작은 모듈이 설치되어 있을 경우는 모듈 설치 메뉴 reopen useEffect(() => { const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) if (modules.length === 0) { return } /** * 랙 설치 시 모듈 크기 검증 * - 남쪽: 아래쪽 모듈이 위쪽 모듈보다 커야 함 * - 북쪽: 위쪽 모듈이 아래쪽 모듈보다 커야 함 * - 동쪽: 오른쪽 모듈이 왼쪽 모듈보다 커야 함 * - 서쪽: 왼쪽 모듈이 오른쪽 모듈보다 커야 함 */ const validateModuleSizeForRack = (surface) => { const { modules, direction, trestleDetail } = surface const { rackYn, moduleIntvlHor, moduleIntvlVer } = trestleDetail if (rackYn === 'N' || !modules || modules.length < 2) { return true // 검증 통과 } // 모듈 중심점 및 크기 정보 계산 const centerPoints = modules.map((module) => { const { x, y } = module.getCenterPoint() const { width, height } = module return { x, y, width: Math.floor(width), height: Math.floor(height), area: Math.floor(width) * Math.floor(height), } }) // 방향별 설정 const isVertical = direction === 'south' || direction === 'north' const primaryInterval = isVertical ? moduleIntvlVer : moduleIntvlHor const secondaryInterval = isVertical ? moduleIntvlHor : moduleIntvlVer // 정렬 함수: 큰 모듈이 있어야 할 위치부터 시작 const getSortFn = () => { switch (direction) { case 'south': return (a, b) => b.y - a.y // 아래쪽(y 큼)부터 case 'north': return (a, b) => a.y - b.y // 위쪽(y 작음)부터 case 'east': return (a, b) => b.x - a.x // 오른쪽(x 큼)부터 case 'west': return (a, b) => a.x - b.x // 왼쪽(x 작음)부터 default: return () => 0 } } // 타겟 모듈 찾기 (현재 모듈보다 작아야 할 위치의 모듈) const findTargetModules = (current, margin) => { return centerPoints.filter(cp => { const sameAxis = isVertical ? Math.abs(cp.x - current.x) < margin : Math.abs(cp.y - current.y) < margin const targetDirection = direction === 'south' ? cp.y < current.y : direction === 'north' ? cp.y > current.y : direction === 'east' ? cp.x < current.x : cp.x > current.x return sameAxis && targetDirection }) } // 가장 가까운 타겟 모듈 찾기 const getClosestTarget = (filtered) => { if (filtered.length === 0) return null return filtered.reduce((closest, cp) => { switch (direction) { case 'south': return cp.y > closest.y ? cp : closest case 'north': return cp.y < closest.y ? cp : closest case 'east': return cp.x > closest.x ? cp : closest case 'west': return cp.x < closest.x ? cp : closest default: return closest } }) } // 두 모듈 간 간격 계산 const getGap = (current, target) => { if (isVertical) { return direction === 'south' ? (current.y - current.height / 2) - (target.y + target.height / 2) : (target.y - target.height / 2) - (current.y + current.height / 2) } else { return direction === 'east' ? (current.x - current.width / 2) - (target.x + target.width / 2) : (target.x - target.width / 2) - (current.x + current.width / 2) } } // 인접 모듈 여부 확인 const isAdjacent = (current, target) => { const gap = getGap(current, target) return gap >= 0 && gap <= primaryInterval + 1 } // 정렬된 모듈 순회 const sortedPoints = [...centerPoints].sort(getSortFn()) for (const current of sortedPoints) { // 1. 일반 배치: 같은 라인에서 인접 모듈 검사 const directTargets = findTargetModules(current, secondaryInterval) const closestTarget = getClosestTarget(directTargets) if (closestTarget && isAdjacent(current, closestTarget) && closestTarget.area > current.area) { return false // 검증 실패 } // 2. 물떼새 배치: 반 오프셋 위치의 인접 모듈 검사 const size = isVertical ? current.width : current.height const halfOffset = (size + secondaryInterval) / 2 for (const sign of [-1, 1]) { const offsetValue = sign * halfOffset const findHalfTarget = centerPoints.filter((cp) => { const offsetAxis = isVertical ? Math.abs(cp.x - (current.x + offsetValue)) <= primaryInterval : Math.abs(cp.y - (current.y + offsetValue)) <= primaryInterval const targetDirection = direction === 'south' ? cp.y < current.y : direction === 'north' ? cp.y > current.y : direction === 'east' ? cp.x < current.x : cp.x > current.x return offsetAxis && targetDirection }) const closestHalf = getClosestTarget(findHalfTarget) if (closestHalf && isAdjacent(current, closestHalf) && closestHalf.area > current.area) { return false // 검증 실패 } } } return true // 검증 통과 } // 모든 설치면에 대해 검증 수행 const moduleSetupSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) for (const surface of moduleSetupSurfaces) { if (!validateModuleSizeForRack(surface)) { swalFire({ text: getMessage('module.size.validation.rack.error'), icon: 'error', confirmFn: () => { // 현재 팝업 닫기 closePopup(id) // 메뉴 하이라이트 변경 setCurrentMenu(MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) // 모듈/가대설정 팝업 열기 const newPopupId = uuidv4() clearTrestle() setAllModuleSurfaceIsComplete(false) addPopup(newPopupId, 1, ) }, }) return } } }, []) const capture = async (type) => { beforeCapture(type) await handleCanvasToPng(type) afterCapture(type) return new Promise((resolve) => { setTimeout(() => { resolve(true) }, 1000) }) } // 캡쳐 전 처리 const beforeCapture = (type) => { setCanvasZoom(100) canvas.set({ zoom: 1 }) // roof 객체들을 찾아서 중앙점 계산 const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof' && !obj.wall) if (roofs.length > 0) { // 모든 roof의 x, y 좌표를 수집 const allPoints = [] roofs.forEach((roof) => { if (roof.getCurrentPoints()) { roof.getCurrentPoints().forEach((point) => { allPoints.push({ x: point.x, y: point.y }) }) } }) if (allPoints.length > 0) { // 모든 점들의 중앙값 계산 const minX = Math.min(...allPoints.map((p) => p.x)) const maxX = Math.max(...allPoints.map((p) => p.x)) const minY = Math.min(...allPoints.map((p) => p.y)) const maxY = Math.max(...allPoints.map((p) => p.y)) const centerX = (minX + maxX) / 2 const centerY = (minY + maxY) / 2 // 캔버스 중앙으로 이동하기 위한 오프셋 계산 const canvasWidth = canvas.getWidth() const canvasHeight = canvas.getHeight() const offsetX = canvasWidth / 2 - centerX const offsetY = canvasHeight / 2 - centerY canvas.viewportTransform = [1, 0, 0, 1, offsetX, offsetY] } else { canvas.viewportTransform = [1, 0, 0, 1, 0, 0] } } else { canvas.viewportTransform = [1, 0, 0, 1, 0, 0] } const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) const circuitNumberTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber') if (type === 2) { modules.forEach((module) => { module.set({ originColor: module.fill, fill: null, strokeWidth: 2 }) }) circuitNumberTexts.forEach((text) => { text.set({ visible: false }) }) } let x, y x = canvas.width / 2 y = canvas.height / 2 canvas.zoomToPoint(new fabric.Point(x, y), 0.4) changeFontSize('lengthText', '28') changeFontSize('circuitNumber', '28') changeFontSize('flowText', '28') canvas.renderAll() } // 캡쳐 후 처리 const afterCapture = (type) => { if (originCanvasViewPortTransform.current[0] !== 1) { setCanvasZoom(Number((originCanvasViewPortTransform.current[0] * 100).toFixed(0))) } canvas.viewportTransform = [...originCanvasViewPortTransform.current] canvas.renderAll() changeFontSize('lengthText', lengthText.fontSize.value) changeFontSize('circuitNumber', circuitNumberText.fontSize.value) changeFontSize('flowText', flowText.fontSize.value) const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) const circuitNumberTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber') if (type === 2) { modules.forEach((module) => { module.set({ fill: module.originColor, strokeWidth: 0.3, }) }) circuitNumberTexts.forEach((text) => { text.set({ visible: true }) }) } canvas.renderAll() } // 수동할당 시 모듈 삭제 // 시리즈중 자동으로 추천 PCS 정보 조회 const onAutoRecommend = () => { if (series.filter((s) => s.selected).length === 0) { swalFire({ title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error02'), type: 'alert', }) return } const isMultiModule = selectedModules.itemList.length > 1 let isAllIndfcs = false if (isMultiModule) { //INDFCS 실내집중, OUTDMULTI 옥외멀티 // 1. 모듈이 혼합형일 경우 선택한 pcs가 실내집중인 경우 alert if (selectedModels.length > 0) { isAllIndfcs = selectedModels.every((model) => model.pcsTpCd === 'INDFCS') } else { isAllIndfcs = models.every((model) => model.pcsTpCd === 'INDFCS') } } if (isAllIndfcs) { swalFire({ title: getMessage('module.circuit.indoor.focused.error'), type: 'alert', }) return } const params = { ...getOptYn(), useModuleItemList: getUseModuleItemList(), roofSurfaceList: getRoofSurfaceList(), pcsItemList: getPcsItemList(isMultiModule), } // 파워컨디셔너 추천 목록 조회 if (selectedModels.length === 0) { // 시리즈중 자동으로 추천 PCS 정보 조회 getPcsAutoRecommendList(params).then((res) => { if (res.data?.pcsItemList) { let pcsItemList = [] let pcsObj = {} models.forEach((model) => { pcsObj[model.itemId] = model }) res.data?.pcsItemList.forEach((item) => { if (pcsObj[item.itemId]) { pcsItemList.push({ ...pcsObj[item.itemId], isUsed: false, id: uuidv4(), }) } }) // 회로 구성 가능 여부 체크 요청 파라미터 const pcsVoltageChkParams = { ...getOptYn(), useModuleItemList: getUseModuleItemList(), roofSurfaceList: getRoofSurfaceList(), pcsItemList: pcsItemList, } // 추천 목록 선택 setSelectedModels(pcsItemList) // 회로 구성 가능 여부 체크 getPcsVoltageChk(pcsVoltageChkParams).then((res) => { if (res.resultCode === 'S') { setTabNum(2) setAllModuleSurfaceIsComplete(false) } else { swalFire({ title: res.resultMsg, type: 'alert', }) } }) } else { // 데이터가 없는 경우 오류 메시지 확인 필요 if (res.result.resultCode === 'E') { swalFire({ title: res.result.resultMsg, type: 'alert', }) } else { swalFire({ title: '파워컨디셔너를 추가해 주세요.', type: 'alert', }) } } }) } else { // 회로 구성 가능 여부 체크 getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList(isMultiModule) }).then((res) => { if (res.resultCode === 'S') { // 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회 getPcsVoltageStepUpList({ ...params, pcsItemList: getSelectedPcsItemList(isMultiModule), }).then((res) => { if (res?.result.resultCode === 'S' && res?.data) { setTabNum(2) setAllModuleSurfaceIsComplete(false) } else { swalFire({ text: getMessage('common.message.send.error') }) } }) } else { swalFire({ title: res.resultMsg, type: 'alert', }) } }) } } // 자동할당 버튼 클릭 시 const onAutoAllocation = () => { let moduleStdQty = 0 let moduleMaxQty = 0 const selectedModels = models.filter((m) => m.selected) // 시리즈중 자동으로 추천 PCS 정보 조회 if (selectedModels.length === 0) { onAutoRecommend() } else { // 모듈 최소 매수 moduleStdQty = selectedModels.reduce((acc, model) => { return acc + parseInt(model.moduleStdQty) }, 0) moduleMaxQty = selectedModels.reduce((acc, model) => { return acc + parseInt(model.moduleMaxQty) }, 0) } // const target = pcsCheck.max ? moduleMaxQty : moduleStdQty // const placementModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) // if (placementModules.length > target) { // swalFire({ // title: '배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.', // type: 'alert', // }) // return // } // setAllocationType(ALLOCATION_TYPE.AUTO) // setTabNum(2) } // 수동할당 버튼 클릭 시 const onPassivityAllocation = () => { if (selectedModels.length === 0) { const params = { ...getOptYn(), useModuleItemList: getUseModuleItemList(), roofSurfaceList: getRoofSurfaceList().map((surface) => { return { ...surface, moduleList: surface.moduleList.map((module) => { return { itemId: module.itemId, uniqueId: module.uniqueId, } }), } }), pcsItemList: getPcsItemList(), } // 파워컨디셔너 추천 목록 조회 getPcsAutoRecommendList(params).then((res) => { if (res.data?.pcsItemList) { let pcsItemList = [] let pcsObj = {} models.forEach((model) => { pcsObj[model.itemId] = model }) res.data?.pcsItemList.forEach((item) => { if (pcsObj[item.itemId]) { pcsItemList.push({ ...pcsObj[item.itemId], isUsed: false, id: uuidv4(), }) } }) const pcsVoltageChkParams = { ...getOptYn(), useModuleItemList: getUseModuleItemList(), roofSurfaceList: getRoofSurfaceList(), pcsItemList: pcsItemList.map((item) => { return { itemId: item.itemId, pcsMkrCd: item.pcsMkrCd, pcsSerCd: item.pcsSerCd, } }), } setSelectedModels(pcsItemList) getPcsVoltageChk(pcsVoltageChkParams).then((res) => { setAllocationType(ALLOCATION_TYPE.PASSIVITY) setAllModuleSurfaceIsComplete(false) clearTrestle() }) } else { swalFire({ title: res.result.resultMsg, type: 'alert', confirmFn: () => { return }, }) return } }) } else { const moduleStdQty = selectedModels.reduce((acc, model) => { return acc + parseInt(model.moduleStdQty) }, 0) const moduleMaxQty = selectedModels.reduce((acc, model) => { return acc + parseInt(model.moduleMaxQty) }, 0) const target = pcsCheck.max ? moduleMaxQty : moduleStdQty const placementModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) let moduleAmount = placementModules.reduce((acc, module) => { if (moduleSelectionData.module.itemList.length === 1 || module.moduleInfo.itemId === moduleSelectionData.module.itemList[0].itemId) { return acc + 1 } else { return acc + 0.66 } }, 0) if (moduleAmount > target) { swalFire({ title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error01'), type: 'alert', }) return } setAllocationType(ALLOCATION_TYPE.PASSIVITY) clearTrestle() } } // StepUp에서 선택된 값들을 처리하는 함수 수정 const handleStepUpValuesSelected = (selectionData) => { const { gooodsNo } = selectionData setSelectedStepUpValues((prev) => ({ ...prev, [gooodsNo]: selectionData, })) } // StepUp 컴포넌트 초기화 핸들러 const handleStepUpInitialize = (getCurrentSelections) => { setGetStepUpSelections(() => getCurrentSelections) } // 회로할당(승압설정) 저장 버튼 클릭 시 const onApply = async () => { setAllModuleSurfaceIsComplete(false) setIsGlobalLoading(true) canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) .map((obj) => { obj.pcses = getStepUpListData() }) await capture(1) //회로할당 저장 시 result=null인 경우에도 회로번호 텍스트 표시 유지 처리 // 회로할당 저장 클릭 시 // 가대 및 지지금구 설치 // apply() // apply() 결과를 체크하여 null이면 함수 종료 const applyResult = apply() if (!applyResult) { setIsGlobalLoading(false) return } const result = await getEstimateData() if (result) { await capture(2) // 견적서 저장 await saveEstimate(result) } else { setIsGlobalLoading(false) } // removeNotAllocationModules() } const changeFontSize = (name, size) => { const textObjs = canvas?.getObjects().filter((obj) => obj.name === name) textObjs.forEach((obj) => { obj.set({ fontSize: size, }) }) canvas.renderAll() } // 이전 버튼 클릭 시 const onClickPrev = () => { // setAllocationType(ALLOCATION_TYPE.AUTO) swalFire({ text: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset.info'), type: 'alert', icon: 'warning', confirmFn: () => { const circuitModules = canvas.getObjects().filter((obj) => obj.name === 'module') canvas.remove(...circuitModules.map((module) => module.circuit)) circuitModules.forEach((obj) => { obj.circuit = null obj.pcsItemId = null obj.circuitNumber = null obj.pcs = null }) setSelectedModels( JSON.parse(JSON.stringify(selectedModels)).map((model) => { model.isUsed = false return model }), ) if (allocationType === ALLOCATION_TYPE.PASSIVITY) { setAllocationType(ALLOCATION_TYPE.AUTO) setTabNum(1) } else { setTabNum(1) } clearTrestle() canvas.renderAll() setModuleStatisticsData() }, }) } // 파워컨디셔너 컴포넌트 속성 const powerConditionalSelectProps = { tabNum, setTabNum, makers, setMakers, selectedMaker, setSelectedMaker, series, setSeries, models, setModels, selectedModels, setSelectedModels, managementState, getUseModuleItemList, } // 수동할당 컴포넌트 속성 const passivityProps = { tabNum, setTabNum, pcsCheck, selectedModels, setSelectedModels, getOptYn, getUseModuleItemList, getRoofSurfaceList, } // 승압설정 컴포넌트 속성 const stepUpProps = { tabNum, setTabNum, models, setModels, allocationType, circuitAllocationType, setCircuitAllocationType, selectedMaker, selectedModels, setSelectedModels, getSelectedPcsItemList, getOptYn, // 옵션 Y/N getUseModuleItemList, // 사용된 모듈아이템 List getRoofSurfaceList, // 지붕면 목록 getPcsItemList, // PCS 아이템 목록 onValuesSelected: handleStepUpValuesSelected, // 선택된 값들을 처리하는 함수 stepUpListData, setStepUpListData, seletedMainOption, setSeletedMainOption, seletedSubOption, setSeletedSubOption, getModuleList, setModuleStatisticsData, } // 승압설정 목록 조회 const getStepUpListData = () => { const pcs = [] console.log(stepUpListData) stepUpListData[0].pcsItemList.map((item, index) => { return item.serQtyList .filter((serQty) => serQty.selected && serQty.paralQty > 0) .forEach((serQty) => { pcs.push({ pcsMkrCd: item.pcsMkrCd, pcsSerCd: item.pcsSerCd, pcsItemId: item.itemId, pscOptCd: getPcsOptCd(index), paralQty: serQty.paralQty, connections: item.connList?.length ? [ { connItemId: item.connList[0].itemId, }, ] : [], }) // return { // pcsMkrCd: item.pcsMkrCd, // pcsSerCd: item.pcsSerCd, // pcsItemId: item.itemId, // pscOptCd: getPcsOptCd(index), // paralQty: serQty.paralQty, // connections: item.connList?.length // ? [ // { // connItemId: item.connList[0].itemId, // }, // ] // : [], // } }) }) return pcs } const getPcsOptCd = (index) => { console.log(selectedModels) console.log(seletedMainOption) console.log(seletedSubOption) if (selectedModels.some((model) => model.pcsSerParallelYn === 'Y')) { if (selectedModels.length > 1) { if (index === 0) { return seletedMainOption.code } else { return seletedSubOption.code } } else { return seletedMainOption.code } } else { return seletedMainOption.code } } const handleStepUp = () => { handlePassivityAllocationCkeck() // const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) // if (notAllocationModules.length > 0) { // swalFire({ // title: getMessage('not.allocation.exist.module'), // type: 'alert', // }) // return // } else { // passivityCircuitAllocationRef.current.onApply() // setTabNum(2) // } } // 닫기 버튼 클릭 시 처리하는 함수 추가 const handleClose = () => { // // 회로 번호 텍스트 제거 if ( canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) .some((surface) => !surface.isComplete) ) { canvas.remove(...canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')) canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE) .forEach((obj) => { obj.circuit = null obj.pcsItemId = null obj.circuitNumber = null }) canvas.renderAll() } closePopup(id) } const handlePassivityAllocationCkeck = () => { let pcsCount = {} let result = {} const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) if (notAllocationModules.length > 0) { swalFire({ text: getMessage('not.allocation.exist.module'), type: 'alert', icon: 'warning', }) return } canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE) .forEach((module) => { const circuitNumber = module.circuitNumber.replace(/[()]/g, '') pcsCount[circuitNumber] = (pcsCount[circuitNumber] || 0) + 1 }) for (const key in pcsCount) { const firstPart = key.split('-')[0] // '-' 기준으로 첫 번째 부분을 추출 const value = pcsCount[key] // 그룹이 없으면 초기화 if (!result[firstPart]) { result[firstPart] = { maxValue: value, count: 1 } } else { // 이미 그룹이 있으면 큰 값으로 갱신, count는 증가 result[firstPart].maxValue = Math.max(result[firstPart].maxValue, value) result[firstPart].count += 1 } } const params = { ...getOptYn(), useModuleItemList: getUseModuleItemList(), roofSurfaceList: getRoofSurfaceList(), pcsItemList: selectedModels.map((model, index) => { return { pcsMkrCd: model.pcsMkrCd, pcsSerCd: model.pcsSerCd, itemId: model.itemId, itemNm: model.itemNm, goodsNo: model.goodsNo, serQtyList: [ { serQty: result[(index + 1).toString()] ? result[(index + 1).toString()].maxValue : 0, paralQty: result[(index + 1).toString()] ? result[(index + 1).toString()].count : 0, rmdYn: 'Y', usePossYn: 'Y', roofSurfaceList: canvas .getObjects() .filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name && obj?.modules.length > 0) .map((surface) => { return { roofSurfaceId: surface.id, roofSurface: surface.direction, roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch, moduleList: surface.modules.map((module) => { return { itemId: module.moduleInfo.itemId, circuit: module.circuitNumber, pcsItemId: module.pcsItemId, } }), } }), }, ], } }), } getPcsManualConfChk(params).then((res) => { if (res?.resultCode === 'E') { swalFire({ text: res.resultMsg, type: 'alert', icon: 'warning', }) return } else { setTabNum(2) setAllModuleSurfaceIsComplete(false) } }) } return ( handleClose()} isFold={isFold} onFold={() => setIsFold(!isFold)} />
{getMessage('modal.circuit.trestle.setting.power.conditional.select')}
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && } {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( )} {tabNum === 2 && }
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
)} {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
)} {tabNum === 2 && (
{/*
)}
) }