Merge branch 'dev' of ssh://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into dev
# Conflicts: # src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
This commit is contained in:
commit
41ab4af9ed
@ -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]
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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 }) {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{selectedModules.itemList &&
|
||||
{selectedModules &&
|
||||
selectedModules.itemList &&
|
||||
selectedModules.itemList.map((row, index) => (
|
||||
<tr key={index}>
|
||||
<td>
|
||||
@ -250,10 +250,10 @@ export default function Module({ setTabNum }) {
|
||||
<div style={{ display: roofTab === index ? 'block' : 'none' }} key={index}>
|
||||
<ModuleTabContents
|
||||
key={index}
|
||||
index={index}
|
||||
tabIndex={index}
|
||||
addRoof={roof}
|
||||
setAddedRoofs={setAddedRoofs}
|
||||
roofTab={index}
|
||||
roofTab={roofTab}
|
||||
tempModuleSelectionData={tempModuleSelectionData}
|
||||
setTempModuleSelectionData={setTempModuleSelectionData}
|
||||
/>
|
||||
|
||||
@ -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
|
||||
<div className="d-check-box pop">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={`ch01_${roofTab}`}
|
||||
id={`ch01_${tabIndex}`}
|
||||
disabled={cvrYn === 'N' ? true : false}
|
||||
checked={cvrChecked}
|
||||
checked={cvrChecked || false}
|
||||
onChange={handleCvrChecked}
|
||||
/>
|
||||
<label htmlFor={`ch01_${roofTab}`}>{getMessage('modal.module.basic.setting.module.eaves.bar.fitting')}</label>
|
||||
<label htmlFor={`ch01_${tabIndex}`}>{getMessage('modal.module.basic.setting.module.eaves.bar.fitting')}</label>
|
||||
</div>
|
||||
<div className="d-check-box pop">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={`ch02_${roofTab}`}
|
||||
id={`ch02_${tabIndex}`}
|
||||
disabled={snowGdPossYn === 'N' ? true : false}
|
||||
checked={snowGdChecked}
|
||||
checked={snowGdChecked || false}
|
||||
onChange={handleSnowGdChecked}
|
||||
/>
|
||||
<label htmlFor={`ch02_${roofTab}`}>{getMessage('modal.module.basic.setting.module.blind.metal.fitting')}</label>
|
||||
<label htmlFor={`ch02_${tabIndex}`}>{getMessage('modal.module.basic.setting.module.blind.metal.fitting')}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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 }) {
|
||||
</div>
|
||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && <PowerConditionalSelect {...powerConditionalSelectProps} />}
|
||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && <PassivityCircuitAllocation {...passivityProps} />}
|
||||
{tabNum === 2 && <StepUp {...stepUpProps} />}
|
||||
{tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
|
||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal mr5" onClick={() => onAutoAllocation()}>
|
||||
@ -308,7 +519,8 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
<button className="btn-frame modal mr5" onClick={() => setTabNum(1)}>
|
||||
{getMessage('modal.common.prev')}
|
||||
</button>
|
||||
<button className="btn-frame modal act" onClick={() => apply()}>
|
||||
{/* <button className="btn-frame modal act" onClick={() => apply()}> */}
|
||||
<button className="btn-frame modal act" onClick={onApply}>
|
||||
{getMessage('modal.common.save')}({getMessage('modal.circuit.trestle.setting.circuit.allocation')})
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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 (
|
||||
<>
|
||||
<div className="properties-setting-wrap outer">
|
||||
@ -143,9 +293,7 @@ export default function StepUp(props) {
|
||||
{stepUp?.pcsItemList.map((_, idx) => (
|
||||
<div key={idx} className="module-table-inner">
|
||||
<div className="mb-box">
|
||||
<div key={idx} className="circuit-table-tit">
|
||||
{stepUp.pcsItemList[idx].goodsNo}
|
||||
</div>
|
||||
<div className="circuit-table-tit">{stepUp.pcsItemList[idx].goodsNo}</div>
|
||||
<div className="roof-module-table overflow-y min">
|
||||
<table>
|
||||
<thead>
|
||||
@ -155,9 +303,21 @@ export default function StepUp(props) {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{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 (
|
||||
<tr className="on">
|
||||
<tr
|
||||
key={rowKey}
|
||||
className={`${
|
||||
(!isManualSelection[stepUp.pcsItemList[idx].goodsNo]?.[pcsKey] && item.rmdYn === 'Y') ||
|
||||
(selectedRows[stepUp.pcsItemList[idx].goodsNo] && selectedRows[stepUp.pcsItemList[idx].goodsNo][pcsKey] === rowKey)
|
||||
? 'on'
|
||||
: ''
|
||||
}`}
|
||||
onClick={() => handleRowClick(stepUp.pcsItemList[idx].goodsNo, idx, serQtyIdx, item.serQty, item.paralQty)}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<td className="al-r">{item.serQty}</td>
|
||||
<td className="al-r">{item.paralQty}</td>
|
||||
</tr>
|
||||
@ -169,20 +329,20 @@ export default function StepUp(props) {
|
||||
</div>
|
||||
<div className="module-box-tab mb10">
|
||||
<button
|
||||
className={`module-btn ${(moduleTabs[`${stepUp.id}_${idx}`] || 1) === 1 ? 'act' : ''}`}
|
||||
onClick={() => handleTabChange(stepUp.id, idx, 1)}
|
||||
className={`module-btn ${(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 1 ? 'act' : ''}`}
|
||||
onClick={() => handleTabChange(stepUp.pcsItemList[idx].goodsNo, idx, 1)}
|
||||
>
|
||||
{getMessage('modal.circuit.trestle.setting.step.up.allocation.connected')}
|
||||
</button>
|
||||
<button
|
||||
className={`module-btn ${(moduleTabs[`${stepUp.id}_${idx}`] || 1) === 2 ? 'act' : ''}`}
|
||||
onClick={() => handleTabChange(stepUp.id, idx, 2)}
|
||||
className={`module-btn ${(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 2 ? 'act' : ''}`}
|
||||
onClick={() => handleTabChange(stepUp.pcsItemList[idx].goodsNo, idx, 2)}
|
||||
>
|
||||
{getMessage('modal.circuit.trestle.setting.step.up.allocation.option')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="circuit-table-flx-wrap">
|
||||
{(moduleTabs[`${stepUp.id}_${idx}`] || 1) === 1 && (
|
||||
{(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 1 && (
|
||||
<div className="circuit-table-flx-box">
|
||||
<div className="roof-module-table min mb10">
|
||||
<table>
|
||||
@ -195,16 +355,24 @@ export default function StepUp(props) {
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="al-c">{stepUp.pcsItemList[idx].connList?.goodsNo}</td>
|
||||
<td className="al-r">{stepUp.pcsItemList[idx].connList?.connMaxParalCnt}</td>
|
||||
<td className="al-r">{stepUp.pcsItemList[idx].connList?.vstuParalCnt}</td>
|
||||
<td className="al-c">
|
||||
{stepUp.pcsItemList[idx].connList?.[0]?.goodsNo ? stepUp.pcsItemList[idx].connList?.[0]?.goodsNo : '-'}
|
||||
</td>
|
||||
<td className="al-c">
|
||||
{stepUp.pcsItemList[idx].connList?.[0]?.connMaxParalCnt
|
||||
? (stepUp.pcsItemList[idx].connList?.[0]?.connMaxParalCnt ?? '-')
|
||||
: '-'}
|
||||
</td>
|
||||
<td className="al-c">
|
||||
{stepUp.pcsItemList[idx].connList?.[0]?.vstuParalCnt ? stepUp.pcsItemList[idx].connList?.[0]?.vstuParalCnt : '-'}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{(moduleTabs[`${stepUp.id}_${idx}`] || 1) === 2 && (
|
||||
{(moduleTabs[`${stepUp.pcsItemList[idx].goodsNo}_${idx}`] || 1) === 2 && (
|
||||
<div className="circuit-table-flx-box">
|
||||
<div className="roof-module-table min mb10">
|
||||
<table>
|
||||
|
||||
@ -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) {
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
{headers.map((header, index) => (
|
||||
{header.map((header, index) => (
|
||||
<th key={'header' + index}>{header.name}</th>
|
||||
))}
|
||||
</tr>
|
||||
@ -289,7 +465,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
<tbody>
|
||||
{rows.map((row, index) => (
|
||||
<tr key={'row' + index}>
|
||||
{headers.map((header, i) => (
|
||||
{header.map((header, i) => (
|
||||
<td className="al-c" key={'rowcell' + i}>
|
||||
{row[header.prop]}
|
||||
</td>
|
||||
@ -297,9 +473,9 @@ export default function PassivityCircuitAllocation(props) {
|
||||
</tr>
|
||||
))}
|
||||
<tr>
|
||||
{footer.map((footer, index) => (
|
||||
<td className="al-c" key={'footer' + index}>
|
||||
{footer}
|
||||
{header.map((header, i) => (
|
||||
<td className="al-c" key={'footer' + i}>
|
||||
{footer[header.prop]}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
@ -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)}
|
||||
/>
|
||||
<label htmlFor={`ra0${index + 1}`}>
|
||||
@ -361,7 +537,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
<div className="input-grid mr5" style={{ width: '70px' }}>
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
className="block input-origin"
|
||||
value={circuitNumber}
|
||||
min={1}
|
||||
max={99}
|
||||
|
||||
@ -350,6 +350,10 @@ export default function StuffDetail() {
|
||||
if (res?.data?.createUser === 'T01' && session?.userId !== 'T01') {
|
||||
//createUser가 T01인데 로그인사용자가 T01이 아니면 버튼숨기기
|
||||
setShowButton('none')
|
||||
} else {
|
||||
if (session.userId !== res?.data?.createUser) {
|
||||
setShowButton('none')
|
||||
}
|
||||
}
|
||||
if (isObjectNotEmpty(res.data)) {
|
||||
let surfaceTypeValue
|
||||
@ -358,7 +362,7 @@ export default function StuffDetail() {
|
||||
} else if (res.data.surfaceType === 'Ⅱ') {
|
||||
surfaceTypeValue = '2'
|
||||
}
|
||||
setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue })
|
||||
setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue, firstFlag: 'Y' })
|
||||
} else {
|
||||
setManagementState({})
|
||||
swalFire({
|
||||
@ -450,7 +454,6 @@ export default function StuffDetail() {
|
||||
firstList = res
|
||||
favList = res.filter((row) => row.priority !== 'B')
|
||||
otherList = res.filter((row) => row.firstAgentYn === 'N')
|
||||
|
||||
setSaleStoreList(firstList)
|
||||
setFavoriteStoreList(firstList)
|
||||
setShowSaleStoreList(firstList)
|
||||
@ -527,6 +530,11 @@ export default function StuffDetail() {
|
||||
get({ url: url }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
if (session?.storeId === 'T01') {
|
||||
//즐겨찾기 구분 추가
|
||||
res.map((row) => {
|
||||
row.value = row.saleStoreId
|
||||
row.label = row.saleStoreName
|
||||
})
|
||||
firstList = res.filter((row) => row.saleStoreLevel === '1')
|
||||
firstList.sort((a, b) => (a.saleStoreId !== 'T01') - (b.saleStoreId !== 'T01') || a.saleStoreId - b.saleStoreId)
|
||||
favList = firstList.filter((row) => row.saleStoreId === 'T01' || row.priority !== 'B')
|
||||
@ -649,7 +657,7 @@ export default function StuffDetail() {
|
||||
//염해지역용아이템사용 saltAreaFlg 1이면 true
|
||||
form.setValue('saltAreaFlg', managementState.saltAreaFlg === '1' ? true : false)
|
||||
//설치높이
|
||||
let installHeight = managementState.installHeight ? managementState.installHeight.split('.')[0] : '0'
|
||||
let installHeight = managementState.installHeight ? managementState.installHeight.split('.')[0] : ''
|
||||
form.setValue('installHeight', installHeight)
|
||||
//계약조건 null로 내려오면 0으로 디폴트셋팅
|
||||
if (managementState.conType === null) {
|
||||
@ -985,7 +993,7 @@ export default function StuffDetail() {
|
||||
form.setValue('saltAreaFlg', false)
|
||||
}
|
||||
|
||||
let installHeight = info.installHeight ? info.installHeight.split('.')[0] : '0'
|
||||
let installHeight = info.installHeight ? info.installHeight.split('.')[0] : ''
|
||||
|
||||
form.setValue('installHeight', installHeight)
|
||||
form.setValue('remarks', info.remarks)
|
||||
@ -1413,8 +1421,6 @@ export default function StuffDetail() {
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
callDetailApi(objectNo)
|
||||
// setManagementState({ ...managementState, params })
|
||||
// router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false })
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -1426,48 +1432,22 @@ export default function StuffDetail() {
|
||||
}
|
||||
}
|
||||
|
||||
const callDetailApi = (objectNo) => {
|
||||
promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
|
||||
if (res.status === 200) {
|
||||
if (res?.data?.createUser === 'T01' && session?.userId !== 'T01') {
|
||||
//createUser가 T01인데 로그인사용자가 T01이 아니면 버튼숨기기
|
||||
const callDetailApi = async (objectNo) => {
|
||||
await promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => {
|
||||
if (res?.data?.createUser === 'T01' && session?.userId !== 'T01') {
|
||||
setShowButton('none')
|
||||
} else {
|
||||
if (session.userId !== res?.data?.createUser) {
|
||||
setShowButton('none')
|
||||
}
|
||||
if (isObjectNotEmpty(res.data)) {
|
||||
let surfaceTypeValue
|
||||
if (res.data.surfaceType === 'Ⅲ・Ⅳ') {
|
||||
surfaceTypeValue = '3'
|
||||
} else if (res.data.surfaceType === 'Ⅱ') {
|
||||
surfaceTypeValue = '2'
|
||||
}
|
||||
setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue })
|
||||
} else {
|
||||
setManagementState({})
|
||||
swalFire({
|
||||
text: getMessage('stuff.detail.header.notExistObjectNo'),
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
router.push('/management/stuff', { scroll: false })
|
||||
},
|
||||
})
|
||||
}
|
||||
if (isNotEmptyArray(res.data.planList)) {
|
||||
setPlanGridProps({ ...planGridProps, planGridData: res.data.planList })
|
||||
} else {
|
||||
setPlanGridProps({ ...planGridProps, planGridData: [] })
|
||||
}
|
||||
} else {
|
||||
setManagementState({})
|
||||
setPlanGridProps({ ...planGridProps, planGridData: [] })
|
||||
|
||||
swalFire({
|
||||
text: getMessage('stuff.detail.header.notExistObjectNo'),
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
router.push('/management/stuff', { scroll: false })
|
||||
},
|
||||
})
|
||||
}
|
||||
let surfaceTypeValue
|
||||
if (res.data.surfaceType === 'Ⅲ・Ⅳ') {
|
||||
surfaceTypeValue = '3'
|
||||
} else {
|
||||
surfaceTypeValue = '2'
|
||||
}
|
||||
setManagementState({ ...res.data, surfaceTypeValue: surfaceTypeValue })
|
||||
})
|
||||
}
|
||||
|
||||
@ -1680,6 +1660,31 @@ export default function StuffDetail() {
|
||||
}
|
||||
}
|
||||
|
||||
const CustomOption = (props) => {
|
||||
const { data, innerRef, innerProps, isSelected, isFocused, isDisabled } = props
|
||||
const customClass = data.saleStoreId === 'T01' || data.priority !== 'B' ? 'special-option' : ''
|
||||
// 기본 선택/호버 상태 적용
|
||||
const optionClass = `${customClass} ${isSelected ? 'custom__option--is-selected' : ''} ${isFocused ? 'custom__option--is-focused' : ''} ${isDisabled ? 'custom__option--is-disabled' : ''}`
|
||||
|
||||
return (
|
||||
<div ref={innerRef} {...innerProps} className={`custom__option ${optionClass}`}>
|
||||
{data.label}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const CustomOption2 = (props) => {
|
||||
const { data, innerRef, innerProps, isSelected, isFocused, isDisabled } = props
|
||||
const customClass = data.priority !== 'B' ? 'special-option' : ''
|
||||
// 기본 선택/호버 상태 적용
|
||||
const optionClass = `${customClass} ${isSelected ? 'custom__option--is-selected' : ''} ${isFocused ? 'custom__option--is-focused' : ''} ${isDisabled ? 'custom__option--is-disabled' : ''}`
|
||||
return (
|
||||
<div ref={innerRef} {...innerProps} className={`custom__option ${optionClass}`}>
|
||||
{data.label}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{(editMode === 'NEW' && (
|
||||
@ -1847,6 +1852,7 @@ export default function StuffDetail() {
|
||||
value={saleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === selOptions
|
||||
})}
|
||||
components={{ Option: CustomOption }}
|
||||
></Select>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -1879,6 +1885,7 @@ export default function StuffDetail() {
|
||||
value={showSaleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === selOptions
|
||||
})}
|
||||
// components={{ Option: CustomOption }}
|
||||
></Select>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -1910,6 +1917,7 @@ export default function StuffDetail() {
|
||||
value={showSaleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === selOptions
|
||||
})}
|
||||
// components={{ Option: CustomOption }}
|
||||
></Select>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -1962,11 +1970,11 @@ export default function StuffDetail() {
|
||||
? true
|
||||
: false
|
||||
}
|
||||
// isDisabled={otherSaleStoreList != null && otherSaleStoreList.length === 1 ? true : false}
|
||||
isClearable={true}
|
||||
value={otherSaleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === otherSelOptions
|
||||
})}
|
||||
components={{ Option: CustomOption2 }}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -2413,7 +2421,7 @@ export default function StuffDetail() {
|
||||
<>
|
||||
<div className="select-wrap mr5" style={{ width: '567px' }}>
|
||||
<Select
|
||||
menuPlacement={'auto'}
|
||||
// menuPlacement={'auto'}
|
||||
id="long-value-select1"
|
||||
instanceId="long-value-select1"
|
||||
className="react-select-custom"
|
||||
@ -2429,6 +2437,7 @@ export default function StuffDetail() {
|
||||
value={saleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === selOptions
|
||||
})}
|
||||
components={{ Option: CustomOption }}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -2469,6 +2478,7 @@ export default function StuffDetail() {
|
||||
value={showSaleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === selOptions
|
||||
})}
|
||||
// components={{ Option: CustomOption }}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -2503,6 +2513,7 @@ export default function StuffDetail() {
|
||||
return option.saleStoreId
|
||||
}
|
||||
})}
|
||||
// components={{ Option: CustomOption }}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
@ -2557,6 +2568,7 @@ export default function StuffDetail() {
|
||||
value={otherSaleStoreList.filter(function (option) {
|
||||
return option.saleStoreId === otherSelOptions
|
||||
})}
|
||||
// components={{ Option: CustomOption2 }}
|
||||
/>
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '216px' }}>
|
||||
|
||||
@ -67,7 +67,9 @@ export default function StuffHeader() {
|
||||
</div>
|
||||
<div className="sub-table-box">
|
||||
<div className="info-title">{getMessage('stuff.detail.header.specificationConfirmDate')}</div>
|
||||
<div className="info-inner">{managementState?.specificationConfirmDate}</div>
|
||||
<div className="info-inner">
|
||||
{managementState?.specificationConfirmDate ? `${dayjs(managementState.specificationConfirmDate).format('YYYY.MM.DD HH:mm:ss')}` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div className="sub-table-box">
|
||||
<div className="info-title">{getMessage('stuff.detail.header.lastEditDatetime')}</div>
|
||||
|
||||
@ -891,7 +891,6 @@ export default function StuffSearchCondition() {
|
||||
const customClass = data.saleStoreId === 'T01' || data.priority !== 'B' ? 'special-option' : ''
|
||||
// 기본 선택/호버 상태 적용
|
||||
const optionClass = `${customClass} ${isSelected ? 'custom__option--is-selected' : ''} ${isFocused ? 'custom__option--is-focused' : ''} ${isDisabled ? 'custom__option--is-disabled' : ''}`
|
||||
console.log(optionClass)
|
||||
return (
|
||||
<div ref={innerRef} {...innerProps} className={`custom__option ${optionClass}`}>
|
||||
{data.label}
|
||||
|
||||
@ -18,7 +18,12 @@ import { convertNumberToPriceDecimal } from '@/util/common-utils'
|
||||
import { usePlan } from '@/hooks/usePlan'
|
||||
import { usePopup, closeAll } from '@/hooks/usePopup'
|
||||
|
||||
import { QcastContext } from '@/app/QcastProvider'
|
||||
|
||||
export default function Simulator() {
|
||||
// global 로딩바
|
||||
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||
|
||||
const { floorPlanState } = useContext(FloorPlanContext)
|
||||
const { objectNo, pid } = floorPlanState
|
||||
const { selectedPlan } = usePlan()
|
||||
@ -136,9 +141,12 @@ export default function Simulator() {
|
||||
const [hatsudenryouPeakcutAllSnow, setHatsudenryouPeakcutAllSnow] = useState([])
|
||||
|
||||
const fetchObjectDetail = async (objectNo, currentPid) => {
|
||||
setIsGlobalLoading(true)
|
||||
|
||||
const apiUrl = `/api/pwrGnrSimulation/calculations?objectNo=${objectNo}&planNo=${currentPid}`
|
||||
|
||||
const resultData = await get({ url: apiUrl })
|
||||
|
||||
if (resultData) {
|
||||
setObjectDetail(resultData)
|
||||
if (resultData.hatsudenryouAll) {
|
||||
@ -161,12 +169,14 @@ export default function Simulator() {
|
||||
setModuleInfoList(resultData.roofModuleList)
|
||||
}
|
||||
}
|
||||
setIsGlobalLoading(false)
|
||||
}
|
||||
|
||||
// 시뮬레이션 안내사항 조회
|
||||
const [content, setContent] = useState('')
|
||||
|
||||
const fetchSimulatorNotice = async () => {
|
||||
setIsGlobalLoading(true)
|
||||
get({ url: '/api/pwrGnrSimulation/guideInfo' }).then((res) => {
|
||||
if (res.data) {
|
||||
setContent(res.data.replaceAll('\n', '<br/>'))
|
||||
@ -174,6 +184,7 @@ export default function Simulator() {
|
||||
setContent(getMessage('common.message.no.data'))
|
||||
}
|
||||
})
|
||||
setIsGlobalLoading(false)
|
||||
}
|
||||
|
||||
// 차트 데이터 변경 시, list type 셋팅
|
||||
|
||||
@ -523,10 +523,26 @@ export function useCommonUtils() {
|
||||
if (object) {
|
||||
canvas?.remove(object)
|
||||
|
||||
// if (object.id) {
|
||||
// const group = canvas.getObjects().filter((obj) => obj.id === object.id)
|
||||
// group.forEach((obj) => canvas?.remove(obj))
|
||||
// }
|
||||
if (object.id) {
|
||||
const group = canvas.getObjects().filter((obj) => obj.id === object.id)
|
||||
group.forEach((obj) => canvas?.remove(obj))
|
||||
}
|
||||
|
||||
if (object.type === 'group') {
|
||||
object._objects.forEach((obj) => {
|
||||
if (obj.hasOwnProperty('texts')) {
|
||||
obj.texts.forEach((text) => {
|
||||
canvas?.remove(text)
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (object.hasOwnProperty('texts')) {
|
||||
object.texts.forEach((text) => {
|
||||
canvas?.remove(text)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -609,6 +625,21 @@ export function useCommonUtils() {
|
||||
commonDeleteText(obj)
|
||||
})
|
||||
}
|
||||
|
||||
selectedObj.forEach((obj) => {
|
||||
if (obj.type === 'group') {
|
||||
obj._objects.forEach((lines) => {
|
||||
if (lines.hasOwnProperty('arrow')) {
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj1) => obj1.name === 'arrow' && lines.id === obj1.parentId)
|
||||
.forEach((arrow) => {
|
||||
canvas?.remove(arrow)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const moveObject = () => {
|
||||
|
||||
@ -147,7 +147,7 @@ export function useMasterController() {
|
||||
],
|
||||
}
|
||||
|
||||
return await post({ url: '/api/v1/master/getPcsSeriesItemList', data: test }).then((res) => {
|
||||
return await post({ url: '/api/v1/master/getPcsSeriesItemList', data: params }).then((res) => {
|
||||
return res
|
||||
})
|
||||
}
|
||||
@ -173,6 +173,22 @@ export function useMasterController() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* PCS로 회로 구성 가능 여부 체크
|
||||
* @param {Max접속(과적)여부} maxConnYn
|
||||
* @param {동일회로도여부} smpCirYn
|
||||
* @param {한랭지여부} coldZoneYn
|
||||
* @param {사용된 모듈 아이템 List} useModuleItemList
|
||||
* @param {지붕면별 목록} roofSurfaceList
|
||||
* @param {PCS 제품 목록} pcsItemList
|
||||
* @returns
|
||||
*/
|
||||
const getPcsVoltageChk = async (params = null) => {
|
||||
return await post({ url: '/api/v1/master/getPcsVoltageChk', data: params }).then((res) => {
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* PCS 승압설정 정보 조회
|
||||
* @param {Max접속(과적)여부} maxConnYn
|
||||
@ -195,10 +211,7 @@ export function useMasterController() {
|
||||
pcsItemList: params2.pcsItemList,
|
||||
}
|
||||
|
||||
console.log('🚀 ~ getPcsVoltageStepUpList ~ params >>>>> :', params)
|
||||
|
||||
return await post({ url: '/api/v1/master/getPcsVoltageStepUpList', data: params }).then((res) => {
|
||||
console.log('🚀🚀 ~ getPcsVoltageStepUpList ~ res:', res)
|
||||
return res
|
||||
})
|
||||
}
|
||||
@ -212,6 +225,7 @@ export function useMasterController() {
|
||||
getPcsMakerList,
|
||||
getPcsModelList,
|
||||
getPcsAutoRecommendList,
|
||||
getPcsVoltageChk,
|
||||
getPcsManualConfChk,
|
||||
getPcsVoltageStepUpList,
|
||||
}
|
||||
|
||||
@ -615,7 +615,7 @@ export function useModuleBasicSetting() {
|
||||
for (let i = 0; i <= totalWidth; i++) {
|
||||
leftMargin = i === 0 ? 0 : intvHor * i
|
||||
chidoriLength = 0
|
||||
if (isChidori) {
|
||||
if (isChidori && !isMaxSetup) {
|
||||
chidoriLength = j % 2 === 0 ? 0 : width / 2 - intvHor
|
||||
}
|
||||
|
||||
@ -716,7 +716,7 @@ export function useModuleBasicSetting() {
|
||||
for (let j = 0; j < totalHeight; j++) {
|
||||
leftMargin = j === 0 ? 0 : intvVer * j
|
||||
chidoriLength = 0
|
||||
if (isChidori) {
|
||||
if (isChidori && !isMaxSetup) {
|
||||
chidoriLength = i % 2 === 0 ? 0 : height / 2
|
||||
}
|
||||
|
||||
@ -827,7 +827,7 @@ export function useModuleBasicSetting() {
|
||||
for (let i = 0; i < diffRightEndPoint; i++) {
|
||||
leftMargin = i === 0 ? 0 : intvHor * i
|
||||
chidoriLength = 0
|
||||
if (isChidori) {
|
||||
if (isChidori && !isMaxSetup) {
|
||||
chidoriLength = j % 2 === 0 ? 0 : width / 2 - intvHor
|
||||
}
|
||||
|
||||
@ -927,7 +927,7 @@ export function useModuleBasicSetting() {
|
||||
leftMargin = j === 0 ? 0 : intvVer * j
|
||||
|
||||
chidoriLength = 0
|
||||
if (isChidori) {
|
||||
if (isChidori && !isMaxSetup) {
|
||||
chidoriLength = i % 2 === 0 ? 0 : height / 2 - intvHor
|
||||
}
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@ import { useContext, useEffect, useState } from 'react'
|
||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||
|
||||
import { selectedModuleState, moduleSelectionInitParamsState, moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
|
||||
export function useModuleSelection(props) {
|
||||
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
|
||||
@ -30,6 +30,8 @@ export function useModuleSelection(props) {
|
||||
setSelectedSurfaceType(managementState?.surfaceType)
|
||||
}
|
||||
|
||||
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
|
||||
|
||||
//탭별 파라메터 초기화
|
||||
useEffect(() => {
|
||||
bindInitData()
|
||||
@ -94,6 +96,13 @@ export function useModuleSelection(props) {
|
||||
}
|
||||
}
|
||||
|
||||
//데이터가 있으면 모듈 자동 선택
|
||||
useEffect(() => {
|
||||
if (moduleList.length > 0 && isObjectNotEmpty(moduleSelectionData.module)) {
|
||||
handleChangeModule(moduleSelectionData.module)
|
||||
}
|
||||
}, [moduleList])
|
||||
|
||||
const handleChangeModule = (option) => {
|
||||
//선택된 모듈
|
||||
setSelectedModules(option) //선택값 저장
|
||||
|
||||
419
src/hooks/module/useModuleTabContents.js
Normal file
419
src/hooks/module/useModuleTabContents.js
Normal file
@ -0,0 +1,419 @@
|
||||
import { useEffect, useState, useRef } from 'react'
|
||||
import { useRecoilValue, useRecoilState } from 'recoil'
|
||||
import { pitchTextSelector } from '@/store/canvasAtom'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||
import { moduleSelectionDataState, moduleSelectionInitParamsState, selectedModuleState } from '@/store/selectedModuleOptions'
|
||||
import { isObjectNotEmpty, isEqualObjects } from '@/util/common-utils'
|
||||
import { addedRoofsState } from '@/store/settingAtom'
|
||||
|
||||
export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) {
|
||||
const addRoofsArray = useRecoilValue(addedRoofsState)
|
||||
const globalPitchText = useRecoilValue(pitchTextSelector) //피치 텍스트
|
||||
|
||||
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 moduleSelectionInitOriginData = useRef(moduleSelectionInitParams)
|
||||
|
||||
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()
|
||||
|
||||
//서까래간격 변경
|
||||
const handleChangeRaftBase = (option) => {
|
||||
setSelectedRaftBase(option)
|
||||
setTrestleParams({ ...trestleParams, raftBaseCd: option.clCode }) //가대메이커
|
||||
setConstMthdList([]) //공법 초기화
|
||||
setRoofBaseList([]) //지붕밑바탕 초기화
|
||||
setConstructionList([]) //공법 초기화
|
||||
}
|
||||
|
||||
//처마력바 체크
|
||||
const handleCvrChecked = () => {
|
||||
setCvrChecked(!cvrChecked)
|
||||
setSelectedConstruction({ ...selectedConstruction, setupCover: !cvrChecked })
|
||||
}
|
||||
|
||||
//눈막이금구 체크
|
||||
const handleSnowGdChecked = () => {
|
||||
setSnowGdChecked(!snowGdChecked)
|
||||
setSelectedConstruction({ ...selectedConstruction, setupSnowCover: !snowGdChecked })
|
||||
}
|
||||
|
||||
const getConstructionListData = async (params) => {
|
||||
if (params.trestleMkrCd && params.constMthdCd && params.roofBaseCd) {
|
||||
const optionsList = await getConstructionList(params)
|
||||
setConstructionList(optionsList.data)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setHajebichi(addRoof.hajebichi)
|
||||
setLengthBase(addRoof.lenBase)
|
||||
|
||||
// 202600 경사도
|
||||
const raftCodeList = findCommonCode('203800')
|
||||
//서까래 코드
|
||||
raftCodeList.forEach((obj) => {
|
||||
obj.name = obj.clCodeNm
|
||||
obj.id = obj.clCode
|
||||
})
|
||||
setRaftCodes(raftCodeList)
|
||||
|
||||
console.log('moduleSelectionData', moduleSelectionData)
|
||||
}, [])
|
||||
|
||||
//리코일에 데이터가 담기는 시점에 시작
|
||||
useEffect(() => {
|
||||
if (
|
||||
isObjectNotEmpty(moduleSelectionData.roofConstructions[tabIndex]) &&
|
||||
isObjectNotEmpty(moduleSelectionData.roofConstructions[tabIndex].trestle) &&
|
||||
isObjectNotEmpty(moduleSelectionData.roofConstructions[tabIndex].construction)
|
||||
) {
|
||||
setModuleConstructionSelectionData(moduleSelectionData.roofConstructions[tabIndex])
|
||||
}
|
||||
}, [moduleSelectionData])
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(moduleConstructionSelectionData)) {
|
||||
setIsExistData(true)
|
||||
}
|
||||
}, [moduleConstructionSelectionData])
|
||||
|
||||
//높이를 변경하면 addRoofs에 적용
|
||||
// useEffect(() => {
|
||||
// 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 (isExistData) {
|
||||
setConstructionListParams({
|
||||
...moduleSelectionInitParams,
|
||||
...roofBaseParams,
|
||||
roofBaseCd: selectedRoofBase.roofBaseCd,
|
||||
inclCd: addRoof.pitch,
|
||||
roofPitch: hajebichiRef.current ? hajebichiRef.current.value : 0,
|
||||
raftBaseCd: addRoof.raftBaseCd,
|
||||
})
|
||||
}
|
||||
}, [selectedRoofBase])
|
||||
|
||||
useEffect(() => {
|
||||
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(() => {
|
||||
//lengbase는 무조건 있다고 가정 하고 최초에 실행 방지
|
||||
if (selectedModules) {
|
||||
//가대메이커 파라메터 만들기
|
||||
setTrestleParams({
|
||||
moduleTpCd: selectedModules.itemTp,
|
||||
roofMatlCd: addRoof.roofMatlCd,
|
||||
raftBaseCd: addRoof.raftBaseCd,
|
||||
workingWidth: lengthBase,
|
||||
})
|
||||
}
|
||||
}, [selectedModules])
|
||||
|
||||
//가대메이커 api 호출
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(trestleParams)) {
|
||||
getModuleOptionsListData(trestleParams, 'trestle')
|
||||
}
|
||||
}, [trestleParams])
|
||||
|
||||
//가대메이커 변경 함수
|
||||
const handleChangeTrestle = (option) => {
|
||||
setSelectedTrestle(option) //선택값 저장
|
||||
setConstructionParams({ ...trestleParams, trestleMkrCd: option.trestleMkrCd, constMthdCd: '', roofBaseCd: '' })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(constructionParams)) {
|
||||
getModuleOptionsListData(constructionParams, 'construction')
|
||||
}
|
||||
}, [constructionParams])
|
||||
|
||||
//공법 변경
|
||||
const handleChangeConstMthd = (option) => {
|
||||
setSelectedConstMthd(option) //선택된값 저장
|
||||
setRoofBaseParams({
|
||||
...trestleParams,
|
||||
trestleMkrCd: selectedTrestle.trestleMkrCd,
|
||||
constMthdCd: option.constMthdCd,
|
||||
roofBaseCd: '',
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(roofBaseParams)) {
|
||||
getModuleOptionsListData(roofBaseParams, 'roofBase')
|
||||
}
|
||||
}, [roofBaseParams])
|
||||
|
||||
const handleChangeRoofBase = (option) => {
|
||||
setConstructionListParams({
|
||||
...moduleSelectionInitParams,
|
||||
trestleMkrCd: selectedTrestle.trestleMkrCd,
|
||||
constMthdCd: selectedConstMthd.constMthdCd,
|
||||
roofBaseCd: option.roofBaseCd,
|
||||
inclCd: addRoof.pitch,
|
||||
roofPitch: hajebichiRef.current ? hajebichiRef.current.value : 0,
|
||||
raftBaseCd: addRoof.raftBaseCd,
|
||||
roofMatlCd: addRoof.roofMatlCd,
|
||||
})
|
||||
setSelectedRoofBase(option)
|
||||
}
|
||||
|
||||
//공법 리스트 변경 함수
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(constructionListParams)) {
|
||||
getConstructionListData(constructionListParams)
|
||||
}
|
||||
}, [constructionListParams])
|
||||
|
||||
//공법 선택 함수
|
||||
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
|
||||
|
||||
setCvrYn(selectedConstruction.cvrYn)
|
||||
setSnowGdPossYn(selectedConstruction.snowGdPossYn)
|
||||
|
||||
//기존에 선택된 데이터가 있으면 체크한다
|
||||
if (moduleConstructionSelectionData && moduleConstructionSelectionData.construction) {
|
||||
selectedConstruction.setupCover = moduleConstructionSelectionData.construction.setupCover || false
|
||||
selectedConstruction.setupSnowCover = moduleConstructionSelectionData.construction.setupSnowCover || false
|
||||
setCvrChecked(selectedConstruction.setupCover)
|
||||
setSnowGdChecked(selectedConstruction.setupSnowCover)
|
||||
}
|
||||
|
||||
setSelectedConstruction(selectedConstruction)
|
||||
} else {
|
||||
constructionRef.current.forEach((ref) => {
|
||||
ref.classList.remove('blue')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//공법 선택시 이후 프로세스
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(selectedRoofBase) && isObjectNotEmpty(selectedConstruction)) {
|
||||
if (tabIndex === roofTab) {
|
||||
const common = { ...moduleSelectionInitParams }
|
||||
const module = { ...selectedModules }
|
||||
const newRoofConstructions = {
|
||||
roofIndex: tabIndex,
|
||||
addRoof: addRoof,
|
||||
trestle: selectedRoofBase,
|
||||
construction: selectedConstruction,
|
||||
}
|
||||
|
||||
const index = tempModuleSelectionData.roofConstructions.findIndex((obj) => obj.roofIndex === tabIndex)
|
||||
|
||||
if (index > -1) {
|
||||
const newArray = [
|
||||
...tempModuleSelectionData.roofConstructions.slice(0, index),
|
||||
newRoofConstructions,
|
||||
...tempModuleSelectionData.roofConstructions.slice(index + 1),
|
||||
]
|
||||
setTempModuleSelectionData({ common: common, module: module, roofConstructions: newArray })
|
||||
} else {
|
||||
setTempModuleSelectionData({
|
||||
common: common,
|
||||
module: module,
|
||||
roofConstructions: [...tempModuleSelectionData.roofConstructions, { ...newRoofConstructions }],
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [selectedConstruction])
|
||||
|
||||
const getModuleOptionsListData = async (params, type) => {
|
||||
const optionsList = await getTrestleList(params)
|
||||
|
||||
if (optionsList.data.length > 0) {
|
||||
if (type === 'trestle') {
|
||||
setTrestleList(optionsList.data)
|
||||
if (isExistData) {
|
||||
handleChangeTrestle(moduleConstructionSelectionData?.trestle)
|
||||
} else {
|
||||
setConstMthdList([])
|
||||
setRoofBaseList([])
|
||||
}
|
||||
} else if (type === 'construction') {
|
||||
setConstMthdList(optionsList.data)
|
||||
if (isExistData) {
|
||||
handleChangeConstMthd(moduleConstructionSelectionData?.trestle)
|
||||
} else {
|
||||
setRoofBaseList([])
|
||||
}
|
||||
} else if (type === 'roofBase') {
|
||||
setRoofBaseList(optionsList.data)
|
||||
if (isExistData) {
|
||||
handleChangeRoofBase(moduleConstructionSelectionData?.trestle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
//모듈이 선택되어있을때
|
||||
if (moduleSelectionInitOriginData.current.moduleItemId && moduleSelectionInitOriginData.current.moduleTpCd) {
|
||||
//초기에 들어온 데이터가 수정된 데이터가 값이 다르다면`
|
||||
if (!isEqualObjects(moduleSelectionInitOriginData.current, moduleSelectionInitParams)) {
|
||||
//가대 선택 초기화
|
||||
setSelectedTrestle({})
|
||||
|
||||
//공법 선택 초기화
|
||||
setSelectedConstMthd({})
|
||||
|
||||
//지붕밑바탕 선택 초기화
|
||||
setSelectedRoofBase({})
|
||||
|
||||
//공법 리스트 초기화
|
||||
setConstructionList([])
|
||||
|
||||
// 기본 정보 초기화
|
||||
setModuleSelectionData({
|
||||
...moduleSelectionData,
|
||||
roofConstructions: [],
|
||||
})
|
||||
|
||||
// 선택 데이터 초 기화
|
||||
setModuleConstructionSelectionData({
|
||||
addRoof: addRoof,
|
||||
trestle: {},
|
||||
construction: {},
|
||||
})
|
||||
|
||||
//임시 데이터 초기화
|
||||
setTempModuleSelectionData({
|
||||
...moduleSelectionData,
|
||||
roofConstructions: [],
|
||||
})
|
||||
|
||||
//처마커버 해제
|
||||
setCvrChecked(false)
|
||||
//눈막이금구 해제
|
||||
setSnowGdChecked(false)
|
||||
|
||||
// 데이터 없음으로 변경
|
||||
setIsExistData(false)
|
||||
|
||||
//변경된 데이터를 ref에 저장
|
||||
moduleSelectionInitOriginData.current = moduleSelectionInitParams
|
||||
}
|
||||
}
|
||||
}, [moduleSelectionInitParams])
|
||||
|
||||
return {
|
||||
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,
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ import { canvasState } from '@/store/canvasAtom'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
||||
import { getDegreeByChon, getTrestleLength } from '@/util/canvas-util'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
// 회로 및 가대설정
|
||||
export const useTrestle = () => {
|
||||
@ -33,15 +34,13 @@ export const useTrestle = () => {
|
||||
alert('앞에서 셋팅 안됨')
|
||||
return
|
||||
}
|
||||
let isEaveBar = construction.setupCover
|
||||
|
||||
let moduleRowsTotCnt = 0
|
||||
let isEaveBar = construction.setupCover
|
||||
let isSnowGuard = construction.setupSnowCover
|
||||
const direction = parent.direction
|
||||
const rack = surface.trestleDetail.rack
|
||||
let { rackQty, rackIntvlPct, rackYn, cvrPlvrYn } = surface.trestleDetail
|
||||
rackYn = 'N'
|
||||
rackQty = 5
|
||||
cvrPlvrYn = 'Y'
|
||||
|
||||
if (!rack) {
|
||||
//25/01/16 기준 랙이 없는 경우는 그냥 안그려준다.
|
||||
@ -93,6 +92,8 @@ export const useTrestle = () => {
|
||||
leftExposedHalfTopModules.length > 0 ||
|
||||
rightExposedHalfTopPoints.length > 0
|
||||
|
||||
surface.set({ isChidory: isChidory })
|
||||
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => ['eaveBar', 'halfEaveBar'].includes(obj.name) && obj.parent === surface)
|
||||
@ -112,6 +113,7 @@ export const useTrestle = () => {
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
surfaceId: surface.id,
|
||||
parentId: module.id,
|
||||
})
|
||||
canvas.add(eaveBar)
|
||||
@ -141,6 +143,7 @@ export const useTrestle = () => {
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
surfaceId: surface.id,
|
||||
parentId: module.id,
|
||||
})
|
||||
canvas.add(halfEaveBar)
|
||||
@ -179,6 +182,8 @@ export const useTrestle = () => {
|
||||
const horizontal = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlHor : surface.trestleDetail.moduleIntvlVer
|
||||
|
||||
const vertical = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlVer : surface.trestleDetail.moduleIntvlHor
|
||||
|
||||
let mostRowsModule = 0 // 모듈 최대 단 수
|
||||
// 가대 설치를 위한 가장 아래 모듈로부터 위로 몇단인지 계산
|
||||
// 오른쪽,왼쪽 둘 다 아래에 아무것도 없는, 처마 커버를 필요로 하는 모듈
|
||||
exposedBottomModules.forEach((module) => {
|
||||
@ -296,6 +301,8 @@ export const useTrestle = () => {
|
||||
return rack.value.moduleRows === centerRows
|
||||
})?.value.racks
|
||||
|
||||
mostRowsModule = Math.max(leftRows, rightRows, centerRows, mostRowsModule)
|
||||
|
||||
if (rackYn === 'Y') {
|
||||
drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
|
||||
drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn)
|
||||
@ -356,7 +363,7 @@ export const useTrestle = () => {
|
||||
const leftRacks = rackInfos.find((rack) => {
|
||||
return rack.value.moduleRows === leftRows
|
||||
})?.value.racks
|
||||
|
||||
mostRowsModule = Math.max(leftRows, mostRowsModule)
|
||||
if (rackYn === 'Y') {
|
||||
drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
|
||||
}
|
||||
@ -409,6 +416,8 @@ export const useTrestle = () => {
|
||||
const rightRacks = rackInfos.find((rack) => {
|
||||
return rack.value.moduleRows === rightRows
|
||||
})?.value.racks
|
||||
|
||||
mostRowsModule = Math.max(rightRows, mostRowsModule)
|
||||
// 해당 rack으로 그려준다.
|
||||
if (rackYn === 'Y') {
|
||||
drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn)
|
||||
@ -417,12 +426,16 @@ export const useTrestle = () => {
|
||||
module.set({ rightRows })
|
||||
})
|
||||
|
||||
surface.set({ moduleRowsTotCnt: mostRowsModule })
|
||||
|
||||
if (rackYn === 'N') {
|
||||
// rack이 없을경우
|
||||
installBracketWithOutRack(surface, exposedBottomModules, leftExposedHalfBottomModules, rightExposedHalfBottomPoints, isChidory)
|
||||
} else if (rackYn === 'Y') {
|
||||
installBracket(surface)
|
||||
}
|
||||
|
||||
console.log(getTrestleParams(surface))
|
||||
})
|
||||
}
|
||||
|
||||
@ -612,32 +625,69 @@ export const useTrestle = () => {
|
||||
switch (direction) {
|
||||
case 'south': {
|
||||
rackInfos.forEach((rackInfo) => {
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct, rackRowsCd, smartRack, smartRackYn } = rackInfo
|
||||
let rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
|
||||
const rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
if (smartRackYn === 'Y') {
|
||||
let smartRackId = uuidv4()
|
||||
smartRack.forEach(({ seq, setRackTpCd, setRackTpLen, supFitQty }) => {
|
||||
rackLength = getTrestleLength(setRackTpLen, degree) / 10
|
||||
if (setRackTpCd === 'RACK') {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], {
|
||||
name: 'smartRack',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY - rackLength], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
fill: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackId: itemId,
|
||||
direction: 'top',
|
||||
})
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackRowsCd,
|
||||
seq,
|
||||
smartRackId,
|
||||
rackId: itemId,
|
||||
direction: 'top',
|
||||
})
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointY -= rackLength + 8
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY - rackLength], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
fill: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackRowsCd,
|
||||
rackId: itemId,
|
||||
direction: 'top',
|
||||
})
|
||||
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
startPointY -= rackLength + 8
|
||||
})
|
||||
@ -646,32 +696,68 @@ export const useTrestle = () => {
|
||||
}
|
||||
case 'east': {
|
||||
rackInfos.forEach((rackInfo) => {
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct, rackRowsCd, smartRack, smartRackYn } = rackInfo
|
||||
|
||||
const rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
let rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
if (smartRackYn === 'Y') {
|
||||
let smartRackId = uuidv4()
|
||||
smartRack.forEach(({ seq, setRackTpCd, setRackTpLen, supFitQty }) => {
|
||||
rackLength = getTrestleLength(setRackTpLen, degree) / 10
|
||||
if (setRackTpCd === 'RACK') {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX - rackLength, startPointY], {
|
||||
name: 'smartRack',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackRowsCd,
|
||||
seq,
|
||||
smartRackId,
|
||||
rackId: itemId,
|
||||
direction: 'left',
|
||||
})
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointX -= rackLength
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX - rackLength, startPointY], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackYn,
|
||||
rackRowsCd,
|
||||
rackId: itemId,
|
||||
direction: 'left',
|
||||
})
|
||||
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX - rackLength, startPointY], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackYn,
|
||||
rackId: itemId,
|
||||
direction: 'left',
|
||||
})
|
||||
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
startPointX -= rackLength + 8
|
||||
})
|
||||
@ -680,31 +766,66 @@ export const useTrestle = () => {
|
||||
|
||||
case 'west': {
|
||||
rackInfos.forEach((rackInfo) => {
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct, rackRowsCd, smartRack, smartRackYn } = rackInfo
|
||||
let rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
if (smartRackYn === 'Y') {
|
||||
let smartRackId = uuidv4()
|
||||
smartRack.forEach(({ seq, setRackTpCd, setRackTpLen, supFitQty }) => {
|
||||
rackLength = getTrestleLength(setRackTpLen, degree) / 10
|
||||
if (setRackTpCd === 'RACK') {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], {
|
||||
name: 'smartRack',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackRowsCd,
|
||||
seq,
|
||||
smartRackId,
|
||||
rackId: itemId,
|
||||
direction: 'right',
|
||||
})
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointX += rackLength + 8
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackRowsCd,
|
||||
rackId: itemId,
|
||||
direction: 'right',
|
||||
})
|
||||
|
||||
const rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackId: itemId,
|
||||
direction: 'right',
|
||||
})
|
||||
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
startPointX += rackLength + 8
|
||||
})
|
||||
@ -712,32 +833,66 @@ export const useTrestle = () => {
|
||||
}
|
||||
case 'north': {
|
||||
rackInfos.forEach((rackInfo) => {
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo
|
||||
|
||||
const rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY + rackLength], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackId: itemId,
|
||||
direction: 'bottom',
|
||||
})
|
||||
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
const { rackLen, itemId, supFitQty, supFitIntvlPct, rackRowsCd, smartRack, smartRackYn } = rackInfo
|
||||
let rackLength = getTrestleLength(rackLen, degree) / 10
|
||||
if (smartRackYn === 'Y') {
|
||||
let smartRackId = uuidv4()
|
||||
smartRack.forEach(({ seq, setRackTpCd, setRackTpLen, supFitQty }) => {
|
||||
rackLength = getTrestleLength(setRackTpLen, degree) / 10
|
||||
if (setRackTpCd === 'RACK') {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], {
|
||||
name: 'smartRack',
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackRowsCd,
|
||||
seq,
|
||||
smartRackId,
|
||||
rackId: itemId,
|
||||
direction: 'right',
|
||||
})
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointY += rackLength + 8
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY + rackLength], {
|
||||
name: 'rack',
|
||||
stroke: 'red',
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
},
|
||||
parentId: module.id,
|
||||
surfaceId: surface.id,
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackRowsCd,
|
||||
rackId: itemId,
|
||||
direction: 'bottom',
|
||||
})
|
||||
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
}
|
||||
startPointY += rackLength + 8
|
||||
})
|
||||
break
|
||||
@ -777,6 +932,7 @@ export const useTrestle = () => {
|
||||
fill: 'green',
|
||||
name: 'bracket',
|
||||
parentId: rack.parentId,
|
||||
surfaceId: surface.id,
|
||||
width: bracketLength,
|
||||
height: bracketLength,
|
||||
selectable: false,
|
||||
@ -795,6 +951,7 @@ export const useTrestle = () => {
|
||||
fill: 'green',
|
||||
name: 'bracket',
|
||||
parentId: rack.parentId,
|
||||
surfaceId: surface.id,
|
||||
width: bracketLength,
|
||||
height: bracketLength,
|
||||
selectable: false,
|
||||
@ -812,6 +969,7 @@ export const useTrestle = () => {
|
||||
top: y2 - bracketLength / 3,
|
||||
fill: 'green',
|
||||
parentId: rack.parentId,
|
||||
surfaceId: surface.id,
|
||||
name: 'bracket',
|
||||
width: bracketLength,
|
||||
height: bracketLength,
|
||||
@ -831,6 +989,7 @@ export const useTrestle = () => {
|
||||
fill: 'green',
|
||||
name: 'bracket',
|
||||
parentId: rack.parentId,
|
||||
surfaceId: surface.id,
|
||||
width: bracketLength,
|
||||
height: bracketLength,
|
||||
selectable: false,
|
||||
@ -845,9 +1004,10 @@ export const useTrestle = () => {
|
||||
|
||||
//랙 없음 인 경우 지지금구 설치
|
||||
const installBracketWithOutRack = (surface, exposedBottomModules, leftExposedHalfBottomModules, rightExposedHalfBottomPoints, isChidory) => {
|
||||
let { rackQty, rackIntvlPct, moduleIntvlHor, moduleIntvlVer } = surface.trestleDetail
|
||||
let { rackQty, rackIntvlPct, moduleIntvlHor, moduleIntvlVer, lessSupFitQty, lessSupFitIntvlPct } = surface.trestleDetail
|
||||
const direction = surface.direction
|
||||
rackQty = 3
|
||||
rackIntvlPct = 10
|
||||
|
||||
canvas.renderAll()
|
||||
exposedBottomModules.forEach((module) => {
|
||||
@ -990,6 +1150,7 @@ export const useTrestle = () => {
|
||||
fill: 'green',
|
||||
name: 'bracket',
|
||||
parentId: module.id,
|
||||
surfaceId: module.surfaceId,
|
||||
width: 10,
|
||||
height: 10,
|
||||
selectable: false,
|
||||
@ -1318,5 +1479,329 @@ export const useTrestle = () => {
|
||||
return groups
|
||||
}
|
||||
|
||||
return { apply }
|
||||
const getTrestleParams = (surface) => {
|
||||
const result = calculateForApi(surface)
|
||||
|
||||
const eaveBar = canvas.getObjects().filter((obj) => obj.surfaceId === surface.id && obj.name === 'eaveBar')
|
||||
const halfEaveBar = canvas.getObjects().filter((obj) => obj.surfaceId === surface.id && obj.name === 'halfEaveBar')
|
||||
|
||||
const rackList = canvas.getObjects().filter((obj) => obj.surfaceId === surface.id && obj.name === 'rack')
|
||||
const smartRackList = canvas.getObjects().filter((obj) => obj.surfaceId === surface.id && obj.name === 'smartRack')
|
||||
// smartRackList을 smartRackId 기준으로 그룹화 한 배열
|
||||
const smartRackGroup = smartRackList.reduce((acc, cur) => {
|
||||
if (!acc[cur.smartRackId]) {
|
||||
acc[cur.smartRackId] = []
|
||||
}
|
||||
acc[cur.smartRackId].push(cur)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const bracketList = canvas.getObjects().filter((obj) => obj.surfaceId === surface.id && obj.name === 'bracket')
|
||||
let rackParams = rackList.map((rack, index) => {
|
||||
return {
|
||||
seq: index,
|
||||
rackId: rack.rackId,
|
||||
rackFittingCnt: rack.supFitQty,
|
||||
rackRows: rack.rackRowsCd,
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
exposedLowerBottomTotCnt: result.exposedBottom, // 노출 최하면 갯수
|
||||
exposedHalfBottomTotCnt: result.exposedHalfBottom, // 노출 반하면 갯수
|
||||
exposedTopTotCnt: result.exposedTop, // 노출 상면 총 수
|
||||
exposedHalfTopTotCnt: result.exposedHalfTop, // 노출 반상면 총 수
|
||||
exposedBottomTotCnt: result.exposedBottomPoints.length, // 노출 하면 수
|
||||
touchedSurfaceTotCnt: result.touchDimension, // 접면 총 수
|
||||
touchedHalfSurfaceTotCnt: result.halfTouchDimension, // 반접면 총 수
|
||||
moduleRowsTotCnt: surface.moduleRowsTotCnt, // 모듈 총 단 수
|
||||
eavesTotCnt: eaveBar.length,
|
||||
eavesHalfTotCnt: halfEaveBar.length,
|
||||
racks: rackParams,
|
||||
rackTotCnt: rackList.length ?? 0 + smartRackGroup.length ?? 0,
|
||||
rackFittingCnt: bracketList.length,
|
||||
moduleRows: getMostLeftModules(surface),
|
||||
}
|
||||
}
|
||||
|
||||
// 가장 왼쪽에 있는 모듈을 기준으로 같은 단에 있는 모듈들 파라미터 생성
|
||||
const getMostLeftModules = (surface) => {
|
||||
const { direction, modules } = surface
|
||||
const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId)
|
||||
const roofMaterialIndex = parent.roofMaterial.index
|
||||
const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction
|
||||
let isEaveBar = construction.setupCover
|
||||
let isSnowGuard = construction.setupSnowCover
|
||||
let { rackYn, cvrPlvrYn, moduleIntvlHor, moduleIntvlVer, rackQty, lessSupFitQty } = surface.trestleDetail
|
||||
|
||||
if (rackYn === 'N') {
|
||||
rackQty = lessSupFitQty
|
||||
}
|
||||
|
||||
// 같은 단에 있는 모듈들의 리스트
|
||||
let sameLineModuleList = []
|
||||
let result = []
|
||||
|
||||
if (direction === 'south') {
|
||||
// 모듈의 top으로 groupBy
|
||||
const groupedByTop = modules.reduce((acc, module) => {
|
||||
const key = module.top
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(module)
|
||||
return acc
|
||||
}, {})
|
||||
// groupedByTop의 키값을 기준으로 정렬한 데이터를 배열로 변환
|
||||
sameLineModuleList = Object.values(groupedByTop).sort((a, b) => b[0].top - a[0].top)
|
||||
} else if (direction === 'north') {
|
||||
const groupedByTop = modules.reduce((acc, module) => {
|
||||
const key = module.top
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(module)
|
||||
return acc
|
||||
}, {})
|
||||
sameLineModuleList = Object.values(groupedByTop).sort((a, b) => a[0].top - b[0].top)
|
||||
} else if (direction === 'east') {
|
||||
const groupedByLeft = modules.reduce((acc, module) => {
|
||||
const key = module.left
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(module)
|
||||
return acc
|
||||
}, {})
|
||||
sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => a[0].left - b[0].left)
|
||||
} else if (direction === 'west') {
|
||||
const groupedByLeft = modules.reduce((acc, module) => {
|
||||
const key = module.left
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(module)
|
||||
return acc
|
||||
}, {})
|
||||
sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => b[0].left - a[0].left)
|
||||
}
|
||||
sameLineModuleList.forEach((modules, index) => {
|
||||
const moduleRowResultData = {
|
||||
seq: index,
|
||||
moduleItemId: modules[0].moduleInfo.itemId,
|
||||
moduleTpCd: modules[0].moduleInfo.itemTp,
|
||||
moduleCnt: modules.length,
|
||||
exposedBottomCnt: 0,
|
||||
exposedHalfBottomCnt: 0,
|
||||
exposedTopCnt: 0,
|
||||
exposedHalfTopCnt: 0,
|
||||
touchedSurfaceCnt: 0,
|
||||
touchedHalfSurfaceCnt: 0,
|
||||
exposedBottomBracketCnt: 0,
|
||||
exposedHalfBottomBracketCnt: 0,
|
||||
exposedTopBracketCnt: 0,
|
||||
exposedHalfTopBracketCnt: 0,
|
||||
touchedSurfaceBracketCnt: 0,
|
||||
touchedHalfSurfaceBracketCnt: 0,
|
||||
eavesCnt: 0,
|
||||
eavesHalfCnt: 0,
|
||||
exposedSideEavesCnt: 0,
|
||||
}
|
||||
|
||||
if (direction === 'south') {
|
||||
modules.sort((a, b) => a.left - b.left)
|
||||
} else if (direction === 'north') {
|
||||
modules.sort((a, b) => b.left - a.left)
|
||||
} else if (direction === 'east') {
|
||||
modules.sort((a, b) => a.top - b.top)
|
||||
} else if (direction === 'west') {
|
||||
modules.sort((a, b) => b.top - a.top)
|
||||
}
|
||||
// 모듈 하면,최하면 등 구해야함
|
||||
modules.forEach((module, index) => {
|
||||
// 해당 모듈 주변에 다른 모듈이 있는지 확인
|
||||
let {
|
||||
bottomModule,
|
||||
topModule,
|
||||
halfBottomLeftModule,
|
||||
halfBottomRightModule,
|
||||
halfTopLeftModule,
|
||||
halfTopRightModule,
|
||||
leftModule,
|
||||
rightModule,
|
||||
bottomLeftModule,
|
||||
bottomRightModule,
|
||||
} = findSideModule(module, surface)
|
||||
if (bottomModule) {
|
||||
moduleRowResultData.touchedSurfaceCnt++
|
||||
}
|
||||
if (!bottomModule) {
|
||||
if (halfBottomLeftModule && halfBottomRightModule) {
|
||||
moduleRowResultData.touchedSurfaceCnt++
|
||||
} else if ((halfBottomLeftModule && !halfBottomRightModule) || (!halfBottomLeftModule && halfBottomRightModule)) {
|
||||
moduleRowResultData.touchedHalfSurfaceCnt++
|
||||
moduleRowResultData.exposedHalfBottomCnt++
|
||||
if (cvrPlvrYn === 'Y') {
|
||||
moduleRowResultData.eavesHalfCnt++
|
||||
if (bottomLeftModule || bottomRightModule || halfBottomLeftModule || halfBottomRightModule) {
|
||||
//처마커버 한개 노출 추가
|
||||
moduleRowResultData.exposedSideEavesCnt++
|
||||
}
|
||||
}
|
||||
} else {
|
||||
moduleRowResultData.exposedBottomCnt++
|
||||
if (isEaveBar) {
|
||||
moduleRowResultData.eavesCnt++
|
||||
if ((rightModule && !leftModule) || (!rightModule && leftModule)) {
|
||||
// 둘중 하나가 없는경우는 처마커버 노출 추가
|
||||
moduleRowResultData.exposedSideEavesCnt++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!topModule) {
|
||||
if ((halfTopLeftModule && !halfTopRightModule) || (!halfTopLeftModule && halfTopRightModule)) {
|
||||
moduleRowResultData.exposedHalfTopCnt++
|
||||
} else if (!halfTopLeftModule && !halfTopRightModule) {
|
||||
moduleRowResultData.exposedTopCnt++
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
result.push(moduleRowResultData)
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 해당 모듈이 해당 설치면에서 상하좌우, 대각선에 있는지 확인
|
||||
const findSideModule = (module, surface) => {
|
||||
const { direction, modules } = surface
|
||||
let { rackYn, cvrPlvrYn, moduleIntvlHor, moduleIntvlVer, rackQty, lessSupFitQty } = surface.trestleDetail
|
||||
|
||||
const centerPoints = modules.map((module) => {
|
||||
return module.getCenterPoint()
|
||||
})
|
||||
|
||||
const horizontal = ['south', 'north'].includes(direction) ? moduleIntvlHor : moduleIntvlVer
|
||||
|
||||
const vertical = ['south', 'north'].includes(direction) ? moduleIntvlVer : moduleIntvlHor
|
||||
const maxX = 2 + horizontal * 3
|
||||
const maxY = 2 + vertical * 3
|
||||
let { width, height } = { ...module }
|
||||
let { x, y } = { ...module.getCenterPoint() }
|
||||
|
||||
let halfBottomLeftPoint
|
||||
let halfBottomRightPoint
|
||||
let halfTopLeftPoint
|
||||
let halfTopRightPoint
|
||||
let leftPoint
|
||||
let rightPoint
|
||||
let bottomLeftPoint
|
||||
let bottomRightPoint
|
||||
|
||||
let bottomModule
|
||||
let topModule
|
||||
let halfBottomLeftModule
|
||||
let halfBottomRightModule
|
||||
let halfTopLeftModule
|
||||
let halfTopRightModule
|
||||
let leftModule
|
||||
let rightModule
|
||||
let bottomLeftModule
|
||||
let bottomRightModule
|
||||
|
||||
switch (direction) {
|
||||
case 'south':
|
||||
width = width + horizontal
|
||||
height = height + vertical
|
||||
bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY)
|
||||
halfBottomLeftPoint = { x: x - width / 2, y: y + height }
|
||||
halfBottomRightPoint = { x: x + width / 2, y: y + height }
|
||||
topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY)
|
||||
halfTopLeftPoint = { x: x - width / 2, y: y - height }
|
||||
halfTopRightPoint = { x: x + width / 2, y: y - height }
|
||||
leftPoint = { x: x - width, y: y }
|
||||
rightPoint = { x: x + width, y: y }
|
||||
bottomLeftModule = { x: x - width, y: y + height }
|
||||
bottomRightModule = { x: x + width, y: y + height }
|
||||
break
|
||||
case 'north':
|
||||
width = width + horizontal
|
||||
height = height + vertical
|
||||
bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY)
|
||||
halfBottomLeftPoint = { x: x + width / 2, y: y - height }
|
||||
halfBottomRightPoint = { x: x - width / 2, y: y - height }
|
||||
topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY)
|
||||
halfTopLeftPoint = { x: x + width / 2, y: y + height }
|
||||
halfTopRightPoint = { x: x - width / 2, y: y + height }
|
||||
leftPoint = { x: x + width, y: y }
|
||||
rightPoint = { x: x - width, y: y }
|
||||
bottomLeftModule = { x: x + width, y: y - height }
|
||||
bottomRightModule = { x: x - width, y: y - height }
|
||||
break
|
||||
case 'east':
|
||||
bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
|
||||
width = width + horizontal
|
||||
halfBottomLeftPoint = { x: x + width, y: y + height / 2 }
|
||||
halfBottomRightPoint = { x: x + width, y: y - height / 2 }
|
||||
topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
|
||||
halfTopLeftPoint = { x: x - width, y: y + height / 2 }
|
||||
halfTopRightPoint = { x: x - width, y: y - height / 2 }
|
||||
leftPoint = { x: x, y: y + height }
|
||||
rightPoint = { x: x, y: y - height }
|
||||
bottomLeftModule = { x: x + width, y: y + height }
|
||||
bottomRightModule = { x: x + width, y: y - height }
|
||||
break
|
||||
case 'west':
|
||||
bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
|
||||
width = width + horizontal
|
||||
halfBottomLeftPoint = { x: x - width, y: y - height / 2 }
|
||||
halfBottomRightPoint = { x: x - width, y: y + height / 2 }
|
||||
topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
|
||||
halfTopLeftPoint = { x: x + width, y: y - height / 2 }
|
||||
halfTopRightPoint = { x: x + width, y: y + height / 2 }
|
||||
leftPoint = { x: x, y: y - height }
|
||||
rightPoint = { x: x, y: y + height }
|
||||
bottomLeftModule = { x: x - width, y: y - height }
|
||||
bottomRightModule = { x: x - width, y: y + height }
|
||||
break
|
||||
}
|
||||
|
||||
halfTopLeftModule = centerPoints.find(
|
||||
(centerPoint) => Math.abs(centerPoint.x - halfTopLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfTopLeftPoint.y) < maxY,
|
||||
)
|
||||
halfTopRightModule = centerPoints.find(
|
||||
(centerPoint) => Math.abs(centerPoint.x - halfTopRightPoint.x) < maxX && Math.abs(centerPoint.y - halfTopRightPoint.y) < maxY,
|
||||
)
|
||||
halfBottomLeftModule = centerPoints.find(
|
||||
(centerPoint) => Math.abs(centerPoint.x - halfBottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomLeftPoint.y) < maxY,
|
||||
)
|
||||
halfBottomRightModule = centerPoints.find(
|
||||
(centerPoint) => Math.abs(centerPoint.x - halfBottomRightPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomRightPoint.y) < maxY,
|
||||
)
|
||||
leftModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - leftPoint.x) < maxX && Math.abs(centerPoint.y - leftPoint.y) < maxY)
|
||||
rightModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - rightPoint.x) < maxX && Math.abs(centerPoint.y - rightPoint.y) < maxY)
|
||||
bottomLeftModule = centerPoints.find(
|
||||
(centerPoint) => Math.abs(centerPoint.x - bottomLeftModule.x) < maxX && Math.abs(centerPoint.y - bottomLeftModule.y) < maxY,
|
||||
)
|
||||
bottomRightModule = centerPoints.find(
|
||||
(centerPoint) => Math.abs(centerPoint.x - bottomRightModule.x) < maxX && Math.abs(centerPoint.y - bottomRightModule.y) < maxY,
|
||||
)
|
||||
|
||||
return {
|
||||
bottomModule,
|
||||
topModule,
|
||||
halfBottomLeftModule,
|
||||
halfBottomRightModule,
|
||||
halfTopLeftModule,
|
||||
halfTopRightModule,
|
||||
leftModule,
|
||||
rightModule,
|
||||
bottomLeftModule,
|
||||
bottomRightModule,
|
||||
}
|
||||
}
|
||||
|
||||
return { apply, getTrestleParams }
|
||||
}
|
||||
|
||||
@ -122,40 +122,47 @@ export function usePropertiesSetting(id) {
|
||||
const handleFix = () => {
|
||||
const isClose = confirm('외벽선 속성 설정을 완료하시겠습니까?')
|
||||
if (isClose) {
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
|
||||
const notSetAttributes = lines.filter((line) => !line.attributes?.type)
|
||||
if (notSetAttributes.length > 0) {
|
||||
// 세팅이 하나라도 안되어있으면 초기화
|
||||
lines.forEach((line) => {
|
||||
line.set({
|
||||
stroke: '#000000',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
})
|
||||
canvas.discardActiveObject()
|
||||
closePopup(id)
|
||||
return
|
||||
}
|
||||
|
||||
lines.forEach((line) => {
|
||||
line.set({
|
||||
attributes: line.attributes ? line.attributes : { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
||||
stroke: '#000000',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
|
||||
hideLine(line)
|
||||
})
|
||||
|
||||
const wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||
|
||||
wall.lines = [...lines]
|
||||
|
||||
const roof = drawRoofPolygon(wall)
|
||||
|
||||
setPoints([])
|
||||
canvas.renderAll()
|
||||
roof.drawHelpLine()
|
||||
|
||||
closePopup(id)
|
||||
return
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
|
||||
const notSetAttributes = lines.filter((line) => !line.attributes?.type)
|
||||
if (notSetAttributes.length > 0) {
|
||||
alert('설정되지 않은 외벽선이 있습니다.')
|
||||
return
|
||||
}
|
||||
|
||||
lines.forEach((line) => {
|
||||
line.set({
|
||||
attributes: line.attributes ? line.attributes : { offset: 0, type: LINE_TYPE.WALLLINE.WALL },
|
||||
stroke: '#000000',
|
||||
strokeWidth: 4,
|
||||
})
|
||||
|
||||
hideLine(line)
|
||||
})
|
||||
|
||||
const wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||
|
||||
wall.lines = [...lines]
|
||||
|
||||
const roof = drawRoofPolygon(wall)
|
||||
|
||||
setPoints([])
|
||||
canvas.renderAll()
|
||||
roof.drawHelpLine()
|
||||
closePopup(id)
|
||||
}
|
||||
|
||||
const closeModal = (fn) => {
|
||||
|
||||
@ -24,6 +24,8 @@ import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
|
||||
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
||||
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
|
||||
|
||||
// 지붕면 할당
|
||||
export function useRoofAllocationSetting(id) {
|
||||
@ -52,6 +54,8 @@ export function useRoofAllocationSetting(id) {
|
||||
|
||||
const { setSurfaceShapePattern } = useRoofFn()
|
||||
|
||||
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentRoofList(roofList)
|
||||
}, [])
|
||||
@ -270,6 +274,7 @@ export function useRoofAllocationSetting(id) {
|
||||
setRoofList(newRoofList)
|
||||
const selectedRoofMaterial = newRoofList.find((roof) => roof.selected)
|
||||
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial)
|
||||
modifyModuleSelectionData()
|
||||
closeAll()
|
||||
}
|
||||
|
||||
@ -369,6 +374,8 @@ export function useRoofAllocationSetting(id) {
|
||||
closeAll()
|
||||
setMenuNumber(3)
|
||||
setMenuType('surface')
|
||||
|
||||
modifyModuleSelectionData()
|
||||
}
|
||||
|
||||
const setLineSize = (id, size) => {
|
||||
@ -500,6 +507,16 @@ export function useRoofAllocationSetting(id) {
|
||||
setCurrentRoofList(newRoofList)
|
||||
}
|
||||
|
||||
// 모듈 선택에서 선택한 데이터 초기화
|
||||
const modifyModuleSelectionData = () => {
|
||||
if (moduleSelectionData.roofConstructions.length > 0) {
|
||||
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: [] })
|
||||
moduleSelectedDataTrigger({ ...moduleSelectionData, roofConstructions: [] })
|
||||
}
|
||||
}
|
||||
|
||||
const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
|
||||
|
||||
return {
|
||||
handleSave,
|
||||
onAddRoofMaterial,
|
||||
|
||||
@ -44,3 +44,8 @@ export const moduleStatisticsState = atom({
|
||||
},
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
|
||||
export const stepUpListDataState = atom({
|
||||
key: 'stepUpListDataState',
|
||||
default: [],
|
||||
})
|
||||
|
||||
@ -153,3 +153,25 @@ export const unescapeString = (str) => {
|
||||
export const isNullOrUndefined = (value) => {
|
||||
return value === null || value === undefined
|
||||
}
|
||||
|
||||
export const isEqualObjects = (obj1, obj2) => {
|
||||
const keys1 = Object.keys(obj1)
|
||||
const keys2 = Object.keys(obj2)
|
||||
|
||||
if (keys1.length !== keys2.length) return false
|
||||
|
||||
for (let key of keys1) {
|
||||
const val1 = obj1[key]
|
||||
const val2 = obj2[key]
|
||||
const areObjects = isObject(val1) && isObject(val2)
|
||||
|
||||
if (areObjects && !deepEqual(val1, val2)) return false
|
||||
if (!areObjects && val1 !== val2) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function isObject(value) {
|
||||
return value !== null && typeof value === 'object'
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user