From a03b38227c21d8c9bed71f9f8535fa4e5256159b 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 14:30:40 +0900 Subject: [PATCH 1/3] =?UTF-8?q?-=20console.log=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCirCuitTrestle.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index aacc7e5d..8e73d59d 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -62,7 +62,6 @@ export function useCircuitTrestle() { // 사용된 모듈아이템 목록 const getUseModuleItemList = () => { - console.log('🚀 ~ getUseModuleItemList ~ selectedModules:', selectedModules) return selectedModules?.itemList?.map((m) => { return { itemId: m.itemId, From f621a9e7bb56eea2da46f31910511ad08fb4d947 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 14:31:26 +0900 Subject: [PATCH 2/3] =?UTF-8?q?-=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 2 ++ src/locales/ko.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/locales/ja.json b/src/locales/ja.json index e78f57d7..2baee42f 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1013,6 +1013,8 @@ "module.place.select.one.module": "モジュールは1つだけ選択してください。", "batch.canvas.delete.all": "配置面の内容をすべて削除しますか?", "module.not.found": "インストールモジュールを選択してください。", + "module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.(JA)", + "module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.(JA)", "construction.length.difference": "屋根面工法をすべて選択してください。", "menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。", "batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。", diff --git a/src/locales/ko.json b/src/locales/ko.json index f898200a..563ab7f2 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1014,6 +1014,8 @@ "module.place.select.one.module": "모듈은 하나만 선택해주세요.", "batch.canvas.delete.all": "배치면 내용을 전부 삭제하시겠습니까?", "module.not.found": "모듈을 선택하세요.", + "module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.", + "module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.", "construction.length.difference": "지붕면 공법을 전부 선택해주세요.", "menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다.", "batch.object.outside.roof": "오브젝트는 지붕내에 설치해야 합니다.", From 48401a06df56a5e06a07c1664fac6b28c08f460d 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 14:32:37 +0900 Subject: [PATCH 3/3] =?UTF-8?q?-=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20=EB=B0=8F=20=ED=95=A0=EB=8B=B9=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/CircuitTrestleSetting.jsx | 111 ++++++++-- .../step/type/PassivityCircuitAllocation.jsx | 201 +++++++++++++++++- 2 files changed, 292 insertions(+), 20 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index a7f26838..0c391c05 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -1,5 +1,5 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' -import { useState, useEffect, useContext } from 'react' +import { useState, useEffect, useContext, useRef } from 'react' import PowerConditionalSelect from '@/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect' import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp' import { useMessage } from '@/hooks/useMessage' @@ -43,7 +43,7 @@ export default function CircuitTrestleSetting({ id }) { const [circuitAllocationType, setCircuitAllocationType] = useState(1) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const selectedModules = useRecoilValue(selectedModuleState) - const { getPcsAutoRecommendList, getPcsVoltageChk, getPcsVoltageStepUpList } = useMasterController() + const { getPcsAutoRecommendList, getPcsVoltageChk, getPcsVoltageStepUpList, getPcsManualConfChk } = useMasterController() // 회로할당(승합설정)에서 선택된 값들을 저장할 상태 추가 const [selectedStepUpValues, setSelectedStepUpValues] = useState({}) @@ -53,10 +53,9 @@ export default function CircuitTrestleSetting({ id }) { const [stepUpListData, setStepUpListData] = useState([]) const [seletedOption, setSeletedOption] = useState(null) const { setModuleStatisticsData } = useCircuitTrestle() - const { handleCanvasToPng } = useImgLoader() const { saveCanvas } = usePlan() - + const passivityCircuitAllocationRef = useRef() const { setIsGlobalLoading } = useContext(QcastContext) const { @@ -385,6 +384,7 @@ export default function CircuitTrestleSetting({ id }) { obj.pcsItemId = null obj.circuitNumber = null }) + setSelectedModels(JSON.parse(JSON.stringify(selectedModels)).map((model) => (model.isUsed = false))) if (allocationType === ALLOCATION_TYPE.PASSIVITY) { setAllocationType(ALLOCATION_TYPE.AUTO) @@ -479,16 +479,18 @@ export default function CircuitTrestleSetting({ id }) { } const handleStepUp = () => { - const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) - if (notAllocationModules.length > 0) { - swalFire({ - title: getMessage('not.allocation.exist.module'), - type: 'alert', - }) - return - } else { - setTabNum(2) - } + handlePassivityAllocationCkeck() + // const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) + // if (notAllocationModules.length > 0) { + // swalFire({ + // title: getMessage('not.allocation.exist.module'), + // type: 'alert', + // }) + // return + // } else { + // passivityCircuitAllocationRef.current.onApply() + // setTabNum(2) + // } } // 닫기 버튼 클릭 시 처리하는 함수 추가 @@ -510,6 +512,83 @@ export default function CircuitTrestleSetting({ id }) { closePopup(id) } + const handlePassivityAllocationCkeck = () => { + let pcsCount = {} + let result = {} + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE) + .forEach((module) => { + 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 params = { + ...getOptYn(), + useModuleItemList: getUseModuleItemList(), + roofSurfaceList: getRoofSurfaceList(), + pcsItemList: selectedModels.map((model, index) => { + return { + pcsMkrCd: model.pcsMkrCd, + pcsSerCd: model.pcsSerCd, + itemId: model.itemId, + itemNm: model.itemNm, + goodsNo: model.goodsNo, + serQtyList: [ + { + serQty: result[index + 1].maxValue, + paralQty: result[index + 1].count, + rmdYn: 'Y', + usePossYn: 'Y', + 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, + } + }), + } + }), + }, + ], + } + }), + } + + getPcsManualConfChk(params).then((res) => { + if (res?.resultCode === 'E') { + swalFire({ + text: res.resultMsg, + type: 'alert', + icon: 'warning', + }) + return + } else { + setTabNum(2) + } + }) + } + return (
@@ -531,7 +610,9 @@ export default function CircuitTrestleSetting({ id }) {
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && } - {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && } + {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( + + )} {tabNum === 2 && } {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 ( <>