591 lines
22 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { forwardRef, use, useContext, useEffect, useImperativeHandle, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { getDegreeInOrientation } from '@/util/canvas-util'
import { numberCheck } from '@/util/common-utils'
import { addedRoofsState, basicSettingState } from '@/store/settingAtom'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import QSelectBox from '@/components/common/select/QSelectBox'
import { roofsState } from '@/store/roofAtom'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import Swal from 'sweetalert2'
import { normalizeDecimal} from '@/util/input-utils'
export const Orientation = forwardRef((props, ref) => {
const { getMessage } = useMessage()
const { findCommonCode } = useCommonCode()
const [hasAnglePassivity, setHasAnglePassivity] = useState(false)
const basicSetting = useRecoilValue(basicSettingState)
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //지붕재 선택
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
const [roofTab, setRoofTab] = useState(0) //지붕재 탭
const [selectedModuleSeries, setSelectedModuleSeries] = useState(null)
const [moduleSeriesList, setModuleSeriesList] = useState([])
const [filteredModuleList, setFilteredModuleList] = useState([])
const {
roofs,
setRoofs,
tabNum,
setTabNum,
compasDeg,
setCompasDeg,
selectedModules,
roughnessCodes,
windSpeedCodes,
managementState,
setManagementState,
moduleList,
moduleSelectionData,
setModuleSelectionData,
setSelectedModules,
selectedSurfaceType,
setSelectedSurfaceType,
installHeight,
setInstallHeight,
standardWindSpeed,
setStandardWindSpeed,
verticalSnowCover,
setVerticalSnowCover,
orientationTrigger,
nextStep,
currentCanvasPlan,
loginUserState,
updateObjectDataApi,
} = props
const [inputCompasDeg, setInputCompasDeg] = useState(compasDeg ?? 0)
const [inputInstallHeight, setInputInstallHeight] = useState('0')
const [inputMargin, setInputMargin] = useState('0')
const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState('0')
const [inputRoughness, setInputRoughness] = useState(selectedSurfaceType)
const [inputStandardWindSpeed, setInputStandardWindSpeed] = useState(standardWindSpeed)
const { restoreModuleInstArea } = useModuleBasicSetting()
const moduleData = {
header: [
{ name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' },
{
name: `${getMessage('height')} (mm)`,
prop: 'height',
},
{ name: `${getMessage('width')} (mm)`, prop: 'width' },
{ name: `${getMessage('output')} (W)`, prop: 'output' },
],
}
useEffect(() => {
if (basicSetting.roofSizeSet == '3') {
restoreModuleInstArea()
}
}, [])
useEffect(() => {
if (moduleSelectionData?.common) {
setInputMargin(moduleSelectionData?.common?.margin)
}
}, [moduleSelectionData])
useEffect(() => {
if (selectedModules) {
const foundModule = moduleList.find((module) => module.itemId === selectedModules.itemId)
if (foundModule) {
setSelectedModules(foundModule)
// 선택된 모듈의 시리즈로 업데이트 (시리즈 목록이 있는 경우에만)
if (moduleSeriesList.length > 0 && foundModule.moduleSerCd) {
const currentSeries = moduleSeriesList.find(series => series.moduleSerCd === foundModule.moduleSerCd)
if (currentSeries && (!selectedModuleSeries || selectedModuleSeries.moduleSerCd !== currentSeries.moduleSerCd)) {
setSelectedModuleSeries(currentSeries)
}
}
}
}
}, [selectedModules, moduleList, moduleSeriesList])
useEffect(() => {
if (selectedSurfaceType) {
setInputRoughness(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue))
}
}, [selectedSurfaceType])
useEffect(() => {
if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId))
}, [standardWindSpeed])
useEffect(() => {
if (managementState?.installHeight && managementState?.installHeight) {
setSelectedSurfaceType(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue))
setInputInstallHeight(managementState?.installHeight)
setStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId))
setInputVerticalSnowCover(managementState?.verticalSnowCover)
}
}, [managementState])
useImperativeHandle(ref, () => ({
handleNextStep,
}))
const handleNextStep = () => {
if (isComplete()) {
const common = {
illuminationTp: inputRoughness.clCode,
illuminationTpNm: inputRoughness.clCodeNm,
instHt: inputInstallHeight,
stdWindSpeed: inputStandardWindSpeed?.clCode,
stdSnowLd: inputVerticalSnowCover,
saleStoreNorthFlg: managementState?.saleStoreNorthFlg,
moduleTpCd: selectedModules.itemTp,
moduleItemId: selectedModules.itemId,
margin: inputMargin,
}
setCompasDeg(inputCompasDeg)
setInstallHeight(inputInstallHeight)
setVerticalSnowCover(inputVerticalSnowCover)
setSelectedSurfaceType(inputRoughness)
setStandardWindSpeed(inputStandardWindSpeed)
nextStep(inputCompasDeg)
setManagementState({
...managementState,
installHeight: inputInstallHeight,
verticalSnowCover: inputVerticalSnowCover,
standardWindSpeedId: inputStandardWindSpeed?.clCode,
surfaceType: inputRoughness.clCodeNm,
surfaceTypeValue: inputRoughness.clCode,
})
setModuleSelectionData({
...moduleSelectionData,
module: {
...selectedModules,
},
common,
})
orientationTrigger({
compasDeg: inputCompasDeg,
common: common,
module: {
...selectedModules,
},
margin: inputMargin,
})
updateObjectDataApi({
objectNo: currentCanvasPlan.objectNo, //오브젝트_no
standardWindSpeedId: inputStandardWindSpeed?.clCode, //기준풍속코드
verticalSnowCover: inputVerticalSnowCover, //적설량
surfaceType: inputRoughness.clCodeNm, //면조도구분
installHeight: inputInstallHeight, //설치높이
userId: loginUserState.userId, //작성자아아디
})
setTabNum(2)
} else {
if (!selectedModules || !selectedModules.itemId) {
Swal.fire({
title: getMessage('module.not.found'),
icon: 'warning',
})
return
}
}
}
const checkDegree = (e) => {
if (e === '-0' || e === '-') {
setInputCompasDeg('-')
return
}
if (e === '0-') {
setInputCompasDeg('-0')
return
}
const n = Number(normalizeDecimal(e))
if (n >= -180 && n <= 180) {
if (numberCheck(n)) {
setInputCompasDeg(n)
}
} else {
setInputCompasDeg(compasDeg)
}
}
const isComplete = () => {
if (!selectedModules || !selectedModules.itemId) return false
if (basicSetting && basicSetting.roofSizeSet !== '3') {
if (inputInstallHeight <= 0) {
return false
}
if (+inputVerticalSnowCover <= 0) {
return false
}
if (!inputStandardWindSpeed) return false
if (!inputRoughness) return false
}
return true
}
const handleChangeModuleSeries = (e) => {
resetRoofs()
setSelectedModuleSeries(e)
// 선택된 시리즈에 맞는 모듈 목록 필터링 및 첫 번째 모듈 선택
if (e && moduleList.length > 0) {
let filtered
if (e.moduleSerCd === 'ALL') {
// "전체" 선택 시 모든 모듈 표시
filtered = moduleList
} else {
// 특정 시리즈 선택 시 해당 시리즈 모듈만 표시
filtered = moduleList.filter(module => module.moduleSerCd === e.moduleSerCd)
}
setFilteredModuleList(filtered)
// 필터링된 목록의 첫 번째 모듈을 자동 선택
if (filtered.length > 0) {
setSelectedModules(filtered[0])
}
}
}
const handleChangeModule = (e) => {
resetRoofs()
setSelectedModules(e)
}
const handleChangeRoughness = (e) => {
resetRoofs()
setInputRoughness(e)
}
const handleChangeInstallHeight = (e) => {
resetRoofs()
setInputInstallHeight(e)
}
const handleChangeStandardWindSpeed = (e) => {
resetRoofs()
setInputStandardWindSpeed(e)
}
const handleChangeVerticalSnowCover = (e) => {
resetRoofs()
setInputVerticalSnowCover(e)
}
const resetRoofs = () => {
const newRoofs = addedRoofs.map((roof) => {
return {
...roof,
trestle: {
lengthBase: null,
trestleMkrCd: null,
constMthdCd: null,
constTp: null,
roofBaseCd: null,
roofPchBase: null,
},
addRoof: {
...roof.addRoof,
lengthBase: null,
eavesMargin: null,
kerabaMargin: null,
ridgeMargin: null,
},
construction: {
constTp: null,
cvrYn: 'N',
snowGdPossYn: 'N',
cvrChecked: false,
snowGdChecked: false,
},
}
})
// setRoofs(newRoofs)
// setAddedRoofs(newRoofs)
setRoofsStore(newRoofs)
}
// 모듈시리즈 목록 생성 및 commonCode와 매핑
useEffect(() => {
if (moduleList.length > 0 && moduleSeriesList.length === 0) {
const moduleSeriesCodes = findCommonCode(207100) || []
// moduleList에서 고유한 moduleSerCd 추출
const uniqueSeriesCd = [...new Set(moduleList.map(module => module.moduleSerCd).filter(Boolean))]
if (uniqueSeriesCd.length > 0) {
// moduleSerCd와 commonCode를 매핑하여 기본 moduleSeriesList 생성
const mappedSeries = uniqueSeriesCd.map(serCd => {
const matchedCode = moduleSeriesCodes.find(code => code.clCode === serCd)
return {
moduleSerCd: serCd,
moduleSerNm: matchedCode ? matchedCode.clCodeNm : serCd
}
})
// "전체" 옵션을 맨 앞에 추가
const allOption = {
moduleSerCd: 'ALL',
moduleSerNm: getMessage("board.sub.total") || 'ALL'
}
const seriesList = [allOption, ...mappedSeries]
setModuleSeriesList(seriesList)
// 현재 선택된 모듈이 있으면 해당 모듈의 시리즈를 찾아서 선택
if (selectedModules && selectedModules.moduleSerCd) {
const currentSeries = seriesList.find(series => series.moduleSerCd === selectedModules.moduleSerCd)
if (currentSeries) {
setSelectedModuleSeries(currentSeries)
} else {
setSelectedModuleSeries(allOption)
}
} else {
// 선택된 모듈이 없으면 "전체"를 기본 선택
setSelectedModuleSeries(allOption)
}
}
}
}, [moduleList, selectedModules])
// 초기 로딩 시에만 필터링된 모듈 목록 설정
useEffect(() => {
if (moduleList.length > 0 && filteredModuleList.length === 0 && selectedModuleSeries) {
let filtered
if (selectedModuleSeries.moduleSerCd === 'ALL') {
// "전체" 선택 시 모든 모듈 표시
filtered = moduleList
} else {
// 특정 시리즈 선택 시 해당 시리즈 모듈만 표시
filtered = moduleList.filter(module => module.moduleSerCd === selectedModuleSeries.moduleSerCd)
}
setFilteredModuleList(filtered)
if (filtered.length > 0 && !selectedModules) {
setSelectedModules(filtered[0])
}
}
}, [moduleList, selectedModuleSeries]);
return (
<>
<div className="properties-setting-wrap">
<div className="outline-wrap">
<div className="roof-module-inner">
<div className="compas-wrapper">
<div className="guide">{getMessage('modal.module.basic.setting.orientation.setting.info')}</div>
<div className="roof-module-compas">
<div className="compas-box">
<div className="compas-box-inner">
{Array.from({ length: 180 / 15 }).map((dot, index) => (
<div
key={index}
className={`circle ${getDegreeInOrientation(inputCompasDeg) === -15 * index + 180 || (index === 0 && inputCompasDeg >= 172 && index === 0 && inputCompasDeg <= 180) || (inputCompasDeg === -180 && index === 0) ? 'act' : ''}`}
onClick={() => {
if (index === 0) {
setInputCompasDeg(180)
return
}
setInputCompasDeg(-15 * index + 180)
}}
>
{index === 0 && <i>180°</i>}
{index === 6 && <i>90°</i>}
</div>
))}
{Array.from({ length: 180 / 15 }).map((dot, index) => (
<div
key={index}
className={`circle ${inputCompasDeg !== 180 && getDegreeInOrientation(inputCompasDeg) === -1 * 15 * index ? 'act' : ''}`}
onClick={() => setInputCompasDeg(15 * index * -1)}
>
{index === 0 && <i>0°</i>}
{index === 6 && <i>-90°</i>}
</div>
))}
<div className="compas">
<div className="compas-arr" style={{ transform: `rotate(${-1 * getDegreeInOrientation(inputCompasDeg)}deg)` }}></div>
</div>
</div>
</div>
</div>
<div className="center-wrap">
<div className="outline-form">
<div className="d-check-box pop mr10">
<input type="checkbox" id="ch99" checked={hasAnglePassivity} onChange={() => setHasAnglePassivity(!hasAnglePassivity)} />
<label htmlFor="ch99">{getMessage('modal.module.basic.setting.orientation.setting.angle.passivity')}</label>
</div>
<div className="input-grid mr10" style={{ width: '60px' }}>
<input
type="text"
className="input-origin block"
value={inputCompasDeg}
readOnly={!hasAnglePassivity}
placeholder={0}
onChange={(e) => checkDegree(e.target.value)}
/>
</div>
<span className="thin">°</span>
<span className="thin"> -180 180 </span>
</div>
</div>
</div>
<div className="compas-table-wrap">
<div className="compas-table-box mb10">
<div className="outline-form mb10">
<span>{getMessage('modal.module.basic.setting.module.series.setting')}</span>
<div className="grid-select">
{moduleSeriesList.length > 0 && (
<QSelectBox
options={moduleSeriesList}
value={selectedModuleSeries}
targetKey={'moduleSerCd'}
sourceKey={'moduleSerCd'}
showKey={'moduleSerNm'}
onChange={(e) => handleChangeModuleSeries(e)}
/>
)}
</div>
</div>
<div className="outline-form mb10">
<span>{getMessage('modal.module.basic.setting.module.setting2')}</span>
<div className="grid-select">
{filteredModuleList && (
<QSelectBox
options={filteredModuleList}
value={selectedModules}
targetKey={'itemId'}
sourceKey={'itemId'}
showKey={'itemNm'}
onChange={(e) => handleChangeModule(e)}
/>
)}
</div>
</div>
<div className="roof-module-table">
<table>
<thead>
<tr>
{moduleData.header.map((header) => {
return (
<th key={header.prop} style={{ width: header.width ? header.width + 'px' : '' }}>
{header.name}
</th>
)
})}
</tr>
</thead>
<tbody>
{Array.from({ length: 3 }).map((_, index) => {
return selectedModules && selectedModules?.itemList && selectedModules?.itemList?.length >= index + 1 ? (
<tr key={index}>
<td>
<div className="color-wrap">
<span
className="color-box"
style={{
backgroundColor: selectedModules.itemList[index].color,
}}
></span>
<span className="name">{selectedModules.itemList[index].itemNm}</span>
</div>
</td>
<td className="al-r">{Number(selectedModules.itemList[index].shortAxis).toFixed(0)}</td>
<td className="al-r">{Number(selectedModules.itemList[index].longAxis).toFixed(0)}</td>
<td className="al-r">{Number(selectedModules.itemList[index].wpOut).toFixed(0)}</td>
</tr>
) : (
<tr key={index}>
<td>
<div className="color-wrap"></div>
</td>
<td className="al-r"></td>
<td className="al-r"></td>
<td className="al-r"></td>
</tr>
)
})}
</tbody>
</table>
</div>
{basicSetting && basicSetting.roofSizeSet == '3' && (
<div className="outline-form mt15">
<span>{getMessage('modal.module.basic.setting.module.placement.area')}</span>
<div className="input-grid mr10" style={{ width: '60px' }}>
<input type="text" className="input-origin block" value={inputMargin} onChange={(e) => setInputMargin(normalizeDecimal(e.target.value))} />
</div>
<span className="thin">m</span>
</div>
)}
</div>
{basicSetting && basicSetting.roofSizeSet != '3' && (
<div className="compas-table-box">
<div className="compas-grid-table">
<div className="outline-form">
<span>{getMessage('modal.module.basic.setting.module.surface.type')}</span>
<div className="grid-select">
{roughnessCodes.length > 0 && managementState && (
<QSelectBox
options={roughnessCodes}
value={inputRoughness}
targetKey={'clCode'}
sourceKey={'clCode'}
showKey={'clCodeNm'}
onChange={(e) => handleChangeRoughness(e)}
/>
)}
</div>
</div>
<div className="outline-form">
<span>{getMessage('modal.module.basic.setting.module.fitting.height')}</span>
<div className="input-grid mr10">
<input
type="text"
className="input-origin block"
value={inputInstallHeight}
onChange={(e) => handleChangeInstallHeight(normalizeDecimal(e.target.value))}
/>
</div>
<span className="thin">m</span>
</div>
<div className="outline-form">
<span>{getMessage('modal.module.basic.setting.module.standard.wind.speed')}</span>
<div className="grid-select">
{windSpeedCodes.length > 0 && managementState && (
<QSelectBox
title={''}
options={windSpeedCodes}
value={inputStandardWindSpeed}
targetKey={'clCode'}
sourceKey={'clCode'}
showKey={'clCodeNm'}
onChange={(e) => handleChangeStandardWindSpeed(e)}
/>
)}
</div>
</div>
<div className="outline-form">
<span>{getMessage('modal.module.basic.setting.module.standard.snowfall.amount')}</span>
<div className="input-grid mr10">
<input
type="text"
className="input-origin block"
value={inputVerticalSnowCover}
onChange={(e) => handleChangeVerticalSnowCover(normalizeDecimal(e.target.value))}
/>
</div>
<span className="thin">cm</span>
</div>
</div>
</div>
)}
</div>
</div>
</div>
</div>
</>
)
})