406 lines
13 KiB
JavaScript
406 lines
13 KiB
JavaScript
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
|
import { POLYGON_TYPE } from '@/common/common'
|
|
import { canvasState } from '@/store/canvasAtom'
|
|
import {
|
|
makersState,
|
|
modelsState,
|
|
moduleStatisticsState,
|
|
pcsCheckState,
|
|
selectedMakerState,
|
|
selectedModelsState,
|
|
seriesState,
|
|
} from '@/store/circuitTrestleAtom'
|
|
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
|
import { useContext, useEffect } from 'react'
|
|
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
|
import { useMessage } from './useMessage'
|
|
import Big from 'big.js'
|
|
|
|
export function useCircuitTrestle(executeEffect = false) {
|
|
const [makers, setMakers] = useRecoilState(makersState)
|
|
const [selectedMaker, setSelectedMaker] = useRecoilState(selectedMakerState)
|
|
const [series, setSeries] = useRecoilState(seriesState)
|
|
const [models, setModels] = useRecoilState(modelsState)
|
|
const [selectedModels, setSelectedModels] = useRecoilState(selectedModelsState)
|
|
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
|
|
const selectedModules = useRecoilValue(selectedModuleState)
|
|
const { managementState } = useContext(GlobalDataContext)
|
|
const canvas = useRecoilValue(canvasState)
|
|
const setModuleStatistics = useSetRecoilState(moduleStatisticsState)
|
|
const resetModuleStatistics = useResetRecoilState(moduleStatisticsState)
|
|
const { getMessage } = useMessage()
|
|
|
|
useEffect(() => {
|
|
if (selectedModules && Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData()
|
|
}, [selectedModules])
|
|
|
|
const getOptYn = () => {
|
|
return {
|
|
maxConnYn: pcsCheck.max ? 'Y' : 'N',
|
|
smpCirYn: pcsCheck.division ? 'Y' : 'N',
|
|
coldZoneYn: managementState?.coldRegionFlg === '1' ? 'Y' : 'N',
|
|
}
|
|
}
|
|
// PCS 아이템 목록
|
|
const getPcsItemList = (isMultiModule = false) => {
|
|
if (isMultiModule) {
|
|
return models
|
|
.filter((model) => model.pcsTpCd !== 'INDFCS')
|
|
.map((model) => {
|
|
return {
|
|
itemId: model.itemId,
|
|
pcsMkrCd: model.pcsMkrCd,
|
|
pcsSerCd: model.pcsSerCd,
|
|
}
|
|
})
|
|
}
|
|
return models.map((model) => {
|
|
return {
|
|
itemId: model.itemId,
|
|
pcsMkrCd: model.pcsMkrCd,
|
|
pcsSerCd: model.pcsSerCd,
|
|
}
|
|
})
|
|
}
|
|
|
|
// 선택된 PCS 아이템 목록
|
|
const getSelectedPcsItemList = (isMultiModule = false) => {
|
|
if (isMultiModule) {
|
|
return selectedModels
|
|
.filter((model) => model.pcsTpCd !== 'INDFCS')
|
|
.map((model) => {
|
|
return {
|
|
itemId: model.itemId,
|
|
pcsMkrCd: model.pcsMkrCd,
|
|
pcsSerCd: model.pcsSerCd,
|
|
}
|
|
})
|
|
}
|
|
return selectedModels.map((model) => {
|
|
return {
|
|
itemId: model.itemId,
|
|
pcsMkrCd: model.pcsMkrCd,
|
|
pcsSerCd: model.pcsSerCd,
|
|
}
|
|
})
|
|
}
|
|
|
|
// 사용된 모듈아이템 목록
|
|
const getUseModuleItemList = () => {
|
|
return selectedModules?.itemList?.map((m) => {
|
|
return {
|
|
itemId: m.itemId,
|
|
mixMatlNo: m.mixMatlNo,
|
|
}
|
|
})
|
|
}
|
|
|
|
// 지붕면 목록
|
|
const getRoofSurfaceList = () => {
|
|
const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
|
roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
|
|
|
|
const result = roofSurfaceList
|
|
.map((obj) => {
|
|
return {
|
|
roofSurfaceId: obj.id,
|
|
roofSurface: canvas
|
|
.getObjects()
|
|
.filter((o) => o.id === obj.parentId)[0]
|
|
.directionText.replace(/[0-9]/g, ''),
|
|
roofSurfaceIncl: +canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch,
|
|
moduleList: getModuleList(obj).map((module) => {
|
|
return {
|
|
itemId: module.moduleInfo.itemId,
|
|
circuit: module.circuitNumber ? module.circuitNumber : null,
|
|
pcsItemId: module.circuit ? module.circuit?.pcsItemId : null,
|
|
uniqueId: module.id ? module.id : null,
|
|
}
|
|
}),
|
|
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
|
|
}
|
|
})
|
|
.filter((surface) => surface.moduleList.length > 0)
|
|
|
|
// result 배열에서 roofSurface 값을 기준으로 순서대로 정렬한다.
|
|
|
|
if (pcsCheck.division) {
|
|
return groupSort(result)
|
|
} else {
|
|
return result
|
|
}
|
|
}
|
|
|
|
const groupSort = (arr) => {
|
|
const result = []
|
|
const seen = new Set() // (roofSurface + "|" + roofSurfaceIncl)
|
|
|
|
let remaining = [...arr]
|
|
|
|
while (remaining.length > 0) {
|
|
const { roofSurface, roofSurfaceIncl } = remaining[0]
|
|
const key = `${roofSurface}|${roofSurfaceIncl}`
|
|
|
|
// 해당 그룹 추출
|
|
const group = remaining.filter((item) => item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl)
|
|
|
|
// 이미 처리했는지 체크 후 저장
|
|
if (!seen.has(key)) {
|
|
result.push(...group)
|
|
seen.add(key)
|
|
}
|
|
|
|
// remaining에서 제거
|
|
remaining = remaining.filter((item) => !(item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl))
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// 모듈 목록
|
|
const getModuleList = (surface) => {
|
|
let moduleList = []
|
|
let [xObj, yObj] = [{}, {}]
|
|
let [xPoints, yPoints] = [[], []]
|
|
surface.modules.forEach((module) => {
|
|
if (!xObj[module.left]) {
|
|
xObj[module.left] = module.left
|
|
xPoints.push(module.left)
|
|
}
|
|
if (!yObj[module.top]) {
|
|
yObj[module.top] = module.top
|
|
yPoints.push(module.top)
|
|
}
|
|
})
|
|
switch (surface.direction) {
|
|
case 'south':
|
|
xPoints.sort((a, b) => a - b)
|
|
yPoints.sort((a, b) => b - a)
|
|
yPoints.forEach((y, index) => {
|
|
let temp = surface.modules.filter((m) => m.top === y)
|
|
if (index % 2 === 0) {
|
|
temp.sort((a, b) => a.left - b.left)
|
|
} else {
|
|
temp.sort((a, b) => b.left - a.left)
|
|
}
|
|
moduleList = [...moduleList, ...temp]
|
|
})
|
|
break
|
|
case 'north':
|
|
xPoints.sort((a, b) => b - a)
|
|
yPoints.sort((a, b) => a - b)
|
|
yPoints.forEach((y, index) => {
|
|
let temp = surface.modules.filter((m) => m.top === y)
|
|
if (index % 2 === 0) {
|
|
temp.sort((a, b) => b.left - a.left)
|
|
} else {
|
|
temp.sort((a, b) => a.left - b.left)
|
|
}
|
|
moduleList = [...moduleList, ...temp]
|
|
})
|
|
break
|
|
case 'west':
|
|
xPoints.sort((a, b) => a - b)
|
|
yPoints.sort((a, b) => a - b)
|
|
xPoints.forEach((x, index) => {
|
|
let temp = surface.modules.filter((m) => m.left === x)
|
|
if (index % 2 === 0) {
|
|
temp.sort((a, b) => a.top - b.top)
|
|
} else {
|
|
temp.sort((a, b) => b.top - a.top)
|
|
}
|
|
moduleList = [...moduleList, ...temp]
|
|
})
|
|
break
|
|
case 'east':
|
|
xPoints.sort((a, b) => b - a)
|
|
yPoints.sort((a, b) => b - a)
|
|
xPoints.forEach((x, index) => {
|
|
let temp = surface.modules.filter((m) => m.left === x)
|
|
if (index % 2 === 0) {
|
|
temp.sort((a, b) => b.top - a.top)
|
|
} else {
|
|
temp.sort((a, b) => a.top - b.top)
|
|
}
|
|
moduleList = [...moduleList, ...temp]
|
|
})
|
|
break
|
|
default:
|
|
return []
|
|
}
|
|
return moduleList
|
|
}
|
|
|
|
const removeNotAllocationModules = () => {
|
|
const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
|
|
canvas.remove(...notAllocationModules)
|
|
canvas.renderAll()
|
|
}
|
|
|
|
const setModuleStatisticsData = () => {
|
|
console.log('selectedModules', selectedModules)
|
|
if (
|
|
!selectedModules ||
|
|
!selectedModules?.itemList ||
|
|
selectedModules?.itemList?.length === 0 ||
|
|
canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length === 0
|
|
) {
|
|
resetModuleStatistics()
|
|
return
|
|
}
|
|
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)
|
|
|
|
surfaces.forEach((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] = Big(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] = Big(
|
|
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits[module.moduleInfo.itemId],
|
|
)
|
|
.plus(1)
|
|
.toNumber()
|
|
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits.wpOut = Big(
|
|
surfaceObjects[surface.id].circuits[module.circuitNumber].circuits.wpOut,
|
|
)
|
|
.plus(+module.moduleInfo.wpOut)
|
|
.toNumber()
|
|
surfaceObjects[surface.id].wpOut = Big(surfaceObjects[surface.id].wpOut).minus(+module.moduleInfo.wpOut).toNumber()
|
|
surfaceObjects[surface.id][module.moduleInfo.itemId] = Big(surfaceObjects[surface.id][module.moduleInfo.itemId]).minus(1).toNumber()
|
|
}
|
|
})
|
|
})
|
|
let tempRows = []
|
|
Object.keys(surfaceObjects).forEach((key) => {
|
|
let tempRow = {
|
|
name: surfaceObjects[key].roofSurface,
|
|
circuit: surfaceObjects[key].circuit,
|
|
wpOut: parseFloat(Big(surfaceObjects[key].wpOut).div(1000).toNumber()),
|
|
}
|
|
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: parseFloat(Big(surfaceObjects[key].circuits[circuit].circuits.wpOut).div(1000).toNumber()),
|
|
}
|
|
selectedModules.itemList.forEach((module) => {
|
|
row[module.itemId] = surfaceObjects[key].circuits[circuit].circuits[module.itemId]
|
|
})
|
|
tempRows.push(row)
|
|
})
|
|
})
|
|
let ftWpOut = 0
|
|
tempRows.forEach((row) => {
|
|
ftWpOut = Big(ftWpOut).plus(Big(row.wpOut)).toNumber()
|
|
})
|
|
|
|
const tempFooter = {
|
|
name: getMessage('modal.panel.batch.statistic.total'),
|
|
circuit: '-',
|
|
wpOut: ftWpOut,
|
|
}
|
|
selectedModules.itemList.forEach((module) => {
|
|
let wpOut = 0
|
|
tempRows.forEach((row) => {
|
|
if (row[module.itemId]) {
|
|
wpOut = Big(wpOut)
|
|
.plus(Big(row[module.itemId] ?? 0))
|
|
.toNumber()
|
|
}
|
|
})
|
|
tempFooter[module.itemId] = wpOut
|
|
})
|
|
canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
|
setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter })
|
|
}
|
|
|
|
const resetCircuits = () => {
|
|
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
|
const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
|
|
|
|
surfaces.forEach((surface) => {
|
|
surface.modules.forEach((module) => {
|
|
module.circuit = null
|
|
module.pcsItemId = null
|
|
module.circuitNumber = null
|
|
})
|
|
surface.isComplete = false
|
|
})
|
|
if (circuitTexts.length > 0) canvas.remove(...circuitTexts)
|
|
canvas.renderAll()
|
|
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const isExistCircuit = () => {
|
|
const circuits = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit)
|
|
return circuits.length > 0
|
|
}
|
|
|
|
return {
|
|
makers,
|
|
setMakers,
|
|
selectedMaker,
|
|
setSelectedMaker,
|
|
series,
|
|
setSeries,
|
|
models,
|
|
setModels,
|
|
selectedModels,
|
|
setSelectedModels,
|
|
pcsCheck,
|
|
setPcsCheck,
|
|
getOptYn,
|
|
getPcsItemList,
|
|
getSelectedPcsItemList,
|
|
getUseModuleItemList,
|
|
getRoofSurfaceList,
|
|
getModuleList,
|
|
removeNotAllocationModules,
|
|
setModuleStatisticsData,
|
|
resetCircuits,
|
|
isExistCircuit,
|
|
}
|
|
}
|