diff --git a/src/common/common.js b/src/common/common.js
index da50a5a8..cf6d37bf 100644
--- a/src/common/common.js
+++ b/src/common/common.js
@@ -182,6 +182,9 @@ export const SAVE_KEY = [
'pcses',
'roofMaterial',
'isComplete',
+ 'moduleInfo',
+ 'circuitNumber',
+ 'circuit',
]
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype]
diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx
index 5b3581e8..52553529 100644
--- a/src/components/floor-plan/CanvasFrame.jsx
+++ b/src/components/floor-plan/CanvasFrame.jsx
@@ -34,7 +34,7 @@ export default function CanvasFrame() {
const currentMenu = useRecoilValue(currentMenuState)
const { floorPlanState } = useContext(FloorPlanContext)
const { contextMenu, handleClick } = useContextMenu()
- const { currentCanvasPlan } = usePlan()
+ const { plans, currentCanvasPlan } = usePlan()
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
const { setIsGlobalLoading } = useContext(QcastContext)
const resetModuleStatisticsState = useResetRecoilState(moduleStatisticsState)
@@ -48,11 +48,14 @@ export default function CanvasFrame() {
const loadCanvas = () => {
if (canvas) {
canvas?.clear() // 캔버스를 초기화합니다.
- if (currentCanvasPlan?.canvasStatus && floorPlanState.objectNo === currentCanvasPlan.objectNo) {
- canvas?.loadFromJSON(JSON.parse(currentCanvasPlan.canvasStatus), function () {
- canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
- canvas?.renderAll() // 캔버스를 다시 그립니다.
- })
+ if (currentCanvasPlan) {
+ const plan = plans.find((plan) => plan.id === currentCanvasPlan.id)
+ if (plan?.canvasStatus && floorPlanState.objectNo === currentCanvasPlan.objectNo) {
+ canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () {
+ canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
+ canvas?.renderAll() // 캔버스를 다시 그립니다.
+ })
+ }
}
gridInit()
}
diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx
index 6c29dd57..6adae9a8 100644
--- a/src/components/floor-plan/FloorPlan.jsx
+++ b/src/components/floor-plan/FloorPlan.jsx
@@ -7,8 +7,9 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
import { usePopup } from '@/hooks/usePopup'
import '@/styles/contents.scss'
import { notFound, useSearchParams } from 'next/navigation'
-import { useRecoilState } from 'recoil'
+import { useRecoilState, useResetRecoilState } from 'recoil'
import { correntObjectNoState } from '@/store/settingAtom'
+import { currentMenuState } from '@/store/canvasAtom'
export default function FloorPlan({ children }) {
const [correntObjectNo, setCurrentObjectNo] = useRecoilState(correntObjectNoState)
@@ -19,6 +20,12 @@ export default function FloorPlan({ children }) {
const { closeAll } = usePopup()
const { menuNumber, setMenuNumber } = useCanvasMenu()
const { fetchSettings, fetchBasicSettings } = useCanvasSetting()
+ const resetCurrentMenu = useResetRecoilState(currentMenuState)
+ useEffect(() => {
+ return () => {
+ resetCurrentMenu()
+ }
+ }, [])
// URL 파라미터에서 objectNo 설정
useEffect(() => {
diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
index 60c2e168..84608186 100644
--- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
@@ -24,6 +24,7 @@ import { useEstimate } from '@/hooks/useEstimate'
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { useImgLoader } from '@/hooks/floorPlan/useImgLoader'
+import { usePlan } from '@/hooks/usePlan'
const ALLOCATION_TYPE = {
AUTO: 'auto',
@@ -53,6 +54,7 @@ export default function CircuitTrestleSetting({ id }) {
const [seletedOption, setSeletedOption] = useState(null)
const { handleCanvasToPng } = useImgLoader()
+ const { saveCanvas } = usePlan()
const {
makers,
@@ -345,6 +347,9 @@ export default function CircuitTrestleSetting({ id }) {
if (result) {
handleCanvasToPng(2)
setViewCircuitNumberTexts(true)
+ // 캔버스 저장
+ await saveCanvas(false)
+ // 견적서 저장
await saveEstimate(result)
}
// removeNotAllocationModules()
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx
index 1d28d7d0..06cab2f1 100644
--- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx
@@ -1,11 +1,12 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import QSelectBox from '@/components/common/select/QSelectBox'
+import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { useMasterController } from '@/hooks/common/useMasterController'
import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
import { pcsCheckState } from '@/store/circuitTrestleAtom'
import { globalLocaleStore } from '@/store/localeAtom'
-import { selectedModuleState } from '@/store/selectedModuleOptions'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isNullOrUndefined } from '@/util/common-utils'
import { useContext, useEffect, useState } from 'react'
import { useRecoilState } from 'recoil'
@@ -37,7 +38,8 @@ export default function PowerConditionalSelect(props) {
const { getPcsMakerList, getPcsModelList } = useMasterController()
const selectedModules = useRecoilValue(selectedModuleState)
const { swalFire } = useSwal()
- // const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
+ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
+ const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const modelHeader = [
{ name: getMessage('시리즈'), width: '15%', prop: 'pcsSerNm', type: 'color-box' },
{ name: getMessage('명칭'), width: '15%', prop: 'goodsNo', type: 'color-box' },
@@ -66,7 +68,6 @@ export default function PowerConditionalSelect(props) {
useEffect(() => {
if (makers.length === 0) {
getPcsMakerList().then((res) => {
- console.log('getPcsMakerList', res.data)
setMakers(res.data)
})
}
@@ -130,7 +131,12 @@ export default function PowerConditionalSelect(props) {
const pcsSerList = selectedSeries.map((series) => {
return { pcsSerCd: series.pcsSerCd }
})
- const moduleItemList = getUseModuleItemList()
+ const moduleItemList = moduleSelectionData.module.itemList.map((item) => {
+ return {
+ itemId: item.itemId,
+ mixMatlNo: item.mixMatlNo,
+ }
+ })
getPcsModelList({ pcsMkrCd, pcsSerList, moduleItemList }).then((res) => {
if (res?.result.code === 200 && res?.data) {
setModels(
@@ -179,7 +185,7 @@ export default function PowerConditionalSelect(props) {
setSelectedMaker(option)
const param = {
pcsMkrCd: option.pcsMkrCd,
- mixMatlNo: getUseModuleItemList()[0].mixMatlNo,
+ mixMatlNo: moduleSelectionData.module.mixMatlNo,
}
getPcsMakerList(param).then((res) => {
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
index 0463734c..635e1f8f 100644
--- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
@@ -2,6 +2,7 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { POLYGON_TYPE } from '@/common/common'
import { useMasterController } from '@/hooks/common/useMasterController'
import { useModule } from '@/hooks/module/useModule'
+import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
import { canvasState } from '@/store/canvasAtom'
@@ -28,9 +29,9 @@ export default function PassivityCircuitAllocation(props) {
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
const [circuitNumber, setCircuitNumber] = useState(1)
const [targetModules, setTargetModules] = useState([])
- const { setModuleStatisticsData } = useModule()
const { getPcsManualConfChk } = useMasterController()
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
+ const { setModuleStatisticsData } = useCircuitTrestle()
useEffect(() => {
setModuleStatisticsData()
@@ -260,7 +261,6 @@ export default function PassivityCircuitAllocation(props) {
return parseInt(circuitNumber[circuitNumber.length - 1])
})
const minCircuitNumber = Math.min(...circuitNumbers)
- console.log(circuitNumbers, minCircuitNumber)
canvas.remove(...circuitModules.map((module) => module.circuit))
circuitModules.forEach((obj) => {
obj.circuit = null
diff --git a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx
index bb23102e..af66b672 100644
--- a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx
+++ b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx
@@ -50,9 +50,7 @@ export default function PanelBatchStatistics() {
{rows.map((row, index) => (
{header.map((item, i) => (
- |
- {typeof row[item.prop] === 'number' ? row[item.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 }) : row[item.prop]}
- |
+ {row[item.prop] ?? 0} |
))}
))}
diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx
index 4a911e9e..2374c582 100644
--- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx
+++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx
@@ -199,9 +199,10 @@ export default function ContextRoofAllocationSetting(props) {
type="text"
className="input-origin block"
onChange={(e) => {
- handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
+ // handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
handleChangePitch(e, index)
}}
+ value={currentAngleType === 'slope' ? roof.pitch : roof.angle}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx
index e9f4468c..acd2291c 100644
--- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx
+++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx
@@ -201,6 +201,7 @@ export default function RoofAllocationSetting(props) {
onChange={(e) => {
handleChangePitch(e, index)
}}
+ value={currentAngleType === 'slope' ? roof.pitch : roof.angle}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js
index 2b81ea05..95af888c 100644
--- a/src/hooks/common/useRoofFn.js
+++ b/src/hooks/common/useRoofFn.js
@@ -307,5 +307,32 @@ export function useRoofFn() {
return area.points.map((p) => fabric.util.transformPoint({ x: p.x - area.pathOffset.x, y: p.y - area.pathOffset.y }, area.calcTransformMatrix()))
}
- return { setSurfaceShapePattern, removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial }
+ const removeOuterLines = (currentMousePos) => {
+ const roofBase = canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.ROOF)
+ .filter((roof) => roof.inPolygon(currentMousePos))
+
+ if (roofBase.length === 0) {
+ return
+ }
+
+ const roof = roofBase[0]
+ const wall = roof.wall
+
+ canvas.remove(roof)
+ canvas.remove(wall)
+
+ const allRoofObject = canvas
+ .getObjects()
+ .filter((obj) => /*obj !== roof && obj !== wall &&*/ obj.attributes?.roofId === roof.id || obj.parentId === roof.id || obj.parentId === wall.id)
+
+ allRoofObject.forEach((obj) => {
+ canvas.remove(obj)
+ })
+
+ canvas.renderAll()
+ }
+
+ return { setSurfaceShapePattern, removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial, removeOuterLines }
}
diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js
index 08e2146b..c4e456a9 100644
--- a/src/hooks/module/useTrestle.js
+++ b/src/hooks/module/useTrestle.js
@@ -1899,7 +1899,7 @@ export const useTrestle = () => {
rackYn,
racks: rackParams,
rackTotCnt: rackList.length ?? 0 + smartRackGroup.length ?? 0,
- rackFittingCnt: bracketList.length,
+ rackFittingTotCnt: bracketList.length,
moduleRows: getMostLeftModules(surface),
cvrYn: moduleSelection.construction.setupCover ? 'Y' : 'N',
snowGdYn: moduleSelection.construction.setupSnowCover ? 'Y' : 'N',
diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js
index ae8c78a0..c4fe1f39 100644
--- a/src/hooks/roofcover/useRoofAllocationSetting.js
+++ b/src/hooks/roofcover/useRoofAllocationSetting.js
@@ -495,7 +495,12 @@ export function useRoofAllocationSetting(id) {
}
const handleChangePitch = (e, index) => {
- const value = e.target.value
+ let value = e.target.value
+
+ const reg = /^[0-9]+(\.[0-9]{0,1})?$/
+ if (!reg.test(value)) {
+ value = value.substring(0, value.length - 1)
+ }
const newRoofList = currentRoofList.map((roof, idx) => {
if (idx === index) {
const result =
diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js
index 8ccd4b07..125d3d91 100644
--- a/src/hooks/roofcover/useRoofShapeSetting.js
+++ b/src/hooks/roofcover/useRoofShapeSetting.js
@@ -190,7 +190,9 @@ export function useRoofShapeSetting(id) {
}
case 4: {
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
+
const pitch = outerLines.find((line) => line.attributes.type === LINE_TYPE.WALLLINE.SHED)?.attributes.pitch
+ let isValid = outerLines.every((line) => line.attributes.isFixed)
// 변별로 설정중 한쪽흐름일 경우 한쪽흐름의 pitch로 설정
if (pitch) {
outerLines.forEach((line) => {
@@ -203,6 +205,10 @@ export function useRoofShapeSetting(id) {
}
})
}
+ if (!isValid) {
+ swalFire({ text: '설정이 완료되지 않았습니다.', icon: 'error' })
+ return
+ }
break
}
diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js
index b72581b3..3b37d226 100644
--- a/src/hooks/useCirCuitTrestle.js
+++ b/src/hooks/useCirCuitTrestle.js
@@ -10,10 +10,11 @@ import {
selectedModelsState,
seriesState,
} from '@/store/circuitTrestleAtom'
-import { selectedModuleState } from '@/store/selectedModuleOptions'
+import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { useContext } from 'react'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import { useMessage } from './useMessage'
+import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusController'
export function useCircuitTrestle() {
const [makers, setMakers] = useRecoilState(makersState)
@@ -25,7 +26,8 @@ export function useCircuitTrestle() {
const selectedModules = useRecoilValue(selectedModuleState)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const canvas = useRecoilValue(canvasState)
-
+ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
+ const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const setModuleStatistics = useSetRecoilState(moduleStatisticsState)
const { getMessage } = useMessage()
const getOptYn = () => {
@@ -60,7 +62,7 @@ export function useCircuitTrestle() {
// 사용된 모듈아이템 목록
const getUseModuleItemList = () => {
console.log('🚀 ~ getUseModuleItemList ~ selectedModules:', selectedModules)
- return selectedModules?.itemList?.map((m) => {
+ return moduleSelectionData.module?.itemList?.map((m) => {
return {
itemId: m.itemId,
mixMatlNo: m.mixMatlNo,
@@ -71,6 +73,10 @@ export function useCircuitTrestle() {
// 지붕면 목록
const getRoofSurfaceList = () => {
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)
+ })
roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
return roofSurfaceList
.map((obj) => {
@@ -177,12 +183,17 @@ export function useCircuitTrestle() {
const setPowerConditionerData = () => {}
const setModuleStatisticsData = () => {
- console.log(canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE))
- if (selectedModules?.length === 0) return
+ 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)
+ })
+ // console.log(moduleSelectionData)
+ if (!moduleSelectionData || !moduleSelectionData.module || moduleSelectionData.module?.itemList?.length === 0) return
const tempHeader = [
{ name: getMessage('simulator.table.sub1'), prop: 'name' },
{ name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' },
- ...selectedModules?.itemList?.map((module) => {
+ ...moduleSelectionData.module?.itemList?.map((module) => {
return {
name: module.itemNm,
prop: module.itemId,
@@ -236,7 +247,7 @@ export function useCircuitTrestle() {
circuit: surfaceObjects[key].circuit,
wpOut: parseFloat(surfaceObjects[key].wpOut / 1000),
}
- selectedModules.itemList.forEach((module) => {
+ moduleSelectionData.module.itemList.forEach((module) => {
tempRow[module.itemId] = surfaceObjects[key][module.itemId]
})
tempRows.push(tempRow)
@@ -247,7 +258,7 @@ export function useCircuitTrestle() {
circuit: surfaceObjects[key].circuits[circuit].circuit,
wpOut: parseFloat(surfaceObjects[key].circuits[circuit].circuits.wpOut / 1000),
}
- selectedModules.itemList.forEach((module) => {
+ moduleSelectionData.module.itemList.forEach((module) => {
row[module.itemId] = surfaceObjects[key].circuits[circuit].circuits[module.itemId]
})
tempRows.push(row)
@@ -259,8 +270,8 @@ export function useCircuitTrestle() {
circuit: '-',
wpOut: tempRows.reduce((acc, row) => acc + row.wpOut, 0),
}
- selectedModules.itemList.forEach((module) => {
- tempFooter[module.itemId] = tempRows.reduce((acc, row) => acc + row[module.itemId], 0)
+ moduleSelectionData.module.itemList.forEach((module) => {
+ tempFooter[module.itemId] = tempRows.reduce((acc, row) => acc + (row[module.itemId] ?? 0), 0)
})
canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter })
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js
index bb3c1683..38cdedc1 100644
--- a/src/hooks/useContextMenu.js
+++ b/src/hooks/useContextMenu.js
@@ -68,7 +68,7 @@ export function useContextMenu() {
const { settingsData, setSettingsDataSave } = useCanvasSetting()
const { swalFire } = useSwal()
const { alignModule, modulesRemove, moduleRoofRemove } = useModule()
- const { removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial } = useRoofFn()
+ const { removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial, removeOuterLines } = useRoofFn()
const currentMenuSetting = () => {
switch (currentMenu) {
@@ -150,7 +150,9 @@ export function useContextMenu() {
{
id: 'wallLineRemove',
name: getMessage('contextmenu.wallline.remove'),
- fn: () => deleteOuterLineObject(),
+ fn: (currentMousePos) => {
+ removeOuterLines(currentMousePos)
+ },
},
],
[
diff --git a/src/hooks/useEstimate.js b/src/hooks/useEstimate.js
index e2ed851d..7abe27b1 100644
--- a/src/hooks/useEstimate.js
+++ b/src/hooks/useEstimate.js
@@ -5,7 +5,6 @@ import { useRecoilValue } from 'recoil'
import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal'
-import { usePlan } from '@/hooks/usePlan'
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { QcastContext } from '@/app/QcastProvider'
import { currentCanvasPlanState } from '@/store/canvasAtom'
@@ -20,7 +19,6 @@ export function useEstimate() {
const { promisePost } = useAxios()
const { swalFire } = useSwal()
- const { saveCanvas } = usePlan()
/**
* 도면 견적서 저장
@@ -58,8 +56,7 @@ export function useEstimate() {
await promisePost({ url: '/api/estimate/save-estimate', data: saveEstimateData })
.then(async () => {
- // 견적서 저장이 완료되면 캔버스 저장 후 견적서 페이지로 이동
- await saveCanvas(false)
+ // 견적서 저장이 완료되면 견적서 페이지로 이동
moveEstimate(planNo, objectNo)
})
.catch((error) => {