diff --git a/src/common/common.js b/src/common/common.js index 59e8be6c..92ddbdca 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -174,6 +174,9 @@ export const SAVE_KEY = [ 'turfPoints', 'tempIndex', 'surfaceId', + 'moduleRowsTotCnt', + 'seq', + 'smartRackId', ] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype] diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 3200ac05..89560025 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -15,6 +15,7 @@ import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { addedRoofsState } from '@/store/settingAtom' import { isObjectNotEmpty } from '@/util/common-utils' import Swal from 'sweetalert2' +import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const { getMessage } = useMessage() diff --git a/src/components/floor-plan/modal/basic/step/Module.jsx b/src/components/floor-plan/modal/basic/step/Module.jsx index 789a1a0c..eb4f0177 100644 --- a/src/components/floor-plan/modal/basic/step/Module.jsx +++ b/src/components/floor-plan/modal/basic/step/Module.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState, useReducer } from 'react' +import { useEffect, useState, useReducer, useRef } from 'react' import { useRecoilValue, useRecoilState } from 'recoil' import { addedRoofsState } from '@/store/settingAtom' import { currentCanvasPlanState } from '@/store/canvasAtom' @@ -41,6 +41,7 @@ export default function Module({ setTabNum }) { const [debouncedVerticalSnowCover] = useDebounceValue(inputVerticalSnowCover, 500) const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 + const [tempModuleSelectionData, setTempModuleSelectionData] = useReducer((prevState, nextState) => { return { ...prevState, ...nextState } }, moduleSelectionData) @@ -55,15 +56,13 @@ export default function Module({ setTabNum }) { }, [installHeight, verticalSnowCover]) useEffect(() => { - if (tempModuleSelectionData) { - setModuleSelectionData(tempModuleSelectionData) - - if ( - tempModuleSelectionData.common.moduleItemId && - isObjectNotEmpty(tempModuleSelectionData.module) && - tempModuleSelectionData.roofConstructions.length > 0 - ) { - moduleSelectedDataTrigger(tempModuleSelectionData) + if (tempModuleSelectionData.roofConstructions.length > 0) { + if (tempModuleSelectionData.common.moduleItemId && isObjectNotEmpty(tempModuleSelectionData.module)) { + //저장된 temp데이터가 지붕재(addedRoofs) 개수와 같으면 모듈 선택 저장 + if (tempModuleSelectionData.roofConstructions.length === addedRoofs.length) { + setModuleSelectionData(tempModuleSelectionData) + moduleSelectedDataTrigger(tempModuleSelectionData) + } } } }, [tempModuleSelectionData]) @@ -134,7 +133,8 @@ export default function Module({ setTabNum }) { - {selectedModules.itemList && + {selectedModules && + selectedModules.itemList && selectedModules.itemList.map((row, index) => ( @@ -250,10 +250,10 @@ export default function Module({ setTabNum }) {
diff --git a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx index 22554a11..ad48695e 100644 --- a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx +++ b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx @@ -1,361 +1,42 @@ -import { useEffect, useState, useRef, useReducer } from 'react' -import { useRecoilValue, useRecoilState } from 'recoil' -import { currentCanvasPlanState, pitchTextSelector } from '@/store/canvasAtom' +import { useState } from 'react' import { useMessage } from '@/hooks/useMessage' -import { useMasterController } from '@/hooks/common/useMasterController' -import { useCommonCode } from '@/hooks/common/useCommonCode' -import { moduleSelectionDataState, moduleSelectionInitParamsState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' import QSelectBox from '@/components/common/select/QSelectBox' -import { addedRoofsState } from '@/store/settingAtom' +import { useModuleTabContents } from '@/hooks/module/useModuleTabContents' -export default function ModuleTabContents({ addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) { +export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) { const { getMessage } = useMessage() const [roofMaterial, setRoofMaterial] = useState(addRoof) //지붕재` - const addRoofsArray = useRecoilValue(addedRoofsState) - - const globalPitchText = useRecoilValue(pitchTextSelector) //피치 텍스트 - const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) - - const { findCommonCode } = useCommonCode() - const [raftCodes, setRaftCodes] = useState([]) //가대 목록 - - const [trestleList, setTrestleList] = useState([]) - const [constMthdList, setConstMthdList] = useState([]) - const [roofBaseList, setRoofBaseList] = useState([]) - const [constructionList, setConstructionList] = useState([{}]) //공법 목록 - - const [selectedRaftBase, setSelectedRaftBase] = useState({}) //선택된 가대 - const [selectedTrestle, setSelectedTrestle] = useState({}) //선택된 가대 - const [selectedConstMthd, setSelectedConstMthd] = useState({}) //선택된 공법 - const [selectedRoofBase, setSelectedRoofBase] = useState({}) //선택된 지붕밑바탕 - const [selectedConstruction, setSelectedConstruction] = useState({}) //선택된 공법 - const [constructionListParams, setConstructionListParams] = useState({}) - - const [trestleParams, setTrestleParams] = useState({}) //서까래, 가대메이커,공법,지붕밑바탕 관련 api호출 파라메터 - const [constructionParams, setConstructionParams] = useState({}) //공법 관련 api호출 파라메터 - const [roofBaseParams, setRoofBaseParams] = useState({}) //지붕밑바탕 관련 api호출 파라메터 - - const moduleSelectionInitParams = useRecoilValue(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등 - - const { getTrestleList, getConstructionList } = useMasterController() - - const constructionRef = useRef([]) - const [cvrYn, setCvrYn] = useState('N') - const [snowGdPossYn, setSnowGdPossYn] = useState('N') - - const [cvrChecked, setCvrChecked] = useState(false) - const [snowGdChecked, setSnowGdChecked] = useState(false) - - const [isExistData, setIsExistData] = useState(false) - - const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈 - const [moduleConstructionSelectionData, setModuleConstructionSelectionData] = useState() - - const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 - - const [hajebichi, setHajebichi] = useState(0) - const [lengthBase, setLengthBase] = useState(0) - - const hajebichiRef = useRef() - const lengthRef = useRef() - - useEffect(() => { - setHajebichi(addRoof.hajebichi) - setLengthBase(addRoof.lenBase) - }, []) - - //높이를 변경하면 addRoofs에 적용 - useEffect(() => { - //가대 조회 api 파라메터 - setTrestleParams({ ...trestleParams, workingWidth: lengthBase }) - - const copyAddRoof = { ...addRoof } - copyAddRoof.length = Number(lengthBase) - copyAddRoof.lenBase = lengthBase - const index = addRoof.index - const newArray = [...addRoofsArray.slice(0, index), copyAddRoof, ...addRoofsArray.slice(index + 1)] - setAddedRoofs(newArray) - }, [lengthBase]) - - //망둥어 피치를 변경하면 addRoof 변경 - useEffect(() => { - const copyAddRoof = { ...addRoof } - copyAddRoof.hajebichi = Number(hajebichi) - copyAddRoof.roofPchBase = hajebichi - const index = addRoof.index - const newArray = [...addRoofsArray.slice(0, index), copyAddRoof, ...addRoofsArray.slice(index + 1)] - setAddedRoofs(newArray) - }, [hajebichi]) - - useEffect(() => { - if (moduleSelectionData.roofConstructions.length > 0) { - setModuleConstructionSelectionData(moduleSelectionData.roofConstructions[roofTab]) - } - }, [moduleSelectionData]) - - //서까래간격 변경 - const handleChangeRaftBase = (option) => { - setSelectedRaftBase(option) - setTrestleParams({ ...trestleParams, raftBaseCd: option.clCode }) //가대메이커 - setConstMthdList([]) //공법 초기화 - setRoofBaseList([]) //지붕밑바탕 초기화 - setConstructionList([]) //공법 초기화 - } - - //가대메이커 변경 - const handleChangeTrestle = (option) => { - setSelectedTrestle(option) //선택값 저장 - setConstructionParams({ ...trestleParams, trestleMkrCd: option.trestleMkrCd, constMthdCd: '', roofBaseCd: '' }) - setConstMthdList([]) //공법 초기화 - setRoofBaseList([]) //지붕밑바탕 초기화 - setConstructionList([]) //공법 초기화 - } - - //공법 변경 - const handleChangeConstMthd = (option) => { - setSelectedConstMthd(option) //선택된값 저장 - setRoofBaseParams({ - ...trestleParams, - trestleMkrCd: selectedTrestle.trestleMkrCd, - constMthdCd: option.constMthdCd, - roofBaseCd: '', - roofPitch: hajebichiRef.current ? hajebichiRef.current.value : '', - }) - setRoofBaseList([]) //지붕밑바탕 초기화 - setConstructionList([]) //공법 초기화 - } - - //지붕밑바탕변경 - const handleChangeRoofBase = (option) => { - // if (option) { - setConstructionListParams({ - ...moduleSelectionInitParams, - ...roofBaseParams, - roofBaseCd: option.roofBaseCd, - inclCd: addRoof.pitch, - }) - setSelectedRoofBase(option) - } - - const handleConstruction = (index) => { - if (index > -1) { - const isPossibleIndex = constructionRef.current - .map((el, i) => (el.classList.contains('white') || el.classList.contains('blue') ? i : -1)) - .filter((index) => index !== -1) - - isPossibleIndex.forEach((index) => { - if (constructionRef.current[index].classList.contains('blue')) { - constructionRef.current[index].classList.remove('blue') - constructionRef.current[index].classList.add('white') - } - }) - constructionRef.current[index].classList.remove('white') - constructionRef.current[index].classList.add('blue') - - const selectedConstruction = constructionList[index] - selectedConstruction.roofIndex = roofTab - selectedConstruction.setupCover = false //처마력바 설치 여부 - selectedConstruction.setupSnowCover = false //눈막이금구 설치 여부 - selectedConstruction.selectedIndex = index - - //기존에 선택된 데이터가 있으면 체크한다 - if (moduleConstructionSelectionData && moduleConstructionSelectionData.construction) { - selectedConstruction.setupCover = moduleConstructionSelectionData.construction.setupCover - selectedConstruction.setupSnowCover = moduleConstructionSelectionData.construction.setupSnowCover - setCvrChecked(selectedConstruction.setupCover) - setSnowGdChecked(selectedConstruction.setupSnowCover) - } - - setCvrYn(selectedConstruction.cvrYn) - setSnowGdPossYn(selectedConstruction.snowGdPossYn) - setSelectedConstruction(selectedConstruction) - } else { - constructionRef.current.forEach((ref) => { - ref.classList.remove('blue') - }) - } - } - - const handleCvrChecked = () => { - setCvrChecked(!cvrChecked) - setSelectedConstruction({ ...selectedConstruction, setupCover: !cvrChecked }) - } - - const handleSnowGdChecked = () => { - setSnowGdChecked(!snowGdChecked) - setSelectedConstruction({ ...selectedConstruction, setupSnowCover: !snowGdChecked }) - } - - const getModuleOptionsListData = async (params) => { - const optionsList = await getTrestleList(params) - - if (optionsList.data.length > 0) { - if (optionsList.data[0].trestleMkrCd && optionsList.data[0].constMthdCd === null) { - setTrestleList(optionsList.data) - if (isExistData) { - setSelectedTrestle({ ...moduleConstructionSelectionData?.trestle }) - } else { - setConstMthdList([]) - setRoofBaseList([]) - } - } - - if (optionsList.data[0].trestleMkrCd && optionsList.data[0].constMthdCd && optionsList.data[0].roofBaseCd === null) { - setConstMthdList(optionsList.data) - if (isExistData) { - setSelectedConstMthd({ ...moduleConstructionSelectionData?.trestle }) - } else { - setRoofBaseList([]) - } - } - - if (optionsList.data[0].trestleMkrCd && optionsList.data[0].constMthdCd && optionsList.data[0].roofBaseCd) { - setRoofBaseList(optionsList.data) - if (isExistData) { - setSelectedRoofBase({ ...moduleConstructionSelectionData?.trestle }) - } - } - } - } - - const getConstructionListData = async (params) => { - if (params.trestleMkrCd && params.constMthdCd && params.roofBaseCd) { - const optionsList = await getConstructionList(params) - setConstructionList(optionsList.data) - } - } - - useEffect(() => { - if (isObjectNotEmpty(selectedRoofBase) && isObjectNotEmpty(selectedConstruction)) { - const newRoofConstructions = { - roofIndex: roofTab, - addRoof: addRoof, - trestle: selectedRoofBase, - construction: selectedConstruction, - } - - const index = tempModuleSelectionData.roofConstructions.findIndex((obj) => obj.roofIndex === roofTab) - - if (index > -1) { - const newArray = [ - ...tempModuleSelectionData.roofConstructions.slice(0, index), - newRoofConstructions, - ...tempModuleSelectionData.roofConstructions.slice(index + 1), - ] - setTempModuleSelectionData({ roofConstructions: newArray }) - } else { - setTempModuleSelectionData({ roofConstructions: [...tempModuleSelectionData.roofConstructions, { ...newRoofConstructions }] }) - } - } - }, [selectedConstruction]) - - useEffect(() => { - if (isExistData) { - setConstructionListParams({ - ...moduleSelectionInitParams, - ...roofBaseParams, - roofBaseCd: selectedRoofBase.roofBaseCd, - inclCd: addRoof.pitch, - }) - } - }, [selectedRoofBase]) - - useEffect(() => { - console.log('moduleConstructionSelectionData', moduleConstructionSelectionData) - - if ( - isExistData && - constructionList.length > 0 && - isObjectNotEmpty(moduleConstructionSelectionData?.construction) && - moduleConstructionSelectionData?.construction.hasOwnProperty('constPossYn') ///키가 있으면 - ) { - const selectedIndex = moduleConstructionSelectionData.construction.selectedIndex - const construction = constructionList[selectedIndex] - if (construction.constPossYn === 'Y') { - handleConstruction(selectedIndex) - } - } - }, [constructionList]) - - useEffect(() => { - if (isObjectNotEmpty(moduleSelectionData) && isObjectNotEmpty(moduleSelectionData.module)) { - setSelectedModules(moduleSelectionData.module) - } - }, [moduleSelectionData]) - - useEffect(() => { - // 202600 경사도 - const raftCodeList = findCommonCode('203800') - //서까래 코드 - raftCodeList.forEach((obj) => { - obj.name = obj.clCodeNm - obj.id = obj.clCode - }) - setRaftCodes(raftCodeList) - }, []) - - useEffect(() => { - //물건 상세의 데이터를 가지고 초기화 데이터를 만든다 - if ( - moduleSelectionInitParams.illuminationTp && - moduleSelectionInitParams.instHt && - moduleSelectionInitParams.stdSnowLd && - moduleSelectionInitParams.stdWindSpeed - ) { - const isModuleLoaded = moduleSelectionInitParams.hasOwnProperty('moduleTpCd') //모듈컬럼이 있으면 모듈을 변경했다는 내용 - if (isModuleLoaded) { - setTrestleParams({ - moduleTpCd: moduleSelectionInitParams.moduleTpCd, - roofMatlCd: addRoof.roofMatlCd, - raftBaseCd: addRoof.raftBaseCd, - workingWidth: lengthBase, - }) - setConstructionList([]) - - if (isObjectNotEmpty(moduleConstructionSelectionData)) { - //기존에 데이터가 있으면 파라메터를 넣는다 - setConstructionParams({ ...moduleConstructionSelectionData.trestle, constMthdCd: '', roofBaseCd: '' }) - setRoofBaseParams({ ...moduleConstructionSelectionData.trestle, roofBaseCd: '' }) - - setIsExistData(true) - } - } - } - - setTempModuleSelectionData({ common: moduleSelectionInitParams, module: selectedModules }) - }, [moduleSelectionInitParams]) - - useEffect(() => { - if (isObjectNotEmpty(trestleParams)) { - getModuleOptionsListData(trestleParams) - } - }, [trestleParams]) - - useEffect(() => { - if (isObjectNotEmpty(constructionParams)) { - getModuleOptionsListData(constructionParams) - } - }, [constructionParams]) - - useEffect(() => { - if (isObjectNotEmpty(roofBaseParams)) { - getModuleOptionsListData(roofBaseParams) - } - }, [roofBaseParams]) - - useEffect(() => { - if (isObjectNotEmpty(constructionListParams)) { - getConstructionListData(constructionListParams) - } - }, [constructionListParams]) - - // useEffect(() => { - // if (isObjectNotEmpty(tempModuleSelectionData)) { - // setModuleSelectionData(tempModuleSelectionData) - // } - // }, [tempModuleSelectionData]) + const { + raftCodes, + trestleList, + constMthdList, + roofBaseList, + constructionList, + globalPitchText, + selectedTrestle, + selectedConstMthd, + selectedRoofBase, + constructionRef, + cvrYn, + cvrChecked, + snowGdPossYn, + snowGdChecked, + lengthBase, + hajebichi, + lengthRef, + hajebichiRef, + setLengthBase, + setHajebichi, + handleChangeRaftBase, + handleChangeTrestle, + handleChangeConstMthd, + handleChangeRoofBase, + handleConstruction, + handleCvrChecked, + handleSnowGdChecked, + } = useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) return ( <> @@ -526,22 +207,22 @@ export default function ModuleTabContents({ addRoof, setAddedRoofs, roofTab, tem
- +
- +
diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 972229a7..4938b1e9 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -8,7 +8,7 @@ import { useModulePlace } from '@/hooks/module/useModulePlace' const Placement = forwardRef((props, refs) => { const { getMessage } = useMessage() - const [isChidori, setIsChidori] = useState('false') + const [isChidori, setIsChidori] = useState(false) const [isChidoriNotAble, setIsChidoriNotAble] = useState(false) const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 3768fec0..b4d13d20 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -18,6 +18,9 @@ import { canvasState } from '@/store/canvasAtom' import { useTrestle } from '@/hooks/module/useTrestle' import { selectedModuleState } from '@/store/selectedModuleOptions' +import { v4 as uuidv4 } from 'uuid' + +import { stepUpListDataState } from '@/store/circuitTrestleAtom' const ALLOCATION_TYPE = { AUTO: 'auto', @@ -42,7 +45,13 @@ export default function CircuitTrestleSetting({ id }) { const [circuitAllocationType, setCircuitAllocationType] = useState(1) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const selectedModules = useRecoilValue(selectedModuleState) - const { getPcsAutoRecommendList } = useMasterController() + const { getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController() + + // 회로할당(승합설정)에서 선택된 값들을 저장할 상태 추가 + const [selectedStepUpValues, setSelectedStepUpValues] = useState({}) + const [getStepUpSelections, setGetStepUpSelections] = useState(null) + + const [stepUpListData, setStepUpListData] = useRecoilState(stepUpListDataState) useEffect(() => { if (!managementState) { @@ -50,6 +59,18 @@ export default function CircuitTrestleSetting({ id }) { } }, []) + useEffect(() => { + if (allocationType === ALLOCATION_TYPE.PASSIVITY && tabNum === 2) { + const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) + canvas.remove(...notAllocationModules) + canvas.renderAll() + } + }, [tabNum]) + + useEffect(() => { + console.log('stepUpListData >>> ', stepUpListData) + }, [stepUpListData]) + const onAutoRecommend = () => { if (series.filter((s) => s.selected).length === 0) { swalFire({ @@ -66,17 +87,48 @@ export default function CircuitTrestleSetting({ id }) { pcsItemList: getPcsItemList(), } - getPcsAutoRecommendList(params).then((res) => { - if (res.data?.pcsItemList) { - setModels(res.data.pcsItemList) + if (selectedModels.length === 0) { + getPcsAutoRecommendList(params).then((res) => { + if (res.data?.pcsItemList) { + const itemList = models.filter((model) => { + return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId) + }) + const selectedModels = itemList.map((model) => { + return { + ...model, + id: uuidv4(), + } + }) + const pcsVoltageChkParams = { + ...getOptYn(), + useModuleItemList: getUseModuleItemList(), + roofSurfaceList: getRoofSurfaceList(), + pcsItemList: getPcsItemList(), + } + setSelectedModels(selectedModels) + getPcsVoltageChk(pcsVoltageChkParams).then((res) => { + setTabNum(2) + }) + } else { + // 데이터가 없는 경우 오류 메시지 확인 필요 + if (res.result.resultCode === 'E') { + swalFire({ + title: res.result.resultMsg, + type: 'alert', + }) + } else { + swalFire({ + title: '파워컨디셔너를 추가해 주세요.', + type: 'alert', + }) + } + } + }) + } else { + getPcsVoltageChk(params).then((res) => { setTabNum(2) - } else { - swalFire({ - title: '파워컨디셔너를 추가해 주세요.', - type: 'alert', - }) - } - }) + }) + } } const getOptYn = () => { @@ -97,45 +149,11 @@ export default function CircuitTrestleSetting({ id }) { }) } - const getSelectModelList = () => { - return selectedModels.map((model) => { - return { - pcsMkrCd: model.pcsMkrCd, - pcsSerCd: model.pcsSerCd, - itemId: model.itemId, - itemNm: model.itemNm, - goodsNo: model.goodsNo, - serQtyList: [ - { - serQty: 0, - paralQty: 0, - rmdYn: 'Y', - usePossYn: 'Y', - roofSurfaceList: [ - { - roofSurfaceId: '', - roofSurface: '', - roofSurfaceIncl: '', - moduleList: [ - { - itemId: '', - circuit: '', - pcsItemId: '', - }, - ], - }, - ], - }, - ], - } - }) - } - const getUseModuleItemList = () => { return selectedModules.itemList.map((m) => { return { itemId: m.itemId, - //mixMatlNo: m.mixMatlNo, + mixMatlNo: m.mixMatlNo, } }) } @@ -145,6 +163,7 @@ export default function CircuitTrestleSetting({ id }) { .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) .map((obj) => { + getModuleList(obj) return { roofSurfaceId: obj.id, roofSurface: canvas @@ -152,15 +171,90 @@ export default function CircuitTrestleSetting({ id }) { .filter((o) => o.id === obj.parentId)[0] .directionText.replace(/[0-9]/g, ''), roofSurfaceIncl: canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch, - moduleList: obj.modules.map((module) => { + moduleList: getModuleList(obj).map((module) => { return { itemId: module.moduleInfo.itemId, + circuit: module.circuitNumber ? module.circuitNumber : null, + pcsItemId: module.circuit ? module.circuit?.pcsItemId : null, } }), } }) } + const getModuleList = (surface) => { + let moduleList = [] + let [xObj, yObj] = [{}, {}] + let [xPoints, yPoints] = [[], []] + surface.modules.forEach((module) => { + if (!xObj[module.left]) { + xObj[module.left] = module.left + xPoints.push(module.left) + } + if (!yObj[module.top]) { + yObj[module.top] = module.top + yPoints.push(module.top) + } + }) + switch (surface.direction) { + case 'south': + xPoints.sort((a, b) => a - b) + yPoints.sort((a, b) => b - a) + yPoints.forEach((y, index) => { + let temp = surface.modules.filter((m) => m.top === y) + if (index % 2 === 0) { + temp.sort((a, b) => a.left - b.left) + } else { + temp.sort((a, b) => b.left - a.left) + } + moduleList = [...moduleList, ...temp] + }) + break + case 'north': + xPoints.sort((a, b) => b - a) + yPoints.sort((a, b) => a - b) + yPoints.forEach((y, index) => { + let temp = surface.modules.filter((m) => m.top === y) + if (index % 2 === 0) { + temp.sort((a, b) => b.left - a.left) + } else { + temp.sort((a, b) => a.left - b.left) + } + moduleList = [...moduleList, ...temp] + }) + break + case 'west': + xPoints.sort((a, b) => a - b) + yPoints.sort((a, b) => a - b) + xPoints.forEach((x, index) => { + let temp = surface.modules.filter((m) => m.left === x) + if (index % 2 === 0) { + temp.sort((a, b) => a.top - b.top) + } else { + temp.sort((a, b) => b.top - a.top) + } + moduleList = [...moduleList, ...temp] + }) + break + case 'east': + xPoints.sort((a, b) => b - a) + yPoints.sort((a, b) => b - a) + xPoints.forEach((x, index) => { + let temp = surface.modules.filter((m) => m.left === x) + if (index % 2 === 0) { + temp.sort((a, b) => b.top - a.top) + } else { + temp.sort((a, b) => a.top - b.top) + } + moduleList = [...moduleList, ...temp] + }) + break + default: + return [] + } + return moduleList + } + const onAutoAllocation = () => { let moduleStdQty = 0 let moduleMaxQty = 0 @@ -176,28 +270,56 @@ export default function CircuitTrestleSetting({ id }) { return acc + parseInt(model.moduleMaxQty) }, 0) } - const target = pcsCheck.max ? moduleMaxQty : moduleStdQty - const placementModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) + // 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 - } + // if (placementModules.length > target) { + // swalFire({ + // title: '배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.', + // type: 'alert', + // }) + // return + // } // setAllocationType(ALLOCATION_TYPE.AUTO) - setTabNum(2) + // setTabNum(2) } const onPassivityAllocation = () => { if (selectedModels.length === 0) { - swalFire({ - title: '파워 컨디셔너를 추가해 주세요.', - type: 'alert', + const params = { + ...getOptYn(), + useModuleItemList: getUseModuleItemList(), + roofSurfaceList: getRoofSurfaceList(), + pcsItemList: getPcsItemList(), + } + + getPcsAutoRecommendList(params).then((res) => { + if (res.data?.pcsItemList) { + const itemList = models.filter((model) => { + return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId) + }) + const selectedModels = itemList.map((model) => { + return { + ...model, + id: uuidv4(), + } + }) + const PcsVoltageChkParams = { + ...getOptYn(), + useModuleItemList: getUseModuleItemList(), + roofSurfaceList: getRoofSurfaceList(), + pcsItemList: getPcsItemList(), + } + setSelectedModels(selectedModels) + getPcsVoltageChk(PcsVoltageChkParams).then((res) => {}) + } else { + swalFire({ + title: '파워컨디셔너를 추가해 주세요.', + type: 'alert', + }) + } }) - return } else if (pcsCheck.max) { const moduleStdQty = selectedModels.reduce((acc, model) => { return acc + parseInt(model.moduleStdQty) @@ -221,6 +343,96 @@ export default function CircuitTrestleSetting({ id }) { setAllocationType(ALLOCATION_TYPE.PASSIVITY) } + // StepUp에서 선택된 값들을 처리하는 함수 수정 + const handleStepUpValuesSelected = (selectionData) => { + const { gooodsNo } = selectionData + + setSelectedStepUpValues((prev) => ({ + ...prev, + [gooodsNo]: selectionData, + })) + } + + // StepUp 컴포넌트 초기화 핸들러 + const handleStepUpInitialize = (getCurrentSelections) => { + setGetStepUpSelections(() => getCurrentSelections) + } + + // apply 함수 수정 + const onApply = () => { + // 현재 선택된 값들 가져오기 + const currentSelections = getStepUpSelections ? getStepUpSelections() : {} + + console.log('currentSelections >>> ', currentSelections) + + // 실제 선택된 값이 있는지 더 정확하게 확인 + const hasSelections = Object.values(currentSelections).some((stepUpConfig) => Object.values(stepUpConfig).length > 0) + + console.log('hasSelections >>> ', hasSelections) + + if (!hasSelections) { + swalFire({ + title: '승압 설정값을 선택해주세요.1', + type: 'alert', + }) + return + } + + // 선택된 값들 로그 + console.log('Applying StepUp configurations:', currentSelections) + + // StepUp 컴포넌트로부터 stepUpListData 받아오기 + //const stepUpData = getStepUpSelections().stepUpListData + //console.log('stepUpData >>> ', stepUpData) + // stepUpListData를 Recoil state에 저장 + // setStepUpListData(stepUpData) + + // 선택된 값들을 배열로 변환하여 처리 + const configurations = Object.values(currentSelections) + .map((stepUpConfig) => { + const firstConfig = Object.values(stepUpConfig)[0] // 첫 번째 설정만 사용 + return { + pcsInfo: firstConfig.pcsInfo, + allocation: firstConfig.allocation, + } + }) + .filter((config) => config.pcsInfo && config.allocation) // 유효한 설정만 필터링 + + console.log('Processed configurations:', configurations) + + // stepUpListData를 Recoil state에 저장 + setStepUpListData(configurations) + + // 기존 apply 로직 실행 전에 필요한 데이터가 모두 있는지 확인 + if (configurations.length > 0) { + apply() + } else { + swalFire({ + title: '승압 설정값을 선택해주세요.2', + type: 'alert', + }) + } + } + + const onClickPrev = () => { + setAllocationType(ALLOCATION_TYPE.AUTO) + swalFire({ + text: '할당한 회로 번호가 초기화됩니다.', + type: 'alert', + icon: 'warning', + confirmFn: () => { + const circuitModules = canvas + .getObjects() + .filter((obj) => obj.name === 'module' && selectedModels.map((model) => model.id).includes(obj.circuit?.circuitInfo?.id)) + canvas.remove(...circuitModules.map((module) => module.circuit)) + circuitModules.forEach((obj) => { + obj.circuit = null + obj.pcsItemId = null + }) + }, + }) + } + const powerConditionalSelectProps = { tabNum, setTabNum, @@ -243,11 +455,9 @@ export default function CircuitTrestleSetting({ id }) { pcsCheck, selectedModels, setSelectedModels, - getApiProps, - getSelectedModuleList, - getSelectModelList, + getOptYn, + getUseModuleItemList, getRoofSurfaceList, - getModelList, } const stepUpProps = { @@ -261,6 +471,7 @@ export default function CircuitTrestleSetting({ id }) { getUseModuleItemList, // 사용된 모듈아이템 List getRoofSurfaceList, // 지붕면 목록 getPcsItemList, // PCS 아이템 목록 + onValuesSelected: handleStepUpValuesSelected, // 선택된 값들을 처리하는 함수 } return ( @@ -282,7 +493,7 @@ export default function CircuitTrestleSetting({ id }) { {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && } {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && } - {tabNum === 2 && } + {tabNum === 2 && } {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
-
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx index 3c581e6f..407c5e34 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx @@ -64,6 +64,7 @@ export default function PowerConditionalSelect(props) { useEffect(() => { if (makers.length === 0) { getPcsMakerList().then((res) => { + console.log('getPcsMakerList', res.data) setMakers(res.data) }) } @@ -90,6 +91,7 @@ export default function PowerConditionalSelect(props) { } const onCheckSeries = (data) => { + console.log('data', data) const copySeries = series.map((s) => { return { ...s, @@ -97,12 +99,19 @@ export default function PowerConditionalSelect(props) { } }) setSeries(copySeries) + console.log('copySeries', copySeries) handleSetmodels(copySeries.filter((s) => s.selected)) } - const handleSetmodels = (series) => { - const pcsMkrCd = series[0]?.pcsMkrCd - const pcsSerList = series.map((series) => { + const handleSetmodels = (selectedSeries) => { + console.log('series', selectedSeries) + if (selectedSeries.length === 0) { + setModels([]) + setSelectedModels([]) + return + } + const pcsMkrCd = selectedSeries[0]?.pcsMkrCd + const pcsSerList = selectedSeries.map((series) => { return { pcsSerCd: series.pcsSerCd } }) const moduleItemList = selectedModules.itemList?.map((module) => { @@ -123,11 +132,10 @@ export default function PowerConditionalSelect(props) { } }), ) - return + } else { + setModels([]) + setSelectedModels([]) } - - setModels([]) - setSelectedModels([]) }) } @@ -146,15 +154,16 @@ export default function PowerConditionalSelect(props) { } const onRemoveSelectedModel = (model) => { - setModels(models.map((m) => ({ ...m, selected: m.code !== model.code ? m.selected : false }))) + setSelectedModels(selectedModels.filter((m) => m.id !== model.id)) } const onChangeMaker = (option) => { if (option) { - setModels(null) + setModels([]) setSelectedMaker(option) getPcsMakerList(option).then((res) => { + console.log('getPcsMakerList(series)', res.data) setSeries( res.data.map((series) => { return { ...series, selected: false } diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index 1d436a13..b098f409 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -24,19 +24,24 @@ export default function StepUp(props) { const [stepUpListData, setStepUpListData] = useState([]) const [optCodes, setOptCodes] = useState([]) - useCanvasPopupStatusController(6) - const canvasPopupStatusState = useRecoilValue(canvasPopupStatusStore) - if (Object.keys(canvasPopupStatusState[6]).length !== 0) { - console.log('🚀 ~ useEffect ~ canvasPopupStatusState :', canvasPopupStatusState) - } + const [selectedRows, setSelectedRows] = useState({}) + const [isManualSelection, setIsManualSelection] = useState({}) + + // 선택된 값들을 저장할 상태 추가 + const [selectedValues, setSelectedValues] = useState({}) + + // useCanvasPopupStatusController(6) + // const canvasPopupStatusState = useRecoilValue(canvasPopupStatusStore) + // if (Object.keys(canvasPopupStatusState[6]).length !== 0) { + // console.log('🚀 ~ useEffect ~ canvasPopupStatusState :', canvasPopupStatusState) + // } useEffect(() => { - console.log('🚀 ~ useEffect ~ >>>>>>>>>>>> props:', props) - // PCS 승압설정 정보 조회 fetchStepUpData() }, []) + // PCS 승압설정 정보 조회 const fetchStepUpData = async () => { try { const params = { @@ -46,14 +51,14 @@ export default function StepUp(props) { pcsItemList: props.getPcsItemList(), // PCS 아이템 목록 } - console.log('🚀 ~ fetchStepUpData ~ params:', params) - + // PCS 승압설정 정보 조회 const res = await getPcsVoltageStepUpList(params) - console.log('🚀 ~ fetchStepUpData ~ res:', res) + if (res?.result.code === 200 && res?.data) { const dataArray = Array.isArray(res.data) ? res.data : [res.data] const stepUpListData = formatStepUpListData(dataArray) - console.log('🚀 ~ useEffect ~ getPcsVoltageStepUpList ~ stepUpListData:', stepUpListData) + + // PCS 승압설정 정보 SET setStepUpListData(stepUpListData) // PCS 옵션 조회 @@ -74,13 +79,59 @@ export default function StepUp(props) { })) } - // PCS 승압설정 정보 포맷 + // // PCS 승압설정 정보 포맷 + // const formatStepUpListData = (dataArray = []) => { + // return dataArray?.map((stepUps) => ({ + // ...stepUps, + // optionList: formatOptionList(stepUps.optionList), + // pcsItemList: formatPcsItemList(stepUps.pcsItemList), + // selectedPcsItem: formatPcsItemList(stepUps.pcsItemList), + // })) + // } + + // PCS 승압설정 정보 포맷 후 추천 값 저장 const formatStepUpListData = (dataArray = []) => { - return dataArray?.map((stepUps) => ({ + const formattedData = dataArray?.map((stepUps) => ({ ...stepUps, optionList: formatOptionList(stepUps.optionList), pcsItemList: formatPcsItemList(stepUps.pcsItemList), + selectedPcsItem: formatPcsItemList(stepUps.pcsItemList), })) + + // 초기 추천 값들을 selectedValues에 저장 + const initialSelectedValues = {} + formattedData.forEach((stepUp) => { + stepUp.pcsItemList.forEach((pcsItem, pcsIdx) => { + const pcsKey = `${stepUp.id}_${pcsIdx}` + + // 추천 값(rmdYn === 'Y') 찾기 + const recommendedRow = pcsItem.serQtyList.find((item) => item.rmdYn === 'Y') + if (recommendedRow) { + const selectionData = { + stepUpId: pcsItem.goodsNo, + pcsInfo: { + itemId: pcsItem.itemId, + goodsNo: pcsItem.goodsNo, + pcsMkrCd: pcsItem.pcsMkrCd, + pcsSerCd: pcsItem.pcsSerCd, + }, + allocation: { + serQty: recommendedRow.serQty, + paralQty: recommendedRow.paralQty, + }, + } + + initialSelectedValues[stepUp.id] = { + ...initialSelectedValues[stepUp.id], + [pcsKey]: selectionData, + } + } + }) + }) + + setSelectedValues(initialSelectedValues) + + return formattedData } // PCS 옵션 포맷 @@ -107,6 +158,8 @@ export default function StepUp(props) { // PCS 연결 포맷 const formatConnList = (connList = []) => { + if (!connList) return [] // null인 경우 빈 배열 반환 + return connList?.map((conn) => ({ connAllowCur: conn.connAllowCur ? conn.connAllowCur : 0, connMaxParalCnt: conn.connMaxParalCnt ? conn.connMaxParalCnt : 0, @@ -122,17 +175,114 @@ export default function StepUp(props) { return serQtyList?.map((qty) => ({ serQty: qty.serQty ? qty.serQty : 0, paralQty: qty.paralQty ? qty.paralQty : 0, + rmdYn: qty.rmdYn ? qty.rmdYn : 'N', + usePossYn: qty.usePossYn ? qty.usePossYn : 'Y', })) } // 각 모듈의 탭을 변경하는 함수 - const handleTabChange = (stepUpId, idx, tabNumber) => { + const handleTabChange = (goodsNo, idx, tabNumber) => { setModuleTabs((prev) => ({ ...prev, - [`${stepUpId}_${idx}`]: tabNumber, + [`${goodsNo}_${idx}`]: tabNumber, })) } + // 행 선택 핸들러 함수 추가 + const handleRowClick = (goodsNo, pcsIdx, serQtyIdx, serQty, paralQty) => { + const rowKey = `${goodsNo}_${pcsIdx}_${serQtyIdx}` + const pcsKey = `${goodsNo}_${pcsIdx}` + + console.log('goodsNo >> ', goodsNo, serQty, paralQty) + + // 현재 선택된 PCS 아이템 정보 가져오기 + const pcsItem = stepUpListData.find((stepUp) => stepUp.pcsItemList.find((item) => item.goodsNo === goodsNo))?.pcsItemList[pcsIdx] + + if (!pcsItem) { + console.error('PCS item not found:', { goodsNo, pcsIdx }) + return + } + + // 선택된 값들 업데이트 - 더 자세한 정보 포함 + const selectionData = { + goodsNo: goodsNo, + pcsInfo: { + itemId: pcsItem?.itemId, + goodsNo: pcsItem?.goodsNo, + pcsMkrCd: pcsItem?.pcsMkrCd, + pcsSerCd: pcsItem?.pcsSerCd, + }, + allocation: { + serQty: serQty, + paralQty: paralQty, + }, + } + + // 선택된 값들 업데이트 + setSelectedValues((prev) => ({ + ...prev, + [goodsNo]: { + ...prev[goodsNo], + [pcsKey]: selectionData, + }, + })) + + // 부모 컴포넌트에 선택된 값들 전달 + if (props.onValuesSelected) { + props.onValuesSelected(selectionData) + } + + setSelectedRows((prev) => { + // 현재 stepUpId에 대한 선택 상태가 없으면 빈 객체로 초기화 + const currentStepUpSelections = prev[goodsNo] || {} + + // 이미 선택된 행을 다시 클릭하는 경우, 선택을 해제하지 않음 + if (currentStepUpSelections[pcsKey] === rowKey) { + return prev + } + + return { + ...prev, + [goodsNo]: { + ...currentStepUpSelections, + [pcsKey]: rowKey, + }, + } + }) + + // 수동 선택 상태를 업데이트하되, 기존 추천 선택은 유지 + setIsManualSelection((prev) => ({ + ...prev, + [goodsNo]: { + ...prev[goodsNo], + [pcsKey]: true, + }, + })) + } + + // 현재 선택된 값들을 가져오는 함수 추가 + const getCurrentSelections = () => { + 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 ( <>
@@ -143,9 +293,7 @@ export default function StepUp(props) { {stepUp?.pcsItemList.map((_, idx) => (
-
- {stepUp.pcsItemList[idx].goodsNo} -
+
{stepUp.pcsItemList[idx].goodsNo}
@@ -155,9 +303,21 @@ export default function StepUp(props) { - {stepUp.pcsItemList[idx].serQtyList.map((item) => { + {stepUp.pcsItemList[idx].serQtyList.map((item, serQtyIdx) => { + const rowKey = `${stepUp.pcsItemList[idx].goodsNo}_${idx}_${serQtyIdx}` + const pcsKey = `${stepUp.pcsItemList[idx].goodsNo}_${idx}` return ( - + handleRowClick(stepUp.pcsItemList[idx].goodsNo, idx, serQtyIdx, item.serQty, item.paralQty)} + style={{ cursor: 'pointer' }} + > @@ -169,20 +329,20 @@ export default function StepUp(props) {
- {(moduleTabs[`${stepUp.id}_${idx}`] || 1) === 1 && ( + {(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 1 && (
{item.serQty} {item.paralQty}
@@ -195,16 +355,24 @@ export default function StepUp(props) { - - - + + +
{stepUp.pcsItemList[idx].connList?.goodsNo}{stepUp.pcsItemList[idx].connList?.connMaxParalCnt}{stepUp.pcsItemList[idx].connList?.vstuParalCnt} + {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.id}_${idx}`] || 1) === 2 && ( + {(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 2 && (
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx index c9da1682..a8cb2e7f 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -10,7 +10,16 @@ import { useContext, useEffect, useState } from 'react' import { useRecoilValue } from 'recoil' export default function PassivityCircuitAllocation(props) { - const { tabNum, setTabNum, selectedModels, getApiProps, getSelectedModuleList, getSelectModelList, getRoofSurfaceList, getModelList } = props + const { + tabNum, + setTabNum, + selectedModels, + getOptYn: getApiProps, + getUseModuleItemList: getSelectedModuleList, + getSelectModelList: getSelectModelList, + getRoofSurfaceList, + getModelList, + } = props const { swalFire } = useSwal() const { getMessage } = useMessage() const canvas = useRecoilValue(canvasState) @@ -19,21 +28,40 @@ export default function PassivityCircuitAllocation(props) { const moduleStatistics = useRecoilValue(moduleStatisticsState) // const [totalWpout, setTotalWpout] = useState(0) const [selectedPcs, setSelectedPcs] = useState(selectedModels[0]) - const { header, rows: row } = moduleStatistics - const [headers, setHeaders] = useState(header) - const [rows, setRows] = useState(row) + // const { header, rows: row } = moduleStatistics + const [header, setHeader] = useState(moduleStatistics.header) + const [rows, setRows] = useState(moduleStatistics.rows) const [footer, setFooter] = useState(['합계']) const [circuitNumber, setCircuitNumber] = useState(1) const [targetModules, setTargetModules] = useState([]) const { getPcsManualConfChk } = useMasterController() useEffect(() => { - console.log('🚀 ~ PassivityCircuitAllocation ~ selectedModels:', selectedModels) - }, []) + console.log('header, rows', header, rows) + console.log('selectedModels', selectedModels) + // setSurfaceInfo() + setTableData() + if (!managementState) { + setManagementState(managementStateLoaded) + } + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE) + .forEach((obj) => { + obj.on('mousedown', (e) => handleTargetModules(obj)) + }) - useEffect(() => { - console.log('🚀 ~ PassivityCircuitAllocation ~ selectedPcs:', selectedPcs) - }, [selectedPcs]) + return () => { + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE) + .forEach((obj) => { + obj.set({ strokeWidth: 0.3 }) + obj.off('mousedown') + }) + canvas.renderAll() + } + }, []) const handleTargetModules = (obj) => { if (!Array.isArray(targetModules)) { @@ -54,32 +82,9 @@ export default function PassivityCircuitAllocation(props) { canvas.renderAll() } - useEffect(() => { - setSurfaceInfo() - if (!managementState) { - setManagementState(managementStateLoaded) - } - const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) - - modules.forEach((obj) => { - obj.on('mousedown', (e) => handleTargetModules(obj)) - }) - - return () => { - canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE) - .forEach((obj) => { - obj.set({ strokeWidth: 0.3 }) - obj.off('mousedown') - }) - canvas.renderAll() - } - }, []) - const setSurfaceInfo = () => { const surfaces = canvas.getObjects().filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name) - setHeaders([header[0], { name: '회로', prop: 'circuit' }, ...header.slice(1)]) + // setHeaders([header[0], { name: '회로', prop: 'circuit' }, ...header.slice(1)]) setRows( rows.map((row) => { return { @@ -155,62 +160,145 @@ export default function PassivityCircuitAllocation(props) { if (!circuitNumber || circuitNumber === 0) { swalFire({ text: '회로번호를 1 이상입력해주세요.', - type: 'warning', + type: 'alert', icon: 'warning', }) return } else if (targetModules.length === 0) { swalFire({ text: '모듈을 선택해주세요.', - type: 'warning', + type: 'alert', icon: 'warning', }) return + } else if (selectedModels.length > 1) { + const uniqueCircuitNumbers = [ + ...new Set( + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuitNumber) + .map((obj) => obj.circuitNumber), + ), + ] + + let result = false + uniqueCircuitNumbers.forEach((number) => { + if ( + number.split('-')[1] === circuitNumber + ')' && + number.split('-')[0] !== '(' + (selectedModels.findIndex((model) => model.id === selectedPcs.id) + 1) + ) { + result = true + } + }) + if (result) { + swalFire({ + text: '회로 번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로 번호를 설정하십시오.', + type: 'alert', + icon: 'warning', + }) + return + } } + + canvas.discardActiveObject() + canvas + .getObjects() + .filter((obj) => targetModules.includes(obj.id)) + .forEach((obj) => { + const moduleCircuitText = new fabric.Text(getCircuitNumber(), { + left: obj.left + obj.width / 2, + top: obj.top + obj.height / 2, + fill: 'black', + fontSize: 20, + width: obj.width, + height: obj.height, + textAlign: 'center', + originX: 'center', + originY: 'center', + name: 'circuitNumber', + parentId: obj.id, + circuitInfo: selectedPcs, + }) + obj.set({ + strokeWidth: 0.3, + }) + obj.pcsItemId = selectedPcs.itemId + obj.circuit = moduleCircuitText + obj.circuitNumber = getCircuitNumber() + canvas.add(moduleCircuitText) + }) + + const roofSurfaceList = canvas + .getObjects() + .filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name) + .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, + } + }), + } + }) + + const pcsItemList = selectedModels.map((model) => { + return { + pcsMkrCd: model.pcsMkrCd, + pcsSerCd: model.pcsSerCd, + itemId: model.itemId, + itemNm: model.itemNm, + goodsNo: model.goodsNo, + serQtyList: [ + { + serQty: 0, + paralQty: 0, + rmdYn: 'Y', + usePossYn: 'Y', + roofSurfaceList: roofSurfaceList, + }, + ], + } + }) + const params = { ...getApiProps(), useModuleItemList: getSelectedModuleList(), - pcsItemList: getSelectModelList(), + pcsItemList: pcsItemList, } - console.log(params) - // getPcsManualConfChk(params).then((res) => { - // console.log(res) - // - // }) - // canvas.discardActiveObject() - // - // canvas - // .getObjects() - // .filter((obj) => targetModules.includes(obj.id)) - // .forEach((obj) => { - // const moduleCircuitText = new fabric.Text(getCircuitNumber(), { - // left: obj.left + obj.width / 2, - // top: obj.top + obj.height / 2, - // fill: 'black', - // fontSize: 20, - // width: obj.width, - // height: obj.height, - // textAlign: 'center', - // originX: 'center', - // originY: 'center', - // name: 'circuitNumber', - // parentId: obj.id, - // circuitInfo: selectedPcs, - // }) - // obj.set({ - // strokeWidth: 0.3, - // }) - // obj.pcsItemId = selectedPcs.itemId + getPcsManualConfChk(params).then((res) => { + if (res.resultCode === 'E') { + swalFire({ + text: res.resultMsg, + type: 'alert', + icon: 'warning', + confirmFn: () => { + const circuitNumbers = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber' && targetModules.includes(obj.parentId)) + canvas.remove(...circuitNumbers) + canvas + .getObjects() + .filter((obj) => obj.name === 'module' && targetModules.includes(obj.id)) + .forEach((obj) => { + obj.pcsItemId = null + obj.circuit = null + obj.circuitNumber = null + }) + canvas.renderAll() + }, + }) - // obj.circuit = moduleCircuitText - // canvas.add(moduleCircuitText) - // canvas.renderAll() - // console.log(obj) - // }) - // setTargetModules([]) - // setCircuitNumber(+circuitNumber + 1) - // canvas.renderAll() + return + } + + setTargetModules([]) + setCircuitNumber(+circuitNumber + 1) + setTableData() + }) } const getCircuitNumber = () => { @@ -221,12 +309,100 @@ export default function PassivityCircuitAllocation(props) { } } + const setTableData = () => { + const tempHeader = [ + { name: '지붕면', prop: 'name' }, + { name: '회로', prop: 'circuit' }, + ...selectedModules.itemList.map((module) => { + return { + name: module.itemNm, + prop: module.itemId, + } + }), + { name: '발전량(kW)', prop: 'wpOut' }, + ] + + const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + const surfaceIds = surfaces.map((surface) => surface.parentId) + const surfaceObjects = {} + const rows = surfaces.map((surface) => { + const moduleObject = {} + surfaceObjects[surface.id] = { + roofSurface: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, + circuit: '-', + amount: 0, + wpOut: 0, + circuits: {}, + } + + surface.modules.forEach((module) => { + if (!surfaceObjects[surface.id][module.moduleInfo.itemId]) { + // 지붕면에 모듈 존재 여부 + surfaceObjects[surface.id][module.moduleInfo.itemId] = 0 // 모듈 초기화 + } + + surfaceObjects[surface.id][module.moduleInfo.itemId]++ + surfaceObjects[surface.id].wpOut += +module.moduleInfo.wpOut + if (module.circuit) { + if (!surfaceObjects[surface.id].circuits[module.circuitNumber]) { + surfaceObjects[surface.id].circuits[module.circuitNumber] = { + circuit: module.circuitNumber, + wpOut: 0, + circuits: { wpOut: 0 }, + } + + if (!surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]) { + surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId] = 0 + } + } + surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]++ + surfaceObjects[surface.id].circuits[module.circuitNumber].circuits.wpOut += +module.moduleInfo.wpOut + surfaceObjects[surface.id].wpOut -= +module.moduleInfo.wpOut + surfaceObjects[surface.id][module.moduleInfo.itemId]-- + } + }) + }) + console.log('rows', rows) + console.log('surfaceObjects', surfaceObjects) + let tempRows = [] + Object.keys(surfaceObjects).forEach((key) => { + let tempRow = { + name: surfaceObjects[key].roofSurface, + circuit: surfaceObjects[key].circuit, + wpOut: surfaceObjects[key].wpOut, + } + selectedModules.itemList.forEach((module) => { + tempRow[module.itemId] = surfaceObjects[key][module.itemId] + }) + tempRows.push(tempRow) + + Object.keys(surfaceObjects[key].circuits).forEach((circuit) => { + let row = { + name: surfaceObjects[key].roofSurface, + circuit: surfaceObjects[key].circuits[circuit].circuit, + wpOut: surfaceObjects[key].circuits[circuit].circuits.wpOut, + } + selectedModules.itemList.forEach((module) => { + row[module.itemId] = surfaceObjects[key].circuits[circuit].circuits[module.itemId] + }) + tempRows.push(row) + }) + }) + const tempFooter = { + name: '총합', + circuit: '-', + wpOut: tempRows.reduce((acc, row) => acc + row.wpOut, 0), + } + selectedModules.itemList.forEach((module) => { + tempFooter[module.itemId] = tempRows.reduce((acc, row) => acc + row[module.itemId], 0) + }) + console.log('tempHeader, tempRows, tempFooter', tempHeader, tempRows, tempFooter) + setHeader(tempHeader) + setRows(tempRows.filter((row) => row.wpOut !== 0)) + setFooter(tempFooter) + } + const initSelectedPcsCircuitNumber = () => { - console.log( - 'module', - canvas.getObjects().filter((obj) => obj.name === 'module'), - ) - console.log('selectedPcs', selectedPcs) swalFire({ title: '선택된 파워 컨디셔너의 회로할당을 초기화합니다.', type: 'confirm', @@ -281,7 +457,7 @@ export default function PassivityCircuitAllocation(props) {
- {headers.map((header, index) => ( + {header.map((header, index) => ( ))} @@ -289,7 +465,7 @@ export default function PassivityCircuitAllocation(props) { {rows.map((row, index) => ( - {headers.map((header, i) => ( + {header.map((header, i) => ( @@ -297,9 +473,9 @@ export default function PassivityCircuitAllocation(props) { ))} - {footer.map((footer, index) => ( - ))} @@ -323,7 +499,7 @@ export default function PassivityCircuitAllocation(props) { name="radio01" id={`ra0${index + 1}`} value={model} - checked={selectedPcs.id === model.id} + checked={selectedPcs?.id === model.id} onChange={() => setSelectedPcs(model)} />
{header.name}
{row[header.prop]}
- {footer} + {header.map((header, i) => ( + + {footer[header.prop]}