From 63db694efa3f105ca390e4acaddcc8e3a224c0dc Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 17 Mar 2025 18:36:39 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=A8=EC=88=98=EC=A7=80=EC=A0=95=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 13 ++- .../floor-plan/modal/basic/step/Placement.jsx | 35 +++++--- src/hooks/module/useModuleBasicSetting.js | 86 +++++++++++++------ src/locales/ja.json | 3 +- src/locales/ko.json | 3 +- src/store/canvasAtom.js | 10 +++ 6 files changed, 104 insertions(+), 46 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 33b0c65f..c76c9394 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -6,7 +6,14 @@ import PitchModule from '@/components/floor-plan/modal/basic/step/pitch/PitchMod import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement' import Placement from '@/components/floor-plan/modal/basic/step/Placement' import { useRecoilValue, useRecoilState } from 'recoil' -import { canvasSettingState, canvasState, checkedModuleState, isManualModuleLayoutSetupState, isManualModuleSetupState } from '@/store/canvasAtom' +import { + canvasSettingState, + canvasState, + checkedModuleState, + isManualModuleLayoutSetupState, + isManualModuleSetupState, + toggleManualSetupModeState, +} from '@/store/canvasAtom' import { usePopup } from '@/hooks/usePopup' import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' @@ -38,7 +45,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const [isClosePopup, setIsClosePopup] = useState({ close: false, id: 0 }) const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState) - const [manualSetupMode, setManualSetupMode] = useState('') + const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState) const [layoutSetup, setLayoutSetup] = useState([{}]) @@ -142,6 +149,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { if (basicSetting.roofSizeSet !== '3') { + console.log('ManualSetupMode', manualSetupMode) + if (manualSetupMode.indexOf('manualSetup') > -1) { manualModuleSetup(placementRef) } else if (manualSetupMode.indexOf('manualLayoutSetup') > -1) { diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 582f291c..8c105e00 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -1,14 +1,21 @@ import { forwardRef, useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' -import { checkedModuleState, currentCanvasPlanState, isManualModuleLayoutSetupState, isManualModuleSetupState } from '@/store/canvasAtom' +import { + checkedModuleState, + currentCanvasPlanState, + isManualModuleLayoutSetupState, + isManualModuleSetupState, + isModuleChidoriSetupState, + toggleManualSetupModeState, +} from '@/store/canvasAtom' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' const Placement = forwardRef((props, refs) => { const { getMessage } = useMessage() - const [isChidori, setIsChidori] = useState(false) + const [isChidori, setIsChidori] = useRecoilState(isModuleChidoriSetupState) const [isChidoriNotAble, setIsChidoriNotAble] = useState(false) const [setupLocation, setSetupLocation] = useState('eaves') @@ -26,6 +33,7 @@ const Placement = forwardRef((props, refs) => { //언마운트시 버튼 초기화 const setIsManualModuleSetup = useSetRecoilState(isManualModuleSetupState) const setIsManualModuleLayoutSetup = useSetRecoilState(isManualModuleLayoutSetupState) + const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) //모듈 배치면 생성 useEffect(() => { @@ -41,6 +49,7 @@ const Placement = forwardRef((props, refs) => { return () => { setIsManualModuleSetup(false) setIsManualModuleLayoutSetup(false) + setManualSetupMode('') } }, []) @@ -60,7 +69,11 @@ const Placement = forwardRef((props, refs) => { setSelectedItems(initCheckedModule) setSelectedModules(moduleSelectionData.module) props.setLayoutSetup(moduleSelectionData.module.itemList.map((item) => ({ moduleId: item.itemId, col: 0, row: 0 }))) - props.layoutSetupRef.current = moduleSelectionData.module.itemList.map((item) => ({ moduleId: item.itemId, col: 0, row: 0 })) + props.layoutSetupRef.current = moduleSelectionData.module.itemList.map((item) => ({ + moduleId: item.itemId, + col: 0, + row: 0, + })) } //모듈 배치면 생성 @@ -101,16 +114,6 @@ const Placement = forwardRef((props, refs) => { refs.setupLocation.current = e.target.value } - const handleMaxSetup = (e) => { - if (e.target.checked) { - setIsMaxSetup('true') - refs.isMaxSetup.current = 'true' - } else { - setIsMaxSetup('false') - refs.isMaxSetup.current = 'false' - } - } - //체크된 모듈 아이디 추출 const handleSelectedItem = (e) => { setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked }) @@ -120,7 +123,11 @@ const Placement = forwardRef((props, refs) => { const newLayoutSetup = [...props.layoutSetup] newLayoutSetup[index] = { ...newLayoutSetup[index], moduleId: itemId, [e.target.name]: Number(e.target.value) } props.setLayoutSetup(newLayoutSetup) - props.layoutSetupRef.current[index] = { ...props.layoutSetupRef.current[index], moduleId: itemId, [e.target.name]: Number(e.target.value) } + props.layoutSetupRef.current[index] = { + ...props.layoutSetupRef.current[index], + moduleId: itemId, + [e.target.name]: Number(e.target.value), + } } return ( diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 5203a972..cc266caa 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -8,6 +8,8 @@ import { currentObjectState, isManualModuleLayoutSetupState, isManualModuleSetupState, + isModuleChidoriSetupState, + toggleManualSetupModeState, } from '@/store/canvasAtom' import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon, toFixedWithoutRounding } from '@/util/canvas-util' @@ -59,6 +61,9 @@ export function useModuleBasicSetting(tabNum) { const [currentObject, setCurrentObject] = useRecoilState(currentObjectState) const { setModuleStatisticsData } = useCircuitTrestle() const { createRoofPolygon, createMarginPolygon, createPaddingPolygon } = useMode() + const isModuleChidoriSetup = useRecoilValue(isModuleChidoriSetupState) + + const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) useEffect(() => { // console.log('basicSetting', basicSetting) @@ -437,19 +442,22 @@ export function useModuleBasicSetting(tabNum) { //레이아웃 수동설치 토글 if (isManualModuleLayoutSetup) { setIsManualModuleLayoutSetup(false) + setManualSetupMode(`manualLayoutSetup_false`) } const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 if (isManualModuleSetup) { if (checkedModule.length === 0) { swalFire({ text: getMessage('module.place.select.module') }) - setIsManualModuleSetup(!isManualModuleSetup) + setIsManualModuleSetup(false) + setManualSetupMode(`manualSetup_false`) return } if (checkedModule.length > 1) { swalFire({ text: getMessage('module.place.select.one.module') }) - setIsManualModuleSetup(!isManualModuleSetup) + setIsManualModuleSetup(false) + setManualSetupMode(`manualSetup_false`) return } @@ -604,18 +612,13 @@ export function useModuleBasicSetting(tabNum) { //흐름방향따라 달라야 한다. if (flowDirection === 'south' || flowDirection === 'north') { if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { + //움직이는 모듈 가운데 -> 설치 모듈 가운데 tempModule.left = holdCellCenterX - toFixedWithoutRounding(width / 2, 2) } - //왼쪽 -> 가운데 + //움직이는 모듈왼쪽 -> 가운데 if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { - // console.log('holdCellCenterX', holdCellCenterX) - // console.log('smallLeft', smallLeft) - - // console.log('모듈 센터에 스냅') tempModule.left = holdCellCenterX + intvHor / 2 - - // console.log('tempModule.left', tempModule.left) } // 오른쪽 -> 가운데 if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { @@ -695,6 +698,10 @@ export function useModuleBasicSetting(tabNum) { if (Math.abs(smallTop - holdCellTop) < sideSnapDistance) { tempModule.top = holdCellTop } + + if (Math.abs(smallLeft - holdCellLeft) < snapDistance) { + tempModule.left = holdCellLeft + } } //가운데 -> 가운대 @@ -734,22 +741,19 @@ export function useModuleBasicSetting(tabNum) { // if (Math.abs(smallLeft - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { // tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 // } - // 모듈이 가운데가 세로중앙선에 붙게 스냅 - if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < trestleSnapDistance) { - tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width / 2 - } - + // if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < trestleSnapDistance) { + // tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width / 2 + // } // 모듈오른쪽이 세로중앙선에 붙게 스냅 // if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < trestleSnapDistance) { // tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX // } } else { // 모듈이 가로중앙선에 스냅 - if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < trestleSnapDistance) { - tempModule.top = bigCenterY - tempModule.height / 2 - } - + // if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < trestleSnapDistance) { + // tempModule.top = bigCenterY - tempModule.height / 2 + // } // if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < trestleSnapDistance) { // tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 // } @@ -869,6 +873,7 @@ export function useModuleBasicSetting(tabNum) { const manualModuleLayoutSetup = (layoutSetupRef) => { if (isManualModuleSetup) { setIsManualModuleSetup(false) + setManualSetupMode(`manualSetup_false`) } const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 @@ -876,7 +881,8 @@ export function useModuleBasicSetting(tabNum) { if (isManualModuleLayoutSetup) { if (checkedModule.length === 0) { swalFire({ text: getMessage('module.place.select.module') }) - setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) + setIsManualModuleLayoutSetup(false) + setManualSetupMode(`manualLayoutSetup_false`) return } @@ -885,8 +891,9 @@ export function useModuleBasicSetting(tabNum) { ) if (hasZeroLength) { - swalFire({ text: getMessage('모듈의 열, 행을 입력해 주세요.') }) - setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) + swalFire({ text: getMessage('module.layout.setup.has.zero.value') }) + setIsManualModuleLayoutSetup(false) + setManualSetupMode(`manualLayoutSetup_false`) return } @@ -1205,6 +1212,7 @@ export function useModuleBasicSetting(tabNum) { if (tempModule) { let startX, startY let installedLastHeightCoord = 0 //마지막으로 설치된 모듈의 좌표 + let installedHeightModuleCount = 0 checkedModule.forEach((module, index) => { //모듈 사이즈 @@ -1233,10 +1241,13 @@ export function useModuleBasicSetting(tabNum) { moduleOptions.fill = module.color - const col = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].col - const row = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].row + let col = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].col + let row = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].row + let tempCol = col + for (let i = 0; i < row; i++) { let tempY = startY - i * height + let isInstalled = false if (index > 0) { //두번째 모듈일때 마지막 설치 지점 @@ -1245,15 +1256,26 @@ export function useModuleBasicSetting(tabNum) { let tempHeightMargin = i === 0 ? 0 : i * intvVer - for (let j = 0; j < col; j++) { + //치도리 설치시 컬럼 조정 + if (isModuleChidoriSetup) { + //치도리면 짝수열은 안으로 넣기 + tempCol = installedHeightModuleCount % 2 === 0 ? col : col - 1 + } + + for (let j = 0; j < tempCol; j++) { + let chidoriMargin = 0 let tempX = startX + j * width let tempWidthMargin = j === 0 ? 0 : j * intvHor + if (isModuleChidoriSetup) { + chidoriMargin = installedHeightModuleCount % 2 === 0 ? 0 : width / 2 + intvHor + } + let rectPoints = [ - { x: tempX + tempWidthMargin, y: tempY - height - tempHeightMargin }, - { x: tempX + tempWidthMargin, y: tempY - tempHeightMargin }, - { x: tempX + width + tempWidthMargin, y: tempY - tempHeightMargin }, - { x: tempX + width + tempWidthMargin, y: tempY - height - tempHeightMargin }, + { x: tempX + tempWidthMargin + chidoriMargin, y: tempY - height - tempHeightMargin }, + { x: tempX + tempWidthMargin + chidoriMargin, y: tempY - tempHeightMargin }, + { x: tempX + width + tempWidthMargin + chidoriMargin, y: tempY - tempHeightMargin }, + { x: tempX + width + tempWidthMargin + chidoriMargin, y: tempY - height - tempHeightMargin }, ] tempModule.set({ points: rectPoints }) @@ -1288,6 +1310,10 @@ export function useModuleBasicSetting(tabNum) { manualDrawModules.push(manualModule) setModuleStatisticsData() installedLastHeightCoord = tempY - height - tempHeightMargin + + if (j === 0) { + isInstalled = true + } } else { //디버깅용 // manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) @@ -1308,6 +1334,10 @@ export function useModuleBasicSetting(tabNum) { // } } } + + if (isInstalled) { + ++installedHeightModuleCount + } } } else if (flowDirection === 'north') { //북북 diff --git a/src/locales/ja.json b/src/locales/ja.json index 0028a047..69b6b28f 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1034,5 +1034,6 @@ "roof.exceed.count": "屋根材は4つまで選択可能です。", "outerLine.property.fix": "外壁線の属性設定 を完了しますか?", "outerLine.property.close": "外壁線の属性設定 を終了しますか?", - "want.to.complete.auxiliary.creation": "보補助線の作成を完了しますか?" + "want.to.complete.auxiliary.creation": "보補助線の作成を完了しますか?", + "module.layout.setup.has.zero.value": "モジュールの列、行を入力してください." } diff --git a/src/locales/ko.json b/src/locales/ko.json index 4c051305..79a47142 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1034,5 +1034,6 @@ "roof.exceed.count": "지붕재는 4개까지 선택 가능합니다.", "outerLine.property.fix": "외벽선 속성 설정을 완료하시겠습니까?", "outerLine.property.close": "외벽선 속성 설정을 종료하시겠습니까?", - "want.to.complete.auxiliary.creation": "보조선 작성을 완료하시겠습니까?" + "want.to.complete.auxiliary.creation": "보조선 작성을 완료하시겠습니까?", + "module.layout.setup.has.zero.value": "모듈의 열, 행을 입력해 주세요." } diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js index b31b8bc3..dc9aeabd 100644 --- a/src/store/canvasAtom.js +++ b/src/store/canvasAtom.js @@ -389,3 +389,13 @@ export const isManualModuleLayoutSetupState = atom({ key: 'isManualModuleLayoutSetupState', default: false, }) + +export const isModuleChidoriSetupState = atom({ + key: 'isModuleChidoriSetupState', + default: false, +}) + +export const toggleManualSetupModeState = atom({ + key: 'toggleManualSetupModeState', + default: '', +})