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 00000000..c0c43e6f Binary files /dev/null and b/qcast3.database.sqlite differ diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index 992c1319..52f8ef47 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -5,6 +5,8 @@ import { useSwal } from '@/hooks/useSwal' 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' /** * 배경 이미지 관리 @@ -19,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() @@ -72,13 +75,17 @@ export function useRefFiles() { /** * 파일 삭제 */ - const handleFileDelete = () => { + 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 +93,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, + }) }, }) } @@ -107,11 +118,27 @@ 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`, }) 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}`, + }) } /** @@ -135,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) @@ -145,6 +182,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 dd0ae21f..abb3688b 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' import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' import { v4 as uuidv4 } from 'uuid' @@ -38,6 +39,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { // const { addCanvasMouseEventListener, initEvent } = useContext(EventContext) const { addPopup, closePopup } = usePopup() const { setSurfaceShapePattern } = useRoofFn() + const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) const applySurfaceShape = (surfaceRefs, selectedType, id) => { let length1, length2, length3, length4, length5 @@ -719,12 +721,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) +}