Merge branch 'dev' into feature/jaeyoung
This commit is contained in:
commit
37a1c2ce39
@ -55,6 +55,10 @@ export default async function RootLayout({ children }) {
|
||||
redirect('/login')
|
||||
}
|
||||
|
||||
if (headerPathname === '/login' && session.isLoggedIn) {
|
||||
redirect('/')
|
||||
}
|
||||
|
||||
return (
|
||||
<RecoilRootWrapper>
|
||||
<html lang="en">
|
||||
|
||||
@ -159,6 +159,7 @@ export const SAVE_KEY = [
|
||||
'offset',
|
||||
'arrow',
|
||||
'surfaceCompass',
|
||||
'surfaceCompassType',
|
||||
'moduleCompass',
|
||||
'isFixed',
|
||||
'modules',
|
||||
|
||||
@ -13,14 +13,14 @@ import ChangePasswordPop from './main/ChangePasswordPop'
|
||||
import { searchState } from '@/store/boardAtom'
|
||||
import { SessionContext } from '@/app/SessionProvider'
|
||||
import { QcastContext } from '@/app/QcastProvider'
|
||||
import { sessionStore } from '@/store/commonAtom'
|
||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
|
||||
export default function MainPage() {
|
||||
export default function MainPage(mainPageProps) {
|
||||
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
||||
const [chagePasswordPopOpen, setChagePasswordPopOpen] = useState(false)
|
||||
const { session } = useContext(SessionContext)
|
||||
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
|
||||
const { promiseGet } = useAxios(globalLocaleState)
|
||||
const router = useRouter()
|
||||
const { getMessage } = useMessage()
|
||||
|
||||
@ -74,10 +74,12 @@ export default function MainPage() {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (session?.pwdInitYn !== 'Y') {
|
||||
setChagePasswordPopOpen(true)
|
||||
if (isObjectNotEmpty(sessionState)) {
|
||||
if (sessionState?.pwdInitYn !== 'Y') {
|
||||
setChagePasswordPopOpen(true)
|
||||
}
|
||||
}
|
||||
}, [session])
|
||||
}, [sessionState])
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@ -8,6 +8,7 @@ import { FaAnglesDown } from 'react-icons/fa6'
|
||||
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { convertDwgToPng } from '@/lib/cadAction'
|
||||
import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom'
|
||||
|
||||
@ -35,6 +36,7 @@ export default function Playground() {
|
||||
const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL
|
||||
const { getMessage } = useMessage()
|
||||
const { swalFire } = useSwal()
|
||||
const { getRoofMaterialList, getModuleTypeItemList } = useMasterController()
|
||||
|
||||
const [color, setColor] = useState('#ff0000')
|
||||
|
||||
@ -156,6 +158,24 @@ export default function Playground() {
|
||||
<>
|
||||
<div className="container mx-auto p-4 m-4 border">
|
||||
<div className={styles.test}>이 영역은 테스트입니다.</div>
|
||||
<div className="my-2">
|
||||
<button
|
||||
className="btn-frame deepgray"
|
||||
onClick={() => {
|
||||
getRoofMaterialList()
|
||||
}}
|
||||
>
|
||||
지붕재 목록 조회 API 호출
|
||||
</button>
|
||||
<button
|
||||
className="btn-frame deepgray"
|
||||
onClick={() => {
|
||||
getModuleTypeItemList('ROOF_ID_HIRA_SEME')
|
||||
}}
|
||||
>
|
||||
모듈 타입별 아이템 목록 조회 API 호출
|
||||
</button>
|
||||
</div>
|
||||
<div className="m-2">
|
||||
<button
|
||||
className="btn-frame deepgray"
|
||||
|
||||
@ -8,13 +8,28 @@ import { contextPopupPositionState } from '@/store/popupAtom'
|
||||
|
||||
export default function ColorPickerModal(props) {
|
||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState) // 현재 메뉴
|
||||
const { isShow, setIsShow, pos = contextPopupPosition, color, setColor, id, isConfig = false } = props //color = '#ff0000'
|
||||
const {
|
||||
isShow,
|
||||
setIsShow,
|
||||
pos = contextPopupPosition,
|
||||
color,
|
||||
setColor,
|
||||
id,
|
||||
name,
|
||||
isConfig = false,
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
} = props //color = '#ff0000'
|
||||
const [originColor, setOriginColor] = useState(color)
|
||||
const { getMessage } = useMessage()
|
||||
const { closePopup } = usePopup()
|
||||
|
||||
useEffect(() => {
|
||||
setOriginColor(originColor)
|
||||
//치수선색설정 아닐 때만 바로 저장 실행
|
||||
if (name !== 'DimensionLineColor') setSettingsDataSave({ ...settingsData })
|
||||
}, [isShow])
|
||||
|
||||
return (
|
||||
@ -49,6 +64,13 @@ export default function ColorPickerModal(props) {
|
||||
if (setColor) setColor(originColor)
|
||||
if (setIsShow) setIsShow(false)
|
||||
|
||||
//치수선색설정 아닐 때만 바로 저장 실행
|
||||
if (name !== 'DimensionLineColor')
|
||||
setSettingsData({
|
||||
...settingsData,
|
||||
color: originColor,
|
||||
})
|
||||
|
||||
closePopup(id, isConfig)
|
||||
}}
|
||||
>
|
||||
|
||||
@ -25,7 +25,6 @@ export default function Estimate({ params }) {
|
||||
const [uniqueData, setUniqueData] = useState([])
|
||||
const [handlePricingFlag, setHandlePricingFlag] = useState(false)
|
||||
const [specialNoteFirstFlg, setSpecialNoteFirstFlg] = useState(false)
|
||||
const fixedKey = 'itemKey'
|
||||
const [itemChangeYn, setItemChangeYn] = useState(false)
|
||||
const { session } = useContext(SessionContext)
|
||||
const [objectNo, setObjectNo] = useState('') //물건번호
|
||||
@ -147,14 +146,18 @@ export default function Estimate({ params }) {
|
||||
}
|
||||
}
|
||||
})
|
||||
//detail과 상관없이 디폴트 체크목록
|
||||
//ATTR003,ATTR007
|
||||
if (row.code === 'ATTR003') {
|
||||
//row.check = true
|
||||
}
|
||||
if (row.code === 'ATTR007') {
|
||||
//row.check = true
|
||||
}
|
||||
|
||||
if (estimateContextState.estimateType === 'YJOD') {
|
||||
if (row.code === 'ATTR002') {
|
||||
row.check = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setSpecialNoteList(res)
|
||||
@ -1100,9 +1103,11 @@ export default function Estimate({ params }) {
|
||||
<div className="input-wrap mr5" style={{ width: '610px' }}>
|
||||
<input type="text" className="input-light" value={roofList} readOnly />
|
||||
</div>
|
||||
<div className="input-wrap" style={{ width: '200px' }}>
|
||||
<input type="text" className="input-light" value={constructSpecificationMulti[index]} readOnly />
|
||||
</div>
|
||||
{constructSpecificationMulti ? (
|
||||
<div className="input-wrap" style={{ width: '200px' }}>
|
||||
<input type="text" className="input-light" value={constructSpecificationMulti[index]} readOnly />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
@ -1191,7 +1196,6 @@ export default function Estimate({ params }) {
|
||||
{originFiles.map((originFile) => {
|
||||
return (
|
||||
<li className="file-item" key={originFile.no}>
|
||||
{/* <li className="file-item" key={uuidv4()}> */}
|
||||
<div className="file-item-wrap">
|
||||
<span
|
||||
style={{ display: originFile.delFlg === '0' ? '' : 'none' }}
|
||||
@ -1254,7 +1258,6 @@ export default function Estimate({ params }) {
|
||||
{specialNoteList.length > 0 &&
|
||||
specialNoteList.map((row) => {
|
||||
return (
|
||||
// <div key={uuidv4()} className="special-note-check-item">
|
||||
<div key={row.code} className="special-note-check-item">
|
||||
<div className="special-note-check-box">
|
||||
<div className="d-check-box light">
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import { useContext, useRef } from 'react'
|
||||
import { useRef } from 'react'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { SessionContext } from '@/app/SessionProvider'
|
||||
|
||||
export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) {
|
||||
const fileInputRef = useRef(null)
|
||||
const { getMessage } = useMessage()
|
||||
const { session } = useContext(SessionContext)
|
||||
|
||||
const handleButtonClick = (e) => {
|
||||
e.preventDefault()
|
||||
@ -20,13 +18,32 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) {
|
||||
return
|
||||
}
|
||||
|
||||
const { files } = e.target
|
||||
const file = files[0]
|
||||
const fileType = file.type
|
||||
if (!fileType.includes('image')) {
|
||||
return alert(getMessage('estimate.detail.fileList.extCheck'))
|
||||
const fileList = []
|
||||
let passFlag = true
|
||||
Array.from(e.target.files).forEach((file) => {
|
||||
let fileType = file.type
|
||||
if (!fileType.includes('image')) {
|
||||
passFlag = false
|
||||
} else {
|
||||
fileList.push({ data: file, id: uuidv4() })
|
||||
}
|
||||
})
|
||||
|
||||
if (!passFlag) {
|
||||
alert(getMessage('estimate.detail.fileList.extCheck'))
|
||||
}
|
||||
|
||||
// const { files } = e.target
|
||||
// const file = files[0]
|
||||
// const fileType = file.type
|
||||
// if (!fileType.includes('image')) {
|
||||
// return alert(getMessage('estimate.detail.fileList.extCheck'))
|
||||
// }
|
||||
|
||||
// setUploadFiles([...uploadFiles, { data: e.target.files[0], id: uuidv4() }])
|
||||
//다중으로 변경
|
||||
setUploadFiles([...uploadFiles, ...fileList])
|
||||
e.target.value = ''
|
||||
// const formData = new FormData()
|
||||
// formData.append('file', e.target.files[0])
|
||||
// formData.append('objectNo', objectNo) // 받아와야 하는 값
|
||||
@ -37,8 +54,6 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) {
|
||||
// await promisePost({ url: '/api/file/fileUpload', data: formData }).then((res) => {
|
||||
// if (res.data > 0) setUploadFiles([...files, { name: e.target.files[0].name, id: uuidv4() }])
|
||||
// })
|
||||
setUploadFiles([...uploadFiles, { data: e.target.files[0], id: uuidv4() }])
|
||||
e.target.value = ''
|
||||
}
|
||||
|
||||
const deleteFile = (id) => {
|
||||
@ -49,9 +64,21 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const fileList = []
|
||||
let passFlag = true
|
||||
|
||||
Array.from(e.dataTransfer.files).forEach((file) => {
|
||||
fileList.push({ data: file, id: uuidv4() })
|
||||
let fileType = file.type
|
||||
if (!fileType.includes('image')) {
|
||||
passFlag = false
|
||||
} else {
|
||||
fileList.push({ data: file, id: uuidv4() })
|
||||
}
|
||||
})
|
||||
|
||||
if (!passFlag) {
|
||||
alert(getMessage('estimate.detail.fileList.extCheck'))
|
||||
}
|
||||
|
||||
setUploadFiles([...uploadFiles, ...fileList])
|
||||
}
|
||||
|
||||
@ -76,7 +103,16 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) {
|
||||
<label className="file-upload" htmlFor="img" onClick={handleButtonClick}>
|
||||
{getMessage('estimate.detail.fileList.btn')}
|
||||
</label>
|
||||
<input type="file" name="file" id="img" accept="image/*" ref={fileInputRef} style={{ display: 'none' }} onChange={(e) => onChangeFiles(e)} />
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
name="file"
|
||||
id="img"
|
||||
accept="image/*"
|
||||
ref={fileInputRef}
|
||||
style={{ display: 'none' }}
|
||||
onChange={(e) => onChangeFiles(e)}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="drag-file-area"
|
||||
|
||||
@ -4,7 +4,7 @@ import { QLine } from '@/components/fabric/QLine'
|
||||
import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util'
|
||||
import { calculateAngle, drawGabledRoof, drawRidgeRoof, drawShedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils'
|
||||
import * as turf from '@turf/turf'
|
||||
import { LINE_TYPE } from '@/common/common'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
|
||||
export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
type: 'QPolygon',
|
||||
@ -689,6 +689,15 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
|
||||
return intersects % 2 === 1
|
||||
},
|
||||
containsPoint: function (point) {
|
||||
if (this.name === POLYGON_TYPE.ROOF && this.isFixed) {
|
||||
const isInside = this.inPolygon(point)
|
||||
this.set('selectable', isInside)
|
||||
return isInside
|
||||
} else {
|
||||
return this.callSuper('containsPoint', point)
|
||||
}
|
||||
},
|
||||
|
||||
inPolygonABType(x, y, polygon) {
|
||||
let inside = false
|
||||
|
||||
@ -41,6 +41,7 @@ import { pwrGnrSimTypeState } from '@/store/simulatorAtom'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
|
||||
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
|
||||
export default function CanvasMenu(props) {
|
||||
const { menuNumber, setMenuNumber } = props
|
||||
@ -78,6 +79,9 @@ export default function CanvasMenu(props) {
|
||||
const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
||||
const { restoreModuleInstArea } = useModuleBasicSetting()
|
||||
|
||||
//견적서버튼 노출용
|
||||
const [buttonStyle, setButtonStyle] = useState('')
|
||||
|
||||
const onClickNav = (menu) => {
|
||||
setMenuNumber(menu.index)
|
||||
setCurrentMenu(menu.title)
|
||||
@ -241,6 +245,16 @@ export default function CanvasMenu(props) {
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(estimateRecoilState)) {
|
||||
if (estimateRecoilState?.createUser === 'T01') {
|
||||
if (sessionState.userId !== 'T01') {
|
||||
setButtonStyle('none')
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [estimateRecoilState])
|
||||
|
||||
return (
|
||||
<div className={`canvas-menu-wrap ${[2, 3, 4].some((num) => num === menuNumber) ? 'active' : ''}`}>
|
||||
<div className="canvas-menu-inner">
|
||||
@ -320,11 +334,12 @@ export default function CanvasMenu(props) {
|
||||
<span className="ico ico01"></span>
|
||||
<span className="name">{getMessage('plan.menu.estimate.docDown')}</span>
|
||||
</button>
|
||||
<button className="btn-frame gray ico-flx" onClick={handleEstimateSubmit}>
|
||||
<button style={{ display: buttonStyle }} className="btn-frame gray ico-flx" onClick={handleEstimateSubmit}>
|
||||
<span className="ico ico02"></span>
|
||||
<span className="name">{getMessage('plan.menu.estimate.save')}</span>
|
||||
</button>
|
||||
<button
|
||||
style={{ display: buttonStyle }}
|
||||
className="btn-frame gray ico-flx"
|
||||
onClick={() => {
|
||||
handleEstimateReset()
|
||||
@ -345,7 +360,7 @@ export default function CanvasMenu(props) {
|
||||
<span className="name">{getMessage('plan.menu.estimate.copy')}</span>
|
||||
</button>
|
||||
)}
|
||||
<button className="btn-frame gray ico-flx">
|
||||
<button style={{ display: buttonStyle }} className="btn-frame gray ico-flx">
|
||||
<span className="ico ico05"></span>
|
||||
<span className="name">{getMessage('plan.menu.estimate.unLock')}</span>
|
||||
</button>
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
import { forwardRef, useState, useEffect } from 'react'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
||||
import { compasDegAtom } from '@/store/orientationAtom'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
|
||||
const PitchPlacement = forwardRef((props, refs) => {
|
||||
const { getMessage } = useMessage()
|
||||
const [setupLocation, setSetupLocation] = useState('south')
|
||||
const { makeModuleInstArea } = useModuleBasicSetting()
|
||||
const compasDeg = useRecoilValue(compasDegAtom)
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const { initEvent } = useEvent()
|
||||
|
||||
useEffect(() => {
|
||||
makeModuleInstArea()
|
||||
@ -45,6 +45,7 @@ const PitchPlacement = forwardRef((props, refs) => {
|
||||
}
|
||||
|
||||
const handleSetupLocation = (e) => {
|
||||
initEvent()
|
||||
refs.setupLocation.current = e.target
|
||||
setSetupLocation(e.target.value)
|
||||
}
|
||||
@ -153,7 +154,7 @@ const PitchPlacement = forwardRef((props, refs) => {
|
||||
value={'south'}
|
||||
checked={setupLocation === 'south'}
|
||||
defaultChecked
|
||||
onChange={handleSetupLocation}
|
||||
onClick={handleSetupLocation}
|
||||
/>
|
||||
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.south')}</label>
|
||||
</div>
|
||||
@ -164,7 +165,7 @@ const PitchPlacement = forwardRef((props, refs) => {
|
||||
id="ra02"
|
||||
value={'excreta'}
|
||||
checked={setupLocation === 'excreta'}
|
||||
onChange={handleSetupLocation}
|
||||
onClick={handleSetupLocation}
|
||||
/>
|
||||
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.select')}</label>
|
||||
</div>
|
||||
|
||||
@ -5,9 +5,14 @@ import { useRecoilValue } from 'recoil'
|
||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
||||
import { FLOW_DIRECTION_TYPE, useFlowDirectionSetting } from '@/hooks/contextpopup/useFlowDirectionSetting'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
|
||||
const FLOW_DIRECTION_TYPE = {
|
||||
EIGHT_AZIMUTH: 'eightAzimuth',
|
||||
TWENTY_FOUR_AZIMUTH: 'twentyFourAzimuth',
|
||||
}
|
||||
|
||||
export default function FlowDirectionSetting(props) {
|
||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||
const { id, pos = contextPopupPosition, target } = props
|
||||
@ -20,10 +25,9 @@ export default function FlowDirectionSetting(props) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const [compasDeg, setCompasDeg] = useState(null)
|
||||
const [compasDeg, setCompasDeg] = useState(target.surfaceCompass ?? null)
|
||||
const [flowDirection, setFlowDirection] = useState(target.direction)
|
||||
const { closePopup } = usePopup()
|
||||
const { changeSurfaceFlowDirection, type, setType } = useFlowDirectionSetting(id)
|
||||
|
||||
const orientations = [
|
||||
{ name: `${getMessage('commons.none')}`, value: 0 },
|
||||
@ -36,7 +40,27 @@ export default function FlowDirectionSetting(props) {
|
||||
{ name: `${getMessage('commons.north')}${getMessage('commons.west')}`, value: 135 },
|
||||
{ name: `${getMessage('commons.north')}`, value: 180 },
|
||||
]
|
||||
const [selectedOrientation, setSelectedOrientation] = useState(orientations[0])
|
||||
|
||||
const { drawDirectionArrow } = usePolygon()
|
||||
|
||||
const [type, setType] = useState(target.surfaceCompassType ?? FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH)
|
||||
|
||||
const changeSurfaceFlowDirection = (roof, direction, orientation) => {
|
||||
roof.set({
|
||||
direction: direction,
|
||||
surfaceCompass: orientation,
|
||||
surfaceCompassType: type,
|
||||
})
|
||||
drawDirectionArrow(roof)
|
||||
canvas?.renderAll()
|
||||
closePopup(id)
|
||||
}
|
||||
|
||||
const [selectedOrientation, setSelectedOrientation] = useState(
|
||||
target.surfaceCompassType !== null && target.surfaceCompassType === FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH
|
||||
? orientations.find((item) => item.value === target.surfaceCompass)
|
||||
: orientations[0],
|
||||
)
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={pos}>
|
||||
@ -84,9 +108,8 @@ export default function FlowDirectionSetting(props) {
|
||||
</div>
|
||||
<div className="grid-select ">
|
||||
<QSelectBox
|
||||
title={''}
|
||||
title={selectedOrientation.name}
|
||||
options={orientations}
|
||||
value={selectedOrientation}
|
||||
onChange={(e) => {
|
||||
setType(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH)
|
||||
setSelectedOrientation(e)
|
||||
@ -116,7 +139,7 @@ export default function FlowDirectionSetting(props) {
|
||||
{Array.from({ length: 180 / 15 + 1 }).map((dot, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`circle ${compasDeg === 15 * (12 + index) ? 'act' : ''}`}
|
||||
className={`circle ${compasDeg === 15 * (12 + index) && type === FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH)
|
||||
setCompasDeg(15 * (12 + index))
|
||||
@ -126,7 +149,7 @@ export default function FlowDirectionSetting(props) {
|
||||
{Array.from({ length: 180 / 15 - 1 }).map((dot, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`circle ${compasDeg === 15 * (index + 1) ? 'act' : ''}`}
|
||||
className={`circle ${compasDeg === 15 * (index + 1) && type === FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH)
|
||||
setCompasDeg(15 * (index + 1))
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
@ -17,27 +17,26 @@ const TYPE = {
|
||||
export default function DotLineGrid(props) {
|
||||
// const [modalOption, setModalOption] = useRecoilState(modalState); //modal 열림닫힘 state
|
||||
//const interval = useRecoilValue(dotLineIntervalSelector)
|
||||
const { id, setIsShow, pos = { x: 840, y: -815 }, isConfig = false } = props
|
||||
const { id, setIsShow, pos = { x: 840, y: -815 }, isConfig = false, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
|
||||
const { getMessage } = useMessage()
|
||||
const { closePopup } = usePopup()
|
||||
const { swalFire } = useSwal()
|
||||
|
||||
const {
|
||||
selectOption,
|
||||
setSelectOption,
|
||||
SelectOptions,
|
||||
currentSetting,
|
||||
setCurrentSetting,
|
||||
dotLineGridSettingState,
|
||||
setSettingModalGridOptions,
|
||||
setDotLineGridSettingState,
|
||||
} = useCanvasSetting()
|
||||
const [selectOption, setSelectOption] = useState()
|
||||
|
||||
const { SelectOptions, currentSetting, setCurrentSetting, dotLineGridSettingState, setSettingModalGridOptions, setDotLineGridSettingState } =
|
||||
useCanvasSetting()
|
||||
|
||||
// 데이터를 최초 한 번만 조회
|
||||
useEffect(() => {
|
||||
console.log('DotLineGrid useEffect 실행')
|
||||
setSettingsDataSave({ ...settingsData })
|
||||
|
||||
// dimension 값에 맞는 옵션을 선택
|
||||
const matchedOption = SelectOptions.find((option) => option.value == currentSetting.INTERVAL.dimension)
|
||||
setSelectOption(matchedOption)
|
||||
|
||||
return () => {
|
||||
setSettingModalGridOptions((prev) => {
|
||||
@ -84,11 +83,23 @@ export default function DotLineGrid(props) {
|
||||
},
|
||||
DOT: currentSetting.DOT,
|
||||
LINE: currentSetting.LINE,
|
||||
flag: true,
|
||||
}
|
||||
//setDotLineGridSettingState({ ...currentSetting })
|
||||
})
|
||||
|
||||
setSettingsData({
|
||||
...settingsData,
|
||||
INTERVAL: {
|
||||
type: currentSetting.INTERVAL.type,
|
||||
horizontalInterval: currentSetting.INTERVAL.horizontalInterval,
|
||||
verticalInterval: currentSetting.INTERVAL.verticalInterval,
|
||||
ratioInterval: currentSetting.INTERVAL.ratioInterval,
|
||||
dimension: currentSetting.INTERVAL.dimension,
|
||||
},
|
||||
DOT: currentSetting.DOT,
|
||||
LINE: currentSetting.LINE,
|
||||
})
|
||||
|
||||
setIsShow(false)
|
||||
closePopup(id, isConfig)
|
||||
}
|
||||
|
||||
@ -8,68 +8,37 @@ import MaterialGuide from '@/components/floor-plan/modal/placementShape/Material
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
|
||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { roofMaterialsAtom } from '@/store/settingAtom'
|
||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
|
||||
export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) {
|
||||
const [showSizeGuideModal, setShowSizeGuidModal] = useState(false)
|
||||
const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false)
|
||||
const { closePopup } = usePopup()
|
||||
const { getMessage } = useMessage()
|
||||
const roofMaterials = useRecoilValue(roofMaterialsAtom)
|
||||
|
||||
const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting()
|
||||
const [currentRoofMaterial, setCurrentRoofMaterial] = useState(
|
||||
isObjectNotEmpty(basicSetting.selectedRoofMaterial) ? basicSetting.selectedRoofMaterial : roofMaterials[0],
|
||||
)
|
||||
|
||||
// 데이터를 최초 한 번만 조회
|
||||
useEffect(() => {
|
||||
fetchBasicSettings()
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
console.log(currentRoofMaterial)
|
||||
}, [roofMaterials])
|
||||
|
||||
// Function to update the roofType and corresponding values
|
||||
const handleRoofTypeChange = (index, value) => {
|
||||
const updatedRoofs = [...basicSetting.roofs]
|
||||
const roofType = parseInt(value, 10)
|
||||
|
||||
// Reset other values based on the selected roofType
|
||||
if (roofType === 1) {
|
||||
updatedRoofs[index] = {
|
||||
...updatedRoofs[index],
|
||||
roofType: 1,
|
||||
roofWidth: 265,
|
||||
roofHeight: 235,
|
||||
roofGap: 455,
|
||||
roofHajebichi: 0,
|
||||
}
|
||||
} else if (roofType === 2) {
|
||||
updatedRoofs[index] = {
|
||||
...updatedRoofs[index],
|
||||
roofType: 2,
|
||||
roofGap: 265,
|
||||
roofHajebichi: 265,
|
||||
roofWidth: 0,
|
||||
roofHeight: 0,
|
||||
}
|
||||
} else if (roofType === 3) {
|
||||
updatedRoofs[index] = {
|
||||
...updatedRoofs[index],
|
||||
roofType: 3,
|
||||
roofHajebichi: 265,
|
||||
roofGap: 0,
|
||||
roofWidth: 0,
|
||||
roofHeight: 0,
|
||||
}
|
||||
} else if (roofType === 4) {
|
||||
updatedRoofs[index] = {
|
||||
...updatedRoofs[index],
|
||||
roofType: 4,
|
||||
roofHeight: 265,
|
||||
roofGap: 265,
|
||||
roofHajebichi: 0,
|
||||
roofWidth: 0,
|
||||
}
|
||||
}
|
||||
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: updatedRoofs,
|
||||
})
|
||||
const handleRoofTypeChange = (value) => {
|
||||
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value)
|
||||
setCurrentRoofMaterial(selectedRoofMaterial)
|
||||
/*const newBasicSetting = { ...basicSetting }
|
||||
setBasicSettings({ ...newBasicSetting, selectedRoofMaterial: selectedRoofMaterial })*/
|
||||
}
|
||||
|
||||
return (
|
||||
@ -180,16 +149,19 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofType"
|
||||
value={basicSetting.roofs[0].roofType}
|
||||
onChange={(e) => handleRoofTypeChange(0, e.target.value)}
|
||||
value={currentRoofMaterial.roofMatlCd}
|
||||
onChange={(e) => handleRoofTypeChange(e.target.value)}
|
||||
>
|
||||
<option value="1">瓦 type A</option>
|
||||
<option value="2">瓦 type B</option>
|
||||
<option value="3">瓦 type C</option>
|
||||
<option value="4">瓦 type D</option>
|
||||
{roofMaterials.map((roof, index) => {
|
||||
return (
|
||||
<option key={index} value={roof.roofMatlCd}>
|
||||
{roof.roofMatlNm}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
{basicSetting.roofs[0].roofType === 1 ? (
|
||||
{['R', 'C'].includes(currentRoofMaterial.widAuth) && (
|
||||
<>
|
||||
<div className="flex-ment">
|
||||
<span>W</span>
|
||||
@ -197,204 +169,67 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofWidth"
|
||||
value={basicSetting.roofs[0].roofWidth}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofWidth: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofWidth: e.target.value })
|
||||
}}
|
||||
>
|
||||
<option>265</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-ment">
|
||||
<span>L</span>
|
||||
<div className="select-wrap" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofHeight"
|
||||
value={basicSetting.roofs[0].roofHeight}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofHeight: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option>235</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||
<div className="select-wrap" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofGap"
|
||||
value={basicSetting.roofs[0].roofGap}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofGap: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option>455</option>
|
||||
<option value={parseInt(currentRoofMaterial.widBase)}>{parseInt(currentRoofMaterial.widBase)}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : basicSetting.roofs[0].roofType === 2 ? (
|
||||
<>
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('hajebichi')}</span>
|
||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofHajebichi"
|
||||
value={basicSetting.roofs[0].roofHajebichi}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofHajebichi: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option>265</option>
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
{['R', 'C'].includes(currentRoofMaterial.lenAuth) && (
|
||||
<div className="flex-ment">
|
||||
<span>L</span>
|
||||
<div className="select-wrap" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofHeight"
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofHeight: e.target.value })
|
||||
}}
|
||||
>
|
||||
<option value={parseInt(currentRoofMaterial.lenBase)}>{parseInt(currentRoofMaterial.lenBase)}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||
<div className="grid-select no-flx right" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofGap"
|
||||
value={basicSetting.roofs[0].roofGap}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofGap: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option>265</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{['C', 'R'].includes(currentRoofMaterial.raftAuth) && (
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||
<div className="select-wrap" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofGap"
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofGap: e.target.value })
|
||||
}}
|
||||
>
|
||||
<option>455</option>
|
||||
</select>
|
||||
</div>
|
||||
</>
|
||||
) : basicSetting.roofs[0].roofType === 3 ? (
|
||||
<>
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('hajebichi')}</span>
|
||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofHajebichi"
|
||||
value={basicSetting.roofs[0].roofHajebichi}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofHajebichi: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option>265</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{['C', 'R'].includes(currentRoofMaterial.roofPchAuth) && (
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('hajebichi')}</span>
|
||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofHajebichi"
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setCurrentRoofMaterial({ ...currentRoofMaterial, roofHajebichi: e.target.value })
|
||||
}}
|
||||
>
|
||||
<option value={parseInt(currentRoofMaterial.roofPchBase)}>{parseInt(currentRoofMaterial.roofPchBase)}</option>
|
||||
</select>
|
||||
</div>
|
||||
</>
|
||||
) : basicSetting.roofs[0].roofType === 4 ? (
|
||||
<>
|
||||
<div className="flex-ment">
|
||||
<span>L</span>
|
||||
<div className="grid-select no-flx" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofHeight"
|
||||
value={basicSetting.roofs[0].roofHeight}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofHeight: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option>265</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||
<div className="grid-select no-flx right" style={{ width: '84px' }}>
|
||||
<select
|
||||
className="select-light dark"
|
||||
name="roofGap"
|
||||
value={basicSetting.roofs[0].roofGap}
|
||||
onChange={(e) => {
|
||||
// 상태 업데이트 함수 호출
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofs: [
|
||||
{
|
||||
...basicSetting.roofs[0],
|
||||
roofGap: e.target.value,
|
||||
},
|
||||
],
|
||||
})
|
||||
}}
|
||||
>
|
||||
<option>265</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@ -8,21 +8,22 @@ import { useEvent } from '@/hooks/useEvent'
|
||||
export default function FirstOption(props) {
|
||||
const { getMessage } = useMessage()
|
||||
// const { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = useCanvasSetting()
|
||||
let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData } = props
|
||||
let { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||
const { initEvent } = useEvent()
|
||||
|
||||
// 데이터를 최초 한 번만 조회
|
||||
useEffect(() => {
|
||||
console.log('FirstOption useEffect 실행')
|
||||
setSettingsDataSave({ ...settingsData })
|
||||
}, [])
|
||||
|
||||
const onClickOption = async (item) => {
|
||||
//치수 표시(단 건 선택)
|
||||
let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay
|
||||
let option1 = settingModalFirstOptions?.option1
|
||||
let option2 = settingModalFirstOptions?.option2
|
||||
|
||||
//치수 표시(단 건 선택)
|
||||
if (item.column === 'corridorDimension' || item.column === 'realDimension' || item.column === 'noneDimension') {
|
||||
dimensionDisplay = settingModalFirstOptions?.dimensionDisplay.map((option) => {
|
||||
option.selected = option.id === item.id
|
||||
@ -33,9 +34,9 @@ export default function FirstOption(props) {
|
||||
|
||||
//화면 표시(단 건 선택)
|
||||
} else if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') {
|
||||
option2 = settingModalFirstOptions?.option2.map((option2) => {
|
||||
option2.selected = option2.id === item.id
|
||||
return option2
|
||||
option2 = settingModalFirstOptions?.option2.map((option) => {
|
||||
option.selected = option.id === item.id
|
||||
return option
|
||||
})
|
||||
|
||||
// setSettingModalFirstOptions({ ...settingModalFirstOptions, option2: [...options] })
|
||||
@ -47,11 +48,11 @@ export default function FirstOption(props) {
|
||||
})
|
||||
//디스플레이 설정 표시(단 건 선택)
|
||||
} else {
|
||||
option1 = settingModalFirstOptions?.option1.map((opt) => {
|
||||
if (opt.id === item.id) {
|
||||
opt.selected = !opt.selected
|
||||
option1 = settingModalFirstOptions?.option1.map((option) => {
|
||||
if (option.id === item.id) {
|
||||
option.selected = !option.selected
|
||||
}
|
||||
return opt
|
||||
return option
|
||||
})
|
||||
|
||||
// setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] })
|
||||
|
||||
@ -28,8 +28,13 @@ export default function GridOption(props) {
|
||||
|
||||
const { initEvent } = useEvent()
|
||||
|
||||
const { SelectOptions, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = useCanvasSetting()
|
||||
|
||||
useEffect(() => {
|
||||
console.log('GridOption useEffect 실행')
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
setGridColor(color.hex)
|
||||
}, [color])
|
||||
|
||||
@ -96,7 +101,7 @@ export default function GridOption(props) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log('🚀 ~ useEffect ~ initEvent:')
|
||||
//console.log('🚀 ~ useEffect ~ initEvent:')
|
||||
initEvent()
|
||||
}, [gridOptions])
|
||||
|
||||
@ -108,10 +113,15 @@ export default function GridOption(props) {
|
||||
x: 845,
|
||||
y: 180,
|
||||
},
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
|
||||
const colorPickerProps = {
|
||||
id: colorId,
|
||||
name: 'gridOptionColor',
|
||||
color: gridColor,
|
||||
setColor: setGridColor,
|
||||
isShow: showColorPickerModal,
|
||||
@ -121,6 +131,10 @@ export default function GridOption(props) {
|
||||
x: 785,
|
||||
y: 180,
|
||||
},
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -27,16 +27,6 @@ export default function SecondOption(props) {
|
||||
|
||||
const { initEvent } = useEvent()
|
||||
|
||||
// const {
|
||||
// fetchSettings,
|
||||
// planSizeSettingMode,
|
||||
// setPlanSizeSettingMode,
|
||||
// settingModalSecondOptions,
|
||||
// setSettingModalSecondOptions,
|
||||
// adsorptionPointMode,
|
||||
// setAdsorptionPointMode,
|
||||
// setAdsorptionRange,
|
||||
// } = useCanvasSetting()
|
||||
const {
|
||||
fetchSettings,
|
||||
planSizeSettingMode,
|
||||
@ -46,12 +36,17 @@ export default function SecondOption(props) {
|
||||
adsorptionPointMode,
|
||||
setAdsorptionPointMode,
|
||||
setAdsorptionRange,
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
} = props
|
||||
const { option3, option4 } = settingModalSecondOptions
|
||||
|
||||
// 데이터를 최초 한 번만 조회
|
||||
useEffect(() => {
|
||||
console.log('SecondOption useEffect 실행')
|
||||
setSettingsDataSave({ ...settingsData })
|
||||
}, [])
|
||||
|
||||
const handlePopup = (type) => {
|
||||
@ -142,18 +137,23 @@ export default function SecondOption(props) {
|
||||
return {
|
||||
...prev,
|
||||
[fontProps.type]: {
|
||||
// fontFamily: font.fontFamily.value,
|
||||
// fontWeight: font.fontWeight.value,
|
||||
// fontSize: font.fontSize.value,
|
||||
// fontColor: font.fontColor.value,
|
||||
fontFamily: font.fontFamily,
|
||||
fontWeight: font.fontWeight,
|
||||
fontSize: font.fontSize,
|
||||
fontColor: font.fontColor,
|
||||
},
|
||||
fontFlag: true,
|
||||
}
|
||||
})
|
||||
|
||||
setSettingsData({
|
||||
...settingsData,
|
||||
[fontProps.type]: {
|
||||
fontFamily: font.fontFamily,
|
||||
fontWeight: font.fontWeight,
|
||||
fontSize: font.fontSize,
|
||||
fontColor: font.fontColor,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const fontProps = {
|
||||
@ -168,6 +168,10 @@ export default function SecondOption(props) {
|
||||
id: dimensionId,
|
||||
isShow: showDimensionLineSettingModal,
|
||||
setIsShow: setShowDimensionLineSettingModal,
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
|
||||
const planSizeProps = {
|
||||
@ -177,9 +181,16 @@ export default function SecondOption(props) {
|
||||
isShow: showPlanSizeSettingModal,
|
||||
setIsShow: setShowPlanSizeSettingModal,
|
||||
pos: { x: 1025, y: 180 },
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
|
||||
const onClickOption = async (item) => {
|
||||
let option4Data = settingModalSecondOptions?.option4
|
||||
let adsorpPointData = adsorptionPointMode.adsorptionPoint
|
||||
|
||||
//흡착범위 설정(단 건 선택)
|
||||
if (
|
||||
item.column === 'adsorpRangeSmall' ||
|
||||
@ -189,21 +200,25 @@ export default function SecondOption(props) {
|
||||
) {
|
||||
// option4에서 한 개만 선택 가능하도록 처리
|
||||
//const updatedOption4 = option4.map((option) => (option.id === item.id ? { ...option, selected: true } : { ...option, selected: false }))
|
||||
const options = settingModalSecondOptions?.option4.map((option4) => {
|
||||
option4.selected = option4.id === item.id
|
||||
return option4
|
||||
option4Data = settingModalSecondOptions?.option4.map((option) => {
|
||||
option.selected = option.id === item.id
|
||||
return option
|
||||
})
|
||||
|
||||
setSettingModalSecondOptions({ ...settingModalSecondOptions, option3, option4, fontFlag: true })
|
||||
//흡착점 범위
|
||||
setAdsorptionRange(item.range)
|
||||
|
||||
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: adsorpPointData })
|
||||
} else if (item === 'adsorpPoint') {
|
||||
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: !adsorptionPointMode.adsorptionPoint, fontFlag: true })
|
||||
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: !adsorpPointData })
|
||||
adsorpPointData = !adsorpPointData
|
||||
}
|
||||
//setAdsorptionRange(item.range) //사용여부 확인 필요
|
||||
setAdsorptionRange(50)
|
||||
|
||||
setSettingsData({ ...settingsData, option4: [...option4Data], adsorptionPoint: adsorpPointData })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log('🚀 ~ useEffect ~ initEvent:')
|
||||
//console.log('🚀 ~ useEffect ~ initEvent:')
|
||||
initEvent()
|
||||
}, [adsorptionPointMode])
|
||||
|
||||
|
||||
@ -24,7 +24,11 @@ export default function SettingModal01(props) {
|
||||
setSettingModalFirstOptions,
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
fetchSettings,
|
||||
globalFont,
|
||||
setGlobalFont,
|
||||
planSizeSettingMode,
|
||||
setPlanSizeSettingMode,
|
||||
settingModalSecondOptions,
|
||||
@ -36,9 +40,19 @@ export default function SettingModal01(props) {
|
||||
setGridColor,
|
||||
color,
|
||||
} = useCanvasSetting()
|
||||
const firstProps = { canvas, settingModalFirstOptions, setSettingModalFirstOptions, settingsData, setSettingsData }
|
||||
const firstProps = {
|
||||
canvas,
|
||||
settingModalFirstOptions,
|
||||
setSettingModalFirstOptions,
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
const secondProps = {
|
||||
fetchSettings,
|
||||
globalFont,
|
||||
setGlobalFont,
|
||||
planSizeSettingMode,
|
||||
setPlanSizeSettingMode,
|
||||
settingModalSecondOptions,
|
||||
@ -46,6 +60,10 @@ export default function SettingModal01(props) {
|
||||
adsorptionPointMode,
|
||||
setAdsorptionPointMode,
|
||||
setAdsorptionRange,
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
const gridProps = { gridColor, setGridColor, color }
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ const fontSizes = [
|
||||
]
|
||||
|
||||
export default function DimensionLineSetting(props) {
|
||||
const { isShow, setIsShow, id, pos = { x: 985, y: 180 } } = props
|
||||
const { isShow, setIsShow, id, pos = { x: 985, y: 180 }, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
||||
const { addPopup, closePopup, closePopups } = usePopup()
|
||||
const pixels = Array.from({ length: 5 }).map((_, index) => {
|
||||
return { id: index, name: index + 1, value: index + 1 }
|
||||
@ -111,11 +111,16 @@ export default function DimensionLineSetting(props) {
|
||||
color: originColor,
|
||||
setColor: setOriginColor,
|
||||
id: colorModalId,
|
||||
name: 'DimensionLineColor',
|
||||
isConfig: true,
|
||||
pos: {
|
||||
x: 495,
|
||||
y: 180,
|
||||
},
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
|
||||
const fontProps = {
|
||||
@ -157,9 +162,9 @@ export default function DimensionLineSetting(props) {
|
||||
fontSize: originFontSize,
|
||||
fontColor: originFontColor,
|
||||
},
|
||||
fontFlag: true,
|
||||
}
|
||||
})
|
||||
|
||||
setDimensionLineSettings((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
@ -167,6 +172,19 @@ export default function DimensionLineSetting(props) {
|
||||
color: originColor,
|
||||
}
|
||||
})
|
||||
|
||||
setSettingsData({
|
||||
...settingsData,
|
||||
dimensionLineText: {
|
||||
fontFamily: originFont,
|
||||
fontWeight: originFontWeight,
|
||||
fontSize: originFontSize,
|
||||
fontColor: originFontColor,
|
||||
},
|
||||
pixel: originPixel.name,
|
||||
color: originColor,
|
||||
})
|
||||
|
||||
setIsShow(false)
|
||||
closePopups([fontModalId, colorModalId, id])
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||
|
||||
export default function PlanSizeSetting(props) {
|
||||
const { setIsShow, horizon, vertical, id, pos = { x: 985, y: 180 } } = props
|
||||
const { setIsShow, horizon, vertical, id, pos = { x: 985, y: 180 }, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
||||
const { closePopup } = usePopup()
|
||||
const { getMessage } = useMessage()
|
||||
|
||||
@ -26,10 +26,15 @@ export default function PlanSizeSetting(props) {
|
||||
...prev,
|
||||
originHorizon: Number(planSizeSettingMode.originHorizon),
|
||||
originVertical: Number(planSizeSettingMode.originVertical),
|
||||
flag: true,
|
||||
}
|
||||
})
|
||||
|
||||
setSettingsData({
|
||||
...settingsData,
|
||||
originHorizon: Number(planSizeSettingMode.originHorizon),
|
||||
originVertical: Number(planSizeSettingMode.originVertical),
|
||||
})
|
||||
|
||||
canvas.setWidth(planSizeSettingMode.originHorizon)
|
||||
canvas.setHeight(planSizeSettingMode.originVertical)
|
||||
canvas.renderAll()
|
||||
@ -40,12 +45,11 @@ export default function PlanSizeSetting(props) {
|
||||
|
||||
const changeInput = (value, e) => {
|
||||
const { name } = e.target
|
||||
console.log('name', name, value)
|
||||
|
||||
setPlanSizeSettingMode((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
[name]: Number(value),
|
||||
flag: false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import { useAxios } from '@/hooks/useAxios'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { setSession } from '@/lib/authActions'
|
||||
|
||||
import { logout } from '@/lib/authActions'
|
||||
export default function ChangePasswordPop(props) {
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
|
||||
@ -77,18 +77,21 @@ export default function ChangePasswordPop(props) {
|
||||
if (res?.result?.code === 200) {
|
||||
if (res?.result?.resultCode === 'S') {
|
||||
alert(getMessage('main.popup.login.success'))
|
||||
logout()
|
||||
//로그인 화면으로 이동해서 다시 로그인해야되서 setSessionState필요없음
|
||||
// setSessionState({ ...sessionState, pwdInitYn: 'Y' })
|
||||
props.setChagePasswordPopOpen(false)
|
||||
router.push('/login')
|
||||
//props.setChagePasswordPopOpen(false)
|
||||
//router.push('/login')
|
||||
} else {
|
||||
alert(res?.result?.resultMsg)
|
||||
}
|
||||
} else {
|
||||
logout()
|
||||
console.log('code not 200 error')
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
logout()
|
||||
console.log('catch::::::::', error)
|
||||
})
|
||||
}
|
||||
@ -165,7 +168,8 @@ export default function ChangePasswordPop(props) {
|
||||
type="button"
|
||||
className="btn-origin grey"
|
||||
onClick={() => {
|
||||
router.push('/login')
|
||||
logout()
|
||||
// router.push('/login')
|
||||
}}
|
||||
>
|
||||
{getMessage('main.popup.login.btn2')}
|
||||
|
||||
@ -10,7 +10,7 @@ import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { useRecoilValue, useSetRecoilState, useResetRecoilState, useRecoilState } from 'recoil'
|
||||
import { useRecoilValue, useSetRecoilState, useResetRecoilState } from 'recoil'
|
||||
import { SessionContext } from '@/app/SessionProvider'
|
||||
import FindAddressPop from './popup/FindAddressPop'
|
||||
import PlanRequestPop from './popup/PlanRequestPop'
|
||||
@ -41,7 +41,6 @@ export default function StuffDetail() {
|
||||
const { session } = useContext(SessionContext)
|
||||
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
const searchParams = useSearchParams()
|
||||
const { getMessage } = useMessage()
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useContext, useEffect } from 'react'
|
||||
import { useState, useContext, useEffect } from 'react'
|
||||
|
||||
import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
@ -11,20 +11,37 @@ import { useSetRecoilState } from 'recoil'
|
||||
import { QcastContext } from '@/app/QcastProvider'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||
import { queryStringFormatter } from '@/util/common-utils'
|
||||
import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils'
|
||||
|
||||
import { ManagementContext } from '@/app/management/ManagementProvider'
|
||||
import { SessionContext } from '@/app/SessionProvider'
|
||||
|
||||
export default function StuffSubHeader({ type }) {
|
||||
const { getMessage } = useMessage()
|
||||
const router = useRouter()
|
||||
const { session } = useContext(SessionContext)
|
||||
|
||||
const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState)
|
||||
|
||||
const { isGlobalLoading } = useContext(QcastContext)
|
||||
|
||||
const { managementState } = useContext(ManagementContext)
|
||||
|
||||
const [buttonStyle, setButtonStyle] = useState('')
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (isObjectNotEmpty(managementState)) {
|
||||
if (managementState.createUser === 'T01') {
|
||||
if (session.userId !== 'T01') {
|
||||
setButtonStyle('none')
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [managementState])
|
||||
|
||||
const searchParams = useSearchParams()
|
||||
const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set
|
||||
|
||||
@ -98,7 +115,7 @@ export default function StuffSubHeader({ type }) {
|
||||
{getMessage('stuff.temp.subTitle')}
|
||||
</Link>
|
||||
</li>
|
||||
<li className="title-item">
|
||||
<li className="title-item" style={{ display: buttonStyle }}>
|
||||
<a className="sub-header-title" onClick={moveFloorPlan}>
|
||||
<span className="icon drawing"></span>
|
||||
{getMessage('stuff.temp.subTitle2')}
|
||||
|
||||
88
src/hooks/common/useMasterController.js
Normal file
88
src/hooks/common/useMasterController.js
Normal file
@ -0,0 +1,88 @@
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { getQueryString } from '@/util/common-utils'
|
||||
import axios from 'axios'
|
||||
|
||||
/**
|
||||
* 마스터 컨트롤러 훅
|
||||
* @returns
|
||||
*/
|
||||
export function useMasterController() {
|
||||
const { get } = useAxios()
|
||||
const { getMessage } = useMessage()
|
||||
const { swalFire } = useSwal()
|
||||
|
||||
/**
|
||||
* 지붕재 목록 조회
|
||||
* @returns
|
||||
*/
|
||||
const getRoofMaterialList = async () => {
|
||||
return await get({ url: '/api/v1/master/getRoofMaterialList' }).then((res) => {
|
||||
console.log('🚀🚀 ~ getRoofMaterialList ~ res:', res)
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 모듈 타입별 아이템 목록 조회
|
||||
* @param {지붕재 코드} roofMatlCd
|
||||
* @returns
|
||||
*/
|
||||
const getModuleTypeItemList = async (roofMatlCd) => {
|
||||
if (!roofMatlCd || roofMatlCd.trim() === '') {
|
||||
swalFire({ text: getMessage('master.moduletypeitem.message.error'), type: 'alert', icon: 'error' })
|
||||
return null
|
||||
}
|
||||
const param = { roofMatlCd: roofMatlCd }
|
||||
const paramString = getQueryString(param)
|
||||
return await get({ url: `/api/v1/master/getModuleTypeItemList${paramString}` }).then((res) => {
|
||||
console.log('🚀🚀 ~ getModuleTypeItemList ~ res:', res)
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 가대 목록 조회
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
const getTrestleList = async (params) => {
|
||||
return await get({ url: `/api/v1/master/getTrestleList/${params}` }).then((res) => {
|
||||
console.log('🚀🚀 ~ getTrestleList ~ res:', res)
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 모듈 시공법 목록 조회
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
const getConstructionList = async (params) => {
|
||||
return await get({ url: `/api/v1/master/getConstructionList/${params}` }).then((res) => {
|
||||
console.log('🚀🚀 ~ getConstructionList ~ res:', res)
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 가대 상세 조회
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
const getTrestleDetailList = async (params) => {
|
||||
return await get({ url: `/api/v1/master/getTrestleDetailList/${params}` }).then((res) => {
|
||||
console.log('🚀🚀 ~ getTrestleDetailList ~ res:', res)
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
getRoofMaterialList,
|
||||
getModuleTypeItemList,
|
||||
getTrestleList,
|
||||
getConstructionList,
|
||||
getTrestleDetailList,
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
import { canvasState } from '@/store/canvasAtom'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import { useState } from 'react'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
|
||||
export const FLOW_DIRECTION_TYPE = {
|
||||
EIGHT_AZIMUTH: 'eightAzimuth',
|
||||
TWENTY_FOUR_AZIMUTH: 'twentyFourAzimuth',
|
||||
}
|
||||
|
||||
export function useFlowDirectionSetting(id) {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const { drawDirectionArrow } = usePolygon()
|
||||
const { closePopup } = usePopup()
|
||||
|
||||
const [type, setType] = useState(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH)
|
||||
|
||||
const changeSurfaceFlowDirection = (roof, direction, orientation) => {
|
||||
roof.set({
|
||||
direction: direction,
|
||||
surfaceCompass: orientation,
|
||||
})
|
||||
drawDirectionArrow(roof)
|
||||
canvas?.renderAll()
|
||||
closePopup(id)
|
||||
}
|
||||
|
||||
return { changeSurfaceFlowDirection, type, setType }
|
||||
}
|
||||
@ -1,13 +1,14 @@
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useContext, useEffect, useReducer, useState } from 'react'
|
||||
import { useContext, useEffect, useState } from 'react'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||
import { isObjectNotEmpty, isEmptyArray, isNotEmptyArray } from '@/util/common-utils'
|
||||
import { isObjectNotEmpty, isEmptyArray } from '@/util/common-utils'
|
||||
import { SessionContext } from '@/app/SessionProvider'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||
import { QcastContext } from '@/app/QcastProvider'
|
||||
|
||||
// Constants
|
||||
const ESTIMATE_API_ENDPOINT = '/api/estimate' // API 엔드포인트 정의
|
||||
@ -19,7 +20,7 @@ const updateItemInList = (itemList, dispOrder, updates) => {
|
||||
|
||||
export const useEstimateController = (planNo) => {
|
||||
const [fileList, setFileList] = useState([])
|
||||
const [deleteFileList, setDeleteFileList] = useState([])
|
||||
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||
|
||||
const router = useRouter()
|
||||
const { session } = useContext(SessionContext)
|
||||
@ -52,6 +53,7 @@ export const useEstimateController = (planNo) => {
|
||||
const fetchSetting = async (objectNo, planNo) => {
|
||||
try {
|
||||
await promiseGet({ url: `/api/estimate/${objectNo}/${planNo}/detail` }).then((res) => {
|
||||
setIsGlobalLoading(true)
|
||||
if (res.status === 200) {
|
||||
if (isObjectNotEmpty(res.data)) {
|
||||
if (res.data.itemList.length > 0) {
|
||||
@ -72,9 +74,11 @@ export const useEstimateController = (planNo) => {
|
||||
}
|
||||
})
|
||||
setIsLoading(true)
|
||||
setIsGlobalLoading(false)
|
||||
} catch (error) {
|
||||
console.error('견적서 상세조회 Error: ', error)
|
||||
setIsLoading(true)
|
||||
setIsGlobalLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,15 +358,16 @@ export const useEstimateController = (planNo) => {
|
||||
// return
|
||||
try {
|
||||
await promisePost({ url: `${ESTIMATE_API_ENDPOINT}/save-estimate`, data: estimateData }).then((res) => {
|
||||
setIsGlobalLoading(true)
|
||||
if (res.status === 201) {
|
||||
estimateData.newFileList = []
|
||||
// estimateData.originFiles = []
|
||||
alert(getMessage('estimate.detail.save.alertMsg'))
|
||||
//어디로 보낼지
|
||||
fetchSetting(objectRecoil.floorPlanObjectNo, estimateData.planNo)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
setIsGlobalLoading(false)
|
||||
console.log('error::::::::::::', e.response.data.message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import { v4 as uuidv4 } from 'uuid'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { canvasSettingState } from '@/store/canvasAtom'
|
||||
import { compasDegAtom } from '@/store/orientationAtom'
|
||||
import { QLine } from '@/components/fabric/QLine'
|
||||
|
||||
export function useModuleBasicSetting() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
@ -51,6 +52,7 @@ export function useModuleBasicSetting() {
|
||||
const makeModuleInstArea = () => {
|
||||
//지붕 객체 반환
|
||||
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
|
||||
let offsetLength = canvasSetting.roofSizeSet === 3 ? -90 : -20
|
||||
|
||||
if (!roofs) {
|
||||
return
|
||||
@ -63,13 +65,11 @@ export function useModuleBasicSetting() {
|
||||
}
|
||||
|
||||
setSurfaceShapePattern(roof, roofDisplay.column, true) //패턴 변경
|
||||
const offsetPoints = offsetPolygon(roof.points, -20) //안쪽 offset
|
||||
const offsetPoints = offsetPolygon(roof.points, offsetLength) //안쪽 offset
|
||||
//모듈설치영역?? 생성
|
||||
|
||||
const surfaceId = uuidv4()
|
||||
|
||||
console.log('roof.moduleCompass', roof.moduleCompass)
|
||||
|
||||
let setupSurface = new QPolygon(offsetPoints, {
|
||||
stroke: 'red',
|
||||
fill: 'transparent',
|
||||
@ -88,7 +88,10 @@ export function useModuleBasicSetting() {
|
||||
flipX: roof.flipX,
|
||||
flipY: roof.flipY,
|
||||
surfaceId: surfaceId,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
modules: [],
|
||||
// angle: -compasDeg,
|
||||
})
|
||||
|
||||
setupSurface.setViewLengthText(false)
|
||||
@ -102,6 +105,7 @@ export function useModuleBasicSetting() {
|
||||
}
|
||||
|
||||
setupSurface.set({ flowLines: flowLines })
|
||||
flatRoofMakeSurface(roof, setupSurface)
|
||||
|
||||
//지붕면 선택 금지
|
||||
roof.set({
|
||||
@ -656,7 +660,7 @@ export function useModuleBasicSetting() {
|
||||
}
|
||||
}
|
||||
|
||||
const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, flowModuleLine, isCenter = false) => {
|
||||
const leftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, aaa, isCenter = false) => {
|
||||
let startPoint = flowModuleLine.left
|
||||
|
||||
//중앙배치일 경우에는 계산한다
|
||||
@ -1206,9 +1210,10 @@ export function useModuleBasicSetting() {
|
||||
return turf.polygon([coordinates])
|
||||
}
|
||||
|
||||
const polygonToTurfPolygon = (object) => {
|
||||
const polygonToTurfPolygon = (object, current = false) => {
|
||||
let coordinates
|
||||
coordinates = object.points.map((point) => [point.x, point.y])
|
||||
if (current) coordinates = object.getCurrentPoints().map((point) => [point.x, point.y])
|
||||
coordinates.push(coordinates[0])
|
||||
return turf.polygon(
|
||||
[coordinates],
|
||||
@ -1526,17 +1531,18 @@ export function useModuleBasicSetting() {
|
||||
let flatBatchType = placementFlatRef.setupLocation.current.value
|
||||
let excretaLinesAngle = []
|
||||
|
||||
if (flatBatchType === 'south') {
|
||||
applyAngle = compasDeg
|
||||
} else {
|
||||
const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine' && obj.isSelected === true)
|
||||
if (flatBatchType === 'excreta') {
|
||||
const excretaLines = canvas.getObjects().filter((obj) => obj.name === 'flatExcretaLine')
|
||||
excretaLines.forEach((obj) => {
|
||||
const points1 = { x: obj.x1, y: obj.y1 }
|
||||
const points2 = { x: obj.x2, y: obj.y2 }
|
||||
excretaLinesAngle.push({
|
||||
surfaceId: obj.surfaceId,
|
||||
angle: calculateAngle(points1, points2),
|
||||
})
|
||||
if (obj.isSelected) {
|
||||
const points1 = { x: obj.x1, y: obj.y1 }
|
||||
const points2 = { x: obj.x2, y: obj.y2 }
|
||||
excretaLinesAngle.push({
|
||||
surfaceId: obj.surfaceId,
|
||||
angle: calculateAngle(points1, points2),
|
||||
})
|
||||
}
|
||||
canvas.remove(obj)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1591,8 +1597,6 @@ export function useModuleBasicSetting() {
|
||||
return transformedCorners
|
||||
}
|
||||
|
||||
function getSelectedExcretaLine() {}
|
||||
|
||||
if (moduleSetupSurfaces.length !== 0) {
|
||||
let tempModule
|
||||
let manualDrawModules = []
|
||||
@ -1606,7 +1610,7 @@ export function useModuleBasicSetting() {
|
||||
const mousePoint = canvas.getPointer(e.e)
|
||||
|
||||
for (let i = 0; i < moduleSetupSurfaces.length; i++) {
|
||||
turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i])
|
||||
turfPolygon = polygonToTurfPolygon(moduleSetupSurfaces[i], true)
|
||||
trestlePolygon = moduleSetupSurfaces[i]
|
||||
manualDrawModules = moduleSetupSurfaces[i].modules // 앞에서 자동으로 했을때 추가됨
|
||||
flowDirection = moduleSetupSurfaces[i].flowDirection //도형의 방향
|
||||
@ -1616,18 +1620,11 @@ export function useModuleBasicSetting() {
|
||||
if (tempLine) {
|
||||
applyAngle = tempLine.angle
|
||||
} else {
|
||||
//혹시나 두개의 지붕을 그리고 한쪽면만 선택했을때 한면은 그냥 기본 기울기를 준다
|
||||
applyAngle = compasDeg
|
||||
}
|
||||
}
|
||||
|
||||
// const excretaLine = excretaLines.find((obj) => obj.isSelected === true && obj.surfaceId === trestlePolygon.surfaceId)
|
||||
|
||||
// console.log('excretaLine', excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2)
|
||||
|
||||
// applyAngle = calculateAngle(excretaLine.x1, excretaLine.y1, excretaLine.x2, excretaLine.y2)
|
||||
|
||||
// console.log('applyAngle', applyAngle)
|
||||
|
||||
let width = flowDirection === 'south' || flowDirection === 'north' ? 172 : 113
|
||||
let height = flowDirection === 'south' || flowDirection === 'north' ? 113 : 172
|
||||
|
||||
@ -1667,123 +1664,125 @@ export function useModuleBasicSetting() {
|
||||
let snapDistance = 10
|
||||
let cellSnapDistance = 20
|
||||
|
||||
const trestleLeft = moduleSetupSurfaces[i].left
|
||||
const trestleTop = moduleSetupSurfaces[i].top
|
||||
const trestleRight = trestleLeft + moduleSetupSurfaces[i].width * moduleSetupSurfaces[i].scaleX
|
||||
const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY
|
||||
const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2
|
||||
// if (applyAngle === 90 || applyAngle === 180 || applyAngle === 270 || applyAngle === 0) {
|
||||
// const trestleLeft = moduleSetupSurfaces[i].left
|
||||
// const trestleTop = moduleSetupSurfaces[i].top
|
||||
// const trestleRight = trestleLeft + moduleSetupSurfaces[i].width * moduleSetupSurfaces[i].scaleX
|
||||
// const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY
|
||||
// const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2
|
||||
|
||||
// 작은 폴리곤의 경계 좌표 계산
|
||||
const smallLeft = tempModule.left
|
||||
const smallTop = tempModule.top
|
||||
const smallRight = smallLeft + tempModule.width * tempModule.scaleX
|
||||
const smallBottom = smallTop + tempModule.height * tempModule.scaleY
|
||||
const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2
|
||||
const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2
|
||||
// // 작은 폴리곤의 경계 좌표 계산
|
||||
// const smallLeft = tempModule.left
|
||||
// const smallTop = tempModule.top
|
||||
// const smallRight = smallLeft + tempModule.width * tempModule.scaleX
|
||||
// const smallBottom = smallTop + tempModule.height * tempModule.scaleY
|
||||
// const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2
|
||||
// const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2
|
||||
|
||||
if (manualDrawModules) {
|
||||
manualDrawModules.forEach((cell) => {
|
||||
const holdCellLeft = cell.left
|
||||
const holdCellTop = cell.top
|
||||
const holdCellRight = holdCellLeft + cell.width * cell.scaleX
|
||||
const holdCellBottom = holdCellTop + cell.height * cell.scaleY
|
||||
const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2
|
||||
const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2
|
||||
// if (manualDrawModules) {
|
||||
// manualDrawModules.forEach((cell) => {
|
||||
// const holdCellLeft = cell.left
|
||||
// const holdCellTop = cell.top
|
||||
// const holdCellRight = holdCellLeft + cell.width * cell.scaleX
|
||||
// const holdCellBottom = holdCellTop + cell.height * cell.scaleY
|
||||
// const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2
|
||||
// const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2
|
||||
|
||||
//설치된 셀에 좌측에 스냅
|
||||
if (Math.abs(smallRight - holdCellLeft) < snapDistance) {
|
||||
tempModule.left = holdCellLeft - width - 0.5
|
||||
}
|
||||
// //설치된 셀에 좌측에 스냅
|
||||
// if (Math.abs(smallRight - holdCellLeft) < snapDistance) {
|
||||
// tempModule.left = holdCellLeft - width - 0.5
|
||||
// }
|
||||
|
||||
//설치된 셀에 우측에 스냅
|
||||
if (Math.abs(smallLeft - holdCellRight) < snapDistance) {
|
||||
tempModule.left = holdCellRight + 0.5
|
||||
}
|
||||
// //설치된 셀에 우측에 스냅
|
||||
// if (Math.abs(smallLeft - holdCellRight) < snapDistance) {
|
||||
// tempModule.left = holdCellRight + 0.5
|
||||
// }
|
||||
|
||||
//설치된 셀에 위쪽에 스냅
|
||||
if (Math.abs(smallBottom - holdCellTop) < snapDistance) {
|
||||
tempModule.top = holdCellTop - height - 0.5
|
||||
}
|
||||
// //설치된 셀에 위쪽에 스냅
|
||||
// if (Math.abs(smallBottom - holdCellTop) < snapDistance) {
|
||||
// tempModule.top = holdCellTop - height - 0.5
|
||||
// }
|
||||
|
||||
//설치된 셀에 밑쪽에 스냅
|
||||
if (Math.abs(smallTop - holdCellBottom) < snapDistance) {
|
||||
tempModule.top = holdCellBottom + 0.5
|
||||
}
|
||||
//가운데 -> 가운데
|
||||
if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) {
|
||||
tempModule.left = holdCellCenterX - width / 2
|
||||
}
|
||||
//왼쪽 -> 가운데
|
||||
if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) {
|
||||
tempModule.left = holdCellCenterX
|
||||
}
|
||||
// 오른쪽 -> 가운데
|
||||
if (Math.abs(smallRight - holdCellCenterX) < cellSnapDistance) {
|
||||
tempModule.left = holdCellCenterX - width
|
||||
}
|
||||
//세로 가운데 -> 가운데
|
||||
if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) {
|
||||
tempModule.top = holdCellCenterY - height / 2
|
||||
}
|
||||
//위쪽 -> 가운데
|
||||
if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) {
|
||||
tempModule.top = holdCellCenterY
|
||||
}
|
||||
//아랫쪽 -> 가운데
|
||||
if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) {
|
||||
tempModule.top = holdCellCenterY - height
|
||||
}
|
||||
})
|
||||
}
|
||||
// //설치된 셀에 밑쪽에 스냅
|
||||
// if (Math.abs(smallTop - holdCellBottom) < snapDistance) {
|
||||
// tempModule.top = holdCellBottom + 0.5
|
||||
// }
|
||||
// //가운데 -> 가운데
|
||||
// if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) {
|
||||
// tempModule.left = holdCellCenterX - width / 2
|
||||
// }
|
||||
// //왼쪽 -> 가운데
|
||||
// if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) {
|
||||
// tempModule.left = holdCellCenterX
|
||||
// }
|
||||
// // 오른쪽 -> 가운데
|
||||
// if (Math.abs(smallRight - holdCellCenterX) < cellSnapDistance) {
|
||||
// tempModule.left = holdCellCenterX - width
|
||||
// }
|
||||
// //세로 가운데 -> 가운데
|
||||
// if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) {
|
||||
// tempModule.top = holdCellCenterY - height / 2
|
||||
// }
|
||||
// //위쪽 -> 가운데
|
||||
// if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) {
|
||||
// tempModule.top = holdCellCenterY
|
||||
// }
|
||||
// //아랫쪽 -> 가운데
|
||||
// if (Math.abs(smallBottom - holdCellCenterY) < cellSnapDistance) {
|
||||
// tempModule.top = holdCellCenterY - height
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// 위쪽 변에 스냅
|
||||
if (Math.abs(smallTop - trestleTop) < snapDistance) {
|
||||
tempModule.top = trestleTop
|
||||
}
|
||||
// // 위쪽 변에 스냅
|
||||
// if (Math.abs(smallTop - trestleTop) < snapDistance) {
|
||||
// tempModule.top = trestleTop
|
||||
// }
|
||||
|
||||
// 아래쪽 변에 스냅
|
||||
if (Math.abs(smallTop + tempModule.height * tempModule.scaleY - (trestleTop + moduleSetupSurfaces[i].height)) < snapDistance) {
|
||||
tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height * tempModule.scaleY
|
||||
}
|
||||
// // 아래쪽 변에 스냅
|
||||
// if (Math.abs(smallTop + tempModule.height * tempModule.scaleY - (trestleTop + moduleSetupSurfaces[i].height)) < snapDistance) {
|
||||
// tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height * tempModule.scaleY
|
||||
// }
|
||||
|
||||
// 왼쪽변에 스냅
|
||||
if (Math.abs(smallLeft - trestleLeft) < snapDistance) {
|
||||
tempModule.left = trestleLeft
|
||||
}
|
||||
//오른쪽 변에 스냅
|
||||
if (Math.abs(smallRight - trestleRight) < snapDistance) {
|
||||
tempModule.left = trestleRight - tempModule.width * tempModule.scaleX
|
||||
}
|
||||
// // 왼쪽변에 스냅
|
||||
// if (Math.abs(smallLeft - trestleLeft) < snapDistance) {
|
||||
// tempModule.left = trestleLeft
|
||||
// }
|
||||
// //오른쪽 변에 스냅
|
||||
// if (Math.abs(smallRight - trestleRight) < snapDistance) {
|
||||
// tempModule.left = trestleRight - tempModule.width * tempModule.scaleX
|
||||
// }
|
||||
|
||||
if (flowDirection === 'south' || flowDirection === 'north') {
|
||||
// 모듈왼쪽이 세로중앙선에 붙게 스냅
|
||||
if (Math.abs(smallLeft - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
|
||||
tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2
|
||||
}
|
||||
// if (flowDirection === 'south' || flowDirection === 'north') {
|
||||
// // 모듈왼쪽이 세로중앙선에 붙게 스냅
|
||||
// if (Math.abs(smallLeft - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
|
||||
// tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2
|
||||
// }
|
||||
|
||||
// 모듈이 가운데가 세로중앙선에 붙게 스냅
|
||||
if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
|
||||
tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - (tempModule.width * tempModule.scaleX) / 2
|
||||
}
|
||||
// // 모듈이 가운데가 세로중앙선에 붙게 스냅
|
||||
// if (Math.abs(smallCenterX - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
|
||||
// tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - (tempModule.width * tempModule.scaleX) / 2
|
||||
// }
|
||||
|
||||
// 모듈오른쪽이 세로중앙선에 붙게 스냅
|
||||
if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
|
||||
tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX
|
||||
}
|
||||
} else {
|
||||
// 모듈이 가로중앙선에 스냅
|
||||
if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < snapDistance) {
|
||||
tempModule.top = bigCenterY - tempModule.height / 2
|
||||
}
|
||||
// // 모듈오른쪽이 세로중앙선에 붙게 스냅
|
||||
// if (Math.abs(smallRight - (trestleLeft + moduleSetupSurfaces[i].width / 2)) < snapDistance) {
|
||||
// tempModule.left = trestleLeft + moduleSetupSurfaces[i].width / 2 - tempModule.width * tempModule.scaleX
|
||||
// }
|
||||
// } else {
|
||||
// // 모듈이 가로중앙선에 스냅
|
||||
// if (Math.abs(smallTop + tempModule.height / 2 - bigCenterY) < snapDistance) {
|
||||
// tempModule.top = bigCenterY - tempModule.height / 2
|
||||
// }
|
||||
|
||||
if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
|
||||
tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2
|
||||
}
|
||||
// 모듈 밑면이 가로중앙선에 스냅
|
||||
if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
|
||||
tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY
|
||||
}
|
||||
}
|
||||
// if (Math.abs(smallTop - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
|
||||
// tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2
|
||||
// }
|
||||
// // 모듈 밑면이 가로중앙선에 스냅
|
||||
// if (Math.abs(smallBottom - (trestleTop + moduleSetupSurfaces[i].height / 2)) < snapDistance) {
|
||||
// tempModule.top = trestleTop + moduleSetupSurfaces[i].height / 2 - tempModule.height * tempModule.scaleY
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
inside = true
|
||||
break
|
||||
@ -1833,8 +1832,6 @@ export function useModuleBasicSetting() {
|
||||
//마우스 클릭시 set으로 해당 위치에 셀을 넣음
|
||||
const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인
|
||||
if (!isOverlap) {
|
||||
console.log('tempModule.points', tempModule.points)
|
||||
|
||||
let manualModule = new QPolygon(tempModule.points, { ...moduleOptions })
|
||||
canvas?.add(manualModule)
|
||||
manualDrawModules.push(tempModule)
|
||||
@ -1849,7 +1846,411 @@ export function useModuleBasicSetting() {
|
||||
}
|
||||
}
|
||||
|
||||
const autoFlatroofModuleSetup = (placementFlatRef) => {}
|
||||
const autoFlatroofModuleSetup = (placementFlatRef) => {
|
||||
initEvent() //마우스 이벤트 초기화
|
||||
|
||||
let flatBatchType = placementFlatRef.setupLocation.current.value
|
||||
const moduleSetupSurfaces = moduleSetupSurface //선택 설치면
|
||||
|
||||
const notSelectedTrestlePolygons = canvas
|
||||
?.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && !moduleSetupSurfaces.includes(obj)) //설치면이 아닌것
|
||||
|
||||
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 객체
|
||||
|
||||
if (moduleSetupSurfaces.length === 0) {
|
||||
alert('선택된 모듈 설치면이 없습니다.')
|
||||
return
|
||||
}
|
||||
|
||||
//어짜피 자동으로 누르면 선택안된데도 다 날아간다
|
||||
canvas.getObjects().forEach((obj) => {
|
||||
if (obj.name === 'module') {
|
||||
canvas.remove(obj)
|
||||
}
|
||||
})
|
||||
|
||||
notSelectedTrestlePolygons.forEach((obj) => {
|
||||
if (obj.modules) {
|
||||
obj.modules.forEach((module) => {
|
||||
canvas?.remove(module)
|
||||
})
|
||||
obj.modules = []
|
||||
}
|
||||
})
|
||||
|
||||
const moduleOptions = {
|
||||
fill: '#BFFD9F',
|
||||
stroke: 'black',
|
||||
strokeWidth: 0.1,
|
||||
selectable: false, // 선택 가능하게 설정
|
||||
lockMovementX: true, // X 축 이동 잠금
|
||||
lockMovementY: true, // Y 축 이동 잠금
|
||||
lockRotation: true, // 회전 잠금
|
||||
lockScalingX: true, // X 축 크기 조정 잠금
|
||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
opacity: 0.8,
|
||||
parentId: moduleSetupSurface.parentId,
|
||||
name: 'module',
|
||||
}
|
||||
|
||||
let leftMargin, bottomMargin, square, chidoriLength
|
||||
|
||||
//선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환
|
||||
const objectsIncludeSurface = (turfModuleSetupSurface) => {
|
||||
let containsBatchObjects = []
|
||||
containsBatchObjects = batchObjects.filter((batchObject) => {
|
||||
let convertBatchObject
|
||||
|
||||
if (batchObject.type === 'group') {
|
||||
//도머는 그룹형태임
|
||||
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
||||
} else {
|
||||
//개구, 그림자
|
||||
batchObject.set({ points: rectToPolygon(batchObject) })
|
||||
canvas?.renderAll() // set된걸 바로 적용하기 위해
|
||||
convertBatchObject = polygonToTurfPolygon(batchObject) //rect를 폴리곤으로 변환 -> turf 폴리곤으로 변환
|
||||
}
|
||||
|
||||
// 폴리곤 안에 도머 폴리곤이 포함되어있는지 확인해서 반환하는 로직
|
||||
return turf.booleanContains(turfModuleSetupSurface, convertBatchObject) || turf.booleanWithin(convertBatchObject, turfModuleSetupSurface)
|
||||
})
|
||||
|
||||
return containsBatchObjects
|
||||
}
|
||||
|
||||
/**
|
||||
* 도머나 개구가 모듈에 걸치는지 확인하는 로직
|
||||
* @param {*} squarePolygon
|
||||
* @param {*} containsBatchObjects
|
||||
* @returns
|
||||
*/
|
||||
const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
|
||||
let isDisjoint = false
|
||||
|
||||
if (containsBatchObjects.length > 0) {
|
||||
let convertBatchObject
|
||||
//도머가 있으면 적용되는 로직
|
||||
isDisjoint = containsBatchObjects.every((batchObject) => {
|
||||
if (batchObject.type === 'group') {
|
||||
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
||||
} else {
|
||||
convertBatchObject = polygonToTurfPolygon(batchObject)
|
||||
}
|
||||
/**
|
||||
* 도머가 여러개일수있으므로 겹치는게 있다면...
|
||||
* 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
|
||||
*/
|
||||
return turf.booleanDisjoint(squarePolygon, convertBatchObject)
|
||||
})
|
||||
} else {
|
||||
isDisjoint = true
|
||||
}
|
||||
return isDisjoint
|
||||
}
|
||||
|
||||
/**
|
||||
* 배치면 안에 있는지 확인
|
||||
* @param {*} squarePolygon
|
||||
* @param {*} turfModuleSetupSurface
|
||||
* @returns
|
||||
*/
|
||||
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
|
||||
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||
}
|
||||
|
||||
let moduleGroup = []
|
||||
|
||||
const flatRoofDownFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
let startPoint = moduleSetupSurface.flowLines.bottom
|
||||
|
||||
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
||||
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
||||
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
||||
|
||||
let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
|
||||
let totalTopEndPoint = maxTopEndPoint - startPoint.y1
|
||||
let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width)
|
||||
let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
|
||||
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
||||
let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
|
||||
let tempMaxWidth = width //최대배치인지 확인하려고 넣음
|
||||
|
||||
for (let j = 0; j < diffTopEndPoint; j++) {
|
||||
bottomMargin = marginHeight * j
|
||||
for (let i = 0; i <= totalWidth; i++) {
|
||||
leftMargin = marginWidth * i
|
||||
|
||||
square = [
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - height - bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin],
|
||||
]
|
||||
|
||||
let squarePolygon = turf.polygon([square])
|
||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||
|
||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleGroup.push(tempModule)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const flatRoofLeftFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
let startPoint = moduleSetupSurface.flowLines.left
|
||||
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
||||
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
||||
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
||||
|
||||
let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
|
||||
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
||||
let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
|
||||
let totalWidth = Math.abs(startPoint.x1 - maxRightEndPoint) / width
|
||||
let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint)
|
||||
let tempMaxHeight = height //최대배치인지 확인하려고 넣음
|
||||
|
||||
for (let i = 0; i <= totalWidth; i++) {
|
||||
bottomMargin = marginHeight * i
|
||||
for (let j = 0; j < totalHeight; j++) {
|
||||
leftMargin = marginWidth * j
|
||||
|
||||
square = [
|
||||
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
|
||||
[startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
|
||||
[startPoint.x1 + width * i + width + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
|
||||
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
|
||||
[startPoint.x1 + width * i + leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
|
||||
]
|
||||
|
||||
let squarePolygon = turf.polygon([square])
|
||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||
|
||||
// if (disjointFromTrestle && isDisjoint) {
|
||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleGroup.push(tempModule)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const flatRoofTopFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
let startPoint = moduleSetupSurface.flowLines.top
|
||||
|
||||
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
||||
const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측
|
||||
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
||||
|
||||
let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1
|
||||
let totalRightEndPoint = maxLeftEndPoint - maxRightEndPoint
|
||||
let totalBottomEndPoint = maxBottomEndPoint - startPoint.y1
|
||||
let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width)
|
||||
let diffRightEndPoint = Math.ceil(Math.abs(totalRightEndPoint / width))
|
||||
let diffBottomEndPoint = Math.ceil(Math.abs(totalBottomEndPoint / height))
|
||||
let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1)
|
||||
let tempMaxWidth = width //최대배치인지 확인하려고 넣음
|
||||
|
||||
for (let j = 0; j < diffBottomEndPoint; j++) {
|
||||
bottomMargin = marginHeight * j
|
||||
for (let i = 0; i < diffRightEndPoint; i++) {
|
||||
leftMargin = marginWidth * i
|
||||
|
||||
square = [
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 + height * j + height + bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
||||
[startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 + height * j + bottomMargin],
|
||||
]
|
||||
|
||||
let squarePolygon = turf.polygon([square])
|
||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||
|
||||
// if (disjointFromTrestle && isDisjoint) {
|
||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleGroup.push(tempModule)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const flatRoofRightFlowSetupModule = (surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => {
|
||||
let startPoint = moduleSetupSurface.flowLines.right
|
||||
|
||||
const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측
|
||||
const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단
|
||||
const maxBottomEndPoint = surfaceMaxLines.bottom.y1 //최하단
|
||||
|
||||
let totalTopEndPoint = Math.abs(maxTopEndPoint - startPoint.y1) //전체 높이에서 현재 높이를 뺌
|
||||
let diffTopEndPoint = Math.abs(totalTopEndPoint / height)
|
||||
let totalHeight = Math.ceil(Math.abs(maxBottomEndPoint - maxTopEndPoint) / height)
|
||||
let totalWidth = Math.abs(startPoint.x1 - maxLeftEndPoint) / width
|
||||
let startRowPoint = startPoint.y1 - height * Math.ceil(diffTopEndPoint) - 3 // -3으로 위치살짝 보정
|
||||
let tempMaxHeight = height //최대배치인지 확인하려고 넣음
|
||||
|
||||
for (let i = 0; i <= totalWidth; i++) {
|
||||
bottomMargin = marginHeight * i
|
||||
for (let j = 0; j < totalHeight; j++) {
|
||||
leftMargin = marginWidth * j
|
||||
|
||||
square = [
|
||||
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
|
||||
[startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
|
||||
[startPoint.x1 - width * i - width - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
|
||||
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + height + bottomMargin],
|
||||
[startPoint.x1 - width * i - leftMargin, startRowPoint + tempMaxHeight * j + bottomMargin],
|
||||
]
|
||||
|
||||
let squarePolygon = turf.polygon([square])
|
||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||
let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||
|
||||
// if (disjointFromTrestle && isDisjoint) {
|
||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleGroup.push(tempModule)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moduleSetupSurfaces.forEach((moduleSetupSurface, index) => {
|
||||
moduleSetupSurface.fire('mousedown')
|
||||
const moduleSetupArray = []
|
||||
|
||||
let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => {
|
||||
return acc.length > cur.length ? acc : cur
|
||||
})
|
||||
|
||||
const turfModuleSetupSurface = polygonToTurfPolygon(moduleSetupSurface, true) //폴리곤을 turf 객체로 변환
|
||||
const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직
|
||||
|
||||
let width = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 172.2 : 113.4
|
||||
let height = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 113.4 : 172.2
|
||||
|
||||
//배치면때는 방향쪽으로 패널이 넓게 누워져야함
|
||||
if (moduleSetupSurface.flowDirection !== undefined) {
|
||||
width = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 172.2 : 113.4
|
||||
height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2
|
||||
}
|
||||
|
||||
const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface)
|
||||
const marginWidth = 0
|
||||
const marginHeight = 0
|
||||
|
||||
canvas.renderAll()
|
||||
|
||||
if (compasDeg >= 0 && compasDeg < 90) {
|
||||
flatRoofDownFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
} else if (compasDeg >= 90 && compasDeg < 180) {
|
||||
flatRoofLeftFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
} else if (compasDeg >= 180 && compasDeg < 270) {
|
||||
flatRoofRightFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
} else {
|
||||
flatRoofTopFlowSetupModule(surfaceMaxLines, width, height, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight)
|
||||
}
|
||||
|
||||
const setupedModules = moduleSetupArray.filter((module, index) => {
|
||||
let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface)
|
||||
let isDisjoint = checkModuleDisjointObjects(module.turfPoints, containsBatchObjects)
|
||||
|
||||
if (!(disjointFromTrestle && isDisjoint)) {
|
||||
canvas?.remove(module)
|
||||
// module.set({ fill: 'rgba(255,190,41, 0.4)', stroke: 'black', strokeWidth: 1 })
|
||||
return false
|
||||
} else {
|
||||
return module
|
||||
}
|
||||
})
|
||||
|
||||
canvas?.renderAll()
|
||||
|
||||
//나간애들 제외하고 설치된 애들로 겹친애들 삭제 하기
|
||||
// setupedModules.forEach((module, index) => {
|
||||
// if (isMaxSetup && index > 0) {
|
||||
// const isOverlap = turf.booleanOverlap(polygonToTurfPolygon(setupedModules[index - 1]), polygonToTurfPolygon(module))
|
||||
// //겹치는지 확인
|
||||
// if (isOverlap) {
|
||||
// //겹쳐있으면 삭제
|
||||
// // canvas?.remove(module)
|
||||
// module.set({ fill: 'rgba(72, 161, 250, 0.4)', stroke: 'black', strokeWidth: 0.1 })
|
||||
// canvas.renderAll()
|
||||
// setupedModules.splice(index, 1)
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
moduleSetupSurface.set({ modules: setupedModules })
|
||||
|
||||
// const moduleArray = [...moduleIsSetup]
|
||||
// moduleArray.push({
|
||||
// surfaceId: moduleSetupSurface.surfaceId,
|
||||
// moduleSetupArray: setupedModules,
|
||||
// })
|
||||
// setModuleIsSetup(moduleArray)
|
||||
})
|
||||
// console.log(calculateForApi())
|
||||
}
|
||||
|
||||
const flatRoofMakeSurface = (roof, setupSurface) => {
|
||||
setupSurface.angle = -compasDeg
|
||||
roof.angle = -compasDeg
|
||||
|
||||
const roofPoints = roof.getCurrentPoints()
|
||||
const roofLines = roofPoints.map((point, index) => {
|
||||
const nextIndex = (index + 1) % roofPoints.length
|
||||
const nextPoint = roofPoints[nextIndex]
|
||||
|
||||
return {
|
||||
x1: point.x,
|
||||
y1: point.y,
|
||||
x2: nextPoint.x,
|
||||
y2: nextPoint.y,
|
||||
}
|
||||
})
|
||||
roof.set({ lines: roofLines })
|
||||
roof.fire('modified')
|
||||
|
||||
const surfacePoints = setupSurface.getCurrentPoints()
|
||||
const surfaceLines = surfacePoints.map((point, index) => {
|
||||
const nextIndex = (index + 1) % surfacePoints.length
|
||||
const nextPoint = surfacePoints[nextIndex]
|
||||
|
||||
return {
|
||||
x1: point.x,
|
||||
y1: point.y,
|
||||
x2: nextPoint.x,
|
||||
y2: nextPoint.y,
|
||||
}
|
||||
})
|
||||
setupSurface.set({ lines: surfaceLines })
|
||||
|
||||
const flowLines = {
|
||||
bottom: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'bottom'),
|
||||
top: bottomTopFlowLine(setupSurface).find((obj) => obj.target === 'top'),
|
||||
left: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'left'),
|
||||
right: leftRightFlowLine(setupSurface).find((obj) => obj.target === 'right'),
|
||||
}
|
||||
setupSurface.set({ flowLines: flowLines })
|
||||
setupSurface.fire('modified')
|
||||
}
|
||||
|
||||
return {
|
||||
makeModuleInstArea,
|
||||
|
||||
@ -20,12 +20,14 @@ import {
|
||||
settingModalGridOptionsState,
|
||||
basicSettingState,
|
||||
settingsState,
|
||||
roofMaterialsAtom,
|
||||
} from '@/store/settingAtom'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
import { globalFontAtom } from '@/store/fontAtom'
|
||||
import { dimensionLineSettingsState } from '@/store/commonUtilsAtom'
|
||||
import { gridColorState } from '@/store/gridAtom'
|
||||
import { useColor } from 'react-color-palette'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
|
||||
const defaultDotLineGridSetting = {
|
||||
INTERVAL: {
|
||||
@ -48,28 +50,15 @@ export function useCanvasSetting() {
|
||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
||||
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
||||
|
||||
// const [settingsData, setSettingsData] = useRecoilState(settingsState)
|
||||
const [settingsData, setSettingsData] = useState({ ...settingModalFirstOptions, ...settingModalSecondOptions })
|
||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||
const { option4 } = settingModalSecondOptions
|
||||
|
||||
const corridorDimension = useRecoilValue(corridorDimensionSelector)
|
||||
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
const { get, post } = useAxios(globalLocaleState)
|
||||
const { getMessage } = useMessage()
|
||||
const { swalFire } = useSwal()
|
||||
|
||||
const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState)
|
||||
const [adsorptionRange, setAdsorptionRange] = useRecoilState(adsorptionRangeState)
|
||||
const [planSizeSettingMode, setPlanSizeSettingMode] = useRecoilState(planSizeSettingState)
|
||||
//const setAdsorptionRange = useSetRecoilState(adsorptionRangeState)
|
||||
|
||||
const [selectedFont, setSelectedFont] = useState()
|
||||
const [selectedFontWeight, setSelectedFontWeight] = useState()
|
||||
const [selectedFontSize, setSelectedFontSize] = useState()
|
||||
const [selectedFontColor, setSelectedFontColor] = useState()
|
||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||
|
||||
const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState)
|
||||
const [adsorptionRange, setAdsorptionRange] = useRecoilState(adsorptionRangeState)
|
||||
const [planSizeSettingMode, setPlanSizeSettingMode] = useRecoilState(planSizeSettingState)
|
||||
const [dimensionLineSettings, setDimensionLineSettings] = useRecoilState(dimensionLineSettingsState)
|
||||
|
||||
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
|
||||
@ -80,10 +69,31 @@ export function useCanvasSetting() {
|
||||
)
|
||||
const [gridColor, setGridColor] = useRecoilState(gridColorState)
|
||||
const [color, setColor] = useColor(gridColor ?? '#FF0000')
|
||||
const [colorTemp, setColorTemp] = useState()
|
||||
|
||||
const [settingsData, setSettingsData] = useState({
|
||||
...settingModalFirstOptions,
|
||||
...settingModalSecondOptions,
|
||||
...globalFont,
|
||||
...dotLineGridSetting,
|
||||
...planSizeSettingMode,
|
||||
...dimensionLineSettings,
|
||||
...color,
|
||||
})
|
||||
const [settingsDataSave, setSettingsDataSave] = useState()
|
||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||
const { option4 } = settingModalSecondOptions
|
||||
|
||||
const corridorDimension = useRecoilValue(corridorDimensionSelector)
|
||||
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
const { get, post } = useAxios(globalLocaleState)
|
||||
const { getMessage } = useMessage()
|
||||
const { swalFire } = useSwal()
|
||||
|
||||
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
|
||||
const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState)
|
||||
const { getRoofMaterialList } = useMasterController()
|
||||
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
|
||||
|
||||
const SelectOptions = [
|
||||
{ id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 },
|
||||
@ -91,7 +101,15 @@ export function useCanvasSetting() {
|
||||
{ id: 3, name: '1/4', value: 1 / 4 },
|
||||
{ id: 4, name: '1/10', value: 1 / 10 },
|
||||
]
|
||||
const [selectOption, setSelectOption] = useState(SelectOptions[0])
|
||||
|
||||
useEffect(() => {
|
||||
addRoofMaterials()
|
||||
}, [])
|
||||
|
||||
const addRoofMaterials = async () => {
|
||||
const { data } = await getRoofMaterialList()
|
||||
setRoofMaterials(data)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!canvas) {
|
||||
@ -132,58 +150,10 @@ export function useCanvasSetting() {
|
||||
}, [canvasSetting])
|
||||
|
||||
useEffect(() => {
|
||||
console.log('🚀 ~ useEffect ~ settingsData:', settingsData)
|
||||
console.log('🚀 ~ useEffect ~ settingsDataSave:', settingsDataSave)
|
||||
if (settingsDataSave !== undefined) onClickOption2()
|
||||
}, [settingsData])
|
||||
|
||||
//흡착점 ON/OFF 변경 시
|
||||
// useEffect(() => {
|
||||
// //console.log('useCanvasSetting 실행2', adsorptionPointMode.fontFlag, correntObjectNo)
|
||||
// if (adsorptionPointMode.fontFlag) {
|
||||
// onClickOption2()
|
||||
// }
|
||||
// }, [adsorptionPointMode])
|
||||
|
||||
// 1 과 2 변경 시
|
||||
// useEffect(() => {
|
||||
// //console.log('useCanvasSetting 실행3', settingModalFirstOptions.fontFlag, settingModalSecondOptions.fontFlag, correntObjectNo)
|
||||
// if (settingModalFirstOptions.fontFlag || settingModalSecondOptions.fontFlag) {
|
||||
// onClickOption2()
|
||||
// }
|
||||
// }, [settingModalFirstOptions, settingModalSecondOptions])
|
||||
|
||||
// 글꼴 변경 시
|
||||
// useEffect(() => {
|
||||
// //console.log('useCanvasSetting 실행4', globalFont.fontFlag, correntObjectNo)
|
||||
// if (globalFont.fontFlag) {
|
||||
// onClickOption2()
|
||||
// }
|
||||
// }, [globalFont])
|
||||
|
||||
// 도명크기 변경 시
|
||||
// useEffect(() => {
|
||||
// //console.log('useCanvasSetting 실행5', planSizeSettingMode.flag, correntObjectNo)
|
||||
// if (planSizeSettingMode.flag) {
|
||||
// onClickOption2()
|
||||
// }
|
||||
// }, [planSizeSettingMode])
|
||||
|
||||
// 점/선 그리드 변경 시
|
||||
// useEffect(() => {
|
||||
// //console.log('useCanvasSetting 실행6', dotLineGridSetting.flag)
|
||||
// if (dotLineGridSetting.flag) {
|
||||
// onClickOption2()
|
||||
// }
|
||||
// }, [dotLineGridSetting])
|
||||
|
||||
// 그리드 색 설정 변경 시
|
||||
// useEffect(() => {
|
||||
// console.log('useCanvasSetting 실행7', colorTemp, gridColor)
|
||||
// //colorTemp는 변경 전.. 값이 있고 변경된 컬러와 다를 때 실행
|
||||
// if (colorTemp !== undefined && colorTemp !== gridColor) {
|
||||
// onClickOption2()
|
||||
// }
|
||||
// }, [color])
|
||||
|
||||
const getFonts = (itemValue) => {
|
||||
if (!itemValue) return { id: 1, name: 'MS PGothic', value: 'MS PGothic' }
|
||||
const data = [
|
||||
@ -329,7 +299,7 @@ export function useCanvasSetting() {
|
||||
objectNo: correntObjectNo,
|
||||
roofSizeSet: basicSetting.roofSizeSet,
|
||||
roofAngleSet: basicSetting.roofAngleSet,
|
||||
roofMaterialsAddList: basicSetting.roofs,
|
||||
roofMaterialsAddList: basicSetting.roofs, // TODO : 선택된 roof로 변경해야함
|
||||
}
|
||||
|
||||
await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => {
|
||||
@ -357,18 +327,13 @@ export function useCanvasSetting() {
|
||||
const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item }))
|
||||
|
||||
//흡착점 ON/OFF
|
||||
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint, fontFlag: false })
|
||||
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint })
|
||||
|
||||
//치수선 설정
|
||||
setDimensionLineSettings({ ...dimensionLineSettings, pixel: res.originPixel, color: res.originColor })
|
||||
|
||||
//도면크기 설정
|
||||
setPlanSizeSettingMode({
|
||||
...planSizeSettingMode,
|
||||
originHorizon: res.originHorizon,
|
||||
originVertical: res.originVertical,
|
||||
flag: false,
|
||||
})
|
||||
setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: res.originHorizon, originVertical: res.originVertical })
|
||||
|
||||
// 데이터 설정
|
||||
setSettingModalFirstOptions({
|
||||
@ -376,13 +341,11 @@ export function useCanvasSetting() {
|
||||
option1: optionData1,
|
||||
option2: optionData2,
|
||||
dimensionDisplay: optionData5,
|
||||
fontFlag: false,
|
||||
})
|
||||
setSettingModalSecondOptions({
|
||||
...settingModalSecondOptions,
|
||||
option3: optionData3,
|
||||
option4: optionData4,
|
||||
fontFlag: false,
|
||||
})
|
||||
|
||||
const fontPatternData = {
|
||||
@ -421,8 +384,6 @@ export function useCanvasSetting() {
|
||||
fontSize: getFontSizes(res.lengthFontSize),
|
||||
fontColor: getFontColors(res.lengthFontColor),
|
||||
},
|
||||
//글꼴 설정 Flag
|
||||
fontFlag: false,
|
||||
}
|
||||
|
||||
//조회된 글꼴 데이터 set
|
||||
@ -439,55 +400,43 @@ export function useCanvasSetting() {
|
||||
},
|
||||
DOT: res.dotGridDisplay,
|
||||
LINE: res.lineGridDisplay,
|
||||
flag: false,
|
||||
}
|
||||
|
||||
const matchedOption = SelectOptions.find((option) => option.value == res.gridDimen)
|
||||
|
||||
// dimension 값에 맞는 옵션을 선택
|
||||
setSelectOption(matchedOption)
|
||||
|
||||
setDotLineGridSettingState(patternData)
|
||||
//setCurrentSetting(patternData)
|
||||
|
||||
//그리드 색 설정
|
||||
setGridColor(res.gridColor)
|
||||
setColorTemp(res.gridColor)
|
||||
} else {
|
||||
//조회된 글꼴 데이터가 없는 경우
|
||||
|
||||
//흡착점 ON/OFF
|
||||
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false, fontFlag: false })
|
||||
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false })
|
||||
|
||||
//치수선 설정
|
||||
setDimensionLineSettings({ ...dimensionLineSettings })
|
||||
|
||||
//도면크기 설정
|
||||
setPlanSizeSettingMode({
|
||||
...planSizeSettingMode,
|
||||
flag: false,
|
||||
})
|
||||
setPlanSizeSettingMode({ ...planSizeSettingMode })
|
||||
|
||||
// 데이터 설정
|
||||
setSettingModalFirstOptions({
|
||||
...settingModalFirstOptions,
|
||||
fontFlag: false,
|
||||
})
|
||||
setSettingModalSecondOptions({
|
||||
...settingModalSecondOptions,
|
||||
fontFlag: false,
|
||||
})
|
||||
|
||||
setGlobalFont({ ...globalFont, fontFlag: false })
|
||||
setGlobalFont({ ...globalFont })
|
||||
|
||||
//점/선 그리드
|
||||
setDotLineGridSettingState({ ...defaultDotLineGridSetting, flag: false })
|
||||
setDotLineGridSettingState({ ...defaultDotLineGridSetting })
|
||||
//setCurrentSetting({ ...defaultDotLineGridSetting })
|
||||
|
||||
//그리드 색 설정
|
||||
setGridColor('#FF0000')
|
||||
setColorTemp('#FF0000')
|
||||
}
|
||||
|
||||
frontSettings()
|
||||
} catch (error) {
|
||||
console.error('Data fetching error:', error)
|
||||
@ -513,9 +462,9 @@ export function useCanvasSetting() {
|
||||
secondOption2: option4.map((item) => ({
|
||||
column: item.column,
|
||||
selected: item.selected,
|
||||
range: item.range,
|
||||
})),
|
||||
}
|
||||
// console.log('globalFont', globalFont)
|
||||
const patternData = {
|
||||
//견적서 번호
|
||||
objectNo: correntObjectNo,
|
||||
@ -543,6 +492,7 @@ export function useCanvasSetting() {
|
||||
adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected,
|
||||
adsorpRangeMedium: dataToSend.secondOption2[2].selected,
|
||||
adsorpRangeLarge: dataToSend.secondOption2[3].selected,
|
||||
|
||||
//흡착점 ON/OFF
|
||||
adsorpPoint: adsorptionPointMode.adsorptionPoint,
|
||||
//??: adsorptionRange, 사용여부 확인 필요
|
||||
@ -594,14 +544,11 @@ export function useCanvasSetting() {
|
||||
gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10,
|
||||
gridDimen: dotLineGridSetting.INTERVAL.dimension,
|
||||
|
||||
//gridColor: gridColor.gridColor,
|
||||
gridColor: gridColor,
|
||||
}
|
||||
|
||||
console.log('patternData ', patternData)
|
||||
|
||||
setColorTemp(gridColor)
|
||||
|
||||
// HTTP POST 요청 보내기
|
||||
await post({ url: `/api/canvas-management/canvas-settings`, data: patternData })
|
||||
.then((res) => {
|
||||
@ -719,15 +666,13 @@ export function useCanvasSetting() {
|
||||
setDimensionLineSettings,
|
||||
planSizeSettingMode,
|
||||
setPlanSizeSettingMode,
|
||||
selectOption,
|
||||
setSelectOption,
|
||||
SelectOptions,
|
||||
currentSetting,
|
||||
setCurrentSetting,
|
||||
dotLineGridSettingState,
|
||||
setSettingModalGridOptions,
|
||||
setDotLineGridSettingState,
|
||||
resetDotLineGridSetting,
|
||||
setSettingModalGridOptions,
|
||||
gridColor,
|
||||
setGridColor,
|
||||
color,
|
||||
@ -740,5 +685,7 @@ export function useCanvasSetting() {
|
||||
basicSettingSave,
|
||||
settingsData,
|
||||
setSettingsData,
|
||||
settingsDataSave,
|
||||
setSettingsDataSave,
|
||||
}
|
||||
}
|
||||
|
||||
@ -840,7 +840,7 @@
|
||||
"estimate.detail.fileFlg": "後日資料提出",
|
||||
"estimate.detail.header.fileList1": "ファイル添付",
|
||||
"estimate.detail.fileList.btn": "ファイル選択",
|
||||
"estimate.detail.fileList.extCheck": "そのファイルはイメージファイルではありません",
|
||||
"estimate.detail.fileList.extCheck": "画像ファイルのみ添付可能.",
|
||||
"estimate.detail.header.fileList2": "添付ファイル一覧",
|
||||
"estimate.detail.fileList2.btn.return": "復元",
|
||||
"estimate.detail.header.specialEstimate": "見積もりの具体的な",
|
||||
@ -932,5 +932,6 @@
|
||||
"simulator.table.sub8": "台",
|
||||
"simulator.table.sub9": "予測発電量 (kWh)",
|
||||
"simulator.notice.sub1": "Hanwha Japan 年間発電量",
|
||||
"simulator.notice.sub2": "シミュレーション案内事項"
|
||||
"simulator.notice.sub2": "シミュレーション案内事項",
|
||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
||||
}
|
||||
|
||||
@ -850,7 +850,7 @@
|
||||
"estimate.detail.fileFlg": "후일자료제출",
|
||||
"estimate.detail.header.fileList1": "파일첨부",
|
||||
"estimate.detail.fileList.btn": "파일선택",
|
||||
"estimate.detail.fileList.extCheck": "해당 파일은 이미지 파일이 아닙니다",
|
||||
"estimate.detail.fileList.extCheck": "이미지 파일만 첨부 가능합니다.",
|
||||
"estimate.detail.header.fileList2": "첨부파일 목록",
|
||||
"estimate.detail.fileList2.btn.return": "복원",
|
||||
"estimate.detail.header.specialEstimate": "견적특이사항",
|
||||
@ -942,5 +942,6 @@
|
||||
"simulator.table.sub8": "대",
|
||||
"simulator.table.sub9": "예측발전량 (kWh)",
|
||||
"simulator.notice.sub1": "Hanwha Japan 연간 발전량",
|
||||
"simulator.notice.sub2": "시뮬레이션 안내사항"
|
||||
"simulator.notice.sub2": "시뮬레이션 안내사항",
|
||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
||||
}
|
||||
|
||||
@ -203,21 +203,16 @@ export const basicSettingState = atom({
|
||||
default: {
|
||||
roofSizeSet: 1,
|
||||
roofAngleSet: 'slope',
|
||||
roofs: [
|
||||
{
|
||||
roofApply: true,
|
||||
roofSeq: 1,
|
||||
roofType: 1,
|
||||
roofWidth: 200,
|
||||
roofHeight: 200,
|
||||
roofHajebichi: 200,
|
||||
roofGap: 0,
|
||||
roofLayout: 'parallel',
|
||||
},
|
||||
],
|
||||
selectedRoofMaterial: {},
|
||||
},
|
||||
})
|
||||
|
||||
// db에 등록된 지붕재 목록
|
||||
export const roofMaterialsAtom = atom({
|
||||
key: 'roofMaterialState',
|
||||
default: [],
|
||||
})
|
||||
|
||||
/**
|
||||
* 현재 선택된 물건 번호
|
||||
*/
|
||||
|
||||
@ -117,3 +117,15 @@ export const calculateFlowDirection = (canvasAngle) => {
|
||||
right: -90 - canvasAngle < -180 ? -90 - canvasAngle + 360 : -90 - canvasAngle,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 자바스크립트 객체로 쿼리스트링 생성
|
||||
* @param {javascript object} o 쿼리스트링 생성할 객체
|
||||
* @returns {string} 쿼리스트링
|
||||
*/
|
||||
export const getQueryString = (o) => {
|
||||
const queryString = Object.keys(o)
|
||||
.map((key) => `${key}=${o[key]}`)
|
||||
.join('&')
|
||||
return `?${queryString}`
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user