# Conflicts:
#	README.md
This commit is contained in:
김민식 2025-04-18 10:23:33 +09:00
commit e717c28758
29 changed files with 2750 additions and 933 deletions

View File

@ -35,4 +35,4 @@ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
test deploy test

View File

@ -24,7 +24,7 @@
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"mathjs": "^13.0.2", "mathjs": "^13.0.2",
"mssql": "^11.0.1", "mssql": "^11.0.1",
"next": "14.2.25", "next": "14.2.26",
"next-international": "^1.2.4", "next-international": "^1.2.4",
"react": "^18", "react": "^18",
"react-chartjs-2": "^5.2.0", "react-chartjs-2": "^5.2.0",

View File

@ -39,7 +39,7 @@ export default function QSelectBox({
if (showKey !== '' && !value) { if (showKey !== '' && !value) {
//value showKey //value showKey
// return options[0][showKey] // return options[0][showKey]
return title return title !== '' ? title : getMessage('selectbox.title')
} else if (showKey !== '' && value) { } else if (showKey !== '' && value) {
//value sourceKey targetKey //value sourceKey targetKey

View File

@ -13,7 +13,7 @@ import dayjs from 'dayjs'
import { useCommonCode } from '@/hooks/common/useCommonCode' import { useCommonCode } from '@/hooks/common/useCommonCode'
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
import { SessionContext } from '@/app/SessionProvider' import { SessionContext } from '@/app/SessionProvider'
import Select, {components} from 'react-select' import Select, { components } from 'react-select'
import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils' import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils'
import ProductFeaturesPop from './popup/ProductFeaturesPop' import ProductFeaturesPop from './popup/ProductFeaturesPop'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
@ -504,6 +504,8 @@ export default function Estimate({}) {
saleStoreId: estimateContextState.sapSaleStoreId, saleStoreId: estimateContextState.sapSaleStoreId,
sapSalesStoreCd: estimateContextState.sapSalesStoreCd, sapSalesStoreCd: estimateContextState.sapSalesStoreCd,
docTpCd: estimateContextState.estimateType, docTpCd: estimateContextState.estimateType,
secSapSalesStoreCd:
estimateContextState.secSapSalesStoreCd?.length > 0 && showPriceCd === 'QSP_PRICE' ? estimateContextState.secSapSalesStoreCd : '',
priceCd: showPriceCd, priceCd: showPriceCd,
itemIdList: estimateContextState.itemList.filter((item) => item.delFlg === '0' && item.paDispOrder === null), itemIdList: estimateContextState.itemList.filter((item) => item.delFlg === '0' && item.paDispOrder === null),
} }
@ -715,7 +717,7 @@ export default function Estimate({}) {
/* 케이블 select 변경시 */ /* 케이블 select 변경시 */
const onChangeDisplayCableItem = (value, itemList) => { const onChangeDisplayCableItem = (value, itemList) => {
itemList.map((item, index) => { itemList.map((item, index) => {
if (item.dispCableFlg === '1') { if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') {
if (value !== '') { if (value !== '') {
onChangeDisplayItem(value, item.dispOrder, index, true) onChangeDisplayItem(value, item.dispOrder, index, true)
} }
@ -1144,7 +1146,7 @@ export default function Estimate({}) {
dispCableFlgCnt++ dispCableFlgCnt++
} }
if (item.dispCableFlg === '1') { if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') {
setCableItem(item.itemId) setCableItem(item.itemId)
} }
} }
@ -1216,6 +1218,21 @@ export default function Estimate({}) {
} }
}, [estimateContextState?.itemList, cableItemList]) }, [estimateContextState?.itemList, cableItemList])
const [agencyCustList, setAgencyCustList] = useState([])
useEffect(() => {
// 952 - 2 sapSalesStoreCd
if (estimateContextState?.sapSalesStoreCd && session?.storeLvl === '1') {
const param = {
sapSalesStoreCd: estimateContextState.sapSalesStoreCd,
}
const apiUrl = `api/estimate/agency-cust-list?${queryStringFormatter(param)}`
get({ url: apiUrl }).then((res) => {
if (isNotEmptyArray(res?.data)) {
setAgencyCustList(res?.data)
}
})
}
}, [estimateContextState?.sapSalesStoreCd])
return ( return (
<div className="sub-content estimate"> <div className="sub-content estimate">
<div className="sub-content-inner"> <div className="sub-content-inner">
@ -1360,41 +1377,79 @@ export default function Estimate({}) {
{getMessage('estimate.detail.estimateType')} <span className="important">*</span> {getMessage('estimate.detail.estimateType')} <span className="important">*</span>
</th> </th>
<td colSpan={3}> <td colSpan={3}>
<div className="radio-wrap"> <div className="form-flex-wrap">
{/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/} <div className="radio-wrap">
<div className="d-check-radio light mr10" style={{display: {/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/}
(isNotEmptyArray(storePriceList) > 0 <div
&& storePriceList[0].pkgRank !== null className="d-check-radio light mr10"
&& storePriceList[0].pkgRank !== '' style={{
|| estimateContextState?.estimateType === 'YJSS') ? "" : "none"}}> display:
<input (isNotEmptyArray(storePriceList) > 0 && storePriceList[0].pkgRank !== null && storePriceList[0].pkgRank !== '') ||
type="radio" estimateContextState?.estimateType === 'YJSS'
name="estimateType" ? ''
id="YJSS" : 'none',
value={'YJSS'}
checked={estimateContextState?.estimateType === 'YJSS' ? true : false}
onChange={(e) => {
//
setHandlePricingFlag(true)
setEstimateContextState({ estimateType: e.target.value })
}} }}
/> >
<label htmlFor="YJSS">{getMessage('estimate.detail.estimateType.yjss')}</label> <input
</div> type="radio"
<div className="d-check-radio light"> name="estimateType"
<input id="YJSS"
type="radio" value={'YJSS'}
name="estimateType" checked={estimateContextState?.estimateType === 'YJSS' ? true : false}
id="YJOD" onChange={(e) => {
value={'YJOD'} //
checked={estimateContextState?.estimateType === 'YJOD' ? true : false} setHandlePricingFlag(true)
onChange={(e) => { setEstimateContextState({ estimateType: e.target.value })
setHandlePricingFlag(true) }}
setEstimateContextState({ estimateType: e.target.value }) />
}} <label htmlFor="YJSS">{getMessage('estimate.detail.estimateType.yjss')}</label>
/> </div>
<label htmlFor="YJOD">{getMessage('estimate.detail.estimateType.yjod')}</label> <div className="d-check-radio light">
<input
type="radio"
name="estimateType"
id="YJOD"
value={'YJOD'}
checked={estimateContextState?.estimateType === 'YJOD' ? true : false}
onChange={(e) => {
setHandlePricingFlag(true)
setEstimateContextState({ estimateType: e.target.value })
}}
/>
<label htmlFor="YJOD">{getMessage('estimate.detail.estimateType.yjod')}</label>
</div>
</div> </div>
{session?.storeLvl === '1' && agencyCustList.length > 0 ? (
<div className="form-flex-select ml10">
<label htmlFor="">{getMessage('estimate.detail.agency')}</label>
<div className="select-wrap" style={{ width: '400px' }}>
<Select
id="agencyName"
instanceId="agencyName"
className="react-select-custom"
classNamePrefix="custom"
placeholder="Select"
options={agencyCustList}
onChange={(e) => {
if (isObjectNotEmpty(e)) {
setEstimateContextState({ secSapSalesStoreCd: e.sapSalesStoreCd })
} else {
setEstimateContextState({ secSapSalesStoreCd: '' })
}
}}
getOptionLabel={(x) => x.sapSalesStoreNm}
getOptionValue={(x) => x.sapSalesStoreCd}
isClearable={true}
isSearchable={true}
value={agencyCustList.filter(function (option) {
return option.sapSalesStoreCd === estimateContextState.secSapSalesStoreCd
})}
/>
</div>
</div>
) : (
''
)}
</div> </div>
</td> </td>
</tr> </tr>
@ -1883,16 +1938,12 @@ export default function Estimate({}) {
} }
}} }}
menuPlacement={'auto'} menuPlacement={'auto'}
getOptionLabel={(x) => x.itemName + " (" + x.itemNo + ")"} getOptionLabel={(x) => x.itemName + ' (' + x.itemNo + ')'}
getOptionValue={(x) => x.itemNo} getOptionValue={(x) => x.itemNo}
components={{ components={{
SingleValue:({children, ...props}) =>{ SingleValue: ({ children, ...props }) => {
return ( return <components.SingleValue {...props}>{props.data.itemName}</components.SingleValue>
<components.SingleValue{...props}> },
{props.data.itemName}
</components.SingleValue>
)
}
}} }}
isClearable={false} isClearable={false}
isDisabled={!!item?.paDispOrder} isDisabled={!!item?.paDispOrder}
@ -1913,21 +1964,17 @@ export default function Estimate({}) {
placeholder="Select" placeholder="Select"
options={cableItemList} options={cableItemList}
menuPlacement={'auto'} menuPlacement={'auto'}
getOptionLabel={(x) => x.clRefChr3 + " (" + x.clRefChr1 + ")"} getOptionLabel={(x) => x.clRefChr3 + ' (' + x.clRefChr1 + ')'}
getOptionValue={(x) => x.clRefChr1} getOptionValue={(x) => x.clRefChr1}
components={{ components={{
SingleValue:({children, ...props}) =>{ SingleValue: ({ children, ...props }) => {
return ( return <components.SingleValue {...props}>{(item.itemTpCd === 'M12')? item.itemName : props.data.clRefChr3}</components.SingleValue>
<components.SingleValue{...props}> },
{props.data.clRefChr3}
</components.SingleValue>
)
}
}} }}
isClearable={false} isClearable={false}
isDisabled={true} isDisabled={true}
value={cableItemList.filter(function (option) { value={cableItemList.filter(function (option) {
return option.clRefChr1 === item.itemId return (item.itemTpCd === 'M12')? item.itemId : option.clRefChr1 === item.itemId
})} })}
/> />
)} )}
@ -1978,7 +2025,11 @@ export default function Estimate({}) {
<input <input
type="text" type="text"
className="input-light al-r" className="input-light al-r"
value={convertNumberToPriceDecimal(item?.showSalePrice === '0' ? null : item?.salePrice?.replaceAll(',', ''))} value={
item.openFlg === '1'
? 'OPEN'
: convertNumberToPriceDecimal(item?.showSalePrice === '0' ? null : item?.salePrice?.replaceAll(',', ''))
}
disabled={ disabled={
item.openFlg === '1' item.openFlg === '1'
? true ? true
@ -2006,15 +2057,17 @@ export default function Estimate({}) {
</div> </div>
</td> </td>
<td className="al-r"> <td className="al-r">
{convertNumberToPriceDecimal( {item?.openFlg === '1'
item?.showSaleTotPrice === '0' ? 'OPEN'
? null : convertNumberToPriceDecimal(
: item?.amount === '' item?.showSaleTotPrice === '0'
? null
: item?.saleTotPrice === '0'
? null ? null
: item?.saleTotPrice?.replaceAll(',', ''), : item?.amount === ''
)} ? null
: item?.saleTotPrice === '0'
? null
: item?.saleTotPrice?.replaceAll(',', ''),
)}
</td> </td>
</tr> </tr>
) )

View File

@ -1,39 +1,41 @@
import { useMessage } from '@/hooks/useMessage' import { POLYGON_TYPE } from '@/common/common'
import WithDraggable from '@/components/common/draggable/WithDraggable' import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useContext, useEffect, useRef, useState } from 'react' import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
import Module from '@/components/floor-plan/modal/basic/step/Module'
import PitchModule from '@/components/floor-plan/modal/basic/step/pitch/PitchModule'
import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement' import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement'
import Placement from '@/components/floor-plan/modal/basic/step/Placement' import Placement from '@/components/floor-plan/modal/basic/step/Placement'
import { useRecoilValue, useRecoilState } from 'recoil'
import { canvasSettingState, canvasState, checkedModuleState, isManualModuleSetupState } from '@/store/canvasAtom'
import { usePopup } from '@/hooks/usePopup'
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { useEvent } from '@/hooks/useEvent'
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { addedRoofsState, corridorDimensionSelector, basicSettingState } from '@/store/settingAtom'
import { isObjectNotEmpty } from '@/util/common-utils'
import Swal from 'sweetalert2'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { useMasterController } from '@/hooks/common/useMasterController' import { useMasterController } from '@/hooks/common/useMasterController'
import { loginUserStore } from '@/store/commonAtom' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { currentCanvasPlanState } from '@/store/canvasAtom'
import { POLYGON_TYPE } from '@/common/common'
import { useModuleSelection } from '@/hooks/module/useModuleSelection' import { useModuleSelection } from '@/hooks/module/useModuleSelection'
import { useOrientation } from '@/hooks/module/useOrientation' import { useOrientation } from '@/hooks/module/useOrientation'
import Trestle from './step/Trestle' import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import {
canvasState,
checkedModuleState,
currentCanvasPlanState,
isManualModuleLayoutSetupState,
isManualModuleSetupState,
toggleManualSetupModeState,
} from '@/store/canvasAtom'
import { loginUserStore } from '@/store/commonAtom'
import { roofsState } from '@/store/roofAtom' import { roofsState } from '@/store/roofAtom'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { addedRoofsState, basicSettingState } from '@/store/settingAtom'
import { isObjectNotEmpty } from '@/util/common-utils'
import { useEffect, useRef, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import Swal from 'sweetalert2'
import Trestle from './step/Trestle'
export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup() const { closePopup } = usePopup()
const [tabNum, setTabNum] = useState(1) const [tabNum, setTabNum] = useState(1)
const canvasSetting = useRecoilValue(canvasSettingState)
const orientationRef = useRef(null) const orientationRef = useRef(null)
const trestleRef = useRef(null)
const { initEvent } = useEvent()
const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState)
const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState)
const trestleRef = useRef(null)
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState)
const loginUserState = useRecoilValue(loginUserStore) const loginUserState = useRecoilValue(loginUserStore)
@ -43,6 +45,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const [isClosePopup, setIsClosePopup] = useState({ close: false, id: 0 }) const [isClosePopup, setIsClosePopup] = useState({ close: false, id: 0 })
const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState) const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState)
const [roofs, setRoofs] = useState(addedRoofs) const [roofs, setRoofs] = useState(addedRoofs)
const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState)
const [layoutSetup, setLayoutSetup] = useState([{}])
const { const {
moduleSelectionInitParams, moduleSelectionInitParams,
selectedModules, selectedModules,
@ -70,23 +74,37 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const { trigger: orientationTrigger } = useCanvasPopupStatusController(1) const { trigger: orientationTrigger } = useCanvasPopupStatusController(1)
const { trigger: trestleTrigger } = useCanvasPopupStatusController(2) const { trigger: trestleTrigger } = useCanvasPopupStatusController(2)
const { trigger: placementTrigger } = useCanvasPopupStatusController(3) const { trigger: placementTrigger } = useCanvasPopupStatusController(3)
const roofsStore = useRecoilValue(roofsState) const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
// const { initEvent } = useContext(EventContext) // const { initEvent } = useContext(EventContext)
const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup } = useModuleBasicSetting(tabNum) const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup, restoreModuleInstArea } =
useModuleBasicSetting(tabNum)
const { updateObjectDate } = useMasterController() const { updateObjectDate } = useMasterController()
useEffect(() => { useEffect(() => {
if (managementState) console.log('managementState', managementState) const moduleTabNum = basicSetting.roofSizeSet != 3 ? 3 : 2
}, [managementState])
let hasModules = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
.some((obj) => obj.modules?.length > 0)
if (hasModules) {
orientationRef.current.handleNextStep()
setTabNum(moduleTabNum)
}
}, [])
useEffect(() => { useEffect(() => {
if (roofsStore && addedRoofs) { if (roofsStore && addedRoofs) {
console.log('🚀 ~ useEffect ~ roofsStore, addedRoofs:', roofsStore, addedRoofs)
setRoofs( setRoofs(
addedRoofs.map((roof, index) => { addedRoofs.map((roof, index) => {
return { return {
...roof, ...roof,
...roofsStore[index].addRoof, ...roofsStore[index]?.addRoof,
construction: roofsStore[index]?.construction,
trestle: roofsStore[index]?.trestle,
trestleDetail: roofsStore[index]?.trestleDetail,
} }
}), }),
) )
@ -95,36 +113,20 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
...moduleSelectionData, ...moduleSelectionData,
roofConstructions: roofsStore.map((roof) => { roofConstructions: roofsStore.map((roof) => {
return { return {
addRoof: { roofIndex: roof.roofIndex,
...roof.addRoof, addRoof: roof.addRoof,
}, construction: roof.construction,
construction: { trestle: roof.trestle,
...roof.construction, trestleDetail: roof.trestleDetail,
},
trestle: {
...roof.trestle,
},
} }
}), }),
}) })
} }
}, [roofsStore, addedRoofs]) }, [roofsStore, addedRoofs])
useEffect(() => {
let hasModules = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
.some((obj) => obj.modules?.length > 0)
if (hasModules) {
orientationRef.current.handleNextStep()
setTabNum(3)
}
}, [])
useEffect(() => { useEffect(() => {
if (basicSetting.roofSizeSet !== '3') { if (basicSetting.roofSizeSet !== '3') {
manualModuleSetup(placementRef) manualModuleSetup()
} else { } else {
manualFlatroofModuleSetup(placementFlatRef) manualFlatroofModuleSetup(placementFlatRef)
} }
@ -137,22 +139,45 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
setIsManualModuleSetup(false) setIsManualModuleSetup(false)
}, [checkedModules]) }, [checkedModules])
useEffect(() => {
if (basicSetting.roofSizeSet !== '3') {
if (manualSetupMode.indexOf('manualSetup') > -1) {
manualModuleSetup()
} else if (manualSetupMode.indexOf('manualLayoutSetup') > -1) {
manualModuleLayoutSetup(layoutSetup)
} else if (manualSetupMode.indexOf('off') > -1) {
manualModuleSetup()
manualModuleLayoutSetup(layoutSetup)
}
} else {
manualFlatroofModuleSetup(placementFlatRef)
}
if (isClosePopup.close) {
closePopup(isClosePopup.id)
}
}, [manualSetupMode, isClosePopup])
useEffect(() => {
if (isManualModuleLayoutSetup) {
manualModuleLayoutSetup(layoutSetup)
}
}, [layoutSetup])
useEffect(() => {
setIsManualModuleSetup(false)
setIsManualModuleLayoutSetup(false)
setManualSetupMode(`off`)
}, [checkedModules])
const handleBtnNextStep = () => { const handleBtnNextStep = () => {
if (tabNum === 1) { if (tabNum === 1) {
console.log('moduleSelectionData', moduleSelectionData)
orientationRef.current.handleNextStep() orientationRef.current.handleNextStep()
setAddedRoofs(roofs) setAddedRoofs(roofs)
// setTabNum(tabNum + 1)
return return
} else if (tabNum === 2) { } else if (tabNum === 2) {
if (basicSetting.roofSizeSet !== '3') { if (basicSetting.roofSizeSet !== '3') {
if (!isObjectNotEmpty(moduleSelectionData.module)) {
Swal.fire({
title: getMessage('module.not.found'),
icon: 'warning',
})
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'),
@ -160,14 +185,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
// }) // })
// return // return
// } // }
trestleRef.current.isComplete().then((res) => {
if (!trestleRef.current.isComplete()) { if (!res) return
Swal.fire({ })
title: getMessage('아직 멀었따'),
icon: 'warning',
})
return
}
// //
} else { } else {
if (!isObjectNotEmpty(moduleSelectionData.module)) { if (!isObjectNotEmpty(moduleSelectionData.module)) {
@ -177,16 +197,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
}) })
return return
} }
setTabNum(tabNum + 1)
} }
} }
setTabNum(tabNum + 1)
}
const placementRef = {
isChidori: useRef('false'),
setupLocation: useRef('eaves'),
isMaxSetup: useRef('false'),
} }
const placementFlatRef = { const placementFlatRef = {
@ -194,9 +208,15 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
} }
const handleManualModuleSetup = () => { const handleManualModuleSetup = () => {
setManualSetupMode(`manualSetup_${!isManualModuleSetup}`)
setIsManualModuleSetup(!isManualModuleSetup) setIsManualModuleSetup(!isManualModuleSetup)
} }
const handleManualModuleLayoutSetup = () => {
setManualSetupMode(`manualLayoutSetup_${!isManualModuleLayoutSetup}`)
setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup)
}
const updateObjectDataApi = async (params) => { const updateObjectDataApi = async (params) => {
const res = await updateObjectDate(params) const res = await updateObjectDate(params)
} }
@ -207,6 +227,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
if (isManualModuleSetup) { if (isManualModuleSetup) {
setIsManualModuleSetup(false) setIsManualModuleSetup(false)
} }
if (isManualModuleLayoutSetup) {
setIsManualModuleLayoutSetup(false)
}
} }
setIsClosePopup({ close: true, id: id }) setIsClosePopup({ close: true, id: id })
} }
@ -250,6 +273,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const trestleProps = { const trestleProps = {
roofs, roofs,
setRoofs, setRoofs,
setRoofsStore,
tabNum,
setTabNum, setTabNum,
moduleSelectionData, moduleSelectionData,
setModuleSelectionData, setModuleSelectionData,
@ -258,7 +283,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const placementProps = {} const placementProps = {}
return ( return (
<WithDraggable isShow={true} pos={pos} className="ll"> <WithDraggable isShow={true} pos={pos} className={basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' ? 'll' : 'lx-2'}>
<WithDraggable.Header title={getMessage('plan.menu.module.circuit.setting.default')} onClose={() => handleClosePopup(id)} /> <WithDraggable.Header title={getMessage('plan.menu.module.circuit.setting.default')} onClose={() => handleClosePopup(id)} />
<WithDraggable.Body> <WithDraggable.Body>
<div className="roof-module-tab"> <div className="roof-module-tab">
@ -280,8 +305,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
{tabNum === 1 && <Orientation ref={orientationRef} {...orientationProps} />} {tabNum === 1 && <Orientation ref={orientationRef} {...orientationProps} />}
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && <Trestle ref={trestleRef} {...trestleProps} />} {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && <Trestle ref={trestleRef} {...trestleProps} />}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && <Placement setTabNum={setTabNum} ref={placementRef} />} {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && (
<Placement setTabNum={setTabNum} layoutSetup={layoutSetup} setLayoutSetup={setLayoutSetup} />
)}
{/*배치면 초기설정 - 입력방법: 육지붕*/} {/*배치면 초기설정 - 입력방법: 육지붕*/}
{/* {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && <PitchModule setTabNum={setTabNum} />} */} {/* {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && <PitchModule setTabNum={setTabNum} />} */}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && ( {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && (
@ -290,35 +316,45 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
<div className="grid-btn-wrap"> <div className="grid-btn-wrap">
{/* {tabNum === 1 && <button className="btn-frame modal mr5">{getMessage('modal.common.save')}</button>} */} {/* {tabNum === 1 && <button className="btn-frame modal mr5">{getMessage('modal.common.save')}</button>} */}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && (
{tabNum !== 1 && (
<button className="btn-frame modal mr5" onClick={() => setTabNum(tabNum - 1)}>
{getMessage('modal.module.basic.setting.prev')}
</button>
)}
{/*{tabNum !== 3 && <button className="btn-frame modal act mr5">{getMessage('modal.common.save')}</button>}*/}
{tabNum !== 3 && (
<button className="btn-frame modal" onClick={handleBtnNextStep}>
Next
</button>
)}
{tabNum === 3 && (
<> <>
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( {tabNum !== 1 && (
<button className="btn-frame modal mr5" onClick={() => setTabNum(tabNum - 1)}>
{getMessage('modal.module.basic.setting.prev')}
</button>
)}
{tabNum !== 3 && (
<button className="btn-frame modal" onClick={handleBtnNextStep}>
Next
</button>
)}
{tabNum === 3 && (
<> <>
<button className="btn-frame modal mr5">{getMessage('modal.module.basic.setting.row.batch')}</button> <button className={`btn-frame modal mr5 ${isManualModuleLayoutSetup ? 'act' : ''}`} onClick={handleManualModuleLayoutSetup}>
{getMessage('modal.module.basic.setting.row.batch')}
</button>
<button className={`btn-frame modal mr5 ${isManualModuleSetup ? 'act' : ''}`} onClick={handleManualModuleSetup}> <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={() => autoModuleSetup(placementRef)}> <button className="btn-frame modal act" onClick={() => autoModuleSetup()}>
{getMessage('modal.module.basic.setting.auto.placement')} {getMessage('modal.module.basic.setting.auto.placement')}
</button> </button>
</> </>
)} )}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( </>
)}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && (
<>
{tabNum === 1 && (
<button className="btn-frame modal" onClick={handleBtnNextStep}>
Next
</button>
)}
{tabNum === 2 && (
<> <>
<button className="btn-frame modal mr5">{getMessage('modal.module.basic.setting.row.batch')}</button> <button className="btn-frame modal mr5" onClick={() => setTabNum(tabNum - 1)}>
{getMessage('modal.module.basic.setting.prev')}
</button>
<button className={`btn-frame modal mr5 ${isManualModuleSetup ? 'act' : ''}`} onClick={handleManualModuleSetup}> <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>

View File

@ -1,19 +1,20 @@
import { forwardRef, use, useContext, useEffect, useImperativeHandle, useState } from 'react' import { forwardRef, use, useContext, useEffect, useImperativeHandle, useState } from 'react'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useOrientation } from '@/hooks/module/useOrientation'
import { getDegreeInOrientation } from '@/util/canvas-util' import { getDegreeInOrientation } from '@/util/canvas-util'
import { numberCheck } from '@/util/common-utils' import { numberCheck } from '@/util/common-utils'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { addedRoofsState, basicSettingState } from '@/store/settingAtom' import { addedRoofsState, basicSettingState } from '@/store/settingAtom'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { roofsState } from '@/store/roofAtom'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import Swal from 'sweetalert2'
export const Orientation = forwardRef((props, ref) => { export const Orientation = forwardRef((props, ref) => {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [hasAnglePassivity, setHasAnglePassivity] = useState(false) const [hasAnglePassivity, setHasAnglePassivity] = useState(false)
const basicSetting = useRecoilValue(basicSettingState) const basicSetting = useRecoilValue(basicSettingState)
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) // const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
const [roofTab, setRoofTab] = useState(0) // const [roofTab, setRoofTab] = useState(0) //
const { const {
roofs, roofs,
@ -48,9 +49,11 @@ export const Orientation = forwardRef((props, ref) => {
} = props } = props
const [inputCompasDeg, setInputCompasDeg] = useState(compasDeg ?? 0) const [inputCompasDeg, setInputCompasDeg] = useState(compasDeg ?? 0)
const [inputInstallHeight, setInputInstallHeight] = useState('0') const [inputInstallHeight, setInputInstallHeight] = useState('0')
const [inputMargin, setInputMargin] = useState('0')
const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState('0') const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState('0')
const [inputRoughness, setInputRoughness] = useState(selectedSurfaceType) const [inputRoughness, setInputRoughness] = useState(selectedSurfaceType)
const [inputStandardWindSpeed, setInputStandardWindSpeed] = useState(standardWindSpeed) const [inputStandardWindSpeed, setInputStandardWindSpeed] = useState(standardWindSpeed)
const { restoreModuleInstArea } = useModuleBasicSetting()
const moduleData = { const moduleData = {
header: [ header: [
{ name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' }, { name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' },
@ -63,20 +66,36 @@ export const Orientation = forwardRef((props, ref) => {
], ],
} }
useEffect(() => {
if (basicSetting.roofSizeSet == '3') {
restoreModuleInstArea()
}
}, [])
useEffect(() => {
if (moduleSelectionData?.common) {
setInputMargin(moduleSelectionData?.common?.margin)
}
}, [moduleSelectionData])
useEffect(() => {
if (selectedModules) {
setSelectedModules(moduleList.find((module) => module.itemId === selectedModules.itemId))
}
}, [selectedModules])
useEffect(() => { useEffect(() => {
if (selectedSurfaceType) { if (selectedSurfaceType) {
console.log(roughnessCodes, selectedSurfaceType) setInputRoughness(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue))
setInputRoughness(roughnessCodes.find((code) => code.clCode === moduleSelectionData.common.illuminationTp))
} }
}, [selectedSurfaceType]) }, [selectedSurfaceType])
useEffect(() => { useEffect(() => {
if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === moduleSelectionData.common.stdWindSpeed)) if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId))
}, [standardWindSpeed]) }, [standardWindSpeed])
useEffect(() => { useEffect(() => {
if (managementState?.installHeight && managementState?.installHeight) { if (managementState?.installHeight && managementState?.installHeight) {
console.log('🚀 ~ useEffect ~ managementState:', managementState)
setSelectedSurfaceType(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue)) setSelectedSurfaceType(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue))
setInputInstallHeight(managementState?.installHeight) setInputInstallHeight(managementState?.installHeight)
setStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId)) setStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId))
@ -84,12 +103,6 @@ export const Orientation = forwardRef((props, ref) => {
} }
}, [managementState]) }, [managementState])
useEffect(() => {
if (moduleSelectionData) {
console.log('moduleSelectionData', moduleSelectionData)
}
}, [moduleSelectionData])
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
handleNextStep, handleNextStep,
})) }))
@ -100,23 +113,24 @@ export const Orientation = forwardRef((props, ref) => {
illuminationTp: inputRoughness.clCode, illuminationTp: inputRoughness.clCode,
illuminationTpNm: inputRoughness.clCodeNm, illuminationTpNm: inputRoughness.clCodeNm,
instHt: inputInstallHeight, instHt: inputInstallHeight,
stdWindSpeed: inputStandardWindSpeed.clCode, stdWindSpeed: inputStandardWindSpeed?.clCode,
stdSnowLd: inputVerticalSnowCover, stdSnowLd: inputVerticalSnowCover,
saleStoreNorthFlg: managementState?.saleStoreNorthFlg, saleStoreNorthFlg: managementState?.saleStoreNorthFlg,
moduleTpCd: selectedModules.itemTp, moduleTpCd: selectedModules.itemTp,
moduleItemId: selectedModules.itemId, moduleItemId: selectedModules.itemId,
margin: inputMargin,
} }
setCompasDeg(inputCompasDeg) setCompasDeg(inputCompasDeg)
setInstallHeight(inputInstallHeight) setInstallHeight(inputInstallHeight)
setVerticalSnowCover(inputVerticalSnowCover) setVerticalSnowCover(inputVerticalSnowCover)
setSelectedSurfaceType(inputRoughness) setSelectedSurfaceType(inputRoughness)
setStandardWindSpeed(inputStandardWindSpeed) setStandardWindSpeed(inputStandardWindSpeed)
nextStep() nextStep(inputCompasDeg)
setManagementState({ setManagementState({
...managementState, ...managementState,
installHeight: inputInstallHeight, installHeight: inputInstallHeight,
verticalSnowCover: inputVerticalSnowCover, verticalSnowCover: inputVerticalSnowCover,
standardWindSpeedId: inputStandardWindSpeed.clCode, standardWindSpeedId: inputStandardWindSpeed?.clCode,
surfaceType: inputRoughness.clCodeNm, surfaceType: inputRoughness.clCodeNm,
surfaceTypeValue: inputRoughness.clCode, surfaceTypeValue: inputRoughness.clCode,
}) })
@ -125,6 +139,7 @@ export const Orientation = forwardRef((props, ref) => {
module: { module: {
...selectedModules, ...selectedModules,
}, },
common,
}) })
orientationTrigger({ orientationTrigger({
compasDeg: inputCompasDeg, compasDeg: inputCompasDeg,
@ -132,16 +147,25 @@ export const Orientation = forwardRef((props, ref) => {
module: { module: {
...selectedModules, ...selectedModules,
}, },
margin: inputMargin,
}) })
updateObjectDataApi({ updateObjectDataApi({
objectNo: currentCanvasPlan.objectNo, //_no objectNo: currentCanvasPlan.objectNo, //_no
standardWindSpeedId: inputStandardWindSpeed.clCode, // standardWindSpeedId: inputStandardWindSpeed?.clCode, //
verticalSnowCover: inputVerticalSnowCover, // verticalSnowCover: inputVerticalSnowCover, //
surfaceType: inputRoughness.clCodeNm, // surfaceType: inputRoughness.clCodeNm, //
installHeight: inputInstallHeight, // installHeight: inputInstallHeight, //
userId: loginUserState.userId, // userId: loginUserState.userId, //
}) })
setTabNum(2) setTabNum(2)
} else {
if (!selectedModules || !selectedModules.itemId) {
Swal.fire({
title: getMessage('module.not.found'),
icon: 'warning',
})
return
}
} }
} }
@ -151,19 +175,20 @@ export const Orientation = forwardRef((props, ref) => {
return return
} }
if (e === '0-') { if (e === '0-') {
setCompasDeg('-0') setInputCompasDeg('-0')
return return
} }
if (Number(e) >= -180 && Number(e) <= 180) { if (Number(e) >= -180 && Number(e) <= 180) {
if (numberCheck(Number(e))) { if (numberCheck(Number(e))) {
setCompasDeg(Number(e)) setInputCompasDeg(Number(e))
} }
} else { } else {
setCompasDeg(compasDeg) setInputCompasDeg(compasDeg)
} }
} }
const isComplete = () => { const isComplete = () => {
if (!selectedModules || !selectedModules.itemId) return false
if (basicSetting && basicSetting.roofSizeSet !== '3') { if (basicSetting && basicSetting.roofSizeSet !== '3') {
if (inputInstallHeight <= 0) { if (inputInstallHeight <= 0) {
return false return false
@ -181,27 +206,61 @@ export const Orientation = forwardRef((props, ref) => {
} }
const handleChangeModule = (e) => { 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) => { const newRoofs = addedRoofs.map((roof) => {
return { return {
...roof, ...roof,
lengthBase: null, trestle: {
raftBaseCd: null, lengthBase: null,
trestleMkrCd: null, trestleMkrCd: null,
constMthdCd: null, constMthdCd: null,
constTp: null, constTp: null,
roofBaseCd: null, roofBaseCd: null,
ridgeMargin: null, roofPchBase: null,
kerabaMargin: null, },
eavesMargin: null, addRoof: {
roofPchBase: null, ...roof.addRoof,
cvrYn: 'N', lengthBase: null,
snowGdPossYn: 'N', eavesMargin: null,
cvrChecked: false, kerabaMargin: null,
snowGdChecked: false, ridgeMargin: null,
},
construction: {
constTp: null,
cvrYn: 'N',
snowGdPossYn: 'N',
cvrChecked: false,
snowGdChecked: false,
},
} }
}) })
setRoofs(newRoofs) // setRoofs(newRoofs)
setSelectedModules(e) // setAddedRoofs(newRoofs)
setRoofsStore(newRoofs)
} }
return ( return (
@ -275,8 +334,8 @@ export const Orientation = forwardRef((props, ref) => {
{moduleList && ( {moduleList && (
<QSelectBox <QSelectBox
options={moduleList} options={moduleList}
value={moduleSelectionInitParams} value={selectedModules}
targetKey={'moduleItemId'} targetKey={'itemId'}
sourceKey={'itemId'} sourceKey={'itemId'}
showKey={'itemNm'} showKey={'itemNm'}
onChange={(e) => handleChangeModule(e)} onChange={(e) => handleChangeModule(e)}
@ -298,7 +357,7 @@ export const Orientation = forwardRef((props, ref) => {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{Array.from({ length: 2 }).map((_, index) => { {Array.from({ length: 3 }).map((_, index) => {
return selectedModules && selectedModules?.itemList && selectedModules?.itemList?.length >= index + 1 ? ( return selectedModules && selectedModules?.itemList && selectedModules?.itemList?.length >= index + 1 ? (
<tr key={index}> <tr key={index}>
<td> <td>
@ -330,23 +389,18 @@ export const Orientation = forwardRef((props, ref) => {
</tbody> </tbody>
</table> </table>
</div> </div>
{basicSetting && basicSetting.roofSizeSet === '3' && ( {basicSetting && basicSetting.roofSizeSet == '3' && (
<div className="outline-form mt15"> <div className="outline-form mt15">
<span>{getMessage('modal.module.basic.setting.module.placement.area')}</span> <span>{getMessage('modal.module.basic.setting.module.placement.area')}</span>
<div className="input-grid mr10" style={{ width: '60px' }}> <div className="input-grid mr10" style={{ width: '60px' }}>
<input <input type="text" className="input-origin block" value={inputMargin} onChange={(e) => setInputMargin(e.target.value)} />
type="text"
className="input-origin block"
value={inputInstallHeight}
onChange={(e) => setInputInstallHeight(e.target.value)}
/>
</div> </div>
<span className="thin">m</span> <span className="thin">m</span>
</div> </div>
)} )}
</div> </div>
{basicSetting && basicSetting.roofSizeSet !== '3' && ( {basicSetting && basicSetting.roofSizeSet != '3' && (
<div className="compas-table-box"> <div className="compas-table-box">
<div className="compas-grid-table"> <div className="compas-grid-table">
<div className="outline-form"> <div className="outline-form">
@ -359,10 +413,7 @@ export const Orientation = forwardRef((props, ref) => {
targetKey={'clCode'} targetKey={'clCode'}
sourceKey={'clCode'} sourceKey={'clCode'}
showKey={'clCodeNm'} showKey={'clCodeNm'}
onChange={(e) => { onChange={(e) => handleChangeRoughness(e)}
console.log('🚀 ~ handleChangeModule ~ inputRoughness:', e)
setInputRoughness(e)
}}
/> />
)} )}
</div> </div>
@ -374,7 +425,7 @@ export const Orientation = forwardRef((props, ref) => {
type="text" type="text"
className="input-origin block" className="input-origin block"
value={inputInstallHeight} value={inputInstallHeight}
onChange={(e) => setInputInstallHeight(e.target.value)} onChange={(e) => handleChangeInstallHeight(e.target.value)}
/> />
</div> </div>
<span className="thin">m</span> <span className="thin">m</span>
@ -390,10 +441,7 @@ export const Orientation = forwardRef((props, ref) => {
targetKey={'clCode'} targetKey={'clCode'}
sourceKey={'clCode'} sourceKey={'clCode'}
showKey={'clCodeNm'} showKey={'clCodeNm'}
onChange={(e) => { onChange={(e) => handleChangeStandardWindSpeed(e)}
console.log('🚀 ~ handleChangeModule ~ inputStandardWindSpeed:', e)
setInputStandardWindSpeed(e)
}}
/> />
)} )}
</div> </div>
@ -405,7 +453,7 @@ export const Orientation = forwardRef((props, ref) => {
type="text" type="text"
className="input-origin block" className="input-origin block"
value={inputVerticalSnowCover} value={inputVerticalSnowCover}
onChange={(e) => setInputVerticalSnowCover(e.target.value)} onChange={(e) => handleChangeVerticalSnowCover(e.target.value)}
/> />
</div> </div>
<span className="thin">cm</span> <span className="thin">cm</span>

View File

@ -1,29 +1,43 @@
import { forwardRef, useEffect, useState } from 'react' import { forwardRef, useEffect, useState } 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 { checkedModuleState, currentCanvasPlanState, isManualModuleSetupState } from '@/store/canvasAtom' import {
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' checkedModuleState,
isManualModuleLayoutSetupState,
isManualModuleSetupState,
moduleRowColArrayState,
moduleSetupOptionState,
toggleManualSetupModeState,
} from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isObjectNotEmpty } from '@/util/common-utils' import { isObjectNotEmpty } from '@/util/common-utils'
const Placement = forwardRef((props, refs) => { const Placement = forwardRef((props, refs) => {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const [isChidori, setIsChidori] = useState(false) const [useTab, setUseTab] = useState(true)
const [isChidoriNotAble, setIsChidoriNotAble] = useState(false) const [isChidoriNotAble, setIsChidoriNotAble] = useState(false)
const [setupLocation, setSetupLocation] = useState('eaves')
const [isMaxSetup, setIsMaxSetup] = useState('false')
const [selectedItems, setSelectedItems] = useState({}) const [selectedItems, setSelectedItems] = useState({})
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState)
const setCheckedModules = useSetRecoilState(checkedModuleState) const setCheckedModules = useSetRecoilState(checkedModuleState)
const moduleSelectionData = useRecoilValue(moduleSelectionDataState) const moduleSelectionData = useRecoilValue(moduleSelectionDataState)
const { makeModuleInitArea } = useModuleBasicSetting(3) const { makeModuleInitArea, roofOutlineColor } = useModuleBasicSetting(3)
const [isMultiModule, setIsMultiModule] = useState(false) const [isMultiModule, setIsMultiModule] = useState(false)
const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) //
const setIsManualModuleSetup = useSetRecoilState(isManualModuleSetupState)
const setIsManualModuleLayoutSetup = useSetRecoilState(isManualModuleLayoutSetupState)
const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState)
const [moduleSetupOption, setModuleSetupOption] = useRecoilState(moduleSetupOptionState) //
const resetModuleSetupOption = useResetRecoilState(moduleSetupOptionState)
const [colspan, setColspan] = useState(1)
const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState)
// //
useEffect(() => { useEffect(() => {
@ -36,13 +50,24 @@ const Placement = forwardRef((props, refs) => {
makeModuleInitArea(moduleSelectionData) makeModuleInitArea(moduleSelectionData)
} }
if (moduleSelectionData.module.itemList.length > 1) {
setColspan(2)
}
return () => { return () => {
refs.isChidori.current = 'false' // refs.isChidori.current = 'false'
refs.setupLocation.current = 'eaves' // refs.setupLocation.current = 'eaves'
setIsManualModuleSetup(false) setIsManualModuleSetup(false)
setIsManualModuleLayoutSetup(false)
setManualSetupMode('off')
resetModuleSetupOption()
} }
}, []) }, [])
useEffect(() => {
console.log('moduleRowColArray', moduleRowColArray)
}, [moduleRowColArray])
// //
useEffect(() => { useEffect(() => {
if (isObjectNotEmpty(moduleSelectionData)) { if (isObjectNotEmpty(moduleSelectionData)) {
@ -56,8 +81,10 @@ const Placement = forwardRef((props, refs) => {
initCheckedModule = { ...initCheckedModule, [obj.itemId]: true } initCheckedModule = { ...initCheckedModule, [obj.itemId]: true }
} }
}) })
setSelectedItems(initCheckedModule) setSelectedItems(initCheckedModule)
setSelectedModules(moduleSelectionData.module) setSelectedModules(moduleSelectionData.module)
props.setLayoutSetup(moduleSelectionData.module.itemList.map((item) => ({ moduleId: item.itemId, col: 0, row: 0, checked: true })))
} }
// //
@ -82,59 +109,75 @@ const Placement = forwardRef((props, refs) => {
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('modal.module.basic.setting.module.placement.mix.asg.yn'), prop: 'mixAsgYn', width: 50 },
{ type: 'text', name: `単数`, prop: 'rows', width: 60 },
{ type: 'text', name: `熱水`, prop: 'cols', width: 60 },
], ],
rows: [], rows: [],
} }
const handleChangeChidori = (e) => { const handleChangeChidori = (e) => {
const bool = e.target.value === 'true' ? true : false const bool = e.target.value === 'true' ? true : false
setIsChidori(bool) setModuleSetupOption({ ...moduleSetupOption, isChidori: bool })
refs.isChidori.current = e.target.value
//
setIsManualModuleSetup(false)
setIsManualModuleLayoutSetup(false)
setManualSetupMode('off')
} }
const handleSetupLocation = (e) => { const handleSetupLocation = (e) => {
setSetupLocation(e.target.value) setModuleSetupOption({ ...moduleSetupOption, setupLocation: e.target.value })
refs.setupLocation.current = e.target.value
}
const handleMaxSetup = (e) => { //
if (e.target.checked) { setIsManualModuleSetup(false)
setIsMaxSetup('true') setIsManualModuleLayoutSetup(false)
refs.isMaxSetup.current = 'true' setManualSetupMode('off')
} else {
setIsMaxSetup('false')
refs.isMaxSetup.current = 'false'
}
} }
// //
const handleSelectedItem = (e) => { const handleSelectedItem = (e, itemId) => {
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked }) setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
const newLayoutSetup = [...props.layoutSetup]
props.layoutSetup.forEach((item, index) => {
if (item.moduleId === itemId) {
newLayoutSetup[index] = { ...props.layoutSetup[index], checked: e.target.checked }
}
})
props.setLayoutSetup(newLayoutSetup)
}
const handleLayoutSetup = (e, itemId, index) => {
const newLayoutSetup = [...props.layoutSetup]
newLayoutSetup[index] = {
...newLayoutSetup[index],
moduleId: itemId,
[e.target.name]: Number(e.target.value),
}
props.setLayoutSetup(newLayoutSetup)
} }
return ( return (
<> <>
<div className="module-table-flex-wrap mb10"> <div className="module-table-flex-wrap">
<div className="module-table-box"> <div className="module-table-box">
<div className="module-table-inner"> <div className="module-table-inner">
<div className="roof-module-table"> <div className="roof-module-table">
<table> <table>
<thead> <thead>
<tr> {moduleData.header.map((data) => (
{moduleData.header.map((data) => ( <th key={data.prop} style={{ width: data.width ? data.width : '' }}>
<th key={data.prop} style={{ width: data.width ? data.width : '' }}> {data.type === 'check' ? (
{data.type === 'check' ? ( <div className="d-check-box no-text pop">
<div className="d-check-box no-text pop"> <input type="checkbox" id="ch01" disabled />
<input type="checkbox" id="ch01" disabled /> <label htmlFor="ch01"></label>
<label htmlFor="ch01"></label> </div>
</div> ) : (
) : ( data.name
data.name )}
)} </th>
</th> ))}
))}
</tr>
</thead> </thead>
<tbody> <tbody>
{selectedModules.itemList && {selectedModules.itemList &&
@ -147,7 +190,7 @@ const Placement = forwardRef((props, refs) => {
id={item.itemId} id={item.itemId}
name={item.itemId} name={item.itemId}
checked={selectedItems[item.itemId]} checked={selectedItems[item.itemId]}
onChange={handleSelectedItem} onChange={(e) => handleSelectedItem(e, item.itemId)}
/> />
<label htmlFor={item.itemId}></label> <label htmlFor={item.itemId}></label>
</div> </div>
@ -158,93 +201,174 @@ const Placement = forwardRef((props, refs) => {
<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-c">
<div className="color-wrap">
<span className="name">{item.mixAsgYn}</span>
</div>
</td>
<td className="al-r">
<div className="input-grid">
<input
type="text"
className="input-origin block"
name="row"
value={props.layoutSetup[index]?.row ?? 1}
defaultValue={0}
onChange={(e) => handleLayoutSetup(e, item.itemId, index)}
/>
</div>
</td>
<td className="al-r">
<div className="input-grid">
<input
type="text"
className="input-origin block"
name="col"
value={props.layoutSetup[index]?.col ?? 1}
defaultValue={0}
onChange={(e) => handleLayoutSetup(e, item.itemId, index)}
/>
</div>
</td>
</tr> </tr>
))} ))}
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
<div className="module-table-box"> <div className="module-table-box non-flex">
<div className="module-table-inner"> <div className="module-table-inner">
<div className="self-table-tit">{getMessage('modal.module.basic.setting.module.placement.select.fitting.type')}</div> <div className="roof-module-table">
<div className="module-self-table"> <table>
<div className="self-table-item"> <thead>
<div className="self-item-th">{getMessage('modal.module.basic.setting.module.placement.waterfowl.arrangement')}</div> <tr>
<div className="self-item-td"> <th>{getMessage('modal.module.basic.setting.module.placement.waterfowl.arrangement')}</th>
<div className="pop-form-radio"> <th>{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}</th>
<div className="d-check-radio pop"> </tr>
<input </thead>
type="radio" <tbody>
name="radio01" <tr>
id="ra01" <td>
checked={isChidori} <div className="hexagonal-radio-wrap">
disabled={isChidoriNotAble} <div className="d-check-radio pop mb10">
value={'true'} <input
onChange={(e) => handleChangeChidori(e)} type="radio"
/> name="radio02"
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.module.placement.do')}</label> id="ra03"
</div> checked={moduleSetupOption.isChidori}
<div className="d-check-radio pop"> disabled={isChidoriNotAble}
<input type="radio" name="radio02" id="ra02" checked={!isChidori} value={'false'} onChange={(e) => handleChangeChidori(e)} /> value={'true'}
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.module.placement.do.not')}</label> onChange={(e) => handleChangeChidori(e)}
</div> />
</div> <label htmlFor="ra03">{getMessage('modal.module.basic.setting.module.placement.do')}</label>
</div> </div>
</div> <div className="d-check-radio pop">
<div className="self-table-item"> <input
<div className="self-item-th">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}</div> type="radio"
<div className="self-item-td"> name="radio02"
<div className="pop-form-radio"> id="ra04"
<div className="d-check-radio pop"> checked={!moduleSetupOption.isChidori}
<input value={'false'}
type="radio" onChange={(e) => handleChangeChidori(e)}
name="radio03" />
id="ra03" <label htmlFor="ra04">{getMessage('modal.module.basic.setting.module.placement.do.not')}</label>
checked={setupLocation === 'center'} </div>
value={'center'} </div>
onChange={handleSetupLocation} </td>
disabled={isMultiModule} <td>
/> <div className="hexagonal-radio-wrap">
<label htmlFor="ra03">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.center')}</label> <div className="d-check-radio pop mb10">
</div> <input
<div className="d-check-radio pop"> type="radio"
<input name="radio03"
type="radio" id="ra05"
name="radio04" checked={moduleSetupOption.setupLocation === 'eaves'}
id="ra04" value={'eaves'}
checked={setupLocation === 'eaves'} onChange={handleSetupLocation}
value={'eaves'} />
onChange={handleSetupLocation} <label htmlFor="ra05">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.eaves')}</label>
/> </div>
<label htmlFor="ra04">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.eaves')}</label> <div className="d-check-radio pop">
</div> <input
<div className="d-check-radio pop"> type="radio"
<input name="radio03"
type="radio" id="ra06"
name="radio05" checked={moduleSetupOption.setupLocation === 'ridge'}
id="ra05" value={'ridge'}
checked={setupLocation === 'ridge'} onChange={handleSetupLocation}
value={'ridge'} disabled={isMultiModule}
onChange={handleSetupLocation} />
disabled={isMultiModule} <label htmlFor="ra06">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.ridge')}</label>
/> </div>
<label htmlFor="ra05">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.ridge')}</label> </div>
</div> </td>
</div> </tr>
</div> </tbody>
</div> </table>
</div>
<div className="self-table-flx">
{/* <div className="d-check-box pop">
<input type="checkbox" id="ch04" checked={isMaxSetup === 'true'} value={'true'} onChange={handleMaxSetup} />
<label htmlFor="ch04">{getMessage('modal.module.basic.setting.module.placement.maximum')}</label>
</div> */}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div className="hide-check-guide">
{getMessage('modal.module.basic.setting.module.placement.max.size.check')}
<button className={`arr ${!useTab ? 'act' : ''}`} onClick={() => setUseTab(!useTab)}></button>
</div>
<div className={`module-table-box mt10 ${useTab ? 'hide' : ''}`}>
<div className="module-table-inner">
<div className="roof-module-table">
<table className="">
<thead>
<tr>
<th rowSpan={2} style={{ width: '22%' }}></th>
{selectedModules &&
selectedModules.itemList.map((item) => (
<th colSpan={colspan}>
<div className="color-wrap">
<span className="color-box" style={{ backgroundColor: item.color }}></span>
<span className="name">{item.itemNm}</span>
</div>
</th>
))}
</tr>
<tr>
{selectedModules.itemList.map((item) => (
<>
<th>{getMessage('modal.module.basic.setting.module.placement.max.row')}</th>
{colspan > 1 && <th>{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}</th>}
</>
))}
</tr>
</thead>
<tbody>
{moduleSelectionData.roofConstructions.map((item, index) => (
<tr>
<td>
<div className="color-wrap">
<span className="color-box" style={{ backgroundColor: roofOutlineColor(item.addRoof?.index) }}></span>
<span className="name">{item.addRoof?.roofMatlNmJp}</span>
</div>
</td>
{moduleRowColArray[index]?.map((item) => (
<>
<td className="al-c">{item.moduleMaxRows}</td>
{colspan > 1 && <td className="al-c">{item.mixModuleMaxRows}</td>}
</>
))}
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</> </>
) )
}) })

View File

@ -1,23 +1,25 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider' import { GlobalDataContext } from '@/app/GlobalDataProvider'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { useModuleTrestle } from '@/hooks/module/useModuleTrestle' import { useModuleTrestle } from '@/hooks/module/useModuleTrestle'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
import { roofsState } from '@/store/roofAtom' import { roofsState } from '@/store/roofAtom'
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isObjectNotEmpty } from '@/util/common-utils' import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react'
import { forwardRef, useContext, useEffect, useImperativeHandle, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import Swal from 'sweetalert2'
const Trestle = forwardRef((props, ref) => { const Trestle = forwardRef((props, ref) => {
const { setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData } = props const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData, setRoofsStore } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
// const [selectedTrestle, setSelectedTrestle] = useState() // const [selectedTrestle, setSelectedTrestle] = useState()
const currentAngleType = useRecoilValue(currentAngleTypeSelector) const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const pitchText = useRecoilValue(pitchTextSelector) const pitchText = useRecoilValue(pitchTextSelector)
const [selectedRoof, setSelectedRoof] = useState() const [selectedRoof, setSelectedRoof] = useState(null)
const { const {
trestleState, trestleState,
trestleDetail,
dispatch, dispatch,
raftBaseList, raftBaseList,
trestleList, trestleList,
@ -30,6 +32,10 @@ const Trestle = forwardRef((props, ref) => {
setEavesMargin, setEavesMargin,
setRidgeMargin, setRidgeMargin,
setKerabaMargin, setKerabaMargin,
lengthBase,
setLengthBase,
hajebichi,
setHajebichi,
cvrYn, cvrYn,
cvrChecked, cvrChecked,
snowGdPossYn, snowGdPossYn,
@ -43,46 +49,84 @@ const Trestle = forwardRef((props, ref) => {
}) })
const selectedModules = useRecoilValue(selectedModuleState) // const selectedModules = useRecoilValue(selectedModuleState) //
// const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) // const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const [lengthBase, setLengthBase] = useState(0)
const [hajebichi, setHajebichi] = useState(0)
const [selectedRaftBase, setSelectedRaftBase] = useState(null) const [selectedRaftBase, setSelectedRaftBase] = useState(null)
const [selectedTrestle, setSelectedTrestle] = useState(null) const [selectedTrestle, setSelectedTrestle] = useState(null)
const [selectedConstMthd, setSelectedConstMthd] = useState(null) const [selectedConstMthd, setSelectedConstMthd] = useState(null)
const [selectedConstruction, setSelectedConstruction] = useState(null) const [selectedConstruction, setSelectedConstruction] = useState(null)
const [selectedRoofBase, setSelectedRoofBase] = useState(null) const [selectedRoofBase, setSelectedRoofBase] = useState(null)
const { managementState } = useContext(GlobalDataContext) const { managementState } = useContext(GlobalDataContext)
const { restoreModuleInstArea } = useModuleBasicSetting()
const [flag, setFlag] = useState(false)
const tempModuleSelectionData = useRef(null)
useEffect(() => { useEffect(() => {
if (roofs && !selectedRoof) { if (roofs && !selectedRoof) {
setSelectedRoof(roofs[0]) setSelectedRoof(roofs[0])
} }
//
restoreModuleInstArea()
}, [roofs]) }, [roofs])
useEffect(() => {
if (flag && moduleSelectionData) {
if (JSON.stringify(tempModuleSelectionData.current) === JSON.stringify(moduleSelectionData)) {
setTabNum(tabNum + 1)
}
}
}, [flag, moduleSelectionData])
useEffect(() => { useEffect(() => {
if (selectedRoof) { if (selectedRoof) {
dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, moduleTpCd: selectedModules.itemTp } }) if (moduleSelectionData?.roofConstructions?.length >= selectedRoof.index + 1) {
const { construction, trestle, trestleDetail } = moduleSelectionData?.roofConstructions[selectedRoof.index]
dispatch({
type: 'SET_INITIALIZE',
roof: { common: moduleSelectionData.common, module: moduleSelectionData.module, construction, trestle, trestleDetail, ...selectedRoof },
})
} else {
dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, common: moduleSelectionData.common, module: moduleSelectionData.module } })
}
} }
}, [selectedRoof]) }, [selectedRoof])
useEffect(() => { useEffect(() => {
if (raftBaseList.length > 0) setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === trestleState?.raftBaseCd) ?? null) if (raftBaseList.length > 0) {
setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === trestleState?.raftBaseCd) ?? null)
} else {
setSelectedRaftBase(null)
}
}, [raftBaseList]) }, [raftBaseList])
useEffect(() => { useEffect(() => {
if (trestleList.length > 0) setSelectedTrestle(trestleList.find((trestle) => trestle.trestleMkrCd === trestleState?.trestleMkrCd) ?? null) if (trestleList.length > 0) {
setSelectedTrestle(trestleList.find((trestle) => trestle.trestleMkrCd === trestleState?.trestleMkrCd) ?? null)
} else {
setSelectedTrestle(null)
}
}, [trestleList]) }, [trestleList])
useEffect(() => { useEffect(() => {
if (roofBaseList.length > 0) setSelectedRoofBase(roofBaseList.find((roofBase) => roofBase.roofBaseCd === trestleState?.roofBaseCd) ?? null) if (roofBaseList.length > 0) {
setSelectedRoofBase(roofBaseList.find((roofBase) => roofBase.roofBaseCd === trestleState?.roofBaseCd) ?? null)
} else {
setSelectedRoofBase(null)
}
}, [roofBaseList]) }, [roofBaseList])
useEffect(() => { useEffect(() => {
if (constMthdList.length > 0) setSelectedConstMthd(constMthdList.find((constMthd) => constMthd.constMthdCd === trestleState?.constMthdCd) ?? null) if (constMthdList.length > 0) {
setSelectedConstMthd(constMthdList.find((constMthd) => constMthd.constMthdCd === trestleState?.constMthdCd) ?? null)
} else {
setSelectedConstMthd(null)
}
}, [constMthdList]) }, [constMthdList])
useEffect(() => { useEffect(() => {
if (constructionList.length > 0) { if (constructionList.length > 0) {
setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.constTp) ?? null) setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.construction?.constTp) ?? null)
} else {
setSelectedConstruction(null)
} }
}, [constructionList]) }, [constructionList])
@ -118,7 +162,7 @@ const Trestle = forwardRef((props, ref) => {
roof: { roof: {
moduleTpCd: selectedModules.itemTp ?? '', moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: e.trestleMkrCd, trestleMkrCd: e.trestleMkrCd,
}, },
}) })
@ -131,8 +175,8 @@ const Trestle = forwardRef((props, ref) => {
roof: { roof: {
moduleTpCd: selectedModules.itemTp ?? '', moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: trestleState.trestleMkrCd, trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: e.constMthdCd, constMthdCd: e.constMthdCd,
}, },
}) })
@ -145,9 +189,9 @@ const Trestle = forwardRef((props, ref) => {
roof: { roof: {
moduleTpCd: selectedModules.itemTp ?? '', moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: trestleState.trestleMkrCd, trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: trestleState.constMthdCd, constMthdCd: selectedConstMthd.constMthdCd,
roofBaseCd: e.roofBaseCd, roofBaseCd: e.roofBaseCd,
illuminationTp: managementState?.surfaceTypeValue ?? '', illuminationTp: managementState?.surfaceTypeValue ?? '',
instHt: managementState?.installHeight ?? '', instHt: managementState?.installHeight ?? '',
@ -158,26 +202,6 @@ const Trestle = forwardRef((props, ref) => {
}, },
}) })
} }
const handleChangeRoofMaterial = (index) => {
const newAddedRoofs = roofs.map((roof, i) => {
if (i === selectedRoof.index) {
return {
...selectedRoof,
...trestleState,
eavesMargin,
ridgeMargin,
kerabaMargin,
cvrYn,
snowGdPossYn,
cvrChecked,
snowGdChecked,
}
}
return { ...roof }
})
setRoofs(newAddedRoofs)
setSelectedRoof(newAddedRoofs[index])
}
const handleConstruction = (index) => { const handleConstruction = (index) => {
if (constructionList[index]?.constPossYn === 'Y') { if (constructionList[index]?.constPossYn === 'Y') {
@ -186,21 +210,21 @@ const Trestle = forwardRef((props, ref) => {
roof: { roof: {
moduleTpCd: selectedModules.itemTp ?? '', moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: trestleState.trestleMkrCd, trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: trestleState.constMthdCd, constMthdCd: selectedConstMthd.constMthdCd,
roofBaseCd: trestleState.roofBaseCd, roofBaseCd: selectedRoofBase.roofBaseCd,
illuminationTp: managementState?.surfaceTypeValue ?? '', illuminationTp: managementState?.surfaceTypeValue ?? '',
instHt: managementState?.installHeight ?? '', instHt: managementState?.installHeight ?? '',
stdWindSpeed: managementState?.standardWindSpeedId ?? '', stdWindSpeed: managementState?.standardWindSpeedId ?? '',
stdSnowLd: +managementState?.verticalSnowCover ?? '', stdSnowLd: +managementState?.verticalSnowCover ?? '',
inclCd: selectedRoof?.pitch.toString() ?? 0, inclCd: selectedRoof?.pitch ?? 0,
roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0),
constTp: constructionList[index].constTp, constTp: constructionList[index].constTp,
snowGdPossYn: constructionList[index].snowGdPossYn,
cvrYn: constructionList[index].cvrYn,
mixMatlNo: selectedModules.mixMatlNo, mixMatlNo: selectedModules.mixMatlNo,
workingWidth: selectedRoof?.length.toString() ?? '', workingWidth: selectedRoof?.length?.toString() ?? '',
// snowGdPossYn: constructionList[index].snowGdPossYn,
// cvrYn: constructionList[index].cvrYn,
}, },
}) })
@ -211,93 +235,254 @@ const Trestle = forwardRef((props, ref) => {
} }
} }
const isComplete = () => { const handleChangeRoofMaterial = (index) => {
const newAddedRoofs = roofs.map((roof, i) => {
if (i === selectedRoof.index) {
return {
...selectedRoof,
hajebichi,
lenBase: lengthBase,
eavesMargin,
ridgeMargin,
kerabaMargin,
roofIndex: selectedRoof.index,
trestle: {
hajebichi: hajebichi,
length: lengthBase,
...selectedRaftBase,
...selectedTrestle,
...selectedConstMthd,
...selectedRoofBase,
},
construction: {
...constructionList.find((data) => data.constTp === trestleState.constTp),
cvrYn: cvrYn,
snowGdPossYn: snowGdPossYn,
cvrChecked: cvrChecked,
snowGdChecked: snowGdChecked,
},
trestleDetail: trestleDetail,
}
}
return roof
})
setRoofs(newAddedRoofs)
setSelectedRoof(newAddedRoofs[index])
}
const isComplete = async () => {
const newAddedRoofs = roofs.map((roof, i) => { const newAddedRoofs = roofs.map((roof, i) => {
if (i === selectedRoof?.index) { if (i === selectedRoof?.index) {
return { return {
...selectedRoof, ...selectedRoof,
...trestleState, length: lengthBase,
eavesMargin, eavesMargin,
ridgeMargin, ridgeMargin,
kerabaMargin, kerabaMargin,
cvrYn, roofIndex: roof.index,
snowGdPossYn, trestle: {
cvrChecked, length: lengthBase,
snowGdChecked, hajebichi: hajebichi,
...selectedRaftBase,
...selectedTrestle,
...selectedConstMthd,
...selectedRoofBase,
},
construction: {
...constructionList.find((data) => data.constTp === trestleState.constTp),
cvrYn,
snowGdPossYn,
cvrChecked,
snowGdChecked,
setupCover: cvrChecked,
setupSnowCover: snowGdChecked,
},
trestleDetail: trestleDetail,
} }
} }
return { ...roof } return roof
}) })
let result = true let result = true
newAddedRoofs.forEach((roof) => { console.log(newAddedRoofs)
if (roof.eavesMargin && roof.ridgeMargin && roof.kerabaMargin) { for (let i = 0; i < newAddedRoofs.length; i++) {
return true const roof = newAddedRoofs[i]
if (!roof.trestle?.trestleMkrCd) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error1', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
} }
if (!roof.trestleMkrCd) result = false if (!roof.trestle?.constMthdCd) {
if (!roof.constMthdCd) result = false Swal.fire({
if (!roof.roofBaseCd) result = false title: getMessage('modal.module.basic.settting.module.error2', [roof.nameJp]), // .
if (!roof.constTp) result = false icon: 'warning',
})
if (selectedRoof.lenAuth === 'C') { result = false
if (!trestleState?.lengthBase) result = false return false
} }
if (['C', 'R'].includes(selectedRoof.raftAuth)) { if (!roof.trestle?.roofBaseCd) {
if (!roof.raftBaseCd) result = false Swal.fire({
title: getMessage('modal.module.basic.settting.module.error3', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
if (!roof.construction?.constTp) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error4', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
} }
if (['C', 'R'].includes(selectedRoof.roofPchAuth)) { if (roof.lenAuth === 'C') {
if (!roof.roofPchBase) result = false if (!roof.trestle?.length) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error5', [roof.nameJp]), // L .
icon: 'warning',
})
result = false
return false
}
}
if (['C', 'R'].includes(roof.raftAuth)) {
if (!roof?.raftBaseCd) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error6', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
} }
})
console.log('newAddedRoofs', newAddedRoofs) if (['C', 'R'].includes(roof.roofPchAuth)) {
if (!roof?.roofPchBase) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error7', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
}
if (!roof?.eavesMargin || !roof?.ridgeMargin || !roof?.kerabaMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error8', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
if (roof.trestle.trestleMkrCd !== 'NO_DATA') {
//
if (roof.trestleDetail?.eaveIntvl > roof.eavesMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error9', [roof.trestleDetail?.eaveIntvl, roof.nameJp]), // {0}mm .
icon: 'warning',
})
result = false
return false
}
if (roof.trestleDetail?.ridgeIntvl > roof.ridgeMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error10', [roof.trestleDetail?.ridgeIntvl, roof.nameJp]), // {0}mm .
icon: 'warning',
})
result = false
return false
}
if (roof.trestleDetail?.kerabaIntvl > roof.kerabaMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error11', [roof.trestleDetail?.kerabaIntvl, roof.nameJp]), // {0}mm .
icon: 'warning',
})
result = false
return false
}
}
}
if (result) { if (result) {
setRoofs(newAddedRoofs) const newRoofs = newAddedRoofs.map((roof) => {
const { addRoof, construction, trestle, trestleDetail, roofConstructions, ...rest } = roof
return rest
})
setModuleSelectionData({ setModuleSelectionData({
...moduleSelectionData, ...moduleSelectionData,
roofConstructions: newAddedRoofs.map((roof) => { roofConstructions: newAddedRoofs.map((roof, index) => ({
return { roofIndex: newRoofs[index].index,
addRoof: { trestle: roof.trestle,
...roof.addRoof, addRoof: newRoofs[index],
}, construction: roof.construction,
trestleDetail: roof.trestleDetail,
})),
})
setFlag(true)
tempModuleSelectionData.current = {
...moduleSelectionData,
roofConstructions: newAddedRoofs.map((roof, index) => ({
roofIndex: newRoofs[index].index,
trestle: roof.trestle,
addRoof: newRoofs[index],
construction: roof.construction,
trestleDetail: roof.trestleDetail,
})),
}
const updatePromises = [
// new Promise((resolve) => {
// resolve()
// }),
new Promise((resolve) => {
setRoofs(newRoofs)
resolve()
}),
new Promise((resolve) => {
const roofConstruction = newAddedRoofs.map((roof, index) => ({
roofIndex: newRoofs[index].index,
addRoof: newRoofs[index],
trestle: { trestle: {
...roof.trestle, ...roof.trestle,
},
construction: {
...roof.construction,
},
}
}),
})
trestleTrigger({
roofConstruction: newAddedRoofs.map((roof) => {
return {
roofIndex: roof.index,
addRoof: {
...roof,
},
trestle: {
...selectedTrestle,
raftBaseCd: roof.raftBaseCd, raftBaseCd: roof.raftBaseCd,
}, },
construction: { construction: {
...constructionList.find((construction) => trestleState.constTp === construction.constTp), // ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp),
...roof.construction,
roofIndex: roof.index, roofIndex: roof.index,
setupCover: roof.cvrYn === 'Y',
setupSnowCover: roof.snowGdYn === 'Y',
selectedIndex: roof.index, selectedIndex: roof.index,
}, },
} trestleDetail: roof.trestleDetail,
}))
trestleTrigger({
roofConstruction,
})
setRoofsStore(roofConstruction)
resolve()
}), }),
}) ]
await Promise.all(updatePromises)
return true
} }
return result return false
} }
const onMarginCheck = (target, data) => {}
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
isComplete, isComplete,
})) }))
@ -330,7 +515,7 @@ const Trestle = forwardRef((props, ref) => {
<input <input
type="text" type="text"
className="input-origin block" className="input-origin block"
value={trestleState?.lengthBase} value={lengthBase}
onChange={(e) => setLengthBase(e.target.value)} onChange={(e) => setLengthBase(e.target.value)}
disabled={selectedRoof.lenAuth === 'R'} disabled={selectedRoof.lenAuth === 'R'}
/> />
@ -371,7 +556,7 @@ const Trestle = forwardRef((props, ref) => {
type="text" type="text"
className="input-origin block" className="input-origin block"
disabled={selectedRoof.roofPchAuth === 'R'} disabled={selectedRoof.roofPchAuth === 'R'}
onChange={(e) => handleHajebichiAndLength(e, 'hajebichi')} onChange={(e) => setHajebichi(e.target.value)}
value={hajebichi} value={hajebichi}
/> />
</div> </div>
@ -469,7 +654,7 @@ const Trestle = forwardRef((props, ref) => {
<input <input
type="checkbox" type="checkbox"
id={`ch02`} id={`ch02`}
disabled={!trestleState?.snowGdPossYn || trestleState?.snowGdPossYn === 'N'} disabled={!snowGdPossYn || snowGdPossYn === 'N'}
checked={snowGdChecked || false} checked={snowGdChecked || false}
// onChange={() => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, snowGdChecked: !trestleState.snowGdChecked } })} // onChange={() => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, snowGdChecked: !trestleState.snowGdChecked } })}
onChange={() => setSnowGdChecked(!snowGdChecked)} onChange={() => setSnowGdChecked(!snowGdChecked)}
@ -490,7 +675,7 @@ const Trestle = forwardRef((props, ref) => {
className="input-origin block" className="input-origin block"
value={eavesMargin ?? 0} value={eavesMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })} // onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })}
onChange={(e) => setEavesMargin(e.target.value)} onChange={(e) => setEavesMargin(+e.target.value)}
/> />
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
@ -503,7 +688,7 @@ const Trestle = forwardRef((props, ref) => {
className="input-origin block" className="input-origin block"
value={ridgeMargin ?? 0} value={ridgeMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })} // onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })}
onChange={(e) => setRidgeMargin(e.target.value)} onChange={(e) => setRidgeMargin(+e.target.value)}
/> />
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
@ -516,7 +701,7 @@ const Trestle = forwardRef((props, ref) => {
className="input-origin block" className="input-origin block"
value={kerabaMargin ?? 0} value={kerabaMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })} // onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })}
onChange={(e) => setKerabaMargin(e.target.value)} onChange={(e) => setKerabaMargin(+e.target.value)}
/> />
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>

View File

@ -33,14 +33,6 @@ const PitchPlacement = forwardRef((props, refs) => {
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked }) setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
} }
const moduleData = {
header: [
{ type: 'check', name: '', prop: 'check', width: 70 },
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
{ type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 },
],
}
// //
useEffect(() => { useEffect(() => {
const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key]) const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
@ -105,87 +97,91 @@ const PitchPlacement = forwardRef((props, refs) => {
return ( return (
<> <>
<div className="module-table-box mb10"> <div className="hexagonal-flex-wrap">
<div className="module-table-inner"> <div className="module-table-box ">
<div className="roof-module-table"> <div className="module-table-inner">
<table> <div className="roof-module-table">
<thead> <table>
<tr> <thead>
{moduleData.header.map((data) => ( <tr>
<th key={data.prop} style={{ width: data.width ? data.width : '' }}> <th style={{ width: '70px' }}>
{data.type === 'check' ? ( <div className="d-check-box no-text pop">
<div className="d-check-box no-text pop"> <input type="checkbox" id="ch01" disabled />
<input type="checkbox" id="ch01" disabled /> <label htmlFor="ch01"></label>
<label htmlFor="ch01"></label> </div>
</div>
) : (
data.name
)}
</th> </th>
))} <th>{getMessage('module')}</th>
</tr> </tr>
</thead> </thead>
<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> </tr>
</tr> ))}
))} </tbody>
</tbody> </table>
</table> </div>
</div> </div>
</div> </div>
</div> <div className="module-table-box non-flex">
<div className="module-table-box mb10"> <div className="module-table-inner">
<div className="module-table-inner"> <div className="roof-module-table">
<div className="hexagonal-wrap"> <table>
<div className="hexagonal-item"> <thead>
<div className="bold-font">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting')}</div> <tr>
</div> <th>{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting')}</th>
<div className="hexagonal-item"> </tr>
<div className="pop-form-radio"> </thead>
<div className="d-check-radio pop"> <tbody>
<input <tr>
type="radio" <td>
name="radio01" <div className="hexagonal-radio-wrap">
id="ra01" <div className="d-check-radio pop mb10">
value={'south'} <input
defaultChecked={setupLocation === 'south'} type="radio"
onClick={handleSetupLocation} name="radio01"
/> id="ra01"
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.south')}</label> value={'south'}
</div> defaultChecked={setupLocation === 'south'}
<div className="d-check-radio pop"> onClick={handleSetupLocation}
<input />
type="radio" <label htmlFor="ra01">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.south')}</label>
name="radio01" </div>
id="ra02" <div className="d-check-radio pop">
value={'excreta'} <input
defaultChecked={setupLocation === 'excreta'} type="radio"
onClick={handleSetupLocation} name="radio01"
/> id="ra02"
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.select')}</label> value={'excreta'}
</div> defaultChecked={setupLocation === 'excreta'}
</div> onClick={handleSetupLocation}
/>
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.select')}</label>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>

View File

@ -100,7 +100,7 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
] ]
return ( return (
<WithDraggable isShow={true} pos={pos} className="lrr" style={{ visibility: isHidden ? 'hidden' : 'visible' }}> <WithDraggable isShow={true} pos={pos} className="lrr" isHidden={isHidden}>
<WithDraggable.Header title={getMessage('plan.menu.placement.surface.object')} onClose={() => closePopup(id)} /> <WithDraggable.Header title={getMessage('plan.menu.placement.surface.object')} onClose={() => closePopup(id)} />
<WithDraggable.Body> <WithDraggable.Body>
<div className="modal-btn-wrap"> <div className="modal-btn-wrap">

View File

@ -16,12 +16,13 @@ import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react' import { useState } from 'react'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
import { useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import { canvasState, currentMenuState } from '@/store/canvasAtom' import { canvasState, currentMenuState } from '@/store/canvasAtom'
import { MENU } from '@/common/common' import { MENU } from '@/common/common'
import { useTrestle } from '@/hooks/module/useTrestle' import { useTrestle } from '@/hooks/module/useTrestle'
import { usePolygon } from '@/hooks/usePolygon' import { usePolygon } from '@/hooks/usePolygon'
import { useOrientation } from '@/hooks/module/useOrientation' import { useOrientation } from '@/hooks/module/useOrientation'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
/** /**
* 메뉴 처리 * 메뉴 처리
@ -36,8 +37,22 @@ export default function useMenu() {
const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({}) const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({})
const { clear: trestleClear, setAllModuleSurfaceIsComplete } = useTrestle() const { clear: trestleClear, setAllModuleSurfaceIsComplete } = useTrestle()
const { nextStep } = useOrientation() const { nextStep } = useOrientation()
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
const handleMenu = (type) => { const handleMenu = (type) => {
if (type === 'outline') { if (type === 'outline') {
// 지붕 덮개 메뉴의 경우는 복도치수로 적용한다.
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 0) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
switch (currentMenu) { switch (currentMenu) {
case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE: case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE:
addPopup(popupId, 1, <WallLineSetting id={popupId} />) addPopup(popupId, 1, <WallLineSetting id={popupId} />)
@ -67,6 +82,19 @@ export default function useMenu() {
} }
if (type === 'surface') { if (type === 'surface') {
// 배치면 메뉴의 경우는 실치수로 적용한다.
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 1) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
switch (currentMenu) { switch (currentMenu) {
// case MENU.BATCH_CANVAS.SLOPE_SETTING: // case MENU.BATCH_CANVAS.SLOPE_SETTING:
// addPopup(popupId, 1, <Slope id={popupId} />) // addPopup(popupId, 1, <Slope id={popupId} />)
@ -87,6 +115,19 @@ export default function useMenu() {
} }
if (type === 'module') { if (type === 'module') {
// 모듈,회로 구성 메뉴의 경우는 실치수로 적용한다.
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 1) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
switch (currentMenu) { switch (currentMenu) {
case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING: case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING:
trestleClear() trestleClear()

View File

@ -130,6 +130,7 @@ export const useEstimateController = (planNo, flag) => {
addFlg: true, addFlg: true,
paDispOrder: null, paDispOrder: null,
dispCableFlg: '0', dispCableFlg: '0',
itemTpCd: '',
}, },
], ],
}) })
@ -321,6 +322,7 @@ export const useEstimateController = (planNo, flag) => {
} }
}) })
if (delCnt === estimateData.itemList.length) { if (delCnt === estimateData.itemList.length) {
itemFlg = false
setIsGlobalLoading(false) setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert', icon: 'warning' }) return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert', icon: 'warning' })
} }

File diff suppressed because it is too large Load Diff

View File

@ -13,26 +13,22 @@ import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
export function useModuleSelection(props) { export function useModuleSelection(props) {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const [roughnessCodes, setRoughnessCodes] = useState([]) //면조도 목록 const [roughnessCodes, setRoughnessCodes] = useState([]) //면조도 목록
const [windSpeedCodes, setWindSpeedCodes] = useState([]) //기준풍속 목록 const [windSpeedCodes, setWindSpeedCodes] = useState([]) //기준풍속 목록
const [moduleList, setModuleList] = useState([{}]) //모듈 목록 const [moduleList, setModuleList] = useState([{}]) //모듈 목록
const [selectedSurfaceType, setSelectedSurfaceType] = useState({}) //선택된 면조도 const [selectedSurfaceType, setSelectedSurfaceType] = useState({}) //선택된 면조도
const [installHeight, setInstallHeight] = useState(managementState?.installHeight) //설치 높이 const [installHeight, setInstallHeight] = useState(managementState?.installHeight) //설치 높이
const [standardWindSpeed, setStandardWindSpeed] = useState() //기준풍속 const [standardWindSpeed, setStandardWindSpeed] = useState() //기준풍속
const [verticalSnowCover, setVerticalSnowCover] = useState(managementState?.verticalSnowCover) //수직적설량 const [verticalSnowCover, setVerticalSnowCover] = useState(managementState?.verticalSnowCover) //수직적설량
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈 const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈
const [margin, setMargin] = useState(100)
const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등 const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등
const { getModuleTypeItemList } = useMasterController() const { getModuleTypeItemList } = useMasterController()
const { findCommonCode } = useCommonCode() const { findCommonCode } = useCommonCode()
const resetStatisticsData = useResetRecoilState(moduleStatisticsState) const resetStatisticsData = useResetRecoilState(moduleStatisticsState)
const { restoreModuleInstArea } = useModuleBasicSetting() const { restoreModuleInstArea } = useModuleBasicSetting()
const bindInitData = () => { const bindInitData = () => {
console.log('bindInitData', managementState)
setInstallHeight(managementState?.installHeight) setInstallHeight(managementState?.installHeight)
setStandardWindSpeed(managementState?.standardWindSpeedId) setStandardWindSpeed(managementState?.standardWindSpeedId)
setVerticalSnowCover(managementState?.verticalSnowCover) setVerticalSnowCover(managementState?.verticalSnowCover)
@ -96,7 +92,7 @@ export function useModuleSelection(props) {
getModuleData(roofsIds) getModuleData(roofsIds)
//모듈설치면 초기화 //모듈설치면 초기화
restoreModuleInstArea() // restoreModuleInstArea()
resetStatisticsData() resetStatisticsData()
}, []) }, [])

View File

@ -2,14 +2,13 @@ import { use, useContext, useEffect, useReducer, useState } from 'react'
import { useCommonCode } from '../common/useCommonCode' import { useCommonCode } from '../common/useCommonCode'
import { useMasterController } from '../common/useMasterController' import { useMasterController } from '../common/useMasterController'
import { selectedModuleState } from '@/store/selectedModuleOptions' import { selectedModuleState } from '@/store/selectedModuleOptions'
import { useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import { GlobalDataContext } from '@/app/GlobalDataProvider' import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { popSpinnerState } from '@/store/popupAtom'
const RAFT_BASE_CODE = '203800' const RAFT_BASE_CODE = '203800'
const trestleReducer = (state, action) => { const trestleReducer = (state, action) => {
console.log('🚀 ~ trestleReducer ~ state:', state)
console.log('🚀 ~ trestleReducer ~ action:', action)
switch (action.type) { switch (action.type) {
case 'SET_RAFT_BASE': case 'SET_RAFT_BASE':
case 'SET_TRESTLE_MAKER': case 'SET_TRESTLE_MAKER':
@ -21,26 +20,26 @@ const trestleReducer = (state, action) => {
...action.roof, ...action.roof,
} }
case 'SET_INITIALIZE': case 'SET_INITIALIZE':
console.log('SET_INITIALIZE')
return { return {
moduleTpCd: action.roof.moduleTpCd ?? '', moduleTpCd: action.roof.module?.itemTp ?? '',
roofMatlCd: action.roof.roofMatlCd ?? '', roofMatlCd: action.roof?.roofMatlCd ?? '',
raftBaseCd: action.roof.raftBaseCd ?? null, hajebichi: action.roof?.hajebichi ?? 0,
trestleMkrCd: action.roof.trestleMkrCd ?? null, raftBaseCd: action.roof?.raftBaseCd ?? null,
constMthdCd: action.roof.constMthdCd ?? null, trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null,
constTp: action.roof.constTp ?? null, constMthdCd: action.roof.trestle?.constMthdCd ?? null,
roofBaseCd: action.roof.roofBaseCd ?? null, constTp: action.roof.construction?.constTp ?? null,
roofBaseCd: action.roof.trestle?.roofBaseCd ?? null,
workingWidth: action.roof.workingWidth ?? 0, workingWidth: action.roof.workingWidth ?? 0,
lengthBase: action.roof.length ?? 0, lengthBase: action.roof?.length ?? 0,
illuminationTp: action.roof.illuminationTp ?? null, illuminationTp: action.roof.common?.illuminationTp ?? null,
instHt: action.roof.instHt ?? null, instHt: action.roof.common?.instHt ?? null,
stdWindSpeed: action.roof.stdWindSpeed ?? null, stdWindSpeed: action.roof.common?.stdWindSpeed ?? null,
stdSnowLd: action.roof.stdSnowLd ?? null, stdSnowLd: action.roof.common?.stdSnowLd ?? null,
inclCd: action.roof.inclCd ?? null, inclCd: action.roof?.pitch ?? null,
roofPitch: action.roof.roofPchBase ?? 0, roofPitch: action.roof?.roofPchBase ?? 0,
eavesMargin: action.roof.eavesMargin ?? null, eavesMargin: action.roof?.eavesMargin ?? null,
ridgeMargin: action.roof.ridgeMargin ?? null, ridgeMargin: action.roof?.ridgeMargin ?? null,
kerabaMargin: action.roof.kerabaMargin ?? null, kerabaMargin: action.roof?.kerabaMargin ?? null,
} }
default: default:
return state return state
@ -56,6 +55,9 @@ export function useModuleTrestle(props) {
const [roofBaseList, setRoofBaseList] = useState([]) const [roofBaseList, setRoofBaseList] = useState([])
const [constructionList, setConstructionList] = useState([]) const [constructionList, setConstructionList] = useState([])
const { getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController() const { getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController()
const [lengthBase, setLengthBase] = useState(0)
const [hajebichi, setHajebichi] = useState(0)
const [cvrYn, setCvrYn] = useState('N') const [cvrYn, setCvrYn] = useState('N')
const [cvrChecked, setCvrChecked] = useState(false) const [cvrChecked, setCvrChecked] = useState(false)
const [snowGdPossYn, setSnowGdPossYn] = useState('N') const [snowGdPossYn, setSnowGdPossYn] = useState('N')
@ -64,6 +66,8 @@ export function useModuleTrestle(props) {
const [ridgeMargin, setRidgeMargin] = useState(0) const [ridgeMargin, setRidgeMargin] = useState(0)
const [kerabaMargin, setKerabaMargin] = useState(0) const [kerabaMargin, setKerabaMargin] = useState(0)
const [trestleState, dispatch] = useReducer(trestleReducer, null) const [trestleState, dispatch] = useReducer(trestleReducer, null)
const [trestleDetail, setTrestleDetail] = useState(null)
const [popSpinnerStore, setPopSpinnerStore] = useRecoilState(popSpinnerState)
useEffect(() => { useEffect(() => {
const raftCodeList = findCommonCode(RAFT_BASE_CODE) const raftCodeList = findCommonCode(RAFT_BASE_CODE)
@ -73,103 +77,138 @@ export function useModuleTrestle(props) {
setConstMthdList([]) setConstMthdList([])
setRoofBaseList([]) setRoofBaseList([])
setConstructionList([]) setConstructionList([])
// setEavesMargin(selectedRoof?.addRoof?.eavesMargin ?? 0)
// setRidgeMargin(selectedRoof?.addRoof?.ridgeMargin ?? 0)
// setKerabaMargin(selectedRoof?.addRoof?.kerabaMargin ?? 0)
setHajebichi(selectedRoof?.hajebichi ?? 0)
setEavesMargin(selectedRoof?.eavesMargin ?? 0) setEavesMargin(selectedRoof?.eavesMargin ?? 0)
setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) setRidgeMargin(selectedRoof?.ridgeMargin ?? 0)
setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) setKerabaMargin(selectedRoof?.kerabaMargin ?? 0)
setCvrYn(selectedRoof?.cvrYn ?? 'N') setLengthBase(Math.round(selectedRoof?.length ?? 0))
setCvrChecked(selectedRoof?.cvrChecked ?? false) setCvrYn(selectedRoof?.construction?.cvrYn ?? 'N')
setSnowGdPossYn(selectedRoof?.snowGdPossYn ?? 'N') setCvrChecked(selectedRoof?.construction?.cvrChecked ?? false)
setSnowGdChecked(selectedRoof?.snowGdChecked ?? false) setSnowGdPossYn(selectedRoof?.construction?.snowGdPossYn ?? 'N')
setSnowGdChecked(selectedRoof?.construction?.snowGdChecked ?? false)
setTrestleDetail(selectedRoof?.trestleDetail)
}, [selectedRoof]) }, [selectedRoof])
useEffect(() => { useEffect(() => {
if (trestleState) { if (trestleState) {
console.log('🚀 ~ useEffect ~ trestleState:', trestleState)
handleSetTrestleList() handleSetTrestleList()
if (!trestleState.trestleMkrCd) { if (!trestleState?.trestleMkrCd) {
setConstMthdList([]) setConstMthdList([])
setRoofBaseList([]) setRoofBaseList([])
setConstructionList([]) setConstructionList([])
setTrestleDetail(null)
return return
} }
handleSetConstMthdList() handleSetConstMthdList()
if (!trestleState.constMthdCd) { if (!trestleState?.constMthdCd) {
setRoofBaseList([]) setRoofBaseList([])
setConstructionList([]) setConstructionList([])
setTrestleDetail(null)
return return
} }
handleSetRoofBaseList() handleSetRoofBaseList()
if (!trestleState.roofBaseCd) { if (!trestleState?.roofBaseCd) {
setConstructionList([]) setConstructionList([])
setTrestleDetail(null)
return return
} }
handleSetConstructionList() handleSetConstructionList()
if (!trestleState.constTp) { if (!trestleState?.constTp) {
setTrestleDetail(null)
return return
} }
if (!trestleState.eavesMargin) { if (!trestleState?.eavesMargin) {
handleSetTrestleDetailData() handleSetTrestleDetailData()
} }
} }
}, [trestleState]) }, [trestleState])
const handleSetTrestleList = () => { const handleSetTrestleList = () => {
setPopSpinnerStore(true)
getTrestleList({ getTrestleList({
moduleTpCd: trestleState.moduleTpCd ?? '', moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: trestleState?.raftBaseCd ?? '',
}).then((res) => {
if (res?.data) setTrestleList(res.data)
}) })
.then((res) => {
if (res?.data) setTrestleList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
} }
const handleSetConstMthdList = () => { const handleSetConstMthdList = () => {
setPopSpinnerStore(true)
getTrestleList({ getTrestleList({
moduleTpCd: trestleState.moduleTpCd ?? '', moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: trestleState?.raftBaseCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd ?? '', trestleMkrCd: trestleState?.trestleMkrCd ?? '',
}).then((res) => {
if (res?.data) setConstMthdList(res.data)
}) })
.then((res) => {
if (res?.data) setConstMthdList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
} }
const handleSetRoofBaseList = () => { const handleSetRoofBaseList = () => {
setPopSpinnerStore(true)
getTrestleList({ getTrestleList({
moduleTpCd: trestleState.moduleTpCd ?? '', moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: trestleState?.raftBaseCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd ?? '', trestleMkrCd: trestleState?.trestleMkrCd ?? '',
constMthdCd: trestleState.constMthdCd ?? '', constMthdCd: trestleState?.constMthdCd ?? '',
}).then((res) => {
if (res?.data) setRoofBaseList(res.data)
}) })
.then((res) => {
if (res?.data) setRoofBaseList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
} }
const handleSetConstructionList = () => { const handleSetConstructionList = () => {
setPopSpinnerStore(true)
getConstructionList({ getConstructionList({
moduleTpCd: trestleState.moduleTpCd ?? '', moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd ?? '', trestleMkrCd: trestleState?.trestleMkrCd ?? '',
constMthdCd: trestleState.constMthdCd ?? '', constMthdCd: trestleState?.constMthdCd ?? '',
roofBaseCd: trestleState.roofBaseCd ?? '', roofBaseCd: trestleState?.roofBaseCd ?? '',
illuminationTp: trestleState.illuminationTp ?? '', illuminationTp: trestleState.illuminationTp ?? '',
instHt: trestleState.instHt ?? '', instHt: trestleState.instHt ?? '',
stdWindSpeed: trestleState.stdWindSpeed ?? '', stdWindSpeed: trestleState.stdWindSpeed ?? '',
stdSnowLd: trestleState.stdSnowLd ?? '', stdSnowLd: trestleState.stdSnowLd ?? '',
inclCd: trestleState.inclCd ?? '', inclCd: trestleState.inclCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '', raftBaseCd: trestleState.raftBaseCd ?? '',
roofPitch: trestleState.roofPitch ?? '', roofPitch: Math.round(trestleState.roofPitch) ?? '',
}).then((res) => {
if (res?.data) setConstructionList(res.data)
}) })
.then((res) => {
if (res?.data) setConstructionList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
} }
const handleSetTrestleDetailData = () => { const handleSetTrestleDetailData = () => {
setPopSpinnerStore(true)
getTrestleDetailList([ getTrestleDetailList([
{ {
moduleTpCd: trestleState.moduleTpCd ?? '', moduleTpCd: trestleState.moduleTpCd ?? '',
@ -187,27 +226,35 @@ export function useModuleTrestle(props) {
roofPitch: trestleState.roofPitch ?? '', roofPitch: trestleState.roofPitch ?? '',
workingWidth: trestleState.workingWidth ?? '', workingWidth: trestleState.workingWidth ?? '',
}, },
]).then((res) => { ])
if (res.length > 0) { .then((res) => {
if (!res[0].data) return if (res.length > 0) {
setEavesMargin(res[0].data.eaveIntvl) if (!res[0].data) return
setRidgeMargin(res[0].data.ridgeIntvl) setEavesMargin(res[0].data.eaveIntvl)
setKerabaMargin(res[0].data.kerabaIntvl) setRidgeMargin(res[0].data.ridgeIntvl)
// dispatch({ setKerabaMargin(res[0].data.kerabaIntvl)
// type: 'SET_TRESTLE_DETAIL', setTrestleDetail(res[0].data)
// roof: {
// ...trestleState, // dispatch({
// eavesMargin: res[0].data.eaveIntvl, // type: 'SET_TRESTLE_DETAIL',
// ridgeMargin: res[0].data.ridgeIntvl, // roof: {
// kerabaMargin: res[0].data.kerabaIntvl, // ...trestleState,
// }, // eavesMargin: res[0].data.eaveIntvl,
// }) // ridgeMargin: res[0].data.ridgeIntvl,
} // kerabaMargin: res[0].data.kerabaIntvl,
}) // },
// })
}
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
} }
return { return {
trestleState, trestleState,
trestleDetail,
dispatch, dispatch,
raftBaseList, raftBaseList,
trestleList, trestleList,
@ -219,16 +266,20 @@ export function useModuleTrestle(props) {
handleSetRoofBaseList, handleSetRoofBaseList,
handleSetConstructionList, handleSetConstructionList,
handleSetTrestleDetailData, handleSetTrestleDetailData,
lengthBase,
setLengthBase,
hajebichi,
setHajebichi,
cvrYn,
cvrChecked,
snowGdPossYn,
snowGdChecked,
eavesMargin, eavesMargin,
ridgeMargin, ridgeMargin,
kerabaMargin, kerabaMargin,
setEavesMargin, setEavesMargin,
setRidgeMargin, setRidgeMargin,
setKerabaMargin, setKerabaMargin,
cvrYn,
cvrChecked,
snowGdPossYn,
snowGdChecked,
setCvrYn, setCvrYn,
setCvrChecked, setCvrChecked,
setSnowGdPossYn, setSnowGdPossYn,

View File

@ -22,8 +22,8 @@ export function useOrientation() {
}) })
}, [])*/ }, [])*/
const nextStep = () => { const nextStep = (compas = compasDeg) => {
if (isNaN(compasDeg)) { if (isNaN(compas)) {
setCompasDeg(0) setCompasDeg(0)
} }
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
@ -36,7 +36,7 @@ export function useOrientation() {
roofs.forEach((roof) => { roofs.forEach((roof) => {
roof.set({ roof.set({
moduleCompass: isNaN(compasDeg) ? 0 : compasDeg, moduleCompass: isNaN(compas) ? 0 : compas,
}) })
drawDirectionArrow(roof) drawDirectionArrow(roof)
}) })

View File

@ -371,11 +371,16 @@ export const useTrestle = () => {
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
) )
} else { } else {
//C1C2C3인 경우
let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo)
return ( return (
rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp &&
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count && newLeftRowsInfo.rowsInfo.every((row, index) => {
Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
) )
} }
})?.value.racks })?.value.racks
@ -388,11 +393,15 @@ export const useTrestle = () => {
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
) )
} else { } else {
let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo)
return ( return (
rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp &&
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count && newRightRowsInfo.rowsInfo.every((row, index) => {
Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
) )
} }
})?.value.racks })?.value.racks
@ -405,11 +414,15 @@ export const useTrestle = () => {
rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
) )
} else { } else {
let newCenterRowsInfo = normalizeModules(rack.value.moduleTpCd, centerRowsInfo)
return ( return (
rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && rack.value.moduleTpCd === newCenterRowsInfo.moduleTotalTp &&
rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && rack.value.moduleRows === newCenterRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === centerRowsInfo.rowsInfo[0].count && newCenterRowsInfo.rowsInfo.every((row, index) => {
Number(rack.value.moduleTpRows2) === centerRowsInfo.rowsInfo[1].count const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
) )
} }
})?.value.racks })?.value.racks
@ -500,11 +513,15 @@ export const useTrestle = () => {
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
) )
} else { } else {
let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo)
return ( return (
rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp &&
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count && newLeftRowsInfo.rowsInfo.every((row, index) => {
Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
) )
} }
})?.value.racks })?.value.racks
@ -576,11 +593,16 @@ export const useTrestle = () => {
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
) )
} else { } else {
// 변환 C1C2만 있는경우 C3 0개로 추가해준다.
let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo)
return ( return (
rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp &&
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count && newRightRowsInfo.rowsInfo.every((row, index) => {
Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
) )
} }
})?.value.racks })?.value.racks
@ -635,6 +657,31 @@ export const useTrestle = () => {
return { moduleTotalTp, rowsInfo } return { moduleTotalTp, rowsInfo }
} }
function normalizeModules(rackTpCd, data) {
// rackTpCd를 숫자를 기준으로 자른다.
const allModules = rackTpCd.match(/[A-Za-z]+\d+/g) || [] // 모든 모듈 유형
// 현재 존재하는 모듈 유형을 추출
const existingModules = data.rowsInfo.map((row) => row.moduleTpCd)
const result = { ...data, rowsInfo: [...data.rowsInfo] }
// 없는 모듈을 추가 (count: 0)
allModules.forEach((module) => {
if (!existingModules.includes(module)) {
result.rowsInfo.push({ moduleTpCd: module, count: 0 })
}
})
// rowsInfo를 C1, C2, C3 순서로 정렬
result.rowsInfo.sort((a, b) => allModules.indexOf(a.moduleTpCd) - allModules.indexOf(b.moduleTpCd))
// moduleTotalTp를 C1C2C3로 설정
result.moduleTotalTp = allModules.join('')
return result
}
// itemList 조회 후 estimateParam에 저장 // itemList 조회 후 estimateParam에 저장
const getEstimateData = async () => { const getEstimateData = async () => {
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
@ -661,13 +708,18 @@ export const useTrestle = () => {
}) })
// trestles 배열에서 null인 경우 제거 // trestles 배열에서 null인 경우 제거
const params = { trestles, pcses, modules }
const dblCblTotCnt = getTotalConnectCableCnt()
const params = { trestles, pcses, modules, dblCblTotCnt }
//견적서 itemList 조회 //견적서 itemList 조회
const { data, data2, result } = await getQuotationItem(params) const { data, data2, result } = await getQuotationItem(params)
if (result.resultCode === 'E') { if (result.resultCode === 'E') {
swalFire({ text: result.resultMsg, icon: 'error' }) swalFire({ text: result.resultMsg, icon: 'error' })
clear()
setViewCircuitNumberTexts(true)
setIsGlobalLoading(false)
return return
} }
@ -1000,9 +1052,7 @@ export const useTrestle = () => {
if (!rackInfos) { if (!rackInfos) {
const maxRows = surface.trestleDetail.moduleMaxRows const maxRows = surface.trestleDetail.moduleMaxRows
const maxCols = surface.trestleDetail.moduleMaxCols const maxCols = surface.trestleDetail.moduleMaxCols
const msg = `選択した家で設置可能 const msg = `段数の上限は${maxRows}段です。 上限より上の段には設置できません`
モジュールの最大段数は${maxRows}最大列数は${maxCols}です
上限より上部に取り付けたモジュールを削除してください`
swalFire({ title: msg, type: 'alert' }) swalFire({ title: msg, type: 'alert' })
throw new Error('rackInfos is null') throw new Error('rackInfos is null')
} }
@ -2131,12 +2181,13 @@ export const useTrestle = () => {
const visited = new Set() const visited = new Set()
const width = Math.floor(moduleExample.width) const width = Math.floor(moduleExample.width)
const height = Math.floor(moduleExample.height) const height = Math.floor(moduleExample.height)
const horizonPadding = 0 // 가로 패딩 const horizonPadding = 3 // 가로 패딩
const verticalPadding = 0 // 세로 패딩 const verticalPadding = 7 // 세로 패딩
function isAdjacent(p1, p2) { function isAdjacent(p1, p2) {
const dx = Math.abs(p1.x - p2.x) const dx = Math.abs(p1.x - p2.x)
const dy = Math.abs(p1.y - p2.y) const dy = Math.abs(p1.y - p2.y)
return ( return (
(Math.abs(width + horizonPadding - dx) < 2 && dy < 2) || (Math.abs(width + horizonPadding - dx) < 2 && dy < 2) ||
(dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 || (dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 ||
@ -2168,6 +2219,128 @@ export const useTrestle = () => {
return groups return groups
} }
function areConnected(m1, m2, surface) {
/*const m1Fill = m1.fill
const m2Fill = m2.fill
m1.set({ fill: 'red' })
m2.set({ fill: 'blue' })
canvas.renderAll()*/
let sizes = []
const { width: currentWidth, height: currentHeight, moduleInfo: currentModuleInfo } = m1
const { width: neighborWidth, height: neighborHeight, moduleInfo: neighborModuleInfo } = m2
const { moduleTpCd: currentModuleTpCd } = currentModuleInfo
const { moduleTpCd: neighborModuleTpCd } = neighborModuleInfo
const { x: m1X, y: m1Y } = m1.getCenterPoint()
const { x: m2X, y: m2Y } = m2.getCenterPoint()
sizes.push({ width: currentWidth, height: currentHeight })
if (currentModuleTpCd !== neighborModuleTpCd) {
sizes.push({ width: neighborWidth, height: neighborHeight })
}
/*m1.set({ fill: m1Fill })
m2.set({ fill: m2Fill })
canvas.renderAll()*/
return sizes.some(({ width, height }) => {
let maxX
let maxY
let halfMaxX
let halfMaxY
const { direction, trestleDetail } = surface
const { moduleIntvlHor, moduleIntvlVer } = trestleDetail
if (direction === 'south' || direction === 'north') {
maxX = width + moduleIntvlHor / 10
maxY = height + moduleIntvlVer / 10
halfMaxX = moduleIntvlHor / 10
halfMaxY = moduleIntvlVer / 10
if (currentModuleTpCd !== neighborModuleTpCd) {
maxX = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10
maxY = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10
}
// console.log(maxX, maxY, halfMaxX, halfMaxY)
if (Math.abs(m1X - m2X) < 1) {
return Math.abs(Math.abs(m1Y - m2Y) - maxY) < 1
} else if (Math.abs(m1Y - m2Y) < 1) {
return Math.abs(Math.abs(m1X - m2X) - maxX) < 1
}
return (
(Math.abs(m1X - m2X) < maxX - moduleIntvlHor / 10 && Math.abs(m1Y - m2Y) < maxY - moduleIntvlVer / 10) ||
(Math.abs(Math.abs(m1X - m2X) - maxX / 2) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY) < halfMaxY + 1) ||
(Math.abs(Math.abs(m1X - m2X) - maxX) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY / 2) < halfMaxY + 1)
)
} else if (direction === 'east' || direction === 'west') {
maxX = height + moduleIntvlHor / 10
maxY = width + moduleIntvlVer / 10
halfMaxX = moduleIntvlVer / 10
halfMaxY = moduleIntvlHor / 10
if (currentModuleTpCd !== neighborModuleTpCd) {
maxX = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10
maxY = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10
}
if (Math.abs(m1X - m2X) < 1) {
return Math.abs(Math.abs(m1Y - m2Y) - maxX) < 1
} else if (Math.abs(m1Y - m2Y) < 1) {
return Math.abs(Math.abs(m1X - m2X) - maxY) < 1
}
return (
(Math.abs(m1X - m2X) <= maxY - moduleIntvlVer / 10 && Math.abs(m1Y - m2Y) <= maxX - moduleIntvlHor / 10) ||
(Math.abs(Math.abs(m1X - m2X) - maxY / 2) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX) < halfMaxX + 1) ||
(Math.abs(Math.abs(m1X - m2X) - maxY) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX / 2) < halfMaxX + 1)
)
}
})
}
// 25-04-02 추가
// 그룹화
function groupPoints(modules, surface) {
const groups = []
const visited = new Set()
for (const point of modules) {
const { x: pointX, y: pointY } = point.getCenterPoint()
const key = `${pointX},${pointY}`
if (visited.has(key)) continue
const queue = [point]
const group = []
while (queue.length > 0) {
const current = queue.shift()
const { x: currentX, y: currentY } = current.getCenterPoint()
const currentKey = `${currentX},${currentY}`
if (visited.has(currentKey)) continue
visited.add(currentKey)
group.push(current)
for (const neighbor of modules) {
const { x: neighborX, y: neighborY } = neighbor.getCenterPoint()
const neighborKey = `${neighborX},${neighborY}`
if (!visited.has(neighborKey) && areConnected(current, neighbor, surface)) {
queue.push(neighbor)
}
}
}
groups.push(group)
}
return groups
}
// 각도에 따른 길이 반환 // 각도에 따른 길이 반환
function getTrestleLength(length, degree) { function getTrestleLength(length, degree) {
if (roofSizeSet !== 1) { if (roofSizeSet !== 1) {
@ -2865,5 +3038,82 @@ export const useTrestle = () => {
return surfaces.every((surface) => surface.isComplete) return surfaces.every((surface) => surface.isComplete)
} }
return { apply, getTrestleParams, clear, setViewCircuitNumberTexts, getEstimateData, setAllModuleSurfaceIsComplete, isAllComplete } const groupByType = (originArr = []) => {
const grouped = {}
const newArr = [...originArr]
// 타입별로 객체들을 분류
for (const item of newArr) {
if (!grouped[item.circuitNumber]) {
grouped[item.circuitNumber] = []
}
grouped[item.circuitNumber].push(item)
}
// 객체를 배열로 변환
return Object.values(grouped)
}
function groupByCircuitAndSurface(arr) {
const circuitGroups = {}
for (const item of arr) {
const { circuitNumber, surfaceId } = item
if (!circuitGroups[circuitNumber]) {
circuitGroups[circuitNumber] = new Map()
}
const surfaceMap = circuitGroups[circuitNumber]
const key = surfaceId
if (!surfaceMap.has(key)) {
surfaceMap.set(key, [])
}
surfaceMap.get(key).push(item)
}
// 결과: circuitNumber별 surface 그룹 수
const result = {}
for (const [circuit, surfaceMap] of Object.entries(circuitGroups)) {
result[circuit] = surfaceMap.size
}
return result
}
// 양단 케이블 구하는 공식
const getTotalConnectCableCnt = () => {
let cnt = 0
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
surfaces.forEach((surface) => {
const modules = surface.modules
const groups = groupByType(modules)
groups.forEach((group) => {
const result = groupPoints(group, surface)
cnt += result.length - 1
})
})
const groupByCircuitAndSurfaceCnt = groupByCircuitAndSurface(modules)
Object.keys(groupByCircuitAndSurfaceCnt).forEach((key) => {
cnt += groupByCircuitAndSurfaceCnt[key] - 1
})
return cnt
}
return {
apply,
getTrestleParams,
clear,
setViewCircuitNumberTexts,
getEstimateData,
setAllModuleSurfaceIsComplete,
isAllComplete,
groupCoordinates,
groupPoints,
}
} }

View File

@ -123,6 +123,7 @@ export function useCanvasSetting(executeEffect = true) {
const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */ const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */
const resetSelectedModules = useResetRecoilState(selectedModuleState) /* 선택된 모듈 */ const resetSelectedModules = useResetRecoilState(selectedModuleState) /* 선택된 모듈 */
const { trigger: orientationTrigger } = useCanvasPopupStatusController(1)
const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
const [raftCodes, setRaftCodes] = useState([]) /* 서까래 정보 */ const [raftCodes, setRaftCodes] = useState([]) /* 서까래 정보 */
@ -526,7 +527,10 @@ export function useCanvasSetting(executeEffect = true) {
/** 모듈 선택 데이터 초기화 */ /** 모듈 선택 데이터 초기화 */
resetModuleSelectionData() resetModuleSelectionData()
moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) //1번 초기화
orientationTrigger({ compasDeg: 0, common: {}, module: {} })
//2번 초기화
moduleSelectedDataTrigger({ roofConstructions: [] })
const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE) const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE)
if (!isModuleExist) { if (!isModuleExist) {
resetSelectedModules() resetSelectedModules()

View File

@ -32,6 +32,7 @@ import { outlineDisplaySelector } from '@/store/settingAtom'
import { usePopup } from '@/hooks/usePopup' import { usePopup } from '@/hooks/usePopup'
import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting' import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting'
import Big from 'big.js' import Big from 'big.js'
import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
//외벽선 그리기 //외벽선 그리기
export function useOuterLineWall(id, propertiesId) { export function useOuterLineWall(id, propertiesId) {
@ -256,7 +257,7 @@ export function useOuterLineWall(id, propertiesId) {
canvas?.renderAll() canvas?.renderAll()
setOuterLineFix(true) setOuterLineFix(true)
closePopup(id) closePopup(id)
addPopup(propertiesId, 1, <PropertiesSetting id={propertiesId} pos={{ x: 50, y: 230 }} />) addPopup(propertiesId, 1, <RoofShapeSetting id={propertiesId} pos={{ x: 50, y: 230 }} />)
} }
if (points.length < 3) { if (points.length < 3) {

View File

@ -11,6 +11,7 @@ import {
roofDisplaySelector, roofDisplaySelector,
roofMaterialsSelector, roofMaterialsSelector,
selectedRoofMaterialSelector, selectedRoofMaterialSelector,
settingModalFirstOptionsState,
} from '@/store/settingAtom' } from '@/store/settingAtom'
import { usePopup } from '@/hooks/usePopup' import { usePopup } from '@/hooks/usePopup'
import { POLYGON_TYPE } from '@/common/common' import { POLYGON_TYPE } from '@/common/common'
@ -28,6 +29,7 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta
import { outerLinePointsState } from '@/store/outerLineAtom' import { outerLinePointsState } from '@/store/outerLineAtom'
import { QcastContext } from '@/app/QcastProvider' import { QcastContext } from '@/app/QcastProvider'
import { usePlan } from '@/hooks/usePlan' import { usePlan } from '@/hooks/usePlan'
import { roofsState } from '@/store/roofAtom'
export function useRoofAllocationSetting(id) { export function useRoofAllocationSetting(id) {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -54,9 +56,10 @@ export function useRoofAllocationSetting(id) {
const { setIsGlobalLoading } = useContext(QcastContext) const { setIsGlobalLoading } = useContext(QcastContext)
const { setSurfaceShapePattern } = useRoofFn() const { setSurfaceShapePattern } = useRoofFn()
const { saveCanvas } = usePlan() const { saveCanvas } = usePlan()
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const resetPoints = useResetRecoilState(outerLinePointsState) const resetPoints = useResetRecoilState(outerLinePointsState)
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
useEffect(() => { useEffect(() => {
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */ /** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
@ -265,6 +268,8 @@ export function useRoofAllocationSetting(id) {
newRoofList[0].selected = true newRoofList[0].selected = true
} }
setCurrentRoofList(newRoofList) setCurrentRoofList(newRoofList)
setRoofsStore(newRoofList)
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
} }
/** /**
@ -305,12 +310,14 @@ export function useRoofAllocationSetting(id) {
setRoofList(newRoofList) setRoofList(newRoofList)
setRoofMaterials(newRoofList) setRoofMaterials(newRoofList)
setRoofsStore(newRoofList)
const selectedRoofMaterial = newRoofList.find((roof) => roof.selected) const selectedRoofMaterial = newRoofList.find((roof) => roof.selected)
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true) setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true)
drawDirectionArrow(currentObject) drawDirectionArrow(currentObject)
modifyModuleSelectionData() modifyModuleSelectionData()
closeAll() closeAll()
basicSettingSave() basicSettingSave()
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
} }
/** /**
@ -419,7 +426,7 @@ export function useRoofAllocationSetting(id) {
}) })
setRoofMaterials(newRoofList) setRoofMaterials(newRoofList)
setRoofsStore(newRoofList)
/** 외곽선 삭제 */ /** 외곽선 삭제 */
const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' || obj.name === 'outerLine') const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' || obj.name === 'outerLine')
removeTargets.forEach((obj) => { removeTargets.forEach((obj) => {
@ -428,9 +435,23 @@ export function useRoofAllocationSetting(id) {
setEditingLines([]) setEditingLines([])
closeAll() closeAll()
setSelectedMenu('surface') setSelectedMenu('surface')
//지붕면 완성 후 실측치 로 보이도록 수정
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 1) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
/** 모듈 선택 데이터 초기화 */ /** 모듈 선택 데이터 초기화 */
modifyModuleSelectionData() // modifyModuleSelectionData()
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
} }
/** /**
@ -548,7 +569,7 @@ export function useRoofAllocationSetting(id) {
* 모듈 선택에서 선택한 데이터 초기화 * 모듈 선택에서 선택한 데이터 초기화
*/ */
const modifyModuleSelectionData = () => { const modifyModuleSelectionData = () => {
if (moduleSelectionData.roofConstructions.length > 0) { if (moduleSelectionData.roofConstructions?.length > 0) {
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: [] }) setModuleSelectionData({ ...moduleSelectionData, roofConstructions: [] })
moduleSelectedDataTrigger({ ...moduleSelectionData, roofConstructions: [] }) moduleSelectedDataTrigger({ ...moduleSelectionData, roofConstructions: [] })
} }

View File

@ -231,6 +231,21 @@ export function useRoofShapeSetting(id) {
pitch: pitchRef.current, pitch: pitchRef.current,
onlyOffset: true, onlyOffset: true,
} }
switch (line.direction) {
case 'bottom':
direction = 'east'
break
case 'top':
direction = 'west'
break
case 'left':
direction = 'south'
break
case 'right':
direction = 'north'
break
}
} }
}) })
} }
@ -716,6 +731,7 @@ export function useRoofShapeSetting(id) {
type: LINE_TYPE.WALLLINE.SHED, type: LINE_TYPE.WALLLINE.SHED,
pitch: shedPitchRef.current, pitch: shedPitchRef.current,
width: shedWidth / 10, width: shedWidth / 10,
offset: shedWidth / 10,
} }
selectedLine.attributes = { ...attributes, isFixed: true } selectedLine.attributes = { ...attributes, isFixed: true }
addPitchText(currentObject) addPitchText(currentObject)

View File

@ -31,7 +31,7 @@ export function useCircuitTrestle(executeEffect = false) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
useEffect(() => { useEffect(() => {
if (Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData() if (selectedModules && Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData()
}, [selectedModules]) }, [selectedModules])
const getOptYn = () => { const getOptYn = () => {

View File

@ -77,10 +77,10 @@ export function useEvent() {
setCanvasZoom(Number((zoom * 100).toFixed(0))) setCanvasZoom(Number((zoom * 100).toFixed(0)))
// 마우스 위치 기준으로 확대/축소 // 마우스 위치 기준으로 확대/축소
canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom) canvas.zoomToPoint(new fabric.Point(opt.e.offsetX, opt.e.offsetY), zoom)
canvas.requestRenderAll()
canvas.calcOffset() canvas.calcOffset()
canvas.setViewportTransform(canvas.viewportTransform)
canvas.requestRenderAll()
// 이벤트의 기본 동작 방지 (스크롤 방지) // 이벤트의 기본 동작 방지 (스크롤 방지)
opt.e.preventDefault() opt.e.preventDefault()

View File

@ -37,7 +37,7 @@
"modal.roof.shape.setting.ridge": "棟", "modal.roof.shape.setting.ridge": "棟",
"modal.roof.shape.setting.patten.a": "Aパターン", "modal.roof.shape.setting.patten.a": "Aパターン",
"modal.roof.shape.setting.patten.b": "Bパターン", "modal.roof.shape.setting.patten.b": "Bパターン",
"modal.roof.shape.setting.side": "別に設定", "modal.roof.shape.setting.side": "別に設定",
"plan.menu.roof.cover": "伏せ図入力", "plan.menu.roof.cover": "伏せ図入力",
"plan.menu.roof.cover.outline.drawing": "外壁線を描く", "plan.menu.roof.cover.outline.drawing": "外壁線を描く",
"plan.menu.roof.cover.roof.shape.setting": "屋根形状の設定", "plan.menu.roof.cover.roof.shape.setting": "屋根形状の設定",
@ -114,6 +114,17 @@
"modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置", "modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置",
"modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置", "modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置",
"modal.module.basic.setting.module.select": "モジュール/架台選択", "modal.module.basic.setting.module.select": "モジュール/架台選択",
"modal.module.basic.settting.module.error1": "架台メーカーを選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error2": "工法を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error3": "屋根の下を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error4": "施工法を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error5": "L を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error7": "下在ビーチを入力してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。(屋根材: {1})(JA)",
"modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。(屋根材: {1})(JA)",
"modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。(屋根材: {1})(JA)",
"modal.module.basic.setting.module.placement": "モジュールの配置", "modal.module.basic.setting.module.placement": "モジュールの配置",
"modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。", "modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置",
@ -125,19 +136,19 @@
"modal.module.basic.setting.module.placement.do.not": "しない", "modal.module.basic.setting.module.placement.do.not": "しない",
"modal.module.basic.setting.module.placement.arrangement.standard": "配置基準", "modal.module.basic.setting.module.placement.arrangement.standard": "配置基準",
"modal.module.basic.setting.module.placement.arrangement.standard.center": "中央", "modal.module.basic.setting.module.placement.arrangement.standard.center": "中央",
"modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒側", "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒側",
"modal.module.basic.setting.module.placement.arrangement.standard.ridge": "龍丸側", "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "側",
"modal.module.basic.setting.module.placement.maximum": "最大配置", "modal.module.basic.setting.module.placement.maximum": "最大配置",
"modal.module.basic.setting.pitch.module.placement.standard.setting": "配置基準設定", "modal.module.basic.setting.pitch.module.placement.standard.setting": "配置基準設定",
"modal.module.basic.setting.pitch.module.placement.standard.setting.south": "南向き設置", "modal.module.basic.setting.pitch.module.placement.standard.setting.south": "南向き設置",
"modal.module.basic.setting.pitch.module.placement.standard.setting.select": "指定した辺を基準に設置", "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "指定した辺を基準に設置する",
"modal.module.basic.setting.pitch.module.allocation.setting": "割り当て設定", "modal.module.basic.setting.pitch.module.allocation.setting": "割り当て設定",
"modal.module.basic.setting.pitch.module.allocation.setting.info": "※配置パネルの種類が1種類の場合のみ使用できます。", "modal.module.basic.setting.pitch.module.allocation.setting.info": "※配置パネルの種類が1種類の場合のみ使用できます。",
"modal.module.basic.setting.pitch.module.row.amount": "単数", "modal.module.basic.setting.pitch.module.row.amount": "単数",
"modal.module.basic.setting.pitch.module.row.margin": "上下間隔", "modal.module.basic.setting.pitch.module.row.margin": "上下間隔",
"modal.module.basic.setting.pitch.module.column.amount": "列数", "modal.module.basic.setting.pitch.module.column.amount": "列数",
"modal.module.basic.setting.pitch.module.column.margin": "左右間隔", "modal.module.basic.setting.pitch.module.column.margin": "左右間隔",
"modal.module.basic.setting.prev": "移転", "modal.module.basic.setting.prev": "前に戻る",
"modal.module.basic.setting.row.batch": "単数指定配置", "modal.module.basic.setting.row.batch": "単数指定配置",
"modal.module.basic.setting.passivity.placement": "手動配置", "modal.module.basic.setting.passivity.placement": "手動配置",
"modal.module.basic.setting.auto.placement": "自動配置", "modal.module.basic.setting.auto.placement": "自動配置",
@ -604,6 +615,7 @@
"myinfo.message.password.error": "パスワードが間違っています。", "myinfo.message.password.error": "パスワードが間違っています。",
"login": "ログイン", "login": "ログイン",
"login.auto.page.text": "自動ログイン中です。", "login.auto.page.text": "自動ログイン中です。",
"login.fail": "계정이 없거나 비밀번호가 잘못되었습니다.",
"login.id.save": "ID保存", "login.id.save": "ID保存",
"login.id.placeholder": "IDを入力してください。", "login.id.placeholder": "IDを入力してください。",
"login.password.placeholder": "パスワードを入力してください。", "login.password.placeholder": "パスワードを入力してください。",
@ -851,7 +863,7 @@
"has.not.sleeve": "袖なし", "has.not.sleeve": "袖なし",
"jerkinhead.width": "半切妻幅", "jerkinhead.width": "半切妻幅",
"jerkinhead.slope": "半切妻傾斜", "jerkinhead.slope": "半切妻傾斜",
"shed.width": "片流幅", "shed.width": "片流れの出幅",
"windage": "片流れ", "windage": "片流れ",
"windage.width": "片流れの出幅", "windage.width": "片流れの出幅",
"write": "作成", "write": "作成",
@ -905,6 +917,7 @@
"estimate.detail.estimateType": "注文分類", "estimate.detail.estimateType": "注文分類",
"estimate.detail.estimateType.yjss": "住宅PKG", "estimate.detail.estimateType.yjss": "住宅PKG",
"estimate.detail.estimateType.yjod": "積上げYJOD", "estimate.detail.estimateType.yjod": "積上げYJOD",
"estimate.detail.agency": "2次店名",
"estimate.detail.roofCns": "屋根材・施工区分", "estimate.detail.roofCns": "屋根材・施工区分",
"estimate.detail.remarks": "備考", "estimate.detail.remarks": "備考",
"estimate.detail.fileFlg": "後日資料提出", "estimate.detail.fileFlg": "後日資料提出",
@ -1046,12 +1059,19 @@
"outerLine.property.fix": "外壁線の属性設定 を完了しますか?", "outerLine.property.fix": "外壁線の属性設定 を完了しますか?",
"outerLine.property.close": "外壁線の属性設定 を終了しますか?", "outerLine.property.close": "外壁線の属性設定 を終了しますか?",
"want.to.complete.auxiliary.creation": "補助線の作成を完了しますか?", "want.to.complete.auxiliary.creation": "補助線の作成を完了しますか?",
"module.layout.setup.has.zero.value": "モジュールの列、行を入力してください.",
"modal.placement.initial.setting.plan.drawing.only.number": "(※数字は[半角]入力のみ可能です。)", "modal.placement.initial.setting.plan.drawing.only.number": "(※数字は[半角]入力のみ可能です。)",
"wall.line.not.found": "外壁がありません", "wall.line.not.found": "外壁がありません",
"roof.line.not.found": "屋根形状がありません", "roof.line.not.found": "屋根形状がありません",
"roof.material.can.not.delete": "割り当てられた配置面があります。", "roof.material.can.not.delete": "割り当てられた配置面があります。",
"chidory.can.not.install": "千鳥配置できない工法です。", "chidory.can.not.install": "千鳥配置できない工法です。",
"module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다. (JA)", "module.layout.setup.max.count": "モジュールの最大段数は{0}、最大列数は{1}です。 (JA)",
"module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다. (JA)", "module.layout.setup.max.count.multiple": "モジュール{0}の最大段数は{1}、最大列数は{2}です。 (JA)",
"roofAllocation.not.found": "할당할 지붕이 없습니다. (JA)" "roofAllocation.not.found": "割り当てる屋根がありません。 (JA)",
"modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの最大単数。混合最大単数を確認してください。 (JA)",
"modal.module.basic.setting.module.placement.max.row": "最大 単数(JA)",
"modal.module.basic.setting.module.placement.max.rows.multiple": "混合単数(JA)",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)",
"modal.module.basic.setting.module.placement.mix.asg.yn": "ミックス. (JA)",
"modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)"
} }

View File

@ -114,6 +114,17 @@
"modal.module.basic.setting.module.eaves.bar.fitting": "처마커버설치", "modal.module.basic.setting.module.eaves.bar.fitting": "처마커버설치",
"modal.module.basic.setting.module.blind.metal.fitting": "적설방지금구설치", "modal.module.basic.setting.module.blind.metal.fitting": "적설방지금구설치",
"modal.module.basic.setting.module.select": "모듈/가대 선택", "modal.module.basic.setting.module.select": "모듈/가대 선택",
"modal.module.basic.settting.module.error1": "가대메이커를 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error2": "공법를 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error3": "지붕밑바탕을 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error4": "시공법을 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error5": "L 을 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error6": "서까래 간격을 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error7": "하제비치를 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error8": "모듈 배치 영역 값을 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error9": "처마쪽 값은 {0}mm 이상이어야 합니다.(지붕재: {1})",
"modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.(지붕재: {1})",
"modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.(지붕재: {1})",
"modal.module.basic.setting.module.placement": "모듈 배치", "modal.module.basic.setting.module.placement": "모듈 배치",
"modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.", "modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치",
@ -128,6 +139,7 @@
"modal.module.basic.setting.module.placement.arrangement.standard.eaves": "처마쪽", "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "처마쪽",
"modal.module.basic.setting.module.placement.arrangement.standard.ridge": "용마루쪽", "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "용마루쪽",
"modal.module.basic.setting.module.placement.maximum": "최대배치", "modal.module.basic.setting.module.placement.maximum": "최대배치",
"modal.module.basic.setting.module.placement.margin.check1": "가대메이커를 선택해주세요.",
"modal.module.basic.setting.pitch.module.placement.standard.setting": "배치기준 설정", "modal.module.basic.setting.pitch.module.placement.standard.setting": "배치기준 설정",
"modal.module.basic.setting.pitch.module.placement.standard.setting.south": "남향설치", "modal.module.basic.setting.pitch.module.placement.standard.setting.south": "남향설치",
"modal.module.basic.setting.pitch.module.placement.standard.setting.select": "지정한 변을 기준으로 설치", "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "지정한 변을 기준으로 설치",
@ -906,6 +918,7 @@
"estimate.detail.estimateType": "주문분류", "estimate.detail.estimateType": "주문분류",
"estimate.detail.estimateType.yjss": "住宅PKG", "estimate.detail.estimateType.yjss": "住宅PKG",
"estimate.detail.estimateType.yjod": "積上げ( YJOD )", "estimate.detail.estimateType.yjod": "積上げ( YJOD )",
"estimate.detail.agency": "2차점명",
"estimate.detail.roofCns": "지붕재・사양시공", "estimate.detail.roofCns": "지붕재・사양시공",
"estimate.detail.remarks": "비고", "estimate.detail.remarks": "비고",
"estimate.detail.fileFlg": "후일자료제출", "estimate.detail.fileFlg": "후일자료제출",
@ -1047,6 +1060,7 @@
"outerLine.property.fix": "외벽선 속성 설정을 완료하시겠습니까?", "outerLine.property.fix": "외벽선 속성 설정을 완료하시겠습니까?",
"outerLine.property.close": "외벽선 속성 설정을 종료하시겠습니까?", "outerLine.property.close": "외벽선 속성 설정을 종료하시겠습니까?",
"want.to.complete.auxiliary.creation": "보조선 작성을 완료하시겠습니까?", "want.to.complete.auxiliary.creation": "보조선 작성을 완료하시겠습니까?",
"module.layout.setup.has.zero.value": "모듈의 열, 행을 입력해 주세요.",
"modal.placement.initial.setting.plan.drawing.only.number": "(※ 숫자는 [반각]입력만 가능합니다.)", "modal.placement.initial.setting.plan.drawing.only.number": "(※ 숫자는 [반각]입력만 가능합니다.)",
"wall.line.not.found": "외벽선이 없습니다.", "wall.line.not.found": "외벽선이 없습니다.",
"roof.line.not.found": "지붕형상이 없습니다.", "roof.line.not.found": "지붕형상이 없습니다.",
@ -1054,5 +1068,11 @@
"chidory.can.not.install": "치조 불가 공법입니다.", "chidory.can.not.install": "치조 불가 공법입니다.",
"module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.", "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.",
"module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다.", "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다.",
"roofAllocation.not.found": "할당할 지붕이 없습니다." "roofAllocation.not.found": "할당할 지붕이 없습니다.",
"modal.module.basic.setting.module.placement.max.size.check": "지붕재별 모듈의 최대 단수. 혼합 최대 단수를 확인하십시오.",
"modal.module.basic.setting.module.placement.max.row": "최대 단수",
"modal.module.basic.setting.module.placement.max.rows.multiple": "혼합 단수",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "혼합 설치 불가능한 모듈입니다.",
"modal.module.basic.setting.module.placement.mix.asg.yn": "혼합",
"modal.module.basic.setting.layoutpassivity.placement": "레이아웃 배치"
} }

View File

@ -384,3 +384,27 @@ export const isManualModuleSetupState = atom({
key: 'isManualModuleSetupState', key: 'isManualModuleSetupState',
default: false, default: false,
}) })
export const isManualModuleLayoutSetupState = atom({
key: 'isManualModuleLayoutSetupState',
default: false,
})
export const moduleSetupOptionState = atom({
key: 'moduleSetupOptionState',
default: {
isChidori: false, //치조 안함
setupLocation: 'eaves', //처마
},
})
export const toggleManualSetupModeState = atom({
key: 'toggleManualSetupModeState',
default: '',
})
export const moduleRowColArrayState = atom({
key: 'moduleRowColArrayState',
default: [],
dangerouslyAllowMutability: true,
})

View File

@ -2,7 +2,7 @@ import { atom } from 'recoil'
export const selectedModuleState = atom({ export const selectedModuleState = atom({
key: 'selectedModuleState', key: 'selectedModuleState',
default: [], default: null,
dangerouslyAllowMutability: true, dangerouslyAllowMutability: true,
}) })

View File

@ -47,6 +47,16 @@ table{
} }
.form-flex-wrap{ .form-flex-wrap{
@include flexbox; @include flexbox;
.form-flex-select{
@include flexbox;
label{
flex: none;
margin-right: 5px;
}
.form-select{
min-width: 300px;
}
}
} }
.date-picker-wrap{ .date-picker-wrap{
width: 100%; width: 100%;

2
startscript-3000.js Normal file
View File

@ -0,0 +1,2 @@
var exec = require('child_process').exec
exec('yarn dev -p 3000', { windowsHide: true })