From 4de8b7d617e2e6da7356510bba848fa795b15b27 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 22 Jan 2025 11:23:02 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=B0=EC=B9=98=20=EC=98=A4=EB=B8=8C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20offset=EB=9D=BC=EC=9D=B8=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 1 + .../floor-plan/modal/basic/step/Module.jsx | 16 +- .../modal/basic/step/ModuleTabContents.jsx | 140 ++++++++++++------ src/hooks/module/useModuleBasicSetting.js | 68 ++++++--- src/hooks/module/useModulePlace.js | 2 +- src/hooks/module/useModuleSelection.js | 9 +- src/hooks/object/useObjectBatch.js | 12 +- src/locales/ko.json | 1 + src/store/selectedModuleOptions.js | 1 + 9 files changed, 166 insertions(+), 84 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index 71a075db..59e8be6c 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -113,6 +113,7 @@ export const POLYGON_TYPE = { TRESTLE: 'trestle', MODULE_SETUP_SURFACE: 'moduleSetupSurface', MODULE: 'module', + OBJECT_SURFACE: 'objectOffset', } export const SAVE_KEY = [ diff --git a/src/components/floor-plan/modal/basic/step/Module.jsx b/src/components/floor-plan/modal/basic/step/Module.jsx index 811b21d3..2ea37896 100644 --- a/src/components/floor-plan/modal/basic/step/Module.jsx +++ b/src/components/floor-plan/modal/basic/step/Module.jsx @@ -12,9 +12,8 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta export default function Module({ setTabNum }) { const { getMessage } = useMessage() - const addedRoofs = useRecoilValue(addedRoofsState) //지붕재 선택 + const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //지붕재 선택 const [roofTab, setRoofTab] = useState(0) //지붕재 탭 - const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) const { moduleSelectionInitParams, @@ -23,7 +22,9 @@ export default function Module({ setTabNum }) { windSpeedCodes, managementState, moduleList, + selectedSurfaceType, installHeight, + standardWindSpeed, verticalSnowCover, handleChangeModule, handleChangeSurfaceType, @@ -32,7 +33,7 @@ export default function Module({ setTabNum }) { handleChangeVerticalSnowCover, } = useModuleSelection({ addedRoofs }) - const [inputInstallHeight, setInputInstallHeight] = useState()`` + const [inputInstallHeight, setInputInstallHeight] = useState() const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState() const [debouncedInstallHeight] = useDebounceValue(inputInstallHeight, 500) @@ -55,7 +56,7 @@ export default function Module({ setTabNum }) { useEffect(() => { if (tempModuleSelectionData) { setModuleSelectionData(tempModuleSelectionData) - moduleSelectedDataTrigger(tempModuleSelectionData) + // moduleSelectedDataTrigger(tempModuleSelectionData) } }, [tempModuleSelectionData]) @@ -88,11 +89,7 @@ export default function Module({ setTabNum }) { setRoofTab(tab) } - const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) - - useEffect(() => { - console.log('moduleSelectionData', moduleSelectionData) - }, []) + // const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) return ( <> @@ -247,6 +244,7 @@ export default function Module({ setTabNum }) { key={index} index={index} addRoof={roof} + setAddedRoofs={setAddedRoofs} roofTab={index} tempModuleSelectionData={tempModuleSelectionData} setTempModuleSelectionData={setTempModuleSelectionData} diff --git a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx index 9d644984..64a93ccd 100644 --- a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx +++ b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx @@ -7,10 +7,14 @@ import { useCommonCode } from '@/hooks/common/useCommonCode' import { moduleSelectionDataState, moduleSelectionInitParamsState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' import QSelectBox from '@/components/common/select/QSelectBox' +import { addedRoofsState } from '@/store/settingAtom' -export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) { +export default function ModuleTabContents({ addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) { const { getMessage } = useMessage() const [roofMaterial, setRoofMaterial] = useState(addRoof) //지붕재` + + const addRoofsArray = useRecoilValue(addedRoofsState) + const globalPitchText = useRecoilValue(pitchTextSelector) //피치 텍스트 const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) @@ -51,6 +55,40 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 + const [hajebichi, setHajebichi] = useState(0) + const [lengthBase, setLengthBase] = useState(0) + + const hajebichiRef = useRef() + const lengthRef = useRef() + + useEffect(() => { + setHajebichi(addRoof.hajebichi) + setLengthBase(addRoof.lenBase) + }, []) + + //높이를 변경하면 addRoofs에 적용 + useEffect(() => { + //가대 조회 api 파라메터 + setTrestleParams({ ...trestleParams, workingWidth: lengthBase }) + + const copyAddRoof = { ...addRoof } + copyAddRoof.length = Number(lengthBase) + copyAddRoof.lenBase = lengthBase + const index = addRoof.index + const newArray = [...addRoofsArray.slice(0, index), copyAddRoof, ...addRoofsArray.slice(index + 1)] + setAddedRoofs(newArray) + }, [lengthBase]) + + //망둥어 피치를 변경하면 addRoof 변경 + useEffect(() => { + const copyAddRoof = { ...addRoof } + copyAddRoof.hajebichi = Number(hajebichi) + copyAddRoof.roofPchBase = hajebichi + const index = addRoof.index + const newArray = [...addRoofsArray.slice(0, index), copyAddRoof, ...addRoofsArray.slice(index + 1)] + setAddedRoofs(newArray) + }, [hajebichi]) + useEffect(() => { setModuleConstructionSelectionData(moduleSelectionData.roofConstructions[roofTab]) }, [moduleSelectionData]) @@ -76,7 +114,13 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio //공법 변경 const handleChangeConstMthd = (option) => { setSelectedConstMthd(option) //선택된값 저장 - setRoofBaseParams({ ...trestleParams, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: option.constMthdCd, roofBaseCd: '' }) + setRoofBaseParams({ + ...trestleParams, + trestleMkrCd: selectedTrestle.trestleMkrCd, + constMthdCd: option.constMthdCd, + roofBaseCd: '', + roofPitch: hajebichiRef.current ? hajebichiRef.current.value : '', + }) setRoofBaseList([]) //지붕밑바탕 초기화 setConstructionList([]) //공법 초기화 } @@ -114,6 +158,14 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio selectedConstruction.setupSnowCover = false //눈막이금구 설치 여부 selectedConstruction.selectedIndex = index + //기존에 선택된 데이터가 있으면 체크한다 + if (moduleConstructionSelectionData && moduleConstructionSelectionData.construction) { + selectedConstruction.setupCover = moduleConstructionSelectionData.construction.setupCover + selectedConstruction.setupSnowCover = moduleConstructionSelectionData.construction.setupSnowCover + setCvrChecked(selectedConstruction.setupCover) + setSnowGdChecked(selectedConstruction.setupSnowCover) + } + setCvrYn(selectedConstruction.cvrYn) setSnowGdPossYn(selectedConstruction.snowGdPossYn) setSelectedConstruction(selectedConstruction) @@ -126,10 +178,12 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio const handleCvrChecked = () => { setCvrChecked(!cvrChecked) + setSelectedConstruction({ ...selectedConstruction, setupCover: !cvrChecked }) } const handleSnowGdChecked = () => { setSnowGdChecked(!snowGdChecked) + setSelectedConstruction({ ...selectedConstruction, setupSnowCover: !snowGdChecked }) } const getModuleOptionsListData = async (params) => { @@ -195,14 +249,6 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio } }, [selectedConstruction]) - useEffect(() => { - setSelectedConstruction({ ...selectedConstruction, setupCover: cvrChecked }) - }, [cvrChecked]) - - useEffect(() => { - setSelectedConstruction({ ...selectedConstruction, setupSnowCover: snowGdChecked }) - }, [snowGdChecked]) - useEffect(() => { if (isExistData) { setConstructionListParams({ @@ -215,7 +261,12 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio }, [selectedRoofBase]) useEffect(() => { - if (isExistData && constructionList.length > 0) { + if ( + isExistData && + constructionList.length > 0 && + isObjectNotEmpty(moduleConstructionSelectionData.construction) && + moduleConstructionSelectionData.construction.hasOwnProperty('constPossYn') ///키가 있으면 + ) { const selectedIndex = moduleConstructionSelectionData.construction.selectedIndex const construction = constructionList[selectedIndex] if (construction.constPossYn === 'Y') { @@ -245,15 +296,19 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio ) { const isModuleLoaded = moduleSelectionInitParams.hasOwnProperty('moduleTpCd') //모듈컬럼이 있으면 모듈을 변경했다는 내용 if (isModuleLoaded) { - setTrestleParams({ moduleTpCd: moduleSelectionInitParams.moduleTpCd, roofMatlCd: addRoof.roofMatlCd, raftBaseCd: addRoof.raftBaseCd }) + setTrestleParams({ + moduleTpCd: moduleSelectionInitParams.moduleTpCd, + roofMatlCd: addRoof.roofMatlCd, + raftBaseCd: addRoof.raftBaseCd, + workingWidth: lengthBase, + }) setConstructionList([]) if (isObjectNotEmpty(moduleConstructionSelectionData)) { //기존에 데이터가 있으면 파라메터를 넣는다 setConstructionParams({ ...moduleConstructionSelectionData.trestle, constMthdCd: '', roofBaseCd: '' }) setRoofBaseParams({ ...moduleConstructionSelectionData.trestle, roofBaseCd: '' }) - setCvrChecked(moduleConstructionSelectionData.construction.setupCover) - setSnowGdChecked(moduleConstructionSelectionData.construction.setupSnowCover) + setIsExistData(true) } } @@ -286,11 +341,11 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio } }, [constructionListParams]) - useEffect(() => { - if (isObjectNotEmpty(tempModuleSelectionData)) { - setModuleSelectionData(tempModuleSelectionData) - } - }, [tempModuleSelectionData]) + // useEffect(() => { + // if (isObjectNotEmpty(tempModuleSelectionData)) { + // setModuleSelectionData(tempModuleSelectionData) + // } + // }, [tempModuleSelectionData]) return ( <> @@ -308,21 +363,21 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio <>
L
-
-
-
- -
-
+
+ setLengthBase(e.target.value)} + disabled={roofMaterial.lenAuth === 'R' ? true : false} + ref={lengthRef} + />
)} +
+
{roofMaterial && ['C', 'R'].includes(roofMaterial.raftAuth) && ( <>
{getMessage('modal.module.basic.setting.module.rafter.margin')}
@@ -343,22 +398,21 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
)} + +
{roofMaterial && ['C', 'R'].includes(roofMaterial.roofPchAuth) && ( <> -
{getMessage('modal.module.basic.setting.module.rafter.margin')}
+
{getMessage('modal.module.basic.setting.module.hajebichi')}
-
-
- 垂木の間隔 -
- -
-
+
+ setHajebichi(e.target.value)} + value={hajebichi} + ref={hajebichiRef} + />
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 305dcda0..af187a0a 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -73,6 +73,7 @@ export function useModuleBasicSetting() { const makeModuleInstArea = () => { //지붕 객체 반환 + const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof') let offsetLength = canvasSetting.roofSizeSet === 3 ? -90 : -20 @@ -80,6 +81,50 @@ export function useModuleBasicSetting() { return } + const batchObjects = canvas + ?.getObjects() + .filter( + (obj) => + obj.name === BATCH_TYPE.OPENING || + obj.name === BATCH_TYPE.SHADOW || + obj.name === BATCH_TYPE.TRIANGLE_DORMER || + obj.name === BATCH_TYPE.PENTAGON_DORMER, + ) //도머s 객체 + + //도머도 외곽을 따야한다 + + const batchObjectOptions = { + stroke: 'red', + fill: 'transparent', + strokeDashArray: [10, 4], + strokeWidth: 1, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + selectable: true, + name: POLYGON_TYPE.OBJECT_SURFACE, + originX: 'center', + originY: 'center', + } + + batchObjects.forEach((obj) => { + if (obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) { + const groupPoints = obj.groupPoints + const offsetObjects = offsetPolygon(groupPoints, 10) + const dormerOffset = new QPolygon(offsetObjects, batchObjectOptions) + dormerOffset.setViewLengthText(false) + canvas.add(dormerOffset) //모듈설치면 만들기 + } else { + const points = obj.points + const offsetObjects = offsetPolygon(points, 10) + const offset = new QPolygon(offsetObjects, batchObjectOptions) + offset.setViewLengthText(false) + canvas.add(offset) //모듈설치면 만들기 + } + }) + roofs.forEach((roof) => { const isExistSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.parentId === roof.id) if (isExistSurface) { @@ -190,15 +235,7 @@ export function useModuleBasicSetting() { } const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 - const batchObjects = canvas - ?.getObjects() - .filter( - (obj) => - obj.name === BATCH_TYPE.OPENING || - obj.name === BATCH_TYPE.TRIANGLE_DORMER || - obj.name === BATCH_TYPE.PENTAGON_DORMER || - obj.name === BATCH_TYPE.SHADOW, - ) //도머s 객체 + const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체 const moduleOptions = { fill: checkedModule[0].color, @@ -449,17 +486,7 @@ export function useModuleBasicSetting() { //도머 객체를 가져옴 if (batchObjects) { batchObjects.forEach((object) => { - let dormerTurfPolygon - - if (object.type === 'group') { - //도머는 그룹형태임 - dormerTurfPolygon = batchObjectGroupToTurfPolygon(object) - } else { - //개구, 그림자 - object.set({ points: rectToPolygon(object) }) - dormerTurfPolygon = polygonToTurfPolygon(object) - } - + let dormerTurfPolygon = polygonToTurfPolygon(object, true) const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인 //겹치면 안됨 if (intersection) { @@ -1220,6 +1247,7 @@ export function useModuleBasicSetting() { } const coordToTurfPolygon = (points) => { + console.log('points', points) const coordinates = points.map((point) => [point.x, point.y]) coordinates.push(coordinates[0]) return turf.polygon([coordinates]) diff --git a/src/hooks/module/useModulePlace.js b/src/hooks/module/useModulePlace.js index b519f063..1716c1c2 100644 --- a/src/hooks/module/useModulePlace.js +++ b/src/hooks/module/useModulePlace.js @@ -28,7 +28,7 @@ export function useModulePlace() { roofBaseCd: item.trestle.roofBaseCd, constTp: item.construction.constTp, mixMatlNo: selectedModules.mixMatlNo, - roofPitch: selectedModules.roofPchBase ? selectedModules.roofPchBase : null, + roofPitch: item.addRoof.roofPchBase ? item.addRoof.roofPchBase : null, inclCd: String(item.addRoof.pitch), roofIndex: item.addRoof.index, workingWidth: item.addRoof.lenBase, diff --git a/src/hooks/module/useModuleSelection.js b/src/hooks/module/useModuleSelection.js index 6bd8ca3b..2cf6e509 100644 --- a/src/hooks/module/useModuleSelection.js +++ b/src/hooks/module/useModuleSelection.js @@ -4,7 +4,7 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider' import { useMasterController } from '@/hooks/common/useMasterController' import { useCommonCode } from '@/hooks/common/useCommonCode' -import { selectedModuleState, moduleSelectionInitParamsState } from '@/store/selectedModuleOptions' +import { selectedModuleState, moduleSelectionInitParamsState, moduleSelectionDataState } from '@/store/selectedModuleOptions' export function useModuleSelection(props) { const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) @@ -13,15 +13,14 @@ export function useModuleSelection(props) { const [windSpeedCodes, setWindSpeedCodes] = useState([]) //기준풍속 목록 const [moduleList, setModuleList] = useState([{}]) //모듈 목록 - const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈 const [selectedSurfaceType, setSelectedSurfaceType] = useState({}) //선택된 면조도 const [installHeight, setInstallHeight] = useState() //설치 높이 const [standardWindSpeed, setStandardWindSpeed] = useState({}) //기준풍속 const [verticalSnowCover, setVerticalSnowCover] = useState() //수직적설량 + + const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈 const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등 - const { getModuleTypeItemList } = useMasterController() - const { findCommonCode } = useCommonCode() const bindInitData = () => { @@ -73,8 +72,6 @@ export function useModuleSelection(props) { return } - console.log('managementState', managementState) - //새로고침시 데이터 날아가는거 방지 if (managementState === null) { setManagementState(managementStateLoaded) diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index 27676eab..fb33c8f0 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -169,7 +169,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } isDown = false - rect.set({ name: objName, parentId: selectedSurface.id }) + rect.set({ name: objName, parentId: selectedSurface.id, points: rectToPolygon(rect) }) rect.setCoords() initEvent() @@ -251,7 +251,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } isDown = false - rect.set({ name: objName, parentId: selectedSurface.id }) + rect.set({ name: objName, parentId: selectedSurface.id, points: rectToPolygon(rect) }) rect.setCoords() initEvent() if (setIsHidden) setIsHidden(false) @@ -377,9 +377,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer)) const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface) - console.log('trianglePolygon', trianglePolygon) - console.log('selectedSurfacePolygon', selectedSurfacePolygon) - //지붕 밖으로 그렸을때 if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) { swalFire({ text: '도머를 배치할 수 없습니다.', icon: 'error' }) @@ -406,6 +403,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { direction = 'north' } + const groupPoints = offsetRef > 0 ? triangleToPolygon(dormerOffset) : triangleToPolygon(dormer) + let splitedTriangle = offsetRef > 0 ? splitDormerTriangle(dormerOffset, directionRef) : splitDormerTriangle(dormer, directionRef) canvas?.remove(offsetRef > 0 ? dormerOffset : dormer) @@ -499,6 +498,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { parentId: selectedSurface.id, originX: 'center', originY: 'center', + groupPoints: groupPoints, }) canvas?.add(objectGroup) @@ -708,6 +708,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } const groupPolygon = offsetPolygon ? [leftPentagon, rightPentagon, offsetPolygon] : [leftPentagon, rightPentagon] + const groupPoints = offsetRef > 0 ? pentagonOffsetPoints : pentagonPoints const objectGroup = new fabric.Group(groupPolygon, { subTargetCheck: true, @@ -717,6 +718,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { groupYn: true, originX: 'center', originY: 'center', + groupPoints: groupPoints, }) canvas?.add(objectGroup) diff --git a/src/locales/ko.json b/src/locales/ko.json index 3cf57205..88f611c2 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -94,6 +94,7 @@ "modal.module.basic.setting.module.construction.method": "공법", "modal.module.basic.setting.module.under.roof": "지붕밑바탕", "modal.module.basic.setting.module.setting": "모듈 선택", + "modal.module.basic.setting.module.hajebichi": "망둥어 피치", "modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만, 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.", "modal.module.basic.setting.module.setting.info2": "※ 모듈 배치 시에는 시공 매뉴얼에 기재된 <모듈 배치 조건>을 반드시 확인해주십시오.", "modal.module.basic.setting.module.stuff.info": "물건정보", diff --git a/src/store/selectedModuleOptions.js b/src/store/selectedModuleOptions.js index faa979fd..c312c694 100644 --- a/src/store/selectedModuleOptions.js +++ b/src/store/selectedModuleOptions.js @@ -81,6 +81,7 @@ export const moduleSelectionDataState = atom({ key: 'moduleSelectionDataState', default: { common: {}, + module: {}, roofConstructions: [], }, dangerouslyAllowMutability: true,