diff --git a/.env.development b/.env.development index 4cc98669..f8aa1483 100644 --- a/.env.development +++ b/.env.development @@ -1,10 +1,10 @@ NEXT_PUBLIC_TEST="테스트변수입니다. development" - NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080" +NEXT_PUBLIC_API_SERVER_PATH="http://1.248.227.176:38080" # NEXT_PUBLIC_API_SERVER_PATH="http://localhost:8080" DATABASE_URL="sqlserver://mssql.devgrr.kr:1433;database=qcast;user=qcast;password=Qwertqaz12345;trustServerCertificate=true" SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" -CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" \ No newline at end of file +NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" \ No newline at end of file diff --git a/.env.production b/.env.production index 145db4d0..91d91ce1 100644 --- a/.env.production +++ b/.env.production @@ -6,4 +6,4 @@ DATABASE_URL="" SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" -CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" \ No newline at end of file +NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" \ No newline at end of file diff --git a/src/components/Playground.jsx b/src/components/Playground.jsx index 4d8007b9..2734ac8c 100644 --- a/src/components/Playground.jsx +++ b/src/components/Playground.jsx @@ -1,7 +1,7 @@ 'use client' -import { useState } from 'react' -import { Button, Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from '@nextui-org/react' +import { useRef, useState } from 'react' +import { Button } from '@nextui-org/react' import ColorPicker from './common/color-picker/ColorPicker' import { useAxios } from '@/hooks/useAxios' @@ -12,11 +12,16 @@ import { convertDwgToPng } from '@/lib/cadAction' import QSelect from '@/components/ui/QSelect' import styles from './playground.module.css' +import { useRecoilState } from 'recoil' +import { cadFileNameState, useCadFileState } from '@/store/canvasAtom' export default function Playground() { + const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) + const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) const fileRef = useRef(null) - const { get, post } = useAxios() + const { get, promisePost } = useAxios() const testVar = process.env.NEXT_PUBLIC_TEST + const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL const { getMessage } = useMessage() const [color, setColor] = useState('#ff0000') @@ -36,8 +41,16 @@ export default function Playground() { const formData = new FormData() formData.append('file', fileRef.current.files[0]) - const result = await post({ url: process.env.CONVERTER_API_URL, data: formData }) - await convertDwgToPng(result.Files[0].FileName, result.Files[0].FileData) + await promisePost({ url: converterUrl, data: formData }) + .then((res) => { + console.log('response: ', res) + convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData) + setUseCadFile(true) + setCadFileName(res.data.Files[0].FileName) + }) + .catch((err) => { + console.error(err) + }) } const data = [ diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 03749bd2..aa99b3c9 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -1,7 +1,7 @@ 'use client' import { useCanvas } from '@/hooks/useCanvas' -import { useCallback, useEffect, useRef, useState } from 'react' +import { useEffect, useRef, useState } from 'react' import { v4 as uuidv4 } from 'uuid' import { useMode } from '@/hooks/useMode' import { Mode } from '@/common/common' @@ -9,6 +9,8 @@ import { Button } from '@nextui-org/react' import RangeSlider from './ui/RangeSlider' import { useRecoilState, useRecoilValue } from 'recoil' import { + cadFileCompleteState, + cadFileNameState, canvasSizeState, compassState, currentObjectState, @@ -17,6 +19,7 @@ import { roofState, sortedPolygonArray, templateTypeState, + useCadFileState, wallState, } from '@/store/canvasAtom' import { QLine } from '@/components/fabric/QLine' @@ -38,7 +41,18 @@ import { SurfaceShapeModal } from '@/components/ui/SurfaceShape' export default function Roof2(props) { const { name, userId, email, isLoggedIn } = props - const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas') + const { + canvas, + handleRedo, + handleUndo, + setCanvasBackgroundWithDots, + saveImage, + addCanvas, + handleCadImageLoad, + handleCadImageInit, + backImg, + setBackImg, + } = useCanvas('canvas') const { get } = useAxios() @@ -84,6 +98,13 @@ export default function Roof2(props) { canvas, } + // cad 파일 업로드 + const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) + const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) + const [cadFileComplete, setCadFileComplete] = useRecoilState(cadFileCompleteState) + let imgPath + useCadFile && (imgPath = `/cadImages/${cadFileName}`) + const { mode, setMode, @@ -130,6 +151,11 @@ export default function Roof2(props) { return } changeMode(canvas, mode) + + if (!cadFileComplete && useCadFile) { + // cad 파일 로드 + useCadFile && handleCadImageLoad(imgPath, canvas) + } }, [canvas, mode]) const makeLine = () => { @@ -757,6 +783,32 @@ export default function Roof2(props) { + + diff --git a/src/hooks/useAxios.js b/src/hooks/useAxios.js index 3fa1f4f4..4c7be165 100644 --- a/src/hooks/useAxios.js +++ b/src/hooks/useAxios.js @@ -45,6 +45,10 @@ export function useAxios() { .catch(console.error) } + const promisePost = async ({ url, data }) => { + return await getInstances(url).post(url, data) + } + const put = async ({ url, data }) => { return await getInstances(url) .put(url, data) @@ -66,5 +70,5 @@ export function useAxios() { .catch(console.error) } - return { get, post, put, patch, del } + return { get, post, promisePost, put, patch, del } } diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 0dc724f3..e4902c33 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -17,6 +17,7 @@ export function useCanvas(id) { const [canvas, setCanvas] = useState() const [isLocked, setIsLocked] = useState(false) const [history, setHistory] = useState([]) + const [backImg, setBackImg] = useState() const [canvasSize] = useRecoilState(canvasSizeState) const [fontSize] = useRecoilState(fontSizeState) const { setCanvasForEvent, attachDefaultEventOnCanvas } = useCanvasEvent() @@ -444,6 +445,30 @@ export function useCanvas(id) { // }, 1000) } + /** + * cad 파일 사용시 이미지 로딩 함수 + */ + const handleCadImageLoad = (url) => { + console.log('image load url: ', url) + + fabric.Image.fromURL(url, function (img) { + img.set({ + left: 0, + top: 0, + width: 1500, + height: 1500, + selectable: true, + }) + canvas.add(img) + canvas.renderAll() + setBackImg(img) + }) + } + + const handleCadImageInit = () => { + canvas.clear() + } + return { canvas, addShape, @@ -459,5 +484,9 @@ export function useCanvas(id) { setCanvasBackgroundWithDots, addCanvas, removeMouseLines, + handleCadImageLoad, + handleCadImageInit, + backImg, + setBackImg, } } diff --git a/src/lib/cadAction.js b/src/lib/cadAction.js index be69fecb..05bc878a 100644 --- a/src/lib/cadAction.js +++ b/src/lib/cadAction.js @@ -1,13 +1,18 @@ +'use server' + +import fs from 'fs/promises' + +const imageSavePath = 'public/cadImages' + const convertDwgToPng = async (fileName, data) => { console.log('fileName', fileName) - const imagePath = 'public/cad-images' try { - await fs.readdir(imagePath) + await fs.readdir(imageSavePath) } catch { - await fs.mkdir(imagePath) + await fs.mkdir(imageSavePath) } - return fs.writeFile(`${imagePath}/${fileName}`, data, 'base64') + return await fs.writeFile(`${imageSavePath}/${fileName}`, data, 'base64') } export { convertDwgToPng } diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js index ed90c2e7..f2bbfa3a 100644 --- a/src/store/canvasAtom.js +++ b/src/store/canvasAtom.js @@ -126,3 +126,21 @@ export const customSettingsState = atom({ default: {}, dangerouslyAllowMutability: true, }) + +// cad 도면 파일 사용 여부 +export const useCadFileState = atom({ + key: 'useCadFile', + default: false, +}) + +// cad 도면 파일 이름 +export const cadFileNameState = atom({ + key: 'cadFileName', + default: '', +}) + +// cad 도면 파일 조정 완료 +export const cadFileCompleteState = atom({ + key: 'cadFileComplete', + default: false, +})