From c9234b264660f3be6a8e317f640f67af077c8baf Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 20 Feb 2025 16:48:21 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=93=8Cfix:=20sqlite3=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 --- package.json | 2 + qcast3.database.sqlite | Bin 0 -> 16384 bytes src/hooks/common/useRefFiles.js | 31 +++++++++++-- src/hooks/surface/useSurfaceShapeBatch.js | 36 ++++++++++++++- src/lib/imageActions.js | 54 ++++++++++++++++++++++ 5 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 qcast3.database.sqlite create mode 100644 src/lib/imageActions.js diff --git a/package.json b/package.json index c2b9e6cf..a9b977ce 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "react-responsive-modal": "^6.4.2", "react-select": "^5.8.1", "recoil": "^0.7.7", + "sqlite": "^5.1.1", + "sqlite3": "^5.1.7", "sweetalert2": "^11.14.1", "sweetalert2-react-content": "^5.0.7", "swr": "^2.3.0", diff --git a/qcast3.database.sqlite b/qcast3.database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..6e35d0d37fabdff88cd32274d68ffa283e682e54 GIT binary patch literal 16384 zcmeI(&u-H&7y$5O9WYJn#sO3bffRPy*xV+L9mm^+fhuv>0Y=B4Q)N4LSK6jsno8`* zcmiI58)qJg8&84Lb%=$-s02clKDSBZeD;?wzqE%)>B|>~-CTQSm<>ekh0blqb)Cna z=QvKyF3WaVvWq+0F8Y_P*mqs4IrZ#wb^V*ORLz|APt~m2zHSP{K>!3m00ck)1V8`; zKmY_lU?Bz08)^>@)7vZ$-(1~V^=#`V#ky$SG}j%SdFe3s(n-HR4Hp45Ovia9Y}_knX^(n8hZRFd znXM%|^LqNs6O(+{O;x4`I?Z>d!-n#mR(abVv(>@tui?p2%?f!Bxv$)7l zidmkQ>-Tx_c{zV|`}xw%+Rl#qwxH7E)4shsZIAWoM5n6Utz4lgjonJcK=0a_+xG7D z!4$kR%~?M8a)0Sc)^hYea$C^9&%KbpDkvHRKmY_l00ck)1V8`;KmY_l00cl_E`h2Y z?QVQ`>>C;gfB*=900@8p2!H?xfB*=900@A<0t?)8EBh<*j$1))`EiD|;{M-0^zUqZ zsXqJlwZNwfrGo$nfB*=900@8p2!H?xfWSW$I9|Ew+;u-Z3?stVPx5@U*JuQFOyWAm ztRApvkNCddn2h>Ek&GKOiZJ6zgnXkyLz7t@r@b6pH&-S$~lfH!d%9P*y0iAJU}GWTp49dM5k#tj-1!?R2wRybu3U4gfUeFgFPOy)Ly=HK { + const handleFileDelete = async () => { swalFire({ text: '삭제하시겠습니까?', type: 'confirm', - confirmFn: () => { + confirmFn: async () => { setRefImage(null) setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: null })) + await deleteBackGroundImage({ + objectId: currentCanvasPlan.id, + planNo: currentCanvasPlan.planNo, + }) }, }) } @@ -86,14 +91,18 @@ export function useRefFiles() { /** * 주소 삭제 */ - const handleAddressDelete = () => { + const handleAddressDelete = async () => { swalFire({ text: '삭제하시겠습니까?', type: 'confirm', - confirmFn: () => { + confirmFn: async () => { setMapPositionAddress('') setCurrentBgImage(null) setCurrentCanvasPlan((prev) => ({ ...prev, mapPositionAddress: null })) + await deleteBackGroundImage({ + objectId: currentCanvasPlan.id, + planNo: currentCanvasPlan.planNo, + }) }, }) } @@ -112,6 +121,12 @@ export function useRefFiles() { }) console.log('🚀 ~ handleMapImageDown ~ res:', res) setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`) + + await setBackGroundImage({ + objectId: currentCanvasPlan.id, + planNo: currentCanvasPlan.planNo, + imagePath: `${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`, + }) } /** @@ -145,6 +160,14 @@ export function useRefFiles() { console.log('🚀 ~ handleUploadImageRefFile ~ res:', res) setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`) setRefImage(file) + + const params = { + objectId: currentCanvasPlan.id, + planNo: currentCanvasPlan.planNo, + imagePath: `${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`, + } + console.log('🚀 ~ handleUploadImageRefFile ~ params:', params) + await setBackGroundImage(params) } /** diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 5dea9058..a2625749 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -2,7 +2,7 @@ import { useEffect } from 'react' import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' -import { canvasState, globalPitchState } from '@/store/canvasAtom' +import { canvasState, currentCanvasPlanState, globalPitchState } from '@/store/canvasAtom' import { MENU, POLYGON_TYPE } from '@/common/common' import { getIntersectionPoint } from '@/util/canvas-util' import { degreesToRadians } from '@turf/turf' @@ -19,6 +19,7 @@ import { QLine } from '@/components/fabric/QLine' import { useRoofFn } from '@/hooks/common/useRoofFn' import { outerLinePointsState } from '@/store/outerLineAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' +import { getBackGroundImage } from '@/lib/imageActions' export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const { getMessage } = useMessage() @@ -36,6 +37,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { // const { addCanvasMouseEventListener, initEvent } = useContext(EventContext) const { closePopup } = usePopup() const { setSurfaceShapePattern } = useRoofFn() + const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) const applySurfaceShape = (surfaceRefs, selectedType, id) => { let length1, length2, length3, length4, length5 @@ -711,12 +713,42 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { return points } - const deleteAllSurfacesAndObjects = () => { + const deleteAllSurfacesAndObjects = async () => { + const backgroundImage = await getBackGroundImage({ + objectId: currentCanvasPlan.id, + planNo: currentCanvasPlan.planNo, + }) + console.log('🚀 ~ deleteAllSurfacesAndObjects ~ backgroundImage:', backgroundImage) + swalFire({ text: getMessage('batch.canvas.delete.all'), type: 'confirm', confirmFn: () => { canvas.clear() + + fabric.Image.fromURL(`${backgroundImage.path}`, function (img) { + console.log('🚀 ~ img:', img) + img.set({ + left: 0, + top: 0, + width: img.width, + height: img.height, + name: 'backGroundImage', + selectable: false, + hasRotatingPoint: false, // 회전 핸들 활성화 + lockMovementX: false, + lockMovementY: false, + lockRotation: false, + lockScalingX: false, + lockScalingY: false, + }) + // image = img + canvas?.add(img) + canvas?.sendToBack(img) + canvas?.renderAll() + // setBackImg(img) + }) + resetOuterLinePoints() resetPlacementShapeDrawingPoints() swalFire({ text: getMessage('plan.message.delete') }) diff --git a/src/lib/imageActions.js b/src/lib/imageActions.js new file mode 100644 index 00000000..f3276d64 --- /dev/null +++ b/src/lib/imageActions.js @@ -0,0 +1,54 @@ +'use server' + +import sqlite3 from 'sqlite3' +import { open } from 'sqlite' + +export const setBackGroundImage = async ({ objectId, planNo, imagePath }) => { + let db = null + + if (!db) { + db = await open({ + filename: 'qcast3.database.sqlite', + driver: sqlite3.Database, + }) + } + + const fetchSql = `SELECT * FROM background_image WHERE object_id = '${objectId}' AND plan_no = '${planNo}'` + const result = await db.get(fetchSql) + if (result) { + const updateSql = `UPDATE background_image SET path = '${imagePath}' WHERE object_id = '${objectId}' AND plan_no = '${planNo}'` + await db.run(updateSql) + } else { + const insertSql = `INSERT INTO background_image (object_id, plan_no, path) VALUES ('${objectId}', '${planNo}', '${imagePath}')` + await db.run(insertSql) + } +} + +export const getBackGroundImage = async ({ objectId, planNo }) => { + let db = null + + if (!db) { + db = await open({ + filename: 'qcast3.database.sqlite', + driver: sqlite3.Database, + }) + } + + const sql = `SELECT * FROM background_image WHERE object_id = '${objectId}' AND plan_no = '${planNo}'` + const result = await db.get(sql) + return result +} + +export const deleteBackGroundImage = async ({ objectId, planNo }) => { + let db = null + + if (!db) { + db = await open({ + filename: 'qcast3.database.sqlite', + driver: sqlite3.Database, + }) + } + + const sql = `DELETE FROM background_image WHERE object_id = '${objectId}' AND plan_no = '${planNo}'` + await db.run(sql) +} From ca24b5531f41baad77976a76a76c578b51a2123a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 20 Feb 2025 16:57:29 +0900 Subject: [PATCH 2/7] =?UTF-8?q?-=20=ED=9A=8C=EB=A1=9C=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 5cc8b7ba..681a425d 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -384,7 +384,12 @@ export default function CircuitTrestleSetting({ id }) { obj.pcsItemId = null obj.circuitNumber = null }) - setSelectedModels(JSON.parse(JSON.stringify(selectedModels)).map((model) => (model.isUsed = false))) + setSelectedModels( + JSON.parse(JSON.stringify(selectedModels)).map((model) => { + model.isUsed = false + return model + }), + ) if (allocationType === ALLOCATION_TYPE.PASSIVITY) { setAllocationType(ALLOCATION_TYPE.AUTO) From f0cbceb64eb5b89ae41488459d1c737bcf945f77 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 20 Feb 2025 16:58:57 +0900 Subject: [PATCH 3/7] =?UTF-8?q?parent=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 17f58814..d7a43c67 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -710,7 +710,7 @@ export const useTrestle = () => { slope, classType: currentAngleType === 'slope' ? '0' : '1', angle: getDegreeByChon(slope), - azimuth: getAzimuth(surface), + azimuth: getAzimuth(parent), moduleList, } }) @@ -726,8 +726,9 @@ export const useTrestle = () => { return { itemList, northArrangement, roofSurfaceList, circuitItemList } } - const getAzimuth = (surface) => { - const { moduleCompass, surfaceCompass, direction } = surface + const getAzimuth = (parent) => { + debugger + const { moduleCompass, surfaceCompass, direction } = parent if (surfaceCompass) { if (surfaceCompass > 180) { From a8cbbee9b1e498ea734f66b93d3efd9f798f6dec Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 20 Feb 2025 17:02:02 +0900 Subject: [PATCH 4/7] =?UTF-8?q?debugger=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index d7a43c67..3304d180 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -727,7 +727,6 @@ export const useTrestle = () => { } const getAzimuth = (parent) => { - debugger const { moduleCompass, surfaceCompass, direction } = parent if (surfaceCompass) { From aead423eda30c7f2e9ecaee5aaa9ad6aaf1731f0 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 20 Feb 2025 17:36:29 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=ED=95=98=EB=A9=B4=20=EA=B0=95=EC=A0=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=84=A4=EC=A0=95=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qcast3.database.sqlite | Bin 16384 -> 16384 bytes src/hooks/common/useRefFiles.js | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/qcast3.database.sqlite b/qcast3.database.sqlite index 6e35d0d37fabdff88cd32274d68ffa283e682e54..c0c43e6faa95884fffddcdf0dcf1413c2e23f368 100644 GIT binary patch delta 72 zcmZo@U~Fh$oFL68HBrWyQEFqte0@gVO$Mv@8F?rB+v#dprlgn~Tc(=orkST1>zY`k c8tEn(r6lSm8k(D$n6#>3 cn(A5_rW)xcTbNrWnVOiSCMOx|738G@0LqXPkN^Mx diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index 69d38954..52f8ef47 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -6,6 +6,7 @@ import { useAxios } from '../useAxios' import { currentCanvasPlanState } from '@/store/canvasAtom' import { useCanvas } from '@/hooks/useCanvas' import { deleteBackGroundImage, setBackGroundImage } from '@/lib/imageActions' +import { settingModalFirstOptionsState } from '@/store/settingAtom' /** * 배경 이미지 관리 @@ -20,6 +21,7 @@ export function useRefFiles() { const [currentBgImage, setCurrentBgImage] = useState(null) const queryRef = useRef(null) const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) + const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const { handleBackImageLoadToCanvas } = useCanvas() const { swalFire } = useSwal() const { get, post } = useAxios() @@ -116,6 +118,16 @@ export function useRefFiles() { return } + const newOption1 = settingModalFirstOptions.option1.map((option) => ({ + ...option, + selected: option.column === 'imageDisplay' ? true : option.selected, + })) + + setSettingModalFirstOptions((prev) => ({ + ...prev, + option1: newOption1, + })) + const res = await get({ url: `${process.env.NEXT_PUBLIC_HOST_URL}/map/convert?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`, }) @@ -150,6 +162,16 @@ export function useRefFiles() { * @param {*} file */ const handleUploadImageRefFile = async (file) => { + const newOption1 = settingModalFirstOptions.option1.map((option) => ({ + ...option, + selected: option.column === 'imageDisplay' ? true : option.selected, + })) + + setSettingModalFirstOptions((prev) => ({ + ...prev, + option1: newOption1, + })) + const formData = new FormData() formData.append('file', file) From 3e16df1a873b4f086eb8c8a78de2d4e2e006aa95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 20 Feb 2025 17:41:31 +0900 Subject: [PATCH 6/7] =?UTF-8?q?-=20=EB=AA=A8=EB=93=88=20circuit=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=97=86=EC=9D=84=EB=95=8C=20=ED=9A=8C?= =?UTF-8?q?=EB=A1=9C=20=ED=95=A0=EB=8B=B9=20=EC=95=88=ED=95=98=EA=B2=8C=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/step/StepUp.jsx | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index 239487e9..f3536bc9 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -364,7 +364,7 @@ export default function StepUp(props) { // console.log('🚀 ~ handleRowClick ~ selectedData:', selectedData) // PCS 2개 이상 또는 첫번째 PCS 선택 시에만 실행 - if (stepUpListData[0].pcsItemList.length > 1 && mainIdx === 0) { + if (tempStepUpListData[0].pcsItemList.length > 1 && mainIdx === 0) { // 파워컨디셔너 옵션 조회 요청 파라미터 const params = { ...props.getOptYn(), // 옵션 Y/N @@ -442,29 +442,30 @@ export default function StepUp(props) { roofSurface.moduleList.forEach((module) => { const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0] - if (module.circuit === '') return - const moduleCircuitText = new fabric.Text(module.circuit, { - left: targetModule.left + targetModule.width / 2, - top: targetModule.top + targetModule.height / 2, - fontFamily: circuitNumberText.fontFamily.value, - fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', - fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontSize: circuitNumberText.fontSize.value, - fill: circuitNumberText.fontColor.value, - width: targetModule.width, - height: targetModule.height, - textAlign: 'center', - originX: 'center', - originY: 'center', - name: 'circuitNumber', - parentId: targetModule.id, - circuitInfo: module.pcsItemId, - visible: isDisplayCircuitNumber, - }) - targetModule.circuit = moduleCircuitText - targetModule.pcsItemId = module.pcsItemId - targetModule.circuitNumber = module.circuit - canvas.add(moduleCircuitText) + if (module.circuit !== '' && module.circuit) { + const moduleCircuitText = new fabric.Text(module.circuit, { + left: targetModule.left + targetModule.width / 2, + top: targetModule.top + targetModule.height / 2, + fontFamily: circuitNumberText.fontFamily.value, + fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', + fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontSize: circuitNumberText.fontSize.value, + fill: circuitNumberText.fontColor.value, + width: targetModule.width, + height: targetModule.height, + textAlign: 'center', + originX: 'center', + originY: 'center', + name: 'circuitNumber', + parentId: targetModule.id, + circuitInfo: module.pcsItemId, + visible: isDisplayCircuitNumber, + }) + targetModule.circuit = moduleCircuitText + targetModule.pcsItemId = module.pcsItemId + targetModule.circuitNumber = module.circuit + canvas.add(moduleCircuitText) + } }) }) From ac2159e920c03219ec906e88523ebd5577f771ea Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Thu, 20 Feb 2025 17:41:48 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=ED=99=94=EB=A9=B4=20=EB=8B=AB?= =?UTF-8?q?=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/placementShape/PlacementShapeSetting.jsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 140c9abd..05880782 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -24,7 +24,6 @@ export const ROOF_MATERIAL_LAYOUT = { export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, planNo, openPoint }) { const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) - const { closePopup } = usePopup() const { getMessage } = useMessage() const roofMaterials = useRecoilValue(roofMaterialsAtom) @@ -221,9 +220,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla

{getMessage('plan.menu.placement.surface.initial.setting')}

-