Merge branch 'dev' of ssh://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into dev
This commit is contained in:
commit
bc1de6e490
@ -1366,6 +1366,9 @@ export default function Estimate({}) {
|
||||
{getMessage('estimate.detail.fileFlg')}
|
||||
</label>
|
||||
</div>
|
||||
{estimateContextState?.northArrangement === '1' && (
|
||||
<div className="drag-file-guide">{getMessage('estimate.detail.dragFileGuide')}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="common-table mb10">
|
||||
|
||||
@ -28,7 +28,6 @@ export default function CanvasFrame() {
|
||||
const { currentCanvasPlan } = usePlan()
|
||||
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
||||
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||
const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
|
||||
const reset = useResetRecoilState(moduleStatisticsState)
|
||||
const loadCanvas = () => {
|
||||
if (canvas) {
|
||||
|
||||
@ -84,10 +84,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
||||
setIsManualModuleSetup(!isManualModuleSetup)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
manualModuleSetup()
|
||||
}, [isManualModuleSetup])
|
||||
|
||||
const updateObjectDataApi = async (params) => {
|
||||
const res = await updateObjectDate(params)
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ export default function Module({ setTabNum }) {
|
||||
onChange={(e) => setInputInstallHeight(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
<span className="thin">m</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -226,7 +226,7 @@ export default function Module({ setTabNum }) {
|
||||
onChange={(e) => setInputVerticalSnowCover(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
<span className="thin">cm</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -10,7 +10,7 @@ const Placement = forwardRef((props, refs) => {
|
||||
const [isChidori, setIsChidori] = useState(false)
|
||||
const [isChidoriNotAble, setIsChidoriNotAble] = useState(false)
|
||||
|
||||
const [setupLocation, setSetupLocation] = useState('center')
|
||||
const [setupLocation, setSetupLocation] = useState('eaves')
|
||||
const [isMaxSetup, setIsMaxSetup] = useState('false')
|
||||
const [selectedItems, setSelectedItems] = useState({})
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import { selectedModuleState } from '@/store/selectedModuleOptions'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
import { stepUpListDataState } from '@/store/circuitTrestleAtom'
|
||||
import { useEstimate } from '@/hooks/useEstimate'
|
||||
|
||||
const ALLOCATION_TYPE = {
|
||||
AUTO: 'auto',
|
||||
@ -31,6 +32,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
const { closePopup } = usePopup()
|
||||
const { apply } = useTrestle()
|
||||
const { swalFire } = useSwal()
|
||||
const { saveEstimate } = useEstimate()
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
|
||||
const [makers, setMakers] = useRecoilState(makersState)
|
||||
@ -45,7 +47,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
const [circuitAllocationType, setCircuitAllocationType] = useState(1)
|
||||
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
|
||||
const selectedModules = useRecoilValue(selectedModuleState)
|
||||
const { getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController()
|
||||
const { getPcsAutoRecommendList, getPcsVoltageChk, getPcsVoltageStepUpList } = useMasterController()
|
||||
|
||||
// 회로할당(승합설정)에서 선택된 값들을 저장할 상태 추가
|
||||
const [selectedStepUpValues, setSelectedStepUpValues] = useState({})
|
||||
@ -61,6 +63,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
// 수동할당 시 모듈 삭제
|
||||
useEffect(() => {
|
||||
if (allocationType === ALLOCATION_TYPE.PASSIVITY && tabNum === 2) {
|
||||
const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
|
||||
@ -69,6 +72,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
}
|
||||
}, [tabNum])
|
||||
|
||||
// 시리즈중 자동으로 추천 PCS 정보 조회
|
||||
const onAutoRecommend = () => {
|
||||
if (series.filter((s) => s.selected).length === 0) {
|
||||
swalFire({
|
||||
@ -85,7 +89,9 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
pcsItemList: getPcsItemList(),
|
||||
}
|
||||
|
||||
// 파워컨디셔너 추천 목록 조회
|
||||
if (selectedModels.length === 0) {
|
||||
// 시리즈중 자동으로 추천 PCS 정보 조회
|
||||
getPcsAutoRecommendList(params).then((res) => {
|
||||
if (res.data?.pcsItemList) {
|
||||
const itemList = models.filter((model) => {
|
||||
@ -98,15 +104,25 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
isUsed: false,
|
||||
}
|
||||
})
|
||||
// 회로 구성 가능 여부 체크 요청 파라미터
|
||||
const pcsVoltageChkParams = {
|
||||
...getOptYn(),
|
||||
useModuleItemList: getUseModuleItemList(),
|
||||
roofSurfaceList: getRoofSurfaceList(),
|
||||
pcsItemList: getPcsItemList(),
|
||||
}
|
||||
// 추천 목록 선택
|
||||
setSelectedModels(selectedModels)
|
||||
// 회로 구성 가능 여부 체크
|
||||
getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
|
||||
setTabNum(2)
|
||||
if (res.resultCode === 'S') {
|
||||
setTabNum(2)
|
||||
} else {
|
||||
swalFire({
|
||||
title: res.resultMsg,
|
||||
type: 'alert',
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 데이터가 없는 경우 오류 메시지 확인 필요
|
||||
@ -124,12 +140,27 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
getPcsVoltageChk(params).then((res) => {
|
||||
setTabNum(2)
|
||||
// 회로 구성 가능 여부 체크
|
||||
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
|
||||
if (res.resultCode === 'S') {
|
||||
// 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
|
||||
getPcsVoltageStepUpList({
|
||||
...params,
|
||||
pcsItemList: getSelectedPcsItemList(),
|
||||
}).then((res) => {
|
||||
setTabNum(2)
|
||||
})
|
||||
} else {
|
||||
swalFire({
|
||||
title: res.resultMsg,
|
||||
type: 'alert',
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 옵션 Y/N
|
||||
const getOptYn = () => {
|
||||
return {
|
||||
maxConnYn: pcsCheck.max ? 'Y' : 'N',
|
||||
@ -138,6 +169,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
}
|
||||
}
|
||||
|
||||
// PCS 아이템 목록
|
||||
const getPcsItemList = () => {
|
||||
return models.map((model) => {
|
||||
return {
|
||||
@ -148,6 +180,18 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
}
|
||||
|
||||
// 선택된 PCS 아이템 목록
|
||||
const getSelectedPcsItemList = () => {
|
||||
return selectedModels.map((model) => {
|
||||
return {
|
||||
itemId: model.itemId,
|
||||
pcsMkrCd: model.pcsMkrCd,
|
||||
pcsSerCd: model.pcsSerCd,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 사용된 모듈아이템 목록
|
||||
const getUseModuleItemList = () => {
|
||||
return selectedModules.itemList.map((m) => {
|
||||
return {
|
||||
@ -157,6 +201,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
}
|
||||
|
||||
// 지붕면 목록
|
||||
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)
|
||||
@ -180,6 +225,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
}
|
||||
|
||||
// 모듈 목록
|
||||
const getModuleList = (surface) => {
|
||||
let moduleList = []
|
||||
let [xObj, yObj] = [{}, {}]
|
||||
@ -253,6 +299,40 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
return moduleList
|
||||
}
|
||||
|
||||
// 자동할당 버튼 클릭 시
|
||||
const onAutoAllocation = () => {
|
||||
let moduleStdQty = 0
|
||||
let moduleMaxQty = 0
|
||||
const selectedModels = models.filter((m) => m.selected)
|
||||
|
||||
// 시리즈중 자동으로 추천 PCS 정보 조회
|
||||
if (selectedModels.length === 0) {
|
||||
onAutoRecommend()
|
||||
} else {
|
||||
// 모듈 최소 매수
|
||||
moduleStdQty = selectedModels.reduce((acc, model) => {
|
||||
return acc + parseInt(model.moduleStdQty)
|
||||
}, 0)
|
||||
moduleMaxQty = selectedModels.reduce((acc, model) => {
|
||||
return acc + parseInt(model.moduleMaxQty)
|
||||
}, 0)
|
||||
}
|
||||
// const target = pcsCheck.max ? moduleMaxQty : moduleStdQty
|
||||
// const placementModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
|
||||
|
||||
// if (placementModules.length > target) {
|
||||
// swalFire({
|
||||
// title: '배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.',
|
||||
// type: 'alert',
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// setAllocationType(ALLOCATION_TYPE.AUTO)
|
||||
// setTabNum(2)
|
||||
}
|
||||
|
||||
// 수동할당 버튼 클릭 시
|
||||
const onPassivityAllocation = () => {
|
||||
if (selectedModels.length === 0) {
|
||||
const params = {
|
||||
@ -262,6 +342,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
pcsItemList: getPcsItemList(),
|
||||
}
|
||||
|
||||
// 파워컨디셔너 추천 목록 조회
|
||||
getPcsAutoRecommendList(params).then((res) => {
|
||||
if (res.data?.pcsItemList) {
|
||||
const itemList = models.filter((model) => {
|
||||
@ -273,22 +354,28 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
id: uuidv4(),
|
||||
}
|
||||
})
|
||||
const PcsVoltageChkParams = {
|
||||
const pcsVoltageChkParams = {
|
||||
...getOptYn(),
|
||||
useModuleItemList: getUseModuleItemList(),
|
||||
roofSurfaceList: getRoofSurfaceList(),
|
||||
pcsItemList: getPcsItemList(),
|
||||
}
|
||||
setSelectedModels(selectedModels)
|
||||
getPcsVoltageChk(PcsVoltageChkParams).then((res) => {})
|
||||
getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
|
||||
setAllocationType(ALLOCATION_TYPE.PASSIVITY)
|
||||
})
|
||||
} else {
|
||||
swalFire({
|
||||
title: '파워컨디셔너를 추가해 주세요.',
|
||||
title: res.result.resultMsg,
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
return
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
})
|
||||
} else if (pcsCheck.max) {
|
||||
} else {
|
||||
const moduleStdQty = selectedModels.reduce((acc, model) => {
|
||||
return acc + parseInt(model.moduleStdQty)
|
||||
}, 0)
|
||||
@ -306,9 +393,9 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
setAllocationType(ALLOCATION_TYPE.PASSIVITY)
|
||||
setAllocationType(ALLOCATION_TYPE.PASSIVITY)
|
||||
}
|
||||
}
|
||||
|
||||
// StepUp에서 선택된 값들을 처리하는 함수 수정
|
||||
@ -336,8 +423,10 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
|
||||
const result = await apply()
|
||||
if (result) {
|
||||
await saveEstimate(result)
|
||||
}
|
||||
removeNotAllocationModules()
|
||||
apply()
|
||||
}
|
||||
|
||||
const removeNotAllocationModules = () => {
|
||||
@ -346,6 +435,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
// 이전 버튼 클릭 시
|
||||
const onClickPrev = () => {
|
||||
setAllocationType(ALLOCATION_TYPE.AUTO)
|
||||
swalFire({
|
||||
@ -367,6 +457,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
}
|
||||
|
||||
// 파워컨디셔너 컴포넌트 속성
|
||||
const powerConditionalSelectProps = {
|
||||
tabNum,
|
||||
setTabNum,
|
||||
@ -383,6 +474,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
managementState,
|
||||
}
|
||||
|
||||
// 수동할당 컴포넌트 속성
|
||||
const passivityProps = {
|
||||
tabNum,
|
||||
setTabNum,
|
||||
@ -394,13 +486,18 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
getRoofSurfaceList,
|
||||
}
|
||||
|
||||
// 승압설정 컴포넌트 속성
|
||||
const stepUpProps = {
|
||||
tabNum,
|
||||
setTabNum,
|
||||
models,
|
||||
setModels,
|
||||
allocationType,
|
||||
circuitAllocationType,
|
||||
setCircuitAllocationType,
|
||||
selectedModels,
|
||||
setSelectedModels,
|
||||
getSelectedPcsItemList,
|
||||
getOptYn, // 옵션 Y/N
|
||||
getUseModuleItemList, // 사용된 모듈아이템 List
|
||||
getRoofSurfaceList, // 지붕면 목록
|
||||
@ -410,8 +507,10 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
setStepUpListData,
|
||||
seletedOption,
|
||||
setSeletedOption,
|
||||
getModuleList,
|
||||
}
|
||||
|
||||
// 승압설정 목록 조회
|
||||
const getStepUpListData = () => {
|
||||
return stepUpListData[0].pcsItemList.map((item) => {
|
||||
return item.serQtyList
|
||||
@ -422,7 +521,6 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
pcsSerCd: item.pcsSerCd,
|
||||
pcsItemId: item.itemId,
|
||||
pscOptCd: seletedOption.code,
|
||||
// pcsOptCd: 'CLC_RMC',
|
||||
paralQty: serQty.paralQty,
|
||||
connections: [
|
||||
{
|
||||
@ -434,12 +532,65 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
}
|
||||
|
||||
// 닫기 버튼 클릭 시 처리하는 함수 추가
|
||||
const handleClose = () => {
|
||||
// // 회로 번호 텍스트 제거
|
||||
// const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
|
||||
// canvas.remove(...circuitTexts)
|
||||
|
||||
// // 모듈의 회로 정보 초기화
|
||||
// canvas
|
||||
// .getObjects()
|
||||
// .filter((obj) => obj.name === POLYGON_TYPE.MODULE)
|
||||
// .forEach((obj) => {
|
||||
// obj.circuit = null
|
||||
// obj.pcsItemId = null
|
||||
// obj.circuitNumber = null
|
||||
// })
|
||||
|
||||
// canvas.renderAll()
|
||||
// closePopup(id)
|
||||
|
||||
swalFire({
|
||||
title: '변경사항을 저장하시겠습니까?',
|
||||
//text: '저장하지 않은 변경사항은 모두 사라집니다.',
|
||||
type: 'confirm',
|
||||
confirmButtonText: '저장',
|
||||
cancelButtonText: '취소',
|
||||
icon: 'warning',
|
||||
confirmFn: async () => {
|
||||
// 저장 로직 실행
|
||||
await onApply()
|
||||
closePopup(id)
|
||||
},
|
||||
denyFn: () => {
|
||||
// 회로 번호 텍스트 제거
|
||||
const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')
|
||||
canvas.remove(...circuitTexts)
|
||||
|
||||
// 모듈의 회로 정보 초기화
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE)
|
||||
.forEach((obj) => {
|
||||
obj.circuit = null
|
||||
obj.pcsItemId = null
|
||||
obj.circuitNumber = null
|
||||
})
|
||||
|
||||
canvas.renderAll()
|
||||
closePopup(id)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={{ x: 50, y: 230 }}>
|
||||
<div className={`modal-pop-wrap l-2`}>
|
||||
<div className="modal-head modal-handle">
|
||||
<h1 className="title">{getMessage('modal.circuit.trestle.setting')} </h1>
|
||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||
{/* <button className="modal-close" onClick={() => closePopup(id)}> */}
|
||||
<button className="modal-close" onClick={handleClose}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -10,16 +10,29 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta
|
||||
import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
|
||||
export default function StepUp(props) {
|
||||
const { stepUpListData, setStepUpListData, seletedOption, setSeletedOption } = props
|
||||
const {
|
||||
models,
|
||||
allocationType,
|
||||
stepUpListData,
|
||||
setStepUpListData,
|
||||
seletedOption,
|
||||
setSeletedOption,
|
||||
selectedModels,
|
||||
setSelectedModels,
|
||||
getSelectedPcsItemList,
|
||||
getModuleList,
|
||||
} = props
|
||||
const { getMessage } = useMessage()
|
||||
const globalLocale = useRecoilValue(globalLocaleStore)
|
||||
const [moduleTab, setModuleTab] = useState(1)
|
||||
const [moduleTabs, setModuleTabs] = useState({})
|
||||
const [arrayLength, setArrayLength] = useState(3) //module-table-inner의 반복 개수
|
||||
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
|
||||
const { models } = props
|
||||
const { getPcsVoltageStepUpList, getPcsAutoRecommendList } = useMasterController()
|
||||
const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController()
|
||||
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const selectedModules = useRecoilValue(selectedModuleState)
|
||||
@ -39,34 +52,55 @@ export default function StepUp(props) {
|
||||
|
||||
useEffect(() => {
|
||||
// PCS 승압설정 정보 조회
|
||||
fetchStepUpData()
|
||||
if (allocationType === 'auto') {
|
||||
fetchStepUpData()
|
||||
} else {
|
||||
// 1-1 2-2
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit)
|
||||
.map((module) => module.circuitNumber)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// PCS 승압설정 정보 조회
|
||||
const fetchStepUpData = async () => {
|
||||
try {
|
||||
const params = {
|
||||
useYn: props.getOptYn(), // 옵션 Y/N
|
||||
...props.getOptYn(), // 옵션 Y/N
|
||||
useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List
|
||||
roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록
|
||||
pcsItemList: props.getPcsItemList(), // PCS 아이템 목록
|
||||
pcsItemList: selectedModels.length === 0 ? props.getPcsItemList() : getSelectedPcsItemList(), // PCS 아이템 목록
|
||||
}
|
||||
|
||||
// PCS 승압설정 정보 조회
|
||||
const res = await getPcsVoltageStepUpList(params)
|
||||
// 회로 구성 가능 여부 체크
|
||||
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
|
||||
if (res.resultCode === 'S') {
|
||||
// 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
|
||||
getPcsVoltageStepUpList(params).then((res) => {
|
||||
if (res?.result.code === 200 && res?.data) {
|
||||
if (selectedModels.length === 0) {
|
||||
setSelectedModels(res.data.pcsItemList)
|
||||
}
|
||||
const dataArray = Array.isArray(res.data) ? res.data : [res.data]
|
||||
const stepUpListData = formatStepUpListData(dataArray)
|
||||
|
||||
if (res?.result.code === 200 && res?.data) {
|
||||
const dataArray = Array.isArray(res.data) ? res.data : [res.data]
|
||||
const stepUpListData = formatStepUpListData(dataArray)
|
||||
// PCS 승압설정 정보 SET
|
||||
setStepUpListData(stepUpListData)
|
||||
|
||||
// PCS 승압설정 정보 SET
|
||||
setStepUpListData(stepUpListData)
|
||||
|
||||
// PCS 옵션 조회
|
||||
const formattedOptCodes = formatOptionCodes(res.data.optionList)
|
||||
setOptCodes(formattedOptCodes)
|
||||
setSeletedOption(formattedOptCodes[0])
|
||||
}
|
||||
// PCS 옵션 조회
|
||||
const formattedOptCodes = formatOptionCodes(res.data.optionList)
|
||||
setOptCodes(formattedOptCodes)
|
||||
setSeletedOption(formattedOptCodes[0])
|
||||
}
|
||||
})
|
||||
} else {
|
||||
swalFire({
|
||||
title: res.resultMsg,
|
||||
type: 'alert',
|
||||
})
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error fetching step up data:', error)
|
||||
}
|
||||
@ -121,6 +155,7 @@ export default function StepUp(props) {
|
||||
})
|
||||
})
|
||||
|
||||
// 초기 추천 값들을 selectedValues에 저장
|
||||
setSelectedValues(initialSelectedValues)
|
||||
|
||||
return formattedData
|
||||
@ -212,17 +247,57 @@ export default function StepUp(props) {
|
||||
}
|
||||
item.selected = index === subIdx
|
||||
})
|
||||
// 선택된 행 정보 저장
|
||||
setStepUpListData(tempStepUpListData)
|
||||
|
||||
console.log('🚀 ~ handleRowClick ~ tempStepUpListData:', tempStepUpListData)
|
||||
console.log('🚀 ~ handleRowClick ~ selectedData:', selectedData)
|
||||
|
||||
// 파워컨디셔너 옵션 조회 요청 파라미터
|
||||
const params = {
|
||||
...props.getOptYn(), // 옵션 Y/N
|
||||
useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List
|
||||
roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록
|
||||
pcsItemList: props.getSelectedPcsItemList().map((pcsItem) => {
|
||||
// PCS 아이템 목록
|
||||
// tempStepUpListData에서 해당 PCS 아이템 찾기
|
||||
const matchingPcsItem = tempStepUpListData[0].pcsItemList.find((item) => item.pcsId === pcsItem.pcsId && item.itemId === pcsItem.itemId)
|
||||
|
||||
// 선택된 serQty 찾기
|
||||
const selectedSerQty = matchingPcsItem?.serQtyList.find((serQty) => serQty.selected)?.serQty || 0
|
||||
|
||||
return {
|
||||
...pcsItem,
|
||||
applySerQty: selectedSerQty,
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
// PCS 승압설정 정보 조회
|
||||
//const res = await getPcsVoltageStepUpList(params)
|
||||
//getPcsManualConfChk(params).then((res) => {
|
||||
getPcsVoltageStepUpList(params).then((res) => {
|
||||
if (res?.result.code === 200 && res?.data) {
|
||||
const dataArray = Array.isArray(res.data) ? res.data : [res.data]
|
||||
const stepUpListData = formatStepUpListData(dataArray)
|
||||
|
||||
// PCS 승압설정 정보 SET
|
||||
setStepUpListData(stepUpListData)
|
||||
|
||||
// PCS 옵션 조회
|
||||
const formattedOptCodes = formatOptionCodes(res.data.optionList)
|
||||
setOptCodes(formattedOptCodes)
|
||||
setSeletedOption(formattedOptCodes[0])
|
||||
}
|
||||
})
|
||||
|
||||
selectedData.roofSurfaceList.forEach((roofSurface) => {
|
||||
const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0]
|
||||
const moduleIds = targetSurface.modules.map((module) => {
|
||||
return module.id
|
||||
})
|
||||
|
||||
// 모듈 목록 삭제
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => moduleIds.includes(obj.parentId))
|
||||
@ -230,7 +305,9 @@ export default function StepUp(props) {
|
||||
canvas.remove(text)
|
||||
})
|
||||
|
||||
// 모듈 목록 추가
|
||||
canvas.renderAll()
|
||||
|
||||
roofSurface.moduleList.forEach((module) => {
|
||||
const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0]
|
||||
const moduleCircuitText = new fabric.Text(module.circuit, {
|
||||
@ -415,8 +492,11 @@ export default function StepUp(props) {
|
||||
<div className="grid-select mr10">
|
||||
{/* <QSelectBox title={'電力検出ユニット (モニター付き)'} /> */}
|
||||
<QSelectBox
|
||||
options={optCodes}
|
||||
title={optCodes[0].name}
|
||||
//options={optCodes}
|
||||
options={optCodes.map((roof) => {
|
||||
return { ...roof, name: globalLocale === 'ko' ? roof.name : roof.nameJp }
|
||||
})}
|
||||
title={globalLocale === 'ko' ? optCodes[0].name : optCodes[0].nameJp}
|
||||
value={seletedOption}
|
||||
sourceKey="code"
|
||||
targetKey="code"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { useModule } from '@/hooks/module/useModule'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
@ -11,37 +12,29 @@ import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
|
||||
export default function PassivityCircuitAllocation(props) {
|
||||
const {
|
||||
tabNum,
|
||||
setTabNum,
|
||||
selectedModels,
|
||||
setSelectedModels,
|
||||
getOptYn: getApiProps,
|
||||
getUseModuleItemList: getSelectedModuleList,
|
||||
getSelectModelList: getSelectModelList,
|
||||
getRoofSurfaceList,
|
||||
getModelList,
|
||||
} = props
|
||||
const { swalFire } = useSwal()
|
||||
const { getMessage } = useMessage()
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
|
||||
const selectedModules = useRecoilValue(selectedModuleState)
|
||||
const [moduleStatistics, setModuleStatistics] = useRecoilState(moduleStatisticsState)
|
||||
// const [totalWpout, setTotalWpout] = useState(0)
|
||||
const [selectedPcs, setSelectedPcs] = useState(selectedModels[0])
|
||||
// const { header, rows: row } = moduleStatistics
|
||||
const [header, setHeader] = useState(moduleStatistics.header)
|
||||
const [rows, setRows] = useState(moduleStatistics.rows)
|
||||
const [footer, setFooter] = useState(['합계'])
|
||||
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
|
||||
const [circuitNumber, setCircuitNumber] = useState(1)
|
||||
const [targetModules, setTargetModules] = useState([])
|
||||
const { setModuleStatisticsData } = useModule()
|
||||
const { getPcsManualConfChk } = useMasterController()
|
||||
|
||||
useEffect(() => {
|
||||
console.log('header, rows', header, rows)
|
||||
console.log('selectedModels', selectedModels)
|
||||
// setSurfaceInfo()
|
||||
setTableData()
|
||||
setModuleStatisticsData()
|
||||
if (!managementState) {
|
||||
setManagementState(managementStateLoaded)
|
||||
}
|
||||
@ -158,7 +151,14 @@ export default function PassivityCircuitAllocation(props) {
|
||||
}
|
||||
|
||||
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) {
|
||||
swalFire({
|
||||
text: '회로번호를 1 이상입력해주세요.',
|
||||
@ -174,15 +174,6 @@ export default function PassivityCircuitAllocation(props) {
|
||||
})
|
||||
return
|
||||
} 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
|
||||
uniqueCircuitNumbers.forEach((number) => {
|
||||
if (
|
||||
@ -335,7 +326,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
|
||||
setTargetModules([])
|
||||
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 = () => {
|
||||
swalFire({
|
||||
title: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.init.info'),
|
||||
@ -516,9 +413,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
<tr>
|
||||
{header.map((header, i) => (
|
||||
<td className="al-c" key={'footer' + i}>
|
||||
{typeof footer[header.prop] === 'number'
|
||||
? footer[header.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 })
|
||||
: footer[header.prop]}
|
||||
{footer[header.prop]}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
|
||||
@ -45,175 +45,188 @@ export default function ContextRoofAllocationSetting(props) {
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={pos}>
|
||||
<div className={`modal-pop-wrap lr mount`}>
|
||||
<div className="modal-head modal-handle">
|
||||
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
|
||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<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'}
|
||||
/>
|
||||
{currentRoofList && (
|
||||
<>
|
||||
<div className="modal-head modal-handle">
|
||||
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
|
||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
className="allocation-edit"
|
||||
onClick={() => {
|
||||
onAddRoofMaterial()
|
||||
}}
|
||||
>
|
||||
<i className="edit-ico"></i>
|
||||
{getMessage('modal.common.add')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid-option-wrap">
|
||||
{currentRoofList.length > 0 &&
|
||||
currentRoofList.map((roof, index) => {
|
||||
return (
|
||||
<div className="grid-option-box" key={index}>
|
||||
<div className="d-check-radio pop no-text">
|
||||
<input type="radio" name="radio01" checked={roof.selected && 'checked'} readOnly={true} />
|
||||
<label
|
||||
htmlFor="ra01"
|
||||
onClick={(e) => {
|
||||
handleDefaultRoofMaterial(index)
|
||||
}}
|
||||
></label>
|
||||
</div>
|
||||
<div className="grid-option-block-form">
|
||||
<div className="block-box">
|
||||
<div className="flex-ment">
|
||||
<div className="grid-select" style={{ width: '248px' }}>
|
||||
<QSelectBox
|
||||
options={roofMaterials}
|
||||
value={roof}
|
||||
showKey={'roofMatlNm'}
|
||||
sourceKey={'roofMatlCd'}
|
||||
targetKey={'roofMatlCd'}
|
||||
onChange={(e) => handleChangeRoofMaterial(e, index)}
|
||||
/>
|
||||
</div>
|
||||
{index === 0 && <span className="dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>}
|
||||
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>}
|
||||
<div className="modal-body">
|
||||
<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>
|
||||
<button
|
||||
className="allocation-edit"
|
||||
onClick={() => {
|
||||
onAddRoofMaterial()
|
||||
}}
|
||||
>
|
||||
<i className="edit-ico"></i>
|
||||
{getMessage('modal.common.add')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid-option-overflow">
|
||||
<div className="grid-option-wrap">
|
||||
{currentRoofList.map((roof, index) => {
|
||||
return (
|
||||
<div className="grid-option-box" key={index}>
|
||||
<div className="d-check-radio pop no-text">
|
||||
<input type="radio" name="radio01" checked={roof.selected && 'checked'} readOnly={true} />
|
||||
<label
|
||||
htmlFor="ra01"
|
||||
onClick={(e) => {
|
||||
handleDefaultRoofMaterial(index)
|
||||
}}
|
||||
></label>
|
||||
</div>
|
||||
</div>
|
||||
<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="grid-option-block-form">
|
||||
<div className="block-box">
|
||||
<div className="flex-ment">
|
||||
<span>W</span>
|
||||
<div className="input-grid" style={{ width: '100px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
|
||||
<div className="grid-select">
|
||||
<QSelectBox
|
||||
options={roofMaterials}
|
||||
value={roof}
|
||||
showKey={'roofMatlNm'}
|
||||
sourceKey={'roofMatlCd'}
|
||||
targetKey={'roofMatlCd'}
|
||||
onChange={(e) => handleChangeRoofMaterial(e, index)}
|
||||
/>
|
||||
</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>
|
||||
)}
|
||||
{roof.lenAuth && (
|
||||
</div>
|
||||
<div className="block-box">
|
||||
<div className="flex-ment">
|
||||
<span>L</span>
|
||||
<div className="input-grid" style={{ width: '100px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} />
|
||||
<span>{getMessage('slope')}</span>
|
||||
<div className="input-grid">
|
||||
<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 className="absol">{pitchText}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{(roof.raftAuth || roof.roofPchAuth) && (
|
||||
<div className="block-box">
|
||||
{roof.raftAuth && (
|
||||
<div className="block-box">
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||
{raftCodes.length > 0 && (
|
||||
<div className="grid-select" style={{ width: '160px' }}>
|
||||
<QSelectBox
|
||||
options={raftCodes}
|
||||
value={roof}
|
||||
showKey={'clCodeNm'}
|
||||
sourceKey={'clCode'}
|
||||
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
|
||||
/>
|
||||
</div>
|
||||
{(roof.widAuth || roof.lenAuth) && (
|
||||
<>
|
||||
{roof.widAuth && (
|
||||
<div className="block-box">
|
||||
<div className="flex-ment">
|
||||
<span>W</span>
|
||||
<div className="input-grid">
|
||||
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
|
||||
</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>
|
||||
)}
|
||||
{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>
|
||||
)}
|
||||
<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>
|
||||
{(roof.raftAuth || roof.roofPchAuth) && (
|
||||
<>
|
||||
{roof.raftAuth && (
|
||||
<div className="block-box">
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||
{raftCodes.length > 0 && (
|
||||
<div className="grid-select">
|
||||
<QSelectBox
|
||||
options={raftCodes}
|
||||
value={roof}
|
||||
showKey={'clCodeNm'}
|
||||
sourceKey={'clCode'}
|
||||
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{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 className="grid-btn-wrap">
|
||||
<button className="btn-frame modal act" onClick={handleSaveContext}>
|
||||
{getMessage('modal.roof.alloc.apply')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal act" onClick={handleSaveContext}>
|
||||
{getMessage('modal.roof.alloc.apply')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="modal-foot modal-handle"></div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
|
||||
@ -411,11 +411,12 @@ export default function StuffDetail() {
|
||||
if (session?.storeId === 'T01') {
|
||||
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
|
||||
} else {
|
||||
if (session.storeLvl === '1') {
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
} else {
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
}
|
||||
// if (session.storeLvl === '1') {
|
||||
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
// } else {
|
||||
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
// }
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
}
|
||||
|
||||
get({ url: url }).then((res) => {
|
||||
@ -523,11 +524,12 @@ export default function StuffDetail() {
|
||||
if (session?.storeId === 'T01') {
|
||||
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
|
||||
} else {
|
||||
if (session.storeLvl === '1') {
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
} else {
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
}
|
||||
// if (session.storeLvl === '1') {
|
||||
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
// } else {
|
||||
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
// }
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
}
|
||||
get({ url: url }).then((res) => {
|
||||
if (!isEmptyArray(res)) {
|
||||
|
||||
@ -474,12 +474,13 @@ export default function StuffSearchCondition() {
|
||||
//T01일떄
|
||||
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
|
||||
} else {
|
||||
if (session.storeLvl === '1') {
|
||||
//T01아닌 1차점일때
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
} else {
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
}
|
||||
// if (session.storeLvl === '1') {
|
||||
// //T01아닌 1차점일때
|
||||
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
// } else {
|
||||
// url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
// }
|
||||
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
|
||||
}
|
||||
|
||||
get({ url: url }).then((res) => {
|
||||
|
||||
@ -201,13 +201,22 @@ export function useMasterController() {
|
||||
* @returns
|
||||
*/
|
||||
const getPcsVoltageStepUpList = async (params2 = null) => {
|
||||
// roofSurfaceList의 moduleList에서 circuit 속성을 제외
|
||||
const modifiedRoofSurfaceList = params2.roofSurfaceList.map((surface) => ({
|
||||
...surface,
|
||||
moduleList: surface.moduleList.map((module) => ({
|
||||
itemId: module.itemId,
|
||||
uniqueId: module.uniqueId,
|
||||
})),
|
||||
}))
|
||||
|
||||
const params = {
|
||||
...params2,
|
||||
maxConnYn: params2.useYn.maxConnYn,
|
||||
smpCirYn: params2.useYn.smpCirYn,
|
||||
coldZoneYn: params2.useYn.coldZoneYn,
|
||||
maxConnYn: params2.maxConnYn,
|
||||
smpCirYn: params2.smpCirYn,
|
||||
coldZoneYn: params2.coldZoneYn,
|
||||
useModuleItemList: params2.useModuleItemList,
|
||||
roofSurfaceList: params2.roofSurfaceList,
|
||||
roofSurfaceList: modifiedRoofSurfaceList,
|
||||
pcsItemList: params2.pcsItemList,
|
||||
}
|
||||
|
||||
|
||||
@ -80,7 +80,6 @@ export const useEstimateController = (planNo) => {
|
||||
|
||||
res.data.pkgAsp = roundedNumber.toString()
|
||||
}
|
||||
|
||||
setEstimateContextState(res.data)
|
||||
}
|
||||
}
|
||||
@ -155,7 +154,7 @@ export const useEstimateController = (planNo) => {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('::FileDownLoad Error::', error)
|
||||
alert('File does not exist.')
|
||||
return swalFire({ text: getMessage('File does not exist'), type: 'alert' })
|
||||
})
|
||||
}
|
||||
|
||||
@ -169,19 +168,19 @@ export const useEstimateController = (planNo) => {
|
||||
if (estimateData?.charger === null || estimateData?.charger?.trim().length === 0) {
|
||||
flag = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredCharger'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredCharger'), type: 'alert' })
|
||||
}
|
||||
|
||||
if (estimateData?.objectName === null || estimateData?.objectName?.trim().length === 0) {
|
||||
flag = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredObjectName'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredObjectName'), type: 'alert' })
|
||||
}
|
||||
|
||||
if (isNaN(Date.parse(estimateData.estimateDate))) {
|
||||
flag = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredEstimateDate'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateDate'), type: 'alert' })
|
||||
}
|
||||
|
||||
if (estimateData.estimateType === 'YJSS') {
|
||||
@ -189,7 +188,7 @@ export const useEstimateController = (planNo) => {
|
||||
if (pkgAsp === '0') {
|
||||
flag = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredPkgAsp'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredPkgAsp'), type: 'alert' })
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +208,14 @@ export const useEstimateController = (planNo) => {
|
||||
//기존에 첨부된 파일이 없으면
|
||||
if (isEmptyArray(estimateData.newFileList)) {
|
||||
//새로 첨부한 파일이 없으면
|
||||
|
||||
//북면 먼저 체크
|
||||
if (estimateData?.northArrangement === '1') {
|
||||
fileFlg = false
|
||||
setIsGlobalLoading(false)
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert' })
|
||||
}
|
||||
|
||||
if (estimateData.itemList.length > 1) {
|
||||
estimateData.itemList.map((row) => {
|
||||
if (row.delFlg === '0') {
|
||||
@ -217,7 +224,7 @@ export const useEstimateController = (planNo) => {
|
||||
if (estimateData.fileFlg === '0') {
|
||||
fileFlg = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredFileUpload'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredFileUpload'), type: 'alert' })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,7 +242,7 @@ export const useEstimateController = (planNo) => {
|
||||
if (item.itemId === '') {
|
||||
itemFlg = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredItemId'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredItemId'), type: 'alert' })
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,7 +258,7 @@ export const useEstimateController = (planNo) => {
|
||||
if (item.amount < 1) {
|
||||
itemFlg = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredAmount'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredAmount'), type: 'alert' })
|
||||
}
|
||||
|
||||
if (estimateData.estimateType !== 'YJSS') {
|
||||
@ -263,7 +270,7 @@ export const useEstimateController = (planNo) => {
|
||||
if (item.salePrice < 1) {
|
||||
itemFlg = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredSalePrice'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' })
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,7 +281,7 @@ export const useEstimateController = (planNo) => {
|
||||
if (isNaN(item.salePrice)) {
|
||||
itemFlg = false
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredSalePrice'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredSalePrice'), type: 'alert' })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,7 +299,7 @@ export const useEstimateController = (planNo) => {
|
||||
})
|
||||
if (delCnt === estimateData.itemList.length) {
|
||||
setIsGlobalLoading(false)
|
||||
return alert(getMessage('estimate.detail.save.requiredItem'))
|
||||
return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import * as turf from '@turf/turf'
|
||||
import { useSwal } from '../useSwal'
|
||||
import { useModuleBasicSetting } from './useModuleBasicSetting'
|
||||
import { useMessage } from '../useMessage'
|
||||
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
||||
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
|
||||
|
||||
export const MODULE_REMOVE_TYPE = {
|
||||
LEFT: 'left',
|
||||
@ -35,6 +37,8 @@ export function useModule() {
|
||||
const { swalFire } = useSwal()
|
||||
const { getMessage } = useMessage()
|
||||
const { checkModuleDisjointObjects } = useModuleBasicSetting()
|
||||
const selectedModules = useRecoilValue(selectedModuleState)
|
||||
const setModuleStatistics = useSetRecoilState(moduleStatisticsState)
|
||||
|
||||
const moduleMove = (length, direction) => {
|
||||
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))
|
||||
}
|
||||
|
||||
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 {
|
||||
moduleMove,
|
||||
moduleMultiMove,
|
||||
@ -942,5 +1032,6 @@ export function useModule() {
|
||||
muduleRowInsert,
|
||||
modulesRemove,
|
||||
alignModule,
|
||||
setModuleStatisticsData,
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,6 +324,18 @@ export function useModuleBasicSetting(tabNum) {
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log('리코일 바뀌냐??')
|
||||
console.log('isManualModuleSetup', isManualModuleSetup)
|
||||
console.log('saleStoreNorthFlg', saleStoreNorthFlg)
|
||||
|
||||
if (moduleSelectionData.common.saleStoreNorthFlg === '1') {
|
||||
setSaleStoreNorthFlg(true)
|
||||
}
|
||||
|
||||
manualModuleSetup()
|
||||
}, [isManualModuleSetup])
|
||||
|
||||
/**
|
||||
* trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 로 진입여부를 확인
|
||||
* 확인 후 셀을 이동시킴
|
||||
@ -364,7 +376,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
lockRotation: true, // 회전 잠금
|
||||
lockScalingX: true, // X 축 크기 조정 잠금
|
||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
name: 'module',
|
||||
name: POLYGON_TYPE.MODULE,
|
||||
}
|
||||
|
||||
if (moduleSetupSurfaces.length !== 0) {
|
||||
@ -429,6 +441,10 @@ export function useModuleBasicSetting(tabNum) {
|
||||
parentId: moduleSetupSurfaces[i].parentId,
|
||||
})
|
||||
|
||||
console.log('trestlePolygon', trestlePolygon)
|
||||
console.log('saleStoreNorthFlg', saleStoreNorthFlg)
|
||||
console.log('trestlePolygon.isNorth', trestlePolygon.isNorth)
|
||||
|
||||
//북면이고 북면설치상점이 아니면 그냥 return
|
||||
if (trestlePolygon.isNorth && !saleStoreNorthFlg) {
|
||||
return
|
||||
@ -646,13 +662,15 @@ export function useModuleBasicSetting(tabNum) {
|
||||
})
|
||||
}
|
||||
} else {
|
||||
//수동모드 해제시 모듈 설치면 선택 잠금
|
||||
moduleSetupSurfaces.forEach((obj) => {
|
||||
obj.set({
|
||||
selectable: true,
|
||||
evented: true,
|
||||
if (moduleSetupSurfaces) {
|
||||
//수동모드 해제시 모듈 설치면 선택 잠금
|
||||
moduleSetupSurfaces.forEach((obj) => {
|
||||
obj.set({
|
||||
selectable: true,
|
||||
evented: true,
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
removeMouseEvent('mouse:up')
|
||||
removeMouseEvent('mouse:move')
|
||||
@ -1693,7 +1711,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
parentId: moduleSetupSurface.parentId,
|
||||
surfaceId: moduleSetupSurface.id,
|
||||
name: 'module',
|
||||
name: POLYGON_TYPE.MODULE,
|
||||
}
|
||||
|
||||
if (moduleSetupSurfaces.length !== 0) {
|
||||
@ -2102,7 +2120,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
parentId: moduleSetupSurface.parentId,
|
||||
surfaceId: moduleSetupSurface.id,
|
||||
name: 'module',
|
||||
name: POLYGON_TYPE.MODULE,
|
||||
}
|
||||
|
||||
let leftMargin, bottomMargin, square
|
||||
@ -2450,7 +2468,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
...surface,
|
||||
name: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, // 지붕면
|
||||
// powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }),
|
||||
wpOut: wpOut,
|
||||
wpOut: (wpOut / 1000).toFixed(3),
|
||||
}
|
||||
})
|
||||
|
||||
@ -2463,7 +2481,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
}),
|
||||
{ name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' },
|
||||
]
|
||||
let footer = ['합계']
|
||||
let footer = [getMessage('modal.panel.batch.statistic.total')]
|
||||
let footerData = {}
|
||||
rows.forEach((row) => {
|
||||
Object.keys(moduleInfo).map((key) => {
|
||||
@ -2474,7 +2492,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
Object.keys(footerData).forEach((key) => {
|
||||
footer.push(footerData[key])
|
||||
})
|
||||
footer.push(totalWpout)
|
||||
footer.push((totalWpout / 1000).toFixed(3))
|
||||
console.log({ header: header, rows, footer: footer })
|
||||
setModuleStatistics({ header: header, rows, footer: footer })
|
||||
}
|
||||
|
||||
@ -89,11 +89,12 @@ export function useModuleSelection(props) {
|
||||
|
||||
getModuleData(roofsIds)
|
||||
|
||||
//메뉴 이동시 배치면 삭제
|
||||
const moduleSurfacesArray = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
||||
//해당 메뉴 이동시 배치면 삭제
|
||||
const moduleSurfacesArray = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE)
|
||||
if (moduleSurfacesArray.length > 0) {
|
||||
moduleSurfacesArray.forEach((moduleSurface) => {
|
||||
moduleSurface.module = []
|
||||
canvas.remove(moduleSurface)
|
||||
})
|
||||
canvas.renderAll()
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { canvasState, currentAngleTypeSelector } from '@/store/canvasAtom'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
||||
import { getDegreeByChon, getTrestleLength } from '@/util/canvas-util'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { estimateParamAtom } from '@/store/estimateAtom'
|
||||
|
||||
// 회로 및 가대설정
|
||||
export const useTrestle = () => {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
|
||||
const { getQuotationItem } = useMasterController()
|
||||
const [estimateParam, setEstimateParam] = useRecoilState(estimateParamAtom)
|
||||
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
|
||||
|
||||
const apply = () => {
|
||||
@ -41,6 +39,7 @@ export const useTrestle = () => {
|
||||
return
|
||||
}
|
||||
|
||||
const plvrYn = construction.plvrYn
|
||||
let moduleRowsTotCnt = 0
|
||||
let isEaveBar = construction.setupCover
|
||||
let isSnowGuard = construction.setupSnowCover
|
||||
@ -102,6 +101,14 @@ export const useTrestle = () => {
|
||||
leftExposedHalfTopModules.length > 0 ||
|
||||
rightExposedHalfTopPoints.length > 0
|
||||
|
||||
console.log('isChidory', isChidory)
|
||||
|
||||
if (plvrYn === 'N' && isChidory) {
|
||||
alert('치조불가공법입니다.')
|
||||
clear()
|
||||
throw new Error('치조불가공법입니다.')
|
||||
}
|
||||
|
||||
surface.set({ isChidory: isChidory })
|
||||
|
||||
canvas
|
||||
@ -210,6 +217,10 @@ export const useTrestle = () => {
|
||||
let findLeft = true
|
||||
let findRight = true
|
||||
|
||||
let leftFindModuleList = [module]
|
||||
let rightFindModuleList = [module]
|
||||
let centerFindModuleList = [module]
|
||||
|
||||
//우선 절반을 나눈 뒤 왼쪽부터 찾는다.
|
||||
while (hasNextModule) {
|
||||
//바로 위에 있는지 확인한다.
|
||||
@ -218,6 +229,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
leftRows++
|
||||
leftFindModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -233,6 +245,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
leftRows++
|
||||
leftFindModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -253,6 +266,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
rightRows++
|
||||
rightFindModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -268,6 +282,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
rightRows++
|
||||
rightFindModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -287,6 +302,7 @@ export const useTrestle = () => {
|
||||
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
centerFindModuleList.push(nextModule)
|
||||
centerRows++
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
@ -295,19 +311,77 @@ export const useTrestle = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const leftModuleInfos = leftFindModuleList.map((module) => {
|
||||
return {
|
||||
moduleTpCd: module.moduleInfo.moduleTpCd,
|
||||
}
|
||||
})
|
||||
|
||||
const rightModuleInfos = rightFindModuleList.map((module) => {
|
||||
return {
|
||||
moduleTpCd: module.moduleInfo.moduleTpCd,
|
||||
}
|
||||
})
|
||||
|
||||
const centerModuleInfos = centerFindModuleList.map((module) => {
|
||||
return {
|
||||
moduleTpCd: module.moduleInfo.moduleTpCd,
|
||||
}
|
||||
})
|
||||
|
||||
const leftRowsInfo = moduleTransformData(leftModuleInfos)
|
||||
const rightRowsInfo = moduleTransformData(rightModuleInfos)
|
||||
const centerRowsInfo = moduleTransformData(centerModuleInfos)
|
||||
|
||||
// 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
|
||||
const leftRacks = rackInfos.find((rack) => {
|
||||
return rack.value.moduleRows === leftRows
|
||||
if (leftRowsInfo.rowsInfo.length === 1) {
|
||||
return (
|
||||
rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
|
||||
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
|
||||
)
|
||||
} else {
|
||||
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
|
||||
)
|
||||
}
|
||||
})?.value.racks
|
||||
|
||||
// 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
|
||||
const rightRacks = rackInfos.find((rack) => {
|
||||
return rack.value.moduleRows === rightRows
|
||||
if (rightRowsInfo.rowsInfo.length === 1) {
|
||||
return (
|
||||
rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
|
||||
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
|
||||
)
|
||||
} else {
|
||||
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
|
||||
)
|
||||
}
|
||||
})?.value.racks
|
||||
// 해당 rack으로 그려준다.
|
||||
|
||||
const centerRacks = rackInfos.find((rack) => {
|
||||
return rack.value.moduleRows === centerRows
|
||||
if (centerRowsInfo.rowsInfo.length === 1) {
|
||||
return (
|
||||
rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp &&
|
||||
rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
|
||||
)
|
||||
} else {
|
||||
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
|
||||
)
|
||||
}
|
||||
})?.value.racks
|
||||
|
||||
mostRowsModule = Math.max(leftRows, rightRows, centerRows, mostRowsModule)
|
||||
@ -336,6 +410,7 @@ export const useTrestle = () => {
|
||||
let leftRows = 1
|
||||
let hasNextModule = true
|
||||
let findLeft = true
|
||||
let findModuleList = [module]
|
||||
|
||||
//우선 절반을 나눈 뒤 왼쪽부터 찾는다.
|
||||
while (hasNextModule) {
|
||||
@ -345,6 +420,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
leftRows++
|
||||
findModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -371,6 +447,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
leftRows++
|
||||
findModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -379,10 +456,30 @@ export const useTrestle = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const leftModuleInfos = findModuleList.map((module) => {
|
||||
return {
|
||||
moduleTpCd: module.moduleInfo.moduleTpCd,
|
||||
}
|
||||
})
|
||||
const leftRowsInfo = moduleTransformData(leftModuleInfos)
|
||||
|
||||
// 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
|
||||
const leftRacks = rackInfos.find((rack) => {
|
||||
return rack.value.moduleRows === leftRows
|
||||
if (leftRowsInfo.rowsInfo.length === 1) {
|
||||
return (
|
||||
rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
|
||||
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
|
||||
)
|
||||
} else {
|
||||
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
|
||||
)
|
||||
}
|
||||
})?.value.racks
|
||||
|
||||
mostRowsModule = Math.max(leftRows, mostRowsModule)
|
||||
if (rackYn === 'Y') {
|
||||
drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn)
|
||||
@ -400,6 +497,7 @@ export const useTrestle = () => {
|
||||
let rightRows = 1
|
||||
let hasNextModule = true
|
||||
let findRight = true
|
||||
let findModuleList = [module]
|
||||
|
||||
// 오른쪽 찾는다.
|
||||
while (hasNextModule) {
|
||||
@ -409,6 +507,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
rightRows++
|
||||
findModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -424,6 +523,7 @@ export const useTrestle = () => {
|
||||
if (nextModule) {
|
||||
// 바로 위 모듈을 찾는다.
|
||||
rightRows++
|
||||
findModuleList.push(nextModule)
|
||||
x = nextModule.x
|
||||
y = nextModule.y
|
||||
} else {
|
||||
@ -432,11 +532,30 @@ export const useTrestle = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const rightRowsInfos = findModuleList.map((module) => {
|
||||
return {
|
||||
moduleTpCd: module.moduleInfo.moduleTpCd,
|
||||
}
|
||||
})
|
||||
|
||||
const rightRowsInfo = moduleTransformData(rightRowsInfos)
|
||||
|
||||
// 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
|
||||
const rightRacks = rackInfos.find((rack) => {
|
||||
return rack.value.moduleRows === rightRows
|
||||
if (rightRowsInfo.rowsInfo.length === 1) {
|
||||
return (
|
||||
rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
|
||||
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
|
||||
)
|
||||
} else {
|
||||
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
|
||||
)
|
||||
}
|
||||
})?.value.racks
|
||||
|
||||
mostRowsModule = Math.max(rightRows, mostRowsModule)
|
||||
// 해당 rack으로 그려준다.
|
||||
if (rackYn === 'Y') {
|
||||
@ -462,10 +581,24 @@ export const useTrestle = () => {
|
||||
|
||||
return setEstimateData()
|
||||
} catch (e) {
|
||||
return false
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
//module Rack 정보를 얻기위한 데이터 가공
|
||||
function moduleTransformData(arr) {
|
||||
let counts = {}
|
||||
|
||||
arr.forEach((item) => {
|
||||
counts[item.moduleTpCd] = (counts[item.moduleTpCd] || 0) + 1
|
||||
})
|
||||
|
||||
let moduleTotalTp = Object.keys(counts).join('')
|
||||
let rowsInfo = Object.entries(counts).map(([moduleTpCd, count]) => ({ moduleTpCd, count }))
|
||||
|
||||
return { moduleTotalTp, rowsInfo }
|
||||
}
|
||||
|
||||
// itemList 조회 후 estimateParam에 저장
|
||||
const setEstimateData = async () => {
|
||||
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
||||
@ -480,7 +613,7 @@ export const useTrestle = () => {
|
||||
//견적서 itemList 조회
|
||||
const res = await getQuotationItem(params)
|
||||
if (!res.data) {
|
||||
return false
|
||||
return null
|
||||
}
|
||||
const itemList = res.data
|
||||
//northArrangement 북면 설치 여부
|
||||
@ -540,10 +673,10 @@ export const useTrestle = () => {
|
||||
}
|
||||
})
|
||||
|
||||
setEstimateParam({ ...estimateParam, itemList, northArrangement, roofSurfaceList, circuitItemList })
|
||||
const estimateParam = { itemList, northArrangement, roofSurfaceList, circuitItemList }
|
||||
|
||||
// 정상적으로 완료 되면 true 반환
|
||||
return true
|
||||
return estimateParam
|
||||
}
|
||||
|
||||
const getNorthArrangement = () => {
|
||||
@ -565,9 +698,11 @@ export const useTrestle = () => {
|
||||
}
|
||||
|
||||
const findNextModule = (currentPoint, centerPoints, direction) => {
|
||||
let { x, y, width, height, horizontal, vertical } = { ...currentPoint }
|
||||
width = width + horizontal
|
||||
height = height + vertical
|
||||
let { x, y, horizontal, vertical } = { ...currentPoint }
|
||||
let { widthArr, heightArr } = centerPoints[0]
|
||||
|
||||
let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
|
||||
let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
|
||||
|
||||
let maxX = 2 + horizontal * 3
|
||||
let maxY = 2 + vertical * 3
|
||||
@ -596,7 +731,11 @@ export const useTrestle = () => {
|
||||
}
|
||||
|
||||
const findNextLeftModule = (currentPoint, centerPoints, direction) => {
|
||||
let { x, y, width, height, horizontal, vertical } = { ...currentPoint }
|
||||
let { x, y, horizontal, vertical } = { ...currentPoint }
|
||||
let { widthArr, heightArr } = centerPoints[0]
|
||||
|
||||
let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
|
||||
let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
|
||||
|
||||
let result
|
||||
let topLeftPoint
|
||||
@ -631,9 +770,11 @@ export const useTrestle = () => {
|
||||
return result
|
||||
}
|
||||
const findNextRightModule = (currentPoint, centerPoints, direction) => {
|
||||
let { x, y, width, height, horizontal, vertical } = { ...currentPoint }
|
||||
width = width + horizontal
|
||||
height = height + vertical
|
||||
let { x, y, horizontal, vertical } = { ...currentPoint }
|
||||
let { widthArr, heightArr } = centerPoints[0]
|
||||
|
||||
let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length + horizontal
|
||||
let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length + vertical
|
||||
let result
|
||||
let topRightPoint
|
||||
|
||||
@ -665,6 +806,9 @@ export const useTrestle = () => {
|
||||
}
|
||||
|
||||
const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l, rackYn) => {
|
||||
if (!rackInfos) {
|
||||
return
|
||||
}
|
||||
const { width, height, left, top, lastX, lastY, surfaceId } = module
|
||||
const surface = canvas.getObjects().find((obj) => obj.id === surfaceId)
|
||||
const roof = canvas.getObjects().find((obj) => obj.id === surface.parentId)
|
||||
@ -762,7 +906,7 @@ export const useTrestle = () => {
|
||||
name: 'smartRack',
|
||||
stroke: 'red',
|
||||
strokeWidth: 4,
|
||||
selectable: false,
|
||||
selectable: true,
|
||||
shadow: {
|
||||
color: 'black', // Outline color
|
||||
blur: 10,
|
||||
@ -774,17 +918,18 @@ export const useTrestle = () => {
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackLen: rackLength,
|
||||
rackRowsCd,
|
||||
seq,
|
||||
smartRackId,
|
||||
rackId: itemId,
|
||||
direction: 'top',
|
||||
})
|
||||
startPointY -= rackLength + 8
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointY -= rackLength + 8
|
||||
startPointY -= rackLength
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -844,13 +989,14 @@ export const useTrestle = () => {
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackLen: rackLength,
|
||||
rackRowsCd,
|
||||
seq,
|
||||
smartRackId,
|
||||
rackId: itemId,
|
||||
direction: 'left',
|
||||
})
|
||||
startPointX -= rackLength + 8
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
@ -873,7 +1019,7 @@ export const useTrestle = () => {
|
||||
selectable: false,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackLen: rackLength,
|
||||
rackYn,
|
||||
rackRowsCd,
|
||||
rackId: itemId,
|
||||
@ -913,17 +1059,18 @@ export const useTrestle = () => {
|
||||
surfaceId: surface.id,
|
||||
supFitQty,
|
||||
supFitIntvlPct,
|
||||
rackLen,
|
||||
rackLen: rackLength,
|
||||
rackRowsCd,
|
||||
seq,
|
||||
smartRackId,
|
||||
rackId: itemId,
|
||||
direction: 'right',
|
||||
})
|
||||
startPointX += rackLength + 8
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointX += rackLength + 8
|
||||
startPointX += rackLength
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -989,8 +1136,9 @@ export const useTrestle = () => {
|
||||
})
|
||||
canvas.add(rack)
|
||||
canvas.renderAll()
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointY += rackLength + 8
|
||||
} else if (setRackTpCd === 'INTVL') {
|
||||
startPointY += rackLength
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -1043,17 +1191,16 @@ export const useTrestle = () => {
|
||||
canvas.renderAll()
|
||||
|
||||
racks.forEach((rack) => {
|
||||
const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen } = rack
|
||||
const { 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 bracket = new fabric.Rect({
|
||||
left: x2 - bracketLength / 3,
|
||||
top: y2 + (rackLen / 10) * percent,
|
||||
top: name === 'smartRack' ? y2 + rackLen * percent : y2 + (rackLen / 10) * percent,
|
||||
fill: 'green',
|
||||
name: 'bracket',
|
||||
parentId: rack.parentId,
|
||||
@ -1071,7 +1218,7 @@ export const useTrestle = () => {
|
||||
|
||||
result.forEach((percent) => {
|
||||
const bracket = new fabric.Rect({
|
||||
left: x2 + (rackLen / 10) * percent,
|
||||
left: name === 'smartRack' ? x2 + rackLen * percent : x2 + (rackLen / 10) * percent,
|
||||
top: y2 - bracketLength / 3,
|
||||
fill: 'green',
|
||||
name: 'bracket',
|
||||
@ -1090,7 +1237,7 @@ export const useTrestle = () => {
|
||||
|
||||
result.forEach((percent) => {
|
||||
const bracket = new fabric.Rect({
|
||||
left: x2 - (rackLen / 10) * percent,
|
||||
left: name === 'smartRack' ? x2 - rackLen * percent : x2 - (rackLen / 10) * percent,
|
||||
top: y2 - bracketLength / 3,
|
||||
fill: 'green',
|
||||
parentId: rack.parentId,
|
||||
@ -1110,7 +1257,7 @@ export const useTrestle = () => {
|
||||
result.forEach((percent) => {
|
||||
const bracket = new fabric.Rect({
|
||||
left: x2 - bracketLength / 3,
|
||||
top: y2 - (rackLen / 10) * percent,
|
||||
top: name === 'smartRack' ? y2 - rackLen * percent : y2 - (rackLen / 10) * percent,
|
||||
fill: 'green',
|
||||
name: 'bracket',
|
||||
parentId: rack.parentId,
|
||||
@ -1337,8 +1484,49 @@ export const useTrestle = () => {
|
||||
return points.slice(0, 2)
|
||||
}
|
||||
|
||||
const calculateForApi = (moduleSurface) => {
|
||||
const getCenterPoints = (moduleSurface) => {
|
||||
const centerPoints = []
|
||||
let widthArr = []
|
||||
let heightArr = []
|
||||
const modules = moduleSurface.modules
|
||||
modules.forEach((module, index) => {
|
||||
module.tempIndex = index
|
||||
const { x, y } = module.getCenterPoint()
|
||||
const { width, height } = { ...module }
|
||||
widthArr.push(width)
|
||||
heightArr.push(height)
|
||||
centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index, moduleInfo: module.moduleInfo })
|
||||
})
|
||||
|
||||
//widthArr 중복 제거 1이상 차이가 나지 않으면 같은 너비로 간주
|
||||
widthArr = removeCloseValues(Array.from(new Set(widthArr)))
|
||||
heightArr = removeCloseValues(Array.from(new Set(heightArr)))
|
||||
|
||||
centerPoints.forEach((centerPoint, index) => {
|
||||
centerPoint.widthArr = [...widthArr]
|
||||
|
||||
centerPoint.heightArr = [...heightArr]
|
||||
})
|
||||
|
||||
function removeCloseValues(arr, threshold = 1) {
|
||||
arr.sort((a, b) => a - b) // 배열을 정렬
|
||||
|
||||
let result = []
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (i === 0 || Math.abs(arr[i] - arr[i - 1]) >= threshold) {
|
||||
result.push(arr[i])
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
return centerPoints
|
||||
}
|
||||
|
||||
const calculateForApi = (moduleSurface) => {
|
||||
const centerPoints = getCenterPoints(moduleSurface)
|
||||
const direction = moduleSurface.direction
|
||||
const modules = moduleSurface.modules
|
||||
|
||||
@ -1350,12 +1538,6 @@ export const useTrestle = () => {
|
||||
|
||||
const maxX = 2 + horizontal * 3
|
||||
const maxY = 2 + vertical * 3
|
||||
modules.forEach((module, index) => {
|
||||
module.tempIndex = index
|
||||
const { x, y } = module.getCenterPoint()
|
||||
const { width, height } = { ...module }
|
||||
centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index })
|
||||
})
|
||||
|
||||
if (centerPoints.length === 0) return
|
||||
|
||||
@ -1382,7 +1564,7 @@ export const useTrestle = () => {
|
||||
let rightExposedHalfTopPoints = []
|
||||
|
||||
centerPoints.forEach((centerPoint, index) => {
|
||||
let { x, y, width, height } = { ...centerPoint }
|
||||
let { x, y, width, height, widthArr, heightArr } = { ...centerPoint }
|
||||
// centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인
|
||||
let bottomCell
|
||||
let bottomLeftPoint
|
||||
@ -1392,28 +1574,29 @@ export const useTrestle = () => {
|
||||
|
||||
switch (direction) {
|
||||
case 'south':
|
||||
width = width + horizontal
|
||||
height = height + vertical
|
||||
//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 }
|
||||
break
|
||||
case 'north':
|
||||
width = width + horizontal
|
||||
height = height + vertical
|
||||
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 }
|
||||
break
|
||||
case 'east':
|
||||
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
|
||||
width = width + horizontal
|
||||
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 }
|
||||
break
|
||||
case 'west':
|
||||
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY)
|
||||
width = width + horizontal
|
||||
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 }
|
||||
break
|
||||
@ -1870,16 +2053,16 @@ export const useTrestle = () => {
|
||||
const { direction, modules } = surface
|
||||
let { rackYn, cvrPlvrYn, moduleIntvlHor, moduleIntvlVer, rackQty, lessSupFitQty } = surface.trestleDetail
|
||||
|
||||
const centerPoints = modules.map((module) => {
|
||||
return module.getCenterPoint()
|
||||
})
|
||||
const centerPoints = getCenterPoints(surface)
|
||||
|
||||
const horizontal = ['south', 'north'].includes(direction) ? moduleIntvlHor : moduleIntvlVer
|
||||
|
||||
const vertical = ['south', 'north'].includes(direction) ? moduleIntvlVer : moduleIntvlHor
|
||||
const maxX = 2 + horizontal * 3
|
||||
const maxY = 2 + vertical * 3
|
||||
let { width, height } = { ...module }
|
||||
let { widthArr, heightArr } = centerPoints[0]
|
||||
let width = widthArr.reduce((acc, num) => acc + num, 0) / widthArr.length
|
||||
let height = heightArr.reduce((acc, num) => acc + num, 0) / heightArr.length
|
||||
let { x, y } = { ...module.getCenterPoint() }
|
||||
|
||||
let halfBottomLeftPoint
|
||||
|
||||
59
src/hooks/useEstimate.js
Normal file
59
src/hooks/useEstimate.js
Normal file
@ -0,0 +1,59 @@
|
||||
import { useContext } from 'react'
|
||||
|
||||
import { useRecoilValue } from 'recoil'
|
||||
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||
import { currentCanvasPlanState } from '@/store/canvasAtom'
|
||||
import { loginUserStore } from '@/store/commonAtom'
|
||||
|
||||
export function useEstimate() {
|
||||
const { managementStateLoaded } = useContext(GlobalDataContext)
|
||||
|
||||
const loginUserState = useRecoilValue(loginUserStore)
|
||||
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
|
||||
|
||||
const { swalFire } = useSwal()
|
||||
const { promisePost } = useAxios()
|
||||
|
||||
/**
|
||||
* 도면 견적서 저장
|
||||
*/
|
||||
const saveEstimate = async (estimateParam) => {
|
||||
const userId = loginUserState.userId
|
||||
const saleStoreId = managementStateLoaded.saleStoreId
|
||||
const objectNo = currentCanvasPlan.objectNo
|
||||
const planNo = currentCanvasPlan.planNo
|
||||
const slope = estimateParam.roofSurfaceList[0].slope
|
||||
const angle = estimateParam.roofSurfaceList[0].angle
|
||||
const surfaceType = managementStateLoaded.surfaceType
|
||||
const setupHeight = managementStateLoaded.installHeight
|
||||
const standardWindSpeedId = managementStateLoaded.standardWindSpeedId
|
||||
const snowfall = managementStateLoaded.verticalSnowCover
|
||||
const drawingFlg = '1'
|
||||
|
||||
const saveEstimateData = {
|
||||
...estimateParam,
|
||||
userId: userId,
|
||||
saleStoreId: saleStoreId,
|
||||
objectNo: objectNo,
|
||||
planNo: planNo,
|
||||
slope: slope,
|
||||
angle: angle,
|
||||
surfaceType: surfaceType,
|
||||
setupHeight: setupHeight,
|
||||
standardWindSpeedId: standardWindSpeedId,
|
||||
snowfall: snowfall,
|
||||
drawingFlg: drawingFlg,
|
||||
}
|
||||
|
||||
await promisePost({ url: '/api/estimate/save-estimate', data: saveEstimateData }).catch((error) => {
|
||||
swalFire({ text: error.message, icon: 'error' })
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
saveEstimate,
|
||||
}
|
||||
}
|
||||
@ -999,5 +999,6 @@
|
||||
"construction.length.difference": "屋根面工法をすべて選択してください。",
|
||||
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
|
||||
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
|
||||
"batch.object.notinstall.cross": "オブジェクトは重複してインストールできません。"
|
||||
"batch.object.notinstall.cross": "オブジェクトは重複してインストールできません。",
|
||||
"module.not.batch.north": "북쪽에는 모듈을 배치할 수 없습니다."
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@
|
||||
"modal.module.basic.setting.orientation.setting.info": "※시뮬레이션 계산용 방위를 지정합니다. 남쪽의 방위를 설정해주세요.",
|
||||
"modal.module.basic.setting.orientation.setting.angle.passivity": "각도를 직접 입력",
|
||||
"modal.module.basic.setting.module.roof.material": "지붕재",
|
||||
"modal.module.basic.setting.module.trestle.maker": "가대메이거",
|
||||
"modal.module.basic.setting.module.trestle.maker": "가대메이커",
|
||||
"modal.module.basic.setting.module.rafter.margin": "서까래 간격",
|
||||
"modal.module.basic.setting.module.construction.method": "공법",
|
||||
"modal.module.basic.setting.module.under.roof": "지붕밑바탕",
|
||||
|
||||
@ -40,7 +40,10 @@ export const moduleStatisticsState = atom({
|
||||
{ name: `발전량(kW)`, prop: 'amount' },
|
||||
],
|
||||
rows: [],
|
||||
footer: ['합계', '0'],
|
||||
footer: [
|
||||
{ name: '-', prop: 'name' },
|
||||
{ name: 0, prop: 'amount' },
|
||||
],
|
||||
},
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user