import { GlobalDataContext } from '@/app/GlobalDataProvider' import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' import { canvasState } from '@/store/canvasAtom' import { modelState, pcsCheckState } from '@/store/circuitTrestleAtom' import { selectedModuleState } from '@/store/selectedModuleOptions' import { useContext, useEffect, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom' import { useMasterController } from '@/hooks/common/useMasterController' import { v4 as uuidv4 } from 'uuid' import { globalLocaleStore } from '@/store/localeAtom' import { POLYGON_TYPE } from '@/common/common' import { useSwal } from '@/hooks/useSwal' import { circuitNumDisplaySelector } from '@/store/settingAtom' import { fontSelector } from '@/store/fontAtom' export default function StepUp(props) { const { models, allocationType, stepUpListData, setStepUpListData, seletedOption, setSeletedOption, selectedModels, setSelectedModels, getSelectedPcsItemList, getModuleList, setModuleStatisticsData, } = props const { getMessage } = useMessage() const { swalFire } = useSwal() const globalLocale = useRecoilValue(globalLocaleStore) const [moduleTab, setModuleTab] = useState(1) const [moduleTabs, setModuleTabs] = useState({}) const [arrayLength, setArrayLength] = useState(3) //module-table-inner의 반복 개수 const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState) const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk, getPcsConnOptionItemList } = useMasterController() const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const canvas = useRecoilValue(canvasState) const selectedModules = useRecoilValue(selectedModuleState) const [optCodes, setOptCodes] = useState([]) const [selectedRows, setSelectedRows] = useState({}) const [isManualSelection, setIsManualSelection] = useState({}) // 선택된 값들을 저장할 상태 추가 const [selectedValues, setSelectedValues] = useState({}) const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector) const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText')) // useCanvasPopupStatusController(6) // const canvasPopupStatusState = useRecoilValue(canvasPopupStatusStore) // if (Object.keys(canvasPopupStatusState[6]).length !== 0) { // console.log('🚀 ~ useEffect ~ canvasPopupStatusState :', canvasPopupStatusState) // } useEffect(() => { if (allocationType === 'auto') { // 자동일 때 모듈의 회로 정보 초기화 canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE) .forEach((module) => { module.circuit = null module.circuitNumber = null module.pcsItemId = null }) canvas.renderAll() // PCS 자동 승압설정 정보 조회 fetchAutoStepUpData() } else { // PCS 수동 승압설정 정보 조회 fetchPassiStepUpData() } }, []) // PCS 자동 승압설정 정보 조회 const fetchAutoStepUpData = async () => { try { const params = { ...props.getOptYn(), // 옵션 Y/N useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록 pcsItemList: props.getSelectedPcsItemList(), // PCS 아이템 목록 } // 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회 getPcsVoltageStepUpList(params).then((res) => { if (res?.result.resultCode === 'S' && res?.data) { const dataArray = Array.isArray(res.data) ? res.data : [res.data] const stepUpListData = formatStepUpListData(dataArray) // PCS 승압설정 정보 SET setStepUpListData(stepUpListData) // PCS 옵션 조회 const formattedOptCodes = formatOptionCodes(res.data.optionList) setOptCodes(formattedOptCodes) setSeletedOption(formattedOptCodes[0]) // 캔버스에 회로 정보 적용 //stepUpListData[0].pcsItemList.forEach((pcsItem) => { stepUpListData[0].pcsItemList.forEach((pcsItem) => { const selectedSerQty = pcsItem.serQtyList.find((serQty) => serQty.selected) if (selectedSerQty) { selectedSerQty.roofSurfaceList.forEach((roofSurface) => { const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0] const moduleIds = targetSurface.modules.map((module) => module.id) // 기존 모듈 텍스트 삭제 canvas .getObjects() .filter((obj) => moduleIds.includes(obj.parentId)) .forEach((text) => canvas.remove(text)) // 새로운 모듈 회로 정보 추가 roofSurface.moduleList.forEach((module) => { const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0] 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, selectable: false, visible: isDisplayCircuitNumber, }) targetModule.circuit = moduleCircuitText targetModule.pcsItemId = module.pcsItemId targetModule.circuitNumber = module.circuit canvas.add(moduleCircuitText) }) }) } }) canvas.renderAll() setModuleStatisticsData() } else { swalFire({ text: getMessage('common.message.send.error') }) // swalFire({ // title: res.result.resultMsg, // type: 'alert', // }) } }) } catch (error) { console.error('Error fetching step up data:', error) } } // PCS 수동 승압설정 정보 조회 const fetchPassiStepUpData = async () => { try { // 1-1 2-2 // canvas // .getObjects() // .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit) // .map((module) => module.circuitNumber) // 모듈 데이터 가져오기 const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) // PCS별 회로 정보를 저장할 객체 const pcsSummary = {} // 각 모듈을 순회하며 PCS별 회로 정보 수집 modules.forEach((module) => { if (!module.circuit || !module.pcsItemId) return if (!pcsSummary[module.pcsItemId]) { pcsSummary[module.pcsItemId] = { circuits: {}, totalModules: 0, } } const circuitNumber = module.circuitNumber if (!pcsSummary[module.pcsItemId].circuits[circuitNumber]) { pcsSummary[module.pcsItemId].circuits[circuitNumber] = 0 } pcsSummary[module.pcsItemId].circuits[circuitNumber]++ pcsSummary[module.pcsItemId].totalModules++ }) const params = { useModuleItemList: props.getUseModuleItemList(), pcsItemList: getSelectedPcsItemList(), } // PCS 접속함 및 옵션 목록 조회 getPcsConnOptionItemList(params).then((res) => { if (res?.result.code === 200 && res?.data) { // PCS 아이템 리스트에 serQtyList 추가 const pcsItemListWithSerQty = res.data.pcsItemList.map((pcsItem) => { const pcsData = pcsSummary[pcsItem.itemId] || { circuits: {}, totalModules: 0 } const circuitCounts = Object.values(pcsData.circuits) return { ...pcsItem, serQtyList: [ { // 한 회로당 최대 모듈 수 serQty: circuitCounts.length > 0 ? Math.max(...circuitCounts) : 0, // 회로 개수 paralQty: Object.keys(pcsData.circuits).length || 0, rmdYn: 'Y', usePossYn: 'Y', roofSurfaceList: props.getRoofSurfaceList(), }, ], } }) // Update res.data with modified pcsItemList res.data.pcsItemList = pcsItemListWithSerQty const dataArray = Array.isArray(res.data) ? res.data : [res.data] const stepUpListData = formatStepUpListData(dataArray) // PCS 승압설정 정보 SET setStepUpListData(stepUpListData) // PCS 옵션 조회 const formattedOptCodes = formatOptionCodes(res.data.optionList) setOptCodes(formattedOptCodes) setSeletedOption(formattedOptCodes[0]) } }) } catch (error) { console.error('Error fetching step up data:', error) } } // PCS 옵션 조회 const formatOptionCodes = (optionList = []) => { return optionList?.map((opt) => ({ code: opt.pcsOptCd ? opt.pcsOptCd : '', name: opt.pcsOptNm ? opt.pcsOptNm : '', nameJp: opt.pcsOptNmJp ? opt.pcsOptNmJp : '', })) } // PCS 승압설정 정보 포맷 후 추천 값 저장 const formatStepUpListData = (dataArray = []) => { const formattedData = dataArray?.map((stepUps) => ({ ...stepUps, optionList: formatOptionList(stepUps.optionList), pcsItemList: formatPcsItemList(stepUps.pcsItemList), selectedPcsItem: formatPcsItemList(stepUps.pcsItemList), })) return formattedData } // PCS 옵션 포맷 const formatOptionList = (optionList = []) => { return optionList?.map((option) => ({ pcsOptCd: option.pcsOptCd ? option.pcsOptCd : '', pcsOptNm: option.pcsOptNm ? option.pcsOptNm : '', pcsOptNmJp: option.pcsOptNmJp ? option.pcsOptNmJp : '', })) } // PCS 아이템 포맷 const formatPcsItemList = (pcsItemList = []) => { return pcsItemList?.map((item, index) => ({ goodsNo: item.goodsNo ? item.goodsNo : '', itemId: item.itemId ? item.itemId : '', itemNm: item.itemNm ? item.itemNm : '', pcsMkrCd: item.pcsMkrCd ? item.pcsMkrCd : '', pcsSerCd: item.pcsSerCd ? item.pcsSerCd : '', uniqueIndex: `${item.itemId}_${index}`, // 고유 식별자 추가(동일한 PCS를 구분) connList: formatConnList(item.connList), serQtyList: formatSerQtyList(item.serQtyList), })) } // PCS 연결 포맷 const formatConnList = (connList = []) => { if (!connList) return [] // null인 경우 빈 배열 반환 return connList?.map((conn) => ({ connAllowCur: conn.connAllowCur ? conn.connAllowCur : 0, connMaxParalCnt: conn.connMaxParalCnt ? conn.connMaxParalCnt : 0, goodsNo: conn.goodsNo ? conn.goodsNo : '', itemId: conn.itemId ? conn.itemId : '', itemNm: conn.itemNm ? conn.itemNm : '', vstuParalCnt: conn.vstuParalCnt ? conn.vstuParalCnt : 0, })) } // PCS 시리즈 포맷 const formatSerQtyList = (serQtyList = []) => { return serQtyList?.map((qty) => ({ code: uuidv4(), serQty: qty.serQty ? qty.serQty : 0, paralQty: qty.paralQty ? qty.paralQty : 0, rmdYn: qty.rmdYn ? qty.rmdYn : 'N', usePossYn: qty.usePossYn ? qty.usePossYn : 'Y', roofSurfaceList: formatRoofSurfaceList(qty.roofSurfaceList), selected: qty.rmdYn === 'Y', })) } // PCS RoofSurface 포맷 const formatRoofSurfaceList = (roofSurfaceList = []) => { return roofSurfaceList?.map((rsf) => ({ moduleList: formatModuleList(rsf.moduleList), roofSurface: rsf.roofSurface ? rsf.roofSurface : '', roofSurfaceId: rsf.roofSurfaceId ? rsf.roofSurfaceId : '', roofSurfaceIncl: rsf.roofSurfaceIncl ? +rsf.roofSurfaceIncl : '', })) } // PCS MatModule 포맷 const formatModuleList = (moduleList = []) => { return moduleList?.map((module) => ({ circuit: module.circuit ? module.circuit : '', itemId: module.itemId ? module.itemId : '', pcsItemId: module.pcsItemId ? module.pcsItemId : '', uniqueId: module.uniqueId ? module.uniqueId : '', })) } // 각 모듈의 탭을 변경하는 함수 const handleTabChange = (goodsNo, idx, tabNumber) => { setModuleTabs((prev) => ({ ...prev, [`${goodsNo}_${idx}`]: tabNumber, })) } // 행 선택 핸들러 함수 추가 const handleRowClick = (mainIdx, subIdx) => { // 자동 승압 설정인 경우만 실행 if (allocationType !== 'auto') return let tempStepUpListData = [...stepUpListData] let selectedData = {} tempStepUpListData[0].pcsItemList[mainIdx].serQtyList.forEach((item, index) => { if (index === subIdx) { selectedData = item } item.selected = index === subIdx }) // 선택된 행 정보 저장 setStepUpListData(tempStepUpListData) // console.log('🚀 ~ handleRowClick ~ tempStepUpListData:', tempStepUpListData) // console.log('🚀 ~ handleRowClick ~ selectedData:', selectedData) // PCS 2개 이상 또는 첫번째 PCS 선택 시에만 실행 if (stepUpListData[0].pcsItemList.length > 1 && mainIdx === 0) { // 파워컨디셔너 옵션 조회 요청 파라미터 const params = { ...props.getOptYn(), // 옵션 Y/N useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록 pcsItemList: props.getSelectedPcsItemList().map((pcsItem, index) => { // PCS 아이템 목록 // tempStepUpListData에서 해당 PCS 아이템 찾기 // uniqueIndex를 사용하여 매칭 const matchingPcsItem = tempStepUpListData[0].pcsItemList.find((item) => item.uniqueIndex === `${pcsItem.itemId}_${index}`) // 선택된 serQty 찾기 const selectedSerQty = matchingPcsItem?.serQtyList.find((serQty) => serQty.selected)?.serQty || 0 return { ...pcsItem, applySerQty: selectedSerQty, } }), } // PCS가 1개 이고 2번째 또는 3번째 PCS serQty가 0인 경우는 추천 API 실행하지 않음 if (params.pcsItemList.length !== 1 && (params.pcsItemList[1]?.applySerQty !== 0 || params.pcsItemList[2]?.applySerQty) !== 0) { // PCS 승압설정 정보 조회 //const res = await getPcsVoltageStepUpList(params) //getPcsManualConfChk(params).then((res) => { getPcsVoltageStepUpList(params).then((res) => { if (res?.result.resultCode === 'S' && res?.data) { const dataArray = Array.isArray(res.data) ? res.data : [res.data] const stepUpListData = formatStepUpListData(dataArray) // PCS 승압설정 정보 SET setStepUpListData(stepUpListData) // PCS 옵션 조회 const formattedOptCodes = formatOptionCodes(res.data.optionList) setOptCodes(formattedOptCodes) setSeletedOption(formattedOptCodes[0]) } else { swalFire({ text: getMessage('common.message.send.error') }) // swalFire({ // title: res.result.resultMsg, // type: 'alert', // }) } }) } } canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE) .forEach((module) => { module.circuit = null module.circuitNumber = null module.pcsItemId = null }) selectedData.roofSurfaceList.forEach((roofSurface) => { const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0] const moduleIds = targetSurface.modules.map((module) => { return module.id }) // 모듈 목록 삭제 canvas .getObjects() .filter((obj) => moduleIds.includes(obj.parentId)) .map((text) => { canvas.remove(text) }) // 모듈 목록 추가 canvas.renderAll() roofSurface.moduleList.forEach((module) => { const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0] if (module.circuit === '') return 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) }) }) canvas.renderAll() setModuleStatisticsData() } // 현재 선택된 값들을 가져오는 함수 추가 const getCurrentSelections = () => { const selectedValues = stepUpListData[0].pcsItemList.forEach((item) => { item.serQtyList.filter((serQty) => serQty.selected) return item.serQtyList.map((serQty) => { return { pcsMkrCd: serQty.pcsMkrCd, pcsSerCd: serQty.pcsSerCd, pcsItemId: serQty.itemId, pcsOptCd: seletedOption, paralQty: serQty.paralQty, connections: { connItemId: item.connList[0].itemId, }, } }) }) return selectedValues } // props로 getCurrentSelections 함수 전달 useEffect(() => { if (props.onInitialize) { props.onInitialize(getCurrentSelections) } }, []) // stepUpListData가 변경될 때마다 업데이트하는 useEffect useEffect(() => { if (props.onInitialize) { // onInitialize를 props에서 가져옴 props.onInitialize(() => ({ ...getCurrentSelections(), stepUpListData, // stepUpListData를 포함하여 반환 })) } }, [stepUpListData]) return ( <>
{getMessage('modal.circuit.trestle.setting.step.up.allocation.select.monitor')} {optCodes.length > 0 && (
{/* */} { return { ...roof, name: globalLocale === 'ko' ? roof.name : roof.nameJp } })} title={globalLocale === 'ko' ? optCodes[0].name : optCodes[0].nameJp} value={seletedOption} sourceKey="code" targetKey="code" showKey="name" onChange={(e) => setSeletedOption(e)} />
)}
{/* 3개일때 className = by-max */} {stepUpListData.map((stepUp, index) => (
{stepUp?.pcsItemList.map((pcsItem, idx) => (
{stepUp.pcsItemList[idx].goodsNo}
{pcsItem.serQtyList.map((item, serQtyIdx) => { return ( handleRowClick(idx, serQtyIdx)} style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }} > ) })}
{getMessage('modal.circuit.trestle.setting.step.up.allocation.serial.amount')} {getMessage('modal.circuit.trestle.setting.step.up.allocation.total.amount')}
{item.serQty} {item.paralQty}
{(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 1 && (
{getMessage('modal.circuit.trestle.setting.power.conditional.select.name')} {getMessage('modal.circuit.trestle.setting.power.conditional.select.circuit.amount')} {getMessage('modal.circuit.trestle.setting.step.up.allocation.circuit.amount')}
{stepUp.pcsItemList[idx].connList?.[0]?.goodsNo ? stepUp.pcsItemList[idx].connList?.[0]?.goodsNo : '-'} {stepUp.pcsItemList[idx].connList?.[0]?.connMaxParalCnt ? (stepUp.pcsItemList[idx].connList?.[0]?.connMaxParalCnt ?? '-') : '-'} {stepUp.pcsItemList[idx].connList?.[0]?.vstuParalCnt ? stepUp.pcsItemList[idx].connList?.[0]?.vstuParalCnt : '-'}
)} {(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 2 && (
{/* */}
名称 昇圧回路数{getMessage('modal.circuit.trestle.setting.power.conditional.select.name')} {getMessage('modal.circuit.trestle.setting.step.up.allocation.circuit.amount')}
- -
)}
))}
))}
) }