육지붕 구현

This commit is contained in:
yjnoh 2025-02-06 17:44:44 +09:00
parent 17378dc3ad
commit 57bfe51146
5 changed files with 795 additions and 693 deletions

View File

@ -12,7 +12,7 @@ import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientatio
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { useEvent } from '@/hooks/useEvent' import { useEvent } from '@/hooks/useEvent'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { addedRoofsState } from '@/store/settingAtom' import { addedRoofsState, corridorDimensionSelector } from '@/store/settingAtom'
import { isObjectNotEmpty } from '@/util/common-utils' import { isObjectNotEmpty } from '@/util/common-utils'
import Swal from 'sweetalert2' import Swal from 'sweetalert2'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
@ -40,31 +40,40 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
if (tabNum === 1) { if (tabNum === 1) {
orientationRef.current.handleNextStep() orientationRef.current.handleNextStep()
} else if (tabNum === 2) { } else if (tabNum === 2) {
if (!isObjectNotEmpty(moduleSelectionData.module)) { if (canvasSetting.roofSizeSet !== '3') {
Swal.fire({ if (!isObjectNotEmpty(moduleSelectionData.module)) {
title: getMessage('module.not.found'), Swal.fire({
icon: 'warning', title: getMessage('module.not.found'),
}) icon: 'warning',
return })
} return
}
if (addedRoofs.length !== moduleSelectionData.roofConstructions.length) { if (addedRoofs.length !== moduleSelectionData.roofConstructions.length) {
Swal.fire({ Swal.fire({
title: getMessage('construction.length.difference'), title: getMessage('construction.length.difference'),
icon: 'warning', icon: 'warning',
})
return
}
//
updateObjectDataApi({
objectNo: currentCanvasPlan.objectNo, //_no
standardWindSpeedId: moduleSelectionData.common.stdWindSpeed, //
verticalSnowCover: moduleSelectionData.common.stdSnowLd, //
surfaceType: moduleSelectionData.common.illuminationTpNm, //
installHeight: moduleSelectionData.common.instHt, //
userId: loginUserState.userId, //
}) })
return } else {
if (!isObjectNotEmpty(moduleSelectionData.flatModule)) {
Swal.fire({
title: getMessage('module.not.found'),
icon: 'warning',
})
return
}
} }
//
updateObjectDataApi({
objectNo: currentCanvasPlan.objectNo, //_no
standardWindSpeedId: moduleSelectionData.common.stdWindSpeed, //
verticalSnowCover: moduleSelectionData.common.stdSnowLd, //
surfaceType: moduleSelectionData.common.illuminationTpNm, //
installHeight: moduleSelectionData.common.instHt, //
userId: loginUserState.userId, //
})
} }
setTabNum(tabNum + 1) setTabNum(tabNum + 1)
@ -88,6 +97,14 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const res = await updateObjectDate(params) const res = await updateObjectDate(params)
} }
useEffect(() => {
if (canvasSetting.roofSizeSet !== '3') {
manualModuleSetup(placementRef)
} else {
manualFlatroofModuleSetup(placementFlatRef)
}
}, [isManualModuleSetup])
return ( return (
<WithDraggable isShow={true} pos={pos}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lx-2`}> <div className={`modal-pop-wrap lx-2`}>
@ -107,12 +124,12 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
</div> </div>
{tabNum === 1 && <Orientation ref={orientationRef} tabNum={tabNum} setTabNum={setTabNum} />} {tabNum === 1 && <Orientation ref={orientationRef} tabNum={tabNum} setTabNum={setTabNum} />}
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 2 && <Module setTabNum={setTabNum} />} {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != '3' && tabNum === 2 && <Module setTabNum={setTabNum} />}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && tabNum === 3 && <Placement setTabNum={setTabNum} ref={placementRef} />} {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != '3' && tabNum === 3 && <Placement setTabNum={setTabNum} ref={placementRef} />}
{/*배치면 초기설정 - 입력방법: 육지붕*/} {/*배치면 초기설정 - 입력방법: 육지붕*/}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 2 && <PitchModule setTabNum={setTabNum} />} {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == '3' && tabNum === 2 && <PitchModule setTabNum={setTabNum} />}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 3 && ( {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == '3' && tabNum === 3 && (
<PitchPlacement setTabNum={setTabNum} ref={placementFlatRef} /> <PitchPlacement setTabNum={setTabNum} ref={placementFlatRef} />
)} )}
@ -141,9 +158,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
</button> </button>
</> </>
)} )}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet === 3 && ( {console.log('canvasSetting.roofSizeSet', canvasSetting.roofSizeSet)}
{canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && (
<> <>
<button className="btn-frame modal mr5" onClick={() => manualFlatroofModuleSetup(placementFlatRef)}> <button className={`btn-frame modal mr5 ${isManualModuleSetup ? 'act' : ''}`} onClick={handleManualModuleSetup}>
{getMessage('modal.module.basic.setting.passivity.placement')} {getMessage('modal.module.basic.setting.passivity.placement')}
</button> </button>
<button className="btn-frame modal act" onClick={() => autoFlatroofModuleSetup(placementFlatRef)}> <button className="btn-frame modal act" onClick={() => autoFlatroofModuleSetup(placementFlatRef)}>

View File

@ -74,6 +74,7 @@ const Placement = forwardRef((props, refs) => {
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked }) setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
} }
//
useEffect(() => { useEffect(() => {
if (moduleSelectionData && moduleSelectionData.module.itemList.length > 0) { if (moduleSelectionData && moduleSelectionData.module.itemList.length > 0) {
let initCheckedModule = {} let initCheckedModule = {}
@ -114,29 +115,27 @@ const Placement = forwardRef((props, refs) => {
<tbody> <tbody>
{selectedModules.itemList && {selectedModules.itemList &&
selectedModules.itemList.map((item, index) => ( selectedModules.itemList.map((item, index) => (
<> <tr key={index}>
<tr key={index}> <td className="al-c">
<td className="al-c"> <div className="d-check-box no-text pop">
<div className="d-check-box no-text pop"> <input
<input type="checkbox"
type="checkbox" id={item.itemId}
id={item.itemId} name={item.itemId}
name={item.itemId} checked={selectedItems[item.itemId]}
checked={selectedItems[item.itemId]} onChange={handleSelectedItem}
onChange={handleSelectedItem} />
/> <label htmlFor={item.itemId}></label>
<label htmlFor={item.itemId}></label> </div>
</div> </td>
</td> <td>
<td> <div className="color-wrap">
<div className="color-wrap"> <span className="color-box" style={{ backgroundColor: item.color }}></span>
<span className="color-box" style={{ backgroundColor: item.color }}></span> <span className="name">{item.itemNm}</span>
<span className="name">{item.itemNm}</span> </div>
</div> </td>
</td> <td className="al-r">{item.wpOut}</td>
<td className="al-r">{item.wpOut}</td> </tr>
</tr>
</>
))} ))}
</tbody> </tbody>
</table> </table>

View File

@ -1,12 +1,22 @@
import { useState, useEffect } from 'react'
import { useRecoilState } from 'recoil'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { useMasterController } from '@/hooks/common/useMasterController'
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { isObjectNotEmpty } from '@/util/common-utils'
export default function PitchModule({}) { export default function PitchModule({}) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const SelectOption01 = [{ name: '0' }, { name: '0' }, { name: '0' }, { name: '0' }] const { getModuleTypeItemList } = useMasterController()
const [moduleList, setModuleList] = useState([])
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) //
const moduleData = { const moduleData = {
header: [ header: [
{ name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' }, { name: getMessage('module'), width: 250, prop: 'module', type: 'color-box' },
{ {
name: `${getMessage('높이')} (mm)`, name: `${getMessage('높이')} (mm)`,
prop: 'height', prop: 'height',
@ -14,24 +24,45 @@ export default function PitchModule({}) {
{ name: `${getMessage('width')} (mm)`, prop: 'width' }, { name: `${getMessage('width')} (mm)`, prop: 'width' },
{ name: `${getMessage('output')} (W)`, prop: 'output' }, { name: `${getMessage('output')} (W)`, prop: 'output' },
], ],
rows: [
{
module: { name: 'Re.RISE-G3 440', color: '#AA6768' },
height: { name: '1134' },
width: { name: '1722' },
output: { name: '440' },
},
{
module: {
name: 'Re.RISE MS-G3 290',
color: '#67A2AA',
},
height: { name: '1134' },
width: { name: '1722' },
output: { name: '240' },
},
],
} }
const getModuleData = async (roofsIds) => {
const list = await getModuleTypeItemList(roofsIds)
if (list.data.length > 0) {
//selectbox
list.data.forEach((item) => {
item.name = item.itemNm
})
//
setModuleList(list.data)
}
}
useEffect(() => {
getModuleData(['FLAT_ROOF'])
}, [])
const handleChangeModule = (option) => {
//
setSelectedModules(option) //
setModuleSelectionData({
...moduleSelectionData,
flatModule: option,
})
moduleSelectedDataTrigger({
...moduleSelectionData,
flatModule: option,
})
}
useEffect(() => {
if (isObjectNotEmpty(moduleSelectionData.flatModule) && moduleList.length > 0) {
handleChangeModule(moduleSelectionData.flatModule)
}
}, [moduleList])
const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
return ( return (
<> <>
<div className="module-table-box"> <div className="module-table-box">
@ -39,7 +70,17 @@ export default function PitchModule({}) {
<div className="outline-form mb10"> <div className="outline-form mb10">
<span className="mr10">{getMessage('modal.module.basic.setting.module.setting')}</span> <span className="mr10">{getMessage('modal.module.basic.setting.module.setting')}</span>
<div className="grid-select"> <div className="grid-select">
<QSelectBox title={'Search'} option={SelectOption01} /> {moduleList && (
<QSelectBox
title={getMessage('selectbox.title')}
options={moduleList}
value={selectedModules}
targetKey={'itemId'}
sourceKey={'itemId'}
showKey={'itemNm'}
onChange={handleChangeModule}
/>
)}
</div> </div>
</div> </div>
<div className="roof-module-table"> <div className="roof-module-table">
@ -54,33 +95,21 @@ export default function PitchModule({}) {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{moduleData.rows.map((row) => ( {selectedModules &&
<> selectedModules.itemList &&
<tr> selectedModules.itemList.map((row, index) => (
{moduleData.header.map((header) => ( <tr key={index}>
<> <td>
{header.type === 'color-box' && ( <div className="color-wrap">
<td> <span className="color-box" style={{ backgroundColor: row.color }}></span>
<div className="color-wrap"> <span className="name">{row.itemNm}</span>
<span className="color-box" style={{ backgroundColor: row[header.prop].color }}></span> </div>
<span className="name">{row[header.prop].name}</span> </td>
</div> <td>{Number(row.shortAxis).toFixed(0)}</td>
</td> <td>{Number(row.longAxis).toFixed(0)}</td>
)} <td>{Number(row.wpOut).toFixed(0)}</td>
{!header.type && header.type !== 'color-box' && <td className="al-r">{row[header.prop].name}</td>}
</>
))}
</tr> </tr>
</> ))}
))}
{Array.from({ length: 3 - moduleData.rows.length }).map((_, i) => (
<tr key={i}>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
))}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -1,49 +1,48 @@
import { forwardRef, useState, useEffect } from 'react' import { forwardRef, useState, useEffect } from 'react'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { canvasState } from '@/store/canvasAtom' import { canvasState, checkedModuleState } from '@/store/canvasAtom'
import { useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import { POLYGON_TYPE } from '@/common/common' import { POLYGON_TYPE } from '@/common/common'
import { useEvent } from '@/hooks/useEvent' import { useEvent } from '@/hooks/useEvent'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
const PitchPlacement = forwardRef((props, refs) => { const PitchPlacement = forwardRef((props, refs) => {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [setupLocation, setSetupLocation] = useState('south') const [setupLocation, setSetupLocation] = useState('south')
const { makeModuleInstArea } = useModuleBasicSetting()
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { initEvent } = useEvent() const { initEvent } = useEvent()
useEffect(() => { const { selectedModules } = useModuleBasicSetting(3)
makeModuleInstArea() const setCheckedModules = useSetRecoilState(checkedModuleState)
}, []) const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //
const [selectedItems, setSelectedItems] = useState({})
useEffect(() => { useEffect(() => {
handleChangeSetupLocation() handleChangeSetupLocation()
}, [setupLocation]) }, [setupLocation])
const handleSelectedItem = (e) => {
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
}
const moduleData = { const moduleData = {
header: [ header: [
{ type: 'check', name: '', prop: 'check', width: 70 }, { type: 'check', name: '', prop: 'check', width: 70 },
{ type: 'color-box', name: getMessage('module'), prop: 'module' }, { type: 'color-box', name: getMessage('module'), prop: 'module' },
{ type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 }, { type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 },
], ],
rows: [
{
check: false,
module: { name: 'Re.RISE-G3 440', color: '#AA6768' },
output: { name: '440' },
},
{
check: false,
module: {
name: 'Re.RISE MS-G3 290',
color: '#67A2AA',
},
output: { name: '240' },
},
],
} }
//
useEffect(() => {
const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
const moduleArray = selectedModules.itemList.filter((item) => {
return checkedModuleIds.includes(item.itemId)
})
setCheckedModules(moduleArray)
}, [selectedItems])
const handleSetupLocation = (e) => { const handleSetupLocation = (e) => {
initEvent() initEvent()
refs.setupLocation.current = e.target refs.setupLocation.current = e.target
@ -81,6 +80,20 @@ const PitchPlacement = forwardRef((props, refs) => {
} }
} }
useEffect(() => {
if (moduleSelectionData && moduleSelectionData.flatModule.itemList.length > 0) {
let initCheckedModule = {}
moduleSelectionData.flatModule.itemList.forEach((obj, index) => {
if (index === 0) {
initCheckedModule = { [obj.itemId]: true }
} else {
initCheckedModule = { ...initCheckedModule, [obj.itemId]: true }
}
})
setSelectedItems(initCheckedModule)
}
}, [])
return ( return (
<> <>
<div className="module-table-box mb10"> <div className="module-table-box mb10">
@ -104,33 +117,30 @@ const PitchPlacement = forwardRef((props, refs) => {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{moduleData.rows.map((row) => ( {selectedModules.itemList &&
<> selectedModules.itemList.map((item, index) => (
<tr> <tr key={index}>
{moduleData.header.map((header) => ( <td className="al-c">
<> <div className="d-check-box no-text pop">
{header.type === 'color-box' && ( <input
<td> type="checkbox"
<div className="color-wrap"> id={item.itemId}
<span className="color-box" style={{ backgroundColor: row[header.prop].color }}></span> name={item.itemId}
<span className="name">{row[header.prop].name}</span> checked={selectedItems[item.itemId]}
</div> onChange={handleSelectedItem}
</td> />
)} <label htmlFor={item.itemId}></label>
{header.type === 'check' && ( </div>
<td className="al-c"> </td>
<div className="d-check-box no-text pop"> <td>
<input type="checkbox" id="ch02" /> <div className="color-wrap">
<label htmlFor="ch02"></label> <span className="color-box" style={{ backgroundColor: item.color }}></span>
</div> <span className="name">{item.itemNm}</span>
</td> </div>
)} </td>
{header.type && header.type !== 'color-box' && header.type !== 'check' && <td className="al-r">{row[header.prop].name}</td>} <td className="al-r">{item.wpOut}</td>
</>
))}
</tr> </tr>
</> ))}
))}
</tbody> </tbody>
</table> </table>
</div> </div>
@ -150,8 +160,7 @@ const PitchPlacement = forwardRef((props, refs) => {
name="radio01" name="radio01"
id="ra01" id="ra01"
value={'south'} value={'south'}
checked={setupLocation === 'south'} defaultChecked={setupLocation === 'south'}
defaultChecked
onClick={handleSetupLocation} onClick={handleSetupLocation}
/> />
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.south')}</label> <label htmlFor="ra01">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.south')}</label>
@ -162,7 +171,7 @@ const PitchPlacement = forwardRef((props, refs) => {
name="radio01" name="radio01"
id="ra02" id="ra02"
value={'excreta'} value={'excreta'}
checked={setupLocation === 'excreta'} defaultChecked={setupLocation === 'excreta'}
onClick={handleSetupLocation} onClick={handleSetupLocation}
/> />
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.select')}</label> <label htmlFor="ra02">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.select')}</label>

File diff suppressed because it is too large Load Diff