From 3df466a7179858864d91465e7dbe5ba536862f85 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 12 Mar 2025 16:44:41 +0900 Subject: [PATCH 001/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EB=8D=B0=EB=AA=A8=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 46 +- .../floor-plan/modal/basic/step/Placement.jsx | 32 ++ src/hooks/module/useModuleBasicSetting.js | 499 +++++++++++++++++- src/store/canvasAtom.js | 5 + 4 files changed, 571 insertions(+), 11 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 291ef086..f607d3cb 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -6,7 +6,7 @@ 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, isManualModuleSetupState } from '@/store/canvasAtom' +import { canvasSettingState, canvasState, isManualModuleLayoutSetupState, 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' @@ -29,6 +29,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const orientationRef = useRef(null) const { initEvent } = useEvent() const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) + const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState) + const moduleSelectionData = useRecoilValue(moduleSelectionDataState) const addedRoofs = useRecoilValue(addedRoofsState) const loginUserState = useRecoilValue(loginUserStore) @@ -37,8 +39,16 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) const [isClosePopup, setIsClosePopup] = useState({ close: false, id: 0 }) + const [manualSetupMode, setManualSetupMode] = useState('manualSetup') + + const [layoutSetup, setLayoutSetup] = useState({ + col: 1, + row: 1, + }) + // const { initEvent } = useContext(EventContext) - const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup } = useModuleBasicSetting(tabNum) + const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup } = + useModuleBasicSetting(tabNum) const { updateObjectDate } = useMasterController() const handleBtnNextStep = () => { if (tabNum === 1) { @@ -86,7 +96,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const placementRef = { isChidori: useRef('false'), setupLocation: useRef('eaves'), - isMaxSetup: useRef('false'), + layoutSetup: useRef({ + col: 1, + row: 1, + }), } const placementFlatRef = { @@ -94,9 +107,15 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { } const handleManualModuleSetup = () => { + setManualSetupMode(`manualSetup_${!isManualModuleSetup}`) setIsManualModuleSetup(!isManualModuleSetup) } + const handleManualModuleLayoutSetup = () => { + setManualSetupMode(`manualLayoutSetup_${!isManualModuleLayoutSetup}`) + setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) + } + const updateObjectDataApi = async (params) => { const res = await updateObjectDate(params) } @@ -125,14 +144,24 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { if (basicSetting.roofSizeSet !== '3') { - manualModuleSetup(placementRef) + if (manualSetupMode.indexOf('manualSetup') > -1) { + manualModuleSetup(placementRef) + } else if (manualSetupMode.indexOf('manualLayoutSetup') > -1) { + manualModuleLayoutSetup(placementRef) + } } else { manualFlatroofModuleSetup(placementFlatRef) } if (isClosePopup.close) { closePopup(isClosePopup.id) } - }, [isManualModuleSetup, isClosePopup]) + }, [manualSetupMode, isClosePopup]) + + useEffect(() => { + if (isManualModuleLayoutSetup) { + manualModuleLayoutSetup(placementRef) + } + }, [layoutSetup]) return ( @@ -156,7 +185,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { {tabNum === 1 && } {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && } - {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && } + {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && ( + + )} {/*배치면 초기설정 - 입력방법: 육지붕*/} {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && } @@ -184,6 +215,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { + diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index d4b979c7..d2fca8b2 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -111,6 +111,11 @@ const Placement = forwardRef((props, refs) => { setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked }) } + const handleLayoutSetup = (e) => { + props.setLayoutSetup({ ...props.layoutSetup, [e.target.name]: Number(e.target.value) }) + refs.layoutSetup.current = { ...props.layoutSetup, [e.target.name]: Number(e.target.value) } + } + return ( <>
@@ -233,6 +238,33 @@ const Placement = forwardRef((props, refs) => {
+
+
레이아웃 입력
+
+
+
+ + {' '} + × + +
+
+
+
{/*
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 44a0d02e..aa008fc8 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1,7 +1,14 @@ import { useState } from 'react' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' -import { canvasSettingState, canvasState, checkedModuleState, currentObjectState, isManualModuleSetupState } from '@/store/canvasAtom' -import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon } from '@/util/canvas-util' +import { + canvasSettingState, + canvasState, + checkedModuleState, + currentObjectState, + isManualModuleLayoutSetupState, + isManualModuleSetupState, +} from '@/store/canvasAtom' +import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon, toFixedWithoutRounding } from '@/util/canvas-util' import { basicSettingState, roofDisplaySelector } from '@/store/settingAtom' import offsetPolygon, { calculateAngle, createLinesFromPolygon } from '@/util/qpolygon-utils' import { QPolygon } from '@/components/fabric/QPolygon' @@ -35,6 +42,7 @@ export function useModuleBasicSetting(tabNum) { const { setSurfaceShapePattern } = useRoofFn() const checkedModule = useRecoilValue(checkedModuleState) const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) + const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState) const setModuleStatistics = useSetRecoilState(moduleStatisticsState) const canvasSetting = useRecoilValue(canvasSettingState) @@ -417,13 +425,18 @@ export function useModuleBasicSetting(tabNum) { setSaleStoreNorthFlg(true) } } - }, [isManualModuleSetup]) + }, [isManualModuleSetup, isManualModuleLayoutSetup]) /** * trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 로 진입여부를 확인 * 확인 후 셀을 이동시킴 */ const manualModuleSetup = (placementRef) => { + //레이아웃 수동설치 토글 + if (isManualModuleLayoutSetup) { + setIsManualModuleLayoutSetup(false) + } + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 if (isManualModuleSetup) { @@ -730,7 +743,7 @@ export function useModuleBasicSetting(tabNum) { tempModule.setCoords() //좌표 재정렬 if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { //마우스 클릭시 set으로 해당 위치에 셀을 넣음 - const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module, true))) //겹치는지 확인 if (!isOverlap) { canvas?.remove(tempModule) @@ -778,6 +791,480 @@ export function useModuleBasicSetting(tabNum) { } } + const manualModuleLayoutSetup = (placementRef) => { + if (isManualModuleSetup) { + setIsManualModuleSetup(false) + } + + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 + + if (isManualModuleLayoutSetup) { + if (checkedModule.length === 0) { + swalFire({ text: getMessage('module.place.select.module') }) + setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) + return + } + + if (checkedModule.length > 1) { + swalFire({ text: getMessage('module.place.select.one.module') }) + setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) + return + } + + const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체 + //수동모드 모듈 설치면 선택 잠금 + moduleSetupSurfaces.forEach((obj) => { + obj.set({ + selectable: false, + evented: false, + }) + }) + + //모듈 기본 옵션 + const moduleOptions = { + fill: checkedModule[0].color, + stroke: 'black', + strokeWidth: 0.3, + selectable: true, // 선택 가능하게 설정 + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + lockScalingX: true, // X 축 크기 조정 잠금 + lockScalingY: true, // Y 축 크기 조정 잠금 + name: POLYGON_TYPE.MODULE, + } + + const objectsIncludeSurface = (turfModuleSetupSurface) => { + let containsBatchObjects = [] + containsBatchObjects = batchObjects.filter((batchObject) => { + let convertBatchObject = polygonToTurfPolygon(batchObject) + // 폴리곤 안에 도머 폴리곤이 포함되어있는지 확인해서 반환하는 로직 + return ( + turf.booleanContains(turfModuleSetupSurface, convertBatchObject) || + turf.booleanWithin(convertBatchObject, turfModuleSetupSurface) || + turf.booleanOverlap(turfModuleSetupSurface, convertBatchObject) + ) + }) + + return containsBatchObjects + } + + if (moduleSetupSurfaces.length !== 0) { + const col = placementRef.layoutSetup.current.col + const row = placementRef.layoutSetup.current.row + + let tempModule + let manualDrawModules = [] + let inside = false + let turfPolygon + let flowDirection + let trestlePolygon + let width, height, intvHor, intvVer + let containsBatchObjects + + addCanvasMouseEventListener('mouse:move', (e) => { + //마우스 이벤트 삭제 후 재추가 + const mousePoint = canvas.getPointer(e.e) + + for (let i = 0; i < moduleSetupSurfaces.length; i++) { + //배치면이 여러개 일때 옮겨가면서 동작해야함 + turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i]) + trestlePolygon = moduleSetupSurfaces[i] + manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨 + flowDirection = moduleSetupSurfaces[i].direction //도형의 방향 + + containsBatchObjects = objectsIncludeSurface(turfPolygon) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 + + const moduleWidth = Number(checkedModule[0].longAxis) / 10 + const moduleHeight = Number(checkedModule[0].shortAxis) / 10 + let tmpWidth = flowDirection === 'south' || flowDirection === 'north' ? moduleWidth : moduleHeight + let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth + + width = + canvasSetting.roofSizeSet == '1' + ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection).width + : tmpWidth + height = + canvasSetting.roofSizeSet == '1' + ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection).height + : tmpHeight + + intvHor = + flowDirection === 'south' || flowDirection === 'north' + ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor / 10 + : moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer / 10 + intvVer = + flowDirection === 'south' || flowDirection === 'north' + ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer / 10 + : moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor / 10 + + let calcHalfWidth = (Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1))) / 2 + let calcHalfHeight = (Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1))) / 2 + + //아래래 + let points = [ + { + x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, + y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, + }, + { + x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, + y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, + }, + { + x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, + y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, + }, + { + x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, + y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, + }, + ] + + // const points = [ + // { + // x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), + // y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + // }, + // { + // x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), + // y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + // }, + // { + // x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), + // y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + // }, + // { + // x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), + // y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + // }, + // ] + + const turfPoints = coordToTurfPolygon(points) + + if (turf.booleanWithin(turfPoints, turfPolygon)) { + let isDrawing = false + + if (isDrawing) return + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임 + + tempModule = new fabric.Rect({ + fill: 'rgba(224, 221, 222, 0.7)', + stroke: 'black', + strokeWidth: 1, + strokeDashArray: [10, 5], + // width: Number(width.toFixed(1)), //작은버전 + // height: Number(height.toFixed(1)), //작은버전 + // left: Number(mousePoint.x.toFixed(1) - Number((width / 2).toFixed(1))), //작은버전 + // top: Number(mousePoint.y.toFixed(1) - Number((height / 2).toFixed(1))), //작은버전 + width: Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1)), //큰버전 + height: Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1)), //큰버전 + left: Number(mousePoint.x.toFixed(1)) - calcHalfWidth.toFixed(1), //큰버전 + top: Number(mousePoint.y.toFixed(1)) - calcHalfHeight.toFixed(1), //큰버전 + selectable: false, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: 'tempModule', + parentId: moduleSetupSurfaces[i].parentId, + }) + + //북면이고 북면설치상점이 아니면 그냥 return + if (trestlePolygon.isNorth && !saleStoreNorthFlg) { + return + } else { + canvas?.add(tempModule) //움직여가면서 추가됨 + } + + /** + * 스냅기능 + */ + let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 70 : 40 + let trestleSnapDistance = 15 + + const trestleLeft = Number(moduleSetupSurfaces[i].left.toFixed(1)) - Number((moduleSetupSurfaces[i].width / 2).toFixed(1)) + const trestleTop = Number(moduleSetupSurfaces[i].top.toFixed(1)) - Number((moduleSetupSurfaces[i].height / 2).toFixed(1)) + const trestleRight = Number(moduleSetupSurfaces[i].left.toFixed(1)) + Number((moduleSetupSurfaces[i].width / 2).toFixed(1)) + const trestleBottom = Number(moduleSetupSurfaces[i].top.toFixed(1)) + Number((moduleSetupSurfaces[i].height / 2).toFixed(1)) + const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2 + + // 이동하는 모듈의 경계 좌표 + const smallLeft = Number(tempModule.left.toFixed(1)) + const smallTop = Number(tempModule.top.toFixed(1)) + const smallRight = smallLeft + Number(tempModule.width.toFixed(1)) + const smallBottom = smallTop + Number(tempModule.height.toFixed(1)) + const smallCenterX = smallLeft + Number((tempModule.width / 2).toFixed(1)) + const smallCenterY = smallTop + Number((tempModule.height / 2).toFixed(1)) + + /** + * 미리 깔아놓은 셀이 있을때 셀에 흡착됨 + */ + // if (manualDrawModules) { + // manualDrawModules.forEach((cell) => { + // const holdCellLeft = cell.left + // const holdCellTop = cell.top + // const holdCellRight = holdCellLeft + Number(cell.width.toFixed(1)) + // const holdCellBottom = holdCellTop + Number(cell.height.toFixed(1)) + // const holdCellCenterX = holdCellLeft + Number((cell.width / 2).toFixed(1)) + // const holdCellCenterY = holdCellTop + Number((cell.height / 2).toFixed(1)) + + // //설치된 셀에 좌측에 스냅 + // if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // tempModule.left = holdCellLeft - width - intvHor + // } + + // //설치된 셀에 우측에 스냅 + // if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // tempModule.left = holdCellRight + intvHor + // } + + // //설치된 셀에 위쪽에 스냅 + // if (Math.abs(smallBottom - holdCellTop) < snapDistance) { + // tempModule.top = holdCellTop - height - intvVer + // } + + // //설치된 셀에 밑쪽에 스냅 + // if (Math.abs(smallTop - holdCellBottom) < snapDistance) { + // tempModule.top = holdCellBottom + intvVer + // } + // //가운데 -> 가운데 + // if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { + // tempModule.left = holdCellCenterX - Number((width / 2).toFixed(1)) + // } + // //왼쪽 -> 가운데 + // if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { + // tempModule.left = holdCellCenterX + // } + // // 오른쪽 -> 가운데 + // if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { + // tempModule.left = holdCellCenterX - width + // } + // //세로 가운데 -> 가운데 + // if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { + // tempModule.top = holdCellCenterY - Number((height / 2).toFixed(1)) + // } + // // //위쪽 -> 가운데 + // // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { + // // tempModule.top = holdCellCenterY + // // } + // // //아랫쪽 -> 가운데 + // // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { + // // tempModule.top = holdCellCenterY - height + // // } + // }) + // } + + // 위쪽 변에 스냅 + if (Math.abs(smallTop - trestleTop) < trestleSnapDistance) { + tempModule.top = trestleTop + 1 + } + + // 아래쪽 변에 스냅 + if (Math.abs(smallBottom - trestleBottom) < trestleSnapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height - 1 + } + + // 왼쪽변에 스냅 + if (Math.abs(smallLeft - trestleLeft) < trestleSnapDistance) { + tempModule.left = trestleLeft + 1 + } + //오른쪽 변에 스냅 + if (Math.abs(smallRight - trestleRight) < trestleSnapDistance) { + tempModule.left = trestleRight - tempModule.width - 1 + } + + if (flowDirection === 'south' || flowDirection === 'north') { + // 모듈왼쪽이 세로중앙선에 붙게 스냅 + // 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(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 - (trestleTop + moduleSetupSurfaces[i].height / 2)) < trestleSnapDistance) { + // tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 + // } + // 모듈 밑면이 가로중앙선에 스냅 + // if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < trestleSnapDistance) { + // tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY + // } + } + + tempModule.setCoords() + canvas?.renderAll() + inside = true + break + } else { + inside = false + } + } + + if (!inside) { + // tempModule.set({ fill: 'red' }) + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) + canvas?.renderAll() + } + }) + + addCanvasMouseEventListener('mouse:up', (e) => { + let isIntersection = true + if (!inside) return + if (tempModule) { + let startX, startY + + console.log(tempModule) + + //그려진 가이드 라인의 포인트를 기준으로 시작점을 만든다 + if (flowDirection === 'south') { + startX = toFixedWithoutRounding(tempModule.left, 1) + startY = toFixedWithoutRounding(tempModule.top + tempModule.height, 1) + + for (let i = 0; i < placementRef.layoutSetup.current.row; i++) { + let tempY = startY - i * height + let tempHeightMargin = i === 0 ? 0 : i * intvVer + for (let j = 0; j < placementRef.layoutSetup.current.col; j++) { + let tempX = startX + j * width + let tempWidthMargin = j === 0 ? 0 : j * 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 }, + ] + // console.log('🚀 ~ addCanvasMouseEventListener ~ rectPoints:', rectPoints) + + tempModule.set({ points: rectPoints }) + const tempTurfModule = polygonToTurfPolygon(tempModule) + tempModule.setCoords() //좌표 재정렬 + + if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { + //마우스 클릭시 set으로 해당 위치에 셀을 넣음 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + if (!isOverlap) { + canvas?.remove(tempModule) + + //안겹치면 넣는다 + // tempModule.setCoords() + moduleOptions.surfaceId = trestlePolygon.id + + let manualModule = new QPolygon(tempModule.points, { + ...moduleOptions, + moduleInfo: checkedModule[0], + // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), + // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), + width: toFixedWithoutRounding(width, 1), + height: toFixedWithoutRounding(height, 1), + }) + + let isDisjoint = checkModuleDisjointObjects(tempTurfModule, containsBatchObjects) + + //오브젝트와 겹치지 않으면 넣는다 + if (isDisjoint) { + canvas?.add(manualModule) + manualDrawModules.push(manualModule) + setModuleStatisticsData() + } + // getModuleStatistics() + } else { + swalFire({ text: getMessage('module.place.overlab') }) + return + } + } + } + } + } else if (flowDirection === 'north') { + startX = tempModule.points[3].x + startY = tempModule.points[3].y + } else if (flowDirection === 'east') { + startX = tempModule.points[2].x + startY = tempModule.points[2].y + } else { + startX = tempModule.points[0].x + startY = tempModule.points[0].y + } + + //도머 객체를 가져옴 + // if (batchObjects) { + // batchObjects.forEach((object) => { + // let dormerTurfPolygon = polygonToTurfPolygon(object, true) + // const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인 + // //겹치면 안됨 + // if (intersection) { + // swalFire({ text: getMessage('module.place.overobject') }) + // isIntersection = false + // } + // }) + // } + + // if (!isIntersection) return + + // tempModule.setCoords() //좌표 재정렬 + // if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { + // //마우스 클릭시 set으로 해당 위치에 셀을 넣음 + // const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + // if (!isOverlap) { + // canvas?.remove(tempModule) + + // //안겹치면 넣는다 + // // tempModule.setCoords() + // moduleOptions.surfaceId = trestlePolygon.id + + // // console.log('tempModule.points', tempModule.points) + + // let manualModule = new QPolygon(tempModule.points, { + // ...moduleOptions, + // moduleInfo: checkedModule[0], + // left: Number(tempModule.left.toFixed(1)), + // top: Number(tempModule.top.toFixed(1)), + // width: Number(tempModule.width.toFixed(1)), + // height: Number(tempModule.height.toFixed(1)), + // }) + // canvas?.add(manualModule) + // manualDrawModules.push(manualModule) + // setModuleStatisticsData() + // // getModuleStatistics() + // } else { + // swalFire({ text: getMessage('module.place.overlab') }) + // } + // } else { + // swalFire({ text: getMessage('module.place.out') }) + // } + } + }) + } + } else { + if (moduleSetupSurfaces) { + //수동모드 해제시 모듈 설치면 선택 잠금 + moduleSetupSurfaces.forEach((obj) => { + obj.set({ + selectable: true, + evented: true, + }) + }) + } + + removeMouseEvent('mouse:up') + removeMouseEvent('mouse:move') + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임 + } + } + //자동 모듈 설치(그리드 방식) const autoModuleSetup = (placementRef) => { initEvent() //마우스 이벤트 초기화 @@ -789,7 +1276,8 @@ export function useModuleBasicSetting(tabNum) { const isChidori = placementRef.isChidori.current === 'true' ? true : false const setupLocation = placementRef.setupLocation.current - const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false + const isMaxSetup = false + // const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false const moduleSetupSurfaces = moduleSetupSurface //선택 설치면 const notSelectedTrestlePolygons = canvas @@ -2726,6 +3214,7 @@ export function useModuleBasicSetting(tabNum) { selectedModules, makeModuleInstArea, manualModuleSetup, + manualModuleLayoutSetup, autoModuleSetup, restoreModuleInstArea, manualFlatroofModuleSetup, diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js index 772e55be..3e795f22 100644 --- a/src/store/canvasAtom.js +++ b/src/store/canvasAtom.js @@ -384,3 +384,8 @@ export const isManualModuleSetupState = atom({ key: 'isManualModuleSetupState', default: false, }) + +export const isManualModuleLayoutSetupState = atom({ + key: 'isManualModuleLayoutSetupState', + default: false, +}) From ae2171c6331d28a48ab911e86280431024899836 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 14 Mar 2025 18:35:13 +0900 Subject: [PATCH 002/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 35 ++- .../floor-plan/modal/basic/step/Placement.jsx | 62 ++-- src/hooks/module/useModuleBasicSetting.js | 284 ++++++++++-------- 3 files changed, 214 insertions(+), 167 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index ff56d212..e2a38de8 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -25,9 +25,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const { getMessage } = useMessage() const { closePopup } = usePopup() const [tabNum, setTabNum] = useState(1) - const canvasSetting = useRecoilValue(canvasSettingState) const orientationRef = useRef(null) - const { initEvent } = useEvent() const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState) @@ -40,12 +38,9 @@ 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('manualSetup') + const [manualSetupMode, setManualSetupMode] = useState('') - const [layoutSetup, setLayoutSetup] = useState({ - col: 1, - row: 1, - }) + const [layoutSetup, setLayoutSetup] = useState([{}]) // const { initEvent } = useContext(EventContext) const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup } = @@ -98,12 +93,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const placementRef = { isChidori: useRef('false'), setupLocation: useRef('eaves'), - layoutSetup: useRef({ - col: 1, - row: 1, - }), } + const layoutSetupRef = useRef([]) + const placementFlatRef = { setupLocation: useRef('south'), } @@ -114,6 +107,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { } const handleManualModuleLayoutSetup = () => { + console.log('asdfasdkljfhaskjdhfakjsdhkfjh') setManualSetupMode(`manualLayoutSetup_${!isManualModuleLayoutSetup}`) setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) } @@ -140,16 +134,21 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { if (isManualModuleSetup) { setIsManualModuleSetup(false) } + if (isManualModuleLayoutSetup) { + setIsManualModuleLayoutSetup(false) + } } setIsClosePopup({ close: true, id: id }) } useEffect(() => { + console.log('asdfasdf', manualSetupMode) + if (basicSetting.roofSizeSet !== '3') { if (manualSetupMode.indexOf('manualSetup') > -1) { manualModuleSetup(placementRef) } else if (manualSetupMode.indexOf('manualLayoutSetup') > -1) { - manualModuleLayoutSetup(placementRef) + manualModuleLayoutSetup(layoutSetupRef) } } else { manualFlatroofModuleSetup(placementFlatRef) @@ -161,7 +160,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { if (isManualModuleLayoutSetup) { - manualModuleLayoutSetup(placementRef) + manualModuleLayoutSetup(layoutSetupRef) } }, [layoutSetup]) @@ -183,7 +182,15 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { {tabNum === 1 && } {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && } - {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && } + {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && ( + + )} {/*배치면 초기설정 - 입력방법: 육지붕*/} {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && } diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index d2fca8b2..f2c3c83f 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -1,7 +1,7 @@ import { forwardRef, useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' -import { checkedModuleState, currentCanvasPlanState, isManualModuleSetupState } from '@/store/canvasAtom' +import { checkedModuleState, currentCanvasPlanState, isManualModuleLayoutSetupState, isManualModuleSetupState } from '@/store/canvasAtom' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' @@ -23,7 +23,9 @@ const Placement = forwardRef((props, refs) => { const [isMultiModule, setIsMultiModule] = useState(false) - const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) + //언마운트시 버튼 초기화 + const setIsManualModuleSetup = useSetRecoilState(isManualModuleSetupState) + const setIsManualModuleLayoutSetup = useSetRecoilState(isManualModuleLayoutSetupState) //모듈 배치면 생성 useEffect(() => { @@ -38,6 +40,7 @@ const Placement = forwardRef((props, refs) => { return () => { setIsManualModuleSetup(false) + setIsManualModuleLayoutSetup(false) } }, []) @@ -56,6 +59,8 @@ 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 })) } //모듈 배치면 생성 @@ -111,9 +116,11 @@ const Placement = forwardRef((props, refs) => { setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked }) } - const handleLayoutSetup = (e) => { - props.setLayoutSetup({ ...props.layoutSetup, [e.target.name]: Number(e.target.value) }) - refs.layoutSetup.current = { ...props.layoutSetup, [e.target.name]: Number(e.target.value) } + 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) + props.layoutSetupRef.current[index] = { ...props.layoutSetupRef.current[index], moduleId: itemId, [e.target.name]: Number(e.target.value) } } return ( @@ -162,6 +169,24 @@ const Placement = forwardRef((props, refs) => {
{item.wpOut} + + handleLayoutSetup(e, item.itemId, index)} + />{' '} + × + handleLayoutSetup(e, item.itemId, index)} + /> ))} @@ -238,33 +263,6 @@ const Placement = forwardRef((props, refs) => {
-
-
레이아웃 입력
-
-
-
- - {' '} - × - -
-
-
-
{/*
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 27dee861..44f7d21e 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -560,7 +560,7 @@ export function useModuleBasicSetting(tabNum) { /** * 스냅기능 */ - let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 70 : 40 + let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 10 : 10 let trestleSnapDistance = 15 let intvHor = @@ -817,7 +817,7 @@ export function useModuleBasicSetting(tabNum) { } } - const manualModuleLayoutSetup = (placementRef) => { + const manualModuleLayoutSetup = (layoutSetupRef) => { if (isManualModuleSetup) { setIsManualModuleSetup(false) } @@ -831,8 +831,12 @@ export function useModuleBasicSetting(tabNum) { return } - if (checkedModule.length > 1) { - swalFire({ text: getMessage('module.place.select.one.module') }) + const hasZeroLength = checkedModule.some((item) => + layoutSetupRef.current.some((layoutItem) => item.itemId === layoutItem.moduleId && (layoutItem.row === 0 || layoutItem.col === 0)), + ) + + if (hasZeroLength) { + swalFire({ text: getMessage('모듈의 열, 행을 입력해 주세요.') }) setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) return } @@ -876,8 +880,8 @@ export function useModuleBasicSetting(tabNum) { } if (moduleSetupSurfaces.length !== 0) { - const col = placementRef.layoutSetup.current.col - const row = placementRef.layoutSetup.current.row + // const col = layoutSetupRef.current[0].col + // const row = layoutSetupRef.current[0].row let tempModule let manualDrawModules = [] @@ -924,48 +928,48 @@ export function useModuleBasicSetting(tabNum) { ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer / 10 : moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor / 10 - let calcHalfWidth = (Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1))) / 2 - let calcHalfHeight = (Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1))) / 2 + // let calcHalfWidth = (Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1))) / 2 + // let calcHalfHeight = (Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1))) / 2 //아래래 - let points = [ - { - x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, - y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, - }, - { - x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, - y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, - }, - { - x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, - y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, - }, - { - x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, - y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, - }, - ] - - // const points = [ + // let points = [ // { - // x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), - // y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + // x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, + // y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, // }, // { - // x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), - // y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + // x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, + // y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, // }, // { - // x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - // y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + // x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, + // y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, // }, // { - // x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - // y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + // x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, + // y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, // }, // ] + const points = [ + { + x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + }, + { + x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + }, + { + x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + }, + { + x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + }, + ] + const turfPoints = coordToTurfPolygon(points) if (turf.booleanWithin(turfPoints, turfPolygon)) { @@ -979,14 +983,14 @@ export function useModuleBasicSetting(tabNum) { stroke: 'black', strokeWidth: 1, strokeDashArray: [10, 5], - // width: Number(width.toFixed(1)), //작은버전 - // height: Number(height.toFixed(1)), //작은버전 - // left: Number(mousePoint.x.toFixed(1) - Number((width / 2).toFixed(1))), //작은버전 - // top: Number(mousePoint.y.toFixed(1) - Number((height / 2).toFixed(1))), //작은버전 - width: Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1)), //큰버전 - height: Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1)), //큰버전 - left: Number(mousePoint.x.toFixed(1)) - calcHalfWidth.toFixed(1), //큰버전 - top: Number(mousePoint.y.toFixed(1)) - calcHalfHeight.toFixed(1), //큰버전 + width: Number(width.toFixed(1)), //작은버전 + height: Number(height.toFixed(1)), //작은버전 + left: Number(mousePoint.x.toFixed(1) - Number((width / 2).toFixed(1))), //작은버전 + top: Number(mousePoint.y.toFixed(1) - Number((height / 2).toFixed(1))), //작은버전 + // width: Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1)), //큰버전 + // height: Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1)), //큰버전 + // left: Number(mousePoint.x.toFixed(1)) - calcHalfWidth.toFixed(1), //큰버전 + // top: Number(mousePoint.y.toFixed(1)) - calcHalfHeight.toFixed(1), //큰버전 selectable: false, lockMovementX: true, lockMovementY: true, @@ -1027,60 +1031,60 @@ export function useModuleBasicSetting(tabNum) { /** * 미리 깔아놓은 셀이 있을때 셀에 흡착됨 */ - // if (manualDrawModules) { - // manualDrawModules.forEach((cell) => { - // const holdCellLeft = cell.left - // const holdCellTop = cell.top - // const holdCellRight = holdCellLeft + Number(cell.width.toFixed(1)) - // const holdCellBottom = holdCellTop + Number(cell.height.toFixed(1)) - // const holdCellCenterX = holdCellLeft + Number((cell.width / 2).toFixed(1)) - // const holdCellCenterY = holdCellTop + Number((cell.height / 2).toFixed(1)) + if (manualDrawModules) { + manualDrawModules.forEach((cell) => { + const holdCellLeft = cell.left + const holdCellTop = cell.top + const holdCellRight = holdCellLeft + Number(cell.width.toFixed(1)) + const holdCellBottom = holdCellTop + Number(cell.height.toFixed(1)) + const holdCellCenterX = holdCellLeft + Number((cell.width / 2).toFixed(1)) + const holdCellCenterY = holdCellTop + Number((cell.height / 2).toFixed(1)) - // //설치된 셀에 좌측에 스냅 - // if (Math.abs(smallRight - holdCellLeft) < snapDistance) { - // tempModule.left = holdCellLeft - width - intvHor - // } + //설치된 셀에 좌측에 스냅 + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + tempModule.left = holdCellLeft - width - intvHor + } - // //설치된 셀에 우측에 스냅 - // if (Math.abs(smallLeft - holdCellRight) < snapDistance) { - // tempModule.left = holdCellRight + intvHor - // } + //설치된 셀에 우측에 스냅 + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + tempModule.left = holdCellRight + intvHor + } - // //설치된 셀에 위쪽에 스냅 - // if (Math.abs(smallBottom - holdCellTop) < snapDistance) { - // tempModule.top = holdCellTop - height - intvVer - // } + //설치된 셀에 위쪽에 스냅 + if (Math.abs(smallBottom - holdCellTop) < snapDistance) { + tempModule.top = holdCellTop - height - intvVer + } - // //설치된 셀에 밑쪽에 스냅 - // if (Math.abs(smallTop - holdCellBottom) < snapDistance) { - // tempModule.top = holdCellBottom + intvVer - // } - // //가운데 -> 가운데 - // if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { - // tempModule.left = holdCellCenterX - Number((width / 2).toFixed(1)) - // } - // //왼쪽 -> 가운데 - // if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { - // tempModule.left = holdCellCenterX - // } - // // 오른쪽 -> 가운데 - // if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { - // tempModule.left = holdCellCenterX - width - // } - // //세로 가운데 -> 가운데 - // if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { - // tempModule.top = holdCellCenterY - Number((height / 2).toFixed(1)) - // } - // // //위쪽 -> 가운데 - // // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { - // // tempModule.top = holdCellCenterY - // // } - // // //아랫쪽 -> 가운데 - // // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { - // // tempModule.top = holdCellCenterY - height - // // } - // }) - // } + //설치된 셀에 밑쪽에 스냅 + if (Math.abs(smallTop - holdCellBottom) < snapDistance) { + tempModule.top = holdCellBottom + intvVer + } + //가운데 -> 가운데 + if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX - Number((width / 2).toFixed(1)) + } + //왼쪽 -> 가운데 + if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX + } + // 오른쪽 -> 가운데 + if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX - width + } + //세로 가운데 -> 가운데 + if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - Number((height / 2).toFixed(1)) + } + // //위쪽 -> 가운데 + // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { + // tempModule.top = holdCellCenterY + // } + // //아랫쪽 -> 가운데 + // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { + // tempModule.top = holdCellCenterY - height + // } + }) + } // 위쪽 변에 스냅 if (Math.abs(smallTop - trestleTop) < trestleSnapDistance) { @@ -1152,37 +1156,66 @@ export function useModuleBasicSetting(tabNum) { if (!inside) return if (tempModule) { let startX, startY - - console.log(tempModule) + let installedLastHeightCoord = 0 //마지막으로 설치된 모듈의 좌표 //그려진 가이드 라인의 포인트를 기준으로 시작점을 만든다 if (flowDirection === 'south') { startX = toFixedWithoutRounding(tempModule.left, 1) startY = toFixedWithoutRounding(tempModule.top + tempModule.height, 1) - for (let i = 0; i < placementRef.layoutSetup.current.row; i++) { - let tempY = startY - i * height - let tempHeightMargin = i === 0 ? 0 : i * intvVer - for (let j = 0; j < placementRef.layoutSetup.current.col; j++) { - let tempX = startX + j * width - let tempWidthMargin = j === 0 ? 0 : j * intvHor + console.log('checkedModule', checkedModule) - 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 }, - ] - // console.log('🚀 ~ addCanvasMouseEventListener ~ rectPoints:', rectPoints) + checkedModule.forEach((module, index) => { + moduleOptions.fill = module.color + const moduleWidth = Number(module.longAxis) / 10 + const moduleHeight = Number(module.shortAxis) / 10 - tempModule.set({ points: rectPoints }) - const tempTurfModule = polygonToTurfPolygon(tempModule) - tempModule.setCoords() //좌표 재정렬 + let tmpWidth = flowDirection === 'south' || flowDirection === 'north' ? moduleWidth : moduleHeight + let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth - if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { - //마우스 클릭시 set으로 해당 위치에 셀을 넣음 - const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 - if (!isOverlap) { + width = + canvasSetting.roofSizeSet == '1' + ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection) + .width + : tmpWidth + height = + canvasSetting.roofSizeSet == '1' + ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection) + .height + : tmpHeight + + const col = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].col + const row = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].row + for (let i = 0; i < row; i++) { + let tempY = startY - i * height + + if (index > 0) { + //두번째 모듈일때 마지막 설치 지점 + tempY = index > 0 && i === 0 ? installedLastHeightCoord - intvVer : installedLastHeightCoord + } + + let tempHeightMargin = i === 0 ? 0 : i * intvVer + + for (let j = 0; j < col; j++) { + let tempX = startX + j * width + let tempWidthMargin = j === 0 ? 0 : j * 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 }, + ] + // console.log('🚀 ~ addCanvasMouseEventListener ~ rectPoints:', rectPoints) + + tempModule.set({ points: rectPoints }) + const tempTurfModule = polygonToTurfPolygon(tempModule) + tempModule.setCoords() //좌표 재정렬 + + if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { + //마우스 클릭시 set으로 해당 위치에 셀을 넣음 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + // if (!isOverlap) { canvas?.remove(tempModule) //안겹치면 넣는다 @@ -1191,7 +1224,7 @@ export function useModuleBasicSetting(tabNum) { let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, - moduleInfo: checkedModule[0], + moduleInfo: module, // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), width: toFixedWithoutRounding(width, 1), @@ -1205,15 +1238,24 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(manualModule) manualDrawModules.push(manualModule) setModuleStatisticsData() + installedLastHeightCoord = tempY - height - tempHeightMargin + } else { + manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + canvas?.add(manualModule) + canvas.renderAll() } // getModuleStatistics() - } else { - swalFire({ text: getMessage('module.place.overlab') }) - return + // } else { + // swalFire({ text: getMessage('module.place.overlab') }) + // return + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() + // } } } } - } + }) } else if (flowDirection === 'north') { startX = tempModule.points[3].x startY = tempModule.points[3].y From 9e66b3ef7d38e4367393dfb815dc44d07d661a1a Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 17 Mar 2025 11:33:44 +0900 Subject: [PATCH 003/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EB=8F=99=EC=84=9C=EB=82=A8=EB=B6=81=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 73 ++-- .../floor-plan/modal/basic/step/Placement.jsx | 4 +- src/hooks/module/useModuleBasicSetting.js | 358 +++++++++++++++--- 3 files changed, 328 insertions(+), 107 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index e2a38de8..33b0c65f 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -6,7 +6,7 @@ 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, isManualModuleLayoutSetupState, isManualModuleSetupState } from '@/store/canvasAtom' +import { canvasSettingState, canvasState, checkedModuleState, isManualModuleLayoutSetupState, 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' @@ -107,7 +107,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { } const handleManualModuleLayoutSetup = () => { - console.log('asdfasdkljfhaskjdhfakjsdhkfjh') setManualSetupMode(`manualLayoutSetup_${!isManualModuleLayoutSetup}`) setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup) } @@ -142,8 +141,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { } useEffect(() => { - console.log('asdfasdf', manualSetupMode) - if (basicSetting.roofSizeSet !== '3') { if (manualSetupMode.indexOf('manualSetup') > -1) { manualModuleSetup(placementRef) @@ -211,47 +208,33 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { )} -
- {tabNum !== 1 && ( - - )} - {/*{tabNum !== 3 && }*/} - {tabNum !== 3 && ( - - )} - - {tabNum === 3 && ( - <> - {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( - <> - - - - - )} - {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( - <> - - - - )} - - )} -
+ {tabNum === 3 && ( + <> + {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( + <> + + + + + )} + {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( + <> + + + + )} + + )}
diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index f2c3c83f..582f291c 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -175,7 +175,7 @@ const Placement = forwardRef((props, refs) => { className="input-origin block mr10" name="col" value={props.layoutSetup[index]?.col ?? 1} - defaultValue={1} + defaultValue={0} onChange={(e) => handleLayoutSetup(e, item.itemId, index)} />{' '} × @@ -184,7 +184,7 @@ const Placement = forwardRef((props, refs) => { className="input-origin block" name="row" value={props.layoutSetup[index]?.row ?? 1} - defaultValue={1} + defaultValue={0} onChange={(e) => handleLayoutSetup(e, item.itemId, index)} /> diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 44f7d21e..c7b9ec38 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1146,43 +1146,43 @@ export function useModuleBasicSetting(tabNum) { if (!inside) { // tempModule.set({ fill: 'red' }) - canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) - canvas?.renderAll() + // canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) + // canvas?.renderAll() } }) addCanvasMouseEventListener('mouse:up', (e) => { - let isIntersection = true if (!inside) return if (tempModule) { let startX, startY let installedLastHeightCoord = 0 //마지막으로 설치된 모듈의 좌표 - //그려진 가이드 라인의 포인트를 기준으로 시작점을 만든다 - if (flowDirection === 'south') { - startX = toFixedWithoutRounding(tempModule.left, 1) - startY = toFixedWithoutRounding(tempModule.top + tempModule.height, 1) + checkedModule.forEach((module, index) => { + //모듈 사이즈 + const moduleWidth = toFixedWithoutRounding(module.longAxis / 10, 1) + const moduleHeight = toFixedWithoutRounding(module.shortAxis / 10, 1) - console.log('checkedModule', checkedModule) + //흐름 방향에 따른 모듈 사이즈 + let tmpWidth = flowDirection === 'south' || flowDirection === 'north' ? moduleWidth : moduleHeight + let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth + + //복시도, 실치수에 따른 모듈 높이 조정 + width = + canvasSetting.roofSizeSet == '1' + ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(trestlePolygon.roofMaterial.pitch), flowDirection).width + : tmpWidth + height = + canvasSetting.roofSizeSet == '1' + ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(trestlePolygon.roofMaterial.pitch), flowDirection).height + : tmpHeight + + //그려진 가이드 라인의 포인트를 기준으로 시작점을 만든다 + if (flowDirection === 'south') { + //남 + startX = toFixedWithoutRounding(tempModule.left, 1) + startY = toFixedWithoutRounding(tempModule.top + tempModule.height, 1) - checkedModule.forEach((module, index) => { moduleOptions.fill = module.color - const moduleWidth = Number(module.longAxis) / 10 - const moduleHeight = Number(module.shortAxis) / 10 - - let tmpWidth = flowDirection === 'south' || flowDirection === 'north' ? moduleWidth : moduleHeight - let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth - - width = - canvasSetting.roofSizeSet == '1' - ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection) - .width - : tmpWidth - height = - canvasSetting.roofSizeSet == '1' - ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection) - .height - : tmpHeight const col = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].col const row = layoutSetupRef.current.filter((item) => item.moduleId === module.itemId)[0].row @@ -1206,7 +1206,6 @@ export function useModuleBasicSetting(tabNum) { { x: tempX + width + tempWidthMargin, y: tempY - tempHeightMargin }, { x: tempX + width + tempWidthMargin, y: tempY - height - tempHeightMargin }, ] - // console.log('🚀 ~ addCanvasMouseEventListener ~ rectPoints:', rectPoints) tempModule.set({ points: rectPoints }) const tempTurfModule = polygonToTurfPolygon(tempModule) @@ -1215,34 +1214,39 @@ export function useModuleBasicSetting(tabNum) { if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { //마우스 클릭시 set으로 해당 위치에 셀을 넣음 const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 - // if (!isOverlap) { - canvas?.remove(tempModule) + if (!isOverlap) { + canvas?.remove(tempModule) - //안겹치면 넣는다 - // tempModule.setCoords() - moduleOptions.surfaceId = trestlePolygon.id + //안겹치면 넣는다 + // tempModule.setCoords() + moduleOptions.surfaceId = trestlePolygon.id - let manualModule = new QPolygon(tempModule.points, { - ...moduleOptions, - moduleInfo: module, - // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), - // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), - width: toFixedWithoutRounding(width, 1), - height: toFixedWithoutRounding(height, 1), - }) + let manualModule = new QPolygon(tempModule.points, { + ...moduleOptions, + moduleInfo: module, + // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), + // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), + width: toFixedWithoutRounding(width, 1), + height: toFixedWithoutRounding(height, 1), + }) - let isDisjoint = checkModuleDisjointObjects(tempTurfModule, containsBatchObjects) + let isDisjoint = checkModuleDisjointObjects(tempTurfModule, containsBatchObjects) - //오브젝트와 겹치지 않으면 넣는다 - if (isDisjoint) { - canvas?.add(manualModule) - manualDrawModules.push(manualModule) - setModuleStatisticsData() - installedLastHeightCoord = tempY - height - tempHeightMargin + //오브젝트와 겹치지 않으면 넣는다 + if (isDisjoint) { + canvas?.add(manualModule) + manualDrawModules.push(manualModule) + setModuleStatisticsData() + installedLastHeightCoord = tempY - height - tempHeightMargin + } else { + //디버깅용 + // manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(manualModule) + // canvas.renderAll() + } } else { - manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(manualModule) - canvas.renderAll() + swalFire({ text: getMessage('module.place.overlab') }) + return } // getModuleStatistics() // } else { @@ -1255,18 +1259,252 @@ export function useModuleBasicSetting(tabNum) { } } } - }) - } else if (flowDirection === 'north') { - startX = tempModule.points[3].x - startY = tempModule.points[3].y - } else if (flowDirection === 'east') { - startX = tempModule.points[2].x - startY = tempModule.points[2].y - } else { - startX = tempModule.points[0].x - startY = tempModule.points[0].y - } + } else if (flowDirection === 'north') { + //북북 + startX = toFixedWithoutRounding(tempModule.left + tempModule.width, 1) + startY = toFixedWithoutRounding(tempModule.top, 1) + 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 + for (let i = 0; i < row; i++) { + let tempY = startY + i * height + + if (index > 0) { + //두번째 모듈일때 마지막 설치 지점 + tempY = index > 0 && i === 0 ? installedLastHeightCoord + intvVer : installedLastHeightCoord + } + + let tempHeightMargin = i === 0 ? 0 : i * intvVer + + for (let j = 0; j < col; j++) { + let tempX = startX - j * width + let tempWidthMargin = j === 0 ? 0 : j * 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 }, + ] + + tempModule.set({ points: rectPoints }) + const tempTurfModule = polygonToTurfPolygon(tempModule) + tempModule.setCoords() //좌표 재정렬 + + if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { + //마우스 클릭시 set으로 해당 위치에 셀을 넣음 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + if (!isOverlap) { + canvas?.remove(tempModule) + + //안겹치면 넣는다 + // tempModule.setCoords() + moduleOptions.surfaceId = trestlePolygon.id + + let manualModule = new QPolygon(tempModule.points, { + ...moduleOptions, + moduleInfo: module, + // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), + // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), + width: toFixedWithoutRounding(width, 1), + height: toFixedWithoutRounding(height, 1), + }) + + let isDisjoint = checkModuleDisjointObjects(tempTurfModule, containsBatchObjects) + + //오브젝트와 겹치지 않으면 넣는다 + if (isDisjoint) { + canvas?.add(manualModule) + manualDrawModules.push(manualModule) + setModuleStatisticsData() + installedLastHeightCoord = tempY + height + tempHeightMargin + } else { + //디버깅용 + // manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(manualModule) + // canvas.renderAll() + } + } else { + swalFire({ text: getMessage('module.place.overlab') }) + return + } + // getModuleStatistics() + // } else { + // swalFire({ text: getMessage('module.place.overlab') }) + // return + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() + // } + } + } + } + } else if (flowDirection === 'west') { + startX = toFixedWithoutRounding(tempModule.left, 1) + startY = toFixedWithoutRounding(tempModule.top, 1) + 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 + + for (let i = 0; i < row; i++) { + //옆으로 올라가는거라 height가 아니고 width로 변경 + let tempX = startX + i * width + let tempWidthMargin = i === 0 ? 0 : i * intvHor + + if (index > 0) { + //두번째 모듈일때 마지막 설치 지점 //명칭은 그대로 쓴다 + tempX = index > 0 && i === 0 ? installedLastHeightCoord + intvHor : installedLastHeightCoord + } + + for (let j = 0; j < col; j++) { + let tempY = startY + j * height + let tempHeightMargin = j === 0 ? 0 : j * intvVer + + let rectPoints = [ + { x: tempX + tempWidthMargin, y: tempY + tempHeightMargin }, + { x: tempX + tempWidthMargin, y: tempY + height + tempHeightMargin }, + { x: tempX + width + tempWidthMargin, y: tempY + height + tempHeightMargin }, + { x: tempX + width + tempWidthMargin, y: tempY + tempHeightMargin }, + ] + + tempModule.set({ points: rectPoints }) + const tempTurfModule = polygonToTurfPolygon(tempModule) + tempModule.setCoords() //좌표 재정렬 + + if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { + //마우스 클릭시 set으로 해당 위치에 셀을 넣음 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + if (!isOverlap) { + canvas?.remove(tempModule) + + //안겹치면 넣는다 + // tempModule.setCoords() + moduleOptions.surfaceId = trestlePolygon.id + + let manualModule = new QPolygon(tempModule.points, { + ...moduleOptions, + moduleInfo: module, + // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), + // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), + width: toFixedWithoutRounding(width, 1), + height: toFixedWithoutRounding(height, 1), + }) + + let isDisjoint = checkModuleDisjointObjects(tempTurfModule, containsBatchObjects) + + //오브젝트와 겹치지 않으면 넣는다 + if (isDisjoint) { + canvas?.add(manualModule) + manualDrawModules.push(manualModule) + setModuleStatisticsData() + installedLastHeightCoord = tempX + width + tempWidthMargin + } else { + //디버깅용 + // manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(manualModule) + // canvas.renderAll() + } + } else { + swalFire({ text: getMessage('module.place.overlab') }) + return + } + // getModuleStatistics() + // } else { + // swalFire({ text: getMessage('module.place.overlab') }) + // return + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() + // } + } + } + } + } else { + startX = toFixedWithoutRounding(tempModule.left + width, 1) + startY = toFixedWithoutRounding(tempModule.top + height, 1) + 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 + + for (let i = 0; i < row; i++) { + //옆으로 올라가는거라 height가 아니고 width로 변경 + let tempX = startX - i * width + let tempWidthMargin = i === 0 ? 0 : i * intvHor + + if (index > 0) { + //두번째 모듈일때 마지막 설치 지점 //명칭은 그대로 쓴다 + tempX = index > 0 && i === 0 ? installedLastHeightCoord - intvHor : installedLastHeightCoord + } + + for (let j = 0; j < col; j++) { + let tempY = startY - j * height + let tempHeightMargin = j === 0 ? 0 : j * intvVer + + let rectPoints = [ + { x: tempX - tempWidthMargin, y: tempY - tempHeightMargin }, + { x: tempX - tempWidthMargin, y: tempY - height - tempHeightMargin }, + { x: tempX - width - tempWidthMargin, y: tempY - height - tempHeightMargin }, + { x: tempX - width - tempWidthMargin, y: tempY - tempHeightMargin }, + ] + + tempModule.set({ points: rectPoints }) + const tempTurfModule = polygonToTurfPolygon(tempModule) + tempModule.setCoords() //좌표 재정렬 + + if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { + //마우스 클릭시 set으로 해당 위치에 셀을 넣음 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + if (!isOverlap) { + canvas?.remove(tempModule) + + //안겹치면 넣는다 + // tempModule.setCoords() + moduleOptions.surfaceId = trestlePolygon.id + + let manualModule = new QPolygon(tempModule.points, { + ...moduleOptions, + moduleInfo: module, + // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), + // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), + width: toFixedWithoutRounding(width, 1), + height: toFixedWithoutRounding(height, 1), + }) + + let isDisjoint = checkModuleDisjointObjects(tempTurfModule, containsBatchObjects) + + //오브젝트와 겹치지 않으면 넣는다 + if (isDisjoint) { + canvas?.add(manualModule) + manualDrawModules.push(manualModule) + setModuleStatisticsData() + installedLastHeightCoord = tempX - width - tempWidthMargin + } else { + //디버깅용 + // manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(manualModule) + // canvas.renderAll() + } + } else { + swalFire({ text: getMessage('module.place.overlab') }) + return + } + // getModuleStatistics() + // } else { + // swalFire({ text: getMessage('module.place.overlab') }) + // return + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() + // } + } + } + } + } + }) //도머 객체를 가져옴 // if (batchObjects) { // batchObjects.forEach((object) => { From 83b27582f7413ea5bd46316d9b887c92008dc342 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 17 Mar 2025 15:01:25 +0900 Subject: [PATCH 004/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 161 ++++++++++++++-------- 1 file changed, 107 insertions(+), 54 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index c7b9ec38..5203a972 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -560,7 +560,8 @@ export function useModuleBasicSetting(tabNum) { /** * 스냅기능 */ - let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 10 : 10 + let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 50 : 50 + let sideSnapDistance = 15 let trestleSnapDistance = 15 let intvHor = @@ -600,51 +601,103 @@ export function useModuleBasicSetting(tabNum) { const holdCellCenterX = holdCellLeft + toFixedWithoutRounding(cell.width / 2, 2) const holdCellCenterY = holdCellTop + toFixedWithoutRounding(cell.height / 2, 2) + //흐름방향따라 달라야 한다. + 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) { + tempModule.left = holdCellCenterX - width - intvHor / 2 + } + + //설치된 셀에 좌측에 스냅 + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // console.log('모듈 좌측 스냅') + tempModule.left = holdCellLeft - width - intvHor + } + + //설치된 셀에 우측에 스냅 + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // console.log('모듈 우측 스냅') + tempModule.left = holdCellRight + intvHor + } + //설치된 셀에 위쪽에 스냅 + if (Math.abs(smallBottom - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop - height - intvVer + } + + //설치된 셀에 밑쪽에 스냅 + if (Math.abs(smallTop - holdCellBottom) < sideSnapDistance) { + tempModule.top = holdCellBottom + intvVer + } + + //설치된 셀에 윗쪽에 스냅 + if (Math.abs(smallTop - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop + } + } else { + //흐름방향 west, east + + //가운데 가운데 + if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - toFixedWithoutRounding(width / 2, 2) + } + + //위쪽 -> 가운데 + if (Math.abs(smallTop - holdCellCenterY) < snapDistance) { + // console.log('holdCellCenterX', holdCellCenterX) + // console.log('smallLeft', smallLeft) + + // console.log('모듈 센터에 스냅') + tempModule.top = holdCellCenterY + intvHor / 2 + + // console.log('tempModule.left', tempModule.left) + } + // 밑 -> 가운데 + if (Math.abs(smallBottom - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - height - intvHor / 2 + } + + //설치된 셀에 좌측에 스냅 + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // console.log('모듈 좌측 스냅') + tempModule.left = holdCellLeft - width - intvHor + } + + //설치된 셀에 우측에 스냅 + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // console.log('모듈 우측 스냅') + tempModule.left = holdCellRight + intvHor + } + //설치된 셀에 위쪽에 스냅 + if (Math.abs(smallBottom - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop - height - intvVer + } + + //설치된 셀에 밑쪽에 스냅 + if (Math.abs(smallTop - holdCellBottom) < sideSnapDistance) { + tempModule.top = holdCellBottom + intvVer + } + + //설치된 셀에 윗쪽에 스냅 + if (Math.abs(smallTop - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop + } + } + //가운데 -> 가운대 - 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) { - tempModule.left = holdCellCenterX - width - intvHor / 2 - } - - //설치된 셀에 좌측에 스냅 - if (Math.abs(smallRight - holdCellLeft) < snapDistance) { - // console.log('모듈 좌측 스냅') - tempModule.left = holdCellLeft - width - intvHor - } - - //설치된 셀에 우측에 스냅 - if (Math.abs(smallLeft - holdCellRight) < snapDistance) { - // console.log('모듈 우측 스냅') - tempModule.left = holdCellRight + intvHor - } - //설치된 셀에 위쪽에 스냅 - if (Math.abs(smallBottom - holdCellTop) < 10) { - tempModule.top = holdCellTop - height - intvVer - } - - //설치된 셀에 밑쪽에 스냅 - if (Math.abs(smallTop - holdCellBottom) < 10) { - tempModule.top = holdCellBottom + intvVer - } - - //설치된 셀에 윗쪽에 스냅 - if (Math.abs(smallTop - holdCellTop) < 10) { - tempModule.top = holdCellTop - } //세로 가운데 -> 가운데 // if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { @@ -653,14 +706,10 @@ export function useModuleBasicSetting(tabNum) { // //위쪽 -> 가운데 // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { // tempModule.top = holdCellCenterY - // } - // //아랫쪽 -> 가운데 - // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { - // tempModule.top = holdCellCenterY - height - // } }) } + //여기서부턴 배치면 설치 외곽선 라인 // 위쪽 변에 스냅 if (Math.abs(smallTop - trestleTop) < trestleSnapDistance) { tempModule.top = trestleTop + 1 @@ -962,11 +1011,11 @@ export function useModuleBasicSetting(tabNum) { }, { x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), }, { x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), }, ] @@ -1146,8 +1195,8 @@ export function useModuleBasicSetting(tabNum) { if (!inside) { // tempModule.set({ fill: 'red' }) - // canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) - // canvas?.renderAll() + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) + canvas?.renderAll() } }) @@ -1235,6 +1284,7 @@ export function useModuleBasicSetting(tabNum) { //오브젝트와 겹치지 않으면 넣는다 if (isDisjoint) { canvas?.add(manualModule) + canvas?.renderAll() manualDrawModules.push(manualModule) setModuleStatisticsData() installedLastHeightCoord = tempY - height - tempHeightMargin @@ -1317,6 +1367,7 @@ export function useModuleBasicSetting(tabNum) { //오브젝트와 겹치지 않으면 넣는다 if (isDisjoint) { canvas?.add(manualModule) + canvas?.renderAll() manualDrawModules.push(manualModule) setModuleStatisticsData() installedLastHeightCoord = tempY + height + tempHeightMargin @@ -1398,6 +1449,7 @@ export function useModuleBasicSetting(tabNum) { //오브젝트와 겹치지 않으면 넣는다 if (isDisjoint) { canvas?.add(manualModule) + canvas?.renderAll() manualDrawModules.push(manualModule) setModuleStatisticsData() installedLastHeightCoord = tempX + width + tempWidthMargin @@ -1479,6 +1531,7 @@ export function useModuleBasicSetting(tabNum) { //오브젝트와 겹치지 않으면 넣는다 if (isDisjoint) { canvas?.add(manualModule) + canvas?.renderAll() manualDrawModules.push(manualModule) setModuleStatisticsData() installedLastHeightCoord = tempX - width - tempWidthMargin From 8ca01757c966f44bb0e626c6f8426877f04f3ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Mar 2025 15:43:37 +0900 Subject: [PATCH 005/196] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_modal.scss | 112 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 103 insertions(+), 9 deletions(-) diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index 65b104b7..f2b6503c 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -2172,17 +2172,13 @@ $alert-color: #101010; &.tab2{ margin-top: 10px; gap: 15px; - + .eaves-keraba-table{ + margin-top: 0; + } } .module-flex-item{ flex: 1; - .module-flex-item-tit{ - font-size: 12px; - font-weight: 500; - color: #fff; - padding-bottom: 10px; - border-bottom: 1px solid #4D4D4D; - } + .flex-item-btn-wrap{ display: grid; grid-template-columns: repeat(2, 1fr); @@ -2194,11 +2190,24 @@ $alert-color: #101010; flex-direction: column; justify-content: flex-start; flex: none; - padding-top: 27.5px; width: 260px; } } } +.module-flex-item-tit-wrap{ + display: flex; + align-items: center; + padding-bottom: 10px; + border-bottom: 1px solid #4D4D4D; + .module-flex-item-tit{ + font-size: 12px; + font-weight: 500; + color: #fff; + } + button{ + margin-left: auto; + } +} .module-table-box{ .module-table-inner{ @@ -2277,4 +2286,89 @@ $alert-color: #101010; box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #fff; } } +} + +.roof-module-inner{ + display: flex; + .compas-wrapper{ + position: relative; + flex: none; + width: 300px; + padding-right: 15px; + &:before{ + content: ''; + position: absolute; + top: 0; + right: 10px; + width: 1px; + height: 100%; + background-color: #424242; + } + } + .compas-table-wrap{ + display: flex; + flex-direction: column; + flex: 1; + + + } + .compas-table-box{ + background-color: #3D3D3D; + padding: 10px; + .outline-form{ + span{ + width: auto; + } + } + .compas-grid-table{ + display: grid; + gap: 10px; + grid-template-columns: repeat(2, 1fr); + .outline-form{ + span{ + width: 60px; + &.thin{ + width: 20px; + } + } + } + } + } +} + +.module-table-block-wrap{ + .roof-module-table{ + &.self{ + table{ + table-layout: fixed; + } + } + } + .self-table-radio{ + display: flex; + align-items: center; + justify-content: center; + } +} + +.module-area{ + display: flex; + align-items: center; + .module-area-title{ + flex: none; + font-size: 12px; + color: #fff; + font-weight: 500; + margin-right: 20px; + } + .outline-form{ + flex: 1; + } +} + +.placement-name-guide{ + font-size: 11px; + margin-left: 10px; + color: #53a7eb; + font-weight: 500; } \ No newline at end of file From e99a1a38548a0292174f0e96d3933a7fb0352667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Mar 2025 15:43:57 +0900 Subject: [PATCH 006/196] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=ED=99=94=EB=A9=B4=20=EB=8B=A4?= =?UTF-8?q?=EA=B5=AD=EC=96=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 1 + src/locales/ko.json | 1 + 2 files changed, 2 insertions(+) diff --git a/src/locales/ja.json b/src/locales/ja.json index 0028a047..e142119b 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -18,6 +18,7 @@ "plan.menu.placement.surface.initial.setting": "配置面初期設定", "modal.placement.initial.setting.plan.drawing": "図面の作成方法", "modal.placement.initial.setting.plan.drawing.size.stuff": "寸法入力による物件作成", + "modal.placement.initial.setting.plan.drawing.size.info": "※数字は[半角]入力のみ可能です。", "modal.placement.initial.setting.size": "寸法入力方法", "modal.placement.initial.setting.size.info": "寸法入力方法案内", "modal.placement.initial.setting.size.roof": "伏図入力", diff --git a/src/locales/ko.json b/src/locales/ko.json index 4c051305..94b5e52e 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -18,6 +18,7 @@ "plan.menu.placement.surface.initial.setting": "배치면 초기설정", "modal.placement.initial.setting.plan.drawing": "도면 작성방법", "modal.placement.initial.setting.plan.drawing.size.stuff": "치수 입력에 의한 물건 작성", + "modal.placement.initial.setting.plan.drawing.size.info": "※숫자는 [반각] 입력만 가능합니다.", "modal.placement.initial.setting.size": "치수 입력방법", "modal.placement.initial.setting.size.info": "치수 입력방법 안내", "modal.placement.initial.setting.size.roof": "복시도 입력", From 16423de079bbe5de6f84182a2e0c6ce9ecd0bdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Mar 2025 15:44:12 +0900 Subject: [PATCH 007/196] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/placementShape/PlacementShapeSetting.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index a70a8c65..364526fb 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -271,7 +271,12 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla {getMessage('modal.placement.initial.setting.plan.drawing')} - {getMessage('modal.placement.initial.setting.plan.drawing.size.stuff')} + +
+ {getMessage('modal.placement.initial.setting.plan.drawing.size.stuff')}{' '} + {getMessage('modal.placement.initial.setting.plan.drawing.size.info')} +
+ From 63db694efa3f105ca390e4acaddcc8e3a224c0dc Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 17 Mar 2025 18:36:39 +0900 Subject: [PATCH 008/196] =?UTF-8?q?=EB=8B=A8=EC=88=98=EC=A7=80=EC=A0=95?= =?UTF-8?q?=EB=B0=B0=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: '', +}) From 2e762537fc1bac06ff8b68fd3fdfe5c0cfcf18db Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 18 Mar 2025 13:24:58 +0900 Subject: [PATCH 009/196] =?UTF-8?q?#918=20=EA=B2=AC=EC=A0=81=EC=84=9C=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=ED=99=94=EB=A9=B4=20=EA=B2=AC=EC=A0=81?= =?UTF-8?q?=EC=9D=BC=20->=20=EA=B2=AC=EC=A0=81=EC=9E=91=EC=84=B1=EC=9D=BC?= =?UTF-8?q?=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index d6670702..ee4c6d28 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -886,7 +886,7 @@ "estimate.detail.drawingEstimateCreateDate": "登録日", "estimate.detail.lastEditDatetime": "変更日時", "estimate.detail.saleStoreId": "一次販売店名", - "estimate.detail.estimateDate": "見積日", + "estimate.detail.estimateDate": "見積作成日", "estimate.detail.otherSaleStoreId": "二次販売店名", "estimate.detail.noOtherSaleStoreId": "二次店なし", "estimate.detail.receiveUser": "担当者", diff --git a/src/locales/ko.json b/src/locales/ko.json index 4c051305..5cfbc50b 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -886,7 +886,7 @@ "estimate.detail.drawingEstimateCreateDate": "등록일", "estimate.detail.lastEditDatetime": "변경일시", "estimate.detail.saleStoreId": "1차 판매점명", - "estimate.detail.estimateDate": "견적일", + "estimate.detail.estimateDate": "견적작성일", "estimate.detail.otherSaleStoreId": "2차 판매점명", "estimate.detail.noOtherSaleStoreId": "2차점 없음", "estimate.detail.receiveUser": "담당자", From 11438773a1b24739623c8495f307933ed3c408be Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 18 Mar 2025 13:28:58 +0900 Subject: [PATCH 010/196] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=97=A4=EB=8D=94=EB=A9=94=EB=89=B4=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index ee4c6d28..b0db31ce 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -178,7 +178,7 @@ "modal.roof.alloc.select.parallel": "筋配置", "modal.roof.alloc.select.stairs": "千鳥配置", "modal.roof.alloc.apply": "選択した屋根材として割り当て", - "plan.menu.estimate.docDown": "各種資料ダウンロード", + "plan.menu.estimate.docDown": "見積書出力", "plan.menu.estimate.save": "保存", "plan.menu.estimate.reset": "初期化", "plan.menu.estimate.copy": "見積書のコピー", From 8a5bd9f505bcc907f5ee61905b2acf13aad59002 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 18 Mar 2025 15:44:41 +0900 Subject: [PATCH 011/196] =?UTF-8?q?=EB=8B=A8=EC=88=98=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 30 +- .../floor-plan/modal/basic/step/Placement.jsx | 65 +- src/hooks/module/useModuleBasicSetting.js | 674 ++++++++++-------- src/store/canvasAtom.js | 9 +- 4 files changed, 409 insertions(+), 369 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index c76c9394..a3f0f08e 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -97,13 +97,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { setTabNum(tabNum + 1) } - const placementRef = { - isChidori: useRef('false'), - setupLocation: useRef('eaves'), - } - - const layoutSetupRef = useRef([]) - const placementFlatRef = { setupLocation: useRef('south'), } @@ -149,16 +142,18 @@ 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) + manualModuleSetup() } else if (manualSetupMode.indexOf('manualLayoutSetup') > -1) { - manualModuleLayoutSetup(layoutSetupRef) + manualModuleLayoutSetup(layoutSetup) + } else if (manualSetupMode.indexOf('off') > -1) { + manualModuleSetup() + manualModuleLayoutSetup(layoutSetup) } } else { manualFlatroofModuleSetup(placementFlatRef) } + if (isClosePopup.close) { closePopup(isClosePopup.id) } @@ -166,12 +161,13 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { if (isManualModuleLayoutSetup) { - manualModuleLayoutSetup(layoutSetupRef) + manualModuleLayoutSetup(layoutSetup) } }, [layoutSetup]) useEffect(() => { setIsManualModuleSetup(false) + setIsManualModuleLayoutSetup(false) }, [checkedModules]) return ( @@ -189,13 +185,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && } {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && ( - + )} {/*배치면 초기설정 - 입력방법: 육지붕*/} @@ -227,7 +217,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { - diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 8c105e00..4afd507b 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -3,10 +3,9 @@ import { useMessage } from '@/hooks/useMessage' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' import { checkedModuleState, - currentCanvasPlanState, isManualModuleLayoutSetupState, isManualModuleSetupState, - isModuleChidoriSetupState, + moduleSetupOptionState, toggleManualSetupModeState, } from '@/store/canvasAtom' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' @@ -15,13 +14,10 @@ import { isObjectNotEmpty } from '@/util/common-utils' const Placement = forwardRef((props, refs) => { const { getMessage } = useMessage() - const [isChidori, setIsChidori] = useRecoilState(isModuleChidoriSetupState) + const [isChidoriNotAble, setIsChidoriNotAble] = useState(false) - const [setupLocation, setSetupLocation] = useState('eaves') - const [isMaxSetup, setIsMaxSetup] = useState('false') const [selectedItems, setSelectedItems] = useState({}) - const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) const setCheckedModules = useSetRecoilState(checkedModuleState) @@ -35,6 +31,8 @@ const Placement = forwardRef((props, refs) => { const setIsManualModuleLayoutSetup = useSetRecoilState(isManualModuleLayoutSetupState) const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) + const [moduleSetupOption, setModuleSetupOption] = useRecoilState(moduleSetupOptionState) //모듈 설치 옵션 + //모듈 배치면 생성 useEffect(() => { if (moduleSelectionData) { @@ -49,7 +47,7 @@ const Placement = forwardRef((props, refs) => { return () => { setIsManualModuleSetup(false) setIsManualModuleLayoutSetup(false) - setManualSetupMode('') + setManualSetupMode('off') } }, []) @@ -69,11 +67,6 @@ 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, - })) } //모듈 배치면 생성 @@ -105,13 +98,21 @@ const Placement = forwardRef((props, refs) => { const handleChangeChidori = (e) => { const bool = e.target.value === 'true' ? true : false - setIsChidori(bool) - refs.isChidori.current = e.target.value + setModuleSetupOption({ ...moduleSetupOption, isChidori: bool }) + + //변경하면 수동 다 꺼짐 + setIsManualModuleSetup(false) + setIsManualModuleLayoutSetup(false) + setManualSetupMode('off') } const handleSetupLocation = (e) => { - setSetupLocation(e.target.value) - refs.setupLocation.current = e.target.value + setModuleSetupOption({ ...moduleSetupOption, setupLocation: e.target.value }) + + //변경하면 수동 다 꺼짐 + setIsManualModuleSetup(false) + setIsManualModuleLayoutSetup(false) + setManualSetupMode('off') } //체크된 모듈 아이디 추출 @@ -123,11 +124,6 @@ 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), - } } return ( @@ -214,7 +210,7 @@ const Placement = forwardRef((props, refs) => { type="radio" name="radio01" id="ra01" - checked={isChidori} + checked={moduleSetupOption.isChidori} disabled={isChidoriNotAble} value={'true'} onChange={(e) => handleChangeChidori(e)} @@ -222,7 +218,14 @@ const Placement = forwardRef((props, refs) => {
- handleChangeChidori(e)} /> + handleChangeChidori(e)} + />
@@ -232,24 +235,12 @@ const Placement = forwardRef((props, refs) => {
{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}
-
- - -
@@ -260,7 +251,7 @@ const Placement = forwardRef((props, refs) => { type="radio" name="radio05" id="ra05" - checked={setupLocation === 'ridge'} + checked={moduleSetupOption.setupLocation === 'ridge'} value={'ridge'} onChange={handleSetupLocation} disabled={isMultiModule} diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index cc266caa..524cbd73 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -8,7 +8,7 @@ import { currentObjectState, isManualModuleLayoutSetupState, isManualModuleSetupState, - isModuleChidoriSetupState, + moduleSetupOptionState, toggleManualSetupModeState, } from '@/store/canvasAtom' @@ -33,6 +33,7 @@ import { v4 as uuidv4 } from 'uuid' import { isObjectNotEmpty } from '@/util/common-utils' import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' import { useMode } from '@/hooks/useMode' +import { usePolygon } from '@/hooks/usePolygon' export function useModuleBasicSetting(tabNum) { const canvas = useRecoilValue(canvasState) @@ -61,7 +62,10 @@ export function useModuleBasicSetting(tabNum) { const [currentObject, setCurrentObject] = useRecoilState(currentObjectState) const { setModuleStatisticsData } = useCircuitTrestle() const { createRoofPolygon, createMarginPolygon, createPaddingPolygon } = useMode() - const isModuleChidoriSetup = useRecoilValue(isModuleChidoriSetupState) + + const { drawDirectionArrow } = usePolygon() + + const moduleSetupOption = useRecoilValue(moduleSetupOptionState) const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) @@ -440,13 +444,15 @@ export function useModuleBasicSetting(tabNum) { */ const manualModuleSetup = (placementRef) => { //레이아웃 수동설치 토글 - if (isManualModuleLayoutSetup) { - setIsManualModuleLayoutSetup(false) - setManualSetupMode(`manualLayoutSetup_false`) - } + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 if (isManualModuleSetup) { + if (isManualModuleLayoutSetup) { + setIsManualModuleLayoutSetup(false) + // setManualSetupMode(`manualLayoutSetup_false`) + } + if (checkedModule.length === 0) { swalFire({ text: getMessage('module.place.select.module') }) setIsManualModuleSetup(false) @@ -871,14 +877,17 @@ 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) //모듈설치면를 가져옴 + const isChidori = moduleSetupOption.isChidori + const setupLocation = moduleSetupOption.setupLocation + if (isManualModuleLayoutSetup) { + if (isManualModuleSetup) { + setIsManualModuleSetup(false) + // setManualSetupMode(`manualSetup_false`) + } + if (checkedModule.length === 0) { swalFire({ text: getMessage('module.place.select.module') }) setIsManualModuleLayoutSetup(false) @@ -887,7 +896,7 @@ export function useModuleBasicSetting(tabNum) { } const hasZeroLength = checkedModule.some((item) => - layoutSetupRef.current.some((layoutItem) => item.itemId === layoutItem.moduleId && (layoutItem.row === 0 || layoutItem.col === 0)), + layoutSetupRef.some((layoutItem) => item.itemId === layoutItem.moduleId && (layoutItem.row === 0 || layoutItem.col === 0)), ) if (hasZeroLength) { @@ -1009,20 +1018,20 @@ export function useModuleBasicSetting(tabNum) { const points = [ { - x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), }, { - x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), }, { - x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), }, { - x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), }, ] @@ -1039,11 +1048,11 @@ export function useModuleBasicSetting(tabNum) { stroke: 'black', strokeWidth: 1, strokeDashArray: [10, 5], - width: Number(width.toFixed(1)), //작은버전 - height: Number(height.toFixed(1)), //작은버전 - left: Number(mousePoint.x.toFixed(1) - Number((width / 2).toFixed(1))), //작은버전 - top: Number(mousePoint.y.toFixed(1) - Number((height / 2).toFixed(1))), //작은버전 - // width: Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1)), //큰버전 + width: toFixedWithoutRounding(width, 2), //작은버전 + height: toFixedWithoutRounding(height, 2), //작은버전 + left: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), //작은버전 + top: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), //작은버전 + // // width: Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1)), //큰버전 // height: Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1)), //큰버전 // left: Number(mousePoint.x.toFixed(1)) - calcHalfWidth.toFixed(1), //큰버전 // top: Number(mousePoint.y.toFixed(1)) - calcHalfHeight.toFixed(1), //큰버전 @@ -1068,77 +1077,131 @@ export function useModuleBasicSetting(tabNum) { * 스냅기능 */ let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 70 : 40 + let sideSnapDistance = 15 let trestleSnapDistance = 15 - const trestleLeft = Number(moduleSetupSurfaces[i].left.toFixed(1)) - Number((moduleSetupSurfaces[i].width / 2).toFixed(1)) - const trestleTop = Number(moduleSetupSurfaces[i].top.toFixed(1)) - Number((moduleSetupSurfaces[i].height / 2).toFixed(1)) - const trestleRight = Number(moduleSetupSurfaces[i].left.toFixed(1)) + Number((moduleSetupSurfaces[i].width / 2).toFixed(1)) - const trestleBottom = Number(moduleSetupSurfaces[i].top.toFixed(1)) + Number((moduleSetupSurfaces[i].height / 2).toFixed(1)) + const trestleLeft = toFixedWithoutRounding(moduleSetupSurfaces[i].left, 2) - toFixedWithoutRounding(moduleSetupSurfaces[i].width / 2, 2) + const trestleTop = toFixedWithoutRounding(moduleSetupSurfaces[i].top, 2) - toFixedWithoutRounding(moduleSetupSurfaces[i].height / 2, 2) + const trestleRight = + toFixedWithoutRounding(moduleSetupSurfaces[i].left, 2) + toFixedWithoutRounding(moduleSetupSurfaces[i].width / 2, 2) + const trestleBottom = + toFixedWithoutRounding(moduleSetupSurfaces[i].top, 2) + toFixedWithoutRounding(moduleSetupSurfaces[i].height / 2, 2) const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2 // 이동하는 모듈의 경계 좌표 - const smallLeft = Number(tempModule.left.toFixed(1)) - const smallTop = Number(tempModule.top.toFixed(1)) - const smallRight = smallLeft + Number(tempModule.width.toFixed(1)) - const smallBottom = smallTop + Number(tempModule.height.toFixed(1)) - const smallCenterX = smallLeft + Number((tempModule.width / 2).toFixed(1)) - const smallCenterY = smallTop + Number((tempModule.height / 2).toFixed(1)) + const smallLeft = toFixedWithoutRounding(tempModule.left, 2) + const smallTop = toFixedWithoutRounding(tempModule.top, 2) + const smallRight = smallLeft + toFixedWithoutRounding(tempModule.width, 2) + const smallBottom = smallTop + toFixedWithoutRounding(tempModule.height, 2) + const smallCenterX = smallLeft + toFixedWithoutRounding(tempModule.width / 2, 2) + const smallCenterY = smallTop + toFixedWithoutRounding(tempModule.height / 2, 2) /** * 미리 깔아놓은 셀이 있을때 셀에 흡착됨 */ if (manualDrawModules) { manualDrawModules.forEach((cell) => { - const holdCellLeft = cell.left - const holdCellTop = cell.top - const holdCellRight = holdCellLeft + Number(cell.width.toFixed(1)) - const holdCellBottom = holdCellTop + Number(cell.height.toFixed(1)) - const holdCellCenterX = holdCellLeft + Number((cell.width / 2).toFixed(1)) - const holdCellCenterY = holdCellTop + Number((cell.height / 2).toFixed(1)) + const holdCellLeft = toFixedWithoutRounding(cell.left, 2) + const holdCellTop = toFixedWithoutRounding(cell.top, 2) + const holdCellRight = holdCellLeft + toFixedWithoutRounding(cell.width, 2) + const holdCellBottom = holdCellTop + toFixedWithoutRounding(cell.height, 2) + const holdCellCenterX = holdCellLeft + toFixedWithoutRounding(cell.width / 2, 2) + const holdCellCenterY = holdCellTop + toFixedWithoutRounding(cell.height / 2, 2) - //설치된 셀에 좌측에 스냅 - if (Math.abs(smallRight - holdCellLeft) < snapDistance) { - tempModule.left = holdCellLeft - width - intvHor - } + //흐름방향따라 달라야 한다. + if (flowDirection === 'south' || flowDirection === 'north') { + if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { + //움직이는 모듈 가운데 -> 설치 모듈 가운데 + tempModule.left = holdCellCenterX - toFixedWithoutRounding(width / 2, 2) + } - //설치된 셀에 우측에 스냅 - if (Math.abs(smallLeft - holdCellRight) < snapDistance) { - tempModule.left = holdCellRight + intvHor - } + //움직이는 모듈왼쪽 -> 가운데 + if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX + intvHor / 2 + } + // 오른쪽 -> 가운데 + if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX - width - intvHor / 2 + } - //설치된 셀에 위쪽에 스냅 - if (Math.abs(smallBottom - holdCellTop) < snapDistance) { - tempModule.top = holdCellTop - height - intvVer - } + //설치된 셀에 좌측에 스냅 + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // console.log('모듈 좌측 스냅') + tempModule.left = holdCellLeft - width - intvHor + } - //설치된 셀에 밑쪽에 스냅 - if (Math.abs(smallTop - holdCellBottom) < snapDistance) { - tempModule.top = holdCellBottom + intvVer + //설치된 셀에 우측에 스냅 + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // console.log('모듈 우측 스냅') + tempModule.left = holdCellRight + intvHor + } + //설치된 셀에 위쪽에 스냅 + if (Math.abs(smallBottom - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop - height - intvVer + } + + //설치된 셀에 밑쪽에 스냅 + if (Math.abs(smallTop - holdCellBottom) < sideSnapDistance) { + tempModule.top = holdCellBottom + intvVer + } + + //설치된 셀에 윗쪽에 스냅 + if (Math.abs(smallTop - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop + } + } else { + //흐름방향 west, east + + //가운데 가운데 + if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - toFixedWithoutRounding(width / 2, 2) + } + + //위쪽 -> 가운데 + if (Math.abs(smallTop - holdCellCenterY) < snapDistance) { + // console.log('holdCellCenterX', holdCellCenterX) + // console.log('smallLeft', smallLeft) + + // console.log('모듈 센터에 스냅') + tempModule.top = holdCellCenterY + intvHor / 2 + + // console.log('tempModule.left', tempModule.left) + } + // 밑 -> 가운데 + if (Math.abs(smallBottom - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - height - intvHor / 2 + } + + //설치된 셀에 좌측에 스냅 + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // console.log('모듈 좌측 스냅') + tempModule.left = holdCellLeft - width - intvHor + } + + //설치된 셀에 우측에 스냅 + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // console.log('모듈 우측 스냅') + tempModule.left = holdCellRight + intvHor + } + //설치된 셀에 위쪽에 스냅 + if (Math.abs(smallBottom - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop - height - intvVer + } + + //설치된 셀에 밑쪽에 스냅 + if (Math.abs(smallTop - holdCellBottom) < sideSnapDistance) { + tempModule.top = holdCellBottom + intvVer + } + + //설치된 셀에 윗쪽에 스냅 + if (Math.abs(smallTop - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop + } + + if (Math.abs(smallLeft - holdCellLeft) < snapDistance) { + tempModule.left = holdCellLeft + } } - //가운데 -> 가운데 - if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX - Number((width / 2).toFixed(1)) - } - //왼쪽 -> 가운데 - if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX - } - // 오른쪽 -> 가운데 - if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX - width - } - //세로 가운데 -> 가운데 - if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { - tempModule.top = holdCellCenterY - Number((height / 2).toFixed(1)) - } - // //위쪽 -> 가운데 - // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { - // tempModule.top = holdCellCenterY - // } - // //아랫쪽 -> 가운데 - // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { - // tempModule.top = holdCellCenterY - height - // } }) } @@ -1162,33 +1225,15 @@ export function useModuleBasicSetting(tabNum) { } if (flowDirection === 'south' || flowDirection === 'north') { - // 모듈왼쪽이 세로중앙선에 붙게 스냅 - // 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(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 - (trestleTop + moduleSetupSurfaces[i].height / 2)) < trestleSnapDistance) { - // tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - // } - // 모듈 밑면이 가로중앙선에 스냅 - // if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < trestleSnapDistance) { - // tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY - // } } tempModule.setCoords() @@ -1234,15 +1279,16 @@ export function useModuleBasicSetting(tabNum) { : tmpHeight //그려진 가이드 라인의 포인트를 기준으로 시작점을 만든다 - if (flowDirection === 'south') { + //남쪽에 처마방향이나 북쪽에 용마루면 + if ((flowDirection === 'south' && setupLocation === 'eaves') || (flowDirection === 'north' && setupLocation === 'ridge')) { //남 startX = toFixedWithoutRounding(tempModule.left, 1) startY = toFixedWithoutRounding(tempModule.top + tempModule.height, 1) moduleOptions.fill = module.color - 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 col = layoutSetupRef.filter((item) => item.moduleId === module.itemId)[0].col + let row = layoutSetupRef.filter((item) => item.moduleId === module.itemId)[0].row let tempCol = col for (let i = 0; i < row; i++) { @@ -1257,7 +1303,7 @@ export function useModuleBasicSetting(tabNum) { let tempHeightMargin = i === 0 ? 0 : i * intvVer //치도리 설치시 컬럼 조정 - if (isModuleChidoriSetup) { + if (isChidori) { //치도리면 짝수열은 안으로 넣기 tempCol = installedHeightModuleCount % 2 === 0 ? col : col - 1 } @@ -1267,7 +1313,7 @@ export function useModuleBasicSetting(tabNum) { let tempX = startX + j * width let tempWidthMargin = j === 0 ? 0 : j * intvHor - if (isModuleChidoriSetup) { + if (isChidori) { chidoriMargin = installedHeightModuleCount % 2 === 0 ? 0 : width / 2 + intvHor } @@ -1324,14 +1370,6 @@ export function useModuleBasicSetting(tabNum) { swalFire({ text: getMessage('module.place.overlab') }) return } - // getModuleStatistics() - // } else { - // swalFire({ text: getMessage('module.place.overlab') }) - // return - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() - // } } } @@ -1339,17 +1377,21 @@ export function useModuleBasicSetting(tabNum) { ++installedHeightModuleCount } } - } else if (flowDirection === 'north') { + //북쪽에 처마거나 남쪽에 용마루일경우 + } else if ((flowDirection === 'north' && setupLocation === 'eaves') || (flowDirection === 'south' && setupLocation === 'ridge')) { //북북 startX = toFixedWithoutRounding(tempModule.left + tempModule.width, 1) startY = toFixedWithoutRounding(tempModule.top, 1) 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 + const col = layoutSetupRef.filter((item) => item.moduleId === module.itemId)[0].col + const row = layoutSetupRef.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) { //두번째 모듈일때 마지막 설치 지점 @@ -1358,15 +1400,24 @@ export function useModuleBasicSetting(tabNum) { let tempHeightMargin = i === 0 ? 0 : i * intvVer - for (let j = 0; j < col; j++) { + if (isChidori) { + 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 (isChidori) { + 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 }) @@ -1386,8 +1437,6 @@ export function useModuleBasicSetting(tabNum) { let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: module, - // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), - // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), width: toFixedWithoutRounding(width, 1), height: toFixedWithoutRounding(height, 1), }) @@ -1401,6 +1450,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 }) @@ -1411,44 +1464,52 @@ export function useModuleBasicSetting(tabNum) { swalFire({ text: getMessage('module.place.overlab') }) return } - // getModuleStatistics() - // } else { - // swalFire({ text: getMessage('module.place.overlab') }) - // return - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() - // } } } + if (isInstalled) { + ++installedHeightModuleCount + } } - } else if (flowDirection === 'west') { + //서쪽에 처마 또는 동쪽의 용마루일경우 + } else if ((flowDirection === 'west' && setupLocation === 'eaves') || (flowDirection === 'east' && setupLocation === 'ridge')) { startX = toFixedWithoutRounding(tempModule.left, 1) startY = toFixedWithoutRounding(tempModule.top, 1) 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 + const col = layoutSetupRef.filter((item) => item.moduleId === module.itemId)[0].col + const row = layoutSetupRef.filter((item) => item.moduleId === module.itemId)[0].row + let tempCol = col //치도리시 하나 빼려고 임시로 for (let i = 0; i < row; i++) { //옆으로 올라가는거라 height가 아니고 width로 변경 let tempX = startX + i * width let tempWidthMargin = i === 0 ? 0 : i * intvHor + let isInstalled = false if (index > 0) { //두번째 모듈일때 마지막 설치 지점 //명칭은 그대로 쓴다 tempX = index > 0 && i === 0 ? installedLastHeightCoord + intvHor : installedLastHeightCoord } - for (let j = 0; j < col; j++) { + if (isChidori) { + tempCol = installedHeightModuleCount % 2 === 0 ? col : col - 1 + } + + for (let j = 0; j < tempCol; j++) { let tempY = startY + j * height let tempHeightMargin = j === 0 ? 0 : j * intvVer + let chidoriMargin = 0 + + if (isChidori) { + chidoriMargin = installedHeightModuleCount % 2 === 0 ? 0 : height / 2 + intvVer + } + let rectPoints = [ - { x: tempX + tempWidthMargin, y: tempY + tempHeightMargin }, - { x: tempX + tempWidthMargin, y: tempY + height + tempHeightMargin }, - { x: tempX + width + tempWidthMargin, y: tempY + height + tempHeightMargin }, - { x: tempX + width + tempWidthMargin, y: tempY + tempHeightMargin }, + { x: tempX + tempWidthMargin, y: tempY + tempHeightMargin + chidoriMargin }, + { x: tempX + tempWidthMargin, y: tempY + height + tempHeightMargin + chidoriMargin }, + { x: tempX + width + tempWidthMargin, y: tempY + height + tempHeightMargin + chidoriMargin }, + { x: tempX + width + tempWidthMargin, y: tempY + tempHeightMargin + chidoriMargin }, ] tempModule.set({ points: rectPoints }) @@ -1468,8 +1529,6 @@ export function useModuleBasicSetting(tabNum) { let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: module, - // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), - // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), width: toFixedWithoutRounding(width, 1), height: toFixedWithoutRounding(height, 1), }) @@ -1483,6 +1542,10 @@ export function useModuleBasicSetting(tabNum) { manualDrawModules.push(manualModule) setModuleStatisticsData() installedLastHeightCoord = tempX + width + tempWidthMargin + + if (j === 0) { + isInstalled = true + } } else { //디버깅용 // manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) @@ -1493,44 +1556,51 @@ export function useModuleBasicSetting(tabNum) { swalFire({ text: getMessage('module.place.overlab') }) return } - // getModuleStatistics() - // } else { - // swalFire({ text: getMessage('module.place.overlab') }) - // return - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() - // } } } + if (isInstalled) { + ++installedHeightModuleCount + } } - } else { + //동쪽의 처마 또는 서쪽의 용마루일경우 + } else if ((flowDirection === 'east' && setupLocation === 'eaves') || (flowDirection === 'west' && setupLocation === 'ridge')) { startX = toFixedWithoutRounding(tempModule.left + width, 1) startY = toFixedWithoutRounding(tempModule.top + height, 1) 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 + const col = layoutSetupRef.filter((item) => item.moduleId === module.itemId)[0].col + const row = layoutSetupRef.filter((item) => item.moduleId === module.itemId)[0].row + let tempCol = col //치도리시 하나 빼려고 임시로 for (let i = 0; i < row; i++) { //옆으로 올라가는거라 height가 아니고 width로 변경 let tempX = startX - i * width let tempWidthMargin = i === 0 ? 0 : i * intvHor + let isInstalled = false if (index > 0) { //두번째 모듈일때 마지막 설치 지점 //명칭은 그대로 쓴다 tempX = index > 0 && i === 0 ? installedLastHeightCoord - intvHor : installedLastHeightCoord } - for (let j = 0; j < col; j++) { + if (isChidori) { + tempCol = installedHeightModuleCount % 2 === 0 ? col : col - 1 + } + + for (let j = 0; j < tempCol; j++) { + let chidoriMargin = 0 let tempY = startY - j * height let tempHeightMargin = j === 0 ? 0 : j * intvVer + if (isChidori) { + chidoriMargin = installedHeightModuleCount % 2 === 0 ? 0 : height / 2 + intvVer + } + let rectPoints = [ - { x: tempX - tempWidthMargin, y: tempY - tempHeightMargin }, - { x: tempX - tempWidthMargin, y: tempY - height - tempHeightMargin }, - { x: tempX - width - tempWidthMargin, y: tempY - height - tempHeightMargin }, - { x: tempX - width - tempWidthMargin, y: tempY - tempHeightMargin }, + { x: tempX - tempWidthMargin, y: tempY - tempHeightMargin - chidoriMargin }, + { x: tempX - tempWidthMargin, y: tempY - height - tempHeightMargin - chidoriMargin }, + { x: tempX - width - tempWidthMargin, y: tempY - height - tempHeightMargin - chidoriMargin }, + { x: tempX - width - tempWidthMargin, y: tempY - tempHeightMargin - chidoriMargin }, ] tempModule.set({ points: rectPoints }) @@ -1550,8 +1620,6 @@ export function useModuleBasicSetting(tabNum) { let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: module, - // left: toFixedWithoutRounding(tempX + tempWidthMargin, 1), - // top: toFixedWithoutRounding(tempY - height - tempHeightMargin, 1), width: toFixedWithoutRounding(width, 1), height: toFixedWithoutRounding(height, 1), }) @@ -1565,6 +1633,10 @@ export function useModuleBasicSetting(tabNum) { manualDrawModules.push(manualModule) setModuleStatisticsData() installedLastHeightCoord = tempX - width - tempWidthMargin + + if (j === 0) { + isInstalled = true + } } else { //디버깅용 // manualModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) @@ -1575,65 +1647,14 @@ export function useModuleBasicSetting(tabNum) { swalFire({ text: getMessage('module.place.overlab') }) return } - // getModuleStatistics() - // } else { - // swalFire({ text: getMessage('module.place.overlab') }) - // return - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() - // } } } + if (isInstalled) { + ++installedHeightModuleCount + } } } }) - //도머 객체를 가져옴 - // if (batchObjects) { - // batchObjects.forEach((object) => { - // let dormerTurfPolygon = polygonToTurfPolygon(object, true) - // const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인 - // //겹치면 안됨 - // if (intersection) { - // swalFire({ text: getMessage('module.place.overobject') }) - // isIntersection = false - // } - // }) - // } - - // if (!isIntersection) return - - // tempModule.setCoords() //좌표 재정렬 - // if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { - // //마우스 클릭시 set으로 해당 위치에 셀을 넣음 - // const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 - // if (!isOverlap) { - // canvas?.remove(tempModule) - - // //안겹치면 넣는다 - // // tempModule.setCoords() - // moduleOptions.surfaceId = trestlePolygon.id - - // // console.log('tempModule.points', tempModule.points) - - // let manualModule = new QPolygon(tempModule.points, { - // ...moduleOptions, - // moduleInfo: checkedModule[0], - // left: Number(tempModule.left.toFixed(1)), - // top: Number(tempModule.top.toFixed(1)), - // width: Number(tempModule.width.toFixed(1)), - // height: Number(tempModule.height.toFixed(1)), - // }) - // canvas?.add(manualModule) - // manualDrawModules.push(manualModule) - // setModuleStatisticsData() - // // getModuleStatistics() - // } else { - // swalFire({ text: getMessage('module.place.overlab') }) - // } - // } else { - // swalFire({ text: getMessage('module.place.out') }) - // } } }) } @@ -1663,8 +1684,8 @@ export function useModuleBasicSetting(tabNum) { return } - const isChidori = placementRef.isChidori.current === 'true' ? true : false - const setupLocation = placementRef.setupLocation.current + const isChidori = moduleSetupOption.isChidori + const setupLocation = moduleSetupOption.setupLocation const isMaxSetup = false // const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false @@ -2784,7 +2805,7 @@ export function useModuleBasicSetting(tabNum) { ) //도머s 객체 let moduleOptions = { - fill: '#BFFD9F', + fill: checkedModule[0].color, stroke: 'black', strokeWidth: 0.3, selectable: true, // 선택 가능하게 설정 @@ -2817,14 +2838,15 @@ export function useModuleBasicSetting(tabNum) { const angle = calculateAngle(points1, points2) //변별로 선택으로 되어있을때 모듈면을 회전시키기 - const targetdSurface = moduleSetupSurfaces.filter((surface) => surface.surfaceId === obj.surfaceId)[0] - targetdSurface.angle = -angle + const targetSurface = moduleSetupSurfaces.filter((surface) => surface.surfaceId === obj.surfaceId)[0] + targetSurface.angle = -angle //변별로 선택되어있는 지붕도 회전시키기 - const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === targetdSurface.parentId)[0] + const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === targetSurface.parentId)[0] targetRoof.angle = -angle targetRoof.fire('modified') - targetdSurface.fire('modified') + targetSurface.fire('modified') + drawDirectionArrow(targetRoof) } canvas.remove(obj) }) @@ -2833,6 +2855,10 @@ export function useModuleBasicSetting(tabNum) { const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === surface.parentId)[0] if (targetRoof) targetRoof.angle = -compasDeg surface.angle = -compasDeg + + targetRoof.fire('modified') + surface.fire('modified') + drawDirectionArrow(targetRoof) }) } canvas.renderAll() @@ -2896,131 +2922,158 @@ export function useModuleBasicSetting(tabNum) { /** * 스냅기능 */ - let snapDistance = 10 - let cellSnapDistance = 50 + let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 70 : 40 + let sideSnapDistance = 15 + let trestleSnapDistance = 15 - let intvHor = flowDirection === 'south' || flowDirection === 'north' ? 1 : 3 - let intvVer = flowDirection === 'south' || flowDirection === 'north' ? 3 : 1 + let intvVer = flowDirection === 'south' || flowDirection === 'north' ? 10 : 30 + let intvHor = flowDirection === 'south' || flowDirection === 'north' ? 30 : 10 - const trestleLeft = moduleSetupSurfaces[i].left - const trestleTop = moduleSetupSurfaces[i].top - const trestleRight = trestleLeft + moduleSetupSurfaces[i].width * moduleSetupSurfaces[i].scaleX - const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY + const trestleLeft = toFixedWithoutRounding(moduleSetupSurfaces[i].left, 2) - toFixedWithoutRounding(moduleSetupSurfaces[i].width / 2, 2) + const trestleTop = toFixedWithoutRounding(moduleSetupSurfaces[i].top, 2) - toFixedWithoutRounding(moduleSetupSurfaces[i].height / 2, 2) + const trestleRight = + toFixedWithoutRounding(moduleSetupSurfaces[i].left, 2) + toFixedWithoutRounding(moduleSetupSurfaces[i].width / 2, 2) + const trestleBottom = + toFixedWithoutRounding(moduleSetupSurfaces[i].top, 2) + toFixedWithoutRounding(moduleSetupSurfaces[i].height / 2, 2) const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2 - // 작은 폴리곤의 경계 좌표 계산 - const smallLeft = tempModule.left - const smallTop = tempModule.top - const smallRight = smallLeft + tempModule.width * tempModule.scaleX - const smallBottom = smallTop + tempModule.height * tempModule.scaleY - const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2 - const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2 + // 이동하는 모듈의 경계 좌표 + const smallLeft = toFixedWithoutRounding(tempModule.left, 2) + const smallTop = toFixedWithoutRounding(tempModule.top, 2) + const smallRight = smallLeft + toFixedWithoutRounding(tempModule.width, 2) + const smallBottom = smallTop + toFixedWithoutRounding(tempModule.height, 2) + const smallCenterX = smallLeft + toFixedWithoutRounding(tempModule.width / 2, 2) + const smallCenterY = smallTop + toFixedWithoutRounding(tempModule.height / 2, 2) /** * 미리 깔아놓은 셀이 있을때 셀에 흡착됨 */ if (manualDrawModules) { manualDrawModules.forEach((cell) => { - const holdCellLeft = cell.left - const holdCellTop = cell.top - const holdCellRight = holdCellLeft + cell.width * cell.scaleX - const holdCellBottom = holdCellTop + cell.height * cell.scaleY - const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2 - const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2 + const holdCellLeft = toFixedWithoutRounding(cell.left, 2) + const holdCellTop = toFixedWithoutRounding(cell.top, 2) + const holdCellRight = holdCellLeft + toFixedWithoutRounding(cell.width, 2) + const holdCellBottom = holdCellTop + toFixedWithoutRounding(cell.height, 2) + const holdCellCenterX = holdCellLeft + toFixedWithoutRounding(cell.width / 2, 2) + const holdCellCenterY = holdCellTop + toFixedWithoutRounding(cell.height / 2, 2) - //설치된 셀에 좌측에 스냅 - if (Math.abs(smallRight - holdCellLeft) < snapDistance) { - tempModule.left = holdCellLeft - width - intvHor - } + //흐름방향따라 달라야 한다. + if (flowDirection === 'south' || flowDirection === 'north') { + if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { + //움직이는 모듈 가운데 -> 설치 모듈 가운데 + tempModule.left = holdCellCenterX - toFixedWithoutRounding(width / 2, 2) + } - //설치된 셀에 우측에 스냅 - if (Math.abs(smallLeft - holdCellRight) < snapDistance) { - tempModule.left = holdCellRight + intvHor - } + //설치된 셀에 좌측에 스냅 + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // console.log('모듈 좌측 스냅') + tempModule.left = holdCellLeft - width - intvHor + } - //설치된 셀에 위쪽에 스냅 - if (Math.abs(smallBottom - holdCellTop) < snapDistance) { - tempModule.top = holdCellTop - height - intvVer - } + //설치된 셀에 우측에 스냅 + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // console.log('모듈 우측 스냅') + tempModule.left = holdCellRight + intvHor + } + //설치된 셀에 위쪽에 스냅 + if (Math.abs(smallBottom - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop - height - intvVer + } - //설치된 셀에 밑쪽에 스냅 - if (Math.abs(smallTop - holdCellBottom) < snapDistance) { - tempModule.top = holdCellBottom + intvVer + //설치된 셀에 밑쪽에 스냅 + if (Math.abs(smallTop - holdCellBottom) < sideSnapDistance) { + tempModule.top = holdCellBottom + intvVer + } + + //설치된 셀에 윗쪽에 스냅 + if (Math.abs(smallTop - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop + } + } else { + //흐름방향 west, east + + //가운데 가운데 + if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - toFixedWithoutRounding(width / 2, 2) + } + + //위쪽 -> 가운데 + if (Math.abs(smallTop - holdCellCenterY) < snapDistance) { + // console.log('holdCellCenterX', holdCellCenterX) + // console.log('smallLeft', smallLeft) + + // console.log('모듈 센터에 스냅') + tempModule.top = holdCellCenterY + intvHor / 2 + + // console.log('tempModule.left', tempModule.left) + } + // 밑 -> 가운데 + if (Math.abs(smallBottom - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - height - intvHor / 2 + } + + //설치된 셀에 좌측에 스냅 + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // console.log('모듈 좌측 스냅') + tempModule.left = holdCellLeft - width - intvHor + } + + //설치된 셀에 우측에 스냅 + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // console.log('모듈 우측 스냅') + tempModule.left = holdCellRight + intvHor + } + //설치된 셀에 위쪽에 스냅 + if (Math.abs(smallBottom - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop - height - intvVer + } + + //설치된 셀에 밑쪽에 스냅 + if (Math.abs(smallTop - holdCellBottom) < sideSnapDistance) { + tempModule.top = holdCellBottom + intvVer + } + + //설치된 셀에 윗쪽에 스냅 + if (Math.abs(smallTop - holdCellTop) < sideSnapDistance) { + tempModule.top = holdCellTop + } + + if (Math.abs(smallLeft - holdCellLeft) < snapDistance) { + tempModule.left = holdCellLeft + } } - //가운데 -> 가운데 - if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) { - tempModule.left = holdCellCenterX - width / 2 - } - //왼쪽 -> 가운데 - if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) { - tempModule.left = holdCellCenterX - } - // 오른쪽 -> 가운데 - if (Math.abs(smallRight - holdCellCenterX) < cellSnapDistance) { - tempModule.left = holdCellCenterX - width - } - //세로 가운데 -> 가운데 - if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) { - tempModule.top = holdCellCenterY - height / 2 - } - // //위쪽 -> 가운데 - // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { - // tempModule.top = holdCellCenterY - // } - // //아랫쪽 -> 가운데 - // if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { - // tempModule.top = holdCellCenterY - height - // } }) } // 위쪽 변에 스냅 - if (Math.abs(smallTop - trestleTop) < snapDistance) { - tempModule.top = trestleTop + if (Math.abs(smallTop - trestleTop) < trestleSnapDistance) { + tempModule.top = trestleTop + 1 } // 아래쪽 변에 스냅 - if (Math.abs(smallTop + tempModule.height * tempModule.scaleY - (trestleTop + moduleSetupSurfaces[i].height)) < snapDistance) { - tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height * tempModule.scaleY + if (Math.abs(smallBottom - trestleBottom) < trestleSnapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height - 1 } // 왼쪽변에 스냅 - if (Math.abs(smallLeft - trestleLeft) < snapDistance) { - tempModule.left = trestleLeft + if (Math.abs(smallLeft - trestleLeft) < trestleSnapDistance) { + tempModule.left = trestleLeft + 1 } //오른쪽 변에 스냅 - if (Math.abs(smallRight - trestleRight) < snapDistance) { - tempModule.left = trestleRight - tempModule.width * tempModule.scaleX + if (Math.abs(smallRight - trestleRight) < trestleSnapDistance) { + tempModule.left = trestleRight - tempModule.width - 1 } if (flowDirection === 'south' || flowDirection === 'north') { - // 모듈왼쪽이 세로중앙선에 붙게 스냅 - 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)) < snapDistance) { - tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - (tempModule.width * tempModule.scaleX) / 2 - } - - // 모듈오른쪽이 세로중앙선에 붙게 스냅 - if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { - tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX + if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < trestleSnapDistance) { + tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width / 2 } } else { // 모듈이 가로중앙선에 스냅 - if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < snapDistance) { + if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < trestleSnapDistance) { tempModule.top = bigCenterY - tempModule.height / 2 } - - if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) { - tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - } - // 모듈 밑면이 가로중앙선에 스냅 - if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) { - tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY - } } tempModule.setCoords() @@ -3185,6 +3238,7 @@ export function useModuleBasicSetting(tabNum) { targetRoof.setCoords() targetSurface.setCoords() moduleSetupSurfaces.push(targetSurface) + drawDirectionArrow(targetSurface) } canvas.remove(obj) }) @@ -3193,6 +3247,10 @@ export function useModuleBasicSetting(tabNum) { const targetRoof = canvas.getObjects().filter((roof) => roof.name === POLYGON_TYPE.ROOF && roof.id === surface.parentId)[0] if (targetRoof) targetRoof.angle = -compasDeg surface.angle = -compasDeg + + targetRoof.fire('modified') + surface.fire('modified') + drawDirectionArrow(surface) }) } canvas.renderAll() @@ -3275,8 +3333,6 @@ export function useModuleBasicSetting(tabNum) { return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) } - let moduleGroup = [] - const flatRoofDownFlowSetupModule = ( surfaceMaxLines, maxLengthLine, diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js index dc9aeabd..0679938f 100644 --- a/src/store/canvasAtom.js +++ b/src/store/canvasAtom.js @@ -390,9 +390,12 @@ export const isManualModuleLayoutSetupState = atom({ default: false, }) -export const isModuleChidoriSetupState = atom({ - key: 'isModuleChidoriSetupState', - default: false, +export const moduleSetupOptionState = atom({ + key: 'moduleSetupOptionState', + default: { + isChidori: false, //치조 안함 + setupLocation: 'eaves', //처마 + }, }) export const toggleManualSetupModeState = atom({ From 9bb72bfa3acc9fdbea8f92179d433846abbecf82 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 19 Mar 2025 13:38:35 +0900 Subject: [PATCH 012/196] =?UTF-8?q?=EA=B7=B8=EB=A6=BC=EC=9E=90=20=EC=A0=9C?= =?UTF-8?q?=EC=99=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 5fa14745..688a457f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -206,13 +206,7 @@ export function useModuleBasicSetting(tabNum) { //도머등 오브젝트 객체가 있으면 아웃라인 낸다 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 객체 + .filter((obj) => obj.name === BATCH_TYPE.OPENING || obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) //그림자 제외 나머지 오브젝트들 //도머도 외곽을 따야한다 const batchObjectOptions = { @@ -850,6 +844,13 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(manualModule) manualDrawModules.push(manualModule) setModuleStatisticsData() + + //그림자는 무조건 가장 앞으로 + const shadowObj = canvas?.getObjects().find((obj) => obj.name === BATCH_TYPE.SHADOW) + if (shadowObj) { + shadowObj.bringToFront() + } + // getModuleStatistics() } else { swalFire({ text: getMessage('module.place.overlab') }) @@ -1656,6 +1657,10 @@ export function useModuleBasicSetting(tabNum) { } } }) + const shadowObj = canvas?.getObjects().find((obj) => obj.name === BATCH_TYPE.SHADOW) + if (shadowObj) { + shadowObj.bringToFront() + } } }) } @@ -2462,6 +2467,12 @@ export function useModuleBasicSetting(tabNum) { // moduleSetupArray: setupedModules, // }) // setModuleIsSetup(moduleArray) + + //그림자는 무조건 가장 앞으로 + const shadowObj = canvas?.getObjects().find((obj) => obj.name === BATCH_TYPE.SHADOW) + if (shadowObj) { + shadowObj.bringToFront() + } }) // calculateForApi() } From c34a7fc54dcaed46e38b7d8cb58da554f64114e7 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 19 Mar 2025 17:49:17 +0900 Subject: [PATCH 013/196] =?UTF-8?q?=EC=88=98=EB=8F=99=EC=8B=9C=20=EC=B9=98?= =?UTF-8?q?=EC=A1=B0=20=EC=97=AC=EB=B6=80=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EA=B0=80=EC=9A=B4=EB=8D=B0=20=ED=9D=A1?= =?UTF-8?q?=EC=B0=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/object/ObjectSetting.jsx | 2 +- src/hooks/module/useModuleBasicSetting.js | 89 +++++++++---------- 2 files changed, 42 insertions(+), 49 deletions(-) diff --git a/src/components/floor-plan/modal/object/ObjectSetting.jsx b/src/components/floor-plan/modal/object/ObjectSetting.jsx index 1bbddfe6..b893bf75 100644 --- a/src/components/floor-plan/modal/object/ObjectSetting.jsx +++ b/src/components/floor-plan/modal/object/ObjectSetting.jsx @@ -100,7 +100,7 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) { ] return ( - + closePopup(id)} />
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 688a457f..c49764c6 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -64,9 +64,7 @@ export function useModuleBasicSetting(tabNum) { const { createRoofPolygon, createMarginPolygon, createPaddingPolygon } = useMode() const { drawDirectionArrow } = usePolygon() - const moduleSetupOption = useRecoilValue(moduleSetupOptionState) - const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) useEffect(() => { @@ -440,6 +438,7 @@ export function useModuleBasicSetting(tabNum) { //레이아웃 수동설치 토글 const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 + const isChidori = moduleSetupOption.isChidori if (isManualModuleSetup) { if (isManualModuleLayoutSetup) { @@ -617,15 +616,16 @@ export function useModuleBasicSetting(tabNum) { tempModule.left = holdCellCenterX - toFixedWithoutRounding(width / 2, 2) } - //움직이는 모듈왼쪽 -> 가운데 - if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX + intvHor / 2 + if (isChidori) { + //움직이는 모듈왼쪽 -> 가운데 + if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX + intvHor / 2 + } + // 오른쪽 -> 가운데 + if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX - width - intvHor / 2 + } } - // 오른쪽 -> 가운데 - if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX - width - intvHor / 2 - } - //설치된 셀에 좌측에 스냅 if (Math.abs(smallRight - holdCellLeft) < snapDistance) { // console.log('모듈 좌측 스냅') @@ -659,21 +659,16 @@ export function useModuleBasicSetting(tabNum) { tempModule.top = holdCellCenterY - toFixedWithoutRounding(width / 2, 2) } - //위쪽 -> 가운데 - if (Math.abs(smallTop - holdCellCenterY) < snapDistance) { - // console.log('holdCellCenterX', holdCellCenterX) - // console.log('smallLeft', smallLeft) - - // console.log('모듈 센터에 스냅') - tempModule.top = holdCellCenterY + intvHor / 2 - - // console.log('tempModule.left', tempModule.left) + if (isChidori) { + //위쪽 -> 가운데 + if (Math.abs(smallTop - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY + intvHor / 2 + } + // 밑 -> 가운데 + if (Math.abs(smallBottom - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - height - intvHor / 2 + } } - // 밑 -> 가운데 - if (Math.abs(smallBottom - holdCellCenterY) < snapDistance) { - tempModule.top = holdCellCenterY - height - intvHor / 2 - } - //설치된 셀에 좌측에 스냅 if (Math.abs(smallRight - holdCellLeft) < snapDistance) { // console.log('모듈 좌측 스냅') @@ -881,8 +876,9 @@ export function useModuleBasicSetting(tabNum) { const manualModuleLayoutSetup = (layoutSetupRef) => { const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 - const isChidori = moduleSetupOption.isChidori - const setupLocation = moduleSetupOption.setupLocation + const isChidori = moduleSetupOption.isChidori //치도리 여부 + const setupLocation = moduleSetupOption.setupLocation //모듈 설치 위치 처마, 용마루 + const isMultiModule = checkedModule.length > 1 //멀티 모듈인지 아닌지 여부 if (isManualModuleLayoutSetup) { if (isManualModuleSetup) { @@ -1117,15 +1113,16 @@ export function useModuleBasicSetting(tabNum) { tempModule.left = holdCellCenterX - toFixedWithoutRounding(width / 2, 2) } - //움직이는 모듈왼쪽 -> 가운데 - if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX + intvHor / 2 + if (isChidori) { + //움직이는 모듈왼쪽 -> 가운데 + if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX + intvHor / 2 + } + // 오른쪽 -> 가운데 + if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX - width - intvHor / 2 + } } - // 오른쪽 -> 가운데 - if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX - width - intvHor / 2 - } - //설치된 셀에 좌측에 스냅 if (Math.abs(smallRight - holdCellLeft) < snapDistance) { // console.log('모듈 좌측 스냅') @@ -1159,21 +1156,16 @@ export function useModuleBasicSetting(tabNum) { tempModule.top = holdCellCenterY - toFixedWithoutRounding(width / 2, 2) } - //위쪽 -> 가운데 - if (Math.abs(smallTop - holdCellCenterY) < snapDistance) { - // console.log('holdCellCenterX', holdCellCenterX) - // console.log('smallLeft', smallLeft) - - // console.log('모듈 센터에 스냅') - tempModule.top = holdCellCenterY + intvHor / 2 - - // console.log('tempModule.left', tempModule.left) + if (isChidori) { + //위쪽 -> 가운데 + if (Math.abs(smallTop - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY + intvHor / 2 + } + // 밑 -> 가운데 + if (Math.abs(smallBottom - holdCellCenterY) < snapDistance) { + tempModule.top = holdCellCenterY - height - intvHor / 2 + } } - // 밑 -> 가운데 - if (Math.abs(smallBottom - holdCellCenterY) < snapDistance) { - tempModule.top = holdCellCenterY - height - intvHor / 2 - } - //설치된 셀에 좌측에 스냅 if (Math.abs(smallRight - holdCellLeft) < snapDistance) { // console.log('모듈 좌측 스냅') @@ -1256,6 +1248,7 @@ export function useModuleBasicSetting(tabNum) { addCanvasMouseEventListener('mouse:up', (e) => { if (!inside) return + if (tempModule) { let startX, startY let installedLastHeightCoord = 0 //마지막으로 설치된 모듈의 좌표 From c99deaf93f657af8eb539d5a58a1910512b69b5f Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 21 Mar 2025 17:47:41 +0900 Subject: [PATCH 014/196] =?UTF-8?q?=EA=B2=AC=EC=A0=81=ED=8A=B9=EC=9D=B4?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=83=81=ED=92=88=20pkgYn=20=EB=8C=80?= =?UTF-8?q?=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 337c0924..c4e5e08e 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -474,6 +474,21 @@ export default function Estimate({}) { } else { item.check = false } + } else { + let codes = item.code.split('、') + let flg = '0' + if (codes.length > 1) { + for (let i = 0; i < pushData.length; i++) { + if (codes.indexOf(pushData[i]) > -1) { + flg = '1' + } + } + if (flg === '1') { + item.check = true + } else { + item.check = false + } + } } }) From b51dacf4219fbc2eeb51b8e1dd9039b2b09e8d65 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 24 Mar 2025 09:27:28 +0900 Subject: [PATCH 015/196] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20=EB=AF=B8=EC=82=AC=EC=9A=A9=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/estimate/useEstimateController.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index e50572b8..2e0bbe1a 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -136,7 +136,7 @@ export const useEstimateController = (planNo, flag) => { } useEffect(() => { - setEstimateData({ ...estimateContextState, userId: session.userId, sapSalesStoreCd: session.custCd }) + setEstimateData({ ...estimateContextState, userId: session.userId }) }, [estimateContextState]) // 첨부파일 다운로드 @@ -452,8 +452,6 @@ export const useEstimateController = (planNo, flag) => { } const params = { - saleStoreId: session.storeId, - sapSalesStoreCd: session.custCd, objectNo: estimateData.objectNo, planNo: sendPlanNo, copySaleStoreId: otherSaleStoreId ? otherSaleStoreId : saleStoreId, From c704207d2f04dba2ae3bcc3347efe665ef059ec9 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Mar 2025 09:35:21 +0900 Subject: [PATCH 016/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 28 +++++++++++++++++++++++ src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index c49764c6..29a1237c 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1249,6 +1249,34 @@ export function useModuleBasicSetting(tabNum) { addCanvasMouseEventListener('mouse:up', (e) => { if (!inside) return + //입력받은 값의 합 + let sumRowCount = layoutSetupRef.reduce((acc, cur) => acc + cur.row, 0) + let sumColCount = layoutSetupRef.reduce((acc, cur) => acc + cur.col, 0) + let maxRow = 0 + let maxCol = trestlePolygon.trestleDetail.moduleMaxCols + + if (checkedModule.length > 1) { + //모듈이 여러개일때 + maxRow = trestlePolygon.trestleDetail.moduleMaxRows + + if (sumRowCount > maxRow || sumColCount > maxCol) { + swalFire({ text: getMessage('module.layout.setup.max.count', [maxRow, maxCol]) }) + return + } + } else { + //모듈이 하나일때는 module에 list를 조회 + const checkModuleId = checkedModule[0].itemId + const targetModuleRows = trestlePolygon.trestleDetail.module.find((item) => item.itemId === checkModuleId).modulemaxRows + const refOption = layoutSetupRef.find((item) => item.moduleId === checkModuleId) + + sumRowCount = refOption.row + + if (sumRowCount > targetModuleRows || sumColCount > maxCol) { + swalFire({ text: getMessage('module.layout.setup.max.count', [targetModuleRows, maxCol]) }) + return + } + } + if (tempModule) { let startX, startY let installedLastHeightCoord = 0 //마지막으로 설치된 모듈의 좌표 diff --git a/src/locales/ja.json b/src/locales/ja.json index 1ae3eadb..618f26c4 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1041,5 +1041,6 @@ "modal.placement.initial.setting.plan.drawing.only.number": "(※数字は[半角]入力のみ可能です。)", "wall.line.not.found": "外壁がありません", "roof.line.not.found": "屋根形状がありません", - "roof.material.can.not.delete": "割り当てられた配置面があります。" + "roof.material.can.not.delete": "割り当てられた配置面があります。", + "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다. (JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index cea4d87e..4e2a5589 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1041,5 +1041,6 @@ "modal.placement.initial.setting.plan.drawing.only.number": "(※ 숫자는 [반각]입력만 가능합니다.)", "wall.line.not.found": "외벽선이 없습니다.", "roof.line.not.found": "지붕형상이 없습니다.", - "roof.material.can.not.delete": "할당된 배치면이 있습니다." + "roof.material.can.not.delete": "할당된 배치면이 있습니다.", + "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다." } From 943fd16e4bda5c316cd231df71e371f86557f84e Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Mar 2025 10:23:35 +0900 Subject: [PATCH 017/196] =?UTF-8?q?=ED=81=B4=EB=A6=AD=EC=8B=9C=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=EB=A9=B4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20validation?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 1 + src/hooks/module/useModuleBasicSetting.js | 32 +++++++------------ 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index a3f0f08e..7edbb05e 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -168,6 +168,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { setIsManualModuleSetup(false) setIsManualModuleLayoutSetup(false) + setManualSetupMode(`off`) }, [checkedModules]) return ( diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 29a1237c..3d0b35df 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1250,31 +1250,21 @@ export function useModuleBasicSetting(tabNum) { if (!inside) return //입력받은 값의 합 - let sumRowCount = layoutSetupRef.reduce((acc, cur) => acc + cur.row, 0) + let sumColCount = layoutSetupRef.reduce((acc, cur) => acc + cur.col, 0) - let maxRow = 0 - let maxCol = trestlePolygon.trestleDetail.moduleMaxCols - if (checkedModule.length > 1) { - //모듈이 여러개일때 - maxRow = trestlePolygon.trestleDetail.moduleMaxRows + const isMultipleModules = checkedModule.length > 1 + const maxRow = isMultipleModules + ? trestlePolygon.trestleDetail.moduleMaxRows + : trestlePolygon.trestleDetail.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows - if (sumRowCount > maxRow || sumColCount > maxCol) { - swalFire({ text: getMessage('module.layout.setup.max.count', [maxRow, maxCol]) }) - return - } - } else { - //모듈이 하나일때는 module에 list를 조회 - const checkModuleId = checkedModule[0].itemId - const targetModuleRows = trestlePolygon.trestleDetail.module.find((item) => item.itemId === checkModuleId).modulemaxRows - const refOption = layoutSetupRef.find((item) => item.moduleId === checkModuleId) + const sumRowCount = isMultipleModules + ? layoutSetupRef.reduce((acc, cur) => acc + cur.row, 0) + : layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row - sumRowCount = refOption.row - - if (sumRowCount > targetModuleRows || sumColCount > maxCol) { - swalFire({ text: getMessage('module.layout.setup.max.count', [targetModuleRows, maxCol]) }) - return - } + if (sumRowCount > maxRow || sumColCount > trestlePolygon.trestleDetail.moduleMaxCols) { + swalFire({ text: getMessage('module.layout.setup.max.count', [maxRow, trestlePolygon.trestleDetail.moduleMaxCols]) }) + return } if (tempModule) { From dc8f033e9f99c4e36a80f768dafd96803ef10750 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Mar 2025 10:49:56 +0900 Subject: [PATCH 018/196] =?UTF-8?q?validation=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 3d0b35df..abfb19ca 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1250,20 +1250,19 @@ export function useModuleBasicSetting(tabNum) { if (!inside) return //입력받은 값의 합 - - let sumColCount = layoutSetupRef.reduce((acc, cur) => acc + cur.col, 0) - - const isMultipleModules = checkedModule.length > 1 + const isMultipleModules = checkedModule.length > 1 //모듈이 여러개면 + const maxCol = trestlePolygon.trestleDetail.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 const maxRow = isMultipleModules ? trestlePolygon.trestleDetail.moduleMaxRows - : trestlePolygon.trestleDetail.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows + : trestlePolygon.trestleDetail.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 + const sumColCount = layoutSetupRef.reduce((acc, cur) => acc + cur.col, 0) //입력한 행의 합 const sumRowCount = isMultipleModules ? layoutSetupRef.reduce((acc, cur) => acc + cur.row, 0) - : layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row + : layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 - if (sumRowCount > maxRow || sumColCount > trestlePolygon.trestleDetail.moduleMaxCols) { - swalFire({ text: getMessage('module.layout.setup.max.count', [maxRow, trestlePolygon.trestleDetail.moduleMaxCols]) }) + if (sumRowCount > maxRow || sumColCount > maxCol) { + swalFire({ text: getMessage('module.layout.setup.max.count', [maxRow, maxCol]) }) return } From f1d976521dbe62b198176774da51102979366596 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Mar 2025 10:55:53 +0900 Subject: [PATCH 019/196] =?UTF-8?q?#=20932=20-=20pcs=20=ED=95=9C=EA=B5=AD?= =?UTF-8?q?=EC=96=B4=20=EA=B8=B0=EC=9E=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/circuitTrestle/step/StepUp.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index d776476b..0e8ad7b6 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -573,7 +573,7 @@ export default function StepUp(props) { value={seletedMainOption} sourceKey="code" targetKey="code" - showKey="name" + showKey={`${globalLocale === 'ja' ? 'nameJp' : 'name'}`} onChange={(e) => setSeletedMainOption(e)} /> )} @@ -586,7 +586,7 @@ export default function StepUp(props) { value={seletedSubOption} sourceKey="code" targetKey="code" - showKey="name" + showKey={`${globalLocale === 'ja' ? 'nameJp' : 'name'}`} onChange={(e) => setSeletedSubOption(e)} /> )} From 1ba9853a3229e90769ca4cfa5389744acba459f9 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Mar 2025 11:06:35 +0900 Subject: [PATCH 020/196] =?UTF-8?q?#935=20=EC=A0=84=EB=B0=98/=EA=B8=80?= =?UTF-8?q?=EC=9E=90=ED=91=9C=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 6 ++++-- src/locales/ja.json | 5 +++-- src/locales/ko.json | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 48ad5913..be795814 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -10,6 +10,7 @@ import { useSwal } from '@/hooks/useSwal' import { useContext } from 'react' import { QcastContext } from '@/app/QcastProvider' import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' +import { useMessage } from '@/hooks/useMessage' // 모듈간 같은 행, 열의 마진이 10 이하인 경우는 같은 행, 열로 간주 const MODULE_MARGIN = 10 @@ -26,6 +27,7 @@ export const useTrestle = () => { const { getSelectedPcsItemList } = useCircuitTrestle() const { resetCircuits } = useCircuitTrestle() + const { getMessage } = useMessage() const apply = () => { const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) @@ -131,9 +133,9 @@ export const useTrestle = () => { surface.isChidory = isChidory if (plvrYn === 'N' && isChidory) { - swalFire({ text: '치조불가공법입니다.', icon: 'error' }) + swalFire({ text: getMessage('chidory.can.not.install'), icon: 'error' }) clear() - throw new Error('치조불가공법입니다.') + throw new Error(getMessage('chidory.can.not.install')) } surface.set({ isChidory: isChidory }) diff --git a/src/locales/ja.json b/src/locales/ja.json index abc9b5cf..3bbc5344 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -128,7 +128,7 @@ "modal.module.basic.setting.pitch.module.row.margin": "上下間隔", "modal.module.basic.setting.pitch.module.column.amount": "列数", "modal.module.basic.setting.pitch.module.column.margin": "左右間隔", - "modal.module.basic.setting.prev": "移転", + "modal.module.basic.setting.prev": "前に戻る", "modal.module.basic.setting.passivity.placement": "手動配置", "modal.module.basic.setting.auto.placement": "設定値に自動配置", "plan.menu.module.circuit.setting.circuit.trestle.setting": "回路設定", @@ -1040,5 +1040,6 @@ "modal.placement.initial.setting.plan.drawing.only.number": "(※数字は[半角]入力のみ可能です。)", "wall.line.not.found": "外壁がありません", "roof.line.not.found": "屋根形状がありません", - "roof.material.can.not.delete": "割り当てられた配置面があります。" + "roof.material.can.not.delete": "割り当てられた配置面があります。", + "chidory.can.not.install" : "千鳥配置できない工法です。" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 3ea284e2..f7dca490 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1040,5 +1040,6 @@ "modal.placement.initial.setting.plan.drawing.only.number": "(※ 숫자는 [반각]입력만 가능합니다.)", "wall.line.not.found": "외벽선이 없습니다.", "roof.line.not.found": "지붕형상이 없습니다.", - "roof.material.can.not.delete": "할당된 배치면이 있습니다." + "roof.material.can.not.delete": "할당된 배치면이 있습니다.", + "chidory.can.not.install" : "치조 불가 공법입니다." } From b458b4e8531762d03f70a6f564e6e5663cd8b7c3 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Mar 2025 11:26:26 +0900 Subject: [PATCH 021/196] =?UTF-8?q?=EC=BA=94=EB=B2=84=EC=8A=A4=20=ED=99=95?= =?UTF-8?q?=EC=8B=9C=EB=8C=80=20=EC=98=A4=EB=B8=8C=EC=A0=9D=ED=8A=B8=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useEvent.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index d3d270f6..2e5d23b0 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -79,6 +79,9 @@ export function useEvent() { // 마우스 위치 기준으로 확대/축소 canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom) + canvas.requestRenderAll() + canvas.calcOffset() + // 이벤트의 기본 동작 방지 (스크롤 방지) opt.e.preventDefault() opt.e.stopPropagation() From 82e35274322d8eec63591695b1da46c7183eee18 Mon Sep 17 00:00:00 2001 From: cha Date: Mon, 24 Mar 2025 13:27:30 +0900 Subject: [PATCH 022/196] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C::=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EB=B6=84=EB=A5=98=EC=97=90=EC=84=9C=20storePriceList?= =?UTF-8?q?=EC=9D=98=20pkgRank=EC=9D=98=20=EA=B0=92=EC=9D=B4=20=EC=97=86?= =?UTF-8?q?=EC=9C=BC=EB=A9=B4=20YJSS=20=EC=84=A0=ED=83=9D=EB=B6=88?= =?UTF-8?q?=EA=B0=80,=20=EA=B8=B0=EB=93=B1=EB=A1=9D=EC=9D=80=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index a44af878..592d5306 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1342,7 +1342,11 @@ export default function Estimate({}) {
-
+ {/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/} +
0 + && storePriceList[0].pkgRank !== null + && storePriceList[0].pkgRank !== '') ? "" : "none"}}> Date: Mon, 24 Mar 2025 14:07:14 +0900 Subject: [PATCH 023/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=96=B4=20=ED=8C=9D?= =?UTF-8?q?=EC=97=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 47 ++++++++++++----------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index abfb19ca..bb0b42c6 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -878,7 +878,6 @@ export function useModuleBasicSetting(tabNum) { const isChidori = moduleSetupOption.isChidori //치도리 여부 const setupLocation = moduleSetupOption.setupLocation //모듈 설치 위치 처마, 용마루 - const isMultiModule = checkedModule.length > 1 //멀티 모듈인지 아닌지 여부 if (isManualModuleLayoutSetup) { if (isManualModuleSetup) { @@ -943,8 +942,8 @@ export function useModuleBasicSetting(tabNum) { } if (moduleSetupSurfaces.length !== 0) { - // const col = layoutSetupRef.current[0].col - // const row = layoutSetupRef.current[0].row + // const col = layoutSetupRef.reduce((acc, cur) => acc + cur.col, 0) + // const row = layoutSetupRef.reduce((acc, cur) => acc + cur.row, 0) let tempModule let manualDrawModules = [] @@ -991,9 +990,30 @@ export function useModuleBasicSetting(tabNum) { ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer / 10 : moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor / 10 + //큰버전용 계산 // let calcHalfWidth = (Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1))) / 2 // let calcHalfHeight = (Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1))) / 2 + //작은버전용 + const points = [ + { + x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), + }, + { + x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), + }, + { + x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), + }, + { + x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), + }, + ] + //아래래 // let points = [ // { @@ -1014,25 +1034,6 @@ export function useModuleBasicSetting(tabNum) { // }, // ] - const points = [ - { - x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), - y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), - }, - { - x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), - y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), - }, - { - x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), - y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), - }, - { - x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), - y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), - }, - ] - const turfPoints = coordToTurfPolygon(points) if (turf.booleanWithin(turfPoints, turfPolygon)) { @@ -1050,7 +1051,7 @@ export function useModuleBasicSetting(tabNum) { height: toFixedWithoutRounding(height, 2), //작은버전 left: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), //작은버전 top: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), //작은버전 - // // width: Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1)), //큰버전 + // width: Number((width * col).toFixed(1)) + Number((intvHor * (col - 1)).toFixed(1)), //큰버전 // height: Number((height * row).toFixed(1)) + Number((intvVer * (row - 1)).toFixed(1)), //큰버전 // left: Number(mousePoint.x.toFixed(1)) - calcHalfWidth.toFixed(1), //큰버전 // top: Number(mousePoint.y.toFixed(1)) - calcHalfHeight.toFixed(1), //큰버전 From 85d9aca6d39fe7dffc5dc45acf08a550715b9278 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Mar 2025 14:50:06 +0900 Subject: [PATCH 024/196] =?UTF-8?q?=EB=B3=91=EB=A0=AC=EC=88=98=200=20?= =?UTF-8?q?=EC=9D=B4=EC=83=81=EC=9D=B8=20=EA=B2=BD=EC=9A=B0=EC=97=90?= =?UTF-8?q?=EB=A7=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 618a65d2..a836044e 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -479,7 +479,7 @@ export default function CircuitTrestleSetting({ id }) { console.log(stepUpListData) stepUpListData[0].pcsItemList.map((item, index) => { return item.serQtyList - .filter((serQty) => serQty.selected) + .filter((serQty) => serQty.selected && serQty.paralQty > 0) .forEach((serQty) => { pcs.push({ pcsMkrCd: item.pcsMkrCd, From c631c6344efd5f4e5628afa202ad68c73b19efcd Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Mar 2025 17:07:19 +0900 Subject: [PATCH 025/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=84=A4=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 --- src/hooks/module/useModuleBasicSetting.js | 35 ++--------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index bb0b42c6..1da528a2 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1251,6 +1251,7 @@ export function useModuleBasicSetting(tabNum) { if (!inside) return //입력받은 값의 합 + //지붕재+공법에 따라 최대 모듈 갯수가 달라지므로 클릭시점에 validate 체크해야함 const isMultipleModules = checkedModule.length > 1 //모듈이 여러개면 const maxCol = trestlePolygon.trestleDetail.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 const maxRow = isMultipleModules @@ -1759,8 +1760,6 @@ export function useModuleBasicSetting(tabNum) { name: 'module', } - let leftMargin, bottomMargin, square, chidoriLength - //선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환 const objectsIncludeSurface = (turfModuleSetupSurface) => { let containsBatchObjects = [] @@ -1777,36 +1776,6 @@ export function useModuleBasicSetting(tabNum) { return containsBatchObjects } - // /** - // * 도머나 개구가 모듈에 걸치는지 확인하는 로직 - // * @param {*} squarePolygon - // * @param {*} containsBatchObjects - // * @returns - // */ - // const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => { - // let isDisjoint = false - // - // if (containsBatchObjects.length > 0) { - // let convertBatchObject - // //도머가 있으면 적용되는 로직 - // isDisjoint = containsBatchObjects.every((batchObject) => { - // if (batchObject.type === 'group') { - // convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) - // } else { - // convertBatchObject = polygonToTurfPolygon(batchObject) - // } - // /** - // * 도머가 여러개일수있으므로 겹치는게 있다면... - // * 안겹치는지 확인하는 로직이라 안겹치면 true를 반환 - // */ - // return turf.booleanDisjoint(squarePolygon, convertBatchObject) - // }) - // } else { - // isDisjoint = true - // } - // return isDisjoint - // } - /** * 배치면 안에 있는지 확인 * @param {*} squarePolygon @@ -1841,7 +1810,7 @@ export function useModuleBasicSetting(tabNum) { checkedModule.forEach((module, moduleIndex) => { const tmpModuleData = trestleDetailData.module.filter((moduleObj) => module.moduleTpCd === moduleObj.moduleTpCd)[0] //혼합모듈일때는 mixModuleMaxRows 값이 0 이상임 - let moduleMaxRows = tmpModuleData.mixModuleMaxRows === 0 ? tmpModuleData.moduleMaxRows : tmpModuleData.mixModuleMaxRows + // let moduleMaxRows = tmpModuleData.mixModuleMaxRows === 0 ? tmpModuleData.moduleMaxRows : tmpModuleData.mixModuleMaxRows //모듈의 넓이 높이를 가져옴 (복시도 촌수 적용) //1번 깔았던 모듈 기준으로 잡야아함 From 437d552b3ab67d01a335499f0e8fd08c508ad4e1 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 25 Mar 2025 11:05:54 +0900 Subject: [PATCH 026/196] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EB=B0=A9?= =?UTF-8?q?=ED=96=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/useSurfaceShapeBatch.js | 310 +++++++++++++++++++--- 1 file changed, 270 insertions(+), 40 deletions(-) diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 296632a7..0de86ecc 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -159,6 +159,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { addCanvasMouseEventListener('mouse:down', (e) => { isDrawing = false + const { xInversion, yInversion } = surfaceRefs canvas?.remove(obj) //각도 추가 @@ -179,6 +180,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } //회전, flip등이 먹은 기준으로 새로생성 + // const batchSurface = addPolygon(reorderedPoints, { const batchSurface = addPolygon(obj.getCurrentPoints(), { fill: 'transparent', stroke: 'red', @@ -208,6 +210,38 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { // const popupId = uuidv4() // addPopup(popupId, 2, ) + // console.log('xInversion', xInversion) //상하반전 + // console.log('yInversion', yInversion) //좌우반전 + + //좌우 반전일때 방향 변경 + if (yInversion) { + batchSurface.lines.forEach((line) => { + const { x1, y1, x2, y2 } = line + if (line.x1 > line.x2) { + if (line.direction === 'left') { + line.direction = 'right' + line.x1 = x2 + line.x2 = x1 + } else if (line.direction === 'right') { + line.direction = 'left' + line.x1 = x2 + line.x2 = x1 + } + } + if (line.y2 > line.y1) { + if (line.direction === 'bottom') { + line.direction = 'top' + line.y1 = y2 + line.y2 = y1 + } else if (line.direction === 'top') { + line.direction = 'bottom' + line.y1 = y2 + line.y2 = y1 + } + } + }) + } + changeSurfaceLineType(batchSurface) if (setIsHidden) setIsHidden(false) @@ -491,18 +525,18 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } case 10: { points = [ - { x: pointer.x + length1 / 2, y: pointer.y + length4 / 2 }, - { x: pointer.x + length1 / 2 - length1, y: pointer.y + length4 / 2 }, { x: pointer.x + length1 / 2 - length1, y: pointer.y + length4 / 2 - length5 }, - { x: pointer.x + length1 / 2 - length1 + length2, y: pointer.y + length4 / 2 - length5 }, - { - x: pointer.x + length1 / 2 - length1 + length2, - y: pointer.y + length4 / 2 - length5 - (length4 - length5), - }, + { x: pointer.x + length1 / 2 - length1, y: pointer.y + length4 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + length4 / 2 }, { x: pointer.x + length1 / 2 - length1 + length2 + length3, y: pointer.y + length4 / 2 - length5 - (length4 - length5), }, + { + x: pointer.x + length1 / 2 - length1 + length2, + y: pointer.y + length4 / 2 - length5 - (length4 - length5), + }, + { x: pointer.x + length1 / 2 - length1 + length2, y: pointer.y + length4 / 2 - length5 }, ] break } @@ -1095,10 +1129,10 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { if (line[coord1] === line[coord2]) { if (line.direction === evaesDirection) { line.attributes.type = LINE_TYPE.WALLLINE.EAVES - line.stroke = 'rgb(47, 0, 255)' + line.stroke = 'rgb(1, 1, 1)' } else if (line.direction === ridgeDirection) { line.attributes.type = LINE_TYPE.SUBLINE.RIDGE - line.stroke = 'rgb(44, 255, 2)' + line.stroke = 'rgb(9, 9, 9)' } } }) @@ -1118,20 +1152,21 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { : a }) - if ( - (polygon.direction === 'south' && maxLineSorted.direction === 'left') || - (polygon.direction === 'north' && maxLineSorted.direction === 'right') || - (polygon.direction === 'east' && maxLineSorted.direction === 'bottom') || - (polygon.direction === 'west' && maxLineSorted.direction === 'top') - ) { - polygon.lines.forEach((line) => { - if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES) { - line.attributes.type = LINE_TYPE.SUBLINE.RIDGE - } else if (line.attributes.type === LINE_TYPE.SUBLINE.RIDGE) { - line.attributes.type = LINE_TYPE.WALLLINE.EAVES - } - }) - } + // if ( + // (polygon.direction === 'south' && maxLineSorted.direction === 'left') || + // (polygon.direction === 'north' && maxLineSorted.direction === 'right') + // // || + // // (polygon.direction === 'east' && maxLineSorted.direction === 'bottom') || + // // (polygon.direction === 'west' && maxLineSorted.direction === 'top') + // ) { + // polygon.lines.forEach((line) => { + // if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES) { + // line.attributes.type = LINE_TYPE.SUBLINE.RIDGE + // } else if (line.attributes.type === LINE_TYPE.SUBLINE.RIDGE) { + // line.attributes.type = LINE_TYPE.WALLLINE.EAVES + // } + // }) + // } if (maxLine.length === 1) { const maxLineCoord = polygon.lines.reduce((a, b) => { @@ -1141,31 +1176,226 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { : a }) - const isRealEavesLine = polygon.lines.find((line) => line.attributes.type === LINE_TYPE.WALLLINE.EAVES) - if (isRealEavesLine) { - if (polygon.direction === 'south' || polygon.direction === 'north') { - const targetCoord = - polygon.direction === 'south' ? Math.max(maxLineCoord.y1, maxLineCoord.y2) : Math.min(maxLineCoord.y1, maxLineCoord.y2) - const realLineCoord = - polygon.direction === 'south' ? Math.max(isRealEavesLine.y1, isRealEavesLine.y2) : Math.min(isRealEavesLine.y1, isRealEavesLine.y2) + const isRealEavesLine = polygon.lines.filter((line) => line.attributes.type === LINE_TYPE.WALLLINE.EAVES) + if (isRealEavesLine.length > 0) { + isRealEavesLine.forEach((line) => { + if (polygon.direction === 'south' || polygon.direction === 'north') { + const targetCoord = + polygon.direction === 'south' ? Math.max(maxLineCoord.y1, maxLineCoord.y2) : Math.min(maxLineCoord.y1, maxLineCoord.y2) + const realLineCoord = polygon.direction === 'south' ? Math.max(line.y1, line.y2) : Math.min(line.y1, line.y2) - if (targetCoord !== realLineCoord) { - isRealEavesLine.attributes.type = LINE_TYPE.SUBLINE.RIDGE - } - } else if (polygon.direction === 'east' || polygon.direction === 'west') { - const targetCoord = polygon.direction === 'east' ? Math.max(maxLineCoord.x1, maxLineCoord.x2) : Math.min(maxLineCoord.x1, maxLineCoord.x2) - const realLineCoord = - polygon.direction === 'east' ? Math.max(isRealEavesLine.x1, isRealEavesLine.x2) : Math.min(isRealEavesLine.x1, isRealEavesLine.x2) + if (targetCoord !== realLineCoord) { + line.attributes.type = LINE_TYPE.SUBLINE.RIDGE + line.stroke = 'rgb(9, 9, 9)' + } + } else if (polygon.direction === 'east' || polygon.direction === 'west') { + const targetCoord = + polygon.direction === 'east' ? Math.max(maxLineCoord.x1, maxLineCoord.x2) : Math.min(maxLineCoord.x1, maxLineCoord.x2) + const realLineCoord = polygon.direction === 'east' ? Math.max(line.x1, line.x2) : Math.min(line.x1, line.x2) - if (targetCoord !== realLineCoord) { - isRealEavesLine.attributes.type = LINE_TYPE.SUBLINE.RIDGE + if (targetCoord !== realLineCoord) { + line.attributes.type = LINE_TYPE.SUBLINE.RIDGE + line.stroke = 'rgb(9, 9, 9)' + } } - } + }) } } } } + function findCentroid(points) { + let sumX = 0, + sumY = 0 + for (let i = 0; i < points.length; i++) { + sumX += points[i].x + sumY += points[i].y + } + return { x: sumX / points.length, y: sumY / points.length } + } + + // 도형의 포인트를 왼쪽부터 반시계 방향으로 정렬하는 함수 + /** + * 다각형의 점들을 시계 반대 방향으로 정렬하는 함수 + * @param {Array} points - {x, y} 좌표 객체 배열 + * @param {Object} startPoint - 시작점 (제공되지 않으면 가장 왼쪽 아래 점을 사용) + * @returns {Array} 시계 반대 방향으로 정렬된 점들의 배열 + */ + function orderPointsCounterClockwise(points, startPoint = null) { + if (points.length <= 3) { + return points // 점이 3개 이하면 이미 다각형의 모든 점이므로 그대로 반환 + } + + // 시작점이 제공되지 않았다면 가장 왼쪽 아래 점을 찾음 + let start = startPoint + if (!start) { + start = points[0] + for (let i = 1; i < points.length; i++) { + if (points[i].x < start.x || (points[i].x === start.x && points[i].y < start.y)) { + start = points[i] + } + } + } + + // 다각형의 중심점 계산 + let centerX = 0, + centerY = 0 + for (let i = 0; i < points.length; i++) { + centerX += points[i].x + centerY += points[i].y + } + centerX /= points.length + centerY /= points.length + + // 시작점에서 시계 반대 방향으로 각도 계산 + let angles = [] + for (let i = 0; i < points.length; i++) { + // 시작점은 제외 + if (points[i] === start) continue + + // 시작점을 기준으로 각 점의 각도 계산 + let angle = Math.atan2(points[i].y - start.y, points[i].x - start.x) + + // 각도가 음수면 2π를 더해 0~2π 범위로 변환 + if (angle < 0) angle += 2 * Math.PI + + angles.push({ + point: points[i], + angle: angle, + }) + } + + // 각도에 따라 정렬 (시계 반대 방향) + angles.sort((a, b) => a.angle - b.angle) + + // 정렬된 배열 생성 (시작점을 첫 번째로) + let orderedPoints = [start] + for (let i = 0; i < angles.length; i++) { + orderedPoints.push(angles[i].point) + } + + return orderedPoints + } + + /** + * 특정 점에서 시작하여 시계 반대 방향으로 다음 점을 찾는 함수 + * @param {Object} currentPoint - 현재 점 {x, y} + * @param {Array} points - 모든 점들의 배열 + * @param {Array} visited - 방문한 점들의 인덱스 배열 + * @param {Object} prevVector - 이전 벡터 방향 (첫 호출에서는 null) + * @returns {Object} 다음 점의 인덱스와 객체 + */ + function findNextCounterClockwisePoint(currentPoint, points, visited, prevVector = null) { + let minAngle = Infinity + let nextIndex = -1 + + // 이전 벡터가 없으면 (첫 점인 경우) 아래쪽을 향하는 벡터 사용 + if (!prevVector) { + prevVector = { x: 0, y: -1 } + } + + for (let i = 0; i < points.length; i++) { + // 이미 방문했거나 현재 점이면 건너뜀 + if (visited.includes(i) || (points[i].x === currentPoint.x && points[i].y === currentPoint.y)) { + continue + } + + // 현재 점에서 다음 후보 점으로의 벡터 + let vector = { + x: points[i].x - currentPoint.x, + y: points[i].y - currentPoint.y, + } + + // 벡터의 크기 + let magnitude = Math.sqrt(vector.x * vector.x + vector.y * vector.y) + + // 단위 벡터로 정규화 + vector.x /= magnitude + vector.y /= magnitude + + // 이전 벡터와 현재 벡터 사이의 각도 계산 (내적 사용) + let dotProduct = prevVector.x * vector.x + prevVector.y * vector.y + let crossProduct = prevVector.x * vector.y - prevVector.y * vector.x + + // 각도 계산 (atan2 사용) + let angle = Math.atan2(crossProduct, dotProduct) + + // 시계 반대 방향으로 가장 작은 각도를 가진 점 찾기 + // 각도가 음수면 2π를 더해 0~2π 범위로 변환 + if (angle < 0) angle += 2 * Math.PI + + if (angle < minAngle) { + minAngle = angle + nextIndex = i + } + } + + return nextIndex !== -1 ? { index: nextIndex, point: points[nextIndex] } : null + } + + /** + * 다각형의 점들을 시계 반대 방향으로 추적하는 함수 + * @param {Array} points - {x, y} 좌표 객체 배열 + * @param {Object} startPoint - 시작점 (제공되지 않으면 가장 왼쪽 아래 점을 사용) + * @returns {Array} 시계 반대 방향으로 정렬된 점들의 배열 + */ + function tracePolygonCounterClockwise(points, startPoint = null) { + if (points.length <= 3) { + return orderPointsCounterClockwise(points, startPoint) + } + + // 시작점이 제공되지 않았다면 가장 왼쪽 아래 점을 찾음 + let startIndex = 0 + if (!startPoint) { + for (let i = 1; i < points.length; i++) { + if (points[i].x < points[startIndex].x || (points[i].x === points[startIndex].x && points[i].y < points[startIndex].y)) { + startIndex = i + } + } + startPoint = points[startIndex] + } else { + // 시작점이 제공된 경우 해당 점의 인덱스 찾기 + for (let i = 0; i < points.length; i++) { + if (points[i].x === startPoint.x && points[i].y === startPoint.y) { + startIndex = i + break + } + } + } + + // 결과 배열 초기화 + let orderedPoints = [startPoint] + let visited = [startIndex] + + let currentPoint = startPoint + let prevVector = null + + // 모든 점을 방문할 때까지 반복 + while (visited.length < points.length) { + let next = findNextCounterClockwisePoint(currentPoint, points, visited, prevVector) + + if (!next) break // 더 이상 찾을 점이 없으면 종료 + + orderedPoints.push(next.point) + visited.push(next.index) + + // 이전 벡터 업데이트 (현재 점에서 다음 점으로의 벡터) + prevVector = { + x: next.point.x - currentPoint.x, + y: next.point.y - currentPoint.y, + } + + // 벡터 정규화 + let magnitude = Math.sqrt(prevVector.x * prevVector.x + prevVector.y * prevVector.y) + prevVector.x /= magnitude + prevVector.y /= magnitude + + currentPoint = next.point + } + + return orderedPoints + } + return { applySurfaceShape, deleteAllSurfacesAndObjects, From 75549b66b57a7eed52800e32d9170fdefb6074e6 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 25 Mar 2025 11:10:56 +0900 Subject: [PATCH 027/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=8B=9C=20canvas=20=EC=A0=80=EC=9E=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/placementShape/PlacementShapeSetting.jsx | 5 ++++- src/hooks/module/useTrestle.js | 1 - src/hooks/roofcover/useRoofAllocationSetting.js | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 25ca72b8..e2e499b6 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -19,6 +19,7 @@ import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import { usePolygon } from '@/hooks/usePolygon' import { canvasState } from '@/store/canvasAtom' import { useRoofFn } from '@/hooks/common/useRoofFn' +import { usePlan } from '@/hooks/usePlan' /** * 지붕 레이아웃 @@ -45,6 +46,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const { setSurfaceShapePattern } = useRoofFn() const canvas = useRecoilValue(canvasState) const roofDisplay = useRecoilValue(roofDisplaySelector) + const { saveCanvas } = usePlan() const roofRef = { roofCd: useRef(null), @@ -205,7 +207,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla /** * 배치면초기설정 저장 버튼 클릭 */ - const handleSaveBtn = () => { + const handleSaveBtn = async () => { const roofInfo = { ...currentRoof, planNo: basicSetting.planNo, @@ -254,6 +256,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla /* 저장 후 화면 닫기 */ closePopup(id) + await saveCanvas(false) } return ( diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index be795814..a584876c 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -60,7 +60,6 @@ export const useTrestle = () => { } const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction if (!construction) { - swalFire({ text: 'construction 존재안함', icon: 'error' }) return } diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index cfc73b81..2b9c9494 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -27,6 +27,7 @@ import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { outerLinePointsState } from '@/store/outerLineAtom' import { QcastContext } from '@/app/QcastProvider' +import { usePlan } from '@/hooks/usePlan' export function useRoofAllocationSetting(id) { const canvas = useRecoilValue(canvasState) @@ -52,6 +53,7 @@ export function useRoofAllocationSetting(id) { const { swalFire } = useSwal() const { setIsGlobalLoading } = useContext(QcastContext) const { setSurfaceShapePattern } = useRoofFn() + const { saveCanvas } = usePlan() const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const resetPoints = useResetRecoilState(outerLinePointsState) @@ -225,6 +227,7 @@ export function useRoofAllocationSetting(id) { await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { swalFire({ text: getMessage(res.returnMessage) }) setIsGlobalLoading(false) + saveCanvas(false) }) //Recoil 설정 From 592275c0de8b5d8790a4d1a88ad093f50b32071f Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 25 Mar 2025 14:49:07 +0900 Subject: [PATCH 028/196] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EB=8F=84?= =?UTF-8?q?=ED=98=95=20=EC=9E=AC=EB=B0=B0=EC=B9=98=20=EB=B0=8F=20=EC=B2=98?= =?UTF-8?q?=EB=A7=88,=EC=9A=A9=EB=A7=88=EB=A3=A8,=EC=BC=80=EB=9D=BC?= =?UTF-8?q?=EB=B0=94=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 1 + src/components/fabric/QPolygon.js | 4 + src/hooks/surface/useSurfaceShapeBatch.js | 114 ++++++++-------------- 3 files changed, 47 insertions(+), 72 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index d82d43f0..abda5acd 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -203,6 +203,7 @@ export const SAVE_KEY = [ 'fontWeight', 'dormerAttributes', 'toFixed', + 'isSortedPoints', ] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype] diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 396ae6af..a471b5be 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -45,8 +45,11 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { options.sort = options.sort ?? true options.parentId = options.parentId ?? null + this.isSortedPoints = false + if (!options.sort && points.length <= 8) { points = sortedPointLessEightPoint(points) + this.isSortedPoints = true } else { let isDiagonal = false points.forEach((point, i) => { @@ -62,6 +65,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { if (!isDiagonal) { points = sortedPoints(points) + this.isSortedPoints = true } } diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 0de86ecc..75da1422 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -199,6 +199,8 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { pitch: globalPitch, surfaceId: surfaceId, direction: direction, + isXInversion: xInversion, + isYInversion: yInversion, }) canvas.setActiveObject(batchSurface) setSurfaceShapePattern(batchSurface, roofDisplay.column) @@ -213,35 +215,6 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { // console.log('xInversion', xInversion) //상하반전 // console.log('yInversion', yInversion) //좌우반전 - //좌우 반전일때 방향 변경 - if (yInversion) { - batchSurface.lines.forEach((line) => { - const { x1, y1, x2, y2 } = line - if (line.x1 > line.x2) { - if (line.direction === 'left') { - line.direction = 'right' - line.x1 = x2 - line.x2 = x1 - } else if (line.direction === 'right') { - line.direction = 'left' - line.x1 = x2 - line.x2 = x1 - } - } - if (line.y2 > line.y1) { - if (line.direction === 'bottom') { - line.direction = 'top' - line.y1 = y2 - line.y2 = y1 - } else if (line.direction === 'top') { - line.direction = 'bottom' - line.y1 = y2 - line.y2 = y1 - } - } - }) - } - changeSurfaceLineType(batchSurface) if (setIsHidden) setIsHidden(false) @@ -650,27 +623,27 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } case 14: { points = [ - { x: pointer.x - length1 / 2 + length2, y: pointer.y + length4 / 2 }, - { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 - length4 }, - { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length4 }, - { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length4 + length4 }, - { x: pointer.x - length1 / 2 + length1 - length3, y: pointer.y + length4 / 2 - length4 + length4 }, + { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, + { x: pointer.x - length1 / 2 + length2, y: pointer.y + length4 / 2 }, { x: pointer.x - length1 / 2 + length2 + (length1 - length2 - length3) / 2, y: pointer.y + length4 / 2 - length4 + length5, }, + { x: pointer.x - length1 / 2 + length1 - length3, y: pointer.y + length4 / 2 - length4 + length4 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length4 + length4 }, + { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 - length4 }, ] break } case 15: { points = [ - { x: pointer.x - length1 / 2, y: pointer.y + length2 - length2 / 2 }, { x: pointer.x - length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 }, - { x: pointer.x, y: pointer.y + length2 - length2 / 2 - length3 - (length2 - length3) }, - { x: pointer.x + length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 }, + { x: pointer.x - length1 / 2, y: pointer.y + length2 - length2 / 2 }, { x: pointer.x + length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 + length3 }, + { x: pointer.x + length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 }, + { x: pointer.x, y: pointer.y + length2 - length2 / 2 - length3 - (length2 - length3) }, ] break } @@ -678,28 +651,28 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { case 16: { points = [ { - x: pointer.x - length1 / 2, - y: pointer.y + length3 / 2, + x: pointer.x - length1 / 2 + (length1 - length2) / 2, + y: pointer.y + length3 / 2 - (length3 - length4) - length4, }, { x: pointer.x - length1 / 2 + (length1 - length2) / 2, y: pointer.y + length3 / 2 - (length3 - length4), }, { - x: pointer.x - length1 / 2 + (length1 - length2) / 2, - y: pointer.y + length3 / 2 - (length3 - length4) - length4, + x: pointer.x - length1 / 2, + y: pointer.y + length3 / 2, }, { - x: pointer.x - length1 / 2 + (length1 - length2) / 2 + length2, - y: pointer.y + length3 / 2 - (length3 - length4) - length4, + x: pointer.x - length1 / 2 + length1, + y: pointer.y + length3 / 2, }, { x: pointer.x - length1 / 2 + (length1 - length2) / 2 + length2, y: pointer.y + length3 / 2 - (length3 - length4) - length4 + length4, }, { - x: pointer.x - length1 / 2 + length1, - y: pointer.y + length3 / 2, + x: pointer.x - length1 / 2 + (length1 - length2) / 2 + length2, + y: pointer.y + length3 / 2 - (length3 - length4) - length4, }, ] break @@ -710,25 +683,25 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const topL = (length1 - length2) / 2 / Math.cos((angle * Math.PI) / 180) // 꺽이는부분 윗쪽 길이 points = [ - { - x: pointer.x - length1 / 2 + length1, - y: pointer.y + length3 / 2, - }, { x: pointer.x - length1 / 2, y: pointer.y + length3 / 2, }, { - x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)), - y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)), + x: pointer.x - length1 / 2 + length1, + y: pointer.y + length3 / 2, + }, + { + x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)) + length2 + topL * Math.cos(degreesToRadians(angle)), + y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)) + topL * Math.sin(degreesToRadians(angle)), }, { x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)) + length2, y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)), }, { - x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)) + length2 + topL * Math.cos(degreesToRadians(angle)), - y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)) + topL * Math.sin(degreesToRadians(angle)), + x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)), + y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)), }, ] break @@ -1111,7 +1084,10 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { * @param { } polygon */ + //폴리곤, 상하반전, 좌우반전 const changeSurfaceLineType = (polygon) => { + const { isXInversion, isYInversion } = polygon //상하반전, 좌우반전 + polygon.lines.forEach((line) => { line.attributes.type = LINE_TYPE.WALLLINE.GABLE }) @@ -1129,10 +1105,8 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { if (line[coord1] === line[coord2]) { if (line.direction === evaesDirection) { line.attributes.type = LINE_TYPE.WALLLINE.EAVES - line.stroke = 'rgb(1, 1, 1)' } else if (line.direction === ridgeDirection) { line.attributes.type = LINE_TYPE.SUBLINE.RIDGE - line.stroke = 'rgb(9, 9, 9)' } } }) @@ -1152,21 +1126,19 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { : a }) - // if ( - // (polygon.direction === 'south' && maxLineSorted.direction === 'left') || - // (polygon.direction === 'north' && maxLineSorted.direction === 'right') - // // || - // // (polygon.direction === 'east' && maxLineSorted.direction === 'bottom') || - // // (polygon.direction === 'west' && maxLineSorted.direction === 'top') - // ) { - // polygon.lines.forEach((line) => { - // if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES) { - // line.attributes.type = LINE_TYPE.SUBLINE.RIDGE - // } else if (line.attributes.type === LINE_TYPE.SUBLINE.RIDGE) { - // line.attributes.type = LINE_TYPE.WALLLINE.EAVES - // } - // }) - // } + //정렬된 폴리곤이 아니면(대각선이 존재하는 폴리곤일때) + if (!polygon.isSortedPoints) { + //좌우 반전을 했으면 반대로 정의함 + if (isYInversion) { + polygon.lines.forEach((line) => { + if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES) { + line.attributes.type = LINE_TYPE.SUBLINE.RIDGE + } else if (line.attributes.type === LINE_TYPE.SUBLINE.RIDGE) { + line.attributes.type = LINE_TYPE.WALLLINE.EAVES + } + }) + } + } if (maxLine.length === 1) { const maxLineCoord = polygon.lines.reduce((a, b) => { @@ -1186,7 +1158,6 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { if (targetCoord !== realLineCoord) { line.attributes.type = LINE_TYPE.SUBLINE.RIDGE - line.stroke = 'rgb(9, 9, 9)' } } else if (polygon.direction === 'east' || polygon.direction === 'west') { const targetCoord = @@ -1195,7 +1166,6 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { if (targetCoord !== realLineCoord) { line.attributes.type = LINE_TYPE.SUBLINE.RIDGE - line.stroke = 'rgb(9, 9, 9)' } } }) From 65ec3d5153475b865ff2d3e699351d7198a983b0 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 25 Mar 2025 15:12:01 +0900 Subject: [PATCH 029/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=8B=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePolygon.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index fd5b5a69..ccb8f60a 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -176,6 +176,10 @@ export const usePolygon = () => { * @param showDirectionText */ const drawDirectionArrow = (polygon, showDirectionText = true) => { + if (!polygon) { + return + } + if (polygon.points.length < 3) { return } From 5597f8ad70dbbaeeffc8a16c216df6a04fb83159 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 25 Mar 2025 15:48:18 +0900 Subject: [PATCH 030/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=9D=BC=EC=9D=B8=20?= =?UTF-8?q?=EC=83=89=EC=B9=A0=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 30 ++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 1da528a2..277ec492 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -81,6 +81,14 @@ export function useModuleBasicSetting(tabNum) { removeMouseEvent('mouse:up') removeMouseEvent('mouse:move') canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임 + canvas.getObjects().forEach((obj) => { + if (obj.name === POLYGON_TYPE.ROOF) { + obj.set({ + stroke: 'black', + strokeWidth: 3, + }) + } + }) } }, []) @@ -147,11 +155,10 @@ export function useModuleBasicSetting(tabNum) { //가대 상세 데이터 들어오면 실행 useEffect(() => { if (trestleDetailList.length > 0) { - console.log('trestleDetailList', trestleDetailList) //지붕을 가져옴 canvas .getObjects() - .filter((roof) => roof.name === 'roof') + .filter((roof) => roof.name === POLYGON_TYPE.ROOF) .forEach((roof) => { if (!roof.roofMaterial) return const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번 @@ -159,7 +166,12 @@ export function useModuleBasicSetting(tabNum) { if (detail.data !== null) { if (Number(detail.data.roofIndex) === roofIndex) { //roof에 상세 데이터 추가 - roof.set({ trestleDetail: detail.data }) + + roof.set({ + trestleDetail: detail.data, + stroke: roofOutlineColor(roofIndex), + strokeWidth: 7, + }) roof.lines.forEach((line) => { line.attributes = { ...line.attributes, @@ -176,6 +188,18 @@ export function useModuleBasicSetting(tabNum) { } }, [trestleDetailList]) + const roofOutlineColor = (roofIndex) => { + if (roofIndex === 1) { + return 'rgb(86,170,255)' + } else if (roofIndex === 2) { + return 'rgb(125, 252, 173)' + } else if (roofIndex === 3) { + return 'rgb(238, 109, 255)' + } else { + return 'rgb(252, 148, 106)' + } + } + const getOffset = (data, type) => { switch (type) { case LINE_TYPE.WALLLINE.EAVES: From 47e3ae7d290e49b90fcbbc9c7c97af91ef07383a Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 25 Mar 2025 16:07:15 +0900 Subject: [PATCH 031/196] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=83=81=ED=95=98=20=EB=B0=98=EC=A0=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/useSurfaceShapeBatch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 75da1422..16f68668 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -1129,7 +1129,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { //정렬된 폴리곤이 아니면(대각선이 존재하는 폴리곤일때) if (!polygon.isSortedPoints) { //좌우 반전을 했으면 반대로 정의함 - if (isYInversion) { + if (isYInversion || isXInversion) { polygon.lines.forEach((line) => { if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES) { line.attributes.type = LINE_TYPE.SUBLINE.RIDGE From a2d192084bb92e05956253c4f7f754afc6077163 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 26 Mar 2025 10:09:40 +0900 Subject: [PATCH 032/196] =?UTF-8?q?usePlan=20=EB=82=B4=EB=B6=80=20currentO?= =?UTF-8?q?bject=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePlan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 013e00c4..8f27a78f 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -414,7 +414,7 @@ export function usePlan(params = {}) { useEffect(() => { setSelectedPlan(currentCanvasPlan) handleCurrentPlanUrl() - resetCurrentObject() + // resetCurrentObject() resetModuleSetupSurface() }, [currentCanvasPlan]) From ba9a49501c7f6d1712a2283805faf6310341d29b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 26 Mar 2025 10:59:29 +0900 Subject: [PATCH 033/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=3D>=20=EB=A7=88=EC=A7=80=EB=A7=89=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=94=EA=B0=80=EB=90=9C=20=EC=A7=80=EB=B6=95?= =?UTF-8?q?=EC=9E=AC=20=EC=9E=90=EB=8F=99=20=EC=84=A0=ED=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roofcover/useRoofAllocationSetting.js | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 2b9c9494..a8caf5ce 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -248,16 +248,22 @@ export function useRoofAllocationSetting(id) { swalFire({ type: 'alert', icon: 'error', text: getMessage('roof.exceed.count') }) return } - setCurrentRoofList([ - ...currentRoofList, - { - ...currentRoofMaterial, + + const originCurrentRoofList = currentRoofList.map((roof) => { + return { + ...roof, selected: false, - id: currentRoofMaterial.roofMatlCd, - name: currentRoofMaterial.roofMatlNm, - index: currentRoofList.length, - }, - ]) + } + }) + originCurrentRoofList.push({ + ...currentRoofMaterial, + selected: true, + id: currentRoofMaterial.roofMatlCd, + name: currentRoofMaterial.roofMatlNm, + index: currentRoofList.length, + }) + + setCurrentRoofList(originCurrentRoofList) } /** From 25778a099f5555c675a499c60de6a73f2ae8e1dc Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 26 Mar 2025 11:10:42 +0900 Subject: [PATCH 034/196] =?UTF-8?q?=ED=8C=9D=EC=97=85=20=EB=8B=AB=EA=B3=A0?= =?UTF-8?q?=20=EC=8B=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasFrame.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 4f957598..c98f686b 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -31,11 +31,13 @@ import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' import { useEvent } from '@/hooks/useEvent' import { compasDegAtom } from '@/store/orientationAtom' import { hotkeyStore } from '@/store/hotkeyAtom' +import { usePopup } from '@/hooks/usePopup' export default function CanvasFrame() { const canvasRef = useRef(null) const { canvas } = useCanvas('canvas') const { canvasLoadInit, gridInit } = useCanvasConfigInitialize() + const { closeAll } = usePopup() const currentMenu = useRecoilValue(currentMenuState) const { floorPlanState } = useContext(FloorPlanContext) const { contextMenu, handleClick } = useContextMenu() @@ -93,6 +95,8 @@ export default function CanvasFrame() { useEffect(() => { setIsGlobalLoading(false) + // 혹시 모를 팝업이 떠있는 경우 닫고 시작한다. + closeAll() return () => { canvas?.clear() From 93b645e9e802e276a28c0ae964bc031897a2a2d6 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 26 Mar 2025 15:08:37 +0900 Subject: [PATCH 035/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=A0=84=20=EC=A0=9C=EA=B1=B0=20=EC=8B=9C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofAllocationSetting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index a8caf5ce..6d573ff0 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -273,7 +273,7 @@ export function useRoofAllocationSetting(id) { const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) for (let i = 0; i < roofs.length; i++) { - if (roofs[i].roofMaterial.index === idx) { + if (roofs[i].roofMaterial?.index === idx) { swalFire({ type: 'alert', icon: 'error', text: getMessage('roof.material.can.not.delete') }) return } From 2473cfac174d3be798467002d222268ca69a06f5 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 27 Mar 2025 10:33:34 +0900 Subject: [PATCH 036/196] =?UTF-8?q?=F0=9F=93=8C=20feat:=20Implement=20useP?= =?UTF-8?q?lan=20hook=20for=20managing=20floor=20plan=20state=20and=20inte?= =?UTF-8?q?ractions,=20including=20canvas=20data=20handling,=20plan=20crea?= =?UTF-8?q?tion,=20deletion,=20and=20context=20management.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePlan.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 8f27a78f..96f823ca 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -52,6 +52,9 @@ export function usePlan(params = {}) { const { fetchBasicSettings, basicSettingCopySave } = useCanvasSetting() const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) + /** 전역 로딩바 컨텍스트 */ + const { setIsGlobalLoading } = useContext(QcastContext) + /** * 플랜 복사 시 모듈이 있을경우 모듈 데이터 복사하기 위한 처리 */ @@ -450,13 +453,21 @@ export function usePlan(params = {}) { text: `Plan ${currentCanvasPlan.planNo} ` + getMessage('plan.message.confirm.copy'), type: 'confirm', confirmFn: async () => { + setIsGlobalLoading(true) await postObjectPlan(userId, objectNo, true, false) + setIsGlobalLoading(false) }, denyFn: async () => { + setIsGlobalLoading(true) await postObjectPlan(userId, objectNo, false, false) + setIsGlobalLoading(false) }, }) - : await postObjectPlan(userId, objectNo, false, false) + : async () => { + setIsGlobalLoading(true) + await postObjectPlan(userId, objectNo, false, false) + setIsGlobalLoading(false) + } } /** From 7f402d5b453e8a4670fecd6a7fd95a378de4b844 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 27 Mar 2025 10:34:15 +0900 Subject: [PATCH 037/196] =?UTF-8?q?=EC=88=98=EB=8F=99=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EC=8B=9C=20text=20=EB=B0=96=EC=9C=BC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapePassivitySetting.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks/roofcover/useRoofShapePassivitySetting.js b/src/hooks/roofcover/useRoofShapePassivitySetting.js index c5077a32..241d2fac 100644 --- a/src/hooks/roofcover/useRoofShapePassivitySetting.js +++ b/src/hooks/roofcover/useRoofShapePassivitySetting.js @@ -28,7 +28,7 @@ export function useRoofShapePassivitySetting(id) { const { addCanvasMouseEventListener, initEvent } = useEvent() // const { addCanvasMouseEventListener, initEvent } = useContext(EventContext) const { drawRoofPolygon } = useMode() - const { addPolygonByLines } = usePolygon() + const { addPolygonByLines, addLengthText } = usePolygon() const currentObject = useRecoilValue(currentObjectState) const offsetRef = useRef(null) const pitchRef = useRef(null) @@ -248,6 +248,7 @@ export function useRoofShapePassivitySetting(id) { // 완료 한 경우에는 지붕까지 그려줌 addPitchTextsByOuterLines() const roof = drawRoofPolygon(wall) + addLengthText(roof) } canvas.renderAll() From 54d06f7d51b2be02ee7f21bac557ef5af32c98e2 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 27 Mar 2025 10:34:40 +0900 Subject: [PATCH 038/196] =?UTF-8?q?=EA=B0=80=EB=A1=9C,=20=EC=84=B8?= =?UTF-8?q?=EB=A1=9C=20=EC=84=A0=20=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=20return?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useEvent.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index 2e5d23b0..8361ff7e 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -107,6 +107,10 @@ export function useEvent() { const horizonLines = canvas.getObjects().filter((obj) => obj.name === 'lineGrid' && obj.direction === 'horizontal') const verticalLines = canvas.getObjects().filter((obj) => obj.name === 'lineGrid' && obj.direction === 'vertical') + if (!horizonLines || !verticalLines) { + return + } + const closestHorizontalLine = horizonLines.reduce((prev, curr) => { const prevDistance = calculateDistance(pointer, prev) const currDistance = calculateDistance(pointer, curr) From 1f723c9ce735b98bd176255b5971e942a5b9999f Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 27 Mar 2025 11:05:30 +0900 Subject: [PATCH 039/196] =?UTF-8?q?fix:=20=EC=9E=84=ED=8F=AC=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=EB=AC=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePlan.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 96f823ca..0bc2a5d5 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -20,6 +20,7 @@ import { compasDegAtom } from '@/store/orientationAtom' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusController' import { useCanvasMenu } from './common/useCanvasMenu' +import { QcastContext } from '@/app/QcastProvider' /** * 플랜 처리 훅 From 3027f47d5d59e04e0f0d4965e7e231bd6147fce6 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 27 Mar 2025 13:33:29 +0900 Subject: [PATCH 040/196] =?UTF-8?q?chore:=20nextjs=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?fix=20&=20pm2=20=EC=8B=A4=ED=96=89=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- startscript.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1f31b9d3..655fce49 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "js-cookie": "^3.0.5", "mathjs": "^13.0.2", "mssql": "^11.0.1", - "next": "14.2.21", + "next": "14.2.25", "next-international": "^1.2.4", "react": "^18", "react-chartjs-2": "^5.2.0", diff --git a/startscript.js b/startscript.js index 37f52696..890c30f8 100644 --- a/startscript.js +++ b/startscript.js @@ -1,2 +1,2 @@ var exec = require('child_process').exec -exec('yarn start', { windowsHide: true }) +exec('yarn dev', { windowsHide: true }) From 25e8dcc0507d52cb6bb190ad1026745e7964e610 Mon Sep 17 00:00:00 2001 From: ysCha Date: Thu, 27 Mar 2025 13:38:15 +0900 Subject: [PATCH 041/196] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C::=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EB=B6=84=EB=A5=98=EC=97=90=EC=84=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EB=93=B1=EB=A1=9D=EB=90=9C=20YJSS=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 4c733de5..83ce0860 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1365,7 +1365,8 @@ export default function Estimate({}) {
0 && storePriceList[0].pkgRank !== null - && storePriceList[0].pkgRank !== '') ? "" : "none"}}> + && storePriceList[0].pkgRank !== '' + || estimateContextState?.estimateType === 'YJSS') ? "" : "none"}}> Date: Thu, 27 Mar 2025 14:11:23 +0900 Subject: [PATCH 042/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=84=A4=EC=B9=98=20validate=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 30 ++++++++++++++++++++--- src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 277ec492..646c743f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -81,7 +81,7 @@ export function useModuleBasicSetting(tabNum) { removeMouseEvent('mouse:up') removeMouseEvent('mouse:move') canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임 - canvas.getObjects().forEach((obj) => { + canvas?.getObjects().forEach((obj) => { if (obj.name === POLYGON_TYPE.ROOF) { obj.set({ stroke: 'black', @@ -1282,13 +1282,35 @@ export function useModuleBasicSetting(tabNum) { ? trestlePolygon.trestleDetail.moduleMaxRows : trestlePolygon.trestleDetail.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 - const sumColCount = layoutSetupRef.reduce((acc, cur) => acc + cur.col, 0) //입력한 행의 합 + //단수 합단수 const sumRowCount = isMultipleModules ? layoutSetupRef.reduce((acc, cur) => acc + cur.row, 0) : layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 - if (sumRowCount > maxRow || sumColCount > maxCol) { - swalFire({ text: getMessage('module.layout.setup.max.count', [maxRow, maxCol]) }) + // + const sumColCount = layoutSetupRef.filter((item) => item.col).some((item) => item.col > maxCol) + + if (sumRowCount > maxRow || sumColCount) { + swalFire({ text: getMessage('module.layout.setup.max.count', [maxRow, maxCol]), icon: 'warning' }) + return + } + + let alertMessage = '' + let isPassed = true + if (isMultipleModules) { + layoutSetupRef.forEach((item, index) => { + const moduleInfo = trestlePolygon.trestleDetail.module[index] + if (item.row > moduleInfo.mixModuleMaxRows) { + alertMessage = getMessage('module.layout.setup.max.count.multiple', [index + 1, moduleInfo.mixModuleMaxRows, maxCol]) + isPassed = false + } + }) + } + + console.log(alertMessage) + + if (!isPassed) { + swalFire({ text: alertMessage, icon: 'warning' }) return } diff --git a/src/locales/ja.json b/src/locales/ja.json index 9ca0466a..c8d080de 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1043,5 +1043,6 @@ "roof.line.not.found": "屋根形状がありません", "roof.material.can.not.delete": "割り当てられた配置面があります。", "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다. (JA)", - "chidory.can.not.install": "千鳥配置できない工法です。" + "chidory.can.not.install": "千鳥配置できない工法です。", + "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다. (JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index f61ea784..6cd3cfb6 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1043,5 +1043,6 @@ "roof.line.not.found": "지붕형상이 없습니다.", "roof.material.can.not.delete": "할당된 배치면이 있습니다.", "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.", - "chidory.can.not.install": "치조 불가 공법입니다." + "chidory.can.not.install": "치조 불가 공법입니다.", + "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다." } From 6f5b70342ddff53258190f71ffd4e2ec74bc8323 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 27 Mar 2025 14:41:29 +0900 Subject: [PATCH 043/196] =?UTF-8?q?-=20pcs=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/step/PowerConditionalSelect.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx index f8d1d530..b7e50fda 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx @@ -110,6 +110,7 @@ export default function PowerConditionalSelect(props) { selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : false, } }) + setSelectedModels([]) } setSeries(copySeries) handleSetmodels(copySeries.filter((s) => s.selected)) From de5901492b1fb85f92fb3a7afa34dfe3f56ac929 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 27 Mar 2025 15:17:42 +0900 Subject: [PATCH 044/196] =?UTF-8?q?=EA=B8=B0=EC=A1=B4=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EB=90=9C=20=EC=A7=80=EB=B6=95=EC=9E=AC=20index=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofAllocationSetting.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 6d573ff0..b5b561cb 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -308,8 +308,17 @@ export function useRoofAllocationSetting(id) { */ const handleSaveContext = () => { const newRoofList = currentRoofList.map((roof, idx) => { + if (roof.index !== idx) { + // 기존 저장된 지붕재의 index 수정 + const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && obj.roofMaterial?.index === roof.index) + roofs.forEach((roof) => { + setSurfaceShapePattern(roof, roofDisplay.column, false, { ...roof, index: idx }, true) + }) + } + return { ...roof, index: idx, raft: roof.raft ? roof.raft : roof.raftBaseCd } }) + setBasicSetting((prev) => { return { ...prev, From 2bb1b71a0bad709fdd2f4fdf871d501f84b19874 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 28 Mar 2025 09:40:19 +0900 Subject: [PATCH 045/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 84 ++++++----------------- 1 file changed, 21 insertions(+), 63 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 646c743f..a196d798 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -275,7 +275,6 @@ export function useModuleBasicSetting(tabNum) { setSurfaceShapePattern(roof, roofDisplay.column, true, roof.roofMaterial) //패턴 변경 // let offsetPoints = createPaddingPolygon(createRoofPolygon(roof.points), roof.lines).vertices //안쪽 offset let offsetPoints = null - console.log(roof, roof.getCurrentPoints()) const polygon = createRoofPolygon(roof.getCurrentPoints()) const originPolygon = new QPolygon(roof.getCurrentPoints(), { fontSize: 0 }) @@ -400,7 +399,7 @@ export function useModuleBasicSetting(tabNum) { canvas?.renderAll() selectedModuleInstSurfaceArray.push(setupSurface) - setCurrentObject({ name: 'moduleSetupSurface', arrayData: [...selectedModuleInstSurfaceArray] }) + setCurrentObject({ name: POLYGON_TYPE.MODULE_SETUP_SURFACE, arrayData: [...selectedModuleInstSurfaceArray] }) } else { //선택후 재선택하면 선택안됨으로 변경 setupSurface.set({ @@ -415,7 +414,7 @@ export function useModuleBasicSetting(tabNum) { const removeIndex = setupSurface.parentId const removeArrayIndex = selectedModuleInstSurfaceArray.findIndex((obj) => obj.parentId === removeIndex) selectedModuleInstSurfaceArray.splice(removeArrayIndex, 1) - setCurrentObject({ name: 'moduleSetupSurface', arrayData: [...selectedModuleInstSurfaceArray] }) + setCurrentObject({ name: POLYGON_TYPE.MODULE_SETUP_SURFACE, arrayData: [...selectedModuleInstSurfaceArray] }) } canvas?.renderAll() @@ -1295,22 +1294,19 @@ export function useModuleBasicSetting(tabNum) { return } - let alertMessage = '' - let isPassed = true - if (isMultipleModules) { - layoutSetupRef.forEach((item, index) => { - const moduleInfo = trestlePolygon.trestleDetail.module[index] - if (item.row > moduleInfo.mixModuleMaxRows) { - alertMessage = getMessage('module.layout.setup.max.count.multiple', [index + 1, moduleInfo.mixModuleMaxRows, maxCol]) - isPassed = false - } + // 혼합일때 모듈 개별의 row를 체크함 + const isPassedObject = + isMultipleModules && layoutSetupRef.find((item, index) => item.row > trestlePolygon.trestleDetail.module[index].mixModuleMaxRows) + + if (isPassedObject) { + swalFire({ + text: getMessage('module.layout.setup.max.count.multiple', [ + layoutSetupRef.indexOf(isPassedObject) + 1, + trestlePolygon.trestleDetail.module[layoutSetupRef.indexOf(isPassedObject)].mixModuleMaxRows, + maxCol, + ]), + icon: 'warning', }) - } - - console.log(alertMessage) - - if (!isPassed) { - swalFire({ text: alertMessage, icon: 'warning' }) return } @@ -1340,6 +1336,7 @@ export function useModuleBasicSetting(tabNum) { //그려진 가이드 라인의 포인트를 기준으로 시작점을 만든다 //남쪽에 처마방향이나 북쪽에 용마루면 + //tempModule에 좌,하 좌표를 기준으로 우측으로 위로 그림 if ((flowDirection === 'south' && setupLocation === 'eaves') || (flowDirection === 'north' && setupLocation === 'ridge')) { //남 startX = toFixedWithoutRounding(tempModule.left, 1) @@ -1438,6 +1435,7 @@ export function useModuleBasicSetting(tabNum) { } } //북쪽에 처마거나 남쪽에 용마루일경우 + //tempModule에 우,상 좌표를 기준으로 좌측으로 아래로 그림 } else if ((flowDirection === 'north' && setupLocation === 'eaves') || (flowDirection === 'south' && setupLocation === 'ridge')) { //북북 startX = toFixedWithoutRounding(tempModule.left + tempModule.width, 1) @@ -1531,6 +1529,7 @@ export function useModuleBasicSetting(tabNum) { } } //서쪽에 처마 또는 동쪽의 용마루일경우 + //tempModule에 좌,상 좌표를 기준으로 아래로 좌측으로 그림 } else if ((flowDirection === 'west' && setupLocation === 'eaves') || (flowDirection === 'east' && setupLocation === 'ridge')) { startX = toFixedWithoutRounding(tempModule.left, 1) startY = toFixedWithoutRounding(tempModule.top, 1) @@ -1623,6 +1622,7 @@ export function useModuleBasicSetting(tabNum) { } } //동쪽의 처마 또는 서쪽의 용마루일경우 + //tempModule에 우,하 좌표를 기준으로 위로 우측으로 그림 } else if ((flowDirection === 'east' && setupLocation === 'eaves') || (flowDirection === 'west' && setupLocation === 'ridge')) { startX = toFixedWithoutRounding(tempModule.left + width, 1) startY = toFixedWithoutRounding(tempModule.top + height, 1) @@ -1715,6 +1715,7 @@ export function useModuleBasicSetting(tabNum) { } } }) + //그림자가 있다면 무조건 그림자를 가장 앞으로 올림 const shadowObj = canvas?.getObjects().find((obj) => obj.name === BATCH_TYPE.SHADOW) if (shadowObj) { shadowObj.bringToFront() @@ -1751,7 +1752,6 @@ export function useModuleBasicSetting(tabNum) { const isChidori = moduleSetupOption.isChidori const setupLocation = moduleSetupOption.setupLocation const isMaxSetup = false - // const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false const moduleSetupSurfaces = moduleSetupSurface //선택 설치면 const notSelectedTrestlePolygons = canvas @@ -1767,24 +1767,11 @@ export function useModuleBasicSetting(tabNum) { //어짜피 자동으로 누르면 선택안된데도 다 날아간다 canvas.getObjects().forEach((obj) => { - if (obj.name === 'module') { + if (obj.name === POLYGON_TYPE.MODULE) { canvas.remove(obj) } }) - // if (moduleIsSetup.length > 0) { - // swalFire({ text: 'alert 아이콘 테스트입니다.', icon: 'error' }) - // } - - // moduleSetupSurfaces.forEach((obj) => { - // if (obj.modules) { - // obj.modules.forEach((module) => { - // canvas?.remove(module) - // }) - // obj.modules = [] - // } - // }) - notSelectedTrestlePolygons.forEach((obj) => { if (obj.modules) { obj.modules.forEach((module) => { @@ -1803,7 +1790,7 @@ export function useModuleBasicSetting(tabNum) { lockRotation: true, // 회전 잠금 lockScalingX: true, // X 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금 - name: 'module', + name: POLYGON_TYPE.MODULE, } //선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환 @@ -2437,37 +2424,8 @@ export function useModuleBasicSetting(tabNum) { if (moduleSetupSurface.direction === 'north') { downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) } - } else if (setupLocation === 'center') { - //중가면 - if (moduleSetupSurface.direction === 'south') { - downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true, intvHor, intvVer) - } - if (moduleSetupSurface.direction === 'west') { - leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true, intvHor, intvVer) - } - if (moduleSetupSurface.direction === 'east') { - rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true, intvHor, intvVer) - } - if (moduleSetupSurface.direction === 'north') { - topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, true, intvHor, intvVer) - } } - // const setupedModules = moduleSetupArray.filter((module, index) => { - // let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface) - // let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects) - - // if (!(disjointFromTrestle && isDisjoint)) { - // canvas?.remove(module) - // // module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) - // return false - // } else { - // return module - // } - // }) - - // canvas?.renderAll() - //나간애들 제외하고 설치된 애들로 겹친애들 삭제 하기 moduleSetupArray.forEach((module, index) => { if (isMaxSetup && index > 0) { From c8f70e074639bf3fc298918c94121255c733a6c4 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 28 Mar 2025 10:58:34 +0900 Subject: [PATCH 046/196] =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 5 ++++- src/locales/ko.json | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 3bbc5344..b6d6ce50 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1041,5 +1041,8 @@ "wall.line.not.found": "外壁がありません", "roof.line.not.found": "屋根形状がありません", "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.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다. (JA)", + "roofAllocation.not.found": "할당할 지붕이 없습니다. (JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index f7dca490..39d48c9e 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1041,5 +1041,8 @@ "wall.line.not.found": "외벽선이 없습니다.", "roof.line.not.found": "지붕형상이 없습니다.", "roof.material.can.not.delete": "할당된 배치면이 있습니다.", - "chidory.can.not.install" : "치조 불가 공법입니다." + "chidory.can.not.install": "치조 불가 공법입니다.", + "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.", + "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다.", + "roofAllocation.not.found": "할당할 지붕이 없습니다." } From 11f69a01bb0512467af672c37e28394b92ef67c8 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 28 Mar 2025 11:15:12 +0900 Subject: [PATCH 047/196] =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roofcover/useRoofAllocationSetting.js | 65 ++++--------------- 1 file changed, 13 insertions(+), 52 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index b5b561cb..bc4d246a 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -71,30 +71,19 @@ export function useRoofAllocationSetting(id) { roof.innerLines.forEach((line) => { /** 실측값이 없는 경우 라인 두께 4로 설정 */ if (!line.attributes.actualSize || line.attributes?.actualSize === 0) { - line.set({ - strokeWidth: 4, - stroke: 'black', - selectable: true, - }) + line.set({ strokeWidth: 4, stroke: 'black', selectable: true }) } /** 현재 선택된 라인인 경우 라인 두께 2로 설정 */ if (editingLines.includes(line)) { - line.set({ - strokeWidth: 2, - stroke: 'black', - selectable: true, - }) + line.set({ strokeWidth: 2, stroke: 'black', selectable: true }) } }) }) /** 현재 선택된 객체가 보조라인, 피라미드, 힙인 경우 두께 4로 설정 */ if (currentObject && currentObject.name && ['auxiliaryLine', 'ridge', 'hip'].includes(currentObject.name)) { - currentObject.set({ - strokeWidth: 4, - stroke: '#EA10AC', - }) + currentObject.set({ strokeWidth: 4, stroke: '#EA10AC' }) } }, [currentObject]) @@ -102,7 +91,7 @@ export function useRoofAllocationSetting(id) { /** 현재 선택된 객체가 보조라인, 피라미드, 힙인 경우 두께 4로 설정 */ const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) if (roofBases.length === 0) { - swalFire({ text: '할당할 지붕이 없습니다.' }) + swalFire({ text: getMessage('roofAllocation.not.found'), icon: 'warning' }) closePopup(id) } @@ -115,9 +104,7 @@ export function useRoofAllocationSetting(id) { */ const fetchBasicSettings = async (planNo) => { try { - await get({ - url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, - }).then((res) => { + await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}` }).then((res) => { let roofsArray = {} if (res.length > 0) { @@ -187,11 +174,7 @@ export function useRoofAllocationSetting(id) { selectedRoofMaterial: selectRoofs.find((roof) => roof.selected), }) - setBasicInfo({ - planNo: '' + res[0].planNo, - roofSizeSet: '' + res[0].roofSizeSet, - roofAngleSet: '' + res[0].roofAngleSet, - }) + setBasicInfo({ planNo: '' + res[0].planNo, roofSizeSet: '' + res[0].roofSizeSet, roofAngleSet: '' + res[0].roofAngleSet }) }) } catch (error) { console.error('Data fetching error:', error) @@ -250,10 +233,7 @@ export function useRoofAllocationSetting(id) { } const originCurrentRoofList = currentRoofList.map((roof) => { - return { - ...roof, - selected: false, - } + return { ...roof, selected: false } }) originCurrentRoofList.push({ ...currentRoofMaterial, @@ -320,10 +300,7 @@ export function useRoofAllocationSetting(id) { }) setBasicSetting((prev) => { - return { - ...prev, - selectedRoofMaterial: newRoofList.find((roof) => roof.selected), - } + return { ...prev, selectedRoofMaterial: newRoofList.find((roof) => roof.selected) } }) setRoofList(newRoofList) @@ -358,11 +335,7 @@ export function useRoofAllocationSetting(id) { if (!checkInnerLines()) { apply() } else { - swalFire({ - type: 'alert', - icon: 'error', - text: getMessage('실제치수를 입력해 주세요.'), - }) + swalFire({ type: 'alert', icon: 'error', text: getMessage('실제치수를 입력해 주세요.') }) } } @@ -377,11 +350,7 @@ export function useRoofAllocationSetting(id) { if (roof.separatePolygon.length === 0) { roof.innerLines.forEach((line) => { if (!line.attributes.actualSize || line.attributes?.actualSize === 0) { - line.set({ - strokeWidth: 4, - stroke: 'black', - selectable: true, - }) + line.set({ strokeWidth: 4, stroke: 'black', selectable: true }) result = true } }) @@ -429,10 +398,7 @@ export function useRoofAllocationSetting(id) { }) setBasicSetting((prev) => { - return { - ...prev, - selectedRoofMaterial: newRoofList.find((roof) => roof.selected), - } + return { ...prev, selectedRoofMaterial: newRoofList.find((roof) => roof.selected) } }) setRoofList(newRoofList) @@ -440,9 +406,7 @@ export function useRoofAllocationSetting(id) { roofs.forEach((roof) => { if (roof.isFixed) return - roof.set({ - isFixed: true, - }) + roof.set({ isFixed: true }) /** 모양 패턴 설정 */ setSurfaceShapePattern( @@ -479,10 +443,7 @@ export function useRoofAllocationSetting(id) { if (id === line.id) { setEditingLines([...editingLines.filter((editLine) => editLine.id !== line.id), line]) line.attributes.actualSize = size - line.set({ - strokeWidth: 2, - stroke: 'black', - }) + line.set({ strokeWidth: 2, stroke: 'black' }) } }) }) From 46f90aff1fb9425868a8cc9393e2223ce9a4cd8c Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 28 Mar 2025 12:27:59 +0900 Subject: [PATCH 048/196] =?UTF-8?q?HANASYS=20=EA=B0=9C=EC=84=A0=EA=B1=B4?= =?UTF-8?q?=20#947?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 40 ++++++++--------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 9f9dfdbf..7b356a42 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -1033,8 +1033,7 @@ export default function StuffDetail() { const _saleStoreId = watch('saleStoreId') // 2차 판매점명 const _otherSaleStoreId = watch('otherSaleStoreId') - // zipNo: '', //우편번호 - const _zipNo = watch('zipNo') + // zipNo: '', //우편번호 필수값제거 #947 // prefId: '', //도도부현 const _prefId = watch('prefId') // address: '', //주소 @@ -1071,10 +1070,6 @@ export default function StuffDetail() { } } - if (!formData.zipNo) { - errors.zipNo = true - } - if (!formData.prefId) { errors.prefId = true } @@ -1115,10 +1110,6 @@ export default function StuffDetail() { } } - if (!formData.zipNo) { - errors.zipNo = true - } - if (!formData.prefId || formData.prefId === '0') { errors.prefId = true } @@ -1144,7 +1135,6 @@ export default function StuffDetail() { _objectName, _saleStoreId, _otherSaleStoreId, - _zipNo, _prefId, _address, _areaId, @@ -1189,6 +1179,14 @@ export default function StuffDetail() { } }, [prefValue]) + // 도도부현 /주소 disabled제거 변경 + const onChangePrefCode = (e) => { + setPrefValue(e.prefId) + + form.setValue('prefId', e.prefId) + form.setValue('prefName', e.prefName) + } + // 발전량 시뮬레이션 변경 const handleAreaIdOnChange = (e) => { form.setValue('areaId', e.areaId) @@ -1243,12 +1241,6 @@ export default function StuffDetail() { errors = fieldNm } - //우편번호 - if (!formData.zipNo) { - fieldNm = getMessage('stuff.detail.zipNo') - errors = fieldNm - } - //1차판매점명 if (!formData.saleStoreId) { fieldNm = getMessage('stuff.detail.saleStoreId') @@ -1558,7 +1550,7 @@ export default function StuffDetail() { type: 'alert', icon: 'error', }) - console.log('error::::::', error) + console.error('error::::::', error) }) } } @@ -2004,9 +1996,7 @@ export default function StuffDetail() { - - {getMessage('stuff.detail.zipNo')} * - + {getMessage('stuff.detail.zipNo')}
@@ -2038,10 +2028,10 @@ export default function StuffDetail() { getOptionLabel={(x) => x.prefName} getOptionValue={(x) => x.prefId} isSearchable={false} + onChange={onChangePrefCode} value={prefCodeList.filter(function (option) { return option.prefId === prefValue })} - isDisabled={true} /> )}
@@ -2571,9 +2561,7 @@ export default function StuffDetail() { - - {getMessage('stuff.detail.zipNo')} * - + {getMessage('stuff.detail.zipNo')}
@@ -2606,10 +2594,10 @@ export default function StuffDetail() { getOptionLabel={(x) => x.prefName} getOptionValue={(x) => x.prefId} isSearchable={false} + onChange={onChangePrefCode} value={prefCodeList.filter(function (option) { return option.prefId === prefValue })} - isDisabled={true} /> )}
From 25957a37e175b14aaa874f27843015b0458a5c3f Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 28 Mar 2025 12:37:54 +0900 Subject: [PATCH 049/196] =?UTF-8?q?HANASYS=20=EA=B0=9C=EC=84=A0=EA=B1=B4?= =?UTF-8?q?=20#950?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index b6d6ce50..82918191 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -999,7 +999,7 @@ "simulator.table.sub5": "枚数", "simulator.table.sub6": "合計", "simulator.table.sub7": "パワーコンディショナー", - "simulator.table.sub8": "ティーン", + "simulator.table.sub8": "台", "simulator.table.sub9": "予測発電量(kWh)", "simulator.notice.sub1": "ハンファジャパン年間発電量", "simulator.notice.sub2": "シミュレーションガイド", From 24ba8bfb14a1a0a24194f0dd919b5b3cc2d8ca01 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 28 Mar 2025 13:27:23 +0900 Subject: [PATCH 050/196] =?UTF-8?q?#944=20=EB=AC=BC=EA=B1=B4=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=83=9D=EC=84=B1=EC=8B=9C=20=EC=8B=9C=EC=9E=91?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20R->S=20=EB=B3=80=EA=B2=BD=EC=97=90?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=A3=BC=EC=84=9D=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/Stuff.jsx | 2 +- src/components/management/StuffDetail.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index c1835874..83bc71ce 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -203,7 +203,7 @@ export default function Stuff() { if (event.column.colId === 'objectNo') { return } else { - //T 면 임시 R은 진짜 + //T 면 임시 S는 진짜 if (event.data.objectNo) { setIsGlobalLoading(true) if (event.data.tempFlg === '0') { diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 7b356a42..2eef9813 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -54,7 +54,7 @@ export default function StuffDetail() { const { get, promiseGet, del, promisePost, promisePut } = useAxios(globalLocaleState) //form const formInitValue = { - // 물건번호 T...(임시) R...(진짜) + // 물건번호 T...(임시) S...(진짜) planReqNo: '', //설계의뢰No receiveUser: session?.userNm, //담당자 로그인사용자명 디폴트 objectStatusId: '0', //물건구분(신축:0 기축 : 1) From 3fd81e771d59805e02144c1a2f338bd8ffa97bc8 Mon Sep 17 00:00:00 2001 From: ysCha Date: Fri, 28 Mar 2025 15:13:05 +0900 Subject: [PATCH 051/196] =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EB=93=9C=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EA=B2=BD=EA=B3=84=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_grid-detail.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/styles/_grid-detail.scss b/src/styles/_grid-detail.scss index b0c88984..5f27bd18 100644 --- a/src/styles/_grid-detail.scss +++ b/src/styles/_grid-detail.scss @@ -24,6 +24,10 @@ .ag-header-cell{ font-size: 13px; color: #fff; + border-right: 1px solid #738596; + &:last-child{ + border: none; + } } .ag-header-cell-label{ justify-content: center; From c88a07a22788b88f4c291a05149db115063c059e Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 28 Mar 2025 15:25:03 +0900 Subject: [PATCH 052/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=82=A8=EC=AA=BD?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EC=B9=98=EC=A1=B0=EC=8B=9C=20=EC=A2=8C?= =?UTF-8?q?=EC=B8=A1=EC=9C=BC=EB=A1=9C=20=EB=B6=99=EB=8A=94=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Placement.jsx | 2 + src/hooks/module/useModuleBasicSetting.js | 83 ++++--------------- 2 files changed, 17 insertions(+), 68 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index d4b979c7..80672471 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -37,6 +37,8 @@ const Placement = forwardRef((props, refs) => { } return () => { + refs.isChidori.current = 'false' + refs.setupLocation.current = 'eaves' setIsManualModuleSetup(false) } }, []) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 8ac88a31..69f790e8 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -2,10 +2,10 @@ import { useState } from 'react' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { canvasSettingState, canvasState, checkedModuleState, currentObjectState, isManualModuleSetupState } from '@/store/canvasAtom' import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon, toFixedWithoutRounding } from '@/util/canvas-util' -import { basicSettingState, roofDisplaySelector } from '@/store/settingAtom' +import { roofDisplaySelector } from '@/store/settingAtom' import offsetPolygon, { calculateAngle, createLinesFromPolygon } from '@/util/qpolygon-utils' import { QPolygon } from '@/components/fabric/QPolygon' -import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom' +import { moduleSetupSurfaceState } from '@/store/canvasAtom' import { useEvent } from '@/hooks/useEvent' import { POLYGON_TYPE, BATCH_TYPE, LINE_TYPE } from '@/common/common' import * as turf from '@turf/turf' @@ -15,7 +15,6 @@ import { QLine } from '@/components/fabric/QLine' import { useRoofFn } from '@/hooks/common/useRoofFn' import { useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' -import { moduleStatisticsState } from '@/store/circuitTrestleAtom' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { useMasterController } from '@/hooks/common/useMasterController' import { v4 as uuidv4 } from 'uuid' @@ -30,12 +29,10 @@ export function useModuleBasicSetting(tabNum) { const [moduleSetupSurface, setModuleSetupSurface] = useRecoilState(moduleSetupSurfaceState) const { addCanvasMouseEventListener, initEvent, removeMouseEvent, addTargetMouseEventListener } = useEvent() const { swalFire } = useSwal() - const compasDeg = useRecoilValue(compasDegAtom) const { setSurfaceShapePattern } = useRoofFn() const checkedModule = useRecoilValue(checkedModuleState) const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) - const setModuleStatistics = useSetRecoilState(moduleStatisticsState) const canvasSetting = useRecoilValue(canvasSettingState) @@ -46,19 +43,11 @@ export function useModuleBasicSetting(tabNum) { const { getTrestleDetailList } = useMasterController() const [saleStoreNorthFlg, setSaleStoreNorthFlg] = useState(false) - const [currentObject, setCurrentObject] = useRecoilState(currentObjectState) + const setCurrentObject = useSetRecoilState(currentObjectState) const { setModuleStatisticsData } = useCircuitTrestle() const { createRoofPolygon, createMarginPolygon, createPaddingPolygon } = useMode() useEffect(() => { - // console.log('basicSetting', basicSetting) - - if (canvas) { - //드래그 여부 - // canvas.selection = true - // canvas.selectionFullyContained = true - } - return () => { //수동 설치시 초기화 removeMouseEvent('mouse:up') @@ -67,8 +56,6 @@ export function useModuleBasicSetting(tabNum) { } }, []) - // const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) - //모듈 선택에서 선택된 값들 넘어옴 const makeModuleInitArea = () => { if (isObjectNotEmpty(moduleSelectionData) && tabNum === 3) { @@ -144,10 +131,7 @@ export function useModuleBasicSetting(tabNum) { //roof에 상세 데이터 추가 roof.set({ trestleDetail: detail.data }) roof.lines.forEach((line) => { - line.attributes = { - ...line.attributes, - offset: getOffset(detail.data, line.attributes.type), - } + line.attributes = { ...line.attributes, offset: getOffset(detail.data, line.attributes.type) } }) //배치면 설치 영역 makeModuleInstArea(roof, detail.data) @@ -353,12 +337,7 @@ export function useModuleBasicSetting(tabNum) { } //기본 선택이랑 스트로크 굵기가 같으면 선택 안됨으로 봄 - setupSurface.set({ - ...setupSurface, - strokeWidth: 3, - strokeDashArray: [0], - fill: 'rgba(255,255,255,0.1)', - }) + setupSurface.set({ ...setupSurface, strokeWidth: 3, strokeDashArray: [0], fill: 'rgba(255,255,255,0.1)' }) canvas.discardActiveObject() // 객체의 활성 상태 해제 //중복으로 들어가는걸 방지하기 위한 코드 @@ -368,12 +347,7 @@ export function useModuleBasicSetting(tabNum) { setCurrentObject({ name: 'moduleSetupSurface', arrayData: [...selectedModuleInstSurfaceArray] }) } else { //선택후 재선택하면 선택안됨으로 변경 - setupSurface.set({ - ...setupSurface, - fill: 'rgba(255,255,255,0.1)', - strokeDashArray: [10, 4], - strokeWidth: 1, - }) + setupSurface.set({ ...setupSurface, fill: 'rgba(255,255,255,0.1)', strokeDashArray: [10, 4], strokeWidth: 1 }) canvas.discardActiveObject() // 객체의 활성 상태 해제 //폴리곤에 커스텀 인덱스를 가지고 해당 배열 인덱스를 찾아 삭제함 @@ -424,8 +398,6 @@ export function useModuleBasicSetting(tabNum) { * 확인 후 셀을 이동시킴 */ const manualModuleSetup = (placementRef) => { - console.log('isManualModuleSetup', isManualModuleSetup) - const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 if (isManualModuleSetup) { @@ -444,10 +416,7 @@ export function useModuleBasicSetting(tabNum) { const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체 //수동모드 모듈 설치면 선택 잠금 moduleSetupSurfaces.forEach((obj) => { - obj.set({ - selectable: false, - evented: false, - }) + obj.set({ selectable: false, evented: false }) }) //모듈 기본 옵션 @@ -836,10 +805,7 @@ export function useModuleBasicSetting(tabNum) { if (moduleSetupSurfaces) { //수동모드 해제시 모듈 설치면 선택 잠금 moduleSetupSurfaces.forEach((obj) => { - obj.set({ - selectable: true, - evented: true, - }) + obj.set({ selectable: true, evented: true }) }) } @@ -1027,7 +993,7 @@ export function useModuleBasicSetting(tabNum) { //근데 양변이 곡선이면 중앙에 맞추기 위해 아래와 위의 길이를 재서 모듈의 길이를 나눠서 들어갈수 있는 갯수가 동일하면 가운데로 정렬 시킨다 if (flowLines.left.type === 'curve' && flowLines.right.type === 'curve') { - startPointX = isChidori ? flowLines.left.x1 + 1 : flowLines.left.x1 + (calcAreaWidth - totalModuleWidthCount * width) / 2 + startPointX = flowLines.left.x1 + (calcAreaWidth - totalModuleWidthCount * width) / 2 } let heightMargin = 0 @@ -1056,7 +1022,7 @@ export function useModuleBasicSetting(tabNum) { let moduleX = startPointX + width * j + 1 //5정도 마진을 준다 widthMargin = j === 0 ? 0 : intvHor * j // 가로 마진값 chidoriLength = 0 //치도리가 아니여도 기본값을 5정도 준다 - if (isChidori && !isMaxSetup) { + if (isChidori) { chidoriLength = installedModuleHeightCount % 2 == 0 ? 0 : width / 2 - intvHor } @@ -1728,11 +1694,7 @@ export function useModuleBasicSetting(tabNum) { const pointY2 = top //디버깅 - const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - }) + const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { stroke: 'red', strokeWidth: 1, selectable: true }) // console.log(`index ${index} : finalLine`, pointX1, pointY1, pointX2, pointY2) @@ -1854,11 +1816,7 @@ export function useModuleBasicSetting(tabNum) { const pointY2 = coords[2].y + ((coords[2].x - top) / (coords[2].x - coords[1].x)) * (coords[1].y - coords[2].y) //디버깅용 - const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - }) + const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { stroke: 'red', strokeWidth: 1, selectable: true }) // canvas?.add(finalLine) // canvas?.renderAll() @@ -1940,12 +1898,7 @@ export function useModuleBasicSetting(tabNum) { { x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스 ) - const obj = { - left: leftFlow, - right: rightFlow, - top: topFlow, - bottom: bottomFlow, - } + const obj = { left: leftFlow, right: rightFlow, top: topFlow, bottom: bottomFlow } return obj } @@ -2240,10 +2193,7 @@ export function useModuleBasicSetting(tabNum) { const rectPoints = [ { x: tempModule.left, y: tempModule.top }, { x: tempModule.left + tempModule.width * tempModule.scaleX, y: tempModule.top }, - { - x: tempModule.left + tempModule.width * tempModule.scaleX, - y: tempModule.top + tempModule.height * tempModule.scaleY, - }, + { x: tempModule.left + tempModule.width * tempModule.scaleX, y: tempModule.top + tempModule.height * tempModule.scaleY }, { x: tempModule.left, y: tempModule.top + tempModule.height * tempModule.scaleY }, ] @@ -2298,10 +2248,7 @@ export function useModuleBasicSetting(tabNum) { if (moduleSetupSurfaces) { //수동모드 해제시 모듈 설치면 선택 잠금 moduleSetupSurfaces.forEach((obj) => { - obj.set({ - selectable: true, - evented: true, - }) + obj.set({ selectable: true, evented: true }) }) } From 3509e5fbb672c1b45124bf11c995f8c403dc8a83 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 28 Mar 2025 17:13:46 +0900 Subject: [PATCH 053/196] Update startscript to run development server on port 5000 --- startscript.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/startscript.js b/startscript.js index 890c30f8..e276be78 100644 --- a/startscript.js +++ b/startscript.js @@ -1,2 +1,2 @@ var exec = require('child_process').exec -exec('yarn dev', { windowsHide: true }) +exec('yarn dev -p 5000', { windowsHide: true }) From 482b6b54777142e39c4d753ca06b9acdf81b0d57 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 31 Mar 2025 10:20:45 +0900 Subject: [PATCH 054/196] =?UTF-8?q?=EC=88=98=EB=8F=99=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=ED=98=BC=ED=95=A9=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 15 +++++++++++++-- src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index a196d798..8065df04 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -457,9 +457,8 @@ export function useModuleBasicSetting(tabNum) { * trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 로 진입여부를 확인 * 확인 후 셀을 이동시킴 */ - const manualModuleSetup = (placementRef) => { + const manualModuleSetup = () => { //레이아웃 수동설치 토글 - const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 const isChidori = moduleSetupOption.isChidori @@ -800,6 +799,18 @@ export function useModuleBasicSetting(tabNum) { addCanvasMouseEventListener('mouse:up', (e) => { let isIntersection = true + + // 혼합 설치 불가능한 모듈인지 확인 Y는 Y끼리 N은 N끼리만 설치 가능 + if (trestlePolygon.modules.length > 0) { + //이미 설치된 모듈중에 한개만 가져옴 + const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn + //현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능 + if (checkedModule[0].mixAsgYn !== mixAsgYn) { + swalFire({ text: getMessage('module.place.mix.asg.yn.error') }) + return + } + } + if (!inside) return if (tempModule) { const rectPoints = [ diff --git a/src/locales/ja.json b/src/locales/ja.json index c8d080de..718aeb8e 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1044,5 +1044,6 @@ "roof.material.can.not.delete": "割り当てられた配置面があります。", "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다. (JA)", "chidory.can.not.install": "千鳥配置できない工法です。", - "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다. (JA)" + "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다. (JA)", + "module.place.mix.asg.yn.error": "혼합 설치가 불가능합니다. (JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 6cd3cfb6..9ff2ecec 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1044,5 +1044,6 @@ "roof.material.can.not.delete": "할당된 배치면이 있습니다.", "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.", "chidory.can.not.install": "치조 불가 공법입니다.", - "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다." + "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다.", + "module.place.mix.asg.yn.error": "혼합 설치가 불가능합니다." } From 826739fb0ea539a86f39fe8c9db3fda199c97c8a Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 31 Mar 2025 10:44:56 +0900 Subject: [PATCH 055/196] =?UTF-8?q?=ED=98=BC=ED=95=A9=20=EA=B0=80=EB=8A=A5?= =?UTF-8?q?=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20validate=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 8065df04..d9b573c5 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1760,6 +1760,16 @@ export function useModuleBasicSetting(tabNum) { return } + //혼합 가능 모듈과 혼합 불가능 모듈을 선택했을때 카운트를 해서 확인 + const mixAsgY = checkedModule.filter((obj) => obj.mixAsgYn === 'Y') + const mixAsgN = checkedModule.filter((obj) => obj.mixAsgYn === 'N') + + //Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가 + if (mixAsgY.length > 0 && mixAsgN.length > 0) { + swalFire({ text: getMessage('module.place.mix.asg.yn.error') }) + return + } + const isChidori = moduleSetupOption.isChidori const setupLocation = moduleSetupOption.setupLocation const isMaxSetup = false From d10642d6d5b710a1b7f94e88d549a746996b6420 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 31 Mar 2025 13:50:06 +0900 Subject: [PATCH 056/196] =?UTF-8?q?=EB=A9=94=EB=89=B4=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=95=88=EC=93=B0=EB=8A=94=20=EB=82=B4=EC=9A=A9=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useCanvasMenu.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hooks/common/useCanvasMenu.js b/src/hooks/common/useCanvasMenu.js index f90881d3..1aaaee23 100644 --- a/src/hooks/common/useCanvasMenu.js +++ b/src/hooks/common/useCanvasMenu.js @@ -7,8 +7,6 @@ import { POLYGON_TYPE } from '@/common/common' export const useCanvasMenu = () => { const [selectedMenu, setSelectedMenu] = useRecoilState(selectedMenuState) - const canvas = useRecoilValue(canvasState) - const { drawDirectionArrow } = usePolygon() return { selectedMenu, From be54df76f7940efc34955ff8023e8d22f5ce8f1a Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 1 Apr 2025 13:19:12 +0900 Subject: [PATCH 057/196] =?UTF-8?q?=ED=86=B5=ED=95=A9=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8(Integration=20Test)=20#956=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/module/PanelEdit.jsx | 7 ++++++- src/hooks/module/useModule.js | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/module/PanelEdit.jsx b/src/components/floor-plan/modal/module/PanelEdit.jsx index 2a06e062..5e8b5a61 100644 --- a/src/components/floor-plan/modal/module/PanelEdit.jsx +++ b/src/components/floor-plan/modal/module/PanelEdit.jsx @@ -38,6 +38,11 @@ export default function PanelEdit(props) { const isSetupModules = canvas.getObjects().filter((obj) => obj.name === 'module') // selectedObj에 없는 객체만 필터링 isSetupModules.forEach((obj) => obj.set({ lockMovementX: false, lockMovementY: false })) } + + //팝업 닫을때 선택 해제 + return () => { + canvas?.discardActiveObject() //선택해제 + } }, []) //모듈 이동 적용 @@ -87,7 +92,7 @@ export default function PanelEdit(props) { moduleMultiCopy('row', length, direction) break } - closePopup(id) + // closePopup(id) } return ( diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 51cffd65..db4762b1 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -54,7 +54,7 @@ export function useModule() { }) return } - canvas.discardActiveObject() //선택해제 + // canvas.discardActiveObject() //선택해제 const isSetupModules = getOtherModules(selectedObj) const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴 From 7d37deb048c1b88047b3786a943359dd7a2c46ca Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 1 Apr 2025 15:31:12 +0900 Subject: [PATCH 058/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 2 +- .../floor-plan/modal/basic/step/Placement.jsx | 295 +++++++++++------- src/hooks/module/useModuleBasicSetting.js | 15 +- src/locales/ja.json | 11 +- src/locales/ko.json | 7 +- 5 files changed, 210 insertions(+), 120 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 7edbb05e..ae99c73b 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -172,7 +172,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { }, [checkedModules]) return ( - + handleClosePopup(id)} />
diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index ab1782bf..16c06ab2 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -8,12 +8,13 @@ import { moduleSetupOptionState, toggleManualSetupModeState, } from '@/store/canvasAtom' -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' const Placement = forwardRef((props, refs) => { const { getMessage } = useMessage() + const [useTab, setUseTab] = useState(true) const [isChidoriNotAble, setIsChidoriNotAble] = useState(false) @@ -22,7 +23,7 @@ const Placement = forwardRef((props, refs) => { const setCheckedModules = useSetRecoilState(checkedModuleState) const moduleSelectionData = useRecoilValue(moduleSelectionDataState) - const { makeModuleInitArea } = useModuleBasicSetting(3) + const { makeModuleInitArea, roofOutlineColor } = useModuleBasicSetting(3) const [isMultiModule, setIsMultiModule] = useState(false) @@ -32,6 +33,9 @@ const Placement = forwardRef((props, refs) => { const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) const [moduleSetupOption, setModuleSetupOption] = useRecoilState(moduleSetupOptionState) //모듈 설치 옵션 + const resetModuleSetupOption = useResetRecoilState(moduleSetupOptionState) + + const [colspan, setColspan] = useState(1) //모듈 배치면 생성 useEffect(() => { @@ -44,17 +48,24 @@ const Placement = forwardRef((props, refs) => { makeModuleInitArea(moduleSelectionData) } + if (moduleSelectionData.module.itemList.length > 1) { + setColspan(2) + } + return () => { - refs.isChidori.current = 'false' - refs.setupLocation.current = 'eaves' + // refs.isChidori.current = 'false' + // refs.setupLocation.current = 'eaves' setIsManualModuleSetup(false) setIsManualModuleLayoutSetup(false) setManualSetupMode('off') + resetModuleSetupOption() } }, []) //최초 지입시 체크 useEffect(() => { + console.log('moduleSelectionData', moduleSelectionData) + if (isObjectNotEmpty(moduleSelectionData)) { //두번째 선택한 데이터가를 기반으로 세번째 선택을 체크한다 if (moduleSelectionData.roofConstructions.length > 0 && moduleSelectionData.module.itemList.length > 0) { @@ -93,7 +104,9 @@ const Placement = forwardRef((props, refs) => { 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 }, + { 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: [], } @@ -130,26 +143,24 @@ const Placement = forwardRef((props, refs) => { return ( <> -
+
- - {moduleData.header.map((data) => ( - - ))} - + {moduleData.header.map((data) => ( + + ))} {selectedModules.itemList && @@ -173,106 +184,174 @@ const Placement = forwardRef((props, refs) => { {item.itemNm} - - - handleLayoutSetup(e, item.itemId, index)} - />{' '} - × - handleLayoutSetup(e, item.itemId, index)} - /> + + + ))} + + + + + + +
- {data.type === 'check' ? ( -
- - -
- ) : ( - data.name - )} -
+ {data.type === 'check' ? ( +
+ + +
+ ) : ( + data.name + )} +
{item.wpOut} +
+ {item.mixAsgYn} +
+
+
+ handleLayoutSetup(e, item.itemId, index)} + /> +
+
+
+ handleLayoutSetup(e, item.itemId, index)} + /> +
+
-
+
-
{getMessage('modal.module.basic.setting.module.placement.select.fitting.type')}
-
-
-
{getMessage('modal.module.basic.setting.module.placement.waterfowl.arrangement')}
-
-
-
- handleChangeChidori(e)} - /> - -
-
- handleChangeChidori(e)} - /> - -
-
-
-
-
-
{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}
-
-
-
- - -
-
- - -
-
-
-
-
-
- {/*
- - -
*/} +
+ + + + + + + + + + + + + +
{getMessage('modal.module.basic.setting.module.placement.waterfowl.arrangement')}{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}
+
+
+ handleChangeChidori(e)} + /> + +
+
+ handleChangeChidori(e)} + /> + +
+
+
+
+
+ + +
+
+ + +
+
+
+
+ {getMessage('modal.module.basic.setting.module.placement.max.size.check')} + +
+
+
+
+ + + + + {selectedModules && + selectedModules.itemList.map((item) => ( + + ))} + + + {selectedModules.itemList.map((item) => ( + <> + + {colspan > 1 && } + + ))} + + + + {moduleSelectionData.roofConstructions.map((item) => ( + + + {selectedModules.itemList.map((item) => ( + <> + + {colspan > 1 && } + + ))} + + ))} + +
+
+ + {item.itemNm} +
+
{getMessage('modal.module.basic.setting.module.placement.max.row')}{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}
+
+ + {item.addRoof.roofMatlNmJp} +
+
75
+
+
+
) }) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 2e490a85..417fdeea 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -114,7 +114,7 @@ export function useModuleBasicSetting(tabNum) { //육지붕 일경우에는 바로 배치면 설치LL canvas .getObjects() - .filter((roof) => roof.name === 'roof') + .filter((roof) => roof.name === POLYGON_TYPE.ROOF) .forEach((roof) => { makeModuleInstArea(roof, null) }) @@ -172,13 +172,13 @@ export function useModuleBasicSetting(tabNum) { const roofOutlineColor = (roofIndex) => { if (roofIndex === 1) { - return 'rgb(86,170,255)' + return '#FFC000' } else if (roofIndex === 2) { - return 'rgb(125, 252, 173)' + return '#7030A0' } else if (roofIndex === 3) { - return 'rgb(238, 109, 255)' + return '#385723' } else { - return 'rgb(252, 148, 106)' + return '#FFFF00' } } @@ -775,7 +775,7 @@ export function useModuleBasicSetting(tabNum) { const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn //현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능 if (checkedModule[0].mixAsgYn !== mixAsgYn) { - swalFire({ text: getMessage('module.place.mix.asg.yn.error') }) + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) return } } @@ -1732,7 +1732,7 @@ export function useModuleBasicSetting(tabNum) { //Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가 if (mixAsgY.length > 0 && mixAsgN.length > 0) { - swalFire({ text: getMessage('module.place.mix.asg.yn.error') }) + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) return } @@ -3575,5 +3575,6 @@ export function useModuleBasicSetting(tabNum) { autoFlatroofModuleSetup, checkModuleDisjointObjects, makeModuleInitArea, + roofOutlineColor, } } diff --git a/src/locales/ja.json b/src/locales/ja.json index b8195843..32bc6743 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -116,8 +116,8 @@ "modal.module.basic.setting.module.placement.do.not": "しない", "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.eaves": "軒", - "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "棟", + "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒側", + "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "棟側", "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.south": "南向き設置", @@ -1045,5 +1045,10 @@ "chidory.can.not.install": "千鳥配置できない工法です。", "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다. (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)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 6ea42c9f..d5dcbb07 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1045,5 +1045,10 @@ "chidory.can.not.install": "치조 불가 공법입니다.", "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.", "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": "혼합" } From 87ef010ae63b0ee8f99023bdb7f30fc255927782 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 1 Apr 2025 15:40:20 +0900 Subject: [PATCH 059/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EB=AC=B8=EA=B5=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/BasicSetting.jsx | 2 +- src/locales/ja.json | 1 + src/locales/ko.json | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index ae99c73b..90ef755c 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -216,7 +216,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { {getMessage('modal.module.basic.setting.passivity.placement')}
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 417fdeea..bb966f4e 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -892,8 +892,11 @@ export function useModuleBasicSetting(tabNum) { return } + //숫자 0이 하나라도 있으면 설치 불가 const hasZeroLength = checkedModule.some((item) => - layoutSetupRef.some((layoutItem) => item.itemId === layoutItem.moduleId && (layoutItem.row === 0 || layoutItem.col === 0)), + layoutSetupRef.some( + (layoutItem) => layoutItem.checked && item.itemId === layoutItem.moduleId && (layoutItem.row === 0 || layoutItem.col === 0), + ), ) if (hasZeroLength) { @@ -903,6 +906,16 @@ export function useModuleBasicSetting(tabNum) { return } + //혼합 가능 모듈과 혼합 불가능 모듈을 선택했을때 카운트를 해서 확인 + const mixAsgY = checkedModule.filter((obj) => obj.mixAsgYn === 'Y') + const mixAsgN = checkedModule.filter((obj) => obj.mixAsgYn === 'N') + + //Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가 + if (mixAsgY.length > 0 && mixAsgN.length > 0) { + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) + return + } + const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체 //수동모드 모듈 설치면 선택 잠금 moduleSetupSurfaces.forEach((obj) => { @@ -1260,7 +1273,7 @@ export function useModuleBasicSetting(tabNum) { //단수 합단수 const sumRowCount = isMultipleModules - ? layoutSetupRef.reduce((acc, cur) => acc + cur.row, 0) + ? layoutSetupRef.filter((item) => item.checked).reduce((acc, cur) => acc + cur.row, 0) : layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 // @@ -1273,7 +1286,8 @@ export function useModuleBasicSetting(tabNum) { // 혼합일때 모듈 개별의 row를 체크함 const isPassedObject = - isMultipleModules && layoutSetupRef.find((item, index) => item.row > trestlePolygon.trestleDetail.module[index].mixModuleMaxRows) + isMultipleModules && + layoutSetupRef.find((item, index) => item.checked && item.row > trestlePolygon.trestleDetail.module[index].mixModuleMaxRows) if (isPassedObject) { swalFire({ diff --git a/src/locales/ja.json b/src/locales/ja.json index 96dc0dde..509e0d62 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -130,7 +130,6 @@ "modal.module.basic.setting.pitch.module.column.margin": "左右間隔", "modal.module.basic.setting.prev": "前に戻る", "modal.module.basic.setting.passivity.placement": "手動配置", - "modal.module.basic.setting.layoutpassivity.placement": "layout配置", "modal.module.basic.setting.auto.placement": "設定値に自動配置", "plan.menu.module.circuit.setting.circuit.trestle.setting": "回路設定", "modal.circuit.trestle.setting": "回路設定", @@ -1051,5 +1050,6 @@ "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.module.placement.mix.asg.yn": "ミックス. (JA)", + "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 4df83b2b..127da1bc 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -130,7 +130,6 @@ "modal.module.basic.setting.pitch.module.column.margin": "좌우간격", "modal.module.basic.setting.prev": "이전", "modal.module.basic.setting.passivity.placement": "수동 배치", - "modal.module.basic.setting.layoutpassivity.placement": "레이아웃 배치", "modal.module.basic.setting.auto.placement": "설정값으로 자동 배치", "plan.menu.module.circuit.setting.circuit.trestle.setting": "회로설정", "modal.circuit.trestle.setting": "회로설정", @@ -1051,5 +1050,6 @@ "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.module.placement.mix.asg.yn": "혼합", + "modal.module.basic.setting.layoutpassivity.placement": "레이아웃 배치" } From 0a5b6ce13222165a9e0b38dd00ef9422e6193a92 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 1 Apr 2025 17:59:57 +0900 Subject: [PATCH 062/196] test: deploy test --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c4033664..1840b37c 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,5 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. + +test From 655fef744c72d19a37ef3470d160b79650b7f6f3 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 2 Apr 2025 11:12:23 +0900 Subject: [PATCH 063/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCanvasEvent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js index ed24387e..1f6466f5 100644 --- a/src/hooks/useCanvasEvent.js +++ b/src/hooks/useCanvasEvent.js @@ -198,7 +198,7 @@ export function useCanvasEvent() { if (selected?.length > 0) { selected.forEach((obj) => { - if (obj.type === 'QPolygon' && obj.name !== 'module') { + if (obj.type === 'QPolygon') { obj.set({ stroke: 'red' }) } }) @@ -235,7 +235,7 @@ export function useCanvasEvent() { if (selected?.length > 0) { selected.forEach((obj) => { - if (obj.type === 'QPolygon' && obj.name !== 'module') { + if (obj.type === 'QPolygon') { obj.set({ stroke: 'red' }) } }) From ced0eb9fc6d646ea98d172947405d2395b13818c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:53:24 +0900 Subject: [PATCH 064/196] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../static/images/canvas/hide-check-arr.svg | 3 + src/styles/_contents.scss | 8 ++ src/styles/_modal.scss | 91 +++++++++++++++---- src/styles/_reset.scss | 12 ++- src/styles/_table.scss | 10 ++ 5 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 public/static/images/canvas/hide-check-arr.svg diff --git a/public/static/images/canvas/hide-check-arr.svg b/public/static/images/canvas/hide-check-arr.svg new file mode 100644 index 00000000..f2a16099 --- /dev/null +++ b/public/static/images/canvas/hide-check-arr.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss index 10a04637..bfd7b1f8 100644 --- a/src/styles/_contents.scss +++ b/src/styles/_contents.scss @@ -340,6 +340,14 @@ &.active{ top: calc(92.8px + 50px); } + .canvas-id{ + display: flex; + align-items: center; + padding: 9.6px 20px; + font-size: 12px; + color: #fff; + background-color: #1083E3; + } .canvas-plane-wrap{ display: flex; align-items: center; diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index f2b6503c..fef7c2fd 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -279,10 +279,11 @@ $alert-color: #101010; border-bottom: 1px solid #424242; } } -.grid-check-form-block{ - display: block; - > div{ - margin-bottom: 10px; +.grid-check-form-flex{ + display: flex; + gap: 10px; + .d-check-box{ + flex: 1; } } .grid-option-overflow{ @@ -1313,13 +1314,13 @@ $alert-color: #101010; .circle { position: absolute; - width: 12px; - height: 12px; + width: 10px; + height: 10px; border: 1px solid #fff; border-radius: 50%; - top: 95%; + top: 88%; left: 50%; - transform-origin: 0 -90px; /* 중심에서 반지름 거리만큼 떨어져 위치 */ + transform-origin: 0 -76px; /* 중심에서 반지름 거리만큼 떨어져 위치 */ cursor:pointer; z-index: 3; /* 0번을 180도 위치(아래)에, 13번을 0도 위치(위)에 배치 */ @@ -1366,8 +1367,8 @@ $alert-color: #101010; top: 50%; left: 50%; transform: translate(-50%, -50%); - width: 5px; - height: 5px; + width: 4px; + height: 4px; background-color: #fff; border-radius: 50%; } @@ -1381,15 +1382,15 @@ $alert-color: #101010; top: 50%; left: 50%; transform: translate(-50%, -50%); - width: 148px; - height: 148px; + width: 121px; + height: 121px; border: 4px solid #fff; border-radius: 50%; .compas-arr{ width: 100%; height: 100%; background: url(../../public/static/images/canvas/compas.svg)no-repeat center; - background-size: 122px 122px; + background-size: 100px 100px; } } } @@ -1441,10 +1442,10 @@ $alert-color: #101010; .roof-module-compas{ margin-bottom: 24px; .compas-box-inner{ - width: 280px; - height: 253px; + width: 235px; + height: 215px; .circle{ - top: 86%; + top: 85%; // &:nth-child(1), // &:nth-child(7), // &:nth-child(13), @@ -1461,7 +1462,7 @@ $alert-color: #101010; // } // } i{ - top: 22px; + top: 19px; } &.act{ i{color: #8B8B8B;} @@ -1482,6 +1483,10 @@ $alert-color: #101010; .outline-form{ flex: 1; } + .non-flex{ + min-width: 300px; + flex: none; + } } .module-box-tab{ @@ -2183,14 +2188,20 @@ $alert-color: #101010; display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; - margin-bottom: 24px; + margin-bottom: 10px; } &.non-flex{ display: flex; flex-direction: column; justify-content: flex-start; flex: none; - width: 260px; + width: 340px; + } + .flex-item-button{ + margin-top: 10px; + button{ + width: 100%; + } } } } @@ -2326,7 +2337,7 @@ $alert-color: #101010; grid-template-columns: repeat(2, 1fr); .outline-form{ span{ - width: 60px; + width: 65px; &.thin{ width: 20px; } @@ -2336,6 +2347,7 @@ $alert-color: #101010; } } + .module-table-block-wrap{ .roof-module-table{ &.self{ @@ -2371,4 +2383,43 @@ $alert-color: #101010; margin-left: 10px; color: #53a7eb; font-weight: 500; +} + +.hexagonal-flex-wrap{ + display: flex; + gap: 10px; + .non-flex{ + flex: none; + } +} + +.hexagonal-radio-wrap{ + padding: 17px 10px; +} + +.hide-check-guide{ + display: flex; + align-items: center; + font-size: 12px; + color: #fff; + margin-top: 10px; + font-weight: 500; + .arr{ + width: 13px; + height: 13px; + margin-left: 10px; + background: url(../../public/static/images/canvas/hide-check-arr.svg) no-repeat center; + background-size: contain; + transform: rotate(180deg); + &.act{ + transform: rotate(0deg); + } + } +} + +.module-table-box{ + &.hide{ + overflow: hidden; + height: 0; + } } \ No newline at end of file diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss index 34dcaf33..fab3eb04 100644 --- a/src/styles/_reset.scss +++ b/src/styles/_reset.scss @@ -222,15 +222,16 @@ button{ padding: 0 10px; line-height: 28px; font-family: 'Noto Sans JP', sans-serif; - background-color: transparent; + background-color: #353535; border: 1px solid #484848; color: #fff; &.blue{ background-color: #4C6FBF; border: 1px solid #4C6FBF; &:hover{ - background-color: #414E6C; - border: 1px solid #414E6C; + background-color: #4C6FBF; + border: 1px solid #4C6FBF; + font-weight: normal; } } &.white{ @@ -241,13 +242,14 @@ button{ background-color: #fff; border: 1px solid #fff; color: #101010; + font-weight: normal; } } &:hover{ - font-weight: 400; - background-color: transparent; + background-color: #353535; border: 1px solid #484848; color: #fff; + font-weight: normal; } } &.self{ diff --git a/src/styles/_table.scss b/src/styles/_table.scss index 5efacd7c..5fe69afe 100644 --- a/src/styles/_table.scss +++ b/src/styles/_table.scss @@ -236,6 +236,16 @@ table{ .d-check-box{ opacity: 0.5; } + .color-wrap{ + display: flex; + align-items: center; + justify-content: center; + .color-box{ + width: 14px; + height: 14px; + margin-right: 8px; + } + } } } tbody{ From 8354508a2bf1e0afa06a50fcc6f887683942a85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:53:34 +0900 Subject: [PATCH 065/196] =?UTF-8?q?=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 17 +++++++++++++---- src/locales/ko.json | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index e142119b..7055cab8 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -89,13 +89,17 @@ "plan.menu.module.circuit.setting.default": "モジュール/架台設定", "modal.module.basic.setting.orientation.setting": "方位設定", "modal.module.basic.setting.orientation.setting.info": "※シミュレーション計算用方位を指定します。南の方位を設定してください。", - "modal.module.basic.setting.orientation.setting.angle.passivity": "勾配を直接入力", + "modal.module.basic.setting.orientation.setting.angle.passivity": "角度変更", "modal.module.basic.setting.module.roof.material": "屋根材", "modal.module.basic.setting.module.trestle.maker": "架台メーカー", "modal.module.basic.setting.module.rafter.margin": "垂木の間隔", "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.placement.area": "モジュール配置領域", + "modal.module.basic.setting.module.placement.area.eaves": "軒側", + "modal.module.basic.setting.module.placement.area.ridge": "棟側", + "modal.module.basic.setting.module.placement.area.keraba": "けらぱ", "modal.module.basic.setting.module.hajebichi": "ハゼピッチ", "modal.module.basic.setting.module.setting.info1": "※勾配の範囲には制限があります。屋根傾斜が2.5値未満10値を超える場合は、施工が可能かどうか施工マニュアルを確認してください。", "modal.module.basic.setting.module.setting.info2": "※モジュール配置時は、施工マニュアルに記載されている<モジュール配置条件>を必ずご確認ください。", @@ -113,12 +117,16 @@ "modal.module.basic.setting.module.placement": "モジュールの配置", "modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置", + "modal.module.basic.setting.module.placement.max.row.amount": "Max単数", + "modal.module.basic.setting.module.placement.mix.max.row.amount": "混合Max単数", + "modal.module.basic.setting.module.placement.row.amount": "単数", + "modal.module.basic.setting.module.placement.column.amount": "熱水", "modal.module.basic.setting.module.placement.do": "する", "modal.module.basic.setting.module.placement.do.not": "しない", "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.eaves": "軒", - "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "棟", + "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒の側", + "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "龍丸側", "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.south": "南向き設置", @@ -130,8 +138,9 @@ "modal.module.basic.setting.pitch.module.column.amount": "列数", "modal.module.basic.setting.pitch.module.column.margin": "左右間隔", "modal.module.basic.setting.prev": "移転", + "modal.module.basic.setting.row.batch": "単数指定配置", "modal.module.basic.setting.passivity.placement": "手動配置", - "modal.module.basic.setting.auto.placement": "設定値に自動配置", + "modal.module.basic.setting.auto.placement": "自動配置", "plan.menu.module.circuit.setting.circuit.trestle.setting": "回路設定", "modal.circuit.trestle.setting": "回路設定", "modal.circuit.trestle.setting.alloc.trestle": "架台配置", diff --git a/src/locales/ko.json b/src/locales/ko.json index 94b5e52e..93801850 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -89,13 +89,17 @@ "plan.menu.module.circuit.setting.default": "모듈/가대설정", "modal.module.basic.setting.orientation.setting": "방위 설정", "modal.module.basic.setting.orientation.setting.info": "※시뮬레이션 계산용 방위를 지정합니다. 남쪽의 방위를 설정해주세요.", - "modal.module.basic.setting.orientation.setting.angle.passivity": "각도를 직접 입력", + "modal.module.basic.setting.orientation.setting.angle.passivity": "각도 입력", "modal.module.basic.setting.module.roof.material": "지붕재", "modal.module.basic.setting.module.trestle.maker": "가대메이커", "modal.module.basic.setting.module.rafter.margin": "서까래 간격", "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.placement.area": "모듈 배치 영역", + "modal.module.basic.setting.module.placement.area.eaves": "처마쪽", + "modal.module.basic.setting.module.placement.area.ridge": "용마루쪽", + "modal.module.basic.setting.module.placement.area.keraba": "케라바쪽", "modal.module.basic.setting.module.hajebichi": "망둥어 피치", "modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.", "modal.module.basic.setting.module.setting.info2": "※ 모듈 배치 시에는 시공 매뉴얼에 기재된 <모듈 배치 조건>을 반드시 확인해주십시오.", @@ -113,12 +117,16 @@ "modal.module.basic.setting.module.placement": "모듈 배치", "modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치", + "modal.module.basic.setting.module.placement.max.row.amount": "Max 단수", + "modal.module.basic.setting.module.placement.mix.max.row.amount": "혼합Max 단수", + "modal.module.basic.setting.module.placement.row.amount": "단수", + "modal.module.basic.setting.module.placement.column.amount": "열수", "modal.module.basic.setting.module.placement.do": "한다", "modal.module.basic.setting.module.placement.do.not": "하지 않는다", "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.eaves": "처마", - "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "용마루", + "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "처마쪽", + "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "용마루쪽", "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.south": "남향설치", @@ -130,6 +138,7 @@ "modal.module.basic.setting.pitch.module.column.amount": "열수", "modal.module.basic.setting.pitch.module.column.margin": "좌우간격", "modal.module.basic.setting.prev": "이전", + "modal.module.basic.setting.row.batch": "단수지정 배치", "modal.module.basic.setting.passivity.placement": "수동 배치", "modal.module.basic.setting.auto.placement": "설정값으로 자동 배치", "plan.menu.module.circuit.setting.circuit.trestle.setting": "회로설정", From 9df16cad02ba0bce3000661cc3e12285fb97c8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:54:06 +0900 Subject: [PATCH 066/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=97=B4/?= =?UTF-8?q?=EB=8B=A8=20=EB=B2=84=ED=8D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 51cffd65..aa856a67 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -991,14 +991,14 @@ export function useModule() { const getRowModules = (target) => { return canvas .getObjects() - .filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.top === target.top) + .filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && Math.abs(obj.top - target.top) < 1) .sort((a, b) => a.left - b.left) } const getColumnModules = (target) => { return canvas .getObjects() - .filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.left === target.left) + .filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && Math.abs(obj.left - target.left) < 1) .sort((a, b) => a.top - b.top) } From 4b6f0b1b06c36eda26ca78db25d31b23575a7c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:54:44 +0900 Subject: [PATCH 067/196] =?UTF-8?q?plan=20tab=20=EC=A2=8C=EC=B8=A1=20objec?= =?UTF-8?q?tNo=20=EC=98=81=EC=97=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasLayout.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 43e4388a..059e96aa 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -31,6 +31,7 @@ export default function CanvasLayout({ children }) { return (
+
{objectNo}
{plans.map((plan, index) => ( } */} + {tabNum !== 1 && ( @@ -189,6 +318,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { )} {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( <> + diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index 4e279f04..59ff4f37 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -1,35 +1,153 @@ -import { forwardRef, useContext, useEffect, useImperativeHandle, useState } from 'react' +import { forwardRef, use, useContext, useEffect, useImperativeHandle, useState } from 'react' import { useMessage } from '@/hooks/useMessage' import { useOrientation } from '@/hooks/module/useOrientation' import { getDegreeInOrientation } from '@/util/canvas-util' import { numberCheck } from '@/util/common-utils' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' +import { addedRoofsState, basicSettingState } from '@/store/settingAtom' +import { useRecoilState, useRecoilValue } from 'recoil' +import QSelectBox from '@/components/common/select/QSelectBox' +import { moduleSelectionDataState } from '@/store/selectedModuleOptions' -export const Orientation = forwardRef(({ tabNum }, ref) => { +export const Orientation = forwardRef((props, ref) => { const { getMessage } = useMessage() - - const { trigger: canvasPopupStatusTrigger } = useCanvasPopupStatusController(1) - - const { nextStep, compasDeg, setCompasDeg } = useOrientation() - const [hasAnglePassivity, setHasAnglePassivity] = useState(false) + const basicSetting = useRecoilValue(basicSettingState) + const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //지붕재 선택 + const [roofTab, setRoofTab] = useState(0) //지붕재 탭 + const { + roofs, + setRoofs, + tabNum, + setTabNum, + compasDeg, + setCompasDeg, + moduleSelectionInitParams, + selectedModules, + roughnessCodes, + windSpeedCodes, + managementState, + setManagementState, + moduleList, + moduleSelectionData, + setModuleSelectionData, + setSelectedModules, + selectedSurfaceType, + setSelectedSurfaceType, + installHeight, + setInstallHeight, + standardWindSpeed, + setStandardWindSpeed, + verticalSnowCover, + setVerticalSnowCover, + orientationTrigger, + nextStep, + currentCanvasPlan, + loginUserState, + updateObjectDataApi, + } = props + const [inputCompasDeg, setInputCompasDeg] = useState(compasDeg ?? 0) + const [inputInstallHeight, setInputInstallHeight] = useState('0') + const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState('0') + const [inputRoughness, setInputRoughness] = useState(selectedSurfaceType) + const [inputStandardWindSpeed, setInputStandardWindSpeed] = useState(standardWindSpeed) + const moduleData = { + header: [ + { name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' }, + { + name: `${getMessage('height')} (mm)`, + prop: 'height', + }, + { name: `${getMessage('width')} (mm)`, prop: 'width' }, + { name: `${getMessage('output')} (W)`, prop: 'output' }, + ], + } + + useEffect(() => { + if (selectedSurfaceType) { + console.log(roughnessCodes, selectedSurfaceType) + setInputRoughness(roughnessCodes.find((code) => code.clCode === moduleSelectionData.common.illuminationTp)) + } + }, [selectedSurfaceType]) + + useEffect(() => { + if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === moduleSelectionData.common.stdWindSpeed)) + }, [standardWindSpeed]) + + useEffect(() => { + if (managementState?.installHeight && managementState?.installHeight) { + console.log('🚀 ~ useEffect ~ managementState:', managementState) + setSelectedSurfaceType(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue)) + setInputInstallHeight(managementState?.installHeight) + setStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId)) + setInputVerticalSnowCover(managementState?.verticalSnowCover) + } + }, [managementState]) + + useEffect(() => { + if (moduleSelectionData) { + console.log('moduleSelectionData', moduleSelectionData) + } + }, [moduleSelectionData]) useImperativeHandle(ref, () => ({ handleNextStep, })) const handleNextStep = () => { - nextStep() - canvasPopupStatusTrigger(compasDeg) + if (isComplete()) { + const common = { + illuminationTp: inputRoughness.clCode, + illuminationTpNm: inputRoughness.clCodeNm, + instHt: inputInstallHeight, + stdWindSpeed: inputStandardWindSpeed.clCode, + stdSnowLd: inputVerticalSnowCover, + saleStoreNorthFlg: managementState?.saleStoreNorthFlg, + moduleTpCd: selectedModules.itemTp, + moduleItemId: selectedModules.itemId, + } + setCompasDeg(inputCompasDeg) + setInstallHeight(inputInstallHeight) + setVerticalSnowCover(inputVerticalSnowCover) + setSelectedSurfaceType(inputRoughness) + setStandardWindSpeed(inputStandardWindSpeed) + nextStep() + setManagementState({ + ...managementState, + installHeight: inputInstallHeight, + verticalSnowCover: inputVerticalSnowCover, + standardWindSpeedId: inputStandardWindSpeed.clCode, + surfaceType: inputRoughness.clCodeNm, + surfaceTypeValue: inputRoughness.clCode, + }) + setModuleSelectionData({ + ...moduleSelectionData, + module: { + ...selectedModules, + }, + }) + orientationTrigger({ + compasDeg: inputCompasDeg, + common: common, + module: { + ...selectedModules, + }, + }) + updateObjectDataApi({ + objectNo: currentCanvasPlan.objectNo, //오브젝트_no + standardWindSpeedId: inputStandardWindSpeed.clCode, //기준풍속코드 + verticalSnowCover: inputVerticalSnowCover, //적설량 + surfaceType: inputRoughness.clCodeNm, //면조도구분 + installHeight: inputInstallHeight, //설치높이 + userId: loginUserState.userId, //작성자아아디 + }) + setTabNum(2) + } } - useEffect(() => { - checkDegree(compasDeg) - }, [compasDeg]) - const checkDegree = (e) => { if (e === '-0' || e === '-') { - setCompasDeg('-') + setInputCompasDeg('-') return } if (e === '0-') { @@ -45,71 +163,256 @@ export const Orientation = forwardRef(({ tabNum }, ref) => { } } + const isComplete = () => { + if (basicSetting && basicSetting.roofSizeSet !== '3') { + if (inputInstallHeight <= 0) { + return false + } + + if (+inputVerticalSnowCover <= 0) { + return false + } + + if (!inputStandardWindSpeed) return false + if (!inputRoughness) return false + } + + return true + } + + const handleChangeModule = (e) => { + const newRoofs = addedRoofs.map((roof) => { + return { + ...roof, + lengthBase: null, + raftBaseCd: null, + trestleMkrCd: null, + constMthdCd: null, + constTp: null, + roofBaseCd: null, + ridgeMargin: null, + kerabaMargin: null, + eavesMargin: null, + roofPchBase: null, + cvrYn: 'N', + snowGdPossYn: 'N', + cvrChecked: false, + snowGdChecked: false, + } + }) + setRoofs(newRoofs) + setSelectedModules(e) + } + return ( <>
-
{getMessage('modal.module.basic.setting.orientation.setting.info')}
-
-
-
- {Array.from({ length: 180 / 15 }).map((dot, index) => ( -
= 172 && index === 0 && compasDeg <= 180) || (compasDeg === -180 && index === 0) ? 'act' : ''}`} - onClick={() => { - if (index === 0) { - setCompasDeg(180) - return - } - setCompasDeg(-1 * (-15 * index + 180)) - }} - > - {index === 0 && 180°} - {index === 6 && -90°} +
+
+
{getMessage('modal.module.basic.setting.orientation.setting.info')}
+
+
+
+ {Array.from({ length: 180 / 15 }).map((dot, index) => ( +
= 172 && index === 0 && inputCompasDeg <= 180) || (inputCompasDeg === -180 && index === 0) ? 'act' : ''}`} + onClick={() => { + if (index === 0) { + setInputCompasDeg(180) + return + } + setInputCompasDeg(-1 * (-15 * index + 180)) + }} + > + {index === 0 && 180°} + {index === 6 && -90°} +
+ ))} + {Array.from({ length: 180 / 15 }).map((dot, index) => ( +
setInputCompasDeg(15 * index)} + > + {index === 0 && } + {index === 6 && 90°} +
+ ))} +
+
+
- ))} - {Array.from({ length: 180 / 15 }).map((dot, index) => ( -
setCompasDeg(15 * index)} - > - {index === 0 && } - {index === 6 && 90°} +
+
+
+
+
+ setHasAnglePassivity(!hasAnglePassivity)} /> +
- ))} -
-
+
+ checkDegree(e.target.value)} + /> +
+ ° + ( -180 〜 180 )
-
-
-
- setHasAnglePassivity(!hasAnglePassivity)} /> - -
-
-
- checkDegree(e.target.value) - // setCompasDeg( - - // e.target.value === '-' || (e.target.value !== '' && parseInt(e.target.value) <= 180 && parseInt(e.target.value) >= -180) - // ? e.target.value - // : 0, - // ) - } - /> +
+
+
+ {getMessage('modal.module.basic.setting.module.setting')} +
+ {moduleList && ( + handleChangeModule(e)} + /> + )} +
+
+
+ + + + {moduleData.header.map((header) => { + return ( + + ) + })} + + + + {Array.from({ length: 2 }).map((_, index) => { + return selectedModules && selectedModules?.itemList && selectedModules?.itemList?.length >= index + 1 ? ( + + + + + + + ) : ( + + + + + + + ) + })} + +
+ {header.name} +
+
+ + {selectedModules.itemList[index].itemNm} +
+
{Number(selectedModules.itemList[index].shortAxis).toFixed(0)}{Number(selectedModules.itemList[index].longAxis).toFixed(0)}{Number(selectedModules.itemList[index].wpOut).toFixed(0)}
+
+
+
+ {basicSetting && basicSetting.roofSizeSet === '3' && ( +
+ {getMessage('modal.module.basic.setting.module.placement.area')} +
+ setInputInstallHeight(e.target.value)} + /> +
+ m +
+ )}
- ° + + {basicSetting && basicSetting.roofSizeSet !== '3' && ( +
+
+
+ {getMessage('modal.module.basic.setting.module.surface.type')} +
+ {roughnessCodes.length > 0 && managementState && ( + { + console.log('🚀 ~ handleChangeModule ~ inputRoughness:', e) + setInputRoughness(e) + }} + /> + )} +
+
+
+ {getMessage('modal.module.basic.setting.module.fitting.height')} +
+ setInputInstallHeight(e.target.value)} + /> +
+ m +
+
+ {getMessage('modal.module.basic.setting.module.standard.wind.speed')} +
+ {windSpeedCodes.length > 0 && managementState && ( + { + console.log('🚀 ~ handleChangeModule ~ inputStandardWindSpeed:', e) + setInputStandardWindSpeed(e) + }} + /> + )} +
+
+
+ {getMessage('modal.module.basic.setting.module.standard.snowfall.amount')} +
+ setInputVerticalSnowCover(e.target.value)} + /> +
+ cm +
+
+
+ )}
diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx new file mode 100644 index 00000000..a6c62750 --- /dev/null +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -0,0 +1,532 @@ +import { GlobalDataContext } from '@/app/GlobalDataProvider' +import QSelectBox from '@/components/common/select/QSelectBox' +import { useModuleTrestle } from '@/hooks/module/useModuleTrestle' +import { useMessage } from '@/hooks/useMessage' +import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' +import { roofsState } from '@/store/roofAtom' +import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' +import { isObjectNotEmpty } from '@/util/common-utils' +import { forwardRef, useContext, useEffect, useImperativeHandle, useState } from 'react' +import { useRecoilState, useRecoilValue } from 'recoil' + +const Trestle = forwardRef((props, ref) => { + const { setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData } = props + const { getMessage } = useMessage() + // const [selectedTrestle, setSelectedTrestle] = useState() + const currentAngleType = useRecoilValue(currentAngleTypeSelector) + const pitchText = useRecoilValue(pitchTextSelector) + const [selectedRoof, setSelectedRoof] = useState() + const { + trestleState, + dispatch, + raftBaseList, + trestleList, + constMthdList, + roofBaseList, + constructionList, + eavesMargin, + ridgeMargin, + kerabaMargin, + setEavesMargin, + setRidgeMargin, + setKerabaMargin, + cvrYn, + cvrChecked, + snowGdPossYn, + snowGdChecked, + setCvrYn, + setCvrChecked, + setSnowGdPossYn, + setSnowGdChecked, + } = useModuleTrestle({ + selectedRoof, + }) + const selectedModules = useRecoilValue(selectedModuleState) //선택된 모듈 + // const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) + const [lengthBase, setLengthBase] = useState(0) + const [hajebichi, setHajebichi] = useState(0) + const [selectedRaftBase, setSelectedRaftBase] = useState(null) + const [selectedTrestle, setSelectedTrestle] = useState(null) + const [selectedConstMthd, setSelectedConstMthd] = useState(null) + const [selectedConstruction, setSelectedConstruction] = useState(null) + const [selectedRoofBase, setSelectedRoofBase] = useState(null) + const { managementState } = useContext(GlobalDataContext) + + useEffect(() => { + if (roofs && !selectedRoof) { + setSelectedRoof(roofs[0]) + } + }, [roofs]) + + useEffect(() => { + if (selectedRoof) { + dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, moduleTpCd: selectedModules.itemTp } }) + } + }, [selectedRoof]) + + useEffect(() => { + if (raftBaseList.length > 0) setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === trestleState?.raftBaseCd) ?? null) + }, [raftBaseList]) + + useEffect(() => { + if (trestleList.length > 0) setSelectedTrestle(trestleList.find((trestle) => trestle.trestleMkrCd === trestleState?.trestleMkrCd) ?? null) + }, [trestleList]) + + useEffect(() => { + if (roofBaseList.length > 0) setSelectedRoofBase(roofBaseList.find((roofBase) => roofBase.roofBaseCd === trestleState?.roofBaseCd) ?? null) + }, [roofBaseList]) + + useEffect(() => { + if (constMthdList.length > 0) setSelectedConstMthd(constMthdList.find((constMthd) => constMthd.constMthdCd === trestleState?.constMthdCd) ?? null) + }, [constMthdList]) + + useEffect(() => { + if (constructionList.length > 0) { + setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.constTp) ?? null) + } + }, [constructionList]) + + const getConstructionState = (index) => { + if (constructionList && constructionList.length > 0) { + if (constructionList[index].constPossYn === 'Y') { + if (trestleState && trestleState.constTp === constructionList[index].constTp) { + return 'blue' + } + return 'white' + } + return 'no-click' + } + return 'no-click' + } + + const onChangeRaftBase = (e) => { + setSelectedRaftBase(e) + dispatch({ + type: 'SET_RAFT_BASE', + roof: { + moduleTpCd: selectedModules.itemTp ?? '', + roofMatlCd: selectedRoof?.roofMatlCd ?? '', + raftBaseCd: e.clCode, + }, + }) + } + + const onChangeTrestleMaker = (e) => { + setSelectedTrestle(e) + dispatch({ + type: 'SET_TRESTLE_MAKER', + roof: { + moduleTpCd: selectedModules.itemTp ?? '', + roofMatlCd: selectedRoof?.roofMatlCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + trestleMkrCd: e.trestleMkrCd, + }, + }) + } + + const onChangeConstMthd = (e) => { + setSelectedConstMthd(e) + dispatch({ + type: 'SET_CONST_MTHD', + roof: { + moduleTpCd: selectedModules.itemTp ?? '', + roofMatlCd: selectedRoof?.roofMatlCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + trestleMkrCd: trestleState.trestleMkrCd, + constMthdCd: e.constMthdCd, + }, + }) + } + + const onChangeRoofBase = (e) => { + setSelectedRoofBase(e) + dispatch({ + type: 'SET_ROOF_BASE', + roof: { + moduleTpCd: selectedModules.itemTp ?? '', + roofMatlCd: selectedRoof?.roofMatlCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + trestleMkrCd: trestleState.trestleMkrCd, + constMthdCd: trestleState.constMthdCd, + roofBaseCd: e.roofBaseCd, + illuminationTp: managementState?.surfaceTypeValue ?? '', + instHt: managementState?.installHeight ?? '', + stdWindSpeed: managementState?.standardWindSpeedId ?? '', + stdSnowLd: managementState?.verticalSnowCover ?? '', + inclCd: selectedRoof?.pitch ?? 0, + roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), + }, + }) + } + 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) => { + if (constructionList[index]?.constPossYn === 'Y') { + dispatch({ + type: 'SET_CONSTRUCTION', + roof: { + moduleTpCd: selectedModules.itemTp ?? '', + roofMatlCd: selectedRoof?.roofMatlCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + trestleMkrCd: trestleState.trestleMkrCd, + constMthdCd: trestleState.constMthdCd, + roofBaseCd: trestleState.roofBaseCd, + illuminationTp: managementState?.surfaceTypeValue ?? '', + instHt: managementState?.installHeight ?? '', + stdWindSpeed: managementState?.standardWindSpeedId ?? '', + stdSnowLd: +managementState?.verticalSnowCover ?? '', + inclCd: selectedRoof?.pitch.toString() ?? 0, + roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), + constTp: constructionList[index].constTp, + mixMatlNo: selectedModules.mixMatlNo, + workingWidth: selectedRoof?.length.toString() ?? '', + // snowGdPossYn: constructionList[index].snowGdPossYn, + // cvrYn: constructionList[index].cvrYn, + }, + }) + + setCvrYn(constructionList[index].cvrYn) + setSnowGdPossYn(constructionList[index].snowGdPossYn) + setCvrChecked(false) + setSnowGdChecked(false) + } + } + + const isComplete = () => { + const newAddedRoofs = roofs.map((roof, i) => { + if (i === selectedRoof?.index) { + return { + ...selectedRoof, + ...trestleState, + eavesMargin, + ridgeMargin, + kerabaMargin, + cvrYn, + snowGdPossYn, + cvrChecked, + snowGdChecked, + } + } + return { ...roof } + }) + + let result = true + newAddedRoofs.forEach((roof) => { + if (roof.eavesMargin && roof.ridgeMargin && roof.kerabaMargin) { + return true + } + + if (!roof.trestleMkrCd) result = false + if (!roof.constMthdCd) result = false + if (!roof.roofBaseCd) result = false + if (!roof.constTp) result = false + + if (selectedRoof.lenAuth === 'C') { + if (!trestleState?.lengthBase) result = false + } + if (['C', 'R'].includes(selectedRoof.raftAuth)) { + if (!roof.raftBaseCd) result = false + } + + if (['C', 'R'].includes(selectedRoof.roofPchAuth)) { + if (!roof.roofPchBase) result = false + } + }) + + console.log('newAddedRoofs', newAddedRoofs) + + if (result) { + setRoofs(newAddedRoofs) + setModuleSelectionData({ + ...moduleSelectionData, + roofConstruction: { + ...newAddedRoofs, + }, + }) + trestleTrigger({ + roofConstruction: newAddedRoofs.map((roof) => { + return { + roofIndex: roof.index, + addRoof: { + ...roof, + }, + trestle: { + ...selectedTrestle, + raftBaseCd: roof.raftBaseCd, + }, + construction: { + ...constructionList.find((construction) => trestleState.constTp === construction.constTp), + roofIndex: roof.index, + setupCover: roof.cvrYn === 'Y', + setupSnowCover: roof.snowGdYn === 'Y', + selectedIndex: roof.index, + }, + } + }), + }) + } + + return result + } + + useImperativeHandle(ref, () => ({ + isComplete, + })) + + return ( +
+
+
+ {roofs && + roofs.map((roof, index) => ( + + ))} +
+
+
+
+
+ {selectedRoof && selectedRoof.lenAuth === 'C' && ( + <> +
+
L
+
+
+ setLengthBase(e.target.value)} + disabled={selectedRoof.lenAuth === 'R'} + /> +
+
+
+ + )} + {selectedRoof && ['C', 'R'].includes(selectedRoof.raftAuth) && ( + <> +
+
{getMessage('modal.module.basic.setting.module.rafter.margin')}
+
+
+ {raftBaseList.length > 0 && ( + onChangeRaftBase(e)} + /> + )} +
+
+
+ + )} + {selectedRoof && ['C', 'R'].includes(selectedRoof.roofPchAuth) && ( + <> +
+
{getMessage('modal.module.basic.setting.module.hajebichi')}
+
+
+ handleHajebichiAndLength(e, 'hajebichi')} + value={hajebichi} + /> +
+
+
+ + )} +
+
{getMessage('modal.module.basic.setting.module.trestle.maker')}
+
+
+ {trestleList && ( + onChangeTrestleMaker(e)} + /> + )} +
+
+
+
+
{getMessage('modal.module.basic.setting.module.construction.method')}
+
+
+ {constMthdList && ( + onChangeConstMthd(e)} + /> + )} +
+
+
+
+
{getMessage('modal.module.basic.setting.module.under.roof')}
+
+
+ {roofBaseList && ( + onChangeRoofBase(e)} + /> + )} +
+
+
+
+
+
+
+ + + + + +
+
+
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, cvrChecked: !trestleState.cvrChecked } })} + onChange={() => setCvrChecked(!cvrChecked)} + /> + +
+
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, snowGdChecked: !trestleState.snowGdChecked } })} + onChange={() => setSnowGdChecked(!snowGdChecked)} + /> + +
+
+
+
+ +
+
{getMessage('modal.module.basic.setting.module.placement.area')}
+
+ {getMessage('modal.module.basic.setting.module.placement.area.eaves')} +
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })} + onChange={(e) => setEavesMargin(e.target.value)} + /> +
+ mm +
+
+ {getMessage('modal.module.basic.setting.module.placement.area.ridge')} +
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })} + onChange={(e) => setRidgeMargin(e.target.value)} + /> +
+ mm +
+
+ {getMessage('modal.module.basic.setting.module.placement.area.keraba')} +
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })} + onChange={(e) => setKerabaMargin(e.target.value)} + /> +
+ mm +
+
+
+
+
+
+
+
+ {getMessage('modal.module.basic.setting.module.setting.info1')} +
+ {getMessage('modal.module.basic.setting.module.setting.info2')} +
+
+
+
+
+ ) +}) + +export default Trestle diff --git a/src/hooks/common/useCanvasPopupStatusController.js b/src/hooks/common/useCanvasPopupStatusController.js index a31bd0ed..4a6ed6dd 100644 --- a/src/hooks/common/useCanvasPopupStatusController.js +++ b/src/hooks/common/useCanvasPopupStatusController.js @@ -1,6 +1,6 @@ 'use client' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import useSWRMutation from 'swr/mutation' import { useAxios } from '../useAxios' import { unescapeString } from '@/util/common-utils' @@ -10,6 +10,8 @@ import { canvasState, currentCanvasPlanState } from '@/store/canvasAtom' import { POLYGON_TYPE } from '@/common/common' import { useCircuitTrestle } from '../useCirCuitTrestle' import { useEffect } from 'react' +import { addedRoofsState } from '@/store/settingAtom' +import { roofsState } from '@/store/roofAtom' /** * 캔버스 팝업 상태 관리 @@ -19,13 +21,14 @@ import { useEffect } from 'react' export function useCanvasPopupStatusController(param = 1) { const popupType = parseInt(param) - const [compasDeg, setCompasDeg] = useRecoilState(compasDegAtom) - const [moduleSelectionDataStore, setModuleSelectionDataStore] = useRecoilState(moduleSelectionDataState) - const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) + const setCompasDeg = useSetRecoilState(compasDegAtom) + const setModuleSelectionDataStore = useSetRecoilState(moduleSelectionDataState) + const setSelectedModules = useSetRecoilState(selectedModuleState) const { get, promiseGet, getFetcher, postFetcher } = useAxios() const canvas = useRecoilValue(canvasState) const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) - + const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) + const [roofs, setRoofs] = useRecoilState(roofsState) /** * 팝업 상태 조회 * @param {number} popupTypeParam @@ -53,19 +56,27 @@ export function useCanvasPopupStatusController(param = 1) { const handleModuleSelectionTotal = async () => { for (let i = 1; i < 3; i++) { const result = await getModuleSelection(i) - console.log('🚀 ~ handleModuleSelectionTotal ~ result:', result) if (!result.objectNo) return if (i === 1) { - setCompasDeg(result.popupStatus) + if (result.popupStatus && unescapeString(result.popupStatus)) { + const data = JSON.parse(unescapeString(result.popupStatus)) + + if (data?.compasDeg) setCompasDeg(data.compasDeg) + if (data?.module) setSelectedModules(data.module) + setModuleSelectionDataStore(data) + } } else if (i === 2) { const data = JSON.parse(unescapeString(result.popupStatus)) - setModuleSelectionDataStore(data) const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) roofSurfaceList.forEach((surface) => { surface.modules = modules.filter((module) => module.surfaceId === surface.id) }) - if (data.module) setSelectedModules(data.module) + if (data.roofConstruction) { + setRoofs(data.roofConstruction) + // setManagementState({ ...managementState, roofs: data.roofConstruction.map((roof) => roof.construction.managementState) }) + } + // if (data?.module) setManagementState(data.common.managementState) } } } @@ -80,7 +91,8 @@ export function useCanvasPopupStatusController(param = 1) { objectNo: currentCanvasPlan.objectNo, planNo: parseInt(currentCanvasPlan.planNo), popupType: popupType.toString(), - popupStatus: popupType === 1 ? arg : JSON.stringify(arg).replace(/"/g, '\"'), + // popupStatus: popupType === 1 ? arg : JSON.stringify(arg).replace(/"/g, '\"'), + popupStatus: JSON.stringify(arg).replace(/"/g, '\"'), } postFetcher(`/api/v1/canvas-popup-status`, params) }, diff --git a/src/hooks/module/useModuleSelection.js b/src/hooks/module/useModuleSelection.js index 8fa274a4..1373ea05 100644 --- a/src/hooks/module/useModuleSelection.js +++ b/src/hooks/module/useModuleSelection.js @@ -19,9 +19,9 @@ export function useModuleSelection(props) { const [moduleList, setModuleList] = useState([{}]) //모듈 목록 const [selectedSurfaceType, setSelectedSurfaceType] = useState({}) //선택된 면조도 - const [installHeight, setInstallHeight] = useState() //설치 높이 - const [standardWindSpeed, setStandardWindSpeed] = useState({}) //기준풍속 - const [verticalSnowCover, setVerticalSnowCover] = useState() //수직적설량 + const [installHeight, setInstallHeight] = useState(managementState?.installHeight) //설치 높이 + const [standardWindSpeed, setStandardWindSpeed] = useState() //기준풍속 + const [verticalSnowCover, setVerticalSnowCover] = useState(managementState?.verticalSnowCover) //수직적설량 const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈 const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등 @@ -32,6 +32,7 @@ export function useModuleSelection(props) { const { restoreModuleInstArea } = useModuleBasicSetting() const bindInitData = () => { + console.log('bindInitData', managementState) setInstallHeight(managementState?.installHeight) setStandardWindSpeed(managementState?.standardWindSpeedId) setVerticalSnowCover(managementState?.verticalSnowCover) @@ -184,14 +185,6 @@ export function useModuleSelection(props) { }) } - useEffect(() => { - // console.log('installHeight', installHeight) - }, [installHeight]) - - useEffect(() => { - // console.log('verticalSnowCover', verticalSnowCover) - }, [verticalSnowCover]) - //TODO: 설치높이, 기준적설량 debounce 적용해서 추가해야됨 // useEffect(() => { @@ -226,11 +219,17 @@ export function useModuleSelection(props) { roughnessCodes, windSpeedCodes, managementState, + setManagementState, moduleList, + setSelectedModules, selectedSurfaceType, + setSelectedSurfaceType, installHeight, + setInstallHeight, standardWindSpeed, + setStandardWindSpeed, verticalSnowCover, + setVerticalSnowCover, handleChangeModule, handleChangeSurfaceType, handleChangeWindSpeed, From fe10ecf476bde27831d927ba42a04e585513ecad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:22:15 +0900 Subject: [PATCH 069/196] PlacementShapeSetting merge --- .../modal/placementShape/PlacementShapeSetting.jsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 364526fb..9cef4f03 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -19,6 +19,7 @@ import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import { usePolygon } from '@/hooks/usePolygon' import { canvasState } from '@/store/canvasAtom' import { useRoofFn } from '@/hooks/common/useRoofFn' +import { usePlan } from '@/hooks/usePlan' /** * 지붕 레이아웃 @@ -53,7 +54,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla rafter: useRef(null), hajebichi: useRef(null), } - + const { saveCanvas } = usePlan() /** * 치수 입력방법(복시도입력/실측값입력/육지붕) */ @@ -260,8 +261,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla -
-
From d165267ec1b3b6d0fee5d4909becb0cef62c86af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:47:09 +0900 Subject: [PATCH 070/196] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_grid-detail.scss | 4 ++++ src/styles/_reset.scss | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/styles/_grid-detail.scss b/src/styles/_grid-detail.scss index b0c88984..5f27bd18 100644 --- a/src/styles/_grid-detail.scss +++ b/src/styles/_grid-detail.scss @@ -24,6 +24,10 @@ .ag-header-cell{ font-size: 13px; color: #fff; + border-right: 1px solid #738596; + &:last-child{ + border: none; + } } .ag-header-cell-label{ justify-content: center; diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss index fab3eb04..ac0d2f73 100644 --- a/src/styles/_reset.scss +++ b/src/styles/_reset.scss @@ -383,7 +383,7 @@ button{ } } &::-webkit-scrollbar { - width: 2px; + width: 5px; background-color: transparent; } From 2dbbd3a9570242ad06e7bb11db2f4b6c742ed0d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:47:21 +0900 Subject: [PATCH 071/196] =?UTF-8?q?roofAtom=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/roofAtom.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/store/roofAtom.js diff --git a/src/store/roofAtom.js b/src/store/roofAtom.js new file mode 100644 index 00000000..36f35b6c --- /dev/null +++ b/src/store/roofAtom.js @@ -0,0 +1,7 @@ +import { atom } from 'recoil' + +export const roofsState = atom({ + key: 'roofs', + default: null, + dangerouslyAllowMutability: true, +}) From ba06fde9cce184ddaf5ded280628cf40f4333234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:50:20 +0900 Subject: [PATCH 072/196] =?UTF-8?q?useModuleTrestle=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleTrestle.js | 237 +++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 src/hooks/module/useModuleTrestle.js diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js new file mode 100644 index 00000000..d0838b34 --- /dev/null +++ b/src/hooks/module/useModuleTrestle.js @@ -0,0 +1,237 @@ +import { use, useContext, useEffect, useReducer, useState } from 'react' +import { useCommonCode } from '../common/useCommonCode' +import { useMasterController } from '../common/useMasterController' +import { selectedModuleState } from '@/store/selectedModuleOptions' +import { useRecoilValue } from 'recoil' +import { GlobalDataContext } from '@/app/GlobalDataProvider' + +const RAFT_BASE_CODE = '203800' + +const trestleReducer = (state, action) => { + console.log('🚀 ~ trestleReducer ~ state:', state) + console.log('🚀 ~ trestleReducer ~ action:', action) + switch (action.type) { + case 'SET_RAFT_BASE': + case 'SET_TRESTLE_MAKER': + case 'SET_CONST_MTHD': + case 'SET_ROOF_BASE': + case 'SET_CONSTRUCTION': + case 'SET_TRESTLE_DETAIL': + return { + ...action.roof, + } + case 'SET_INITIALIZE': + console.log('SET_INITIALIZE') + return { + moduleTpCd: action.roof.moduleTpCd ?? '', + roofMatlCd: action.roof.roofMatlCd ?? '', + raftBaseCd: action.roof.raftBaseCd ?? null, + trestleMkrCd: action.roof.trestleMkrCd ?? null, + constMthdCd: action.roof.constMthdCd ?? null, + constTp: action.roof.constTp ?? null, + roofBaseCd: action.roof.roofBaseCd ?? null, + workingWidth: action.roof.workingWidth ?? 0, + lengthBase: action.roof.length ?? 0, + illuminationTp: action.roof.illuminationTp ?? null, + instHt: action.roof.instHt ?? null, + stdWindSpeed: action.roof.stdWindSpeed ?? null, + stdSnowLd: action.roof.stdSnowLd ?? null, + inclCd: action.roof.inclCd ?? null, + roofPitch: action.roof.roofPchBase ?? 0, + eavesMargin: action.roof.eavesMargin ?? null, + ridgeMargin: action.roof.ridgeMargin ?? null, + kerabaMargin: action.roof.kerabaMargin ?? null, + } + default: + return state + } +} + +export function useModuleTrestle(props) { + const { selectedRoof } = props + const { findCommonCode } = useCommonCode() + const [raftBaseList, setRaftBaseList] = useState([]) + const [trestleList, setTrestleList] = useState([]) + const [constMthdList, setConstMthdList] = useState([]) + const [roofBaseList, setRoofBaseList] = useState([]) + const [constructionList, setConstructionList] = useState([]) + const { getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController() + const [cvrYn, setCvrYn] = useState('N') + const [cvrChecked, setCvrChecked] = useState(false) + const [snowGdPossYn, setSnowGdPossYn] = useState('N') + const [snowGdChecked, setSnowGdChecked] = useState(false) + const [eavesMargin, setEavesMargin] = useState(0) + const [ridgeMargin, setRidgeMargin] = useState(0) + const [kerabaMargin, setKerabaMargin] = useState(0) + const [trestleState, dispatch] = useReducer(trestleReducer, null) + + useEffect(() => { + const raftCodeList = findCommonCode(RAFT_BASE_CODE) + + setRaftBaseList(raftCodeList) + setTrestleList([]) + setConstMthdList([]) + setRoofBaseList([]) + setConstructionList([]) + setEavesMargin(selectedRoof?.eavesMargin ?? 0) + setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) + setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) + setCvrYn(selectedRoof?.cvrYn ?? 'N') + setCvrChecked(selectedRoof?.cvrChecked ?? false) + setSnowGdPossYn(selectedRoof?.snowGdPossYn ?? 'N') + setSnowGdChecked(selectedRoof?.snowGdChecked ?? false) + }, [selectedRoof]) + + useEffect(() => { + if (trestleState) { + console.log('🚀 ~ useEffect ~ trestleState:', trestleState) + handleSetTrestleList() + if (!trestleState.trestleMkrCd) { + setConstMthdList([]) + setRoofBaseList([]) + setConstructionList([]) + return + } + + handleSetConstMthdList() + if (!trestleState.constMthdCd) { + setRoofBaseList([]) + setConstructionList([]) + return + } + + handleSetRoofBaseList() + if (!trestleState.roofBaseCd) { + setConstructionList([]) + return + } + + handleSetConstructionList() + if (!trestleState.constTp) { + return + } + + if (!trestleState.eavesMargin) { + handleSetTrestleDetailData() + } + } + }, [trestleState]) + + const handleSetTrestleList = () => { + getTrestleList({ + moduleTpCd: trestleState.moduleTpCd ?? '', + roofMatlCd: trestleState.roofMatlCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + }).then((res) => { + if (res?.data) setTrestleList(res.data) + }) + } + + const handleSetConstMthdList = () => { + getTrestleList({ + moduleTpCd: trestleState.moduleTpCd ?? '', + roofMatlCd: trestleState.roofMatlCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + trestleMkrCd: trestleState.trestleMkrCd ?? '', + }).then((res) => { + if (res?.data) setConstMthdList(res.data) + }) + } + + const handleSetRoofBaseList = () => { + getTrestleList({ + moduleTpCd: trestleState.moduleTpCd ?? '', + roofMatlCd: trestleState.roofMatlCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + trestleMkrCd: trestleState.trestleMkrCd ?? '', + constMthdCd: trestleState.constMthdCd ?? '', + }).then((res) => { + if (res?.data) setRoofBaseList(res.data) + }) + } + + const handleSetConstructionList = () => { + getConstructionList({ + moduleTpCd: trestleState.moduleTpCd ?? '', + roofMatlCd: trestleState.roofMatlCd ?? '', + trestleMkrCd: trestleState.trestleMkrCd ?? '', + constMthdCd: trestleState.constMthdCd ?? '', + roofBaseCd: trestleState.roofBaseCd ?? '', + illuminationTp: trestleState.illuminationTp ?? '', + instHt: trestleState.instHt ?? '', + stdWindSpeed: trestleState.stdWindSpeed ?? '', + stdSnowLd: trestleState.stdSnowLd ?? '', + inclCd: trestleState.inclCd ?? '', + raftBaseCd: trestleState.raftBaseCd ?? '', + roofPitch: trestleState.roofPitch ?? '', + }).then((res) => { + if (res?.data) setConstructionList(res.data) + }) + } + + const handleSetTrestleDetailData = () => { + getTrestleDetailList([ + { + moduleTpCd: trestleState.moduleTpCd ?? '', + roofMatlCd: trestleState.roofMatlCd ?? '', + trestleMkrCd: trestleState.trestleMkrCd ?? '', + constMthdCd: trestleState.constMthdCd ?? '', + roofBaseCd: trestleState.roofBaseCd ?? '', + illuminationTp: trestleState.illuminationTp ?? '', + instHt: trestleState.instHt ?? '', + stdWindSpeed: trestleState.stdWindSpeed ?? '', + stdSnowLd: trestleState.stdSnowLd ?? '', + inclCd: trestleState.inclCd ?? '', + constTp: trestleState.constTp ?? '', + mixMatlNo: trestleState.mixMatlNo ?? '', + roofPitch: trestleState.roofPitch ?? '', + workingWidth: trestleState.workingWidth ?? '', + }, + ]).then((res) => { + if (res.length > 0) { + if (!res[0].data) return + setEavesMargin(res[0].data.eaveIntvl) + setRidgeMargin(res[0].data.ridgeIntvl) + setKerabaMargin(res[0].data.kerabaIntvl) + // dispatch({ + // type: 'SET_TRESTLE_DETAIL', + // roof: { + // ...trestleState, + // eavesMargin: res[0].data.eaveIntvl, + // ridgeMargin: res[0].data.ridgeIntvl, + // kerabaMargin: res[0].data.kerabaIntvl, + // }, + // }) + } + }) + } + + return { + trestleState, + dispatch, + raftBaseList, + trestleList, + constMthdList, + roofBaseList, + constructionList, + handleSetTrestleList, + handleSetConstMthdList, + handleSetRoofBaseList, + handleSetConstructionList, + handleSetTrestleDetailData, + eavesMargin, + ridgeMargin, + kerabaMargin, + setEavesMargin, + setRidgeMargin, + setKerabaMargin, + cvrYn, + cvrChecked, + snowGdPossYn, + snowGdChecked, + setCvrYn, + setCvrChecked, + setSnowGdPossYn, + setSnowGdChecked, + } +} From d8e43b0d8191ccd9c6b66b8ce3d77ff613df663c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 15:19:00 +0900 Subject: [PATCH 073/196] =?UTF-8?q?BasicSetting=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 2 +- .../floor-plan/modal/basic/step/Trestle.jsx | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 1f19f950..240d1514 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -42,7 +42,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) const [isClosePopup, setIsClosePopup] = useState({ close: false, id: 0 }) const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState) - const [roofs, setRoofs] = useState(null) + const [roofs, setRoofs] = useState(addedRoofs) const { moduleSelectionInitParams, selectedModules, diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index a6c62750..dd5a7529 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -258,9 +258,19 @@ const Trestle = forwardRef((props, ref) => { setRoofs(newAddedRoofs) setModuleSelectionData({ ...moduleSelectionData, - roofConstruction: { - ...newAddedRoofs, - }, + roofConstructions: newAddedRoofs.map((roof) => { + return { + addRoof: { + ...roof.addRoof, + }, + trestle: { + ...roof.trestle, + }, + construction: { + ...roof.construction, + }, + } + }), }) trestleTrigger({ roofConstruction: newAddedRoofs.map((roof) => { From b7cbc3ec470ce0acb5ad1b268d26b4bfe40a2fee Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 2 Apr 2025 16:00:55 +0900 Subject: [PATCH 074/196] test: deploy test --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c4033664..3154862f 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,5 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. + +deploy test From de8ba00e55588bccc4f96c3efb1d51515339b41f Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 2 Apr 2025 16:17:52 +0900 Subject: [PATCH 075/196] chore: Update startscript to run development server on port 5000 --- startscript.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/startscript.js b/startscript.js index 37f52696..e276be78 100644 --- a/startscript.js +++ b/startscript.js @@ -1,2 +1,2 @@ var exec = require('child_process').exec -exec('yarn start', { windowsHide: true }) +exec('yarn dev -p 5000', { windowsHide: true }) From ee6f62b4ba8285a8d004ade6c3f3b5a3db56a2df Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 2 Apr 2025 16:32:19 +0900 Subject: [PATCH 076/196] =?UTF-8?q?chore:=20nextjs=20hotfix=20=EB=A1=9C=20?= =?UTF-8?q?=EB=B2=84=EC=A0=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf52888e..e6aabebd 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "js-cookie": "^3.0.5", "mathjs": "^13.0.2", "mssql": "^11.0.1", - "next": "14.2.21", + "next": "14.2.26", "next-international": "^1.2.4", "react": "^18", "react-chartjs-2": "^5.2.0", From 648c2e208a89c0080e49d9c570ac2b3700374b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 16:54:04 +0900 Subject: [PATCH 077/196] =?UTF-8?q?Trestle=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Trestle.jsx | 11 ++++++++++- src/hooks/module/useModuleTrestle.js | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index dd5a7529..e3d093a7 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -18,6 +18,7 @@ const Trestle = forwardRef((props, ref) => { const [selectedRoof, setSelectedRoof] = useState() const { trestleState, + trestleDetail, dispatch, raftBaseList, trestleList, @@ -171,6 +172,7 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, + trestleDetail, } } return { ...roof } @@ -224,6 +226,7 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, + trestleDetail, } } return { ...roof } @@ -258,16 +261,22 @@ const Trestle = forwardRef((props, ref) => { setRoofs(newAddedRoofs) setModuleSelectionData({ ...moduleSelectionData, - roofConstructions: newAddedRoofs.map((roof) => { + roofConstructions: newAddedRoofs.map((roof, index) => { return { addRoof: { ...roof.addRoof, + ...moduleSelectionData.roofConstructions[index].addRoof, }, trestle: { ...roof.trestle, + ...moduleSelectionData.roofConstructions[index].trestle, }, construction: { ...roof.construction, + ...moduleSelectionData.roofConstructions[index].construction, + }, + trestleDetail: { + ...roof.trestleDetail, }, } }), diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index d0838b34..178054ef 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -64,6 +64,7 @@ export function useModuleTrestle(props) { const [ridgeMargin, setRidgeMargin] = useState(0) const [kerabaMargin, setKerabaMargin] = useState(0) const [trestleState, dispatch] = useReducer(trestleReducer, null) + const [trestleDetail, setTrestleDetail] = useState(null) useEffect(() => { const raftCodeList = findCommonCode(RAFT_BASE_CODE) @@ -90,6 +91,7 @@ export function useModuleTrestle(props) { setConstMthdList([]) setRoofBaseList([]) setConstructionList([]) + setTrestleDetail(null) return } @@ -97,17 +99,20 @@ export function useModuleTrestle(props) { if (!trestleState.constMthdCd) { setRoofBaseList([]) setConstructionList([]) + setTrestleDetail(null) return } handleSetRoofBaseList() if (!trestleState.roofBaseCd) { setConstructionList([]) + setTrestleDetail(null) return } handleSetConstructionList() if (!trestleState.constTp) { + setTrestleDetail(null) return } @@ -193,6 +198,7 @@ export function useModuleTrestle(props) { setEavesMargin(res[0].data.eaveIntvl) setRidgeMargin(res[0].data.ridgeIntvl) setKerabaMargin(res[0].data.kerabaIntvl) + setTrestleDetail(res[0].data) // dispatch({ // type: 'SET_TRESTLE_DETAIL', // roof: { @@ -208,6 +214,7 @@ export function useModuleTrestle(props) { return { trestleState, + trestleDetail, dispatch, raftBaseList, trestleList, From bfc7b3fe328162e3e4ae7c50c66efcd48800ff3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 16:54:21 +0900 Subject: [PATCH 078/196] =?UTF-8?q?Revert=20"Trestle=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=B6=94=EA=B0=80=20=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 648c2e208a89c0080e49d9c570ac2b3700374b2a. --- .../floor-plan/modal/basic/step/Trestle.jsx | 11 +---------- src/hooks/module/useModuleTrestle.js | 7 ------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index e3d093a7..dd5a7529 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -18,7 +18,6 @@ const Trestle = forwardRef((props, ref) => { const [selectedRoof, setSelectedRoof] = useState() const { trestleState, - trestleDetail, dispatch, raftBaseList, trestleList, @@ -172,7 +171,6 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, - trestleDetail, } } return { ...roof } @@ -226,7 +224,6 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, - trestleDetail, } } return { ...roof } @@ -261,22 +258,16 @@ const Trestle = forwardRef((props, ref) => { setRoofs(newAddedRoofs) setModuleSelectionData({ ...moduleSelectionData, - roofConstructions: newAddedRoofs.map((roof, index) => { + roofConstructions: newAddedRoofs.map((roof) => { return { addRoof: { ...roof.addRoof, - ...moduleSelectionData.roofConstructions[index].addRoof, }, trestle: { ...roof.trestle, - ...moduleSelectionData.roofConstructions[index].trestle, }, construction: { ...roof.construction, - ...moduleSelectionData.roofConstructions[index].construction, - }, - trestleDetail: { - ...roof.trestleDetail, }, } }), diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 178054ef..d0838b34 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -64,7 +64,6 @@ export function useModuleTrestle(props) { const [ridgeMargin, setRidgeMargin] = useState(0) const [kerabaMargin, setKerabaMargin] = useState(0) const [trestleState, dispatch] = useReducer(trestleReducer, null) - const [trestleDetail, setTrestleDetail] = useState(null) useEffect(() => { const raftCodeList = findCommonCode(RAFT_BASE_CODE) @@ -91,7 +90,6 @@ export function useModuleTrestle(props) { setConstMthdList([]) setRoofBaseList([]) setConstructionList([]) - setTrestleDetail(null) return } @@ -99,20 +97,17 @@ export function useModuleTrestle(props) { if (!trestleState.constMthdCd) { setRoofBaseList([]) setConstructionList([]) - setTrestleDetail(null) return } handleSetRoofBaseList() if (!trestleState.roofBaseCd) { setConstructionList([]) - setTrestleDetail(null) return } handleSetConstructionList() if (!trestleState.constTp) { - setTrestleDetail(null) return } @@ -198,7 +193,6 @@ export function useModuleTrestle(props) { setEavesMargin(res[0].data.eaveIntvl) setRidgeMargin(res[0].data.ridgeIntvl) setKerabaMargin(res[0].data.kerabaIntvl) - setTrestleDetail(res[0].data) // dispatch({ // type: 'SET_TRESTLE_DETAIL', // roof: { @@ -214,7 +208,6 @@ export function useModuleTrestle(props) { return { trestleState, - trestleDetail, dispatch, raftBaseList, trestleList, From 82632b962e93eaaae4731c1cebbc1e90fc7b3516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 2 Apr 2025 16:55:23 +0900 Subject: [PATCH 079/196] =?UTF-8?q?Trestle=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Trestle.jsx | 11 ++++++++++- src/hooks/module/useModuleTrestle.js | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index dd5a7529..e3d093a7 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -18,6 +18,7 @@ const Trestle = forwardRef((props, ref) => { const [selectedRoof, setSelectedRoof] = useState() const { trestleState, + trestleDetail, dispatch, raftBaseList, trestleList, @@ -171,6 +172,7 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, + trestleDetail, } } return { ...roof } @@ -224,6 +226,7 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, + trestleDetail, } } return { ...roof } @@ -258,16 +261,22 @@ const Trestle = forwardRef((props, ref) => { setRoofs(newAddedRoofs) setModuleSelectionData({ ...moduleSelectionData, - roofConstructions: newAddedRoofs.map((roof) => { + roofConstructions: newAddedRoofs.map((roof, index) => { return { addRoof: { ...roof.addRoof, + ...moduleSelectionData.roofConstructions[index].addRoof, }, trestle: { ...roof.trestle, + ...moduleSelectionData.roofConstructions[index].trestle, }, construction: { ...roof.construction, + ...moduleSelectionData.roofConstructions[index].construction, + }, + trestleDetail: { + ...roof.trestleDetail, }, } }), diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index d0838b34..178054ef 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -64,6 +64,7 @@ export function useModuleTrestle(props) { const [ridgeMargin, setRidgeMargin] = useState(0) const [kerabaMargin, setKerabaMargin] = useState(0) const [trestleState, dispatch] = useReducer(trestleReducer, null) + const [trestleDetail, setTrestleDetail] = useState(null) useEffect(() => { const raftCodeList = findCommonCode(RAFT_BASE_CODE) @@ -90,6 +91,7 @@ export function useModuleTrestle(props) { setConstMthdList([]) setRoofBaseList([]) setConstructionList([]) + setTrestleDetail(null) return } @@ -97,17 +99,20 @@ export function useModuleTrestle(props) { if (!trestleState.constMthdCd) { setRoofBaseList([]) setConstructionList([]) + setTrestleDetail(null) return } handleSetRoofBaseList() if (!trestleState.roofBaseCd) { setConstructionList([]) + setTrestleDetail(null) return } handleSetConstructionList() if (!trestleState.constTp) { + setTrestleDetail(null) return } @@ -193,6 +198,7 @@ export function useModuleTrestle(props) { setEavesMargin(res[0].data.eaveIntvl) setRidgeMargin(res[0].data.ridgeIntvl) setKerabaMargin(res[0].data.kerabaIntvl) + setTrestleDetail(res[0].data) // dispatch({ // type: 'SET_TRESTLE_DETAIL', // roof: { @@ -208,6 +214,7 @@ export function useModuleTrestle(props) { return { trestleState, + trestleDetail, dispatch, raftBaseList, trestleList, From 2e60e848c8933deb820029cdd7561b21c936b691 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 2 Apr 2025 17:01:37 +0900 Subject: [PATCH 080/196] =?UTF-8?q?basicsetting=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 22 +++++++++---------- .../floor-plan/modal/basic/step/Trestle.jsx | 5 ++++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 9ae90e71..57264d89 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -1,8 +1,6 @@ import { useMessage } from '@/hooks/useMessage' import WithDraggable from '@/components/common/draggable/WithDraggable' import { useContext, useEffect, useRef, useState } from 'react' -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 Placement from '@/components/floor-plan/modal/basic/step/Placement' import { useRecoilValue, useRecoilState } from 'recoil' @@ -37,9 +35,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const { closePopup } = usePopup() const [tabNum, setTabNum] = useState(1) const orientationRef = useRef(null) + const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) + const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState) const trestleRef = useRef(null) - const { initEvent } = useEvent() - const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const loginUserState = useRecoilValue(loginUserStore) @@ -49,6 +47,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const [isClosePopup, setIsClosePopup] = useState({ close: false, id: 0 }) const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState) const [roofs, setRoofs] = useState(addedRoofs) + const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState) + const [layoutSetup, setLayoutSetup] = useState([{}]) + const { moduleSelectionInitParams, selectedModules, @@ -132,7 +133,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { if (basicSetting.roofSizeSet !== '3') { - manualModuleSetup(placementRef) + manualModuleSetup() } else { manualFlatroofModuleSetup(placementFlatRef) } @@ -171,7 +172,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { if (!trestleRef.current.isComplete()) { Swal.fire({ - title: getMessage('아직 멀었따'), + title: getMessage('construction.length.difference'), icon: 'warning', }) return @@ -300,7 +301,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { }, [checkedModules]) return ( - + handleClosePopup(id)} />
@@ -350,13 +351,12 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { <> {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( <> - + - diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index dd5a7529..89724109 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -258,16 +258,19 @@ const Trestle = forwardRef((props, ref) => { setRoofs(newAddedRoofs) setModuleSelectionData({ ...moduleSelectionData, - roofConstructions: newAddedRoofs.map((roof) => { + roofConstructions: newAddedRoofs.map((roof, index) => { return { addRoof: { ...roof.addRoof, + ...moduleSelectionData.roofConstructions[index].addRoof, }, trestle: { ...roof.trestle, + ...moduleSelectionData.roofConstructions[index].trestle, }, construction: { ...roof.construction, + ...moduleSelectionData.roofConstructions[index].construction, }, } }), From 265593f6ddc8ec464d36621ecd9eafe9c319d83a Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 2 Apr 2025 17:36:25 +0900 Subject: [PATCH 081/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EA=B7=B8=EB=A3=B9?= =?UTF-8?q?=ED=99=94=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 --- src/hooks/module/useTrestle.js | 139 ++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 3 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index a584876c..01e9ec8b 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -2131,12 +2131,13 @@ export const useTrestle = () => { const visited = new Set() const width = Math.floor(moduleExample.width) const height = Math.floor(moduleExample.height) - const horizonPadding = 0 // 가로 패딩 - const verticalPadding = 0 // 세로 패딩 + const horizonPadding = 3 // 가로 패딩 + const verticalPadding = 7 // 세로 패딩 function isAdjacent(p1, p2) { const dx = Math.abs(p1.x - p2.x) const dy = Math.abs(p1.y - p2.y) + return ( (Math.abs(width + horizonPadding - dx) < 2 && dy < 2) || (dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 || @@ -2168,6 +2169,128 @@ export const useTrestle = () => { 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 && Math.abs(m1Y - m2Y) <= maxY) || + (Math.abs(Math.abs(m1X - m2X) - maxX / 2) <= halfMaxX && Math.abs(Math.abs(m1Y - m2Y) - maxY) <= halfMaxY) || + (Math.abs(Math.abs(m1X - m2X) - maxX) <= halfMaxX && Math.abs(Math.abs(m1Y - m2Y) - maxY / 2) <= halfMaxY) + ) + } 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 && Math.abs(m1Y - m2Y) <= maxX) || + (Math.abs(Math.abs(m1X - m2X) - maxY / 2) <= halfMaxY && Math.abs(Math.abs(m1Y - m2Y) - maxX) <= halfMaxX) || + (Math.abs(Math.abs(m1X - m2X) - maxY) <= halfMaxY && Math.abs(Math.abs(m1Y - m2Y) - maxX / 2) <= halfMaxX) + ) + } + }) + } + + // 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) { if (roofSizeSet !== 1) { @@ -2865,5 +2988,15 @@ export const useTrestle = () => { return surfaces.every((surface) => surface.isComplete) } - return { apply, getTrestleParams, clear, setViewCircuitNumberTexts, getEstimateData, setAllModuleSurfaceIsComplete, isAllComplete } + return { + apply, + getTrestleParams, + clear, + setViewCircuitNumberTexts, + getEstimateData, + setAllModuleSurfaceIsComplete, + isAllComplete, + groupCoordinates, + groupPoints, + } } From 001143954ec510375943affd4e1b5901c7c8de27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 3 Apr 2025 10:22:14 +0900 Subject: [PATCH 082/196] =?UTF-8?q?QSelectbox=20value=20=EC=97=86=EC=9D=84?= =?UTF-8?q?=EB=95=8C=20title=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/select/QSelectBox.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/select/QSelectBox.jsx b/src/components/common/select/QSelectBox.jsx index a027cb55..3e797071 100644 --- a/src/components/common/select/QSelectBox.jsx +++ b/src/components/common/select/QSelectBox.jsx @@ -39,7 +39,7 @@ export default function QSelectBox({ if (showKey !== '' && !value) { //value가 없으면 showKey가 있으면 우선 보여준다 // return options[0][showKey] - return title + return title !== '' ? title : getMessage('selectbox.title') } else if (showKey !== '' && value) { //value가 있으면 sourceKey와 targetKey를 비교하여 보여준다 From 6c6e5845ef0341b4125f19d16837ddcddaefbd86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 3 Apr 2025 10:22:48 +0900 Subject: [PATCH 083/196] =?UTF-8?q?=EC=A0=81=EC=84=A4=EB=9F=89,=20?= =?UTF-8?q?=ED=92=8D=EC=86=8D=20=EB=93=B1=20=EC=88=98=EC=A0=95=ED=96=88?= =?UTF-8?q?=EC=9D=84=EB=95=8C=20=EC=84=A4=EC=A0=95=ED=95=9C=20roof=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/basic/step/Orientation.jsx | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index 59ff4f37..6dcadde8 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -66,12 +66,12 @@ export const Orientation = forwardRef((props, ref) => { useEffect(() => { if (selectedSurfaceType) { console.log(roughnessCodes, selectedSurfaceType) - setInputRoughness(roughnessCodes.find((code) => code.clCode === moduleSelectionData.common.illuminationTp)) + setInputRoughness(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue)) } }, [selectedSurfaceType]) useEffect(() => { - if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === moduleSelectionData.common.stdWindSpeed)) + if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId)) }, [standardWindSpeed]) useEffect(() => { @@ -181,11 +181,35 @@ export const Orientation = forwardRef((props, ref) => { } const handleChangeModule = (e) => { + resetRoofs() + setSelectedModules(e) + } + + const handleChangeRoughness = (e) => { + resetRoofs() + setInputRoughness(e) + } + + const handleChangeInstallHeight = (e) => { + resetRoofs() + setInputInstallHeight(e) + } + + const handleChangeStandardWindSpeed = (e) => { + resetRoofs() + setInputStandardWindSpeed(e) + } + + const handleChangeVerticalSnowCover = (e) => { + resetRoofs() + setInputVerticalSnowCover(e) + } + + const resetRoofs = () => { const newRoofs = addedRoofs.map((roof) => { return { ...roof, lengthBase: null, - raftBaseCd: null, trestleMkrCd: null, constMthdCd: null, constTp: null, @@ -201,7 +225,6 @@ export const Orientation = forwardRef((props, ref) => { } }) setRoofs(newRoofs) - setSelectedModules(e) } return ( @@ -359,10 +382,7 @@ export const Orientation = forwardRef((props, ref) => { targetKey={'clCode'} sourceKey={'clCode'} showKey={'clCodeNm'} - onChange={(e) => { - console.log('🚀 ~ handleChangeModule ~ inputRoughness:', e) - setInputRoughness(e) - }} + onChange={(e) => handleChangeRoughness(e)} /> )}
@@ -374,7 +394,7 @@ export const Orientation = forwardRef((props, ref) => { type="text" className="input-origin block" value={inputInstallHeight} - onChange={(e) => setInputInstallHeight(e.target.value)} + onChange={(e) => handleChangeInstallHeight(e.target.value)} /> m @@ -390,10 +410,7 @@ export const Orientation = forwardRef((props, ref) => { targetKey={'clCode'} sourceKey={'clCode'} showKey={'clCodeNm'} - onChange={(e) => { - console.log('🚀 ~ handleChangeModule ~ inputStandardWindSpeed:', e) - setInputStandardWindSpeed(e) - }} + onChange={(e) => handleChangeStandardWindSpeed(e)} /> )} @@ -405,7 +422,7 @@ export const Orientation = forwardRef((props, ref) => { type="text" className="input-origin block" value={inputVerticalSnowCover} - onChange={(e) => setInputVerticalSnowCover(e.target.value)} + onChange={(e) => handleChangeVerticalSnowCover(e.target.value)} /> cm From 7d7692968912e5aeaba348383587fd7a55b46634 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 3 Apr 2025 11:23:37 +0900 Subject: [PATCH 084/196] =?UTF-8?q?=EA=B3=A0=EB=8F=84=ED=99=94=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=84=A4=EC=B9=98=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 2 +- .../modal/basic/step/Orientation.jsx | 2 +- .../floor-plan/modal/basic/step/Placement.jsx | 16 +++++--- .../floor-plan/modal/basic/step/Trestle.jsx | 11 ++++-- src/hooks/module/useModuleBasicSetting.js | 39 +++++++++++++------ src/store/canvasAtom.js | 6 +++ 6 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 57264d89..3e22c508 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -95,7 +95,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { addedRoofs.map((roof, index) => { return { ...roof, - ...roofsStore[index].addRoof, + ...roofsStore[index]?.addRoof, } }), ) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index 6dcadde8..2ce0d536 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -321,7 +321,7 @@ export const Orientation = forwardRef((props, ref) => {
- {Array.from({ length: 2 }).map((_, index) => { + {Array.from({ length: 3 }).map((_, index) => { return selectedModules && selectedModules?.itemList && selectedModules?.itemList?.length >= index + 1 ? ( - {moduleSelectionData.roofConstructions.map((item) => ( + {moduleSelectionData.roofConstructions.map((item, index) => ( - {selectedModules.itemList.map((item) => ( + {moduleRowColArray[index]?.map((item) => ( <> - - {colspan > 1 && } + + {colspan > 1 && } ))} diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index a7bb39d9..529b2fcb 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -1,5 +1,6 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider' import QSelectBox from '@/components/common/select/QSelectBox' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' import { useModuleTrestle } from '@/hooks/module/useModuleTrestle' import { useMessage } from '@/hooks/useMessage' import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' @@ -52,11 +53,15 @@ const Trestle = forwardRef((props, ref) => { const [selectedConstruction, setSelectedConstruction] = useState(null) const [selectedRoofBase, setSelectedRoofBase] = useState(null) const { managementState } = useContext(GlobalDataContext) + const { restoreModuleInstArea } = useModuleBasicSetting() useEffect(() => { if (roofs && !selectedRoof) { setSelectedRoof(roofs[0]) } + + //모듈 설치 영역 복구 + restoreModuleInstArea() }, [roofs]) useEffect(() => { @@ -263,16 +268,16 @@ const Trestle = forwardRef((props, ref) => { roofConstructions: newAddedRoofs.map((roof, index) => { return { addRoof: { + ...moduleSelectionData.roofConstructions[index]?.addRoof, ...roof.addRoof, - ...moduleSelectionData.roofConstructions[index].addRoof, }, trestle: { ...roof.trestle, - ...moduleSelectionData.roofConstructions[index].trestle, + ...moduleSelectionData.roofConstructions[index]?.trestle, }, construction: { ...roof.construction, - ...moduleSelectionData.roofConstructions[index].construction, + ...moduleSelectionData.roofConstructions[index]?.construction, }, trestleDetail: { ...roof.trestleDetail, diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index bb966f4e..6e8d5fce 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -10,6 +10,7 @@ import { isManualModuleSetupState, moduleSetupOptionState, toggleManualSetupModeState, + moduleRowColArrayState, } from '@/store/canvasAtom' import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon, toFixedWithoutRounding } from '@/util/canvas-util' @@ -61,6 +62,7 @@ export function useModuleBasicSetting(tabNum) { const { drawDirectionArrow } = usePolygon() const moduleSetupOption = useRecoilValue(moduleSetupOptionState) const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) + const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState) useEffect(() => { return () => { @@ -81,6 +83,8 @@ export function useModuleBasicSetting(tabNum) { //모듈 선택에서 선택된 값들 넘어옴 const makeModuleInitArea = () => { + console.log('moduleSelectionData', moduleSelectionData) + if (isObjectNotEmpty(moduleSelectionData) && tabNum === 3) { if (canvasSetting.roofSizeSet !== '3') { const common = moduleSelectionData.common @@ -90,11 +94,11 @@ export function useModuleBasicSetting(tabNum) { const listParams = roofConstructions.map((item) => { return { ...common, - roofMatlCd: item.trestle.roofMatlCd, - trestleMkrCd: item.trestle.trestleMkrCd, - constMthdCd: item.trestle.constMthdCd, - roofBaseCd: item.trestle.roofBaseCd, - constTp: item.construction.constTp, + roofMatlCd: item.addRoof.roofMatlCd, + trestleMkrCd: item.addRoof.trestleMkrCd, + constMthdCd: item.addRoof.constMthdCd, + roofBaseCd: item.addRoof.roofBaseCd, + constTp: item.addRoof.constTp, mixMatlNo: selectedModules.mixMatlNo, roofPitch: item.addRoof.hajebichi ? item.addRoof.hajebichi : 0, inclCd: String(item.addRoof.pitch), @@ -140,6 +144,7 @@ export function useModuleBasicSetting(tabNum) { //가대 상세 데이터 들어오면 실행 useEffect(() => { if (trestleDetailList.length > 0) { + let rowColArray = [] //지붕을 가져옴 canvas .getObjects() @@ -147,26 +152,38 @@ export function useModuleBasicSetting(tabNum) { .forEach((roof) => { if (!roof.roofMaterial) return const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번 + + console.log('moduleSelectionData', moduleSelectionData) + trestleDetailList.forEach((detail) => { if (detail.data !== null) { + const moduleRowArray = [] if (Number(detail.data.roofIndex) === roofIndex) { //roof에 상세 데이터 추가 - roof.set({ trestleDetail: detail.data, stroke: roofOutlineColor(roofIndex), strokeWidth: 7, }) + + const offsetObjects = moduleSelectionData.roofConstructions.find((item) => item.addRoof.index === roofIndex) + + console.log('offsetObjects', offsetObjects) + roof.lines.forEach((line) => { - line.attributes = { ...line.attributes, offset: getOffset(detail.data, line.attributes.type) } + line.attributes = { ...line.attributes, offset: getOffset(offsetObjects.addRoof, line.attributes.type) } }) //배치면 설치 영역 makeModuleInstArea(roof, detail.data) - //surface에 상세 데이터 추가 } + detail.data.module.forEach((module) => { + moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows }) + }) + rowColArray.push(moduleRowArray) } }) }) + setModuleRowColArray(rowColArray) } }, [trestleDetailList]) @@ -185,12 +202,12 @@ export function useModuleBasicSetting(tabNum) { const getOffset = (data, type) => { switch (type) { case LINE_TYPE.WALLLINE.EAVES: - return data.eaveIntvl / 10 + return data.eavesMargin / 10 case LINE_TYPE.WALLLINE.GABLE: - return data.kerabaIntvl / 10 + return data.kerabaMargin / 10 case LINE_TYPE.SUBLINE.RIDGE: case LINE_TYPE.WALLLINE.SHED: - return data.ridgeIntvl / 10 + return data.ridgeMargin / 10 default: return 200 / 10 } diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js index 0679938f..c8bb1ad0 100644 --- a/src/store/canvasAtom.js +++ b/src/store/canvasAtom.js @@ -402,3 +402,9 @@ export const toggleManualSetupModeState = atom({ key: 'toggleManualSetupModeState', default: '', }) + +export const moduleRowColArrayState = atom({ + key: 'moduleRowColArrayState', + default: [], + dangerouslyAllowMutability: true, +}) From f32e77214127ce3bfdcb79a4ee6c16905bd25d2b Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 3 Apr 2025 13:36:46 +0900 Subject: [PATCH 085/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=ED=91=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 6e8d5fce..6aea3d59 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -153,11 +153,8 @@ export function useModuleBasicSetting(tabNum) { if (!roof.roofMaterial) return const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번 - console.log('moduleSelectionData', moduleSelectionData) - trestleDetailList.forEach((detail) => { if (detail.data !== null) { - const moduleRowArray = [] if (Number(detail.data.roofIndex) === roofIndex) { //roof에 상세 데이터 추가 roof.set({ @@ -168,21 +165,23 @@ export function useModuleBasicSetting(tabNum) { const offsetObjects = moduleSelectionData.roofConstructions.find((item) => item.addRoof.index === roofIndex) - console.log('offsetObjects', offsetObjects) - roof.lines.forEach((line) => { line.attributes = { ...line.attributes, offset: getOffset(offsetObjects.addRoof, line.attributes.type) } }) //배치면 설치 영역 makeModuleInstArea(roof, detail.data) } - detail.data.module.forEach((module) => { - moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows }) - }) - rowColArray.push(moduleRowArray) } }) }) + + trestleDetailList.forEach((detail) => { + const moduleRowArray = [] + detail.data.module.forEach((module) => { + moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows }) + }) + rowColArray.push(moduleRowArray) + }) setModuleRowColArray(rowColArray) } }, [trestleDetailList]) From aa2685e5585527cea09f3fa4a6dd6d65587908e1 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 3 Apr 2025 14:33:54 +0900 Subject: [PATCH 086/196] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 6aea3d59..7b2bc999 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1277,6 +1277,16 @@ export function useModuleBasicSetting(tabNum) { }) addCanvasMouseEventListener('mouse:up', (e) => { + if (trestlePolygon.modules.length > 0) { + //이미 설치된 모듈중에 한개만 가져옴 + const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn + //현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능 + if (checkedModule[0].mixAsgYn !== mixAsgYn) { + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) + return + } + } + if (!inside) return //입력받은 값의 합 From 3f40725647cf742e28e26a9c4cef811bbd6eb95c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 3 Apr 2025 16:28:58 +0900 Subject: [PATCH 087/196] =?UTF-8?q?3=EC=A4=91=20=EB=A9=80=ED=8B=B0?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 96 ++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index a584876c..963c4cf7 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -370,7 +370,20 @@ export const useTrestle = () => { rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else { + } else if (leftRowsInfo.rowsInfo.length >= 2) { + //C1C2C3인 경우 + if (rack.value.moduleTpCd.length === 6) { + // 변환 C1C2만 있는경우 C3 0개로 추가해준다. + let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo) + + return ( + rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp && + rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + Number(rack.value.moduleTpRows1) === newLeftRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === newLeftRowsInfo.rowsInfo[1].count && + Number(rack.value.moduleTpRows3) === newLeftRowsInfo.rowsInfo[2].count + ) + } return ( rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && @@ -387,7 +400,19 @@ export const useTrestle = () => { rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else { + } else if (rightRowsInfo.rowsInfo.length === 2) { + if (rack.value.moduleTpCd.length === 6) { + // 변환 C1C2만 있는경우 C3 0개로 추가해준다. + let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo) + + return ( + rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp && + rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + Number(rack.value.moduleTpRows1) === newRightRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === newRightRowsInfo.rowsInfo[1].count && + Number(rack.value.moduleTpRows3) === newRightRowsInfo.rowsInfo[2].count + ) + } return ( rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && @@ -404,7 +429,19 @@ export const useTrestle = () => { rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else { + } else if (centerRowsInfo.rowsInfo.length === 2) { + if (rack.value.moduleTpCd.length === 6) { + // 변환 C1C2만 있는경우 C3 0개로 추가해준다. + let newCenterRowsInfo = normalizeModules(rack.value.moduleTpCd, centerRowsInfo) + + return ( + rack.value.moduleTpCd === newCenterRowsInfo.moduleTotalTp && + rack.value.moduleRows === newCenterRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + Number(rack.value.moduleTpRows1) === newCenterRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === newCenterRowsInfo.rowsInfo[1].count && + Number(rack.value.moduleTpRows3) === newCenterRowsInfo.rowsInfo[2].count + ) + } return ( rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && @@ -499,7 +536,19 @@ export const useTrestle = () => { rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else { + } else if (leftRowsInfo.rowsInfo.length === 2) { + if (rack.value.moduleTpCd.length === 6) { + // 변환 C1C2만 있는경우 C3 0개로 추가해준다. + let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo) + + return ( + rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp && + rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + Number(rack.value.moduleTpRows1) === newLeftRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === newLeftRowsInfo.rowsInfo[1].count && + Number(rack.value.moduleTpRows3) === newLeftRowsInfo.rowsInfo[2].count + ) + } return ( rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && @@ -575,7 +624,19 @@ export const useTrestle = () => { rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else { + } else if (rightRowsInfo.rowsInfo.length === 2) { + if (rack.value.moduleTpCd.length === 6) { + // 변환 C1C2만 있는경우 C3 0개로 추가해준다. + let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo) + + return ( + rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp && + rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + Number(rack.value.moduleTpRows1) === newRightRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === newRightRowsInfo.rowsInfo[1].count && + Number(rack.value.moduleTpRows3) === newRightRowsInfo.rowsInfo[2].count + ) + } return ( rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && @@ -635,6 +696,31 @@ export const useTrestle = () => { 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에 저장 const getEstimateData = async () => { const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) From d524b33f5694417f59c3068934ecfd666bbda7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 3 Apr 2025 16:31:12 +0900 Subject: [PATCH 088/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=88=98=EC=A0=95=EC=8B=9C=20?= =?UTF-8?q?roofs=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 16 +++++++------- .../floor-plan/modal/basic/step/Trestle.jsx | 22 ++++++++----------- src/hooks/module/useModuleTrestle.js | 6 +---- .../roofcover/useRoofAllocationSetting.js | 8 ++++--- 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 3e22c508..79e12280 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -91,14 +91,14 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { if (roofsStore && addedRoofs) { console.log('🚀 ~ useEffect ~ roofsStore, addedRoofs:', roofsStore, addedRoofs) - setRoofs( - addedRoofs.map((roof, index) => { - return { - ...roof, - ...roofsStore[index]?.addRoof, - } - }), - ) + // setRoofs( + // addedRoofs.map((roof, index) => { + // return { + // ...roof, + // ...roofsStore[index]?.addRoof, + // } + // }), + // ) setModuleSelectionData({ ...moduleSelectionData, diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 529b2fcb..b54c12ee 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -1,6 +1,5 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider' import QSelectBox from '@/components/common/select/QSelectBox' -import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' import { useModuleTrestle } from '@/hooks/module/useModuleTrestle' import { useMessage } from '@/hooks/useMessage' import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' @@ -46,22 +45,18 @@ const Trestle = forwardRef((props, ref) => { const selectedModules = useRecoilValue(selectedModuleState) //선택된 모듈 // const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const [lengthBase, setLengthBase] = useState(0) - const [hajebichi, setHajebichi] = useState(0) + const [hajebichi, setHajebichi] = useState(trestleState?.roofPitch ?? 0) const [selectedRaftBase, setSelectedRaftBase] = useState(null) const [selectedTrestle, setSelectedTrestle] = useState(null) const [selectedConstMthd, setSelectedConstMthd] = useState(null) const [selectedConstruction, setSelectedConstruction] = useState(null) const [selectedRoofBase, setSelectedRoofBase] = useState(null) const { managementState } = useContext(GlobalDataContext) - const { restoreModuleInstArea } = useModuleBasicSetting() useEffect(() => { if (roofs && !selectedRoof) { setSelectedRoof(roofs[0]) } - - //모듈 설치 영역 복구 - restoreModuleInstArea() }, [roofs]) useEffect(() => { @@ -201,10 +196,12 @@ const Trestle = forwardRef((props, ref) => { stdWindSpeed: managementState?.standardWindSpeedId ?? '', stdSnowLd: +managementState?.verticalSnowCover ?? '', inclCd: selectedRoof?.pitch.toString() ?? 0, - roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), + // roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), + roofPitch: hajebichi ?? 0, constTp: constructionList[index].constTp, mixMatlNo: selectedModules.mixMatlNo, - workingWidth: selectedRoof?.length.toString() ?? '', + // workingWidth: selectedRoof?.length.toString() ?? '', + workingWidth: lengthBase ?? '', // snowGdPossYn: constructionList[index].snowGdPossYn, // cvrYn: constructionList[index].cvrYn, }, @@ -259,14 +256,13 @@ const Trestle = forwardRef((props, ref) => { } }) - console.log('newAddedRoofs', newAddedRoofs) - if (result) { setRoofs(newAddedRoofs) setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newAddedRoofs.map((roof, index) => { return { + roofIndex: index, addRoof: { ...moduleSelectionData.roofConstructions[index]?.addRoof, ...roof.addRoof, @@ -276,8 +272,8 @@ const Trestle = forwardRef((props, ref) => { ...moduleSelectionData.roofConstructions[index]?.trestle, }, construction: { - ...roof.construction, ...moduleSelectionData.roofConstructions[index]?.construction, + ...roof.construction, }, trestleDetail: { ...roof.trestleDetail, @@ -343,7 +339,7 @@ const Trestle = forwardRef((props, ref) => { setLengthBase(e.target.value)} disabled={selectedRoof.lenAuth === 'R'} /> @@ -384,7 +380,7 @@ const Trestle = forwardRef((props, ref) => { type="text" className="input-origin block" disabled={selectedRoof.roofPchAuth === 'R'} - onChange={(e) => handleHajebichiAndLength(e, 'hajebichi')} + onChange={(e) => setHajebichi(e.target.value)} value={hajebichi} /> diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 178054ef..6d0544e3 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -8,8 +8,6 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider' const RAFT_BASE_CODE = '203800' const trestleReducer = (state, action) => { - console.log('🚀 ~ trestleReducer ~ state:', state) - console.log('🚀 ~ trestleReducer ~ action:', action) switch (action.type) { case 'SET_RAFT_BASE': case 'SET_TRESTLE_MAKER': @@ -21,7 +19,6 @@ const trestleReducer = (state, action) => { ...action.roof, } case 'SET_INITIALIZE': - console.log('SET_INITIALIZE') return { moduleTpCd: action.roof.moduleTpCd ?? '', roofMatlCd: action.roof.roofMatlCd ?? '', @@ -85,7 +82,6 @@ export function useModuleTrestle(props) { useEffect(() => { if (trestleState) { - console.log('🚀 ~ useEffect ~ trestleState:', trestleState) handleSetTrestleList() if (!trestleState.trestleMkrCd) { setConstMthdList([]) @@ -168,7 +164,7 @@ export function useModuleTrestle(props) { stdSnowLd: trestleState.stdSnowLd ?? '', inclCd: trestleState.inclCd ?? '', raftBaseCd: trestleState.raftBaseCd ?? '', - roofPitch: trestleState.roofPitch ?? '', + roofPitch: Math.round(trestleState.roofPitch) ?? '', }).then((res) => { if (res?.data) setConstructionList(res.data) }) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index bc4d246a..428cd853 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -296,7 +296,7 @@ export function useRoofAllocationSetting(id) { }) } - return { ...roof, index: idx, raft: roof.raft ? roof.raft : roof.raftBaseCd } + return { ...roof, index: idx, raft: roof.raft ? roof.raft : roof.raftBaseCd, raftBaseCd: roof.raft ? roof.raft : roof.raftBaseCd } }) setBasicSetting((prev) => { @@ -308,7 +308,8 @@ export function useRoofAllocationSetting(id) { const selectedRoofMaterial = newRoofList.find((roof) => roof.selected) setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true) drawDirectionArrow(currentObject) - modifyModuleSelectionData() + setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList }) + // modifyModuleSelectionData() closeAll() basicSettingSave() } @@ -430,7 +431,8 @@ export function useRoofAllocationSetting(id) { setSelectedMenu('surface') /** 모듈 선택 데이터 초기화 */ - modifyModuleSelectionData() + // modifyModuleSelectionData() + setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList }) } /** From e872df680d43901d908ca2a6c864cd54f3508054 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 3 Apr 2025 17:09:17 +0900 Subject: [PATCH 089/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=EB=A9=B4=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Trestle.jsx | 22 +++++++++++-------- src/hooks/module/useModuleBasicSetting.js | 18 +++++---------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index b54c12ee..529b2fcb 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -1,5 +1,6 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider' import QSelectBox from '@/components/common/select/QSelectBox' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' import { useModuleTrestle } from '@/hooks/module/useModuleTrestle' import { useMessage } from '@/hooks/useMessage' import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' @@ -45,18 +46,22 @@ const Trestle = forwardRef((props, ref) => { const selectedModules = useRecoilValue(selectedModuleState) //선택된 모듈 // const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const [lengthBase, setLengthBase] = useState(0) - const [hajebichi, setHajebichi] = useState(trestleState?.roofPitch ?? 0) + const [hajebichi, setHajebichi] = useState(0) const [selectedRaftBase, setSelectedRaftBase] = useState(null) const [selectedTrestle, setSelectedTrestle] = useState(null) const [selectedConstMthd, setSelectedConstMthd] = useState(null) const [selectedConstruction, setSelectedConstruction] = useState(null) const [selectedRoofBase, setSelectedRoofBase] = useState(null) const { managementState } = useContext(GlobalDataContext) + const { restoreModuleInstArea } = useModuleBasicSetting() useEffect(() => { if (roofs && !selectedRoof) { setSelectedRoof(roofs[0]) } + + //모듈 설치 영역 복구 + restoreModuleInstArea() }, [roofs]) useEffect(() => { @@ -196,12 +201,10 @@ const Trestle = forwardRef((props, ref) => { stdWindSpeed: managementState?.standardWindSpeedId ?? '', stdSnowLd: +managementState?.verticalSnowCover ?? '', inclCd: selectedRoof?.pitch.toString() ?? 0, - // roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), - roofPitch: hajebichi ?? 0, + roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), constTp: constructionList[index].constTp, mixMatlNo: selectedModules.mixMatlNo, - // workingWidth: selectedRoof?.length.toString() ?? '', - workingWidth: lengthBase ?? '', + workingWidth: selectedRoof?.length.toString() ?? '', // snowGdPossYn: constructionList[index].snowGdPossYn, // cvrYn: constructionList[index].cvrYn, }, @@ -256,13 +259,14 @@ const Trestle = forwardRef((props, ref) => { } }) + console.log('newAddedRoofs', newAddedRoofs) + if (result) { setRoofs(newAddedRoofs) setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newAddedRoofs.map((roof, index) => { return { - roofIndex: index, addRoof: { ...moduleSelectionData.roofConstructions[index]?.addRoof, ...roof.addRoof, @@ -272,8 +276,8 @@ const Trestle = forwardRef((props, ref) => { ...moduleSelectionData.roofConstructions[index]?.trestle, }, construction: { - ...moduleSelectionData.roofConstructions[index]?.construction, ...roof.construction, + ...moduleSelectionData.roofConstructions[index]?.construction, }, trestleDetail: { ...roof.trestleDetail, @@ -339,7 +343,7 @@ const Trestle = forwardRef((props, ref) => { setLengthBase(e.target.value)} disabled={selectedRoof.lenAuth === 'R'} /> @@ -380,7 +384,7 @@ const Trestle = forwardRef((props, ref) => { type="text" className="input-origin block" disabled={selectedRoof.roofPchAuth === 'R'} - onChange={(e) => setHajebichi(e.target.value)} + onChange={(e) => handleHajebichiAndLength(e, 'hajebichi')} value={hajebichi} /> diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 7b2bc999..4ca7082c 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -94,17 +94,9 @@ export function useModuleBasicSetting(tabNum) { const listParams = roofConstructions.map((item) => { return { ...common, - roofMatlCd: item.addRoof.roofMatlCd, - trestleMkrCd: item.addRoof.trestleMkrCd, - constMthdCd: item.addRoof.constMthdCd, - roofBaseCd: item.addRoof.roofBaseCd, - constTp: item.addRoof.constTp, - mixMatlNo: selectedModules.mixMatlNo, + ...item.addRoof, roofPitch: item.addRoof.hajebichi ? item.addRoof.hajebichi : 0, inclCd: String(item.addRoof.pitch), - roofIndex: item.addRoof.index, - workingWidth: item.addRoof.lenBase, - raftBaseCd: item.trestle.raftBaseCd, } }) setTrestleDetailParams(listParams) @@ -177,9 +169,11 @@ export function useModuleBasicSetting(tabNum) { trestleDetailList.forEach((detail) => { const moduleRowArray = [] - detail.data.module.forEach((module) => { - moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows }) - }) + if (detail.data !== null && detail.data.module.length > 0) { + detail.data.module.forEach((module) => { + moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows }) + }) + } rowColArray.push(moduleRowArray) }) setModuleRowColArray(rowColArray) From 22f8cd3fa74df8fd722dfa0e87c1e274c50a40cb Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 4 Apr 2025 10:18:52 +0900 Subject: [PATCH 090/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 6 +++++- src/hooks/roofcover/useRoofAllocationSetting.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 76f42075..7bde5638 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -123,6 +123,7 @@ export function useCanvasSetting(executeEffect = true) { const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */ const resetSelectedModules = useResetRecoilState(selectedModuleState) /* 선택된 모듈 */ + const { trigger: orientationTrigger } = useCanvasPopupStatusController(1) const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) const [raftCodes, setRaftCodes] = useState([]) /* 서까래 정보 */ @@ -526,7 +527,10 @@ export function useCanvasSetting(executeEffect = true) { /** 모듈 선택 데이터 초기화 */ 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) if (!isModuleExist) { resetSelectedModules() diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 428cd853..77ddb24c 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -552,7 +552,7 @@ export function useRoofAllocationSetting(id) { const modifyModuleSelectionData = () => { if (moduleSelectionData.roofConstructions.length > 0) { setModuleSelectionData({ ...moduleSelectionData, roofConstructions: [] }) - moduleSelectedDataTrigger({ ...moduleSelectionData, roofConstructions: [] }) + moduleSelectedDataTrigger({ roofConstructions: [] }) } } From 9400ee77076c96a89e6d4966aea9d55e76eccd0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:58:02 +0900 Subject: [PATCH 091/196] =?UTF-8?q?trestle=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 16 ++++++------- .../modal/basic/step/Orientation.jsx | 8 +++++-- .../floor-plan/modal/basic/step/Trestle.jsx | 24 +++++++++---------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 79e12280..3e22c508 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -91,14 +91,14 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useEffect(() => { if (roofsStore && addedRoofs) { console.log('🚀 ~ useEffect ~ roofsStore, addedRoofs:', roofsStore, addedRoofs) - // setRoofs( - // addedRoofs.map((roof, index) => { - // return { - // ...roof, - // ...roofsStore[index]?.addRoof, - // } - // }), - // ) + setRoofs( + addedRoofs.map((roof, index) => { + return { + ...roof, + ...roofsStore[index]?.addRoof, + } + }), + ) setModuleSelectionData({ ...moduleSelectionData, diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index 2ce0d536..de34aac6 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -5,15 +5,17 @@ import { getDegreeInOrientation } from '@/util/canvas-util' import { numberCheck } from '@/util/common-utils' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' 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 { moduleSelectionDataState } from '@/store/selectedModuleOptions' +import { roofsState } from '@/store/roofAtom' export const Orientation = forwardRef((props, ref) => { const { getMessage } = useMessage() const [hasAnglePassivity, setHasAnglePassivity] = useState(false) const basicSetting = useRecoilValue(basicSettingState) const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //지붕재 선택 + const setRoofsStore = useSetRecoilState(roofsState) const [roofTab, setRoofTab] = useState(0) //지붕재 탭 const { roofs, @@ -224,7 +226,9 @@ export const Orientation = forwardRef((props, ref) => { snowGdChecked: false, } }) - setRoofs(newRoofs) + // setRoofs(newRoofs) + // setAddedRoofs(newRoofs) + setRoofsStore(newRoofs) } return ( diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index b54c12ee..ab261be8 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -119,7 +119,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', + raftBaseCd: selectedRaftBase.clCode, trestleMkrCd: e.trestleMkrCd, }, }) @@ -132,8 +132,8 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', - trestleMkrCd: trestleState.trestleMkrCd, + raftBaseCd: selectedRaftBase.clCode, + trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: e.constMthdCd, }, }) @@ -146,9 +146,9 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', - trestleMkrCd: trestleState.trestleMkrCd, - constMthdCd: trestleState.constMthdCd, + raftBaseCd: selectedRaftBase.clCode, + trestleMkrCd: selectedTrestle.trestleMkrCd, + constMthdCd: selectedConstMthd.constMthdCd, roofBaseCd: e.roofBaseCd, illuminationTp: managementState?.surfaceTypeValue ?? '', instHt: managementState?.installHeight ?? '', @@ -187,10 +187,10 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', - trestleMkrCd: trestleState.trestleMkrCd, - constMthdCd: trestleState.constMthdCd, - roofBaseCd: trestleState.roofBaseCd, + raftBaseCd: selectedRaftBase.clCode, + trestleMkrCd: selectedTrestle.trestleMkrCd, + constMthdCd: selectedConstMthd.constMthdCd, + roofBaseCd: selectedRoofBase.roofBaseCd, illuminationTp: managementState?.surfaceTypeValue ?? '', instHt: managementState?.installHeight ?? '', stdWindSpeed: managementState?.standardWindSpeedId ?? '', @@ -219,7 +219,7 @@ const Trestle = forwardRef((props, ref) => { if (i === selectedRoof?.index) { return { ...selectedRoof, - ...trestleState, + trestle: trestleState, eavesMargin, ridgeMargin, kerabaMargin, @@ -268,8 +268,8 @@ const Trestle = forwardRef((props, ref) => { ...roof.addRoof, }, trestle: { - ...roof.trestle, ...moduleSelectionData.roofConstructions[index]?.trestle, + ...roof.trestle, }, construction: { ...moduleSelectionData.roofConstructions[index]?.construction, From 15cb2cf270614ebac9b94095b7eb7d52fe7c52b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 4 Apr 2025 11:32:32 +0900 Subject: [PATCH 092/196] =?UTF-8?q?roofIndex=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index c6dfa244..6bdfd8ce 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -267,6 +267,7 @@ const Trestle = forwardRef((props, ref) => { ...moduleSelectionData, roofConstructions: newAddedRoofs.map((roof, index) => { return { + roofIndex: index, addRoof: { ...moduleSelectionData.roofConstructions[index]?.addRoof, ...roof.addRoof, From 59f9377cc908793c8ee8a4f9e5a1bb2b36a888c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 4 Apr 2025 12:28:42 +0900 Subject: [PATCH 093/196] =?UTF-8?q?trestleDetail=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=EC=8B=9C=20trestle=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 4ca7082c..67b5a9b9 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -95,6 +95,7 @@ export function useModuleBasicSetting(tabNum) { return { ...common, ...item.addRoof, + ...item.trestle, roofPitch: item.addRoof.hajebichi ? item.addRoof.hajebichi : 0, inclCd: String(item.addRoof.pitch), } From 804911af3e9e56c59c0e1a3f3dd97be31f446796 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 4 Apr 2025 12:38:49 +0900 Subject: [PATCH 094/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=ED=98=BC=ED=95=A9?= =?UTF-8?q?=20=EC=88=98=20=EB=8F=99=EC=A0=81=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 121 +++++++++++---------------------- 1 file changed, 41 insertions(+), 80 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index ecb8ee55..af2e8e6a 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -370,25 +370,17 @@ export const useTrestle = () => { rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else if (leftRowsInfo.rowsInfo.length >= 2) { + } else { //C1C2C3인 경우 - if (rack.value.moduleTpCd.length === 6) { - // 변환 C1C2만 있는경우 C3 0개로 추가해준다. - let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo) + let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo) - return ( - rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp && - rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === newLeftRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === newLeftRowsInfo.rowsInfo[1].count && - Number(rack.value.moduleTpRows3) === newLeftRowsInfo.rowsInfo[2].count - ) - } return ( - rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && - rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count + rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp && + rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + newLeftRowsInfo.rowsInfo.every((row, index) => { + const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근 + return rackRowCount === row.count + }) ) } })?.value.racks @@ -400,24 +392,16 @@ export const useTrestle = () => { rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else if (rightRowsInfo.rowsInfo.length === 2) { - if (rack.value.moduleTpCd.length === 6) { - // 변환 C1C2만 있는경우 C3 0개로 추가해준다. - let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo) + } else { + let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo) - return ( - rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp && - rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === newRightRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === newRightRowsInfo.rowsInfo[1].count && - Number(rack.value.moduleTpRows3) === newRightRowsInfo.rowsInfo[2].count - ) - } return ( - rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && - rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count + rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp && + rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + newRightRowsInfo.rowsInfo.every((row, index) => { + const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근 + return rackRowCount === row.count + }) ) } })?.value.racks @@ -429,24 +413,16 @@ export const useTrestle = () => { rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else if (centerRowsInfo.rowsInfo.length === 2) { - if (rack.value.moduleTpCd.length === 6) { - // 변환 C1C2만 있는경우 C3 0개로 추가해준다. - let newCenterRowsInfo = normalizeModules(rack.value.moduleTpCd, centerRowsInfo) + } else { + let newCenterRowsInfo = normalizeModules(rack.value.moduleTpCd, centerRowsInfo) - return ( - rack.value.moduleTpCd === newCenterRowsInfo.moduleTotalTp && - rack.value.moduleRows === newCenterRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === newCenterRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === newCenterRowsInfo.rowsInfo[1].count && - Number(rack.value.moduleTpRows3) === newCenterRowsInfo.rowsInfo[2].count - ) - } return ( - rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && - rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === centerRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === centerRowsInfo.rowsInfo[1].count + rack.value.moduleTpCd === newCenterRowsInfo.moduleTotalTp && + rack.value.moduleRows === newCenterRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + newCenterRowsInfo.rowsInfo.every((row, index) => { + const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근 + return rackRowCount === row.count + }) ) } })?.value.racks @@ -536,24 +512,16 @@ export const useTrestle = () => { rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else if (leftRowsInfo.rowsInfo.length === 2) { - if (rack.value.moduleTpCd.length === 6) { - // 변환 C1C2만 있는경우 C3 0개로 추가해준다. - let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo) + } else { + let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo) - return ( - rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp && - rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === newLeftRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === newLeftRowsInfo.rowsInfo[1].count && - Number(rack.value.moduleTpRows3) === newLeftRowsInfo.rowsInfo[2].count - ) - } return ( - rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && - rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count + rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp && + rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + newLeftRowsInfo.rowsInfo.every((row, index) => { + const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근 + return rackRowCount === row.count + }) ) } })?.value.racks @@ -624,24 +592,17 @@ export const useTrestle = () => { rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) ) - } else if (rightRowsInfo.rowsInfo.length === 2) { - if (rack.value.moduleTpCd.length === 6) { - // 변환 C1C2만 있는경우 C3 0개로 추가해준다. - let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo) + } else { + // 변환 C1C2만 있는경우 C3 0개로 추가해준다. + let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo) - return ( - rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp && - rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === newRightRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === newRightRowsInfo.rowsInfo[1].count && - Number(rack.value.moduleTpRows3) === newRightRowsInfo.rowsInfo[2].count - ) - } return ( - rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && - rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count && - Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count + rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp && + rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + newRightRowsInfo.rowsInfo.every((row, index) => { + const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근 + return rackRowCount === row.count + }) ) } })?.value.racks From a316664b20ce4541e5422c6bc192e4cb5b4691be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 4 Apr 2025 12:47:50 +0900 Subject: [PATCH 095/196] =?UTF-8?q?addRoof,=20index=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 6bdfd8ce..d34c36fb 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -222,6 +222,7 @@ const Trestle = forwardRef((props, ref) => { if (i === selectedRoof?.index) { return { ...selectedRoof, + addRoof: roof, trestle: trestleState, eavesMargin, ridgeMargin, @@ -267,7 +268,7 @@ const Trestle = forwardRef((props, ref) => { ...moduleSelectionData, roofConstructions: newAddedRoofs.map((roof, index) => { return { - roofIndex: index, + roofIndex: roof.index, addRoof: { ...moduleSelectionData.roofConstructions[index]?.addRoof, ...roof.addRoof, From b8f05a6ff0a2cb09d2cc42cfc31b7e82583c8819 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 4 Apr 2025 13:15:21 +0900 Subject: [PATCH 096/196] =?UTF-8?q?fix:=20promise.all=20=ED=98=95=ED=83=9C?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Trestle.jsx | 95 ++++++++++--------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index d34c36fb..2b6be851 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -217,7 +217,7 @@ const Trestle = forwardRef((props, ref) => { } } - const isComplete = () => { + const isComplete = async () => { const newAddedRoofs = roofs.map((roof, i) => { if (i === selectedRoof?.index) { return { @@ -263,51 +263,60 @@ const Trestle = forwardRef((props, ref) => { console.log('newAddedRoofs', newAddedRoofs) if (result) { - setRoofs(newAddedRoofs) - setModuleSelectionData({ - ...moduleSelectionData, - roofConstructions: newAddedRoofs.map((roof, index) => { - return { - roofIndex: roof.index, - addRoof: { - ...moduleSelectionData.roofConstructions[index]?.addRoof, - ...roof.addRoof, - }, - trestle: { - ...moduleSelectionData.roofConstructions[index]?.trestle, - ...roof.trestle, - }, - construction: { - ...roof.construction, - ...moduleSelectionData.roofConstructions[index]?.construction, - }, - trestleDetail: { - ...roof.trestleDetail, - }, - } + const updatePromises = [ + new Promise((resolve) => { + setRoofs(newAddedRoofs) + resolve() }), - }) - trestleTrigger({ - roofConstruction: newAddedRoofs.map((roof) => { - return { - roofIndex: roof.index, - addRoof: { - ...roof, - }, - trestle: { - ...selectedTrestle, - raftBaseCd: roof.raftBaseCd, - }, - construction: { - ...constructionList.find((construction) => trestleState.constTp === construction.constTp), + new Promise((resolve) => { + setModuleSelectionData({ + ...moduleSelectionData, + roofConstructions: newAddedRoofs.map((roof, index) => ({ roofIndex: roof.index, - setupCover: roof.cvrYn === 'Y', - setupSnowCover: roof.snowGdYn === 'Y', - selectedIndex: roof.index, - }, - } + addRoof: { + ...moduleSelectionData.roofConstructions[index]?.addRoof, + ...roof.addRoof, + }, + trestle: { + ...moduleSelectionData.roofConstructions[index]?.trestle, + ...roof.trestle, + }, + construction: { + ...roof.construction, + ...moduleSelectionData.roofConstructions[index]?.construction, + }, + trestleDetail: { + ...roof.trestleDetail, + }, + })), + }) + resolve() }), - }) + new Promise((resolve) => { + trestleTrigger({ + roofConstruction: newAddedRoofs.map((roof) => ({ + roofIndex: roof.index, + addRoof: { + ...roof, + }, + trestle: { + ...selectedTrestle, + raftBaseCd: roof.raftBaseCd, + }, + construction: { + ...constructionList.find((construction) => trestleState.constTp === construction.constTp), + roofIndex: roof.index, + setupCover: roof.cvrYn === 'Y', + setupSnowCover: roof.snowGdYn === 'Y', + selectedIndex: roof.index, + }, + })), + }) + resolve() + }), + ] + + await Promise.all(updatePromises) } return result From d38acba7c9e8fdb3f45686b185a009b9fc38f6f7 Mon Sep 17 00:00:00 2001 From: ysCha Date: Fri, 4 Apr 2025 16:34:09 +0900 Subject: [PATCH 097/196] =?UTF-8?q?955-=EA=B2=AC=EC=A0=81=EC=84=9C=202?= =?UTF-8?q?=EC=B0=A8=20SAP=20=ED=8C=90=EB=A7=A4=EC=A0=90=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 109 +++++++++++++++++++-------- src/locales/ja.json | 1 + src/locales/ko.json | 1 + src/styles/_table.scss | 10 +++ 4 files changed, 91 insertions(+), 30 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index a544ced7..11a67b59 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -504,6 +504,7 @@ export default function Estimate({}) { saleStoreId: estimateContextState.sapSaleStoreId, sapSalesStoreCd: estimateContextState.sapSalesStoreCd, docTpCd: estimateContextState.estimateType, + secSapSalesStoreCd:(estimateContextState.secSapSalesStoreCd?.length > 0 && showPriceCd === 'QSP_PRICE')? estimateContextState.secSapSalesStoreCd :'', priceCd: showPriceCd, itemIdList: estimateContextState.itemList.filter((item) => item.delFlg === '0' && item.paDispOrder === null), } @@ -1216,6 +1217,23 @@ export default function Estimate({}) { } }, [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 (
@@ -1360,41 +1378,72 @@ export default function Estimate({}) { {getMessage('estimate.detail.estimateType')} *
diff --git a/src/locales/ja.json b/src/locales/ja.json index 1122d3d7..86a76864 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -905,6 +905,7 @@ "estimate.detail.estimateType": "注文分類", "estimate.detail.estimateType.yjss": "住宅PKG", "estimate.detail.estimateType.yjod": "積上げ(YJOD)", + "estimate.detail.agency": "2次店名", "estimate.detail.roofCns": "屋根材・施工区分", "estimate.detail.remarks": "備考", "estimate.detail.fileFlg": "後日資料提出", diff --git a/src/locales/ko.json b/src/locales/ko.json index abd8594b..7fb5f013 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -906,6 +906,7 @@ "estimate.detail.estimateType": "주문분류", "estimate.detail.estimateType.yjss": "住宅PKG", "estimate.detail.estimateType.yjod": "積上げ( YJOD )", + "estimate.detail.agency": "2차점명", "estimate.detail.roofCns": "지붕재・사양시공", "estimate.detail.remarks": "비고", "estimate.detail.fileFlg": "후일자료제출", diff --git a/src/styles/_table.scss b/src/styles/_table.scss index 5fe69afe..31b96bd9 100644 --- a/src/styles/_table.scss +++ b/src/styles/_table.scss @@ -47,6 +47,16 @@ table{ } .form-flex-wrap{ @include flexbox; + .form-flex-select{ + @include flexbox; + label{ + flex: none; + margin-right: 5px; + } + .form-select{ + min-width: 300px; + } + } } .date-picker-wrap{ width: 100%; From d6d626f2d7251461568265a8e30f76b497eab5d4 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 7 Apr 2025 14:35:23 +0900 Subject: [PATCH 098/196] =?UTF-8?q?=EC=96=91=EB=8B=A8=20=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 83 +++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index af2e8e6a..9671c88e 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -708,7 +708,9 @@ export const useTrestle = () => { }) // trestles 배열에서 null인 경우 제거 - const params = { trestles, pcses, modules } + + const dblCblTotCnt = getTotalConnectCableCnt() + const params = { trestles, pcses, modules, dblCblTotCnt } //견적서 itemList 조회 const { data, data2, result } = await getQuotationItem(params) @@ -2270,9 +2272,9 @@ export const useTrestle = () => { } return ( - (Math.abs(m1X - m2X) <= maxX && Math.abs(m1Y - m2Y) <= maxY) || - (Math.abs(Math.abs(m1X - m2X) - maxX / 2) <= halfMaxX && Math.abs(Math.abs(m1Y - m2Y) - maxY) <= halfMaxY) || - (Math.abs(Math.abs(m1X - m2X) - maxX) <= halfMaxX && Math.abs(Math.abs(m1Y - m2Y) - maxY / 2) <= halfMaxY) + (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 @@ -2292,9 +2294,9 @@ export const useTrestle = () => { } return ( - (Math.abs(m1X - m2X) <= maxY && Math.abs(m1Y - m2Y) <= maxX) || - (Math.abs(Math.abs(m1X - m2X) - maxY / 2) <= halfMaxY && Math.abs(Math.abs(m1Y - m2Y) - maxX) <= halfMaxX) || - (Math.abs(Math.abs(m1X - m2X) - maxY) <= halfMaxY && Math.abs(Math.abs(m1Y - m2Y) - maxX / 2) <= halfMaxX) + (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) ) } }) @@ -3035,6 +3037,73 @@ export const useTrestle = () => { return surfaces.every((surface) => surface.isComplete) } + 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, From f54850617974a2365cbbcbe541f25a89d9d7943e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 7 Apr 2025 18:21:31 +0900 Subject: [PATCH 099/196] =?UTF-8?q?moduleSelectionData=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 44 ++--- .../modal/basic/step/Orientation.jsx | 48 +++-- .../floor-plan/modal/basic/step/Trestle.jsx | 175 ++++++++++-------- src/hooks/module/useModuleTrestle.js | 92 ++++----- .../roofcover/useRoofAllocationSetting.js | 9 +- 5 files changed, 200 insertions(+), 168 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 3e22c508..2e8c471e 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -84,13 +84,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useModuleBasicSetting(tabNum) const { updateObjectDate } = useMasterController() - useEffect(() => { - if (managementState) console.log('managementState', managementState) - }, [managementState]) - useEffect(() => { if (roofsStore && addedRoofs) { - console.log('🚀 ~ useEffect ~ roofsStore, addedRoofs:', roofsStore, addedRoofs) setRoofs( addedRoofs.map((roof, index) => { return { @@ -104,15 +99,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { ...moduleSelectionData, roofConstructions: roofsStore.map((roof) => { return { - addRoof: { - ...roof.addRoof, - }, - construction: { - ...roof.construction, - }, - trestle: { - ...roof.trestle, - }, + roofIndex: roof.index, + addRoof: roof.addRoof, + construction: roof.construction, + trestle: roof.trestle, } }), }) @@ -148,9 +138,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const handleBtnNextStep = () => { if (tabNum === 1) { - console.log('moduleSelectionData', moduleSelectionData) orientationRef.current.handleNextStep() setAddedRoofs(roofs) + setTabNum(tabNum + 1) return } else if (tabNum === 2) { if (basicSetting.roofSizeSet !== '3') { @@ -169,14 +159,17 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { // }) // return // } - - if (!trestleRef.current.isComplete()) { - Swal.fire({ - title: getMessage('construction.length.difference'), - icon: 'warning', - }) - return - } + trestleRef.current.isComplete().then((res) => { + if (!res) { + Swal.fire({ + title: getMessage('construction.length.difference'), + icon: 'warning', + }) + return + } else { + // setTabNum(tabNum + 1) + } + }) //물건정보 갱신일 수정 } else { if (!isObjectNotEmpty(moduleSelectionData.module)) { @@ -186,10 +179,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { }) return } + + setTabNum(tabNum + 1) } } - - setTabNum(tabNum + 1) } const placementFlatRef = { @@ -262,6 +255,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const trestleProps = { roofs, setRoofs, + tabNum, setTabNum, moduleSelectionData, setModuleSelectionData, diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index de34aac6..ae03ca56 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -15,7 +15,7 @@ export const Orientation = forwardRef((props, ref) => { const [hasAnglePassivity, setHasAnglePassivity] = useState(false) const basicSetting = useRecoilValue(basicSettingState) const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //지붕재 선택 - const setRoofsStore = useSetRecoilState(roofsState) + const [roofsStore, setRoofsStore] = useRecoilState(roofsState) const [roofTab, setRoofTab] = useState(0) //지붕재 탭 const { roofs, @@ -67,7 +67,6 @@ export const Orientation = forwardRef((props, ref) => { useEffect(() => { if (selectedSurfaceType) { - console.log(roughnessCodes, selectedSurfaceType) setInputRoughness(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue)) } }, [selectedSurfaceType]) @@ -78,7 +77,6 @@ export const Orientation = forwardRef((props, ref) => { useEffect(() => { if (managementState?.installHeight && managementState?.installHeight) { - console.log('🚀 ~ useEffect ~ managementState:', managementState) setSelectedSurfaceType(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue)) setInputInstallHeight(managementState?.installHeight) setStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId)) @@ -87,10 +85,11 @@ export const Orientation = forwardRef((props, ref) => { }, [managementState]) useEffect(() => { - if (moduleSelectionData) { - console.log('moduleSelectionData', moduleSelectionData) + if (addedRoofs) { + setRoofs(addedRoofs) + // setAddedRoofs(roofsStore) } - }, [moduleSelectionData]) + }, [addedRoofs]) useImperativeHandle(ref, () => ({ handleNextStep, @@ -127,6 +126,7 @@ export const Orientation = forwardRef((props, ref) => { module: { ...selectedModules, }, + common, }) orientationTrigger({ compasDeg: inputCompasDeg, @@ -166,6 +166,7 @@ export const Orientation = forwardRef((props, ref) => { } const isComplete = () => { + if (!selectedModules) return false if (basicSetting && basicSetting.roofSizeSet !== '3') { if (inputInstallHeight <= 0) { return false @@ -211,19 +212,28 @@ export const Orientation = forwardRef((props, ref) => { const newRoofs = addedRoofs.map((roof) => { return { ...roof, - lengthBase: null, - trestleMkrCd: null, - constMthdCd: null, - constTp: null, - roofBaseCd: null, - ridgeMargin: null, - kerabaMargin: null, - eavesMargin: null, - roofPchBase: null, - cvrYn: 'N', - snowGdPossYn: 'N', - cvrChecked: false, - snowGdChecked: false, + trestle: { + lengthBase: null, + trestleMkrCd: null, + constMthdCd: null, + constTp: null, + roofBaseCd: null, + roofPchBase: null, + }, + addRoof: { + ...roof.addRoof, + lengthBase: null, + eavesMargin: null, + kerabaMargin: null, + ridgeMargin: null, + }, + construction: { + constTp: null, + cvrYn: 'N', + snowGdPossYn: 'N', + cvrChecked: false, + snowGdChecked: false, + }, } }) // setRoofs(newRoofs) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 2b6be851..a4ab7c27 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -7,16 +7,16 @@ import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' import { roofsState } from '@/store/roofAtom' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' -import { forwardRef, useContext, useEffect, useImperativeHandle, useState } from 'react' +import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' const Trestle = forwardRef((props, ref) => { - const { setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData } = props + const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData } = props const { getMessage } = useMessage() // const [selectedTrestle, setSelectedTrestle] = useState() const currentAngleType = useRecoilValue(currentAngleTypeSelector) const pitchText = useRecoilValue(pitchTextSelector) - const [selectedRoof, setSelectedRoof] = useState() + const [selectedRoof, setSelectedRoof] = useState(null) const { trestleState, trestleDetail, @@ -54,6 +54,8 @@ const Trestle = forwardRef((props, ref) => { const [selectedRoofBase, setSelectedRoofBase] = useState(null) const { managementState } = useContext(GlobalDataContext) const { restoreModuleInstArea } = useModuleBasicSetting() + const [flag, setFlag] = useState(false) + const tempModuleSelectionData = useRef(null) useEffect(() => { if (roofs && !selectedRoof) { @@ -64,9 +66,23 @@ const Trestle = forwardRef((props, ref) => { restoreModuleInstArea() }, [roofs]) + useEffect(() => {}, [moduleSelectionData]) + + useEffect(() => { + if (flag && moduleSelectionData) { + if (JSON.stringify(tempModuleSelectionData.current) === JSON.stringify(moduleSelectionData)) { + setTabNum(tabNum + 1) + } + } + }, [flag, moduleSelectionData]) + useEffect(() => { if (selectedRoof) { - dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, moduleTpCd: selectedModules.itemTp } }) + setHajebichi(selectedRoof.hajebichi) + setEavesMargin(selectedRoof?.eavesMargin ?? 0) + setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) + setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) + dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, ...moduleSelectionData } }) } }, [selectedRoof]) @@ -88,7 +104,7 @@ const Trestle = forwardRef((props, ref) => { useEffect(() => { if (constructionList.length > 0) { - setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.constTp) ?? null) + setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.construction?.constTp) ?? null) } }, [constructionList]) @@ -124,7 +140,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase.clCode, + raftBaseCd: selectedRaftBase?.clCode, trestleMkrCd: e.trestleMkrCd, }, }) @@ -137,7 +153,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase.clCode, + raftBaseCd: selectedRaftBase?.clCode, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: e.constMthdCd, }, @@ -151,7 +167,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase.clCode, + raftBaseCd: selectedRaftBase?.clCode, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: selectedConstMthd.constMthdCd, roofBaseCd: e.roofBaseCd, @@ -169,17 +185,24 @@ const Trestle = forwardRef((props, ref) => { if (i === selectedRoof.index) { return { ...selectedRoof, - ...trestleState, eavesMargin, ridgeMargin, kerabaMargin, - cvrYn, - snowGdPossYn, - cvrChecked, - snowGdChecked, + roofIndex: roof.index, + trestle: { + lengthBase: lengthBase, + ...selectedRaftBase, + ...selectedTrestle, + ...selectedConstMthd, + ...selectedRoofBase, + }, + construction: { + ...constructionList.find((data) => data.constTp === trestleState.constTp), + }, + trestleDetail: trestleDetail, } } - return { ...roof } + return roof }) setRoofs(newAddedRoofs) setSelectedRoof(newAddedRoofs[index]) @@ -192,7 +215,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase.clCode, + raftBaseCd: selectedRaftBase?.clCode, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: selectedConstMthd.constMthdCd, roofBaseCd: selectedRoofBase.roofBaseCd, @@ -200,7 +223,7 @@ const Trestle = forwardRef((props, ref) => { instHt: managementState?.installHeight ?? '', stdWindSpeed: managementState?.standardWindSpeedId ?? '', stdSnowLd: +managementState?.verticalSnowCover ?? '', - inclCd: selectedRoof?.pitch.toString() ?? 0, + inclCd: selectedRoof?.pitch ?? 0, roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), constTp: constructionList[index].constTp, mixMatlNo: selectedModules.mixMatlNo, @@ -219,86 +242,89 @@ const Trestle = forwardRef((props, ref) => { const isComplete = async () => { const newAddedRoofs = roofs.map((roof, i) => { - if (i === selectedRoof?.index) { + if (i === selectedRoof?.roofIndex) { return { ...selectedRoof, - addRoof: roof, - trestle: trestleState, eavesMargin, ridgeMargin, kerabaMargin, - cvrYn, - snowGdPossYn, - cvrChecked, - snowGdChecked, - trestleDetail, + roofIndex: roof.index, + trestle: { + lengthBase: lengthBase, + ...selectedRaftBase, + ...selectedTrestle, + ...selectedConstMthd, + ...selectedRoofBase, + }, + construction: { + ...constructionList.find((data) => data.constTp === trestleState.constTp), + }, + trestleDetail: trestleDetail, } } - return { ...roof } + return roof }) let result = true newAddedRoofs.forEach((roof) => { - if (roof.eavesMargin && roof.ridgeMargin && roof.kerabaMargin) { - return true + if (!roof?.eavesMargin || !roof?.ridgeMargin || !roof?.kerabaMargin) result = false + if (!roof.trestle?.trestleMkrCd) result = false + if (!roof.trestle?.constMthdCd) result = false + if (!roof.trestle?.roofBaseCd) result = false + if (!roof.construction?.constTp) result = false + + if (roof.lenAuth === 'C') { + if (!roof.trestle?.lengthBase) result = false + } + if (['C', 'R'].includes(roof.raftAuth)) { + if (!roof?.raftBaseCd) result = false } - if (!roof.trestleMkrCd) result = false - if (!roof.constMthdCd) result = false - if (!roof.roofBaseCd) result = false - if (!roof.constTp) result = false - - if (selectedRoof.lenAuth === 'C') { - if (!trestleState?.lengthBase) result = false - } - if (['C', 'R'].includes(selectedRoof.raftAuth)) { - if (!roof.raftBaseCd) result = false - } - - if (['C', 'R'].includes(selectedRoof.roofPchAuth)) { - if (!roof.roofPchBase) result = false + if (['C', 'R'].includes(roof.roofPchAuth)) { + if (!roof?.roofPchBase) result = false } }) - console.log('newAddedRoofs', newAddedRoofs) - + const newRoofs = newAddedRoofs.map((roof) => { + const { addRoof, trestle, construction, ...rest } = roof + return rest + }) if (result) { + setModuleSelectionData({ + ...moduleSelectionData, + roofConstructions: newAddedRoofs.map((roof, index) => ({ + roofIndex: roof.index, + trestle: roof.trestle, + addRoof: newRoofs[index], + construction: roof.construction, + trestleDetail: roof.trestleDetail, + })), + }) + setFlag(true) + tempModuleSelectionData.current = { + ...moduleSelectionData, + roofConstructions: newAddedRoofs.map((roof, index) => ({ + roofIndex: roof.index, + trestle: roof.trestle, + addRoof: newRoofs[index], + construction: roof.construction, + trestleDetail: roof.trestleDetail, + })), + } const updatePromises = [ + // new Promise((resolve) => { + // resolve() + // }), new Promise((resolve) => { - setRoofs(newAddedRoofs) - resolve() - }), - new Promise((resolve) => { - setModuleSelectionData({ - ...moduleSelectionData, - roofConstructions: newAddedRoofs.map((roof, index) => ({ - roofIndex: roof.index, - addRoof: { - ...moduleSelectionData.roofConstructions[index]?.addRoof, - ...roof.addRoof, - }, - trestle: { - ...moduleSelectionData.roofConstructions[index]?.trestle, - ...roof.trestle, - }, - construction: { - ...roof.construction, - ...moduleSelectionData.roofConstructions[index]?.construction, - }, - trestleDetail: { - ...roof.trestleDetail, - }, - })), - }) + setRoofs(newRoofs) resolve() }), + new Promise((resolve) => { trestleTrigger({ - roofConstruction: newAddedRoofs.map((roof) => ({ + roofConstruction: newAddedRoofs.map((roof, index) => ({ roofIndex: roof.index, - addRoof: { - ...roof, - }, + addRoof: newRoofs[index], trestle: { ...selectedTrestle, raftBaseCd: roof.raftBaseCd, @@ -317,11 +343,14 @@ const Trestle = forwardRef((props, ref) => { ] await Promise.all(updatePromises) + return true } - return result + return false } + const getFlag = () => {} + useImperativeHandle(ref, () => ({ isComplete, })) diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 6d0544e3..b6462887 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -20,24 +20,24 @@ const trestleReducer = (state, action) => { } case 'SET_INITIALIZE': return { - moduleTpCd: action.roof.moduleTpCd ?? '', - roofMatlCd: action.roof.roofMatlCd ?? '', - raftBaseCd: action.roof.raftBaseCd ?? null, - trestleMkrCd: action.roof.trestleMkrCd ?? null, - constMthdCd: action.roof.constMthdCd ?? null, - constTp: action.roof.constTp ?? null, - roofBaseCd: action.roof.roofBaseCd ?? null, + moduleTpCd: action.roof.module?.itemTp ?? '', + roofMatlCd: action.roof?.roofMatlCd ?? '', + raftBaseCd: action.roof?.raftBaseCd ?? null, + trestleMkrCd: action.roof.roofConstructions[action.roof.index].trestle?.trestleMkrCd ?? null, + constMthdCd: action.roof.roofConstructions[action.roof.index].trestle?.constMthdCd ?? null, + constTp: action.roof.roofConstructions[action.roof.index].construction?.constTp ?? null, + roofBaseCd: action.roof.roofConstructions[action.roof.index].trestle?.roofBaseCd ?? null, workingWidth: action.roof.workingWidth ?? 0, - lengthBase: action.roof.length ?? 0, - illuminationTp: action.roof.illuminationTp ?? null, - instHt: action.roof.instHt ?? null, - stdWindSpeed: action.roof.stdWindSpeed ?? null, - stdSnowLd: action.roof.stdSnowLd ?? null, - inclCd: action.roof.inclCd ?? null, - roofPitch: action.roof.roofPchBase ?? 0, - eavesMargin: action.roof.eavesMargin ?? null, - ridgeMargin: action.roof.ridgeMargin ?? null, - kerabaMargin: action.roof.kerabaMargin ?? null, + lengthBase: action.roof.roofConstructions[action.roof.index].addRoof?.length ?? 0, + illuminationTp: action.roof.common.illuminationTp ?? null, + instHt: action.roof.common.instHt ?? null, + stdWindSpeed: action.roof.common.stdWindSpeed ?? null, + stdSnowLd: action.roof.common.stdSnowLd ?? null, + inclCd: action.roof.roofConstructions[action.roof.index].addRoof?.pitch ?? null, + roofPitch: action.roof.roofConstructions[action.roof.index].addRoof?.roofPchBase ?? 0, + eavesMargin: action.roof.roofConstructions[action.roof.index].addRoof?.eavesMargin ?? null, + ridgeMargin: action.roof.roofConstructions[action.roof.index].addRoof?.ridgeMargin ?? null, + kerabaMargin: action.roof.roofConstructions[action.roof.index].addRoof?.kerabaMargin ?? null, } default: return state @@ -71,19 +71,19 @@ export function useModuleTrestle(props) { setConstMthdList([]) setRoofBaseList([]) setConstructionList([]) - setEavesMargin(selectedRoof?.eavesMargin ?? 0) - setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) - setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) - setCvrYn(selectedRoof?.cvrYn ?? 'N') - setCvrChecked(selectedRoof?.cvrChecked ?? false) - setSnowGdPossYn(selectedRoof?.snowGdPossYn ?? 'N') - setSnowGdChecked(selectedRoof?.snowGdChecked ?? false) + // setEavesMargin(selectedRoof?.addRoof?.eavesMargin ?? 0) + // setRidgeMargin(selectedRoof?.addRoof?.ridgeMargin ?? 0) + // setKerabaMargin(selectedRoof?.addRoof?.kerabaMargin ?? 0) + setCvrYn(selectedRoof?.construction?.cvrYn ?? 'N') + setCvrChecked(selectedRoof?.construction?.cvrChecked ?? false) + setSnowGdPossYn(selectedRoof?.construction?.snowGdPossYn ?? 'N') + setSnowGdChecked(selectedRoof?.construction?.snowGdChecked ?? false) }, [selectedRoof]) useEffect(() => { if (trestleState) { handleSetTrestleList() - if (!trestleState.trestleMkrCd) { + if (!trestleState?.trestleMkrCd) { setConstMthdList([]) setRoofBaseList([]) setConstructionList([]) @@ -92,7 +92,7 @@ export function useModuleTrestle(props) { } handleSetConstMthdList() - if (!trestleState.constMthdCd) { + if (!trestleState?.constMthdCd) { setRoofBaseList([]) setConstructionList([]) setTrestleDetail(null) @@ -100,19 +100,19 @@ export function useModuleTrestle(props) { } handleSetRoofBaseList() - if (!trestleState.roofBaseCd) { + if (!trestleState?.roofBaseCd) { setConstructionList([]) setTrestleDetail(null) return } handleSetConstructionList() - if (!trestleState.constTp) { + if (!trestleState?.constTp) { setTrestleDetail(null) return } - if (!trestleState.eavesMargin) { + if (!trestleState?.eavesMargin) { handleSetTrestleDetailData() } } @@ -120,9 +120,9 @@ export function useModuleTrestle(props) { const handleSetTrestleList = () => { getTrestleList({ - moduleTpCd: trestleState.moduleTpCd ?? '', - roofMatlCd: trestleState.roofMatlCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', + moduleTpCd: trestleState?.moduleTpCd ?? '', + roofMatlCd: trestleState?.roofMatlCd ?? '', + raftBaseCd: trestleState?.raftBaseCd ?? '', }).then((res) => { if (res?.data) setTrestleList(res.data) }) @@ -130,10 +130,10 @@ export function useModuleTrestle(props) { const handleSetConstMthdList = () => { getTrestleList({ - moduleTpCd: trestleState.moduleTpCd ?? '', - roofMatlCd: trestleState.roofMatlCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', - trestleMkrCd: trestleState.trestleMkrCd ?? '', + moduleTpCd: trestleState?.moduleTpCd ?? '', + roofMatlCd: trestleState?.roofMatlCd ?? '', + raftBaseCd: trestleState?.raftBaseCd ?? '', + trestleMkrCd: trestleState?.trestleMkrCd ?? '', }).then((res) => { if (res?.data) setConstMthdList(res.data) }) @@ -141,11 +141,11 @@ export function useModuleTrestle(props) { const handleSetRoofBaseList = () => { getTrestleList({ - moduleTpCd: trestleState.moduleTpCd ?? '', - roofMatlCd: trestleState.roofMatlCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', - trestleMkrCd: trestleState.trestleMkrCd ?? '', - constMthdCd: trestleState.constMthdCd ?? '', + moduleTpCd: trestleState?.moduleTpCd ?? '', + roofMatlCd: trestleState?.roofMatlCd ?? '', + raftBaseCd: trestleState?.raftBaseCd ?? '', + trestleMkrCd: trestleState?.trestleMkrCd ?? '', + constMthdCd: trestleState?.constMthdCd ?? '', }).then((res) => { if (res?.data) setRoofBaseList(res.data) }) @@ -153,11 +153,11 @@ export function useModuleTrestle(props) { const handleSetConstructionList = () => { getConstructionList({ - moduleTpCd: trestleState.moduleTpCd ?? '', - roofMatlCd: trestleState.roofMatlCd ?? '', - trestleMkrCd: trestleState.trestleMkrCd ?? '', - constMthdCd: trestleState.constMthdCd ?? '', - roofBaseCd: trestleState.roofBaseCd ?? '', + moduleTpCd: trestleState?.moduleTpCd ?? '', + roofMatlCd: trestleState?.roofMatlCd ?? '', + trestleMkrCd: trestleState?.trestleMkrCd ?? '', + constMthdCd: trestleState?.constMthdCd ?? '', + roofBaseCd: trestleState?.roofBaseCd ?? '', illuminationTp: trestleState.illuminationTp ?? '', instHt: trestleState.instHt ?? '', stdWindSpeed: trestleState.stdWindSpeed ?? '', diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 77ddb24c..675f2f7c 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -296,7 +296,7 @@ export function useRoofAllocationSetting(id) { }) } - return { ...roof, index: idx, raft: roof.raft ? roof.raft : roof.raftBaseCd, raftBaseCd: roof.raft ? roof.raft : roof.raftBaseCd } + return { ...roof, index: idx, raft: roof.raft ? roof.raft : roof.raftBaseCd } }) setBasicSetting((prev) => { @@ -308,8 +308,7 @@ export function useRoofAllocationSetting(id) { const selectedRoofMaterial = newRoofList.find((roof) => roof.selected) setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true) drawDirectionArrow(currentObject) - setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList }) - // modifyModuleSelectionData() + modifyModuleSelectionData() closeAll() basicSettingSave() } @@ -550,9 +549,9 @@ export function useRoofAllocationSetting(id) { * 모듈 선택에서 선택한 데이터 초기화 */ const modifyModuleSelectionData = () => { - if (moduleSelectionData.roofConstructions.length > 0) { + if (moduleSelectionData.roofConstructions?.length > 0) { setModuleSelectionData({ ...moduleSelectionData, roofConstructions: [] }) - moduleSelectedDataTrigger({ roofConstructions: [] }) + moduleSelectedDataTrigger({ ...moduleSelectionData, roofConstructions: [] }) } } From 468c7fda6fb11253c41087f8408e6eb641549098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 8 Apr 2025 13:03:23 +0900 Subject: [PATCH 100/196] =?UTF-8?q?moduleSelectionData=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 4 +- .../floor-plan/modal/basic/step/Placement.jsx | 4 +- .../floor-plan/modal/basic/step/Trestle.jsx | 112 ++++++++++-------- src/hooks/module/useModuleTrestle.js | 20 ++-- 4 files changed, 76 insertions(+), 64 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 2e8c471e..3dce3409 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -77,7 +77,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const { trigger: orientationTrigger } = useCanvasPopupStatusController(1) const { trigger: trestleTrigger } = useCanvasPopupStatusController(2) const { trigger: placementTrigger } = useCanvasPopupStatusController(3) - const roofsStore = useRecoilValue(roofsState) + const [roofsStore, setRoofsStore] = useRecoilState(roofsState) // const { initEvent } = useContext(EventContext) const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup } = @@ -95,6 +95,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { }), ) + console.log(roofsStore) setModuleSelectionData({ ...moduleSelectionData, roofConstructions: roofsStore.map((roof) => { @@ -255,6 +256,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const trestleProps = { roofs, setRoofs, + setRoofsStore, tabNum, setTabNum, moduleSelectionData, diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 726d3c24..9e4fe5b8 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -352,8 +352,8 @@ const Placement = forwardRef((props, refs) => { {moduleRowColArray[index]?.map((item) => ( diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index a4ab7c27..180807e4 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -6,12 +6,11 @@ import { useMessage } from '@/hooks/useMessage' import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' import { roofsState } from '@/store/roofAtom' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' -import { isObjectNotEmpty } from '@/util/common-utils' import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' const Trestle = forwardRef((props, ref) => { - const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData } = props + const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData, setRoofsStore } = props const { getMessage } = useMessage() // const [selectedTrestle, setSelectedTrestle] = useState() const currentAngleType = useRecoilValue(currentAngleTypeSelector) @@ -66,8 +65,6 @@ const Trestle = forwardRef((props, ref) => { restoreModuleInstArea() }, [roofs]) - useEffect(() => {}, [moduleSelectionData]) - useEffect(() => { if (flag && moduleSelectionData) { if (JSON.stringify(tempModuleSelectionData.current) === JSON.stringify(moduleSelectionData)) { @@ -82,7 +79,16 @@ const Trestle = forwardRef((props, ref) => { setEavesMargin(selectedRoof?.eavesMargin ?? 0) setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) - dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, ...moduleSelectionData } }) + setLengthBase(Math.round(selectedRoof?.lenBase ?? 0)) + 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, ...moduleSelectionData } }) + } } }, [selectedRoof]) @@ -180,33 +186,6 @@ const Trestle = forwardRef((props, ref) => { }, }) } - const handleChangeRoofMaterial = (index) => { - const newAddedRoofs = roofs.map((roof, i) => { - if (i === selectedRoof.index) { - return { - ...selectedRoof, - eavesMargin, - ridgeMargin, - kerabaMargin, - roofIndex: roof.index, - trestle: { - lengthBase: lengthBase, - ...selectedRaftBase, - ...selectedTrestle, - ...selectedConstMthd, - ...selectedRoofBase, - }, - construction: { - ...constructionList.find((data) => data.constTp === trestleState.constTp), - }, - trestleDetail: trestleDetail, - } - } - return roof - }) - setRoofs(newAddedRoofs) - setSelectedRoof(newAddedRoofs[index]) - } const handleConstruction = (index) => { if (constructionList[index]?.constPossYn === 'Y') { @@ -227,7 +206,7 @@ const Trestle = forwardRef((props, ref) => { roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), constTp: constructionList[index].constTp, mixMatlNo: selectedModules.mixMatlNo, - workingWidth: selectedRoof?.length.toString() ?? '', + workingWidth: selectedRoof?.length?.toString() ?? '', // snowGdPossYn: constructionList[index].snowGdPossYn, // cvrYn: constructionList[index].cvrYn, }, @@ -240,9 +219,38 @@ const Trestle = forwardRef((props, ref) => { } } + const handleChangeRoofMaterial = (index) => { + const newAddedRoofs = roofs.map((roof, i) => { + if (i === selectedRoof.index) { + return { + ...selectedRoof, + eavesMargin, + ridgeMargin, + kerabaMargin, + roofIndex: selectedRoof.index, + trestle: { + lengthBase: lengthBase, + ...selectedRaftBase, + ...selectedTrestle, + ...selectedConstMthd, + ...selectedRoofBase, + }, + construction: { + ...constructionList.find((data) => data.constTp === trestleState.constTp), + }, + trestleDetail: trestleDetail, + } + } + return roof + }) + setRoofs(newAddedRoofs) + setSelectedRoof(newAddedRoofs[index]) + console.log(newAddedRoofs) + } + const isComplete = async () => { const newAddedRoofs = roofs.map((roof, i) => { - if (i === selectedRoof?.roofIndex) { + if (i === selectedRoof?.index) { return { ...selectedRoof, eavesMargin, @@ -286,7 +294,7 @@ const Trestle = forwardRef((props, ref) => { }) const newRoofs = newAddedRoofs.map((roof) => { - const { addRoof, trestle, construction, ...rest } = roof + const { addRoof, construction, trestle, trestleDetail, roofConstructions, ...rest } = roof return rest }) if (result) { @@ -321,23 +329,25 @@ const Trestle = forwardRef((props, ref) => { }), new Promise((resolve) => { - trestleTrigger({ - roofConstruction: newAddedRoofs.map((roof, index) => ({ + const roofConstruction = newAddedRoofs.map((roof, index) => ({ + roofIndex: roof.index, + addRoof: newRoofs[index], + trestle: { + ...roof.trestle, + raftBaseCd: roof.raftBaseCd, + }, + construction: { + ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp), roofIndex: roof.index, - addRoof: newRoofs[index], - trestle: { - ...selectedTrestle, - raftBaseCd: roof.raftBaseCd, - }, - construction: { - ...constructionList.find((construction) => trestleState.constTp === construction.constTp), - roofIndex: roof.index, - setupCover: roof.cvrYn === 'Y', - setupSnowCover: roof.snowGdYn === 'Y', - selectedIndex: roof.index, - }, - })), + setupCover: roof.cvrYn === 'Y', + setupSnowCover: roof.snowGdYn === 'Y', + selectedIndex: roof.index, + }, + })) + trestleTrigger({ + roofConstruction, }) + setRoofsStore(roofConstruction) resolve() }), ] @@ -383,7 +393,7 @@ const Trestle = forwardRef((props, ref) => { setLengthBase(e.target.value)} disabled={selectedRoof.lenAuth === 'R'} /> diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index b6462887..70a57481 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -23,21 +23,21 @@ const trestleReducer = (state, action) => { moduleTpCd: action.roof.module?.itemTp ?? '', roofMatlCd: action.roof?.roofMatlCd ?? '', raftBaseCd: action.roof?.raftBaseCd ?? null, - trestleMkrCd: action.roof.roofConstructions[action.roof.index].trestle?.trestleMkrCd ?? null, - constMthdCd: action.roof.roofConstructions[action.roof.index].trestle?.constMthdCd ?? null, - constTp: action.roof.roofConstructions[action.roof.index].construction?.constTp ?? null, - roofBaseCd: action.roof.roofConstructions[action.roof.index].trestle?.roofBaseCd ?? null, + trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null, + constMthdCd: action.roof.trestle?.constMthdCd ?? null, + constTp: action.roof.construction?.constTp ?? null, + roofBaseCd: action.roof.trestle?.roofBaseCd ?? null, workingWidth: action.roof.workingWidth ?? 0, - lengthBase: action.roof.roofConstructions[action.roof.index].addRoof?.length ?? 0, + lengthBase: action.roof?.length ?? 0, illuminationTp: action.roof.common.illuminationTp ?? null, instHt: action.roof.common.instHt ?? null, stdWindSpeed: action.roof.common.stdWindSpeed ?? null, stdSnowLd: action.roof.common.stdSnowLd ?? null, - inclCd: action.roof.roofConstructions[action.roof.index].addRoof?.pitch ?? null, - roofPitch: action.roof.roofConstructions[action.roof.index].addRoof?.roofPchBase ?? 0, - eavesMargin: action.roof.roofConstructions[action.roof.index].addRoof?.eavesMargin ?? null, - ridgeMargin: action.roof.roofConstructions[action.roof.index].addRoof?.ridgeMargin ?? null, - kerabaMargin: action.roof.roofConstructions[action.roof.index].addRoof?.kerabaMargin ?? null, + inclCd: action.roof?.pitch ?? null, + roofPitch: action.roof?.roofPchBase ?? 0, + eavesMargin: action.roof?.eavesMargin ?? null, + ridgeMargin: action.roof?.ridgeMargin ?? null, + kerabaMargin: action.roof?.kerabaMargin ?? null, } default: return state From c35f3c1adb8f081ac5da430b0c7d5efd2119e73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 8 Apr 2025 14:19:03 +0900 Subject: [PATCH 101/196] =?UTF-8?q?moduleSelectionData=20trestleDetail=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 4 +-- .../floor-plan/modal/basic/step/Trestle.jsx | 35 ++++++++++++++----- src/hooks/module/useModuleTrestle.js | 8 ++--- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 3dce3409..7245f7b2 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -95,15 +95,15 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { }), ) - console.log(roofsStore) setModuleSelectionData({ ...moduleSelectionData, roofConstructions: roofsStore.map((roof) => { return { - roofIndex: roof.index, + roofIndex: roof.roofIndex, addRoof: roof.addRoof, construction: roof.construction, trestle: roof.trestle, + trestleDetail: roof.trestleDetail, } }), }) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 180807e4..fdfc8db1 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -87,30 +87,48 @@ const Trestle = forwardRef((props, ref) => { roof: { common: moduleSelectionData.common, module: moduleSelectionData.module, construction, trestle, trestleDetail, ...selectedRoof }, }) } else { - dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, ...moduleSelectionData } }) + dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, common: moduleSelectionData.common, module: moduleSelectionData.module } }) } } }, [selectedRoof]) 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]) 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]) 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]) 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]) useEffect(() => { if (constructionList.length > 0) { setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.construction?.constTp) ?? null) + } else { + setSelectedConstruction(null) } }, [constructionList]) @@ -301,7 +319,7 @@ const Trestle = forwardRef((props, ref) => { setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newAddedRoofs.map((roof, index) => ({ - roofIndex: roof.index, + roofIndex: newRoofs[index].index, trestle: roof.trestle, addRoof: newRoofs[index], construction: roof.construction, @@ -312,7 +330,7 @@ const Trestle = forwardRef((props, ref) => { tempModuleSelectionData.current = { ...moduleSelectionData, roofConstructions: newAddedRoofs.map((roof, index) => ({ - roofIndex: roof.index, + roofIndex: newRoofs[index].index, trestle: roof.trestle, addRoof: newRoofs[index], construction: roof.construction, @@ -330,7 +348,7 @@ const Trestle = forwardRef((props, ref) => { new Promise((resolve) => { const roofConstruction = newAddedRoofs.map((roof, index) => ({ - roofIndex: roof.index, + roofIndex: newRoofs[index].index, addRoof: newRoofs[index], trestle: { ...roof.trestle, @@ -343,6 +361,7 @@ const Trestle = forwardRef((props, ref) => { setupSnowCover: roof.snowGdYn === 'Y', selectedIndex: roof.index, }, + trestleDetail: roof.trestleDetail, })) trestleTrigger({ roofConstruction, diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 70a57481..ff6acb17 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -29,10 +29,10 @@ const trestleReducer = (state, action) => { roofBaseCd: action.roof.trestle?.roofBaseCd ?? null, workingWidth: action.roof.workingWidth ?? 0, lengthBase: action.roof?.length ?? 0, - illuminationTp: action.roof.common.illuminationTp ?? null, - instHt: action.roof.common.instHt ?? null, - stdWindSpeed: action.roof.common.stdWindSpeed ?? null, - stdSnowLd: action.roof.common.stdSnowLd ?? null, + illuminationTp: action.roof.common?.illuminationTp ?? null, + instHt: action.roof.common?.instHt ?? null, + stdWindSpeed: action.roof.common?.stdWindSpeed ?? null, + stdSnowLd: action.roof.common?.stdSnowLd ?? null, inclCd: action.roof?.pitch ?? null, roofPitch: action.roof?.roofPchBase ?? 0, eavesMargin: action.roof?.eavesMargin ?? null, From 91ccfcb20ea6d5c71b21090bf1dda703026f1409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 8 Apr 2025 15:16:44 +0900 Subject: [PATCH 102/196] =?UTF-8?q?DB=EC=97=90=EC=84=9C=20=EB=B6=88?= =?UTF-8?q?=EB=9F=AC=EC=98=A8=20=EA=B0=92=20roof=EC=97=90=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/BasicSetting.jsx | 3 +++ src/components/floor-plan/modal/basic/step/Trestle.jsx | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 7245f7b2..36ca8d50 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -91,6 +91,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { return { ...roof, ...roofsStore[index]?.addRoof, + construction: roofsStore[index]?.construction, + trestle: roofsStore[index]?.trestle, + trestleDetail: roofsStore[index]?.trestleDetail, } }), ) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index fdfc8db1..6e84805a 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -263,7 +263,6 @@ const Trestle = forwardRef((props, ref) => { }) setRoofs(newAddedRoofs) setSelectedRoof(newAddedRoofs[index]) - console.log(newAddedRoofs) } const isComplete = async () => { From 468980abbc423870e94e490224c991b36bf631d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 8 Apr 2025 15:54:31 +0900 Subject: [PATCH 103/196] =?UTF-8?q?roofConstruction=20=EC=B2=AB=EB=B2=88?= =?UTF-8?q?=EC=A7=B8=20trestleDetail=20null=EB=A1=9C=20=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Orientation.jsx | 10 ++++++++-- src/hooks/module/useModuleTrestle.js | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index ae03ca56..f78d4cd9 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -65,6 +65,12 @@ export const Orientation = forwardRef((props, ref) => { ], } + useEffect(() => { + if (selectedModules) { + setSelectedModules(moduleList.find((module) => module.itemId === selectedModules.itemId)) + } + }, [selectedModules]) + useEffect(() => { if (selectedSurfaceType) { setInputRoughness(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue)) @@ -312,8 +318,8 @@ export const Orientation = forwardRef((props, ref) => { {moduleList && ( handleChangeModule(e)} diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index ff6acb17..e657c3c0 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -78,6 +78,7 @@ export function useModuleTrestle(props) { setCvrChecked(selectedRoof?.construction?.cvrChecked ?? false) setSnowGdPossYn(selectedRoof?.construction?.snowGdPossYn ?? 'N') setSnowGdChecked(selectedRoof?.construction?.snowGdChecked ?? false) + setTrestleDetail(selectedRoof?.trestleDetail) }, [selectedRoof]) useEffect(() => { From 597aaa6d4298cf9bfdd6710f9e6f2750f5f466a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 8 Apr 2025 16:14:57 +0900 Subject: [PATCH 104/196] =?UTF-8?q?orientation=20module=20validation=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 10 +--------- .../floor-plan/modal/basic/step/Orientation.jsx | 12 +++++++++++- src/hooks/useCirCuitTrestle.js | 2 +- src/store/selectedModuleOptions.js | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 36ca8d50..cfbdffe9 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -144,18 +144,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { if (tabNum === 1) { orientationRef.current.handleNextStep() setAddedRoofs(roofs) - setTabNum(tabNum + 1) + // setTabNum(tabNum + 1) return } else if (tabNum === 2) { if (basicSetting.roofSizeSet !== '3') { - if (!isObjectNotEmpty(moduleSelectionData.module)) { - Swal.fire({ - title: getMessage('module.not.found'), - icon: 'warning', - }) - return - } - // if (addedRoofs.length !== moduleSelectionData.roofConstructions.length) { // Swal.fire({ // title: getMessage('construction.length.difference'), diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index f78d4cd9..c0352a38 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -9,6 +9,7 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import QSelectBox from '@/components/common/select/QSelectBox' import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { roofsState } from '@/store/roofAtom' +import Swal from 'sweetalert2' export const Orientation = forwardRef((props, ref) => { const { getMessage } = useMessage() @@ -150,6 +151,14 @@ export const Orientation = forwardRef((props, ref) => { userId: loginUserState.userId, //작성자아아디 }) setTabNum(2) + } else { + if (!selectedModules || !selectedModules.itemId) { + Swal.fire({ + title: getMessage('module.not.found'), + icon: 'warning', + }) + return + } } } @@ -172,7 +181,7 @@ export const Orientation = forwardRef((props, ref) => { } const isComplete = () => { - if (!selectedModules) return false + if (!selectedModules || !selectedModules.itemId) return false if (basicSetting && basicSetting.roofSizeSet !== '3') { if (inputInstallHeight <= 0) { return false @@ -190,6 +199,7 @@ export const Orientation = forwardRef((props, ref) => { } const handleChangeModule = (e) => { + console.log('hhㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗ') resetRoofs() setSelectedModules(e) } diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index 027b965a..ae90be97 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -31,7 +31,7 @@ export function useCircuitTrestle(executeEffect = false) { const { getMessage } = useMessage() useEffect(() => { - if (Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData() + if (selectedModules && Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData() }, [selectedModules]) const getOptYn = () => { diff --git a/src/store/selectedModuleOptions.js b/src/store/selectedModuleOptions.js index 5165fb48..7b769844 100644 --- a/src/store/selectedModuleOptions.js +++ b/src/store/selectedModuleOptions.js @@ -2,7 +2,7 @@ import { atom } from 'recoil' export const selectedModuleState = atom({ key: 'selectedModuleState', - default: [], + default: null, dangerouslyAllowMutability: true, }) From 7ff52a7b19457942f25469064519463b256a84b5 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 8 Apr 2025 16:33:06 +0900 Subject: [PATCH 105/196] =?UTF-8?q?QCast=20Front=20#886=20=EA=B2=AC?= =?UTF-8?q?=EC=A0=81=EC=84=9C=20OPEN=20=EC=A0=9C=ED=92=88=20=EB=8B=A8?= =?UTF-8?q?=EA=B0=80=ED=95=84=EB=93=9C=EC=97=90=20OPEN=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 116 ++++++++++++++------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 11a67b59..64b0ffbb 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -13,7 +13,7 @@ import dayjs from 'dayjs' import { useCommonCode } from '@/hooks/common/useCommonCode' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' 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 ProductFeaturesPop from './popup/ProductFeaturesPop' import { v4 as uuidv4 } from 'uuid' @@ -504,7 +504,8 @@ export default function Estimate({}) { saleStoreId: estimateContextState.sapSaleStoreId, sapSalesStoreCd: estimateContextState.sapSalesStoreCd, docTpCd: estimateContextState.estimateType, - secSapSalesStoreCd:(estimateContextState.secSapSalesStoreCd?.length > 0 && showPriceCd === 'QSP_PRICE')? estimateContextState.secSapSalesStoreCd :'', + secSapSalesStoreCd: + estimateContextState.secSapSalesStoreCd?.length > 0 && showPriceCd === 'QSP_PRICE' ? estimateContextState.secSapSalesStoreCd : '', priceCd: showPriceCd, itemIdList: estimateContextState.itemList.filter((item) => item.delFlg === '0' && item.paDispOrder === null), } @@ -1220,19 +1221,17 @@ export default function Estimate({}) { const [agencyCustList, setAgencyCustList] = useState([]) useEffect(() => { // 952 - 2차점 특가 sapSalesStoreCd - if(estimateContextState?.sapSalesStoreCd && session?.storeLvl === '1') { + 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); + setAgencyCustList(res?.data) } - }) } - }, [estimateContextState?.sapSalesStoreCd]) return (
@@ -1381,11 +1380,16 @@ export default function Estimate({}) {
{/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/} -
0 - && storePriceList[0].pkgRank !== null - && storePriceList[0].pkgRank !== '' - || estimateContextState?.estimateType === 'YJSS') ? "" : "none"}}> +
0 && storePriceList[0].pkgRank !== null && storePriceList[0].pkgRank !== '') || + estimateContextState?.estimateType === 'YJSS' + ? '' + : 'none', + }} + > {getMessage('estimate.detail.estimateType.yjod')}
- { (session?.storeLvl === '1' && agencyCustList.length > 0 )? ( -
- -
- { + 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 + })} + /> +
+
+ ) : ( + '' + )}
@@ -1932,16 +1938,12 @@ export default function Estimate({}) { } }} menuPlacement={'auto'} - getOptionLabel={(x) => x.itemName + " (" + x.itemNo + ")"} + getOptionLabel={(x) => x.itemName + ' (' + x.itemNo + ')'} getOptionValue={(x) => x.itemNo} components={{ - SingleValue:({children, ...props}) =>{ - return ( - - {props.data.itemName} - - ) - } + SingleValue: ({ children, ...props }) => { + return {props.data.itemName} + }, }} isClearable={false} isDisabled={!!item?.paDispOrder} @@ -1962,16 +1964,12 @@ export default function Estimate({}) { placeholder="Select" options={cableItemList} menuPlacement={'auto'} - getOptionLabel={(x) => x.clRefChr3 + " (" + x.clRefChr1 + ")"} + getOptionLabel={(x) => x.clRefChr3 + ' (' + x.clRefChr1 + ')'} getOptionValue={(x) => x.clRefChr1} components={{ - SingleValue:({children, ...props}) =>{ - return ( - - {props.data.clRefChr3} - - ) - } + SingleValue: ({ children, ...props }) => { + return {props.data.clRefChr3} + }, }} isClearable={false} isDisabled={true} @@ -2027,7 +2025,11 @@ export default function Estimate({}) { Date: Tue, 8 Apr 2025 17:43:19 +0900 Subject: [PATCH 106/196] =?UTF-8?q?trestleDetail=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 24 +++++----- .../floor-plan/modal/basic/step/Trestle.jsx | 3 ++ src/hooks/module/useModuleBasicSetting.js | 45 ++++++------------- src/hooks/module/useModuleSelection.js | 2 +- 4 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index cfbdffe9..17cd131b 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -84,6 +84,18 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { useModuleBasicSetting(tabNum) const { updateObjectDate } = useMasterController() + 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(() => { if (roofsStore && addedRoofs) { setRoofs( @@ -113,18 +125,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { } }, [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(() => { if (basicSetting.roofSizeSet !== '3') { manualModuleSetup() diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 6e84805a..3c0d8e8a 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -266,6 +266,8 @@ const Trestle = forwardRef((props, ref) => { } const isComplete = async () => { + console.log('roofs', roofs) + const newAddedRoofs = roofs.map((roof, i) => { if (i === selectedRoof?.index) { return { @@ -291,6 +293,7 @@ const Trestle = forwardRef((props, ref) => { }) let result = true + console.log('newAddedRoofs', newAddedRoofs) newAddedRoofs.forEach((roof) => { if (!roof?.eavesMargin || !roof?.ridgeMargin || !roof?.kerabaMargin) result = false if (!roof.trestle?.trestleMkrCd) result = false diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 67b5a9b9..e03f3852 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -91,16 +91,10 @@ export function useModuleBasicSetting(tabNum) { const roofConstructions = moduleSelectionData.roofConstructions if (roofConstructions && roofConstructions.length > 0) { - const listParams = roofConstructions.map((item) => { - return { - ...common, - ...item.addRoof, - ...item.trestle, - roofPitch: item.addRoof.hajebichi ? item.addRoof.hajebichi : 0, - inclCd: String(item.addRoof.pitch), - } - }) - setTrestleDetailParams(listParams) + //roofIndex 넣기 + const roofConstructionArray = roofConstructions.map((detail) => ({ ...detail.trestleDetail, roofIndex: detail.roofIndex })) + + setTrestleDetailList(roofConstructionArray) //북면 설치 가능 판매점 if (moduleSelectionData.common.saleStoreNorthFlg === '1') { @@ -119,23 +113,10 @@ export function useModuleBasicSetting(tabNum) { } } - //가대 상세 데이터 조회 - const getTrestleDetailListData = async () => { - const trestleDetailList = await getTrestleDetailList(trestleDetailParams) - if (trestleDetailList.length > 0) { - setTrestleDetailList(trestleDetailList) - } - } - - //가대 상세 데이터 파라메터 담기면 실행 - useEffect(() => { - if (trestleDetailParams.length > 0) { - getTrestleDetailListData(trestleDetailParams) - } - }, [trestleDetailParams]) - //가대 상세 데이터 들어오면 실행 useEffect(() => { + console.log('trestleDetailList', trestleDetailList) + if (trestleDetailList.length > 0) { let rowColArray = [] //지붕을 가져옴 @@ -147,11 +128,11 @@ export function useModuleBasicSetting(tabNum) { const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번 trestleDetailList.forEach((detail) => { - if (detail.data !== null) { - if (Number(detail.data.roofIndex) === roofIndex) { + if (isObjectNotEmpty(detail)) { + if (Number(detail.roofIndex) === roofIndex) { //roof에 상세 데이터 추가 roof.set({ - trestleDetail: detail.data, + trestleDetail: detail, stroke: roofOutlineColor(roofIndex), strokeWidth: 7, }) @@ -162,7 +143,7 @@ export function useModuleBasicSetting(tabNum) { line.attributes = { ...line.attributes, offset: getOffset(offsetObjects.addRoof, line.attributes.type) } }) //배치면 설치 영역 - makeModuleInstArea(roof, detail.data) + makeModuleInstArea(roof, detail) } } }) @@ -170,8 +151,8 @@ export function useModuleBasicSetting(tabNum) { trestleDetailList.forEach((detail) => { const moduleRowArray = [] - if (detail.data !== null && detail.data.module.length > 0) { - detail.data.module.forEach((module) => { + if (isObjectNotEmpty(detail) && detail.module.length > 0) { + detail.module.forEach((module) => { moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows }) }) } @@ -407,6 +388,8 @@ export function useModuleBasicSetting(tabNum) { //모듈,회로에서 다른메뉴 -> 배치면으로 갈 경수 초기화 const restoreModuleInstArea = () => { + console.log('tabnum', tabNum) + //설치면 삭제 const setupArea = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.OBJECT_SURFACE) diff --git a/src/hooks/module/useModuleSelection.js b/src/hooks/module/useModuleSelection.js index 1373ea05..3477cada 100644 --- a/src/hooks/module/useModuleSelection.js +++ b/src/hooks/module/useModuleSelection.js @@ -96,7 +96,7 @@ export function useModuleSelection(props) { getModuleData(roofsIds) //모듈설치면 초기화 - restoreModuleInstArea() + // restoreModuleInstArea() resetStatisticsData() }, []) From 9e9bd8f9c4ff25ec0b557f5cd5f34fe0bf7e8e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 9 Apr 2025 10:39:57 +0900 Subject: [PATCH 107/196] =?UTF-8?q?withDraggable=20spinner=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/basic/step/Orientation.jsx | 16 ++-- src/hooks/module/useModuleTrestle.js | 86 +++++++++++++------ 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index c0352a38..c9b5d296 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -51,6 +51,7 @@ export const Orientation = forwardRef((props, ref) => { } = props const [inputCompasDeg, setInputCompasDeg] = useState(compasDeg ?? 0) const [inputInstallHeight, setInputInstallHeight] = useState('0') + const [inputMargin, setInputMargin] = useState('0') const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState('0') const [inputRoughness, setInputRoughness] = useState(selectedSurfaceType) const [inputStandardWindSpeed, setInputStandardWindSpeed] = useState(standardWindSpeed) @@ -93,7 +94,7 @@ export const Orientation = forwardRef((props, ref) => { useEffect(() => { if (addedRoofs) { - setRoofs(addedRoofs) + // setRoofs(addedRoofs) // setAddedRoofs(roofsStore) } }, [addedRoofs]) @@ -113,6 +114,7 @@ export const Orientation = forwardRef((props, ref) => { saleStoreNorthFlg: managementState?.saleStoreNorthFlg, moduleTpCd: selectedModules.itemTp, moduleItemId: selectedModules.itemId, + margin: inputMargin, } setCompasDeg(inputCompasDeg) setInstallHeight(inputInstallHeight) @@ -199,7 +201,6 @@ export const Orientation = forwardRef((props, ref) => { } const handleChangeModule = (e) => { - console.log('hhㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗㅗ') resetRoofs() setSelectedModules(e) } @@ -383,23 +384,18 @@ export const Orientation = forwardRef((props, ref) => {
diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index b7ba409e..726d3c24 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -5,6 +5,7 @@ import { checkedModuleState, isManualModuleLayoutSetupState, isManualModuleSetupState, + moduleRowColArrayState, moduleSetupOptionState, toggleManualSetupModeState, } from '@/store/canvasAtom' @@ -36,6 +37,7 @@ const Placement = forwardRef((props, refs) => { const resetModuleSetupOption = useResetRecoilState(moduleSetupOptionState) const [colspan, setColspan] = useState(1) + const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState) //모듈 배치면 생성 useEffect(() => { @@ -62,6 +64,10 @@ const Placement = forwardRef((props, refs) => { } }, []) + useEffect(() => { + console.log('moduleRowColArray', moduleRowColArray) + }, [moduleRowColArray]) + //최초 지입시 체크 useEffect(() => { if (isObjectNotEmpty(moduleSelectionData)) { @@ -342,18 +348,18 @@ const Placement = forwardRef((props, refs) => {
- + {item.addRoof.roofMatlNmJp}
75{item.moduleMaxRows}{item.mixModuleMaxRows}
-
- {/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/} -
0 - && storePriceList[0].pkgRank !== null - && storePriceList[0].pkgRank !== '' - || estimateContextState?.estimateType === 'YJSS') ? "" : "none"}}> - { - //주문분류 - setHandlePricingFlag(true) - setEstimateContextState({ estimateType: e.target.value }) - }} - /> - +
+
+ {/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/} +
0 + && storePriceList[0].pkgRank !== null + && storePriceList[0].pkgRank !== '' + || estimateContextState?.estimateType === 'YJSS') ? "" : "none"}}> + { + //주문분류 + setHandlePricingFlag(true) + setEstimateContextState({ estimateType: e.target.value }) + }} + /> + +
+
+ { + setHandlePricingFlag(true) + setEstimateContextState({ estimateType: e.target.value }) + }} + /> + +
-
- 0 )? ( +
+ +
+
- - {item.addRoof.roofMatlNmJp} + + {item.addRoof?.roofMatlNmJp}
- {basicSetting && basicSetting.roofSizeSet === '3' && ( + {basicSetting && basicSetting.roofSizeSet == '3' && (
{getMessage('modal.module.basic.setting.module.placement.area')}
- setInputInstallHeight(e.target.value)} - /> + setInputMargin(e.target.value)} />
m
)}
- {basicSetting && basicSetting.roofSizeSet !== '3' && ( + {basicSetting && basicSetting.roofSizeSet != '3' && (
diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index e657c3c0..60b1a7fb 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -2,8 +2,9 @@ import { use, useContext, useEffect, useReducer, useState } from 'react' import { useCommonCode } from '../common/useCommonCode' import { useMasterController } from '../common/useMasterController' import { selectedModuleState } from '@/store/selectedModuleOptions' -import { useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue } from 'recoil' import { GlobalDataContext } from '@/app/GlobalDataProvider' +import { popSpinnerState } from '@/store/popupAtom' const RAFT_BASE_CODE = '203800' @@ -62,6 +63,7 @@ export function useModuleTrestle(props) { const [kerabaMargin, setKerabaMargin] = useState(0) const [trestleState, dispatch] = useReducer(trestleReducer, null) const [trestleDetail, setTrestleDetail] = useState(null) + const [popSpinnerStore, setPopSpinnerStore] = useRecoilState(popSpinnerState) useEffect(() => { const raftCodeList = findCommonCode(RAFT_BASE_CODE) @@ -120,39 +122,58 @@ export function useModuleTrestle(props) { }, [trestleState]) const handleSetTrestleList = () => { + setPopSpinnerStore(true) getTrestleList({ moduleTpCd: trestleState?.moduleTpCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '', 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 = () => { + setPopSpinnerStore(true) getTrestleList({ moduleTpCd: trestleState?.moduleTpCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '', raftBaseCd: trestleState?.raftBaseCd ?? '', 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 = () => { + setPopSpinnerStore(true) getTrestleList({ moduleTpCd: trestleState?.moduleTpCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '', raftBaseCd: trestleState?.raftBaseCd ?? '', trestleMkrCd: trestleState?.trestleMkrCd ?? '', 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 = () => { + setPopSpinnerStore(true) getConstructionList({ moduleTpCd: trestleState?.moduleTpCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '', @@ -166,12 +187,18 @@ export function useModuleTrestle(props) { inclCd: trestleState.inclCd ?? '', raftBaseCd: trestleState.raftBaseCd ?? '', 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 = () => { + setPopSpinnerStore(true) getTrestleDetailList([ { moduleTpCd: trestleState.moduleTpCd ?? '', @@ -189,24 +216,29 @@ export function useModuleTrestle(props) { roofPitch: trestleState.roofPitch ?? '', workingWidth: trestleState.workingWidth ?? '', }, - ]).then((res) => { - if (res.length > 0) { - if (!res[0].data) return - setEavesMargin(res[0].data.eaveIntvl) - setRidgeMargin(res[0].data.ridgeIntvl) - setKerabaMargin(res[0].data.kerabaIntvl) - setTrestleDetail(res[0].data) - // dispatch({ - // type: 'SET_TRESTLE_DETAIL', - // roof: { - // ...trestleState, - // eavesMargin: res[0].data.eaveIntvl, - // ridgeMargin: res[0].data.ridgeIntvl, - // kerabaMargin: res[0].data.kerabaIntvl, - // }, - // }) - } - }) + ]) + .then((res) => { + if (res.length > 0) { + if (!res[0].data) return + setEavesMargin(res[0].data.eaveIntvl) + setRidgeMargin(res[0].data.ridgeIntvl) + setKerabaMargin(res[0].data.kerabaIntvl) + setTrestleDetail(res[0].data) + // dispatch({ + // type: 'SET_TRESTLE_DETAIL', + // roof: { + // ...trestleState, + // eavesMargin: res[0].data.eaveIntvl, + // ridgeMargin: res[0].data.ridgeIntvl, + // kerabaMargin: res[0].data.kerabaIntvl, + // }, + // }) + } + setPopSpinnerStore(false) + }) + .catch((e) => { + setPopSpinnerStore(false) + }) } return { From 115544edb4b19b6cfb3b33ec069e8694972ec88e Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 9 Apr 2025 11:04:10 +0900 Subject: [PATCH 108/196] =?UTF-8?q?=EB=B2=88=EC=97=AD=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 4f345476..f8b76a17 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -604,6 +604,7 @@ "myinfo.message.password.error": "パスワードが間違っています。", "login": "ログイン", "login.auto.page.text": "自動ログイン中です。", + "login.fail": "계정이 없거나 비밀번호가 잘못되었습니다.", "login.id.save": "ID保存", "login.id.placeholder": "IDを入力してください。", "login.password.placeholder": "パスワードを入力してください。", @@ -1053,13 +1054,13 @@ "roof.line.not.found": "屋根形状がありません", "roof.material.can.not.delete": "割り当てられた配置面があります。", "chidory.can.not.install": "千鳥配置できない工法です。", - "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다. (JA)", - "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다. (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)", + "module.layout.setup.max.count": "モジュールの最大段数は{0}、最大列数は{1}です。 (JA)", + "module.layout.setup.max.count.multiple": "モジュール{0}の最大段数は{1}、最大列数は{2}です。 (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)" } From e940884312f5abb8a5f939706f5739a36ff59028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 9 Apr 2025 13:34:34 +0900 Subject: [PATCH 109/196] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=EC=9D=BC?= =?UTF-8?q?=EB=95=8C=20moduleSelectionData=20=EC=97=90=20margin=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 99 +++++++++---------- .../modal/basic/step/Orientation.jsx | 14 +-- src/hooks/module/useModuleSelection.js | 6 +- 3 files changed, 56 insertions(+), 63 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 17cd131b..cbabd3e3 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -1,34 +1,32 @@ -import { useMessage } from '@/hooks/useMessage' +import { POLYGON_TYPE } from '@/common/common' 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 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 { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' +import { useMasterController } from '@/hooks/common/useMasterController' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' +import { useModuleSelection } from '@/hooks/module/useModuleSelection' +import { useOrientation } from '@/hooks/module/useOrientation' +import { useMessage } from '@/hooks/useMessage' +import { usePopup } from '@/hooks/usePopup' import { - canvasSettingState, canvasState, checkedModuleState, + currentCanvasPlanState, 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' -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 { useMasterController } from '@/hooks/common/useMasterController' import { loginUserStore } from '@/store/commonAtom' -import { currentCanvasPlanState } from '@/store/canvasAtom' -import { POLYGON_TYPE } from '@/common/common' -import { useModuleSelection } from '@/hooks/module/useModuleSelection' -import { useOrientation } from '@/hooks/module/useOrientation' -import Trestle from './step/Trestle' 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 } }) { const { getMessage } = useMessage() @@ -49,7 +47,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const [roofs, setRoofs] = useState(addedRoofs) const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState) const [layoutSetup, setLayoutSetup] = useState([{}]) - const { moduleSelectionInitParams, selectedModules, @@ -140,6 +137,37 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { setIsManualModuleSetup(false) }, [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 = () => { if (tabNum === 1) { orientationRef.current.handleNextStep() @@ -260,37 +288,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { } const placementProps = {} - 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]) - return ( handleClosePopup(id)} /> diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index c9b5d296..3b5a55ad 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -67,6 +67,12 @@ export const Orientation = forwardRef((props, ref) => { ], } + useEffect(() => { + if (moduleSelectionData?.common) { + setInputMargin(moduleSelectionData?.common?.margin) + } + }, [moduleSelectionData]) + useEffect(() => { if (selectedModules) { setSelectedModules(moduleList.find((module) => module.itemId === selectedModules.itemId)) @@ -92,13 +98,6 @@ export const Orientation = forwardRef((props, ref) => { } }, [managementState]) - useEffect(() => { - if (addedRoofs) { - // setRoofs(addedRoofs) - // setAddedRoofs(roofsStore) - } - }, [addedRoofs]) - useImperativeHandle(ref, () => ({ handleNextStep, })) @@ -143,6 +142,7 @@ export const Orientation = forwardRef((props, ref) => { module: { ...selectedModules, }, + margin: inputMargin, }) updateObjectDataApi({ objectNo: currentCanvasPlan.objectNo, //오브젝트_no diff --git a/src/hooks/module/useModuleSelection.js b/src/hooks/module/useModuleSelection.js index 3477cada..c78ffff1 100644 --- a/src/hooks/module/useModuleSelection.js +++ b/src/hooks/module/useModuleSelection.js @@ -13,26 +13,22 @@ import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' export function useModuleSelection(props) { const canvas = useRecoilValue(canvasState) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) - const [roughnessCodes, setRoughnessCodes] = useState([]) //면조도 목록 const [windSpeedCodes, setWindSpeedCodes] = useState([]) //기준풍속 목록 const [moduleList, setModuleList] = useState([{}]) //모듈 목록 - const [selectedSurfaceType, setSelectedSurfaceType] = useState({}) //선택된 면조도 const [installHeight, setInstallHeight] = useState(managementState?.installHeight) //설치 높이 const [standardWindSpeed, setStandardWindSpeed] = useState() //기준풍속 const [verticalSnowCover, setVerticalSnowCover] = useState(managementState?.verticalSnowCover) //수직적설량 - const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈 + const [margin, setMargin] = useState(100) const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등 const { getModuleTypeItemList } = useMasterController() const { findCommonCode } = useCommonCode() const resetStatisticsData = useResetRecoilState(moduleStatisticsState) - const { restoreModuleInstArea } = useModuleBasicSetting() const bindInitData = () => { - console.log('bindInitData', managementState) setInstallHeight(managementState?.installHeight) setStandardWindSpeed(managementState?.standardWindSpeedId) setVerticalSnowCover(managementState?.verticalSnowCover) From c42e244f24027459b5174889dd783334926afcc2 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 9 Apr 2025 14:13:55 +0900 Subject: [PATCH 110/196] =?UTF-8?q?=EC=A2=8C=ED=91=9C=EA=B0=80=20=EC=9D=8C?= =?UTF-8?q?=EC=88=98=EC=9D=BC=EB=95=8C=20=EB=B3=B4=EC=A0=95=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index e03f3852..c7631dcb 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -388,8 +388,6 @@ export function useModuleBasicSetting(tabNum) { //모듈,회로에서 다른메뉴 -> 배치면으로 갈 경수 초기화 const restoreModuleInstArea = () => { - console.log('tabnum', tabNum) - //설치면 삭제 const setupArea = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.OBJECT_SURFACE) @@ -2494,8 +2492,9 @@ export function useModuleBasicSetting(tabNum) { } return acc }, - { x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스 + { x1: -Infinity, y1: -Infinity, index: -1 }, ) + flowArray.push(bottomFlow) const topFlow = surface.lines.reduce( @@ -2505,8 +2504,9 @@ export function useModuleBasicSetting(tabNum) { } return acc }, - { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스 + { x1: Infinity, y1: Infinity, index: -1 }, ) + flowArray.push(topFlow) let rtnObjArray = [] @@ -2557,9 +2557,6 @@ export function useModuleBasicSetting(tabNum) { //디버깅 const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { stroke: 'red', strokeWidth: 1, selectable: true }) - - // console.log(`index ${index} : finalLine`, pointX1, pointY1, pointX2, pointY2) - // canvas?.add(finalLine) // canvas?.renderAll() @@ -2610,8 +2607,9 @@ export function useModuleBasicSetting(tabNum) { } return acc }, - { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스 + { x1: Infinity, y1: Infinity, index: -1 }, ) + flowArray.push(leftFlow) const rightFlow = surface.lines.reduce( @@ -2621,8 +2619,9 @@ export function useModuleBasicSetting(tabNum) { } return acc }, - { x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스 + { x1: -Infinity, y1: -Infinity, index: -1 }, ) + flowArray.push(rightFlow) let rtnObjArray = [] From 29e8ca25a5914f7d568f74bce6abf1313c6793e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 9 Apr 2025 14:35:59 +0900 Subject: [PATCH 111/196] =?UTF-8?q?BasicSetting=20=ED=95=98=EB=8B=A8=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=A6=AC=ED=8E=99=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index cbabd3e3..3087fe54 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -322,22 +322,19 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
{/* {tabNum === 1 && } */} - - {tabNum !== 1 && ( - - )} - {/*{tabNum !== 3 && }*/} - {tabNum !== 3 && ( - - )} - - {tabNum === 3 && ( + {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( <> - {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( + {tabNum !== 1 && ( + + )} + {tabNum !== 3 && ( + + )} + {tabNum === 3 && ( <> )} - {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( + + )} + {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( + <> + {tabNum === 1 && ( + + )} + {tabNum === 2 && ( <> - + - From c869e9d5a304aecf468d7385c29ad1170cf8d90f Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 9 Apr 2025 16:56:43 +0900 Subject: [PATCH 112/196] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 8 +- .../modal/basic/step/Orientation.jsx | 17 +- .../modal/basic/step/pitch/PitchPlacement.jsx | 168 +++++++++--------- src/hooks/module/useModuleBasicSetting.js | 39 ++-- src/locales/ja.json | 6 +- 5 files changed, 130 insertions(+), 108 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 3087fe54..7e026584 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -77,11 +77,13 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const [roofsStore, setRoofsStore] = useRecoilState(roofsState) // const { initEvent } = useContext(EventContext) - const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup } = + const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup, restoreModuleInstArea } = useModuleBasicSetting(tabNum) const { updateObjectDate } = useMasterController() useEffect(() => { + const moduleTabNum = basicSetting.roofSizeSet != 3 ? 3 : 2 + let hasModules = canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) @@ -89,7 +91,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { if (hasModules) { orientationRef.current.handleNextStep() - setTabNum(3) + setTabNum(moduleTabNum) } }, []) @@ -364,7 +366,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { - diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index 3b5a55ad..a6b54bd0 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -1,14 +1,12 @@ import { forwardRef, use, useContext, useEffect, useImperativeHandle, useState } from 'react' import { useMessage } from '@/hooks/useMessage' -import { useOrientation } from '@/hooks/module/useOrientation' import { getDegreeInOrientation } from '@/util/canvas-util' import { numberCheck } from '@/util/common-utils' -import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { addedRoofsState, basicSettingState } from '@/store/settingAtom' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' 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) => { @@ -55,6 +53,7 @@ export const Orientation = forwardRef((props, ref) => { const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState('0') const [inputRoughness, setInputRoughness] = useState(selectedSurfaceType) const [inputStandardWindSpeed, setInputStandardWindSpeed] = useState(standardWindSpeed) + const { restoreModuleInstArea } = useModuleBasicSetting() const moduleData = { header: [ { name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' }, @@ -67,6 +66,12 @@ export const Orientation = forwardRef((props, ref) => { ], } + useEffect(() => { + if (basicSetting.roofSizeSet == '3') { + restoreModuleInstArea() + } + }, []) + useEffect(() => { if (moduleSelectionData?.common) { setInputMargin(moduleSelectionData?.common?.margin) @@ -108,7 +113,7 @@ export const Orientation = forwardRef((props, ref) => { illuminationTp: inputRoughness.clCode, illuminationTpNm: inputRoughness.clCodeNm, instHt: inputInstallHeight, - stdWindSpeed: inputStandardWindSpeed.clCode, + stdWindSpeed: inputStandardWindSpeed?.clCode, stdSnowLd: inputVerticalSnowCover, saleStoreNorthFlg: managementState?.saleStoreNorthFlg, moduleTpCd: selectedModules.itemTp, @@ -125,7 +130,7 @@ export const Orientation = forwardRef((props, ref) => { ...managementState, installHeight: inputInstallHeight, verticalSnowCover: inputVerticalSnowCover, - standardWindSpeedId: inputStandardWindSpeed.clCode, + standardWindSpeedId: inputStandardWindSpeed?.clCode, surfaceType: inputRoughness.clCodeNm, surfaceTypeValue: inputRoughness.clCode, }) @@ -146,7 +151,7 @@ export const Orientation = forwardRef((props, ref) => { }) updateObjectDataApi({ objectNo: currentCanvasPlan.objectNo, //오브젝트_no - standardWindSpeedId: inputStandardWindSpeed.clCode, //기준풍속코드 + standardWindSpeedId: inputStandardWindSpeed?.clCode, //기준풍속코드 verticalSnowCover: inputVerticalSnowCover, //적설량 surfaceType: inputRoughness.clCodeNm, //면조도구분 installHeight: inputInstallHeight, //설치높이 diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx index b4137ac6..d1810bd4 100644 --- a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx @@ -33,14 +33,6 @@ const PitchPlacement = forwardRef((props, refs) => { 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(() => { const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key]) @@ -105,87 +97,91 @@ const PitchPlacement = forwardRef((props, refs) => { return ( <> -
-
-
- - - - {moduleData.header.map((data) => ( - + + + + {selectedModules.itemList && + selectedModules.itemList.map((item, index) => ( + + + + + ))} + +
- {data.type === 'check' ? ( -
- - -
- ) : ( - data.name - )} +
+
+
+
+ + + + - ))} - - - - {selectedModules.itemList && - selectedModules.itemList.map((item, index) => ( - - - - - - ))} - -
+
+ + +
-
- - -
-
-
- - {item.itemNm} -
-
{item.wpOut}
+
{getMessage('module')}
+
+ + +
+
+
+ + {item.itemNm} +
+
+
-
-
-
-
-
-
{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting')}
-
-
-
-
- - -
-
- - -
-
+
+
+
+ + + + + + + + + + + +
{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting')}
+
+
+ + +
+
+ + +
+
+
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index c7631dcb..1a71c671 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -83,8 +83,6 @@ export function useModuleBasicSetting(tabNum) { //모듈 선택에서 선택된 값들 넘어옴 const makeModuleInitArea = () => { - console.log('moduleSelectionData', moduleSelectionData) - if (isObjectNotEmpty(moduleSelectionData) && tabNum === 3) { if (canvasSetting.roofSizeSet !== '3') { const common = moduleSelectionData.common @@ -115,8 +113,6 @@ export function useModuleBasicSetting(tabNum) { //가대 상세 데이터 들어오면 실행 useEffect(() => { - console.log('trestleDetailList', trestleDetailList) - if (trestleDetailList.length > 0) { let rowColArray = [] //지붕을 가져옴 @@ -258,8 +254,10 @@ export function useModuleBasicSetting(tabNum) { const allPointsOutside = result.every((point) => !originPolygon.inPolygon(point)) if (canvasSetting.roofSizeSet == '3') { + const margin = moduleSelectionData.common.margin ? moduleSelectionData.common.margin : 200 + //육지붕일때는 그냥 하드코딩 - offsetPoints = offsetPolygon(roof.points, -30) //육지붕일때 + offsetPoints = offsetPolygon(roof.points, -Number(margin) / 10) //육지붕일때 } else { //육지붕이 아닐때 if (allPointsOutside) { @@ -410,7 +408,7 @@ export function useModuleBasicSetting(tabNum) { } useEffect(() => { - if (canvasSetting.roofSizeSet !== '3') { + if (canvasSetting.roofSizeSet != '3') { if (isObjectNotEmpty(moduleSelectionData) && moduleSelectionData.common.saleStoreNorthFlg === '1') { setSaleStoreNorthFlg(true) } @@ -2833,7 +2831,7 @@ export function useModuleBasicSetting(tabNum) { targetRoof.fire('modified') targetSurface.fire('modified') - drawDirectionArrow(targetRoof) + // drawDirectionArrow(targetRoof) } canvas.remove(obj) }) @@ -2845,7 +2843,7 @@ export function useModuleBasicSetting(tabNum) { targetRoof.fire('modified') surface.fire('modified') - drawDirectionArrow(targetRoof) + // drawDirectionArrow(targetRoof) }) } canvas.renderAll() @@ -3081,6 +3079,17 @@ export function useModuleBasicSetting(tabNum) { addCanvasMouseEventListener('mouse:up', (e) => { let isIntersection = true + + if (trestlePolygon.modules.length > 0) { + //이미 설치된 모듈중에 한개만 가져옴 + const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn + //현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능 + if (checkedModule[0].mixAsgYn !== mixAsgYn) { + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) + return + } + } + if (!inside) return if (tempModule) { const rectPoints = [ @@ -3154,6 +3163,16 @@ export function useModuleBasicSetting(tabNum) { const autoFlatroofModuleSetup = (placementFlatRef) => { initEvent() //마우스 이벤트 초기화 + //혼합 가능 모듈과 혼합 불가능 모듈을 선택했을때 카운트를 해서 확인 + const mixAsgY = checkedModule.filter((obj) => obj.mixAsgYn === 'Y') + const mixAsgN = checkedModule.filter((obj) => obj.mixAsgYn === 'N') + + //Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가 + if (mixAsgY.length > 0 && mixAsgN.length > 0) { + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) + return + } + const moduleSetupSurfaces = moduleSetupSurface //선택 설치면 const notSelectedTrestlePolygons = canvas ?.getObjects() @@ -3219,7 +3238,7 @@ export function useModuleBasicSetting(tabNum) { targetRoof.setCoords() targetSurface.setCoords() moduleSetupSurfaces.push(targetSurface) - drawDirectionArrow(targetSurface) + // drawDirectionArrow(targetSurface) } canvas.remove(obj) }) @@ -3231,7 +3250,7 @@ export function useModuleBasicSetting(tabNum) { targetRoof.fire('modified') surface.fire('modified') - drawDirectionArrow(surface) + // drawDirectionArrow(surface) }) } canvas.renderAll() diff --git a/src/locales/ja.json b/src/locales/ja.json index f8b76a17..5849f3da 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -128,9 +128,9 @@ "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒の側", "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "龍丸側", "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.south": "南向き設置", - "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "指定した辺を基準に設置", + "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.select": "指定した辺を基準に設置する", "modal.module.basic.setting.pitch.module.allocation.setting": "割り当て設定", "modal.module.basic.setting.pitch.module.allocation.setting.info": "※配置パネルの種類が1種類の場合のみ使用できます。", "modal.module.basic.setting.pitch.module.row.amount": "単数", From 11cf3b840352c77449bf632a38f83754aee48f20 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 9 Apr 2025 17:18:58 +0900 Subject: [PATCH 113/196] =?UTF-8?q?chore:=20=EB=82=B4=EB=B6=80=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=20=EC=84=9C=EB=B2=84=20=EA=B8=B0=EB=8F=99=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=8B=A4=ED=96=89=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 추후에 제거 예정 --- startscript-3000.js | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 startscript-3000.js diff --git a/startscript-3000.js b/startscript-3000.js new file mode 100644 index 00000000..9130126e --- /dev/null +++ b/startscript-3000.js @@ -0,0 +1,2 @@ +var exec = require('child_process').exec +exec('yarn dev -p 3000', { windowsHide: true }) From defebb21d7de4637066acf6fe6b44fcfabc2907a Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 9 Apr 2025 17:20:05 +0900 Subject: [PATCH 114/196] =?UTF-8?q?chore:=20=EB=82=B4=EB=B6=80=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=EC=84=9C=EB=B2=84=EC=9A=A9=20=EC=8B=A4=ED=96=89=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- startscript-3000.js | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 startscript-3000.js diff --git a/startscript-3000.js b/startscript-3000.js new file mode 100644 index 00000000..9130126e --- /dev/null +++ b/startscript-3000.js @@ -0,0 +1,2 @@ +var exec = require('child_process').exec +exec('yarn dev -p 3000', { windowsHide: true }) From 8662a371772cd4201c2d4b63ed253e0554516cee Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 9 Apr 2025 17:22:55 +0900 Subject: [PATCH 115/196] =?UTF-8?q?#=20974=20-=20=EC=A7=80=EB=B6=95?= =?UTF-8?q?=ED=98=95=EC=83=81=20=EC=84=A4=EC=A0=95=20=EC=A0=84=20=ED=8C=9D?= =?UTF-8?q?=EC=97=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useOuterLineWall.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks/roofcover/useOuterLineWall.js b/src/hooks/roofcover/useOuterLineWall.js index bced656b..18a07cf8 100644 --- a/src/hooks/roofcover/useOuterLineWall.js +++ b/src/hooks/roofcover/useOuterLineWall.js @@ -32,6 +32,7 @@ import { outlineDisplaySelector } from '@/store/settingAtom' import { usePopup } from '@/hooks/usePopup' import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting' import Big from 'big.js' +import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting' //외벽선 그리기 export function useOuterLineWall(id, propertiesId) { @@ -256,7 +257,7 @@ export function useOuterLineWall(id, propertiesId) { canvas?.renderAll() setOuterLineFix(true) closePopup(id) - addPopup(propertiesId, 1, ) + addPopup(propertiesId, 1, ) } if (points.length < 3) { From 546133c27e70e07dfc152cbd3af481ad874d0e31 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 9 Apr 2025 17:29:37 +0900 Subject: [PATCH 116/196] =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=AC=B8=EA=B5=AC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index a584876c..2874435d 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1000,9 +1000,7 @@ export const useTrestle = () => { if (!rackInfos) { const maxRows = surface.trestleDetail.moduleMaxRows const maxCols = surface.trestleDetail.moduleMaxCols - const msg = `選択した家で設置可能 -モジュールの最大段数は${maxRows}、最大列数は${maxCols}です。 -上限より上部に取り付けたモジュールを削除してください。` + const msg = `段数の上限は${maxRows}段です。 上限より上の段には設置できません` swalFire({ title: msg, type: 'alert' }) throw new Error('rackInfos is null') } From 82210a99c9264d37dd3bfd28267c5db079597686 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 10 Apr 2025 10:45:36 +0900 Subject: [PATCH 117/196] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=98=A4?= =?UTF-8?q?=ED=94=88=ED=94=8C=EB=9E=98=EA=B7=B8=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 64b0ffbb..e2c6c088 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -2057,15 +2057,17 @@ export default function Estimate({}) {
- {convertNumberToPriceDecimal( - item?.showSaleTotPrice === '0' - ? null - : item?.amount === '' - ? null - : item?.saleTotPrice === '0' + {item?.openFlg === '1' + ? 'OPEN' + : convertNumberToPriceDecimal( + item?.showSaleTotPrice === '0' ? null - : item?.saleTotPrice?.replaceAll(',', ''), - )} + : item?.amount === '' + ? null + : item?.saleTotPrice === '0' + ? null + : item?.saleTotPrice?.replaceAll(',', ''), + )} ) From 74b3c6dac70a92de91b2d86ad0bce4a801254f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 10:46:01 +0900 Subject: [PATCH 118/196] =?UTF-8?q?=EC=B2=98=EB=A7=88=EB=A0=A5=20=EC=BB=A4?= =?UTF-8?q?=EB=B2=84=20=EC=84=A4=EC=B9=98=EC=97=AC=EB=B6=80=20,=20?= =?UTF-8?q?=EC=A0=81=EC=84=A4=EB=B0=A9=EC=A7=80=EA=B8=88=EA=B5=AC=EC=84=A4?= =?UTF-8?q?=EC=B9=98=20=EC=97=AC=EB=B6=80=20=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Trestle.jsx | 32 +++++++++++-------- src/hooks/module/useModuleTrestle.js | 18 +++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 3c0d8e8a..c8ece93c 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -31,6 +31,10 @@ const Trestle = forwardRef((props, ref) => { setEavesMargin, setRidgeMargin, setKerabaMargin, + lengthBase, + setLengthBase, + hajebichi, + setHajebichi, cvrYn, cvrChecked, snowGdPossYn, @@ -44,8 +48,6 @@ const Trestle = forwardRef((props, ref) => { }) const selectedModules = useRecoilValue(selectedModuleState) //선택된 모듈 // const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) - const [lengthBase, setLengthBase] = useState(0) - const [hajebichi, setHajebichi] = useState(0) const [selectedRaftBase, setSelectedRaftBase] = useState(null) const [selectedTrestle, setSelectedTrestle] = useState(null) const [selectedConstMthd, setSelectedConstMthd] = useState(null) @@ -75,11 +77,6 @@ const Trestle = forwardRef((props, ref) => { useEffect(() => { if (selectedRoof) { - setHajebichi(selectedRoof.hajebichi) - setEavesMargin(selectedRoof?.eavesMargin ?? 0) - setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) - setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) - setLengthBase(Math.round(selectedRoof?.lenBase ?? 0)) if (moduleSelectionData?.roofConstructions?.length >= selectedRoof.index + 1) { const { construction, trestle, trestleDetail } = moduleSelectionData?.roofConstructions[selectedRoof.index] dispatch({ @@ -223,10 +220,10 @@ const Trestle = forwardRef((props, ref) => { inclCd: selectedRoof?.pitch ?? 0, roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), constTp: constructionList[index].constTp, + snowGdPossYn: constructionList[index].snowGdPossYn, + cvrYn: constructionList[index].cvrYn, mixMatlNo: selectedModules.mixMatlNo, workingWidth: selectedRoof?.length?.toString() ?? '', - // snowGdPossYn: constructionList[index].snowGdPossYn, - // cvrYn: constructionList[index].cvrYn, }, }) @@ -247,6 +244,7 @@ const Trestle = forwardRef((props, ref) => { kerabaMargin, roofIndex: selectedRoof.index, trestle: { + hajebichi: hajebichi, lengthBase: lengthBase, ...selectedRaftBase, ...selectedTrestle, @@ -255,6 +253,10 @@ const Trestle = forwardRef((props, ref) => { }, construction: { ...constructionList.find((data) => data.constTp === trestleState.constTp), + cvrYn: cvrYn, + snowGdPossYn: snowGdPossYn, + cvrChecked: cvrChecked, + snowGdChecked: snowGdChecked, }, trestleDetail: trestleDetail, } @@ -278,6 +280,7 @@ const Trestle = forwardRef((props, ref) => { roofIndex: roof.index, trestle: { lengthBase: lengthBase, + hajebichi: hajebichi, ...selectedRaftBase, ...selectedTrestle, ...selectedConstMthd, @@ -285,6 +288,10 @@ const Trestle = forwardRef((props, ref) => { }, construction: { ...constructionList.find((data) => data.constTp === trestleState.constTp), + cvrYn, + snowGdPossYn, + cvrChecked, + snowGdChecked, }, trestleDetail: trestleDetail, } @@ -357,7 +364,8 @@ const Trestle = forwardRef((props, ref) => { raftBaseCd: roof.raftBaseCd, }, construction: { - ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp), + // ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp), + ...roof.construction, roofIndex: roof.index, setupCover: roof.cvrYn === 'Y', setupSnowCover: roof.snowGdYn === 'Y', @@ -380,8 +388,6 @@ const Trestle = forwardRef((props, ref) => { return false } - const getFlag = () => {} - useImperativeHandle(ref, () => ({ isComplete, })) @@ -553,7 +559,7 @@ const Trestle = forwardRef((props, ref) => { dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, snowGdChecked: !trestleState.snowGdChecked } })} onChange={() => setSnowGdChecked(!snowGdChecked)} diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 60b1a7fb..5c50a706 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -54,6 +54,9 @@ export function useModuleTrestle(props) { const [roofBaseList, setRoofBaseList] = useState([]) const [constructionList, setConstructionList] = useState([]) const { getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController() + + const [lengthBase, setLengthBase] = useState(0) + const [hajebichi, setHajebichi] = useState(0) const [cvrYn, setCvrYn] = useState('N') const [cvrChecked, setCvrChecked] = useState(false) const [snowGdPossYn, setSnowGdPossYn] = useState('N') @@ -76,6 +79,12 @@ export function useModuleTrestle(props) { // setEavesMargin(selectedRoof?.addRoof?.eavesMargin ?? 0) // setRidgeMargin(selectedRoof?.addRoof?.ridgeMargin ?? 0) // setKerabaMargin(selectedRoof?.addRoof?.kerabaMargin ?? 0) + + setHajebichi(selectedRoof?.trestle?.hajebichi ?? 0) + setEavesMargin(selectedRoof?.eavesMargin ?? 0) + setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) + setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) + setLengthBase(Math.round(selectedRoof?.trestle?.lengthBase ?? 0)) setCvrYn(selectedRoof?.construction?.cvrYn ?? 'N') setCvrChecked(selectedRoof?.construction?.cvrChecked ?? false) setSnowGdPossYn(selectedRoof?.construction?.snowGdPossYn ?? 'N') @@ -224,6 +233,7 @@ export function useModuleTrestle(props) { setRidgeMargin(res[0].data.ridgeIntvl) setKerabaMargin(res[0].data.kerabaIntvl) setTrestleDetail(res[0].data) + // dispatch({ // type: 'SET_TRESTLE_DETAIL', // roof: { @@ -255,6 +265,14 @@ export function useModuleTrestle(props) { handleSetRoofBaseList, handleSetConstructionList, handleSetTrestleDetailData, + lengthBase, + setLengthBase, + hajebichi, + setHajebichi, + cvrYn, + cvrChecked, + snowGdPossYn, + snowGdChecked, eavesMargin, ridgeMargin, kerabaMargin, From 134becaa9391f09cf009e66540c9b3d1cf4df3e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 10:47:00 +0900 Subject: [PATCH 119/196] =?UTF-8?q?=EC=A4=91=EB=B3=B5=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleTrestle.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 5c50a706..026f6b2c 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -279,10 +279,6 @@ export function useModuleTrestle(props) { setEavesMargin, setRidgeMargin, setKerabaMargin, - cvrYn, - cvrChecked, - snowGdPossYn, - snowGdChecked, setCvrYn, setCvrChecked, setSnowGdPossYn, From 990de88cafeeb426652b9bfa681188d03ca94ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 10:51:59 +0900 Subject: [PATCH 120/196] =?UTF-8?q?=ED=82=A4=20=EA=B0=92=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index c8ece93c..82bd3de7 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -292,6 +292,8 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, + setupCover: cvrChecked, + setupSnowCover: snowGdChecked, }, trestleDetail: trestleDetail, } From 089ffed7afcdc1169851e1d94929e9e84f45ed20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 10:54:21 +0900 Subject: [PATCH 121/196] =?UTF-8?q?=ED=82=A4=20=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 82bd3de7..ccfdf063 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -369,8 +369,8 @@ const Trestle = forwardRef((props, ref) => { // ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp), ...roof.construction, roofIndex: roof.index, - setupCover: roof.cvrYn === 'Y', - setupSnowCover: roof.snowGdYn === 'Y', + setupCover: cvrChecked, + setupSnowCover: snowGdChecked, selectedIndex: roof.index, }, trestleDetail: roof.trestleDetail, From e67fc749f46895a36f5ee5b428c053d337d6974f Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 10 Apr 2025 10:55:00 +0900 Subject: [PATCH 122/196] =?UTF-8?q?=EB=A7=88=EC=9A=B0=EC=8A=A4=20=ED=9C=A0?= =?UTF-8?q?=20=EC=A4=8C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=B3=B4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useEvent.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index 8361ff7e..593fd76f 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -77,10 +77,10 @@ export function useEvent() { setCanvasZoom(Number((zoom * 100).toFixed(0))) // 마우스 위치 기준으로 확대/축소 - canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom) - - canvas.requestRenderAll() + canvas.zoomToPoint(new fabric.Point(opt.e.offsetX, opt.e.offsetY), zoom) canvas.calcOffset() + canvas.setViewportTransform(canvas.viewportTransform) + canvas.requestRenderAll() // 이벤트의 기본 동작 방지 (스크롤 방지) opt.e.preventDefault() From 070e9d933fe746a7b4c5f29ab9b697cc4b4e9b6e Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 10 Apr 2025 11:36:44 +0900 Subject: [PATCH 123/196] =?UTF-8?q?api=20=EC=98=A4=EB=A5=98=20=EC=8B=9C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 835609af..7048e64e 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -717,6 +717,9 @@ export const useTrestle = () => { if (result.resultCode === 'E') { swalFire({ text: result.resultMsg, icon: 'error' }) + clear() + setViewCircuitNumberTexts(true) + setIsGlobalLoading(false) return } From af63891df25b73a7b8e6bcf6069d17899a3df09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:24:29 +0900 Subject: [PATCH 124/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EC=8B=9C=20=EB=AA=A8=EB=93=88.=EA=B0=80=EB=8C=80=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 6 ++---- src/hooks/module/useModuleTrestle.js | 3 ++- src/hooks/roofcover/useRoofAllocationSetting.js | 9 +++++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index c8ece93c..ce0d093e 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -239,6 +239,7 @@ const Trestle = forwardRef((props, ref) => { if (i === selectedRoof.index) { return { ...selectedRoof, + hajebichi, eavesMargin, ridgeMargin, kerabaMargin, @@ -268,8 +269,6 @@ const Trestle = forwardRef((props, ref) => { } const isComplete = async () => { - console.log('roofs', roofs) - const newAddedRoofs = roofs.map((roof, i) => { if (i === selectedRoof?.index) { return { @@ -300,7 +299,6 @@ const Trestle = forwardRef((props, ref) => { }) let result = true - console.log('newAddedRoofs', newAddedRoofs) newAddedRoofs.forEach((roof) => { if (!roof?.eavesMargin || !roof?.ridgeMargin || !roof?.kerabaMargin) result = false if (!roof.trestle?.trestleMkrCd) result = false @@ -461,7 +459,7 @@ const Trestle = forwardRef((props, ref) => { type="text" className="input-origin block" disabled={selectedRoof.roofPchAuth === 'R'} - onChange={(e) => handleHajebichiAndLength(e, 'hajebichi')} + onChange={(e) => setHajebichi(e.target.value)} value={hajebichi} />
diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 026f6b2c..14e93de3 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -23,6 +23,7 @@ const trestleReducer = (state, action) => { return { moduleTpCd: action.roof.module?.itemTp ?? '', roofMatlCd: action.roof?.roofMatlCd ?? '', + hajebichi: action.roof?.hajebichi ?? 0, raftBaseCd: action.roof?.raftBaseCd ?? null, trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null, constMthdCd: action.roof.trestle?.constMthdCd ?? null, @@ -80,7 +81,7 @@ export function useModuleTrestle(props) { // setRidgeMargin(selectedRoof?.addRoof?.ridgeMargin ?? 0) // setKerabaMargin(selectedRoof?.addRoof?.kerabaMargin ?? 0) - setHajebichi(selectedRoof?.trestle?.hajebichi ?? 0) + setHajebichi(selectedRoof?.hajebichi ?? 0) setEavesMargin(selectedRoof?.eavesMargin ?? 0) setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 675f2f7c..797985aa 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -28,6 +28,7 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta import { outerLinePointsState } from '@/store/outerLineAtom' import { QcastContext } from '@/app/QcastProvider' import { usePlan } from '@/hooks/usePlan' +import { roofsState } from '@/store/roofAtom' export function useRoofAllocationSetting(id) { const canvas = useRecoilValue(canvasState) @@ -54,7 +55,7 @@ export function useRoofAllocationSetting(id) { const { setIsGlobalLoading } = useContext(QcastContext) const { setSurfaceShapePattern } = useRoofFn() const { saveCanvas } = usePlan() - + const [roofsStore, setRoofsStore] = useRecoilState(roofsState) const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const resetPoints = useResetRecoilState(outerLinePointsState) @@ -265,6 +266,8 @@ export function useRoofAllocationSetting(id) { newRoofList[0].selected = true } setCurrentRoofList(newRoofList) + setRoofsStore(newRoofList) + setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList }) } /** @@ -305,12 +308,14 @@ export function useRoofAllocationSetting(id) { setRoofList(newRoofList) setRoofMaterials(newRoofList) + setRoofsStore(newRoofList) const selectedRoofMaterial = newRoofList.find((roof) => roof.selected) setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true) drawDirectionArrow(currentObject) modifyModuleSelectionData() closeAll() basicSettingSave() + setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList }) } /** @@ -419,7 +424,7 @@ export function useRoofAllocationSetting(id) { }) setRoofMaterials(newRoofList) - + setRoofsStore(newRoofList) /** 외곽선 삭제 */ const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' || obj.name === 'outerLine') removeTargets.forEach((obj) => { From e2b8bc19b10e9cfb6f07384073dfcb68f97efda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:33:42 +0900 Subject: [PATCH 125/196] =?UTF-8?q?lenBase=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 1 + src/hooks/module/useModuleTrestle.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 9fd2a7aa..5ed0bdfa 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -240,6 +240,7 @@ const Trestle = forwardRef((props, ref) => { return { ...selectedRoof, hajebichi, + lenBase: lengthBase, eavesMargin, ridgeMargin, kerabaMargin, diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 14e93de3..e1957913 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -85,7 +85,7 @@ export function useModuleTrestle(props) { setEavesMargin(selectedRoof?.eavesMargin ?? 0) setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) - setLengthBase(Math.round(selectedRoof?.trestle?.lengthBase ?? 0)) + setLengthBase(Math.round(selectedRoof?.lenBase ?? 0)) setCvrYn(selectedRoof?.construction?.cvrYn ?? 'N') setCvrChecked(selectedRoof?.construction?.cvrChecked ?? false) setSnowGdPossYn(selectedRoof?.construction?.snowGdPossYn ?? 'N') From cf900c3e92fb5068b2169d56e645bdc845508225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:54:05 +0900 Subject: [PATCH 126/196] =?UTF-8?q?lenBase=20->=20length=20=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 8 +++++--- src/hooks/module/useModuleTrestle.js | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 9fd2a7aa..0afbc92c 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -240,13 +240,14 @@ const Trestle = forwardRef((props, ref) => { return { ...selectedRoof, hajebichi, + lenBase: lengthBase, eavesMargin, ridgeMargin, kerabaMargin, roofIndex: selectedRoof.index, trestle: { hajebichi: hajebichi, - lengthBase: lengthBase, + length: lengthBase, ...selectedRaftBase, ...selectedTrestle, ...selectedConstMthd, @@ -273,12 +274,13 @@ const Trestle = forwardRef((props, ref) => { if (i === selectedRoof?.index) { return { ...selectedRoof, + length: lengthBase, eavesMargin, ridgeMargin, kerabaMargin, roofIndex: roof.index, trestle: { - lengthBase: lengthBase, + length: lengthBase, hajebichi: hajebichi, ...selectedRaftBase, ...selectedTrestle, @@ -309,7 +311,7 @@ const Trestle = forwardRef((props, ref) => { if (!roof.construction?.constTp) result = false if (roof.lenAuth === 'C') { - if (!roof.trestle?.lengthBase) result = false + if (!roof.trestle?.length) result = false } if (['C', 'R'].includes(roof.raftAuth)) { if (!roof?.raftBaseCd) result = false diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 14e93de3..3d14d600 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -85,7 +85,7 @@ export function useModuleTrestle(props) { setEavesMargin(selectedRoof?.eavesMargin ?? 0) setRidgeMargin(selectedRoof?.ridgeMargin ?? 0) setKerabaMargin(selectedRoof?.kerabaMargin ?? 0) - setLengthBase(Math.round(selectedRoof?.trestle?.lengthBase ?? 0)) + setLengthBase(Math.round(selectedRoof?.length ?? 0)) setCvrYn(selectedRoof?.construction?.cvrYn ?? 'N') setCvrChecked(selectedRoof?.construction?.cvrChecked ?? false) setSnowGdPossYn(selectedRoof?.construction?.snowGdPossYn ?? 'N') From 08a29aec2695f13e0ae2fd42ef8aa1a1a51aa00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 10 Apr 2025 14:23:43 +0900 Subject: [PATCH 127/196] =?UTF-8?q?cvrCheck,=20snowCheck=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 0afbc92c..4c883512 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -369,8 +369,8 @@ const Trestle = forwardRef((props, ref) => { // ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp), ...roof.construction, roofIndex: roof.index, - setupCover: cvrChecked, - setupSnowCover: snowGdChecked, + setupCover: roof.construction.cvrChecked, + setupSnowCover: roof.construction.snowGdChecked, selectedIndex: roof.index, }, trestleDetail: roof.trestleDetail, From 61f1036a248dbc64294185d50e8e0118ab43edc6 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 11 Apr 2025 10:58:04 +0900 Subject: [PATCH 128/196] =?UTF-8?q?=EB=B3=80=EB=B3=84=EB=A1=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20-=20=ED=95=9C=EC=AA=BD=ED=9D=90=EB=A6=84=20?= =?UTF-8?q?=EC=B6=9C=ED=8F=AD=20=EC=A0=81=EC=9A=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index 1881b184..b6fc5036 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -716,6 +716,7 @@ export function useRoofShapeSetting(id) { type: LINE_TYPE.WALLLINE.SHED, pitch: shedPitchRef.current, width: shedWidth / 10, + offset: shedWidth / 10, } selectedLine.attributes = { ...attributes, isFixed: true } addPitchText(currentObject) From 2897dc26e3cfa2e4dd95d04ac7a822b136e3927f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 11 Apr 2025 16:41:28 +0900 Subject: [PATCH 129/196] =?UTF-8?q?Orientation=EC=97=90=EC=84=9C=20nextste?= =?UTF-8?q?p=EC=8B=9C=20compas=20=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Orientation.jsx | 2 +- src/components/floor-plan/modal/basic/step/Trestle.jsx | 2 -- src/hooks/module/useModuleBasicSetting.js | 2 +- src/hooks/module/useOrientation.js | 6 +++--- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index a6b54bd0..8eee35d3 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -125,7 +125,7 @@ export const Orientation = forwardRef((props, ref) => { setVerticalSnowCover(inputVerticalSnowCover) setSelectedSurfaceType(inputRoughness) setStandardWindSpeed(inputStandardWindSpeed) - nextStep() + nextStep(inputCompasDeg) setManagementState({ ...managementState, installHeight: inputInstallHeight, diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 4c883512..6060d8c8 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -369,8 +369,6 @@ const Trestle = forwardRef((props, ref) => { // ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp), ...roof.construction, roofIndex: roof.index, - setupCover: roof.construction.cvrChecked, - setupSnowCover: roof.construction.snowGdChecked, selectedIndex: roof.index, }, trestleDetail: roof.trestleDetail, diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 1a71c671..1871e34a 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -409,7 +409,7 @@ export function useModuleBasicSetting(tabNum) { useEffect(() => { if (canvasSetting.roofSizeSet != '3') { - if (isObjectNotEmpty(moduleSelectionData) && moduleSelectionData.common.saleStoreNorthFlg === '1') { + if (isObjectNotEmpty(moduleSelectionData) && moduleSelectionData?.common?.saleStoreNorthFlg === '1') { setSaleStoreNorthFlg(true) } } diff --git a/src/hooks/module/useOrientation.js b/src/hooks/module/useOrientation.js index 649d8f79..cf15390e 100644 --- a/src/hooks/module/useOrientation.js +++ b/src/hooks/module/useOrientation.js @@ -22,8 +22,8 @@ export function useOrientation() { }) }, [])*/ - const nextStep = () => { - if (isNaN(compasDeg)) { + const nextStep = (compas = compasDeg) => { + if (isNaN(compas)) { setCompasDeg(0) } const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) @@ -36,7 +36,7 @@ export function useOrientation() { roofs.forEach((roof) => { roof.set({ - moduleCompass: isNaN(compasDeg) ? 0 : compasDeg, + moduleCompass: isNaN(compas) ? 0 : compas, }) drawDirectionArrow(roof) }) From ed69943dc6386b8c203cd3c23d35aee906828aff Mon Sep 17 00:00:00 2001 From: ysCha Date: Mon, 14 Apr 2025 15:01:18 +0900 Subject: [PATCH 130/196] =?UTF-8?q?975-=20=EC=95=84=EC=9D=B4=ED=85=9C(?= =?UTF-8?q?=EC=96=91=EB=8B=A8=EC=BC=80=EC=9D=B4=EB=B8=94)=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=95=84=EC=9D=B4=ED=85=9C=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 8 ++++---- src/hooks/floorPlan/estimate/useEstimateController.js | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index e2c6c088..aa11943e 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -717,7 +717,7 @@ export default function Estimate({}) { /* 케이블 select 변경시 */ const onChangeDisplayCableItem = (value, itemList) => { itemList.map((item, index) => { - if (item.dispCableFlg === '1') { + if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') { if (value !== '') { onChangeDisplayItem(value, item.dispOrder, index, true) } @@ -1146,7 +1146,7 @@ export default function Estimate({}) { dispCableFlgCnt++ } - if (item.dispCableFlg === '1') { + if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') { setCableItem(item.itemId) } } @@ -1968,13 +1968,13 @@ export default function Estimate({}) { getOptionValue={(x) => x.clRefChr1} components={{ SingleValue: ({ children, ...props }) => { - return {props.data.clRefChr3} + return {(item.itemTpCd === 'M12')? item.itemName : props.data.clRefChr3} }, }} isClearable={false} isDisabled={true} value={cableItemList.filter(function (option) { - return option.clRefChr1 === item.itemId + return (item.itemTpCd === 'M12')? item.itemId : option.clRefChr1 === item.itemId })} /> )} diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 2e0bbe1a..34ac80fb 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -130,6 +130,7 @@ export const useEstimateController = (planNo, flag) => { addFlg: true, paDispOrder: null, dispCableFlg: '0', + itemTpCd:'', }, ], }) From 8f4e53c759d07ffece55f8e26ae1948780717a53 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 14 Apr 2025 18:14:49 +0900 Subject: [PATCH 131/196] =?UTF-8?q?#982=20=ED=91=9C=EC=8B=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 86a76864..0b3f5b52 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -37,7 +37,7 @@ "modal.roof.shape.setting.ridge": "棟", "modal.roof.shape.setting.patten.a": "Aパターン", "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.outline.drawing": "外壁線を描く", "plan.menu.roof.cover.roof.shape.setting": "屋根形状の設定", @@ -125,8 +125,8 @@ "modal.module.basic.setting.module.placement.do.not": "しない", "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.eaves": "軒の側", - "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "龍丸側", + "modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒側", + "modal.module.basic.setting.module.placement.arrangement.standard.ridge": "棟側", "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.south": "南向き設置", @@ -851,7 +851,7 @@ "has.not.sleeve": "袖なし", "jerkinhead.width": "半切妻幅", "jerkinhead.slope": "半切妻傾斜", - "shed.width": "片流幅", + "shed.width": "片流れの出幅", "windage": "片流れ", "windage.width": "片流れの出幅", "write": "作成", From 3c14f5de52aa9a6689b408976ad2ed4dc2d5419a Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 15 Apr 2025 18:08:05 +0900 Subject: [PATCH 132/196] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EC=8B=9C=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/estimate/useEstimateController.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 34ac80fb..a0765766 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -130,7 +130,7 @@ export const useEstimateController = (planNo, flag) => { addFlg: true, paDispOrder: null, dispCableFlg: '0', - itemTpCd:'', + itemTpCd: '', }, ], }) @@ -322,6 +322,7 @@ export const useEstimateController = (planNo, flag) => { } }) if (delCnt === estimateData.itemList.length) { + itemFlg = false setIsGlobalLoading(false) return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert', icon: 'warning' }) } From bdcacd554252c0cc7dd977edc0db4fc9f4469a53 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 16 Apr 2025 15:39:48 +0900 Subject: [PATCH 133/196] =?UTF-8?q?=EB=B3=80=EB=B3=84=EB=A1=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=ED=9B=84=20=ED=95=9C=EC=AA=BD=ED=9D=90=EB=A6=84?= =?UTF-8?q?=EA=B3=BC=20=EA=B0=99=EC=9D=B4=20=EB=B3=80=20=EC=86=8D=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=84=A0=ED=83=9D=ED=95=A0=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index b6fc5036..e36dbd08 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -231,6 +231,21 @@ export function useRoofShapeSetting(id) { pitch: pitchRef.current, onlyOffset: true, } + + switch (line.direction) { + case 'bottom': + direction = 'west' + break + case 'top': + direction = 'east' + break + case 'left': + direction = 'north' + break + case 'right': + direction = 'south' + break + } } }) } From bcc91e76097015becae943bae5ae9c0629af7e3c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 16 Apr 2025 15:53:54 +0900 Subject: [PATCH 134/196] =?UTF-8?q?=EB=B0=98=EB=8C=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index e36dbd08..192d8cc0 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -234,16 +234,16 @@ export function useRoofShapeSetting(id) { switch (line.direction) { case 'bottom': - direction = 'west' - break - case 'top': direction = 'east' break + case 'top': + direction = 'west' + break case 'left': - direction = 'north' + direction = 'south' break case 'right': - direction = 'south' + direction = 'north' break } } From 30414568e0800c0a32ca7df5182b1ef2def36c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 17 Apr 2025 14:11:55 +0900 Subject: [PATCH 135/196] =?UTF-8?q?=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 11 +++++++++++ src/locales/ko.json | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/locales/ja.json b/src/locales/ja.json index 5849f3da..87b6502e 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -114,6 +114,17 @@ "modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置", "modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置", "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.select.fitting.type": "設置形態を選択してください。", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置", diff --git a/src/locales/ko.json b/src/locales/ko.json index 98960614..55fa6da1 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -114,6 +114,17 @@ "modal.module.basic.setting.module.eaves.bar.fitting": "처마커버설치", "modal.module.basic.setting.module.blind.metal.fitting": "적설방지금구설치", "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.select.fitting.type": "설치형태를 선택합니다.", "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.ridge": "용마루쪽", "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.south": "남향설치", "modal.module.basic.setting.pitch.module.placement.standard.setting.select": "지정한 변을 기준으로 설치", From 4c219ddce9d51be8dbe96f88a93c70a55be98be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 17 Apr 2025 14:12:50 +0900 Subject: [PATCH 136/196] =?UTF-8?q?validation=20=EB=B0=A9=EC=8B=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 10 +- .../floor-plan/modal/basic/step/Trestle.jsx | 129 +++++++++++++++--- 2 files changed, 113 insertions(+), 26 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 7e026584..72f8e595 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -186,15 +186,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { // return // } trestleRef.current.isComplete().then((res) => { - if (!res) { - Swal.fire({ - title: getMessage('construction.length.difference'), - icon: 'warning', - }) - return - } else { - // setTabNum(tabNum + 1) - } + if (!res) return }) //물건정보 갱신일 수정 } else { diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 6060d8c8..bd9bf705 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -8,6 +8,7 @@ import { roofsState } from '@/store/roofAtom' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' +import Swal from 'sweetalert2' const Trestle = forwardRef((props, ref) => { const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData, setRoofsStore } = props @@ -303,30 +304,122 @@ const Trestle = forwardRef((props, ref) => { }) let result = true - newAddedRoofs.forEach((roof) => { - if (!roof?.eavesMargin || !roof?.ridgeMargin || !roof?.kerabaMargin) result = false - if (!roof.trestle?.trestleMkrCd) result = false - if (!roof.trestle?.constMthdCd) result = false - if (!roof.trestle?.roofBaseCd) result = false - if (!roof.construction?.constTp) result = false + console.log(newAddedRoofs) + for (let i = 0; i < newAddedRoofs.length; i++) { + 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.trestle?.constMthdCd) { + Swal.fire({ + title: getMessage('modal.module.basic.settting.module.error2', [roof.nameJp]), // 공법을 선택해주세요. + icon: 'warning', + }) + result = false + return false + } + if (!roof.trestle?.roofBaseCd) { + 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 (roof.lenAuth === 'C') { - if (!roof.trestle?.length) 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) result = false + if (!roof?.raftBaseCd) { + Swal.fire({ + title: getMessage('modal.module.basic.settting.module.error6', [roof.nameJp]), // 서까래 간격을 입력해주세요. + icon: 'warning', + }) + result = false + return false + } } if (['C', 'R'].includes(roof.roofPchAuth)) { - if (!roof?.roofPchBase) result = false + if (!roof?.roofPchBase) { + Swal.fire({ + title: getMessage('modal.module.basic.settting.module.error7', [roof.nameJp]), // 하제비치를 입력해주세요. + icon: 'warning', + }) + result = false + return false + } } - }) - const newRoofs = newAddedRoofs.map((roof) => { - const { addRoof, construction, trestle, trestleDetail, roofConstructions, ...rest } = roof - return rest - }) + 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) { + const newRoofs = newAddedRoofs.map((roof) => { + const { addRoof, construction, trestle, trestleDetail, roofConstructions, ...rest } = roof + return rest + }) + setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newAddedRoofs.map((roof, index) => ({ @@ -388,6 +481,8 @@ const Trestle = forwardRef((props, ref) => { return false } + const onMarginCheck = (target, data) => {} + useImperativeHandle(ref, () => ({ isComplete, })) @@ -580,7 +675,7 @@ const Trestle = forwardRef((props, ref) => { className="input-origin block" value={eavesMargin ?? 0} // 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)} />
mm @@ -593,7 +688,7 @@ const Trestle = forwardRef((props, ref) => { className="input-origin block" value={ridgeMargin ?? 0} // 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)} />
mm @@ -606,7 +701,7 @@ const Trestle = forwardRef((props, ref) => { className="input-origin block" value={kerabaMargin ?? 0} // 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)} />
mm From 29ccf72c5ebaac79b09845e3f15e9001d74caf7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 17 Apr 2025 14:13:05 +0900 Subject: [PATCH 137/196] =?UTF-8?q?=EC=88=98=EB=8F=99=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B0=A9=EC=9C=84=EC=84=A4=EC=A0=95=20=EC=95=88=EB=90=98?= =?UTF-8?q?=EB=8D=98=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Orientation.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index 8eee35d3..e8acbc3f 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -175,15 +175,15 @@ export const Orientation = forwardRef((props, ref) => { return } if (e === '0-') { - setCompasDeg('-0') + setInputCompasDeg('-0') return } if (Number(e) >= -180 && Number(e) <= 180) { if (numberCheck(Number(e))) { - setCompasDeg(Number(e)) + setInputCompasDeg(Number(e)) } } else { - setCompasDeg(compasDeg) + setInputCompasDeg(compasDeg) } } From 21dcdfb3efa979da50c664409f27f1ea4ae2bbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 17 Apr 2025 14:22:58 +0900 Subject: [PATCH 138/196] =?UTF-8?q?=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 22 +++++++++++----------- src/locales/ko.json | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 38191964..3c047d8a 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -114,17 +114,17 @@ "modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置", "modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置", "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.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.select.fitting.type": "設置形態を選択してください。", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置", diff --git a/src/locales/ko.json b/src/locales/ko.json index 55fa6da1..530fe555 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -121,7 +121,7 @@ "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.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})", From a3b62db4fa521e3fbc865c76dcd51d21cf5fee2c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 17 Apr 2025 16:35:06 +0900 Subject: [PATCH 139/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=8D=AE=EA=B0=9C=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20-=20=EB=B3=B5=EB=8F=84=EC=B9=98=EC=88=98?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9=20=EA=B7=B8=20=EC=99=B8=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20-=20=EC=8B=A4=EC=B9=98=EC=88=98=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useMenu.js | 40 ++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js index 7fdd6a31..4261d7e6 100644 --- a/src/hooks/common/useMenu.js +++ b/src/hooks/common/useMenu.js @@ -16,12 +16,13 @@ import { usePopup } from '@/hooks/usePopup' import { useState } from 'react' import { v4 as uuidv4 } from 'uuid' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' -import { useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue } from 'recoil' import { canvasState, currentMenuState } from '@/store/canvasAtom' import { MENU } from '@/common/common' import { useTrestle } from '@/hooks/module/useTrestle' import { usePolygon } from '@/hooks/usePolygon' import { useOrientation } from '@/hooks/module/useOrientation' +import { settingModalFirstOptionsState } from '@/store/settingAtom' /** * 메뉴 처리 훅 @@ -36,8 +37,21 @@ export default function useMenu() { const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({}) const { clear: trestleClear, setAllModuleSurfaceIsComplete } = useTrestle() const { nextStep } = useOrientation() + const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const handleMenu = (type) => { 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) { case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE: addPopup(popupId, 1, ) @@ -67,6 +81,18 @@ export default function useMenu() { } 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) { // case MENU.BATCH_CANVAS.SLOPE_SETTING: // addPopup(popupId, 1, ) @@ -87,6 +113,18 @@ export default function useMenu() { } 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) { case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING: trestleClear() From 76938af446cef38d4772f4ae90aba2e07d1fea67 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 17 Apr 2025 16:40:40 +0900 Subject: [PATCH 140/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=8B=9C=EC=97=90=EB=8F=84=20=EC=8B=A4=EC=B9=98?= =?UTF-8?q?=EC=88=98=20=EC=A0=81=EC=9A=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useMenu.js | 3 +++ src/hooks/roofcover/useRoofAllocationSetting.js | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js index 4261d7e6..8b0540dd 100644 --- a/src/hooks/common/useMenu.js +++ b/src/hooks/common/useMenu.js @@ -40,6 +40,7 @@ export default function useMenu() { const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const handleMenu = (type) => { if (type === 'outline') { + // 지붕 덮개 메뉴의 경우는 복도치수로 적용한다. setSettingModalFirstOptions((prev) => { return { ...prev, @@ -81,6 +82,7 @@ export default function useMenu() { } if (type === 'surface') { + // 배치면 메뉴의 경우는 실치수로 적용한다. setSettingModalFirstOptions((prev) => { return { ...prev, @@ -113,6 +115,7 @@ export default function useMenu() { } if (type === 'module') { + // 모듈,회로 구성 메뉴의 경우는 실치수로 적용한다. setSettingModalFirstOptions((prev) => { return { ...prev, diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index bc4d246a..42dbb947 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -11,6 +11,7 @@ import { roofDisplaySelector, roofMaterialsSelector, selectedRoofMaterialSelector, + settingModalFirstOptionsState, } from '@/store/settingAtom' import { usePopup } from '@/hooks/usePopup' import { POLYGON_TYPE } from '@/common/common' @@ -57,6 +58,7 @@ export function useRoofAllocationSetting(id) { const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const resetPoints = useResetRecoilState(outerLinePointsState) + const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) useEffect(() => { /** 배치면 초기설정에서 선택한 지붕재 배열 설정 */ @@ -428,6 +430,19 @@ export function useRoofAllocationSetting(id) { setEditingLines([]) closeAll() 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() From d1ea6229a2b68b435ef30a5b85856ff77862fa43 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 18 Apr 2025 11:44:58 +0900 Subject: [PATCH 141/196] =?UTF-8?q?=EC=B9=98=EC=88=98=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?selector=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useMenu.js | 43 +++---------------- .../roofcover/useRoofAllocationSetting.js | 16 ++----- src/store/settingAtom.js | 16 +++++++ 3 files changed, 24 insertions(+), 51 deletions(-) diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js index 8b0540dd..f8bc2a31 100644 --- a/src/hooks/common/useMenu.js +++ b/src/hooks/common/useMenu.js @@ -22,7 +22,7 @@ import { MENU } from '@/common/common' import { useTrestle } from '@/hooks/module/useTrestle' import { usePolygon } from '@/hooks/usePolygon' import { useOrientation } from '@/hooks/module/useOrientation' -import { settingModalFirstOptionsState } from '@/store/settingAtom' +import { corridorDimensionSelector, settingModalFirstOptionsState } from '@/store/settingAtom' /** * 메뉴 처리 훅 @@ -37,22 +37,11 @@ export default function useMenu() { const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({}) const { clear: trestleClear, setAllModuleSurfaceIsComplete } = useTrestle() const { nextStep } = useOrientation() - const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) + const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector) const handleMenu = (type) => { 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 } - } - }), - } - }) + setCorridorDimension(0) switch (currentMenu) { case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE: addPopup(popupId, 1, ) @@ -83,18 +72,7 @@ export default function useMenu() { 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 } - } - }), - } - }) + setCorridorDimension(1) switch (currentMenu) { // case MENU.BATCH_CANVAS.SLOPE_SETTING: // addPopup(popupId, 1, ) @@ -116,18 +94,7 @@ export default function useMenu() { 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 } - } - }), - } - }) + setCorridorDimension(1) switch (currentMenu) { case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING: trestleClear() diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 5f7e7505..d9c2073c 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -12,6 +12,7 @@ import { roofMaterialsSelector, selectedRoofMaterialSelector, settingModalFirstOptionsState, + corridorDimensionSelector, } from '@/store/settingAtom' import { usePopup } from '@/hooks/usePopup' import { POLYGON_TYPE } from '@/common/common' @@ -59,7 +60,7 @@ export function useRoofAllocationSetting(id) { const [roofsStore, setRoofsStore] = useRecoilState(roofsState) const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const resetPoints = useResetRecoilState(outerLinePointsState) - const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) + const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector) useEffect(() => { /** 배치면 초기설정에서 선택한 지붕재 배열 설정 */ @@ -436,18 +437,7 @@ export function useRoofAllocationSetting(id) { closeAll() setSelectedMenu('surface') //지붕면 완성 후 실측치 로 보이도록 수정 - setSettingModalFirstOptions((prev) => { - return { - ...prev, - dimensionDisplay: prev.dimensionDisplay.map((item, index) => { - if (index === 1) { - return { ...item, selected: true } - } else { - return { ...item, selected: false } - } - }), - } - }) + setCorridorDimension(1) /** 모듈 선택 데이터 초기화 */ // modifyModuleSelectionData() diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js index 012e5bdc..32a620a1 100644 --- a/src/store/settingAtom.js +++ b/src/store/settingAtom.js @@ -221,6 +221,22 @@ export const corridorDimensionSelector = selector({ const settingModalFirstOptions = get(settingModalFirstOptionsState) return settingModalFirstOptions.dimensionDisplay.find((option) => option.selected) }, + set: ({ set }, newValue) => { + //0 : 복도치수 , 1 : 실제치수 + + set(settingModalFirstOptionsState, (prev) => { + return { + ...prev, + dimensionDisplay: prev.dimensionDisplay.map((item, index) => { + if (index === newValue) { + return { ...item, selected: true } + } else { + return { ...item, selected: false } + } + }), + } + }) + }, dangerouslyAllowMutability: true, }) From 51a2782d3c0dec0da8a708edf6b9c07dc883aba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 18 Apr 2025 14:24:46 +0900 Subject: [PATCH 142/196] =?UTF-8?q?plan=20=EC=B6=94=EA=B0=80=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=82=BC=ED=95=AD=EC=97=B0=EC=82=B0=EC=9E=90=20->?= =?UTF-8?q?=20if=20=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePlan.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 0bc2a5d5..f812f00e 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -449,26 +449,26 @@ export function usePlan(params = {}) { if (currentCanvasPlan?.id) { await saveCanvas(false) } - JSON.parse(currentCanvasData()).objects.length > 0 - ? swalFire({ - text: `Plan ${currentCanvasPlan.planNo} ` + getMessage('plan.message.confirm.copy'), - type: 'confirm', - confirmFn: async () => { - setIsGlobalLoading(true) - await postObjectPlan(userId, objectNo, true, false) - setIsGlobalLoading(false) - }, - denyFn: async () => { - setIsGlobalLoading(true) - await postObjectPlan(userId, objectNo, false, false) - setIsGlobalLoading(false) - }, - }) - : async () => { + if (JSON.parse(currentCanvasData()).objects.length > 0) { + swalFire({ + text: `Plan ${currentCanvasPlan.planNo} ` + getMessage('plan.message.confirm.copy'), + type: 'confirm', + confirmFn: async () => { + setIsGlobalLoading(true) + await postObjectPlan(userId, objectNo, true, false) + setIsGlobalLoading(false) + }, + denyFn: async () => { setIsGlobalLoading(true) await postObjectPlan(userId, objectNo, false, false) setIsGlobalLoading(false) - } + }, + }) + } else { + setIsGlobalLoading(true) + await postObjectPlan(userId, objectNo, false, false) + setIsGlobalLoading(false) + } } /** From 77b473c0a1c52e06bfe6efd304b403a85967a042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 18 Apr 2025 14:39:07 +0900 Subject: [PATCH 143/196] =?UTF-8?q?input=20type=20text->=20number=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index bd9bf705..b2d5fc78 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -671,7 +671,7 @@ const Trestle = forwardRef((props, ref) => { {getMessage('modal.module.basic.setting.module.placement.area.eaves')}
dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })} @@ -684,7 +684,7 @@ const Trestle = forwardRef((props, ref) => { {getMessage('modal.module.basic.setting.module.placement.area.ridge')}
dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })} @@ -697,7 +697,7 @@ const Trestle = forwardRef((props, ref) => { {getMessage('modal.module.basic.setting.module.placement.area.keraba')}
dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })} From b12b7aaa3a7925371b1f744a2298721f20137bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 18 Apr 2025 14:41:11 +0900 Subject: [PATCH 144/196] =?UTF-8?q?input=20type=20text->=20number=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Orientation.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index e8acbc3f..a2625233 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -393,7 +393,7 @@ export const Orientation = forwardRef((props, ref) => {
{getMessage('modal.module.basic.setting.module.placement.area')}
- setInputMargin(e.target.value)} /> + setInputMargin(e.target.value)} />
m
@@ -422,7 +422,7 @@ export const Orientation = forwardRef((props, ref) => { {getMessage('modal.module.basic.setting.module.fitting.height')}
handleChangeInstallHeight(e.target.value)} @@ -450,7 +450,7 @@ export const Orientation = forwardRef((props, ref) => { {getMessage('modal.module.basic.setting.module.standard.snowfall.amount')}
handleChangeVerticalSnowCover(e.target.value)} From bee4ee3e7466b3945269187d92efec04d32218ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 18 Apr 2025 14:52:29 +0900 Subject: [PATCH 145/196] =?UTF-8?q?=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EA=B0=9C?= =?UTF-8?q?=ED=96=89=EB=AC=B8=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 22 +++++++++++----------- src/locales/ko.json | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 3c047d8a..42f54fbd 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -114,17 +114,17 @@ "modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置", "modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置", "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.settting.module.error1": "架台メーカーを選択してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error2": "工法を選択してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error3": "屋根の下を選択してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error4": "施工法を選択してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error5": "L を選択してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error7": "下在ビーチを入力してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)", + "modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)", + "modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)", "modal.module.basic.setting.module.placement": "モジュールの配置", "modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置", diff --git a/src/locales/ko.json b/src/locales/ko.json index 530fe555..0164a546 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -114,17 +114,17 @@ "modal.module.basic.setting.module.eaves.bar.fitting": "처마커버설치", "modal.module.basic.setting.module.blind.metal.fitting": "적설방지금구설치", "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.settting.module.error1": "가대메이커를 선택해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error2": "공법를 선택해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error3": "지붕밑바탕을 선택해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error4": "시공법을 선택해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error5": "L 을 입력해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error6": "서까래 간격을 입력해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error7": "하제비치를 입력해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error8": "모듈 배치 영역 값을 입력해주세요.\n(지붕재: {0})", + "modal.module.basic.settting.module.error9": "처마쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})", + "modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})", + "modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})", "modal.module.basic.setting.module.placement": "모듈 배치", "modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치", From da162ac25941fe7a4c6ac745725e0dafed77a63c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 18 Apr 2025 16:03:52 +0900 Subject: [PATCH 146/196] =?UTF-8?q?=EB=AA=A8=EB=93=88,=ED=9A=8C=EB=A1=9C?= =?UTF-8?q?=EA=B5=AC=EC=84=B1=20=20=3D>=20=EB=AA=A8=EB=93=88/=EA=B0=80?= =?UTF-8?q?=EB=8C=80=20=EC=84=A4=EC=A0=95=20=EB=A9=94=EB=89=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20roof=20=EC=84=A0=ED=83=9D=20=EC=95=88=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCanvasEvent.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js index 1f6466f5..4204dc71 100644 --- a/src/hooks/useCanvasEvent.js +++ b/src/hooks/useCanvasEvent.js @@ -1,9 +1,10 @@ import { useEffect, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { v4 as uuidv4 } from 'uuid' -import { canvasSizeState, canvasState, canvasZoomState, currentObjectState } from '@/store/canvasAtom' +import { canvasSizeState, canvasState, canvasZoomState, currentMenuState, currentObjectState } from '@/store/canvasAtom' import { QPolygon } from '@/components/fabric/QPolygon' import { fontSelector } from '@/store/fontAtom' +import { MENU } from '@/common/common' // 캔버스에 필요한 이벤트 export function useCanvasEvent() { @@ -13,11 +14,16 @@ export function useCanvasEvent() { const canvasSize = useRecoilValue(canvasSizeState) const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const lengthTextOption = useRecoilValue(fontSelector('lengthText')) + const currentMenu = useRecoilValue(currentMenuState) useEffect(() => { canvas?.setZoom(canvasZoom / 100) }, [canvasZoom]) + useEffect(() => { + attachDefaultEventOnCanvas() + }, [currentMenu]) + // 기본적인 이벤트 필요시 추가 const attachDefaultEventOnCanvas = () => { removeEventOnCanvas() @@ -198,7 +204,7 @@ export function useCanvasEvent() { if (selected?.length > 0) { selected.forEach((obj) => { - if (obj.type === 'QPolygon') { + if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { obj.set({ stroke: 'red' }) } }) @@ -211,7 +217,7 @@ export function useCanvasEvent() { if (deselected?.length > 0) { deselected.forEach((obj) => { - if (obj.type === 'QPolygon') { + if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { if (obj.name !== 'moduleSetupSurface') { obj.set({ stroke: 'black' }) } @@ -227,7 +233,7 @@ export function useCanvasEvent() { if (deselected?.length > 0) { deselected.forEach((obj) => { - if (obj.type === 'QPolygon') { + if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { obj.set({ stroke: 'black' }) } }) @@ -235,7 +241,7 @@ export function useCanvasEvent() { if (selected?.length > 0) { selected.forEach((obj) => { - if (obj.type === 'QPolygon') { + if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { obj.set({ stroke: 'red' }) } }) From 479f5d342a9eff292044c7db9f758fa015a9dbdd Mon Sep 17 00:00:00 2001 From: ysCha Date: Fri, 18 Apr 2025 16:40:52 +0900 Subject: [PATCH 147/196] =?UTF-8?q?975=20-=20=EC=BC=80=EC=9D=B4=EB=B8=94?= =?UTF-8?q?=20=EC=84=A0=ED=83=9D=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index aa11943e..dfa313d2 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1075,7 +1075,7 @@ export default function Estimate({}) { item.showSaleTotPrice = '0' } - if (item.dispCableFlg === '1') { + if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') { dispCableFlgCnt++ setCableItem(item.itemId) } From 11a7061e0a4f068b966f1f23cdbe24cf676387fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 21 Apr 2025 11:33:08 +0900 Subject: [PATCH 148/196] =?UTF-8?q?roof=20=EB=B3=80=EA=B2=BD=ED=96=88?= =?UTF-8?q?=EC=9D=84=EB=95=8C=20setupCover=20=EA=B0=92=20=EC=95=88=20?= =?UTF-8?q?=EB=84=A3=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index b2d5fc78..3c500444 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -260,6 +260,8 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn: snowGdPossYn, cvrChecked: cvrChecked, snowGdChecked: snowGdChecked, + setupCover: cvrChecked ?? false, + setupSnowCover: snowGdChecked ?? false, }, trestleDetail: trestleDetail, } @@ -294,8 +296,8 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn, cvrChecked, snowGdChecked, - setupCover: cvrChecked, - setupSnowCover: snowGdChecked, + setupCover: cvrChecked ?? false, + setupSnowCover: snowGdChecked ?? false, }, trestleDetail: trestleDetail, } @@ -304,7 +306,6 @@ const Trestle = forwardRef((props, ref) => { }) let result = true - console.log(newAddedRoofs) for (let i = 0; i < newAddedRoofs.length; i++) { const roof = newAddedRoofs[i] From 159bbf2e6e9e024d7127b1e488272c29e8af5711 Mon Sep 17 00:00:00 2001 From: ysCha Date: Mon, 21 Apr 2025 13:12:43 +0900 Subject: [PATCH 149/196] =?UTF-8?q?993=20-=20HANASYS=E8=A8=AD=E8=A8=88=20?= =?UTF-8?q?=3D>=20HANASYS=20DESIGN=20=EB=B3=80=EA=B2=BD=EB=B0=8F=20?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EB=A1=9C=EA=B3=A0=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/static/images/common/Logo.svg | 32 ++++++++++++++-------------- src/app/layout.js | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/public/static/images/common/Logo.svg b/public/static/images/common/Logo.svg index fa04f4d3..01e85313 100644 --- a/public/static/images/common/Logo.svg +++ b/public/static/images/common/Logo.svg @@ -1,17 +1,17 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/src/app/layout.js b/src/app/layout.js index a77f926c..6186f5ed 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -21,8 +21,8 @@ import GlobalLoadingProvider from './GlobalLoadingProvider' * 서버 컴포넌트에 한해서 개별로 설정할 수 있음 */ export const metadata = { - title: 'HANASYS設計', - description: 'HANASYS設計', + title: 'HANASYS DESIGN', + description: 'HANASYS DESIGN', } /** From ac4449f3f350c78540e40b9688809b85839ac25d Mon Sep 17 00:00:00 2001 From: ysCha Date: Mon, 21 Apr 2025 13:13:26 +0900 Subject: [PATCH 150/196] =?UTF-8?q?993=20-=20HANASYS=E8=A8=AD=E8=A8=88=20?= =?UTF-8?q?=3D>=20HANASYS=20DESIGN=20=EB=B3=80=EA=B2=BD=EB=B0=8F=20?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EB=A1=9C=EA=B3=A0=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 42f54fbd..4dd62685 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -570,7 +570,7 @@ "color.pink": "ピンク", "color.gold": "黄金色", "color.darkblue": "藍色", - "site.name": "HANASYS設計", + "site.name": "HANASYS DESIGN", "site.sub_name": "太陽光発電システム図面管理サイト", "site.header.link1": "選択してください。", "site.header.link2": "オンライン保証システム", From d4a83c4ec585d8190a52502c4fc6bf34cb67a37a Mon Sep 17 00:00:00 2001 From: ysCha Date: Tue, 22 Apr 2025 13:21:30 +0900 Subject: [PATCH 151/196] =?UTF-8?q?1006-=EC=98=A4=ED=83=80=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 22 +++++++++++----------- src/locales/ko.json | 12 ++++++------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 4dd62685..da906a33 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -94,7 +94,7 @@ "modal.module.basic.setting.module.trestle.maker": "架台メーカー", "modal.module.basic.setting.module.rafter.margin": "垂木の間隔", "modal.module.basic.setting.module.construction.method": "工法", - "modal.module.basic.setting.module.under.roof": "屋根の下", + "modal.module.basic.setting.module.under.roof": "屋根下地", "modal.module.basic.setting.module.setting": "モジュールの選択", "modal.module.basic.setting.module.placement.area": "モジュール配置領域", "modal.module.basic.setting.module.placement.area.eaves": "軒側", @@ -130,8 +130,8 @@ "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置", "modal.module.basic.setting.module.placement.max.row.amount": "Max単数", "modal.module.basic.setting.module.placement.mix.max.row.amount": "混合Max単数", - "modal.module.basic.setting.module.placement.row.amount": "単数", - "modal.module.basic.setting.module.placement.column.amount": "熱水", + "modal.module.basic.setting.module.placement.row.amount": "段数", + "modal.module.basic.setting.module.placement.column.amount": "列数", "modal.module.basic.setting.module.placement.do": "する", "modal.module.basic.setting.module.placement.do.not": "しない", "modal.module.basic.setting.module.placement.arrangement.standard": "配置基準", @@ -149,7 +149,7 @@ "modal.module.basic.setting.pitch.module.column.amount": "列数", "modal.module.basic.setting.pitch.module.column.margin": "左右間隔", "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.auto.placement": "自動配置", "plan.menu.module.circuit.setting.circuit.trestle.setting": "回路設定", @@ -163,7 +163,7 @@ "modal.circuit.trestle.setting.power.conditional.select.max.connection": "標準枚数", "modal.circuit.trestle.setting.power.conditional.select.max.overload": "最大枚数", "modal.circuit.trestle.setting.power.conditional.select.output.current": "出力電流", - "modal.circuit.trestle.setting.power.conditional.select.check1": "同じ傾斜同じ方向の面積ケース同じ面として回路分ける。", + "modal.circuit.trestle.setting.power.conditional.select.check1": "同一勾配・同一方面の面である場合、同じ面として回路分けを行う", "modal.circuit.trestle.setting.power.conditional.select.check2": "MAX接続(過積)で回路を分ける。", "modal.circuit.trestle.setting.circuit.allocation": "回路割り当て", "modal.circuit.trestle.setting.circuit.allocation.auto": "自動回路割り当て", @@ -174,7 +174,7 @@ "modal.circuit.trestle.setting.circuit.allocation.passivity.info": "同じ回路のモジュールを選択状態にした後、[番号確定]ボタンを押すと番号が割り当てられます。", "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional": "選択したパワーコンディショナー", "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num": "設定する回路番号(1~)", - "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info": "標準回路{0}章~{1}章", + "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info": "標準回路{0}~{1}直", "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset": "選択したパワーコンディショナーの回路番号の初期化", "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset.info": "選択したパワーコンディショナーの回路割り当てを初期化します。", "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset": "すべての回路番号の初期化", @@ -1059,7 +1059,7 @@ "outerLine.property.fix": "外壁線の属性設定 を完了しますか?", "outerLine.property.close": "外壁線の属性設定 を終了しますか?", "want.to.complete.auxiliary.creation": "補助線の作成を完了しますか?", - "module.layout.setup.has.zero.value": "モジュールの列、行を入力してください.", + "module.layout.setup.has.zero.value": "モジュールの列数、段数を入力して下さい。", "modal.placement.initial.setting.plan.drawing.only.number": "(※数字は[半角]入力のみ可能です。)", "wall.line.not.found": "外壁がありません", "roof.line.not.found": "屋根形状がありません", @@ -1068,10 +1068,10 @@ "module.layout.setup.max.count": "モジュールの最大段数は{0}、最大列数は{1}です。 (JA)", "module.layout.setup.max.count.multiple": "モジュール{0}の最大段数は{1}、最大列数は{2}です。 (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.max.size.check": "屋根材別モジュールの単体の最大段数、2種混合の段数を確認して下さい", + "modal.module.basic.setting.module.placement.max.row": "最大段数", + "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合最大段数", "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.module.placement.mix.asg.yn": "混合", "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 0164a546..e006a26a 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -150,7 +150,7 @@ "modal.module.basic.setting.pitch.module.column.amount": "열수", "modal.module.basic.setting.pitch.module.column.margin": "좌우간격", "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.auto.placement": "설정값으로 자동 배치", "plan.menu.module.circuit.setting.circuit.trestle.setting": "회로설정", @@ -164,7 +164,7 @@ "modal.circuit.trestle.setting.power.conditional.select.max.connection": "표준매수", "modal.circuit.trestle.setting.power.conditional.select.max.overload": "최대매수", "modal.circuit.trestle.setting.power.conditional.select.output.current": "출력전류", - "modal.circuit.trestle.setting.power.conditional.select.check1": "동일경사 동일방면의 면적인 경우 같은 면으로서 회로를 나눈다.", + "modal.circuit.trestle.setting.power.conditional.select.check1": "동일 구배·동일 방면의 면인 경우, 같은 면으로서 회로를 나눈다", "modal.circuit.trestle.setting.power.conditional.select.check2": "MAX 접속(과적)으로 회로를 나눈다.", "modal.circuit.trestle.setting.circuit.allocation": "회로 할당", "modal.circuit.trestle.setting.circuit.allocation.auto": "자동회로 할당", @@ -175,7 +175,7 @@ "modal.circuit.trestle.setting.circuit.allocation.passivity.info": "동일한 회로의 모듈을 선택 상태로 만든 후 [번호 확정] 버튼을 누르면 번호가 할당됩니다.", "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional": "선택된 파워컨디셔너", "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num": "설정할 회로번호(1~)", - "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info": "표준회로{0}장~{1}장", + "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info": "표준회로{0}~{1}직", "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset": "선택된 파워컨디셔너의 회로번호 초기화", "modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional.reset.info": "선택된 파워 컨디셔너의 회로할당을 초기화합니다.", "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.reset": "모든 회로번호 초기화", @@ -1060,7 +1060,7 @@ "outerLine.property.fix": "외벽선 속성 설정을 완료하시겠습니까?", "outerLine.property.close": "외벽선 속성 설정을 종료하시겠습니까?", "want.to.complete.auxiliary.creation": "보조선 작성을 완료하시겠습니까?", - "module.layout.setup.has.zero.value": "모듈의 열, 행을 입력해 주세요.", + "module.layout.setup.has.zero.value": "모듈의 열수, 단수를 입력해 주세요.", "modal.placement.initial.setting.plan.drawing.only.number": "(※ 숫자는 [반각]입력만 가능합니다.)", "wall.line.not.found": "외벽선이 없습니다.", "roof.line.not.found": "지붕형상이 없습니다.", @@ -1069,9 +1069,9 @@ "module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.", "module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다.", "roofAllocation.not.found": "할당할 지붕이 없습니다.", - "modal.module.basic.setting.module.placement.max.size.check": "지붕재별 모듈의 최대 단수. 혼합 최대 단수를 확인하십시오.", + "modal.module.basic.setting.module.placement.max.size.check": "지붕재별 모듈 단체의 최대 단수, 2종 혼합 단수를 확인하십시오.", "modal.module.basic.setting.module.placement.max.row": "최대 단수", - "modal.module.basic.setting.module.placement.max.rows.multiple": "혼합 단수", + "modal.module.basic.setting.module.placement.max.rows.multiple": "2종 혼합 최대단수", "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": "레이아웃 배치" From 04d49e6aa662be8830a89e6cf6fb42e5c4dd4a93 Mon Sep 17 00:00:00 2001 From: ysCha Date: Tue, 22 Apr 2025 13:54:40 +0900 Subject: [PATCH 152/196] =?UTF-8?q?991-=EA=B2=AC=EC=A0=81=EC=84=9C=20prici?= =?UTF-8?q?ng=20=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD,=20confirm=20?= =?UTF-8?q?=EB=85=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 17 +++++++++++++++-- src/locales/ja.json | 1 + src/locales/ko.json | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index dfa313d2..cf38bd7b 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -498,6 +498,18 @@ export default function Estimate({}) { }) } + //Pricing 버튼클릭시 confirm 노출 + const handlePricingBtn = (showPriceCd) => { + swalFire({ + text: getMessage('estimate.detail.showPrice.pricingBtn.confirm'), + type: 'confirm', + icon: 'warning', + confirmFn: () => { + handlePricing(showPriceCd) + }, + }) + } + //Pricing 버튼 const handlePricing = async (showPriceCd) => { const param = { @@ -1808,9 +1820,10 @@ export default function Estimate({}) {
From 08722e8b51e3392b1f1960445f7f8ef6f0f1bf0e Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 2 May 2025 15:50:27 +0900 Subject: [PATCH 175/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=84=A4=EC=B9=98=20=EC=9E=91=EC=97=85?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 79 +++++++++++++++++------ 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index ffff4344..785c6b0f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1822,20 +1822,35 @@ export function useModuleBasicSetting(tabNum) { } //어짜피 자동으로 누르면 선택안된데도 다 날아간다 - canvas.getObjects().forEach((obj) => { - if (obj.name === POLYGON_TYPE.MODULE) { - canvas.remove(obj) - } - }) + // canvas.getObjects().forEach((obj) => { + // if (obj.name === POLYGON_TYPE.MODULE) { + // canvas.remove(obj) + // } + // }) - notSelectedTrestlePolygons.forEach((obj) => { - if (obj.modules) { - obj.modules.forEach((module) => { - canvas?.remove(module) - }) - obj.modules = [] - } - }) + //자동일때만 선택 안된 모듈 삭제 + if (type === MODULE_SETUP_TYPE.AUTO) { + notSelectedTrestlePolygons.forEach((obj) => { + if (obj.modules) { + obj.modules.forEach((module) => { + canvas?.remove(module) + canvas?.renderAll() + }) + obj.modules = [] + } + }) + } else { + //레이아웃일때는 기존에 깔린 모듈은 삭제 하지 않음 선택된 영역만 모듈 삭제 + moduleSetupSurfaces.forEach((obj) => { + if (obj.modules) { + obj.modules.forEach((module) => { + canvas?.remove(module) + canvas?.renderAll() + }) + obj.modules = [] + } + }) + } let moduleOptions = { stroke: 'black', @@ -1936,23 +1951,25 @@ export function useModuleBasicSetting(tabNum) { } else { const normalModule = checkedModule.filter((item) => item.northModuleYn === 'N') const northModule = checkedModule.filter((item) => item.northModuleYn === 'Y') + const northModuleIds = northModule.map((item) => item.itemId) //만약 북면 모듈이 2개면 이 하위 로직 가져다가 쓰면됨 northModule === 만 바꾸면 될듯 // northModule을 배열로 만들고 include로 해서 체크 해야됨 if (normalModule.length > 0 && !moduleSetupSurface.isNorth) { + //C1C2 모듈일 경우ㅁㅁ const isMultipleModules = normalModule.length > 1 //모듈이 여러개면 const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 const maxRow = isMultipleModules ? trestleDetailData.moduleMaxRows : trestleDetailData.module.find((item) => item.moduleTpCd === normalModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 - //단수 합단수 + //북면 모듈 id를 제외한 모듈의 단 체크 const sumRowCount = isMultipleModules - ? layoutSetupRef.filter((item) => item.checked && item.moduleId !== northModule[0].itemId).reduce((acc, cur) => acc + cur.row, 0) + ? layoutSetupRef.filter((item) => item.checked && !northModuleIds.includes(item.moduleId)).reduce((acc, cur) => acc + cur.row, 0) : layoutSetupRef.find((item) => item.moduleId === normalModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 - // - const sumColCount = layoutSetupRef.filter((item) => item.col && item.moduleId !== northModule[0].itemId).some((item) => item.col > maxCol) + //북면 모듈 id를 제외한 모듈의 열 체크 + const sumColCount = layoutSetupRef.filter((item) => item.col && !northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol) if (sumRowCount > maxRow || sumColCount) { failAutoSetupRoof.push(moduleSetupSurface) @@ -1964,7 +1981,7 @@ export function useModuleBasicSetting(tabNum) { isMultipleModules && layoutSetupRef.find( (item, index) => - item.checked && item.moduleId !== northModule[0].itemId && item.row > trestleDetailData.module[index].mixModuleMaxRows, + item.checked && !item.moduleId.includes(northModuleIds) && item.row > trestleDetailData.module[index].mixModuleMaxRows, ) if (isPassedObject) { @@ -1974,16 +1991,36 @@ export function useModuleBasicSetting(tabNum) { } if (northModule.length > 0 && moduleSetupSurface.isNorth) { + const isMultipleModules = northModule.length > 1 //모듈이 여러개면 const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 - const maxRow = trestleDetailData.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 - const sumRowCount = layoutSetupRef.find((item) => item.moduleId === northModule[0].itemId).row - const sumColCount = layoutSetupRef.filter((item) => item.col && item.moduleId !== northModule[0].itemId).some((item) => item.col > maxCol) + const maxRow = isMultipleModules + ? trestleDetailData.moduleMaxRows + : trestleDetailData.module.find((item) => item.moduleTpCd === northModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 + + const sumRowCount = isMultipleModules + ? layoutSetupRef.filter((item) => northModuleIds.includes(item.moduleId)).reduce((acc, cur) => acc + cur.row, 0) + : layoutSetupRef.find((item) => item.moduleId === northModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 + + const sumColCount = layoutSetupRef.filter((item) => item.col && northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol) if (sumRowCount > maxRow || sumColCount) { failAutoSetupRoof.push(moduleSetupSurface) return false } + + // 혼합일때 모듈 개별의 row를 체크함 + const isPassedObject = + isMultipleModules && + layoutSetupRef.find( + (item, index) => + item.checked && northModuleIds.includes(item.moduleId) && item.row > trestleDetailData.module[index].mixModuleMaxRows, + ) + + if (isPassedObject) { + failAutoSetupRoof.push(moduleSetupSurface) + return false + } } } } From e3df21f827a14eba0316775a732bb33d22f51ff7 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 2 May 2025 16:16:23 +0900 Subject: [PATCH 176/196] =?UTF-8?q?http://1.248.227.176:43333/issues/1022?= =?UTF-8?q?=20=EC=83=81=EB=8B=A8=20=EC=9C=A0=ED=8B=B8=EB=A6=AC=ED=8B=B0=20?= =?UTF-8?q?title=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/select/QSelectBox.jsx | 2 ++ src/components/floor-plan/CanvasMenu.jsx | 33 ++++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/components/common/select/QSelectBox.jsx b/src/components/common/select/QSelectBox.jsx index 3e797071..495f3ae6 100644 --- a/src/components/common/select/QSelectBox.jsx +++ b/src/components/common/select/QSelectBox.jsx @@ -26,6 +26,7 @@ export default function QSelectBox({ targetKey = '', showKey = '', params = {}, + tagTitle = '', }) { const { getMessage } = useMessage() @@ -82,6 +83,7 @@ export default function QSelectBox({ className={`sort-select ${openSelect ? 'active' : ''} ${disabled ? 'disabled' : ''}`} ref={ref} onClick={disabled ? () => {} : () => setOpenSelect(!openSelect)} + title={tagTitle} >

{selected}

    diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index a268604e..d4cacee0 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -548,13 +548,26 @@ export default function CanvasMenu(props) { {
    {getMessage('plan.mode.vertical.horizontal')} - +
    }
    - - - + + +
    {isObjectNotEmpty(selectedRoofMaterial) && addedRoofs.length > 0 && (
    @@ -580,6 +593,7 @@ export default function CanvasMenu(props) { sourceKey={'index'} targetKey={'index'} disabled={+basicSetting.roofSizeSet === 3} + tagTitle={'屋根材変更'} /> }
    @@ -588,9 +602,10 @@ export default function CanvasMenu(props) { {/**/} - +
- {canvasZoom}% + + {canvasZoom}% +
- - + +
)} From 9a800d307bce8d6981e7075c3c3dd3928339e5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 2 May 2025 16:42:38 +0900 Subject: [PATCH 177/196] =?UTF-8?q?-=20=EB=8B=A4=EC=84=A4=EC=8B=9C?= =?UTF-8?q?=EA=B3=B5=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?-=20trestle=EC=97=90=EC=84=9C=20=EC=B0=B8=EC=A1=B0=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=A7=80=EB=B6=95=EC=A0=95=EB=B3=B4=EC=97=90=20?= =?UTF-8?q?=EC=B0=B8=EC=A1=B0=ED=95=98=EB=8A=94=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EC=A4=91=20raftBaseCd=20->=20raft=20=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Trestle.jsx | 10 +++++----- src/hooks/module/useModuleTrestle.js | 2 +- src/locales/ja.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 872ab6b9..ae471bc0 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -625,19 +625,19 @@ const Trestle = forwardRef((props, ref) => {
diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 3d14d600..361ad541 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -24,7 +24,7 @@ const trestleReducer = (state, action) => { moduleTpCd: action.roof.module?.itemTp ?? '', roofMatlCd: action.roof?.roofMatlCd ?? '', hajebichi: action.roof?.hajebichi ?? 0, - raftBaseCd: action.roof?.raftBaseCd ?? null, + raftBaseCd: action.roof?.raft ?? null, trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null, constMthdCd: action.roof.trestle?.constMthdCd ?? null, constTp: action.roof.construction?.constTp ?? null, diff --git a/src/locales/ja.json b/src/locales/ja.json index 73ee56c9..f68f5ff5 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -110,7 +110,7 @@ "modal.module.basic.setting.module.standard.snowfall.amount": "積雪量", "modal.module.basic.setting.module.standard.construction": "標準施工", "modal.module.basic.setting.module.enforce.construction": "強化施工", - "modal.module.basic.setting.module.multiple.construction": "多設施工", + "modal.module.basic.setting.module.multiple.construction": "多雪施工", "modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置", "modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置", "modal.module.basic.setting.module.select": "モジュール/架台選択", From 655f0781a2652a6d3dd97a44aac23949365a58f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 7 May 2025 11:34:03 +0900 Subject: [PATCH 178/196] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../images/sub/oneonone_profile_icon.svg | 4 + src/styles/_contents.scss | 40 ++-- src/styles/_modal.scss | 42 ++-- src/styles/_reset.scss | 19 ++ src/styles/_submodal.scss | 200 ++++++++++++++---- 5 files changed, 228 insertions(+), 77 deletions(-) create mode 100644 public/static/images/sub/oneonone_profile_icon.svg diff --git a/public/static/images/sub/oneonone_profile_icon.svg b/public/static/images/sub/oneonone_profile_icon.svg new file mode 100644 index 00000000..f1c3d923 --- /dev/null +++ b/public/static/images/sub/oneonone_profile_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss index bfd7b1f8..58f9a3ca 100644 --- a/src/styles/_contents.scss +++ b/src/styles/_contents.scss @@ -806,28 +806,28 @@ color: #45576F; margin-left: 5px; } -.drag-file-box{ - padding: 10px; - .btn-area{ - padding-bottom: 15px; - border-bottom: 1px solid #ECF0F4; - .file-upload{ - display: inline-block; - height: 30px; - background-color: #94A0AD; - padding: 0 10px; - border-radius: 2px; - font-size: 13px; - line-height: 30px; - color: #fff; - font-weight: 500; - cursor: pointer; - transition: background .15s ease-in-out; - &:hover{ - background-color: #607F9A; - } +.btn-area{ + padding-bottom: 15px; + border-bottom: 1px solid #ECF0F4; + .file-upload{ + display: inline-block; + height: 30px; + background-color: #94A0AD; + padding: 0 10px; + border-radius: 2px; + font-size: 13px; + line-height: 30px; + color: #fff; + font-weight: 500; + cursor: pointer; + transition: background .15s ease-in-out; + &:hover{ + background-color: #607F9A; } } +} +.drag-file-box{ + padding: 10px; .drag-file-area{ position: relative; margin-top: 15px; diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index fef7c2fd..7b94f2b4 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -2363,20 +2363,6 @@ $alert-color: #101010; } } -.module-area{ - display: flex; - align-items: center; - .module-area-title{ - flex: none; - font-size: 12px; - color: #fff; - font-weight: 500; - margin-right: 20px; - } - .outline-form{ - flex: 1; - } -} .placement-name-guide{ font-size: 11px; @@ -2422,4 +2408,32 @@ $alert-color: #101010; overflow: hidden; height: 0; } +} + +// 2025-05-07 지붕모듈 +.module-input-area{ + display: flex; + align-items: center; + margin-top: 10px; + .module-area-title{ + flex: none; + font-size: 12px; + color: #fff; + font-weight: 500; + margin-right: 20px; + } + .module-input-wrap{ + width: 100%; + display: flex; + .outline-form{ + width: calc(33.333% - 10px); + margin-right: 15px; + &:last-child{ + margin-right: 0; + } + .input-grid{ + width: 100%; + } + } + } } \ No newline at end of file diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss index a3d2bddc..ecb7f2cb 100644 --- a/src/styles/_reset.scss +++ b/src/styles/_reset.scss @@ -1024,4 +1024,23 @@ input:checked + .slider { // alert z-index .swal2-container{ z-index: 120000; +} + +// textarea +.textarea-form{ + width: 100%; + outline: none; + resize: none; + border: none; + border: 1px solid #eee; + min-height: 150px; + padding: 10px; + font-size: 13px; + color: #45576F; + border-radius: 2px; + font-family: "Noto Sans JP", sans-serif; + transition: border .15s ease-in-out; + &:focus{ + border-color: #94a0ad; + } } \ No newline at end of file diff --git a/src/styles/_submodal.scss b/src/styles/_submodal.scss index de53d584..40beae5e 100644 --- a/src/styles/_submodal.scss +++ b/src/styles/_submodal.scss @@ -288,55 +288,56 @@ } // 커뮤니티 -.community_detail{ - .community_detail-tit{ - font-size: 16px; - color: #101010; - font-weight: 600; - padding-bottom: 14px; - border-bottom: 2px solid #101010; - } - .community_detail-file-wrap{ - padding: 24px 0; - border-bottom: 1px solid #E5E5E5; - dt{ - font-size: 13px; - color: #101010; - font-weight: 500; - margin-bottom: 15px; - } - dd{ - font-size: 12px; - font-weight: 400; - margin-bottom: 3px; - color: #344356; - &:last-child{ - margin-bottom: 0; - } - } - } - .community_detail-inner{ - max-height: 300px; - overflow-y: auto; - margin-top: 20px; - margin-bottom: 20px; +.community_detail-tit{ + font-size: 16px; + color: #101010; + font-weight: 600; + padding-bottom: 14px; + border-bottom: 2px solid #101010; +} +.community_detail-file-wrap{ + padding: 24px 0; + border-bottom: 1px solid #E5E5E5; + dt{ font-size: 13px; + color: #101010; + font-weight: 500; + } + dd{ + font-size: 12px; font-weight: 400; - color: #45576F; - line-height: 26px; - word-break: keep-all; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; + margin-bottom: 3px; + color: #344356; + &:nth-child(2){ + margin-top: 15px; } - &::-webkit-scrollbar-thumb { - background-color: #C1CCD7; - } - &::-webkit-scrollbar-track { - background-color: transparent; + &:last-child{ + margin-bottom: 0; } } } +.community_detail-inner{ + max-height: 300px; + overflow-y: auto; + margin-top: 20px; + margin-bottom: 20px; + font-size: 13px; + font-weight: 400; + color: #45576F; + line-height: 26px; + word-break: keep-all; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #C1CCD7; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } +} + // 견적 복사 .estimate-copy-info-item{ @@ -368,4 +369,117 @@ color: #999; } } +} + +// 1:1문의 +.one-on-one{ + .select-wrap{ + width: 250px; + } + .input-wrap{ + flex: 1 1 auto; + } + &.btn-area{ + padding-bottom: 0; + border: none; + margin-left: 10px; + } + &.drag-file-box{ + border: 1px solid #eee; + .drag-file-area{ + margin-top: 0; + } + } +} + +.oneonone-header-wrap{ + padding-bottom: 14px; + border-bottom: 2px solid #101010; + .oneonone-title{ + font-size: 16px; + color: #101010; + font-weight: 600; + margin-bottom: 14px; + } +} +.oneonone-infor{ + display: flex; + align-items: center; + .profile{ + position: relative; + padding-left: 26px; + padding-right: 8px; + font-size: 13px; + font-weight: 400; + color: #101010; + &::before{ + content: ''; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + width: 24px; + height: 24px; + background: url(./../../public/static/images/sub/oneonone_profile_icon.svg)no-repeat center; + } + &::after{ + content: ''; + position: absolute; + top: 50%; + right: 0; + transform: translateY(-50%); + width: 1px; + height: 8px; + background-color: #CCCCCC; + } + } + .date{ + padding-left: 8px; + font-size: 13px; + font-weight: 400; + color: #101010; + } +} +.oneonone-detail{ + padding: 20px; + border: 1px solid #101010; + border-top: none; + .community_detail-file-wrap{ + padding-top: 0; + } + .community_detail-inner{ + max-height: 110px; + margin-top: 24px; + margin-bottom: 0; + } +} + +.oneonone-answer{ + margin-top: 8px; + padding: 20px; + border: 1px solid #101010; + .community_detail-inner{ + max-height: 110px; + + } + .community_detail-file-wrap{ + border-top: 1px solid #D4DCE7; + padding: 16px 0 0 0; + border-bottom: none; + } +} + +.answer-title-wrap{ + display: flex; + align-items: center; + padding-bottom: 14px; + border-bottom: 1px solid #D4DCE7; + .answer-title{ + font-size: 14px; + color: #101010; + font-weight: 600; + } + .oneonone-infor{ + margin-left: auto; + } } \ No newline at end of file From f846644145c20fbcef7512a9b585bb51ee3664bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 7 May 2025 11:34:22 +0900 Subject: [PATCH 179/196] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EA=B0=84=EA=B2=A9?= =?UTF-8?q?=20=EC=98=81=EC=97=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Trestle.jsx | 91 ++++++++++++------- src/locales/ja.json | 3 + src/locales/ko.json | 3 + 3 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index ae471bc0..b184670e 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -667,46 +667,67 @@ const Trestle = forwardRef((props, ref) => {
-
+
{getMessage('modal.module.basic.setting.module.placement.area')}
-
- {getMessage('modal.module.basic.setting.module.placement.area.eaves')} -
- dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })} - onChange={(e) => setEavesMargin(+e.target.value)} - /> +
+
+ {getMessage('modal.module.basic.setting.module.placement.area.eaves')} +
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })} + onChange={(e) => setEavesMargin(+e.target.value)} + /> +
+ mm +
+
+ {getMessage('modal.module.basic.setting.module.placement.area.ridge')} +
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })} + onChange={(e) => setRidgeMargin(+e.target.value)} + /> +
+ mm +
+
+ {getMessage('modal.module.basic.setting.module.placement.area.keraba')} +
+ dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })} + onChange={(e) => setKerabaMargin(+e.target.value)} + /> +
+ mm
- mm
-
- {getMessage('modal.module.basic.setting.module.placement.area.ridge')} -
- dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })} - onChange={(e) => setRidgeMargin(+e.target.value)} - /> +
+
+
{getMessage('modal.module.basic.setting.module.placement.margin')}
+
+
+ {getMessage('modal.module.basic.setting.module.placement.margin.horizontal')} +
+ +
+ mm
- mm -
-
- {getMessage('modal.module.basic.setting.module.placement.area.keraba')} -
- dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })} - onChange={(e) => setKerabaMargin(+e.target.value)} - /> +
+ {getMessage('modal.module.basic.setting.module.placement.margin.vertical')} +
+ +
+ mm
- mm
diff --git a/src/locales/ja.json b/src/locales/ja.json index fddf8719..5aa10f4b 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -97,9 +97,12 @@ "modal.module.basic.setting.module.under.roof": "屋根下地", "modal.module.basic.setting.module.setting": "モジュールの選択", "modal.module.basic.setting.module.placement.area": "モジュール配置領域", + "modal.module.basic.setting.module.placement.margin": "モジュール間の間隙", "modal.module.basic.setting.module.placement.area.eaves": "軒側", "modal.module.basic.setting.module.placement.area.ridge": "棟側", "modal.module.basic.setting.module.placement.area.keraba": "けらぱ", + "modal.module.basic.setting.module.placement.margin.horizontal": "左右", + "modal.module.basic.setting.module.placement.margin.vertical": "上下", "modal.module.basic.setting.module.hajebichi": "ハゼピッチ", "modal.module.basic.setting.module.setting.info1": "※勾配の範囲には制限があります。屋根傾斜が2.5値未満10値を超える場合は、施工が可能かどうか施工マニュアルを確認してください。", "modal.module.basic.setting.module.setting.info2": "※モジュール配置時は、施工マニュアルに記載されている<モジュール配置条件>を必ずご確認ください。", diff --git a/src/locales/ko.json b/src/locales/ko.json index 1090b4b1..675dc84f 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -97,9 +97,12 @@ "modal.module.basic.setting.module.under.roof": "지붕밑바탕", "modal.module.basic.setting.module.setting": "모듈 선택", "modal.module.basic.setting.module.placement.area": "모듈 배치 영역", + "modal.module.basic.setting.module.placement.margin": "모듈 배치 간격", "modal.module.basic.setting.module.placement.area.eaves": "처마쪽", "modal.module.basic.setting.module.placement.area.ridge": "용마루쪽", "modal.module.basic.setting.module.placement.area.keraba": "케라바쪽", + "modal.module.basic.setting.module.placement.margin.horizontal": "좌우", + "modal.module.basic.setting.module.placement.margin.vertical": "상하", "modal.module.basic.setting.module.hajebichi": "망둥어 피치", "modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.", "modal.module.basic.setting.module.setting.info2": "※ 모듈 배치 시에는 시공 매뉴얼에 기재된 <모듈 배치 조건>을 반드시 확인해주십시오.", From d6b0e4994af85b6360f2b60759027913e68ae235 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 7 May 2025 14:47:08 +0900 Subject: [PATCH 180/196] =?UTF-8?q?#=20[1014]=20:=20819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # [작업내용] : http://1.248.227.176:43333/issues/1014 --- .../floor-plan/modal/basic/BasicSetting.jsx | 6 +- .../floor-plan/modal/basic/step/Placement.jsx | 6 +- src/hooks/module/useModuleBasicSetting.js | 170 +++++------------- src/locales/ja.json | 4 +- 4 files changed, 57 insertions(+), 129 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 66a76d71..a70b9a22 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -331,15 +331,15 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { + - )} diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 5d2c8c6a..c6556ea3 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -37,7 +37,7 @@ const Placement = forwardRef((props, refs) => { const resetModuleSetupOption = useResetRecoilState(moduleSetupOptionState) const [colspan, setColspan] = useState(1) - const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState) + const moduleRowColArray = useRecoilValue(moduleRowColArrayState) //모듈 배치면 생성 useEffect(() => { @@ -337,6 +337,7 @@ const Placement = forwardRef((props, refs) => {
))} + {colspan > 1 && {getMessage('total')}} {selectedModules.itemList.map((item) => ( @@ -356,10 +357,11 @@ const Placement = forwardRef((props, refs) => { {item.addRoof?.roofMatlNmJp}
- {moduleRowColArray[index]?.map((item) => ( + {moduleRowColArray[index]?.map((item, index2) => ( <> {item.moduleMaxRows} {colspan > 1 && {item.mixModuleMaxRows}} + {colspan > 1 && index2 === moduleRowColArray[index].length - 1 && {item.maxRow}} ))} diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 785c6b0f..c43477d7 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -49,20 +49,17 @@ export function useModuleBasicSetting(tabNum) { const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState) const canvasSetting = useRecoilValue(canvasSettingState) const moduleSelectionData = useRecoilValue(moduleSelectionDataState) - const [trestleDetailParams, setTrestleDetailParams] = useState([]) const [trestleDetailList, setTrestleDetailList] = useState([]) const selectedModules = useRecoilValue(selectedModuleState) - const { getTrestleDetailList } = useMasterController() const [saleStoreNorthFlg, setSaleStoreNorthFlg] = useState(false) const setCurrentObject = useSetRecoilState(currentObjectState) const { setModuleStatisticsData } = useCircuitTrestle() const { createRoofPolygon, createMarginPolygon, createPaddingPolygon } = useMode() - const { drawDirectionArrow } = usePolygon() const moduleSetupOption = useRecoilValue(moduleSetupOptionState) const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState) - const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState) + const setModuleRowColArray = useSetRecoilState(moduleRowColArrayState) useEffect(() => { return () => { @@ -111,10 +108,6 @@ export function useModuleBasicSetting(tabNum) { } } - useEffect(() => { - console.log('saleStoreNorthFlg', saleStoreNorthFlg) - }, [saleStoreNorthFlg]) - //가대 상세 데이터 들어오면 실행 useEffect(() => { if (trestleDetailList.length > 0) { @@ -153,7 +146,7 @@ export function useModuleBasicSetting(tabNum) { const moduleRowArray = [] if (isObjectNotEmpty(detail) && detail.module.length > 0) { detail.module.forEach((module) => { - moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows }) + moduleRowArray.push({ moduleMaxRows: module.moduleMaxRows, mixModuleMaxRows: module.mixModuleMaxRows, maxRow: detail.moduleMaxRows }) }) } rowColArray.push(moduleRowArray) @@ -456,14 +449,14 @@ export function useModuleBasicSetting(tabNum) { } if (checkedModule.length === 0) { - swalFire({ text: getMessage('module.place.select.module') }) + swalFire({ text: getMessage('module.place.select.module'), icon: 'warning' }) setIsManualModuleSetup(false) setManualSetupMode(`manualSetup_false`) return } if (checkedModule.length > 1) { - swalFire({ text: getMessage('module.place.select.one.module') }) + swalFire({ text: getMessage('module.place.select.one.module'), icon: 'warning' }) setIsManualModuleSetup(false) setManualSetupMode(`manualSetup_false`) return @@ -1048,26 +1041,6 @@ export function useModuleBasicSetting(tabNum) { }, ] - //아래래 - // let points = [ - // { - // x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, - // y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, - // }, - // { - // x: Number(mousePoint.x.toFixed(1)) - calcHalfWidth, - // y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, - // }, - // { - // x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, - // y: Number(mousePoint.y.toFixed(1)) + calcHalfHeight, - // }, - // { - // x: Number(mousePoint.x.toFixed(1)) + calcHalfWidth, - // y: Number(mousePoint.y.toFixed(1)) - calcHalfHeight, - // }, - // ] - const turfPoints = coordToTurfPolygon(points) if (turf.booleanWithin(turfPoints, turfPolygon)) { @@ -1829,6 +1802,16 @@ export function useModuleBasicSetting(tabNum) { // }) //자동일때만 선택 안된 모듈 삭제 + moduleSetupSurfaces.forEach((obj) => { + if (obj.modules) { + obj.modules.forEach((module) => { + canvas?.remove(module) + canvas?.renderAll() + }) + obj.modules = [] + } + }) + if (type === MODULE_SETUP_TYPE.AUTO) { notSelectedTrestlePolygons.forEach((obj) => { if (obj.modules) { @@ -1839,17 +1822,6 @@ export function useModuleBasicSetting(tabNum) { obj.modules = [] } }) - } else { - //레이아웃일때는 기존에 깔린 모듈은 삭제 하지 않음 선택된 영역만 모듈 삭제 - moduleSetupSurfaces.forEach((obj) => { - if (obj.modules) { - obj.modules.forEach((module) => { - canvas?.remove(module) - canvas?.renderAll() - }) - obj.modules = [] - } - }) } let moduleOptions = { @@ -1864,9 +1836,6 @@ export function useModuleBasicSetting(tabNum) { name: POLYGON_TYPE.MODULE, } - //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직 - const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y') - //선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환 const objectsIncludeSurface = (turfModuleSetupSurface) => { let containsBatchObjects = [] @@ -1895,49 +1864,46 @@ export function useModuleBasicSetting(tabNum) { /** * 자동 레이아웃 설치 일시 row col 초과 여부 확인 + * 체크된 모듈중에 북면 모듈이 있으면 북면 모듈만 따로 계산하고 아니면 전체 모듈을 계산 + * 북면 모듈이 있고 북면이 들어오면 북면의 row를 계산한다 + * * @param {*} trestleDetailData * @returns */ const checkAutoLayoutModuleSetup = (moduleSetupSurface, trestleDetailData) => { - /** - * 체크된 모듈중에 북면 모듈이 있으면 북면 모듈만 따로 계산하고 아니면 전체 모듈을 계산 - * 북면 모듈이 있고 북면이 들어오면 북면의 row를 계산한다 - * - */ - //북면 모듈이 없을때 + //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직 + const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y') + const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 + + //북면 모듈이 없으면 if (!isIncludeNorthModule) { - const isMultipleModules = checkedModule.length > 1 //모듈이 여러개면 - const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 + const isMultipleModules = checkedModule.length > 1 //모듈이 여러개인지 체크하고 + + //멀티 모듈이면 모듈밖에 내려온 정보의 maxRow 단일 모듈이면 모듈에 maxRow const maxRow = isMultipleModules ? trestleDetailData.moduleMaxRows : trestleDetailData.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 - //단수 합단수 + //멀티 모듈이면 모듈밖에 내려온 정보의 row 합, 단일 모듈이면 모듈에 row const sumRowCount = isMultipleModules ? layoutSetupRef.filter((item) => item.checked).reduce((acc, cur) => acc + cur.row, 0) : layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 - // + //col는 moduleItems 배열 밖에 내려옴 const sumColCount = layoutSetupRef.filter((item) => item.col).some((item) => item.col > maxCol) - if (sumRowCount > maxRow || sumColCount) { - failAutoSetupRoof.push(moduleSetupSurface) - return false - } - - // 혼합일때 모듈 개별의 row를 체크함 + // 혼합일때 모듈 개별의 maxRow를 체크해서 가능여부 확인 const isPassedObject = - isMultipleModules && layoutSetupRef.find((item, index) => item.checked && item.row > trestleDetailData.module[index].mixModuleMaxRows) - - if (isPassedObject) { + isMultipleModules && layoutSetupRef.find((item, index) => item.checked && item.row > trestleDetailData.module[index].mixModuleMaxRows) //체크된 배열은 checked여부로 체크해서 index와 동일함 + //전체 카은트된 열수가 크거나 혼합카운트가 존재 하면 실패 + if (sumRowCount > maxRow || sumColCount || isPassedObject) { failAutoSetupRoof.push(moduleSetupSurface) return false } } else { //북면 모듈만 선택했을때 if (checkedModule.length === 1) { - const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 const maxRow = trestleDetailData.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 //단수 합단수 @@ -1958,7 +1924,6 @@ export function useModuleBasicSetting(tabNum) { if (normalModule.length > 0 && !moduleSetupSurface.isNorth) { //C1C2 모듈일 경우ㅁㅁ const isMultipleModules = normalModule.length > 1 //모듈이 여러개면 - const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 const maxRow = isMultipleModules ? trestleDetailData.moduleMaxRows : trestleDetailData.module.find((item) => item.moduleTpCd === normalModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 @@ -1971,11 +1936,6 @@ export function useModuleBasicSetting(tabNum) { //북면 모듈 id를 제외한 모듈의 열 체크 const sumColCount = layoutSetupRef.filter((item) => item.col && !northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol) - if (sumRowCount > maxRow || sumColCount) { - failAutoSetupRoof.push(moduleSetupSurface) - return false - } - // 혼합일때 모듈 개별의 row를 체크함 const isPassedObject = isMultipleModules && @@ -1984,16 +1944,15 @@ export function useModuleBasicSetting(tabNum) { item.checked && !item.moduleId.includes(northModuleIds) && item.row > trestleDetailData.module[index].mixModuleMaxRows, ) - if (isPassedObject) { + // 합산 단수가 맥스단수보다 크거나 열이 맥스열수보다 크거나 혼합일때 모듈 개별의 row가 맥스단수보다 크면 실패 + if (sumRowCount > maxRow || sumColCount || isPassedObject) { failAutoSetupRoof.push(moduleSetupSurface) return false } } - if (northModule.length > 0 && moduleSetupSurface.isNorth) { + if (northModule.length > 0) { const isMultipleModules = northModule.length > 1 //모듈이 여러개면 - const maxCol = trestleDetailData.moduleMaxCols //최대 열수 -> 얘는 멀티랑 관계없음 - const maxRow = isMultipleModules ? trestleDetailData.moduleMaxRows : trestleDetailData.module.find((item) => item.moduleTpCd === northModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 @@ -2004,11 +1963,6 @@ export function useModuleBasicSetting(tabNum) { const sumColCount = layoutSetupRef.filter((item) => item.col && northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol) - if (sumRowCount > maxRow || sumColCount) { - failAutoSetupRoof.push(moduleSetupSurface) - return false - } - // 혼합일때 모듈 개별의 row를 체크함 const isPassedObject = isMultipleModules && @@ -2017,7 +1971,8 @@ export function useModuleBasicSetting(tabNum) { item.checked && northModuleIds.includes(item.moduleId) && item.row > trestleDetailData.module[index].mixModuleMaxRows, ) - if (isPassedObject) { + // 합산 단수가 맥스단수보다 크거나 열이 맥스열수보다 크거나 혼합일때 모듈 개별의 row가 맥스단수보다 크면 실패 + if (sumRowCount > maxRow || sumColCount || isPassedObject) { failAutoSetupRoof.push(moduleSetupSurface) return false } @@ -2028,16 +1983,7 @@ export function useModuleBasicSetting(tabNum) { } //흐름 방향이 남쪽(아래) - const downFlowSetupModule = ( - surfaceMaxLines, //deprecated - maxLengthLine, - moduleSetupArray, - moduleSetupSurface, - containsBatchObjects, - isCenter = false, //deprecated - intvHor, - intvVer, - ) => { + const downFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => { let setupModule = [] const trestleDetailData = moduleSetupSurface.trestleDetail @@ -2215,16 +2161,7 @@ export function useModuleBasicSetting(tabNum) { } } - const topFlowSetupModule = ( - surfaceMaxLines, - maxLengthLine, - moduleSetupArray, - moduleSetupSurface, - containsBatchObjects, - isCenter = false, - intvHor, - intvVer, - ) => { + const topFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => { let setupModule = [] const trestleDetailData = moduleSetupSurface.trestleDetail @@ -2405,12 +2342,11 @@ export function useModuleBasicSetting(tabNum) { //남, 북과 같은 로직으로 적용하려면 좌우는 열 -> 행 으로 그려야함 //변수명은 bottom 기준으로 작성하여 동일한 방향으로 진행한다 const leftFlowSetupModule = ( - surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, - isCenter = false, + intvHor, intvVer, ) => { @@ -2597,16 +2533,7 @@ export function useModuleBasicSetting(tabNum) { } } - const rightFlowSetupModule = ( - surfaceMaxLines, - maxLengthLine, - moduleSetupArray, - moduleSetupSurface, - containsBatchObjects, - isCenter = false, - intvHor, - intvVer, - ) => { + const rightFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => { let setupModule = [] const trestleDetailData = moduleSetupSurface.trestleDetail //가대 상세 데이터 @@ -2798,7 +2725,6 @@ export function useModuleBasicSetting(tabNum) { const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //폴리곤을 turf 객체로 변환 const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 - const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface) let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => { return acc.length > cur.length ? acc : cur @@ -2819,30 +2745,30 @@ export function useModuleBasicSetting(tabNum) { if (setupLocation === 'eaves') { // 흐름방향이 남쪽일때 if (moduleSetupSurface.direction === 'south') { - downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + downFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } if (moduleSetupSurface.direction === 'west') { - leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + leftFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } if (moduleSetupSurface.direction === 'east') { - rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + rightFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } if (moduleSetupSurface.direction === 'north') { - topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + topFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } } else if (setupLocation === 'ridge') { //용마루 if (moduleSetupSurface.direction === 'south') { - topFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + topFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } if (moduleSetupSurface.direction === 'west') { - rightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + rightFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } if (moduleSetupSurface.direction === 'east') { - leftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + leftFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } if (moduleSetupSurface.direction === 'north') { - downFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, false, intvHor, intvVer) + downFlowSetupModule(maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) } } diff --git a/src/locales/ja.json b/src/locales/ja.json index c6a1ea0e..44bf3bb4 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1071,8 +1071,8 @@ "module.layout.setup.max.count.multiple": "モジュール{0}の単体での最大段数は{1}、最大列数は{2}です。 (JA)", "roofAllocation.not.found": "割り当てる屋根がありません。 (JA)", "modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの単体の単体での最大段数、2種混合の段数を確認して下さい", - "modal.module.basic.setting.module.placement.max.row": "単体での最大段数", - "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時の最大段数", + "modal.module.basic.setting.module.placement.max.row": "単体で\rの最大段数", + "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時\rの最大段数", "modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)", "modal.module.basic.setting.module.placement.mix.asg.yn": "混合", "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)" From d244ba3b97c426cefbfa7923a7a8c438c37d5b0e Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 7 May 2025 15:18:59 +0900 Subject: [PATCH 181/196] =?UTF-8?q?[1014]=20:=20[819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 고도화 단수 열수 자동 배치 작업 --- .gitmessage.txt | 3 +++ .../floor-plan/modal/basic/step/Placement.jsx | 9 +++++---- src/hooks/module/useModuleBasicSetting.js | 11 +++-------- src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 5 files changed, 15 insertions(+), 14 deletions(-) create mode 100644 .gitmessage.txt diff --git a/.gitmessage.txt b/.gitmessage.txt new file mode 100644 index 00000000..07932f22 --- /dev/null +++ b/.gitmessage.txt @@ -0,0 +1,3 @@ +[일감번호] : [제목] + +[작업내용] : \ No newline at end of file diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index c6556ea3..1d2545e6 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -330,20 +330,21 @@ const Placement = forwardRef((props, refs) => { {selectedModules && selectedModules.itemList.map((item) => ( - + // +
{item.itemNm}
))} - {colspan > 1 && {getMessage('total')}} + {colspan > 1 && {getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}} {selectedModules.itemList.map((item) => ( <> {getMessage('modal.module.basic.setting.module.placement.max.row')} - {colspan > 1 && {getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}} + {/* {colspan > 1 && {getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}} */} ))} @@ -360,7 +361,7 @@ const Placement = forwardRef((props, refs) => { {moduleRowColArray[index]?.map((item, index2) => ( <> {item.moduleMaxRows} - {colspan > 1 && {item.mixModuleMaxRows}} + {/* {colspan > 1 && {item.mixModuleMaxRows}} */} {colspan > 1 && index2 === moduleRowColArray[index].length - 1 && {item.maxRow}} ))} diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index c43477d7..c7173dca 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -2809,14 +2809,9 @@ export function useModuleBasicSetting(tabNum) { /** * 자동 레이아웃일떄 설치 가능한 애들은 설치 해주고 실패한 애들은 이름, 최대 설치 가능한 높이 알려줄라고 */ - if (type === MODULE_SETUP_TYPE.LAYOUT && failAutoSetupRoof.length > 0) { - const roofNamesList = failAutoSetupRoof.map((roof) => ({ - roofName: roof.roofMaterial.roofMatlNmJp, - moduleMaxRows: roof.trestleDetail.moduleMaxRows, - })) - - const alertString = roofNamesList.map((item, index) => `${item.roofName}(${item.moduleMaxRows})`) - swalFire({ text: alertString, icon: 'warning' }) + if (type === MODULE_SETUP_TYPE.LAYOUT && failAutoSetupRoof.length) { + const roofNames = failAutoSetupRoof.map((roof) => roof.roofMaterial.roofMatlNmJp).join(', ') + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.over.max.row', [roofNames]), icon: 'warning' }) } } diff --git a/src/locales/ja.json b/src/locales/ja.json index 44bf3bb4..343673d5 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1075,5 +1075,6 @@ "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時\rの最大段数", "modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)", "modal.module.basic.setting.module.placement.mix.asg.yn": "混合", - "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)" + "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)", + "modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요.(JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index cd8b855b..b3e3e99b 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1076,5 +1076,6 @@ "modal.module.basic.setting.module.placement.max.rows.multiple": "2종 혼합 최대단수", "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": "레이아웃 배치" + "modal.module.basic.setting.layoutpassivity.placement": "레이아웃 배치", + "modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요." } From f3b8ee40fab1f229f975c57ae7707b6a7b9b0494 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 7 May 2025 16:56:28 +0900 Subject: [PATCH 182/196] =?UTF-8?q?[1014]=20:=20[819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 문구 수정 및 alert icon 정리 --- src/hooks/module/useModuleBasicSetting.js | 34 +++++++++++------------ src/locales/ja.json | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index c7173dca..4471bc74 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -89,12 +89,12 @@ export function useModuleBasicSetting(tabNum) { //roofIndex 넣기 const roofConstructionArray = roofConstructions.map((detail) => ({ ...detail.trestleDetail, roofIndex: detail.roofIndex })) - setTrestleDetailList(roofConstructionArray) - //북면 설치 가능 판매점 if (moduleSelectionData.common.saleStoreNorthFlg == '1') { setSaleStoreNorthFlg(true) } + + setTrestleDetailList(roofConstructionArray) } } else { //육지붕 일경우에는 바로 배치면 설치LL @@ -865,10 +865,10 @@ export function useModuleBasicSetting(tabNum) { // getModuleStatistics() } else { - swalFire({ text: getMessage('module.place.overlab') }) + swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' }) } } else { - swalFire({ text: getMessage('module.place.out') }) + swalFire({ text: getMessage('module.place.out'), icon: 'warning' }) } } }) @@ -1266,7 +1266,7 @@ export function useModuleBasicSetting(tabNum) { const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn //현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능 if (checkedModule[0].mixAsgYn !== mixAsgYn) { - swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' }) return } } @@ -1425,7 +1425,7 @@ export function useModuleBasicSetting(tabNum) { // canvas.renderAll() } } else { - swalFire({ text: getMessage('module.place.overlab') }) + swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' }) return } } @@ -1520,7 +1520,7 @@ export function useModuleBasicSetting(tabNum) { // canvas.renderAll() } } else { - swalFire({ text: getMessage('module.place.overlab') }) + swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' }) return } } @@ -1613,7 +1613,7 @@ export function useModuleBasicSetting(tabNum) { // canvas.renderAll() } } else { - swalFire({ text: getMessage('module.place.overlab') }) + swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' }) return } } @@ -1705,7 +1705,7 @@ export function useModuleBasicSetting(tabNum) { // canvas.renderAll() } } else { - swalFire({ text: getMessage('module.place.overlab') }) + swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' }) return } } @@ -1790,7 +1790,7 @@ export function useModuleBasicSetting(tabNum) { const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체 if (moduleSetupSurfaces.length === 0) { - swalFire({ text: getMessage('module.place.no.surface') }) + swalFire({ text: getMessage('module.place.no.surface'), icon: 'warning' }) return } @@ -3119,13 +3119,13 @@ export function useModuleBasicSetting(tabNum) { let 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') }) + swalFire({ text: getMessage('module.place.select.module'), icon: 'warning' }) setIsManualModuleSetup(!isManualModuleSetup) return } if (checkedModule.length > 1) { - swalFire({ text: getMessage('module.place.select.one.module') }) + swalFire({ text: getMessage('module.place.select.one.module'), icon: 'warning' }) setIsManualModuleSetup(!isManualModuleSetup) return } @@ -3438,7 +3438,7 @@ export function useModuleBasicSetting(tabNum) { const mixAsgYn = trestlePolygon.modules[0].moduleInfo.mixAsgYn //현재 체크된 모듈기준으로 혼합가능인지 확인 Y === Y, N === N 일때만 설치 가능 if (checkedModule[0].mixAsgYn !== mixAsgYn) { - swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' }) return } } @@ -3471,7 +3471,7 @@ export function useModuleBasicSetting(tabNum) { const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인 //겹치면 안됨 if (intersection) { - swalFire({ text: getMessage('module.place.overobject') }) + swalFire({ text: getMessage('module.place.overobject'), icon: 'warning' }) isIntersection = false } }) @@ -3489,10 +3489,10 @@ export function useModuleBasicSetting(tabNum) { manualDrawModules.push(manualModule) setModuleStatisticsData() } else { - swalFire({ text: getMessage('module.place.overlab') }) + swalFire({ text: getMessage('module.place.overlab'), icon: 'warning' }) } } else { - swalFire({ text: getMessage('module.place.out') }) + swalFire({ text: getMessage('module.place.out'), icon: 'warning' }) } } }) @@ -3522,7 +3522,7 @@ export function useModuleBasicSetting(tabNum) { //Y인 모듈과 N인 모듈이 둘다 존재하면 설치 불가 if (mixAsgY.length > 0 && mixAsgN.length > 0) { - swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error') }) + swalFire({ text: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn.error'), icon: 'warning' }) return } diff --git a/src/locales/ja.json b/src/locales/ja.json index b37fbc3a..d378ff36 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1079,5 +1079,5 @@ "modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)", "modal.module.basic.setting.module.placement.mix.asg.yn": "混合", "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)", - "modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요.(JA)" + "modal.module.basic.setting.module.placement.over.max.row": "{0} 最大段数超過しました。最大段数表を参考にしてください。" } From 0fc7ed857d02271264f13afa298a749a33c7c6e2 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 7 May 2025 17:56:36 +0900 Subject: [PATCH 183/196] =?UTF-8?q?[=EA=B3=B5=ED=86=B5]=20:=20[=EC=84=A0?= =?UTF-8?q?=ED=83=9D=EB=A9=B4=20=EC=B5=9C=EC=83=81=EC=9C=84=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : canvas 객체 선택시 선택된 객체 최상위 레이어으로 이동 --- src/hooks/useCanvasEvent.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js index 4204dc71..4a601ed8 100644 --- a/src/hooks/useCanvasEvent.js +++ b/src/hooks/useCanvasEvent.js @@ -206,6 +206,7 @@ export function useCanvasEvent() { selected.forEach((obj) => { if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { obj.set({ stroke: 'red' }) + obj.bringToFront() } }) canvas.renderAll() @@ -243,6 +244,7 @@ export function useCanvasEvent() { selected.forEach((obj) => { if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { obj.set({ stroke: 'red' }) + obj.bringToFront() } }) } From 47245e438c5200849078d9dc7a80c7d92700f372 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 8 May 2025 09:48:31 +0900 Subject: [PATCH 184/196] =?UTF-8?q?[1014]=20:=20[819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 불필요 소스 삭제 --- src/locales/ja.json | 1 - src/locales/ko.json | 1 - 2 files changed, 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index d378ff36..796eea85 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1078,6 +1078,5 @@ "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時\rの最大段数", "modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)", "modal.module.basic.setting.module.placement.mix.asg.yn": "混合", - "modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)", "modal.module.basic.setting.module.placement.over.max.row": "{0} 最大段数超過しました。最大段数表を参考にしてください。" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 9bc55162..c67e3823 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1079,6 +1079,5 @@ "modal.module.basic.setting.module.placement.max.rows.multiple": "2종 혼합 최대단수", "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": "레이아웃 배치", "modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요." } From 704fe887f1b9e9a2f04510456e5d443c5d283284 Mon Sep 17 00:00:00 2001 From: ysCha Date: Thu, 8 May 2025 10:09:45 +0900 Subject: [PATCH 185/196] =?UTF-8?q?939=20-=20=EB=B0=B0=EC=B9=98=EB=A9=B4?= =?UTF-8?q?=20=EA=B7=B8=EB=A6=AC=EA=B8=B0=EC=97=90=20=ED=9D=A1=EC=B0=A9?= =?UTF-8?q?=EC=A0=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/usePlacementShapeDrawing.js | 80 ++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/src/hooks/surface/usePlacementShapeDrawing.js b/src/hooks/surface/usePlacementShapeDrawing.js index db0859cf..d53faa39 100644 --- a/src/hooks/surface/usePlacementShapeDrawing.js +++ b/src/hooks/surface/usePlacementShapeDrawing.js @@ -14,7 +14,7 @@ import { useMouse } from '@/hooks/useMouse' import { useLine } from '@/hooks/useLine' import { useTempGrid } from '@/hooks/useTempGrid' import { useEffect, useRef } from 'react' -import { distanceBetweenPoints } from '@/util/canvas-util' +import { calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util' import { fabric } from 'fabric' import { calculateAngle } from '@/util/qpolygon-utils' import { @@ -37,12 +37,13 @@ import { useSurfaceShapeBatch } from './useSurfaceShapeBatch' import { roofDisplaySelector } from '@/store/settingAtom' import { useRoofFn } from '@/hooks/common/useRoofFn' import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' +import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint' // 배치면 그리기 export function usePlacementShapeDrawing(id) { const canvas = useRecoilValue(canvasState) const roofDisplay = useRecoilValue(roofDisplaySelector) - const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } = + const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseLine } = useEvent() // const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } = // useContext(EventContext) @@ -118,6 +119,7 @@ export function usePlacementShapeDrawing(id) { }, [type]) const clear = () => { + addCanvasMouseEventListener('mouse:move', mouseMove) setLength1(0) setLength2(0) @@ -173,6 +175,80 @@ export function usePlacementShapeDrawing(id) { } } +/* +mouseMove + */ + const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + const roofAdsorptionPoints = useRef([]) + const intersectionPoints = useRef([]) + const { getAdsorptionPoints } = useAdsorptionPoint() + + const mouseMove = (e) => { + removeMouseLine(); + const pointer = canvas.getPointer(e.e) + const roofsPoints = roofs.map((roof) => roof.points).flat() + roofAdsorptionPoints.current = [...roofsPoints] + + const auxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isFixed) + const otherAdsorptionPoints = [] + + auxiliaryLines.forEach((line1) => { + auxiliaryLines.forEach((line2) => { + if (line1 === line2) { + return + } + + const intersectionPoint = calculateIntersection(line1, line2) + if (!intersectionPoint || intersectionPoints.current.some((point) => point.x === intersectionPoint.x && point.y === intersectionPoint.y)) { + return + } + otherAdsorptionPoints.push(intersectionPoint) + }) + }) + + let innerLinePoints = [] + canvas + .getObjects() + .filter((obj) => obj.innerLines) + .forEach((polygon) => { + polygon.innerLines.forEach((line) => { + innerLinePoints.push({ x: line.x1, y: line.y1 }) + innerLinePoints.push({ x: line.x2, y: line.y2 }) + }) + }) + + const adsorptionPoints = [ + ...getAdsorptionPoints(), + ...roofAdsorptionPoints.current, + ...otherAdsorptionPoints, + ...intersectionPoints.current, + ...innerLinePoints, + ] + + let arrivalPoint = { x: pointer.x, y: pointer.y } + let adsorptionPoint = findClosestPoint(pointer, adsorptionPoints) + + if (adsorptionPoint && distanceBetweenPoints(pointer, adsorptionPoint) <= adsorptionRange) { + arrivalPoint = { ...adsorptionPoint } + } + const horizontalLine = new fabric.Line([-1 * canvas.width, arrivalPoint.y, 2 * canvas.width, arrivalPoint.y], { + stroke: 'red', + strokeWidth: 1, + selectable: false, + name: 'mouseLine', + }) + + const verticalLine = new fabric.Line([arrivalPoint.x, -1 * canvas.height, arrivalPoint.x, 2 * canvas.height], { + stroke: 'red', + strokeWidth: 1, + selectable: false, + name: 'mouseLine', + }) + canvas?.add(horizontalLine, verticalLine) + canvas?.renderAll() + + } + useEffect(() => { canvas ?.getObjects() From c0c3295b04385f14433f02d58295c19f481ce490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 8 May 2025 13:21:54 +0900 Subject: [PATCH 186/196] =?UTF-8?q?[1027]=20:=20[=E3=80=90HANASYS=20DESIGN?= =?UTF-8?q?=E3=80=91=E6=A8=AA=E8=91=BA=E3=81=AB=E4=BD=BF=E7=94=A8=E3=81=99?= =?UTF-8?q?=E3=82=8B=E9=87=91=E5=85=B7=E3=81=AE=E9=9B=A2=E9=9A=94=E3=81=AB?= =?UTF-8?q?=E3=81=A4=E3=81=84=E3=81=A6]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : length 변경시 하위 필드 초기화 --- .../floor-plan/modal/basic/step/Trestle.jsx | 21 +++++++++++++++---- src/hooks/module/useModuleTrestle.js | 17 ++++++++++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index b184670e..6a1ef3e2 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -124,7 +124,6 @@ const Trestle = forwardRef((props, ref) => { useEffect(() => { if (constructionList.length > 0) { - console.log(constructionList) setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.construction?.constTp) ?? null) } else { setSelectedConstruction(null) @@ -144,6 +143,19 @@ const Trestle = forwardRef((props, ref) => { return 'no-click' } + const onChangeLength = (e) => { + setLengthBase(e) + dispatch({ + type: 'SET_LENGTH', + roof: { + length: e, + moduleTpCd: selectedModules.itemTp ?? '', + roofMatlCd: selectedRoof?.roofMatlCd ?? '', + raftBaseCd: selectedRaftBase?.clCode, + }, + }) + } + const onChangeRaftBase = (e) => { setSelectedRaftBase(e) dispatch({ @@ -225,7 +237,8 @@ const Trestle = forwardRef((props, ref) => { snowGdPossYn: constructionList[index].snowGdPossYn, cvrYn: constructionList[index].cvrYn, mixMatlNo: selectedModules.mixMatlNo, - workingWidth: selectedRoof?.length?.toString() ?? '', + // workingWidth: selectedRoof?.length?.toString() ?? '', + workingWidth: lengthBase, }, }) @@ -242,7 +255,7 @@ const Trestle = forwardRef((props, ref) => { return { ...selectedRoof, hajebichi, - lenBase: lengthBase, + length: lengthBase, eavesMargin, ridgeMargin, kerabaMargin, @@ -518,7 +531,7 @@ const Trestle = forwardRef((props, ref) => { type="text" className="input-origin block" value={lengthBase} - onChange={(e) => setLengthBase(e.target.value)} + onChange={(e) => onChangeLength(e.target.value)} disabled={selectedRoof.lenAuth === 'R'} />
diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 361ad541..e89d6089 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -10,6 +10,7 @@ const RAFT_BASE_CODE = '203800' const trestleReducer = (state, action) => { switch (action.type) { + case 'SET_LENGTH': case 'SET_RAFT_BASE': case 'SET_TRESTLE_MAKER': case 'SET_CONST_MTHD': @@ -96,11 +97,15 @@ export function useModuleTrestle(props) { useEffect(() => { if (trestleState) { handleSetTrestleList() + if (!trestleState?.trestleMkrCd) { setConstMthdList([]) setRoofBaseList([]) setConstructionList([]) setTrestleDetail(null) + setEavesMargin(0) + setRidgeMargin(0) + setKerabaMargin(0) return } @@ -109,6 +114,9 @@ export function useModuleTrestle(props) { setRoofBaseList([]) setConstructionList([]) setTrestleDetail(null) + setEavesMargin(0) + setRidgeMargin(0) + setKerabaMargin(0) return } @@ -116,12 +124,18 @@ export function useModuleTrestle(props) { if (!trestleState?.roofBaseCd) { setConstructionList([]) setTrestleDetail(null) + setEavesMargin(0) + setRidgeMargin(0) + setKerabaMargin(0) return } handleSetConstructionList() if (!trestleState?.constTp) { setTrestleDetail(null) + setEavesMargin(0) + setRidgeMargin(0) + setKerabaMargin(0) return } @@ -224,7 +238,8 @@ export function useModuleTrestle(props) { constTp: trestleState.constTp ?? '', mixMatlNo: trestleState.mixMatlNo ?? '', roofPitch: trestleState.roofPitch ?? '', - workingWidth: trestleState.workingWidth ?? '', + // workingWidth: trestleState.length ?? '', + workingWidth: lengthBase ?? '', }, ]) .then((res) => { From b2065e76998bde391b30566490b348d7aaccab49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 8 May 2025 14:48:05 +0900 Subject: [PATCH 187/196] =?UTF-8?q?[1030]=20:=20[=E3=80=90HANASYS=20DESIGN?= =?UTF-8?q?=E3=80=91=E6=96=87=E5=AD=97=E4=BF=AE=E6=AD=A3]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 다국어 수정 --- src/locales/ja.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 5aa10f4b..cea000ad 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -3,7 +3,7 @@ "welcome": "ようこそ。 {0}さん", "header.menus.home": "ホーム", "header.menus.management": "見積書管理画面", - "header.menus.management.newStuff": "新規見積登録", + "header.menus.management.newStuff": "新規物件登録", "header.menus.management.detail": "物件詳細", "header.menus.management.stuffList": "物件検索", "header.menus.community": "コミュニティ", @@ -186,7 +186,7 @@ "modal.circuit.trestle.setting.circuit.allocation.passivity.all.power.conditional.validation.error02": "シリーズを選択してください。", "modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.num.fix": "番号確定", "modal.circuit.trestle.setting.step.up.allocation": "昇圧設定", - "modal.circuit.trestle.setting.step.up.allocation.serial.amount": "シリアル枚数", + "modal.circuit.trestle.setting.step.up.allocation.serial.amount": "直列枚数", "modal.circuit.trestle.setting.step.up.allocation.total.amount": "総回路数", "modal.circuit.trestle.setting.step.up.allocation.connected": "接続する", "modal.circuit.trestle.setting.step.up.allocation.circuit.amount": "昇圧回路数", From e961648d853bbbcc9e1e4b98626f9059524cb4bc Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 8 May 2025 16:55:39 +0900 Subject: [PATCH 188/196] =?UTF-8?q?[1014]=20:=20[819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 멀티모듈일때 북면 모듈 포함일 경우 북면이 아닌 면에 설치되는 오류 수정 --- src/hooks/module/useModuleBasicSetting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 4471bc74..2880d29a 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1951,7 +1951,7 @@ export function useModuleBasicSetting(tabNum) { } } - if (northModule.length > 0) { + if (northModule.length > 0 && moduleSetupSurface.isNorth) { const isMultipleModules = northModule.length > 1 //모듈이 여러개면 const maxRow = isMultipleModules ? trestleDetailData.moduleMaxRows From 694923696013a462e0a65dfab99f03cc36491a34 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 8 May 2025 18:02:41 +0900 Subject: [PATCH 189/196] =?UTF-8?q?[1014]=20:=20[819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 북면설치 모듈일 경우, 북면과, 북면이 아닐때 분기 처리 --- src/hooks/module/useModuleBasicSetting.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 2880d29a..1d9c7d66 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1902,7 +1902,7 @@ export function useModuleBasicSetting(tabNum) { return false } } else { - //북면 모듈만 선택했을때 + //북면 모듈이 1개만있을때 if (checkedModule.length === 1) { const maxRow = trestleDetailData.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 @@ -1951,7 +1951,8 @@ export function useModuleBasicSetting(tabNum) { } } - if (northModule.length > 0 && moduleSetupSurface.isNorth) { + //북면 모듈이 있고 북면에 있을때 + if (northModule.length > 0 && (moduleSetupSurface.isNorth || !moduleSetupSurface.isNorth)) { const isMultipleModules = northModule.length > 1 //모듈이 여러개면 const maxRow = isMultipleModules ? trestleDetailData.moduleMaxRows From b8dad6211697ceea8522f805c55c5ee8f89df825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 9 May 2025 14:19:05 +0900 Subject: [PATCH 190/196] =?UTF-8?q?[929]=20:=20[=E7=BF=BB=E8=A8=B3?= =?UTF-8?q?=E5=A4=89=E6=9B=B4]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 다국어 수정 및 validation 로직 추가 --- .../floor-plan/modal/basic/step/Trestle.jsx | 10 +++++++-- src/locales/ja.json | 21 ++++++++++--------- src/locales/ko.json | 1 + 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index 6a1ef3e2..e1cca8db 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -125,6 +125,12 @@ const Trestle = forwardRef((props, ref) => { useEffect(() => { if (constructionList.length > 0) { setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.construction?.constTp) ?? null) + if (constructionList.filter((construction) => construction.constPossYn === 'Y').length === 0) { + Swal.fire({ + title: getMessage('modal.module.basic.settting.module.error4', [selectedRoof?.nameJp]), // 시공법법을 선택해주세요. + icon: 'warning', + }) + } } else { setSelectedConstruction(null) } @@ -342,7 +348,7 @@ const Trestle = forwardRef((props, ref) => { } if (!roof.trestle?.roofBaseCd) { Swal.fire({ - title: getMessage('modal.module.basic.settting.module.error3', [roof.nameJp]), // 지붕밑바탕탕을 선택해주세요. + title: getMessage('modal.module.basic.settting.module.error3', [roof.nameJp]), // 지붕밑바탕을 선택해주세요. icon: 'warning', }) result = false @@ -350,7 +356,7 @@ const Trestle = forwardRef((props, ref) => { } if (!roof.construction?.constTp) { Swal.fire({ - title: getMessage('modal.module.basic.settting.module.error4', [roof.nameJp]), // 시공법법을 선택해주세요. + title: getMessage('modal.module.basic.settting.module.error12', [roof.nameJp]), // 시공법법을 선택해주세요. icon: 'warning', }) result = false diff --git a/src/locales/ja.json b/src/locales/ja.json index cea000ad..e866e95e 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -117,17 +117,18 @@ "modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置", "modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置", "modal.module.basic.setting.module.select": "モジュール/架台選択", - "modal.module.basic.settting.module.error1": "架台メーカーを選択してください。\n(屋根材: {0})(JA)", - "modal.module.basic.settting.module.error2": "工法を選択してください。\n(屋根材: {0})(JA)", - "modal.module.basic.settting.module.error3": "屋根の下を選択してください。\n(屋根材: {0})(JA)", + "modal.module.basic.settting.module.error1": "架台メーカーを選択してください。\n(屋根材: {0})", + "modal.module.basic.settting.module.error2": "工法を選択してください。\n(屋根材: {0})", + "modal.module.basic.settting.module.error3": "屋根の下を選択してください。\n(屋根材: {0})", "modal.module.basic.settting.module.error4": "設置可能な施工条件がないので設置条件を変更してください。\n(屋根材: {0})", - "modal.module.basic.settting.module.error5": "L を選択してください。\n(屋根材: {0})(JA)", - "modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。\n(屋根材: {0})(JA)", - "modal.module.basic.settting.module.error7": "下在ビーチを入力してください。\n(屋根材: {0})(JA)", - "modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。\n(屋根材: {0})(JA)", - "modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)", - "modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)", - "modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。\n(屋根材: {1})(JA)", + "modal.module.basic.settting.module.error5": "L を選択してください。\n(屋根材: {0})", + "modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。\n(屋根材: {0})", + "modal.module.basic.settting.module.error7": "下在ビーチを入力してください。\n(屋根材: {0})", + "modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。\n(屋根材: {0})", + "modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。\n(屋根材: {1})", + "modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。\n(屋根材: {1})", + "modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。\n(屋根材: {1})", + "modal.module.basic.settting.module.error12": "施工方法を選択してください。\n(屋根材: {0})", "modal.module.basic.setting.module.placement": "モジュールの配置", "modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置", diff --git a/src/locales/ko.json b/src/locales/ko.json index 675dc84f..43b45c52 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -128,6 +128,7 @@ "modal.module.basic.settting.module.error9": "처마쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})", "modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})", "modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})", + "modal.module.basic.settting.module.error12": "시공법을 선택해주세요.\n(지붕재: {0})", "modal.module.basic.setting.module.placement": "모듈 배치", "modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.", "modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치", From 391fe39a2d48ab39c659b19b7e0891b764bd4bfa Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 9 May 2025 15:04:21 +0900 Subject: [PATCH 191/196] =?UTF-8?q?[1014]=20:=20[819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 하단방향 오류 수정 --- src/hooks/module/useModuleBasicSetting.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 1d9c7d66..57218019 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1996,6 +1996,7 @@ export function useModuleBasicSetting(tabNum) { let flowLines let installedModuleMixYn const isNorthSurface = moduleSetupSurface.isNorth + const isIncludeNorthModule = checkedModule.some((module) => module.northModuleYn === 'Y') //체크된 모듈 중에 북면 모듈이 있는지 확인하는 로직 let layoutRow = 0 let layoutCol = 0 @@ -2342,15 +2343,7 @@ export function useModuleBasicSetting(tabNum) { //남, 북과 같은 로직으로 적용하려면 좌우는 열 -> 행 으로 그려야함 //변수명은 bottom 기준으로 작성하여 동일한 방향으로 진행한다 - const leftFlowSetupModule = ( - maxLengthLine, - moduleSetupArray, - moduleSetupSurface, - containsBatchObjects, - - intvHor, - intvVer, - ) => { + const leftFlowSetupModule = (maxLengthLine, moduleSetupArray, moduleSetupSurface, containsBatchObjects, intvHor, intvVer) => { let setupModule = [] const trestleDetailData = moduleSetupSurface.trestleDetail //가대 상세 데이터 From 35708f65e9f5186aa41af9281c87206497731cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 9 May 2025 15:36:28 +0900 Subject: [PATCH 192/196] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=EB=B3=84=20?= =?UTF-8?q?=EA=B0=80=EB=8C=80=EC=A0=95=EB=B3=B4=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/Trestle.jsx | 22 +++++++++---------- src/hooks/module/useModuleTrestle.js | 11 +++++----- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Trestle.jsx b/src/components/floor-plan/modal/basic/step/Trestle.jsx index e1cca8db..44a68236 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -92,7 +92,7 @@ const Trestle = forwardRef((props, ref) => { useEffect(() => { if (raftBaseList.length > 0) { - setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === trestleState?.raftBaseCd) ?? null) + setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === selectedRoof?.raft) ?? null) } else { setSelectedRaftBase(null) } @@ -157,7 +157,7 @@ const Trestle = forwardRef((props, ref) => { length: e, moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase?.clCode, + raft: selectedRaftBase?.clCode, }, }) } @@ -169,7 +169,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: e.clCode, + raft: e.clCode, }, }) } @@ -181,7 +181,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase?.clCode, + raft: selectedRaftBase?.clCode, trestleMkrCd: e.trestleMkrCd, }, }) @@ -194,7 +194,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase?.clCode, + raft: selectedRaftBase?.clCode, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: e.constMthdCd, }, @@ -208,7 +208,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase?.clCode, + raft: selectedRaftBase?.clCode, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: selectedConstMthd.constMthdCd, roofBaseCd: e.roofBaseCd, @@ -229,7 +229,7 @@ const Trestle = forwardRef((props, ref) => { roof: { moduleTpCd: selectedModules.itemTp ?? '', roofMatlCd: selectedRoof?.roofMatlCd ?? '', - raftBaseCd: selectedRaftBase?.clCode, + raft: selectedRaftBase?.clCode, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: selectedConstMthd.constMthdCd, roofBaseCd: selectedRoofBase.roofBaseCd, @@ -266,6 +266,7 @@ const Trestle = forwardRef((props, ref) => { ridgeMargin, kerabaMargin, roofIndex: selectedRoof.index, + raft: selectedRaftBase?.clCode, trestle: { hajebichi: hajebichi, length: lengthBase, @@ -302,6 +303,7 @@ const Trestle = forwardRef((props, ref) => { ridgeMargin, kerabaMargin, roofIndex: roof.index, + raft: selectedRaftBase?.clCode, trestle: { length: lengthBase, hajebichi: hajebichi, @@ -374,7 +376,7 @@ const Trestle = forwardRef((props, ref) => { } } if (['C', 'R'].includes(roof.raftAuth)) { - if (!roof?.raftBaseCd) { + if (!roof?.raft) { Swal.fire({ title: getMessage('modal.module.basic.settting.module.error6', [roof.nameJp]), // 서까래 간격을 입력해주세요. icon: 'warning', @@ -477,7 +479,7 @@ const Trestle = forwardRef((props, ref) => { addRoof: newRoofs[index], trestle: { ...roof.trestle, - raftBaseCd: roof.raftBaseCd, + raft: roof.raftBaseCd, }, construction: { // ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp), @@ -502,8 +504,6 @@ const Trestle = forwardRef((props, ref) => { return false } - const onMarginCheck = (target, data) => {} - useImperativeHandle(ref, () => ({ isComplete, })) diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index e89d6089..0143e92e 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -25,7 +25,7 @@ const trestleReducer = (state, action) => { moduleTpCd: action.roof.module?.itemTp ?? '', roofMatlCd: action.roof?.roofMatlCd ?? '', hajebichi: action.roof?.hajebichi ?? 0, - raftBaseCd: action.roof?.raft ?? null, + raft: action.roof?.raft ?? null, trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null, constMthdCd: action.roof.trestle?.constMthdCd ?? null, constTp: action.roof.construction?.constTp ?? null, @@ -72,7 +72,6 @@ export function useModuleTrestle(props) { useEffect(() => { const raftCodeList = findCommonCode(RAFT_BASE_CODE) - setRaftBaseList(raftCodeList) setTrestleList([]) setConstMthdList([]) @@ -150,7 +149,7 @@ export function useModuleTrestle(props) { getTrestleList({ moduleTpCd: trestleState?.moduleTpCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '', - raftBaseCd: trestleState?.raftBaseCd ?? '', + raftBaseCd: trestleState?.raft ?? '', }) .then((res) => { if (res?.data) setTrestleList(res.data) @@ -166,7 +165,7 @@ export function useModuleTrestle(props) { getTrestleList({ moduleTpCd: trestleState?.moduleTpCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '', - raftBaseCd: trestleState?.raftBaseCd ?? '', + raftBaseCd: trestleState?.raft ?? '', trestleMkrCd: trestleState?.trestleMkrCd ?? '', }) .then((res) => { @@ -183,7 +182,7 @@ export function useModuleTrestle(props) { getTrestleList({ moduleTpCd: trestleState?.moduleTpCd ?? '', roofMatlCd: trestleState?.roofMatlCd ?? '', - raftBaseCd: trestleState?.raftBaseCd ?? '', + raftBaseCd: trestleState?.raft ?? '', trestleMkrCd: trestleState?.trestleMkrCd ?? '', constMthdCd: trestleState?.constMthdCd ?? '', }) @@ -209,7 +208,7 @@ export function useModuleTrestle(props) { stdWindSpeed: trestleState.stdWindSpeed ?? '', stdSnowLd: trestleState.stdSnowLd ?? '', inclCd: trestleState.inclCd ?? '', - raftBaseCd: trestleState.raftBaseCd ?? '', + raftBaseCd: trestleState.raft ?? '', roofPitch: Math.round(trestleState.roofPitch) ?? '', }) .then((res) => { From 56b891734597a9e1409477f2a688007668780113 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 9 May 2025 15:48:08 +0900 Subject: [PATCH 193/196] =?UTF-8?q?[1014]=20:=20[819=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=80=80=E3=83=AC=E3=82=A4=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E9=85=8D=E7=BD=AE=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 멀티모듈일 경우에 북면 모듈이 같이 계산되는 로직 수정 --- src/hooks/module/useModuleBasicSetting.js | 80 +++++++++++------------ 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 57218019..a3f2eb0e 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1902,57 +1902,51 @@ export function useModuleBasicSetting(tabNum) { return false } } else { - //북면 모듈이 1개만있을때 - if (checkedModule.length === 1) { - const maxRow = trestleDetailData.module.find((item) => item.moduleTpCd === checkedModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 + const normalModule = checkedModule.filter((item) => item.northModuleYn === 'N') + const northModule = checkedModule.filter((item) => item.northModuleYn === 'Y') + const northModuleIds = northModule.map((item) => item.itemId) + let isPassedNormalModule = false - //단수 합단수 - const sumRowCount = layoutSetupRef.find((item) => item.moduleId === checkedModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 - const sumColCount = layoutSetupRef.filter((item) => item.col).some((item) => item.col > maxCol) + //만약 북면 모듈이 2개면 이 하위 로직 가져다가 쓰면됨 northModule === 만 바꾸면 될듯 + // northModule을 배열로 만들고 include로 해서 체크 해야됨 + if (normalModule.length > 0 && !moduleSetupSurface.isNorth) { + //C1C2 모듈일 경우ㅁㅁ + const isMultipleModules = normalModule.length > 1 //모듈이 여러개면 + const maxRow = isMultipleModules + ? trestleDetailData.moduleMaxRows + : trestleDetailData.module.find((item) => item.moduleTpCd === normalModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 - if (sumRowCount > maxRow || sumColCount) { + //북면 모듈 id를 제외한 모듈의 단 체크 + const sumRowCount = isMultipleModules + ? layoutSetupRef.filter((item) => item.checked && !northModuleIds.includes(item.moduleId)).reduce((acc, cur) => acc + cur.row, 0) + : layoutSetupRef.find((item) => item.moduleId === normalModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 + + //북면 모듈 id를 제외한 모듈의 열 체크 + const sumColCount = layoutSetupRef.filter((item) => item.col && !northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol) + + // 혼합일때 모듈 개별의 row를 체크함 + const isPassedObject = + isMultipleModules && + layoutSetupRef.find( + (item, index) => item.checked && !item.moduleId.includes(northModuleIds) && item.row > trestleDetailData.module[index].mixModuleMaxRows, + ) + + // 합산 단수가 맥스단수보다 크거나 열이 맥스열수보다 크거나 혼합일때 모듈 개별의 row가 맥스단수보다 크면 실패 + if (sumRowCount > maxRow || sumColCount || isPassedObject) { failAutoSetupRoof.push(moduleSetupSurface) return false + } else { + isPassedNormalModule = true } - } else { - const normalModule = checkedModule.filter((item) => item.northModuleYn === 'N') - const northModule = checkedModule.filter((item) => item.northModuleYn === 'Y') - const northModuleIds = northModule.map((item) => item.itemId) - - //만약 북면 모듈이 2개면 이 하위 로직 가져다가 쓰면됨 northModule === 만 바꾸면 될듯 - // northModule을 배열로 만들고 include로 해서 체크 해야됨 - if (normalModule.length > 0 && !moduleSetupSurface.isNorth) { - //C1C2 모듈일 경우ㅁㅁ - const isMultipleModules = normalModule.length > 1 //모듈이 여러개면 - const maxRow = isMultipleModules - ? trestleDetailData.moduleMaxRows - : trestleDetailData.module.find((item) => item.moduleTpCd === normalModule[0].moduleTpCd).moduleMaxRows //멀티모듈이면 밖에 maxRows로 판단 아니면 module->itemmList를 가지고 판단 - - //북면 모듈 id를 제외한 모듈의 단 체크 - const sumRowCount = isMultipleModules - ? layoutSetupRef.filter((item) => item.checked && !northModuleIds.includes(item.moduleId)).reduce((acc, cur) => acc + cur.row, 0) - : layoutSetupRef.find((item) => item.moduleId === normalModule[0].itemId).row //멀티모듈이면 전체 합, 체크된 한개의 열 - - //북면 모듈 id를 제외한 모듈의 열 체크 - const sumColCount = layoutSetupRef.filter((item) => item.col && !northModuleIds.includes(item.moduleId)).some((item) => item.col > maxCol) - - // 혼합일때 모듈 개별의 row를 체크함 - const isPassedObject = - isMultipleModules && - layoutSetupRef.find( - (item, index) => - item.checked && !item.moduleId.includes(northModuleIds) && item.row > trestleDetailData.module[index].mixModuleMaxRows, - ) - - // 합산 단수가 맥스단수보다 크거나 열이 맥스열수보다 크거나 혼합일때 모듈 개별의 row가 맥스단수보다 크면 실패 - if (sumRowCount > maxRow || sumColCount || isPassedObject) { - failAutoSetupRoof.push(moduleSetupSurface) - return false - } - } + } + //위에서 일반 모듈이 설치가 완료면 그냥 넘어간다 + //일반 모듈이 pass라면 일반 모듈이 설치됨 + //만약 일반모듈이 체크가 안되어 있으면 밑에 로직을 탐 + if (!isPassedNormalModule) { //북면 모듈이 있고 북면에 있을때 if (northModule.length > 0 && (moduleSetupSurface.isNorth || !moduleSetupSurface.isNorth)) { + //북면 모듈이 있는데 일반 모듈이 있을때 북면이 아니면 그냥 북면은 그냥 pass const isMultipleModules = northModule.length > 1 //모듈이 여러개면 const maxRow = isMultipleModules ? trestleDetailData.moduleMaxRows From f03d35ec8db9bbcef240561fe5430139f177faf4 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 12 May 2025 11:11:09 +0900 Subject: [PATCH 194/196] =?UTF-8?q?[1037]=20:=20[=E3=83=A2=E3=82=B8?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=83=AB1=E6=9E=9A=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4=E3=81=99=E3=82=8B=E6=99=82=E3=81=AE=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 모듈 선택시 아웃라인 두께 조정 --- src/hooks/useCanvasEvent.js | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js index 4a601ed8..22aad7cf 100644 --- a/src/hooks/useCanvasEvent.js +++ b/src/hooks/useCanvasEvent.js @@ -4,7 +4,7 @@ import { v4 as uuidv4 } from 'uuid' import { canvasSizeState, canvasState, canvasZoomState, currentMenuState, currentObjectState } from '@/store/canvasAtom' import { QPolygon } from '@/components/fabric/QPolygon' import { fontSelector } from '@/store/fontAtom' -import { MENU } from '@/common/common' +import { MENU, POLYGON_TYPE } from '@/common/common' // 캔버스에 필요한 이벤트 export function useCanvasEvent() { @@ -204,9 +204,12 @@ export function useCanvasEvent() { if (selected?.length > 0) { selected.forEach((obj) => { - if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + // if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + if (obj.type === 'QPolygon') { obj.set({ stroke: 'red' }) - obj.bringToFront() + if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + obj.set({ strokeWidth: 3 }) + } } }) canvas.renderAll() @@ -218,10 +221,13 @@ export function useCanvasEvent() { if (deselected?.length > 0) { deselected.forEach((obj) => { - if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + if (obj.type === 'QPolygon') { if (obj.name !== 'moduleSetupSurface') { obj.set({ stroke: 'black' }) } + if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + obj.set({ strokeWidth: 0.3 }) + } } }) } @@ -234,17 +240,24 @@ export function useCanvasEvent() { if (deselected?.length > 0) { deselected.forEach((obj) => { - if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + if (obj.type === 'QPolygon') { obj.set({ stroke: 'black' }) + if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + //모듈 미선택시 라인 두께 변경 + obj.set({ strokeWidth: 0.3 }) + } } }) } if (selected?.length > 0) { selected.forEach((obj) => { - if (obj.type === 'QPolygon' && currentMenu !== MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + if (obj.type === 'QPolygon') { obj.set({ stroke: 'red' }) - obj.bringToFront() + if (obj.name === POLYGON_TYPE.MODULE && currentMenu === MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING) { + //모듈 선택시 라인 두께 변경 + obj.set({ strokeWidth: 3 }) + } } }) } From a652d09b8d7eb99f879f05d7a180d114e67bc91e Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 13 May 2025 10:46:26 +0900 Subject: [PATCH 195/196] =?UTF-8?q?[1036]=20:=20[=E3=83=97=E3=83=A9?= =?UTF-8?q?=E3=83=B3=E3=82=92=E3=82=B3=E3=83=94=E3=83=BC/=E7=A7=BB?= =?UTF-8?q?=E5=8B=95=E3=81=99=E3=82=8B=E6=99=82=E3=81=AE=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 탭간 이동, 복사시 저장 여부 확인 로직 추가 --- src/components/floor-plan/CanvasLayout.jsx | 2 +- .../floor-plan/modal/basic/step/Placement.jsx | 19 ++++----- src/hooks/useCanvasEvent.js | 12 +++++- src/hooks/usePlan.js | 40 +++++++++++++++---- 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 059e96aa..cce79df2 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -37,7 +37,7 @@ export default function CanvasLayout({ children }) {