diff --git a/src/components/floor-plan/modal/ImgLoad.jsx b/src/components/floor-plan/modal/ImgLoad.jsx index 2a5e77aa..341f9b94 100644 --- a/src/components/floor-plan/modal/ImgLoad.jsx +++ b/src/components/floor-plan/modal/ImgLoad.jsx @@ -34,11 +34,11 @@ export default function ImgLoad() { const handleModal = () => { setFloorPlanState({ ...floorPlanState, refFileModalOpen: false, toggleRotate: false }) - setCurrentCanvasPlan({ - ...currentCanvasPlan, - bgImageName: refImage?.name ?? null, - mapPositionAddress, - }) + // setCurrentCanvasPlan({ + // ...currentCanvasPlan, + // bgImageName: refImage?.name ?? null, + // mapPositionAddress, + // }) } useEffect(() => { diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index adeb0300..e53c8619 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -21,6 +21,7 @@ import { selectedModuleState } from '@/store/selectedModuleOptions' import { v4 as uuidv4 } from 'uuid' import { stepUpListDataState } from '@/store/circuitTrestleAtom' +import { useEstimate } from '@/hooks/useEstimate' const ALLOCATION_TYPE = { AUTO: 'auto', @@ -31,6 +32,7 @@ export default function CircuitTrestleSetting({ id }) { const { closePopup } = usePopup() const { apply } = useTrestle() const { swalFire } = useSwal() + const { saveEstimate } = useEstimate() const canvas = useRecoilValue(canvasState) const [makers, setMakers] = useRecoilState(makersState) @@ -336,8 +338,10 @@ export default function CircuitTrestleSetting({ id }) { }) const result = await apply() + if (result) { + await saveEstimate(result) + } removeNotAllocationModules() - apply() } const removeNotAllocationModules = () => { diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index bb079bc7..027a2d87 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -131,12 +131,16 @@ export function useRefFiles() { // setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) } + /** + * 배경 이미지 로드를 위한 세팅 + */ useEffect(() => { if (!currentBgImage) { return } console.log('🚀 ~ useEffect ~ currentBgImage:', currentBgImage) - handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) + // handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) + handleBackImageLoadToCanvas(currentBgImage) setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: refImage?.name ?? null, mapPositionAddress: queryRef.current.value })) }, [currentBgImage]) @@ -147,15 +151,15 @@ export function useRefFiles() { const handleUploadImageRefFile = async (file) => { const formData = new FormData() formData.append('file', file) - formData.append('fileName', currentCanvasPlan.id) + // formData.append('fileName', currentCanvasPlan.id) // const res = await post({ url: `${process.env.NEXT_PUBLIC_API_SERVER_PATH}/api/image-upload`, data: formData }) - const res = await post({ url: `http://localhost:3000/api/image-upload`, data: formData }) + const res = await post({ url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/upload`, data: formData }) console.log('🚀 ~ handleUploadImageRefFile ~ res:', res) - const image = await readImage(res.fileNm) - console.log('🚀 ~ handleUploadImageRefFile ~ file:', image) + // const image = await readImage(res.filePath) + // console.log('🚀 ~ handleUploadImageRefFile ~ file:', image) - setCurrentBgImage(image) + setCurrentBgImage(`${process.env.NEXT_PUBLIC_HOST_URL}${res.filePath}`) setRefImage(file) } diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 083c24c3..9c580971 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1,18 +1,16 @@ -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilValue } from 'recoil' import { canvasState, currentAngleTypeSelector } from '@/store/canvasAtom' import { POLYGON_TYPE } from '@/common/common' import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { getDegreeByChon, getTrestleLength } from '@/util/canvas-util' import { v4 as uuidv4 } from 'uuid' import { useMasterController } from '@/hooks/common/useMasterController' -import { estimateParamAtom } from '@/store/estimateAtom' // 회로 및 가대설정 export const useTrestle = () => { const canvas = useRecoilValue(canvasState) const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 const { getQuotationItem } = useMasterController() - const [estimateParam, setEstimateParam] = useRecoilState(estimateParamAtom) const currentAngleType = useRecoilValue(currentAngleTypeSelector) const apply = () => { @@ -41,6 +39,7 @@ export const useTrestle = () => { return } + const plvrYn = construction.plvrYn let moduleRowsTotCnt = 0 let isEaveBar = construction.setupCover let isSnowGuard = construction.setupSnowCover @@ -102,6 +101,14 @@ export const useTrestle = () => { leftExposedHalfTopModules.length > 0 || rightExposedHalfTopPoints.length > 0 + console.log('isChidory', isChidory) + + if (plvrYn === 'N' && isChidory) { + alert('치조불가공법입니다.') + clear() + throw new Error('치조불가공법입니다.') + } + surface.set({ isChidory: isChidory }) canvas @@ -210,6 +217,10 @@ export const useTrestle = () => { let findLeft = true let findRight = true + let leftFindModuleList = [module] + let rightFindModuleList = [module] + let centerFindModuleList = [module] + //우선 절반을 나눈 뒤 왼쪽부터 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. @@ -218,6 +229,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. leftRows++ + leftFindModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -233,6 +245,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. leftRows++ + leftFindModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -253,6 +266,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. rightRows++ + rightFindModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -268,6 +282,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. rightRows++ + rightFindModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -287,6 +302,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. + centerFindModuleList.push(nextModule) centerRows++ x = nextModule.x y = nextModule.y @@ -295,19 +311,77 @@ export const useTrestle = () => { } } + const leftModuleInfos = leftFindModuleList.map((module) => { + return { + moduleTpCd: module.moduleInfo.moduleTpCd, + } + }) + + const rightModuleInfos = rightFindModuleList.map((module) => { + return { + moduleTpCd: module.moduleInfo.moduleTpCd, + } + }) + + const centerModuleInfos = centerFindModuleList.map((module) => { + return { + moduleTpCd: module.moduleInfo.moduleTpCd, + } + }) + + const leftRowsInfo = moduleTransformData(leftModuleInfos) + const rightRowsInfo = moduleTransformData(rightModuleInfos) + const centerRowsInfo = moduleTransformData(centerModuleInfos) + // 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다. const leftRacks = rackInfos.find((rack) => { - return rack.value.moduleRows === leftRows + if (leftRowsInfo.rowsInfo.length === 1) { + return ( + rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && + rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) + ) + } else { + return ( + rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && + rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + rack.value.moduleTpRows1 === leftRowsInfo.rowsInfo[0].count && + rack.value.moduleTpRows2 === leftRowsInfo.rowsInfo[1].count + ) + } })?.value.racks // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다. const rightRacks = rackInfos.find((rack) => { - return rack.value.moduleRows === rightRows + if (rightRowsInfo.rowsInfo.length === 1) { + return ( + rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && + rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) + ) + } else { + return ( + rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && + rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + rack.value.moduleTpRows1 === rightRowsInfo.rowsInfo[0].count && + rack.value.moduleTpRows2 === rightRowsInfo.rowsInfo[1].count + ) + } })?.value.racks // 해당 rack으로 그려준다. const centerRacks = rackInfos.find((rack) => { - return rack.value.moduleRows === centerRows + if (centerRowsInfo.rowsInfo.length === 1) { + return ( + rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && + rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) + ) + } else { + return ( + rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && + rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + rack.value.moduleTpRows1 === centerRowsInfo.rowsInfo[0].count && + rack.value.moduleTpRows2 === centerRowsInfo.rowsInfo[1].count + ) + } })?.value.racks mostRowsModule = Math.max(leftRows, rightRows, centerRows, mostRowsModule) @@ -336,6 +410,7 @@ export const useTrestle = () => { let leftRows = 1 let hasNextModule = true let findLeft = true + let findModuleList = [module] //우선 절반을 나눈 뒤 왼쪽부터 찾는다. while (hasNextModule) { @@ -345,6 +420,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. leftRows++ + findModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -371,6 +447,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. leftRows++ + findModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -379,10 +456,30 @@ export const useTrestle = () => { } } + const leftModuleInfos = findModuleList.map((module) => { + return { + moduleTpCd: module.moduleInfo.moduleTpCd, + } + }) + const leftRowsInfo = moduleTransformData(leftModuleInfos) + // 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다. const leftRacks = rackInfos.find((rack) => { - return rack.value.moduleRows === leftRows + if (leftRowsInfo.rowsInfo.length === 1) { + return ( + rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && + rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) + ) + } else { + return ( + rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && + rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + rack.value.moduleTpRows1 === leftRowsInfo.rowsInfo[0].count && + rack.value.moduleTpRows2 === leftRowsInfo.rowsInfo[1].count + ) + } })?.value.racks + mostRowsModule = Math.max(leftRows, mostRowsModule) if (rackYn === 'Y') { drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn) @@ -400,6 +497,7 @@ export const useTrestle = () => { let rightRows = 1 let hasNextModule = true let findRight = true + let findModuleList = [module] // 오른쪽 찾는다. while (hasNextModule) { @@ -409,6 +507,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. rightRows++ + findModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -424,6 +523,7 @@ export const useTrestle = () => { if (nextModule) { // 바로 위 모듈을 찾는다. rightRows++ + findModuleList.push(nextModule) x = nextModule.x y = nextModule.y } else { @@ -432,11 +532,30 @@ export const useTrestle = () => { } } + const rightRowsInfos = findModuleList.map((module) => { + return { + moduleTpCd: module.moduleInfo.moduleTpCd, + } + }) + + const rightRowsInfo = moduleTransformData(rightRowsInfos) + // 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다. const rightRacks = rackInfos.find((rack) => { - return rack.value.moduleRows === rightRows + if (rightRowsInfo.rowsInfo.length === 1) { + return ( + rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && + rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) + ) + } else { + return ( + rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && + rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && + rack.value.moduleTpRows1 === rightRowsInfo.rowsInfo[0].count && + rack.value.moduleTpRows2 === rightRowsInfo.rowsInfo[1].count + ) + } })?.value.racks - mostRowsModule = Math.max(rightRows, mostRowsModule) // 해당 rack으로 그려준다. if (rackYn === 'Y') { @@ -462,10 +581,24 @@ export const useTrestle = () => { return setEstimateData() } catch (e) { - return false + return null } } + //module Rack 정보를 얻기위한 데이터 가공 + function moduleTransformData(arr) { + let counts = {} + + arr.forEach((item) => { + counts[item.moduleTpCd] = (counts[item.moduleTpCd] || 0) + 1 + }) + + let moduleTotalTp = Object.keys(counts).join('') + let rowsInfo = Object.entries(counts).map(([moduleTpCd, count]) => ({ moduleTpCd, count })) + + return { moduleTotalTp, rowsInfo } + } + // itemList 조회 후 estimateParam에 저장 const setEstimateData = async () => { const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) @@ -480,7 +613,7 @@ export const useTrestle = () => { //견적서 itemList 조회 const res = await getQuotationItem(params) if (!res.data) { - return false + return null } const itemList = res.data //northArrangement 북면 설치 여부 @@ -540,10 +673,10 @@ export const useTrestle = () => { } }) - setEstimateParam({ ...estimateParam, itemList, northArrangement, roofSurfaceList, circuitItemList }) + const estimateParam = { itemList, northArrangement, roofSurfaceList, circuitItemList } // 정상적으로 완료 되면 true 반환 - return true + return estimateParam } const getNorthArrangement = () => { @@ -565,9 +698,11 @@ export const useTrestle = () => { } const findNextModule = (currentPoint, centerPoints, direction) => { - let { x, y, width, height, horizontal, vertical } = { ...currentPoint } - width = width + horizontal - height = height + vertical + let { x, y, horizontal, vertical } = { ...currentPoint } + let { widthArr, heightArr } = centerPoints[0] + + let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal + let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical let maxX = 2 + horizontal * 3 let maxY = 2 + vertical * 3 @@ -596,7 +731,11 @@ export const useTrestle = () => { } const findNextLeftModule = (currentPoint, centerPoints, direction) => { - let { x, y, width, height, horizontal, vertical } = { ...currentPoint } + let { x, y, horizontal, vertical } = { ...currentPoint } + let { widthArr, heightArr } = centerPoints[0] + + let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal + let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical let result let topLeftPoint @@ -631,9 +770,11 @@ export const useTrestle = () => { return result } const findNextRightModule = (currentPoint, centerPoints, direction) => { - let { x, y, width, height, horizontal, vertical } = { ...currentPoint } - width = width + horizontal - height = height + vertical + let { x, y, horizontal, vertical } = { ...currentPoint } + let { widthArr, heightArr } = centerPoints[0] + + let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal + let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical let result let topRightPoint @@ -665,6 +806,9 @@ export const useTrestle = () => { } const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l, rackYn) => { + if (!rackInfos) { + return + } const { width, height, left, top, lastX, lastY, surfaceId } = module const surface = canvas.getObjects().find((obj) => obj.id === surfaceId) const roof = canvas.getObjects().find((obj) => obj.id === surface.parentId) @@ -762,7 +906,7 @@ export const useTrestle = () => { name: 'smartRack', stroke: 'red', strokeWidth: 4, - selectable: false, + selectable: true, shadow: { color: 'black', // Outline color blur: 10, @@ -774,17 +918,18 @@ export const useTrestle = () => { surfaceId: surface.id, supFitQty, supFitIntvlPct, - rackLen, + rackLen: rackLength, rackRowsCd, seq, smartRackId, rackId: itemId, direction: 'top', }) + startPointY -= rackLength + 8 canvas.add(rack) canvas.renderAll() } else if (setRackTpCd === 'INTVL') { - startPointY -= rackLength + 8 + startPointY -= rackLength } }) } else { @@ -844,13 +989,14 @@ export const useTrestle = () => { surfaceId: surface.id, supFitQty, supFitIntvlPct, - rackLen, + rackLen: rackLength, rackRowsCd, seq, smartRackId, rackId: itemId, direction: 'left', }) + startPointX -= rackLength + 8 canvas.add(rack) canvas.renderAll() } else if (setRackTpCd === 'INTVL') { @@ -873,7 +1019,7 @@ export const useTrestle = () => { selectable: false, supFitQty, supFitIntvlPct, - rackLen, + rackLen: rackLength, rackYn, rackRowsCd, rackId: itemId, @@ -913,17 +1059,18 @@ export const useTrestle = () => { surfaceId: surface.id, supFitQty, supFitIntvlPct, - rackLen, + rackLen: rackLength, rackRowsCd, seq, smartRackId, rackId: itemId, direction: 'right', }) + startPointX += rackLength + 8 canvas.add(rack) canvas.renderAll() } else if (setRackTpCd === 'INTVL') { - startPointX += rackLength + 8 + startPointX += rackLength } }) } else { @@ -989,8 +1136,9 @@ export const useTrestle = () => { }) canvas.add(rack) canvas.renderAll() - } else if (setRackTpCd === 'INTVL') { startPointY += rackLength + 8 + } else if (setRackTpCd === 'INTVL') { + startPointY += rackLength } }) } else { @@ -1043,17 +1191,16 @@ export const useTrestle = () => { canvas.renderAll() racks.forEach((rack) => { - const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen } = rack + const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen, name } = rack const bracketLength = 10 if (direction === 'top') { const result = getBracketPoints(supFitQty, supFitIntvlPct) - result.forEach((percent) => { const bracket = new fabric.Rect({ left: x2 - bracketLength / 3, - top: y2 + (rackLen / 10) * percent, + top: name === 'smartRack' ? y2 + rackLen * percent : y2 + (rackLen / 10) * percent, fill: 'green', name: 'bracket', parentId: rack.parentId, @@ -1071,7 +1218,7 @@ export const useTrestle = () => { result.forEach((percent) => { const bracket = new fabric.Rect({ - left: x2 + (rackLen / 10) * percent, + left: name === 'smartRack' ? x2 + rackLen * percent : x2 + (rackLen / 10) * percent, top: y2 - bracketLength / 3, fill: 'green', name: 'bracket', @@ -1090,7 +1237,7 @@ export const useTrestle = () => { result.forEach((percent) => { const bracket = new fabric.Rect({ - left: x2 - (rackLen / 10) * percent, + left: name === 'smartRack' ? x2 - rackLen * percent : x2 - (rackLen / 10) * percent, top: y2 - bracketLength / 3, fill: 'green', parentId: rack.parentId, @@ -1110,7 +1257,7 @@ export const useTrestle = () => { result.forEach((percent) => { const bracket = new fabric.Rect({ left: x2 - bracketLength / 3, - top: y2 - (rackLen / 10) * percent, + top: name === 'smartRack' ? y2 - rackLen * percent : y2 - (rackLen / 10) * percent, fill: 'green', name: 'bracket', parentId: rack.parentId, @@ -1337,8 +1484,49 @@ export const useTrestle = () => { return points.slice(0, 2) } - const calculateForApi = (moduleSurface) => { + const getCenterPoints = (moduleSurface) => { const centerPoints = [] + let widthArr = [] + let heightArr = [] + const modules = moduleSurface.modules + modules.forEach((module, index) => { + module.tempIndex = index + const { x, y } = module.getCenterPoint() + const { width, height } = { ...module } + widthArr.push(width) + heightArr.push(height) + centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index, moduleInfo: module.moduleInfo }) + }) + + //widthArr 중복 제거 1이상 차이가 나지 않으면 같은 너비로 간주 + widthArr = removeCloseValues(Array.from(new Set(widthArr))) + heightArr = removeCloseValues(Array.from(new Set(heightArr))) + + centerPoints.forEach((centerPoint, index) => { + centerPoint.widthArr = [...widthArr] + + centerPoint.heightArr = [...heightArr] + }) + + function removeCloseValues(arr, threshold = 1) { + arr.sort((a, b) => a - b) // 배열을 정렬 + + let result = [] + + for (let i = 0; i < arr.length; i++) { + if (i === 0 || Math.abs(arr[i] - arr[i - 1]) >= threshold) { + result.push(arr[i]) + } + } + + return result + } + + return centerPoints + } + + const calculateForApi = (moduleSurface) => { + const centerPoints = getCenterPoints(moduleSurface) const direction = moduleSurface.direction const modules = moduleSurface.modules @@ -1350,12 +1538,6 @@ export const useTrestle = () => { const maxX = 2 + horizontal * 3 const maxY = 2 + vertical * 3 - 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 @@ -1382,7 +1564,7 @@ export const useTrestle = () => { let rightExposedHalfTopPoints = [] centerPoints.forEach((centerPoint, index) => { - let { x, y, width, height } = { ...centerPoint } + let { x, y, width, height, widthArr, heightArr } = { ...centerPoint } // centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인 let bottomCell let bottomLeftPoint @@ -1392,28 +1574,29 @@ export const useTrestle = () => { switch (direction) { case 'south': - width = width + horizontal - height = height + vertical + //widthArr의 값을 전부 더한 후 widthArr의 길이로 나누어 평균값을 구한다. + width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal + height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) bottomLeftPoint = { x: x - width / 2, y: y + height } bottomRightPoint = { x: x + width / 2, y: y + height } break case 'north': - width = width + horizontal - height = height + vertical + width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal + height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) 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)) < maxX && Math.abs(centerPoint.y - y) < maxY) - width = width + horizontal + width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal 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)) < maxX && Math.abs(centerPoint.y - y) < maxY) - width = width + horizontal + width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal bottomLeftPoint = { x: x - width, y: y - height / 2 } bottomRightPoint = { x: x - width, y: y + height / 2 } break @@ -1870,16 +2053,16 @@ export const useTrestle = () => { const { direction, modules } = surface let { rackYn, cvrPlvrYn, moduleIntvlHor, moduleIntvlVer, rackQty, lessSupFitQty } = surface.trestleDetail - const centerPoints = modules.map((module) => { - return module.getCenterPoint() - }) + const centerPoints = getCenterPoints(surface) const horizontal = ['south', 'north'].includes(direction) ? moduleIntvlHor : moduleIntvlVer const vertical = ['south', 'north'].includes(direction) ? moduleIntvlVer : moduleIntvlHor const maxX = 2 + horizontal * 3 const maxY = 2 + vertical * 3 - let { width, height } = { ...module } + let { widthArr, heightArr } = centerPoints[0] + let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length let { x, y } = { ...module.getCenterPoint() } let halfBottomLeftPoint diff --git a/src/hooks/useEstimate.js b/src/hooks/useEstimate.js new file mode 100644 index 00000000..7fa4ff60 --- /dev/null +++ b/src/hooks/useEstimate.js @@ -0,0 +1,59 @@ +import { useContext } from 'react' + +import { useRecoilValue } from 'recoil' + +import { useAxios } from '@/hooks/useAxios' +import { useSwal } from '@/hooks/useSwal' +import { GlobalDataContext } from '@/app/GlobalDataProvider' +import { currentCanvasPlanState } from '@/store/canvasAtom' +import { loginUserStore } from '@/store/commonAtom' + +export function useEstimate() { + const { managementStateLoaded } = useContext(GlobalDataContext) + + const loginUserState = useRecoilValue(loginUserStore) + const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) + + const { swalFire } = useSwal() + const { promisePost } = useAxios() + + /** + * 도면 견적서 저장 + */ + const saveEstimate = async (estimateParam) => { + const userId = loginUserState.userId + const saleStoreId = managementStateLoaded.saleStoreId + const objectNo = currentCanvasPlan.objectNo + const planNo = currentCanvasPlan.planNo + const slope = estimateParam.roofSurfaceList[0].slope + const angle = estimateParam.roofSurfaceList[0].angle + const surfaceType = managementStateLoaded.surfaceType + const setupHeight = managementStateLoaded.installHeight + const standardWindSpeedId = managementStateLoaded.standardWindSpeedId + const snowfall = managementStateLoaded.verticalSnowCover + const drawingFlg = '1' + + const saveEstimateData = { + ...estimateParam, + userId: userId, + saleStoreId: saleStoreId, + objectNo: objectNo, + planNo: planNo, + slope: slope, + angle: angle, + surfaceType: surfaceType, + setupHeight: setupHeight, + standardWindSpeedId: standardWindSpeedId, + snowfall: snowfall, + drawingFlg: drawingFlg, + } + + await promisePost({ url: '/api/estimate/save-estimate', data: saveEstimateData }).catch((error) => { + swalFire({ text: error.message, icon: 'error' }) + }) + } + + return { + saveEstimate, + } +} diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index b904611d..3691035e 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -394,6 +394,7 @@ export function usePlan(params = {}) { canvas, plans, currentCanvasPlan, + setCurrentCanvasPlan, selectedPlan, saveCanvas, handleCurrentPlan, diff --git a/src/lib/fileAction.js b/src/lib/fileAction.js index d2c4cff9..6b531d77 100644 --- a/src/lib/fileAction.js +++ b/src/lib/fileAction.js @@ -72,7 +72,8 @@ const writeImage = async (fileName, file) => { } const readImage = async (fileName) => { - const file = await fs.readFile(`${FILE_PATH}/${fileName}`) + // const file = await fs.readFile(`${FILE_PATH}/${fileName}`) + const file = await fs.readFile(`${process.env.NEXT_PUBLIC_HOST_URL}${fileName}`) // .then((res) => { // console.log('readImage-then', res) // }) diff --git a/src/locales/ja.json b/src/locales/ja.json index 0951418c..38723da7 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -877,6 +877,7 @@ "estimate.detail.roofCns": "屋根材・仕様施工", "estimate.detail.remarks": "備考", "estimate.detail.fileFlg": "後日資料提出", + "estimate.detail.dragFileGuide": "(※北面設置の場合、ファイル添付が必須です.)", "estimate.detail.header.fileList1": "ファイル添付", "estimate.detail.fileList.btn": "ファイル選択", "estimate.detail.fileList.extCheck": "画像ファイルのみ添付可能です。", @@ -942,6 +943,7 @@ "estimate.detail.save.alertMsg": "保存されました。見積書で製品を変更すると、図面や回路には反映されません。", "estimate.detail.copy.alertMsg": "コピーされました。", "estimate.detail.save.requiredFileUpload": "ファイル添付が必須のアイテムがあります。ファイルを添付するか、後日添付をチェックしてください。", + "estimate.detail.save.requiredNorthArrangementFileUpload": "北面にモジュールを配置した場合、北面配置許可書を必ず添付する必要があります.", "estimate.detail.save.requiredItem": "製品は1つ以上登録する必要があります。", "estimate.detail.save.requiredCharger": "担当者は必須です。", "estimate.detail.save.requiredObjectName": "案件名は必須です。", diff --git a/src/locales/ko.json b/src/locales/ko.json index 9037ade4..5c7c17d6 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -877,6 +877,7 @@ "estimate.detail.roofCns": "지붕재・사양시공", "estimate.detail.remarks": "비고", "estimate.detail.fileFlg": "후일자료제출", + "estimate.detail.dragFileGuide": "(※ 북면설치인 경우, 파일 첨부가 필수입니다.)", "estimate.detail.header.fileList1": "파일첨부", "estimate.detail.fileList.btn": "파일선택", "estimate.detail.fileList.extCheck": "이미지 파일만 첨부 가능합니다.", @@ -942,6 +943,7 @@ "estimate.detail.save.alertMsg": "저장되었습니다. 견적서에서 제품을 변경할 경우 도면 및 회로에 반영되지 않습니다.", "estimate.detail.copy.alertMsg": "복사되었습니다.", "estimate.detail.save.requiredFileUpload": "파일첨부가 필수인 아이템이 있습니다. 파일을 첨부하거나 후일첨부를 체크해주십시오.", + "estimate.detail.save.requiredNorthArrangementFileUpload": "북면에 모듈을 배치한 경우, 북면배치허가서를 반드시 첨부해야 합니다.", "estimate.detail.save.requiredItem": "제품은 1개이상 등록해야 됩니다.", "estimate.detail.save.requiredCharger": "담당자는 필수값 입니다.", "estimate.detail.save.requiredObjectName": "안건명은 필수값 입니다.",