From 7edc6752e4683c8fde6404ef60adc9ae7e6ab706 Mon Sep 17 00:00:00 2001 From: Minsiki Date: Sun, 9 Feb 2025 13:43:07 +0900 Subject: [PATCH 01/27] =?UTF-8?q?-=20=EB=8B=A8=EC=9C=84=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8(Unit=20Test)=20#679=20=EC=88=98=EC=A0=95=20-=20?= =?UTF-8?q?=EB=A7=88=ED=95=A0=EB=8B=B9=20=ED=9A=8C=EB=A1=9C=20=EC=9E=88?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EC=8A=B9=EC=95=95=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=20=EB=AA=BB=EA=B0=80=EA=B2=8C=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 --- .../floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx | 3 --- src/hooks/useCirCuitTrestle.js | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 1e989963..ad929138 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -458,11 +458,8 @@ export default function CircuitTrestleSetting({ id }) { swalFire({ title: getMessage('not.allocation.exist.module'), type: 'alert', - confirmFn: () => {}, }) return - // canvas.remove(...notAllocationModules) - // canvas.renderAll() } setTabNum(2) } diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index 4cae3ab3..fd4cb180 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -61,8 +61,7 @@ export function useCircuitTrestle() { // 사용된 모듈아이템 목록 const getUseModuleItemList = () => { - console.log('🚀 ~ getUseModuleItemList ~ selectedModules:', selectedModules) - return moduleSelectionData.module?.itemList?.map((m) => { + return selectedModules?.itemList?.map((m) => { return { itemId: m.itemId, mixMatlNo: m.mixMatlNo, From 4e162582cc92250cc083642ec1c95d8f01cf393d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 10 Feb 2025 15:13:12 +0900 Subject: [PATCH 02/27] =?UTF-8?q?-=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useContextMenu.js | 4 ++-- src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 184a3aea..f2e73748 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -243,7 +243,7 @@ export function useContextMenu() { name: getMessage('contextmenu.auxiliary.remove.all'), fn: () => { if (!currentObject) { - swalFire({ text: '지붕을 선택해주세요.' }) + swalFire({ text: getMessage('roof.is.not.selected') }) return } const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]?.innerLines @@ -405,7 +405,7 @@ export function useContextMenu() { [ { id: 'sizeEdit', - name: '사이즈 변경', + name: getMessage('contextmenu.size.edit'), component: , }, { diff --git a/src/locales/ja.json b/src/locales/ja.json index ab6d722b..a9ae072d 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1011,5 +1011,6 @@ "batch.object.notinstall.cross": "オブジェクトは重複してインストールできません。", "module.not.batch.north": "북쪽에는 모듈을 배치할 수 없습니다.", "max.select": "최대 {0}개까지 선택할 수 있습니다.(JA)", - "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다.(JA)" + "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다.(JA)", + "roof.is.not.selected": "지붕을 선택해주세요.(JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 887e9cae..dbcae2b4 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1013,5 +1013,6 @@ "module.not.batch.north": "북쪽에는 모듈을 배치할 수 없습니다.", "module.trestleDetail.not.exist": "가대 상세 정보가 없습니다.", "max.select": "최대 {0}개까지 선택할 수 있습니다.", - "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다." + "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다.", + "roof.is.not.selected": "지붕을 선택해주세요." } From 90541851a175883fa6a0768b2cc7602cea715602 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 10 Feb 2025 15:26:30 +0900 Subject: [PATCH 03/27] =?UTF-8?q?bracket=20=EB=82=B4=EC=9A=A9=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/common/common.js | 1 + src/hooks/module/useTrestle.js | 107 +++++++++++++++++++++++++++------ 2 files changed, 89 insertions(+), 19 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index f53210ab..9aad21d6 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -186,6 +186,7 @@ export const SAVE_KEY = [ 'circuitNumber', 'circuit', 'onlyOffset', + 'isChidory', ] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype] diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 20e8b4ac..c7c67d70 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -114,6 +114,8 @@ export const useTrestle = () => { leftExposedHalfTopModules.length > 0 || rightExposedHalfTopPoints.length > 0 + surface.isChidory = isChidory + if (plvrYn === 'N' && isChidory) { alert('치조불가공법입니다.') clear() @@ -132,7 +134,6 @@ export const useTrestle = () => { if (isEaveBar) { // 처마력바설치 true인 경우 설치 exposedBottomModules.forEach((module) => { - //TODO : 방향별로 처마력바 설치해야함 const bottomPoints = findTopTwoPoints([...module.getCurrentPoints()], direction) if (!bottomPoints) return const eaveBar = new fabric.Line([bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y], { @@ -419,7 +420,6 @@ export const useTrestle = () => { const { width, height } = module let { x: startX, y: startY } = { ...module.getCenterPoint() } let { x, y } = { ...module.getCenterPoint() } - //TODO : 방향별로 가대 설치해야함 let leftRows = 1 let hasNextModule = true @@ -506,7 +506,6 @@ export const useTrestle = () => { const { width, height } = module let { x: startX, y: startY } = { ...module.getCenterPoint() } let { x, y } = { ...module.getCenterPoint() } - //TODO : 방향별로 가대 설치해야함 let rightRows = 1 let hasNextModule = true @@ -588,7 +587,7 @@ export const useTrestle = () => { installBracket(surface) } - const quotationParam = getTrestleParams(surface) + const quotationParam = getTrestleParams(surface, exposedBottomModules) surface.set({ quotationParam, isComplete: true }) }) @@ -597,7 +596,7 @@ export const useTrestle = () => { } catch (e) { // 에러 발생시 가대 초기화 console.error(e) - clear() + // clear() setViewCircuitNumberTexts(true) return null } @@ -1353,8 +1352,8 @@ export const useTrestle = () => { leftExposedHalfBottomModules.forEach((module) => { drawBracketWithOutRack(module, rackIntvlPct, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) - if (rackQty === 3 && findSamePointInBottom(exposedBottomModules, module)) { - // 해당 모듈과 같은 위치 맨 아래에 모듈이 있는 경우 하나 더 설치 필요 + if (rackQty === 3 && !findSamePointInBottom(exposedBottomModules, module)) { + // 해당 모듈과 같은 위치 맨 아래에 모듈이 없는 경우 하나 더 설치 필요 drawBracketWithOutRack(module, rackIntvlPct / 3, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) } if (rackQty === 4) { @@ -1364,7 +1363,7 @@ export const useTrestle = () => { rightExposedHalfBottomPoints.forEach((module) => { drawBracketWithOutRack(module, rackIntvlPct, module.rightRows + 1, 'R', surface.direction, moduleIntvlHor, moduleIntvlVer) - if (rackQty === 3 && !findSamePointInBottom(exposedBottomModules, module)) { + if (rackQty === 3 && !findSamePointInBottom(exposedBottomModules, module, direction)) { // 해당 모듈과 같은 위치 맨 아래에 모듈이 없는 경우 하나 더 설치 필요 drawBracketWithOutRack(module, rackIntvlPct / 3, module.rightRows + 1, 'R', surface.direction, moduleIntvlHor, moduleIntvlVer) } @@ -1375,12 +1374,35 @@ export const useTrestle = () => { } // 방향에 따라 가장 아래모듈중 같은 좌표가 있는지 확인 - const findSamePointInBottom = (exposedBottomModules, module) => { + const findSamePointInBottom = (exposedBottomModules, module, direction) => { const { x, y } = module.getCenterPoint() - return exposedBottomModules.find((exposedBottomModule) => { - const { x: exposedX, y: exposedY } = exposedBottomModule.getCenterPoint() - return Math.abs(x - exposedX) < 2 || Math.abs(y - exposedY) < 2 - }) + + switch (direction) { + case 'south': { + return exposedBottomModules.find((exposedBottomModule) => { + const { x: exposedX, y: exposedY } = exposedBottomModule.getCenterPoint() + return Math.abs(x - exposedX) < 2 && Math.abs(y - exposedY) > module.height + }) + } + case 'north': { + return exposedBottomModules.find((exposedBottomModule) => { + const { x: exposedX, y: exposedY } = exposedBottomModule.getCenterPoint() + return Math.abs(x - exposedX) < 2 && Math.abs(y - exposedY) > module.height + }) + } + case 'east': { + return exposedBottomModules.find((exposedBottomModule) => { + const { x: exposedX, y: exposedY } = exposedBottomModule.getCenterPoint() + return Math.abs(y - exposedY) < 2 && Math.abs(x - exposedX) > module.width + }) + } + case 'west': { + return exposedBottomModules.find((exposedBottomModule) => { + const { x: exposedX, y: exposedY } = exposedBottomModule.getCenterPoint() + return Math.abs(y - exposedY) < 2 && Math.abs(x - exposedX) > module.width + }) + } + } } const drawBracketWithOutRack = (module, rackIntvlPct, count, l, direction, moduleIntvlHor, moduleIntvlVer) => { @@ -1844,7 +1866,7 @@ export const useTrestle = () => { } // 견적서 아이템 조회 api parameter 생성 - const getTrestleParams = (surface) => { + const getTrestleParams = (surface, exposedBottomModules) => { const result = calculateForApi(surface) const eaveBar = canvas.getObjects().filter((obj) => obj.surfaceId === surface.id && obj.name === 'eaveBar') @@ -1904,7 +1926,7 @@ export const useTrestle = () => { racks: rackParams, rackTotCnt: rackList.length ?? 0 + smartRackGroup.length ?? 0, rackFittingTotCnt: bracketList.length, - moduleRows: getMostLeftModules(surface), + moduleRows: getMostLeftModules(surface, exposedBottomModules), cvrYn: moduleSelection.construction.setupCover ? 'Y' : 'N', snowGdYn: moduleSelection.construction.setupSnowCover ? 'Y' : 'N', plvrYn: cvrPlvrYn, @@ -1954,8 +1976,8 @@ export const useTrestle = () => { } // 가장 왼쪽에 있는 모듈을 기준으로 같은 단에 있는 모듈들 파라미터 생성 - const getMostLeftModules = (surface) => { - const { direction, modules } = surface + const getMostLeftModules = (surface, exposedBottomModules) => { + const { direction, modules, isChidory } = surface const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId) const roofMaterialIndex = parent.roofMaterial.index const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction @@ -2002,7 +2024,7 @@ export const useTrestle = () => { acc[key].push(module) return acc }, {}) - sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => a[0].left - b[0].left) + sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => b[0].left - a[0].left) } else if (direction === 'west') { const groupedByLeft = modules.reduce((acc, module) => { const key = module.left @@ -2012,8 +2034,9 @@ export const useTrestle = () => { acc[key].push(module) return acc }, {}) - sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => b[0].left - a[0].left) + sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => a[0].left - b[0].left) } + sameLineModuleList.forEach((modules, index) => { const moduleRowResultData = { seq: index, @@ -2063,13 +2086,46 @@ export const useTrestle = () => { } = findSideModule(module, surface) if (bottomModule) { moduleRowResultData.touchedSurfaceCnt++ + if (rackYn === 'N') { + moduleRowResultData.touchedSurfaceBracketCnt += rackQty + } } if (!bottomModule) { if (halfBottomLeftModule && halfBottomRightModule) { moduleRowResultData.touchedSurfaceCnt++ + if (rackYn === 'N') { + moduleRowResultData.touchedSurfaceBracketCnt += rackQty + } } else if ((halfBottomLeftModule && !halfBottomRightModule) || (!halfBottomLeftModule && halfBottomRightModule)) { moduleRowResultData.touchedHalfSurfaceCnt++ moduleRowResultData.exposedHalfBottomCnt++ + + if (rackYn === 'N') { + if (rackQty !== 3) { + // 3개가 아닌경우는 반반 + moduleRowResultData.exposedHalfBottomBracketCnt += rackQty / 2 + moduleRowResultData.touchedHalfSurfaceBracketCnt += rackQty / 2 + } else { + // 3개인 경우 왼쪽 아래가 없는 경우 touched는 2개, exposed는 1개 + if (!halfBottomLeftModule && findSamePointInBottom(exposedBottomModules, module, direction)) { + moduleRowResultData.exposedHalfBottomBracketCnt += 2 + moduleRowResultData.touchedHalfSurfaceBracketCnt += 1 + } else if (!halfBottomLeftModule && !findSamePointInBottom(exposedBottomModules, module, direction)) { + // 왼쪽 아래가 없고, 하단에 같은 점이 없는 경우는 touched는 1개, exposed는 2개 + moduleRowResultData.exposedHalfBottomBracketCnt += 1 + moduleRowResultData.touchedHalfSurfaceBracketCnt += 2 + } else if (!halfBottomRightModule && findSamePointInBottom(exposedBottomModules, module, direction)) { + // 오른쪽 아래가 없고, 하단에 같은 점이 있는 경우는 exposed는 2개, touched는 1개 + moduleRowResultData.exposedHalfBottomBracketCnt += 1 + moduleRowResultData.touchedHalfSurfaceBracketCnt += 2 + } else if (!halfBottomRightModule && !findSamePointInBottom(exposedBottomModules, module, direction)) { + // 오른쪽 아래가 없고, 하단에 같은 점이 없는 경우는 exposed는 1개, touched는 2개 + moduleRowResultData.exposedHalfBottomBracketCnt += 2 + moduleRowResultData.touchedHalfSurfaceBracketCnt += 1 + } + } + } + if (cvrPlvrYn === 'Y') { moduleRowResultData.eavesHalfCnt++ if (bottomLeftModule || bottomRightModule || halfBottomLeftModule || halfBottomRightModule) { @@ -2079,6 +2135,9 @@ export const useTrestle = () => { } } else { moduleRowResultData.exposedBottomCnt++ + if (rackYn === 'N') { + moduleRowResultData.exposedBottomBracketCnt += rackQty + } if (isEaveBar) { moduleRowResultData.eavesCnt++ if ((rightModule && !leftModule) || (!rightModule && leftModule)) { @@ -2091,8 +2150,16 @@ export const useTrestle = () => { if (!topModule) { if ((halfTopLeftModule && !halfTopRightModule) || (!halfTopLeftModule && halfTopRightModule)) { moduleRowResultData.exposedHalfTopCnt++ + if (rackYn === 'N') { + if (rackQty !== 3) { + moduleRowResultData.exposedHalfTopBracketCnt += rackQty / 2 + } + } } else if (!halfTopLeftModule && !halfTopRightModule) { moduleRowResultData.exposedTopCnt++ + if (rackYn === 'N') { + moduleRowResultData.exposedTopBracketCnt += rackQty + } } } }) @@ -2100,6 +2167,8 @@ export const useTrestle = () => { result.push(moduleRowResultData) }) + canvas.renderAll() + return result } From bda9b7bd6d72f7366deb8db07d55bd2511917264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:15:27 +0900 Subject: [PATCH 04/27] =?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/_grid-detail.scss | 4 +++- src/styles/_modal.scss | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/styles/_grid-detail.scss b/src/styles/_grid-detail.scss index affe56fd..b0c88984 100644 --- a/src/styles/_grid-detail.scss +++ b/src/styles/_grid-detail.scss @@ -134,11 +134,12 @@ display: flex; flex-direction: column; gap: 5px; - width: 117px; + max-width: 100%; margin: 0 auto; .grid-btn{ display: block; width: 100%; + padding: 0 10px; height: 30px; display: flex; align-items: center; @@ -150,6 +151,7 @@ color: #94A0AD; font-weight: 400; text-align: center; + word-break: break-all; span{ display: block; margin-right: 5px; diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index 7c959e83..bbdf38f8 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -2033,7 +2033,7 @@ $alert-color: #101010; width: 95.77px; } .thin{ - margin-left: auto; + margin-left: 0; } } } From 83f0e54dc5cbfe7a411c6f517870ebf9f674a573 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 10 Feb 2025 16:21:18 +0900 Subject: [PATCH 05/27] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EB=93=9C=20=EC=85=80=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EB=93=9C=EB=9E=98=EA=B7=B8=20=EB=B3=B5=EC=82=AC=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80=20&?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/Stuff.jsx | 11 ++++++++++- src/components/management/StuffSearchCondition.jsx | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 51154e92..ee0a1930 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -241,6 +241,10 @@ export default function Stuff() { params.saleStoreId = session.storeId } + if (params.saleStoreId !== session.storeId) { + params.saleStoreId = session.storeId + } + async function fetchData() { const apiUrl = `/api/object/list?${queryStringFormatter(params)}` await get({ @@ -296,6 +300,11 @@ export default function Stuff() { if (!stuffSearchParams.saleStoreId) { stuffSearchParams.saleStoreId = session.storeId } + + if (stuffSearchParams.saleStoreId !== session.storeId) { + stuffSearchParams.saleStoreId = session.storeId + } + if (stuffSearchParams.schMyDataCheck) { //0203 내물건보기 체크시 schSaleStoreId에 storeId셋팅 schSelSaleStoreId, schOtherSelSaleStoreId 비우기 stuffSearchParams.schSaleStoreId = session.storeId @@ -358,7 +367,7 @@ export default function Stuff() { fetchData() } else if (stuffSearchParams?.code === 'DELETE') { const newParams = { - saleStoreId: session.storeId, + saleStoreId: '', schObjectNo: '', schAddress: '', schObjectName: '', diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index c5862641..d259e573 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -188,7 +188,7 @@ export default function StuffSearchCondition() { schAddress: address ? address.trim() : '', schObjectName: objectName ? objectName.trim() : '', schDispCompanyName: dispCompanyName ? dispCompanyName.trim() : '', - schSelSaleStoreId: schSelSaleStoreId ? schSelSaleStoreId : stuffSearch.schSelSaleStoreId, + schSelSaleStoreId: stuffSearch?.schSelSaleStoreId ? stuffSearch.schSelSaleStoreId : '', schOtherSelSaleStoreId: otherSaleStoreId ? otherSaleStoreId : stuffSearch.schOtherSelSaleStoreId, schReceiveUser: receiveUser ? receiveUser.trim() : '', schDateType: dateType, @@ -673,11 +673,11 @@ export default function StuffSearchCondition() { } } else { //X누르면 검색조건에 1차점으로 셋팅 - if (session.storeLvl === '1') { if (stuffSearch.schOtherSelSaleStoreId === '') { // 화면에선 지우는데 조회누르기 전이면 리코일은 남김 setSchSelSaleStoreId(session.storeId) + setOtherSaleStoreId('') } else { // 화면에선 지우는데 조회누르기 전이면 리코일은 남김 setOtherSaleStoreId('') From f0e13bd233f3e398fa49cd4f22e8a5b4e0ce272b Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Mon, 10 Feb 2025 16:56:50 +0900 Subject: [PATCH 06/27] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=A7=80=EB=B6=95=EC=9E=AC=20select=20=ED=95=9C/?= =?UTF-8?q?=EC=9D=BC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/CircuitTrestleSetting.jsx | 1 + .../ContextRoofAllocationSetting.jsx | 16 ++++++++++++---- .../roofAllocation/RoofAllocationSetting.jsx | 14 ++++++++++---- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index d0cee8ba..f1362fca 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -364,6 +364,7 @@ export default function CircuitTrestleSetting({ id }) { if (allocationType === ALLOCATION_TYPE.PASSIVITY) { setAllocationType(ALLOCATION_TYPE.AUTO) + setTabNum(1) } else { setTabNum(1) } diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx index 2374c582..a4cfa8dd 100644 --- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx @@ -10,6 +10,7 @@ import { basicSettingState } from '@/store/settingAtom' import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useCommonCode } from '@/hooks/common/useCommonCode' +import { globalLocaleStore } from '@/store/localeAtom' import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' export default function ContextRoofAllocationSetting(props) { @@ -36,6 +37,7 @@ export default function ContextRoofAllocationSetting(props) { const { findCommonCode } = useCommonCode() const pitchText = useRecoilValue(pitchTextSelector) + const globalLocale = useRecoilValue(globalLocaleStore) const currentAngleType = useRecoilValue(currentAngleTypeSelector) const [raftCodes, setRaftCodes] = useState([]) useEffect(() => { @@ -60,13 +62,15 @@ export default function ContextRoofAllocationSetting(props) { {getMessage('modal.roof.alloc.select.roof.material')}
{ + return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } + })} value={roofMaterials[0]} onChange={(e) => { // const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id) setCurrentRoofMaterial(e) }} - showKey={'roofMatlNm'} + showKey="name" sourceKey={'roofMatlCd'} targetKey={'roofMatlCd'} /> @@ -100,9 +104,13 @@ export default function ContextRoofAllocationSetting(props) {
{ + return { ...roof2, name: globalLocale === 'ko' ? roof2.roofMatlNm : roof2.roofMatlNmJp } + })} value={roof} - showKey={'roofMatlNm'} + //showKey={'roofMatlNm'} + showKey="name" sourceKey={'roofMatlCd'} targetKey={'roofMatlCd'} onChange={(e) => handleChangeRoofMaterial(e, index)} diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx index acd2291c..9ceeb9e0 100644 --- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -62,13 +62,15 @@ export default function RoofAllocationSetting(props) { {getMessage('modal.roof.alloc.select.roof.material')}
{ + return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } + })} value={roofMaterials[0]} onChange={(e) => { // const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id) setCurrentRoofMaterial(e) }} - showKey={'roofMatlNm'} + showKey="name" sourceKey={'roofMatlCd'} targetKey={'roofMatlCd'} /> @@ -102,9 +104,13 @@ export default function RoofAllocationSetting(props) {
{ + return { ...roof2, name: globalLocale === 'ko' ? roof2.roofMatlNm : roof2.roofMatlNmJp } + })} value={roof} - showKey={'roofMatlNm'} + //showKey={'roofMatlNm'} + showKey="name" sourceKey={'roofMatlCd'} targetKey={'roofMatlCd'} onChange={(e) => handleChangeRoofMaterial(e, index)} From 66b95b565c3d271a2212254ff21dd9d3657aa180 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 10 Feb 2025 17:03:43 +0900 Subject: [PATCH 07/27] =?UTF-8?q?=EC=A7=80=EC=A7=80=EA=B8=88=EA=B5=AC=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EC=9C=84=EC=B9=98=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index c7c67d70..ff13e305 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1171,7 +1171,7 @@ export const useTrestle = () => { seq, smartRackId, rackId: itemId, - direction: 'right', + direction: 'bottom', }) canvas.add(rack) canvas.renderAll() @@ -1231,16 +1231,17 @@ export const useTrestle = () => { canvas.renderAll() racks.forEach((rack) => { - const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen, name } = rack + let { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen, name } = rack const bracketLength = 10 if (direction === 'top') { const result = getBracketPoints(supFitQty, supFitIntvlPct) result.forEach((percent) => { + const len = name === 'smartRack' ? y2 - (y2 - y1) * percent - bracketLength / 2 : y2 - (y2 - y1) * percent - bracketLength / 2 const bracket = new fabric.Rect({ left: x2 - bracketLength / 3, - top: name === 'smartRack' ? y2 + rackLen * percent : y2 + (rackLen / 10) * percent, + top: len, fill: 'green', name: 'bracket', parentId: rack.parentId, @@ -1258,8 +1259,10 @@ export const useTrestle = () => { const result = getBracketPoints(supFitQty, supFitIntvlPct) result.forEach((percent) => { + const len = + name === 'smartRack' ? x1 - Math.abs(x2 - x1) * percent - bracketLength / 2 : x1 - Math.abs(x2 - x1) * percent - bracketLength / 2 const bracket = new fabric.Rect({ - left: name === 'smartRack' ? x2 + rackLen * percent : x2 + (rackLen / 10) * percent, + left: len, top: y2 - bracketLength / 3, fill: 'green', name: 'bracket', @@ -1278,8 +1281,10 @@ export const useTrestle = () => { const result = getBracketPoints(supFitQty, supFitIntvlPct) result.forEach((percent) => { + const len = + name === 'smartRack' ? x2 - Math.abs(x2 - x1) * percent - bracketLength / 2 : x2 - Math.abs(x2 - x1) * percent - bracketLength / 2 const bracket = new fabric.Rect({ - left: name === 'smartRack' ? x2 - rackLen * percent : x2 - (rackLen / 10) * percent, + left: len, top: y2 - bracketLength / 3, fill: 'green', parentId: rack.parentId, @@ -1298,9 +1303,10 @@ export const useTrestle = () => { const result = getBracketPoints(supFitQty, supFitIntvlPct) result.forEach((percent) => { + const len = name === 'smartRack' ? y2 - (y2 - y1) * percent - bracketLength / 2 : y2 - (y2 - y1) * percent - bracketLength / 2 const bracket = new fabric.Rect({ left: x2 - bracketLength / 3, - top: name === 'smartRack' ? y2 - rackLen * percent : y2 - (rackLen / 10) * percent, + top: len, fill: 'green', name: 'bracket', parentId: rack.parentId, From c81d4a87513d6ab54ce73464e4192f919b339f8b Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Mon, 10 Feb 2025 17:21:08 +0900 Subject: [PATCH 08/27] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=ED=95=A0=EB=8B=B9=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EC=8B=9C=20result=3Dnull=EC=9D=B8=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EC=97=90=EB=8F=84=20=ED=9A=8C=EB=A1=9C?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EC=9C=A0=EC=A7=80=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index f1362fca..5107d585 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -335,9 +335,13 @@ export default function CircuitTrestleSetting({ id }) { handleCanvasToPng(1) + //회로할당 저장 클릭 시 const result = await apply() + + //회로할당 저장 시 result=null인 경우에도 회로번호 텍스트 표시 유지 처리 + setViewCircuitNumberTexts(true) + if (result) { - setViewCircuitNumberTexts(true) handleCanvasToPng(2) // 캔버스 저장 await saveCanvas(false) From 0597a10af2f44cd53802f3f4a74916d8d62c5305 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 11 Feb 2025 09:52:19 +0900 Subject: [PATCH 09/27] =?UTF-8?q?=F0=9F=93=8Cfix:=20Add=20render=20key=20p?= =?UTF-8?q?rops?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/step/PowerConditionalSelect.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx index 5ab5b70c..5957103c 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx @@ -229,8 +229,8 @@ export default function PowerConditionalSelect(props) { {models?.map((model, index) => ( setSelectedRow(model)} className={model === selectedRow ? 'on' : ''}> - {modelHeader.map((header) => ( - {model[header.prop]} + {modelHeader.map((header, index) => ( + {model[header.prop]} ))} ))} From c253cfe07ec43c10d9b4967779efa0013dcde50c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 11 Feb 2025 10:02:33 +0900 Subject: [PATCH 10/27] =?UTF-8?q?=EC=BA=94=EB=B2=84=EC=8A=A4=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=A1=9C=EB=93=9C=EC=8B=9C=20module=20dat?= =?UTF-8?q?a=20=EC=A0=80=EC=9E=A5=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/useCanvasPopupStatusController.js | 7 +++++-- src/hooks/useCirCuitTrestle.js | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hooks/common/useCanvasPopupStatusController.js b/src/hooks/common/useCanvasPopupStatusController.js index 4757fbc0..d7845362 100644 --- a/src/hooks/common/useCanvasPopupStatusController.js +++ b/src/hooks/common/useCanvasPopupStatusController.js @@ -5,16 +5,18 @@ import useSWR from 'swr' import useSWRMutation from 'swr/mutation' import { useAxios } from '../useAxios' import { unescapeString } from '@/util/common-utils' -import { moduleSelectionDataState, moduleSelectionTotalState } from '@/store/selectedModuleOptions' +import { moduleSelectionDataState, moduleSelectionTotalState, selectedModuleOptionsState, selectedModuleState } from '@/store/selectedModuleOptions' import { compasDegAtom } from '@/store/orientationAtom' import { canvasState, currentCanvasPlanState } from '@/store/canvasAtom' import { POLYGON_TYPE } from '@/common/common' +import { DateRangePickerField } from '@nextui-org/react' export function useCanvasPopupStatusController(param = 1) { const popupType = parseInt(param) const [compasDeg, setCompasDeg] = useRecoilState(compasDegAtom) const [moduleSelectionDataStore, setModuleSelectionDataStore] = useRecoilState(moduleSelectionDataState) + const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) const { get, getFetcher, postFetcher } = useAxios() const canvas = useRecoilValue(canvasState) const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) @@ -50,12 +52,13 @@ export function useCanvasPopupStatusController(param = 1) { for (let i = 1; i < 3; i++) { const result = await getModuleSelection(i) // setModuleSelectionTotal((prev) => ({ ...prev, [i]: JSON.parse(unescapeString(result.popupStatus)) })) - if(!result) return + if (!result) return if (i === 1) { setCompasDeg(result.popupStatus) } else if (i === 2) { const data = JSON.parse(unescapeString(result.popupStatus)) setModuleSelectionDataStore(data) + if (data.module) setSelectedModules(data.module) const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index fd4cb180..8e4b9ade 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -61,6 +61,7 @@ export function useCircuitTrestle() { // 사용된 모듈아이템 목록 const getUseModuleItemList = () => { + console.log('🚀 ~ getUseModuleItemList ~ selectedModules:', selectedModules) return selectedModules?.itemList?.map((m) => { return { itemId: m.itemId, From 62b86764d5952c7cc1106f664abbc1291d253a76 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 11 Feb 2025 10:27:02 +0900 Subject: [PATCH 11/27] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20swalFire=20?= =?UTF-8?q?icon=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffQGrid.jsx | 1 + .../estimate/useEstimateController.js | 23 ++++++++++--------- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/components/management/StuffQGrid.jsx b/src/components/management/StuffQGrid.jsx index 6de31379..0f589447 100644 --- a/src/components/management/StuffQGrid.jsx +++ b/src/components/management/StuffQGrid.jsx @@ -97,6 +97,7 @@ export default function StuffQGrid(props) { overlayNoRowsTemplate={`${getMessage('stuff.grid.noData')}`} getRowClass={getRowClass} autoSizeAllColumns={true} + enableCellTextSelection={true} />
) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index c87e77de..fbcea158 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -168,19 +168,19 @@ export const useEstimateController = (planNo) => { if (estimateData?.charger === null || estimateData?.charger?.trim().length === 0) { flag = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredCharger'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredCharger'), type: 'alert', icon: 'warning' }) } if (estimateData?.objectName === null || estimateData?.objectName?.trim().length === 0) { flag = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredObjectName'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredObjectName'), type: 'alert', icon: 'warning' }) } if (isNaN(Date.parse(estimateData.estimateDate))) { flag = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateDate'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateDate'), type: 'alert', icon: 'warning' }) } if (estimateData.estimateType === 'YJSS') { @@ -188,7 +188,7 @@ export const useEstimateController = (planNo) => { if (pkgAsp === '0') { flag = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredPkgAsp'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredPkgAsp'), type: 'alert', icon: 'warning' }) } } @@ -214,7 +214,7 @@ export const useEstimateController = (planNo) => { if (estimateData?.northArrangement === '1') { fileFlg = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert', icon: 'warning' }) } } @@ -226,7 +226,7 @@ export const useEstimateController = (planNo) => { if (estimateData.fileFlg === '0') { fileFlg = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredFileUpload'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredFileUpload'), type: 'alert', icon: 'warning' }) } } } @@ -244,7 +244,7 @@ export const useEstimateController = (planNo) => { if (item.itemId === '') { itemFlg = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredItemId'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredItemId'), type: 'alert', icon: 'warning' }) } } @@ -260,7 +260,7 @@ export const useEstimateController = (planNo) => { if (item.amount < 1) { itemFlg = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredAmount'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredAmount'), type: 'alert', icon: 'warning' }) } if (estimateData.estimateType !== 'YJSS') { @@ -272,7 +272,7 @@ export const useEstimateController = (planNo) => { if (item.salePrice < 1) { itemFlg = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert', icon: 'warning' }) } } @@ -283,7 +283,7 @@ export const useEstimateController = (planNo) => { if (isNaN(item.salePrice)) { itemFlg = false setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert', icon: 'warning' }) } } } @@ -301,7 +301,7 @@ export const useEstimateController = (planNo) => { }) if (delCnt === estimateData.itemList.length) { setIsGlobalLoading(false) - return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert' }) + return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert', icon: 'warning' }) } } @@ -387,6 +387,7 @@ export const useEstimateController = (planNo) => { estimateData.pkgAsp = estimateData.pkgAsp.replaceAll(',', '') } + return //2. 상세데이터 저장 try { setIsGlobalLoading(true) diff --git a/src/locales/ja.json b/src/locales/ja.json index 441cb9d7..817c6f6e 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -905,7 +905,7 @@ "estimate.detail.header.showPrice": "価格表示", "estimate.detail.header.unitPrice": "定価", "estimate.detail.showPrice.pricingBtn": "Pricing", - "estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります。 Pricingを進めてください。", + "estimate.detail.showPrice.pricingBtn.noItemId": "Pricingが欠落しているアイテムがあります. 製品を選択してPricingを進めてください.", "estimate.detail.showPrice.description1": "製品価格OPEN", "estimate.detail.showPrice.description2": "追加の変更品目", "estimate.detail.showPrice.description3": "添付必須", diff --git a/src/locales/ko.json b/src/locales/ko.json index d044217c..35f7e55f 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -906,7 +906,7 @@ "estimate.detail.header.showPrice": "가격표시", "estimate.detail.header.unitPrice": "정가", "estimate.detail.showPrice.pricingBtn": "Pricing", - "estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. Pricing을 진행해주세요.", + "estimate.detail.showPrice.pricingBtn.noItemId": "Pricing이 누락된 아이템이 있습니다. 제품 선택 후 Pricing을 진행해주세요.", "estimate.detail.showPrice.description1": "제품 가격 OPEN", "estimate.detail.showPrice.description2": "추가 변경 자재", "estimate.detail.showPrice.description3": "첨부필수", From 18b9cafbce9ac7ad843979cbdd9ff02aa2946344 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 11 Feb 2025 10:46:48 +0900 Subject: [PATCH 12/27] =?UTF-8?q?=F0=9F=93=8Cfix:=20=EA=B2=AC=EC=A0=81?= =?UTF-8?q?=EC=84=9C=20=EC=83=9D=EC=84=B1=20=ED=98=B8=EC=B6=9C=EC=8B=9C=20?= =?UTF-8?q?=EB=A1=9C=EB=94=A9=EB=B0=94=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.js | 4 +- .../circuitTrestle/CircuitTrestleSetting.jsx | 4 + src/hooks/floorPlan/useImgLoader.js | 83 ++++++++++--------- src/hooks/module/useTrestle.js | 1 + src/hooks/useEstimate.js | 1 + 5 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/app/layout.js b/src/app/layout.js index 8c78f6c7..8071159a 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -72,10 +72,10 @@ export default async function RootLayout({ children }) {
+ + )} - - diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 5107d585..be4653c0 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -24,6 +24,7 @@ import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { useImgLoader } from '@/hooks/floorPlan/useImgLoader' import { usePlan } from '@/hooks/usePlan' +import { QcastContext } from '@/app/QcastProvider' const ALLOCATION_TYPE = { AUTO: 'auto', @@ -56,6 +57,8 @@ export default function CircuitTrestleSetting({ id }) { const { handleCanvasToPng } = useImgLoader() const { saveCanvas } = usePlan() + const { setIsGlobalLoading } = useContext(QcastContext) + const { makers, setMakers, @@ -324,6 +327,7 @@ export default function CircuitTrestleSetting({ id }) { // 회로할당(승압설정) 저장 버튼 클릭 시 const onApply = async () => { + setIsGlobalLoading(true) canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) diff --git a/src/hooks/floorPlan/useImgLoader.js b/src/hooks/floorPlan/useImgLoader.js index 9b23d36d..4be21e67 100644 --- a/src/hooks/floorPlan/useImgLoader.js +++ b/src/hooks/floorPlan/useImgLoader.js @@ -4,6 +4,8 @@ import { useCanvas } from '../useCanvas' import { useAxios } from '../useAxios' import { usePlan } from '../usePlan' import { POLYGON_TYPE } from '@/common/common' +import { QcastContext } from '@/app/QcastProvider' +import { useContext } from 'react' /** * 이미지 로더 hook @@ -13,7 +15,7 @@ export function useImgLoader() { const canvas = useRecoilValue(canvasState) const { currentCanvasPlan } = usePlan() const { post } = useAxios() - + const { setIsGlobalLoading } = useContext(QcastContext) /** * 이미지 저장 시 왼쪽 위, 오른쪽 아래 좌표 * return [start, end] @@ -39,48 +41,53 @@ export function useImgLoader() { * @param {integer} type 1: 모듈만 있는 상태, 2: 가대까지 올린 상태 */ const handleCanvasToPng = async (type) => { - removeMouseLines() + try { + removeMouseLines() - canvas.getObjects('image').forEach((obj) => { - if (obj.getSrc) { - const img = new Image() - img.crossOrigin = 'anonymous' - img.src = obj.getSrc() - obj.setElement(img) + canvas.getObjects('image').forEach((obj) => { + if (obj.getSrc) { + const img = new Image() + img.crossOrigin = 'anonymous' + img.src = obj.getSrc() + obj.setElement(img) + } + }) + + canvas.renderAll() + + const formData = new FormData() + const dataUrl = canvas.toDataURL('image/png') + const blobBin = atob(dataUrl.split(',')[1]) + const array = [] + for (let i = 0; i < blobBin.length; i++) { + array.push(blobBin.charCodeAt(i)) } - }) + const file = new Blob([new Uint8Array(array)], { type: 'image/png' }) + formData.append('file', file, 'canvas.png') + formData.append('objectNo', currentCanvasPlan.objectNo) + formData.append('planNo', currentCanvasPlan.planNo) + formData.append('type', type) + // formData.append('coordinates', getImageCoordinates()) + const positionObj = getImageCoordinates() + console.log('🚀 ~ handleCanvasToPng ~ positionObj:', positionObj) + formData.append('width', Math.round(positionObj[1].x - positionObj[0].x - 350)) + formData.append('height', Math.round(positionObj[1].y - positionObj[0].y - 100)) + formData.append('left', Math.round(positionObj[0].x)) + formData.append('top', Math.round(positionObj[0].y)) + console.log('🚀 ~ handleCanvasToPng ~ formData:', formData) - canvas.renderAll() + // 이미지 크롭 요청 + const result = await post({ + url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`, + data: formData, + }) + console.log('🚀 ~ handleCanvasToPng ~ result:', result) - const formData = new FormData() - const dataUrl = canvas.toDataURL('image/png') - const blobBin = atob(dataUrl.split(',')[1]) - const array = [] - for (let i = 0; i < blobBin.length; i++) { - array.push(blobBin.charCodeAt(i)) + return result + } catch (e) { + setIsGlobalLoading(false) + console.log('🚀 ~ handleCanvasToPng ~ e:', e) } - const file = new Blob([new Uint8Array(array)], { type: 'image/png' }) - formData.append('file', file, 'canvas.png') - formData.append('objectNo', currentCanvasPlan.objectNo) - formData.append('planNo', currentCanvasPlan.planNo) - formData.append('type', type) - // formData.append('coordinates', getImageCoordinates()) - const positionObj = getImageCoordinates() - console.log('🚀 ~ handleCanvasToPng ~ positionObj:', positionObj) - formData.append('width', Math.round(positionObj[1].x - positionObj[0].x - 350)) - formData.append('height', Math.round(positionObj[1].y - positionObj[0].y - 100)) - formData.append('left', Math.round(positionObj[0].x)) - formData.append('top', Math.round(positionObj[0].y)) - console.log('🚀 ~ handleCanvasToPng ~ formData:', formData) - - // 이미지 크롭 요청 - const result = await post({ - url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`, - data: formData, - }) - console.log('🚀 ~ handleCanvasToPng ~ result:', result) - - return result } /** diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index ff13e305..213bd62d 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -598,6 +598,7 @@ export const useTrestle = () => { console.error(e) // clear() setViewCircuitNumberTexts(true) + setIsGlobalLoading(false) return null } } diff --git a/src/hooks/useEstimate.js b/src/hooks/useEstimate.js index 7abe27b1..5192ec0c 100644 --- a/src/hooks/useEstimate.js +++ b/src/hooks/useEstimate.js @@ -60,6 +60,7 @@ export function useEstimate() { moveEstimate(planNo, objectNo) }) .catch((error) => { + setIsGlobalLoading(false) swalFire({ text: error.message, icon: 'error' }) }) } From dd95c36b0846d71933cf1db10595a1d6479d8af3 Mon Sep 17 00:00:00 2001 From: Daseul Kim Date: Tue, 11 Feb 2025 10:53:18 +0900 Subject: [PATCH 13/27] =?UTF-8?q?fix:=20plan=20=EB=A7=B5=ED=95=91=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePlan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 9db69642..7d9bc925 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -425,7 +425,7 @@ export function usePlan(params = {}) { await getCanvasByObjectNo(objectNo, planNo).then((res) => { if (res.length > 0) { setCurrentCanvasPlan((prev) => ({ ...prev, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus })) - setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((plan) => plan.planNo === planNo).canvasStatus }))) + setPlans((plans) => plans.map((plan) => ({ ...plan, canvasStatus: res.find((resPlan) => resPlan.planNo === plan.planNo).canvasStatus }))) } }) } From 22d340991467c48096b04d3ce8feadc87c291443 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 11 Feb 2025 12:33:32 +0900 Subject: [PATCH 14/27] =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 817c6f6e..dee68fff 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -765,7 +765,7 @@ "stuff.search.grid.all": "全体", "stuff.search.grid.selected": "選択", "stuff.search.grid.schSortTypeR": "最近の登録日", - "stuff.search.grid.schSortTypeU": "最近の修正日", + "stuff.search.grid.schSortTypeU": "最近の更新日", "stuff.windSelectPopup.title": "風速選択", "stuff.windSelectPopup.table.selected": "選択", "stuff.windSelectPopup.table.windspeed": "風速", diff --git a/src/locales/ko.json b/src/locales/ko.json index 35f7e55f..7315ce2c 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -765,7 +765,7 @@ "stuff.search.grid.all": "전체", "stuff.search.grid.selected": "선택", "stuff.search.grid.schSortTypeR": "최근 등록일", - "stuff.search.grid.schSortTypeU": "최근 수정일", + "stuff.search.grid.schSortTypeU": "최근 갱신일", "stuff.windSelectPopup.title": "풍속선택", "stuff.windSelectPopup.table.selected": "선택", "stuff.windSelectPopup.table.windspeed": "풍속", From 54b69b13779ee7ec14db5eaffccb95f6b7f71c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 11 Feb 2025 13:08:53 +0900 Subject: [PATCH 15/27] =?UTF-8?q?-=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B3=B4=EC=A1=B0=EC=84=A0=20?= =?UTF-8?q?validation=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/auxiliary/AuxiliaryEdit.jsx | 23 ++++++++++++++----- .../floor-plan/modal/grid/GridMove.jsx | 4 ++-- src/hooks/useContextMenu.js | 6 +---- src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx index e0f3522b..1da94050 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx @@ -21,23 +21,34 @@ export default function AuxiliaryEdit(props) { const currentObject = useRecoilValue(currentObjectState) const { swalFire } = useSwal() const handleSave = () => { - if (!horizonSize || !verticalSize || !arrow1 || !arrow2) { - swalFire({ title: '길이와 방향을 입력하세요.', type: 'alert' }) + if ((!arrow1 && !arrow2) || (+verticalSize === 0 && +horizonSize === 0)) { + swalFire({ title: getMessage('length.direction.is.required'), type: 'alert' }) return } + + if ((verticalSize && +verticalSize === 0) || !arrow1) { + swalFire({ title: getMessage('length.direction.is.required'), type: 'alert' }) + return + } + + if ((horizonSize && +horizonSize === 0) || !arrow2) { + swalFire({ title: getMessage('length.direction.is.required'), type: 'alert' }) + return + } + if (type === 'copy') { if (currentObject) { copy( currentObject, - arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize), - arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize), + arrow2 ? (arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize)) : 0, + arrow1 ? (arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize)) : 0, ) } } else { move( currentObject, - arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize), - arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize), + arrow2 ? (arrow2 === '←' ? Number(horizonSize) * -1 : Number(horizonSize)) : 0, + arrow1 ? (arrow1 === '↑' ? Number(verticalSize) * -1 : Number(verticalSize)) : 0, ) } diff --git a/src/components/floor-plan/modal/grid/GridMove.jsx b/src/components/floor-plan/modal/grid/GridMove.jsx index e28d8564..1713647b 100644 --- a/src/components/floor-plan/modal/grid/GridMove.jsx +++ b/src/components/floor-plan/modal/grid/GridMove.jsx @@ -38,12 +38,12 @@ export default function GridMove(props) { const handleApply = () => { if (currentObject?.direction === 'vertical') { if (!horizonSize || !arrow2) { - swalFire({ title: '길이와 방향을 입력하세요.', type: 'alert' }) + swalFire({ title: getMessage('length.direction.is.required'), type: 'alert' }) return } } else { if (!verticalSize || !arrow1) { - swalFire({ title: '길이와 방향을 입력하세요.', type: 'alert' }) + swalFire({ title: getMessage('length.direction.is.required'), type: 'alert' }) } } diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 577d5b2e..e5006927 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -130,11 +130,7 @@ export function useContextMenu() { name: getMessage('contextmenu.roof.material.placement'), component: , }, - { - id: 'roofMaterialRemove', - name: getMessage('contextmenu.roof.material.remove'), - fn: () => removeRoofMaterial(), - }, + { id: 'roofMaterialRemoveAll', name: getMessage('contextmenu.roof.material.remove.all'), diff --git a/src/locales/ja.json b/src/locales/ja.json index 441cb9d7..c8246a5a 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1014,5 +1014,6 @@ "max.select": "최대 {0}개까지 선택할 수 있습니다.(JA)", "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다.(JA)", "roof.is.not.selected": "지붕을 선택해주세요.(JA)", - "module.delete.confirm": "パネルを削除して面入力に戻ります。正しいですか?\nはい]を選択すると削除し、面入力に戻ります。\nいいえ」を選択すると、削除せずに現在の状態を維持します。" + "module.delete.confirm": "パネルを削除して面入力に戻ります。正しいですか?\nはい]を選択すると削除し、面入力に戻ります。\nいいえ」を選択すると、削除せずに現在の状態を維持します。", + "length.direction.is.required": "길이와 방향을 입력하세요.(JA)" } diff --git a/src/locales/ko.json b/src/locales/ko.json index d044217c..518f96b9 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1015,5 +1015,6 @@ "max.select": "최대 {0}개까지 선택할 수 있습니다.", "module.delete.confirm": "패널을 삭제하고 면입력으로 돌아갑니다. 맞습니까?\n[예]를 선택하면 삭제하고, 면 입력으로 돌아갑니다.\n[아니오]를 선택하면 삭제하지 않고 현재 상태를 유지합니다.", "not.allocation.exist.module": "할당하지 않은 모듈이 있습니다.", - "roof.is.not.selected": "지붕을 선택해주세요." + "roof.is.not.selected": "지붕을 선택해주세요.", + "length.direction.is.required": "길이와 방향을 입력하세요." } From 4e1b7cc0100104c61c81195300c24c4e58f1feac Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 11 Feb 2025 13:09:47 +0900 Subject: [PATCH 16/27] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20item=20?= =?UTF-8?q?=EB=A9=80=ED=8B=B0=EB=AA=A8=EB=93=88=20=EB=8C=80=EC=9D=91=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 630 +++++++++++++++++++++++++-------- 1 file changed, 488 insertions(+), 142 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index ff13e305..f2fe4117 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -359,8 +359,8 @@ export const useTrestle = () => { return ( rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - rack.value.moduleTpRows1 === leftRowsInfo.rowsInfo[0].count && - rack.value.moduleTpRows2 === leftRowsInfo.rowsInfo[1].count + Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count ) } })?.value.racks @@ -376,8 +376,8 @@ export const useTrestle = () => { return ( rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - rack.value.moduleTpRows1 === rightRowsInfo.rowsInfo[0].count && - rack.value.moduleTpRows2 === rightRowsInfo.rowsInfo[1].count + Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count ) } })?.value.racks @@ -393,8 +393,8 @@ export const useTrestle = () => { return ( rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp && rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - rack.value.moduleTpRows1 === centerRowsInfo.rowsInfo[0].count && - rack.value.moduleTpRows2 === centerRowsInfo.rowsInfo[1].count + Number(rack.value.moduleTpRows1) === centerRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === centerRowsInfo.rowsInfo[1].count ) } })?.value.racks @@ -488,8 +488,8 @@ export const useTrestle = () => { return ( rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp && rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - rack.value.moduleTpRows1 === leftRowsInfo.rowsInfo[0].count && - rack.value.moduleTpRows2 === leftRowsInfo.rowsInfo[1].count + Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count ) } })?.value.racks @@ -564,8 +564,8 @@ export const useTrestle = () => { return ( rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp && rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) && - rack.value.moduleTpRows1 === rightRowsInfo.rowsInfo[0].count && - rack.value.moduleTpRows2 === rightRowsInfo.rowsInfo[1].count + Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count && + Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count ) } })?.value.racks @@ -743,19 +743,32 @@ export const useTrestle = () => { let result switch (direction) { case 'south': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) + heightArr.forEach((height) => { + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) + }) + break } case 'north': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) + heightArr.forEach((height) => { + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) + }) break } case 'east': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) + widthArr.forEach((width) => { + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) + }) break } case 'west': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) + widthArr.forEach((width) => { + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) + }) break } } @@ -779,27 +792,47 @@ export const useTrestle = () => { case 'south': { width = width + horizontal height = height + vertical - topLeftPoint = { x: x - width / 2, y: y - height } + heightArr.forEach((h) => { + topLeftPoint = { x: x - width / 2, y: y - h } + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y)) + }) + break } case 'north': { width = width + horizontal height = height + vertical - topLeftPoint = { x: x + width / 2, y: y + height } + heightArr.forEach((h) => { + topLeftPoint = { x: x + width / 2, y: y + h } + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y)) + }) break } case 'east': { - topLeftPoint = { x: x - width, y: y + height / 2 } + widthArr.forEach((w) => { + topLeftPoint = { x: x - w, y: y + height / 2 } + if (result) return + result = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, + ) + }) + break } case 'west': { - topLeftPoint = { x: x + width, y: y - height / 2 } + widthArr.forEach((w) => { + topLeftPoint = { x: x + w, y: y - height / 2 } + if (result) return + result = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, + ) + }) break } } - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY) - return result } const findNextRightModule = (currentPoint, centerPoints, direction) => { @@ -816,25 +849,44 @@ export const useTrestle = () => { switch (direction) { case 'south': { - topRightPoint = { x: x + width / 2, y: y - height } + heightArr.forEach((h) => { + topRightPoint = { x: x + width / 2, y: y - h } + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y)) + }) + break } case 'north': { - topRightPoint = { x: x - width / 2, y: y + height } + heightArr.forEach((h) => { + topRightPoint = { x: x - width / 2, y: y + h } + if (result) return + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y)) + }) break } case 'east': { - topRightPoint = { x: x - width, y: y - height / 2 } + widthArr.forEach((w) => { + topRightPoint = { x: x + w, y: y + height / 2 } + if (result) return + result = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, + ) + }) break } case 'west': { - topRightPoint = { x: x + width, y: y + height / 2 } + widthArr.forEach((w) => { + topRightPoint = { x: x - w, y: y - height / 2 } + if (result) return + result = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, + ) + }) break } } - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY) - return result } @@ -1575,8 +1627,13 @@ export const useTrestle = () => { //widthArr 중복 제거 1이상 차이가 나지 않으면 같은 너비로 간주 widthArr = removeCloseValues(Array.from(new Set(widthArr))) heightArr = removeCloseValues(Array.from(new Set(heightArr))) - + const widthAvg = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + const heightAvg = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + widthArr.push(widthAvg) + heightArr.push(heightAvg) centerPoints.forEach((centerPoint, index) => { + // widthArr의 평균값을 추가한다. + centerPoint.widthArr = [...widthArr] centerPoint.heightArr = [...heightArr] @@ -1610,8 +1667,8 @@ export const useTrestle = () => { const vertical = ['south', 'north'].includes(direction) ? moduleSurface.trestleDetail.moduleIntvlVer : moduleSurface.trestleDetail.moduleIntvlHor - const maxX = 2 + horizontal * 3 - const maxY = 2 + vertical * 3 + const maxX = 2 + (horizontal / 10) * 3 + const maxY = 2 + (vertical / 10) * 3 if (centerPoints.length === 0) return @@ -1643,50 +1700,97 @@ export const useTrestle = () => { let bottomCell let bottomLeftPoint let bottomRightPoint - let leftBottomCnt - let rightBottomCnt + let leftBottomCnt = 0 + let rightBottomCnt = 0 switch (direction) { case 'south': //widthArr의 값을 전부 더한 후 widthArr의 길이로 나누어 평균값을 구한다. width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) - bottomLeftPoint = { x: x - width / 2, y: y + height } - bottomRightPoint = { x: x + width / 2, y: y + height } + heightArr.forEach((h) => { + if (bottomCell) return + bottomCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + h)) < maxY) + if (leftBottomCnt === 0) { + bottomLeftPoint = { x: x - width / 2, y: y + h } + leftBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ).length + } + + if (rightBottomCnt === 0) { + bottomRightPoint = { x: x + width / 2, y: y + h } + rightBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ).length + } + }) + break case 'north': width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) - bottomLeftPoint = { x: x + width / 2, y: y - height } - bottomRightPoint = { x: x - width / 2, y: y - height } + heightArr.forEach((h) => { + if (bottomCell) return + bottomCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - h)) < maxY) + if (leftBottomCnt === 0) { + bottomLeftPoint = { x: x + width / 2, y: y - h } + leftBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ).length + } + if (rightBottomCnt === 0) { + bottomRightPoint = { x: x - width / 2, y: y - h } + rightBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ).length + } + }) break case 'east': - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal - bottomLeftPoint = { x: x + width, y: y + height / 2 } - bottomRightPoint = { x: x + width, y: y - height / 2 } + widthArr.forEach((w) => { + if (bottomCell) return + bottomCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + if (leftBottomCnt === 0) { + bottomLeftPoint = { x: x + w, y: y + height / 2 } + leftBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ).length + } + if (rightBottomCnt === 0) { + bottomRightPoint = { x: x + w, y: y - height / 2 } + rightBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ).length + } + }) break case 'west': - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal - bottomLeftPoint = { x: x - width, y: y - height / 2 } - bottomRightPoint = { x: x - width, y: y + height / 2 } + widthArr.forEach((w) => { + if (bottomCell) return + bottomCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + if (leftBottomCnt === 0) { + bottomLeftPoint = { x: x - w, y: y - height / 2 } + leftBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ).length + } + if (rightBottomCnt === 0) { + bottomRightPoint = { x: x - w, y: y + height / 2 } + rightBottomCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ).length + } + }) + break } - if (bottomCell.length === 1) { + if (bottomCell) { return } // 바로 아래에 셀이 없는 경우 물떼세 배치가 왼쪽 되어있는 셀을 찾는다. - leftBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, - ).length - rightBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, - ).length if (leftBottomCnt + rightBottomCnt === 1) { exposedHalfBottom++ @@ -1703,54 +1807,100 @@ export const useTrestle = () => { // 노출상면 및 접면 체크 centerPoints.forEach((centerPoint, index) => { - let { x, y, width, height } = { ...centerPoint } + let { x, y, width, height, widthArr, heightArr } = { ...centerPoint } let topCell let topLeftPoint let topRightPoint - let leftTopCnt - let rightTopCnt + let leftTopCnt = 0 + let rightTopCnt = 0 switch (direction) { case 'south': width = width + horizontal height = height + vertical - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) - topLeftPoint = { x: x - width / 2, y: y - height } - topRightPoint = { x: x + width / 2, y: y - height } + heightArr.forEach((h) => { + if (topCell) return + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + h)) < maxY) + if (leftTopCnt === 0) { + topLeftPoint = { x: x - width / 2, y: y - h } + leftTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, + ).length + } + if (rightTopCnt === 0) { + topRightPoint = { x: x + width / 2, y: y - h } + rightTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, + ).length + } + }) break case 'north': height = height + vertical - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) - topLeftPoint = { x: x + width / 2, y: y + height } - topRightPoint = { x: x - width / 2, y: y + height } + heightArr.forEach((h) => { + if (topCell) return + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - h)) < maxY) + if (leftTopCnt === 0) { + topLeftPoint = { x: x + width / 2, y: y + h } + leftTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, + ).length + } + if (rightTopCnt === 0) { + topRightPoint = { x: x - width / 2, y: y + h } + rightTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, + ).length + } + }) break case 'east': width = width + horizontal - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - topLeftPoint = { x: x - width, y: y + height / 2 } - topRightPoint = { x: x - width, y: y - height / 2 } + widthArr.forEach((w) => { + if (topCell) return + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + if (leftTopCnt === 0) { + topLeftPoint = { x: x - w, y: y + height / 2 } + leftTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, + ).length + } + + if (rightTopCnt === 0) { + topRightPoint = { x: x - w, y: y - height / 2 } + rightTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, + ).length + } + }) break case 'west': width = width + horizontal - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - topLeftPoint = { x: x + width, y: y - height / 2 } - topRightPoint = { x: x + width, y: y + height / 2 } + widthArr.forEach((w) => { + if (topCell) return + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + if (leftTopCnt === 0) { + topLeftPoint = { x: x + w, y: y - height / 2 } + leftTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, + ).length + } + if (rightTopCnt === 0) { + topRightPoint = { x: x + w, y: y + height / 2 } + rightTopCnt = centerPoints.filter( + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, + ).length + } + }) break } - if (topCell.length === 1) { + if (topCell) { touchDimension++ return } - leftTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, - ).length - rightTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, - ).length - if (leftTopCnt + rightTopCnt === 2) { touchDimension++ return @@ -1981,6 +2131,34 @@ export const useTrestle = () => { }) } + // 키값의 차이가 2이하인 경우 한개로 합침 + function mergeCloseKeys(data) { + // 키 값을 숫자로 변환 후 정렬 + const keys = Object.keys(data) + .map(parseFloat) + .sort((a, b) => a - b) + const result = {} + + let baseKey = keys[0] + result[baseKey.toString()] = [...data[baseKey.toString()]] + + for (let i = 1; i < keys.length; i++) { + const currentKey = keys[i] + const prevKey = baseKey + + if (Math.abs(currentKey - prevKey) <= 2) { + // 키 차이가 2 이하인 경우 병합 + result[baseKey.toString()].push(...data[currentKey.toString()]) + } else { + // 새로운 그룹 시작 + baseKey = currentKey + result[baseKey.toString()] = [...data[currentKey.toString()]] + } + } + + return result + } + // 가장 왼쪽에 있는 모듈을 기준으로 같은 단에 있는 모듈들 파라미터 생성 const getMostLeftModules = (surface, exposedBottomModules) => { const { direction, modules, isChidory } = surface @@ -2001,7 +2179,7 @@ export const useTrestle = () => { if (direction === 'south') { // 모듈의 top으로 groupBy - const groupedByTop = modules.reduce((acc, module) => { + let groupedByTop = modules.reduce((acc, module) => { const key = module.top if (!acc[key]) { acc[key] = [] @@ -2009,10 +2187,11 @@ export const useTrestle = () => { acc[key].push(module) return acc }, {}) + groupedByTop = mergeCloseKeys(groupedByTop) // groupedByTop의 키값을 기준으로 정렬한 데이터를 배열로 변환 sameLineModuleList = Object.values(groupedByTop).sort((a, b) => b[0].top - a[0].top) } else if (direction === 'north') { - const groupedByTop = modules.reduce((acc, module) => { + let groupedByTop = modules.reduce((acc, module) => { const key = module.top if (!acc[key]) { acc[key] = [] @@ -2020,9 +2199,10 @@ export const useTrestle = () => { acc[key].push(module) return acc }, {}) + groupedByTop = mergeCloseKeys(groupedByTop) sameLineModuleList = Object.values(groupedByTop).sort((a, b) => a[0].top - b[0].top) } else if (direction === 'east') { - const groupedByLeft = modules.reduce((acc, module) => { + let groupedByLeft = modules.reduce((acc, module) => { const key = module.left if (!acc[key]) { acc[key] = [] @@ -2030,9 +2210,10 @@ export const useTrestle = () => { acc[key].push(module) return acc }, {}) + groupedByLeft = mergeCloseKeys(groupedByLeft) sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => b[0].left - a[0].left) } else if (direction === 'west') { - const groupedByLeft = modules.reduce((acc, module) => { + let groupedByLeft = modules.reduce((acc, module) => { const key = module.left if (!acc[key]) { acc[key] = [] @@ -2040,6 +2221,8 @@ export const useTrestle = () => { acc[key].push(module) return acc }, {}) + //groupedByLeft의 키값의 차이가 2이하인 경우 같은 라인으로 합친다. + groupedByLeft = mergeCloseKeys(groupedByLeft) sameLineModuleList = Object.values(groupedByLeft).sort((a, b) => a[0].left - b[0].left) } @@ -2219,80 +2402,243 @@ export const useTrestle = () => { case 'south': width = width + horizontal height = height + vertical - bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) - halfBottomLeftPoint = { x: x - width / 2, y: y + height } - halfBottomRightPoint = { x: x + width / 2, y: y + height } - topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) - halfTopLeftPoint = { x: x - width / 2, y: y - height } - halfTopRightPoint = { x: x + width / 2, y: y - height } - leftPoint = { x: x - width, y: y } - rightPoint = { x: x + width, y: y } - bottomLeftModule = { x: x - width, y: y + height } - bottomRightModule = { x: x + width, y: y + height } + heightArr.forEach((h) => { + if (!bottomModule) { + bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + h)) < maxY) + } + if (!topModule) { + topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - h)) < maxY) + } + if (!halfBottomLeftModule) { + halfBottomLeftPoint = { x: x - width / 2, y: y + h } + halfBottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomLeftPoint.y) < maxY, + ) + } + if (!halfBottomRightModule) { + halfBottomRightPoint = { x: x + width / 2, y: y + h } + halfBottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomRightPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomRightPoint.y) < maxY, + ) + } + if (!halfTopLeftModule) { + halfTopLeftPoint = { x: x - width / 2, y: y - h } + halfTopLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfTopLeftPoint.y) < maxY, + ) + } + if (!halfTopRightModule) { + halfTopRightPoint = { x: x + width / 2, y: y - h } + halfTopRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopRightPoint.x) < maxX && Math.abs(centerPoint.y - halfTopRightPoint.y) < maxY, + ) + } + if (leftModule) { + leftPoint = { x: x - width, y: y } + leftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - leftPoint.x) < maxX && Math.abs(centerPoint.y - leftPoint.y) < maxY, + ) + } + if (rightModule) { + rightPoint = { x: x + width, y: y } + rightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - rightPoint.x) < maxX && Math.abs(centerPoint.y - rightPoint.y) < maxY, + ) + } + if (bottomLeftModule) { + bottomLeftPoint = { x: x - width, y: y + h } + bottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ) + } + if (bottomRightModule) { + bottomRightPoint = { x: x + width, y: y + h } + bottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ) + } + }) + break case 'north': width = width + horizontal height = height + vertical - bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) - halfBottomLeftPoint = { x: x + width / 2, y: y - height } - halfBottomRightPoint = { x: x - width / 2, y: y - height } - topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) - halfTopLeftPoint = { x: x + width / 2, y: y + height } - halfTopRightPoint = { x: x - width / 2, y: y + height } - leftPoint = { x: x + width, y: y } - rightPoint = { x: x - width, y: y } - bottomLeftModule = { x: x + width, y: y - height } - bottomRightModule = { x: x - width, y: y - height } + heightArr.forEach((h) => { + if (!bottomModule) { + bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - h)) < maxY) + } + if (!topModule) { + topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + h)) < maxY) + } + if (!halfBottomLeftModule) { + halfBottomLeftPoint = { x: x + width / 2, y: y - h } + halfBottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomLeftPoint.y) < maxY, + ) + } + if (!halfBottomRightModule) { + halfBottomRightPoint = { x: x - width / 2, y: y - h } + halfBottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomRightPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomRightPoint.y) < maxY, + ) + } + if (!halfTopLeftModule) { + halfTopLeftPoint = { x: x + width / 2, y: y + h } + halfTopLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfTopLeftPoint.y) < maxY, + ) + } + if (!halfTopRightModule) { + halfTopRightPoint = { x: x - width / 2, y: y + h } + halfTopRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopRightPoint.x) < maxX && Math.abs(centerPoint.y - halfTopRightPoint.y) < maxY, + ) + } + if (leftModule) { + leftPoint = { x: x + width, y: y } + leftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - leftPoint.x) < maxX && Math.abs(centerPoint.y - leftPoint.y) < maxY, + ) + } + if (rightModule) { + rightPoint = { x: x - width, y: y } + rightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - rightPoint.x) < maxX && Math.abs(centerPoint.y - rightPoint.y) < maxY, + ) + } + if (bottomLeftModule) { + bottomLeftPoint = { x: x + width, y: y - h } + bottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ) + } + if (bottomRightModule) { + bottomRightPoint = { x: x - width, y: y - h } + bottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ) + } + }) + break case 'east': - bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - width = width + horizontal - halfBottomLeftPoint = { x: x + width, y: y + height / 2 } - halfBottomRightPoint = { x: x + width, y: y - height / 2 } - topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - halfTopLeftPoint = { x: x - width, y: y + height / 2 } - halfTopRightPoint = { x: x - width, y: y - height / 2 } - leftPoint = { x: x, y: y + height } - rightPoint = { x: x, y: y - height } - bottomLeftModule = { x: x + width, y: y + height } - bottomRightModule = { x: x + width, y: y - height } + widthArr.forEach((w) => { + if (!bottomModule) { + bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + } + if (!topModule) { + topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + } + if (!halfBottomLeftModule) { + halfBottomLeftPoint = { x: x + w, y: y - height / 2 } + halfBottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomLeftPoint.y) < maxY, + ) + } + if (!halfBottomRightModule) { + halfBottomRightPoint = { x: x + w, y: y - height / 2 } + halfBottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomRightPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomRightPoint.y) < maxY, + ) + } + if (!halfTopLeftModule) { + halfTopLeftPoint = { x: x - w, y: y + height / 2 } + halfTopLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfTopLeftPoint.y) < maxY, + ) + } + if (!halfTopRightModule) { + halfTopRightPoint = { x: x - w, y: y - height / 2 } + halfTopRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopRightPoint.x) < maxX && Math.abs(centerPoint.y - halfTopRightPoint.y) < maxY, + ) + } + if (!leftModule) { + leftPoint = { x: x, y: y + height } + leftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - leftPoint.x) < maxX && Math.abs(centerPoint.y - leftPoint.y) < maxY, + ) + } + if (!rightModule) { + rightPoint = { x: x, y: y - height } + rightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - rightPoint.x) < maxX && Math.abs(centerPoint.y - rightPoint.y) < maxY, + ) + } + if (!bottomLeftModule) { + bottomLeftPoint = { x: x + w, y: y + height } + bottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ) + } + if (!bottomRightModule) { + bottomRightPoint = { x: x + w, y: y - height } + bottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ) + } + }) break case 'west': - bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - width = width + horizontal - halfBottomLeftPoint = { x: x - width, y: y - height / 2 } - halfBottomRightPoint = { x: x - width, y: y + height / 2 } - topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) - halfTopLeftPoint = { x: x + width, y: y - height / 2 } - halfTopRightPoint = { x: x + width, y: y + height / 2 } - leftPoint = { x: x, y: y - height } - rightPoint = { x: x, y: y + height } - bottomLeftModule = { x: x - width, y: y - height } - bottomRightModule = { x: x - width, y: y + height } + widthArr.forEach((w) => { + if (!bottomModule) { + bottomModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + } + if (!topModule) { + topModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + } + if (!halfBottomLeftModule) { + halfBottomLeftPoint = { x: x - w, y: y - height / 2 } + halfBottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomLeftPoint.y) < maxY, + ) + } + if (!halfBottomRightModule) { + halfBottomRightPoint = { x: x - w, y: y + height / 2 } + halfBottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfBottomRightPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomRightPoint.y) < maxY, + ) + } + if (!halfTopLeftModule) { + halfTopLeftPoint = { x: x + w, y: y - height / 2 } + halfTopLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfTopLeftPoint.y) < maxY, + ) + } + if (!halfTopRightModule) { + halfTopRightPoint = { x: x + w, y: y + height / 2 } + halfTopRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - halfTopRightPoint.x) < maxX && Math.abs(centerPoint.y - halfTopRightPoint.y) < maxY, + ) + } + if (!leftModule) { + leftPoint = { x: x, y: y - height } + leftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - leftPoint.x) < maxX && Math.abs(centerPoint.y - leftPoint.y) < maxY, + ) + } + if (!rightModule) { + rightPoint = { x: x, y: y + height } + rightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - rightPoint.x) < maxX && Math.abs(centerPoint.y - rightPoint.y) < maxY, + ) + } + if (!bottomLeftModule) { + bottomLeftPoint = { x: x - w, y: y - height } + bottomLeftModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, + ) + } + if (!bottomRightModule) { + bottomRightPoint = { x: x - w, y: y + height } + bottomRightModule = centerPoints.find( + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, + ) + } + }) break } - halfTopLeftModule = centerPoints.find( - (centerPoint) => Math.abs(centerPoint.x - halfTopLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfTopLeftPoint.y) < maxY, - ) - halfTopRightModule = centerPoints.find( - (centerPoint) => Math.abs(centerPoint.x - halfTopRightPoint.x) < maxX && Math.abs(centerPoint.y - halfTopRightPoint.y) < maxY, - ) - halfBottomLeftModule = centerPoints.find( - (centerPoint) => Math.abs(centerPoint.x - halfBottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomLeftPoint.y) < maxY, - ) - halfBottomRightModule = centerPoints.find( - (centerPoint) => Math.abs(centerPoint.x - halfBottomRightPoint.x) < maxX && Math.abs(centerPoint.y - halfBottomRightPoint.y) < maxY, - ) - leftModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - leftPoint.x) < maxX && Math.abs(centerPoint.y - leftPoint.y) < maxY) - rightModule = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - rightPoint.x) < maxX && Math.abs(centerPoint.y - rightPoint.y) < maxY) - bottomLeftModule = centerPoints.find( - (centerPoint) => Math.abs(centerPoint.x - bottomLeftModule.x) < maxX && Math.abs(centerPoint.y - bottomLeftModule.y) < maxY, - ) - bottomRightModule = centerPoints.find( - (centerPoint) => Math.abs(centerPoint.x - bottomRightModule.x) < maxX && Math.abs(centerPoint.y - bottomRightModule.y) < maxY, - ) - return { bottomModule, topModule, From c95267e1bd45f7d7f6b4961b8f68e59fefbfc3d0 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 11 Feb 2025 13:29:47 +0900 Subject: [PATCH 17/27] =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=ED=9B=84=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=20=ED=9A=8C=EB=A1=9C=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20=EC=8B=9C=20=EB=B0=A9=EC=9C=84=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=95=88=EB=90=98=EC=9E=88=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=B2=98=EB=A6=AC=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/useMenu.js | 10 +++++++++- src/hooks/module/useTrestle.js | 7 ++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js index 5eadcf18..84c8cef7 100644 --- a/src/hooks/common/useMenu.js +++ b/src/hooks/common/useMenu.js @@ -17,17 +17,21 @@ import { useState } from 'react' import { v4 as uuidv4 } from 'uuid' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' import { useRecoilValue } from 'recoil' -import { currentMenuState } from '@/store/canvasAtom' +import { canvasState, currentMenuState } from '@/store/canvasAtom' import { MENU } from '@/common/common' import { useTrestle } from '@/hooks/module/useTrestle' +import { usePolygon } from '@/hooks/usePolygon' +import { useOrientation } from '@/hooks/module/useOrientation' export default function useMenu() { const menus = [] const currentMenu = useRecoilValue(currentMenuState) + const canvas = useRecoilValue(canvasState) const [popupId, setPopupId] = useState(uuidv4()) const { addPopup } = usePopup() const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({}) const { clear: trestleClear } = useTrestle() + const { nextStep } = useOrientation() const handleMenu = (type) => { if (type === 'outline') { switch (currentMenu) { @@ -85,6 +89,10 @@ export default function useMenu() { addPopup(popupId, 1, ) break case MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING: + const hasModules = canvas.getObjects().some((obj) => obj.name === 'module') + if (hasModules) { + nextStep() + } addPopup(popupId, 1, ) break } diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 7c8412db..3e6adaab 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -646,7 +646,12 @@ export const useTrestle = () => { const params = { trestles, pcses, modules } //견적서 itemList 조회 - const { data: itemList, data2, result } = await getQuotationItem(params) + const { data, data2, result } = await getQuotationItem(params) + let itemList + if (!data) { + return + } + itemList = data if (result.resultCode === 'E') { swalFire({ text: result.resultMsg, icon: 'error' }) From b4f2272a6b4a2f3851f045ac693f413c9732a814 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 11 Feb 2025 13:41:33 +0900 Subject: [PATCH 18/27] =?UTF-8?q?polygon=EC=9D=98=20point=EA=B0=80=203?= =?UTF-8?q?=EA=B0=9C=20=EB=AF=B8=EB=A7=8C=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useRoofFn.js | 4 +++- src/hooks/module/useOrientation.js | 4 ++-- src/hooks/usePolygon.js | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js index 54ebaecb..35ec81df 100644 --- a/src/hooks/common/useRoofFn.js +++ b/src/hooks/common/useRoofFn.js @@ -33,6 +33,9 @@ export function useRoofFn() { if (!polygon) { return } + if (polygon.points.length < 3) { + return + } if (isForceChange && !isDisplay) { /*if (polygon.roofMaterial) { polygon.roofMaterial = null @@ -156,7 +159,6 @@ export function useRoofFn() { combinedPatternCanvas.width = polygon.width * ratio combinedPatternCanvas.height = polygon.height * ratio const combinedCtx = combinedPatternCanvas.getContext('2d') - // 첫 번째 패턴을 그린 후 두 번째 패턴을 덧입힘 combinedCtx.drawImage(patternSourceCanvas, 0, 0) combinedCtx.drawImage(hachingPatternSourceCanvas, 0, 0) diff --git a/src/hooks/module/useOrientation.js b/src/hooks/module/useOrientation.js index 36b4e640..9e57c687 100644 --- a/src/hooks/module/useOrientation.js +++ b/src/hooks/module/useOrientation.js @@ -12,7 +12,7 @@ export function useOrientation() { const { drawDirectionArrow } = usePolygon() - useEffect(() => { + /*useEffect(() => { const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) roofs.forEach((roof) => { roof.set({ @@ -20,7 +20,7 @@ export function useOrientation() { }) drawDirectionArrow(roof) }) - }, []) + }, [])*/ const nextStep = () => { if (isNaN(compasDeg)) { diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 309688a7..2a024626 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -174,6 +174,9 @@ export const usePolygon = () => { * @param polygon */ const drawDirectionArrow = (polygon) => { + if (polygon.points.length < 3) { + return + } const direction = polygon.direction if (!direction) { return From 1fca294089ee75140802bea9d10097a9777b2658 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 11 Feb 2025 14:08:36 +0900 Subject: [PATCH 19/27] =?UTF-8?q?topRightPoint=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EB=B2=94=EC=9C=84=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/useTrestle.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 3e6adaab..2c9e43ad 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -873,7 +873,7 @@ export const useTrestle = () => { } case 'east': { widthArr.forEach((w) => { - topRightPoint = { x: x + w, y: y + height / 2 } + topRightPoint = { x: x - w, y: y - height / 2 } if (result) return result = centerPoints.find( (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, @@ -883,7 +883,7 @@ export const useTrestle = () => { } case 'west': { widthArr.forEach((w) => { - topRightPoint = { x: x - w, y: y - height / 2 } + topRightPoint = { x: x + w, y: y + height / 2 } if (result) return result = centerPoints.find( (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, From 88be8a23ca9a2221b09df811e78d65253cdd3363 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 11 Feb 2025 15:43:09 +0900 Subject: [PATCH 20/27] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../management/StuffSearchCondition.jsx | 46 +++---------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index d259e573..ecac7471 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -611,14 +611,9 @@ export default function StuffSearchCondition() { //판매대리점 자동완성 변경 const onSelectionChange = (key) => { - //내 물건보기 체크 풀어주기 - setMyDataCheck(stuffSearch.schMyDataCheck) - // stuffSearch.schMyDataCheck = false - if (isObjectNotEmpty(key)) { setOtherSaleStoreId('') setSchSelSaleStoreId(key.saleStoreId) - // stuffSearch.schSelSaleStoreId = key.saleStoreId //고른 1차점의 saleStoreId로 2차점 API호출하기 let url = `/api/object/saleStore/${key.saleStoreId}/list?firstFlg=0&userId=${session?.userId}` let otherList @@ -663,7 +658,6 @@ export default function StuffSearchCondition() { stuffSearch.schMyDataCheck = false if (isObjectNotEmpty(key)) { setOtherSaleStoreId(key.saleStoreId) - // stuffSearch.schOtherSelSaleStoreId = key.saleStoreId //2차점 골랐을때 1차점 값 if (session.storeId === 'T01') { @@ -767,7 +761,6 @@ export default function StuffSearchCondition() { setOtherSaleStoreId('') } else { setTempFlg(stuffSearch.schTempFlg ? stuffSearch.schTempFlg : tempFlg) - setMyDataCheck(stuffSearch.schMyDataCheck) } } else { if (stuffSearch.code === 'DELETE') { @@ -820,7 +813,7 @@ export default function StuffSearchCondition() { setReceiveUser(stuffSearch.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser) setDateType(stuffSearch.schDateType ? stuffSearch.schDateType : dateType) setTempFlg(stuffSearch.schTempFlg ? stuffSearch.schTempFlg : tempFlg) - setMyDataCheck(stuffSearch.schMyDataCheck) + if (session.storeLvl !== '1') { stuffSearch.schSelSaleStoreId = '' } @@ -836,12 +829,6 @@ export default function StuffSearchCondition() { } else if (stuffSearch.schTempFlg === '1') { setTempFlg('1') } - - if (stuffSearch.schMyDataCheck) { - setMyDataCheck(true) - } else { - setMyDataCheck(false) - } }, [stuffSearch]) useEffect(() => { @@ -865,42 +852,35 @@ export default function StuffSearchCondition() { //0203 내물건보기 체크시 공통 schSaleStoreId에 storeId담아 전송 schSelSaleStoreId, schOtherSelSaleStoreId 비우기 if (session?.storeId === 'T01') { if (e.target.checked) { - stuffSearch.schMyDataCheck = e.target.checked setMyDataCheck(true) setOtherSaleStoreId('') //2차점 비우기 setSchSelSaleStoreId('T01') - stuffSearch.schSaleStoreId = session.storeId stuffSearch.schSelSaleStoreId = '' stuffSearch.schOtherSelSaleStoreId = '' const key = { saleStoreId: session.storeId } onSelectionChange(key) } else { stuffSearch.schSaleStoreId = '' - stuffSearch.schMyDataCheck = e.target.checked setSchSelSaleStoreId('') setMyDataCheck(false) + //아래꺼 확인필요 onSelectionChange(null) } } else if (session?.storeLvl === '1') { if (e.target.checked) { - stuffSearch.schMyDataCheck = e.target.checked setMyDataCheck(true) setOtherSaleStoreId('') //2차점 비우기 setSchSelSaleStoreId(schSelSaleStoreId) - stuffSearch.schSaleStoreId = session.storeId stuffSearch.schSelSaleStoreId = '' stuffSearch.schOtherSelSaleStoreId = '' } else { - stuffSearch.schMyDataCheck = e.target.checked - stuffSearch.schSaleStoreId = '' setMyDataCheck(false) } } else { //2차점인제 3,4가 없으면 상관없음 //3,4등등이 있는경우 처리필요 if (e.target.checked) { - stuffSearch.schMyDataCheck = e.target.checked setMyDataCheck(true) if (otherSaleStoreList.length > 1) { stuffSearch.schSaleStoreId = session.storeId @@ -913,7 +893,6 @@ export default function StuffSearchCondition() { } } else { setMyDataCheck(false) - stuffSearch.schMyDataCheck = e.target.checked stuffSearch.schSaleStoreId = '' } } @@ -996,7 +975,6 @@ export default function StuffSearchCondition() { className="input-light" defaultValue={stuffSearch?.schObjectNo ? stuffSearch.schObjectNo : objectNo} onChange={() => { - // stuffSearch.schObjectNo = objectNoRef.current.value setObjectNo(objectNoRef.current.value) }} onKeyUp={handleByOnKeyUp} @@ -1012,7 +990,6 @@ export default function StuffSearchCondition() { className="input-light" defaultValue={stuffSearch?.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName} onChange={() => { - // stuffSearch.schSaleStoreName = saleStoreNameRef.current.value setSaleStoreName(saleStoreNameRef.current.value) }} onKeyUp={handleByOnKeyUp} @@ -1029,7 +1006,6 @@ export default function StuffSearchCondition() { className="input-light" defaultValue={stuffSearch?.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName} onChange={() => { - // stuffSearch.schDispCompanyName = dispCompanyNameRef.current.value setDispCompanyName(dispCompanyNameRef.current.value) }} onKeyUp={handleByOnKeyUp} @@ -1047,7 +1023,6 @@ export default function StuffSearchCondition() { className="input-light" defaultValue={stuffSearch?.schObjectName ? stuffSearch.schObjectName : objectName} onChange={() => { - // stuffSearch.schObjectName = objectNameRef.current.value setObjectName(objectNameRef.current.value) }} onKeyUp={handleByOnKeyUp} @@ -1063,7 +1038,6 @@ export default function StuffSearchCondition() { ref={receiveUserRef} defaultValue={stuffSearch?.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser} onChange={() => { - // stuffSearch.schReceiveUser = receiveUserRef.current.value setReceiveUser(receiveUserRef.current.value) }} onKeyUp={handleByOnKeyUp} @@ -1079,7 +1053,6 @@ export default function StuffSearchCondition() { className="input-light" defaultValue={stuffSearch?.schAddress ? stuffSearch.schAddress : address} onChange={() => { - // stuffSearch.schAddress = addressRef.current.value setAddress(addressRef.current.value) }} onKeyUp={handleByOnKeyUp} @@ -1101,7 +1074,6 @@ export default function StuffSearchCondition() { value={'U'} onChange={(e) => { setDateType(e.target.value) - // stuffSearch.schDateType = e.target.value }} /> @@ -1115,7 +1087,6 @@ export default function StuffSearchCondition() { value={'R'} onChange={(e) => { setDateType(e.target.value) - // stuffSearch.schDateType = e.target.value }} /> @@ -1140,11 +1111,10 @@ export default function StuffSearchCondition() { type="radio" name="schTempFlg" id="schTempFlg" - checked={stuffSearch.schTempFlg === '' ? true : false} + checked={tempFlg === '' ? true : false} value={''} onChange={(e) => { setTempFlg(e.target.value) - stuffSearch.schTempFlg = e.target.value }} /> @@ -1154,11 +1124,10 @@ export default function StuffSearchCondition() { type="radio" name="schTempFlg" id="schTempFlg0" - checked={stuffSearch.schTempFlg === '0' ? true : false} + checked={tempFlg === '0' ? true : false} value={'0'} onChange={(e) => { setTempFlg(e.target.value) - stuffSearch.schTempFlg = e.target.value }} /> @@ -1168,11 +1137,10 @@ export default function StuffSearchCondition() { type="radio" name="schTempFlg" id="schTempFlg1" - checked={stuffSearch.schTempFlg === '1' ? true : false} + checked={tempFlg === '1' ? true : false} value={'1'} onChange={(e) => { setTempFlg(e.target.value) - stuffSearch.schTempFlg = e.target.value }} /> @@ -1297,7 +1265,6 @@ export default function StuffSearchCondition() { onChange={onSelectionChange2} getOptionLabel={(x) => x.saleStoreName} getOptionValue={(x) => x.saleStoreId} - // isDisabled={otherSaleStoreList != null && otherSaleStoreList.length === 1 ? true : false} isDisabled={ session?.storeLvl === '1' ? (otherSaleStoreList.length > 0 ? false : true) : otherSaleStoreList.length === 1 ? true : false } @@ -1312,10 +1279,9 @@ export default function StuffSearchCondition() { { checkMyData(e) - stuffSearch.schMyDataCheck = e.target.checked }} /> From d2d44333067b0758402b58045c7b3fd41d553cdb Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 11 Feb 2025 15:53:23 +0900 Subject: [PATCH 21/27] =?UTF-8?q?=F0=9F=93=8Cfix:=20canvas-popup-status=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EA=B5=AC=EC=A1=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/useCanvasPopupStatusController.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/hooks/common/useCanvasPopupStatusController.js b/src/hooks/common/useCanvasPopupStatusController.js index d7845362..c6be7f9c 100644 --- a/src/hooks/common/useCanvasPopupStatusController.js +++ b/src/hooks/common/useCanvasPopupStatusController.js @@ -17,7 +17,7 @@ export function useCanvasPopupStatusController(param = 1) { const [compasDeg, setCompasDeg] = useRecoilState(compasDegAtom) const [moduleSelectionDataStore, setModuleSelectionDataStore] = useRecoilState(moduleSelectionDataState) const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) - const { get, getFetcher, postFetcher } = useAxios() + const { get, promiseGet, getFetcher, postFetcher } = useAxios() const canvas = useRecoilValue(canvasState) const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) // console.log('🚀 ~ Orientation ~ currentCanvasPlan:', currentCanvasPlan) @@ -37,11 +37,18 @@ export function useCanvasPopupStatusController(param = 1) { // getFetcher, // ) - const res = await get({ + const result = await promiseGet({ url: `/api/v1/canvas-popup-status?objectNo=${currentCanvasPlan.objectNo}&planNo=${currentCanvasPlan.planNo}&popupType=${popupTypeParam}`, }) + .then((res) => { + return res + }) + .catch((err) => { + console.log('🚀 ~ getModuleSelection ~ err:', err) + return null + }) - return res + return result.data } /** @@ -51,8 +58,9 @@ export function useCanvasPopupStatusController(param = 1) { const handleModuleSelectionTotal = async () => { for (let i = 1; i < 3; i++) { const result = await getModuleSelection(i) + console.log('🚀 ~ handleModuleSelectionTotal ~ result:', result) // setModuleSelectionTotal((prev) => ({ ...prev, [i]: JSON.parse(unescapeString(result.popupStatus)) })) - if (!result) return + if (!result.objectNo) return if (i === 1) { setCompasDeg(result.popupStatus) } else if (i === 2) { From 8248a56d60f0913b0899a8307c859a5778bf432d Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 11 Feb 2025 15:57:44 +0900 Subject: [PATCH 22/27] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B8=20=EB=A9=94=EB=89=B4=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=EC=8B=9C=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/Stuff.jsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index ee0a1930..0a3be3ee 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -214,7 +214,7 @@ export default function Stuff() { // 진입시 그리드 데이터 조회 useEffect(() => { - if (stuffSearchParams?.code === 'S') { + if (stuffSearchParams?.code === 'S' || stuffSearchParams?.code === 'END') { const params = { saleStoreId: session.storeId, schObjectNo: stuffSearchParams?.schObjectNo, @@ -267,7 +267,11 @@ export default function Stuff() { setIsGlobalLoading(false) }) } - fetchData() + if (stuffSearchParams.code === 'S') { + fetchData() + } else { + stuffSearchParams.code = 'S' + } } else if (stuffSearchParams?.code === 'M') { const params = { schObjectNo: stuffSearchParams.schObjectNo, @@ -328,7 +332,6 @@ export default function Stuff() { stuffSearchParams.startRow = 1 stuffSearchParams.endRow = 1 * stuffSearchParams.pageSize } - setIsGlobalLoading(false) }) } @@ -383,7 +386,7 @@ export default function Stuff() { schSelSaleStoreId: '', schOtherSelSaleStoreId: '', schSortType: 'U', - code: 'S', + code: 'END', pageNo: 1, pageSize: 100, schMyDataCheck: false, @@ -392,7 +395,6 @@ export default function Stuff() { setStuffSearch({ ...newParams, }) - setIsGlobalLoading(false) } else { stuffSearchParams.code = 'DELETE' From 261d4fb9feea2b861ea5d4044e2b7cb5fe499762 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 11 Feb 2025 16:09:34 +0900 Subject: [PATCH 23/27] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20=EC=98=A4=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 --- docs/2025-02-10_Qcell_회의.txt | 26 +++++++++ src/hooks/object/useObjectBatch.js | 85 +++++++++++++++++++++++++++--- src/hooks/useContextMenu.js | 4 +- 3 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 docs/2025-02-10_Qcell_회의.txt diff --git a/docs/2025-02-10_Qcell_회의.txt b/docs/2025-02-10_Qcell_회의.txt new file mode 100644 index 00000000..48224f78 --- /dev/null +++ b/docs/2025-02-10_Qcell_회의.txt @@ -0,0 +1,26 @@ +공통. 기본 폰트값 통일 -> + 1. 전체 화면 기본폰트 MS PGothic으로 통일 (폰트 기능 협의) + 2. 번역이 후짐 + +1. 지붕덮개 -> + 1-1. '외벽선 속성 설정을 완료하시겠습니까?' 문구 메시지 처리 + 1-2. 지붕재 설정 selectbox 한글로 나옴 + +2. 배치면 -> + +3. 모듈 -> + 3-1. 모듈 선택 화면 -> + 1) 서까래 간격 유지 안됨 + 2) 데이터 저장 이후 모듈 변경으로 인해 셀렉트박스의 데이터가 없을 경우 이전 데이터로 설정됨 + 3-2. 모듈 설치 -> + 1) 모듈 설치시 방향에 따른 기준 설정 문제 + +4. 회로 -> + 4-1. 회로 선택 화면 -> pcs 선택 화면 관련 시리즈 영역 width값 조정 + +5. 가대설정 -> + 5-1. 가대 그릴시 금구 위치 다름(좌,우, T01 / RA03250210002 / PLAN 1참고) + 5-2. 가대 설치 후 견적서로 넘어가는 시간이 너무 빠르다고 함 + +6. 견적서 -> + 6-1. 견적서 문서 다운로드 도면 이미지 포함 안됨 \ No newline at end of file diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index e93d4ff8..b63cdb97 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -425,7 +425,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { lockMovementY: true, // Y 축 이동 잠금 lockRotation: true, // 회전 잠금 viewLengthText: true, - direction: direction, + // direction: direction, originX: 'center', originY: 'center', name: dormerName, @@ -444,7 +444,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { lockMovementY: true, // Y 축 이동 잠금 lockRotation: true, // 회전 잠금 viewLengthText: true, - direction: direction, + // direction: direction, originX: 'center', originY: 'center', name: dormerName, @@ -462,8 +462,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { setSurfaceShapePattern(rightTriangle) //방향 - drawDirectionArrow(leftTriangle) - drawDirectionArrow(rightTriangle) + // drawDirectionArrow(leftTriangle) + // drawDirectionArrow(rightTriangle) let offsetPolygon @@ -649,7 +649,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { lockRotation: true, // 회전 잠금 viewLengthText: true, fontSize: 14, - direction: direction, + // direction: direction, originX: 'center', originY: 'center', name: dormerName, @@ -666,7 +666,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { lockRotation: true, // 회전 잠금 viewLengthText: true, fontSize: 14, - direction: direction, + // direction: direction, originX: 'center', originY: 'center', name: dormerName, @@ -680,8 +680,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { setSurfaceShapePattern(leftPentagon) setSurfaceShapePattern(rightPentagon) //방향 - drawDirectionArrow(leftPentagon) - drawDirectionArrow(rightPentagon) + // drawDirectionArrow(leftPentagon) + // drawDirectionArrow(rightPentagon) let offsetPolygon @@ -1025,6 +1025,74 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } } + const copyObjectBatch = () => { + const obj = canvas.getActiveObject() + if (obj) { + let clonedObj = null + const parentSurface = canvas?.getObjects().filter((item) => item.name === POLYGON_TYPE.ROOF && item.id === obj.parentId)[0] + + obj.clone((cloned) => { + clonedObj = cloned + }) + + addCanvasMouseEventListener('mouse:move', (e) => { + const pointer = canvas?.getPointer(e.e) + if (!clonedObj) return + + canvas + .getObjects() + .filter((clonedObj) => clonedObj.name === 'clonedObj') + .forEach((clonedObj) => canvas?.remove(clonedObj)) + + clonedObj.set({ + left: pointer.x, + top: pointer.y, + name: 'clonedObj', + }) + canvas.add(clonedObj) + }) + + addCanvasMouseEventListener('mouse:up', (e) => { + //개구, 그림자 타입일 경우 폴리곤 타입 변경 + if (BATCH_TYPE.OPENING == obj.name || BATCH_TYPE.SHADOW == obj.name) { + clonedObj.set({ + points: rectToPolygon(clonedObj), + }) + + const turfSurface = pointsToTurfPolygon(parentSurface.points) + const turfObject = pointsToTurfPolygon(clonedObj.points) + + if (turf.booleanWithin(turfObject, turfSurface)) { + clonedObj.set({ + lockMovementX: true, + lockMovementY: true, + name: BATCH_TYPE.OPENING, + parentId: parentSurface.id, + }) + clonedObj.setCoords() + } else { + swalFire({ + title: getMessage('batch.object.outside.roof'), + icon: 'warning', + }) + canvas.remove(clonedObj) + } + } else { + clonedObj.set({ + lockMovementX: true, + lockMovementY: true, + name: obj.name, + }) + + if (clonedObj.type === 'group') reGroupObject(clonedObj) + clonedObj.setCoords() + } + canvas.discardActiveObject() + initEvent() + }) + } + } + const dormerOffsetKeyEvent = (setArrow1, setArrow2) => { addDocumentEventListener('keydown', document, (e) => { if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { @@ -1061,5 +1129,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { moveObjectBatch, dormerOffsetKeyEvent, dormerOffset, + copyObjectBatch, } } diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 577d5b2e..3ab2c566 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -58,7 +58,7 @@ export function useContextMenu() { const [cell, setCell] = useState(null) const [column, setColumn] = useState(null) const { handleZoomClear } = useCanvasEvent() - const { moveObjectBatch } = useObjectBatch({}) + const { moveObjectBatch, copyObjectBatch } = useObjectBatch({}) const { moveSurfaceShapeBatch } = useSurfaceShapeBatch({}) const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom) const { addLine, removeLine } = useLine() @@ -470,7 +470,7 @@ export function useContextMenu() { id: 'openingCopy', shortcut: ['c', 'C'], name: `${getMessage('contextmenu.copy')}(C)`, - fn: () => copyObject(), + fn: () => copyObjectBatch(), }, { id: 'openingOffset', From 415139ee1b30321e58b2cb16b7a43a687677ae4a Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 11 Feb 2025 16:31:04 +0900 Subject: [PATCH 24/27] =?UTF-8?q?=EC=86=8C=EC=8A=A4=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/estimate/useEstimateController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index fbcea158..c63633cc 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -387,7 +387,6 @@ export const useEstimateController = (planNo) => { estimateData.pkgAsp = estimateData.pkgAsp.replaceAll(',', '') } - return //2. 상세데이터 저장 try { setIsGlobalLoading(true) From 9c6e812b193cb487ce7174631e0b215f23618c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 11 Feb 2025 16:32:23 +0900 Subject: [PATCH 25/27] =?UTF-8?q?-=20=ED=9A=8C=EB=A1=9C=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EB=A1=9C=EC=A7=81=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 --- .../circuitTrestle/CircuitTrestleSetting.jsx | 1 + .../modal/circuitTrestle/step/StepUp.jsx | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 5107d585..015d5173 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -364,6 +364,7 @@ export default function CircuitTrestleSetting({ id }) { circuitModules.forEach((obj) => { obj.circuit = null obj.pcsItemId = null + obj.circuitNumber = null }) if (allocationType === ALLOCATION_TYPE.PASSIVITY) { diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index e0bd7592..7ac64fde 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -392,18 +392,21 @@ export default function StepUp(props) { } } + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE) + .forEach((module) => { + module.circuit = null + module.circuitNumber = null + module.pcsItemId = null + }) + selectedData.roofSurfaceList.forEach((roofSurface) => { const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0] const moduleIds = targetSurface.modules.map((module) => { return module.id }) - targetSurface.modules.map((module) => { - module.circuit = null - module.circuitNumber = null - module.pcsItemId = null - }) - // 모듈 목록 삭제 canvas .getObjects() From 6d809a0b656d7de4983d5ea458ddf39be1dd1ee6 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 11 Feb 2025 16:34:36 +0900 Subject: [PATCH 26/27] =?UTF-8?q?setIsGlobalLoading(false)=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/module/useTrestle.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 2c9e43ad..a9289861 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -7,6 +7,8 @@ import { v4 as uuidv4 } from 'uuid' import { useMasterController } from '@/hooks/common/useMasterController' import { basicSettingState, trestleDisplaySelector } from '@/store/settingAtom' import { useSwal } from '@/hooks/useSwal' +import { useContext } from 'react' +import { QcastContext } from '@/app/QcastProvider' // 회로 및 가대설정 export const useTrestle = () => { @@ -17,10 +19,12 @@ export const useTrestle = () => { const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet const isTrestleDisplay = useRecoilValue(trestleDisplaySelector) const { swalFire } = useSwal() + const { setIsGlobalLoading } = useContext(QcastContext) const apply = () => { const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) if (notAllocationModules.length > 0) { swalFire({ text: '回路番号が設定されていないモジュールがあります。 番号を設定しなおすか、 パネルを削除してください。', icon: 'error' }) + setIsGlobalLoading(false) return null } try { From dd0c5e00aa0e3bdbd58b32b2d78fd9b71e1f7371 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 11 Feb 2025 16:43:15 +0900 Subject: [PATCH 27/27] =?UTF-8?q?circuitNumber=20=EA=B8=80=EA=BC=B4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useFont.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/hooks/common/useFont.js b/src/hooks/common/useFont.js index cb305565..9498b036 100644 --- a/src/hooks/common/useFont.js +++ b/src/hooks/common/useFont.js @@ -75,7 +75,21 @@ export function useFont() { } }, [lengthText]) - useEffect(() => {}, [circuitNumberText]) + useEffect(() => { + if (canvas && circuitNumberText.fontWeight.value) { + const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'circuitNumber') + textObjs.forEach((obj) => { + obj.set({ + fontFamily: circuitNumberText.fontFamily.value, + fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', + fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontSize: circuitNumberText.fontSize.value, + fill: circuitNumberText.fontColor.value, + }) + }) + canvas.renderAll() + } + }, [circuitNumberText]) return {} }