diff --git a/src/app/floor-plan/FloorPlanProvider.js b/src/app/floor-plan/FloorPlanProvider.js index ba2a8226..37399ddd 100644 --- a/src/app/floor-plan/FloorPlanProvider.js +++ b/src/app/floor-plan/FloorPlanProvider.js @@ -2,8 +2,6 @@ import { correntObjectNoState } from '@/store/settingAtom' import { notFound, usePathname, useSearchParams } from 'next/navigation' -// import { ErrorBoundary } from 'next/dist/client/components/error-boundary' -// import ServerError from '../error' import { createContext, useReducer, useState } from 'react' import { useSetRecoilState } from 'recoil' diff --git a/src/app/floor-plan/layout.js b/src/app/floor-plan/layout.js index 2a6fb8fd..19c730cf 100644 --- a/src/app/floor-plan/layout.js +++ b/src/app/floor-plan/layout.js @@ -3,15 +3,23 @@ import FloorPlanProvider from './FloorPlanProvider' import FloorPlan from '@/components/floor-plan/FloorPlan' import CanvasLayout from '@/components/floor-plan/CanvasLayout' +import { usePathname } from 'next/navigation' export default function FloorPlanLayout({ children }) { console.log('๐Ÿš€ ~ FloorPlanLayout ~ FloorPlanLayout:') + const pathname = usePathname() + console.log('๐Ÿš€ ~ FloorPlanLayout ~ pathname:', pathname) return ( <> - {children} + {pathname.includes('estimate') || pathname.includes('simulator') ? ( +
{children}
+ ) : ( + {children} + )} + {/* {children} */}
diff --git a/src/app/management/stuff/tempReg/page.jsx b/src/app/management/stuff/tempReg/page.jsx new file mode 100644 index 00000000..ce7e684a --- /dev/null +++ b/src/app/management/stuff/tempReg/page.jsx @@ -0,0 +1,18 @@ +import React from 'react' +import StuffSubHeader from '@/components/management/StuffSubHeader' +import '@/styles/contents.scss' +import StuffDetail from '@/components/management/StuffDetail' +export default function ManagementStuffRegPage() { + return ( + <> + +
+
+
+ +
+
+
+ + ) +} diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index a14622f7..88ae05fe 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1,7 +1,7 @@ 'use client' import { useEffect, useState, useContext } from 'react' -import { useRecoilValue } from 'recoil' +import { useRecoilValue, useSetRecoilState } from 'recoil' import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { useMessage } from '@/hooks/useMessage' import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' @@ -9,7 +9,7 @@ import SingleDatePicker from '../common/datepicker/SingleDatePicker' import EstimateFileUploader from './EstimateFileUploader' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' -import { isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' +import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' import dayjs from 'dayjs' import { useCommonCode } from '@/hooks/common/useCommonCode' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' @@ -18,6 +18,8 @@ import Select, { components } from 'react-select' import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils' import ProductFeaturesPop from './popup/ProductFeaturesPop' import { v4 as uuidv4 } from 'uuid' +import { correntObjectNoState } from '@/store/settingAtom' +import { useSearchParams } from 'next/navigation' export default function Estimate({ params }) { const [uniqueData, setUniqueData] = useState([]) @@ -74,6 +76,15 @@ export default function Estimate({ params }) { const { setMenuNumber } = useCanvasMenu() + /** + * objectNo ์…‹ํŒ… + * url๋กœ ๋„˜์–ด์˜จ objectNo์„ ๋ฆฌ์ฝ”์ผ์— ์„ธํŒ… + */ + const setCurrentObjectNo = useSetRecoilState(correntObjectNoState) + const searchParams = useSearchParams() + const currentObjectNo = searchParams.get('objectNo') + setCurrentObjectNo(currentObjectNo) + //์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ ์ฒจ๋ถ€ํŒŒ์ผ props const fileUploadProps = { uploadFiles: files, @@ -120,7 +131,6 @@ export default function Estimate({ params }) { let url = `/api/estimate/special-note-title-list` get({ url: url }).then((res) => { if (isNotEmptyArray(res)) { - //๋””ํ…Œ์ผ ATTR001ใ€ATTR002ใ€ATTR003ใ€ATTR007ใ€ATTR009ใ€ATTR010ใ€ATTR015ใ€ATTR019 if (estimateContextState?.estimateOption) { res.map((row) => { let estimateOption = estimateContextState?.estimateOption?.split('ใ€') @@ -140,10 +150,10 @@ export default function Estimate({ params }) { //detail๊ณผ ์ƒ๊ด€์—†์ด ๋””ํดํŠธ ์ฒดํฌ๋ชฉ๋ก //ATTR003,ATTR007 if (row.code === 'ATTR003') { - row.check = true + //row.check = true } if (row.code === 'ATTR007') { - row.check = true + //row.check = true } }) @@ -191,9 +201,8 @@ export default function Estimate({ params }) { }, [specialNoteList]) // ๊ฒฌ์ ํŠน์ด์‚ฌํ•ญ remark ๋ณด์—ฌ์ฃผ๊ธฐ - const settingShowContent = (code, event) => { + const settingShowContent = (code) => { setShowContentCode(code) - event.stopPropagation() } // ์ถ”๊ฐ€ํ•œ ์ฒจ๋ถ€ํŒŒ์ผ estimateContextState์— ๋„ฃ๊ธฐ @@ -203,49 +212,62 @@ export default function Estimate({ params }) { files.map((row) => { fileList.push(row.data) setEstimateContextState({ fileList: row.data, newFileList: fileList }) + // setEstimateContextState({ fileList: row.data }) }) } else { - setEstimateContextState({ fileList: [] }) + setEstimateContextState({ fileList: [], newFileList: [] }) } }, [files]) - useEffect(() => { - if (originFiles.length > 0) { - setEstimateContextState({ - originFiles: originFiles, - }) - } - }, [originFiles]) - //์ƒ์„ธ์—์„œ ๋‚ด๋ ค์˜จ ์ฒจ๋ถ€ํŒŒ์ผ set ๋งŒ๋“ค๊ธฐ useEffect(() => { if (isNotEmptyArray(estimateContextState.fileList)) { //๋“œ๋ž˜๊ทธ์˜์—ญ ๋น„์›Œ์ฃผ๊ธฐ setFiles([]) setOriginFiles(estimateContextState.fileList) + } else { + if (originFiles.length > 0) { + if (isEmptyArray(files)) { + let file + file = originFiles.filter((item) => item.delFlg === '0') + setEstimateContextState({ + originFiles: file, + }) + setOriginFiles(file) + } + } } }, [estimateContextState?.fileList]) + // ์‚ญ์ œ๋ˆ„๋ฅธ ์ฒจ๋ถ€ํŒŒ์ผ ๋ณต์› + const returnOriginFile = (no) => { + originFiles.map((file) => { + if (file.no === no) { + file.delFlg = '0' + } + }) + setOriginFiles((prev) => { + return [...prev] + }) + setEstimateContextState({ + originFiles: originFiles, + }) + } // ๊ธฐ์กด์ฒจ๋ถ€ํŒŒ์ผ ์‚ญ์ œ (ํ”Œ๋ž˜๊ทธ๊ฐ’ ์ถ”๊ฐ€?) ์ €์žฅํ• ๋•Œ ํ”Œ๋ž˜๊ทธ๊ฐ’์— ๋”ฐ๋ผ ์ง„์งœ ์‚ญ์ œ - const deleteOriginFile = async (objectNo, no) => { - const delParams = { - userId: session.userId, - objectNo: objectNo, - no: no, - } - alert(getMessage('estimate.detail.alert.delFile')) - // await promisePost({ url: 'api/file/fileDelete', data: delParams }).then((res) => { - // if (res.status === 204) { - // setOriginFiles(originFiles.filter((file) => file.objectNo === objectNo && file.no !== no)) - // setEstimateContextState({ - // fileList: originFiles.filter((file) => file.objectNo === objectNo && file.no !== no), - // originFiles: originFiles.filter((file) => file.objectNo === objectNo && file.no !== no), - // newFileList: originFiles.filter((file) => file.objectNo === objectNo && file.no !== no), - // }) + const deleteOriginFile = (no) => { + originFiles.map((file) => { + if (file.no === no) { + file.delFlg = '1' + } + }) - // alert(getMessage('plan.message.delete')) - // } - // }) + setOriginFiles((prev) => { + return [...prev] + }) + setEstimateContextState({ + originFiles: originFiles, + }) + alert(getMessage('estimate.detail.alert.delFile')) } //๊ฐ€๊ฒฉํ‘œ์‹œ option ๋ชฉ๋ก ์ตœ์ดˆ์„ธํŒ… && ์ฃผ๋ฌธ๋ถ„๋ฅ˜ ๋ณ€๊ฒฝ์‹œ @@ -408,24 +430,26 @@ export default function Estimate({ params }) { if (isNotEmptyArray(data.data2)) { estimateContextState.itemList.map((item) => { let checkYn = false - data.data2.map((item2) => { - if (item2) { - if (item2.itemId === item.itemId) { + for (let i = 0; i < data.data2.length; i++) { + if (data.data2[i]) { + if (data.data2[i].itemId === item.itemId) { updateList.push({ ...item, - openFlg: item2.unitPrice === '0.0' ? '1' : '0', - salePrice: item2.unitPrice === null ? '0' : item2.unitPrice, - saleTotPrice: (item.amount * item2.unitPrice).toString(), + openFlg: data.data2[i].unitPrice === '0.0' ? '1' : '0', + salePrice: data.data2[i].unitPrice === null ? '0' : data.data2[i].unitPrice, + saleTotPrice: (item.amount * data.data2[i].unitPrice).toString(), }) checkYn = true + break } } - }) + } if (!checkYn) { updateList.push({ ...item, salePrice: '0', saleTotPrice: '0' }) } }) + setEstimateContextState({ priceCd: showPriceCd, itemList: updateList, @@ -472,7 +496,7 @@ export default function Estimate({ params }) { //์ฃผํƒPKG input ๋ณ€๊ฒฝ const onChangePkgAsp = (value) => { if (estimateContextState.estimateType === 'YJSS') { - let pkgAsp = Number(value.replace(/[^0-9]/g, '').replaceAll(',', '')) + let pkgAsp = Number(value.replace(/[^-\.0-9]/g, '').replaceAll(',', '')) if (isNaN(pkgAsp)) { pkgAsp = 0 } else { @@ -485,7 +509,7 @@ export default function Estimate({ params }) { setEstimateContextState({ pkgAsp: pkgAsp, - pkgTotPrice: pkgTotPrice.toFixed(3), + pkgTotPrice: pkgTotPrice.toFixed(2), }) //์•„์ดํ…œ๋“ค ์ค‘ ์กฐ๊ฑด์— ๋งž๋Š”์• ๋“ค ๋ฝ‘์•„์„œ ์ƒ๋‹จ ๊ณต๊ธ‰๊ฐ€์•ก ๋ถ€๊ฐ€์„ธ ์ด์•ก ์ˆ˜์ • setItemChangeYn(true) @@ -496,6 +520,7 @@ export default function Estimate({ params }) { const onChangeAmount = (value, dispOrder, index) => { //itemChangeFlg = 1, partAdd = 0 ์…‹ํŒ… let amount = Number(value.replace(/[^0-9]/g, '').replaceAll(',', '')) + if (isNaN(amount)) { amount = '0' } else { @@ -584,14 +609,12 @@ export default function Estimate({ params }) { updates.pkgMaterialFlg = res.pkgMaterialFlg updates.pnowW = res.pnowW updates.salePrice = res.salePrice - // updates.salePrice = '' updates.specification = res.specification updates.unit = res.unit updates.specialNoteCd = res.spnAttrCds updates.itemGroup = res.itemGroup updates.delFlg = '0' // ์‚ญ์ œํ”Œ๋ž˜๊ทธ 0 updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString() - // updates.saleTotPrice = '' updates.amount = '' updates.openFlg = res.openFlg @@ -622,7 +645,6 @@ export default function Estimate({ params }) { } } } else if (item.paDispOrder === dispOrder) { - //๋ด„์ œํ’ˆ์„ ๋ฐ”๊ฟจ์„๋–„ return { ...item, delFlg: '1' } } else { return item @@ -639,12 +661,14 @@ export default function Estimate({ params }) { bomItem.salePrice = '0' bomItem.saleTotPrice = '0' bomItem.unitPrice = '0' + bomItem.showSalePrice = '0' } else { bomItem.dispOrder = (index + 1 + Number(dispOrder)).toString() bomItem.paDispOrder = dispOrder bomItem.salePrice = '0' bomItem.saleTotPrice = '0' bomItem.unitPrice = '0' + bomItem.showSalePrice = '0' } bomItem.delFlg = '0' @@ -653,6 +677,7 @@ export default function Estimate({ params }) { bomItem.addFlg = true //๋ด„ ์ถ”๊ฐ€์‹œ๋„ addFlg }) + updateList = updateList.filter((item) => item.delFlg === '0') setEstimateContextState({ itemList: [...updateList, ...bomList], }) @@ -729,15 +754,24 @@ export default function Estimate({ params }) { delete item.showSaleTotPrice if (item.delFlg === '0') { let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 - let price = Number(item.saleTotPrice?.replaceAll(',', '')) || 0 + let price + if (amount === 0) { + price = 0 + } else { + price = Number(item.saleTotPrice?.replaceAll(',', '')) || 0 + } if (item.moduleFlg === '1') { const volKw = (item.pnowW * amount) / 1000 totals.totVolKw += volKw } - totals.totAmount += amount totals.supplyPrice += price + totals.totAmount += amount + if (item.paDispOrder) { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } if (item.openFlg === '1') { item.showSalePrice = '0' item.showSaleTotPrice = '0' @@ -755,12 +789,16 @@ export default function Estimate({ params }) { itemList.forEach((item) => { if (item.delFlg === '0') { let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 - let salePrice = Number(item.salePrice?.replaceAll(',', '')) || 0 - + let salePrice if (item.moduleFlg === '1') { const volKw = (item.pnowW * amount) / 1000 totals.totVolKw += volKw } + if (amount === 0) { + salePrice = 0 + } else { + salePrice = Number(item.salePrice?.replaceAll(',', '')) || 0 + } totals.totAmount += amount if (item.pkgMaterialFlg === '1') { @@ -773,6 +811,14 @@ export default function Estimate({ params }) { item.showSalePrice = '0' item.showSaleTotPrice = '0' } + } else { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + + if (item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' } } }) @@ -782,25 +828,24 @@ export default function Estimate({ params }) { totals.vatPrice = totals.supplyPrice * 0.1 totals.totPrice = totals.supplyPrice + totals.vatPrice } - if (estimateContextState.estimateType === 'YJOD') { calculateYJODTotals(estimateContextState.itemList) setEstimateContextState({ totAmount: totals.totAmount, - totVolKw: totals.totVolKw.toFixed(3), - supplyPrice: totals.supplyPrice.toFixed(3), - vatPrice: totals.vatPrice.toFixed(3), - totPrice: totals.totPrice.toFixed(3), + totVolKw: totals.totVolKw.toFixed(2), + supplyPrice: totals.supplyPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + vatPrice: totals.vatPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + totPrice: totals.totPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ }) } else if (estimateContextState.estimateType === 'YJSS') { calculateYJSSTotals(estimateContextState.itemList) setEstimateContextState({ pkgTotPrice: totals.pkgTotPrice, totAmount: totals.totAmount, - totVolKw: totals.totVolKw.toFixed(3), - supplyPrice: totals.supplyPrice.toFixed(3), - vatPrice: totals.vatPrice.toFixed(3), - totPrice: totals.totPrice.toFixed(3), + totVolKw: totals.totVolKw.toFixed(2), + supplyPrice: totals.supplyPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + vatPrice: totals.vatPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ + totPrice: totals.totPrice.toFixed(0), //์†Œ์ˆ˜์ฒซ์ž๋ฆฌ์—์„œ ๋ฐ˜์˜ฌ๋ฆผ }) } @@ -1014,16 +1059,14 @@ export default function Estimate({ params }) { let constructSpecificationMulti = estimateContextState?.constructSpecificationMulti?.split('ใ€') return ( - <> -
-
- -
-
- -
+
+
+
- +
+ +
+
) })} @@ -1110,18 +1153,38 @@ export default function Estimate({ params }) {
{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')} - {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 3)} + {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)} {getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')} {convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)} @@ -1292,14 +1375,19 @@ export default function Estimate({ params }) {
{session?.storeLvl === '1' ? ( ) : ( { onChangeSalePrice(e.target.value, item.dispOrder, index) @@ -1501,7 +1591,15 @@ export default function Estimate({ params }) {
- {convertNumberToPriceDecimal(item?.showSaleTotPrice === '0' ? null : item?.saleTotPrice?.replaceAll(',', ''))} + {convertNumberToPriceDecimal( + item?.showSaleTotPrice === '0' + ? null + : item?.amount === '' + ? null + : item?.saleTotPrice === '0' + ? null + : item?.saleTotPrice?.replaceAll(',', ''), + )} ) diff --git a/src/components/estimate/popup/ProductFeaturesPop.jsx b/src/components/estimate/popup/ProductFeaturesPop.jsx index 5b1af6aa..f2d98800 100644 --- a/src/components/estimate/popup/ProductFeaturesPop.jsx +++ b/src/components/estimate/popup/ProductFeaturesPop.jsx @@ -40,9 +40,8 @@ export default function ProductFeaturesPop({ popShowSpecialNoteList, showProduct {showSpecialNoteList.length > 0 && showSpecialNoteList.map((row) => { return ( -
+
{row.codeNm}
- {/*
*/}
) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index ed9257a4..5ed215f9 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -318,11 +318,11 @@ export default function CanvasMenu(props) {
{estimateRecoilState?.docNo !== null && (sessionState.storeId === 'T01' || sessionState.storeLvl === '1') && ( @@ -342,9 +342,13 @@ export default function CanvasMenu(props) { }} > - {getMessage('plan.menu.estimate.copy')} + {getMessage('plan.menu.estimate.copy')} )} +
)} diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index af5d9037..ea46bd3b 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -20,7 +20,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { const orientationRef = useRef(null) const { initEvent } = useEvent() // const { initEvent } = useContext(EventContext) - const { makeModuleInstArea, manualModuleSetup, autoModuleSetup } = useModuleBasicSetting() + const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup } = useModuleBasicSetting() const handleBtnNextStep = () => { if (tabNum === 1) { orientationRef.current.handleNextStep() @@ -28,20 +28,16 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { setTabNum(tabNum + 1) } - useEffect(() => { - makeModuleInstArea() //๊ธฐ๋ถ• ๋ชจ๋“ˆ์„ค์น˜๋ฉด ์ƒ์„ฑ - - return () => { - initEvent() //๋ชจ๋“ˆ์„ค์น˜๋ฉด ์„ ํƒ ์ด๋ฒคํŠธ ์‚ญ์ œ - } - }, []) - const placementRef = { isChidori: useRef('false'), setupLocation: useRef('center'), isMaxSetup: useRef('false'), } + const placementFlatRef = { + setupLocation: useRef('south'), + } + return (
@@ -66,7 +62,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { {/*๋ฐฐ์น˜๋ฉด ์ดˆ๊ธฐ์„ค์ • - ์ž…๋ ฅ๋ฐฉ๋ฒ•: ์œก์ง€๋ถ•*/} {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 2 && } - {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 3 && } + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet == 3 && tabNum === 3 && ( + + )}
{tabNum !== 1 && ( @@ -80,14 +78,29 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { Next )} + {tabNum === 3 && ( <> - - + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet != 3 && ( + <> + + + + )} + {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet === 3 && ( + <> + + + + )} )}
diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 13c48a08..a087f3dc 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -1,5 +1,6 @@ +import { forwardRef, useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' -import { forwardRef, useState } from 'react' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' const Placement = forwardRef((props, refs) => { const { getMessage } = useMessage() @@ -7,6 +8,12 @@ const Placement = forwardRef((props, refs) => { const [setupLocation, setSetupLocation] = useState('center') const [isMaxSetup, setIsMaxSetup] = useState('false') + const { makeModuleInstArea } = useModuleBasicSetting() + + useEffect(() => { + makeModuleInstArea() + }, []) + const moduleData = { header: [ { type: 'check', name: '', prop: 'check', width: 70 }, diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx index a2dcd556..7b00478e 100644 --- a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx @@ -1,7 +1,26 @@ +import { forwardRef, useState, useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' +import { compasDegAtom } from '@/store/orientationAtom' +import { canvasState } from '@/store/canvasAtom' +import { useRecoilValue } from 'recoil' +import { POLYGON_TYPE } from '@/common/common' -export default function PitchPlacement() { +const PitchPlacement = forwardRef((props, refs) => { const { getMessage } = useMessage() + const [setupLocation, setSetupLocation] = useState('south') + const { makeModuleInstArea } = useModuleBasicSetting() + const compasDeg = useRecoilValue(compasDegAtom) + const canvas = useRecoilValue(canvasState) + + useEffect(() => { + makeModuleInstArea() + }, []) + + useEffect(() => { + handleChangeSetupLocation() + }, [setupLocation]) + const moduleData = { header: [ { type: 'check', name: '', prop: 'check', width: 70 }, @@ -24,6 +43,45 @@ export default function PitchPlacement() { }, ], } + + const handleSetupLocation = (e) => { + refs.setupLocation.current = e.target + setSetupLocation(e.target.value) + } + + const handleChangeSetupLocation = () => { + if (setupLocation === 'south') { + canvas.getObjects().forEach((obj) => obj.name === 'flatExcretaLine' && canvas.remove(obj)) + return null + } else { + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //๋ชจ๋“ˆ์„ค์น˜๋ฉด๋ฅผ ๊ฐ€์ ธ์˜ด + moduleSetupSurfaces.forEach((surface, index) => { + console.log(`surface ${index} : `, surface) + + const excretaLine = surface.lines + + excretaLine.forEach((line) => { + line.set({ + stroke: '#642EFB', + strokeWidth: 5, + surfaceId: surface.surfaceId, + name: 'flatExcretaLine', + }) + canvas.add(line) + + line.on('selected', () => { + excretaLine.forEach((obj) => obj.set({ stroke: '#642EFB', isSelected: false })) + if (!line.isSelected) { + line.set({ stroke: 'red', isSelected: true }) + } else { + line.set({ stroke: '#642EFB', isSelected: false }) + } + }) + }) + }) + } + } + return ( <>
@@ -88,11 +146,26 @@ export default function PitchPlacement() {
- +
- +
@@ -102,4 +175,6 @@ export default function PitchPlacement() {
) -} +}) + +export default PitchPlacement diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 26d6f1b9..1ce18a85 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -1,113 +1,26 @@ import { useEffect, useState } from 'react' -import { useRecoilState } from 'recoil' - -import { canvasSettingState } from '@/store/canvasAtom' -import { basicSettingState } from '@/store/settingAtom' import { useMessage } from '@/hooks/useMessage' -import { useAxios } from '@/hooks/useAxios' -import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' import SizeGuide from '@/components/floor-plan/modal/placementShape/SizeGuide' import MaterialGuide from '@/components/floor-plan/modal/placementShape/MaterialGuide' import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' + export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) { - const [objectNo, setObjectNo] = useState('test123241008001') // ํ›„์— ์‚ญ์ œ ํ•„์š” const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) - const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(1) - const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) const { closePopup } = usePopup() - const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) - const { getMessage } = useMessage() - const { get, post } = useAxios() - const { swalFire } = useSwal() + + const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting() // ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์ดˆ ํ•œ ๋ฒˆ๋งŒ ์กฐํšŒ useEffect(() => { - console.log('PlacementShapeSetting useEffect ์‹คํ–‰') - - fetchSettings() - }, [objectNo]) - - // PlacementShapeSetting ์กฐํšŒ ๋ฐ ์ดˆ๊ธฐํ™” - const fetchSettings = async () => { - try { - await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${objectNo}` }).then((res) => { - if (res.length == 0) return - - // 'roofs' ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ - const roofsRow = res.map((item) => { - return { - roofSizeSet: item.roofSizeSet, - roofAngleSet: item.roofAngleSet, - } - }) - - const roofsArray = res.some((item) => !item.roofSeq) - ? //์ตœ์ดˆ ์ง€๋ถ•์žฌ ์ถ”๊ฐ€ ์ •๋ณด์˜ ๊ฒฝ์šฐ roofsArray๋ฅผ ์ดˆ๊ธฐํ™” ์„ค์ • - res.map(() => ({ - roofApply: true, - roofSeq: 1, - roofType: 1, - roofWidth: 200, - roofHeight: 200, - roofHajebichi: 200, - roofGap: 0, - roofLayout: 'parallel', - })) - : res.map((item) => ({ - roofApply: item.roofApply === '' || item.roofApply === false ? false : true, - roofSeq: item.roofSeq, - roofType: item.roofType, - roofWidth: item.roofWidth, - roofHeight: item.roofHeight, - roofHajebichi: item.roofHajebichi, - roofGap: item.roofGap, - roofLayout: item.roofLayout, - })) - console.log('roofsArray ', roofsArray) - // ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ 'roofs' ๋ฐฐ์—ด์„ patternData์— ๋„ฃ์Œ - const patternData = { - roofSizeSet: roofsRow[0].roofSizeSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ - roofAngleSet: roofsRow[0].roofAngleSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ - roofs: roofsArray, // ๋งŒ๋“ค์–ด์ง„ roofs ๋ฐฐ์—ด - } - - // ๋ฐ์ดํ„ฐ ์„ค์ • - setBasicSettings({ ...patternData }) - }) - } catch (error) { - console.error('Data fetching error:', error) - } - - if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { - setBasicSettings({ ...canvasSetting }) - } - } - - const submitCanvasConfig = async () => { - try { - const patternData = { - objectNo, - roofSizeSet: basicSetting.roofSizeSet, - roofAngleSet: basicSetting.roofAngleSet, - roofMaterialsAddList: basicSetting.roofs, - } - - await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { - swalFire({ text: getMessage(res.returnMessage) }) - }) - - //Recoil ์„ค์ • - setCanvasSetting({ ...basicSetting }) - } catch (error) { - swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) - } - } + fetchBasicSettings() + }, []) // Function to update the roofType and corresponding values const handleRoofTypeChange = (index, value) => { @@ -122,7 +35,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set roofWidth: 265, roofHeight: 235, roofGap: 455, - hajebichi: 0, + roofHajebichi: 0, } } else if (roofType === 2) { updatedRoofs[index] = { @@ -490,7 +403,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
-
diff --git a/src/components/floor-plan/modal/placementShape/SizeGuide.jsx b/src/components/floor-plan/modal/placementShape/SizeGuide.jsx index 1f9d2770..fff7dbe8 100644 --- a/src/components/floor-plan/modal/placementShape/SizeGuide.jsx +++ b/src/components/floor-plan/modal/placementShape/SizeGuide.jsx @@ -14,7 +14,7 @@ export default function SizeGuide({ setShowSizeGuidModal }) {
- + diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 2674936c..4776b0ff 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -96,7 +96,8 @@ export default function Header(props) { name: 'header.menus.management', url: '', children: [ - { id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempdetail', children: [] }, + // { id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempdetail', children: [] }, + { id: 3, name: 'header.menus.management.newStuff', url: '/management/stuff/tempReg', children: [] }, { id: 4, name: 'header.menus.management.stuffList', url: '/management/stuff', children: [] }, ], }, @@ -154,7 +155,9 @@ export default function Header(props) { onMouseEnter={(e) => ToggleonMouse(e, 'add', 'li > ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')} > - {getMessage(m.name)} + + {getMessage(m.name)} + ) })} diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx index e45cfd33..3cb668cc 100644 --- a/src/components/main/MainContents.jsx +++ b/src/components/main/MainContents.jsx @@ -128,9 +128,9 @@ export default function MainContents() { className="recently-item" onClick={() => { if (row.tempFlg === '0') { - router.push(`/management/stuff/detail?objectNo=${row.objectNo.toString()}`) + router.push(`/management/stuff/detail?objectNo=${row.objectNo.toString()}`, { scroll: false }) } else { - router.push(`/management/stuff/tempdetail?objectNo=${row.objectNo.toString()}`) + router.push(`/management/stuff/tempdetail?objectNo=${row.objectNo.toString()}`, { scroll: false }) } }} > diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 231ce94c..190e0754 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -75,7 +75,7 @@ export default function StuffDetail() { installHeight: '', //์„ค์น˜๋†’์ด conType: '0', //๊ณ„์•ฝ์กฐ๊ฑด(์ž‰์—ฌ / ์ „๋Ÿ‰) remarks: '', //๋ฉ”๋ชจ - tempFlag: 'T', //์ž„์‹œ์ €์žฅ(1) ์ €์žฅ(0) + tempFlg: 'T', //์ž„์‹œ์ €์žฅ(1) ์ €์žฅ(0) } const { register, setValue, getValues, handleSubmit, resetField, control, watch } = useForm({ defaultValues: formInitValue, @@ -108,7 +108,6 @@ export default function StuffDetail() { const [editMode, setEditMode] = useState('NEW') const { managementState, setManagementState } = useContext(ManagementContext) - const [planGridProps, setPlanGridProps] = useState({ planGridData: [], isPageable: false, @@ -135,6 +134,7 @@ export default function StuffDetail() { field: 'moduleModel', headerName: getMessage('stuff.detail.planGridHeader.moduleModel'), flex: 1, + wrapText: true, cellStyle: { justifyContent: 'flex-start' /* ์ขŒ์ธก์ •๋ ฌ*/ }, }, { @@ -283,6 +283,7 @@ export default function StuffDetail() { {getMessage('stuff.detail.planGrid.btn1')} diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index f59ed69e..708471ce 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -3,7 +3,7 @@ import { useContext, useEffect, useReducer, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { globalLocaleStore } from '@/store/localeAtom' import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom' -import { isObjectNotEmpty } from '@/util/common-utils' +import { isObjectNotEmpty, isEmptyArray, isNotEmptyArray } from '@/util/common-utils' import { SessionContext } from '@/app/SessionProvider' import { useMessage } from '@/hooks/useMessage' import { useRouter } from 'next/navigation' @@ -18,6 +18,9 @@ const updateItemInList = (itemList, dispOrder, updates) => { } export const useEstimateController = (planNo) => { + const [fileList, setFileList] = useState([]) + const [deleteFileList, setDeleteFileList] = useState([]) + const router = useRouter() const { session } = useContext(SessionContext) const globalLocaleState = useRecoilValue(globalLocaleStore) @@ -39,6 +42,12 @@ export const useEstimateController = (planNo) => { } }, []) + useEffect(() => { + if (fileList.length > 0) { + realSave(fileList) + } + }, [fileList]) + // ์ƒ์„ธ ์กฐํšŒ const fetchSetting = async (objectNo, planNo) => { try { @@ -50,6 +59,7 @@ export const useEstimateController = (planNo) => { item.delFlg = '0' }) } + setEstimateContextState(res.data) } } @@ -146,19 +156,22 @@ export const useEstimateController = (planNo) => { return alert(getMessage('estimate.detail.save.requiredEstimateDate')) } - //์ฒจ๋ถ€ํŒŒ์ผ์„ ์ฒจ๋ถ€์•ˆํ–ˆ๋Š”๋ฐ - //์•„์ดํ…œ fileUploadFlg๊ฐ€1(์ฒจ๋ถ€ํŒŒ์ผ ํ•„์ˆ˜)์ด 1๊ฐœ๋ผ๋„ ์žˆ๋Š”๋ฐ ํ›„์ผ ์ž๋ฃŒ ์ œ์ถœ(fileFlg) ์ฒดํฌ์•ˆํ–ˆ์œผ๋ฉด(0) alert ์ €์žฅ์•ˆ๋ผ - console.log('์ƒˆ๋กœ์ถ”๊ฐ€์ฒจ๋ถ€ํŒŒ์ผ:::', estimateData.newFileList) - console.log('๊ธฐ์กด์ฒจ๋ถ€ํŒŒ์ผ:::', estimateData.originFiles) - - // return - + //๊ธฐ์กด์— ์ฒจ๋ถ€๋œ ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด ํŒŒ์ผ์ฒจ๋ถ€๊ด€๋ จ ํ†ต๊ณผ if (estimateData?.originFiles?.length > 0) { - originFileFlg = true + let cnt = estimateData.originFiles.filter((file) => file.delFlg === '0').length + + if (cnt == 0) { + originFileFlg = false + } else { + originFileFlg = true + } } + if (flag) { if (!originFileFlg) { - if (estimateData.newFileList?.length < 1) { + //๊ธฐ์กด์— ์ฒจ๋ถ€๋œ ํŒŒ์ผ์ด ์—†์œผ๋ฉด + if (isEmptyArray(estimateData.newFileList)) { + //์ƒˆ๋กœ ์ฒจ๋ถ€ํ•œ ํŒŒ์ผ์ด ์—†์œผ๋ฉด if (estimateData.itemList.length > 1) { estimateData.itemList.map((row) => { if (row.delFlg === '0') { @@ -181,9 +194,8 @@ export const useEstimateController = (planNo) => { estimateData.itemList.map((item) => { if (item.delFlg === '0') { item.amount = item.amount?.replaceAll(',', '') - item.salePrice = parseFloat(item.salePrice?.replaceAll(',', '')).toFixed(2) - item.saleTotPrice = parseFloat(item.saleTotPrice?.replaceAll(',', '')).toFixed(2) - + item.salePrice = Number(item.salePrice?.replaceAll(',', '')).toFixed(2) + item.saleTotPrice = Number(item.saleTotPrice?.replaceAll(',', '')).toFixed(2) if (!item.paDispOrder) { if (itemFlg) { if (isNaN(item.amount)) { @@ -214,6 +226,17 @@ export const useEstimateController = (planNo) => { } } }) + estimateData.itemList = estimateData.itemList.filter((item) => item.delFlg === '0' || !item.addFlg) + + let delCnt = 0 + estimateData.itemList.map((item) => { + if (item.delFlg === '1') { + delCnt++ + } + }) + if (delCnt === estimateData.itemList.length) { + return alert(getMessage('estimate.detail.save.requiredItem')) + } } if (flag && fileFlg && itemFlg) { @@ -228,83 +251,93 @@ export const useEstimateController = (planNo) => { formData.append('category', '10') formData.append('userId', estimateData.userId) - await post({ url: '/api/file/fileUpload', data: formData }) - } - - //์ฒจ๋ถ€ํŒŒ์ผ์ €์žฅ๋ - - //์ œํ’ˆ๋ผ์ธ ์ถ”๊ฐ€ํ–ˆ๋Š”๋ฐ ์•„์ดํ…œ ์•ˆ๊ณ ๋ฅด๊ณ  ์ €์žฅํ•˜๋ฉดitemId=''์€ ๋‚ ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ์ €์žฅํ•˜๊ธฐ - // estimateData.itemList = estimateData.itemList.filter((item) => item.itemId !== '') - estimateData.itemList = estimateData.itemList.filter((item) => item.delFlg === '0' || !item.addFlg) - - let delCnt = 0 - estimateData.itemList.map((item) => { - if (item.delFlg === '1') { - delCnt++ - } - }) - if (delCnt === estimateData.itemList.length) { - return alert(getMessage('estimate.detail.save.requiredItem')) - } - - let option = [] - estimateData.itemList.forEach((item) => { - if (item.specialNoteCd) { - let split2 = item.specialNoteCd.split('ใ€') - option = option.concat(split2) - } - }) - - let estimateOptions = '' - let estimateOptionsArray - estimateData.specialNoteList.map((item) => { - if (item.pkgYn === '0') { - if (item.check) { - if (estimateOptions === '') { - estimateOptions = item.code - } else { - estimateOptions += 'ใ€' + item.code - } - } - } else { - if (item.check) { - let flg = '0' - for (let i = 0; i < estimateData.uniqueData.length; i++) { - if (item.code.indexOf(estimateData.uniqueData[i]) > -1) { - flg = '1' - } - if (flg === '1') { - estimateOptions += 'ใ€' + estimateData.uniqueData[i] - } - } - } - } - }) - - estimateOptionsArray = estimateOptions.split('ใ€').sort() - estimateOptionsArray = Array.from(new Set(estimateOptionsArray)) - - estimateOptions = estimateOptionsArray.join('ใ€') - - estimateData.estimateOption = estimateOptions - console.log('์ตœ์ข…์•„์ดํ…œ:::', estimateData.itemList) - console.log('์ตœ์ข…์ €์žฅ::', estimateData) - //2. ์ƒ์„ธ๋ฐ์ดํ„ฐ ์ €์žฅ - // return - try { - await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { - if (res.status === 201) { - alert(getMessage('estimate.detail.save.alertMsg')) - //์–ด๋””๋กœ ๋ณด๋‚ผ์ง€ - fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) - } + await post({ url: '/api/file/fileUpload', data: formData }).then((res) => { + setFileList(res) }) - } catch (e) { - console.log('error::::::::::::', e.response.data.message) + } else { + setFileList([]) + realSave() } } } + const realSave = async (fileList) => { + //์ฒจ๋ถ€ํŒŒ์ผ์ €์žฅ๋ + + let option = [] + estimateData.itemList.forEach((item) => { + if (item.specialNoteCd) { + let split2 = item.specialNoteCd.split('ใ€') + option = option.concat(split2) + } + }) + + let estimateOptions = '' + let estimateOptionsArray + estimateData.specialNoteList.map((item) => { + if (item.pkgYn === '0') { + if (item.check) { + if (estimateOptions === '') { + estimateOptions = item.code + } else { + estimateOptions += 'ใ€' + item.code + } + } + } else { + if (item.check) { + let flg = '0' + for (let i = 0; i < estimateData.uniqueData.length; i++) { + if (item.code.indexOf(estimateData.uniqueData[i]) > -1) { + flg = '1' + } + if (flg === '1') { + estimateOptions += 'ใ€' + estimateData.uniqueData[i] + } + } + } + } + }) + + estimateOptionsArray = estimateOptions.split('ใ€').sort() + estimateOptionsArray = Array.from(new Set(estimateOptionsArray)) + + estimateOptions = estimateOptionsArray.join('ใ€') + + estimateData.estimateOption = estimateOptions + // console.log('์ตœ์ข…์•„์ดํ…œ:::', estimateData.itemList) + if (fileList?.length > 0) { + estimateData.fileList = fileList + } else { + estimateData.fileList = [] + } + if (estimateData.originFiles?.length > 0) { + estimateData.deleteFileList = estimateData.originFiles?.filter((item) => item.delFlg === '1') + } else { + estimateData.deleteFileList = [] + } + + if (estimateData.estimateType === 'YJSS') { + estimateData.pkgAsp = estimateData.pkgAsp.replaceAll(',', '') + } + + console.log('์ตœ์ข…์ €์žฅ::', estimateData) + //2. ์ƒ์„ธ๋ฐ์ดํ„ฐ ์ €์žฅ + // return + try { + await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { + if (res.status === 201) { + estimateData.newFileList = [] + // estimateData.originFiles = [] + alert(getMessage('estimate.detail.save.alertMsg')) + //์–ด๋””๋กœ ๋ณด๋‚ผ์ง€ + fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) + } + }) + } catch (e) { + console.log('error::::::::::::', e.response.data.message) + } + } + /** * ๊ฒฌ์ ์„œ ๋ณต์‚ฌ๋ฒ„ํŠผ * (๊ฒฌ์ ์„œ ๋ฒˆํ˜ธ(estimateData.docNo)๊ฐ€ ์ƒ์„ฑ๋œ ์ดํ›„ ๋ฒ„ํŠผ ํ™œ์„ฑํ™” ) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 0b3be4d5..f51cf00f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -2,21 +2,27 @@ import { useRecoilState, useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { rectToPolygon, setSurfaceShapePattern } from '@/util/canvas-util' import { roofDisplaySelector } from '@/store/settingAtom' -import offsetPolygon from '@/util/qpolygon-utils' +import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils' import { QPolygon } from '@/components/fabric/QPolygon' -import { QLine } from '@/components/fabric/QLine' import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom' import { useEvent } from '@/hooks/useEvent' import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common' import * as turf from '@turf/turf' import { v4 as uuidv4 } from 'uuid' +import { useSwal } from '@/hooks/useSwal' +import { canvasSettingState } from '@/store/canvasAtom' +import { compasDegAtom } from '@/store/orientationAtom' export function useModuleBasicSetting() { const canvas = useRecoilValue(canvasState) const roofDisplay = useRecoilValue(roofDisplaySelector) const [moduleSetupSurface, setModuleSetupSurface] = useRecoilState(moduleSetupSurfaceState) - // const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState) + const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState) const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useEvent() + const { swalFire } = useSwal() + const canvasSetting = useRecoilValue(canvasSettingState) + const compasDeg = useRecoilValue(compasDegAtom) + // const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) let selectedModuleInstSurfaceArray = [] @@ -62,6 +68,8 @@ export function useModuleBasicSetting() { const surfaceId = uuidv4() + console.log('roof.moduleCompass', roof.moduleCompass) + let setupSurface = new QPolygon(offsetPoints, { stroke: 'red', fill: 'transparent', @@ -440,6 +448,7 @@ export function useModuleBasicSetting() { //์ž๋™ ๋ชจ๋“ˆ ์„ค์น˜(๊ทธ๋ฆฌ๋“œ ๋ฐฉ์‹) const autoModuleSetup = (placementRef) => { + initEvent() //๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ์ดˆ๊ธฐํ™” const isChidori = placementRef.isChidori.current === 'true' ? true : false const setupLocation = placementRef.setupLocation.current const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false @@ -472,14 +481,20 @@ export function useModuleBasicSetting() { } }) - moduleSetupSurfaces.forEach((obj) => { - if (obj.modules) { - obj.modules.forEach((module) => { - canvas?.remove(module) - }) - obj.modules = [] - } - }) + // console.log('moduleIsSetup', moduleIsSetup) + + // if (moduleIsSetup.length > 0) { + // swalFire({ text: 'alert ์•„์ด์ฝ˜ ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค.', icon: 'error' }) + // } + + // moduleSetupSurfaces.forEach((obj) => { + // if (obj.modules) { + // obj.modules.forEach((module) => { + // canvas?.remove(module) + // }) + // obj.modules = [] + // } + // }) notSelectedTrestlePolygons.forEach((obj) => { if (obj.modules) { @@ -614,20 +629,20 @@ export function useModuleBasicSetting() { if (isMaxSetup) totalWidth = totalWidth * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌํ•˜๊ธฐ์œ„ํ•จ for (let j = 0; j < diffTopEndPoint; j++) { - bottomMargin = j === 0 ? 1 : 0 + bottomMargin = j === 0 ? 1 : 2 for (let i = 0; i <= totalWidth; i++) { - leftMargin = i === 0 ? 1.1 : 0 //์ˆซ์ž๊ฐ€ 0์ด๋ฉด 0, 1์ด๋ฉด 1๋กœ ๋ฐ”๊พธ๊ธฐ + leftMargin = i === 0 ? 1 : 2 chidoriLength = 0 if (isChidori) { chidoriLength = j % 2 === 0 ? 0 : width / 2 } square = [ - [startColPoint + tempMaxWidth * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], - [startColPoint + tempMaxWidth * i + width - chidoriLength, startPoint.y1 - height * j - bottomMargin], - [startColPoint + tempMaxWidth * i + width - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + tempMaxWidth * i - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + tempMaxWidth * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + tempMaxWidth * i + width - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + tempMaxWidth * i - chidoriLength + leftMargin, startPoint.y1 - height * j - bottomMargin], ] let squarePolygon = turf.polygon([square]) @@ -674,9 +689,9 @@ export function useModuleBasicSetting() { if (isMaxSetup) totalHeight = totalHeight * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌ for (let i = 0; i <= totalWidth; i++) { - bottomMargin = i === 0 ? 1 : 0.1 + bottomMargin = i === 0 ? 1 : 2 for (let j = 0; j < totalHeight; j++) { - leftMargin = i === 0 ? 0 : 0.5 * i + leftMargin = i === 0 ? 1 : 2 chidoriLength = 0 if (isChidori) { chidoriLength = i % 2 === 0 ? 0 : height / 2 @@ -746,17 +761,19 @@ export function useModuleBasicSetting() { if (isMaxSetup) diffRightEndPoint = diffRightEndPoint * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌํ•˜๊ธฐ์œ„ํ•จ for (let j = 0; j < diffBottomEndPoint; j++) { + bottomMargin = j === 0 ? 1 : 2 for (let i = 0; i < diffRightEndPoint; i++) { + leftMargin = i === 0 ? 1 : 2 chidoriLength = 0 if (isChidori) { chidoriLength = j % 2 === 0 ? 0 : width / 2 } square = [ - [startColPoint + tempMaxWidth * i + chidoriLength, startPoint.y1 + height * j + 1], - [startColPoint + tempMaxWidth * i + chidoriLength, startPoint.y1 + height * j + height + 1], - [startColPoint + tempMaxWidth * i + width + chidoriLength, startPoint.y1 + height * j + height + 1], - [startColPoint + tempMaxWidth * i + width + chidoriLength, startPoint.y1 + height * j + 1], - [startColPoint + tempMaxWidth * i + chidoriLength, startPoint.y1 + height * j + 1], + [startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin], + [startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin], + [startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + height + bottomMargin], + [startColPoint + tempMaxWidth * i + width + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin], + [startColPoint + tempMaxWidth * i + chidoriLength + leftMargin, startPoint.y1 + height * j + bottomMargin], ] let squarePolygon = turf.polygon([square]) @@ -804,9 +821,9 @@ export function useModuleBasicSetting() { if (isMaxSetup) totalHeight = totalHeight * 2 //์ตœ๋Œ€๋ฐฐ์น˜์‹œ 2๋ฐฐ๋กœ ๋Š˜๋ ค์„œ ๋ฐ˜์”ฉ ๊ฒ€์‚ฌ for (let i = 0; i <= totalWidth; i++) { + bottomMargin = i === 0 ? 1 : 2 for (let j = 0; j < totalHeight; j++) { - bottomMargin = j === 0 ? 0.5 : 0.5 * j - leftMargin = i === 0 ? 0 : 0.5 * i + leftMargin = j === 0 ? 1 : 2 chidoriLength = 0 if (isChidori) { chidoriLength = i % 2 === 0 ? 0 : height / 2 @@ -912,11 +929,12 @@ export function useModuleBasicSetting() { } }) + canvas?.renderAll() + //๋‚˜๊ฐ„์• ๋“ค ์ œ์™ธํ•˜๊ณ  ์„ค์น˜๋œ ์• ๋“ค๋กœ ๊ฒน์นœ์• ๋“ค ์‚ญ์ œ ํ•˜๊ธฐ setupedModules.forEach((module, index) => { if (isMaxSetup && index > 0) { const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(setupedModules[index - 1]), polygonToTurfPolygon(module)) - //๊ฒน์น˜๋Š”์ง€ ํ™•์ธ if (isOverlap) { //๊ฒน์ณ์žˆ์œผ๋ฉด ์‚ญ์ œ @@ -930,142 +948,231 @@ export function useModuleBasicSetting() { }) moduleSetupSurface.set({ modules: setupedModules }) - // setModuleIsSetup(moduleSetupArray) + + // const moduleArray = [...moduleIsSetup] + // moduleArray.push({ + // surfaceId: moduleSetupSurface.surfaceId, + // moduleSetupArray: setupedModules, + // }) + // setModuleIsSetup(moduleArray) }) + calculateForApi() } - const calculateForApi = (moduleSetupArray) => { - // TODO : ํ˜„์žฌ๋Š” ๋‚จ์ชฝ๊ธฐ์ค€. ๋™,์„œ,๋ถ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ ํ•„์š” - const centerPoints = [] - moduleSetupArray.forEach((module, index) => { - module.tempIndex = index - const { x, y } = module.getCenterPoint() - const { width, height } = module - centerPoints.push({ x, y, width, height, index }) - const circle = new fabric.Circle({ - radius: 5, - fill: 'red', - name: 'redCircle', - left: x - 5, - top: y - 5, - index: index, - selectable: false, + const calculateForApi = () => { + const moduleSufaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + + const results = [] + + moduleSufaces.forEach((moduleSurface) => { + const centerPoints = [] + const direction = moduleSurface.direction + const modules = moduleSurface.modules + + modules.forEach((module, index) => { + module.tempIndex = index + const { x, y } = module.getCenterPoint() + const { width, height } = module + centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index }) + }) + + if (centerPoints.length === 0) return + + //์™„์ „ ๋…ธ์ถœ ํ•˜๋ฉด + let exposedBottom = 0 + // ๋ฐ˜ ๋…ธ์ถœ ํ•˜๋ฉด + let exposedHalfBottom = 0 + // ์™„์ „ ๋…ธ์ถœ ์ƒ๋ฉด + let exposedTop = 0 + //๋ฐ˜ ๋…ธ์ถœ ์ƒ๋ฉด + let exposedHalfTop = 0 + // ์™„์ „ ์ ‘๋ฉด + let touchDimension = 0 + //๋ฐ˜์ ‘๋ฉด + let halfTouchDimension = 0 + // ๋…ธ์ถœํ•˜๋ฉด ์ฒดํฌ + centerPoints.forEach((centerPoint, index) => { + const { x, y, width, height } = centerPoint + // centerPoints์ค‘์— ํ˜„์žฌ centerPoint์™€ x๊ฐ’์ด ๊ฐ™๊ณ , y๊ฐ’์ด y-height๊ฐ’๊ณผ ๊ฐ™์€ centerPoint๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ + let bottomCell + let bottomLeftPoint + let bottomRightPoint + let leftBottomCnt + let rightBottomCnt + + switch (direction) { + case 'south': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + bottomLeftPoint = { x: x - width / 2, y: y + height } + bottomRightPoint = { x: x + width / 2, y: y + height } + break + case 'north': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + bottomLeftPoint = { x: x + width / 2, y: y - height } + bottomRightPoint = { x: x - width / 2, y: y - height } + break + case 'east': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + bottomLeftPoint = { x: x + width, y: y + height / 2 } + bottomRightPoint = { x: x + width, y: y - height / 2 } + break + case 'west': + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + bottomLeftPoint = { x: x - width, y: y - height / 2 } + bottomRightPoint = { x: x - width, y: y + height / 2 } + break + } + + if (bottomCell.length === 1) { + return + } + + // ๋ฐ”๋กœ ์•„๋ž˜์— ์…€์ด ์—†๋Š” ๊ฒฝ์šฐ ๋ฌผ๋–ผ์„ธ ๋ฐฐ์น˜๊ฐ€ ์™ผ์ชฝ ๋˜์–ด์žˆ๋Š” ์…€์„ ์ฐพ๋Š”๋‹ค. + leftBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2, + ).length + rightBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2, + ).length + + if (leftBottomCnt + rightBottomCnt === 1) { + exposedHalfBottom++ + return + } + }) + // ๋…ธ์ถœ์ƒ๋ฉด ์ฒดํฌ + + centerPoints.forEach((centerPoint, index) => { + const { x, y, width, height } = centerPoint + + let topCell + let topLeftPoint + let topRightPoint + let leftTopCnt + let rightTopCnt + + switch (direction) { + case 'south': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + topLeftPoint = { x: x - width / 2, y: y - height } + topRightPoint = { x: x + width / 2, y: y - height } + break + case 'north': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + topLeftPoint = { x: x + width / 2, y: y + height } + topRightPoint = { x: x - width / 2, y: y + height } + break + case 'east': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + topLeftPoint = { x: x - width, y: y + height / 2 } + topRightPoint = { x: x - width, y: y - height / 2 } + break + case 'west': + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + topLeftPoint = { x: x + width, y: y - height / 2 } + topRightPoint = { x: x + width, y: y + height / 2 } + break + } + + if (topCell.length === 1) { + touchDimension++ + return + } + + leftTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2, + ).length + rightTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, + ).length + + if (leftTopCnt + rightTopCnt === 2) { + touchDimension++ + return + } + + if (leftTopCnt + rightTopCnt === 1) { + exposedHalfTop++ + halfTouchDimension++ + return + } + if (leftTopCnt + rightTopCnt === 0) { + exposedTop++ + } + }) + // ์™„์ „ ๋…ธ์ถœ ํ•˜๋ฉด ๊ณ„์‚ฐ + + /*const cells = canvas.getObjects().filter((obj) => polygon.id === obj.parentId) + const points = cells.map((cell) => { + return cell.getCenterPoint() + })*/ + const groupPoints = groupCoordinates(centerPoints, modules[0], direction) + + groupPoints.forEach((group) => { + let maxY = group.reduce((acc, cur) => (acc.y > cur.y ? acc : cur)).y + let minY = group.reduce((acc, cur) => (acc.y < cur.y ? acc : cur)).y + let maxX = group.reduce((acc, cur) => (acc.x > cur.x ? acc : cur)).x + let minX = group.reduce((acc, cur) => (acc.x < cur.x ? acc : cur)).x + + let maxYCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.y - maxY) < 2) + let minYCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.y - minY) < 2) + let maxXCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.x - maxX) < 2) + let minXCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.x - minX) < 2) + + switch (direction) { + case 'south': + exposedBottom += maxYCenterPoint.length + break + case 'north': + exposedBottom += minYCenterPoint.length + break + case 'east': + exposedBottom += maxXCenterPoint.length + break + case 'west': + exposedBottom += minXCenterPoint.length + break + } + }) + + results.push({ + exposedBottom, + exposedHalfBottom, + exposedTop, + exposedHalfTop, + touchDimension, + halfTouchDimension, + }) + console.log({ + direction, + exposedBottom, + exposedHalfBottom, + exposedTop, + exposedHalfTop, + touchDimension, + halfTouchDimension, }) - canvas.add(circle) }) - //์™„์ „ ๋…ธ์ถœ ํ•˜๋ฉด - let exposedBottom = 0 - // ๋ฐ˜ ๋…ธ์ถœ ํ•˜๋ฉด - let exposedHalfBottom = 0 - // ์™„์ „ ๋…ธ์ถœ ์ƒ๋ฉด - let exposedTop = 0 - //๋ฐ˜ ๋…ธ์ถœ ์ƒ๋ฉด - let exposedHalfTop = 0 - // ์™„์ „ ์ ‘๋ฉด - let touchDimension = 0 - //๋ฐ˜์ ‘๋ฉด - let halfTouchDimension = 0 - // ๋…ธ์ถœํ•˜๋ฉด ์ฒดํฌ - centerPoints.forEach((centerPoint, index) => { - const { x, y, width, height } = centerPoint - // centerPoints์ค‘์— ํ˜„์žฌ centerPoint์™€ x๊ฐ’์ด ๊ฐ™๊ณ , y๊ฐ’์ด y-height๊ฐ’๊ณผ ๊ฐ™์€ centerPoint๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ - const bottomCell = centerPoints.filter((centerPoint) => centerPoint.x === x && Math.abs(centerPoint.y - (y + height)) < 2) - if (bottomCell.length === 1) { - touchDimension++ - return - } - - const bottomLeftPoint = { x: x - width / 2, y: y + height } - const bottomRightPoint = { x: x + width / 2, y: y + height } - - // ๋ฐ”๋กœ ์•„๋ž˜์— ์…€์ด ์—†๋Š” ๊ฒฝ์šฐ ๋ฌผ๋–ผ์„ธ ๋ฐฐ์น˜๊ฐ€ ์™ผ์ชฝ ๋˜์–ด์žˆ๋Š” ์…€์„ ์ฐพ๋Š”๋‹ค. - const leftBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2, - ).length - const rightBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2, - ).length - if (leftBottomCnt + rightBottomCnt === 2) { - touchDimension++ - return - } - if (leftBottomCnt + rightBottomCnt === 1) { - halfTouchDimension++ - exposedHalfBottom++ - return - } - }) - // ๋…ธ์ถœ์ƒ๋ฉด ์ฒดํฌ - - centerPoints.forEach((centerPoint, index) => { - const { x, y, width, height } = centerPoint - const topCell = centerPoints.filter((centerPoint) => centerPoint.x === x && Math.abs(centerPoint.y - (y - height)) < 2) - if (topCell.length === 1) { - return - } - - const topLeftPoint = { x: x - width / 2, y: y - height } - const topRightPoint = { x: x + width / 2, y: y - height } - - const leftTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, - ).length - const rightTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, - ).length - - if (leftTopCnt + rightTopCnt === 1) { - exposedHalfTop++ - return - } - if (leftTopCnt + rightTopCnt === 0) { - exposedTop++ - return - } - }) - // ์™„์ „ ๋…ธ์ถœ ํ•˜๋ฉด ๊ณ„์‚ฐ - - /*const cells = canvas.getObjects().filter((obj) => polygon.id === obj.parentId) - const points = cells.map((cell) => { - return cell.getCenterPoint() - })*/ - const groupPoints = groupCoordinates(centerPoints) - - groupPoints.forEach((group) => { - // ๊ฐ ๊ทธ๋ฃน์—์„œ y๊ฐ’์ด ํฐ ๊ฐ’์„ ์ฐพ๋Š”๋‹ค. - // ๊ทธ๋ฆฌ๊ณ  ๊ทธ y๊ฐ’๊ณผ ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง€๋Š” centerPoint๋ฅผ ์ฐพ๋Š”๋‹ค. - const maxY = group.reduce((acc, cur) => (acc.y > cur.y ? acc : cur)).y - const maxYCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.y - maxY) < 2) - exposedBottom += maxYCenterPoint.length - }) - - return { - exposedBottom, - exposedHalfBottom, - exposedTop, - exposedHalfTop, - touchDimension, - halfTouchDimension, - } + return results } // polygon ๋‚ด๋ถ€ cell๋“ค์˜ centerPoint ๋ฐฐ์—ด์„ ๊ทธ๋ฃนํ™” ํ•ด์„œ ๋ฐ˜ํ™˜ - const groupCoordinates = (points) => { + const groupCoordinates = (points, moduleExample, direction) => { const groups = [] const visited = new Set() - const width = 100 - const height = 100 - const horizonPadding = 5 // ๊ฐ€๋กœ ํŒจ๋”ฉ - const verticalPadding = 3 // ์„ธ๋กœ ํŒจ๋”ฉ + const width = Math.floor(moduleExample.width) + const height = Math.floor(moduleExample.height) + const horizonPadding = 0 // ๊ฐ€๋กœ ํŒจ๋”ฉ + const verticalPadding = 0 // ์„ธ๋กœ ํŒจ๋”ฉ function isAdjacent(p1, p2) { const dx = Math.abs(p1.x - p2.x) const dy = Math.abs(p1.y - p2.y) return ( - (dx === width + horizonPadding && dy === 0) || - (dx === 0 && dy === height + verticalPadding) || - (dx === width / 2 + horizonPadding / 2 && dy === height + verticalPadding) + (Math.abs(width + horizonPadding - dx) < 2 && dy < 2) || + (dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 || + (Math.abs(dx - width / 2 + horizonPadding / 2) < 2 && Math.abs(dy - height + verticalPadding) < 2) ) } @@ -1182,7 +1289,7 @@ export function useModuleBasicSetting() { const angle2 = Math.abs(Math.round(Math.atan(height2 / adjust2) * (180 / Math.PI) * 1000) / 1000) const angle3 = 180 - (angle1 + angle2) - const charlie = 173.3 + 3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ ์คŒ + const charlie = 173.3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ ์คŒ const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180) const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180)) const h = beta * Math.sin((angle1 * Math.PI) / 180) // ๋†’์ด @@ -1297,7 +1404,7 @@ export function useModuleBasicSetting() { const angle2 = Math.abs(Math.round(Math.atan(adjust2 / height2) * (180 / Math.PI) * 1000) / 1000) const angle3 = 180 - (angle1 + angle2) - const charlie = 173.3 + 3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ์คŒ + const charlie = 173.3 // ํ‰ํ–‰์„ ๊ธธ์ด ์•ฝ๊ฐ„ ์—ฌ์œ ๋ฅผ์คŒ const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180) const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180)) @@ -1413,10 +1520,343 @@ export function useModuleBasicSetting() { return obj } + const manualFlatroofModuleSetup = (placementFlatRef) => { + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //๋ชจ๋“ˆ์„ค์น˜๋ฉด๋ฅผ ๊ฐ€์ ธ์˜ด + let applyAngle + let flatBatchType = placementFlatRef.setupLocation.current.value + let excretaLinesAngle = [] + + if (flatBatchType === 'south') { + applyAngle = compasDeg + } else { + const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine' && obj.isSelected === true) + excretaLines.forEach((obj) => { + const points1 = { x: obj.x1, y: obj.y1 } + const points2 = { x: obj.x2, y: obj.y2 } + excretaLinesAngle.push({ + surfaceId: obj.surfaceId, + angle: calculateAngle(points1, points2), + }) + }) + } + + //calculateAngle + + const batchObjects = canvas + ?.getObjects() + .filter( + (obj) => + obj.name === BATCH_TYPE.OPENING || + obj.name === BATCH_TYPE.TRIANGLE_DORMER || + obj.name === BATCH_TYPE.PENTAGON_DORMER || + obj.name === BATCH_TYPE.SHADOW, + ) //๋„๋จธs ๊ฐ์ฒด + + const moduleOptions = { + fill: '#BFFD9F', + stroke: 'black', + strokeWidth: 0.1, + selectable: false, // ์„ ํƒ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ • + lockMovementX: true, // X ์ถ• ์ด๋™ ์ž ๊ธˆ + lockMovementY: true, // Y ์ถ• ์ด๋™ ์ž ๊ธˆ + lockRotation: true, // ํšŒ์ „ ์ž ๊ธˆ + lockScalingX: true, // X ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + lockScalingY: true, // Y ์ถ• ํฌ๊ธฐ ์กฐ์ • ์ž ๊ธˆ + opacity: 0.8, + parentId: moduleSetupSurface.parentId, + name: 'module', + } + + function getRotatedCorners(rect) { + // ์‚ฌ๊ฐํ˜•์˜ ์ค‘์‹ฌ์  + const center = rect.getCenterPoint() + + // ์‚ฌ๊ฐํ˜•์˜ ์›๋ž˜ ๊ผญ์ง“์  ์ขŒํ‘œ (๋กœ์ปฌ ์ขŒํ‘œ ๊ธฐ์ค€) + const halfWidth = (rect.width / 2) * rect.scaleX + const halfHeight = (rect.height / 2) * rect.scaleY + + const corners = [ + { x: -halfWidth, y: -halfHeight }, // ์ขŒ์ƒ๋‹จ + { x: halfWidth, y: -halfHeight }, // ์šฐ์ƒ๋‹จ + { x: halfWidth, y: halfHeight }, // ์šฐํ•˜๋‹จ + { x: -halfWidth, y: halfHeight }, // ์ขŒํ•˜๋‹จ + ] + + // ๊ฐ ๊ผญ์ง“์  ์ขŒํ‘œ๋ฅผ ์บ”๋ฒ„์Šค ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ + const transformedCorners = corners.map((corner) => { + const point = new fabric.Point(corner.x, corner.y) + return fabric.util.transformPoint(point, rect.calcTransformMatrix()) + }) + + return transformedCorners + } + + function getSelectedExcretaLine() {} + + if (moduleSetupSurfaces.length !== 0) { + let tempModule + let manualDrawModules = [] + let inside = false + let turfPolygon + let flowDirection + let trestlePolygon + + addCanvasMouseEventListener('mouse:move', (e) => { + //๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ์‚ญ์ œ ํ›„ ์žฌ์ถ”๊ฐ€ + const mousePoint = canvas.getPointer(e.e) + + for (let i = 0; i < moduleSetupSurfaces.length; i++) { + turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i]) + trestlePolygon = moduleSetupSurfaces[i] + manualDrawModules = moduleSetupSurfaces[i].modules // ์•ž์—์„œ ์ž๋™์œผ๋กœ ํ–ˆ์„๋•Œ ์ถ”๊ฐ€๋จ + flowDirection = moduleSetupSurfaces[i].flowDirection //๋„ํ˜•์˜ ๋ฐฉํ–ฅ + + if (flatBatchType === 'excreta') { + const tempLine = excretaLinesAngle.find((obj) => obj.surfaceId === trestlePolygon.surfaceId) + if (tempLine) { + applyAngle = tempLine.angle + } else { + applyAngle = compasDeg + } + } + + // const excretaLine = excretaLines.find((obj) => obj.isSelected === true && obj.surfaceId === trestlePolygon.surfaceId) + + // console.log('excretaLine', excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2) + + // applyAngle = calculateAngle(excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2) + + // console.log('applyAngle', applyAngle) + + let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113 + let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172 + + const angledModule = new fabric.Rect({ + width: width, + height: height, + left: mousePoint.x - width / 2, + top: mousePoint.y - height / 2, + }) + + const center = angledModule.getCenterPoint() + angledModule.set('angle', applyAngle) + angledModule.setPositionByOrigin(center, 'center', 'center') + + const points = getRotatedCorners(angledModule) // + const turfPoints = coordToTurfPolygon(points) + + if (turf.booleanWithin(turfPoints, turfPolygon)) { + let isDrawing = false + + if (isDrawing) return + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //์›€์ง์ผ๋•Œ ์ผ๋‹จ ์ง€์›Œ๊ฐ€๋ฉด์„œ ์›€์ง์ž„ + + tempModule = new QPolygon(points, { + fill: 'white', + stroke: 'black', + strokeWidth: 0.3, + name: 'tempModule', + }) + + canvas?.add(tempModule) //์›€์ง์—ฌ๊ฐ€๋ฉด์„œ ์ถ”๊ฐ€๋จ + canvas?.renderAll() + + /** + * ์Šค๋ƒ…๊ธฐ๋Šฅ + */ + let snapDistance = 10 + let cellSnapDistance = 20 + + const trestleLeft = moduleSetupSurfaces[i].left + const trestleTop = moduleSetupSurfaces[i].top + const trestleRight = trestleLeft + moduleSetupSurfaces[i].width * moduleSetupSurfaces[i].scaleX + const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY + const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2 + + // ์ž‘์€ ํด๋ฆฌ๊ณค์˜ ๊ฒฝ๊ณ„ ์ขŒํ‘œ ๊ณ„์‚ฐ + const smallLeft = tempModule.left + const smallTop = tempModule.top + const smallRight = smallLeft + tempModule.width * tempModule.scaleX + const smallBottom = smallTop + tempModule.height * tempModule.scaleY + const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2 + const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2 + + if (manualDrawModules) { + manualDrawModules.forEach((cell) => { + const holdCellLeft = cell.left + const holdCellTop = cell.top + const holdCellRight = holdCellLeft + cell.width * cell.scaleX + const holdCellBottom = holdCellTop + cell.height * cell.scaleY + const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2 + const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2 + + //์„ค์น˜๋œ ์…€์— ์ขŒ์ธก์— ์Šค๋ƒ… + if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + tempModule.left = holdCellLeft - width - 0.5 + } + + //์„ค์น˜๋œ ์…€์— ์šฐ์ธก์— ์Šค๋ƒ… + if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + tempModule.left = holdCellRight + 0.5 + } + + //์„ค์น˜๋œ ์…€์— ์œ„์ชฝ์— ์Šค๋ƒ… + if (Math.abs(smallBottom - holdCellTop) < snapDistance) { + tempModule.top = holdCellTop - height - 0.5 + } + + //์„ค์น˜๋œ ์…€์— ๋ฐ‘์ชฝ์— ์Šค๋ƒ… + if (Math.abs(smallTop - holdCellBottom) < snapDistance) { + tempModule.top = holdCellBottom + 0.5 + } + //๊ฐ€์šด๋ฐ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) { + tempModule.left = holdCellCenterX - width / 2 + } + //์™ผ์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) { + tempModule.left = holdCellCenterX + } + // ์˜ค๋ฅธ์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallRight - holdCellCenterX) < cellSnapDistance) { + tempModule.left = holdCellCenterX - width + } + //์„ธ๋กœ ๊ฐ€์šด๋ฐ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) { + tempModule.top = holdCellCenterY - height / 2 + } + //์œ„์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { + tempModule.top = holdCellCenterY + } + //์•„๋žซ์ชฝ -> ๊ฐ€์šด๋ฐ + if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) { + tempModule.top = holdCellCenterY - height + } + }) + } + + // ์œ„์ชฝ ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallTop - trestleTop) < snapDistance) { + tempModule.top = trestleTop + } + + // ์•„๋ž˜์ชฝ ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallTop + tempModule.height * tempModule.scaleY - (trestleTop + moduleSetupSurfaces[i].height)) < snapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height * tempModule.scaleY + } + + // ์™ผ์ชฝ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallLeft - trestleLeft) < snapDistance) { + tempModule.left = trestleLeft + } + //์˜ค๋ฅธ์ชฝ ๋ณ€์— ์Šค๋ƒ… + if (Math.abs(smallRight - trestleRight) < snapDistance) { + tempModule.left = trestleRight - tempModule.width * tempModule.scaleX + } + + if (flowDirection === 'south' || flowDirection === 'north') { + // ๋ชจ๋“ˆ์™ผ์ชฝ์ด ์„ธ๋กœ์ค‘์•™์„ ์— ๋ถ™๊ฒŒ ์Šค๋ƒ… + if (Math.abs(smallLeft - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { + tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 + } + + // ๋ชจ๋“ˆ์ด ๊ฐ€์šด๋ฐ๊ฐ€ ์„ธ๋กœ์ค‘์•™์„ ์— ๋ถ™๊ฒŒ ์Šค๋ƒ… + if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { + tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - (tempModule.width * tempModule.scaleX) / 2 + } + + // ๋ชจ๋“ˆ์˜ค๋ฅธ์ชฝ์ด ์„ธ๋กœ์ค‘์•™์„ ์— ๋ถ™๊ฒŒ ์Šค๋ƒ… + if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) { + tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX + } + } else { + // ๋ชจ๋“ˆ์ด ๊ฐ€๋กœ์ค‘์•™์„ ์— ์Šค๋ƒ… + if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < snapDistance) { + tempModule.top = bigCenterY - tempModule.height / 2 + } + + if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 + } + // ๋ชจ๋“ˆ ๋ฐ‘๋ฉด์ด ๊ฐ€๋กœ์ค‘์•™์„ ์— ์Šค๋ƒ… + if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) { + tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY + } + } + + inside = true + break + } else { + inside = false + } + } + + if (!inside) { + // tempModule.set({ fill: 'red' }) + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) + canvas?.renderAll() + } + }) + + addCanvasMouseEventListener('mouse:up', (e) => { + let isIntersection = true + if (!inside) return + if (tempModule) { + const tempTurfModule = polygonToTurfPolygon(tempModule) + + //๋„๋จธ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ด + if (batchObjects) { + batchObjects.forEach((object) => { + let dormerTurfPolygon + + if (object.type === 'group') { + //๋„๋จธ๋Š” ๊ทธ๋ฃนํ˜•ํƒœ์ž„ + dormerTurfPolygon = batchObjectGroupToTurfPolygon(object) + } else { + //๊ฐœ๊ตฌ, ๊ทธ๋ฆผ์ž + dormerTurfPolygon = polygonToTurfPolygon(rectToPolygon(object)) + } + + const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //๊ฒน์น˜๋Š”์ง€ ํ™•์ธ + //๊ฒน์น˜๋ฉด ์•ˆ๋จ + if (intersection) { + alert('๋„๋จธ์œ„์— ๋ชจ๋“ˆ์„ ์˜ฌ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.') + isIntersection = false + } + }) + } + + if (!isIntersection) return + + if (turf.booleanWithin(tempTurfModule, turfPolygon)) { + //๋งˆ์šฐ์Šค ํด๋ฆญ์‹œ set์œผ๋กœ ํ•ด๋‹น ์œ„์น˜์— ์…€์„ ๋„ฃ์Œ + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //๊ฒน์น˜๋Š”์ง€ ํ™•์ธ + if (!isOverlap) { + console.log('tempModule.points', tempModule.points) + + let manualModule = new QPolygon(tempModule.points, { ...moduleOptions }) + canvas?.add(manualModule) + manualDrawModules.push(tempModule) + } else { + alert('์…€๋ผ๋ฆฌ ๊ฒน์น˜๋ฉด ์•ˆ๋˜์ฃ ?') + } + } else { + alert('๋‚˜๊ฐ”์ฃ ?!!') + } + } + }) + } + } + + const autoFlatroofModuleSetup = (placementFlatRef) => {} + return { makeModuleInstArea, manualModuleSetup, autoModuleSetup, restoreModuleInstArea, + manualFlatroofModuleSetup, + autoFlatroofModuleSetup, } } diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index d37ce040..6c73efcc 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -1,6 +1,13 @@ import { useCallback, useEffect, useState } from 'react' import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' -import { adsorptionPointModeState, adsorptionRangeState, canvasState, planSizeSettingState, dotLineGridSettingState } from '@/store/canvasAtom' +import { + adsorptionPointModeState, + adsorptionRangeState, + canvasState, + planSizeSettingState, + dotLineGridSettingState, + canvasSettingState, +} from '@/store/canvasAtom' import { globalLocaleStore } from '@/store/localeAtom' import { useMessage } from '@/hooks/useMessage' import { useAxios } from '@/hooks/useAxios' @@ -11,6 +18,7 @@ import { settingModalFirstOptionsState, settingModalSecondOptionsState, settingModalGridOptionsState, + basicSettingState, } from '@/store/settingAtom' import { POLYGON_TYPE } from '@/common/common' import { globalFontAtom } from '@/store/fontAtom' @@ -70,6 +78,9 @@ export function useCanvasSetting() { const [color, setColor] = useColor(gridColor ?? '#FF0000') const [colorTemp, setColorTemp] = useState() + const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) + const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState) + const SelectOptions = [ { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, { id: 2, name: '1/2', value: 1 / 2 }, @@ -112,6 +123,14 @@ export function useCanvasSetting() { console.log('useCanvasSetting ์‹คํ–‰1', correntObjectNo) }, []) + // ๋ฐฐ์น˜๋ฉด ์ดˆ๊ธฐ์„ค์ • ๋ณ€๊ฒฝ ์‹œ + useEffect(() => { + //console.log('useCanvasSetting canvasSetting ์‹คํ–‰', canvasSetting) + if (canvasSetting.flag) { + basicSettingSave() + } + }, [canvasSetting]) + //ํก์ฐฉ์  ON/OFF ๋ณ€๊ฒฝ ์‹œ useEffect(() => { //console.log('useCanvasSetting ์‹คํ–‰2', adsorptionPointMode.fontFlag, correntObjectNo) @@ -232,6 +251,95 @@ export function useCanvasSetting() { } } + // ๊ธฐ๋ณธ์„ค์ •(PlacementShapeSetting) ์กฐํšŒ ๋ฐ ์ดˆ๊ธฐํ™” + const fetchBasicSettings = async () => { + try { + await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}` }).then((res) => { + console.log('fetchBasicSettings res ', res) + if (res.length == 0) return + + // 'roofs' ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ + const roofsRow = res.map((item) => { + return { + roofSizeSet: item.roofSizeSet, + roofAngleSet: item.roofAngleSet, + } + }) + + const roofsArray = res.some((item) => !item.roofSeq) + ? //์ตœ์ดˆ ์ง€๋ถ•์žฌ ์ถ”๊ฐ€ ์ •๋ณด์˜ ๊ฒฝ์šฐ roofsArray๋ฅผ ์ดˆ๊ธฐํ™” ์„ค์ • + res.map(() => ({ + flag: false, + roofApply: true, + roofSeq: 1, + roofType: 1, + roofWidth: 265, + roofHeight: 235, + roofHajebichi: 0, + roofGap: 455, + // roofType: 1, + // roofWidth: 200, + // roofHeight: 200, + // roofHajebichi: 200, + // roofGap: 0, + roofLayout: 'parallel', + })) + : res.map((item) => ({ + flag: false, + roofApply: item.roofApply === '' || item.roofApply === false ? false : true, + roofSeq: item.roofSeq, + roofType: item.roofType, + roofWidth: item.roofWidth, + roofHeight: item.roofHeight, + roofHajebichi: item.roofHajebichi, + roofGap: item.roofGap, + roofLayout: item.roofLayout, + })) + console.log('roofsArray ', roofsArray) + // ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ 'roofs' ๋ฐฐ์—ด์„ patternData์— ๋„ฃ์Œ + const patternData = { + roofSizeSet: roofsRow[0].roofSizeSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ + roofAngleSet: roofsRow[0].roofAngleSet, // ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์˜ ๊ฐ’์„ ์‚ฌ์šฉ + roofs: roofsArray, // ๋งŒ๋“ค์–ด์ง„ roofs ๋ฐฐ์—ด + } + + //console.error('patternData', patternData) + + // ๋ฐ์ดํ„ฐ ์„ค์ • + setBasicSettings({ ...patternData }) + }) + } catch (error) { + console.error('Data fetching error:', error) + } + + if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { + setBasicSettings({ ...canvasSetting }) + } + //setCanvasSetting({ ...basicSetting }) + } + + // ๊ธฐ๋ณธ์„ค์ •(PlacementShapeSetting) ์ €์žฅ + const basicSettingSave = async () => { + try { + const patternData = { + objectNo: correntObjectNo, + roofSizeSet: basicSetting.roofSizeSet, + roofAngleSet: basicSetting.roofAngleSet, + roofMaterialsAddList: basicSetting.roofs, + } + + await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { + swalFire({ text: getMessage(res.returnMessage) }) + }) + + //Recoil ์„ค์ • + setCanvasSetting({ ...basicSetting, flag: false }) + } catch (error) { + swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) + } + } + + // CanvasSetting ์กฐํšŒ ๋ฐ ์ดˆ๊ธฐํ™” const fetchSettings = async () => { try { const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${correntObjectNo}` }) @@ -382,7 +490,7 @@ export function useCanvasSetting() { } } - // ์˜ต์…˜ ํด๋ฆญ ํ›„ ์ €์žฅ + // CanvasSetting ์˜ต์…˜ ํด๋ฆญ ํ›„ ์ €์žฅ const onClickOption2 = useCallback(async () => { // ์„œ๋ฒ„์— ์ „์†กํ•  ๋ฐ์ดํ„ฐ const dataToSend = { @@ -592,7 +700,6 @@ export function useCanvasSetting() { adsorptionRange, setAdsorptionRange, fetchSettings, - //onClickOption, frontSettings, globalFont, setGlobalFont, @@ -621,5 +728,11 @@ export function useCanvasSetting() { setGridColor, color, setColor, + canvasSetting, + setCanvasSetting, + basicSetting, + setBasicSettings, + fetchBasicSettings, + basicSettingSave, } } diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 7bf43bbd..786e2660 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react' import { useRecoilState } from 'recoil' -import { v4 as uuidv4, validate as isValidUUID } from 'uuid' +import { v4 as uuidv4 } from 'uuid' import { canvasState, currentCanvasPlanState, plansState, modifiedPlansState, modifiedPlanFlagState } from '@/store/canvasAtom' import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' @@ -179,7 +179,7 @@ export function usePlan() { * objectNo์— ํ•ด๋‹นํ•˜๋Š” canvas ๋ชฉ๋ก์„ ์กฐํšŒ */ const getCanvasByObjectNo = async (userId, objectNo) => { - return get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) => + return await get({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}/${userId}` }).then((res) => res.map((item, index) => ({ id: item.id, userId: item.userId, @@ -237,15 +237,15 @@ export function usePlan() { /** * id์— ํ•ด๋‹นํ•˜๋Š” canvas ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œ */ - const delCanvasById = (id) => { - return promiseDel({ url: `/api/canvas-management/canvas-statuses/by-id/${id}` }) + const delCanvasById = async (id) => { + return await promiseDel({ url: `/api/canvas-management/canvas-statuses/by-id/${id}` }) } /** * objectNo์— ํ•ด๋‹นํ•˜๋Š” canvas ๋ฐ์ดํ„ฐ๋“ค์„ ์‚ญ์ œ */ - const delCanvasByObjectNo = (objectNo) => { - return promiseDel({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}` }) + const delCanvasByObjectNo = async (objectNo) => { + return await promiseDel({ url: `/api/canvas-management/canvas-statuses/by-object/${objectNo}` }) } /** @@ -282,19 +282,19 @@ export function usePlan() { * ์ƒˆ๋กœ์šด plan ์ƒ์„ฑ * ํ˜„์žฌ plan์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ๋ณต์ œ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ */ - const handleAddPlan = (userId, objectNo) => { + const handleAddPlan = async (userId, objectNo) => { JSON.parse(currentCanvasData()).objects.length > 0 ? swalFire({ text: `Plan ${currentCanvasPlan.ordering} ` + getMessage('plan.message.confirm.copy'), type: 'confirm', - confirmFn: () => { - postCanvasStatus(userId, objectNo, currentCanvasData()) + confirmFn: async () => { + await postCanvasStatus(userId, objectNo, currentCanvasData()) }, - denyFn: () => { - postCanvasStatus(userId, objectNo, '') + denyFn: async () => { + await postCanvasStatus(userId, objectNo, '') }, }) - : postCanvasStatus(userId, objectNo, '') + : await postCanvasStatus(userId, objectNo, '') } /** @@ -317,10 +317,10 @@ export function usePlan() { /** * plan ์‚ญ์ œ */ - const handleDeletePlan = (e, id) => { + const handleDeletePlan = async (e, id) => { e.stopPropagation() // ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง ๋ฐฉ์ง€ - delCanvasById(id) + await delCanvasById(id) .then((res) => { setPlans((plans) => plans.filter((plan) => plan.id !== id)) setModifiedPlans((modifiedPlans) => modifiedPlans.filter((planId) => planId !== currentCanvasPlan.id)) @@ -344,8 +344,8 @@ export function usePlan() { /** * plan ์กฐํšŒ */ - const loadCanvasPlanData = (userId, objectNo, pid) => { - getCanvasByObjectNo(userId, objectNo).then((res) => { + const loadCanvasPlanData = async (userId, objectNo, pid) => { + await getCanvasByObjectNo(userId, objectNo).then((res) => { // console.log('canvas ๋ชฉ๋ก ', res) if (res.length > 0) { setPlans(res) diff --git a/src/lib/session.js b/src/lib/session.js index ff5a2078..bcedecf4 100644 --- a/src/lib/session.js +++ b/src/lib/session.js @@ -3,8 +3,8 @@ export const defaultSession = {} export const sessionOptions = { password: process.env.SESSION_SECRET, cookieName: 'lama-session', - cookieOptions: { - httpOnly: true, - secure: process.env.NODE_ENV === 'production', - }, + // cookieOptions: { + // httpOnly: true, + // secure: process.env.NODE_ENV === 'production', + // }, } diff --git a/src/locales/ja.json b/src/locales/ja.json index 7276c6c0..1dea67e7 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -164,6 +164,7 @@ "plan.menu.estimate.save": "ไฟๅญ˜", "plan.menu.estimate.reset": "ๅˆๆœŸๅŒ–", "plan.menu.estimate.copy": "่ฆ‹็ฉๆ›ธใฎใ‚ณใƒ”ใƒผ", + "plan.menu.estimate.unLock": "ใƒญใƒƒใ‚ฏ่งฃ้™ค", "plan.menu.simulation": "็™บๅฑ•ใ‚ทใƒŸใƒฅใƒฌใƒผใ‚ทใƒงใƒณ", "plan.menu.simulation.excel": "Excel", "plan.menu.simulation.pdf": "PDF", @@ -841,6 +842,7 @@ "estimate.detail.fileList.btn": "ใƒ•ใ‚กใ‚คใƒซ้ธๆŠž", "estimate.detail.fileList.extCheck": "ใใฎใƒ•ใ‚กใ‚คใƒซใฏใ‚คใƒกใƒผใ‚ธใƒ•ใ‚กใ‚คใƒซใงใฏใ‚ใ‚Šใพใ›ใ‚“", "estimate.detail.header.fileList2": "ๆทปไป˜ใƒ•ใ‚กใ‚คใƒซไธ€่ฆง", + "estimate.detail.fileList2.btn.return": "ๅพฉๅ…ƒ", "estimate.detail.header.specialEstimate": "่ฆ‹็ฉใ‚‚ใ‚Šใฎๅ…ทไฝ“็š„ใช", "estimate.detail.header.specialEstimateProductInfo": "่ฃฝๅ“ๆƒ…ๅ ฑ", "estimate.detail.sepcialEstimateProductInfo.totAmount": "ๆ•ฐ้‡ (PCS)", diff --git a/src/locales/ko.json b/src/locales/ko.json index 42bcd69b..b1d7c7da 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -168,6 +168,7 @@ "plan.menu.estimate.save": "์ €์žฅ", "plan.menu.estimate.reset": "์ดˆ๊ธฐํ™”", "plan.menu.estimate.copy": "๊ฒฌ์ ์„œ ๋ณต์‚ฌ", + "plan.menu.estimate.unLock": "์ž ๊ธˆ ํ•ด์ œ", "plan.menu.simulation": "๋ฐœ์ „ ์‹œ๋ฎฌ๋ ˆ์ด์…˜", "plan.menu.simulation.excel": "Excel", "plan.menu.simulation.pdf": "PDF", @@ -851,6 +852,7 @@ "estimate.detail.fileList.btn": "ํŒŒ์ผ์„ ํƒ", "estimate.detail.fileList.extCheck": "ํ•ด๋‹น ํŒŒ์ผ์€ ์ด๋ฏธ์ง€ ํŒŒ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค", "estimate.detail.header.fileList2": "์ฒจ๋ถ€ํŒŒ์ผ ๋ชฉ๋ก", + "estimate.detail.fileList2.btn.return": "๋ณต์›", "estimate.detail.header.specialEstimate": "๊ฒฌ์ ํŠน์ด์‚ฌํ•ญ", "estimate.detail.header.specialEstimateProductInfo": "์ œํ’ˆ์ •๋ณด", "estimate.detail.sepcialEstimateProductInfo.totAmount": "์ˆ˜๋Ÿ‰ (PCS)", diff --git a/src/util/common-utils.js b/src/util/common-utils.js index fd8f6ca5..06b96b60 100644 --- a/src/util/common-utils.js +++ b/src/util/common-utils.js @@ -113,7 +113,7 @@ export const calculateFlowDirection = (canvasAngle) => { return { down: -canvasAngle, up: 180 - canvasAngle, - left: 90 - canvasAngle, - right: -90 - canvasAngle, + left: 90 - canvasAngle < 180 ? 90 - canvasAngle : 90 - canvasAngle - 360, + right: -90 - canvasAngle < -180 ? -90 - canvasAngle + 360 : -90 - canvasAngle, } }