배치 오브젝트 offset라인 작업

This commit is contained in:
yjnoh 2025-01-22 11:23:02 +09:00
parent 3a24cbc305
commit 4de8b7d617
9 changed files with 166 additions and 84 deletions

View File

@ -113,6 +113,7 @@ export const POLYGON_TYPE = {
TRESTLE: 'trestle',
MODULE_SETUP_SURFACE: 'moduleSetupSurface',
MODULE: 'module',
OBJECT_SURFACE: 'objectOffset',
}
export const SAVE_KEY = [

View File

@ -12,9 +12,8 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta
export default function Module({ setTabNum }) {
const { getMessage } = useMessage()
const addedRoofs = useRecoilValue(addedRoofsState) //
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //
const [roofTab, setRoofTab] = useState(0) //
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
const {
moduleSelectionInitParams,
@ -23,7 +22,9 @@ export default function Module({ setTabNum }) {
windSpeedCodes,
managementState,
moduleList,
selectedSurfaceType,
installHeight,
standardWindSpeed,
verticalSnowCover,
handleChangeModule,
handleChangeSurfaceType,
@ -32,7 +33,7 @@ export default function Module({ setTabNum }) {
handleChangeVerticalSnowCover,
} = useModuleSelection({ addedRoofs })
const [inputInstallHeight, setInputInstallHeight] = useState()``
const [inputInstallHeight, setInputInstallHeight] = useState()
const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState()
const [debouncedInstallHeight] = useDebounceValue(inputInstallHeight, 500)
@ -55,7 +56,7 @@ export default function Module({ setTabNum }) {
useEffect(() => {
if (tempModuleSelectionData) {
setModuleSelectionData(tempModuleSelectionData)
moduleSelectedDataTrigger(tempModuleSelectionData)
// moduleSelectedDataTrigger(tempModuleSelectionData)
}
}, [tempModuleSelectionData])
@ -88,11 +89,7 @@ export default function Module({ setTabNum }) {
setRoofTab(tab)
}
const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
useEffect(() => {
console.log('moduleSelectionData', moduleSelectionData)
}, [])
// const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
return (
<>
@ -247,6 +244,7 @@ export default function Module({ setTabNum }) {
key={index}
index={index}
addRoof={roof}
setAddedRoofs={setAddedRoofs}
roofTab={index}
tempModuleSelectionData={tempModuleSelectionData}
setTempModuleSelectionData={setTempModuleSelectionData}

View File

@ -7,10 +7,14 @@ import { useCommonCode } from '@/hooks/common/useCommonCode'
import { moduleSelectionDataState, moduleSelectionInitParamsState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isObjectNotEmpty } from '@/util/common-utils'
import QSelectBox from '@/components/common/select/QSelectBox'
import { addedRoofsState } from '@/store/settingAtom'
export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) {
export default function ModuleTabContents({ addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) {
const { getMessage } = useMessage()
const [roofMaterial, setRoofMaterial] = useState(addRoof) //`
const addRoofsArray = useRecoilValue(addedRoofsState)
const globalPitchText = useRecoilValue(pitchTextSelector) //
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
@ -51,6 +55,40 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) //
const [hajebichi, setHajebichi] = useState(0)
const [lengthBase, setLengthBase] = useState(0)
const hajebichiRef = useRef()
const lengthRef = useRef()
useEffect(() => {
setHajebichi(addRoof.hajebichi)
setLengthBase(addRoof.lenBase)
}, [])
// addRoofs
useEffect(() => {
// api
setTrestleParams({ ...trestleParams, workingWidth: lengthBase })
const copyAddRoof = { ...addRoof }
copyAddRoof.length = Number(lengthBase)
copyAddRoof.lenBase = lengthBase
const index = addRoof.index
const newArray = [...addRoofsArray.slice(0, index), copyAddRoof, ...addRoofsArray.slice(index + 1)]
setAddedRoofs(newArray)
}, [lengthBase])
// addRoof
useEffect(() => {
const copyAddRoof = { ...addRoof }
copyAddRoof.hajebichi = Number(hajebichi)
copyAddRoof.roofPchBase = hajebichi
const index = addRoof.index
const newArray = [...addRoofsArray.slice(0, index), copyAddRoof, ...addRoofsArray.slice(index + 1)]
setAddedRoofs(newArray)
}, [hajebichi])
useEffect(() => {
setModuleConstructionSelectionData(moduleSelectionData.roofConstructions[roofTab])
}, [moduleSelectionData])
@ -76,7 +114,13 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
//
const handleChangeConstMthd = (option) => {
setSelectedConstMthd(option) //
setRoofBaseParams({ ...trestleParams, trestleMkrCd: selectedTrestle.trestleMkrCd, constMthdCd: option.constMthdCd, roofBaseCd: '' })
setRoofBaseParams({
...trestleParams,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: option.constMthdCd,
roofBaseCd: '',
roofPitch: hajebichiRef.current ? hajebichiRef.current.value : '',
})
setRoofBaseList([]) //
setConstructionList([]) //
}
@ -114,6 +158,14 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
selectedConstruction.setupSnowCover = false //
selectedConstruction.selectedIndex = index
//
if (moduleConstructionSelectionData && moduleConstructionSelectionData.construction) {
selectedConstruction.setupCover = moduleConstructionSelectionData.construction.setupCover
selectedConstruction.setupSnowCover = moduleConstructionSelectionData.construction.setupSnowCover
setCvrChecked(selectedConstruction.setupCover)
setSnowGdChecked(selectedConstruction.setupSnowCover)
}
setCvrYn(selectedConstruction.cvrYn)
setSnowGdPossYn(selectedConstruction.snowGdPossYn)
setSelectedConstruction(selectedConstruction)
@ -126,10 +178,12 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
const handleCvrChecked = () => {
setCvrChecked(!cvrChecked)
setSelectedConstruction({ ...selectedConstruction, setupCover: !cvrChecked })
}
const handleSnowGdChecked = () => {
setSnowGdChecked(!snowGdChecked)
setSelectedConstruction({ ...selectedConstruction, setupSnowCover: !snowGdChecked })
}
const getModuleOptionsListData = async (params) => {
@ -195,14 +249,6 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
}
}, [selectedConstruction])
useEffect(() => {
setSelectedConstruction({ ...selectedConstruction, setupCover: cvrChecked })
}, [cvrChecked])
useEffect(() => {
setSelectedConstruction({ ...selectedConstruction, setupSnowCover: snowGdChecked })
}, [snowGdChecked])
useEffect(() => {
if (isExistData) {
setConstructionListParams({
@ -215,7 +261,12 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
}, [selectedRoofBase])
useEffect(() => {
if (isExistData && constructionList.length > 0) {
if (
isExistData &&
constructionList.length > 0 &&
isObjectNotEmpty(moduleConstructionSelectionData.construction) &&
moduleConstructionSelectionData.construction.hasOwnProperty('constPossYn') ///
) {
const selectedIndex = moduleConstructionSelectionData.construction.selectedIndex
const construction = constructionList[selectedIndex]
if (construction.constPossYn === 'Y') {
@ -245,15 +296,19 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
) {
const isModuleLoaded = moduleSelectionInitParams.hasOwnProperty('moduleTpCd') //
if (isModuleLoaded) {
setTrestleParams({ moduleTpCd: moduleSelectionInitParams.moduleTpCd, roofMatlCd: addRoof.roofMatlCd, raftBaseCd: addRoof.raftBaseCd })
setTrestleParams({
moduleTpCd: moduleSelectionInitParams.moduleTpCd,
roofMatlCd: addRoof.roofMatlCd,
raftBaseCd: addRoof.raftBaseCd,
workingWidth: lengthBase,
})
setConstructionList([])
if (isObjectNotEmpty(moduleConstructionSelectionData)) {
//
setConstructionParams({ ...moduleConstructionSelectionData.trestle, constMthdCd: '', roofBaseCd: '' })
setRoofBaseParams({ ...moduleConstructionSelectionData.trestle, roofBaseCd: '' })
setCvrChecked(moduleConstructionSelectionData.construction.setupCover)
setSnowGdChecked(moduleConstructionSelectionData.construction.setupSnowCover)
setIsExistData(true)
}
}
@ -286,11 +341,11 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
}
}, [constructionListParams])
useEffect(() => {
if (isObjectNotEmpty(tempModuleSelectionData)) {
setModuleSelectionData(tempModuleSelectionData)
}
}, [tempModuleSelectionData])
// useEffect(() => {
// if (isObjectNotEmpty(tempModuleSelectionData)) {
// setModuleSelectionData(tempModuleSelectionData)
// }
// }, [tempModuleSelectionData])
return (
<>
@ -308,21 +363,21 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
<>
<div className="eaves-keraba-th">L</div>
<div className="eaves-keraba-td">
<div className="keraba-flex">
<div className="outline-form">
<div className="grid-select">
<input
type="text"
className="input-origin block"
value={roofMaterial.lenBase}
disabled={roofMaterial.lenAuth === 'R' ? true : false}
/>
</div>
</div>
<div className="grid-select">
<input
type="text"
className="input-origin block"
value={lengthBase}
onChange={(e) => setLengthBase(e.target.value)}
disabled={roofMaterial.lenAuth === 'R' ? true : false}
ref={lengthRef}
/>
</div>
</div>
</>
)}
</div>
<div className="eaves-keraba-item">
{roofMaterial && ['C', 'R'].includes(roofMaterial.raftAuth) && (
<>
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.rafter.margin')}</div>
@ -343,22 +398,21 @@ export default function ModuleTabContents({ addRoof, roofTab, tempModuleSelectio
</div>
</>
)}
</div>
<div className="eaves-keraba-item">
{roofMaterial && ['C', 'R'].includes(roofMaterial.roofPchAuth) && (
<>
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.rafter.margin')}</div>
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.hajebichi')}</div>
<div className="eaves-keraba-td">
<div className="keraba-flex">
<div className="outline-form">
<span>垂木の間隔</span>
<div className="grid-select">
<input
type="text"
className="input-origin block"
value={roofMaterial.hajebichi}
disabled={roofMaterial.roofPchAuth === 'R' ? true : false}
/>
</div>
</div>
<div className="grid-select">
<input
type="text"
className="input-origin block"
disabled={roofMaterial.roofPchAuth === 'R' ? true : false}
onChange={(e) => setHajebichi(e.target.value)}
value={hajebichi}
ref={hajebichiRef}
/>
</div>
</div>
</>

View File

@ -73,6 +73,7 @@ export function useModuleBasicSetting() {
const makeModuleInstArea = () => {
//지붕 객체 반환
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
let offsetLength = canvasSetting.roofSizeSet === 3 ? -90 : -20
@ -80,6 +81,50 @@ export function useModuleBasicSetting() {
return
}
const batchObjects = canvas
?.getObjects()
.filter(
(obj) =>
obj.name === BATCH_TYPE.OPENING ||
obj.name === BATCH_TYPE.SHADOW ||
obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
obj.name === BATCH_TYPE.PENTAGON_DORMER,
) //도머s 객체
//도머도 외곽을 따야한다
const batchObjectOptions = {
stroke: 'red',
fill: 'transparent',
strokeDashArray: [10, 4],
strokeWidth: 1,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
selectable: true,
name: POLYGON_TYPE.OBJECT_SURFACE,
originX: 'center',
originY: 'center',
}
batchObjects.forEach((obj) => {
if (obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) {
const groupPoints = obj.groupPoints
const offsetObjects = offsetPolygon(groupPoints, 10)
const dormerOffset = new QPolygon(offsetObjects, batchObjectOptions)
dormerOffset.setViewLengthText(false)
canvas.add(dormerOffset) //모듈설치면 만들기
} else {
const points = obj.points
const offsetObjects = offsetPolygon(points, 10)
const offset = new QPolygon(offsetObjects, batchObjectOptions)
offset.setViewLengthText(false)
canvas.add(offset) //모듈설치면 만들기
}
})
roofs.forEach((roof) => {
const isExistSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.parentId === roof.id)
if (isExistSurface) {
@ -190,15 +235,7 @@ export function useModuleBasicSetting() {
}
const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴
const batchObjects = canvas
?.getObjects()
.filter(
(obj) =>
obj.name === BATCH_TYPE.OPENING ||
obj.name === BATCH_TYPE.TRIANGLE_DORMER ||
obj.name === BATCH_TYPE.PENTAGON_DORMER ||
obj.name === BATCH_TYPE.SHADOW,
) //도머s 객체
const batchObjects = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.OBJECT_SURFACE) //도머s 객체
const moduleOptions = {
fill: checkedModule[0].color,
@ -449,17 +486,7 @@ export function useModuleBasicSetting() {
//도머 객체를 가져옴
if (batchObjects) {
batchObjects.forEach((object) => {
let dormerTurfPolygon
if (object.type === 'group') {
//도머는 그룹형태임
dormerTurfPolygon = batchObjectGroupToTurfPolygon(object)
} else {
//개구, 그림자
object.set({ points: rectToPolygon(object) })
dormerTurfPolygon = polygonToTurfPolygon(object)
}
let dormerTurfPolygon = polygonToTurfPolygon(object, true)
const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
//겹치면 안됨
if (intersection) {
@ -1220,6 +1247,7 @@ export function useModuleBasicSetting() {
}
const coordToTurfPolygon = (points) => {
console.log('points', points)
const coordinates = points.map((point) => [point.x, point.y])
coordinates.push(coordinates[0])
return turf.polygon([coordinates])

View File

@ -28,7 +28,7 @@ export function useModulePlace() {
roofBaseCd: item.trestle.roofBaseCd,
constTp: item.construction.constTp,
mixMatlNo: selectedModules.mixMatlNo,
roofPitch: selectedModules.roofPchBase ? selectedModules.roofPchBase : null,
roofPitch: item.addRoof.roofPchBase ? item.addRoof.roofPchBase : null,
inclCd: String(item.addRoof.pitch),
roofIndex: item.addRoof.index,
workingWidth: item.addRoof.lenBase,

View File

@ -4,7 +4,7 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { useMasterController } from '@/hooks/common/useMasterController'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import { selectedModuleState, moduleSelectionInitParamsState } from '@/store/selectedModuleOptions'
import { selectedModuleState, moduleSelectionInitParamsState, moduleSelectionDataState } from '@/store/selectedModuleOptions'
export function useModuleSelection(props) {
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
@ -13,15 +13,14 @@ export function useModuleSelection(props) {
const [windSpeedCodes, setWindSpeedCodes] = useState([]) //기준풍속 목록
const [moduleList, setModuleList] = useState([{}]) //모듈 목록
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈
const [selectedSurfaceType, setSelectedSurfaceType] = useState({}) //선택된 면조도
const [installHeight, setInstallHeight] = useState() //설치 높이
const [standardWindSpeed, setStandardWindSpeed] = useState({}) //기준풍속
const [verticalSnowCover, setVerticalSnowCover] = useState() //수직적설량
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈
const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등
const { getModuleTypeItemList } = useMasterController()
const { findCommonCode } = useCommonCode()
const bindInitData = () => {
@ -73,8 +72,6 @@ export function useModuleSelection(props) {
return
}
console.log('managementState', managementState)
//새로고침시 데이터 날아가는거 방지
if (managementState === null) {
setManagementState(managementStateLoaded)

View File

@ -169,7 +169,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
}
isDown = false
rect.set({ name: objName, parentId: selectedSurface.id })
rect.set({ name: objName, parentId: selectedSurface.id, points: rectToPolygon(rect) })
rect.setCoords()
initEvent()
@ -251,7 +251,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
}
isDown = false
rect.set({ name: objName, parentId: selectedSurface.id })
rect.set({ name: objName, parentId: selectedSurface.id, points: rectToPolygon(rect) })
rect.setCoords()
initEvent()
if (setIsHidden) setIsHidden(false)
@ -377,9 +377,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer))
const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface)
console.log('trianglePolygon', trianglePolygon)
console.log('selectedSurfacePolygon', selectedSurfacePolygon)
//지붕 밖으로 그렸을때
if (!turf.booleanWithin(trianglePolygon, selectedSurfacePolygon)) {
swalFire({ text: '도머를 배치할 수 없습니다.', icon: 'error' })
@ -406,6 +403,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
direction = 'north'
}
const groupPoints = offsetRef > 0 ? triangleToPolygon(dormerOffset) : triangleToPolygon(dormer)
let splitedTriangle = offsetRef > 0 ? splitDormerTriangle(dormerOffset, directionRef) : splitDormerTriangle(dormer, directionRef)
canvas?.remove(offsetRef > 0 ? dormerOffset : dormer)
@ -499,6 +498,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
parentId: selectedSurface.id,
originX: 'center',
originY: 'center',
groupPoints: groupPoints,
})
canvas?.add(objectGroup)
@ -708,6 +708,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
}
const groupPolygon = offsetPolygon ? [leftPentagon, rightPentagon, offsetPolygon] : [leftPentagon, rightPentagon]
const groupPoints = offsetRef > 0 ? pentagonOffsetPoints : pentagonPoints
const objectGroup = new fabric.Group(groupPolygon, {
subTargetCheck: true,
@ -717,6 +718,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
groupYn: true,
originX: 'center',
originY: 'center',
groupPoints: groupPoints,
})
canvas?.add(objectGroup)

View File

@ -94,6 +94,7 @@
"modal.module.basic.setting.module.construction.method": "공법",
"modal.module.basic.setting.module.under.roof": "지붕밑바탕",
"modal.module.basic.setting.module.setting": "모듈 선택",
"modal.module.basic.setting.module.hajebichi": "망둥어 피치",
"modal.module.basic.setting.module.setting.info1": "※ 구배의 범위에는 제한이 있습니다. 지붕경사가 2.5치 미만, 10치를 초과하는 경우에는 시공이 가능한지 시공 매뉴얼을 확인해주십시오.",
"modal.module.basic.setting.module.setting.info2": "※ 모듈 배치 시에는 시공 매뉴얼에 기재된 <모듈 배치 조건>을 반드시 확인해주십시오.",
"modal.module.basic.setting.module.stuff.info": "물건정보",

View File

@ -81,6 +81,7 @@ export const moduleSelectionDataState = atom({
key: 'moduleSelectionDataState',
default: {
common: {},
module: {},
roofConstructions: [],
},
dangerouslyAllowMutability: true,