diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 9441dc7c..20d6a348 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -33,6 +33,7 @@ import { compasDegAtom } from '@/store/orientationAtom' import { hotkeyStore } from '@/store/hotkeyAtom' import { usePopup } from '@/hooks/usePopup' import { outerLinePointsState } from '@/store/outerLineAtom' +import { canvasSettingState } from '@/store/canvasAtom' export default function CanvasFrame() { const canvasRef = useRef(null) @@ -59,6 +60,7 @@ export default function CanvasFrame() { const { basicSetting, fetchBasicSettings } = useCanvasSetting() const { selectedMenu, setSelectedMenu } = useCanvasMenu() const { initEvent } = useEvent() + const canvasSetting = useRecoilValue(canvasSettingState) const loadCanvas = () => { if (!canvas) return @@ -82,7 +84,12 @@ export default function CanvasFrame() { setSelectedMenu('module') }, 500) } else if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL).length > 0) { - setSelectedMenu('outline') + // canvasSetting.roofSizeSet에 따라 메뉴 결정 + if (canvasSetting?.roofSizeSet === '2') { + setSelectedMenu('surface') // 실측값입력 → surface + } else { + setSelectedMenu('outline') // 복시도입력 → outline + } } else { setTimeout(() => { setSelectedMenu('surface') @@ -121,7 +128,11 @@ export default function CanvasFrame() { if (currentCanvasPlan.planNo) { /* 약간의 지연을 줘서 roofMaterials가 로드될 시간을 확보 */ setTimeout(() => { - fetchBasicSettings(Number(currentCanvasPlan.planNo), null) + // 메뉴 이동 시 canvasSetting이 덮어쓰이는 것을 방지 + // 이미 canvasSetting에 roofSizeSet이 있으면 API 호출 건너뛰기 + if (!canvasSetting?.roofSizeSet) { + fetchBasicSettings(Number(currentCanvasPlan.planNo), null) + } }, 100) } }, [currentCanvasPlan, canvas]) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 97d878a0..be42c977 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -426,7 +426,7 @@ export default function CanvasMenu(props) { return ( (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.type === 'outline') || (selectedMenu === 'module' && ['placement', 'outline'].includes(menu.type)) || - (isExistModule() && ['placement', 'outline'].some((num) => num === menu.type)) || + (isExistModule() && canvasSetting?.roofSizeSet !== '1' && ['placement', 'outline'].some((num) => num === menu.type)) || (['estimate', 'simulation'].includes(selectedMenu) && ['placement', 'outline', 'surface'].includes(menu.type)) ) } diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 417cc559..6098aec3 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -41,7 +41,7 @@ export default function FloorPlan({ children }) { promiseGet({ url: `/api/object/${objectNo}/detail` }).then((res) => { if (res.status === 200) { const { data } = res - console.log(data) + //console.log(data) let surfaceTypeValue if (res.data.surfaceType === 'Ⅲ・Ⅳ') { diff --git a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx index cda87230..9fd7da9a 100644 --- a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx +++ b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx @@ -211,8 +211,8 @@ export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, ro diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 091129a8..2dced068 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -194,7 +194,7 @@ const Placement = forwardRef((props, refs) => { type="checkbox" id={item.itemId} name={item.itemId} - checked={selectedItems[item.itemId]} + checked={selectedItems[item.itemId] || false} onChange={(e) => handleSelectedItem(e, item.itemId)} /> @@ -217,8 +217,7 @@ const Placement = forwardRef((props, refs) => { type="text" className="input-origin block" name="row" - value={props.layoutSetup[index]?.row ?? 1} - //defaultValue={0} + value={props.layoutSetup[index]?.row || 1} onChange={(e) => handleLayoutSetup(e, item.itemId, index)} /> @@ -229,8 +228,7 @@ const Placement = forwardRef((props, refs) => { type="text" className="input-origin block" name="col" - value={props.layoutSetup[index]?.col ?? 1} - //defaultValue={0} + value={props.layoutSetup[index]?.col || 1} onChange={(e) => handleLayoutSetup(e, item.itemId, index)} /> @@ -268,7 +266,7 @@ const Placement = forwardRef((props, refs) => { type="radio" name="radio02" id="ra03" - checked={moduleSetupOption.isChidori} + checked={moduleSetupOption.isChidori === true} disabled={isChidoriNotAble} value={'true'} onChange={(e) => handleChangeChidori(e)} @@ -280,7 +278,7 @@ const Placement = forwardRef((props, refs) => { type="radio" name="radio02" id="ra04" - checked={!moduleSetupOption.isChidori} + checked={moduleSetupOption.isChidori === false} value={'false'} onChange={(e) => handleChangeChidori(e)} /> diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 02e9d171..c98b75f0 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -63,6 +63,7 @@ export default function CircuitTrestleSetting({ id }) { const originCanvasViewPortTransform = useRef([]) const [isFold, setIsFold] = useState(false) + const [showHiddenBasicSetting, setShowHiddenBasicSetting] = useState(true) const { makers, @@ -108,6 +109,14 @@ export default function CircuitTrestleSetting({ id }) { } }, []) + // 모듈/가대설정 팝업을 순간적으로 열었다가 닫아 초기화 로직 실행 + useEffect(() => { + const timer = setTimeout(() => { + setShowHiddenBasicSetting(false) + }, 300) + return () => clearTimeout(timer) + }, []) + // 모듈이 설치된 경우 rack설치 여부에 따라 설치 된 모듈 아래에 작은 모듈이 설치되어 있을 경우는 모듈 설치 메뉴 reopen useEffect(() => { const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -998,63 +1007,70 @@ export default function CircuitTrestleSetting({ id }) { } return ( - - handleClose()} - isFold={isFold} - onFold={() => setIsFold(!isFold)} - /> - -
-
-
-
{getMessage('modal.circuit.trestle.setting.power.conditional.select')}
- -
- {getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')}) + <> + {showHiddenBasicSetting && ( +
+ +
+ )} + + handleClose()} + isFold={isFold} + onFold={() => setIsFold(!isFold)} + /> + +
+
+
+
{getMessage('modal.circuit.trestle.setting.power.conditional.select')}
+ +
+ {getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')}) +
+ {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && } + {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( + + )} + {tabNum === 2 && }
- {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && } - {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( - - )} - {tabNum === 2 && } -
- {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && ( -
- - -
- )} - {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( -
- - -
- )} - {tabNum === 2 && ( -
- - {/* -
- )} - - + {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && ( +
+ + +
+ )} + {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( +
+ + +
+ )} + {tabNum === 2 && ( +
+ + {/* +
+ )} + + + ) } diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 95442b8a..87ad753c 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -8,7 +8,7 @@ import MaterialGuide from '@/components/floor-plan/modal/placementShape/Material import WithDraggable from '@/components/common/draggable/WithDraggable' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { addedRoofsState, roofDisplaySelector, roofMaterialsAtom } from '@/store/settingAtom' import { useCommonCode } from '@/hooks/common/useCommonCode' import QSelectBox from '@/components/common/select/QSelectBox' @@ -16,11 +16,12 @@ import { globalLocaleStore } from '@/store/localeAtom' import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import { usePolygon } from '@/hooks/usePolygon' -import { canvasState } from '@/store/canvasAtom' +import { canvasState, canvasSettingState, currentCanvasPlanState, currentMenuState } from '@/store/canvasAtom' +import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' +import { MENU, POLYGON_TYPE } from '@/common/common' import { useRoofFn } from '@/hooks/common/useRoofFn' import { usePlan } from '@/hooks/usePlan' -import { normalizeDecimal, normalizeDigits } from '@/util/input-utils' -import { logger } from '@/util/logger' +import { normalizeDecimal } from '@/util/input-utils' import { CalculatorInput } from '@/components/common/input/CalcInput' /** @@ -41,14 +42,23 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting() const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const { findCommonCode } = useCommonCode() - const [raftCodes, setRaftCodes] = useState([]) /** 서까래 정보 */ - const [currentRoof, setCurrentRoof] = useState(null) /** 현재 선택된 지붕재 정보 */ - const { closePopup } = usePopup() /** usePopup에서 closePopup 함수 가져오기 */ + const [raftCodes, setRaftCodes] = useState([]) + /** 서까래 정보 */ + const [currentRoof, setCurrentRoof] = useState(null) + /** 현재 선택된 지붕재 정보 */ + const { closePopup } = usePopup() + /** usePopup에서 closePopup 함수 가져오기 */ const { drawDirectionArrow } = usePolygon() const { setSurfaceShapePattern } = useRoofFn() const canvas = useRecoilValue(canvasState) + const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) + const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) const roofDisplay = useRecoilValue(roofDisplaySelector) + const { setPolygonLinesActualSize } = usePolygon() + const { setSelectedMenu } = useCanvasMenu() + const setCurrentMenu = useSetRecoilState(currentMenuState) + const roofRef = { roofCd: useRef(null), width: useRef(null), @@ -114,6 +124,15 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla if (openPoint && openPoint === 'canvasMenus') fetchBasicSettings(planNo, openPoint) }, []) + /** + * 현재 활성 플랜이 변경될 때 currentRoof.planNo 업데이트 + */ + useEffect(() => { + if (currentCanvasPlan?.planNo && currentRoof) { + setCurrentRoof(prev => ({ ...prev, planNo: currentCanvasPlan.planNo })) + } + }, [currentCanvasPlan?.planNo]) + /** * 배치면초기설정 데이터 조회 후 화면 오픈 */ @@ -121,7 +140,12 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla if (addedRoofs.length > 0) { const raftCodeList = findCommonCode('203800') setRaftCodes(raftCodeList) - setCurrentRoof({ ...addedRoofs[0], planNo: planNo, roofSizeSet: String(basicSetting.roofSizeSet), roofAngleSet: basicSetting.roofAngleSet }) + setCurrentRoof({ + ...addedRoofs[0], + planNo: currentCanvasPlan?.planNo || planNo, + roofSizeSet: String(basicSetting.roofSizeSet), + roofAngleSet: basicSetting.roofAngleSet, + }) } else { /** 데이터 설정 확인 후 데이터가 없으면 기본 데이터 설정 */ setCurrentRoof({ ...DEFAULT_ROOF_SETTINGS }) @@ -154,10 +178,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla }) }, [currentRoof]) - const handleRoofSizeSetChange = (value) => { - setCurrentRoof({ ...currentRoof, roofSizeSet: value }) - } - const handleRoofAngleSetChange = (value) => { setCurrentRoof({ ...currentRoof, roofAngleSet: value }) } @@ -209,10 +229,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla * 배치면초기설정 저장 버튼 클릭 */ const handleSaveBtn = async () => { - const roofInfo = { ...currentRoof, - planNo: basicSetting.planNo, + planNo: currentCanvasPlan?.planNo || basicSetting.planNo, roofCd: roofRef.roofCd.current?.value, width: roofRef.width.current?.value, length: roofRef.length.current?.value, @@ -227,25 +246,22 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla newAddedRoofs[0] = { ...roofInfo } setAddedRoofs(newAddedRoofs) - logger.debug('save Info', { - ...basicSetting, - selectedRoofMaterial: { - ...newAddedRoofs[0], - }, - }) + // currentRoof의 roofSizeSet을 canvasSetting에 반영 + setCanvasSetting({ ...canvasSetting, roofSizeSet: currentRoof?.roofSizeSet }) /** - * 배치면초기설정 저장 + * 배치면초기설정 저장 (메뉴 변경/useEffect 트리거 없이) */ basicSettingSave({ ...basicSetting, + planNo: currentCanvasPlan?.planNo || basicSetting.planNo, /** * 선택된 지붕재 정보 */ selectedRoofMaterial: { ...newAddedRoofs[0], }, - }) + }, { skipSideEffects: true }) const roofs = canvas.getObjects().filter((obj) => obj.roofMaterial?.index === 0) @@ -254,7 +270,27 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla setSurfaceShapePattern(roof, roofDisplay.column, false, { ...roofInfo }) roof.roofMaterial = { ...roofInfo } drawDirectionArrow(roof) + setPolygonLinesActualSize(roof, true) }) + canvas.renderAll() + + /** 지붕면 존재 여부에 따라 메뉴 설정 */ + const hasRoofs = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.ROOF) + + // roofSizeSet에 따라 메뉴 설정 + if (currentRoof?.roofSizeSet === '2') { + setSelectedMenu('surface') + setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) + } else if (currentRoof?.roofSizeSet === '1') { + setSelectedMenu('outline') + setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) + } else if (hasRoofs) { + setSelectedMenu('surface') + setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) + } else { + setSelectedMenu('outline') + setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) + } /* 저장 후 화면 닫기 */ closePopup(id) @@ -353,26 +389,26 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla value={index === 0 ? (currentRoof?.pitch ?? basicSetting?.inclBase ?? '0') : (currentRoof?.angle ?? '0')} onChange={(value) => { if (index === 0) { - const pitch = value === '' ? '' : Number(value); - const angle = pitch === '' ? '' : getDegreeByChon(pitch); - setCurrentRoof(prev => ({ + const pitch = value === '' ? '' : Number(value) + const angle = pitch === '' ? '' : getDegreeByChon(pitch) + setCurrentRoof((prev) => ({ ...prev, pitch, - angle - })); + angle, + })) } else { - const angle = value === '' ? '' : Number(value); - const pitch = angle === '' ? '' : getChonByDegree(angle); - setCurrentRoof(prev => ({ + const angle = value === '' ? '' : Number(value) + const pitch = angle === '' ? '' : getChonByDegree(angle) + setCurrentRoof((prev) => ({ ...prev, pitch, - angle - })); + angle, + })) } }} options={{ allowNegative: false, - allowDecimal: true + allowDecimal: true, }} />
@@ -432,7 +468,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla label="" className="input-origin block" ref={roofRef.width} - value={currentRoof?.width||0} + value={currentRoof?.width || 0} onChange={(value) => { setCurrentRoof({ ...currentRoof, value }) }} @@ -440,7 +476,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla disabled={currentRoof?.roofSizeSet === '3'} options={{ allowNegative: false, - allowDecimal: false //(index !== 0), + allowDecimal: false, //(index !== 0), }} />
@@ -467,7 +503,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla label="" className="input-origin block" ref={roofRef.length} - value={currentRoof?.length||0} + value={currentRoof?.length || 0} onChange={(value) => { setCurrentRoof({ ...currentRoof, value }) }} @@ -475,7 +511,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla disabled={currentRoof?.roofSizeSet === '3'} options={{ allowNegative: false, - allowDecimal: false //(index !== 0), + allowDecimal: false, //(index !== 0), }} />
@@ -522,20 +558,19 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla ref={roofRef.hajebichi} value={currentRoof?.hajebichi ?? basicSetting?.roofPchBase ?? '0'} onChange={(value) => { - const hajebichi = value === '' ? '' : Number(value); - setCurrentRoof(prev => ({ + const hajebichi = value === '' ? '' : Number(value) + setCurrentRoof((prev) => ({ ...prev, - hajebichi - })); + hajebichi, + })) }} readOnly={currentRoof?.roofPchAuth === 'R'} disabled={currentRoof?.roofSizeSet === '3'} options={{ allowNegative: false, - allowDecimal: false //(index !== 0), + allowDecimal: false, //(index !== 0), }} /> - )} diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 75db2623..98eec095 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -357,7 +357,11 @@ export default function StuffDetail() { if (res?.data?.createSaleStoreId === 'T01') { if (session?.storeId !== 'T01') { - setShowButton('none') + //T01 계정이 작성한 안건 중 해당 판매점 ID가 열람 가능한 것에 한합니다. + if(session?.storeId !== managementState?.saleStoreId){ + return false + } + } } if (isObjectNotEmpty(res.data)) { @@ -1658,7 +1662,11 @@ export default function StuffDetail() { const getCellDoubleClicked = (params) => { if (managementState?.createSaleStoreId === 'T01') { if (session?.storeId !== 'T01') { - return false + //T01 계정이 작성한 안건 중 해당 판매점 ID가 열람 가능한 것에 한합니다. + if(session?.storeId !== managementState?.saleStoreId){ + return false + } + } } diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index 6cbfd862..b5df5411 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -39,7 +39,11 @@ export default function StuffSubHeader({ type }) { if (isObjectNotEmpty(managementState)) { if (managementState?.createSaleStoreId === 'T01') { if (session?.storeId !== 'T01') { - setButtonStyle('none') + //T01 계정이 작성한 안건 중 해당 판매점 ID가 열람 가능한 것에 한합니다. + if(session?.storeId !== managementState?.saleStoreId){ + setButtonStyle('none') + } + } } } diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index 0b028f32..fc4c907b 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -633,9 +633,7 @@ export function useCommonUtils() { // 원본 roof의 자식 오브젝트들 찾기 (개구, 그림자, 도머 등) const childObjectTypes = [BATCH_TYPE.OPENING, BATCH_TYPE.SHADOW, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER] - const childObjects = canvas.getObjects().filter( - (o) => o.parentId === obj.id && childObjectTypes.includes(o.name) - ) + const childObjects = canvas.getObjects().filter((o) => o.parentId === obj.id && childObjectTypes.includes(o.name)) // 원본 roof 중심점 계산 const originalPoints = obj.getCurrentPoints() @@ -669,24 +667,28 @@ export function useCommonUtils() { y: p.y + offsetY, })) - clonedObj = new QPolygon(newPoints, { - fill: obj.fill || 'transparent', - stroke: obj.stroke || 'black', - strokeWidth: obj.strokeWidth || 1, - fontSize: 0, // 이동 중에는 lengthText 생성하지 않음 (fontSize=0이면 addLengthText가 스킵됨) - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: 'clonedObj', - originX: 'center', - originY: 'center', - pitch: obj.pitch, - surfaceId: obj.surfaceId, - sort: false, - }, canvas) + clonedObj = new QPolygon( + newPoints, + { + fill: obj.fill || 'transparent', + stroke: obj.stroke || 'black', + strokeWidth: obj.strokeWidth || 1, + fontSize: 0, // 이동 중에는 lengthText 생성하지 않음 (fontSize=0이면 addLengthText가 스킵됨) + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: 'clonedObj', + originX: 'center', + originY: 'center', + pitch: obj.pitch, + surfaceId: obj.surfaceId, + // sort: false, + }, + canvas, + ) canvas.add(clonedObj) diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js index 1148eed3..7c32505e 100644 --- a/src/hooks/common/useRoofFn.js +++ b/src/hooks/common/useRoofFn.js @@ -179,7 +179,7 @@ export function useRoofFn() { polygon.set('fill', null) polygon.set('fill', pattern) polygon.roofMaterial = roofMaterial - setPolygonLinesActualSize(polygon) + setPolygonLinesActualSize(polygon, true) changeCorridorDimensionText() polygon.canvas?.renderAll() } catch (e) { diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 8e59a1e7..c81c54cb 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -1059,7 +1059,7 @@ export function useModule() { } const isOutsideSurface = (module, moduleSetupSurface) => { - return !checkModuleDisjointSurface(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)) + return !checkModuleDisjointSurface(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true), 0.5) } const getRowModules = (target) => { diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 88c32d5f..fc80fe70 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -440,15 +440,21 @@ export function useCanvasSetting(executeEffect = true) { }) setAddedRoofs(addRoofs) - setCanvasSetting({ - ...basicSetting, - roofMaterials: addRoofs[0], - planNo: roofsRow[0].planNo, - roofSizeSet: roofsRow[0].roofSizeSet, - roofAngleSet: roofsRow[0].roofAngleSet, - roofsData: roofsArray, - selectedRoofMaterial: addRoofs.find((roof) => roof.selected), - }) + if (openPoint !== 'basicSettingSave') { + // canvasSetting은 현재 값을 유지하고 basicSetting만 업데이트 + // 새로고침 시 canvasSetting이 바뀌는 문제 방지 + if (!canvasSetting?.roofSizeSet) { + setCanvasSetting({ + ...basicSetting, + roofMaterials: addRoofs[0], + planNo: roofsRow[0].planNo, + roofSizeSet: roofsRow[0].roofSizeSet, + roofAngleSet: roofsRow[0].roofAngleSet, + roofsData: roofsArray, + selectedRoofMaterial: addRoofs.find((roof) => roof.selected), + }) + } + } } }) } catch (error) { @@ -474,7 +480,8 @@ export function useCanvasSetting(executeEffect = true) { /** * 기본설정(PlacementShapeSetting) 저장 */ - const basicSettingSave = async (params) => { + const basicSettingSave = async (params, options = {}) => { + const { skipSideEffects = false } = options try { const patternData = { objectNo: correntObjectNo, @@ -527,13 +534,17 @@ export function useCanvasSetting(executeEffect = true) { setBasicSettings({ ...params }) }) - /** CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ - setCanvasSetting({ - ...basicSetting, - roofSizeSet: String(params.roofSizeSet), - }) + if (!skipSideEffects) { + /** CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ + setCanvasSetting({ + ...basicSetting, + roofSizeSet: String(params.roofSizeSet), + }) - /** 메뉴 설정 */ + /** 메뉴 설정 */ + //setMenuByRoofSize(params.roofSizeSet) + } + //메뉴를 찾아가지 못하는 오류 발생으로 변경 setMenuByRoofSize(params.roofSizeSet) /** 배치면초기설정 조회 */ @@ -559,12 +570,44 @@ export function useCanvasSetting(executeEffect = true) { */ const basicSettingCopySave = async (params) => { try { - const patternData = { - objectNo: correntObjectNo, - planNo: Number(params.planNo), - roofSizeSet: Number(params.roofSizeSet), - roofAngleSet: params.roofAngleSet, - roofMaterialsAddList: params.roofsData.map((item) => ({ + // roofsData가 단일 항목인 경우, 모든 추가된 지붕재(addedRoofs)를 사용하여 다중 항목으로 확장 + let roofMaterialsList = [] + + if (params.roofsData && params.roofsData.length === 1) { + // 단일 항목인 경우 addedRoofs의 모든 항목을 사용 + if (addedRoofs && addedRoofs.length > 0) { + roofMaterialsList = addedRoofs.map((roof, index) => ({ + planNo: Number(params.planNo), + roofApply: roof.selected || index === 0, // 첫 번째 또는 선택된 항목 + roofSeq: index, + roofMatlCd: roof.roofMatlCd, + roofWidth: roof.width || roof.roofWidth, + roofHeight: roof.length || roof.roofHeight, + roofHajebichi: roof.hajebichi || 0, + roofGap: roof.raft || roof.roofGap, + roofLayout: roof.layout || 'P', + roofPitch: roof.pitch || 0, + roofAngle: roof.angle || 0, + })) + } else { + // addedRoofs가 비어있을 경우 원래 단일 항목 사용 + roofMaterialsList = params.roofsData.map((item) => ({ + planNo: Number(item.planNo), + roofApply: item.roofApply, + roofSeq: item.roofSeq, + roofMatlCd: item.roofMatlCd, + roofWidth: item.roofWidth, + roofHeight: item.roofHeight, + roofHajebichi: item.roofHajebichi, + roofGap: item.roofGap, + roofLayout: item.roofLayout, + roofPitch: item.roofPitch, + roofAngle: item.roofAngle, + })) + } + } else { + // 다중 항목인 경우 기존 방식 사용 + roofMaterialsList = params.roofsData.map((item) => ({ planNo: Number(item.planNo), roofApply: item.roofApply, roofSeq: item.roofSeq, @@ -576,7 +619,15 @@ export function useCanvasSetting(executeEffect = true) { roofLayout: item.roofLayout, roofPitch: item.roofPitch, roofAngle: item.roofAngle, - })), + })) + } + + const patternData = { + objectNo: correntObjectNo, + planNo: Number(params.planNo), + roofSizeSet: Number(params.roofSizeSet), + roofAngleSet: params.roofAngleSet, + roofMaterialsAddList: roofMaterialsList, } await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index de5534a5..d7df9b6d 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -1573,13 +1573,13 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { currentObject.fire('modified') currentObject.fire('polygonMoved') // 화살표와 선 다시 그리기 + setPolygonLinesActualSize(currentObject, true) drawDirectionArrow(currentObject) setTimeout(() => { - setPolygonLinesActualSize(currentObject) changeSurfaceLineType(currentObject) currentObject.dirty = true currentObject.setCoords() - canvas.requestRenderAll() + canvas.renderAll() setCurrentObject(currentObject) }, 500) } diff --git a/src/locales/ja.json b/src/locales/ja.json index 2953688e..feb9945f 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -76,7 +76,7 @@ "common.setting.rollback": "前に戻る", "modal.cover.outline.remove": "外壁の取り外し", "modal.cover.outline.select.move": "外壁選択の移動", - "plan.menu.placement.surface": "実測値入力", + "plan.menu.placement.surface": "配置面", "plan.menu.placement.surface.slope.setting": "傾斜設定", "plan.menu.placement.surface.drawing": "配置面の描画", "modal.placement.surface.drawing.straight.line": "直線",