From 308e41ac2644e75c910ca82a3c66cde33b162460 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 29 May 2025 16:47:17 +0900 Subject: [PATCH 01/32] Fix background image path in useRefFiles hook to use AWS S3 URL format. --- src/hooks/common/useRefFiles.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index e287221a..be3b9abf 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -271,8 +271,8 @@ export function useRefFiles() { }) console.log('🚀 ~ handleUploadConvertRefFile ~ result:', result) - // setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${result.fileName}`) - setCurrentBgImage(result.filePath) + setCurrentBgImage(`${process.env.NEXT_PUBLIC_AWS_S3_BASE_URL}/${result.fileName}`) + // setCurrentBgImage(result.filePath) setRefImage(file) const params = { From 27e923ecd4e12b0a7220dd2f9378d369186d66c0 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 29 May 2025 16:49:17 +0900 Subject: [PATCH 02/32] Fix build script in package.json to correctly reference the production environment file. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d784f800..792ddde9 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "env-cmd -f .env.localhost next dev", "local:dev": "env-cmd -f .env.local.dev next dev", - "build": "env-cmd -f .env.productionnext build", + "build": "env-cmd -f .env.production next build", "build:dev": "env-cmd -f .env.development next build", "build:local.dev": "env-cmd -f .env.local.dev next build", "start:cluster1": "env-cmd -f .env.production next start -p 5000", From 2be0cd341ad386891ae26b758bf400e332226501 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 29 May 2025 19:11:32 +0900 Subject: [PATCH 03/32] Add start scripts for cluster1 and cluster2; log run mode in config export --- src/config/config.export.js | 1 + startscript-cluster1.js | 2 ++ startscript-cluster2.js | 2 ++ 3 files changed, 5 insertions(+) create mode 100644 startscript-cluster1.js create mode 100644 startscript-cluster2.js diff --git a/src/config/config.export.js b/src/config/config.export.js index 650e1f58..620bd65c 100644 --- a/src/config/config.export.js +++ b/src/config/config.export.js @@ -5,6 +5,7 @@ import configProduction from './config.production' // 클라이언트에서는 이 함수를 사용하여 config 값을 참조합니다. const Config = () => { + console.log('🚀 ~ Config ~ process.env.NEXT_PUBLIC_RUN_MODE:', process.env.NEXT_PUBLIC_RUN_MODE) switch (process.env.NEXT_PUBLIC_RUN_MODE) { case 'local': return configLocal diff --git a/startscript-cluster1.js b/startscript-cluster1.js new file mode 100644 index 00000000..a1c03b69 --- /dev/null +++ b/startscript-cluster1.js @@ -0,0 +1,2 @@ +var exec = require('child_process').exec +exec('yarn start:cluster1', { windowsHide: true }) diff --git a/startscript-cluster2.js b/startscript-cluster2.js new file mode 100644 index 00000000..20fc5f42 --- /dev/null +++ b/startscript-cluster2.js @@ -0,0 +1,2 @@ +var exec = require('child_process').exec +exec('yarn start:cluster2', { windowsHide: true }) From f323d312d72326b7d4331c5ef67a84e2c64308ab Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 29 May 2025 19:13:12 +0900 Subject: [PATCH 04/32] Add development start script to execute 'yarn start:dev' --- startscript-dev.js | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 startscript-dev.js diff --git a/startscript-dev.js b/startscript-dev.js new file mode 100644 index 00000000..31300d78 --- /dev/null +++ b/startscript-dev.js @@ -0,0 +1,2 @@ +var exec = require('child_process').exec +exec('yarn start:dev', { windowsHide: true }) From 0ed1ed56233468190ee00ac2ce2b79770ee14cb1 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 30 May 2025 11:29:05 +0900 Subject: [PATCH 05/32] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=82=AC?= =?UTF-8?q?=EC=A7=84=20=EC=9E=98=EB=A6=AC=EB=8A=94=20=ED=98=84=EC=83=81=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 --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index d268cc21..f4972c54 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -13,7 +13,7 @@ import { useRecoilState } from 'recoil' import { makersState, modelsState, modelState, pcsCheckState, selectedMakerState, selectedModelsState, seriesState } from '@/store/circuitTrestleAtom' import { POLYGON_TYPE } from '@/common/common' import { useSwal } from '@/hooks/useSwal' -import { canvasState } from '@/store/canvasAtom' +import { canvasState, canvasZoomState } from '@/store/canvasAtom' import { useTrestle } from '@/hooks/module/useTrestle' import { selectedModuleState } from '@/store/selectedModuleOptions' @@ -37,7 +37,7 @@ export default function CircuitTrestleSetting({ id }) { const { swalFire } = useSwal() const { saveEstimate } = useEstimate() const canvas = useRecoilValue(canvasState) - + const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const [tabNum, setTabNum] = useState(1) const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO) const [circuitAllocationType, setCircuitAllocationType] = useState(1) @@ -102,6 +102,13 @@ export default function CircuitTrestleSetting({ id }) { } }, []) + const handleZoomClear = () => { + setCanvasZoom(100) + canvas.set({ zoom: 1 }) + canvas.viewportTransform = [1, 0, 0, 1, 0, 0] + canvas.renderAll() + } + // 수동할당 시 모듈 삭제 // 시리즈중 자동으로 추천 PCS 정보 조회 @@ -343,6 +350,7 @@ export default function CircuitTrestleSetting({ id }) { // 회로할당(승압설정) 저장 버튼 클릭 시 const onApply = async () => { + handleZoomClear() setAllModuleSurfaceIsComplete(false) setIsGlobalLoading(true) From 9302ba216fa413b07288926b11b4e4f116354d2c Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 30 May 2025 13:06:07 +0900 Subject: [PATCH 06/32] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20->=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=9D=B4=EB=8F=99=20=ED=9B=84=20=EC=BA=94?= =?UTF-8?q?=EB=B2=84=EC=8A=A4=20=EB=AF=B8=EB=85=B8=EC=B6=9C=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 --- src/hooks/usePlan.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index d8e1c9d6..afae51c8 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -602,8 +602,10 @@ export function usePlan(params = {}) { if (pathname === '/floor-plan/estimate/5' || pathname === '/floor-plan/simulator/6') { await getCanvasByObjectNo(objectNo, planNo).then((res) => { if (res.length > 0) { - setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus })) - setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((resPlan) => resPlan.planNo === plan.planNo).canvasStatus }))) + // setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus })) + // setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((resPlan) => resPlan.planNo === plan.planNo).canvasStatus }))) + setCurrentCanvasPlan(res.find((plan) => plan.planNo === planNo)) + setPlans(res) } }) } From d16c3869d14c0905ae8d77cde98005f5930ec86d Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 30 May 2025 13:42:48 +0900 Subject: [PATCH 07/32] =?UTF-8?q?path=20=EB=B3=80=EA=B2=BD=EB=90=98?= =?UTF-8?q?=EB=A9=B4=20FloorPlan=20state=EA=B0=92=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/floor-plan/FloorPlanProvider.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/app/floor-plan/FloorPlanProvider.js b/src/app/floor-plan/FloorPlanProvider.js index 5019e8a4..1e5c536d 100644 --- a/src/app/floor-plan/FloorPlanProvider.js +++ b/src/app/floor-plan/FloorPlanProvider.js @@ -45,8 +45,19 @@ const FloorPlanProvider = ({ children }) => { // const pathname = usePathname() // const setCorrentObjectNo = useSetRecoilState(correntObjectNoState) const searchParams = useSearchParams() + const path = usePathname() const objectNo = searchParams.get('objectNo') const pid = searchParams.get('pid') + + useEffect(() => { + setFloorPlanState((prev) => { + return { + ...prev, + objectNo, + pid, + } + }) + }, [path]) // useEffect(() => { // console.log('🚀 ~ useEffect ~ objectNo:') // if (pathname === '/floor-plan') { From 51d892ed29450e27e6f8c6e44600857cb15eaf09 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 30 May 2025 14:10:31 +0900 Subject: [PATCH 08/32] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=ED=9D=A1=EC=B0=A9?= =?UTF-8?q?=20=EC=88=98=EC=A0=95,=20=EB=AA=A8=EB=93=88=EC=B0=BD=20?= =?UTF-8?q?=ED=86=A0=EA=B8=80=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/Placement.jsx | 6 ++++-- src/hooks/module/useModuleBasicSetting.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index ffb96d83..29ea0d10 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -318,8 +318,10 @@ const Placement = forwardRef((props, refs) => {
- {getMessage('modal.module.basic.setting.module.placement.max.size.check')} - +
setUseTab(!useTab)}> + {getMessage('modal.module.basic.setting.module.placement.max.size.check')} + +
diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index a3f2eb0e..8f4a2a7e 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -661,7 +661,7 @@ export function useModuleBasicSetting(tabNum) { //가운데 가운데 if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { - tempModule.top = holdCellCenterY - toFixedWithoutRounding(width / 2, 2) + tempModule.top = holdCellCenterY - toFixedWithoutRounding(height / 2, 2) } if (isChidori) { From 022125759f3d62388fb1858b76861a5ec0ada8e2 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, 30 May 2025 17:18:22 +0900 Subject: [PATCH 09/32] =?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/canvas/roof_warning_correct.png | Bin 0 -> 15340 bytes .../images/canvas/roof_warning_wrong.png | Bin 0 -> 16392 bytes src/styles/_modal.scss | 19 ++++++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 public/static/images/canvas/roof_warning_correct.png create mode 100644 public/static/images/canvas/roof_warning_wrong.png diff --git a/public/static/images/canvas/roof_warning_correct.png b/public/static/images/canvas/roof_warning_correct.png new file mode 100644 index 0000000000000000000000000000000000000000..4f9741a55adbf802e5e312a181dd6819b1fba282 GIT binary patch literal 15340 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 literal 0 HcmV?d00001 diff --git a/public/static/images/canvas/roof_warning_wrong.png b/public/static/images/canvas/roof_warning_wrong.png new file mode 100644 index 0000000000000000000000000000000000000000..3a245d5174f26bd14e385d3b3d63ff2528ee2610 GIT binary patch literal 16392 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 literal 0 HcmV?d00001 diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index 30c18715..c90372bf 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -2457,3 +2457,22 @@ $alert-color: #101010; } } } + +// 2025-05-30 지붕 모듈 +.roof-warning-img-wrap{ + display: flex; + align-items: center; + gap: 15px; + justify-content: center; +} + +.roof-content-tab-wrap{ + display: flex; + padding-top: 10px; +} +.hide-tab-contents{ + &.hide{ + height: 0; + overflow: hidden; + } +} \ No newline at end of file From 66827d4c87cf94a0fcb9bcc1ce4f1c41fce4c210 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, 30 May 2025 17:19:35 +0900 Subject: [PATCH 10/32] =?UTF-8?q?[1069]=20:=20[=E3=80=90HANASYS=20DESIGN?= =?UTF-8?q?=E3=80=91=E4=B8=8D=E6=AD=A3=E3=81=AA=E9=85=8D=E7=BD=AE=E3=81=AB?= =?UTF-8?q?=E3=81=A4=E3=81=84=E3=81=A6[=E3=82=A2=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=81=AE=E8=A1=A8=E7=A4=BA]]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 모듈 배치 화면에 안내 문구 추가 --- .../floor-plan/modal/basic/step/Placement.jsx | 139 +++++++++++------- src/locales/ja.json | 5 + src/locales/ko.json | 5 + 3 files changed, 96 insertions(+), 53 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index ffb96d83..aaab0add 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -12,10 +12,12 @@ import { import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' +import Image from 'next/image' const Placement = forwardRef((props, refs) => { const { getMessage } = useMessage() const [useTab, setUseTab] = useState(true) + const [guideType, setGuideType] = useState('batch') const [isChidoriNotAble, setIsChidoriNotAble] = useState(false) @@ -317,60 +319,91 @@ const Placement = forwardRef((props, refs) => {
-
- {getMessage('modal.module.basic.setting.module.placement.max.size.check')} - -
-
-
-
- - - - - {selectedModules && - selectedModules.itemList?.map((item) => ( - // - ))} - {colspan > 1 && } - - - {selectedModules && - selectedModules.itemList?.map((item) => ( - <> - - {/* {colspan > 1 && } */} - - ))} - - - - {moduleSelectionData.roofConstructions.map((item, index) => ( - - - {moduleRowColArray[index]?.map((item, index2) => ( - <> - - {/* {colspan > 1 && } */} - {colspan > 1 && index2 === moduleRowColArray[index].length - 1 && } - - ))} - - ))} - -
- -
- - {item.itemNm} -
-
{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}
{getMessage('modal.module.basic.setting.module.placement.max.row')}{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}
-
- - {item.addRoof?.roofMatlNmJp} -
-
{item.moduleMaxRows}{item.mixModuleMaxRows}{item.maxRow}
+
+
+ {getMessage('modal.module.basic.setting.module.placement.info')} + +
+
+
+ +
+ {guideType === 'batch' && ( +
+
+ {getMessage('modal.module.basic.setting.module.placement.info.batch.content1')} +
+ {getMessage('modal.module.basic.setting.module.placement.info.batch.content2')} +
+
+
+ +
+
+ +
+
+
+ )} + {guideType === 'module' && ( +
+
+
+ + + + + {selectedModules && + selectedModules.itemList?.map((item) => ( + // + ))} + {colspan > 1 && } + + + {selectedModules && + selectedModules.itemList?.map((item) => ( + <> + + {/* {colspan > 1 && } */} + + ))} + + + + {moduleSelectionData.roofConstructions.map((item, index) => ( + + + {moduleRowColArray[index]?.map((item, index2) => ( + <> + + {/* {colspan > 1 && } */} + {colspan > 1 && index2 === moduleRowColArray[index].length - 1 && } + + ))} + + ))} + +
+ +
+ + {item.itemNm} +
+
{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}
{getMessage('modal.module.basic.setting.module.placement.max.row')}{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}
+
+ + {item.addRoof?.roofMatlNmJp} +
+
{item.moduleMaxRows}{item.mixModuleMaxRows}{item.maxRow}
+
+
+
+ )}
diff --git a/src/locales/ja.json b/src/locales/ja.json index 8ce666f8..b44ea70b 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1105,6 +1105,11 @@ "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.info": "モジュール配置案内", + "modal.module.basic.setting.module.placement.info.batch": "千鳥配置を手動で行う際の注意事項", + "modal.module.basic.setting.module.placement.info.batch.content1": "千鳥配置する時に図のような配置ができてしまいますが、正常な積算ができません。", + "modal.module.basic.setting.module.placement.info.batch.content2": "千鳥で配置する時は、千鳥配置を「する」にして、モジュールが吸着されるようにして下さい。", + "modal.module.basic.setting.module.placement.info.module": "屋根材別 単一・混合モジュールの最大段数", "modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの単体の単体での最大段数、2種混合の段数を確認して下さい", "modal.module.basic.setting.module.placement.max.row": "単体で\rの最大段数", "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時\rの最大段数", diff --git a/src/locales/ko.json b/src/locales/ko.json index 67176ee8..11bc85c9 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1105,6 +1105,11 @@ "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.info": "모듈 배치 안내", + "modal.module.basic.setting.module.placement.info.batch": "치도리 수동 배치 시 유의사항", + "modal.module.basic.setting.module.placement.info.batch.content1": "치조 배치할 때 그림과 같은 배치가 되어 버립니다만, 정상적인 적산을 할 수 없습니다.", + "modal.module.basic.setting.module.placement.info.batch.content2": "치조로 배치할 때는, 치조 배치를 「한다」로 하고, 모듈이 흡착되도록 해 주세요.", + "modal.module.basic.setting.module.placement.info.module": "지붕재별 단일·혼합 모듈 최대 단수", "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종 혼합 최대단수", From 5986fe51ffedd07c8793682e802cc5e9ab49eafb Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 30 May 2025 17:23:16 +0900 Subject: [PATCH 11/32] =?UTF-8?q?=EB=8C=80=ED=91=9C=EB=9D=BC=EC=9D=B8=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=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 | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index bcaec973..39e82210 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -1093,14 +1093,12 @@ export const usePolygon = () => { }) if (startFlag && endFlag) { - if (!representLines.includes(line)) { + if (!representLines.includes(line) && line.attributes.type === LINE_TYPE.WALLLINE.EAVES) { representLines.push(line) } } }) - // blue로 생성된 것들은 대표라인이 될 수 없음. - representLines = representLines.filter((line) => line.stroke !== 'blue') // representLines중 가장 긴 line을 찾는다. representLines.forEach((line) => { if (!representLine) { @@ -1111,7 +1109,21 @@ export const usePolygon = () => { } } }) - const direction = polygon.direction ?? representLine?.direction + + if (!representLine) { + representLines = representLines.filter((line) => line.stroke !== 'blue') + representLines.forEach((line) => { + if (!representLine) { + representLine = line + } else { + if (representLine.length < line.length) { + representLine = line + } + } + }) + } + + const direction = polygon.direction ?? representLine?.direction ?? '' const polygonDirection = polygon.direction switch (direction) { From 401d752ac7cadc1c3d4756efb584c9be64e41244 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, 30 May 2025 17:23:57 +0900 Subject: [PATCH 12/32] =?UTF-8?q?=EC=98=A4=ED=83=80=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/Placement.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index aaab0add..497d1307 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -351,7 +351,7 @@ const Placement = forwardRef((props, refs) => {
)} {guideType === 'module' && ( -
+
From 94985feed8eb993ecdf61f2c70179f40fdd5dc5f Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 30 May 2025 17:29:37 +0900 Subject: [PATCH 13/32] =?UTF-8?q?length=EA=B0=80=20=EC=97=86=EB=8A=94?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EB=94=B0=EB=A1=9C=20=EA=B3=84=EC=82=B0=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/useLine.js | 1 + src/hooks/usePolygon.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hooks/useLine.js b/src/hooks/useLine.js index fcf14312..9d1a48eb 100644 --- a/src/hooks/useLine.js +++ b/src/hooks/useLine.js @@ -159,5 +159,6 @@ export const useLine = () => { addPitchText, removePitchText, addPitchTextsByOuterLines, + getLengthByLine, } } diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 39e82210..558bec36 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -15,6 +15,7 @@ import { flowDisplaySelector } from '@/store/settingAtom' import { fontSelector } from '@/store/fontAtom' import { QLine } from '@/components/fabric/QLine' import { LINE_TYPE, POLYGON_TYPE } from '@/common/common' +import { useLine } from '@/hooks/useLine' export const usePolygon = () => { const canvas = useRecoilValue(canvasState) @@ -24,6 +25,8 @@ export const usePolygon = () => { const currentAngleType = useRecoilValue(currentAngleTypeSelector) const pitchText = useRecoilValue(pitchTextSelector) + const { getLengthByLine } = useLine() + const addPolygon = (points, options, isAddCanvas = true) => { const polygon = new QPolygon(points, { ...options, @@ -1104,7 +1107,7 @@ export const usePolygon = () => { if (!representLine) { representLine = line } else { - if (representLine.length < line.length) { + if (getLengthByLine(representLine) < getLengthByLine(line)) { representLine = line } } From 8b81998f8ccf398292f92e8b5279dc16e3d1df70 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 30 May 2025 17:56:39 +0900 Subject: [PATCH 14/32] =?UTF-8?q?[1068]=20:=20[=EA=B2=AC=EC=A0=81=EC=84=9C?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=EB=90=9C=20=ED=94=8C=EB=9E=9C=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20-->=20=EB=B3=B5=EC=82=AC=EB=90=9C=20=ED=94=8C?= =?UTF-8?q?=EB=9E=9C=EC=97=90=EC=84=9C=20=EB=AA=A8=EB=93=88=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20-->=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=EC=9D=B4=20=EB=90=A8..=20]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 가대까지 완성 -> 삭제 안함, 그 전상태면 무조건 삭제 로직으로 구현 --- .../floorPlan/estimate/useEstimateController.js | 14 ++++++++++++++ src/hooks/usePlan.js | 15 +++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 4a752a9f..ae37c8db 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -489,6 +489,19 @@ export const useEstimateController = (planNo, flag) => { }) } + const handleDeleteEstimate = async (canvasStatus) => { + try { + setIsGlobalLoading(true) + await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/delete-estimate`, data: canvasStatus }).then((res) => { + if (res.status === 201) { + } + }) + } catch (e) { + console.error('error::::::::::::', e.response.data.message) + } + setIsGlobalLoading(false) + } + /** * 전각20자 (반각40자) */ @@ -509,5 +522,6 @@ export const useEstimateController = (planNo, flag) => { fetchSetting, handleEstimateFileDownload, handleEstimateCopy, + handleDeleteEstimate, } } diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index afae51c8..81d66455 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -30,6 +30,7 @@ import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusCon import { useCanvasMenu } from './common/useCanvasMenu' import { QcastContext } from '@/app/QcastProvider' import { unescapeString } from '@/util/common-utils' +import { useTrestle } from '@/hooks/module/useTrestle' /** * 플랜 처리 훅 @@ -54,7 +55,7 @@ export function usePlan(params = {}) { const { getMessage } = useMessage() const { get, post, promisePost, promisePut, promiseDel, promiseGet } = useAxios() - const { setEstimateContextState } = useEstimateController() + const { setEstimateContextState, handleDeleteEstimate } = useEstimateController() const resetOuterLinePoints = useResetRecoilState(outerLinePointsState) const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState) @@ -79,6 +80,8 @@ export function usePlan(params = {}) { //선택된 모듈 배치면 초기화 const resetModuleSetupSurface = useResetRecoilState(moduleSetupSurfaceState) + const { isAllComplete } = useTrestle() + /** * 마우스 포인터의 가이드라인 제거 */ @@ -172,7 +175,11 @@ export function usePlan(params = {}) { */ const saveCanvas = async (saveAlert = true) => { const canvasStatus = currentCanvasData('save') - await putCanvasStatus(canvasStatus, saveAlert) + const result = await putCanvasStatus(canvasStatus, saveAlert) + //캔버스 저장 완료 후 + if (result && !isAllComplete()) { + handleDeleteEstimate(currentCanvasPlan) + } } /** @@ -318,20 +325,24 @@ export function usePlan(params = {}) { * @param {boolean} saveAlert - 저장 완료 알림 표시 여부 */ const putCanvasStatus = async (canvasStatus, saveAlert = true) => { + let rtn = false const planData = { id: currentCanvasPlan.id, bgImageName: currentCanvasPlan?.bgImageName ?? null, mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null, canvasStatus: canvasToDbFormat(canvasStatus), } + await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData }) .then((res) => { setPlans((plans) => plans.map((plan) => (plan.id === currentCanvasPlan.id ? { ...plan, canvasStatus: canvasStatus } : plan))) if (saveAlert) swalFire({ text: getMessage('plan.message.save') }) + rtn = true }) .catch((error) => { swalFire({ text: error.message, icon: 'error' }) }) + return rtn } /** From 286dad7021097ba99d34789b2577e15b73868f42 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 2 Jun 2025 10:16:23 +0900 Subject: [PATCH 15/32] =?UTF-8?q?[1076]=20:=20[=E9=87=91=E5=B1=9E=E7=B8=A6?= =?UTF-8?q?=E8=91=BA=E3=83=BB=E3=83=8F=E3=82=BC=E5=BC=8F=E6=8A=98=E6=9D=BF?= =?UTF-8?q?=E3=83=BB=E9=87=8D=E3=81=AD=E5=BC=8F=E6=8A=98=E6=9D=BF=E3=83=BB?= =?UTF-8?q?=E7=93=A6=E6=A3=92=E8=91=BA(=E8=8A=AF=E6=9C=A8=E3=81=AA?= =?UTF-8?q?=E3=81=97)=E3=81=AE=E5=B1=8B=E6=A0=B9=E3=81=A8=E3=83=A9?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=83=AC=E3=82=B9=E5=B7=A5=E6=B3=95=E3=81=AE?= =?UTF-8?q?=E7=B5=84=E3=81=BF=E5=90=88=E3=82=8F=E3=81=9B=E3=81=AE=E6=99=82?= =?UTF-8?q?=E3=80=81=E5=83=8D=E3=81=8D=E5=B9=85=E3=81=AB=E3=82=88=E3=82=8B?= =?UTF-8?q?=E3=83=A2=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E8=A8=AD=E7=BD=AE?= =?UTF-8?q?=E5=88=B6=E9=99=90=E3=81=8C=E3=81=A7=E3=81=8D=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=81=AA=E3=81=84=E3=80=82]?= 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 44a68236..f350ff5a 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) => { stdWindSpeed: managementState?.standardWindSpeedId ?? '', stdSnowLd: managementState?.verticalSnowCover ?? '', inclCd: selectedRoof?.pitch ?? 0, - roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), + roofPitch: Math.round(hajebichi ?? 0), }, }) } @@ -238,7 +238,7 @@ const Trestle = forwardRef((props, ref) => { stdWindSpeed: managementState?.standardWindSpeedId ?? '', stdSnowLd: +managementState?.verticalSnowCover ?? '', inclCd: selectedRoof?.pitch ?? 0, - roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0), + roofPitch: Math.round(hajebichi ?? 0), constTp: constructionList[index].constTp, snowGdPossYn: constructionList[index].snowGdPossYn, cvrYn: constructionList[index].cvrYn, From 806c829adabe0a0206a5c87d2fb7faadd4dc5c89 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 2 Jun 2025 10:42:18 +0900 Subject: [PATCH 16/32] =?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=20alert=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/useRoofAllocationSetting.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index fee893a6..5fbc3ab3 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -212,7 +212,6 @@ export function useRoofAllocationSetting(id) { } await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { - swalFire({ text: getMessage(res.returnMessage) }) setIsGlobalLoading(false) }) From 49c3cae9fab5d931d6548d25dee7282d5463321f Mon Sep 17 00:00:00 2001 From: ysCha Date: Mon, 2 Jun 2025 11:09:43 +0900 Subject: [PATCH 17/32] =?UTF-8?q?[1074]HANASYS=20=EC=84=A4=EA=B3=84=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20ID=20=EB=B0=9C=EA=B8=89=20?= =?UTF-8?q?=EC=8B=A0=EC=B2=AD=20=ED=99=94=EB=A9=B4=EC=9D=98=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=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 | 6 +++--- src/locales/ko.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 4ce9156b..16d4f6cd 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -666,9 +666,9 @@ "join.sub1.title": "販売代理店情報", "join.sub1.comment": "※登録される販売店の会社名を入力してください。 (2次店は「○○販売株式会社(2次店:××設備株式会社)」でご記入ください。)", "join.sub1.storeQcastNm": "販売代理店名", - "join.sub1.storeQcastNm_placeholder": "株式会社エネルギーギアソリューションアンサービス(2次点:山口周期販売有限会社)", + "join.sub1.storeQcastNm_placeholder": "ハンファジャパン株式会社", "join.sub1.storeQcastNmKana": "販売代理店名フリガナ", - "join.sub1.storeQcastNmKana_placeholder": "株式会社エネルギーギアソリューション", + "join.sub1.storeQcastNmKana_placeholder": "ハンファジャパンカブシキカイシャ", "join.sub1.postCd": "郵便番号", "join.sub1.postCd_placeholder": "数字7桁", "join.sub1.addr": "住所", @@ -681,7 +681,7 @@ "join.sub2.title": "担当者情報", "join.sub2.userNm": "担当者名", "join.sub2.userNmKana": "担当者名ふりがな", - "join.sub2.userId": "申請ID", + "join.sub2.userId": "ユーザーID", "join.sub2.email": "メールアドレス", "join.sub2.telNo": "電話番号", "join.sub2.telNo_placeholder": "00 0000 0000", diff --git a/src/locales/ko.json b/src/locales/ko.json index 11bc85c9..f0169fbb 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -666,9 +666,9 @@ "join.sub1.title": "판매대리점 정보", "join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점:××설비주식회사)」로 기입해 주세요.)", "join.sub1.storeQcastNm": "판매대리점명", - "join.sub1.storeQcastNm_placeholder": "주식회사 에너지 기어 솔루션 앤 서비스 (2차점: 야마구치 주기 판매 유한회사)", + "join.sub1.storeQcastNm_placeholder": "한화재팬 주식회사", "join.sub1.storeQcastNmKana": "판매대리점명 후리가나", - "join.sub1.storeQcastNmKana_placeholder": "주식회사 에너지 기어 솔루션", + "join.sub1.storeQcastNmKana_placeholder": "한화재팬 카부시키 카이샤", "join.sub1.postCd": "우편번호", "join.sub1.postCd_placeholder": "숫자 7자리", "join.sub1.addr": "주소", @@ -681,7 +681,7 @@ "join.sub2.title": "담당자 정보", "join.sub2.userNm": "담당자명", "join.sub2.userNmKana": "담당자명 후리가나", - "join.sub2.userId": "신청 ID", + "join.sub2.userId": "사용자 ID", "join.sub2.email": "이메일 주소", "join.sub2.telNo": "전화번호", "join.sub2.telNo_placeholder": "00 0000 0000", From 8dafc239b3ff4411e3e13ecd077f128d22d20fcf Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 2 Jun 2025 13:48:53 +0900 Subject: [PATCH 18/32] =?UTF-8?q?[1076]=20:=20[=E9=87=91=E5=B1=9E=E7=B8=A6?= =?UTF-8?q?=E8=91=BA=E3=83=BB=E3=83=8F=E3=82=BC=E5=BC=8F=E6=8A=98=E6=9D=BF?= =?UTF-8?q?=E3=83=BB=E9=87=8D=E3=81=AD=E5=BC=8F=E6=8A=98=E6=9D=BF=E3=83=BB?= =?UTF-8?q?=E7=93=A6=E6=A3=92=E8=91=BA(=E8=8A=AF=E6=9C=A8=E3=81=AA?= =?UTF-8?q?=E3=81=97)=E3=81=AE=E5=B1=8B=E6=A0=B9=E3=81=A8=E3=83=A9?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=83=AC=E3=82=B9=E5=B7=A5=E6=B3=95=E3=81=AE?= =?UTF-8?q?=E7=B5=84=E3=81=BF=E5=90=88=E3=82=8F=E3=81=9B=E3=81=AE=E6=99=82?= =?UTF-8?q?]?= 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 ++- src/hooks/module/useModuleTrestle.js | 4 ++-- 2 files 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 f350ff5a..070ce979 100644 --- a/src/components/floor-plan/modal/basic/step/Trestle.jsx +++ b/src/components/floor-plan/modal/basic/step/Trestle.jsx @@ -236,7 +236,7 @@ const Trestle = forwardRef((props, ref) => { illuminationTp: managementState?.surfaceTypeValue ?? '', instHt: managementState?.installHeight ?? '', stdWindSpeed: managementState?.standardWindSpeedId ?? '', - stdSnowLd: +managementState?.verticalSnowCover ?? '', + stdSnowLd: managementState?.verticalSnowCover ?? '', inclCd: selectedRoof?.pitch ?? 0, roofPitch: Math.round(hajebichi ?? 0), constTp: constructionList[index].constTp, @@ -304,6 +304,7 @@ const Trestle = forwardRef((props, ref) => { kerabaMargin, roofIndex: roof.index, raft: selectedRaftBase?.clCode, + hajebichi: hajebichi, trestle: { length: lengthBase, hajebichi: hajebichi, diff --git a/src/hooks/module/useModuleTrestle.js b/src/hooks/module/useModuleTrestle.js index 0143e92e..a39c8c1d 100644 --- a/src/hooks/module/useModuleTrestle.js +++ b/src/hooks/module/useModuleTrestle.js @@ -209,7 +209,7 @@ export function useModuleTrestle(props) { stdSnowLd: trestleState.stdSnowLd ?? '', inclCd: trestleState.inclCd ?? '', raftBaseCd: trestleState.raft ?? '', - roofPitch: Math.round(trestleState.roofPitch) ?? '', + roofPitch: trestleState.hajebichi ? trestleState.hajebichi : (trestleState.roofPitch ?? ''), }) .then((res) => { if (res?.data) setConstructionList(res.data) @@ -236,7 +236,7 @@ export function useModuleTrestle(props) { inclCd: trestleState.inclCd ?? '', constTp: trestleState.constTp ?? '', mixMatlNo: trestleState.mixMatlNo ?? '', - roofPitch: trestleState.roofPitch ?? '', + roofPitch: trestleState.hajebichi ? trestleState.hajebichi : (trestleState.roofPitch ?? ''), // workingWidth: trestleState.length ?? '', workingWidth: lengthBase ?? '', }, From 84c18c80f058953ecce9f2bb6ef6aaf03b90afee Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 2 Jun 2025 15:00:33 +0900 Subject: [PATCH 19/32] =?UTF-8?q?[1079]=20:=20[ID=E7=94=B3=E8=AB=8B?= =?UTF-8?q?=E7=94=BB=E9=9D=A2=E7=BF=BB=E8=A8=B3=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 16d4f6cd..3b6962c6 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -689,12 +689,12 @@ "join.sub2.fax_placeholder": "00 0000 0000", "join.sub2.category": "部署名", "join.btn.login_page": "ログイン画面に移動", - "join.btn.approval_request": "ID承認要求", + "join.btn.approval_request": "ID申請", "join.complete.title": "HANASYS設計ログインID発行申請完了", "join.complete.contents": "※申請したIDが承認されると、担当者情報に入力したEメールアドレスにログイン関連案内メールが送信されます。", "join.complete.email_comment": "担当者のメールアドレス", "join.validation.check1": "{0}形式を確認してください。", - "join.complete.save.confirm": "ハンファジャパンの担当者にID承認が要求された場合、これ以上情報を修正することはできません。申請しますか?", + "join.complete.save.confirm": "ID申請を完了後は申請情報の修正が出来ません。申請しますか?", "stuff.gridHeader.lastEditDatetime": "更新日時", "stuff.gridHeader.objectNo": "物件番号", "stuff.gridHeader.planTotCnt": "プラン数", From 639c057e0c8939485cdfd5c07f954c7c4a485b4f Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 2 Jun 2025 17:40:38 +0900 Subject: [PATCH 20/32] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20->=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20=EB=A1=9C=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 --- .../api/image/estimate-image-copy/route.js | 42 +++++++++++++++++++ .../estimate/useEstimateController.js | 14 ++++++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/app/api/image/estimate-image-copy/route.js diff --git a/src/app/api/image/estimate-image-copy/route.js b/src/app/api/image/estimate-image-copy/route.js new file mode 100644 index 00000000..720dd5f0 --- /dev/null +++ b/src/app/api/image/estimate-image-copy/route.js @@ -0,0 +1,42 @@ +import { NextResponse } from 'next/server' +import { S3Client, CopyObjectCommand } from '@aws-sdk/client-s3' +import sharp from 'sharp' +import { v4 as uuidv4 } from 'uuid' +const Bucket = process.env.AMPLIFY_BUCKET +const s3 = new S3Client({ + region: process.env.AWS_REGION, + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + }, +}) + +export async function POST(req) { + try { + const { objectNo, planNo, newObjectNo, newPlanNo } = await req.json() + + const responseArray = [] + + const copyCommand = new CopyObjectCommand({ + Bucket, + CopySource: encodeURI(`${Bucket}/Drawing/${objectNo}_${planNo}_1.png`), + Key: `Drawing/${newObjectNo}_${newPlanNo}_1.png`, + }) + + const response = await s3.send(copyCommand) + + const copyCommand2 = new CopyObjectCommand({ + Bucket, + CopySource: encodeURI(`${Bucket}/Drawing/${objectNo}_${planNo}_2.png`), + Key: `Drawing/${newObjectNo}_${newPlanNo}_2.png`, + }) + + const response2 = await s3.send(copyCommand2) + + responseArray.push(response, response2) + return NextResponse.json({ message: '견적서 이미지 복사 성공', responseArray }, { status: 200 }) + } catch (error) { + console.error(error) + return NextResponse.json({ message: '견적서 이미지 복사 실패' }, { status: 500 }) + } +} diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index ae37c8db..64ff13e9 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -13,6 +13,8 @@ import { useSwal } from '@/hooks/useSwal' // Constants const ESTIMATE_API_ENDPOINT = '/api/estimate' // API 엔드포인트 정의 +import Config from '@/config/config.export' + // Helper functions const updateItemInList = (itemList, dispOrder, updates) => { return itemList.map((item) => (item.dispOrder === dispOrder ? { ...item, ...updates } : item)) @@ -464,11 +466,13 @@ export const useEstimateController = (planNo, flag) => { setIsGlobalLoading(true) await promisePost({ url: '/api/estimate/save-estimate-copy', data: params }) - .then((res) => { + .then(async (res) => { setIsGlobalLoading(false) if (res.status === 201) { if (isObjectNotEmpty(res.data)) { let newObjectNo = res.data.objectNo + const copyImage = await handleEstimateImageCopy(params.objectNo, params.planNo, newObjectNo, '1') + swalFire({ text: getMessage('estimate.detail.estimateCopyPopup.copy.alertMessage'), type: 'alert', @@ -489,6 +493,14 @@ export const useEstimateController = (planNo, flag) => { }) } + const handleEstimateImageCopy = async (objectNo, planNo, newObjectNo, newPlanNo) => { + await promisePost({ url: `${Config().baseUrl}/api/image/estimate-image-copy`, data: { objectNo, planNo, newObjectNo, newPlanNo } }).then( + (res) => { + return res + }, + ) + } + const handleDeleteEstimate = async (canvasStatus) => { try { setIsGlobalLoading(true) From 6e811c9cd493be014cb56beb32ccd0e0ffd208f4 Mon Sep 17 00:00:00 2001 From: ysCha Date: Mon, 2 Jun 2025 17:43:37 +0900 Subject: [PATCH 21/32] =?UTF-8?q?[1080]=ED=94=8C=EB=9E=9C=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=AF=B8=ED=91=9C=EC=8B=9C?= 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 7237e056..9a60fd0e 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1281,7 +1281,7 @@ export default function Estimate({}) {
{getMessage('estimate.detail.objectNo')}
- {currentObjectNo} (Plan No: {planNo}) + {currentObjectNo} (Plan No: {currentPid})
From 16c97ae041c268badb2ba54b1bd2b45bba90851e Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 3 Jun 2025 10:26:08 +0900 Subject: [PATCH 22/32] =?UTF-8?q?=ED=94=8C=EB=9E=9C=20=EB=B3=B5=EC=82=AC?= =?UTF-8?q?=EC=8B=9C=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EB=B3=B5=EC=82=AC=20=EB=A1=9C=EC=A7=81=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 --- .../api/image/estimate-image-copy/route.js | 19 ++++++++++++++++++- .../estimate/useEstimateController.js | 1 + src/hooks/usePlan.js | 6 ++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/app/api/image/estimate-image-copy/route.js b/src/app/api/image/estimate-image-copy/route.js index 720dd5f0..16984c8c 100644 --- a/src/app/api/image/estimate-image-copy/route.js +++ b/src/app/api/image/estimate-image-copy/route.js @@ -1,5 +1,5 @@ import { NextResponse } from 'next/server' -import { S3Client, CopyObjectCommand } from '@aws-sdk/client-s3' +import { S3Client, CopyObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3' import sharp from 'sharp' import { v4 as uuidv4 } from 'uuid' const Bucket = process.env.AMPLIFY_BUCKET @@ -17,6 +17,23 @@ export async function POST(req) { const responseArray = [] + // const isExistImage1 = await s3.send( + // new GetObjectCommand({ + // Bucket, + // Key: `Drawing/${objectNo}_${planNo}_1.png`, + // }), + // ) + + // const isExistImage2 = await s3.send( + // new GetObjectCommand({ + // Bucket, + // Key: `Drawing/${objectNo}_${planNo}_1.png`, + // }), + // ) + + // console.log('🚀 ~ isExistImage1:', isExistImage1.$metadata.httpStatusCode === 200) + // console.log('🚀 ~ isExistImage2:', isExistImage2.$metadata.httpStatusCode === 200) + const copyCommand = new CopyObjectCommand({ Bucket, CopySource: encodeURI(`${Bucket}/Drawing/${objectNo}_${planNo}_1.png`), diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 64ff13e9..9acb79f7 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -535,5 +535,6 @@ export const useEstimateController = (planNo, flag) => { handleEstimateFileDownload, handleEstimateCopy, handleDeleteEstimate, + handleEstimateImageCopy, } } diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 81d66455..52c60f80 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -55,7 +55,7 @@ export function usePlan(params = {}) { const { getMessage } = useMessage() const { get, post, promisePost, promisePut, promiseDel, promiseGet } = useAxios() - const { setEstimateContextState, handleDeleteEstimate } = useEstimateController() + const { setEstimateContextState, handleDeleteEstimate, handleEstimateImageCopy } = useEstimateController() const resetOuterLinePoints = useResetRecoilState(outerLinePointsState) const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState) @@ -79,7 +79,6 @@ export function usePlan(params = {}) { const resetCurrentObject = useResetRecoilState(currentObjectState) //선택된 모듈 배치면 초기화 const resetModuleSetupSurface = useResetRecoilState(moduleSetupSurfaceState) - const { isAllComplete } = useTrestle() /** @@ -308,6 +307,9 @@ export function usePlan(params = {}) { setModuleSelectionDataStore(copyData) if (copyData.module) setSelectedModules(copyData.module) setSelectedMenu(currentSelectedMenu) + + //이미지 복사 + handleEstimateImageCopy(planData.objectNo, planData.planNo, planData.objectNo, newPlan.planNo) } else { setSelectedMenu('placement') } From 387a1fd57713db0d19fb453740195b20d0ec4bb2 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 4 Jun 2025 08:54:00 +0900 Subject: [PATCH 23/32] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 이미지 존재 여부 확인 후 복사 진행 --- .../api/image/estimate-image-copy/route.js | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/app/api/image/estimate-image-copy/route.js b/src/app/api/image/estimate-image-copy/route.js index 16984c8c..5d8a6348 100644 --- a/src/app/api/image/estimate-image-copy/route.js +++ b/src/app/api/image/estimate-image-copy/route.js @@ -12,28 +12,29 @@ const s3 = new S3Client({ }) export async function POST(req) { - try { - const { objectNo, planNo, newObjectNo, newPlanNo } = await req.json() + const { objectNo, planNo, newObjectNo, newPlanNo } = await req.json() - const responseArray = [] + const responseArray = [] - // const isExistImage1 = await s3.send( - // new GetObjectCommand({ - // Bucket, - // Key: `Drawing/${objectNo}_${planNo}_1.png`, - // }), - // ) + //견적서1 번 이미지 + const isExistImage1 = await s3.send( + new GetObjectCommand({ + Bucket, + Key: `Drawing/${objectNo}_${planNo}_1.png`, + }), + ) - // const isExistImage2 = await s3.send( - // new GetObjectCommand({ - // Bucket, - // Key: `Drawing/${objectNo}_${planNo}_1.png`, - // }), - // ) - - // console.log('🚀 ~ isExistImage1:', isExistImage1.$metadata.httpStatusCode === 200) - // console.log('🚀 ~ isExistImage2:', isExistImage2.$metadata.httpStatusCode === 200) + //견적서2 번 이미지 + const isExistImage2 = await s3.send( + new GetObjectCommand({ + Bucket, + Key: `Drawing/${objectNo}_${planNo}_1.png`, + }), + ) + //견적서1,2 번 이미지 둘다 있어야함 + if (isExistImage1.$metadata.httpStatusCode === 200 && isExistImage2.$metadata.httpStatusCode === 200) { + //견적서1 번 이미지 복사 const copyCommand = new CopyObjectCommand({ Bucket, CopySource: encodeURI(`${Bucket}/Drawing/${objectNo}_${planNo}_1.png`), @@ -52,8 +53,7 @@ export async function POST(req) { responseArray.push(response, response2) return NextResponse.json({ message: '견적서 이미지 복사 성공', responseArray }, { status: 200 }) - } catch (error) { - console.error(error) - return NextResponse.json({ message: '견적서 이미지 복사 실패' }, { status: 500 }) + } else { + return NextResponse.json({ message: '견적서 이미지 복사 실패(존재하지 않는 이미지)', responseArray }, { status: 400 }) } } From 514545cf6526fecc1679f00aa69c3233353c2492 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 4 Jun 2025 09:03:21 +0900 Subject: [PATCH 24/32] =?UTF-8?q?=EB=B3=B5=EC=82=AC=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=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/app/api/image/estimate-image-copy/route.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/image/estimate-image-copy/route.js b/src/app/api/image/estimate-image-copy/route.js index 5d8a6348..d7c80b13 100644 --- a/src/app/api/image/estimate-image-copy/route.js +++ b/src/app/api/image/estimate-image-copy/route.js @@ -28,7 +28,7 @@ export async function POST(req) { const isExistImage2 = await s3.send( new GetObjectCommand({ Bucket, - Key: `Drawing/${objectNo}_${planNo}_1.png`, + Key: `Drawing/${objectNo}_${planNo}_2.png`, }), ) From 904b7afd3869fc8f93419b387fa63780bb80ab0e Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Jun 2025 10:35:14 +0900 Subject: [PATCH 25/32] =?UTF-8?q?#1085=20=E3=80=90HANASYS=20DESIGN?= =?UTF-8?q?=E3=80=91=E6=9E=B6=E5=8F=B0=E8=A1=A8=E7=A4=BA=E3=81=AE=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=20=EC=A7=80?= =?UTF-8?q?=EC=A7=80=EA=B8=88=EA=B5=AC=20=EC=9C=84=EC=B9=98=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/module/useTrestle.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 8a41149d..0aea8bfc 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1627,6 +1627,8 @@ export const useTrestle = () => { // 랙 없음의 지지금구를 그린다. const drawBracketWithOutRack = (module, rackIntvlPct, count, l, direction, moduleIntvlHor, moduleIntvlVer) => { const { leftFindModuleList, rightFindModuleList, centerFindModuleList } = module + rackIntvlPct = rackIntvlPct === 0 ? 1 : rackIntvlPct // 0인 경우 1로 변경 + rackIntvlPct = 100 / rackIntvlPct // 퍼센트로 변경 let { width, height, left, top } = module let startPointX @@ -1641,14 +1643,14 @@ export const useTrestle = () => { break } else if (direction === 'east') { startPointX = left + width - startPointY = top + height - height / rackIntvlPct + startPointY = top + height - height / rackIntvlPct - 10 break } else if (direction === 'west') { startPointX = left startPointY = top + height / rackIntvlPct break } else if (direction === 'north') { - startPointX = left + width - width / rackIntvlPct + startPointX = left + width - width / rackIntvlPct - 10 startPointY = top break } @@ -1657,7 +1659,7 @@ export const useTrestle = () => { case 'R': { // 오른쪽부분 시작 점 if (direction === 'south') { - startPointX = left + width - width / rackIntvlPct + startPointX = left + width - width / rackIntvlPct - 10 startPointY = top + height / 2 + height / 2 break } else if (direction === 'east') { @@ -1666,7 +1668,7 @@ export const useTrestle = () => { break } else if (direction === 'west') { startPointX = left - startPointY = top + height - height / rackIntvlPct + startPointY = top + height - height / rackIntvlPct - 10 break } else if (direction === 'north') { startPointX = left + width / rackIntvlPct From ab93c5ffe5193288d8395fb00b683fe876b163c9 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Jun 2025 11:06:28 +0900 Subject: [PATCH 26/32] =?UTF-8?q?=EC=8B=A4=EC=B8=A1=EC=B9=98=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EC=A0=84=ED=99=98=20=EC=95=88=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=ED=98=84=EC=83=81=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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 558bec36..b83d4ac4 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -1193,7 +1193,7 @@ export const usePolygon = () => { }) canvas.add(roof) - // addLengthText(roof) + addLengthText(roof) canvas.remove(polygon) canvas.renderAll() }) From bcb8a11d5a8e1448d0c34842e918a309f2ac50a2 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Jun 2025 15:45:30 +0900 Subject: [PATCH 27/32] =?UTF-8?q?zoom=EA=B0=92=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=9D=BC=20mouseLine=20=EC=95=88=EA=B7=B8=EB=A0=A4=EC=A7=80?= =?UTF-8?q?=EB=8A=94=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/hooks/useEvent.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index 9f9e4ea0..f3c6dee8 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -1,4 +1,4 @@ -import { useRef } from 'react' +import { useEffect, useRef } from 'react' import { useRecoilValue, useSetRecoilState } from 'recoil' import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom' import { fabric } from 'fabric' @@ -25,6 +25,7 @@ export function useEvent() { const setCanvasZoom = useSetRecoilState(canvasZoomState) const gridColor = useRecoilValue(gridColorState) const isGridDisplay = useRecoilValue(gridDisplaySelector) + const zoom = useRecoilValue(canvasZoomState) const { adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, getAdsorptionPoints, adsorptionPointAddModeStateEvent } = useAdsorptionPoint() const { dotLineGridSetting, interval, getClosestLineGrid } = useDotLineGrid() @@ -59,6 +60,12 @@ export function useEvent() { addDefaultEvent() } + useEffect(() => { + if (canvas) { + addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent) + } + }, [zoom]) + const addDefaultEvent = () => { //default Event 추가 addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent) @@ -280,7 +287,7 @@ export function useEvent() { } const drawMouseLine = (pointer) => { - const horizontalLine = new fabric.Line([-4 * canvas.width, pointer.y, 4 * canvas.width, pointer.y], { + const horizontalLine = new fabric.Line([-2 * canvas.width, pointer.y, 2 * canvas.width, pointer.y], { stroke: 'red', strokeWidth: 1, selectable: false, @@ -288,7 +295,7 @@ export function useEvent() { }) // 세로선 - const verticalLine = new fabric.Line([pointer.x, -4 * canvas.height, pointer.x, 4 * canvas.height], { + const verticalLine = new fabric.Line([pointer.x, -2 * canvas.height, pointer.x, 2 * canvas.height], { stroke: 'red', strokeWidth: 1, selectable: false, From 5395dff08170332b68eb891c2ebbfe50793c6664 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Jun 2025 15:52:20 +0900 Subject: [PATCH 28/32] =?UTF-8?q?=ED=95=B4=EB=8B=B9=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=EA=B0=80=20mouseMove=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EB=A5=BC=20?= =?UTF-8?q?=EA=B0=96=EA=B3=A0=20=EC=9E=88=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useEvent.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index f3c6dee8..ea941d1e 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -15,7 +15,8 @@ import { useDotLineGrid } from '@/hooks/useDotLineGrid' import { useTempGrid } from '@/hooks/useTempGrid' import { gridColorState } from '@/store/gridAtom' import { gridDisplaySelector } from '@/store/settingAtom' -import { POLYGON_TYPE } from '@/common/common' +import { MENU, POLYGON_TYPE } from '@/common/common' +import useMenu from '@/hooks/common/useMenu' export function useEvent() { const canvas = useRecoilValue(canvasState) @@ -61,7 +62,8 @@ export function useEvent() { } useEffect(() => { - if (canvas) { + const whiteMenus = [MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH, MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING] + if (canvas && !whiteMenus.includes(currentMenu)) { addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent) } }, [zoom]) From acdec6d2f2b4f1acf69fd16d1fc5b759c1767428 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Jun 2025 15:55:35 +0900 Subject: [PATCH 29/32] =?UTF-8?q?mouseMove=ED=95=B4=EB=8B=B9=20=EC=95=88?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EB=A9=94=EB=89=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useEvent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index ea941d1e..8b7b687d 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -62,7 +62,7 @@ export function useEvent() { } useEffect(() => { - const whiteMenus = [MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH, MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING] + const whiteMenus = [MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH, MENU.BATCH_CANVAS.OBJECT_BATCH, MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING] if (canvas && !whiteMenus.includes(currentMenu)) { addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent) } From 32884830c82f65e3c97b3830be20c86f42442ae1 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Jun 2025 17:21:03 +0900 Subject: [PATCH 30/32] =?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=EC=8B=9C=20=EC=84=9C=EA=B9=8C?= =?UTF-8?q?=EB=9E=98=20=EA=B0=92=20=EC=9D=B4=EC=83=81=20=ED=98=84=EC=83=81?= =?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 --- .../placementShape/PlacementShapeSetting.jsx | 4 ++-- src/hooks/option/useCanvasSetting.js | 23 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 0ac134ef..91332f43 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -227,7 +227,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla console.log('save Info', { ...basicSetting, selectedRoofMaterial: { - roofInfo, + ...newAddedRoofs[0], }, }) @@ -240,7 +240,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla * 선택된 지붕재 정보 */ selectedRoofMaterial: { - roofInfo, + ...newAddedRoofs[0], }, }) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 1c7c0e39..6d0d5acf 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -498,11 +498,26 @@ export function useCanvasSetting(executeEffect = true) { roofSeq: 0, roofMatlCd: params.roofsData.roofMatlCd === null || params.roofsData.roofMatlCd === undefined ? 'ROOF_ID_WA_53A' : params.roofsData.roofMatlCd, - roofWidth: params.roofsData.roofWidth === null || params.roofsData.roofWidth === undefined ? 0 : params.roofsData.roofWidth, - roofHeight: params.roofsData.roofHeight === null || params.roofsData.roofHeight === undefined ? 0 : params.roofsData.roofHeight, + roofWidth: + params.selectedRoofMaterial.width === null || params.selectedRoofMaterial.width === undefined + ? !params.selectedRoofMaterial.widBase + ? 0 + : params.roofsData.widBase + : params.selectedRoofMaterial.width, + roofHeight: + params.selectedRoofMaterial.height === null || params.selectedRoofMaterial.height === undefined + ? !params.selectedRoofMaterial.lenBase + ? 0 + : params.selectedRoofMaterial.lenBase + : params.roofsData.roofHeight, roofHajebichi: - params.roofsData.roofHajebichi === null || params.roofsData.roofHajebichi === undefined ? 0 : params.roofsData.roofHajebichi, - roofGap: params.roofsData.roofGap === null || params.roofsData.roofGap === undefined ? 'HEI_455' : params.roofsData.roofGap, + params.selectedRoofMaterial.hajebichi === null || params.selectedRoofMaterial.hajebichi === undefined + ? 0 + : params.selectedRoofMaterial.hajebichi, + roofGap: + params.selectedRoofMaterial.raft === null || params.selectedRoofMaterial.raft === undefined + ? params.selectedRoofMaterial.raftBaseCd + : params.roofsData.raft, roofLayout: params.roofsData.roofLayout === null || params.roofsData.roofLayout === undefined ? 'P' : params.roofsData.roofLayout, roofPitch: params.roofsData.roofPitch === null || params.roofsData.roofPitch === undefined ? 0 : params.roofsData.roofPitch, roofAngle: params.roofsData.roofAngle === null || params.roofsData.roofAngle === undefined ? 0 : params.roofsData.roofAngle, From 9d91533922c8a028d8710fe5ce5db09a97a52c31 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Jun 2025 17:31:42 +0900 Subject: [PATCH 31/32] =?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=EC=8B=9C=20=EC=84=9C=EA=B9=8C?= =?UTF-8?q?=EB=9E=98=20=EA=B0=92=20=EC=9D=B4=EC=83=81=20=ED=98=84=EC=83=81?= =?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/option/useCanvasSetting.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 6d0d5acf..db374c7f 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -502,18 +502,18 @@ export function useCanvasSetting(executeEffect = true) { params.selectedRoofMaterial.width === null || params.selectedRoofMaterial.width === undefined ? !params.selectedRoofMaterial.widBase ? 0 - : params.roofsData.widBase - : params.selectedRoofMaterial.width, + : Number(params.roofsData.widBase) + : Number(params.selectedRoofMaterial.width), roofHeight: params.selectedRoofMaterial.height === null || params.selectedRoofMaterial.height === undefined ? !params.selectedRoofMaterial.lenBase ? 0 - : params.selectedRoofMaterial.lenBase - : params.roofsData.roofHeight, + : Number(params.selectedRoofMaterial.lenBase) + : Number(params.roofsData.roofHeight), roofHajebichi: params.selectedRoofMaterial.hajebichi === null || params.selectedRoofMaterial.hajebichi === undefined ? 0 - : params.selectedRoofMaterial.hajebichi, + : Number(params.selectedRoofMaterial.hajebichi), roofGap: params.selectedRoofMaterial.raft === null || params.selectedRoofMaterial.raft === undefined ? params.selectedRoofMaterial.raftBaseCd From 31bf7529701a1ca87e4ee72b836e2acc9fb9c2d0 Mon Sep 17 00:00:00 2001 From: ysCha Date: Wed, 4 Jun 2025 19:17:53 +0900 Subject: [PATCH 32/32] selectedPlan?.planNo?? currentPid or pid --- src/components/estimate/Estimate.jsx | 2 +- src/components/floor-plan/CanvasMenu.jsx | 8 ++++---- src/components/simulator/Simulator.jsx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 9a60fd0e..e59dd9ff 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -154,7 +154,7 @@ export default function Estimate({}) { useEffect(() => { // console.log('🚀 ~ Estimate ~ selectedPlan:', selectedPlan) - if (selectedPlan) initEstimate(selectedPlan.planNo) + if (selectedPlan) initEstimate(selectedPlan?.planNo?? currentPid) }, [selectedPlan]) useEffect(() => { diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 5d2d1030..b876d517 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -241,7 +241,7 @@ export default function CanvasMenu(props) { return } setIsGlobalLoading(true) - promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { + promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan?.planNo??pid}/detail` }).then((res) => { if (res.status === 200) { const estimateDetail = res.data if (estimateDetail.estimateDate !== null) { @@ -249,7 +249,7 @@ export default function CanvasMenu(props) { setCurrentMenu(menu.title) setFloorPlanObjectNo({ floorPlanObjectNo: objectNo }) setIsGlobalLoading(false) - router.push(`/floor-plan/estimate/5?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) + router.push(`/floor-plan/estimate/5?pid=${selectedPlan?.planNo??pid}&objectNo=${objectNo}`) if (pathname === '/floor-plan/estimate/5') { setIsGlobalLoading(false) } @@ -262,13 +262,13 @@ export default function CanvasMenu(props) { break case 'simulation': setIsGlobalLoading(true) - promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { + promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan?.planNo??pid}/detail` }).then((res) => { if (res.status === 200) { const estimateDetail = res.data if (estimateDetail.estimateDate !== null && estimateDetail.docNo) { setSelectedMenu(menu.type) setCurrentMenu(menu.title) - router.push(`/floor-plan/simulator/6?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) + router.push(`/floor-plan/simulator/6?pid=${selectedPlan?.planNo??pid}&objectNo=${objectNo}`) if (pathname === '/floor-plan/simulator/6') { setIsGlobalLoading(false) } diff --git a/src/components/simulator/Simulator.jsx b/src/components/simulator/Simulator.jsx index 6683ff9e..94307e8d 100644 --- a/src/components/simulator/Simulator.jsx +++ b/src/components/simulator/Simulator.jsx @@ -114,7 +114,7 @@ export default function Simulator() { setHatsudenryouPeakcutAllSnow([]) if (objectNo && pid && selectedPlan) { - fetchObjectDetail(objectNo, selectedPlan.planNo) + fetchObjectDetail(objectNo, selectedPlan?.planNo??pid) fetchSimulatorNotice() setPwrGnrSimType('D') setPwrRecoil({ ...pwrRecoil, type: 'D' })