From dc717b051a3ae56e361f7706de74d057f783265b Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 28 Nov 2024 10:18:41 +0900 Subject: [PATCH 01/98] =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 245 +++++++++++++--------- 1 file changed, 143 insertions(+), 102 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 067d9f8a..7b56c5f1 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -434,19 +434,25 @@ export function useModuleBasicSetting() { } }) - const moduleSetupArray = [] - moduleSetupSurfaces.forEach((moduleSetupSurface, index) => { - moduleSetupSurface.fire('mousedown') + const moduleOptions = { + fill: '#BFFD9F', + stroke: 'black', + strokeWidth: 0.1, + selectable: true, // 선택 가능하게 설정 + lockMovementX: false, // X 축 이동 잠금 + lockMovementY: false, // Y 축 이동 잠금 + lockRotation: false, // 회전 잠금 + lockScalingX: false, // X 축 크기 조정 잠금 + lockScalingY: false, // Y 축 크기 조정 잠금 + opacity: 0.8, + parentId: moduleSetupSurface.parentId, + name: 'module', + } - const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface) - - let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => { - return acc.length > cur.length ? acc : cur - }) - - const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //폴리곤을 turf 객체로 변환 - - const containsBatchObjects = batchObjects.filter((batchObject) => { + //선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환 + const objectsIncludeSurface = (turfModuleSetupSurface) => { + let containsBatchObjects = [] + containsBatchObjects = batchObjects.filter((batchObject) => { let convertBatchObject if (batchObject.type === 'group') { @@ -454,9 +460,7 @@ export function useModuleBasicSetting() { convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) } else { //개구, 그림자 - batchObject.set({ - points: rectToPolygon(batchObject), - }) + batchObject.set({ points: rectToPolygon(batchObject) }) canvas?.renderAll() // set된걸 바로 적용하기 위해 convertBatchObject = polygonToTurfPolygon(batchObject) //rect를 폴리곤으로 변환 -> turf 폴리곤으로 변환 } @@ -465,19 +469,59 @@ export function useModuleBasicSetting() { return turf.booleanContains(turfModuleSetupSurface, convertBatchObject) || turf.booleanWithin(convertBatchObject, turfModuleSetupSurface) }) - let difference = turfModuleSetupSurface //기본 객체(면형상) + return containsBatchObjects + } + + /** + * 도머나 개구가 모듈에 걸치는지 확인하는 로직 + * @param {*} squarePolygon + * @param {*} containsBatchObjects + * @returns + */ + const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => { + let isDisjoint = false if (containsBatchObjects.length > 0) { - //turf로 도머를 제외시키는 로직 - for (let i = 0; i < containsBatchObjects.length; i++) { - let convertBatchObject - if (containsBatchObjects[i].type === 'group') { - convertBatchObject = batchObjectGroupToTurfPolygon(containsBatchObjects[i]) + let convertBatchObject + //도머가 있으면 적용되는 로직 + isDisjoint = containsBatchObjects.every((batchObject) => { + if (batchObject.type === 'group') { + convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) } else { - convertBatchObject = polygonToTurfPolygon(containsBatchObjects[i]) + convertBatchObject = polygonToTurfPolygon(batchObject) } - } + /** + * 도머가 여러개일수있으므로 겹치는게 있다면... + * 안겹치는지 확인하는 로직이라 안겹치면 true를 반환 + */ + return turf.booleanDisjoint(squarePolygon, convertBatchObject) + }) + } else { + isDisjoint = true } + return isDisjoint + } + + /** + * 배치면 안에 있는지 확인 + * @param {*} squarePolygon + * @param {*} turfModuleSetupSurface + * @returns + */ + const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => { + return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) + } + + moduleSetupSurfaces.forEach((moduleSetupSurface, index) => { + moduleSetupSurface.fire('mousedown') + const moduleSetupArray = [] + + let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => { + return acc.length > cur.length ? acc : cur + }) + + const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface) //폴리곤을 turf 객체로 변환 + const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 let width = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 172.2 : 113.4 let height = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 113.4 : 172.2 @@ -488,102 +532,99 @@ export function useModuleBasicSetting() { height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2 } - let square - let startPoint, endPoint + const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface) + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 + const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 + const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 + const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최 하단 + let leftMargin, bottomMargin, square if (setupLocation === 'eaves') { if (moduleSetupSurface.flowDirection === 'south') { - startPoint = flowModuleLine.find((obj) => obj.target === 'bottom') - endPoint = flowModuleLine.find((obj) => obj.target === 'top') - const totalHeight = endPoint.y1 - startPoint.y1 - const diffHeight = Math.abs(totalHeight / height) - let leftMargin = 0 - let bottomMargin = 0 + let startPoint = flowModuleLine.find((obj) => obj.target === 'bottom') + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 + let totalTopEndPoint = maxTopEndPoint - startPoint.y1 + let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) + let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) - for (let i = 0; i < diffHeight; i++) { - leftMargin = i === 0 ? 1 : 0 - bottomMargin = i === 0 ? 0 : 1 - - square = [ - [startPoint.x1 + leftMargin, startPoint.y1 - height - bottomMargin], - [startPoint.x1 + leftMargin, startPoint.y1 - bottomMargin], - [startPoint.x1 + leftMargin + width, startPoint.y1 - bottomMargin], - [startPoint.x1 + leftMargin + width, startPoint.y1 - height - bottomMargin], - [startPoint.x1 + leftMargin, startPoint.y1 - height - bottomMargin], - ] - - const squarePolygon = turf.polygon([square]) - - //설치면 안에 있는지 확인 - const disjointFromTrestle = - turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) - - if (disjointFromTrestle) { + for (let j = 0; j < diffTopEndPoint; j++) { + bottomMargin = 1 + for (let i = 0; i <= totalWidth; i++) { + leftMargin = i === 0 ? 0 : 1 //숫자가 0이면 0, 1이면 1로 바꾸기 + square = [ + [startColPoint + width * i + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + width * i + width - leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + width * i + width - leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + width * i + leftMargin, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + width * i + leftMargin, startPoint.y1 - height * j - bottomMargin], + ] + let squarePolygon = turf.polygon([square]) let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - const points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - if (containsBatchObjects.length > 0) { - let convertBatchObject - //도머가 있으면 적용되는 로직 - const isDisjoint = containsBatchObjects.every((batchObject) => { - if (batchObject.type === 'group') { - convertBatchObject = batchObjectGroupToTurfPolygon(batchObject) - } else { - convertBatchObject = polygonToTurfPolygon(batchObject) - } - return turf.booleanDisjoint(squarePolygon, convertBatchObject) //도머가 여러개일수있으므로 겹치는게 있다면... - }) - if (isDisjoint) { - const tempModule = new QPolygon(points, { - fill: '#BFFD9F', - stroke: 'black', - strokeWidth: 0.1, - selectable: true, // 선택 가능하게 설정 - lockMovementX: false, // X 축 이동 잠금 - lockMovementY: false, // Y 축 이동 잠금 - lockRotation: false, // 회전 잠금 - lockScalingX: false, // X 축 크기 조정 잠금 - lockScalingY: false, // Y 축 크기 조정 잠금 - opacity: 0.8, - parentId: moduleSetupSurface.parentId, - name: 'module', - }) - tempModule.setViewLengthText(false) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - } else { - //도머가 없을땐 그냥 그림 - const tempModule = new QPolygon(points, { - fill: '#BFFD9F', - stroke: 'black', - selectable: true, // 선택 가능하게 설정 - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - lockRotation: true, // 회전 잠금 - lockScalingX: true, // X 축 크기 조정 잠금 - lockScalingY: true, // Y 축 크기 조정 잠금 - opacity: 0.8, - parentId: moduleSetupSurface.parentId, - name: 'module', - }) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - startPoint = { x1: points[0].x, y1: points[0].y, x2: points[3].x, y2: points[3].y } + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) } } } } else if (setupLocation === 'ridge') { + if (moduleSetupSurface.flowDirection === 'south') { + let startPoint = flowModuleLine.find((obj) => obj.target === 'top') + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 + let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint + let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1 + let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) + let diffRightEndPoint = Math.abs(totalRightEndPoint / width) + let diffBottomEndPoint = Math.abs(totalBottomEndPoint / height) + let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + + for (let j = 0; j < diffBottomEndPoint; j++) { + bottomMargin = 1 + for (let i = 0; i < diffRightEndPoint; i++) { + leftMargin = i === 0 ? 0 : 1 + + square = [ + [startColPoint + width * i - leftMargin, startPoint.y1 + height * j + bottomMargin], + [startColPoint + width * i - leftMargin, startPoint.y1 + height * j + height + bottomMargin], + [startColPoint + width * i + width - leftMargin, startPoint.y1 + height * j + height + bottomMargin], + [startColPoint + width * i + width - leftMargin, startPoint.y1 + height * j + bottomMargin], + [startColPoint + width * i - leftMargin, startPoint.y1 + height * j + bottomMargin], + ] + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } } else { } - moduleSetupSurface.set({ modules: moduleSetupArray }) + const setupedModules = moduleSetupArray.filter((module) => { + let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface) + let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects) + + if (!(disjointFromTrestle && isDisjoint)) { + canvas?.remove(module) + return false + } else { + return module + } + }) + moduleSetupSurface.set({ modules: setupedModules }) }) setModuleIsSetup(moduleSetupArray) - console.log(calculateForApi(moduleSetupArray)) + // console.log(calculateForApi(moduleSetupArray)) } const calculateForApi = (moduleSetupArray) => { From 05f187fda43f3ae7f0457e698bac93b4decc1f05 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 28 Nov 2024 17:45:33 +0900 Subject: [PATCH 02/98] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=9E=91=EC=97=85=EC=A7=84=ED=96=89?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 165 ++++++++++++++++++---- 1 file changed, 135 insertions(+), 30 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 7b56c5f1..b7b941f3 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -54,8 +54,7 @@ export function useModuleBasicSetting() { }) setupSurface.setViewLengthText(false) - - canvas.add(setupSurface) + canvas.add(setupSurface) //모듈설치면 만들기 if (setupSurface.flowDirection === 'south' || setupSurface.flowDirection === 'north') { setFlowModuleLine(bottomTopFlowLine(setupSurface)) @@ -392,11 +391,10 @@ export function useModuleBasicSetting() { //자동 모듈 설치(그리드 방식) const autoModuleSetup = (placementRef) => { - const isChidori = placementRef.isChidori.current + const isChidori = placementRef.isChidori.current === 'true' ? true : false const setupLocation = placementRef.setupLocation.current const isMaxSetup = placementRef.isMaxSetup.current - initEvent() const moduleSetupSurfaces = moduleSetupSurface //선택 설치면 const notSelectedTrestlePolygons = canvas @@ -438,7 +436,7 @@ export function useModuleBasicSetting() { fill: '#BFFD9F', stroke: 'black', strokeWidth: 0.1, - selectable: true, // 선택 가능하게 설정 + selectable: false, // 선택 가능하게 설정 lockMovementX: false, // X 축 이동 잠금 lockMovementY: false, // Y 축 이동 잠금 lockRotation: false, // 회전 잠금 @@ -537,9 +535,11 @@ export function useModuleBasicSetting() { const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최 하단 - let leftMargin, bottomMargin, square + let leftMargin, bottomMargin, square, chidoriLength + //처마면 배치 if (setupLocation === 'eaves') { + // 흐름방향이 남쪽일때 if (moduleSetupSurface.flowDirection === 'south') { let startPoint = flowModuleLine.find((obj) => obj.target === 'bottom') let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 @@ -550,16 +550,59 @@ export function useModuleBasicSetting() { let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) for (let j = 0; j < diffTopEndPoint; j++) { - bottomMargin = 1 + bottomMargin = j === 0 ? 1 : 0 for (let i = 0; i <= totalWidth; i++) { - leftMargin = i === 0 ? 0 : 1 //숫자가 0이면 0, 1이면 1로 바꾸기 + leftMargin = i === 0 ? 1 : 0 //숫자가 0이면 0, 1이면 1로 바꾸기 + chidoriLength = 0 + if (isChidori) { + chidoriLength = j % 2 === 0 ? 0 : width / 2 + } + square = [ - [startColPoint + width * i + leftMargin, startPoint.y1 - height * j - bottomMargin], - [startColPoint + width * i + width - leftMargin, startPoint.y1 - height * j - bottomMargin], - [startColPoint + width * i + width - leftMargin, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + width * i + leftMargin, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + width * i + leftMargin, startPoint.y1 - height * j - bottomMargin], + [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], + [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - bottomMargin], + [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + if (moduleSetupSurface.flowDirection === 'west') { + let startPoint = flowModuleLine.find((obj) => obj.target === 'left') + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) + let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width + let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) + + for (let j = 0; j < totalHeight; j++) { + bottomMargin = j === 0 ? 1 : 0 + for (let i = 0; i <= totalWidth; i++) { + leftMargin = 1 + chidoriLength = 0 + if (isChidori) { + chidoriLength = i % 2 === 0 ? 0 : height / 2 + } + + square = [ + [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], + ] + let squarePolygon = turf.polygon([square]) let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) @@ -583,17 +626,61 @@ export function useModuleBasicSetting() { let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) for (let j = 0; j < diffBottomEndPoint; j++) { - bottomMargin = 1 for (let i = 0; i < diffRightEndPoint; i++) { - leftMargin = i === 0 ? 0 : 1 + chidoriLength = 0 + if (isChidori) { + chidoriLength = j % 2 === 0 ? 0 : width / 2 + } + square = [ + [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j], + [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + height], + [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j + height], + [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j], + [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + if (moduleSetupSurface.flowDirection === 'west') { + let startPoint = flowModuleLine.find((obj) => obj.target === 'right') + //계산하기 편하게 그냥 y1을 작은수로 만든다 + let correctPoint = + startPoint.y1 > startPoint.y2 + ? { x1: startPoint.x2, x2: startPoint.x1, y1: startPoint.y2, y2: startPoint.y1 } + : { x1: startPoint.x1, x2: startPoint.x2, y1: startPoint.y1, y2: startPoint.y2 } + + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) + let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width + let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) + + for (let j = 0; j < totalHeight; j++) { + bottomMargin = j === 0 ? 1 : 0 + for (let i = 0; i <= totalWidth; i++) { + leftMargin = 1 + chidoriLength = 0 + if (isChidori) { + chidoriLength = i % 2 === 0 ? 0 : height / 2 + } square = [ - [startColPoint + width * i - leftMargin, startPoint.y1 + height * j + bottomMargin], - [startColPoint + width * i - leftMargin, startPoint.y1 + height * j + height + bottomMargin], - [startColPoint + width * i + width - leftMargin, startPoint.y1 + height * j + height + bottomMargin], - [startColPoint + width * i + width - leftMargin, startPoint.y1 + height * j + bottomMargin], - [startColPoint + width * i - leftMargin, startPoint.y1 + height * j + bottomMargin], + [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j - bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j - bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j + height - bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + height - bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j - bottomMargin + chidoriLength], ] + let squarePolygon = turf.polygon([square]) let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) @@ -613,17 +700,17 @@ export function useModuleBasicSetting() { let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects) if (!(disjointFromTrestle && isDisjoint)) { - canvas?.remove(module) + // canvas?.remove(module) + module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) return false } else { return module } }) moduleSetupSurface.set({ modules: setupedModules }) + setModuleIsSetup(moduleSetupArray) }) - setModuleIsSetup(moduleSetupArray) - // console.log(calculateForApi(moduleSetupArray)) } @@ -826,12 +913,6 @@ export function useModuleBasicSetting() { const h = beta * Math.sin((angle1 * Math.PI) / 180) // 높이 const sign = Math.sign(coords[0].y - coords[1].y) // 진행방향 const top = coords[1].y + sign * h // 변경되는 높이 좌표 값 - // const line3 = new QLine([coords[1].x, coords[1].y, coords[1].x, top], { - // stroke: 'blue', - // strokeWidth: 1, - // selectable: true, - // }) - // // canvas?.add(line3) const pointX1 = coords[0].x + ((coords[0].y - top) / (coords[0].y - coords[1].y)) * (coords[1].x - coords[0].x) const pointY1 = top @@ -845,8 +926,31 @@ export function useModuleBasicSetting() { }) canvas?.add(finalLine) canvas?.renderAll() + let rtnObj + + if (alpha === 0 || beta === 0 || h === 0 || sign === 0) { + //꼭지점이 없고 평평할때 ex) 네모 + let standardLine + if (center.index === 0) { + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) { + return { x1: line.x1, y1: line.y1, index: index } + } + return acc + }) + } else { + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.y1 > acc.y1) { + return { x1: line.x1, y1: line.y1, index: index } + } + return acc + }) + } + rtnObj = { target: idx === 0 ? 'bottom' : 'top', x1: standardLine.x1, y1: pointY1, x2: standardLine.x1 + charlie, y2: pointY2 } + } else { + rtnObj = { target: idx === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + } - const rtnObj = { target: idx === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } rtnObjArray.push(rtnObj) ++idx }) @@ -943,6 +1047,7 @@ export function useModuleBasicSetting() { rtnObjArray.push(rtnObj) ++idx }) + return rtnObjArray } const findSetupSurfaceMaxLines = (surface) => { From 9e1a0699b2a6e1c044a9e18b6c025ace6618ace0 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 28 Nov 2024 18:04:26 +0900 Subject: [PATCH 03/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 14 +++++++++----- .../floorPlan/estimate/useEstimateController.js | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index a52f8423..578b16fa 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -356,6 +356,7 @@ export default function Estimate({ params }) { if (item2.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(), }) @@ -535,6 +536,7 @@ export default function Estimate({ params }) { updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString() // updates.saleTotPrice = '' updates.amount = '' + updates.openFlg = res.openFlg if (estimateContextState.estimateType === 'YJSS') { if (res.pkgMaterialFlg === '0') { @@ -1322,9 +1324,9 @@ export default function Estimate({ params }) { - + - + @@ -1451,9 +1453,11 @@ export default function Estimate({ params }) { maxLength={12} /> - {/*
- -
*/} + {item.openFlg === '1' && ( +
+ +
+ )} ) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index f59ed69e..dfd66960 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -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) @@ -148,8 +151,8 @@ export const useEstimateController = (planNo) => { //첨부파일을 첨부안했는데 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 - console.log('새로추가첨부파일:::', estimateData.newFileList) - console.log('기존첨부파일:::', estimateData.originFiles) + // console.log('새로추가첨부파일:::', estimateData.newFileList) + // console.log('기존첨부파일:::', estimateData.originFiles) // return @@ -228,13 +231,12 @@ export const useEstimateController = (planNo) => { formData.append('category', '10') formData.append('userId', estimateData.userId) - await post({ url: '/api/file/fileUpload', data: formData }) + await post({ url: '/api/file/fileUpload', data: formData }).then((res) => { + console.log('리턴::::::::::::', res) + }) } //첨부파일저장끝 - - //제품라인 추가했는데 아이템 안고르고 저장하면itemId=''은 날리고 나머지 저장하기 - // estimateData.itemList = estimateData.itemList.filter((item) => item.itemId !== '') estimateData.itemList = estimateData.itemList.filter((item) => item.delFlg === '0' || !item.addFlg) let delCnt = 0 @@ -287,10 +289,11 @@ export const useEstimateController = (planNo) => { estimateOptions = estimateOptionsArray.join('、') estimateData.estimateOption = estimateOptions - console.log('최종아이템:::', estimateData.itemList) + // console.log('첨부파일::::::::', fileList) + // console.log('최종아이템:::', estimateData.itemList) console.log('최종저장::', estimateData) //2. 상세데이터 저장 - // return + return try { await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { if (res.status === 201) { diff --git a/src/locales/ja.json b/src/locales/ja.json index 7276c6c0..8efb602d 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -841,6 +841,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..ad437c99 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -851,6 +851,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)", From 75abf8c3922e212d02e5222d100861ec6114a146 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 3 Dec 2024 17:44:03 +0900 Subject: [PATCH 36/98] =?UTF-8?q?return=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/estimate/useEstimateController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index dfd66960..63f92832 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -293,7 +293,7 @@ export const useEstimateController = (planNo) => { // console.log('최종아이템:::', estimateData.itemList) console.log('최종저장::', estimateData) //2. 상세데이터 저장 - return + // return try { await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { if (res.status === 201) { From 5de9242e08aa1532bed35b44c2c83036dbf20e7c Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 3 Dec 2024 17:54:52 +0900 Subject: [PATCH 37/98] =?UTF-8?q?=EC=B5=9C=EB=8C=80=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 74 ++++++++++++++--------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 0b3be4d5..979ee7ec 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -4,19 +4,21 @@ import { rectToPolygon, setSurfaceShapePattern } from '@/util/canvas-util' import { roofDisplaySelector } from '@/store/settingAtom' import offsetPolygon 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' 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 { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) let selectedModuleInstSurfaceArray = [] @@ -440,6 +442,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 +475,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 +623,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 +683,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 +755,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 +815,9 @@ export function useModuleBasicSetting() { if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사 for (let i = 0; i <= totalWidth; i++) { + bottomMargin = j === 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 = i === 0 ? 1 : 2 chidoriLength = 0 if (isChidori) { chidoriLength = i % 2 === 0 ? 0 : height / 2 @@ -912,11 +923,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,7 +942,13 @@ export function useModuleBasicSetting() { }) moduleSetupSurface.set({ modules: setupedModules }) - // setModuleIsSetup(moduleSetupArray) + + // const moduleArray = [...moduleIsSetup] + // moduleArray.push({ + // surfaceId: moduleSetupSurface.surfaceId, + // moduleSetupArray: setupedModules, + // }) + // setModuleIsSetup(moduleArray) }) } From e1eae2ae4547e432ee5e457b8686a57e4e9d2656 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 3 Dec 2024 18:31:31 +0900 Subject: [PATCH 38/98] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placementShape/PlacementShapeSetting.jsx | 103 ++------------- .../modal/placementShape/SizeGuide.jsx | 2 +- src/hooks/option/useCanvasSetting.js | 119 +++++++++++++++++- 3 files changed, 125 insertions(+), 99 deletions(-) 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/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index e48d6b76..75ed2aba 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -89,6 +89,7 @@ export const useEstimateController = (planNo) => { partAdd: '1', //NEW 체인지 플래그 delFlg: '0', //삭제 플래그 0 삭제하면 1 addFlg: true, + paDispOrder: null, }, ], }) From 66376f4a3069ca3f0f8467419d31c84986e0b997 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 29 Nov 2024 18:13:46 +0900 Subject: [PATCH 04/98] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EA=B4=80=EB=A0=A8=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 424 +++++++++++++--------- 1 file changed, 255 insertions(+), 169 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index b7b941f3..7a72a379 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -9,9 +9,9 @@ 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 { EventContext } from '@/app/floor-plan/EventProvider' +import { v4 as uuidv4 } from 'uuid' export function useModuleBasicSetting() { const canvas = useRecoilValue(canvasState) @@ -20,7 +20,6 @@ export function useModuleBasicSetting() { const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState) const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useEvent() // const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) - const [flowModuleLine, setFlowModuleLine] = useState({}) let selectedModuleInstSurfaceArray = [] const makeModuleInstArea = () => { @@ -35,6 +34,9 @@ export function useModuleBasicSetting() { setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경 const offsetPoints = offsetPolygon(roof.points, -20) //안쪽 offset //모듈설치영역?? 생성 + + const surfaceId = uuidv4() + let setupSurface = new QPolygon(offsetPoints, { stroke: 'red', fill: 'transparent', @@ -51,15 +53,20 @@ export function useModuleBasicSetting() { flowDirection: roof.direction, flipX: roof.flipX, flipY: roof.flipY, + surfaceId: surfaceId, }) setupSurface.setViewLengthText(false) canvas.add(setupSurface) //모듈설치면 만들기 if (setupSurface.flowDirection === 'south' || setupSurface.flowDirection === 'north') { - setFlowModuleLine(bottomTopFlowLine(setupSurface)) + setupSurface.set({ + flowLines: bottomTopFlowLine(setupSurface), + }) } else { - setFlowModuleLine(leftRightFlowLine(setupSurface)) + setupSurface.set({ + flowLines: leftRightFlowLine(setupSurface), + }) } //지붕면 선택 금지 @@ -423,6 +430,13 @@ export function useModuleBasicSetting() { }) } + //어짜피 자동으로 누르면 선택안된데도 다 날아간다 + canvas.getObjects().forEach((obj) => { + if (obj.name === 'module') { + canvas.remove(obj) + } + }) + notSelectedTrestlePolygons.forEach((obj) => { if (obj.modules) { obj.modules.forEach((module) => { @@ -437,16 +451,18 @@ export function useModuleBasicSetting() { stroke: 'black', strokeWidth: 0.1, selectable: false, // 선택 가능하게 설정 - lockMovementX: false, // X 축 이동 잠금 - lockMovementY: false, // Y 축 이동 잠금 - lockRotation: false, // 회전 잠금 - lockScalingX: false, // X 축 크기 조정 잠금 - lockScalingY: false, // Y 축 크기 조정 잠금 + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + lockScalingX: true, // X 축 크기 조정 잠금 + lockScalingY: true, // Y 축 크기 조정 잠금 opacity: 0.8, parentId: moduleSetupSurface.parentId, name: 'module', } + let leftMargin, bottomMargin, square, chidoriLength + //선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환 const objectsIncludeSurface = (turfModuleSetupSurface) => { let containsBatchObjects = [] @@ -510,6 +526,173 @@ export function useModuleBasicSetting() { return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) } + const downFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 + const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 + const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 + + let startPoint = flowModuleLine.find((obj) => obj.target === 'bottom') + + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 + let totalTopEndPoint = maxTopEndPoint - startPoint.y1 + let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) + let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + + for (let j = 0; j < diffTopEndPoint; j++) { + bottomMargin = j === 0 ? 1 : 0 + for (let i = 0; i <= totalWidth; i++) { + leftMargin = i === 0 ? 1 : 0 //숫자가 0이면 0, 1이면 1로 바꾸기 + chidoriLength = 0 + if (isChidori) { + chidoriLength = j % 2 === 0 ? 0 : width / 2 + } + + square = [ + [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], + [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - bottomMargin], + [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], + [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { + let startPoint = flowModuleLine.find((obj) => obj.target === 'left') + + const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 + const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 + const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단 + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) + let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width + let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) + + for (let j = 0; j < totalHeight; j++) { + bottomMargin = j === 0 ? 1 : 0 + for (let i = 0; i <= totalWidth; i++) { + leftMargin = 1 + chidoriLength = 0 + if (isChidori) { + chidoriLength = i % 2 === 0 ? 0 : height / 2 + } + + square = [ + [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], + ] + + console.log('square', square) + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + const topFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { + let startPoint = flowModuleLine.find((obj) => obj.target === 'top') + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 + const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 + + const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단 + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 + let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint + let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1 + let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) + let diffRightEndPoint = Math.abs(totalRightEndPoint / width) + let diffBottomEndPoint = Math.abs(totalBottomEndPoint / height) + let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + + for (let j = 0; j < diffBottomEndPoint; j++) { + for (let i = 0; i < diffRightEndPoint; i++) { + chidoriLength = 0 + if (isChidori) { + chidoriLength = j % 2 === 0 ? 0 : width / 2 + } + square = [ + [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + 1], + [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + height + 1], + [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j + height + 1], + [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j + 1], + [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + 1], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + + const rightFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { + let startPoint = flowModuleLine.find((obj) => obj.target === 'right') + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 + + const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 + const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단 + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 + let diffTopEndPoint = Math.abs(totalTopEndPoint / height) + let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) + let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width + let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) + + for (let j = 0; j < totalHeight; j++) { + bottomMargin = j === 0 ? 1 : 0 + for (let i = 0; i <= totalWidth; i++) { + leftMargin = 1 + chidoriLength = 0 + if (isChidori) { + chidoriLength = i % 2 === 0 ? 0 : height / 2 + } + + square = [ + [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j + height + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + height + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + bottomMargin + chidoriLength], + ] + + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + + // if (disjointFromTrestle && isDisjoint) { + let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + } + } + } + moduleSetupSurfaces.forEach((moduleSetupSurface, index) => { moduleSetupSurface.fire('mousedown') const moduleSetupArray = [] @@ -531,166 +714,34 @@ export function useModuleBasicSetting() { } const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface) - const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 - const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 - const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 - const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최 하단 - let leftMargin, bottomMargin, square, chidoriLength //처마면 배치 if (setupLocation === 'eaves') { // 흐름방향이 남쪽일때 if (moduleSetupSurface.flowDirection === 'south') { - let startPoint = flowModuleLine.find((obj) => obj.target === 'bottom') - let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 - let totalTopEndPoint = maxTopEndPoint - startPoint.y1 - let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) - let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) - let diffTopEndPoint = Math.abs(totalTopEndPoint / height) - let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) - - for (let j = 0; j < diffTopEndPoint; j++) { - bottomMargin = j === 0 ? 1 : 0 - for (let i = 0; i <= totalWidth; i++) { - leftMargin = i === 0 ? 1 : 0 //숫자가 0이면 0, 1이면 1로 바꾸기 - chidoriLength = 0 - if (isChidori) { - chidoriLength = j % 2 === 0 ? 0 : width / 2 - } - - square = [ - [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], - [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - bottomMargin], - [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], - ] - - let squarePolygon = turf.polygon([square]) - let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - - // if (disjointFromTrestle && isDisjoint) { - let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - } + downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } - if (moduleSetupSurface.flowDirection === 'west') { - let startPoint = flowModuleLine.find((obj) => obj.target === 'left') - let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 - let diffTopEndPoint = Math.abs(totalTopEndPoint / height) - let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) - let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width - let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - - for (let j = 0; j < totalHeight; j++) { - bottomMargin = j === 0 ? 1 : 0 - for (let i = 0; i <= totalWidth; i++) { - leftMargin = 1 - chidoriLength = 0 - if (isChidori) { - chidoriLength = i % 2 === 0 ? 0 : height / 2 - } - - square = [ - [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], - ] - - let squarePolygon = turf.polygon([square]) - let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - - // if (disjointFromTrestle && isDisjoint) { - let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - } + leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'east') { + rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'north') { + topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } } else if (setupLocation === 'ridge') { if (moduleSetupSurface.flowDirection === 'south') { - let startPoint = flowModuleLine.find((obj) => obj.target === 'top') - let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 - let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint - let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1 - let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) - let diffRightEndPoint = Math.abs(totalRightEndPoint / width) - let diffBottomEndPoint = Math.abs(totalBottomEndPoint / height) - let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) - - for (let j = 0; j < diffBottomEndPoint; j++) { - for (let i = 0; i < diffRightEndPoint; i++) { - chidoriLength = 0 - if (isChidori) { - chidoriLength = j % 2 === 0 ? 0 : width / 2 - } - square = [ - [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j], - [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + height], - [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j + height], - [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j], - [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j], - ] - - let squarePolygon = turf.polygon([square]) - let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - - // if (disjointFromTrestle && isDisjoint) { - let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - } + topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } if (moduleSetupSurface.flowDirection === 'west') { - let startPoint = flowModuleLine.find((obj) => obj.target === 'right') - //계산하기 편하게 그냥 y1을 작은수로 만든다 - let correctPoint = - startPoint.y1 > startPoint.y2 - ? { x1: startPoint.x2, x2: startPoint.x1, y1: startPoint.y2, y2: startPoint.y1 } - : { x1: startPoint.x1, x2: startPoint.x2, y1: startPoint.y1, y2: startPoint.y2 } - - let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 - let diffTopEndPoint = Math.abs(totalTopEndPoint / height) - let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) - let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width - let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - - for (let j = 0; j < totalHeight; j++) { - bottomMargin = j === 0 ? 1 : 0 - for (let i = 0; i <= totalWidth; i++) { - leftMargin = 1 - chidoriLength = 0 - if (isChidori) { - chidoriLength = i % 2 === 0 ? 0 : height / 2 - } - - square = [ - [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j - bottomMargin + chidoriLength], - [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j - bottomMargin + chidoriLength], - [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j + height - bottomMargin + chidoriLength], - [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + height - bottomMargin + chidoriLength], - [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j - bottomMargin + chidoriLength], - ] - - let squarePolygon = turf.polygon([square]) - let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - - // if (disjointFromTrestle && isDisjoint) { - let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - } - } + rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'east') { + leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) + } + if (moduleSetupSurface.flowDirection === 'north') { + downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } } else { } @@ -872,9 +923,8 @@ export function useModuleBasicSetting() { ) flowArray.push(topFlow) - let idx = 0 let rtnObjArray = [] - flowArray.forEach((center) => { + flowArray.forEach((center, index) => { const linesArray = new Array() surface.lines.filter((line) => { @@ -926,33 +976,40 @@ export function useModuleBasicSetting() { }) canvas?.add(finalLine) canvas?.renderAll() - let rtnObj + let rtnObj + //평평하면 if (alpha === 0 || beta === 0 || h === 0 || sign === 0) { //꼭지점이 없고 평평할때 ex) 네모 let standardLine - if (center.index === 0) { + if (index === 0) { + //bottom standardLine = surface.lines.reduce((acc, line, index) => { - if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) { + if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.y2 > acc.y2)) { return { x1: line.x1, y1: line.y1, index: index } } return acc }) } else { standardLine = surface.lines.reduce((acc, line, index) => { - if (line.y1 > acc.y1) { + if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.y2 < acc.y2)) { return { x1: line.x1, y1: line.y1, index: index } } return acc }) } - rtnObj = { target: idx === 0 ? 'bottom' : 'top', x1: standardLine.x1, y1: pointY1, x2: standardLine.x1 + charlie, y2: pointY2 } + rtnObj = { + target: index === 0 ? 'bottom' : 'top', + x1: standardLine.x1, + y1: standardLine.y1, + x2: standardLine.x1 + charlie, + y2: standardLine.y1, + } } else { - rtnObj = { target: idx === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + rtnObj = { target: index === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } } rtnObjArray.push(rtnObj) - ++idx }) return rtnObjArray @@ -984,7 +1041,7 @@ export function useModuleBasicSetting() { let idx = 0 let rtnObjArray = [] - flowArray.forEach((center) => { + flowArray.forEach((center, index) => { const linesArray = surface.lines.filter((line) => { if ((center.x1 === line.x1 && center.y1 === line.y1) || (center.x1 === line.x2 && center.y1 === line.y2)) { return line @@ -1043,9 +1100,38 @@ export function useModuleBasicSetting() { canvas?.add(finalLine) canvas?.renderAll() - const rtnObj = { target: idx === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + let rtnObj + //평평하면 + if (alpha === 0 || beta === 0 || h === 0 || sign === 0) { + //꼭지점이 없고 평평할때 ex) 네모 + let standardLine + if (index === 0) { + //bottom + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) { + return { x1: line.x1, y1: line.y1, index: index } + } + return acc + }) + } else { + standardLine = surface.lines.reduce((acc, line, index) => { + if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) { + return { x1: line.x1, y1: line.y1, index: index } + } + return acc + }) + } + rtnObj = { + target: index === 0 ? 'left' : 'right', + x1: standardLine.x1, + y1: standardLine.y1, + x2: standardLine.x1, + y2: standardLine.y1 + charlie, + } + } else { + rtnObj = { target: idx === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + } rtnObjArray.push(rtnObj) - ++idx }) return rtnObjArray } From 5e54269456d830770ed88a831a4e941fdb009e91 Mon Sep 17 00:00:00 2001 From: basssy Date: Sat, 30 Nov 2024 22:19:30 +0900 Subject: [PATCH 05/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 81 ++++++++++++++----- .../estimate/useEstimateController.js | 30 ++++++- 2 files changed, 87 insertions(+), 24 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 578b16fa..d5739680 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -20,6 +20,7 @@ import ProductFeaturesPop from './popup/ProductFeaturesPop' import { v4 as uuidv4 } from 'uuid' export default function Estimate({ params }) { + const [uniqueData, setUniqueData] = useState([]) const [handlePricingFlag, setHandlePricingFlag] = useState(false) const [specialNoteFirstFlg, setSpecialNoteFirstFlg] = useState(false) const fixedKey = 'itemKey' @@ -123,7 +124,6 @@ export default function Estimate({ params }) { if (estimateContextState?.estimateOption) { res.map((row) => { let estimateOption = estimateContextState?.estimateOption?.split('、') - // console.log('최초:::', estimateOption) row.check = false estimateOption.map((row2) => { if (row.pkgYn === '0') { @@ -175,6 +175,8 @@ export default function Estimate({ params }) { useEffect(() => { //선택된 견적특이사항 setEstimateContextState + + // console.log('specialNoteList::', specialNoteList) if (isNotEmptyArray(specialNoteList)) { const liveCheckedData = specialNoteList.filter((row) => row.check === true) @@ -184,7 +186,9 @@ export default function Estimate({ params }) { } const newData = data.join('、') - setEstimateContextState({ estimateOption: newData }) + //저장용 보내기 + // console.log('유니크??', uniqueData) + setEstimateContextState({ estimateOption: newData, specialNoteList: specialNoteList, uniqueData: uniqueData }) } }, [specialNoteList]) @@ -309,6 +313,52 @@ export default function Estimate({ params }) { }) } + const makeUniqueSpecialNoteCd = (itemList) => { + let pushData = [] + let uniquSet = new Set() + + itemList.forEach((item) => { + if (item.delFlg === '0') { + if (item.specialNoteCd) { + let splitData = item.specialNoteCd.split('、') + splitData.forEach((note) => { + if (!uniquSet.has(note)) { + uniquSet.add(note) + pushData.push(note) + } + }) + + setSpecialNoteFirstFlg(false) + } + } + }) + + // console.log('특이사항 유니크:::', pushData) + setUniqueData(pushData) + specialNoteList.map((item) => { + if (item.pkgYn === '1') { + let flg = '0' + let codes = item.code + for (let i = 0; i < pushData.length; i++) { + if (codes.indexOf(pushData[i]) > -1) { + flg = '1' + } + } + + if (flg === '1') { + item.check = true + } else { + item.check = false + } + } + }) + + setEstimateContextState({ + specialNoteList: specialNoteList, + uniqueData: uniqueData, + }) + } + //Pricing 버튼 const handlePricing = async (showPriceCd) => { const param = { @@ -656,26 +706,10 @@ export default function Estimate({ params }) { estimateContextState.itemList.sort((a, b) => { return a.dispOrder - b.dispOrder }) - console.log('YJOD 토탈만들어주기::::::::::', estimateContextState.itemList) + // console.log('YJOD 토탈만들어주기::::::::::', estimateContextState.itemList) - let pushData = [] - let uniquSet = new Set() - - estimateContextState.itemList.forEach((item) => { - if (item.delFlg === '1') { - if (item.specialNoteCd) { - let splitData = item.specialNoteCd.split('、') - splitData.forEach((note) => { - if (!uniquSet.has(note)) { - uniquSet.add(note) - pushData.push(note) - } - }) - - setSpecialNoteFirstFlg(false) - } - } - }) + //아이템에서 제품관련 특이사항 중복제거해서 만드는 함수 + makeUniqueSpecialNoteCd(estimateContextState.itemList) estimateContextState.itemList.map((item) => { delete item.showSalePrice @@ -712,8 +746,10 @@ export default function Estimate({ params }) { totPrice: totPrice.toFixed(3), }) } else { + //아이템에서 제품관련 특이사항 중복제거해서 만드는 함수 + makeUniqueSpecialNoteCd(estimateContextState.itemList) //YJSS - console.log('YJSS 토탈만들어주기::::::::::', estimateContextState.itemList) + // console.log('YJSS 토탈만들어주기::::::::::', estimateContextState.itemList) estimateContextState.itemList.sort((a, b) => { return a.dispOrder - b.dispOrder }) @@ -1127,6 +1163,7 @@ export default function Estimate({ params }) { setSpecialNoteList((specialNote) => specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)), ) + settingShowContent(row.code, event) }} /> diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 75ed2aba..f40d171e 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -242,8 +242,34 @@ export const useEstimateController = (planNo) => { } }) - console.log('아이템리스트::', estimateData.itemList) - console.log('최종 정보::;', estimateData) + let estimateOptions = '' + 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] + } + } + } + } + }) + estimateData.estimateOption = estimateOptions + // console.log('최종첨부파일:::', estimateData.fileList) + // console.log('최종아이템:::', estimateData.itemList) + // console.log('최종저장::', estimateData) //2. 상세데이터 저장 // return try { From eaa38270dbecec8d1c4c413c56e93694b8643730 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Mon, 2 Dec 2024 09:12:45 +0900 Subject: [PATCH 06/98] =?UTF-8?q?=F0=9F=93=8Cchore:=20lock=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20pipe=20=ED=95=A8=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/common-utils.js | 7 + yarn.lock | 617 +++++++++++---------------------------- 2 files changed, 174 insertions(+), 450 deletions(-) diff --git a/src/util/common-utils.js b/src/util/common-utils.js index 5a7ebde4..a5f689db 100644 --- a/src/util/common-utils.js +++ b/src/util/common-utils.js @@ -93,3 +93,10 @@ export const inputNumberCheck = (e) => { input.value = input.value.replace(/[^\d]/g, '') } } + +/** + * 파이프함수 정의 + * @param {...any} fns 순수함수들 + * @returns + */ +export const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x) diff --git a/yarn.lock b/yarn.lock index 1a4d340d..6dd98dd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -223,7 +223,14 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.20.13", "@babel/runtime@^7.24.8": +"@babel/runtime@^7.20.13": + version "7.25.0" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.24.8": version "7.25.0" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz" integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== @@ -532,21 +539,6 @@ resolved "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz" integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw== -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" - integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - "@next/env@14.2.14": version "14.2.14" resolved "https://registry.npmjs.org/@next/env/-/env-14.2.14.tgz" @@ -1251,7 +1243,7 @@ "@react-types/shared" "3.23.1" clsx "^1.2.1" -"@nextui-org/system@2.2.5": +"@nextui-org/system@>=2.0.0", "@nextui-org/system@>=2.1.0", "@nextui-org/system@2.2.5": version "2.2.5" resolved "https://registry.npmjs.org/@nextui-org/system/-/system-2.2.5.tgz" integrity sha512-nrX6768aiyWtpxX3OTFBIVWR+v9nlMsC3KaBinNfek97sNm7gAfTHi7q5kylE3L5yIMpNG+DclAKpuxgDQEmvw== @@ -1304,7 +1296,7 @@ "@react-types/tabs" "3.3.7" scroll-into-view-if-needed "3.0.10" -"@nextui-org/theme@2.2.9": +"@nextui-org/theme@>=2.1.0", "@nextui-org/theme@>=2.2.0", "@nextui-org/theme@2.2.9": version "2.2.9" resolved "https://registry.npmjs.org/@nextui-org/theme/-/theme-2.2.9.tgz" integrity sha512-TN2I9sMriLaj00pXsIMlg19+UHeOdjzS2JV0u4gjL14mSbQl5BYNxgbvU3gbMqkZZQ6OpwT4RnT8RS+ks6TXCw== @@ -1525,7 +1517,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1658,7 +1650,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/focus@3.17.1", "@react-aria/focus@^3.17.1": +"@react-aria/focus@^3.17.1", "@react-aria/focus@3.17.1": version "3.17.1" resolved "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz" integrity sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ== @@ -1680,7 +1672,7 @@ "@swc/helpers" "^0.5.0" clsx "^2.0.0" -"@react-aria/form@3.0.5", "@react-aria/form@^3.0.5": +"@react-aria/form@^3.0.5", "@react-aria/form@3.0.5": version "3.0.5" resolved "https://registry.npmjs.org/@react-aria/form/-/form-3.0.5.tgz" integrity sha512-n290jRwrrRXO3fS82MyWR+OKN7yznVesy5Q10IclSTVYHHI3VI53xtAPr/WzNjJR1um8aLhOcDNFKwnNIUUCsQ== @@ -1710,7 +1702,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/i18n@3.11.1", "@react-aria/i18n@^3.11.1": +"@react-aria/i18n@^3.11.1", "@react-aria/i18n@3.11.1": version "3.11.1" resolved "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.11.1.tgz" integrity sha512-vuiBHw1kZruNMYeKkTGGnmPyMnM5T+gT8bz97H1FqIq1hQ6OPzmtBZ6W6l6OIMjeHI5oJo4utTwfZl495GALFQ== @@ -1738,7 +1730,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/interactions@3.21.3", "@react-aria/interactions@^3.21.3": +"@react-aria/interactions@^3.21.3", "@react-aria/interactions@3.21.3": version "3.21.3" resolved "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz" integrity sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA== @@ -1758,7 +1750,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/label@3.7.8", "@react-aria/label@^3.7.8": +"@react-aria/label@^3.7.8", "@react-aria/label@3.7.8": version "3.7.8" resolved "https://registry.npmjs.org/@react-aria/label/-/label-3.7.8.tgz" integrity sha512-MzgTm5+suPA3KX7Ug6ZBK2NX9cin/RFLsv1BdafJ6CZpmUSpWnGE/yQfYUB7csN7j31OsZrD3/P56eShYWAQfg== @@ -1767,7 +1759,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/link@3.7.1", "@react-aria/link@^3.7.1": +"@react-aria/link@^3.7.1", "@react-aria/link@3.7.1": version "3.7.1" resolved "https://registry.npmjs.org/@react-aria/link/-/link-3.7.1.tgz" integrity sha512-a4IaV50P3fXc7DQvEIPYkJJv26JknFbRzFT5MJOMgtzuhyJoQdILEUK6XHYjcSSNCA7uLgzpojArVk5Hz3lCpw== @@ -1779,7 +1771,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/listbox@3.12.1", "@react-aria/listbox@^3.12.1": +"@react-aria/listbox@^3.12.1", "@react-aria/listbox@3.12.1": version "3.12.1" resolved "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.12.1.tgz" integrity sha512-7JiUp0NGykbv/HgSpmTY1wqhuf/RmjFxs1HZcNaTv8A+DlzgJYc7yQqFjP3ZA/z5RvJFuuIxggIYmgIFjaRYdA== @@ -1801,7 +1793,7 @@ dependencies: "@swc/helpers" "^0.5.0" -"@react-aria/menu@3.14.1", "@react-aria/menu@^3.14.1": +"@react-aria/menu@^3.14.1", "@react-aria/menu@3.14.1": version "3.14.1" resolved "https://registry.npmjs.org/@react-aria/menu/-/menu-3.14.1.tgz" integrity sha512-BYliRb38uAzq05UOFcD5XkjA5foQoXRbcH3ZufBsc4kvh79BcP1PMW6KsXKGJ7dC/PJWUwCui6QL1kUg8PqMHA== @@ -1820,7 +1812,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/overlays@3.22.1", "@react-aria/overlays@^3.22.1": +"@react-aria/overlays@^3.22.1", "@react-aria/overlays@3.22.1": version "3.22.1" resolved "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.22.1.tgz" integrity sha512-GHiFMWO4EQ6+j6b5QCnNoOYiyx1Gk8ZiwLzzglCI4q1NY5AG2EAmfU4Z1+Gtrf2S5Y0zHbumC7rs9GnPoGLUYg== @@ -1865,7 +1857,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-aria/selection@3.18.1", "@react-aria/selection@^3.18.1": +"@react-aria/selection@^3.18.1", "@react-aria/selection@3.18.1": version "3.18.1" resolved "https://registry.npmjs.org/@react-aria/selection/-/selection-3.18.1.tgz" integrity sha512-GSqN2jX6lh7v+ldqhVjAXDcrWS3N4IsKXxO6L6Ygsye86Q9q9Mq9twWDWWu5IjHD6LoVZLUBCMO+ENGbOkyqeQ== @@ -1918,7 +1910,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-aria/ssr@3.9.4", "@react-aria/ssr@^3.9.4": +"@react-aria/ssr@^3.9.4", "@react-aria/ssr@3.9.4": version "3.9.4" resolved "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz" integrity sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ== @@ -1978,7 +1970,7 @@ "@react-types/tabs" "^3.3.7" "@swc/helpers" "^0.5.0" -"@react-aria/textfield@3.14.5", "@react-aria/textfield@^3.14.5": +"@react-aria/textfield@^3.14.5", "@react-aria/textfield@3.14.5": version "3.14.5" resolved "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.5.tgz" integrity sha512-hj7H+66BjB1iTKKaFXwSZBZg88YT+wZboEXZ0DNdQB2ytzoz/g045wBItUuNi4ZjXI3P+0AOZznVMYadWBAmiA== @@ -2019,7 +2011,7 @@ "@react-types/tooltip" "^3.4.9" "@swc/helpers" "^0.5.0" -"@react-aria/utils@3.24.1", "@react-aria/utils@^3.24.1": +"@react-aria/utils@^3.24.1", "@react-aria/utils@3.24.1": version "3.24.1" resolved "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz" integrity sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q== @@ -2041,7 +2033,7 @@ "@swc/helpers" "^0.5.0" clsx "^2.0.0" -"@react-aria/visually-hidden@3.8.12", "@react-aria/visually-hidden@^3.8.12": +"@react-aria/visually-hidden@^3.8.12", "@react-aria/visually-hidden@3.8.12": version "3.8.12" resolved "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.12.tgz" integrity sha512-Bawm+2Cmw3Xrlr7ARzl2RLtKh0lNUdJ0eNqzWcyx4c0VHUAWtThmH5l+HRqFUGzzutFZVo89SAy40BAbd0gjVw== @@ -2051,7 +2043,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/calendar@3.5.1", "@react-stately/calendar@^3.5.1": +"@react-stately/calendar@^3.5.1", "@react-stately/calendar@3.5.1": version "3.5.1" resolved "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.1.tgz" integrity sha512-7l7QhqGUJ5AzWHfvZzbTe3J4t72Ht5BmhW4hlVI7flQXtfrmYkVtl3ZdytEZkkHmWGYZRW9b4IQTQGZxhtlElA== @@ -2062,7 +2054,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/checkbox@3.6.5", "@react-stately/checkbox@^3.6.5": +"@react-stately/checkbox@^3.6.5", "@react-stately/checkbox@3.6.5": version "3.6.5" resolved "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.5.tgz" integrity sha512-IXV3f9k+LtmfQLE+DKIN41Q5QB/YBLDCB1YVx5PEdRp52S9+EACD5683rjVm8NVRDwjMi2SP6RnFRk7fVb5Azg== @@ -2073,7 +2065,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/collections@3.10.7", "@react-stately/collections@^3.10.7": +"@react-stately/collections@^3.10.7", "@react-stately/collections@3.10.7": version "3.10.7" resolved "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.7.tgz" integrity sha512-KRo5O2MWVL8n3aiqb+XR3vP6akmHLhLWYZEmPKjIv0ghQaEebBTrN3wiEjtd6dzllv0QqcWvDLM1LntNfJ2TsA== @@ -2089,7 +2081,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/combobox@3.8.4", "@react-stately/combobox@^3.8.4": +"@react-stately/combobox@^3.8.4", "@react-stately/combobox@3.8.4": version "3.8.4" resolved "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.8.4.tgz" integrity sha512-iLVGvKRRz0TeJXZhZyK783hveHpYA6xovOSdzSD+WGYpiPXo1QrcrNoH3AE0Z2sHtorU+8nc0j58vh5PB+m2AA== @@ -2104,7 +2096,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/datepicker@3.9.4", "@react-stately/datepicker@^3.9.4": +"@react-stately/datepicker@^3.9.4", "@react-stately/datepicker@3.9.4": version "3.9.4" resolved "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.9.4.tgz" integrity sha512-yBdX01jn6gq4NIVvHIqdjBUPo+WN8Bujc4OnPw+ZnfA4jI0eIgq04pfZ84cp1LVXW0IB0VaCu1AlQ/kvtZjfGA== @@ -2125,7 +2117,7 @@ dependencies: "@swc/helpers" "^0.5.0" -"@react-stately/form@3.0.3", "@react-stately/form@^3.0.3": +"@react-stately/form@^3.0.3", "@react-stately/form@3.0.3": version "3.0.3" resolved "https://registry.npmjs.org/@react-stately/form/-/form-3.0.3.tgz" integrity sha512-92YYBvlHEWUGUpXgIaQ48J50jU9XrxfjYIN8BTvvhBHdD63oWgm8DzQnyT/NIAMzdLnhkg7vP+fjG8LjHeyIAg== @@ -2152,7 +2144,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/list@3.10.5", "@react-stately/list@^3.10.5": +"@react-stately/list@^3.10.5", "@react-stately/list@3.10.5": version "3.10.5" resolved "https://registry.npmjs.org/@react-stately/list/-/list-3.10.5.tgz" integrity sha512-fV9plO+6QDHiewsYIhboxcDhF17GO95xepC5ki0bKXo44gr14g/LSo/BMmsaMnV+1BuGdBunB05bO4QOIaigXA== @@ -2174,7 +2166,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/menu@3.7.1", "@react-stately/menu@^3.7.1": +"@react-stately/menu@^3.7.1", "@react-stately/menu@3.7.1": version "3.7.1" resolved "https://registry.npmjs.org/@react-stately/menu/-/menu-3.7.1.tgz" integrity sha512-mX1w9HHzt+xal1WIT2xGrTQsoLvDwuB2R1Er1MBABs//MsJzccycatcgV/J/28m6tO5M9iuFQQvLV+i1dCtodg== @@ -2184,7 +2176,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/overlays@3.6.7", "@react-stately/overlays@^3.6.7": +"@react-stately/overlays@^3.6.7", "@react-stately/overlays@3.6.7": version "3.6.7" resolved "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.7.tgz" integrity sha512-6zp8v/iNUm6YQap0loaFx6PlvN8C0DgWHNlrlzMtMmNuvjhjR0wYXVaTfNoUZBWj25tlDM81ukXOjpRXg9rLrw== @@ -2202,7 +2194,7 @@ "@react-types/overlays" "^3.8.9" "@swc/helpers" "^0.5.0" -"@react-stately/radio@3.10.4", "@react-stately/radio@^3.10.4": +"@react-stately/radio@^3.10.4", "@react-stately/radio@3.10.4": version "3.10.4" resolved "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.4.tgz" integrity sha512-kCIc7tAl4L7Hu4Wt9l2jaa+MzYmAJm0qmC8G8yPMbExpWbLRu6J8Un80GZu+JxvzgDlqDyrVvyv9zFifwH/NkQ== @@ -2235,7 +2227,7 @@ "@react-types/shared" "^3.24.1" "@swc/helpers" "^0.5.0" -"@react-stately/slider@3.5.4", "@react-stately/slider@^3.5.4": +"@react-stately/slider@^3.5.4", "@react-stately/slider@3.5.4": version "3.5.4" resolved "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.4.tgz" integrity sha512-Jsf7K17dr93lkNKL9ij8HUcoM1sPbq8TvmibD6DhrK9If2lje+OOL8y4n4qreUnfMT56HCAeS9wCO3fg3eMyrw== @@ -2245,7 +2237,7 @@ "@react-types/slider" "^3.7.3" "@swc/helpers" "^0.5.0" -"@react-stately/table@3.11.8", "@react-stately/table@^3.11.8": +"@react-stately/table@^3.11.8", "@react-stately/table@3.11.8": version "3.11.8" resolved "https://registry.npmjs.org/@react-stately/table/-/table-3.11.8.tgz" integrity sha512-EdyRW3lT1/kAVDp5FkEIi1BQ7tvmD2YgniGdLuW/l9LADo0T+oxZqruv60qpUS6sQap+59Riaxl91ClDxrJnpg== @@ -2260,7 +2252,7 @@ "@react-types/table" "^3.9.5" "@swc/helpers" "^0.5.0" -"@react-stately/tabs@3.6.6", "@react-stately/tabs@^3.6.6": +"@react-stately/tabs@^3.6.6", "@react-stately/tabs@3.6.6": version "3.6.6" resolved "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.6.tgz" integrity sha512-sOLxorH2uqjAA+v1ppkMCc2YyjgqvSGeBDgtR/lyPSDd4CVMoTExszROX2dqG0c8il9RQvzFuufUtQWMY6PgSA== @@ -2270,7 +2262,7 @@ "@react-types/tabs" "^3.3.7" "@swc/helpers" "^0.5.0" -"@react-stately/toggle@3.7.4", "@react-stately/toggle@^3.7.4": +"@react-stately/toggle@^3.7.4", "@react-stately/toggle@3.7.4": version "3.7.4" resolved "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.4.tgz" integrity sha512-CoYFe9WrhLkDP4HGDpJYQKwfiYCRBAeoBQHv+JWl5eyK61S8xSwoHsveYuEZ3bowx71zyCnNAqWRrmNOxJ4CKA== @@ -2288,7 +2280,7 @@ "@react-types/checkbox" "^3.8.3" "@swc/helpers" "^0.5.0" -"@react-stately/tooltip@3.4.9", "@react-stately/tooltip@^3.4.9": +"@react-stately/tooltip@^3.4.9", "@react-stately/tooltip@3.4.9": version "3.4.9" resolved "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.9.tgz" integrity sha512-P7CDJsdoKarz32qFwf3VNS01lyC+63gXpDZG31pUu+EO5BeQd4WKN/AH1Beuswpr4GWzxzFc1aXQgERFGVzraA== @@ -2297,7 +2289,7 @@ "@react-types/tooltip" "^3.4.9" "@swc/helpers" "^0.5.0" -"@react-stately/tree@3.8.1", "@react-stately/tree@^3.8.1": +"@react-stately/tree@^3.8.1", "@react-stately/tree@3.8.1": version "3.8.1" resolved "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.1.tgz" integrity sha512-LOdkkruJWch3W89h4B/bXhfr0t0t1aRfEp+IMrrwdRAl23NaPqwl5ILHs4Xu5XDHqqhg8co73pHrJwUyiTWEjw== @@ -2308,7 +2300,7 @@ "@react-types/shared" "^3.23.1" "@swc/helpers" "^0.5.0" -"@react-stately/utils@3.10.1", "@react-stately/utils@^3.10.1": +"@react-stately/utils@^3.10.1", "@react-stately/utils@3.10.1": version "3.10.1" resolved "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz" integrity sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg== @@ -2322,7 +2314,7 @@ dependencies: "@swc/helpers" "^0.5.0" -"@react-stately/virtualizer@3.7.1", "@react-stately/virtualizer@^3.7.1": +"@react-stately/virtualizer@^3.7.1", "@react-stately/virtualizer@3.7.1": version "3.7.1" resolved "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-3.7.1.tgz" integrity sha512-voHgE6EQ+oZaLv6u2umKxakvIKNkCQuUihqKACTjdslp7SJh4Mvs3oLBI0hf0JOh+rCcFIKDvQtFwy1fXFRYBA== @@ -2338,7 +2330,7 @@ dependencies: "@react-types/shared" "^3.23.1" -"@react-types/breadcrumbs@3.7.5", "@react-types/breadcrumbs@^3.7.5": +"@react-types/breadcrumbs@^3.7.5", "@react-types/breadcrumbs@3.7.5": version "3.7.5" resolved "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.5.tgz" integrity sha512-lV9IDYsMiu2TgdMIjEmsOE0YWwjb3jhUNK1DCZZfq6uWuiHLgyx2EncazJBUWSjHJ4ta32j7xTuXch+8Ai6u/A== @@ -2346,7 +2338,7 @@ "@react-types/link" "^3.5.5" "@react-types/shared" "^3.23.1" -"@react-types/button@3.9.4", "@react-types/button@^3.9.4": +"@react-types/button@^3.9.4", "@react-types/button@3.9.4": version "3.9.4" resolved "https://registry.npmjs.org/@react-types/button/-/button-3.9.4.tgz" integrity sha512-raeQBJUxBp0axNF74TXB8/H50GY8Q3eV6cEKMbZFP1+Dzr09Ngv0tJBeW0ewAxAguNH5DRoMUAUGIXtSXskVdA== @@ -2360,7 +2352,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/calendar@3.4.6", "@react-types/calendar@^3.4.6": +"@react-types/calendar@^3.4.6", "@react-types/calendar@3.4.6": version "3.4.6" resolved "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.6.tgz" integrity sha512-WSntZPwtvsIYWvBQRAPvuCn55UTJBZroTvX0vQvWykJRQnPAI20G1hMQ3dNsnAL+gLZUYxBXn66vphmjUuSYew== @@ -2368,7 +2360,7 @@ "@internationalized/date" "^3.5.4" "@react-types/shared" "^3.23.1" -"@react-types/checkbox@3.8.1", "@react-types/checkbox@^3.8.1": +"@react-types/checkbox@^3.8.1", "@react-types/checkbox@3.8.1": version "3.8.1" resolved "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.1.tgz" integrity sha512-5/oVByPw4MbR/8QSdHCaalmyWC71H/QGgd4aduTJSaNi825o+v/hsN2/CH7Fq9atkLKsC8fvKD00Bj2VGaKriQ== @@ -2382,14 +2374,14 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/combobox@3.11.1", "@react-types/combobox@^3.11.1": +"@react-types/combobox@^3.11.1", "@react-types/combobox@3.11.1": version "3.11.1" resolved "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.11.1.tgz" integrity sha512-UNc3OHt5cUt5gCTHqhQIqhaWwKCpaNciD8R7eQazmHiA9fq8ROlV+7l3gdNgdhJbTf5Bu/V5ISnN7Y1xwL3zqQ== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/datepicker@3.7.4", "@react-types/datepicker@^3.7.4": +"@react-types/datepicker@^3.7.4", "@react-types/datepicker@3.7.4": version "3.7.4" resolved "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.7.4.tgz" integrity sha512-ZfvgscvNzBJpYyVWg3nstJtA/VlWLwErwSkd1ivZYam859N30w8yH+4qoYLa6FzWLCFlrsRHyvtxlEM7lUAt5A== @@ -2407,7 +2399,7 @@ "@react-types/overlays" "^3.8.9" "@react-types/shared" "^3.24.1" -"@react-types/grid@3.2.6", "@react-types/grid@^3.2.6": +"@react-types/grid@^3.2.6", "@react-types/grid@3.2.6": version "3.2.6" resolved "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.6.tgz" integrity sha512-XfHenL2jEBUYrhKiPdeM24mbLRXUn79wVzzMhrNYh24nBwhsPPpxF+gjFddT3Cy8dt6tRInfT6pMEu9nsXwaHw== @@ -2421,7 +2413,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/link@3.5.5", "@react-types/link@^3.5.5": +"@react-types/link@^3.5.5", "@react-types/link@3.5.5": version "3.5.5" resolved "https://registry.npmjs.org/@react-types/link/-/link-3.5.5.tgz" integrity sha512-G6P5WagHDR87npN7sEuC5IIgL1GsoY4WFWKO4734i2CXRYx24G9P0Su3AX4GA3qpspz8sK1AWkaCzBMmvnunfw== @@ -2435,7 +2427,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/menu@3.9.9", "@react-types/menu@^3.9.9": +"@react-types/menu@^3.9.9", "@react-types/menu@3.9.9": version "3.9.9" resolved "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.9.tgz" integrity sha512-FamUaPVs1Fxr4KOMI0YcR2rYZHoN7ypGtgiEiJ11v/tEPjPPGgeKDxii0McCrdOkjheatLN1yd2jmMwYj6hTDg== @@ -2443,7 +2435,7 @@ "@react-types/overlays" "^3.8.7" "@react-types/shared" "^3.23.1" -"@react-types/overlays@3.8.7", "@react-types/overlays@^3.8.7": +"@react-types/overlays@^3.8.7", "@react-types/overlays@3.8.7": version "3.8.7" resolved "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.7.tgz" integrity sha512-zCOYvI4at2DkhVpviIClJ7bRrLXYhSg3Z3v9xymuPH3mkiuuP/dm8mUCtkyY4UhVeUTHmrQh1bzaOP00A+SSQA== @@ -2457,27 +2449,20 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/progress@3.5.4", "@react-types/progress@^3.5.4": +"@react-types/progress@^3.5.4", "@react-types/progress@3.5.4": version "3.5.4" resolved "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.4.tgz" integrity sha512-JNc246sTjasPyx5Dp7/s0rp3Bz4qlu4LrZTulZlxWyb53WgBNL7axc26CCi+I20rWL9+c7JjhrRxnLl/1cLN5g== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/radio@3.8.1", "@react-types/radio@^3.8.1": +"@react-types/radio@^3.8.1", "@react-types/radio@3.8.1": version "3.8.1" resolved "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.1.tgz" integrity sha512-bK0gio/qj1+0Ldu/3k/s9BaOZvnnRgvFtL3u5ky479+aLG5qf1CmYed3SKz8ErZ70JkpuCSrSwSCFf0t1IHovw== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/select@3.9.4": - version "3.9.4" - resolved "https://registry.npmjs.org/@react-types/select/-/select-3.9.4.tgz" - integrity sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg== - dependencies: - "@react-types/shared" "^3.23.1" - "@react-types/select@^3.9.6": version "3.9.6" resolved "https://registry.npmjs.org/@react-types/select/-/select-3.9.6.tgz" @@ -2485,7 +2470,14 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/shared@3.23.1", "@react-types/shared@^3.23.1": +"@react-types/select@3.9.4": + version "3.9.4" + resolved "https://registry.npmjs.org/@react-types/select/-/select-3.9.4.tgz" + integrity sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg== + dependencies: + "@react-types/shared" "^3.23.1" + +"@react-types/shared@^3.23.1", "@react-types/shared@3.23.1": version "3.23.1" resolved "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz" integrity sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw== @@ -2509,7 +2501,7 @@ dependencies: "@react-types/shared" "^3.24.1" -"@react-types/table@3.9.5", "@react-types/table@^3.9.5": +"@react-types/table@^3.9.5", "@react-types/table@3.9.5": version "3.9.5" resolved "https://registry.npmjs.org/@react-types/table/-/table-3.9.5.tgz" integrity sha512-fgM2j9F/UR4Anmd28CueghCgBwOZoCVyN8fjaIFPd2MN4gCwUUfANwxLav65gZk4BpwUXGoQdsW+X50L3555mg== @@ -2517,21 +2509,21 @@ "@react-types/grid" "^3.2.6" "@react-types/shared" "^3.23.1" -"@react-types/tabs@3.3.7", "@react-types/tabs@^3.3.7": +"@react-types/tabs@^3.3.7", "@react-types/tabs@3.3.7": version "3.3.7" resolved "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.7.tgz" integrity sha512-ZdLe5xOcFX6+/ni45Dl2jO0jFATpTnoSqj6kLIS/BYv8oh0n817OjJkLf+DS3CLfNjApJWrHqAk34xNh6nRnEg== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/textfield@3.9.3", "@react-types/textfield@^3.9.3": +"@react-types/textfield@^3.9.3", "@react-types/textfield@3.9.3": version "3.9.3" resolved "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.3.tgz" integrity sha512-DoAY6cYOL0pJhgNGI1Rosni7g72GAt4OVr2ltEx2S9ARmFZ0DBvdhA9lL2nywcnKMf27PEJcKMXzXc10qaHsJw== dependencies: "@react-types/shared" "^3.23.1" -"@react-types/tooltip@3.4.9", "@react-types/tooltip@^3.4.9": +"@react-types/tooltip@^3.4.9", "@react-types/tooltip@3.4.9": version "3.4.9" resolved "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.9.tgz" integrity sha512-wZ+uF1+Zc43qG+cOJzioBmLUNjRa7ApdcT0LI1VvaYvH5GdfjzUJOorLX9V/vAci0XMJ50UZ+qsh79aUlw2yqg== @@ -2544,6 +2536,13 @@ resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz" integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== +"@swc/helpers@^0.5.0": + version "0.5.13" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz" + integrity sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w== + dependencies: + tslib "^2.4.0" + "@swc/helpers@0.5.5": version "0.5.5" resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz" @@ -2552,13 +2551,6 @@ "@swc/counter" "^0.1.3" tslib "^2.4.0" -"@swc/helpers@^0.5.0": - version "0.5.13" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz" - integrity sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w== - dependencies: - tslib "^2.4.0" - "@tediousjs/connection-string@^0.5.0": version "0.5.0" resolved "https://registry.npmjs.org/@tediousjs/connection-string/-/connection-string-0.5.0.tgz" @@ -4057,7 +4049,7 @@ dependencies: "@types/react" "*" -"@types/react@*": +"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^16.9.0 || ^17.0.0 || ^18.0.0": version "18.3.11" resolved "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz" integrity sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ== @@ -4078,11 +4070,6 @@ abab@^2.0.5, abab@^2.0.6: resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" @@ -4133,13 +4120,6 @@ ag-grid-react@^32.0.2: ag-grid-community "32.1.0" prop-types "^15.8.1" -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - agent-base@^7.0.2, agent-base@^7.1.0: version "7.1.1" resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz" @@ -4147,6 +4127,13 @@ agent-base@^7.0.2, agent-base@^7.1.0: dependencies: debug "^4.3.4" +agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" @@ -4189,19 +4176,6 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - arg@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" @@ -4260,14 +4234,6 @@ body-scroll-lock@^3.1.5: resolved "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz" integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - brace-expansion@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" @@ -4322,15 +4288,6 @@ caniuse-lite@^1.0.30001579: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001634.tgz" integrity sha512-fbBYXQ9q3+yp1q1gBk86tOFs4pyn/yxFm5ZNP18OXJDfA3txImOY9PhfxVggZ4vRHDqoU8NrKU81eN0OtzOgRA== -canvas@^2.8.0: - version "2.11.2" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.11.2.tgz#553d87b1e0228c7ac0fc72887c3adbac4abbd860" - integrity sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - nan "^2.17.0" - simple-get "^3.0.3" - chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" @@ -4340,14 +4297,14 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chart.js@^4.4.6: +chart.js@^4.1.1, chart.js@^4.4.6: version "4.4.6" resolved "https://registry.npmjs.org/chart.js/-/chart.js-4.4.6.tgz" integrity sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA== dependencies: "@kurkle/color" "^0.3.0" -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: +chokidar@^3.5.3, "chokidar@>=3.0.0 <4.0.0": version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -4362,22 +4319,22 @@ chart.js@^4.4.6: optionalDependencies: fsevents "~2.3.2" -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - classnames@^2.3.1: version "2.5.1" resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== -client-only@0.0.1, client-only@^0.0.1: +client-only@^0.0.1, client-only@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== -clsx@^1.1.1, clsx@^1.2.1: +clsx@^1.1.1: + version "1.2.1" + resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + +clsx@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== @@ -4401,16 +4358,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-string@^1.9.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" @@ -4419,16 +4376,6 @@ color-string@^1.9.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -color2k@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz" - integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== - color@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz" @@ -4437,6 +4384,11 @@ color@^4.2.3: color-convert "^2.0.1" color-string "^1.9.0" +color2k@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz" + integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -4444,11 +4396,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@2: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@^11.0.0: version "11.1.0" resolved "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz" @@ -4459,6 +4406,11 @@ commander@^4.0.0: resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@2: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + complex.js@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz" @@ -4469,11 +4421,6 @@ compute-scroll-into-view@^3.0.2: resolved "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz" integrity sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg== -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - concaveman@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz" @@ -4484,11 +4431,6 @@ concaveman@^1.2.1: robust-predicates "^2.0.4" tinyqueue "^2.0.3" -console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - convert-source-map@^1.5.0: version "1.9.0" resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" @@ -4589,13 +4531,6 @@ dayjs@^1.11.13: resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== -debug@4, debug@^4.3.3, debug@^4.3.4: - version "4.3.5" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz" - integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== - dependencies: - ms "2.1.2" - debug@^4.3.1: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" @@ -4603,18 +4538,18 @@ debug@^4.3.1: dependencies: ms "^2.1.3" +debug@^4.3.3, debug@^4.3.4, debug@4: + version "4.3.5" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + decimal.js@^10.3.1, decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - deepmerge@4.3.1: version "4.3.1" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" @@ -4630,16 +4565,6 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -detect-libc@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" - integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== - detect-node-es@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" @@ -4830,25 +4755,13 @@ fraction.js@^4.3.7: resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz" integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== -framer-motion@^11.2.13: +framer-motion@^11.2.13, framer-motion@>=10.17.0: version "11.3.21" resolved "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.21.tgz" integrity sha512-D+hfIsvzV8eL/iycld4K+tKlg2Q2LdwnrcBEohtGw3cG1AIuNYATbT5RUqIM1ndsAk+EfGhoSGf0UaiFodc5Tw== dependencies: tslib "^2.4.0" -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - fs@^0.0.1-security: version "0.0.1-security" resolved "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz" @@ -4864,21 +4777,6 @@ function-bind@^1.1.2: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - geojson-equality-ts@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/geojson-equality-ts/-/geojson-equality-ts-1.0.2.tgz" @@ -4923,18 +4821,6 @@ glob@^10.3.10: minipass "^7.1.2" path-scurry "^1.11.1" -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -4955,11 +4841,6 @@ has-flag@^3.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - hasown@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" @@ -5014,7 +4895,7 @@ https-proxy-agent@^7.0.0: agent-base "^7.0.2" debug "4" -iconv-lite@0.6.3, iconv-lite@^0.6.3: +iconv-lite@^0.6.3, iconv-lite@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -5039,17 +4920,9 @@ import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3, inherits@^2.0.4: +inherits@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== international-types@^0.8.1: @@ -5380,13 +5253,6 @@ lru-cache@^10.2.0: resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz" integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== -make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - marchingsquares@^1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/marchingsquares/-/marchingsquares-1.3.3.tgz" @@ -5437,18 +5303,6 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimatch@^9.0.4: version "9.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz" @@ -5456,37 +5310,17 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": version "7.1.2" resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" +minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.1.2, ms@^2.1.1: +ms@^2.1.1, ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -5517,11 +5351,6 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.17.0: - version "2.22.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.22.0.tgz#31bc433fc33213c97bad36404bb68063de604de3" - integrity sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw== - nanoid@^3.3.6, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" @@ -5564,35 +5393,11 @@ next@14.2.14: "@next/swc-win32-ia32-msvc" "14.2.14" "@next/swc-win32-x64-msvc" "14.2.14" -node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - nwsapi@^2.2.0: version "2.2.10" resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz" @@ -5608,13 +5413,6 @@ object-hash@^3.0.0: resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -once@^1.3.0, once@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - open@^8.0.0: version "8.4.2" resolved "https://registry.npmjs.org/open/-/open-8.4.2.tgz" @@ -5646,11 +5444,6 @@ parse5@6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" @@ -5756,6 +5549,15 @@ postcss-value-parser@^4.0.0: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== +postcss@^8, postcss@^8.0.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@>=8.0.9: + version "8.4.38" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + postcss@8.4.31: version "8.4.31" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" @@ -5765,15 +5567,6 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8, postcss@^8.4.23: - version "8.4.38" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" - integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.2.0" - prettier@^3.3.3: version "3.3.3" resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz" @@ -5868,7 +5661,7 @@ react-datepicker@^7.3.0: prop-types "^15.7.2" react-onclickoutside "^6.13.0" -react-dom@^18: +"react-dom@^15.5.x || ^16.x || ^17.x || ^18.x", "react-dom@^16.3.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17 || ^18", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react-dom@^16.9.0 || ^17 || ^18", react-dom@^18, react-dom@^18.0.0, react-dom@^18.2.0, "react-dom@>= 16.3.0", react-dom@>=16.6.0, react-dom@>=16.8.0, react-dom@>=18: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -5980,7 +5773,7 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^18: +react@*, "react@^15.5.x || ^16.x || ^17.x || ^18.x", "react@^16.3.0 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react@^16.9.0 || ^17 || ^18", react@^18, react@^18.0.0, react@^18.2.0, react@^18.3.1, "react@>= 16.3.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16.13.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=18: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -5994,15 +5787,6 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readable-stream@^4.2.0: version "4.5.2" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz" @@ -6062,13 +5846,6 @@ rfdc@^1.3.0: resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - robust-predicates@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz" @@ -6101,7 +5878,7 @@ safe-buffer@~5.1.1: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass@^1.77.8: +sass@^1.3.0, sass@^1.77.8: version "1.77.8" resolved "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz" integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ== @@ -6136,14 +5913,9 @@ seedrandom@^3.0.5: resolved "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz" integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== -semver@^6.0.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.5, semver@^7.5.4: +semver@^7.5.4: version "7.6.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== server-only@^0.0.1: @@ -6151,11 +5923,6 @@ server-only@^0.0.1: resolved "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz" integrity sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA== -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -6168,30 +5935,11 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - signal-exit@^4.0.1: version "4.1.0" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" - integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" - simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" @@ -6204,7 +5952,7 @@ skmeans@0.9.7: resolved "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz" integrity sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2, source-map-js@^1.2.0: +source-map-js@^1.0.2, source-map-js@^1.2.0, "source-map-js@>=0.6.2 <2.0.0": version "1.2.0" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== @@ -6239,6 +5987,13 @@ streamsearch@^1.1.0: resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +string_decoder@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -6248,16 +6003,16 @@ streamsearch@^1.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3: +string-width@^4.1.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: +string-width@^5.0.1: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== @@ -6266,14 +6021,23 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1, string_decoder@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== +string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: - safe-buffer "~5.2.0" + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -6336,7 +6100,7 @@ sweetalert2-react-content@^5.0.7: resolved "https://registry.npmjs.org/sweetalert2-react-content/-/sweetalert2-react-content-5.0.7.tgz" integrity sha512-8Fk82Mpk45lFXpJWKIFF/lq8k/dJKDDQGFcuqVosaL/qRdViyAs5+u37LoTGfnOIvf+rfQB3PAXcp1XLLn+0ew== -sweetalert2@^11.14.1: +sweetalert2@^11.0.0, sweetalert2@^11.14.1: version "11.14.1" resolved "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.14.1.tgz" integrity sha512-xadhfcA4STGMh8nC5zHFFWURhRpWc4zyI3GdMDFH/m3hGWZeQQNWhX9xcG4lI9gZYsi/IlazKbwvvje3juL3Xg== @@ -6363,7 +6127,7 @@ tailwind-variants@^0.1.20: dependencies: tailwind-merge "^1.14.0" -tailwindcss@^3.4.1: +tailwindcss@*, tailwindcss@^3.4.1, tailwindcss@>=3.4.0: version "3.4.4" resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz" integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== @@ -6391,18 +6155,6 @@ tailwindcss@^3.4.1: resolve "^1.22.2" sucrase "^3.32.0" -tar@^6.1.11: - version "6.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - tarn@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz" @@ -6491,11 +6243,6 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" @@ -6566,9 +6313,9 @@ use-sidecar@^1.1.2: detect-node-es "^1.1.0" tslib "^2.0.0" -util-deprecate@^1.0.1, util-deprecate@^1.0.2: +util-deprecate@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== uuid@^10.0.0: @@ -6595,11 +6342,6 @@ w3c-xmlserializer@^3.0.0: dependencies: xml-name-validator "^4.0.0" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" @@ -6633,14 +6375,6 @@ whatwg-url@^11.0.0: tr46 "^3.0.0" webidl-conversions "^7.0.0" -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -6648,13 +6382,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@^1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -6673,11 +6400,6 @@ wrap-ansi@^8.1.0: string-width "^5.0.1" strip-ansi "^7.0.1" -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - ws@^8.2.3: version "8.17.1" resolved "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz" @@ -6693,11 +6415,6 @@ xmlchars@^2.2.0: resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@^1.10.0: version "1.10.2" resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" From 3e57d53ec76f9c735c2af1012a255205e321b5fc Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 2 Dec 2024 09:53:19 +0900 Subject: [PATCH 07/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index d5739680..27a3f37f 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -702,6 +702,7 @@ export default function Estimate({ params }) { let vatPrice = 0 let totPrice = 0 let addSupplyPrice = 0 + let pkgTotPrice = 0 if (estimateContextState.estimateType === 'YJOD') { estimateContextState.itemList.sort((a, b) => { return a.dispOrder - b.dispOrder @@ -773,20 +774,16 @@ export default function Estimate({ params }) { if (item.moduleFlg === '1') { //용량(Kw)은 모듈플래그 1만 합산 const volKw = (item.pnowW * amount) / 1000 - // const volKw = item.pnowW * amount totVolKw += volKw } - setEstimateContextState({ - pkgTotPrice: estimateContextState.pkgAsp.replaceAll(',', '') * totVolKw * 1000, - }) - //pkgTotPrice + // const saleTotPrice totAmount += amount if (item.pkgMaterialFlg === '1') { - const pkgPrice = amount * salePrice + const saleTotPrice = amount * salePrice //다시계산하기 //YJSS는 PKG제외상품들만(1) 모아서 수량 * 단가를 공급가액(supplyPrice)에 추가로 더해줌 - addSupplyPrice += pkgPrice + addSupplyPrice += saleTotPrice } if (!item.paDispOrder) { @@ -798,7 +795,12 @@ export default function Estimate({ params }) { } } }) - supplyPrice = addSupplyPrice + Number(estimateContextState.pkgTotPrice / 1000) + pkgTotPrice = estimateContextState.pkgAsp.replaceAll(',', '') * totVolKw * 1000 + setEstimateContextState({ + pkgTotPrice: pkgTotPrice, + }) + + supplyPrice = addSupplyPrice + pkgTotPrice vatPrice = supplyPrice * 0.1 totPrice = supplyPrice + vatPrice setEstimateContextState({ @@ -811,6 +813,18 @@ export default function Estimate({ params }) { } setItemChangeYn(false) + } else { + estimateContextState.itemList.map((item) => { + if (estimateContextState.estimateType === 'YJSS') { + if (!item.paDispOrder) { + //paDispOrder + if (item.pkgMaterialFlg === '0') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + } + } + }) } }, [itemChangeYn, estimateContextState.itemList]) From 11d4bb9167a5b2a6f40346168619901e55fbbe28 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 2 Dec 2024 10:16:58 +0900 Subject: [PATCH 08/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/popup/EstimateCopyPop.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/estimate/popup/EstimateCopyPop.jsx b/src/components/estimate/popup/EstimateCopyPop.jsx index 39ca5a28..04414b9f 100644 --- a/src/components/estimate/popup/EstimateCopyPop.jsx +++ b/src/components/estimate/popup/EstimateCopyPop.jsx @@ -11,7 +11,7 @@ export default function EstimateCopyPop({ planNo, setEstimateCopyPopupOpen }) { const { getMessage } = useMessage() const { get } = useAxios() - const { handleEstimateCopy, state } = useEstimateController(planNo) + const { handleEstimateCopy, estimateContextState } = useEstimateController(planNo) const { session } = useContext(SessionContext) @@ -105,10 +105,10 @@ export default function EstimateCopyPop({ planNo, setEstimateCopyPopupOpen }) { }, [planNo]) useEffect(() => { - if (state?.charger) { - setCopyReceiveUser(state.charger) + if (estimateContextState?.charger) { + setCopyReceiveUser(estimateContextState.charger) } - }, [state.charger]) + }, [estimateContextState?.charger]) //T01 1차점 자동완성 인풋때 목록 변환 const onInputChange = (key) => { @@ -282,7 +282,7 @@ export default function EstimateCopyPop({ planNo, setEstimateCopyPopupOpen }) { type="text" className="input-light" required - defaultValue={state?.charger} + defaultValue={estimateContextState?.charger} onChange={(e) => { setCopyReceiveUser(e.target.value) }} From 186c15bedf46ae18c6829620a79813a3c4a1f8a1 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 2 Dec 2024 14:20:10 +0900 Subject: [PATCH 09/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=86=8C?= =?UTF-8?q?=EC=8A=A4=EC=A0=95=EB=A6=AC=20&=20=EC=B2=A8=EB=B6=80=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 164 +++++++----------- .../estimate/useEstimateController.js | 4 +- 2 files changed, 64 insertions(+), 104 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 27a3f37f..9b0bbd5c 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -562,7 +562,7 @@ export default function Estimate({ params }) { let updateList = [] let updates = {} get({ url: apiUrl }).then((res) => { - console.log('아이템디테일::::::::', res) + // console.log('아이템디테일::::::::', res) updates.objectNo = objectNo updates.planNo = planNo updates.itemId = res.itemId @@ -696,98 +696,61 @@ export default function Estimate({ params }) { useEffect(() => { if (itemChangeYn) { - let totAmount = 0 - let totVolKw = 0 - let supplyPrice = 0 - let vatPrice = 0 - let totPrice = 0 - let addSupplyPrice = 0 - let pkgTotPrice = 0 - if (estimateContextState.estimateType === 'YJOD') { - estimateContextState.itemList.sort((a, b) => { - return a.dispOrder - b.dispOrder - }) - // console.log('YJOD 토탈만들어주기::::::::::', estimateContextState.itemList) + let totals = { + totAmount: 0, + totVolKw: 0, + supplyPrice: 0, + vatPrice: 0, + totPrice: 0, + addSupplyPrice: 0, + pkgTotPrice: 0, + } - //아이템에서 제품관련 특이사항 중복제거해서 만드는 함수 - makeUniqueSpecialNoteCd(estimateContextState.itemList) + const calculateYJODTotals = (itemList) => { + itemList.sort((a, b) => a.dispOrder - b.dispOrder) + makeUniqueSpecialNoteCd(itemList) - estimateContextState.itemList.map((item) => { + itemList.forEach((item) => { delete item.showSalePrice delete item.showSaleTotPrice if (item.delFlg === '0') { - let amount = Number(item?.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) - if (isNaN(amount)) { - amount = '0' - } - let price = Number(item?.saleTotPrice?.replaceAll(',', '')) - if (isNaN(price)) { - price = 0 - } + let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 + let price = Number(item.saleTotPrice?.replaceAll(',', '')) || 0 + if (item.moduleFlg === '1') { - //용량(Kw)은 모듈플래그 1만 합산 const volKw = (item.pnowW * amount) / 1000 - // const volKw = item.pnowW * amount - totVolKw += volKw + totals.totVolKw += volKw } - // const price - totAmount += amount - supplyPrice += price + totals.totAmount += amount + totals.supplyPrice += price } }) - vatPrice = supplyPrice * 0.1 - totPrice = supplyPrice + vatPrice + totals.vatPrice = totals.supplyPrice * 0.1 + totals.totPrice = totals.supplyPrice + totals.vatPrice + } - setEstimateContextState({ - totAmount: totAmount, - totVolKw: totVolKw.toFixed(3), - supplyPrice: supplyPrice.toFixed(3), - vatPrice: vatPrice.toFixed(3), - totPrice: totPrice.toFixed(3), - }) - } else { - //아이템에서 제품관련 특이사항 중복제거해서 만드는 함수 - makeUniqueSpecialNoteCd(estimateContextState.itemList) - //YJSS - // console.log('YJSS 토탈만들어주기::::::::::', estimateContextState.itemList) - estimateContextState.itemList.sort((a, b) => { - return a.dispOrder - b.dispOrder - }) - estimateContextState.itemList.map((item) => { + const calculateYJSSTotals = (itemList) => { + itemList.sort((a, b) => a.dispOrder - b.dispOrder) + makeUniqueSpecialNoteCd(itemList) + + itemList.forEach((item) => { if (item.delFlg === '0') { - let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) - let salePrice = Number(item.salePrice?.replaceAll(',', '')) - let saleTotPrice = Number(item.saleTotPrice?.replaceAll(',', '')) + let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 + let salePrice = Number(item.salePrice?.replaceAll(',', '')) || 0 - if (isNaN(amount)) { - amount = '0' - } - - if (isNaN(saleTotPrice)) { - saleTotPrice = 0 - } - - if (isNaN(salePrice)) { - salePrice = 0 - } if (item.moduleFlg === '1') { - //용량(Kw)은 모듈플래그 1만 합산 const volKw = (item.pnowW * amount) / 1000 - totVolKw += volKw + totals.totVolKw += volKw } - // const saleTotPrice - totAmount += amount + totals.totAmount += amount if (item.pkgMaterialFlg === '1') { const saleTotPrice = amount * salePrice - //다시계산하기 - //YJSS는 PKG제외상품들만(1) 모아서 수량 * 단가를 공급가액(supplyPrice)에 추가로 더해줌 - addSupplyPrice += saleTotPrice + totals.addSupplyPrice += saleTotPrice } if (!item.paDispOrder) { - //paDispOrder if (item.pkgMaterialFlg === '0') { item.showSalePrice = '0' item.showSaleTotPrice = '0' @@ -795,34 +758,40 @@ export default function Estimate({ params }) { } } }) - pkgTotPrice = estimateContextState.pkgAsp.replaceAll(',', '') * totVolKw * 1000 - setEstimateContextState({ - pkgTotPrice: pkgTotPrice, - }) - supplyPrice = addSupplyPrice + pkgTotPrice - vatPrice = supplyPrice * 0.1 - totPrice = supplyPrice + vatPrice + totals.pkgTotPrice = Number(estimateContextState.pkgAsp.replaceAll(',', '')) * totals.totVolKw * 1000 + totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice + totals.vatPrice = totals.supplyPrice * 0.1 + totals.totPrice = totals.supplyPrice + totals.vatPrice + } + + if (estimateContextState.estimateType === 'YJOD') { + calculateYJODTotals(estimateContextState.itemList) setEstimateContextState({ - totAmount: totAmount, - totVolKw: totVolKw.toFixed(3), - supplyPrice: supplyPrice.toFixed(3), - vatPrice: vatPrice.toFixed(3), - totPrice: totPrice.toFixed(3), + totAmount: totals.totAmount, + totVolKw: totals.totVolKw.toFixed(3), + supplyPrice: totals.supplyPrice.toFixed(3), + vatPrice: totals.vatPrice.toFixed(3), + totPrice: totals.totPrice.toFixed(3), + }) + } 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), }) } setItemChangeYn(false) } else { - estimateContextState.itemList.map((item) => { - if (estimateContextState.estimateType === 'YJSS') { - if (!item.paDispOrder) { - //paDispOrder - if (item.pkgMaterialFlg === '0') { - item.showSalePrice = '0' - item.showSaleTotPrice = '0' - } - } + estimateContextState.itemList.forEach((item) => { + if (estimateContextState.estimateType === 'YJSS' && !item.paDispOrder && item.pkgMaterialFlg === '0') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' } }) } @@ -1160,13 +1129,7 @@ export default function Estimate({ params }) { {specialNoteList.length > 0 && specialNoteList.map((row) => { return ( -
{ - // settingShowContent(row.code, event) - }} - > +
- +
) @@ -1386,7 +1347,6 @@ export default function Estimate({ params }) {
- {/*
*/}
diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index f40d171e..8229d85d 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, isNotEmptyArray } from '@/util/common-utils' +import { isObjectNotEmpty } from '@/util/common-utils' import { SessionContext } from '@/app/SessionProvider' import { useMessage } from '@/hooks/useMessage' import { useRouter } from 'next/navigation' @@ -206,7 +206,7 @@ export const useEstimateController = (planNo) => { if (flag && fileFlg && itemFlg) { //1. 첨부파일 저장시작 const formData = new FormData() - if (isNotEmptyArray(estimateData.tempFileList) > 1) { + if (estimateData?.tempFileList?.length > 0) { estimateData.tempFileList.forEach((file) => { formData.append('files', file) }) From 0a9618e642a00268489c6ba1506197743ffcc592 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Mon, 2 Dec 2024 15:06:41 +0900 Subject: [PATCH 10/98] =?UTF-8?q?Canvas=20=EA=B7=B8=EB=A6=AC=EB=93=9C?= =?UTF-8?q?=EC=83=89=20=EC=84=A4=EC=A0=95=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/color-picker/ColorPickerModal.jsx | 6 +- .../floor-plan/modal/grid/DotLineGrid.jsx | 151 +++++++----------- .../floor-plan/modal/setting01/GridOption.jsx | 8 +- .../setting01/planSize/PlanSizeSetting.jsx | 4 - src/hooks/option/useCanvasSetting.js | 151 +++++++++++++++--- 5 files changed, 189 insertions(+), 131 deletions(-) diff --git a/src/components/common/color-picker/ColorPickerModal.jsx b/src/components/common/color-picker/ColorPickerModal.jsx index 03d9899f..37a5343c 100644 --- a/src/components/common/color-picker/ColorPickerModal.jsx +++ b/src/components/common/color-picker/ColorPickerModal.jsx @@ -8,13 +8,13 @@ import { contextPopupPositionState } from '@/store/popupAtom' export default function ColorPickerModal(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) // 현재 메뉴 - const { isShow, setIsShow, pos = contextPopupPosition, color = '#ff0000', setColor, id, isConfig = false } = props - const { getMessage } = useMessage() + const { isShow, setIsShow, pos = contextPopupPosition, color, setColor, id, isConfig = false } = props //color = '#ff0000' const [originColor, setOriginColor] = useState(color) + const { getMessage } = useMessage() const { closePopup } = usePopup() useEffect(() => { - setOriginColor(color) + setOriginColor(originColor) }, [isShow]) return ( diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index f4caa40b..3928353c 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -1,54 +1,44 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' import QSelectBox from '@/components/common/select/QSelectBox' -import { useEffect, useState } from 'react' +import { useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' -import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom' -import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' +import { canvasState } from '@/store/canvasAtom' +import { useRecoilValue } from 'recoil' import { onlyNumberInputChange } from '@/util/input-utils' -import { settingModalGridOptionsState } from '@/store/settingAtom' -import { useAxios } from '@/hooks/useAxios' -import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { useSwal } from '@/hooks/useSwal' const TYPE = { DOT: 'DOT', LINE: 'LINE', } -const defaultDotLineGridSetting = { - INTERVAL: { - type: 2, // 1: 가로,세로 간격 수동, 2: 비율 간격 - ratioInterval: 910, - verticalInterval: 910, - horizontalInterval: 910, - dimension: 1, // 치수 - }, - DOT: false, - LINE: false, -} - export default function DotLineGrid(props) { // const [modalOption, setModalOption] = useRecoilState(modalState); //modal 열림닫힘 state - const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요 - const [close, setClose] = useState(false) + //const interval = useRecoilValue(dotLineIntervalSelector) const { id, setIsShow, pos = { x: 840, y: -815 }, isConfig = false } = props - const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) - const canvas = useRecoilValue(canvasState) - const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState) - const [currentSetting, setCurrentSetting] = useState( - JSON.stringify(dotLineGridSetting) === JSON.stringify(defaultDotLineGridSetting) ? { ...defaultDotLineGridSetting } : { ...dotLineGridSetting }, - ) - const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState) - const interval = useRecoilValue(dotLineIntervalSelector) - const { getMessage } = useMessage() - const { get, post } = useAxios() - const { swalFire } = useSwal() const { closePopup } = usePopup() + const { swalFire } = useSwal() + const { + selectOption, + setSelectOption, + SelectOptions, + currentSetting, + setCurrentSetting, + dotLineGridSettingState, + setSettingModalGridOptions, + setDotLineGridSettingState, + } = useCanvasSetting() + + // 데이터를 최초 한 번만 조회 useEffect(() => { + console.log('DotLineGrid useEffect 실행') + return () => { setSettingModalGridOptions((prev) => { const newSettingOptions = [...prev] @@ -58,20 +48,6 @@ export default function DotLineGrid(props) { } }, []) - const SelectOption = [ - { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, - { id: 2, name: '1/2', value: 1 / 2 }, - { id: 3, name: '1/4', value: 1 / 4 }, - { id: 4, name: '1/10', value: 1 / 10 }, - ] - const [selectOption, setSelectOption] = useState(SelectOption[0]) - - // 데이터를 최초 한 번만 조회 - useEffect(() => { - console.log('DotLineGrid useEffect 실행') - fetchGridSettings() - }, [objectNo]) - const HandleClickClose = () => { // setClose(true) // setTimeout(() => { @@ -90,61 +66,31 @@ export default function DotLineGrid(props) { }) } - // Canvas Grid Setting 조회 및 초기화 - const fetchGridSettings = async () => { - try { - const res = await get({ url: `/api/canvas-management/canvas-grid-settings/by-object/${objectNo}` }) - - const patternData = { - INTERVAL: { - type: res.gridType, - horizontalInterval: res.gridHorizon * 10, - verticalInterval: res.gridVertical * 10, - ratioInterval: res.gridRatio * 10, - }, - dimension: res.gridDimen, - DOT: res.dotGridDisplay, - LINE: res.lineGridDisplay, - } - - const matchedOption = SelectOption.find((option) => option.value == res.gridDimen) - - // dimension 값에 맞는 옵션을 선택 - setSelectOption(matchedOption) - - // 서버에서 받은 데이터로 상태 업데이트 - setCurrentSetting(patternData) - } catch (error) { - console.error('Data fetching error:', error) - } - } - const handleSave = async () => { if (!currentSetting.DOT && !currentSetting.LINE) { swalFire({ text: '배치할 그리드를 설정해주세요.' }) return } - try { - const patternData = { - objectNo, - dotGridDisplay: currentSetting.DOT, - lineGridDisplay: currentSetting.LINE, - gridType: currentSetting.INTERVAL.type, - gridHorizon: currentSetting.INTERVAL.horizontalInterval / 10, - gridVertical: currentSetting.INTERVAL.verticalInterval / 10, - gridRatio: currentSetting.INTERVAL.ratioInterval / 10, - gridDimen: currentSetting.INTERVAL.dimension, - } - // HTTP POST 요청 보내기 - await post({ url: `/api/canvas-management/canvas-grid-settings`, data: patternData }).then((res) => { - swalFire({ text: getMessage(res.returnMessage) }) - setDotLineGridSettingState({ ...currentSetting }) - closePopup(id, isConfig) - }) - } catch (error) { - swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) - } + setDotLineGridSettingState((prev) => { + return { + ...prev, + INTERVAL: { + type: currentSetting.INTERVAL.type, + horizontalInterval: currentSetting.INTERVAL.horizontalInterval, + verticalInterval: currentSetting.INTERVAL.verticalInterval, + ratioInterval: currentSetting.INTERVAL.ratioInterval, + dimension: currentSetting.INTERVAL.dimension, + }, + DOT: currentSetting.DOT, + LINE: currentSetting.LINE, + flag: true, + } + //setDotLineGridSettingState({ ...currentSetting }) + }) + + setIsShow(false) + closePopup(id, isConfig) } const handleRadioChange = (e) => { @@ -198,8 +144,19 @@ export default function DotLineGrid(props) { .filter((obj) => obj.name === 'dotGrid') .forEach((obj) => canvas?.remove(obj)) - resetDotLineGridSetting() - setSelectOption(SelectOption[0]) + // resetDotLineGridSetting() + setCurrentSetting({ + INTERVAL: { + type: 2, // 1: 가로,세로 간격 수동, 2: 비율 간격 + ratioInterval: 910, + verticalInterval: 910, + horizontalInterval: 910, + dimension: 1, // 치수 + }, + DOT: false, + LINE: false, + }) + setSelectOption(SelectOptions[0]) } return ( @@ -296,7 +253,7 @@ export default function DotLineGrid(props) { mm
- +
diff --git a/src/components/floor-plan/modal/setting01/GridOption.jsx b/src/components/floor-plan/modal/setting01/GridOption.jsx index f3465365..bb6adef7 100644 --- a/src/components/floor-plan/modal/setting01/GridOption.jsx +++ b/src/components/floor-plan/modal/setting01/GridOption.jsx @@ -4,12 +4,11 @@ import { settingModalGridOptionsState } from '@/store/settingAtom' import { useMessage } from '@/hooks/useMessage' import { adsorptionPointAddModeState } from '@/store/canvasAtom' import { useTempGrid } from '@/hooks/useTempGrid' -import { gridColorState } from '@/store/gridAtom' -import { useColor } from 'react-color-palette' import ColorPickerModal from '@/components/common/color-picker/ColorPickerModal' import { usePopup } from '@/hooks/usePopup' import { v4 as uuidv4 } from 'uuid' import DotLineGrid from '@/components/floor-plan/modal/grid/DotLineGrid' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' export default function GridOption() { const [gridOptions, setGridOptions] = useRecoilState(settingModalGridOptionsState) @@ -17,15 +16,16 @@ export default function GridOption() { const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) const { getMessage } = useMessage() const { tempGridMode, setTempGridMode } = useTempGrid() - const [gridColor, setGridColor] = useRecoilState(gridColorState) - const [color, setColor] = useColor(gridColor) const [showColorPickerModal, setShowColorPickerModal] = useState(false) const [showDotLineGridModal, setShowDotLineGridModal] = useState(false) const { addPopup, closePopup, closePopups } = usePopup() const [colorId, setColorId] = useState(uuidv4()) const [dotLineId, setDotLineId] = useState(uuidv4()) + const { gridColor, setGridColor, color } = useCanvasSetting() + useEffect(() => { + console.log(gridColor, color) setGridColor(color.hex) }, [color]) diff --git a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx index a841efd5..e65d28ca 100644 --- a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx +++ b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx @@ -75,8 +75,6 @@ export default function PlanSizeSetting(props) { className="input-origin block" name={`originHorizon`} value={planSizeSettingMode.originHorizon} - //onChange={(e) => setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: Number(e.target.value), flag: false })} - //onFocus={(e) => (originHorizon.current.value = '')} onChange={(e) => onlyNumberInputChange(e, changeInput)} /> @@ -90,8 +88,6 @@ export default function PlanSizeSetting(props) { className="input-origin block" name={`originVertical`} value={planSizeSettingMode.originVertical} - //onChange={(e) => setPlanSizeSettingMode({ ...planSizeSettingMode, originVertical: Number(e.target.value), flag: false })} - //onFocus={(e) => (originVertical.current.value = '')} onChange={(e) => onlyNumberInputChange(e, changeInput)} /> diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index c3155512..d37ce040 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -1,16 +1,34 @@ import { useCallback, useEffect, useState } from 'react' -import { useRecoilState, useRecoilValue } from 'recoil' -import { adsorptionPointModeState, adsorptionRangeState, canvasState, planSizeSettingState } from '@/store/canvasAtom' +import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' +import { adsorptionPointModeState, adsorptionRangeState, canvasState, planSizeSettingState, dotLineGridSettingState } from '@/store/canvasAtom' import { globalLocaleStore } from '@/store/localeAtom' import { useMessage } from '@/hooks/useMessage' import { useAxios } from '@/hooks/useAxios' import { useSwal } from '@/hooks/useSwal' -import { correntObjectNoState, corridorDimensionSelector, settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom' +import { + correntObjectNoState, + corridorDimensionSelector, + settingModalFirstOptionsState, + settingModalSecondOptionsState, + settingModalGridOptionsState, +} from '@/store/settingAtom' import { POLYGON_TYPE } from '@/common/common' import { globalFontAtom } from '@/store/fontAtom' import { dimensionLineSettingsState } from '@/store/commonUtilsAtom' +import { gridColorState } from '@/store/gridAtom' +import { useColor } from 'react-color-palette' -let objectNo +const defaultDotLineGridSetting = { + INTERVAL: { + type: 2, // 1: 가로,세로 간격 수동, 2: 비율 간격 + ratioInterval: 910, + verticalInterval: 910, + horizontalInterval: 910, + dimension: 1, // 치수 + }, + DOT: false, + LINE: false, +} export function useCanvasSetting() { const canvas = useRecoilValue(canvasState) @@ -21,7 +39,7 @@ export function useCanvasSetting() { const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) const { option1, option2, dimensionDisplay } = settingModalFirstOptions - const { option3, option4 } = settingModalSecondOptions + const { option4 } = settingModalSecondOptions const corridorDimension = useRecoilValue(corridorDimensionSelector) @@ -42,6 +60,24 @@ export function useCanvasSetting() { const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom) const [dimensionLineSettings, setDimensionLineSettings] = useRecoilState(dimensionLineSettingsState) + const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) + const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState) + const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState) + const [currentSetting, setCurrentSetting] = useState( + JSON.stringify(dotLineGridSetting) === JSON.stringify(defaultDotLineGridSetting) ? { ...defaultDotLineGridSetting } : { ...dotLineGridSetting }, + ) + const [gridColor, setGridColor] = useRecoilState(gridColorState) + const [color, setColor] = useColor(gridColor ?? '#FF0000') + const [colorTemp, setColorTemp] = useState() + + 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 }, + { id: 3, name: '1/4', value: 1 / 4 }, + { id: 4, name: '1/10', value: 1 / 10 }, + ] + const [selectOption, setSelectOption] = useState(SelectOptions[0]) + useEffect(() => { if (!canvas) { return @@ -73,51 +109,58 @@ export function useCanvasSetting() { }, [corridorDimension]) useEffect(() => { - console.log('useCanvasSetting useEffect 실행1', correntObjectNo) + console.log('useCanvasSetting 실행1', correntObjectNo) }, []) //흡착점 ON/OFF 변경 시 useEffect(() => { - console.log('useCanvasSetting useEffect 실행2', adsorptionPointMode.fontFlag, correntObjectNo) - + //console.log('useCanvasSetting 실행2', adsorptionPointMode.fontFlag, correntObjectNo) if (adsorptionPointMode.fontFlag) { onClickOption2() - frontSettings() - fetchSettings() } }, [adsorptionPointMode]) // 1 과 2 변경 시 useEffect(() => { - console.log('useCanvasSetting useEffect 실행3', settingModalFirstOptions.fontFlag, settingModalSecondOptions.fontFlag, correntObjectNo) + //console.log('useCanvasSetting 실행3', settingModalFirstOptions.fontFlag, settingModalSecondOptions.fontFlag, correntObjectNo) if (settingModalFirstOptions.fontFlag || settingModalSecondOptions.fontFlag) { onClickOption2() - frontSettings() - fetchSettings() } }, [settingModalFirstOptions, settingModalSecondOptions]) // 글꼴 변경 시 useEffect(() => { - console.log('useCanvasSetting useEffect 실행4', globalFont.fontFlag, correntObjectNo) + //console.log('useCanvasSetting 실행4', globalFont.fontFlag, correntObjectNo) if (globalFont.fontFlag) { onClickOption2() - frontSettings() - fetchSettings() } }, [globalFont]) // 도명크기 변경 시 useEffect(() => { - console.log('useCanvasSetting useEffect 실행5', planSizeSettingMode.flag, correntObjectNo) - + //console.log('useCanvasSetting 실행5', planSizeSettingMode.flag, correntObjectNo) if (planSizeSettingMode.flag) { onClickOption2() - frontSettings() - fetchSettings() } }, [planSizeSettingMode]) + // 점/선 그리드 변경 시 + useEffect(() => { + //console.log('useCanvasSetting 실행6', dotLineGridSetting.flag) + if (dotLineGridSetting.flag) { + onClickOption2() + } + }, [dotLineGridSetting]) + + // 그리드 색 설정 변경 시 + useEffect(() => { + console.log('useCanvasSetting 실행7', colorTemp, gridColor) + //colorTemp는 변경 전.. 값이 있고 변경된 컬러와 다를 때 실행 + if (colorTemp !== undefined && colorTemp !== gridColor) { + onClickOption2() + } + }, [color]) + const getFonts = (itemValue) => { if (!itemValue) return { id: 1, name: 'MS PGothic', value: 'MS PGothic' } const data = [ @@ -269,10 +312,35 @@ export function useCanvasSetting() { //글꼴 설정 Flag fontFlag: false, } - console.log('fontPatternData', fontPatternData) //조회된 글꼴 데이터 set setGlobalFont(fontPatternData) + + //점/선 그리드 + const patternData = { + INTERVAL: { + type: res.gridType, + horizontalInterval: res.gridHorizon * 10, + verticalInterval: res.gridVertical * 10, + ratioInterval: res.gridRatio * 10, + dimension: res.gridDimen, + }, + DOT: res.dotGridDisplay, + LINE: res.lineGridDisplay, + flag: false, + } + + const matchedOption = SelectOptions.find((option) => option.value == res.gridDimen) + + // dimension 값에 맞는 옵션을 선택 + setSelectOption(matchedOption) + + setDotLineGridSettingState(patternData) + //setCurrentSetting(patternData) + + //그리드 색 설정 + setGridColor(res.gridColor) + setColorTemp(res.gridColor) } else { //조회된 글꼴 데이터가 없는 경우 @@ -299,6 +367,14 @@ export function useCanvasSetting() { }) setGlobalFont({ ...globalFont, fontFlag: false }) + + //점/선 그리드 + setDotLineGridSettingState({ ...defaultDotLineGridSetting, flag: false }) + //setCurrentSetting({ ...defaultDotLineGridSetting }) + + //그리드 색 설정 + setGridColor('#FF0000') + setColorTemp('#FF0000') } frontSettings() } catch (error) { @@ -394,13 +470,26 @@ export function useCanvasSetting() { originPixel: dimensionLineSettings.pixel, originColor: dimensionLineSettings.color, - //치수선 설정 + //도면크기 설정 originHorizon: planSizeSettingMode.originHorizon, originVertical: planSizeSettingMode.originVertical, + + dotGridDisplay: dotLineGridSetting.DOT, + lineGridDisplay: dotLineGridSetting.LINE, + gridType: dotLineGridSetting.INTERVAL.type, + gridHorizon: dotLineGridSetting.INTERVAL.horizontalInterval / 10, + gridVertical: dotLineGridSetting.INTERVAL.verticalInterval / 10, + gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10, + gridDimen: dotLineGridSetting.INTERVAL.dimension, + + //gridColor: gridColor.gridColor, + gridColor: gridColor, } console.log('patternData ', patternData) + setColorTemp(gridColor) + // HTTP POST 요청 보내기 await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) .then((res) => { @@ -408,13 +497,15 @@ export function useCanvasSetting() { // Canvas 디스플레이 설정 시 해당 옵션 적용 frontSettings() + // 저장 후 재조회 + fetchSettings() }) .catch((error) => { swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) }) //setAdsorptionRange(item.range) - }, [settingModalFirstOptions, settingModalSecondOptions, adsorptionPointMode, globalFont, planSizeSettingMode]) + }, [settingModalFirstOptions, settingModalSecondOptions, adsorptionPointMode, globalFont, planSizeSettingMode, dotLineGridSetting, color]) // Canvas 디스플레이 설정 시 해당 옵션 적용 const frontSettings = async () => { @@ -491,6 +582,7 @@ export function useCanvasSetting() { return { canvas, + correntObjectNo, settingModalFirstOptions, setSettingModalFirstOptions, settingModalSecondOptions, @@ -516,5 +608,18 @@ export function useCanvasSetting() { setDimensionLineSettings, planSizeSettingMode, setPlanSizeSettingMode, + selectOption, + setSelectOption, + SelectOptions, + currentSetting, + setCurrentSetting, + dotLineGridSettingState, + setSettingModalGridOptions, + setDotLineGridSettingState, + resetDotLineGridSetting, + gridColor, + setGridColor, + color, + setColor, } } From a94b328ae3d7fe1e314c80e3c9762be705046d59 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 2 Dec 2024 15:27:42 +0900 Subject: [PATCH 11/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 15 ++++++-- .../estimate/useEstimateController.js | 38 +++++++++++-------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 9b0bbd5c..3c451220 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -176,7 +176,6 @@ export default function Estimate({ params }) { useEffect(() => { //선택된 견적특이사항 setEstimateContextState - // console.log('specialNoteList::', specialNoteList) if (isNotEmptyArray(specialNoteList)) { const liveCheckedData = specialNoteList.filter((row) => row.check === true) @@ -187,7 +186,6 @@ export default function Estimate({ params }) { const newData = data.join('、') //저장용 보내기 - // console.log('유니크??', uniqueData) setEstimateContextState({ estimateOption: newData, specialNoteList: specialNoteList, uniqueData: uniqueData }) } }, [specialNoteList]) @@ -204,13 +202,21 @@ export default function Estimate({ params }) { let fileList = [] files.map((row) => { fileList.push(row.data) - setEstimateContextState({ fileList: row.data, tempFileList: fileList }) + setEstimateContextState({ fileList: row.data, newFileList: fileList }) }) } else { setEstimateContextState({ fileList: [] }) } }, [files]) + useEffect(() => { + if (originFiles.length > 0) { + setEstimateContextState({ + originFiles: originFiles, + }) + } + }, [originFiles]) + //상세에서 내려온 첨부파일 set 만들기 useEffect(() => { if (isNotEmptyArray(estimateContextState.fileList)) { @@ -232,6 +238,8 @@ export default function Estimate({ params }) { 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), }) alert(getMessage('plan.message.delete')) @@ -333,7 +341,6 @@ export default function Estimate({ params }) { } }) - // console.log('특이사항 유니크:::', pushData) setUniqueData(pushData) specialNoteList.map((item) => { if (item.pkgYn === '1') { diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 8229d85d..7790c9bb 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -128,6 +128,7 @@ export const useEstimateController = (planNo) => { const handleEstimateSubmit = async () => { //0. 필수체크 let flag = true + let originFileFlg = false let fileFlg = true let itemFlg = true if (estimateData.charger.trim().length === 0) { @@ -147,21 +148,26 @@ export const useEstimateController = (planNo) => { //첨부파일을 첨부안했는데 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 + if (estimateData?.originFiles?.length > 0) { + originFileFlg = true + } if (flag) { - if (estimateData.fileList.length < 1) { - if (estimateData.itemList.length > 1) { - estimateData.itemList.map((row) => { - if (row.delFlg === '0') { - if (row.fileUploadFlg === '1') { - if (fileFlg) { - if (estimateData.fileFlg === '0') { - fileFlg = false - return alert(getMessage('estimate.detail.save.requiredFileUpload')) + if (!originFileFlg) { + if (estimateData.newFileList.length < 1) { + if (estimateData.itemList.length > 1) { + estimateData.itemList.map((row) => { + if (row.delFlg === '0') { + if (row.fileUploadFlg === '1') { + if (fileFlg) { + if (estimateData.fileFlg === '0') { + fileFlg = false + return alert(getMessage('estimate.detail.save.requiredFileUpload')) + } } } } - } - }) + }) + } } } } @@ -206,8 +212,8 @@ export const useEstimateController = (planNo) => { if (flag && fileFlg && itemFlg) { //1. 첨부파일 저장시작 const formData = new FormData() - if (estimateData?.tempFileList?.length > 0) { - estimateData.tempFileList.forEach((file) => { + if (estimateData?.newFileList?.length > 0) { + estimateData.newFileList.forEach((file) => { formData.append('files', file) }) formData.append('objectNo', estimateData.objectNo) @@ -267,9 +273,9 @@ export const useEstimateController = (planNo) => { } }) estimateData.estimateOption = estimateOptions - // console.log('최종첨부파일:::', estimateData.fileList) - // console.log('최종아이템:::', estimateData.itemList) - // console.log('최종저장::', estimateData) + console.log('최종첨부파일:::', estimateData.newFileList) + console.log('최종아이템:::', estimateData.itemList) + console.log('최종저장::', estimateData) //2. 상세데이터 저장 // return try { From 47e5b62e9cd8f1ed909bbc868111021e6c63d501 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 2 Dec 2024 15:40:25 +0900 Subject: [PATCH 12/98] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=B5=9C=EB=8C=80?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 119 ++++++++++++++-------- 1 file changed, 74 insertions(+), 45 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 7a72a379..6bae162a 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -12,6 +12,7 @@ import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common' import * as turf from '@turf/turf' import { EventContext } from '@/app/floor-plan/EventProvider' import { v4 as uuidv4 } from 'uuid' +import { useMainContentsController } from '../main/useMainContentsController' export function useModuleBasicSetting() { const canvas = useRecoilValue(canvasState) @@ -400,7 +401,7 @@ export function useModuleBasicSetting() { const autoModuleSetup = (placementRef) => { const isChidori = placementRef.isChidori.current === 'true' ? true : false const setupLocation = placementRef.setupLocation.current - const isMaxSetup = placementRef.isMaxSetup.current + const isMaxSetup = placementRef.isMaxSetup.current === 'true' ? true : false const moduleSetupSurfaces = moduleSetupSurface //선택 설치면 @@ -539,29 +540,34 @@ export function useModuleBasicSetting() { let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) let diffTopEndPoint = Math.abs(totalTopEndPoint / height) let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음 + if (isMaxSetup) totalWidth = totalWidth * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함 for (let j = 0; j < diffTopEndPoint; j++) { bottomMargin = j === 0 ? 1 : 0 for (let i = 0; i <= totalWidth; i++) { - leftMargin = i === 0 ? 1 : 0 //숫자가 0이면 0, 1이면 1로 바꾸기 + leftMargin = i === 0 ? 1.1 : 0 //숫자가 0이면 0, 1이면 1로 바꾸기 chidoriLength = 0 if (isChidori) { chidoriLength = j % 2 === 0 ? 0 : width / 2 } + let squarePolygon + let turfCoordnates + let points + square = [ - [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], - [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - bottomMargin], - [startColPoint + width * i + width - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + width * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], + [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], ] - let squarePolygon = turf.polygon([square]) - let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + squarePolygon = turf.polygon([square]) + turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) - // if (disjointFromTrestle && isDisjoint) { let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) canvas?.add(tempModule) moduleSetupArray.push(tempModule) @@ -581,25 +587,26 @@ export function useModuleBasicSetting() { let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - for (let j = 0; j < totalHeight; j++) { - bottomMargin = j === 0 ? 1 : 0 - for (let i = 0; i <= totalWidth; i++) { - leftMargin = 1 + let tempMaxHeight = isMaxSetup ? height / 2 : height //최대배치인지 확인하려고 넣음 + if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사 + + for (let i = 0; i <= totalWidth; i++) { + bottomMargin = i === 0 ? 1 : 0.1 + for (let j = 0; j < totalHeight; j++) { + leftMargin = i === 0 ? 0 : 0.5 * i chidoriLength = 0 if (isChidori) { - chidoriLength = i % 2 === 0 ? 0 : height / 2 + chidoriLength = j % 2 === 0 ? 0 : height / 2 } square = [ - [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + width + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + height + bottomMargin - chidoriLength], - [startPoint.x1 + width * i + leftMargin, startRowPoint + height * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin - chidoriLength], + [startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin - chidoriLength], ] - console.log('square', square) - let squarePolygon = turf.polygon([square]) let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) @@ -622,9 +629,11 @@ export function useModuleBasicSetting() { let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1 let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) - let diffRightEndPoint = Math.abs(totalRightEndPoint / width) - let diffBottomEndPoint = Math.abs(totalBottomEndPoint / height) + let diffRightEndPoint = Math.ceil(Math.abs(totalRightEndPoint / width)) + let diffBottomEndPoint = Math.ceil(Math.abs(totalBottomEndPoint / height)) let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) + let tempMaxWidth = isMaxSetup ? width / 2 : width //최대배치인지 확인하려고 넣음 + if (isMaxSetup) diffRightEndPoint = diffRightEndPoint * 2 //최대배치시 2배로 늘려서 반씩 검사하기위함 for (let j = 0; j < diffBottomEndPoint; j++) { for (let i = 0; i < diffRightEndPoint; i++) { @@ -633,11 +642,11 @@ export function useModuleBasicSetting() { chidoriLength = j % 2 === 0 ? 0 : width / 2 } square = [ - [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + 1], - [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + height + 1], - [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j + height + 1], - [startColPoint + width * i + width + chidoriLength, startPoint.y1 + height * j + 1], - [startColPoint + width * i + chidoriLength, startPoint.y1 + height * j + 1], + [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], ] let squarePolygon = turf.polygon([square]) @@ -662,23 +671,26 @@ export function useModuleBasicSetting() { let diffTopEndPoint = Math.abs(totalTopEndPoint / height) let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width - let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) + let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - 3 // -3으로 위치살짝 보정 - for (let j = 0; j < totalHeight; j++) { - bottomMargin = j === 0 ? 1 : 0 - for (let i = 0; i <= totalWidth; i++) { - leftMargin = 1 + let tempMaxHeight = isMaxSetup ? height / 2 : height //최대배치인지 확인하려고 넣음 + if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사 + + for (let i = 0; i <= totalWidth; i++) { + for (let j = 0; j < totalHeight; j++) { + bottomMargin = j === 0 ? 0.5 : 0.5 * j + leftMargin = i === 0 ? 0 : 0.5 * i chidoriLength = 0 if (isChidori) { chidoriLength = i % 2 === 0 ? 0 : height / 2 } square = [ - [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + bottomMargin + chidoriLength], - [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j + bottomMargin + chidoriLength], - [startPoint.x1 - width * i - width - leftMargin, startRowPoint + height * j + height + bottomMargin + chidoriLength], - [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + height + bottomMargin + chidoriLength], - [startPoint.x1 - width * i - leftMargin, startRowPoint + height * j + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin + chidoriLength], + [startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin + chidoriLength], ] let squarePolygon = turf.polygon([square]) @@ -743,10 +755,9 @@ export function useModuleBasicSetting() { if (moduleSetupSurface.flowDirection === 'north') { downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } - } else { } - const setupedModules = moduleSetupArray.filter((module) => { + const setupedModules = moduleSetupArray.filter((module, index) => { let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface) let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects) @@ -758,11 +769,29 @@ export function useModuleBasicSetting() { return module } }) + + console.log('setupedModules.length', setupedModules.length) + //나간애들 제외하고 설치된 애들로 겹친애들 삭제 하기 + setupedModules.forEach((module, index) => { + if (isMaxSetup && index > 0) { + const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(setupedModules[index - 1]), polygonToTurfPolygon(module)) + console.log(isOverlap) + //겹치는지 확인 + if (isOverlap) { + //겹쳐있으면 삭제 + // canvas?.remove(module) + // module.set({ fill: 'rgba(72, 161, 250, 0.4)', stroke: 'black', strokeWidth: 0.1 }) + canvas.renderAll() + setupedModules.splice(index, 1) + + return false + } + } + }) + moduleSetupSurface.set({ modules: setupedModules }) setModuleIsSetup(moduleSetupArray) }) - - // console.log(calculateForApi(moduleSetupArray)) } const calculateForApi = (moduleSetupArray) => { @@ -1129,7 +1158,7 @@ export function useModuleBasicSetting() { y2: standardLine.y1 + charlie, } } else { - rtnObj = { target: idx === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + rtnObj = { target: index === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } } rtnObjArray.push(rtnObj) }) From d305877d2d4adf829aeb0e996421ccbca24a8890 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Mon, 2 Dec 2024 16:01:50 +0900 Subject: [PATCH 13/98] =?UTF-8?q?=F0=9F=93=83fix:=20customHooks=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useCommonCode.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/hooks/common/useCommonCode.js b/src/hooks/common/useCommonCode.js index f912beb9..bab32007 100644 --- a/src/hooks/common/useCommonCode.js +++ b/src/hooks/common/useCommonCode.js @@ -5,14 +5,28 @@ import { globalLocaleStore } from '@/store/localeAtom' import { isObjectNotEmpty } from '@/util/common-utils' import { useAxios } from '../useAxios' +/** + * 공통코드 관리를 위한 커스텀 훅 + * + * @description + * - 공통코드를 전역 상태로 관리하고 필요한 곳에서 사용할 수 있도록 함 + * - 최초 1회만 API를 호출하여 공통코드를 가져옴 + * - 언어 설정에 따라 한국어/일본어 코드명을 자동으로 변환 + * + * @returns {Object} + * - commonCode: 전체 공통코드 객체(recoil state) + * - findCommonCode: 특정 공통코드 그룹을 조회하는 함수 + * + * @example + * const { commonCode, findCommonCode } = useCommonCode(); + * const honorificCodes = findCommonCode(200800); + */ export const useCommonCode = () => { const [commonCode, setCommonCode] = useRecoilState(commonCodeState) const globalLocale = useRecoilValue(globalLocaleStore) const { promiseGet } = useAxios() const findCommonCode = (key) => { - // const arr = commonCode[key] - // return arr.sort((a, b) => a.clPriority - b.clPriority) const resultCodes = commonCode[key]?.map((code) => { const result = { clHeadCd: code.clHeadCd, From ae1c28d52508b657d82a0167b718e4c4dd945886 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 2 Dec 2024 16:15:48 +0900 Subject: [PATCH 14/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B4=84?= =?UTF-8?q?=EC=A0=9C=ED=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 1 + src/hooks/floorPlan/estimate/useEstimateController.js | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 3c451220..531dcaa9 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -644,6 +644,7 @@ export default function Estimate({ params }) { bomItem.delFlg = '0' bomItem.objectNo = objectNo bomItem.planNo = planNo + bomItem.addFlg = true //봄 추가시도 addFlg }) setEstimateContextState({ diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 7790c9bb..414e9a06 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -273,9 +273,10 @@ export const useEstimateController = (planNo) => { } }) estimateData.estimateOption = estimateOptions - console.log('최종첨부파일:::', estimateData.newFileList) - console.log('최종아이템:::', estimateData.itemList) - console.log('최종저장::', estimateData) + // console.log('새로추가첨부파일:::', estimateData.newFileList) + // console.log('기존첨부파일:::', estimateData.originFiles) + // console.log('최종아이템:::', estimateData.itemList) + // console.log('최종저장::', estimateData) //2. 상세데이터 저장 // return try { From ca0fe4335ec79c309ccb1276a0c8732822c64786 Mon Sep 17 00:00:00 2001 From: minsik Date: Mon, 2 Dec 2024 16:30:21 +0900 Subject: [PATCH 15/98] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_contents.scss | 2 +- src/styles/spinner.scss | 152 +++++++++++--------------------------- 2 files changed, 45 insertions(+), 109 deletions(-) diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss index 08b40e93..e72637e4 100644 --- a/src/styles/_contents.scss +++ b/src/styles/_contents.scss @@ -884,7 +884,7 @@ border: 1px solid #ECF0F4; border-radius: 3px; padding: 24px; - max-height: 350px; + height: 350px; overflow-y: auto; margin-bottom: 30px; dl{ diff --git a/src/styles/spinner.scss b/src/styles/spinner.scss index 18993c78..b6398e94 100644 --- a/src/styles/spinner.scss +++ b/src/styles/spinner.scss @@ -1,109 +1,45 @@ -.spinner-wrap { - width: 100%; - height: 100vh; - display: flex; - align-items: center; - justify-content: center; - background-color: #fff; - .loader { - font-size: 10px; - width: 1.2em; - height: 1.2em; - border-radius: 50%; - position: relative; - text-indent: -9999em; - animation: mulShdSpin 1.1s infinite ease; - transform: translateZ(0); - } - @keyframes mulShdSpin { - 0%, - 100% { - box-shadow: - 0em -2.6em 0em 0em #101010, - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.5), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7); +.spinner-wrap{ + width: 100%; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background-color: #fff; + .loader { + font-size: 10px; + width: 1.2em; + height: 1.2em; + border-radius: 50%; + position: relative; + text-indent: -9999em; + animation: mulShdSpin 1.1s infinite ease; + transform: translateZ(0); } - 12.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.7), - 1.8em -1.8em 0 0em #101010, - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5); - } - 25% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.5), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7), - 2.5em 0em 0 0em #101010, - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 37.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.7), - 1.75em 1.75em 0 0em #101010, - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 50% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.5), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.7), - 0em 2.5em 0 0em #101010, - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 62.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.5), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.7), - -1.8em 1.8em 0 0em #101010, - -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 75% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.5), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.7), - -2.6em 0em 0 0em #101010, - -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); - } - 87.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), - 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), - 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), - 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), - 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), - -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.5), - -2.6em 0em 0 0em rgba(16, 16, 16, 0.7), - -1.8em -1.8em 0 0em #101010; - } - } -} + @keyframes mulShdSpin { + 0%, + 100% { + box-shadow: 0em -2.6em 0em 0em #101010, 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.5), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7); + } + 12.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.7), 1.8em -1.8em 0 0em #101010, 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5); + } + 25% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.5), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.7), 2.5em 0em 0 0em #101010, 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 37.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.5), 2.5em 0em 0 0em rgba(16, 16, 16, 0.7), 1.75em 1.75em 0 0em #101010, 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 50% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.5), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.7), 0em 2.5em 0 0em #101010, -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.2), -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 62.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.5), 0em 2.5em 0 0em rgba(16, 16, 16, 0.7), -1.8em 1.8em 0 0em #101010, -2.6em 0em 0 0em rgba(16, 16, 16, 0.2), -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 75% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.5), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.7), -2.6em 0em 0 0em #101010, -1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2); + } + 87.5% { + box-shadow: 0em -2.6em 0em 0em rgba(16, 16, 16, 0.2), 1.8em -1.8em 0 0em rgba(16, 16, 16, 0.2), 2.5em 0em 0 0em rgba(16, 16, 16, 0.2), 1.75em 1.75em 0 0em rgba(16, 16, 16, 0.2), 0em 2.5em 0 0em rgba(16, 16, 16, 0.2), -1.8em 1.8em 0 0em rgba(16, 16, 16, 0.5), -2.6em 0em 0 0em rgba(16, 16, 16, 0.7), -1.8em -1.8em 0 0em #101010; + } + } +} \ No newline at end of file From bf679bad1c432ea31e7b897733a2ecf42d0aad79 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 2 Dec 2024 16:46:47 +0900 Subject: [PATCH 16/98] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EA=B7=B8=EB=A3=B9?= =?UTF-8?q?=ED=99=94=20=EA=B3=84=EC=82=B0=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 64 +++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 7a72a379..980460dc 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -766,6 +766,7 @@ export function useModuleBasicSetting() { } const calculateForApi = (moduleSetupArray) => { + // TODO : 현재는 남쪽기준. 동,서,북 분기처리 필요 const centerPoints = [] moduleSetupArray.forEach((module, index) => { module.tempIndex = index @@ -825,10 +826,6 @@ export function useModuleBasicSetting() { exposedHalfBottom++ return } - if (leftBottomCnt + rightBottomCnt === 0) { - exposedBottom++ - return - } }) // 노출상면 체크 @@ -858,6 +855,22 @@ export function useModuleBasicSetting() { 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, @@ -868,6 +881,49 @@ export function useModuleBasicSetting() { } } + // polygon 내부 cell들의 centerPoint 배열을 그룹화 해서 반환 + const groupCoordinates = (points) => { + const groups = [] + const visited = new Set() + const width = 100 + const height = 100 + const horizonPadding = 5 // 가로 패딩 + const verticalPadding = 3 // 세로 패딩 + + 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) + ) + } + + function dfs(point, group) { + visited.add(`${point.x},${point.y}`) + group.push(point) + + for (const nextPoint of points) { + const key = `${nextPoint.x},${nextPoint.y}` + if (!visited.has(key) && isAdjacent(point, nextPoint)) { + dfs(nextPoint, group) + } + } + } + + for (const point of points) { + const key = `${point.x},${point.y}` + if (!visited.has(key)) { + const group = [] + dfs(point, group) + groups.push(group) + } + } + + return groups + } + const coordToTurfPolygon = (points) => { const coordinates = points.map((point) => [point.x, point.y]) coordinates.push(coordinates[0]) From 29cf1c11d9984887b28f8606dcb2ce72dbdda49b Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 3 Dec 2024 09:54:02 +0900 Subject: [PATCH 17/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9CYJOD=20?= =?UTF-8?q?=EC=98=A4=ED=94=88=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 24 +++++++++++++++++-- .../estimate/useEstimateController.js | 10 ++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 531dcaa9..7bedc1c7 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -600,7 +600,13 @@ export default function Estimate({ params }) { updates.showSalePrice = '0' updates.showSaleTotPrice = '0' } + } else { + if (res.openFlg === '1') { + updates.showSalePrice = '0' + updates.showSaleTotPrice = '0' + } } + //104671 let bomList = res.itemBomList @@ -719,8 +725,6 @@ export default function Estimate({ params }) { makeUniqueSpecialNoteCd(itemList) itemList.forEach((item) => { - delete item.showSalePrice - 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 @@ -731,6 +735,11 @@ export default function Estimate({ params }) { } totals.totAmount += amount totals.supplyPrice += price + + if (item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } } }) @@ -802,6 +811,13 @@ export default function Estimate({ params }) { item.showSaleTotPrice = '0' } }) + + estimateContextState.itemList.forEach((item) => { + if (estimateContextState.estimateType === 'YJOD' && item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } + }) } }, [itemChangeYn, estimateContextState.itemList]) @@ -1465,6 +1481,10 @@ export default function Estimate({ params }) { ? true : item.pkgMaterialFlg !== '1' : item.itemId === '' || !!item?.paDispOrder + ? true + : item.openFlg === '1' + ? true + : false } onChange={(e) => { onChangeSalePrice(e.target.value, item.dispOrder, index) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 414e9a06..016fda78 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -153,7 +153,7 @@ export const useEstimateController = (planNo) => { } if (flag) { if (!originFileFlg) { - if (estimateData.newFileList.length < 1) { + if (estimateData.newFileList?.length < 1) { if (estimateData.itemList.length > 1) { estimateData.itemList.map((row) => { if (row.delFlg === '0') { @@ -195,9 +195,11 @@ export const useEstimateController = (planNo) => { item.salePrice = '0' } - if (item.salePrice < 1) { - itemFlg = false - return alert(getMessage('estimate.detail.save.requiredSalePrice')) + if (item.openFlg !== '1') { + if (item.salePrice < 1) { + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredSalePrice')) + } } estimateData.pkgAsp = '0' From b7168f885b2476331387d99457c31299e50b4e48 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 3 Dec 2024 10:44:32 +0900 Subject: [PATCH 18/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 1 + src/locales/ko.json | 1 + 2 files changed, 2 insertions(+) diff --git a/src/locales/ja.json b/src/locales/ja.json index 23903120..7697cf69 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -901,6 +901,7 @@ "estimate.detail.save.requiredAmount": "数量は0より大きい値を入力してください.", "estimate.detail.save.requiredSalePrice": "単価は0より大きい値を入力してください.", "estimate.detail.reset.confirmMsg": "保存した見積書情報が初期化され、図面情報が反映されます。本当に初期化しますか?", + "estimate.detail.confirm.delFile": "添付ファイルを完全に削除するには[保存]ボタンをクリックしてください", "simulator.title.sub1": "物件番号", "simulator.title.sub2": "作成日", "simulator.title.sub3": "システム容量", diff --git a/src/locales/ko.json b/src/locales/ko.json index 0cf7217b..4b12d055 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -911,6 +911,7 @@ "estimate.detail.save.requiredAmount": "수량은 0보다 큰값을 입력해주세요.", "estimate.detail.save.requiredSalePrice": "단가는 0보다 큰값을 입력해주세요.", "estimate.detail.reset.confirmMsg": "저장된 견적서 정보가 초기화되고, 도면정보가 반영됩니다. 정말로 초기화 하시겠습니까?", + "estimate.detail.alert.delFile": "첨부파일을 완전히 삭제하려면 [저장]버튼을 클릭하십시오.", "simulator.title.sub1": "물건번호", "simulator.title.sub2": "작성일", "simulator.title.sub3": "시스템 용량", From 204a222e133663ca82a7fbcaf1168d6e2c89135e Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 3 Dec 2024 12:02:31 +0900 Subject: [PATCH 19/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 28 ++++++++++--------- .../estimate/useEstimateController.js | 11 +++++--- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 7bedc1c7..bb4dbe27 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -226,25 +226,26 @@ export default function Estimate({ params }) { } }, [estimateContextState?.fileList]) - // 기존첨부파일 삭제 + // 기존첨부파일 삭제 (플래그값 추가?) 저장할때 플래그값에 따라 진짜 삭제 const deleteOriginFile = async (objectNo, no) => { const delParams = { userId: session.userId, objectNo: objectNo, no: no, } - 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), - }) + 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), + // }) - alert(getMessage('plan.message.delete')) - } - }) + // alert(getMessage('plan.message.delete')) + // } + // }) } //가격표시 option 목록 최초세팅 && 주문분류 변경시 @@ -725,6 +726,8 @@ export default function Estimate({ params }) { makeUniqueSpecialNoteCd(itemList) itemList.forEach((item) => { + delete item.showSalePrice + 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 @@ -750,7 +753,6 @@ export default function Estimate({ params }) { const calculateYJSSTotals = (itemList) => { itemList.sort((a, b) => a.dispOrder - b.dispOrder) makeUniqueSpecialNoteCd(itemList) - itemList.forEach((item) => { if (item.delFlg === '0') { let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 016fda78..2c863a15 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -148,6 +148,11 @@ export const useEstimateController = (planNo) => { //첨부파일을 첨부안했는데 //아이템 fileUploadFlg가1(첨부파일 필수)이 1개라도 있는데 후일 자료 제출(fileFlg) 체크안했으면(0) alert 저장안돼 + console.log('새로추가첨부파일:::', estimateData.newFileList) + console.log('기존첨부파일:::', estimateData.originFiles) + + // return + if (estimateData?.originFiles?.length > 0) { originFileFlg = true } @@ -275,10 +280,8 @@ export const useEstimateController = (planNo) => { } }) estimateData.estimateOption = estimateOptions - // console.log('새로추가첨부파일:::', estimateData.newFileList) - // console.log('기존첨부파일:::', estimateData.originFiles) - // console.log('최종아이템:::', estimateData.itemList) - // console.log('최종저장::', estimateData) + console.log('최종아이템:::', estimateData.itemList) + console.log('최종저장::', estimateData) //2. 상세데이터 저장 // return try { From 5e51952aabf98605d1e8905b9b7d75813fa65fb7 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 3 Dec 2024 12:39:53 +0900 Subject: [PATCH 20/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=ED=8A=B9?= =?UTF-8?q?=EC=9D=B4=EC=82=AC=ED=95=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 5 ++--- src/hooks/floorPlan/estimate/useEstimateController.js | 7 +++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index bb4dbe27..a14622f7 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -360,7 +360,6 @@ export default function Estimate({ params }) { } } }) - setEstimateContextState({ specialNoteList: specialNoteList, uniqueData: uniqueData, @@ -473,7 +472,7 @@ export default function Estimate({ params }) { //주택PKG input 변경 const onChangePkgAsp = (value) => { if (estimateContextState.estimateType === 'YJSS') { - let pkgAsp = Number(value.replaceAll(',', '')) + let pkgAsp = Number(value.replace(/[^0-9]/g, '').replaceAll(',', '')) if (isNaN(pkgAsp)) { pkgAsp = 0 } else { @@ -482,7 +481,7 @@ export default function Estimate({ params }) { //현재 PKG용량값 가져오기 let totVolKw = estimateContextState.totVolKw * 1000 - let pkgTotPrice = pkgAsp.replaceAll(',', '') * totVolKw * 1000 + let pkgTotPrice = pkgAsp?.replaceAll(',', '') * totVolKw * 1000 setEstimateContextState({ pkgAsp: pkgAsp, diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 2c863a15..f59ed69e 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -256,6 +256,7 @@ export const useEstimateController = (planNo) => { }) let estimateOptions = '' + let estimateOptionsArray estimateData.specialNoteList.map((item) => { if (item.pkgYn === '0') { if (item.check) { @@ -279,6 +280,12 @@ export const useEstimateController = (planNo) => { } } }) + + estimateOptionsArray = estimateOptions.split('、').sort() + estimateOptionsArray = Array.from(new Set(estimateOptionsArray)) + + estimateOptions = estimateOptionsArray.join('、') + estimateData.estimateOption = estimateOptions console.log('최종아이템:::', estimateData.itemList) console.log('최종저장::', estimateData) From eeb2ba6c17b753bc976c4ad8739fddd29f102723 Mon Sep 17 00:00:00 2001 From: minsik Date: Tue, 3 Dec 2024 13:05:41 +0900 Subject: [PATCH 21/98] =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 5 +++++ src/locales/ko.json | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/locales/ja.json b/src/locales/ja.json index 23903120..0409bee0 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -341,6 +341,7 @@ "modal.panel.column.insert.info": "挿入する方向を選択してください。", "modal.panel.column.insert.type.left": "左挿入", "modal.panel.column.insert.type.right": "右挿入", + "modal.image.load.size.rotate": "サイズ調整と回転", "contextmenu.column.insert": "列の挿入", "contextmenu.row.move": "단 이동(JA)", "contextmenu.row.copy": "단 복사(JA)", @@ -483,9 +484,13 @@ "common.message.writeToConfirm": "作成解除を実行しますか?", "common.message.password.init.success": "パスワード [{0}] に初期化されました。", "common.message.no.edit.save": "この文書は変更できません。", + "common.load": "ファイルの追加", "common.input.file": "ファイルを読み込む", "common.input.file.load": "ファイルの追加", + "common.input.image.load": "이미지 불러오기", + "common.input.address.load": "アドレスを読み込む", "common.require": "必須", + "common.finish": "完了", "common.ok": "確認", "commons.west": "立つ", "commons.east": "ドン", diff --git a/src/locales/ko.json b/src/locales/ko.json index 0cf7217b..2adcdb28 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -348,6 +348,7 @@ "modal.panel.column.insert.info": "삽입할 방향을 선택해주세요.", "modal.panel.column.insert.type.left": "왼쪽 삽입", "modal.panel.column.insert.type.right": "오른쪽 삽입", + "modal.image.load.size.rotate": "크기 조절 및 회전", "contextmenu.row.move": "단 이동", "contextmenu.row.copy": "단 복사", "contextmenu.row.remove": "단 삭제", @@ -492,9 +493,13 @@ "common.message.writeToConfirm": "작성 해제를 실행하시겠습니까?", "common.message.password.init.success": "비밀번호 [{0}]로 초기화 되었습니다.", "common.message.no.edit.save": "This document cannot be changed.", + "common.load": "불러오기", "common.input.file": "파일 불러오기", "common.input.file.load": "불러오기", + "common.input.image.load": "이미지 불러오기", + "common.input.address.load": "주소 불러오기", "common.require": "필수", + "common.finish": "완료", "common.ok": "확인", "commons.west": "서", "commons.east": "동", From 57ce17a9323985bb9f15de5b294f865c1b96fa23 Mon Sep 17 00:00:00 2001 From: minsik Date: Tue, 3 Dec 2024 13:08:29 +0900 Subject: [PATCH 22/98] =?UTF-8?q?-=20=ED=8C=8C=EC=9D=BC=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EA=B3=B5=ED=86=B5=20=EC=BD=94=EB=93=9C=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20-=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20-=20=EB=8B=A4?= =?UTF-8?q?=EA=B5=AD=EC=96=B4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/html2canvas/route.js | 10 +-- src/app/api/image-upload/route.js | 20 ++--- src/components/floor-plan/modal/ImgLoad.jsx | 31 ++++---- src/hooks/common/useRefFiles.js | 81 ++++++++++++++++++--- src/hooks/usePlan.js | 9 +++ src/lib/fileAction.js | 62 ++++++++++++---- 6 files changed, 155 insertions(+), 58 deletions(-) diff --git a/src/app/api/html2canvas/route.js b/src/app/api/html2canvas/route.js index ada6c54a..21f93c82 100644 --- a/src/app/api/html2canvas/route.js +++ b/src/app/api/html2canvas/route.js @@ -3,6 +3,7 @@ import fs from 'fs/promises' import { NextResponse } from 'next/server' +import { writeImage, writeImageBuffer } from '@/lib/fileAction' export async function GET(req) { const path = 'public/plan-map-images' @@ -15,14 +16,7 @@ export async function GET(req) { const response = await fetch(decodeUrl) const data = await response.arrayBuffer() const buffer = Buffer.from(data) - - try { - await fs.readdir(path) - } catch { - await fs.mkdir(path) - } finally { - await fs.writeFile(`${path}/${fileNm}.png`, buffer) - } + await writeImage(fileNm, buffer) return NextResponse.json({ fileNm: `${fileNm}.png` }) } diff --git a/src/app/api/image-upload/route.js b/src/app/api/image-upload/route.js index e817bd3b..92cf7da4 100644 --- a/src/app/api/image-upload/route.js +++ b/src/app/api/image-upload/route.js @@ -3,23 +3,25 @@ import fs from 'fs/promises' import { NextResponse } from 'next/server' +import { writeImage } from '@/lib/fileAction' export async function POST(req) { const path = 'public/plan-bg-images' const formData = await req.formData() const file = formData.get('file') + const fileName = formData.get('fileName') const arrayBuffer = await file.arrayBuffer() const buffer = Buffer.from(arrayBuffer) // const buffer = new Uint8Array(arrayBuffer) + await writeImage(fileName, buffer) + // try { + // await fs.readdir(path) + // } catch { + // await fs.mkdir(path) + // } finally { + // await fs.writeFile(`${path}/${fileName}`, buffer) + // } - try { - await fs.readdir(path) - } catch { - await fs.mkdir(path) - } finally { - await fs.writeFile(`${path}/${file.name}`, buffer) - } - - return NextResponse.json({ fileNm: `${file.name}` }) + return NextResponse.json({ fileNm: `${fileName}` }) } diff --git a/src/components/floor-plan/modal/ImgLoad.jsx b/src/components/floor-plan/modal/ImgLoad.jsx index c95d62a9..d5724972 100644 --- a/src/components/floor-plan/modal/ImgLoad.jsx +++ b/src/components/floor-plan/modal/ImgLoad.jsx @@ -22,18 +22,20 @@ export default function ImgLoad() { setMapPositionAddress, handleFileDelete, handleMapImageDown, + handleAddressDelete, } = useRefFiles() const { currentCanvasPlan } = usePlan() const { getMessage } = useMessage() const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext) const handleModal = () => { + console.log(floorPlanState) setFloorPlanState({ ...floorPlanState, refFileModalOpen: false }) } useEffect(() => { - console.log('🚀 ~ ImgLoad ~ floorPlanState.refFileModalOpen:', floorPlanState.refFileModalOpen) - console.log('🚀 ~ ImgLoad ~ currentCanvasPlan:', currentCanvasPlan) + // console.log('🚀 ~ ImgLoad ~ floorPlanState.refFileModalOpen:', floorPlanState.refFileModalOpen) + // console.log('🚀 ~ ImgLoad ~ currentCanvasPlan:', currentCanvasPlan) }, [floorPlanState.refFileModalOpen]) useEffect(() => { @@ -50,7 +52,7 @@ export default function ImgLoad() {
- サイズ調整と回転 + {getMessage('modal.image.load.size.rotate')}
diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index 05f60afe..5997b399 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -5,7 +5,7 @@ import { v4 as uuidv4 } from 'uuid' import { useSwal } from '@/hooks/useSwal' import { useAxios } from '../useAxios' import { currentCanvasPlanState } from '@/store/canvasAtom' -import { convertDwgToPng, writeImageBuffer } from '@/lib/fileAction' +import { convertDwgToPng, removeImage, writeImageBuffer } from '@/lib/fileAction' export function useRefFiles() { const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL @@ -19,17 +19,51 @@ export function useRefFiles() { const { get, promisePut, promisePost } = useAxios() // const { currentCanvasPlan, setCurrentCanvasPlan } = usePlan() + useEffect(() => { + console.log('refImage', refImage) + }, [refImage]) + + useEffect(() => { + if (refFileMethod === '1') { + // 파일 불러오기 + setMapPositionAddress('') + } else { + setRefImage(null) + } + }, [refFileMethod]) /** * 파일 불러오기 버튼 컨트롤 * @param {*} file */ const handleRefFile = (file) => { - setRefImage(file) + console.log('handleRefFile', file) + console.log('refImage', refImage) + if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) { + // setRefImage(file) + file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) + } else { + swalFire({ + text: '이미지가 아닙니다.', + type: 'alert', + icon: 'error', + }) + } + if (refImage) { + swalFire({ + text: '파일을 변경하시겠습니까?', + type: 'confirm', + confirmFn: () => { + setRefImage(file) + file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) + }, + }) + } + /** * 파일 확장자가 dwg일 경우 변환하여 이미지로 저장 * 파일 확장자가 이미지일 경우 이미지 저장 */ - file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) + // handleUploadRefFile(file) } @@ -37,15 +71,34 @@ export function useRefFiles() { * 파일 삭제 */ const handleFileDelete = () => { - setRefImage(null) - setCurrentCanvasPlan((prev) => ({ ...prev, bgFileName: null })) + swalFire({ + text: '삭제하시겠습니까?', + type: 'confirm', + confirmFn: () => { + setRefImage(null) + setCurrentCanvasPlan((prev) => ({ ...prev, bgFileName: null })) + removeImage(currentCanvasPlan.id).then((res) => { + console.log(res) + }) + }, + }) } /** * 주소 삭제 */ const handleAddressDelete = () => { - setCurrentCanvasPlan((prev) => ({ ...prev, mapPositionAddress: null })) + swalFire({ + text: '삭제하시겠습니까?', + type: 'confirm', + confirmFn: () => { + setMapPositionAddress('') + setCurrentCanvasPlan((prev) => ({ ...prev, mapPositionAddress: null })) + removeImage(currentCanvasPlan.id).then((res) => { + console.log(res) + }) + }, + }) } /** @@ -56,9 +109,10 @@ export function useRefFiles() { return } - const res = await get({ url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${uuidv4()}&zoom=20` }) - console.log('🚀 ~ handleMapImageDown ~ res:', res) - setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: res.fileNm, mapPositionAddress: queryRef.current.value })) + const res = await get({ url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20` }) + // console.log('🚀 ~ handleMapImageDown ~ res:', res) + console.log('currentCanvasPlan', currentCanvasPlan) + setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) } /** @@ -66,9 +120,10 @@ export function useRefFiles() { * @param {*} file */ const handleUploadImageRefFile = async (file) => { - console.log('🚀 ~ handleUploadImageRefFile ~ file:', file) + // console.log('🚀 ~ handleUploadImageRefFile ~ file:', file) const formData = new FormData() formData.append('file', file) + formData.append('fileName', currentCanvasPlan.id) const response = await fetch('http://localhost:3000/api/image-upload', { method: 'POST', @@ -76,7 +131,8 @@ export function useRefFiles() { }) const result = await response.json() - console.log('🚀 ~ handleUploadImageRefFile ~ res:', result) + setRefImage(file) + // console.log('🚀 ~ handleUploadImageRefFile ~ res:', result) // writeImageBuffer(file) } @@ -92,6 +148,7 @@ export function useRefFiles() { .then((res) => { convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData) swalFire({ text: '파일 변환 성공' }) + setRefImage(res.data.Files[0].FileData) }) .catch((err) => { swalFire({ text: '파일 변환 실패', icon: 'error' }) @@ -110,7 +167,7 @@ export function useRefFiles() { * 현재 플랜이 변경되면 플랜 상태 저장 */ useEffect(() => { - console.log('🚀 ~ useRefFiles ~ currentCanvasPlan:', currentCanvasPlan) + // console.log('🚀 ~ useRefFiles ~ currentCanvasPlan:', currentCanvasPlan) // const handleCurrentPlan = async () => { // await promisePut({ url: '/api/canvas-management/canvas-statuses', data: currentCanvasPlan }).then((res) => { // console.log('🚀 ~ awaitpromisePut ~ res:', res) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 6b1336a5..3f3ad1a0 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -6,6 +6,7 @@ import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' import { useSwal } from '@/hooks/useSwal' import { SAVE_KEY } from '@/common/common' +import { readImage } from '@/lib/fileAction' export function usePlan() { const [planNum, setPlanNum] = useState(0) @@ -204,6 +205,7 @@ export function usePlan() { userId: userId, imageName: 'image_name', // api 필수항목이여서 임시로 넣음, 이후 삭제 필요 objectNo: currentCanvasPlan.objectNo, + mapPositionAddress: currentCanvasPlan.mapPositionAddress, canvasStatus: canvasToDbFormat(canvasStatus), } await promisePost({ url: '/api/canvas-management/canvas-statuses', data: planData }) @@ -233,6 +235,7 @@ export function usePlan() { const putCanvasStatus = async (canvasStatus) => { const planData = { id: currentCanvasPlan.id, + mapPositionAddress: currentCanvasPlan.mapPositionAddress, canvasStatus: canvasToDbFormat(canvasStatus), } await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData }) @@ -285,6 +288,7 @@ export function usePlan() { updateCurrentPlan(newCurrentId) } } + const updateCurrentPlan = (newCurrentId) => { setPlans((plans) => plans.map((plan) => { @@ -295,8 +299,13 @@ export function usePlan() { useEffect(() => { setCurrentCanvasPlan(plans.find((plan) => plan.isCurrent) || null) setSelectedPlan(plans.find((plan) => plan.isCurrent)) + // setBgImage() }, [plans]) + const setBgImage = () => { + readImage(selectedPlan?.id) + } + /** * 새로운 plan 생성 * 현재 plan의 데이터가 있을 경우 복제 여부를 확인 diff --git a/src/lib/fileAction.js b/src/lib/fileAction.js index d09473a8..6f88758a 100644 --- a/src/lib/fileAction.js +++ b/src/lib/fileAction.js @@ -4,6 +4,7 @@ import fs from 'fs/promises' const CAD_FILE_PATH = 'public/cad-images' const IMAGE_FILE_PATH = 'public/plan-bg-images' +const FILE_PATH = 'public/plan-images' /** * 파일 변환 & 저장 @@ -39,25 +40,54 @@ const writeImageBase64 = async (title, data) => { return fs.writeFile(`${IMAGE_FILE_PATH}/${title}.png`, data, 'base64') } -/** - * 이미지 저장 - * Buffer 형식으로 저장 - * @param {*} title - * @param {*} data - * @returns - */ -const writeImageBuffer = async (file) => { - // 해당 경로에 Directory 가 없다면 생성 +// /** +// * 이미지 저장 +// * Buffer 형식으로 저장 +// * @param {*} title +// * @param {*} data +// * @returns +// */ +// const writeImageBuffer = async (file) => { +// // 해당 경로에 Directory 가 없다면 생성 +// try { +// await fs.readdir(IMAGE_FILE_PATH) +// } catch { +// await fs.mkdir(IMAGE_FILE_PATH) +// } +// +// const arrayBuffer = await fileURLToPath.arrayBuffer() +// const buffer = new Uint8Array(arrayBuffer) +// +// return fs.writeFile(`${IMAGE_FILE_PATH}/${file.fileName}`, buffer) +// } + +const writeImage = async (fileName, file) => { try { - await fs.readdir(IMAGE_FILE_PATH) + await fs.readdir(FILE_PATH) } catch { - await fs.mkdir(IMAGE_FILE_PATH) + await fs.mkdir(FILE_PATH) } - const arrayBuffer = await fileURLToPath.arrayBuffer() - const buffer = new Uint8Array(arrayBuffer) - - return fs.writeFile(`${IMAGE_FILE_PATH}/${file.fileName}`, buffer) + return fs.writeFile(`${FILE_PATH}/${fileName}.png`, file) } -export { convertDwgToPng, writeImageBase64, writeImageBuffer } +const readImage = async (fileName) => { + await fs + .readFile(`${FILE_PATH}/${fileName}.png`) + .then((res) => { + console.log('readImage-then', res) + }) + .catch((e) => { + console.log('readImage-catch', e) + }) +} + +const removeImage = async (fileName) => { + try { + await fs.rm(`${FILE_PATH}/${fileName}.png`) + } catch (e) { + console.log(e) + } +} + +export { convertDwgToPng, writeImageBase64, writeImage, readImage, removeImage } From d0eee3cb60db3cd9640b7cd152aed60c1e4eda24 Mon Sep 17 00:00:00 2001 From: minsik Date: Tue, 3 Dec 2024 13:08:46 +0900 Subject: [PATCH 23/98] =?UTF-8?q?-=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/grid/GridCopy.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/grid/GridCopy.jsx b/src/components/floor-plan/modal/grid/GridCopy.jsx index 86f79df7..2f768406 100644 --- a/src/components/floor-plan/modal/grid/GridCopy.jsx +++ b/src/components/floor-plan/modal/grid/GridCopy.jsx @@ -17,8 +17,7 @@ export default function GridCopy(props) { const currentObject = useRecoilValue(currentObjectState) const { copy } = useGrid() const handleApply = () => { - // copy(currentObject, ) - copy(currentObject, ['↑', '←'].includes(arrow) ? Number(length) * -1 : Number(length)) + copy(currentObject, ['↑', '←'].includes(arrow) ? +length * -1 : +length) } return ( From 4aae0bccb3ed3867f7c9bc712b5e1286713d5a62 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 3 Dec 2024 13:13:53 +0900 Subject: [PATCH 24/98] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=B5=9C=EB=8C=80?= =?UTF-8?q?=EB=B0=B0=EC=B9=98,=20=EC=A4=91=EC=95=99=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 214 ++++++++++++++++------ 1 file changed, 156 insertions(+), 58 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 85597456..361347f0 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -52,6 +52,7 @@ export function useModuleBasicSetting() { parentId: roof.id, //가대 폴리곤의 임시 인덱스를 넣어줌 name: POLYGON_TYPE.MODULE_SETUP_SURFACE, flowDirection: roof.direction, + direction: roof.direction, flipX: roof.flipX, flipY: roof.flipY, surfaceId: surfaceId, @@ -60,16 +61,15 @@ export function useModuleBasicSetting() { setupSurface.setViewLengthText(false) canvas.add(setupSurface) //모듈설치면 만들기 - if (setupSurface.flowDirection === 'south' || setupSurface.flowDirection === 'north') { - setupSurface.set({ - flowLines: bottomTopFlowLine(setupSurface), - }) - } else { - setupSurface.set({ - flowLines: leftRightFlowLine(setupSurface), - }) + const flowLines = { + bottom: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'bottom'), + top: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'top'), + left: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'left'), + right: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'right'), } + setupSurface.set({ flowLines: flowLines }) + //지붕면 선택 금지 roof.set({ selectable: false, @@ -527,13 +527,40 @@ export function useModuleBasicSetting() { return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface) } - const downFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { + const downFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.bottom + + if (isCenter) { + //중앙배치일 경우에는 계산한다 + + if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치 + const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다 + const halfModuleWidthLength = width / 2 + startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + + if (flowModuleLine.top.type === 'flat') { + //상단까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산 + const heightLength = Math.abs(flowModuleLine.left.y1 - flowModuleLine.left.y2) //옆에에 길이에서 반을 가른다 + const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2 + startPoint = { ...startPoint, y1: startPoint.y1 - heightMargin } + } + } + } + // else { + // //중앙배치가 아닐때도 흐름 방향 기준면으로 양면이 직선이면 가운데 배치 + // if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + // //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치 + // const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다 + // const halfModuleWidthLength = width / 2 + // startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + // } + // } + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 - let startPoint = flowModuleLine.find((obj) => obj.target === 'bottom') - let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 let totalTopEndPoint = maxTopEndPoint - startPoint.y1 let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) @@ -552,10 +579,6 @@ export function useModuleBasicSetting() { chidoriLength = j % 2 === 0 ? 0 : width / 2 } - let squarePolygon - let turfCoordnates - let points - square = [ [startColPoint + tempMaxWidth * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], [startColPoint + tempMaxWidth * i + width - chidoriLength, startPoint.y1 - height * j - bottomMargin], @@ -564,9 +587,9 @@ export function useModuleBasicSetting() { [startColPoint + tempMaxWidth * i - chidoriLength, startPoint.y1 - height * j - bottomMargin], ] - squarePolygon = turf.polygon([square]) - turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) - points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) + let squarePolygon = turf.polygon([square]) + let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) + let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) canvas?.add(tempModule) @@ -575,12 +598,29 @@ export function useModuleBasicSetting() { } } - const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { - let startPoint = flowModuleLine.find((obj) => obj.target === 'left') + const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.left + + //중앙배치일 경우에는 계산한다 + if (isCenter) { + if (flowModuleLine.left.type === 'flat' && flowModuleLine.bottom.type === 'flat' && flowModuleLine.top.type === 'flat') { + //좌측 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치 + const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //밑에 길이에서 반을 가른다 + const halfModuleWidthLength = height / 2 + startPoint = { ...startPoint, y1: halfWidthLength - halfModuleWidthLength } + if (flowModuleLine.right.type === 'flat') { + //우측까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산 + const widthLength = Math.abs(flowModuleLine.top.x1 - flowModuleLine.top.x2) //옆에에 길이에서 반을 가른다 + const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2 + startPoint = { ...startPoint, x1: startPoint.x1 + widthMargin } + } + } + } const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단 + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 let diffTopEndPoint = Math.abs(totalTopEndPoint / height) let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) @@ -596,7 +636,7 @@ export function useModuleBasicSetting() { leftMargin = i === 0 ? 0 : 0.5 * i chidoriLength = 0 if (isChidori) { - chidoriLength = j % 2 === 0 ? 0 : height / 2 + chidoriLength = i % 2 === 0 ? 0 : height / 2 } square = [ @@ -619,12 +659,39 @@ export function useModuleBasicSetting() { } } - const topFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { - let startPoint = flowModuleLine.find((obj) => obj.target === 'top') + const topFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.top + + if (isCenter) { + //중앙배치일 경우에는 계산한다 + if (flowModuleLine.top.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치 + const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다 + const halfModuleWidthLength = width / 2 + startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + + if (flowModuleLine.bottom.type === 'flat') { + //상단까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산 + const heightLength = Math.abs(flowModuleLine.left.y1 - flowModuleLine.left.y2) //옆에에 길이에서 반을 가른다 + const heightMargin = Math.abs(heightLength - height * Math.floor(heightLength / height)) / 2 + startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength, y1: startPoint.y1 - heightMargin } + } + } + } + // else { + // //중앙배치가 아닐때도 흐름 방향 기준면으로 양면이 직선이면 가운데 배치 + // if (flowModuleLine.bottom.type === 'flat' && flowModuleLine.left.type === 'flat' && flowModuleLine.right.type === 'flat') { + // //하단 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치 + // const halfWidthLength = Math.abs(startPoint.x1 + startPoint.x2) / 2 //밑에 길이에서 반을 가른다 + // const halfModuleWidthLength = width / 2 + // startPoint = { ...startPoint, x1: halfWidthLength - halfModuleWidthLength } + // } + // } + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 - const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단 + let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1 @@ -661,12 +728,29 @@ export function useModuleBasicSetting() { } } - const rightFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine) => { - let startPoint = flowModuleLine.find((obj) => obj.target === 'right') - const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 + const rightFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => { + let startPoint = flowModuleLine.right + if (isCenter) { + if (flowModuleLine.left.type === 'flat' && flowModuleLine.bottom.type === 'flat' && flowModuleLine.top.type === 'flat') { + //좌측 기준으로 양면이 직선이면 하단 방면으로 가운데로 배치 + const halfWidthLength = Math.abs(startPoint.y1 + startPoint.y2) / 2 //밑에 길이에서 반을 가른다 + const halfModuleWidthLength = height / 2 + startPoint = { ...startPoint, y1: halfWidthLength + halfModuleWidthLength } + + if (flowModuleLine.right.type === 'flat') { + //우측까지 평면이면 직사각,정사각이라 가정하고 상자의 중심으로 계산 + const widthLength = Math.abs(flowModuleLine.top.x1 - flowModuleLine.top.x2) //옆에에 길이에서 반을 가른다 + const widthMargin = Math.abs(widthLength - width * Math.floor(widthLength / width)) / 2 + startPoint = { ...startPoint, x1: startPoint.x1 - widthMargin } + } + } + } + + const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단 + let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌 let diffTopEndPoint = Math.abs(totalTopEndPoint / height) let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height) @@ -743,6 +827,7 @@ export function useModuleBasicSetting() { topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } } else if (setupLocation === 'ridge') { + //용마루 if (moduleSetupSurface.flowDirection === 'south') { topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } @@ -755,6 +840,20 @@ export function useModuleBasicSetting() { if (moduleSetupSurface.flowDirection === 'north') { downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines) } + } else if (setupLocation === 'center') { + //중가면 + if (moduleSetupSurface.flowDirection === 'south') { + downFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } + if (moduleSetupSurface.flowDirection === 'west') { + leftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } + if (moduleSetupSurface.flowDirection === 'east') { + rightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } + if (moduleSetupSurface.flowDirection === 'north') { + topFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface.flowLines, true) + } } const setupedModules = moduleSetupArray.filter((module, index) => { @@ -762,28 +861,26 @@ export function useModuleBasicSetting() { let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects) if (!(disjointFromTrestle && isDisjoint)) { - // canvas?.remove(module) - module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) + canvas?.remove(module) + // module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 }) return false } else { return module } }) - console.log('setupedModules.length', setupedModules.length) //나간애들 제외하고 설치된 애들로 겹친애들 삭제 하기 setupedModules.forEach((module, index) => { if (isMaxSetup && index > 0) { const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(setupedModules[index - 1]), polygonToTurfPolygon(module)) - console.log(isOverlap) + //겹치는지 확인 if (isOverlap) { //겹쳐있으면 삭제 - // canvas?.remove(module) + canvas?.remove(module) // module.set({ fill: 'rgba(72, 161, 250, 0.4)', stroke: 'black', strokeWidth: 0.1 }) canvas.renderAll() setupedModules.splice(index, 1) - return false } } @@ -1054,13 +1151,13 @@ export function useModuleBasicSetting() { const pointX2 = coords[2].x + ((coords[2].y - top) / (coords[2].y - coords[1].y)) * (coords[1].x - coords[2].x) const pointY2 = top - const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - }) - canvas?.add(finalLine) - canvas?.renderAll() + // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { + // stroke: 'red', + // strokeWidth: 1, + // selectable: true, + // }) + // canvas?.add(finalLine) + // canvas?.renderAll() let rtnObj //평평하면 @@ -1071,14 +1168,14 @@ export function useModuleBasicSetting() { //bottom standardLine = surface.lines.reduce((acc, line, index) => { if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.y2 > acc.y2)) { - return { x1: line.x1, y1: line.y1, index: index } + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } } return acc }) } else { standardLine = surface.lines.reduce((acc, line, index) => { if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.y2 < acc.y2)) { - return { x1: line.x1, y1: line.y1, index: index } + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } } return acc }) @@ -1087,11 +1184,12 @@ export function useModuleBasicSetting() { target: index === 0 ? 'bottom' : 'top', x1: standardLine.x1, y1: standardLine.y1, - x2: standardLine.x1 + charlie, - y2: standardLine.y1, + x2: standardLine.x2, + y2: standardLine.y2, + type: 'flat', } } else { - rtnObj = { target: index === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + rtnObj = { target: index === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2, type: 'curve' } } rtnObjArray.push(rtnObj) @@ -1124,7 +1222,6 @@ export function useModuleBasicSetting() { ) flowArray.push(rightFlow) - let idx = 0 let rtnObjArray = [] flowArray.forEach((center, index) => { const linesArray = surface.lines.filter((line) => { @@ -1177,13 +1274,13 @@ export function useModuleBasicSetting() { const pointX2 = top const pointY2 = coords[2].y + ((coords[2].x - top) / (coords[2].x - coords[1].x)) * (coords[1].y - coords[2].y) - const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - }) - canvas?.add(finalLine) - canvas?.renderAll() + // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { + // stroke: 'red', + // strokeWidth: 1, + // selectable: true, + // }) + // canvas?.add(finalLine) + // canvas?.renderAll() let rtnObj //평평하면 @@ -1194,14 +1291,14 @@ export function useModuleBasicSetting() { //bottom standardLine = surface.lines.reduce((acc, line, index) => { if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) { - return { x1: line.x1, y1: line.y1, index: index } + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } } return acc }) } else { standardLine = surface.lines.reduce((acc, line, index) => { if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) { - return { x1: line.x1, y1: line.y1, index: index } + return { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2, index: index } } return acc }) @@ -1210,11 +1307,12 @@ export function useModuleBasicSetting() { target: index === 0 ? 'left' : 'right', x1: standardLine.x1, y1: standardLine.y1, - x2: standardLine.x1, - y2: standardLine.y1 + charlie, + x2: standardLine.x2, + y2: standardLine.y2, + type: 'flat', } } else { - rtnObj = { target: index === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 } + rtnObj = { target: index === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2, type: 'curve' } } rtnObjArray.push(rtnObj) }) From 58c2c3cfc9127598e07762680487d0b05d02ec9e Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 3 Dec 2024 13:18:43 +0900 Subject: [PATCH 25/98] =?UTF-8?q?=F0=9F=99=80fix:=20useEvent=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=ED=98=B8=EC=B6=9C=EB=90=98=EB=8D=98=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - initEvent() 함수 중복 호출로 이벤트 바인딩 중복 되던 문제 해결 - 초기화 함수 호출 최소화 - useEffect 호출 정리 --- src/app/floor-plan/layout.js | 13 +++++-------- .../floor-plan/modal/setting01/FirstOption.jsx | 7 +++++++ .../floor-plan/modal/setting01/GridOption.jsx | 8 ++++++++ .../floor-plan/modal/setting01/SecondOption.jsx | 8 ++++++++ src/hooks/useEvent.js | 14 ++++++++++---- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/app/floor-plan/layout.js b/src/app/floor-plan/layout.js index 532a83d6..2a6fb8fd 100644 --- a/src/app/floor-plan/layout.js +++ b/src/app/floor-plan/layout.js @@ -3,20 +3,17 @@ import FloorPlanProvider from './FloorPlanProvider' import FloorPlan from '@/components/floor-plan/FloorPlan' import CanvasLayout from '@/components/floor-plan/CanvasLayout' -import EventProvider from './EventProvider' export default function FloorPlanLayout({ children }) { console.log('🚀 ~ FloorPlanLayout ~ FloorPlanLayout:') return ( <> - - - - {children} - - - + + + {children} + + ) } diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index 1f70f21f..566e38b5 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -3,11 +3,13 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useMessage } from '@/hooks/useMessage' import { POLYGON_TYPE } from '@/common/common' import { setSurfaceShapePattern } from '@/util/canvas-util' +import { useEvent } from '@/hooks/useEvent' export default function FirstOption() { const { getMessage } = useMessage() const { canvas, settingModalFirstOptions, setSettingModalFirstOptions } = useCanvasSetting() const { option1, option2, dimensionDisplay } = settingModalFirstOptions + const { initEvent } = useEvent() // 데이터를 최초 한 번만 조회 useEffect(() => { @@ -42,6 +44,11 @@ export default function FirstOption() { setSettingModalFirstOptions({ ...settingModalFirstOptions, option1, option2, dimensionDisplay, fontFlag: true }) } + // useEffect(() => { + // console.log('🚀 ~ useEffect ~ initEvent:') + // initEvent() + // }, [onClickOption]) + return ( <>
diff --git a/src/components/floor-plan/modal/setting01/GridOption.jsx b/src/components/floor-plan/modal/setting01/GridOption.jsx index bb6adef7..8c66534a 100644 --- a/src/components/floor-plan/modal/setting01/GridOption.jsx +++ b/src/components/floor-plan/modal/setting01/GridOption.jsx @@ -9,6 +9,7 @@ import { usePopup } from '@/hooks/usePopup' import { v4 as uuidv4 } from 'uuid' import DotLineGrid from '@/components/floor-plan/modal/grid/DotLineGrid' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { useEvent } from '@/hooks/useEvent' export default function GridOption() { const [gridOptions, setGridOptions] = useRecoilState(settingModalGridOptionsState) @@ -24,6 +25,8 @@ export default function GridOption() { const { gridColor, setGridColor, color } = useCanvasSetting() + const { initEvent } = useEvent() + useEffect(() => { console.log(gridColor, color) setGridColor(color.hex) @@ -91,6 +94,11 @@ export default function GridOption() { setGridOptions(newGridOptions) } + useEffect(() => { + console.log('🚀 ~ useEffect ~ initEvent:') + initEvent() + }, [gridOptions]) + const dotLineGridProps = { id: dotLineId, setIsShow: setShowDotLineGridModal, diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx index b5e9d98d..0b350067 100644 --- a/src/components/floor-plan/modal/setting01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -8,6 +8,7 @@ import PlanSizeSetting from '@/components/floor-plan/modal/setting01/planSize/Pl import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useRecoilState, useRecoilValue } from 'recoil' import { fontSelector, globalFontAtom } from '@/store/fontAtom' +import { useEvent } from '@/hooks/useEvent' export default function SecondOption() { const { getMessage } = useMessage() @@ -24,6 +25,8 @@ export default function SecondOption() { const [fontId, setFontId] = useState(uuidv4()) const [planSizeId, setPlanSizeId] = useState(uuidv4()) + const { initEvent } = useEvent() + const { fetchSettings, planSizeSettingMode, @@ -189,6 +192,11 @@ export default function SecondOption() { setAdsorptionRange(50) } + useEffect(() => { + console.log('🚀 ~ useEffect ~ initEvent:') + initEvent() + }, [adsorptionPointMode]) + return ( <>
diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index 16d0896d..55058cf4 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef } from 'react' +import { useRef } from 'react' import { useRecoilValue, useSetRecoilState } from 'recoil' import { canvasState, canvasZoomState, currentMenuState, textModeState } from '@/store/canvasAtom' import { fabric } from 'fabric' @@ -20,9 +20,15 @@ export function useEvent() { const textMode = useRecoilValue(textModeState) - useEffect(() => { - initEvent() - }, [currentMenu, canvas, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, dotLineGridSetting, tempGridMode]) + // 이벤트 초기화 위치 수정 -> useCanvasSetting에서 세팅값 불러오고 나서 초기화 함수 호출 + // useEffect(() => { + // initEvent() + // }, [currentMenu, canvas, adsorptionPointAddMode, adsorptionPointMode, adsorptionRange, dotLineGridSetting]) + + // 임시 그리드 모드 변경 시 이벤트 초기화 호출 위치 수정 -> GridOption 컴포넌트에서 임시 그리드 모드 변경 시 이벤트 초기화 함수 호출 + // useEffect(() => { + // initEvent() + // }, [tempGridMode]) const initEvent = () => { if (!canvas) { From 228fe576fc7b40d31c2aca8e09ca211f6d0d3539 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 3 Dec 2024 14:27:20 +0900 Subject: [PATCH 26/98] =?UTF-8?q?=F0=9F=93=8Cchore:=20Remove=20unused=20fi?= =?UTF-8?q?les?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../option/useCanvasSettingController.js | 127 ------------------ 1 file changed, 127 deletions(-) delete mode 100644 src/hooks/option/useCanvasSettingController.js diff --git a/src/hooks/option/useCanvasSettingController.js b/src/hooks/option/useCanvasSettingController.js deleted file mode 100644 index 48db6c08..00000000 --- a/src/hooks/option/useCanvasSettingController.js +++ /dev/null @@ -1,127 +0,0 @@ -import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom' -import { useEffect, useState } from 'react' -import { useRecoilState } from 'recoil' - -export const useCanvasSettingController = () => { - const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) - const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) - const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요 - const { get } = useAxios() - - useEffect(() => { - fetchSettings() - }, [objectNo]) - - useEffect(() => { - fetchSettings() - }, []) - - useEffect(() => { - onClickOnlyOne() - fetchSettings() - }, [settingModalFirstOptions, settingModalSecondOptions]) - - const fetchSettings = async () => { - try { - const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` }) - const optionData1 = settingModalFirstOptions.option1.map((item) => ({ ...item, selected: res[item.column] })) - const optionData2 = settingModalFirstOptions.option2.map((item) => ({ ...item, selected: res[item.column] })) - const optionData3 = settingModalSecondOptions.option3.map((item) => ({ ...item })) - const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] })) - const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ - ...item, - })) - // 데이터 설정 - setSettingModalFirstOptions({ - option1: optionData1, - option2: optionData2, - dimensionDisplay: optionData5, - }) - setSettingModalSecondOptions({ - option3: optionData3, - option4: optionData4, - }) - } catch (error) { - console.error('Data fetching error:', error) - } - } - - // - const onClickOption = async (option) => { - option.selected = !option.selected - - setSettingModalFirstOptions({ option1, option2, dimensionDisplay }) - setSettingModalSecondOptions({ option3, option4 }) - - try { - // 서버에 전송할 데이터 - const dataToSend = { - firstOption1: option1.map((item) => ({ - column: item.column, - selected: item.selected, - })), - firstOption2: option2.map((item) => ({ - column: item.column, - selected: item.selected, - })), - firstOption3: dimensionDisplay.map((item) => ({ - column: item.column, - selected: item.selected, - })), - // secondOption1: secondOptions[0].option1.map((item) => ({ - // name: item.id, - // name: item.name, - // // 필요한 경우 데이터 항목 추가 - // })), - secondOption2: option4.map((item) => ({ - column: item.column, - selected: item.selected, - })), - } - - const patternData = { - objectNo, - //디스플레이 설정(다중) - allocDisplay: dataToSend.firstOption1[0].selected, - outlineDisplay: dataToSend.firstOption1[1].selected, - gridDisplay: dataToSend.firstOption1[2].selected, - lineDisplay: dataToSend.firstOption1[3].selected, - wordDisplay: dataToSend.firstOption1[4].selected, - circuitNumDisplay: dataToSend.firstOption1[5].selected, - flowDisplay: dataToSend.firstOption1[6].selected, - trestleDisplay: dataToSend.firstOption1[7].selected, - totalDisplay: dataToSend.firstOption1[8].selected, - //차수 표시(다건) - corridorDimension: dataToSend.firstOption3[0].selected, - realDimension: dataToSend.firstOption3[1].selected, - noneDimension: dataToSend.firstOption3[2].selected, - //화면 표시(다중) - onlyBorder: dataToSend.firstOption2[0].selected, - lineHatch: dataToSend.firstOption2[1].selected, - allPainted: dataToSend.firstOption2[2].selected, - //흡착범위 설정(단건) - adsorpRangeSmall: dataToSend.secondOption2[0].selected, - adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected, - adsorpRangeMedium: dataToSend.secondOption2[2].selected, - adsorpRangeLarge: dataToSend.secondOption2[3].selected, - } - - // HTTP POST 요청 보내기 - await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }).then((res) => { - swalFire({ text: getMessage(res.returnMessage) }) - }) - } catch (error) { - swalFire({ text: getMessage(res.returnMessage), icon: 'error' }) - } - } - - return { - fetchSettings, - settingModalFirstOptions, - setSettingModalFirstOptions, - settingModalSecondOptions, - setSettingModalSecondOptions, - onClickOption, - ß, - } -} From 23264bd1e08992a413ac6f060ac1543f02182d54 Mon Sep 17 00:00:00 2001 From: minsik Date: Tue, 3 Dec 2024 14:36:20 +0900 Subject: [PATCH 27/98] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/static/images/canvas/ico-flx05.svg | 5 +++ public/static/images/canvas/return-btn.svg | 3 ++ src/styles/_contents.scss | 52 ++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 public/static/images/canvas/ico-flx05.svg create mode 100644 public/static/images/canvas/return-btn.svg diff --git a/public/static/images/canvas/ico-flx05.svg b/public/static/images/canvas/ico-flx05.svg new file mode 100644 index 00000000..350aee07 --- /dev/null +++ b/public/static/images/canvas/ico-flx05.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/static/images/canvas/return-btn.svg b/public/static/images/canvas/return-btn.svg new file mode 100644 index 00000000..f33f417b --- /dev/null +++ b/public/static/images/canvas/return-btn.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss index e72637e4..8d3b1408 100644 --- a/src/styles/_contents.scss +++ b/src/styles/_contents.scss @@ -139,6 +139,7 @@ &.ico02{background-image: url(../../public/static/images/canvas/ico-flx02.svg);} &.ico03{background-image: url(../../public/static/images/canvas/ico-flx03.svg);} &.ico04{background-image: url(../../public/static/images/canvas/ico-flx04.svg);} + &.ico05{background-image: url(../../public/static/images/canvas/ico-flx05.svg);} } .name{ font-size: 12px; @@ -827,6 +828,47 @@ &:last-child{ margin-bottom: 0; } + .file-item-wrap{ + display: flex; + align-items: center; + gap: 30px; + .return-wrap{ + display: flex; + align-items: center; + } + .return{ + padding: 0; + font-size: 13px; + color: #B0BCCD; + text-decoration: line-through; + } + .return-btn{ + flex: none; + position: relative; + top: 0; + left: 0; + transform: none; + display: flex; + align-items: center; + height: 24px; + padding: 0 9px; + margin-left: 10px; + background: none; + border: 1px solid #B0BCCD; + border-radius: 2px; + font-size: 12px; + color: #B0BCCD; + font-weight: 500; + .return-ico{ + display: block; + width: 14px; + height: 14px; + background: url(../../public/static/images/canvas/return-btn.svg)no-repeat center; + background-size: contain; + margin-right: 5px; + } + } + } } } } @@ -877,6 +919,16 @@ &.act{ background-color: #F7F9FA; } + .special-note-check-box{ + display: flex; + align-items: center; + .check-name{ + font-size: 13px; + color: #45576F; + cursor: pointer; + line-height: 1.3; + } + } } } From 0dfc2c415e6d5e3e9eaf128d96a8119f6bba7fc4 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 3 Dec 2024 14:53:08 +0900 Subject: [PATCH 28/98] =?UTF-8?q?=F0=9F=9A=A8chore:=20Remove=20unused=20fi?= =?UTF-8?q?les?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- prisma/schema.prisma | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 prisma/schema.prisma diff --git a/prisma/schema.prisma b/prisma/schema.prisma deleted file mode 100644 index 027c8859..00000000 --- a/prisma/schema.prisma +++ /dev/null @@ -1,28 +0,0 @@ -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "sqlserver" - url = env("DATABASE_URL") -} - -model M_USER { - USER_ID String @id(map: "M_USER_pk") @db.VarChar(50) - SALE_STORE_ID String @db.VarChar(10) - PASSWORD String @db.VarChar(10) - CATEGORY String? @db.NVarChar(20) - NAME String @db.NVarChar(20) - NAME_KANA String @db.NVarChar(20) - TEL String? @db.VarChar(15) - FAX String? @db.VarChar(15) - MAIL String? @db.NVarChar(100) - GROUP_ID String @db.VarChar(5) - MODULE_SELECT_GROUP_ID String? @db.VarChar(5) - VERSION_MANAGEMENT_ID String? @db.VarChar(20) - DISP_COST_PRICE Boolean? - DISP_SELLING_PRICE Boolean? - REGIST_DATETIME DateTime? @db.DateTime - LAST_EDIT_DATETIME DateTime? @db.DateTime - LAST_EDIT_USER String? @db.VarChar(50) -} \ No newline at end of file From 24db76fa01680cff0e61b9198a263bc6b507a2cf Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 3 Dec 2024 14:54:26 +0900 Subject: [PATCH 29/98] =?UTF-8?q?=F0=9F=93=8Cfix:=20Optimize=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reformat code - Optimize imports - Rearrange code - isGlobalLoaing 구문 추가 -> StuffSubHeader.jsx --- src/app/management/stuff/page.jsx | 4 +- src/components/management/StuffSubHeader.jsx | 173 ++++++++++--------- 2 files changed, 94 insertions(+), 83 deletions(-) diff --git a/src/app/management/stuff/page.jsx b/src/app/management/stuff/page.jsx index 414f377b..c1a3729c 100644 --- a/src/app/management/stuff/page.jsx +++ b/src/app/management/stuff/page.jsx @@ -1,7 +1,9 @@ -import StuffSearchCondition from '@/components/management/StuffSearchCondition' import Stuff from '@/components/management/Stuff' +import StuffSearchCondition from '@/components/management/StuffSearchCondition' import StuffSubHeader from '@/components/management/StuffSubHeader' + import '@/styles/grid.scss' + export default async function ManagementStuffPage() { return ( <> diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index 1ea2a699..ab838335 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -1,19 +1,26 @@ 'use client' -import { useEffect } from 'react' +import { useContext, useEffect } from 'react' + import Link from 'next/link' import Image from 'next/image' -import { useMessage } from '@/hooks/useMessage' import { useRouter, useSearchParams } from 'next/navigation' -import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' + import { useSetRecoilState } from 'recoil' + +import { QcastContext } from '@/app/QcastProvider' +import { useMessage } from '@/hooks/useMessage' +import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { queryStringFormatter } from '@/util/common-utils' + export default function StuffSubHeader({ type }) { const { getMessage } = useMessage() const router = useRouter() const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) + const { isGlobalLoading } = useContext(QcastContext) + useEffect(() => { window.scrollTo(0, 0) }, []) @@ -35,85 +42,87 @@ export default function StuffSubHeader({ type }) { } return ( - <> -
-
- {type === 'list' && ( - <> - -

{getMessage('header.menus.management')}

- -
    -
  • - - react - -
  • -
  • - {getMessage('header.menus.management')} -
  • -
  • - {getMessage('header.menus.management.stuffList')} -
  • -
- - )} - {type === 'temp' && ( - <> -
    -
  • - - {getMessage('stuff.temp.subTitle')} - -
  • -
-
    -
  • - - react - -
  • -
  • - {getMessage('header.menus.management')} -
  • -
  • - {getMessage('header.menus.management.newStuff')} -
  • -
- - )} - {type === 'detail' && ( - <> - -
    -
  • - - react - -
  • -
  • - {getMessage('header.menus.management')} -
  • -
  • - {getMessage('header.menus.management.detail')} -
  • -
- - )} + !isGlobalLoading && ( + <> +
+
+ {type === 'list' && ( + <> + +

{getMessage('header.menus.management')}

+ +
    +
  • + + react + +
  • +
  • + {getMessage('header.menus.management')} +
  • +
  • + {getMessage('header.menus.management.stuffList')} +
  • +
+ + )} + {type === 'temp' && ( + <> +
    +
  • + + {getMessage('stuff.temp.subTitle')} + +
  • +
+
    +
  • + + react + +
  • +
  • + {getMessage('header.menus.management')} +
  • +
  • + {getMessage('header.menus.management.newStuff')} +
  • +
+ + )} + {type === 'detail' && ( + <> + +
    +
  • + + react + +
  • +
  • + {getMessage('header.menus.management')} +
  • +
  • + {getMessage('header.menus.management.detail')} +
  • +
+ + )} +
-
- + + ) ) } From 9dc0c392abc0ef629b655e7c924837fe6cf00bbd Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 3 Dec 2024 15:15:16 +0900 Subject: [PATCH 30/98] =?UTF-8?q?=F0=9F=9A=A8chore:=20Reformat=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/floor-plan/EventProvider.js | 34 ------------------- src/components/floor-plan/CanvasFrame.jsx | 1 - .../floor-plan/modal/object/SizeSetting.jsx | 4 +-- src/hooks/module/useModuleBasicSetting.js | 5 +-- src/hooks/roofcover/useOuterLineWall.js | 3 +- 5 files changed, 3 insertions(+), 44 deletions(-) delete mode 100644 src/app/floor-plan/EventProvider.js diff --git a/src/app/floor-plan/EventProvider.js b/src/app/floor-plan/EventProvider.js deleted file mode 100644 index 991b19bb..00000000 --- a/src/app/floor-plan/EventProvider.js +++ /dev/null @@ -1,34 +0,0 @@ -import { useEvent } from '@/hooks/useEvent' -import { createContext, useState } from 'react' - -export const EventContext = createContext({}) - -const EventProvider = ({ children }) => { - const { - addDocumentEventListener, - addCanvasMouseEventListener, - addTargetMouseEventListener, - removeAllMouseEventListeners, - removeAllDocumentEventListeners, - removeDocumentEvent, - removeMouseEvent, - removeMouseLine, - initEvent, - } = useEvent() - - const [value, setValue] = useState({ - addDocumentEventListener, - addCanvasMouseEventListener, - addTargetMouseEventListener, - removeAllMouseEventListeners, - removeAllDocumentEventListeners, - removeDocumentEvent, - removeMouseEvent, - removeMouseLine, - initEvent, - }) - - return {children} -} - -export default EventProvider diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index d43afc59..cd39cda0 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -15,7 +15,6 @@ import { MENU } from '@/common/common' import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics' import { totalDisplaySelector } from '@/store/settingAtom' import ImgLoad from '@/components/floor-plan/modal/ImgLoad' -import { EventContext } from '@/app/floor-plan/EventProvider' export default function CanvasFrame() { const canvasRef = useRef(null) diff --git a/src/components/floor-plan/modal/object/SizeSetting.jsx b/src/components/floor-plan/modal/object/SizeSetting.jsx index bddc9f07..3466e2ed 100644 --- a/src/components/floor-plan/modal/object/SizeSetting.jsx +++ b/src/components/floor-plan/modal/object/SizeSetting.jsx @@ -5,12 +5,10 @@ import { useMessage } from '@/hooks/useMessage' import WithDraggable from '@/components/common/draggable/WithDraggable' import { usePopup } from '@/hooks/usePopup' import { contextPopupPositionState } from '@/store/popupAtom' -import { useRef, useState, useEffect, useContext } from 'react' +import { useRef, useState } from 'react' import { useObjectBatch } from '@/hooks/object/useObjectBatch' -import { useEvent } from '@/hooks/useEvent' import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' -import { EventContext } from '@/app/floor-plan/EventProvider' export default function SizeSetting(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 361347f0..133e014f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1,5 +1,4 @@ -import { useContext, useEffect, useState } from 'react' -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { useRecoilState, useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { rectToPolygon, setSurfaceShapePattern } from '@/util/canvas-util' import { roofDisplaySelector } from '@/store/settingAtom' @@ -10,9 +9,7 @@ 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 { EventContext } from '@/app/floor-plan/EventProvider' import { v4 as uuidv4 } from 'uuid' -import { useMainContentsController } from '../main/useMainContentsController' export function useModuleBasicSetting() { const canvas = useRecoilValue(canvasState) diff --git a/src/hooks/roofcover/useOuterLineWall.js b/src/hooks/roofcover/useOuterLineWall.js index c668dd60..74bfcbcc 100644 --- a/src/hooks/roofcover/useOuterLineWall.js +++ b/src/hooks/roofcover/useOuterLineWall.js @@ -1,4 +1,4 @@ -import { useContext, useEffect, useRef } from 'react' +import { useEffect, useRef } from 'react' import { distanceBetweenPoints } from '@/util/canvas-util' import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { @@ -31,7 +31,6 @@ import { fabric } from 'fabric' import { outlineDisplaySelector } from '@/store/settingAtom' import { usePopup } from '@/hooks/usePopup' import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting' -import { EventContext } from '@/app/floor-plan/EventProvider' //외벽선 그리기 export function useOuterLineWall(id, propertiesId) { From 732e520c7b77c2b9fc8f02b8ae7a2539a1beb5dd Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 3 Dec 2024 16:06:52 +0900 Subject: [PATCH 31/98] =?UTF-8?q?=EB=AA=A8=EB=93=88=20->=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=EB=A9=B4=20=EC=9D=B4=EB=8F=99=EC=8B=9C=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=EB=A9=B4=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 1 + src/components/floor-plan/CanvasMenu.jsx | 9 ++- src/hooks/module/useModuleBasicSetting.js | 81 ++++++++++++++++++----- src/util/canvas-util.js | 2 + 4 files changed, 75 insertions(+), 18 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index 02a953fe..9bf6d367 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -161,6 +161,7 @@ export const SAVE_KEY = [ 'surfaceCompass', 'moduleCompass', 'isFixed', + 'modules', ] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype] diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 79944044..3fcdfd44 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -40,6 +40,8 @@ import EstimateCopyPop from '../estimate/popup/EstimateCopyPop' import { pwrGnrSimTypeState } from '@/store/simulatorAtom' import { useAxios } from '@/hooks/useAxios' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' + export default function CanvasMenu(props) { const { menuNumber, setMenuNumber } = props const pathname = usePathname() @@ -49,7 +51,7 @@ export default function CanvasMenu(props) { const [type, setType] = useRecoilState(menuTypeState) const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState) const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore) - const setCurrentMenu = useSetRecoilState(currentMenuState) + const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState) const setOuterLinePoints = useSetRecoilState(outerLinePointsState) const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState) const canvasSetting = useRecoilValue(canvasSettingState) @@ -74,6 +76,7 @@ export default function CanvasMenu(props) { const { commonFunctions } = useCommonUtils() const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext) + const { restoreModuleInstArea } = useModuleBasicSetting() const onClickNav = (menu) => { setMenuNumber(menu.index) @@ -88,6 +91,10 @@ export default function CanvasMenu(props) { setType('outline') break case 3: + if (type === 'module') { + restoreModuleInstArea() + } + setType('surface') break case 4: diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 361347f0..7fd11bc3 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -18,11 +18,33 @@ 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 { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) let selectedModuleInstSurfaceArray = [] + //모듈,회로에서 다른메뉴 -> 배치면으로 갈 경수 초기화 + const restoreModuleInstArea = () => { + //설치면 삭제 + const setupArea = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + + //모듈 삭제 및 초기화 + setupArea.forEach((obj) => { + if (obj.modules.length > 0) { + obj.modules.forEach((module) => { + canvas.remove(module) + }) + } + canvas.remove(obj) + obj.modules = [] + }) + + //지붕패턴 변경 + const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof') + roofs.forEach((roof) => { + setSurfaceShapePattern(roof, roofDisplay.column, false) //패턴 변경 + }) + } const makeModuleInstArea = () => { //지붕 객체 반환 const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof') @@ -32,6 +54,11 @@ export function useModuleBasicSetting() { } roofs.forEach((roof) => { + const isExistSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.parentId === roof.id) + if (isExistSurface) { + return + } + setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경 const offsetPoints = offsetPolygon(roof.points, -20) //안쪽 offset //모듈설치영역?? 생성 @@ -56,6 +83,7 @@ export function useModuleBasicSetting() { flipX: roof.flipX, flipY: roof.flipY, surfaceId: surfaceId, + modules: [], }) setupSurface.setViewLengthText(false) @@ -135,13 +163,29 @@ export function useModuleBasicSetting() { 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', + } + if (moduleSetupSurfaces.length !== 0) { let tempModule - let manualDrawModules = moduleIsSetup // 앞에서 자동으로 했을때 추가됨 + let manualDrawModules = [] let inside = false let turfPolygon let flowDirection let trestlePolygon + addCanvasMouseEventListener('mouse:move', (e) => { //마우스 이벤트 삭제 후 재추가 const mousePoint = canvas.getPointer(e.e) @@ -149,6 +193,7 @@ export function useModuleBasicSetting() { for (let i = 0; i < moduleSetupSurfaces.length; i++) { turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i]) trestlePolygon = moduleSetupSurfaces[i] + manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨 flowDirection = moduleSetupSurfaces[i].flowDirection //도형의 방향 let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113 let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172 @@ -326,6 +371,7 @@ export function useModuleBasicSetting() { } if (!inside) { + // tempModule.set({ fill: 'red' }) canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) canvas?.renderAll() } @@ -378,14 +424,12 @@ export function useModuleBasicSetting() { //마우스 클릭시 set으로 해당 위치에 셀을 넣음 const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 if (!isOverlap) { + canvas?.remove(tempModule) //안겹치면 넣는다 - tempModule.setCoords() - tempModule.set({ name: 'module', fill: '#BFFD9F' }) - manualDrawModules.push(tempModule) //모듈배열에 추가 - //해당 모듈에 프로퍼티로 넣는다 - trestlePolygon.set({ - modules: manualDrawModules, - }) + // tempModule.setCoords() + let manualModule = new QPolygon(tempModule.points, { ...moduleOptions }) + canvas?.add(manualModule) + manualDrawModules.push(manualModule) } else { alert('셀끼리 겹치면 안되죠?') } @@ -424,13 +468,6 @@ export function useModuleBasicSetting() { return } - if (moduleIsSetup.length > 0) { - alert('기존 모듈은 제거됩니다.') - moduleIsSetup.forEach((module) => { - canvas?.remove(module) - }) - } - //어짜피 자동으로 누르면 선택안된데도 다 날아간다 canvas.getObjects().forEach((obj) => { if (obj.name === 'module') { @@ -438,6 +475,15 @@ export function useModuleBasicSetting() { } }) + moduleSetupSurfaces.forEach((obj) => { + if (obj.modules) { + obj.modules.forEach((module) => { + canvas?.remove(module) + }) + obj.modules = [] + } + }) + notSelectedTrestlePolygons.forEach((obj) => { if (obj.modules) { obj.modules.forEach((module) => { @@ -887,7 +933,7 @@ export function useModuleBasicSetting() { }) moduleSetupSurface.set({ modules: setupedModules }) - setModuleIsSetup(moduleSetupArray) + // setModuleIsSetup(moduleSetupArray) }) } @@ -1374,5 +1420,6 @@ export function useModuleBasicSetting() { makeModuleInstArea, manualModuleSetup, autoModuleSetup, + restoreModuleInstArea, } } diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js index 65c46b74..b27f91db 100644 --- a/src/util/canvas-util.js +++ b/src/util/canvas-util.js @@ -824,6 +824,8 @@ export function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode ctx.strokeStyle = 'black' ctx.lineWidth = 0.2 ctx.fillStyle = 'rgba(0, 0, 0, 0.1)' + } else { + ctx.fillStyle = 'rgba(255, 255, 255, 1)' } if (polygon.direction === 'east' || polygon.direction === 'west') { From b5b907040963227e3c97701fc1768208536c8359 Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Tue, 3 Dec 2024 16:26:32 +0900 Subject: [PATCH 32/98] =?UTF-8?q?refactor:=20plan=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=8B=9C=20=EB=B9=88=EC=BA=94=EB=B2=84=EC=8A=A4=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit canvas plan 생성 시 빈 캔버스 데이터를 DB에 저장 후 표출되도록 로직 변경 initCanvasPlans 삭제 --- src/app/QcastProvider.js | 2 +- src/components/floor-plan/CanvasLayout.jsx | 10 +- src/components/floor-plan/CanvasMenu.jsx | 10 +- src/hooks/usePlan.js | 127 +++++++-------------- src/locales/ja.json | 1 + src/locales/ko.json | 1 + src/store/canvasAtom.js | 6 - 7 files changed, 52 insertions(+), 105 deletions(-) diff --git a/src/app/QcastProvider.js b/src/app/QcastProvider.js index 23ad5a75..16a62d63 100644 --- a/src/app/QcastProvider.js +++ b/src/app/QcastProvider.js @@ -34,7 +34,7 @@ export const QcastProvider = ({ children }) => { const targetElement = document.getElementById('canvas') if (!targetElement && currentCanvasPlan?.id && planSave) { setPlanSave((prev) => !prev) - checkUnsavedCanvasPlan(currentCanvasPlan.userId) + checkUnsavedCanvasPlan() } else if (targetElement && currentCanvasPlan?.id) { setPlanSave(true) } diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index fcaabb6f..9e48873e 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -20,7 +20,7 @@ export default function CanvasLayout({ children }) { const { getMessage } = useMessage() const { swalFire } = useSwal() - const { plans, initCanvasPlans, modifiedPlans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan() + const { plans, modifiedPlans, loadCanvasPlanData, handleCurrentPlan, handleAddPlan, handleDeletePlan } = usePlan() useEffect(() => { loadCanvasPlanData(session.userId, objectNo, pid) @@ -34,10 +34,9 @@ export default function CanvasLayout({ children }) { - +
+ + {originFile.faileName} + + + {/*
+ {originFile.faileName} + +
*/} +
) })} @@ -1155,21 +1191,29 @@ export default function Estimate({ params }) { specialNoteList.map((row) => { return (
-
- { - setSpecialNoteList((specialNote) => - specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)), - ) - - settingShowContent(row.code, event) +
+
+ { + setSpecialNoteList((specialNote) => + specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)), + ) + }} + /> + +
+ { + settingShowContent(row.code) }} - /> - + > + {row.codeNm} +
) @@ -1501,7 +1545,9 @@ export default function Estimate({ params }) {
- {convertNumberToPriceDecimal(item?.showSaleTotPrice === '0' ? null : item?.saleTotPrice?.replaceAll(',', ''))} + {convertNumberToPriceDecimal( + item?.showSaleTotPrice === '0' ? null : item?.saleTotPrice === '0' ? null : item?.saleTotPrice?.replaceAll(',', ''), + )}
-
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/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, } } From 921b19b7e63971b83889463fbfb3476d242838b3 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 08:50:44 +0900 Subject: [PATCH 39/98] =?UTF-8?q?=EC=B2=A8=EB=B6=80=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C/=EB=B3=B5=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 50 ++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index ff9e7af2..6c77d183 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -61,7 +61,7 @@ export default function Estimate({ params }) { const objectRecoil = useRecoilValue(floorPlanObjectState) //견적서 상세데이터 - const { estimateContextState, setEstimateContextState, addItem, handleEstimateFileDownload } = useEstimateController(params.pid) + const { estimateContextState, setEstimateContextState, addItem } = useEstimateController(params.pid) //견적특이사항 List const [specialNoteList, setSpecialNoteList] = useState([]) @@ -120,7 +120,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('、') @@ -226,8 +225,20 @@ export default function Estimate({ params }) { } }, [estimateContextState?.fileList]) + // 삭제누른 첨부파일 복원 + const returnOriginFile = (no) => { + originFiles.map((file) => { + if (file.no === no) { + file.delFlg = '0' + } + }) + + setOriginFiles((prev) => { + return [...prev] + }) + } // 기존첨부파일 삭제 (플래그값 추가?) 저장할때 플래그값에 따라 진짜 삭제 - const deleteOriginFile = (objectNo, no) => { + const deleteOriginFile = (no) => { originFiles.map((file) => { if (file.no === no) { file.delFlg = '1' @@ -235,12 +246,15 @@ export default function Estimate({ params }) { }) // console.log('originFiles::', originFiles) - setOriginFiles(originFiles) - const delParams = { - userId: session.userId, - objectNo: objectNo, - no: no, - } + setOriginFiles((prev) => { + return [...prev] + }) + // setOriginFiles(originFiles) + // 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) { @@ -1139,24 +1153,32 @@ export default function Estimate({ params }) { return (
  • - + 플래그::::::{originFile.delFlg} /// + {originFile.faileName} - {/*
    +
    {originFile.faileName} - -
    */} +
  • ) From 69d11336d57e6ffa8ab6d821fff7b0c9b6292bff Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 08:52:52 +0900 Subject: [PATCH 40/98] =?UTF-8?q?=ED=99=95=EC=9D=B8=EC=9A=A9=20=EC=86=8C?= =?UTF-8?q?=EC=8A=A4=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 6c77d183..6b257645 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1153,7 +1153,6 @@ export default function Estimate({ params }) { return (
  • - 플래그::::::{originFile.delFlg} /// {originFile.faileName} {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/locales/ja.json b/src/locales/ja.json index 8efb602d..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", diff --git a/src/locales/ko.json b/src/locales/ko.json index ad437c99..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", From fecae44c9ab78e9d89ac8caa1070753b5ba63d63 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 12:36:49 +0900 Subject: [PATCH 43/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 35 ++++++++++------------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 192a7e8e..534eda0b 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -245,29 +245,10 @@ export default function Estimate({ params }) { } }) - // console.log('originFiles::', originFiles) setOriginFiles((prev) => { return [...prev] }) - // setOriginFiles(originFiles) - // 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), - // }) - - // alert(getMessage('plan.message.delete')) - // } - // }) } //가격표시 option 목록 최초세팅 && 주문분류 변경시 @@ -609,7 +590,7 @@ export default function Estimate({ params }) { let updateList = [] let updates = {} get({ url: apiUrl }).then((res) => { - // console.log('아이템디테일::::::::', res) + console.log('아이템디테일::::::::', res) updates.objectNo = objectNo updates.planNo = planNo updates.itemId = res.itemId @@ -631,6 +612,8 @@ export default function Estimate({ params }) { updates.itemGroup = res.itemGroup updates.delFlg = '0' // 삭제플래그 0 updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString() + //console.log('updates::', updates) + //console.log('estimateContextState.itemList[index].amount::', estimateContextState.itemList[index].amount) // updates.saleTotPrice = '' updates.amount = '' updates.openFlg = res.openFlg @@ -765,7 +748,7 @@ export default function Estimate({ params }) { makeUniqueSpecialNoteCd(itemList) itemList.forEach((item) => { - // console.log('YJOD::::::', item) + console.log('YJOD::::::', item) delete item.showSalePrice delete item.showSaleTotPrice if (item.delFlg === '0') { @@ -794,7 +777,7 @@ export default function Estimate({ params }) { itemList.sort((a, b) => a.dispOrder - b.dispOrder) makeUniqueSpecialNoteCd(itemList) itemList.forEach((item) => { - // console.log('YJSSS::', item) + console.log('YJSSS::', item) if (item.delFlg === '0') { let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 let salePrice = Number(item.salePrice?.replaceAll(',', '')) || 0 @@ -1570,7 +1553,13 @@ export default function Estimate({ params }) {
  • From dd92a47b0b51c610979ae3856e5012c0b9da821c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 4 Dec 2024 13:59:58 +0900 Subject: [PATCH 44/98] =?UTF-8?q?moduleSetupSurfaces=20=EB=B3=84=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 228 +++++++++++----------- 1 file changed, 118 insertions(+), 110 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 4e5e3534..4a435a11 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -955,120 +955,128 @@ export function useModuleBasicSetting() { const calculateForApi = () => { // TODO : 현재는 남쪽기준. 동,서,북 분기처리 필요 - const centerPoints = [] - const modules = canvas.getObjects().filter((obj) => obj.name === 'module') - modules.forEach((module, index) => { - module.tempIndex = index - const { x, y } = module.getCenterPoint() - const { width, height } = module - centerPoints.push({ x, y, width: Math.abs(width), height: Math.abs(height), index }) - const circle = new fabric.Circle({ - radius: 5, - fill: 'red', - name: 'redCircle', - left: x - 5, - top: y - 5, - index: index, - selectable: false, + const moduleSufaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + const results = [] + + moduleSufaces.forEach((moduleSurface) => { + const centerPoints = [] + 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.abs(width), height: Math.abs(height), index }) + const circle = new fabric.Circle({ + radius: 5, + fill: 'red', + name: 'redCircle', + left: x - 5, + top: y - 5, + index: index, + selectable: false, + }) + // 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) => Math.abs(centerPoint.x - x) < 2 && 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) => Math.abs(centerPoint.x - x) < 2 && 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, modules[0]) + console.log('groupPoints', groupPoints) + 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 + }) + + results.push({ + 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) => Math.abs(centerPoint.x - x) < 2 && 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) => Math.abs(centerPoint.x - x) < 2 && 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, modules[0]) - console.log('groupPoints', groupPoints) - 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 배열을 그룹화 해서 반환 From 7a7a6f4c08c12e9fc597e4880cd6e8e3eaff11ab Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 14:20:59 +0900 Subject: [PATCH 45/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 44 +++++++------------ .../estimate/useEstimateController.js | 20 ++++----- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 534eda0b..65a24def 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -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' @@ -209,11 +209,12 @@ export default function Estimate({ params }) { }, [files]) useEffect(() => { - if (originFiles.length > 0) { - setEstimateContextState({ - originFiles: originFiles, - }) - } + // console.log('USEEFFECT originFiles::::::::::', originFiles) + // if (originFiles.length > 0) { + // setEstimateContextState({ + // originFiles: originFiles, + // }) + // } }, [originFiles]) //상세에서 내려온 첨부파일 set 만들기 @@ -232,10 +233,12 @@ export default function Estimate({ params }) { file.delFlg = '0' } }) - setOriginFiles((prev) => { return [...prev] }) + setEstimateContextState({ + originFiles: originFiles, + }) } // 기존첨부파일 삭제 (플래그값 추가?) 저장할때 플래그값에 따라 진짜 삭제 const deleteOriginFile = (no) => { @@ -248,6 +251,9 @@ export default function Estimate({ params }) { setOriginFiles((prev) => { return [...prev] }) + setEstimateContextState({ + originFiles: originFiles, + }) alert(getMessage('estimate.detail.alert.delFile')) } @@ -427,20 +433,6 @@ export default function Estimate({ params }) { } } } - // data.data2.map((item2) => { - // if (item2) { - // // console.log('프라이싱아이템::::', item2) - // if (item2.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(), - // }) - // checkYn = true - // } - // } - // }) if (!checkYn) { updateList.push({ ...item, salePrice: '0', saleTotPrice: '0' }) @@ -590,7 +582,7 @@ export default function Estimate({ params }) { let updateList = [] let updates = {} get({ url: apiUrl }).then((res) => { - console.log('아이템디테일::::::::', res) + // console.log('아이템디테일::::::::', res) updates.objectNo = objectNo updates.planNo = planNo updates.itemId = res.itemId @@ -605,16 +597,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() - //console.log('updates::', updates) - //console.log('estimateContextState.itemList[index].amount::', estimateContextState.itemList[index].amount) - // updates.saleTotPrice = '' updates.amount = '' updates.openFlg = res.openFlg @@ -748,7 +736,7 @@ export default function Estimate({ params }) { makeUniqueSpecialNoteCd(itemList) itemList.forEach((item) => { - console.log('YJOD::::::', item) + // console.log('YJOD::::::', item) delete item.showSalePrice delete item.showSaleTotPrice if (item.delFlg === '0') { @@ -777,7 +765,7 @@ export default function Estimate({ params }) { itemList.sort((a, b) => a.dispOrder - b.dispOrder) makeUniqueSpecialNoteCd(itemList) itemList.forEach((item) => { - console.log('YJSSS::', item) + // console.log('YJSSS::', item) if (item.delFlg === '0') { let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 let salePrice = Number(item.salePrice?.replaceAll(',', '')) || 0 diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index cde893ed..dea8c9aa 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 } from '@/util/common-utils' import { SessionContext } from '@/app/SessionProvider' import { useMessage } from '@/hooks/useMessage' import { useRouter } from 'next/navigation' @@ -59,6 +59,7 @@ export const useEstimateController = (planNo) => { item.delFlg = '0' }) } + setEstimateContextState(res.data) } } @@ -155,13 +156,6 @@ 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) - - // console.log('estimateData::', estimateData) - //기존에 첨부된 파일이 있으면 파일첨부관련 통과 if (estimateData?.originFiles?.length > 0) { originFileFlg = true @@ -169,8 +163,9 @@ export const useEstimateController = (planNo) => { if (flag) { if (!originFileFlg) { //기존에 첨부된 파일이 없으면 - if (estimateData.newFileList?.length < 1) { - //새로 첨부한 파일이 있으면 + // if (estimateData.newFileList?.length < 1) { + if (isEmptyArray(estimateData.newFileList)) { + //새로 첨부한 파일이 없으면 if (estimateData.itemList.length > 1) { estimateData.itemList.map((row) => { if (row.delFlg === '0') { @@ -244,7 +239,7 @@ export const useEstimateController = (planNo) => { //1. 첨부파일 저장시작 const formData = new FormData() if (estimateData?.newFileList?.length > 0) { - console.log('새로추가한 첨부파일있음:::', estimateData?.newFileList) + // console.log('새로추가한 첨부파일있음:::', estimateData?.newFileList) estimateData.newFileList.forEach((file) => { formData.append('files', file) }) @@ -316,12 +311,15 @@ export const useEstimateController = (planNo) => { } else { estimateData.deleteFileList = [] } + 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.originFileList = [] alert(getMessage('estimate.detail.save.alertMsg')) //어디로 보낼지 fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) From 5cb50ae21e1f0a0a610192a301d3a3c5202858ba Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 4 Dec 2024 14:57:46 +0900 Subject: [PATCH 46/98] =?UTF-8?q?=EC=B2=98=EB=A7=88=EB=A9=B4=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 4e5e3534..126f064a 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -10,6 +10,7 @@ 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' export function useModuleBasicSetting() { const canvas = useRecoilValue(canvasState) @@ -18,7 +19,7 @@ export function useModuleBasicSetting() { const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState) const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useEvent() const { swalFire } = useSwal() - + const canvasSetting = useRecoilValue(canvasSettingState) // const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) let selectedModuleInstSurfaceArray = [] @@ -64,6 +65,8 @@ export function useModuleBasicSetting() { const surfaceId = uuidv4() + console.log('roof.moduleCompass', roof.moduleCompass) + let setupSurface = new QPolygon(offsetPoints, { stroke: 'red', fill: 'transparent', @@ -815,9 +818,9 @@ export function useModuleBasicSetting() { if (isMaxSetup) totalHeight = totalHeight * 2 //최대배치시 2배로 늘려서 반씩 검사 for (let i = 0; i <= totalWidth; i++) { - bottomMargin = j === 0 ? 1 : 2 + bottomMargin = i === 0 ? 1 : 2 for (let j = 0; j < totalHeight; j++) { - leftMargin = i === 0 ? 1 : 2 + leftMargin = j === 0 ? 1 : 2 chidoriLength = 0 if (isChidori) { chidoriLength = i % 2 === 0 ? 0 : height / 2 @@ -1203,7 +1206,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) // 높이 @@ -1318,7 +1321,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)) @@ -1434,10 +1437,16 @@ export function useModuleBasicSetting() { return obj } + const manualFlatroofModuleSetup = () => {} + + const autoFlatroofModuleSetup = (placementFlatRef) => {} + return { makeModuleInstArea, manualModuleSetup, autoModuleSetup, restoreModuleInstArea, + manualFlatroofModuleSetup, + autoFlatroofModuleSetup, } } From 9699ccbe0305e60d34f18eb4ddd09a1d45cb4a44 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 4 Dec 2024 14:58:05 +0900 Subject: [PATCH 47/98] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 45 ++++++++++++------- .../floor-plan/modal/basic/step/Placement.jsx | 9 +++- .../modal/basic/step/pitch/PitchPlacement.jsx | 40 +++++++++++++++-- 3 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index af5d9037..c6dee35b 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..239e0a82 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,16 @@ +import { forwardRef, useState, useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' -export default function PitchPlacement() { +const PitchPlacement = forwardRef((props, refs) => { const { getMessage } = useMessage() + const [setupLocation, setSetupLocation] = useState('south') + const { makeModuleInstArea } = useModuleBasicSetting() + + useEffect(() => { + makeModuleInstArea() + }, []) + const moduleData = { header: [ { type: 'check', name: '', prop: 'check', width: 70 }, @@ -24,6 +33,12 @@ export default function PitchPlacement() { }, ], } + + const handleSetupLocation = (e) => { + setSetupLocation(e.target.value) + refs.setupLocation.current = e.target.value + } + return ( <>
    @@ -88,11 +103,26 @@ export default function PitchPlacement() {
    - +
    - +
    @@ -102,4 +132,6 @@ export default function PitchPlacement() {
    ) -} +}) + +export default PitchPlacement From cb3780844c3fa8fce131330c6fa6e8d4bf06638a Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 15:14:51 +0900 Subject: [PATCH 48/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 19 ++++++++++--------- .../estimate/useEstimateController.js | 3 +-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 65a24def..6dbde060 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -202,20 +202,21 @@ 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(() => { - // console.log('USEEFFECT originFiles::::::::::', originFiles) - // if (originFiles.length > 0) { - // setEstimateContextState({ - // originFiles: originFiles, - // }) - // } - }, [originFiles]) + // useEffect(() => { + // // console.log('USEEFFECT originFiles::::::::::', originFiles) + // // if (originFiles.length > 0) { + // // setEstimateContextState({ + // // originFiles: originFiles, + // // }) + // // } + // }, [originFiles]) //상세에서 내려온 첨부파일 set 만들기 useEffect(() => { diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index dea8c9aa..9ce5808b 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -163,7 +163,6 @@ export const useEstimateController = (planNo) => { if (flag) { if (!originFileFlg) { //기존에 첨부된 파일이 없으면 - // if (estimateData.newFileList?.length < 1) { if (isEmptyArray(estimateData.newFileList)) { //새로 첨부한 파일이 없으면 if (estimateData.itemList.length > 1) { @@ -239,7 +238,6 @@ export const useEstimateController = (planNo) => { //1. 첨부파일 저장시작 const formData = new FormData() if (estimateData?.newFileList?.length > 0) { - // console.log('새로추가한 첨부파일있음:::', estimateData?.newFileList) estimateData.newFileList.forEach((file) => { formData.append('files', file) }) @@ -252,6 +250,7 @@ export const useEstimateController = (planNo) => { setFileList(res) }) } else { + setFileList([]) realSave() } } From d68610440ec1c802bd4c6912f577c8473c94aabc Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 4 Dec 2024 15:52:45 +0900 Subject: [PATCH 49/98] =?UTF-8?q?=E2=80=BC=EF=B8=8Ffix:=20floor-plan=20?= =?UTF-8?q?=ED=95=98=EC=9C=84=20=EB=A0=8C=EB=8D=94=EB=A7=81=EC=8B=9C=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EB=B6=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - floot-plan , estimate, simulator 렌더링 조건 분리 - ManagementProvider 에 리코일 로직 추가 --- src/app/floor-plan/FloorPlanProvider.js | 2 -- src/app/floor-plan/layout.js | 10 +++++++++- src/app/management/ManagementProvider.js | 8 ++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) 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/ManagementProvider.js b/src/app/management/ManagementProvider.js index 197b30c0..f1e3a91b 100644 --- a/src/app/management/ManagementProvider.js +++ b/src/app/management/ManagementProvider.js @@ -1,6 +1,9 @@ 'ues client' import { createContext, useEffect, useState } from 'react' +import { useSearchParams } from 'next/navigation' +import { useSetRecoilState } from 'recoil' +import { correntObjectNoState } from '@/store/settingAtom' export const ManagementContext = createContext({ managementState: {}, @@ -10,6 +13,11 @@ export const ManagementContext = createContext({ const ManagementProvider = ({ children }) => { const [managementState, setManagementState] = useState({}) + const setCurrentObjectNo = useSetRecoilState(correntObjectNoState) + const searchParams = useSearchParams() + const objectNo = searchParams.get('objectNo') + setCurrentObjectNo(objectNo) + useEffect(() => { console.log('🚀 ~ managementState:', managementState) }, [managementState]) From f290491caa12b4e2157365e36f568625b4998866 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 16:03:51 +0900 Subject: [PATCH 50/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 7 +++++++ .../floorPlan/estimate/useEstimateController.js | 13 ++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 6dbde060..94d4d479 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -224,6 +224,13 @@ export default function Estimate({ params }) { //드래그영역 비워주기 setFiles([]) setOriginFiles(estimateContextState.fileList) + } else { + // setOriginFiles([]) + if (originFiles.length > 0) { + let file + file = originFiles.filter((item) => item.delFlg === '0') + setOriginFiles(file) + } } }, [estimateContextState?.fileList]) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 9ce5808b..c5c77253 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, isEmptyArray } 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' @@ -158,8 +158,15 @@ export const useEstimateController = (planNo) => { //기존에 첨부된 파일이 있으면 파일첨부관련 통과 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) { //기존에 첨부된 파일이 없으면 @@ -318,7 +325,7 @@ export const useEstimateController = (planNo) => { await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => { if (res.status === 201) { estimateData.newFileList = [] - estimateData.originFileList = [] + // estimateData.originFiles = [] alert(getMessage('estimate.detail.save.alertMsg')) //어디로 보낼지 fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo) From fecfa673050622ff0ae8e2f663db59ef58dced2b Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 4 Dec 2024 17:27:57 +0900 Subject: [PATCH 51/98] =?UTF-8?q?=F0=9F=93=8Cfix:=20objectNo=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=20=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/management/ManagementProvider.js | 8 -------- src/components/estimate/Estimate.jsx | 13 ++++++++++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/app/management/ManagementProvider.js b/src/app/management/ManagementProvider.js index f1e3a91b..197b30c0 100644 --- a/src/app/management/ManagementProvider.js +++ b/src/app/management/ManagementProvider.js @@ -1,9 +1,6 @@ 'ues client' import { createContext, useEffect, useState } from 'react' -import { useSearchParams } from 'next/navigation' -import { useSetRecoilState } from 'recoil' -import { correntObjectNoState } from '@/store/settingAtom' export const ManagementContext = createContext({ managementState: {}, @@ -13,11 +10,6 @@ export const ManagementContext = createContext({ const ManagementProvider = ({ children }) => { const [managementState, setManagementState] = useState({}) - const setCurrentObjectNo = useSetRecoilState(correntObjectNoState) - const searchParams = useSearchParams() - const objectNo = searchParams.get('objectNo') - setCurrentObjectNo(objectNo) - useEffect(() => { console.log('🚀 ~ managementState:', managementState) }, [managementState]) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 94d4d479..4eb74504 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' @@ -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, From 4e05a7423de7580b1f757bb014c0f1963c6e5682 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 4 Dec 2024 17:53:27 +0900 Subject: [PATCH 52/98] =?UTF-8?q?=F0=9F=93=8Cchore:=20session=20=EC=8A=A4?= =?UTF-8?q?=ED=8E=99=20=EC=9E=84=EC=8B=9C=20=EC=88=98=EC=A0=95=20->=20prod?= =?UTF-8?q?uction=20=EB=AA=A8=EB=93=9C=EC=97=90=EC=84=9C=EB=A7=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/session.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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', + // }, } From b1c896c01af3c0e058aa116c46a6f1b1bfe38a04 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 18:04:46 +0900 Subject: [PATCH 53/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 4eb74504..abc9584d 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -760,14 +760,20 @@ 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 = 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.openFlg === '1') { item.showSalePrice = '0' @@ -778,6 +784,8 @@ export default function Estimate({ params }) { totals.vatPrice = totals.supplyPrice * 0.1 totals.totPrice = totals.supplyPrice + totals.vatPrice + + // console.log('YJOD:::totlas:::', totals) } const calculateYJSSTotals = (itemList) => { @@ -787,11 +795,17 @@ export default function Estimate({ params }) { // console.log('YJSSS::', 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 = 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') { @@ -812,6 +826,8 @@ export default function Estimate({ params }) { totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice totals.vatPrice = totals.supplyPrice * 0.1 totals.totPrice = totals.supplyPrice + totals.vatPrice + + // console.log('YJOD:::totlas:::', totals) } if (estimateContextState.estimateType === 'YJOD') { From 7c26569b613bb226e71f47ac0679049d7482bb85 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 4 Dec 2024 18:21:44 +0900 Subject: [PATCH 54/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index abc9584d..e416cd50 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -150,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 } }) @@ -203,7 +203,6 @@ export default function Estimate({ params }) { // 견적특이사항 remark 보여주기 const settingShowContent = (code) => { setShowContentCode(code) - // event.stopPropagation() } // 추가한 첨부파일 estimateContextState에 넣기 @@ -1062,8 +1061,8 @@ export default function Estimate({ params }) { return ( <> -
    -
    +
    +
    @@ -1242,7 +1241,7 @@ export default function Estimate({ params }) { settingShowContent(row.code) }} > - {row.codeNm} + {row.codeNm} / {row.code}
    @@ -1267,6 +1266,8 @@ export default function Estimate({ params }) { } else { let pushData = [] popShowSpecialNoteList.map((item) => { + //console.log('showContentCode::', showContentCode) + //console.log('unique::', uniqueData) let option = showContentCode.split('、') option.map((item2) => { if (item.code === item2) { @@ -1483,7 +1484,8 @@ export default function Estimate({ params }) {
    -
    -
    - -
    +
    +
    +
    - +
    + +
    +
    ) })} @@ -1156,7 +1154,8 @@ export default function Estimate({ params }) {
      {originFiles.map((originFile) => { return ( -
    • +
    • + {/*
    • */}
      0 && specialNoteList.map((row) => { return ( -
      + //
      +
      { + // readOnly + // onClick={(event) => { + onChange={() => { setSpecialNoteList((specialNote) => specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)), ) @@ -1258,7 +1260,7 @@ export default function Estimate({ params }) { if (isObjectNotEmpty(showcontent)) { return ( -
      +
      {showcontent.codeNm}
      @@ -1266,8 +1268,6 @@ export default function Estimate({ params }) { } else { let pushData = [] popShowSpecialNoteList.map((item) => { - //console.log('showContentCode::', showContentCode) - //console.log('unique::', uniqueData) let option = showContentCode.split('、') option.map((item2) => { if (item.code === item2) { @@ -1275,12 +1275,23 @@ export default function Estimate({ params }) { } }) }) - return pushData.map((item) => ( -
      -
      {item.codeNm}
      -
      -
      - )) + //제품에 있는 특이사항만 보여주기 제품에 특이사항이 없으면 전부 + let filterData = pushData.filter((item) => uniqueData.includes(item.code)) + if (filterData.length > 0) { + return filterData.map((item) => ( +
      +
      {item.codeNm}
      +
      +
      + )) + } else { + return pushData.map((item) => ( +
      +
      {item.codeNm}
      +
      +
      + )) + } } } })} @@ -1367,14 +1378,19 @@ export default function Estimate({ params }) {
      {session?.storeLvl === '1' ? ( ) : ( 0 && showSpecialNoteList.map((row) => { return ( -
      +
      {row.codeNm}
      - {/*
      */}
      ) From 269f7cd09551eb48dbd2e62126d4349743d84c92 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 5 Dec 2024 10:27:28 +0900 Subject: [PATCH 56/98] =?UTF-8?q?=F0=9F=93=8Cfix:=20=EB=B0=A9=EC=9C=84?= =?UTF-8?q?=EA=B0=81=20=EA=B3=84=EC=82=B0=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/common-utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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, } } From 0455bc3a31231f98e9d656b58faf0ba19092b758 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 5 Dec 2024 10:47:08 +0900 Subject: [PATCH 57/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20pkgAsp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/estimate/useEstimateController.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index c5c77253..28037be5 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -318,6 +318,10 @@ export const useEstimateController = (planNo) => { estimateData.deleteFileList = [] } + if (estimateData.estimateType === 'YJSS') { + estimateData.pkgAsp = estimateData.pkgAsp.replaceAll(',', '') + } + console.log('최종저장::', estimateData) //2. 상세데이터 저장 // return From 069b4f2363ce407c266bb5789c178a701ed8cf17 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 5 Dec 2024 10:58:08 +0900 Subject: [PATCH 58/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 6867ba63..bdca2ea6 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -516,7 +516,7 @@ export default function Estimate({ params }) { setEstimateContextState({ pkgAsp: pkgAsp, - pkgTotPrice: pkgTotPrice.toFixed(3), + pkgTotPrice: pkgTotPrice.toFixed(2), }) //아이템들 중 조건에 맞는애들 뽑아서 상단 공급가액 부가세 총액 수정 setItemChangeYn(true) @@ -833,20 +833,20 @@ export default function Estimate({ params }) { 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(2), + vatPrice: totals.vatPrice.toFixed(2), + totPrice: totals.totPrice.toFixed(2), }) } 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(2), + vatPrice: totals.vatPrice.toFixed(2), + totPrice: totals.totPrice.toFixed(2), }) } @@ -1317,7 +1317,7 @@ export default function Estimate({ params }) {
      {getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}
      -
      {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 3)}
      +
      {convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}
      {getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}
      @@ -1363,7 +1363,7 @@ export default function Estimate({ params }) {
    - + From 6ad8a0cb8a434084ed09921a34687c152faac524 Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Thu, 5 Dec 2024 10:59:28 +0900 Subject: [PATCH 59/98] =?UTF-8?q?refactor:=20usePlan=20=EB=82=B4=20api=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EA=B4=80=EB=A0=A8=20=ED=95=A8=EC=88=98?= =?UTF-8?q?=EB=93=A4=20await=20=ED=82=A4=EC=9B=8C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePlan.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 7e76cac5..b12468b4 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' @@ -177,7 +177,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, @@ -234,15 +234,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}` }) } /** @@ -279,19 +279,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, '') } /** @@ -314,10 +314,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)) @@ -340,8 +340,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) From bb116768d37a3992820572ab78dfed03ec9e44f5 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 5 Dec 2024 13:51:48 +0900 Subject: [PATCH 60/98] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=83=81=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 24 +++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 231ce94c..58ccf7f8 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, @@ -283,6 +282,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 708471ce..4a56e462 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -156,6 +156,14 @@ export const useEstimateController = (planNo) => { return alert(getMessage('estimate.detail.save.requiredEstimateDate')) } + if (estimateData.estimateType === 'YJSS') { + let pkgAsp = estimateData.pkgAsp + if (pkgAsp === '0') { + flag = false + return alert(getMessage('estimate.detail.save.requiredPkgAsp')) + } + } + //기존에 첨부된 파일이 있으면 파일첨부관련 통과 if (estimateData?.originFiles?.length > 0) { let cnt = estimateData.originFiles.filter((file) => file.delFlg === '0').length @@ -221,6 +229,13 @@ export const useEstimateController = (planNo) => { estimateData.pkgAsp = '0' estimateData.pkgTotPrice = '0' + } else { + if (item.pkgMaterialFlg === '1') { + if (Number(item.salePrice) === 0) { + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredSalePrice')) + } + } } } } diff --git a/src/locales/ja.json b/src/locales/ja.json index 1dea67e7..7f3dcee1 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -905,6 +905,7 @@ "estimate.detail.save.requiredItem": "製品は1つ以上登録する必要があります.", "estimate.detail.save.requiredCharger": "担当者は必須です.", "estimate.detail.save.requiredObjectName": "案件名は必須です.", + "estimate.detail.save.requiredPkgAsp": "住宅pkg単価は0より大きい値を入力してください.", "estimate.detail.save.requiredEstimateDate": "見積日は必須です.", "estimate.detail.save.requiredAmount": "数量は0より大きい値を入力してください.", "estimate.detail.save.requiredSalePrice": "単価は0より大きい値を入力してください.", diff --git a/src/locales/ko.json b/src/locales/ko.json index b1d7c7da..d7c164cd 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -915,6 +915,7 @@ "estimate.detail.save.requiredItem": "제품은 1개이상 등록해야 됩니다.", "estimate.detail.save.requiredCharger": "담당자는 필수값 입니다.", "estimate.detail.save.requiredObjectName": "안건명은 필수값 입니다.", + "estimate.detail.save.requiredPkgAsp": "주택pkg 단가는 0보다 큰 값을 입력하세요.", "estimate.detail.save.requiredEstimateDate": "견적일은 필수값 입니다.", "estimate.detail.save.requiredAmount": "수량은 0보다 큰값을 입력해주세요.", "estimate.detail.save.requiredSalePrice": "단가는 0보다 큰값을 입력해주세요.", From b2293962c5729166b85caa4412546b49c28a6db1 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 18:14:08 +0900 Subject: [PATCH 84/98] TEMP --- .../floorPlan/estimate/useEstimateController.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 4a56e462..c58fddb4 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -230,12 +230,13 @@ export const useEstimateController = (planNo) => { estimateData.pkgAsp = '0' estimateData.pkgTotPrice = '0' } else { - if (item.pkgMaterialFlg === '1') { - if (Number(item.salePrice) === 0) { - itemFlg = false - return alert(getMessage('estimate.detail.save.requiredSalePrice')) - } - } + console.log('item:::', item) + // if (item.pkgMaterialFlg === '1') { + // if (Number(item.salePrice) === 0) { + // itemFlg = false + // return alert(getMessage('estimate.detail.save.requiredSalePrice')) + // } + // } } } } From 655b8f29cddd89673a9a2954341a5e8a29606f5f Mon Sep 17 00:00:00 2001 From: basssy Date: Sat, 7 Dec 2024 07:01:24 +0900 Subject: [PATCH 85/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20pkgAsp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 32 ++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 63c35b35..c800d831 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -493,19 +493,37 @@ export default function Estimate({ params }) { setSelection(newSelection) } + function formatNumberWithComma(number) { + return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') + } + //주택PKG input 변경 const onChangePkgAsp = (value) => { if (estimateContextState.estimateType === 'YJSS') { - let pkgAsp = Number(value.replace(/[^-\.0-9]/g, '').replaceAll(',', '')) - if (isNaN(pkgAsp)) { - pkgAsp = 0 - } else { - pkgAsp = pkgAsp.toLocaleString() + let newValue = value.replace(/[^0-9.]/g, '') + if (newValue.length > 1) { + newValue = newValue.replace(/(^0+)/, '') + if (newValue.length === 0) { + newValue = '0' + } } - //현재 PKG용량값 가져오기 + const parts = newValue.split('.') + if (parts.length > 2) { + newValue = parts[0] + '.' + parts.slice(1).join('') + } + + if (parts[1] && parts[1].length > 2) { + newValue = parts[0] + '.' + parts[1].substring(0, 2) + } + + let pkgAsp = newValue || '0' + + //현재 PKG용량값 가져오기 let totVolKw = estimateContextState.totVolKw * 1000 - let pkgTotPrice = pkgAsp?.replaceAll(',', '') * totVolKw * 1000 + let pkgTotPrice = parseFloat(pkgAsp?.replaceAll(',', '')) * totVolKw * 1000 + + // pkgAsp = formatNumberWithComma(parseFloat(pkgAsp).toFixed(2)) setEstimateContextState({ pkgAsp: pkgAsp, From ba9e45fcd6fcd1b7c77dc6dee8507f14115e17a9 Mon Sep 17 00:00:00 2001 From: basssy Date: Sat, 7 Dec 2024 07:27:16 +0900 Subject: [PATCH 86/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B4=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 6 ++++-- src/components/main/ProductItem.jsx | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index c800d831..4f42af51 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -840,7 +840,6 @@ export default function Estimate({ params }) { } } }) - // totals.pkgTotPrice = estimateContextState.pkgAspNumber(estimateContextState.pkgAsp.replaceAll(',', '')) * totals.totVolKw * 1000 let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0 totals.pkgTotPrice = pkgAsp * totals.totVolKw * 1000 @@ -876,8 +875,11 @@ export default function Estimate({ params }) { item.showSalePrice = '0' item.showSaleTotPrice = '0' } + if (estimateContextState.estimateType === 'YJSS' && item.paDispOrder) { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } }) - estimateContextState.itemList.forEach((item) => { if (estimateContextState.estimateType === 'YJOD' && item.openFlg === '1') { item.showSalePrice = '0' diff --git a/src/components/main/ProductItem.jsx b/src/components/main/ProductItem.jsx index 928bc269..707e35c7 100644 --- a/src/components/main/ProductItem.jsx +++ b/src/components/main/ProductItem.jsx @@ -6,7 +6,7 @@ export default function ProductItem({ num, name, children }) { // 더보기 페이지 이동 const pageMove = (num) => { if (num === 1) { - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } else if (num === 2) { router.push('/community/notice') } else { From 32108583e9749aaddbb07b73b3bb34a8d39746dc Mon Sep 17 00:00:00 2001 From: basssy Date: Sat, 7 Dec 2024 07:34:18 +0900 Subject: [PATCH 87/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floorPlan/estimate/useEstimateController.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index c58fddb4..02f82a64 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -230,13 +230,13 @@ export const useEstimateController = (planNo) => { estimateData.pkgAsp = '0' estimateData.pkgTotPrice = '0' } else { - console.log('item:::', item) - // if (item.pkgMaterialFlg === '1') { - // if (Number(item.salePrice) === 0) { - // itemFlg = false - // return alert(getMessage('estimate.detail.save.requiredSalePrice')) - // } - // } + if (item.pkgMaterialFlg === '1') { + if (Number(item.salePrice) === 0) { + console.log('item:::', item) + itemFlg = false + return alert(getMessage('estimate.detail.save.requiredSalePrice')) + } + } } } } From 4114a3ca1ef67b9bd370b88fe835eb15d97e56e2 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 9 Dec 2024 09:23:37 +0900 Subject: [PATCH 88/98] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=83=81=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Main.jsx | 29 ++-------------------------- src/components/main/MainContents.jsx | 29 ---------------------------- src/components/management/Stuff.jsx | 4 +--- 3 files changed, 3 insertions(+), 59 deletions(-) diff --git a/src/components/Main.jsx b/src/components/Main.jsx index e3c491e3..cb51b352 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -27,37 +27,12 @@ export default function MainPage() { const [searchRadioType, setSearchRadioType] = useState('object') - // const [saleStoreId, setSaleStoreId] = useState('') - // const [saleStoreName, setSaleStoreName] = useState('') - const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) const [searchForm, setSearchForm] = useRecoilState(searchState) const { qcastState } = useContext(QcastContext) - // useEffect(() => { - // if (session.pwdInitYn === 'Y') { - // fetchObjectList() - // } - // }, [session]) - - const fetchObjectList = async () => { - try { - const apiUrl = `/api/main-page/object/${session?.storeId}/list` - await promiseGet({ - url: apiUrl, - }).then((res) => { - if (res.status === 200) { - setSaleStoreId(res.data.saleStoreId) - setSaleStoreName(res.data.saleStoreName) - } - }) - } catch (error) { - console.error('MAIN API fetching error:', error) - } - } - // 엔터 이벤트 const handleByOnKeyUp = (e) => { if (e.key === 'Enter') { @@ -68,7 +43,7 @@ export default function MainPage() { schObjectNo: searchTxt, code: 'M', }) - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } else { setSearchForm({ ...searchForm, searchValue: searchTxt, mainFlag: 'Y' }) router.push('/community/faq') @@ -90,7 +65,7 @@ export default function MainPage() { code: 'M', }) - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } else { setSearchForm({ ...searchForm, searchValue: searchTxt, mainFlag: 'Y' }) router.push('/community/faq') diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx index 3cb668cc..ccae193a 100644 --- a/src/components/main/MainContents.jsx +++ b/src/components/main/MainContents.jsx @@ -22,19 +22,12 @@ export default function MainContents() { const globalLocaleState = useRecoilValue(globalLocaleStore) const { promiseGet } = useAxios(globalLocaleState) - //최근 물건 - // const [objectList, setObjectList] = useState([]) - //공지사항 const [recentNoticeList, setRecentNoticeList] = useState([]) //FAQ const [recentFaqList, setRecentFaqList] = useState([]) - //Sales Contact info - // const [businessCharger, setBusinessCharger] = useState(null) - // const [businessChargerMail, setBusinessChargerMail] = useState(null) - const { qcastState } = useContext(QcastContext) const { fetchObjectList, initObjectList } = useMainContentsController() @@ -47,28 +40,6 @@ export default function MainContents() { } }, []) - //최근 갱신 물건목록 / Sales Contact info 정보 - // const fetchObjectList = async () => { - // try { - // const apiUrl = `/api/main-page/object/${session?.storeId}/list` - // await promiseGet({ - // url: apiUrl, - // }).then((res) => { - // if (res.status === 200) { - // setObjectList(res.data.objectList) - // setBusinessCharger(res.data.businessCharger) - // setBusinessChargerMail(res.data.businessChargerMail) - // } else { - // setObjectList([]) - // setBusinessCharger(null) - // setBusinessChargerMail(null) - // } - // }) - // } catch (error) { - // console.error('MAIN API fetching error:', error) - // } - // } - //공지사항 호출 const fetchNoticeList = async () => { try { diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 52b09755..33d7883b 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -211,7 +211,6 @@ export default function Stuff() { fetchData() } else if (stuffSearchParams?.code === 'M') { const params = { - saleStoreId: session?.storeId, schObjectNo: stuffSearchParams.schObjectNo, schAddress: '', schObjectName: '', @@ -225,7 +224,7 @@ export default function Stuff() { endRow: pageNo * pageSize, schSelSaleStoreId: stuffSearchParams?.schOtherSelSaleStoreId ? stuffSearchParams.schOtherSelSaleStoreId : stuffSearchParams.schSelSaleStoreId, schSortType: 'R', - code: 'S', + code: 'E', pageNo: 1, pageSize: 100, } @@ -338,7 +337,6 @@ export default function Stuff() { //최근 등록일 수정일 정렬 이벤트 const onChangeSortType = (e) => { - // let startRow = (stuffSearchParams.pageNo - 1) * pageSize + 1 let startRow = (1 - 1) * stuffSearchParams.pageSize + 1 stuffSearchParams.startRow = startRow stuffSearchParams.endRow = startRow * stuffSearchParams.pageSize From 90a0a3893152a2a3598ba42dd09d139a88972de6 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 9 Dec 2024 09:35:57 +0900 Subject: [PATCH 89/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/estimate/useEstimateController.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 02f82a64..77141fdf 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -231,8 +231,7 @@ export const useEstimateController = (planNo) => { estimateData.pkgTotPrice = '0' } else { if (item.pkgMaterialFlg === '1') { - if (Number(item.salePrice) === 0) { - console.log('item:::', item) + if (isNaN(item.salePrice)) { itemFlg = false return alert(getMessage('estimate.detail.save.requiredSalePrice')) } From 610aa3433f61cef981189394a0036ae50e0495ff Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 9 Dec 2024 09:55:40 +0900 Subject: [PATCH 90/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B4=84?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 4 ++++ src/components/management/StuffDetail.jsx | 24 ++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 4f42af51..96749fb0 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -885,6 +885,10 @@ export default function Estimate({ params }) { item.showSalePrice = '0' item.showSaleTotPrice = '0' } + if (estimateContextState.estimateType === 'YJOD' && item.paDispOrder) { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } }) } }, [itemChangeYn, estimateContextState.itemList]) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index fce17748..bba99266 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -1403,15 +1403,21 @@ export default function StuffDetail() { alert(getMessage('stuff.detail.delete.message1')) } else { if (confirm(getMessage('common.message.data.delete'))) { - del({ url: `/api/object/${objectNo}?${queryStringFormatter(delParams)}` }).then(() => { - setFloorPlanObjectNo({ floorPlanObjectNo: '' }) - if (session.storeId === 'T01') { - stuffSearchParams.code = 'DELETE' - } else { - resetStuffRecoil() - } - router.push('/management/stuff', { scroll: false }) - }) + // setIsGlobalLoading(true) + del({ url: `/api/object/${objectNo}?${queryStringFormatter(delParams)}` }) + .then(() => { + setFloorPlanObjectNo({ floorPlanObjectNo: '' }) + if (session.storeId === 'T01') { + stuffSearchParams.code = 'DELETE' + } else { + resetStuffRecoil() + } + // setIsGlobalLoading(false) + router.push('/management/stuff', { scroll: false }) + }) + .catch(() => { + // setIsGlobalLoading(false) + }) } } } From 44c0247c0464808fce20d4694df562d84c6d5549 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 9 Dec 2024 10:25:59 +0900 Subject: [PATCH 91/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 96749fb0..cab162d1 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -875,6 +875,10 @@ export default function Estimate({ params }) { item.showSalePrice = '0' item.showSaleTotPrice = '0' } + if (estimateContextState.estimateType === 'YJSS' && item.openFlg === '1') { + item.showSalePrice = '0' + item.showSaleTotPrice = '0' + } if (estimateContextState.estimateType === 'YJSS' && item.paDispOrder) { item.showSalePrice = '0' item.showSaleTotPrice = '0' From d01d7f6791d89fd29f26b5c60ceddc3c2da44fea Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 9 Dec 2024 10:43:37 +0900 Subject: [PATCH 92/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EA=B0=80?= =?UTF-8?q?=EA=B2=A9=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index cab162d1..1af506a8 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -326,22 +326,22 @@ export default function Estimate({ params }) { //가격 표시 option 변경 이벤트 const onChangeStorePriceList = (priceCd) => { - const param = { - saleStoreId: session.storeId, - sapSalesStoreCd: session.custCd, - docTpCd: priceCd, - } - //프라이싱 했을때 priceCd setEstimateContextState //화면에 보여지는 값은 showPriceCd로 관리 setShowPriceCd(priceCd) + // return + // const param = { + // saleStoreId: session.storeId, + // sapSalesStoreCd: session.custCd, + // docTpCd: priceCd, + // } - const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}` - get({ url: apiUrl }).then((res) => { - if (isNotEmptyArray(res?.data)) { - setStorePriceList(res.data) - } - }) + // const apiUrl = `/api/estimate/price/store-price-list?${queryStringFormatter(param)}` + // get({ url: apiUrl }).then((res) => { + // if (isNotEmptyArray(res?.data)) { + // setStorePriceList(res.data) + // } + // }) } const makeUniqueSpecialNoteCd = (itemList) => { @@ -1404,7 +1404,6 @@ export default function Estimate({ params }) {
    {session?.storeLvl === '1' ? (
    {convertNumberToPriceDecimal( - item?.showSaleTotPrice === '0' ? null : item?.saleTotPrice === '0' ? null : item?.saleTotPrice?.replaceAll(',', ''), + item?.showSaleTotPrice === '0' + ? null + : item?.amount === '' + ? null + : item?.saleTotPrice === '0' + ? null + : item?.saleTotPrice?.replaceAll(',', ''), )}
    {getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')}{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 3)}{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)} {getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')} {convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)}
    + 신규
    + 상세
    - 신규 {getMessage('stuff.search.title')}
    - + + {/* */} From fb577316a0d5adaa21b6e70a76f7f02a4302f8ac Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 5 Dec 2024 14:40:14 +0900 Subject: [PATCH 62/98] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EC=88=98?= =?UTF-8?q?=EB=8F=99=20=EB=AA=A8=EB=93=88=20=EC=84=A4=EC=B9=98=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 2 +- .../modal/basic/step/pitch/PitchPlacement.jsx | 45 ++- src/hooks/module/useModuleBasicSetting.js | 334 +++++++++++++++++- 3 files changed, 377 insertions(+), 4 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index c6dee35b..ea46bd3b 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -93,7 +93,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { )} {canvasSetting.roofSizeSet && canvasSetting.roofSizeSet === 3 && ( <> -
    diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 5d37538f..9e83ca92 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -134,6 +134,7 @@ export default function StuffDetail() { field: 'moduleModel', headerName: getMessage('stuff.detail.planGridHeader.moduleModel'), flex: 1, + wrapText: true, cellStyle: { justifyContent: 'flex-start' /* 좌측정렬*/ }, }, { diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 28037be5..708471ce 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -194,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)) { @@ -227,7 +226,6 @@ export const useEstimateController = (planNo) => { } } }) - estimateData.itemList = estimateData.itemList.filter((item) => item.delFlg === '0' || !item.addFlg) let delCnt = 0 From ffc2ce08dc2a3101d15442b90e4ffa94cfb5e5e0 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 5 Dec 2024 16:07:46 +0900 Subject: [PATCH 66/98] =?UTF-8?q?refactor:=20=EC=BA=94=EB=B2=84=EC=8A=A4?= =?UTF-8?q?=20=EB=B0=B0=EA=B2=BD=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useRefFiles.js | 26 ++++++++++++++++++------ src/lib/fileAction.js | 35 +++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index ecca2f62..5877a668 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -1,11 +1,12 @@ import { useEffect, useRef, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' import { v4 as uuidv4 } from 'uuid' +import fs from 'fs/promises' import { useSwal } from '@/hooks/useSwal' import { useAxios } from '../useAxios' import { canvasState, currentCanvasPlanState } from '@/store/canvasAtom' -import { convertDwgToPng, removeImage, writeImageBuffer } from '@/lib/fileAction' +import { convertDwgToPng, removeImage, writeImageBuffer, readImage } from '@/lib/fileAction' import { useCanvas } from '@/hooks/useCanvas' export function useRefFiles() { @@ -16,6 +17,7 @@ export function useRefFiles() { const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) const queryRef = useRef(null) const canvas = useRecoilValue(canvasState) + const [currentBgImage, setCurrentBgImage] = useState(null) const { swalFire } = useSwal() const { get, promisePut, promiseGet, promisePost } = useAxios() @@ -109,19 +111,31 @@ export function useRefFiles() { * 주소로 구글 맵 이미지 다운로드 */ const handleMapImageDown = async () => { + console.log('🚀 ~ handleMapImageDown ~ handleMapImageDown:') if (queryRef.current.value === '' || queryRef.current.value === null) { return } - const res = await promiseGet({ + const res = await get({ url: `http://localhost:3000/api/html2canvas?q=${queryRef.current.value}&fileNm=${currentCanvasPlan.id}&zoom=20`, - }).then((req, res) => { - console.log('handleMapImageDown', res) - handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) - setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) }) + console.log('🚀 ~ handleMapImageDown ~ res:', res) + const file = await readImage(res.fileNm) + console.log('🚀 ~ handleMapImageDown ~ file:', file) + setCurrentBgImage(file) + // handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) + // 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`) + setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) + }, [currentBgImage]) + /** * 이미지 파일 업로드 * @param {*} file diff --git a/src/lib/fileAction.js b/src/lib/fileAction.js index fe870374..efc532aa 100644 --- a/src/lib/fileAction.js +++ b/src/lib/fileAction.js @@ -62,24 +62,29 @@ const writeImageBase64 = async (title, data) => { // } const writeImage = async (fileName, file) => { - try { - await fs.readdir(FILE_PATH) - } catch { - await fs.mkdir(FILE_PATH) - } + return new Promise((resolve, reject) => { + try { + fs.readdir(FILE_PATH) + } catch { + fs.mkdir(FILE_PATH) + } - return fs.writeFile(`${FILE_PATH}/${fileName}.png`, file) + fs.writeFile(`${FILE_PATH}/${fileName}.png`, file) + resolve(true) + }) } const readImage = async (fileName) => { - await fs - .readFile(`${FILE_PATH}/${fileName}.png`) - .then((res) => { - console.log('readImage-then', res) - }) - .catch((e) => { - console.log('readImage-catch', e) - }) + const file = await fs.readFile(`${FILE_PATH}/${fileName}`) + // .then((res) => { + // console.log('readImage-then', res) + // }) + // .catch((e) => { + // console.log('readImage-catch', e) + // }) + console.log('🚀 ~ readImage ~ file:', file) + + return file } const removeImage = async (fileName) => { @@ -90,4 +95,4 @@ const removeImage = async (fileName) => { } } -export { convertDwgToPng, writeImageBase64, writeImage, removeImage } +export { convertDwgToPng, writeImageBase64, writeImage, readImage, removeImage } From 60592f0a59ccc33fa824d703d4b5b4d8159ca47d Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 5 Dec 2024 16:51:25 +0900 Subject: [PATCH 67/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 2a49e5db..b139a851 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -230,6 +230,9 @@ export default function Estimate({ params }) { if (isEmptyArray(files)) { let file file = originFiles.filter((item) => item.delFlg === '0') + setEstimateContextState({ + originFiles: file, + }) setOriginFiles(file) } } From bdffcc78b6b41308e77d43164036a13b6395685a Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 5 Dec 2024 18:05:47 +0900 Subject: [PATCH 68/98] =?UTF-8?q?moduleSetupSurfaces=20=EB=B3=84=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 31c5ee7f..f51cf00f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1080,7 +1080,7 @@ export function useModuleBasicSetting() { } leftTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, + (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, @@ -1098,7 +1098,6 @@ export function useModuleBasicSetting() { } if (leftTopCnt + rightTopCnt === 0) { exposedTop++ - return } }) // 완전 노출 하면 계산 From 96290ea060b4ca7c6a36d1e5491e4452a2ecffe3 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 08:46:44 +0900 Subject: [PATCH 69/98] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=20&=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/header/Header.jsx | 4 +++- src/components/main/MainContents.jsx | 4 ++-- src/components/management/StuffDetail.jsx | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index fe3c202d..4776b0ff 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -155,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 9e83ca92..190e0754 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -322,7 +322,7 @@ export default function StuffDetail() { } else { setManagementState({}) alert(getMessage('stuff.detail.header.notExistObjectNo')) - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } if (isNotEmptyArray(res.data.planList)) { setPlanGridProps({ ...planGridProps, planGridData: res.data.planList }) @@ -334,7 +334,7 @@ export default function StuffDetail() { setPlanGridProps({ ...planGridProps, planGridData: [] }) alert(getMessage('stuff.detail.header.notExistObjectNo')) - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) } }) } else { @@ -1381,7 +1381,7 @@ export default function StuffDetail() { } else { resetStuffRecoil() } - router.push('/management/stuff') + router.push('/management/stuff', { scroll: false }) }) } } From 706af69fefd6a648c3435650e623eaeb2fc1efca Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 10:15:28 +0900 Subject: [PATCH 70/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EB=B4=84=EC=A0=9C=ED=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 59 ++++++++++++++++------------ 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index b139a851..88ae05fe 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -661,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' @@ -748,12 +750,10 @@ export default function Estimate({ params }) { makeUniqueSpecialNoteCd(itemList) itemList.forEach((item) => { - // console.log('YJOD::::::', item) delete item.showSalePrice 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 @@ -768,6 +768,10 @@ export default function Estimate({ params }) { 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' @@ -777,8 +781,6 @@ export default function Estimate({ params }) { totals.vatPrice = totals.supplyPrice * 0.1 totals.totPrice = totals.supplyPrice + totals.vatPrice - - // console.log('YJOD:::totlas:::', totals) } const calculateYJSSTotals = (itemList) => { @@ -787,7 +789,6 @@ 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 @@ -810,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' } } }) @@ -818,18 +827,15 @@ export default function Estimate({ params }) { totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice totals.vatPrice = totals.supplyPrice * 0.1 totals.totPrice = totals.supplyPrice + totals.vatPrice - - // console.log('YJOD:::totlas:::', totals) } - if (estimateContextState.estimateType === 'YJOD') { calculateYJODTotals(estimateContextState.itemList) setEstimateContextState({ totAmount: totals.totAmount, totVolKw: totals.totVolKw.toFixed(2), - supplyPrice: totals.supplyPrice.toFixed(2), - vatPrice: totals.vatPrice.toFixed(2), - totPrice: totals.totPrice.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) @@ -837,9 +843,9 @@ export default function Estimate({ params }) { pkgTotPrice: totals.pkgTotPrice, totAmount: totals.totAmount, totVolKw: totals.totVolKw.toFixed(2), - supplyPrice: totals.supplyPrice.toFixed(2), - vatPrice: totals.vatPrice.toFixed(2), - totPrice: totals.totPrice.toFixed(2), + supplyPrice: totals.supplyPrice.toFixed(0), //소수첫자리에서 반올림 + vatPrice: totals.vatPrice.toFixed(0), //소수첫자리에서 반올림 + totPrice: totals.totPrice.toFixed(0), //소수첫자리에서 반올림 }) } @@ -1312,15 +1318,15 @@ export default function Estimate({ params }) {
    {getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}
    -
    {convertNumberToPriceDecimal(estimateContextState?.supplyPrice)}
    +
    {convertNumberToPriceDecimalToFixed(estimateContextState?.supplyPrice, 0)}
    {getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}
    -
    {convertNumberToPriceDecimal(estimateContextState?.vatPrice)}
    +
    {convertNumberToPriceDecimalToFixed(estimateContextState?.vatPrice, 0)}
    {getMessage('estimate.detail.sepcialEstimateProductInfo.totPrice')}
    -
    {convertNumberToPriceDecimal(estimateContextState?.totPrice)}
    +
    {convertNumberToPriceDecimalToFixed(estimateContextState?.totPrice, 0)}
    @@ -1491,7 +1497,6 @@ export default function Estimate({ params }) {
    - */} - {!currentCanvasPlan?.bgImageName ? ( - - ) : ( - - )} - {(refImage || currentCanvasPlan?.bgImageName) && } + + {refImage && }
    diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index 566e38b5..de019730 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -37,11 +37,18 @@ export default function FirstOption() { setSurfaceShapePattern(polygon, item.column) }) //디스플레이 설정 표시(단 건 선택) + } else if (item.column === 'imageDisplay') { + item.selected = !item.selected + canvas + .getObjects() + .filter((obj) => obj.name === 'backGroundImage') + .forEach((image) => (image.visible = item.selected)) + canvas.renderAll() } else { item.selected = !item.selected } - setSettingModalFirstOptions({ ...settingModalFirstOptions, option1, option2, dimensionDisplay, fontFlag: true }) + setSettingModalFirstOptions({ ...settingModalFirstOptions, option2, dimensionDisplay, fontFlag: true }) } // useEffect(() => { diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index 5877a668..df0b5634 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -1,7 +1,5 @@ import { useEffect, useRef, useState } from 'react' import { useRecoilState, useRecoilValue } from 'recoil' -import { v4 as uuidv4 } from 'uuid' -import fs from 'fs/promises' import { useSwal } from '@/hooks/useSwal' import { useAxios } from '../useAxios' @@ -14,13 +12,13 @@ export function useRefFiles() { const [refImage, setRefImage] = useState(null) const [refFileMethod, setRefFileMethod] = useState('1') const [mapPositionAddress, setMapPositionAddress] = useState('') - const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) - const queryRef = useRef(null) - const canvas = useRecoilValue(canvasState) const [currentBgImage, setCurrentBgImage] = useState(null) - + const queryRef = useRef(null) + const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) + const canvas = useRecoilValue(canvasState) + const { handleBackImageLoadToCanvas } = useCanvas() const { swalFire } = useSwal() - const { get, promisePut, promiseGet, promisePost } = useAxios() + const { get, post, promisePost } = useAxios() useEffect(() => { if (refFileMethod === '1') { @@ -30,6 +28,20 @@ export function useRefFiles() { setRefImage(null) } }, [refFileMethod]) + + /** + * 현재 플랜이 변경되면 플랜 상태 저장 + */ + useEffect(() => { + // console.log('🚀 ~ useRefFiles ~ currentCanvasPlan:', currentCanvasPlan) + // const handleCurrentPlan = async () => { + // await promisePut({ url: '/api/canvas-management/canvas-statuses', data: currentCanvasPlan }).then((res) => { + // console.log('🚀 ~ awaitpromisePut ~ res:', res) + // }) + // } + // handleCurrentPlan() + }, [currentCanvasPlan]) + /** * 파일 불러오기 버튼 컨트롤 * @param {*} file @@ -37,11 +49,26 @@ export function useRefFiles() { const handleRefFile = (file) => { console.log('handleRefFile', file) console.log('refImage', refImage) + + if (refImage) { + swalFire({ + text: '파일을 변경하시겠습니까?', + type: 'confirm', + confirmFn: () => { + refFileSetting(file) + // setRefImage(file) + // file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) + }, + }) + } else { + refFileSetting(file) + } + } + + const refFileSetting = (file) => { if (file && ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif'].includes(file.type)) { // setRefImage(file) file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) - - return } else { swalFire({ text: '이미지가 아닙니다.', @@ -49,30 +76,7 @@ export function useRefFiles() { icon: 'error', }) } - if (refImage) { - swalFire({ - text: '파일을 변경하시겠습니까?', - type: 'confirm', - confirmFn: () => { - setRefImage(file) - const backGroundImage = canvas.getObjects().filter((obj) => obj.name === 'backGroundImage') - if (backGroundImage.length > 0) { - canvas.remove(backGroundImage) - } - canvas.renderAll() - file.name.split('.').pop() === 'dwg' ? handleUploadConvertRefFile(file) : handleUploadImageRefFile(file) - }, - }) - } - - /** - * 파일 확장자가 dwg일 경우 변환하여 이미지로 저장 - * 파일 확장자가 이미지일 경우 이미지 저장 - */ - - // handleUploadRefFile(file) } - /** * 파일 삭제 */ @@ -133,30 +137,25 @@ export function useRefFiles() { } console.log('🚀 ~ useEffect ~ currentBgImage:', currentBgImage) handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) - setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: currentCanvasPlan.id, mapPositionAddress: queryRef.current.value })) + setCurrentCanvasPlan((prev) => ({ ...prev, bgImageName: refImage?.name ?? null, mapPositionAddress: queryRef.current.value })) }, [currentBgImage]) /** * 이미지 파일 업로드 * @param {*} file */ - const { handleBackImageLoadToCanvas } = useCanvas() const handleUploadImageRefFile = async (file) => { - // console.log('🚀 ~ handleUploadImageRefFile ~ file:', file) const formData = new FormData() formData.append('file', file) formData.append('fileName', currentCanvasPlan.id) - const response = await fetch('http://localhost:3000/api/image-upload', { - method: 'POST', - body: formData, - }) + const res = await post({ url: 'http://localhost:3000/api/image-upload', data: formData }) + console.log('🚀 ~ handleUploadImageRefFile ~ res:', res) + const image = await readImage(res.fileNm) + console.log('🚀 ~ handleUploadImageRefFile ~ file:', image) - handleBackImageLoadToCanvas(`plan-images/${currentCanvasPlan.id}.png`) - const result = await response.json() + setCurrentBgImage(image) setRefImage(file) - // console.log('🚀 ~ handleUploadImageRefFile ~ res:', result) - // writeImageBuffer(file) } /** @@ -186,19 +185,6 @@ export function useRefFiles() { setRefFileMethod(e.target.value) } - /** - * 현재 플랜이 변경되면 플랜 상태 저장 - */ - useEffect(() => { - // console.log('🚀 ~ useRefFiles ~ currentCanvasPlan:', currentCanvasPlan) - // const handleCurrentPlan = async () => { - // await promisePut({ url: '/api/canvas-management/canvas-statuses', data: currentCanvasPlan }).then((res) => { - // console.log('🚀 ~ awaitpromisePut ~ res:', res) - // }) - // } - // handleCurrentPlan() - }, [currentCanvasPlan]) - return { refImage, queryRef, diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 33e4a8d3..d6443c2a 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -507,8 +507,6 @@ export function useCanvas(id) { * cad 파일 사용시 이미지 로딩 함수 */ const handleBackImageLoadToCanvas = (url) => { - console.log('image load url: ', url) - canvas .getObjects() .filter((obj) => obj.name === 'backGroundImage') @@ -516,7 +514,7 @@ export function useCanvas(id) { canvas.remove(img) canvas?.renderAll() }) - fabric.Image.fromURL(url, function (img) { + fabric.Image.fromURL(`${url}?${new Date().getTime()}`, function (img) { console.log(img) img.set({ left: 0, @@ -536,7 +534,6 @@ export function useCanvas(id) { canvas?.add(img) canvas?.sendToBack(img) canvas?.renderAll() - console.log(canvas.getObjects().filter((obj) => obj.name === 'backGroundImage')) setBackImg(img) }) } diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 786e2660..532759a4 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -200,6 +200,7 @@ export function usePlan() { userId: userId, imageName: 'image_name', // api 필수항목이여서 임시로 넣음, 이후 삭제 필요 objectNo: objectNo, + bgImageName: currentCanvasPlan?.bgImageName ?? null, mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null, canvasStatus: canvasToDbFormat(canvasStatus), } @@ -220,8 +221,8 @@ export function usePlan() { const putCanvasStatus = async (canvasStatus) => { const planData = { id: currentCanvasPlan.id, - bgImageName: currentCanvasPlan?.id ?? null, - mapPositionAddress: currentCanvasPlan.mapPositionAddress, + bgImageName: currentCanvasPlan?.bgImageName ?? null, + mapPositionAddress: currentCanvasPlan?.mapPositionAddress ?? null, canvasStatus: canvasToDbFormat(canvasStatus), } await promisePut({ url: '/api/canvas-management/canvas-statuses', data: planData }) diff --git a/src/lib/fileAction.js b/src/lib/fileAction.js index efc532aa..d2c4cff9 100644 --- a/src/lib/fileAction.js +++ b/src/lib/fileAction.js @@ -62,16 +62,13 @@ const writeImageBase64 = async (title, data) => { // } const writeImage = async (fileName, file) => { - return new Promise((resolve, reject) => { - try { - fs.readdir(FILE_PATH) - } catch { - fs.mkdir(FILE_PATH) - } + try { + await fs.readdir(FILE_PATH) + } catch { + await fs.mkdir(FILE_PATH) + } - fs.writeFile(`${FILE_PATH}/${fileName}.png`, file) - resolve(true) - }) + return fs.writeFile(`${FILE_PATH}/${fileName}.png`, file) } const readImage = async (fileName) => { From 50c24a5368aced7bee97fc3935821a37689cb6d1 Mon Sep 17 00:00:00 2001 From: minsik Date: Fri, 6 Dec 2024 13:31:52 +0900 Subject: [PATCH 74/98] =?UTF-8?q?=EB=B0=A9=EC=9C=84=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EB=A7=88=ED=81=AC=EC=97=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Orientation.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Orientation.jsx b/src/components/floor-plan/modal/basic/step/Orientation.jsx index b080b1b1..296cce4a 100644 --- a/src/components/floor-plan/modal/basic/step/Orientation.jsx +++ b/src/components/floor-plan/modal/basic/step/Orientation.jsx @@ -34,7 +34,7 @@ export const Orientation = forwardRef(({ tabNum }, ref) => { onClick={() => setCompasDeg(15 * (12 + index))} > {index === 0 && 180°} - {index === 6 && 270°} + {index === 6 && -90°} ))} {Array.from({ length: 180 / 15 }).map((dot, index) => ( @@ -56,7 +56,7 @@ export const Orientation = forwardRef(({ tabNum }, ref) => {
    setHasAnglePassivity(!hasAnglePassivity)} /> - +
    From d353ebac99b37a546950bbf21cf15de4d8747077 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 13:33:51 +0900 Subject: [PATCH 75/98] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../management/StuffSearchCondition.jsx | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 6c0ec2c4..8b5f3156 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -291,17 +291,39 @@ export default function StuffSearchCondition() { schSortType: 'R', pageNo: 1, pageSize: 100, - code: 'S', + // code: 'S', }) } else { if (otherSaleStoreList.length > 1) { handleClear2() setOtherSaleStoreId('') stuffSearch.schObjectNo = '' + stuffSearch.schAddress = '' + stuffSearch.schObjectName = '' + stuffSearch.schSaleStoreName = '' + stuffSearch.schReceiveUser = '' + stuffSearch.schDispCompanyName = '' stuffSearch.schDateType = 'U' + + stuffSearch.startRow = 1 + stuffSearch.endRow = 100 + stuffSearch.schSortType = 'R' + stuffSearch.pageNo = 1 + stuffSearch.pageSize = 100 } else { stuffSearch.schObjectNo = '' + stuffSearch.schAddress = '' + stuffSearch.schObjectName = '' + stuffSearch.schSaleStoreName = '' + stuffSearch.schReceiveUser = '' + stuffSearch.schDispCompanyName = '' stuffSearch.schDateType = 'U' + + stuffSearch.startRow = 1 + stuffSearch.endRow = 100 + stuffSearch.schSortType = 'R' + stuffSearch.pageNo = 1 + stuffSearch.pageSize = 100 } } } From 9042731ff8409422d524eb921c358af6609b4081 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 14:10:33 +0900 Subject: [PATCH 76/98] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20api=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EB=9D=84=EC=9A=B0=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 83 +++++++++++++++-------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 190e0754..c1a59b1a 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -917,7 +917,11 @@ export default function StuffDetail() { }) //설계의뢰 팝업에선 WL_안붙어서 옴 - form.setValue('standardWindSpeedId', `WL_${info.windSpeed}`) + if (info.windSpeed !== '') { + form.setValue('standardWindSpeedId', `WL_${info.windSpeed}`) + } else { + form.setValue('standardWindSpeedId', `WL_${info.windSpeed}`) + } form.setValue('verticalSnowCover', info.verticalSnowCover) form.setValue('surfaceType', info.surfaceType) @@ -1046,7 +1050,7 @@ export default function StuffDetail() { errors.prefId = true } - if (!formData.areaId) { + if (!formData.areaId || formData.areaId === '0') { errors.areaId = true } @@ -1290,23 +1294,34 @@ export default function StuffDetail() { } if (editMode === 'NEW') { - await promisePost({ url: apiUrl, data: params }).then((res) => { - //상세화면으로 전환 - if (res.status === 201) { - alert(getMessage('stuff.detail.save')) - setFloorPlanObjectNo({ floorPlanObjectNo: objectNo }) - router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) - } - }) + await promisePost({ url: apiUrl, data: params }) + .then((res) => { + //상세화면으로 전환 + if (res.status === 201) { + alert(getMessage('stuff.detail.save')) + setFloorPlanObjectNo({ floorPlanObjectNo: objectNo }) + router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) + } + }) + .catch((error) => { + console.log('error::::::', error) + alert(error?.response.data.message) + }) } else { // 수정모드일때는 PUT - await promisePut({ url: apiUrl, data: params }).then((res) => { - if (res.status === 201) { - setFloorPlanObjectNo({ floorPlanObjectNo: res.data.objectNo }) - alert(getMessage('stuff.detail.save')) - router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) - } - }) + // await promisePut({ url: apiUrl, data: params }).then((res) => { + await promisePut({ url: apiUrl, data: params }) + .then((res) => { + if (res.status === 201) { + setFloorPlanObjectNo({ floorPlanObjectNo: res.data.objectNo }) + alert(getMessage('stuff.detail.save')) + router.push(`/management/stuff/detail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) + } + }) + .catch((error) => { + console.log('error::::::', error) + alert(error?.response.data.message) + }) } } @@ -1351,19 +1366,29 @@ export default function StuffDetail() { const apiUrl = '/api/object/save-object' if (objectNo) { - await promisePut({ url: apiUrl, data: params }).then((res) => { - if (res.status === 201) { - alert(getMessage('stuff.detail.tempSave.message1')) - router.push(`/management/stuff/tempdetail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) - } - }) + await promisePut({ url: apiUrl, data: params }) + .then((res) => { + if (res.status === 201) { + alert(getMessage('stuff.detail.tempSave.message1')) + router.push(`/management/stuff/tempdetail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) + } + }) + .catch((error) => { + console.log('error::::::', error) + alert(error?.response.data.message) + }) } else { - await promisePost({ url: apiUrl, data: params }).then((res) => { - if (res.status === 201) { - alert(getMessage('stuff.detail.tempSave.message1')) - router.push(`/management/stuff/tempdetail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) - } - }) + await promisePost({ url: apiUrl, data: params }) + .then((res) => { + if (res.status === 201) { + alert(getMessage('stuff.detail.tempSave.message1')) + router.push(`/management/stuff/tempdetail?objectNo=${res.data.objectNo.toString()}`, { scroll: false }) + } + }) + .catch((error) => { + console.log('error::::::', error) + alert(error?.response.data.message) + }) } } From b07273ea86d4cdc2ffa278f4c92878c8484155fd Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 14:51:05 +0900 Subject: [PATCH 77/98] recoil --- src/store/stuffAtom.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/store/stuffAtom.js b/src/store/stuffAtom.js index 1608beac..8f19303d 100644 --- a/src/store/stuffAtom.js +++ b/src/store/stuffAtom.js @@ -1,8 +1,7 @@ import { atom } from 'recoil' import dayjs from 'dayjs' -import { v1 } from 'uuid' export const stuffSearchState = atom({ - key: `stuffSearchState/${v1()}`, + key: `stuffSearchState/`, default: { schObjectNo: '', //물건번호 schAddress: '', //물건주소 From 6e4082935f8c585b1948ddde794f67156d856e4c Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Fri, 6 Dec 2024 16:02:45 +0900 Subject: [PATCH 78/98] =?UTF-8?q?Canvas=20=EC=84=A4=EC=A0=95=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/setting01/FirstOption.jsx | 32 ++++++++-------- .../floor-plan/modal/setting01/GridOption.jsx | 7 ++-- .../modal/setting01/SecondOption.jsx | 14 ++++++- .../modal/setting01/SettingModal01.jsx | 38 +++++++++++++++++-- src/hooks/option/useCanvasSetting.js | 12 ++---- src/store/settingAtom.js | 5 +++ 6 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index 92e9f3d5..f3ef9b8b 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -5,9 +5,10 @@ import { POLYGON_TYPE } from '@/common/common' import { setSurfaceShapePattern } from '@/util/canvas-util' import { useEvent } from '@/hooks/useEvent' -export default function FirstOption() { +export default function FirstOption(props) { const { getMessage } = useMessage() - const { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = useCanvasSetting() + // const { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = useCanvasSetting() + let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = props const { option1, option2, dimensionDisplay } = settingModalFirstOptions const { initEvent } = useEvent() @@ -18,22 +19,26 @@ export default function FirstOption() { const onClickOption = async (item) => { //치수 표시(단 건 선택) + let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay + let option1 = settingModalFirstOptions?.option1 + let option2 = settingModalFirstOptions?.option2 + if (item.column === 'corridorDimension' || item.column === 'realDimension' || item.column === 'noneDimension') { - const options = settingModalFirstOptions?.dimensionDisplay.map((option) => { + dimensionDisplay = settingModalFirstOptions?.dimensionDisplay.map((option) => { option.selected = option.id === item.id return option }) - setSettingModalFirstOptions({ ...settingModalFirstOptions, dimensionDisplay: [...options] }) + // setSettingModalFirstOptions({ ...settingModalFirstOptions, dimensionDisplay: [...options] }) //화면 표시(단 건 선택) } else if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') { - const options = settingModalFirstOptions?.option2.map((option2) => { + option2 = settingModalFirstOptions?.option2.map((option2) => { option2.selected = option2.id === item.id return option2 }) - setSettingModalFirstOptions({ ...settingModalFirstOptions, option2: [...options] }) + // setSettingModalFirstOptions({ ...settingModalFirstOptions, option2: [...options] }) const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) @@ -41,25 +46,18 @@ export default function FirstOption() { setSurfaceShapePattern(polygon, item.column) }) //디스플레이 설정 표시(단 건 선택) - } else if (item.column === 'imageDisplay') { - item.selected = !item.selected - canvas - .getObjects() - .filter((obj) => obj.name === 'backGroundImage') - .forEach((image) => (image.visible = item.selected)) - canvas.renderAll() - }else { - const options = settingModalFirstOptions?.option1.map((opt) => { + } else { + option1 = settingModalFirstOptions?.option1.map((opt) => { if (opt.id === item.id) { opt.selected = !opt.selected } return opt }) - setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] }) + // setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] }) } - setSettingsData({ ...settingsData, ...settingModalFirstOptions }) + setSettingsData({ ...settingsData, option1: [...option1], option2: [...option2], dimensionDisplay: [...dimensionDisplay] }) } // useEffect(() => { diff --git a/src/components/floor-plan/modal/setting01/GridOption.jsx b/src/components/floor-plan/modal/setting01/GridOption.jsx index 8c66534a..1d40ddbc 100644 --- a/src/components/floor-plan/modal/setting01/GridOption.jsx +++ b/src/components/floor-plan/modal/setting01/GridOption.jsx @@ -11,7 +11,7 @@ import DotLineGrid from '@/components/floor-plan/modal/grid/DotLineGrid' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useEvent } from '@/hooks/useEvent' -export default function GridOption() { +export default function GridOption(props) { const [gridOptions, setGridOptions] = useRecoilState(settingModalGridOptionsState) const [adsorptionPointAddMode, setAdsorptionPointAddMode] = useRecoilState(adsorptionPointAddModeState) const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState) @@ -23,12 +23,13 @@ export default function GridOption() { const [colorId, setColorId] = useState(uuidv4()) const [dotLineId, setDotLineId] = useState(uuidv4()) - const { gridColor, setGridColor, color } = useCanvasSetting() + // const { gridColor, setGridColor, color } = useCanvasSetting() + const { gridColor, setGridColor, color } = props const { initEvent } = useEvent() useEffect(() => { - console.log(gridColor, color) + console.log('GridOption useEffect 실행') setGridColor(color.hex) }, [color]) diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx index 0b350067..df60763d 100644 --- a/src/components/floor-plan/modal/setting01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -10,7 +10,7 @@ import { useRecoilState, useRecoilValue } from 'recoil' import { fontSelector, globalFontAtom } from '@/store/fontAtom' import { useEvent } from '@/hooks/useEvent' -export default function SecondOption() { +export default function SecondOption(props) { const { getMessage } = useMessage() const { addPopup, closePopup } = usePopup() const [showFontSettingModal, setShowFontSettingModal] = useState(false) @@ -27,6 +27,16 @@ export default function SecondOption() { const { initEvent } = useEvent() + // const { + // fetchSettings, + // planSizeSettingMode, + // setPlanSizeSettingMode, + // settingModalSecondOptions, + // setSettingModalSecondOptions, + // adsorptionPointMode, + // setAdsorptionPointMode, + // setAdsorptionRange, + // } = useCanvasSetting() const { fetchSettings, planSizeSettingMode, @@ -36,7 +46,7 @@ export default function SecondOption() { adsorptionPointMode, setAdsorptionPointMode, setAdsorptionRange, - } = useCanvasSetting() + } = props const { option3, option4 } = settingModalSecondOptions // 데이터를 최초 한 번만 조회 diff --git a/src/components/floor-plan/modal/setting01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx index 222226c1..73ce8fa2 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -9,6 +9,7 @@ import GridOption from '@/components/floor-plan/modal/setting01/GridOption' import { canGridOptionSeletor } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' import { usePopup } from '@/hooks/usePopup' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' export default function SettingModal01(props) { const { id } = props @@ -17,6 +18,37 @@ export default function SettingModal01(props) { const canGridOptionSeletorValue = useRecoilValue(canGridOptionSeletor) const { closePopup } = usePopup() + const { + canvas, + settingModalFirstOptions, + setSettingModalFirstOptions, + settingsData, + setSettingsData, + fetchSettings, + planSizeSettingMode, + setPlanSizeSettingMode, + settingModalSecondOptions, + setSettingModalSecondOptions, + adsorptionPointMode, + setAdsorptionPointMode, + setAdsorptionRange, + gridColor, + setGridColor, + color, + } = useCanvasSetting() + const firstProps = { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } + const secondProps = { + fetchSettings, + planSizeSettingMode, + setPlanSizeSettingMode, + settingModalSecondOptions, + setSettingModalSecondOptions, + adsorptionPointMode, + setAdsorptionPointMode, + setAdsorptionRange, + } + const gridProps = { gridColor, setGridColor, color } + const handleBtnClick = (num) => { setButtonAct(num) } @@ -46,9 +78,9 @@ export default function SettingModal01(props) { )}
    - {buttonAct === 1 && } - {buttonAct === 2 && } - {buttonAct === 3 && } + {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && }
    diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 08063193..238b956d 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -19,6 +19,7 @@ import { settingModalSecondOptionsState, settingModalGridOptionsState, basicSettingState, + settingsState, } from '@/store/settingAtom' import { POLYGON_TYPE } from '@/common/common' import { globalFontAtom } from '@/store/fontAtom' @@ -46,7 +47,8 @@ export function useCanvasSetting() { const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) - const [settingsData, setSettingsData] = useState({ ...settingModalFirstOptions, ...settingModalSecondOptions }) + + const [settingsData, setSettingsData] = useRecoilState(settingsState) const { option1, option2, dimensionDisplay } = settingModalFirstOptions const { option4 } = settingModalSecondOptions @@ -120,10 +122,6 @@ export function useCanvasSetting() { canvas?.renderAll() }, [corridorDimension]) - useEffect(() => { - console.log('🚀 ~ useCanvasSetting ~ settingsData:', settingsData) - }, []) - // 배치면 초기설정 변경 시 useEffect(() => { //console.log('useCanvasSetting canvasSetting 실행', canvasSetting) @@ -132,9 +130,7 @@ export function useCanvasSetting() { } }, [canvasSetting]) - useEffect(() => { - console.log('useCanvasSetting ------------->', settingsData) - }, [settingsData]) + useEffect(() => {}, [settingsData]) //흡착점 ON/OFF 변경 시 // useEffect(() => { diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js index 9e64d72f..54944142 100644 --- a/src/store/settingAtom.js +++ b/src/store/settingAtom.js @@ -77,6 +77,11 @@ export const settingModalSecondOptionsState = atom({ dangerouslyAllowMutability: true, }) +export const settingsState = atom({ + key: 'settingsData', + default: { ...settingModalFirstOptionsState, ...settingModalSecondOptionsState }, +}) + export const settingModalGridOptionsState = atom({ key: 'settingModalGridOptions', default: [ From 9c226791ae7b5a5f58e3cb0db99b159823872701 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 6 Dec 2024 16:17:07 +0900 Subject: [PATCH 79/98] =?UTF-8?q?=E2=80=BC=EF=B8=8Ffix:=20settings=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - useEffect 두번 실행 되던 문제 해결 --- src/hooks/option/useCanvasSetting.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 238b956d..77ff8bc3 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -48,7 +48,8 @@ export function useCanvasSetting() { const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState) const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState) - const [settingsData, setSettingsData] = useRecoilState(settingsState) + // const [settingsData, setSettingsData] = useRecoilState(settingsState) + const [settingsData, setSettingsData] = useState({ ...settingModalFirstOptions, ...settingModalSecondOptions }) const { option1, option2, dimensionDisplay } = settingModalFirstOptions const { option4 } = settingModalSecondOptions @@ -130,7 +131,9 @@ export function useCanvasSetting() { } }, [canvasSetting]) - useEffect(() => {}, [settingsData]) + useEffect(() => { + console.log('🚀 ~ useEffect ~ settingsData:', settingsData) + }, [settingsData]) //흡착점 ON/OFF 변경 시 // useEffect(() => { From a2bf337b75ffe29fb073729cc9c2d8daf6264d96 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 6 Dec 2024 16:20:56 +0900 Subject: [PATCH 80/98] =?UTF-8?q?=F0=9F=9A=A8fix:=20settingAtom=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/settingAtom.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js index 54944142..9e64d72f 100644 --- a/src/store/settingAtom.js +++ b/src/store/settingAtom.js @@ -77,11 +77,6 @@ export const settingModalSecondOptionsState = atom({ dangerouslyAllowMutability: true, }) -export const settingsState = atom({ - key: 'settingsData', - default: { ...settingModalFirstOptionsState, ...settingModalSecondOptionsState }, -}) - export const settingModalGridOptionsState = atom({ key: 'settingModalGridOptions', default: [ From 97c86e29690b4d66435c2714a4d80b789bfddc16 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 16:53:31 +0900 Subject: [PATCH 81/98] =?UTF-8?q?=EB=AC=BC=EA=B1=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/Stuff.jsx | 7 ++++ src/components/management/StuffDetail.jsx | 24 +++++++++---- .../management/StuffSearchCondition.jsx | 35 +++++++++++++++++-- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 9eb50dca..52b09755 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -261,6 +261,7 @@ export default function Stuff() { fetchData() } else if (stuffSearchParams?.code === 'C') { resetStuffRecoil() + setIsGlobalLoading(false) } else if (stuffSearchParams?.code === 'FINISH') { stuffSearchParams.startRow = 1 stuffSearchParams.endRow = 1 * pageSize @@ -278,6 +279,7 @@ export default function Stuff() { setTotalCount(0) } }) + setIsGlobalLoading(false) } fetchData() } else if (stuffSearchParams?.code === 'DELETE') { @@ -305,6 +307,11 @@ export default function Stuff() { setStuffSearch({ ...newParams, }) + + setIsGlobalLoading(false) + } else { + stuffSearchParams.code = 'DELETE' + setIsGlobalLoading(false) } }, [stuffSearchParams]) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index c1a59b1a..ee6476e4 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -7,7 +7,7 @@ import Select, { components } from 'react-select' import Link from 'next/link' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' -import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty } from '@/util/common-utils' +import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' import { useMessage } from '@/hooks/useMessage' import { useForm } from 'react-hook-form' import { useRecoilValue, useSetRecoilState, useResetRecoilState, useRecoilState } from 'recoil' @@ -1395,11 +1395,14 @@ export default function StuffDetail() { // 물건삭제 const onDelete = () => { const specificationConfirmDate = managementState.specificationConfirmDate + const delParams = { + userId: session.userId, + } if (specificationConfirmDate != null) { alert(getMessage('stuff.detail.delete.message1')) } else { if (confirm(getMessage('common.message.data.delete'))) { - del({ url: `/api/object/${objectNo}` }).then(() => { + del({ url: `/api/object/${objectNo}?${queryStringFormatter(delParams)}` }).then(() => { setFloorPlanObjectNo({ floorPlanObjectNo: '' }) if (session.storeId === 'T01') { stuffSearchParams.code = 'DELETE' @@ -1418,6 +1421,11 @@ export default function StuffDetail() { input.value = input.value.replace(/[^0-9]/g, '') } + const handleBlur = (e) => { + let input = e.target + input.value = input.value.replace(/[^0-9]/g, '') + } + //자동완성 옵션 없을때 메세지 컴포넌트.. const NoOptionsMessage = (props) => { return ( @@ -1805,7 +1813,8 @@ export default function StuffDetail() { @@ -1872,7 +1881,8 @@ export default function StuffDetail() { @@ -2327,7 +2337,8 @@ export default function StuffDetail() { @@ -2399,7 +2410,8 @@ export default function StuffDetail() { diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 8b5f3156..d25f3648 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -83,7 +83,6 @@ export default function StuffSearchCondition() { } setIsGlobalLoading(true) - if (stuffSearch.code === 'S') { if (stuffSearch.pageNo !== 1) { setStuffSearch({ @@ -254,6 +253,7 @@ export default function StuffSearchCondition() { //초기화 const resetRecoil = () => { + setIsGlobalLoading(false) //T01아니면 자동완성 초기화 막기 objectNoRef.current.value = '' saleStoreNameRef.current.value = '' @@ -513,7 +513,6 @@ export default function StuffSearchCondition() { } useEffect(() => { - //X42 if (session?.storeId === 'T01') { if (stuffSearch.code === 'DELETE') { setObjectNo('') @@ -545,6 +544,38 @@ export default function StuffSearchCondition() { stuffSearch.pageNo = 1 stuffSearch.pageSize = 100 + setSchSelSaleStoreId('') + setOtherSaleStoreId('') + } else { + setObjectNo('') + setSaleStoreName('') + setAddress('') + setobjectName('') + setDispCompanyName('') + setReceiveUser('') + objectNoRef.current.value = '' + saleStoreNameRef.current.value = '' + addressRef.current.value = '' + objectNameRef.current.value = '' + dispCompanyNameRef.current.value = '' + receiveUserRef.current.value = '' + stuffSearch.schObjectNo = '' + stuffSearch.schAddress = '' + stuffSearch.schObjectName = '' + stuffSearch.schSaleStoreName = '' + stuffSearch.schReceiveUser = '' + stuffSearch.schDispCompanyName = '' + stuffSearch.schDateType = 'U' + stuffSearch.schFromDt = dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD') + stuffSearch.schToDt = dayjs(new Date()).format('YYYY-MM-DD') + stuffSearch.startRow = 1 + stuffSearch.endRow = 100 + stuffSearch.schSelSaleStoreId = '' + stuffSearch.schOtherSelSaleStoreId = '' + stuffSearch.schSortType = 'R' + stuffSearch.pageNo = 1 + stuffSearch.pageSize = 100 + setSchSelSaleStoreId('') setOtherSaleStoreId('') } From 9c31d63e31fa10e92d23ef94f231092b450e833d Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 17:13:07 +0900 Subject: [PATCH 82/98] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=ED=99=94=EB=A9=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 1 + src/components/management/StuffSearchCondition.jsx | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index ee6476e4..fce17748 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -310,6 +310,7 @@ export default function StuffDetail() { useEffect(() => { if (objectNo) { + setManagementState({}) setEditMode('EDIT') if (objectNo.substring(0, 1) !== 'T') { //벨리데이션 체크용.. diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index d25f3648..111383ed 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -546,7 +546,7 @@ export default function StuffSearchCondition() { setSchSelSaleStoreId('') setOtherSaleStoreId('') - } else { + } else if (stuffSearch.code === 'S') { setObjectNo('') setSaleStoreName('') setAddress('') @@ -575,7 +575,6 @@ export default function StuffSearchCondition() { stuffSearch.schSortType = 'R' stuffSearch.pageNo = 1 stuffSearch.pageSize = 100 - setSchSelSaleStoreId('') setOtherSaleStoreId('') } From d822b390b0de7024f62410f0ead27b8ba599e547 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 6 Dec 2024 17:51:22 +0900 Subject: [PATCH 83/98] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=A3=BC?= =?UTF-8?q?=ED=83=9Dpkg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 7 ++++--- .../floorPlan/estimate/useEstimateController.js | 15 +++++++++++++++ src/locales/ja.json | 1 + src/locales/ko.json | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 88ae05fe..63c35b35 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -822,8 +822,10 @@ export default function Estimate({ params }) { } } }) + // totals.pkgTotPrice = estimateContextState.pkgAspNumber(estimateContextState.pkgAsp.replaceAll(',', '')) * totals.totVolKw * 1000 + let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0 - totals.pkgTotPrice = Number(estimateContextState.pkgAsp.replaceAll(',', '')) * totals.totVolKw * 1000 + totals.pkgTotPrice = pkgAsp * totals.totVolKw * 1000 totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice totals.vatPrice = totals.supplyPrice * 0.1 totals.totPrice = totals.supplyPrice + totals.vatPrice @@ -1057,7 +1059,6 @@ export default function Estimate({ params }) { } //사양시공 let constructSpecificationMulti = estimateContextState?.constructSpecificationMulti?.split('、') - return (
    @@ -1076,7 +1077,7 @@ export default function Estimate({ params }) {
    {getMessage('estimate.detail.remarks')}
    - +