hyojun.choi 19ec9ad874 Merge branch 'dev' of https://git.hanasys.jp/qcast3/qcast-front into feature/jaeyoung
# Conflicts:
#	src/common/common.js
#	src/components/floor-plan/CanvasFrame.jsx
#	src/hooks/roofcover/useWallLineOffsetSetting.js
#	src/util/qpolygon-utils.js
2025-05-13 15:22:11 +09:00

201 lines
7.2 KiB
JavaScript

'use client'
import { useContext, useEffect, useRef } from 'react'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import QContextMenu from '@/components/common/context-menu/QContextMenu'
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
import ImgLoad from '@/components/floor-plan/modal/ImgLoad'
import { useCanvas } from '@/hooks/useCanvas'
import { usePlan } from '@/hooks/usePlan'
import { useContextMenu } from '@/hooks/useContextMenu'
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
import { currentMenuState } from '@/store/canvasAtom'
import { roofMaterialsAtom, totalDisplaySelector } from '@/store/settingAtom'
import { MENU, POLYGON_TYPE } from '@/common/common'
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
import { QcastContext } from '@/app/QcastProvider'
import {
makersState,
modelsState,
moduleStatisticsState,
pcsCheckState,
selectedMakerState,
selectedModelsState,
seriesState,
} from '@/store/circuitTrestleAtom'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
import { useEvent } from '@/hooks/useEvent'
import { compasDegAtom } from '@/store/orientationAtom'
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
import { useMasterController } from '@/hooks/common/useMasterController'
import { hotkeyStore } from '@/store/hotkeyAtom'
import { usePopup } from '@/hooks/usePopup'
export default function CanvasFrame() {
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
const { getRoofMaterialList } = useMasterController()
useEffect(() => {
async function initRoofMaterial() {
if (roofMaterials.length !== 0) {
return
}
const { data } = await getRoofMaterialList()
const roofLists = data.map((item, idx) => ({
...item,
id: item.roofMatlCd,
name: item.roofMatlNm,
selected: idx === 0,
index: idx,
nameJp: item.roofMatlNmJp,
length: item.lenBase && parseInt(item.lenBase),
width: item.widBase && parseInt(item.widBase),
raft: item.raftBase && parseInt(item.raftBase),
layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL,
hajebichi: item.roofPchBase && parseInt(item.roofPchBase),
pitch: item.pitch ? parseInt(item.pitch) : 4,
angle: item.angle ? parseInt(item.angle) : 21.8,
}))
setRoofMaterials(roofLists)
}
initRoofMaterial()
}, [])
const canvasRef = useRef(null)
const { canvas } = useCanvas('canvas')
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
const { closeAll } = usePopup()
const currentMenu = useRecoilValue(currentMenuState)
const { floorPlanState } = useContext(FloorPlanContext)
const { contextMenu, handleClick } = useContextMenu()
const { plans, currentCanvasPlan, resetCanvasStatus } = usePlan()
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
const { setIsGlobalLoading } = useContext(QcastContext)
const resetModuleStatisticsState = useResetRecoilState(moduleStatisticsState)
const resetMakersState = useResetRecoilState(makersState)
const resetSelectedMakerState = useResetRecoilState(selectedMakerState)
const resetSeriesState = useResetRecoilState(seriesState)
const resetModelsState = useResetRecoilState(modelsState)
const resetCompasDeg = useResetRecoilState(compasDegAtom)
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
const { basicSetting, fetchBasicSettings } = useCanvasSetting()
const { selectedMenu, setSelectedMenu } = useCanvasMenu()
const { initEvent } = useEvent()
const loadCanvas = () => {
if (!canvas) return
canvas?.clear() // 캔버스를 초기화합니다.
if (currentCanvasPlan) {
const plan = plans.find((plan) => plan.id === currentCanvasPlan.id)
if (plan?.canvasStatus && floorPlanState.objectNo === currentCanvasPlan.objectNo) {
canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () {
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
canvas?.renderAll() // 캔버스를 다시 그립니다.
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
setSelectedMenu('module')
} else {
setSelectedMenu('surface')
}
initEvent()
})
}
Object.keys(currentCanvasPlan).length > 0 && canvas && handleModuleSelectionTotal()
}
gridInit()
}
useEffect(() => {
loadCanvas()
resetRecoilData()
/* 플랜번호가 있으면 베이직세팅 팝업 데이터 로드 */
if (currentCanvasPlan.planNo) {
/* 약간의 지연을 줘서 roofMaterials가 로드될 시간을 확보 */
setTimeout(() => {
fetchBasicSettings(Number(currentCanvasPlan.planNo), null)
}, 100)
}
}, [currentCanvasPlan, canvas])
useEffect(() => {
setIsGlobalLoading(false)
// 혹시 모를 팝업이 떠있는 경우 닫고 시작한다.
closeAll()
return () => {
canvas?.clear()
resetCanvasStatus()
}
}, [])
const resetRecoilData = () => {
// resetModuleStatisticsState()
resetMakersState()
resetSelectedMakerState()
resetSeriesState()
resetModelsState()
resetCompasDeg()
resetSelectedModelsState()
resetPcsCheckState()
}
/**
* 캔버스가 있을 경우 핫키 이벤트 처리
* hotkeyStore에 핫키 이벤트 리스너 추가
*
* const hotkeys = [
{ key: 'c', fn: () => asdf() },
{ key: 'v', fn: () => qwer() },
]
setHotkeyStore(hotkeys)
*/
const hotkeyState = useRecoilValue(hotkeyStore)
const hotkeyHandlerRef = useRef(null)
useEffect(() => {
hotkeyHandlerRef.current = (e) => {
hotkeyState.forEach((hotkey) => {
if (e.key === hotkey.key) {
hotkey.fn()
}
})
}
document.addEventListener('keyup', hotkeyHandlerRef.current)
return () => {
if (hotkeyHandlerRef.current) {
document.removeEventListener('keyup', hotkeyHandlerRef.current)
}
}
}, [hotkeyState])
/** 핫키 이벤트 처리 끝 */
return (
<div className="canvas-frame">
<canvas ref={canvasRef} id="canvas" style={{ position: 'relative' }}></canvas>
<QContextMenu contextRef={canvasRef} canvasProps={canvas}>
{contextMenu?.map((menus, index) => (
<ul key={index}>
{menus.map((menu) => (
<li key={menu.id} onClick={(e) => handleClick(e, menu)}>
{menu.name}
</li>
))}
</ul>
))}
</QContextMenu>
{selectedMenu === 'module' && totalDisplay && <PanelBatchStatistics />}
{/* 이미지 로드 팝업 */}
<ImgLoad />
</div>
)
}