Merge branch 'qcast-pub' into dev

This commit is contained in:
김민식 2025-02-05 09:55:54 +09:00
commit f7e8655d60
7 changed files with 294 additions and 287 deletions

View File

@ -28,7 +28,6 @@ export default function CanvasFrame() {
const { currentCanvasPlan } = usePlan() const { currentCanvasPlan } = usePlan()
const totalDisplay = useRecoilValue(totalDisplaySelector) // const totalDisplay = useRecoilValue(totalDisplaySelector) //
const { setIsGlobalLoading } = useContext(QcastContext) const { setIsGlobalLoading } = useContext(QcastContext)
const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
const reset = useResetRecoilState(moduleStatisticsState) const reset = useResetRecoilState(moduleStatisticsState)
const loadCanvas = () => { const loadCanvas = () => {
if (canvas) { if (canvas) {

View File

@ -354,22 +354,28 @@ export default function CircuitTrestleSetting({ id }) {
id: uuidv4(), id: uuidv4(),
} }
}) })
const PcsVoltageChkParams = { const pcsVoltageChkParams = {
...getOptYn(), ...getOptYn(),
useModuleItemList: getUseModuleItemList(), useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(), roofSurfaceList: getRoofSurfaceList(),
pcsItemList: getPcsItemList(), pcsItemList: getPcsItemList(),
} }
setSelectedModels(selectedModels) setSelectedModels(selectedModels)
getPcsVoltageChk(PcsVoltageChkParams).then((res) => {}) getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
setAllocationType(ALLOCATION_TYPE.PASSIVITY)
})
} else { } else {
swalFire({ swalFire({
title: '파워컨디셔너를 추가해 주세요.', title: res.result.resultMsg,
type: 'alert', type: 'alert',
confirmFn: () => {
return
},
}) })
return
} }
}) })
} else if (pcsCheck.max) { } else {
const moduleStdQty = selectedModels.reduce((acc, model) => { const moduleStdQty = selectedModels.reduce((acc, model) => {
return acc + parseInt(model.moduleStdQty) return acc + parseInt(model.moduleStdQty)
}, 0) }, 0)
@ -387,9 +393,9 @@ export default function CircuitTrestleSetting({ id }) {
}) })
return return
} }
}
setAllocationType(ALLOCATION_TYPE.PASSIVITY) setAllocationType(ALLOCATION_TYPE.PASSIVITY)
}
} }
// StepUp // StepUp

View File

@ -1,6 +1,7 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider' import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { POLYGON_TYPE } from '@/common/common' import { POLYGON_TYPE } from '@/common/common'
import { useMasterController } from '@/hooks/common/useMasterController' import { useMasterController } from '@/hooks/common/useMasterController'
import { useModule } from '@/hooks/module/useModule'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
@ -11,37 +12,29 @@ import { useRecoilState, useRecoilValue } from 'recoil'
export default function PassivityCircuitAllocation(props) { export default function PassivityCircuitAllocation(props) {
const { const {
tabNum,
setTabNum,
selectedModels, selectedModels,
setSelectedModels, setSelectedModels,
getOptYn: getApiProps, getOptYn: getApiProps,
getUseModuleItemList: getSelectedModuleList, getUseModuleItemList: getSelectedModuleList,
getSelectModelList: getSelectModelList, getSelectModelList: getSelectModelList,
getRoofSurfaceList,
getModelList,
} = props } = props
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { getMessage } = useMessage() const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const selectedModules = useRecoilValue(selectedModuleState) const selectedModules = useRecoilValue(selectedModuleState)
const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
// const [totalWpout, setTotalWpout] = useState(0)
const [selectedPcs, setSelectedPcs] = useState(selectedModels[0]) const [selectedPcs, setSelectedPcs] = useState(selectedModels[0])
// const { header, rows: row } = moduleStatistics const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
const [header, setHeader] = useState(moduleStatistics.header)
const [rows, setRows] = useState(moduleStatistics.rows)
const [footer, setFooter] = useState(['합계'])
const [circuitNumber, setCircuitNumber] = useState(1) const [circuitNumber, setCircuitNumber] = useState(1)
const [targetModules, setTargetModules] = useState([]) const [targetModules, setTargetModules] = useState([])
const { setModuleStatisticsData } = useModule()
const { getPcsManualConfChk } = useMasterController() const { getPcsManualConfChk } = useMasterController()
useEffect(() => { useEffect(() => {
console.log('header, rows', header, rows) console.log('header, rows', header, rows)
console.log('selectedModels', selectedModels) console.log('selectedModels', selectedModels)
// setSurfaceInfo() // setSurfaceInfo()
setTableData() setModuleStatisticsData()
if (!managementState) { if (!managementState) {
setManagementState(managementStateLoaded) setManagementState(managementStateLoaded)
} }
@ -158,7 +151,14 @@ export default function PassivityCircuitAllocation(props) {
} }
const handleCircuitNumberFix = () => { const handleCircuitNumberFix = () => {
let uniqueCircuitNumbers = null let uniqueCircuitNumbers = [
...new Set(
canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuitNumber)
.map((obj) => obj.circuitNumber),
),
]
if (!circuitNumber || circuitNumber === 0) { if (!circuitNumber || circuitNumber === 0) {
swalFire({ swalFire({
text: '회로번호를 1 이상입력해주세요.', text: '회로번호를 1 이상입력해주세요.',
@ -174,15 +174,6 @@ export default function PassivityCircuitAllocation(props) {
}) })
return return
} else if (selectedModels.length > 1) { } else if (selectedModels.length > 1) {
uniqueCircuitNumbers = [
...new Set(
canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuitNumber)
.map((obj) => obj.circuitNumber),
),
]
let result = false let result = false
uniqueCircuitNumbers.forEach((number) => { uniqueCircuitNumbers.forEach((number) => {
if ( if (
@ -335,7 +326,7 @@ export default function PassivityCircuitAllocation(props) {
setTargetModules([]) setTargetModules([])
setCircuitNumber(+circuitNumber + 1) setCircuitNumber(+circuitNumber + 1)
setTableData() setModuleStatisticsData()
}) })
} }
@ -347,100 +338,6 @@ export default function PassivityCircuitAllocation(props) {
} }
} }
const setTableData = () => {
const tempHeader = [
{ name: getMessage('simulator.table.sub1'), prop: 'name' },
{ name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' },
...selectedModules.itemList.map((module) => {
return {
name: module.itemNm,
prop: module.itemId,
}
}),
{ name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
]
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
const surfaceIds = surfaces.map((surface) => surface.parentId)
const surfaceObjects = {}
const rows = surfaces.map((surface) => {
const moduleObject = {}
surfaceObjects[surface.id] = {
roofSurface: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText,
circuit: '-',
amount: 0,
wpOut: 0,
circuits: {},
}
surface.modules.forEach((module) => {
if (!surfaceObjects[surface.id][module.moduleInfo.itemId]) {
//
surfaceObjects[surface.id][module.moduleInfo.itemId] = 0 //
}
surfaceObjects[surface.id][module.moduleInfo.itemId]++
surfaceObjects[surface.id].wpOut += +module.moduleInfo.wpOut
if (module.circuit) {
if (!surfaceObjects[surface.id].circuits[module.circuitNumber]) {
surfaceObjects[surface.id].circuits[module.circuitNumber] = {
circuit: module.circuitNumber,
wpOut: 0,
circuits: { wpOut: 0 },
}
if (!surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]) {
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId] = 0
}
}
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]++
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits.wpOut += +module.moduleInfo.wpOut
surfaceObjects[surface.id].wpOut -= +module.moduleInfo.wpOut
surfaceObjects[surface.id][module.moduleInfo.itemId]--
}
})
})
console.log('rows', rows)
console.log('surfaceObjects', surfaceObjects)
let tempRows = []
Object.keys(surfaceObjects).forEach((key) => {
let tempRow = {
name: surfaceObjects[key].roofSurface,
circuit: surfaceObjects[key].circuit,
wpOut: surfaceObjects[key].wpOut,
}
selectedModules.itemList.forEach((module) => {
tempRow[module.itemId] = surfaceObjects[key][module.itemId]
})
tempRows.push(tempRow)
Object.keys(surfaceObjects[key].circuits).forEach((circuit) => {
let row = {
name: surfaceObjects[key].roofSurface,
circuit: surfaceObjects[key].circuits[circuit].circuit,
wpOut: surfaceObjects[key].circuits[circuit].circuits.wpOut,
}
selectedModules.itemList.forEach((module) => {
row[module.itemId] = surfaceObjects[key].circuits[circuit].circuits[module.itemId]
})
tempRows.push(row)
})
})
const tempFooter = {
name: '총합',
circuit: '-',
wpOut: tempRows.reduce((acc, row) => acc + row.wpOut, 0),
}
selectedModules.itemList.forEach((module) => {
tempFooter[module.itemId] = tempRows.reduce((acc, row) => acc + row[module.itemId], 0)
})
setHeader(tempHeader)
setRows(tempRows.filter((row) => row.wpOut !== 0))
setFooter(tempFooter)
setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter })
}
const initSelectedPcsCircuitNumber = () => { const initSelectedPcsCircuitNumber = () => {
swalFire({ swalFire({
title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.init.info'), title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.init.info'),
@ -516,9 +413,7 @@ export default function PassivityCircuitAllocation(props) {
<tr> <tr>
{header.map((header, i) => ( {header.map((header, i) => (
<td className="al-c" key={'footer' + i}> <td className="al-c" key={'footer' + i}>
{typeof footer[header.prop] === 'number' {footer[header.prop]}
? footer[header.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 })
: footer[header.prop]}
</td> </td>
))} ))}
</tr> </tr>

View File

@ -45,175 +45,188 @@ export default function ContextRoofAllocationSetting(props) {
return ( return (
<WithDraggable isShow={true} pos={pos}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lr mount`}> <div className={`modal-pop-wrap lr mount`}>
<div className="modal-head modal-handle"> {currentRoofList && (
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1> <>
<button className="modal-close" onClick={() => closePopup(id)}> <div className="modal-head modal-handle">
닫기 <h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
</button> <button className="modal-close" onClick={() => closePopup(id)}>
</div> 닫기
<div className="modal-body"> </button>
<div className="properties-guide">{getMessage('modal.roof.alloc.info')}</div>
<div className="allocation-select-wrap">
<span>{getMessage('modal.roof.alloc.select.roof.material')}</span>
<div className="grid-select">
<QSelectBox
options={roofMaterials}
value={roofMaterials[0]}
onChange={(e) => {
// const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
setCurrentRoofMaterial(e)
}}
showKey={'roofMatlNm'}
sourceKey={'roofMatlCd'}
targetKey={'roofMatlCd'}
/>
</div> </div>
<button <div className="modal-body">
className="allocation-edit" <div className="properties-guide">{getMessage('modal.roof.alloc.info')}</div>
onClick={() => { <div className="allocation-select-wrap">
onAddRoofMaterial() <span>{getMessage('modal.roof.alloc.select.roof.material')}</span>
}} <div className="grid-select">
> <QSelectBox
<i className="edit-ico"></i> options={roofMaterials}
{getMessage('modal.common.add')} value={roofMaterials[0]}
</button> onChange={(e) => {
</div> // const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
<div className="grid-option-wrap"> setCurrentRoofMaterial(e)
{currentRoofList.length > 0 && }}
currentRoofList.map((roof, index) => { showKey={'roofMatlNm'}
return ( sourceKey={'roofMatlCd'}
<div className="grid-option-box" key={index}> targetKey={'roofMatlCd'}
<div className="d-check-radio pop no-text"> />
<input type="radio" name="radio01" checked={roof.selected && 'checked'} readOnly={true} /> </div>
<label <button
htmlFor="ra01" className="allocation-edit"
onClick={(e) => { onClick={() => {
handleDefaultRoofMaterial(index) onAddRoofMaterial()
}} }}
></label> >
</div> <i className="edit-ico"></i>
<div className="grid-option-block-form"> {getMessage('modal.common.add')}
<div className="block-box"> </button>
<div className="flex-ment"> </div>
<div className="grid-select" style={{ width: '248px' }}> <div className="grid-option-overflow">
<QSelectBox <div className="grid-option-wrap">
options={roofMaterials} {currentRoofList.map((roof, index) => {
value={roof} return (
showKey={'roofMatlNm'} <div className="grid-option-box" key={index}>
sourceKey={'roofMatlCd'} <div className="d-check-radio pop no-text">
targetKey={'roofMatlCd'} <input type="radio" name="radio01" checked={roof.selected && 'checked'} readOnly={true} />
onChange={(e) => handleChangeRoofMaterial(e, index)} <label
/> htmlFor="ra01"
</div> onClick={(e) => {
{index === 0 && <span className="dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>} handleDefaultRoofMaterial(index)
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>} }}
></label>
</div> </div>
</div> <div className="grid-option-block-form">
<div className="block-box"> <div className="block-box">
<div className="flex-ment">
<span>{getMessage('slope')}</span>
<div className="input-grid" style={{ width: '214px' }}>
<input
type="text"
className="input-origin block"
onChange={(e) => {
handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
}}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
</div>
<span>{pitchText}</span>
</div>
</div>
{(roof.widAuth || roof.lenAuth) && (
<div className="block-box">
{roof.widAuth && (
<div className="flex-ment"> <div className="flex-ment">
<span>W</span> <div className="grid-select">
<div className="input-grid" style={{ width: '100px' }}> <QSelectBox
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} /> options={roofMaterials}
value={roof}
showKey={'roofMatlNm'}
sourceKey={'roofMatlCd'}
targetKey={'roofMatlCd'}
onChange={(e) => handleChangeRoofMaterial(e, index)}
/>
</div> </div>
{index === 0 && <span className="absol dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>}
{index !== 0 && (
<span className="absol">
<button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>
</span>
)}
</div> </div>
)} </div>
{roof.lenAuth && ( <div className="block-box">
<div className="flex-ment"> <div className="flex-ment">
<span>L</span> <span>{getMessage('slope')}</span>
<div className="input-grid" style={{ width: '100px' }}> <div className="input-grid">
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} /> <input
type="text"
className="input-origin block"
onChange={(e) => {
handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
}}
defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle}
/>
</div> </div>
<span className="absol">{pitchText}</span>
</div> </div>
)} </div>
</div> {(roof.widAuth || roof.lenAuth) && (
)} <>
{(roof.raftAuth || roof.roofPchAuth) && ( {roof.widAuth && (
<div className="block-box"> <div className="block-box">
{roof.raftAuth && ( <div className="flex-ment">
<div className="block-box"> <span>W</span>
<div className="flex-ment"> <div className="input-grid">
<span>{getMessage('modal.placement.initial.setting.rafter')}</span> <input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
{raftCodes.length > 0 && ( </div>
<div className="grid-select" style={{ width: '160px' }}>
<QSelectBox
options={raftCodes}
value={roof}
showKey={'clCodeNm'}
sourceKey={'clCode'}
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
/>
</div> </div>
)}
</div>
</div>
)}
{roof.roofPchAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('hajebichi')}</span>
<div className="input-grid" style={{ width: '84px' }}>
<input
type="text"
className="input-origin block"
value={parseInt(roof.hajebichi)}
readOnly={roof.roofPchAuth === 'R'}
/>
</div> </div>
</div> )}
</div> {roof.lenAuth && (
<div className="block-box">
<div className="flex-ment">
<span>L</span>
<div className="input-grid">
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} />
</div>
</div>
</div>
)}
</>
)} )}
</div> {(roof.raftAuth || roof.roofPchAuth) && (
)} <>
<div className="block-box"> {roof.raftAuth && (
<div className="icon-btn-wrap"> <div className="block-box">
<button <div className="flex-ment">
className={roof.layout === ROOF_MATERIAL_LAYOUT.PARALLEL ? 'act' : ''} <span>{getMessage('modal.placement.initial.setting.rafter')}</span>
onClick={() => { {raftCodes.length > 0 && (
handleChangeLayout(ROOF_MATERIAL_LAYOUT.PARALLEL, index) <div className="grid-select">
}} <QSelectBox
> options={raftCodes}
{getMessage('modal.roof.alloc.select.parallel')} value={roof}
<i className="allocation01"></i> showKey={'clCodeNm'}
</button> sourceKey={'clCode'}
<button targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
className={roof.layout === ROOF_MATERIAL_LAYOUT.STAIRS ? 'act' : ''} />
onClick={() => { </div>
handleChangeLayout(ROOF_MATERIAL_LAYOUT.STAIRS, index) )}
}} </div>
> </div>
{getMessage('modal.roof.alloc.select.stairs')} <i className="allocation02"></i> )}
</button> {roof.roofPchAuth && (
<div className="block-box">
<div className="flex-ment">
<span>{getMessage('hajebichi')}</span>
<div className="input-grid">
<input
type="text"
className="input-origin block"
value={parseInt(roof.hajebichi)}
readOnly={roof.roofPchAuth === 'R'}
/>
</div>
</div>
</div>
)}
</>
)}
<div className="block-box">
<div className="icon-btn-wrap">
<button
className={roof.layout === ROOF_MATERIAL_LAYOUT.PARALLEL ? 'act' : ''}
onClick={() => {
handleChangeLayout(ROOF_MATERIAL_LAYOUT.PARALLEL, index)
}}
>
{getMessage('modal.roof.alloc.select.parallel')}
<i className="allocation01"></i>
</button>
<button
className={roof.layout === ROOF_MATERIAL_LAYOUT.STAIRS ? 'act' : ''}
onClick={() => {
handleChangeLayout(ROOF_MATERIAL_LAYOUT.STAIRS, index)
}}
>
{getMessage('modal.roof.alloc.select.stairs')} <i className="allocation02"></i>
</button>
</div>
</div>
</div> </div>
</div> </div>
</div> )
</div> })}
) </div>
})} </div>
</div> <div className="grid-btn-wrap">
<div className="grid-btn-wrap"> <button className="btn-frame modal act" onClick={handleSaveContext}>
<button className="btn-frame modal act" onClick={handleSaveContext}> {getMessage('modal.roof.alloc.apply')}
{getMessage('modal.roof.alloc.apply')} </button>
</button> </div>
</div> </div>
</div> </>
)}
<div className="modal-foot modal-handle"></div> <div className="modal-foot modal-handle"></div>
</div> </div>
</WithDraggable> </WithDraggable>

View File

@ -1,12 +1,14 @@
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common' import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util' import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
import { useRecoilValue } from 'recoil' import { useRecoilValue, useSetRecoilState } from 'recoil'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import { useSwal } from '../useSwal' import { useSwal } from '../useSwal'
import { useModuleBasicSetting } from './useModuleBasicSetting' import { useModuleBasicSetting } from './useModuleBasicSetting'
import { useMessage } from '../useMessage' import { useMessage } from '../useMessage'
import { selectedModuleState } from '@/store/selectedModuleOptions'
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
export const MODULE_REMOVE_TYPE = { export const MODULE_REMOVE_TYPE = {
LEFT: 'left', LEFT: 'left',
@ -35,6 +37,8 @@ export function useModule() {
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { checkModuleDisjointObjects } = useModuleBasicSetting() const { checkModuleDisjointObjects } = useModuleBasicSetting()
const selectedModules = useRecoilValue(selectedModuleState)
const setModuleStatistics = useSetRecoilState(moduleStatisticsState)
const moduleMove = (length, direction) => { const moduleMove = (length, direction) => {
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴 const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
@ -929,6 +933,92 @@ export function useModule() {
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name)) .filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
} }
const setModuleStatisticsData = () => {
const tempHeader = [
{ name: getMessage('simulator.table.sub1'), prop: 'name' },
{ name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' },
...selectedModules.itemList.map((module) => {
return {
name: module.itemNm,
prop: module.itemId,
}
}),
{ name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
]
const surfaceObjects = {}
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
const rows = surfaces.map((surface) => {
surfaceObjects[surface.id] = {
roofSurface: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText,
circuit: '-',
amount: 0,
wpOut: 0,
circuits: {},
}
surface.modules.forEach((module) => {
if (!surfaceObjects[surface.id][module.moduleInfo.itemId]) {
// 지붕면에 모듈 존재 여부
surfaceObjects[surface.id][module.moduleInfo.itemId] = 0 // 모듈 초기화
}
surfaceObjects[surface.id][module.moduleInfo.itemId]++
surfaceObjects[surface.id].wpOut += +module.moduleInfo.wpOut
if (module.circuit) {
if (!surfaceObjects[surface.id].circuits[module.circuitNumber]) {
surfaceObjects[surface.id].circuits[module.circuitNumber] = {
circuit: module.circuitNumber,
wpOut: 0,
circuits: { wpOut: 0 },
}
if (!surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]) {
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId] = 0
}
}
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId]++
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits.wpOut += +module.moduleInfo.wpOut
surfaceObjects[surface.id].wpOut -= +module.moduleInfo.wpOut
surfaceObjects[surface.id][module.moduleInfo.itemId]--
}
})
})
let tempRows = []
Object.keys(surfaceObjects).forEach((key) => {
let tempRow = {
name: surfaceObjects[key].roofSurface,
circuit: surfaceObjects[key].circuit,
wpOut: parseInt((surfaceObjects[key].wpOut / 1000).toFixed(3)),
}
selectedModules.itemList.forEach((module) => {
tempRow[module.itemId] = surfaceObjects[key][module.itemId]
})
tempRows.push(tempRow)
Object.keys(surfaceObjects[key].circuits).forEach((circuit) => {
let row = {
name: surfaceObjects[key].roofSurface,
circuit: surfaceObjects[key].circuits[circuit].circuit,
wpOut: parseInt((surfaceObjects[key].circuits[circuit].circuits.wpOut / 1000).toFixed(3)),
}
selectedModules.itemList.forEach((module) => {
row[module.itemId] = surfaceObjects[key].circuits[circuit].circuits[module.itemId]
})
tempRows.push(row)
})
})
const tempFooter = {
name: getMessage('modal.panel.batch.statistic.total'),
circuit: '-',
wpOut: tempRows.reduce((acc, row) => acc + row.wpOut, 0),
}
selectedModules.itemList.forEach((module) => {
tempFooter[module.itemId] = tempRows.reduce((acc, row) => acc + row[module.itemId], 0)
})
setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter })
}
return { return {
moduleMove, moduleMove,
moduleMultiMove, moduleMultiMove,
@ -942,5 +1032,6 @@ export function useModule() {
muduleRowInsert, muduleRowInsert,
modulesRemove, modulesRemove,
alignModule, alignModule,
setModuleStatisticsData,
} }
} }

View File

@ -2468,7 +2468,7 @@ export function useModuleBasicSetting(tabNum) {
...surface, ...surface,
name: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, // 지붕면 name: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, // 지붕면
// powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }), // powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }),
wpOut: wpOut, wpOut: (wpOut / 1000).toFixed(3),
} }
}) })
@ -2481,7 +2481,7 @@ export function useModuleBasicSetting(tabNum) {
}), }),
{ name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' }, { name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
] ]
let footer = ['합계'] let footer = [getMessage('modal.panel.batch.statistic.total')]
let footerData = {} let footerData = {}
rows.forEach((row) => { rows.forEach((row) => {
Object.keys(moduleInfo).map((key) => { Object.keys(moduleInfo).map((key) => {
@ -2492,7 +2492,7 @@ export function useModuleBasicSetting(tabNum) {
Object.keys(footerData).forEach((key) => { Object.keys(footerData).forEach((key) => {
footer.push(footerData[key]) footer.push(footerData[key])
}) })
footer.push(totalWpout) footer.push((totalWpout / 1000).toFixed(3))
console.log({ header: header, rows, footer: footer }) console.log({ header: header, rows, footer: footer })
setModuleStatistics({ header: header, rows, footer: footer }) setModuleStatistics({ header: header, rows, footer: footer })
} }

View File

@ -40,7 +40,10 @@ export const moduleStatisticsState = atom({
{ name: `발전량(kW)`, prop: 'amount' }, { name: `발전량(kW)`, prop: 'amount' },
], ],
rows: [], rows: [],
footer: ['합계', '0'], footer: [
{ name: '-', prop: 'name' },
{ name: 0, prop: 'amount' },
],
}, },
dangerouslyAllowMutability: true, dangerouslyAllowMutability: true,
}) })