}
+ {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
+
}
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
index 36fdad35..a526f05a 100644
--- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx
@@ -15,6 +15,7 @@ import { useRecoilState, useRecoilValue } from 'recoil'
export default function PassivityCircuitAllocation(props) {
const {
+ setTabNum,
selectedModels,
setSelectedModels,
getOptYn: getApiProps,
@@ -88,14 +89,14 @@ export default function PassivityCircuitAllocation(props) {
]
if (!circuitNumber || circuitNumber === 0) {
swalFire({
- text: '회로번호를 1 이상입력해주세요.',
+ text: getMessage('module.circuit.minimun.error'),
type: 'alert',
icon: 'warning',
})
return
} else if (targetModules.length === 0) {
swalFire({
- text: '모듈을 선택해주세요.',
+ text: getMessage('module.not.found'),
type: 'alert',
icon: 'warning',
})
@@ -113,7 +114,7 @@ export default function PassivityCircuitAllocation(props) {
})
if (result) {
swalFire({
- text: '회로 번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로 번호를 설정하십시오.',
+ text: getMessage('module.already.exist.error'),
type: 'alert',
icon: 'warning',
})
@@ -185,7 +186,30 @@ export default function PassivityCircuitAllocation(props) {
}),
}
})
+ let pcsCount = {}
+ let result = {}
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE)
+ .forEach((module) => {
+ if (module.circuitNumber) {
+ const circuitNumber = module.circuitNumber.replace(/[()]/g, '')
+ pcsCount[circuitNumber] = (pcsCount[circuitNumber] || 0) + 1
+ }
+ })
+ for (const key in pcsCount) {
+ const firstPart = key.split('-')[0] // '-' 기준으로 첫 번째 부분을 추출
+ const value = pcsCount[key]
+ // 그룹이 없으면 초기화
+ if (!result[firstPart]) {
+ result[firstPart] = { maxValue: value, count: 1 }
+ } else {
+ // 이미 그룹이 있으면 큰 값으로 갱신, count는 증가
+ result[firstPart].maxValue = Math.max(result[firstPart].maxValue, value)
+ result[firstPart].count += 1
+ }
+ }
const usedPcses = pcsList.filter((model) => model.isUsed)
const pcsItemList = usedPcses.map((model, index) => {
return {
@@ -196,8 +220,8 @@ export default function PassivityCircuitAllocation(props) {
goodsNo: model.goodsNo,
serQtyList: [
{
- serQty: targetModules.length,
- paralQty: uniqueCircuitNumbers.length,
+ serQty: result[index + 1].maxValue,
+ paralQty: result[index + 1].count,
rmdYn: 'Y',
usePossYn: 'Y',
roofSurfaceList: roofSurfaceList,
@@ -305,6 +329,173 @@ export default function PassivityCircuitAllocation(props) {
})
}
+ const onApply = () => {
+ let uniqueCircuitNumbers = [
+ ...new Set(
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuitNumber)
+ .map((obj) => obj.circuitNumber),
+ ),
+ ]
+ if (!circuitNumber || circuitNumber === 0) {
+ swalFire({
+ text: getMessage('module.circuit.minimun.error'),
+ type: 'alert',
+ icon: 'warning',
+ })
+ return
+ } else if (targetModules.length === 0) {
+ swalFire({
+ text: getMessage('module.not.found'),
+ type: 'alert',
+ icon: 'warning',
+ })
+ return
+ } else if (selectedModels.length > 1) {
+ let result = false
+
+ uniqueCircuitNumbers.forEach((number) => {
+ if (
+ number.split('-')[1] === circuitNumber + ')' &&
+ number.split('-')[0] !== '(' + (selectedModels.findIndex((model) => model.id === selectedPcs.id) + 1)
+ ) {
+ result = true
+ }
+ })
+ if (result) {
+ swalFire({
+ text: getMessage('module.already.exist.error'),
+ type: 'alert',
+ icon: 'warning',
+ })
+ return
+ }
+ }
+
+ let tempSelectedPcs = { ...selectedPcs }
+ canvas.discardActiveObject()
+ canvas
+ .getObjects()
+ .filter((obj) => targetModules.includes(obj.id))
+ .forEach((obj) => {
+ if (obj.circuit) {
+ canvas.remove(obj.circuit)
+ }
+ const moduleCircuitText = new fabric.Text(getCircuitNumber(), {
+ left: obj.left + obj.width / 2,
+ top: obj.top + obj.height / 2,
+ 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,
+ width: obj.width,
+ height: obj.height,
+ textAlign: 'center',
+ originX: 'center',
+ originY: 'center',
+ name: 'circuitNumber',
+ selectable: false,
+ parentId: obj.id,
+ circuitInfo: selectedPcs,
+ visible: isDisplayCircuitNumber,
+ })
+ obj.set({
+ strokeWidth: 0.3,
+ })
+ obj.pcsItemId = selectedPcs.itemId
+ obj.pcsItemCode = selectedPcs.id
+ obj.circuit = moduleCircuitText
+ obj.circuitNumber = getCircuitNumber()
+ tempSelectedPcs.used = true
+ setSelectedPcs(tempSelectedPcs)
+ canvas.add(moduleCircuitText)
+ })
+
+ let pcsList = JSON.parse(JSON.stringify(selectedModels)).map((model) => {
+ if (model.id === selectedPcs.id) {
+ model.isUsed = true
+ }
+ return model
+ })
+
+ const roofSurfaceList = canvas
+ .getObjects()
+ .filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name && obj?.modules.length > 0)
+ .map((surface) => {
+ return {
+ roofSurfaceId: surface.id,
+ roofSurface: surface.direction,
+ roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
+ moduleList: surface.modules.map((module) => {
+ return {
+ itemId: module.moduleInfo.itemId,
+ circuit: module.circuitNumber,
+ pcsItemId: module.pcsItemId,
+ }
+ }),
+ }
+ })
+ const usedPcses = pcsList.filter((model) => model.isUsed)
+ const pcsItemList = usedPcses.map((model, index) => {
+ return {
+ pcsMkrCd: model.pcsMkrCd,
+ pcsSerCd: model.pcsSerCd,
+ itemId: model.itemId,
+ itemNm: model.itemNm,
+ goodsNo: model.goodsNo,
+ serQtyList: [
+ {
+ serQty: targetModules.length,
+ paralQty: uniqueCircuitNumbers.length,
+ rmdYn: 'Y',
+ usePossYn: 'Y',
+ roofSurfaceList: roofSurfaceList,
+ },
+ ],
+ }
+ })
+
+ const params = {
+ ...getApiProps(),
+ useModuleItemList: getSelectedModuleList(),
+ pcsItemList: pcsItemList,
+ }
+
+ getPcsManualConfChk(params).then((res) => {
+ if (res?.resultCode === 'E') {
+ swalFire({
+ text: res.resultMsg,
+ type: 'alert',
+ icon: 'warning',
+ confirmFn: () => {
+ const circuitNumbers = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber' && targetModules.includes(obj.parentId))
+ canvas.remove(...circuitNumbers)
+ canvas
+ .getObjects()
+ .filter((obj) => obj.name === 'module' && targetModules.includes(obj.id))
+ .forEach((obj) => {
+ obj.pcsItemId = null
+ obj.circuit = null
+ obj.circuitNumber = null
+ })
+ canvas.renderAll()
+ },
+ })
+ setSelectedPcs({ ...selectedPcs, used: false })
+ setTargetModules([])
+ return
+ }
+
+ setSelectedModels(pcsList)
+
+ setTargetModules([])
+ setModuleStatisticsData()
+ setTabNum(2)
+ })
+ }
+
return (
<>
From 21aae63c4675e29626ede8e61bb3dcfc9066ed67 Mon Sep 17 00:00:00 2001
From: "hyojun.choi"
Date: Thu, 20 Feb 2025 14:37:37 +0900
Subject: [PATCH 38/47] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EC=84=A4=EC=A0=95?=
=?UTF-8?q?=20=EC=9D=B4=EC=A0=84=20=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD?=
=?UTF-8?q?=20=EC=8B=9C=20=EA=B0=80=EB=8C=80=20=EC=84=A4=EC=B9=98=20?=
=?UTF-8?q?=EB=90=9C=EA=B2=83=EB=93=A4=20clear?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
index a7f26838..b705520e 100644
--- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
+++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx
@@ -33,7 +33,7 @@ const ALLOCATION_TYPE = {
export default function CircuitTrestleSetting({ id }) {
const { getMessage } = useMessage()
const { closePopup } = usePopup()
- const { apply, setViewCircuitNumberTexts, getEstimateData } = useTrestle()
+ const { apply, setViewCircuitNumberTexts, getEstimateData, clear: clearTrestle } = useTrestle()
const { swalFire } = useSwal()
const { saveEstimate } = useEstimate()
const canvas = useRecoilValue(canvasState)
@@ -392,6 +392,7 @@ export default function CircuitTrestleSetting({ id }) {
} else {
setTabNum(1)
}
+ clearTrestle()
canvas.renderAll()
setModuleStatisticsData()
From bab752ebe52c6eba07199f6126fb93c149a5f126 Mon Sep 17 00:00:00 2001
From: "hyojun.choi"
Date: Thu, 20 Feb 2025 15:07:28 +0900
Subject: [PATCH 39/47] =?UTF-8?q?raft=20=EC=84=A4=EC=A0=95=20=EC=95=88?=
=?UTF-8?q?=ED=95=9C=20=EA=B2=BD=EC=9A=B0=20=EA=B8=B0=EB=B3=B8=20=EA=B0=92?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/hooks/module/useTrestle.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js
index 686643a7..248568b5 100644
--- a/src/hooks/module/useTrestle.js
+++ b/src/hooks/module/useTrestle.js
@@ -2086,7 +2086,7 @@ export const useTrestle = () => {
moduleTpCd: module.itemTp,
roofMatlCd: parent.roofMaterial.roofMatlCd,
mixMatlNo: module.mixMatlNo,
- raftBaseCd: addRoof.raft,
+ raftBaseCd: addRoof.raft ?? addRoof.raftBaseCd,
inclCd: addRoof.pitch,
roofPitch: !addRoof.roofPchBase ? addRoof.roofPchBase : Number(addRoof.roofPchBase),
exposedLowerBottomTotCnt: result.exposedBottom, // 노출 최하면 갯수
From 1245bbb663ae49e62a24bfe54e1e1d7326c7e1d3 Mon Sep 17 00:00:00 2001
From: basssy
Date: Thu, 20 Feb 2025 15:56:53 +0900
Subject: [PATCH 40/47] =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=88=98?=
=?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/estimate/popup/EstimateCopyPop.jsx | 2 +-
src/hooks/floorPlan/estimate/useEstimateController.js | 10 +++++++---
src/locales/ja.json | 6 +++---
src/locales/ko.json | 2 +-
4 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/components/estimate/popup/EstimateCopyPop.jsx b/src/components/estimate/popup/EstimateCopyPop.jsx
index 6ff2e540..3bc25c74 100644
--- a/src/components/estimate/popup/EstimateCopyPop.jsx
+++ b/src/components/estimate/popup/EstimateCopyPop.jsx
@@ -296,7 +296,7 @@ export default function EstimateCopyPop({ planNo, setEstimateCopyPopupOpen }) {
type="button"
className="btn-origin navy mr5"
onClick={() => {
- handleEstimateCopy(sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId)
+ handleEstimateCopy(sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId, setEstimateCopyPopupOpen)
}}
>
{getMessage('estimate.detail.estimateCopyPopup.copyBtn')}
diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js
index 10d90416..4a3bf0c2 100644
--- a/src/hooks/floorPlan/estimate/useEstimateController.js
+++ b/src/hooks/floorPlan/estimate/useEstimateController.js
@@ -83,6 +83,10 @@ export const useEstimateController = (planNo, flag) => {
res.data.pkgAsp = roundedNumber.toString()
}
setEstimateContextState(res.data)
+ } else {
+ swalFire({ text: getMessage('stuff.detail.header.notExistObjectNo'), type: 'alert', icon: 'error' })
+ setIsLoading(true)
+ setIsGlobalLoading(false)
}
}
})
@@ -90,8 +94,7 @@ export const useEstimateController = (planNo, flag) => {
setIsGlobalLoading(false)
} catch (error) {
console.error('견적서 상세조회 Error: ', error)
-
- swalFire({ text: getMessage('estimate.menu.move.valid1') })
+ swalFire({ text: getMessage('stuff.detail.header.notExistObjectNo'), type: 'alert', icon: 'error' })
setIsLoading(true)
setIsGlobalLoading(false)
}
@@ -415,7 +418,7 @@ export const useEstimateController = (planNo, flag) => {
* (견적서 번호(estimateData.docNo)가 생성된 이후 버튼 활성화 )
* T01관리자 계정 및 1차판매점에게만 제공
*/
- const handleEstimateCopy = async (sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId) => {
+ const handleEstimateCopy = async (sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId, setEstimateCopyPopupOpen) => {
//todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요
if (estimateData.estimateType === 'YJSS') {
return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' })
@@ -455,6 +458,7 @@ export const useEstimateController = (planNo, flag) => {
text: getMessage('estimate.detail.estimateCopyPopup.copy.alertMessage'),
type: 'alert',
confirmFn: () => {
+ setEstimateCopyPopupOpen(false) //팝업닫고
router.push(`/management/stuff/detail?objectNo=${newObjectNo.toString()}`, { scroll: false })
},
})
diff --git a/src/locales/ja.json b/src/locales/ja.json
index 2baee42f..677f9cab 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -663,9 +663,9 @@
"stuff.planReqPopup.title": "設計依頼のインポート",
"stuff.temp.subTitle": "商品情報",
"stuff.temp.subTitle2": "作図",
- "stuff.detail.header.notExistObjectNo": "存在しないものです。",
- "stuff.detail.header.successCopy": "物件番号がコピーされました。",
- "stuff.detail.header.failCopy": "物件番号のコピーに失敗しました。",
+ "stuff.detail.header.notExistObjectNo": "存在しないもの番号です.",
+ "stuff.detail.header.successCopy": "物件番号がコピーされました.",
+ "stuff.detail.header.failCopy": "物件番号のコピーに失敗しました.",
"stuff.detail.header.objectNo": "物件番号",
"stuff.detail.header.specificationConfirmDate": "仕様確認日",
"stuff.detail.header.lastEditDatetime": "更新日時",
diff --git a/src/locales/ko.json b/src/locales/ko.json
index 563ab7f2..67b4b301 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -663,7 +663,7 @@
"stuff.planReqPopup.title": "설계의뢰 불러오기",
"stuff.temp.subTitle": "물건정보",
"stuff.temp.subTitle2": "도면작성",
- "stuff.detail.header.notExistObjectNo": "존재하지 않는 물건입니다.",
+ "stuff.detail.header.notExistObjectNo": "존재하지 않는 물건번호 입니다.",
"stuff.detail.header.successCopy": "물건번호가 복사되었습니다.",
"stuff.detail.header.failCopy": "물건번호 복사에 실패했습니다.",
"stuff.detail.header.objectNo": "물건번호",
From d9bb1deee8ecf0d2cd8f8e238849ca0945e75a4d Mon Sep 17 00:00:00 2001
From: LEEYONGJAE
Date: Thu, 20 Feb 2025 16:04:32 +0900
Subject: [PATCH 41/47] =?UTF-8?q?=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AE=AC?=
=?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=EB=A9=94=EB=89=B4=EC=9D=B4?=
=?UTF-8?q?=EB=8F=99=20=EB=A1=9C=EB=94=A9=EB=B0=94=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/floor-plan/CanvasMenu.jsx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx
index df43d7bb..553b3613 100644
--- a/src/components/floor-plan/CanvasMenu.jsx
+++ b/src/components/floor-plan/CanvasMenu.jsx
@@ -239,7 +239,6 @@ export default function CanvasMenu(props) {
break
case 6:
setIsGlobalLoading(true)
- //로딩바해제는 발전시뮬레이션 조회쪽에서(Simulator.jsx) setIsGlobalLoading(false)
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => {
if (res.status === 200) {
const estimateDetail = res.data
@@ -247,7 +246,9 @@ export default function CanvasMenu(props) {
setMenuNumber(menu.index)
setCurrentMenu(menu.title)
router.push(`/floor-plan/simulator/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`)
- setIsGlobalLoading(false)
+ if (pathname === '/floor-plan/simulator/6') {
+ setIsGlobalLoading(false)
+ }
} else {
setIsGlobalLoading(false)
swalFire({ text: getMessage('simulator.menu.move.valid1') })
From 364299b30b5692d9d45e05f2aebca1fbb3bd826c 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: Thu, 20 Feb 2025 16:07:18 +0900
Subject: [PATCH 42/47] =?UTF-8?q?-=201=EC=B0=A8=20=ED=86=B5=ED=95=A9?=
=?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8(Integration=20Test)=20#789=20?=
=?UTF-8?q?=EC=88=98=EC=A0=95=20-=20=EB=A9=B4=ED=98=95=EC=83=81=20?=
=?UTF-8?q?=EB=B0=B0=EC=B9=98=EC=8B=9C=20=EB=B3=80=20=EC=86=8D=EC=84=B1=20?=
=?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../PlacementSurfaceLineProperty.jsx | 12 ++++++++++--
.../surface/useRoofLinePropertySetting.js | 4 +++-
src/hooks/surface/useSurfaceShapeBatch.js | 18 +++++++++++++-----
3 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx
index 00f00e80..cd20adf3 100644
--- a/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx
+++ b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx
@@ -7,10 +7,14 @@ import { LINE_TYPE } from '@/common/common'
import { useSwal } from '@/hooks/useSwal'
export default function PlacementSurfaceLineProperty(props) {
- const { id, pos = { x: 50, y: 230 }, roof } = props
+ const { id, pos = { x: 50, y: 230 }, roof, setIsHidden } = props
const { closePopup } = usePopup()
// const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting(id)
- const { roofLinesInit, handleSetRidge, handleSetEaves, handleSetGable, handleRollback, handleFix } = useRoofLinePropertySetting(id, roof)
+ const { roofLinesInit, handleSetRidge, handleSetEaves, handleSetGable, handleRollback, handleFix } = useRoofLinePropertySetting({
+ id,
+ roof,
+ setIsHidden,
+ })
const { getMessage } = useMessage()
const { swalFire } = useSwal()
@@ -29,6 +33,10 @@ export default function PlacementSurfaceLineProperty(props) {
}
closePopup(id)
+
+ if (setIsHidden) {
+ setIsHidden(false)
+ }
}
return (
diff --git a/src/hooks/surface/useRoofLinePropertySetting.js b/src/hooks/surface/useRoofLinePropertySetting.js
index ba5eedee..a37c1995 100644
--- a/src/hooks/surface/useRoofLinePropertySetting.js
+++ b/src/hooks/surface/useRoofLinePropertySetting.js
@@ -15,7 +15,8 @@ const LINE_COLOR = {
ACTIVE: '#EA10AC',
}
-export function useRoofLinePropertySetting(id, roof) {
+export function useRoofLinePropertySetting(props) {
+ const { id, roof, setIsHidden } = props
const canvas = useRecoilValue(canvasState)
const currentObject = useRecoilValue(currentObjectState)
const history = useRef([])
@@ -132,6 +133,7 @@ export function useRoofLinePropertySetting(id, roof) {
canvas.renderAll()
closePopup(id)
+ if (setIsHidden) setIsHidden(false)
}
const nextLineFocus = (selectedLine) => {
diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js
index 5dea9058..dd0ae21f 100644
--- a/src/hooks/surface/useSurfaceShapeBatch.js
+++ b/src/hooks/surface/useSurfaceShapeBatch.js
@@ -19,6 +19,8 @@ import { QLine } from '@/components/fabric/QLine'
import { useRoofFn } from '@/hooks/common/useRoofFn'
import { outerLinePointsState } from '@/store/outerLineAtom'
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
+import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty'
+import { v4 as uuidv4 } from 'uuid'
export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
const { getMessage } = useMessage()
@@ -34,7 +36,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
const { swalFire } = useSwal()
const { addCanvasMouseEventListener, initEvent } = useEvent()
// const { addCanvasMouseEventListener, initEvent } = useContext(EventContext)
- const { closePopup } = usePopup()
+ const { addPopup, closePopup } = usePopup()
const { setSurfaceShapePattern } = useRoofFn()
const applySurfaceShape = (surfaceRefs, selectedType, id) => {
@@ -113,9 +115,13 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
let imageRotate = 0
if (xInversion && !yInversion) {
if (rotate % 180 === 0 || rotate < 0) {
- imageRotate = Math.abs((rotate - 180) % 360)
+ imageRotate = Math.abs(rotate % 360)
} else {
- imageRotate = Math.abs((rotate + 180) % 4)
+ if (rotate < 0) {
+ imageRotate = Math.abs((rotate - 180) % 360)
+ } else {
+ imageRotate = Math.abs((rotate + 180) % 360)
+ }
}
} else if (xInversion && yInversion) {
imageRotate = Math.abs((rotate + 360) % 360)
@@ -132,7 +138,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
}
}
} else {
- imageRotate = (rotate + 360) % 360
+ imageRotate = (rotate + 4) % 4
}
obj.set({ angle: imageRotate })
obj.setCoords() //좌표 변경 적용
@@ -188,10 +194,12 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
setSurfaceShapePattern(batchSurface, roofDisplay.column)
drawDirectionArrow(batchSurface)
- if (setIsHidden) setIsHidden(false)
+ // if (setIsHidden) setIsHidden(false)
// closePopup(id)
initEvent()
+ const popupId = uuidv4()
+ addPopup(popupId, 2, )
})
} else {
if (setIsHidden) setIsHidden(false)
From c93280840975503d2ce3fb33fa4681d4dbd94f58 Mon Sep 17 00:00:00 2001
From: changkyu choi
Date: Thu, 20 Feb 2025 16:07:48 +0900
Subject: [PATCH 43/47] =?UTF-8?q?=ED=94=8C=EB=9E=9C=20=EB=B3=B5=EC=82=AC?=
=?UTF-8?q?=20=EC=8B=9C=20=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88=EA=B8=B0?=
=?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=A0=95=EB=B3=B4=20=EB=B3=B5=EC=82=AC(ba?=
=?UTF-8?q?sicSettingCopySave)=20=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/hooks/option/useCanvasSetting.js | 62 +++++++++++++++++++
src/hooks/usePlan.js | 93 ++++++++++++++++------------
2 files changed, 117 insertions(+), 38 deletions(-)
diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js
index 179b2221..a013ba38 100644
--- a/src/hooks/option/useCanvasSetting.js
+++ b/src/hooks/option/useCanvasSetting.js
@@ -501,6 +501,67 @@ export function useCanvasSetting() {
}
}
+ /**
+ * 기본설정(PlacementShapeSetting) 복사 저장
+ */
+ const basicSettingCopySave = async (params) => {
+ try {
+ const patternData = {
+ objectNo: correntObjectNo,
+ planNo: Number(params.planNo),
+ roofSizeSet: Number(params.roofSizeSet),
+ roofAngleSet: params.roofAngleSet,
+ roofMaterialsAddList: params.roofsData.map((item) => ({
+ planNo: Number(item.planNo),
+ roofApply: item.roofApply,
+ roofSeq: item.roofSeq,
+ roofMatlCd: item.roofMatlCd,
+ roofWidth: item.roofWidth,
+ roofHeight: item.roofHeight,
+ roofHajebichi: item.roofHajebichi,
+ roofGap: item.roofGap,
+ roofLayout: item.roofLayout,
+ roofPitch: item.roofPitch,
+ roofAngle: item.roofAngle,
+ })),
+ }
+
+ await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => {
+ swalFire({ text: getMessage(res.returnMessage) })
+ })
+
+ /* CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */
+ setCanvasSetting({
+ ...basicSetting,
+ roofSizeSet: String(params.roofSizeSet),
+ })
+
+ /* 배치면초기설정 조회 */
+ fetchBasicSettings(Number(params.planNo), null)
+
+ /* 메뉴 설정 */
+ if (['2', '3'].includes(params?.roofSizeSet)) {
+ setMenuNumber(3)
+ setType('surface')
+ setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING)
+ } else {
+ setMenuNumber(2)
+ setType('outline')
+ setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE)
+ }
+
+ /* 모듈 선택 데이터 초기화 */
+ resetModuleSelectionData()
+ moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] })
+ const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE)
+ if (!isModuleExist) {
+ resetSelectedModules()
+ }
+ } catch (error) {
+ swalFire({ text: error.message, icon: 'error' })
+ }
+ }
+
/**
* CanvasSetting 조회 및 초기화
*/
@@ -915,6 +976,7 @@ export function useCanvasSetting() {
setAdsorptionRange,
fetchSettings,
fetchBasicSettings,
+ basicSettingCopySave,
frontSettings,
globalFont,
setGlobalFont,
diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js
index 01579ca7..10bc7e45 100644
--- a/src/hooks/usePlan.js
+++ b/src/hooks/usePlan.js
@@ -5,7 +5,7 @@ import { usePathname, useRouter } from 'next/navigation'
import { useRecoilState, useResetRecoilState } from 'recoil'
-import { canvasState, currentCanvasPlanState, plansState } from '@/store/canvasAtom'
+import { canvasState, currentCanvasPlanState, plansState, canvasSettingState } from '@/store/canvasAtom'
import { useAxios } from '@/hooks/useAxios'
import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
@@ -39,7 +39,8 @@ export function usePlan(params = {}) {
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
- const { fetchBasicSettings } = useCanvasSetting()
+ const { fetchBasicSettings, basicSettingCopySave } = useCanvasSetting()
+ const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
/**
* 마우스 포인터의 가이드라인 제거
@@ -184,41 +185,55 @@ export function usePlan(params = {}) {
objectNo: objectNo,
copyFlg: '0',
}
- await promisePost({ url: '/api/object/add-plan', data: planData })
- .then((res) => {
- let newPlan = {
- id: res.data.canvasId,
- objectNo: objectNo,
- planNo: res.data.planNo,
- userId: userId,
- canvasStatus: '',
- isCurrent: true,
- bgImageName: null,
- mapPositionAddress: null,
- }
+ try {
+ const res = await promisePost({ url: '/api/object/add-plan', data: planData })
+ let newPlan = {
+ id: res.data.canvasId,
+ objectNo: objectNo,
+ planNo: res.data.planNo,
+ userId: userId,
+ canvasStatus: '',
+ isCurrent: true,
+ bgImageName: null,
+ mapPositionAddress: null,
+ }
- if (isInitPlan) {
- /* 초기 플랜 생성인 경우 플랜 목록 초기화 */
- setCurrentCanvasPlan(newPlan)
- setPlans([newPlan])
- } else {
- if (isCopy) {
- /* 복제 플랜 생성인 경우 현재 캔버스 데이터를 복제 */
- newPlan.canvasStatus = currentCanvasData()
- newPlan.bgImageName = currentCanvasPlan?.bgImageName ?? null
- newPlan.mapPositionAddress = currentCanvasPlan?.mapPositionAddress ?? null
- }
- setCurrentCanvasPlan(newPlan)
- setPlans((plans) => [...plans.map((plan) => ({ ...plan, isCurrent: false })), newPlan])
- swalFire({ text: getMessage('plan.message.save') })
- }
+ if (isInitPlan) {
+ /* 초기 플랜 생성인 경우 플랜 목록 초기화 */
+ setCurrentCanvasPlan(newPlan)
+ setPlans([newPlan])
/* 플랜 추가 시 배치면초기설정 정보 조회 */
fetchBasicSettings(newPlan.planNo, null)
- })
- .catch((error) => {
- swalFire({ text: error.response.data.message, icon: 'error' })
- })
+ } else {
+ if (isCopy) {
+ /* 복제 플랜 생성인 경우 현재 캔버스 데이터를 복제 */
+ newPlan.canvasStatus = currentCanvasData()
+ newPlan.bgImageName = currentCanvasPlan?.bgImageName ?? null
+ newPlan.mapPositionAddress = currentCanvasPlan?.mapPositionAddress ?? null
+
+ /* 복제 시 배치면 초기설정 복사 */
+ basicSettingCopySave({
+ ...canvasSetting,
+ planNo: newPlan.planNo,
+ selectedRoofMaterial: {
+ ...canvasSetting.selectedRoofMaterial,
+ planNo: newPlan.planNo,
+ },
+ roofsData: canvasSetting.roofsData.map((roof) => ({
+ ...roof,
+ planNo: newPlan.planNo,
+ })),
+ })
+ }
+ setCurrentCanvasPlan(newPlan)
+ setPlans((plans) => [...plans.map((plan) => ({ ...plan, isCurrent: false })), newPlan])
+
+ swalFire({ text: getMessage('plan.message.save') })
+ }
+ } catch (error) {
+ swalFire({ text: error.response.data.message, icon: 'error' })
+ }
}
/**
@@ -275,7 +290,6 @@ export function usePlan(params = {}) {
const objectNo = floorPlanState.objectNo
//견적서 or 발전시뮬
-
if (pathname !== '/floor-plan') {
await promiseGet({ url: `/api/estimate/${objectNo}/${planNo}/detail` })
.then((res) => {
@@ -304,9 +318,6 @@ export function usePlan(params = {}) {
// 클릭한 플랜 탭으로 이동
setCurrentCanvasPlan(plans.find((plan) => plan.id === newCurrentId))
setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === newCurrentId })))
-
- /* 플랜 이동 시 배치면초기설정 정보 조회 (견적서 메뉴 제외) */
- fetchBasicSettings(planNo, null)
} else {
swalFire({ text: getMessage('estimate.menu.move.valid1') })
}
@@ -494,7 +505,13 @@ export function usePlan(params = {}) {
* @param {string} planNo - 플랜번호
*/
const deleteBasicSettings = async (objectNo, planNo) => {
- await promiseDel({ url: `/api/canvas-management/canvas-basic-settings/delete-basic-settings/${objectNo}/${planNo}` })
+ try {
+ await promiseDel({ url: `/api/canvas-management/canvas-basic-settings/delete-basic-settings/${objectNo}/${planNo}` })
+ } catch (error) {
+ /* 오류를 무시하고 계속 진행 */
+ console.log('Basic settings delete failed or not found:', error)
+ // swalFire({ text: error.message, icon: 'error' })
+ }
}
return {
From a60de8396186942913338e24d6fe0152e7b66e7e 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: Thu, 20 Feb 2025 16:23:28 +0900
Subject: [PATCH 44/47] =?UTF-8?q?-=20=EC=9D=BC=EB=B3=80=EC=A0=84=EC=9C=BC?=
=?UTF-8?q?=EB=A1=9C=20=EB=8F=8C=EC=95=84=EA=B0=80=EA=B8=B0=20=EC=8B=9C=20?=
=?UTF-8?q?active=20color=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/hooks/surface/useRoofLinePropertySetting.js | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/hooks/surface/useRoofLinePropertySetting.js b/src/hooks/surface/useRoofLinePropertySetting.js
index a37c1995..d6615ddf 100644
--- a/src/hooks/surface/useRoofLinePropertySetting.js
+++ b/src/hooks/surface/useRoofLinePropertySetting.js
@@ -26,10 +26,20 @@ export function useRoofLinePropertySetting(props) {
useEffect(() => {
if (currentObject && currentObject.name === 'roofLine') {
+ roof.lines.forEach((line) => {
+ const lineType = line.attributes?.type
+ if (!lineType) {
+ line.set({
+ stroke: '#000000',
+ strokeWidth: 4,
+ })
+ }
+ })
currentObject.set({
stroke: LINE_COLOR.ACTIVE,
strokeWidth: 4,
})
+ canvas.renderAll()
}
}, [currentObject])
@@ -98,11 +108,8 @@ export function useRoofLinePropertySetting(props) {
}
const lastLine = history.current.pop()
- // delete lastLine.attributes
- lastLine.attributes = {
- ...lastLine.attributes,
- type: null,
- }
+ delete lastLine.attributes
+
lastLine.set({
stroke: LINE_COLOR.DEFAULT,
strokeWidth: 4,
From 29f8f22c2676cb23fddc8dea603187a37503b9ec Mon Sep 17 00:00:00 2001
From: basssy
Date: Thu, 20 Feb 2025 16:24:29 +0900
Subject: [PATCH 45/47] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=A1=9C?=
=?UTF-8?q?=EB=94=A9=EB=B0=94=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/floor-plan/CanvasMenu.jsx | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx
index 553b3613..1ed413cf 100644
--- a/src/components/floor-plan/CanvasMenu.jsx
+++ b/src/components/floor-plan/CanvasMenu.jsx
@@ -221,6 +221,7 @@ export default function CanvasMenu(props) {
await reloadCanvasStatus(objectNo, pid)
break
case 5:
+ setIsGlobalLoading(true)
promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => {
if (res.status === 200) {
const estimateDetail = res.data
@@ -230,6 +231,9 @@ export default function CanvasMenu(props) {
setFloorPlanObjectNo({ floorPlanObjectNo: objectNo })
setIsGlobalLoading(false)
router.push(`/floor-plan/estimate/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`)
+ if (pathname === '/floor-plan/estimate/5') {
+ setIsGlobalLoading(false)
+ }
} else {
setIsGlobalLoading(false)
swalFire({ text: getMessage('estimate.menu.move.valid1') })
From 010b34f5fb89d5ad2b02a844750e8060d8173c0a Mon Sep 17 00:00:00 2001
From: "hyojun.choi"
Date: Thu, 20 Feb 2025 16:32:54 +0900
Subject: [PATCH 46/47] =?UTF-8?q?=EB=B0=9C=EC=A0=84=20=EC=8B=9C=EB=AE=AC?=
=?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=EA=B0=81=EB=8F=84=20=EA=B3=84?=
=?UTF-8?q?=EC=82=B0=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 | 66 +++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js
index 248568b5..17f58814 100644
--- a/src/hooks/module/useTrestle.js
+++ b/src/hooks/module/useTrestle.js
@@ -710,7 +710,7 @@ export const useTrestle = () => {
slope,
classType: currentAngleType === 'slope' ? '0' : '1',
angle: getDegreeByChon(slope),
- azimuth: surfaceCompass ?? moduleCompass ?? 0,
+ azimuth: getAzimuth(surface),
moduleList,
}
})
@@ -726,6 +726,70 @@ export const useTrestle = () => {
return { itemList, northArrangement, roofSurfaceList, circuitItemList }
}
+ const getAzimuth = (surface) => {
+ const { moduleCompass, surfaceCompass, direction } = surface
+
+ if (surfaceCompass) {
+ if (surfaceCompass > 180) {
+ return surfaceCompass - 360
+ }
+ return surfaceCompass
+ }
+
+ switch (direction) {
+ case 'south': {
+ if (moduleCompass < 0) {
+ return -1 * moduleCompass
+ } else if (moduleCompass === 0) {
+ return 0
+ } else if (moduleCompass < 180) {
+ return -1 * moduleCompass
+ } else if (moduleCompass === 180) {
+ return 180
+ }
+ }
+ case 'north': {
+ if (moduleCompass < 0) {
+ return -1 * (180 + moduleCompass)
+ } else if (moduleCompass === 0) {
+ return 180
+ } else if (moduleCompass < 180) {
+ return 180 - moduleCompass
+ } else if (moduleCompass === 180) {
+ return 0
+ }
+ }
+ case 'west': {
+ if (moduleCompass > -180 && moduleCompass < -90) {
+ return -180 - (90 + moduleCompass)
+ } else if (moduleCompass < 0) {
+ return 180 - (90 + moduleCompass)
+ } else if (moduleCompass === 0) {
+ return 90
+ } else if (moduleCompass < 180) {
+ return 90 - moduleCompass
+ } else if (moduleCompass === 180) {
+ return -90
+ }
+ }
+ case 'east': {
+ if (moduleCompass < 0) {
+ return -(90 + moduleCompass)
+ } else if (moduleCompass === 0) {
+ return -90
+ } else if (moduleCompass < 90) {
+ return -180 + (90 - moduleCompass)
+ } else if (moduleCompass < 180) {
+ return 180 + (90 - moduleCompass)
+ } else if (moduleCompass === 180) {
+ return 90
+ }
+ }
+ }
+
+ return 0
+ }
+
const getNorthArrangement = () => {
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
let northArrangement = '0'
From 094ac464bfb9726be0b072d184e07638a592a737 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: Thu, 20 Feb 2025 16:43:26 +0900
Subject: [PATCH 47/47] =?UTF-8?q?-=20BackGround=20Image=20show/hide=20?=
=?UTF-8?q?=EA=B8=B0=EB=8A=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/option/useCanvasSetting.js | 2 +-
src/hooks/useCanvas.js | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js
index a013ba38..37161700 100644
--- a/src/hooks/option/useCanvasSetting.js
+++ b/src/hooks/option/useCanvasSetting.js
@@ -939,7 +939,7 @@ export function useCanvasSetting() {
optionName = ['rack', 'smartRack', 'bracket', 'eaveBar', 'halfEaveBar']
break
case 'imageDisplay':
- optionName = ['9']
+ optionName = ['backGroundImage']
break
case 'totalDisplay':
/**
diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js
index 52be5c90..2afbe126 100644
--- a/src/hooks/useCanvas.js
+++ b/src/hooks/useCanvas.js
@@ -3,7 +3,7 @@ import { fabric } from 'fabric'
import { actionHandler, anchorWrapper, polygonPositionHandler } from '@/util/canvas-util'
-import { useRecoilState } from 'recoil'
+import { useRecoilState, useRecoilValue } from 'recoil'
import { canvasSizeState, canvasState, fontSizeState } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
import { QPolygon } from '@/components/fabric/QPolygon'
@@ -15,6 +15,7 @@ import { useAxios } from '@/hooks/useAxios'
import { useFont } from '@/hooks/common/useFont'
import { OBJECT_PROTOTYPE, POLYGON_TYPE, RELOAD_TYPE_PROTOTYPE, SAVE_KEY } from '@/common/common'
import { usePlan } from './usePlan'
+import { imageDisplaySelector } from '@/store/settingAtom'
export function useCanvas(id) {
const [canvas, setCanvas] = useRecoilState(canvasState)
@@ -24,6 +25,7 @@ export function useCanvas(id) {
const [canvasSize] = useRecoilState(canvasSizeState)
const [fontSize] = useRecoilState(fontSizeState)
const { setCanvasForEvent, attachDefaultEventOnCanvas } = useCanvasEvent()
+ const isImageDisplay = useRecoilValue(imageDisplaySelector)
const {} = useFont()
/**
@@ -530,6 +532,7 @@ export function useCanvas(id) {
lockRotation: false,
lockScalingX: false,
lockScalingY: false,
+ visible: isImageDisplay,
})
// image = img
canvas?.add(img)