Merge branch 'dev' into feature/test-jy
This commit is contained in:
commit
d5d6cda1f0
@ -1,10 +1,11 @@
|
|||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
|
|
||||||
const fonts = [
|
const fonts = [
|
||||||
{ id: 1, name: 'MS PGothic', value: 'MS PGothic' },
|
{ id: 1, name: 'MS PGothic', value: 'MS PGothic' },
|
||||||
@ -12,7 +13,6 @@ const fonts = [
|
|||||||
{ id: 3, name: 'Yu Gothic', value: 'Yu Gothic' },
|
{ id: 3, name: 'Yu Gothic', value: 'Yu Gothic' },
|
||||||
{ id: 4, name: '@Yu Gothic UI', value: '@Yu Gothic UI' },
|
{ id: 4, name: '@Yu Gothic UI', value: '@Yu Gothic UI' },
|
||||||
{ id: 5, name: 'Yu Gothic UI', value: 'Yu Gothic UI' },
|
{ id: 5, name: 'Yu Gothic UI', value: 'Yu Gothic UI' },
|
||||||
3,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const fontSizes = [
|
const fontSizes = [
|
||||||
@ -36,14 +36,11 @@ export default function FontSetting(props) {
|
|||||||
const [selectedFontWeight, setSelectedFontWeight] = useState(font.fontWeight)
|
const [selectedFontWeight, setSelectedFontWeight] = useState(font.fontWeight)
|
||||||
const [selectedFontSize, setSelectedFontSize] = useState(font.fontSize)
|
const [selectedFontSize, setSelectedFontSize] = useState(font.fontSize)
|
||||||
const [selectedFontColor, setSelectedFontColor] = useState(font.fontColor)
|
const [selectedFontColor, setSelectedFontColor] = useState(font.fontColor)
|
||||||
|
|
||||||
const fontOptions = [
|
const fontOptions = [
|
||||||
{ id: 'normal', name: getMessage('font.style.normal'), value: 'normal' },
|
{ id: 'normal', name: getMessage('font.style.normal'), value: 'normal' },
|
||||||
{ id: 'italic', name: getMessage('font.style.italic'), value: 'italic' },
|
{ id: 'italic', name: getMessage('font.style.italic'), value: 'italic' },
|
||||||
{
|
{ id: 'bold', name: getMessage('font.style.bold'), value: 'bold' },
|
||||||
id: 'bold',
|
|
||||||
name: getMessage('font.style.bold'),
|
|
||||||
value: 'bold',
|
|
||||||
},
|
|
||||||
{ id: 'boldAndItalic', name: getMessage('font.style.bold.italic'), value: 'boldAndItalic' },
|
{ id: 'boldAndItalic', name: getMessage('font.style.bold.italic'), value: 'boldAndItalic' },
|
||||||
]
|
]
|
||||||
const fontColors = [
|
const fontColors = [
|
||||||
@ -57,12 +54,30 @@ export default function FontSetting(props) {
|
|||||||
{ id: 'gold', name: getMessage('color.gold'), value: 'gold' },
|
{ id: 'gold', name: getMessage('color.gold'), value: 'gold' },
|
||||||
{ id: 'darkblue', name: getMessage('color.darkblue'), value: 'darkblue' },
|
{ id: 'darkblue', name: getMessage('color.darkblue'), value: 'darkblue' },
|
||||||
]
|
]
|
||||||
|
useEffect(() => {
|
||||||
|
if (font.fontFamily) {
|
||||||
|
setSelectedFont(fonts.filter((data) => data.value === font.fontFamily)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font.fontWeight) {
|
||||||
|
setSelectedFontWeight(fontOptions.filter((data) => data.value === font.fontWeight)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font.fontSize) {
|
||||||
|
setSelectedFontSize(fontSizes.filter((data) => data.value === font.fontSize)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font.fontColor) {
|
||||||
|
setSelectedFontColor(fontColors.filter((data) => data.value === font.fontColor)[0])
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const handleSaveBtn = () => {
|
const handleSaveBtn = () => {
|
||||||
onSave({
|
onSave({
|
||||||
fontFamily: selectedFont,
|
fontFamily: selectedFont,
|
||||||
|
fontWeight: selectedFontWeight,
|
||||||
fontSize: selectedFontSize,
|
fontSize: selectedFontSize,
|
||||||
fontColor: selectedFontColor,
|
fontColor: selectedFontColor,
|
||||||
fontWeight: selectedFontWeight,
|
|
||||||
})
|
})
|
||||||
if (setIsShow) setIsShow(false)
|
if (setIsShow) setIsShow(false)
|
||||||
closePopup(id, isConfig)
|
closePopup(id, isConfig)
|
||||||
@ -117,9 +132,9 @@ export default function FontSetting(props) {
|
|||||||
<span
|
<span
|
||||||
style={{
|
style={{
|
||||||
fontFamily: selectedFont?.value ?? '',
|
fontFamily: selectedFont?.value ?? '',
|
||||||
|
fontWeight: selectedFontWeight?.value?.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
||||||
|
fontStyle: selectedFontWeight?.value?.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||||
fontSize: selectedFontSize?.value ?? '12px',
|
fontSize: selectedFontSize?.value ?? '12px',
|
||||||
fontStyle: selectedFontWeight?.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
|
||||||
fontWeight: selectedFontWeight?.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
|
||||||
color: selectedFontColor?.value ?? 'black',
|
color: selectedFontColor?.value ?? 'black',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -15,11 +15,12 @@ import { useCommonCode } from '@/hooks/common/useCommonCode'
|
|||||||
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
import Select, { components } from 'react-select'
|
import Select, { components } from 'react-select'
|
||||||
import { convertNumberToPriceDecimal } from '@/util/common-utils'
|
import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils'
|
||||||
import ProductFeaturesPop from './popup/ProductFeaturesPop'
|
import ProductFeaturesPop from './popup/ProductFeaturesPop'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
export default function Estimate({ params }) {
|
export default function Estimate({ params }) {
|
||||||
|
const [specialNoteFirstFlg, setSpecialNoteFirstFlg] = useState(false)
|
||||||
const fixedKey = 'itemKey'
|
const fixedKey = 'itemKey'
|
||||||
const [itemChangeYn, setItemChangeYn] = useState(false)
|
const [itemChangeYn, setItemChangeYn] = useState(false)
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
@ -102,44 +103,97 @@ export default function Estimate({ params }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//견적특이사항 API호출
|
//견적특이사항 API호출
|
||||||
//여러개 선택하면 구분자로 (、)
|
//여러개 선택하면 구분자로 (、)
|
||||||
let url = `/api/estimate/special-note-list`
|
if (!specialNoteFirstFlg) {
|
||||||
get({ url: url }).then((res) => {
|
let url = `/api/estimate/special-note-list`
|
||||||
if (isNotEmptyArray(res)) {
|
get({ url: url }).then((res) => {
|
||||||
if (estimateContextState?.estimateOption) {
|
if (isNotEmptyArray(res)) {
|
||||||
res.map((row) => {
|
if (estimateContextState?.estimateOption) {
|
||||||
let estimateOption = estimateContextState?.estimateOption?.split('、')
|
res.map((row) => {
|
||||||
row.check = false
|
let estimateOption = estimateContextState?.estimateOption?.split('、')
|
||||||
estimateOption.map((row2) => {
|
row.check = false
|
||||||
if (row2 === row.code) {
|
estimateOption.map((row2) => {
|
||||||
|
if (row2 === row.code) {
|
||||||
|
row.check = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//detail과 상관없이 디폴트 체크목록
|
||||||
|
//ATTR003,ATTR007
|
||||||
|
if (row.code === 'ATTR003') {
|
||||||
|
row.check = true
|
||||||
|
}
|
||||||
|
if (row.code === 'ATTR007') {
|
||||||
row.check = true
|
row.check = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
//detail과 상관없이 디폴트 체크목록
|
|
||||||
//ATTR003,ATTR007
|
setSpecialNoteList(res)
|
||||||
if (row.code === 'ATTR003') {
|
|
||||||
row.check = true
|
setSpecialNoteFirstFlg(true)
|
||||||
}
|
}
|
||||||
if (row.code === 'ATTR007') {
|
|
||||||
row.check = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setSpecialNoteList(res)
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
}
|
||||||
}, [estimateContextState?.estimateOption])
|
}, [estimateContextState?.estimateOption])
|
||||||
|
|
||||||
|
//변경버전
|
||||||
|
// useEffect(() => {
|
||||||
|
// //견적특이사항 API호출
|
||||||
|
// //여러개 선택하면 구분자로 (、)
|
||||||
|
// let url = `/api/estimate/special-note-title-list`
|
||||||
|
// // let url = `/api/estimate/special-note-list`
|
||||||
|
// get({ url: url }).then((res) => {
|
||||||
|
// if (isNotEmptyArray(res)) {
|
||||||
|
// if (estimateContextState?.estimateOption) {
|
||||||
|
// res.map((row) => {
|
||||||
|
// // console.log('API결과:::', row)
|
||||||
|
// //ATTR001、ATTR002、ATTR009、ATTR010
|
||||||
|
// let estimateOption = estimateContextState?.estimateOption?.split('、')
|
||||||
|
// row.check = false
|
||||||
|
// estimateOption.map((row2) => {
|
||||||
|
// if (row.pkgYn === '0') {
|
||||||
|
// if (row2 === row.code) {
|
||||||
|
// row.check = true
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if (row.code.includes(row2)) {
|
||||||
|
// row.check = true
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// //detail과 상관없이 디폴트 체크목록
|
||||||
|
// //ATTR003,ATTR007
|
||||||
|
// if (row.code === 'ATTR003') {
|
||||||
|
// row.check = true
|
||||||
|
// }
|
||||||
|
// if (row.code === 'ATTR007') {
|
||||||
|
// row.check = true
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// setSpecialNoteList(res)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }, [estimateContextState?.estimateOption])
|
||||||
|
|
||||||
|
//API데이터로 견적일 셋팅
|
||||||
|
let begin = 1
|
||||||
|
useEffect(() => {
|
||||||
|
if (begin === 1) {
|
||||||
|
setStartDate(estimateContextState?.estimateDate)
|
||||||
|
begin++
|
||||||
|
}
|
||||||
|
}, [estimateContextState?.estimateDate])
|
||||||
|
|
||||||
//견적일 set
|
//견적일 set
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let estimateDate = dayjs(startDate).format('YYYY-MM-DD')
|
let estimateDate = dayjs(startDate).format('YYYY-MM-DD')
|
||||||
setEstimateContextState({ estimateDate: estimateDate })
|
if (begin === 1) {
|
||||||
|
setEstimateContextState({ estimateDate: estimateDate })
|
||||||
|
}
|
||||||
}, [startDate])
|
}, [startDate])
|
||||||
|
|
||||||
//API데이터로 견적일 셋팅
|
|
||||||
useEffect(() => {
|
|
||||||
setStartDate(estimateContextState?.estimateDate)
|
|
||||||
}, [estimateContextState?.estimateDate])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//선택된 견적특이사항 setEstimateContextState
|
//선택된 견적특이사항 setEstimateContextState
|
||||||
if (isNotEmptyArray(specialNoteList)) {
|
if (isNotEmptyArray(specialNoteList)) {
|
||||||
@ -231,6 +285,15 @@ export default function Estimate({ params }) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//비워주기
|
||||||
|
setEstimateContextState({
|
||||||
|
pkgAsp: '0',
|
||||||
|
pkgTotPrice: '0',
|
||||||
|
})
|
||||||
|
|
||||||
|
//YJOD로 돌아가도 UNIT_PRICE로 프라이싱 실행해서 정가로 셋팅
|
||||||
|
handlePricing('UNIT_PRICE')
|
||||||
}
|
}
|
||||||
|
|
||||||
setItemChangeYn(true)
|
setItemChangeYn(true)
|
||||||
@ -296,9 +359,8 @@ export default function Estimate({ params }) {
|
|||||||
//기존itemList랑 프라이싱결과랑 비교해서 단가만 업뎃 서로 갯수가 안맞을 수 있음 없는 itemId면 unitPrice 0으로
|
//기존itemList랑 프라이싱결과랑 비교해서 단가만 업뎃 서로 갯수가 안맞을 수 있음 없는 itemId면 unitPrice 0으로
|
||||||
//itemId로 비교해서 salePrice만 업데이트
|
//itemId로 비교해서 salePrice만 업데이트
|
||||||
if (data.result.code === 200) {
|
if (data.result.code === 200) {
|
||||||
console.log('data::확인해서 넣기:::::::::', data.data.pkgUnitPrice)
|
|
||||||
setEstimateContextState({
|
setEstimateContextState({
|
||||||
pkgAsp: data.data.pkgUnitPrice,
|
pkgAsp: data?.data?.pkgUnitPrice,
|
||||||
})
|
})
|
||||||
//주택PKG단가 체인지 이벤트 발생시키기
|
//주택PKG단가 체인지 이벤트 발생시키기
|
||||||
onChangePkgAsp(data.data.pkgUnitPrice)
|
onChangePkgAsp(data.data.pkgUnitPrice)
|
||||||
@ -309,7 +371,11 @@ export default function Estimate({ params }) {
|
|||||||
data.data2.map((item2) => {
|
data.data2.map((item2) => {
|
||||||
if (item2) {
|
if (item2) {
|
||||||
if (item2.itemId === item.itemId) {
|
if (item2.itemId === item.itemId) {
|
||||||
updateList.push({ ...item, salePrice: item2.unitPrice, saleTotPrice: (item.amount * item2.unitPrice).toString() })
|
updateList.push({
|
||||||
|
...item,
|
||||||
|
salePrice: item2.unitPrice === null ? '0' : item2.unitPrice,
|
||||||
|
saleTotPrice: (item.amount * item2.unitPrice).toString(),
|
||||||
|
})
|
||||||
checkYn = true
|
checkYn = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,7 +385,6 @@ export default function Estimate({ params }) {
|
|||||||
updateList.push({ ...item, salePrice: '0', saleTotPrice: '0' })
|
updateList.push({ ...item, salePrice: '0', saleTotPrice: '0' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setEstimateContextState({
|
setEstimateContextState({
|
||||||
priceCd: showPriceCd,
|
priceCd: showPriceCd,
|
||||||
itemList: updateList,
|
itemList: updateList,
|
||||||
@ -333,6 +398,24 @@ export default function Estimate({ params }) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getAbledItems = (items) => {
|
||||||
|
return items.filter((items) => items.paDispOrder === null)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onChangeSelectAll = (e) => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
const allCheckedSelection = new Set(getAbledItems(estimateContextState.itemList).map((item) => item.dispOrder))
|
||||||
|
|
||||||
|
setSelection(allCheckedSelection)
|
||||||
|
} else {
|
||||||
|
setSelection(new Set())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isSelectedAll = () => {
|
||||||
|
return selection.size === getAbledItems(estimateContextState.itemList).length
|
||||||
|
}
|
||||||
|
|
||||||
//row 체크박스 컨트롤
|
//row 체크박스 컨트롤
|
||||||
const onChangeSelect = (dispOrder) => {
|
const onChangeSelect = (dispOrder) => {
|
||||||
const newSelection = new Set(selection)
|
const newSelection = new Set(selection)
|
||||||
@ -358,13 +441,13 @@ export default function Estimate({ params }) {
|
|||||||
|
|
||||||
let totVolKw = estimateContextState.totVolKw * 1000
|
let totVolKw = estimateContextState.totVolKw * 1000
|
||||||
let pkgTotPrice = pkgAsp.replaceAll(',', '') * totVolKw
|
let pkgTotPrice = pkgAsp.replaceAll(',', '') * totVolKw
|
||||||
|
|
||||||
setEstimateContextState({
|
setEstimateContextState({
|
||||||
pkgAsp: pkgAsp,
|
pkgAsp: pkgAsp,
|
||||||
pkgTotPrice: pkgTotPrice.toFixed(3),
|
pkgTotPrice: pkgTotPrice.toFixed(3),
|
||||||
})
|
})
|
||||||
//아이템들 중 조건에 맞는애들 뽑아서 상단 공급가액 부가세 총액 수정
|
//아이템들 중 조건에 맞는애들 뽑아서 상단 공급가액 부가세 총액 수정
|
||||||
// setItemChangeYn(true)
|
setItemChangeYn(true)
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +475,6 @@ export default function Estimate({ params }) {
|
|||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setEstimateContextState({
|
setEstimateContextState({
|
||||||
itemList: updateList,
|
itemList: updateList,
|
||||||
})
|
})
|
||||||
@ -429,7 +511,7 @@ export default function Estimate({ params }) {
|
|||||||
setItemChangeYn(true)
|
setItemChangeYn(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 아이템 자동완성 검색시 아이템 변경
|
// 아이템 자동완성 검색시 아이템 추가/변경시
|
||||||
const onChangeDisplayItem = (itemId, dispOrder, index) => {
|
const onChangeDisplayItem = (itemId, dispOrder, index) => {
|
||||||
const param = {
|
const param = {
|
||||||
itemId: itemId,
|
itemId: itemId,
|
||||||
@ -438,7 +520,7 @@ export default function Estimate({ params }) {
|
|||||||
let updateList = []
|
let updateList = []
|
||||||
let updates = {}
|
let updates = {}
|
||||||
get({ url: apiUrl }).then((res) => {
|
get({ url: apiUrl }).then((res) => {
|
||||||
// console.log('아이템상세정보:::::::', res)
|
console.log('아이템디테일::::::::', res)
|
||||||
updates.objectNo = objectNo
|
updates.objectNo = objectNo
|
||||||
updates.planNo = planNo
|
updates.planNo = planNo
|
||||||
updates.itemId = res.itemId
|
updates.itemId = res.itemId
|
||||||
@ -460,6 +542,12 @@ export default function Estimate({ params }) {
|
|||||||
updates.delFlg = '0' // 삭제플래그 0
|
updates.delFlg = '0' // 삭제플래그 0
|
||||||
updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString()
|
updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString()
|
||||||
|
|
||||||
|
if (estimateContextState.estimateType === 'YJSS') {
|
||||||
|
if (res.pkgMaterialFlg === '0') {
|
||||||
|
//updates.showSalePrice = '0'
|
||||||
|
//updates.showSaleTotPrice = '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
//104671
|
//104671
|
||||||
let bomList = res.itemBomList
|
let bomList = res.itemBomList
|
||||||
|
|
||||||
@ -467,7 +555,8 @@ export default function Estimate({ params }) {
|
|||||||
if (item.dispOrder === dispOrder) {
|
if (item.dispOrder === dispOrder) {
|
||||||
return { ...item, ...updates }
|
return { ...item, ...updates }
|
||||||
} else if (item.paDispOrder === dispOrder) {
|
} else if (item.paDispOrder === dispOrder) {
|
||||||
return { ...item, delFlg: '1' }
|
return { ...item, delFlg: '0' }
|
||||||
|
// return { ...item, delFlg: '1' }
|
||||||
} else {
|
} else {
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
@ -475,8 +564,21 @@ export default function Estimate({ params }) {
|
|||||||
//paDispOrder
|
//paDispOrder
|
||||||
if (bomList) {
|
if (bomList) {
|
||||||
bomList.map((bomItem, index) => {
|
bomList.map((bomItem, index) => {
|
||||||
let newItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder))
|
let maxItemDispOrder = Math.max(...estimateContextState.itemList.map((item) => item.dispOrder))
|
||||||
bomItem.dispOrder = index + 1 + newItemDispOrder
|
if (maxItemDispOrder == dispOrder) {
|
||||||
|
bomItem.dispOrder = (index + 1 + maxItemDispOrder).toString()
|
||||||
|
bomItem.paDispOrder = dispOrder
|
||||||
|
bomItem.salePrice = '0'
|
||||||
|
//unitPrice는??
|
||||||
|
bomItem.saleTotPrice = '0'
|
||||||
|
} else {
|
||||||
|
bomItem.dispOrder = (index + 1 + Number(dispOrder)).toString()
|
||||||
|
bomItem.paDispOrder = dispOrder
|
||||||
|
bomItem.salePrice = '0'
|
||||||
|
//unitPrice는??
|
||||||
|
bomItem.saleTotPrice = '0'
|
||||||
|
}
|
||||||
|
|
||||||
bomItem.delFlg = '0'
|
bomItem.delFlg = '0'
|
||||||
bomItem.objectNo = objectNo
|
bomItem.objectNo = objectNo
|
||||||
bomItem.planNo = planNo
|
bomItem.planNo = planNo
|
||||||
@ -539,21 +641,31 @@ export default function Estimate({ params }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (itemChangeYn) {
|
if (itemChangeYn) {
|
||||||
console.log(' 토탈만들어주기::::::::::', estimateContextState.itemList)
|
|
||||||
|
|
||||||
let totAmount = 0
|
let totAmount = 0
|
||||||
let totVolKw = 0
|
let totVolKw = 0
|
||||||
let supplyPrice = 0
|
let supplyPrice = 0
|
||||||
let vatPrice = 0
|
let vatPrice = 0
|
||||||
let totPrice = 0
|
let totPrice = 0
|
||||||
let addPkgPrice = 0
|
let addSupplyPrice = 0
|
||||||
if (estimateContextState.estimateType === 'YJOD') {
|
if (estimateContextState.estimateType === 'YJOD') {
|
||||||
|
console.log('YJOD 토탈만들어주기::::::::::', estimateContextState.itemList)
|
||||||
|
|
||||||
|
estimateContextState.itemList.sort((a, b) => {
|
||||||
|
return a.dispOrder - b.dispOrder
|
||||||
|
})
|
||||||
|
|
||||||
estimateContextState.itemList.map((item) => {
|
estimateContextState.itemList.map((item) => {
|
||||||
|
//delete item.showSalePrice
|
||||||
|
//delete item.showSaleTotPrice
|
||||||
if (item.delFlg === '0') {
|
if (item.delFlg === '0') {
|
||||||
const amount = Number(item.amount.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
let amount = Number(item?.amount?.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
||||||
|
if (isNaN(amount)) {
|
||||||
const price = Number(item.saleTotPrice.replaceAll(',', ''))
|
amount = 0
|
||||||
|
}
|
||||||
|
let price = Number(item?.saleTotPrice?.replaceAll(',', ''))
|
||||||
|
if (isNaN(price)) {
|
||||||
|
price = 0
|
||||||
|
}
|
||||||
if (item.moduleFlg === '1') {
|
if (item.moduleFlg === '1') {
|
||||||
//용량(Kw)은 모듈플래그 1만 합산
|
//용량(Kw)은 모듈플래그 1만 합산
|
||||||
const volKw = (item.pnowW * amount) / 1000
|
const volKw = (item.pnowW * amount) / 1000
|
||||||
@ -577,32 +689,55 @@ export default function Estimate({ params }) {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
//YJSS
|
//YJSS
|
||||||
|
console.log('YJSS 토탈만들어주기::::::::::', estimateContextState.itemList)
|
||||||
|
estimateContextState.itemList.sort((a, b) => {
|
||||||
|
return a.dispOrder - b.dispOrder
|
||||||
|
})
|
||||||
estimateContextState.itemList.map((item) => {
|
estimateContextState.itemList.map((item) => {
|
||||||
if (item.delFlg === '0') {
|
if (item.delFlg === '0') {
|
||||||
const amount = Number(item.amount.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
||||||
const price = Number(item.saleTotPrice.replaceAll(',', ''))
|
let price = Number(item.saleTotPrice?.replaceAll(',', ''))
|
||||||
const salePrice = Number(item.salePrice.replaceAll(',', ''))
|
let salePrice = Number(item.salePrice?.replaceAll(',', ''))
|
||||||
|
|
||||||
|
if (isNaN(amount)) {
|
||||||
|
amount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(price)) {
|
||||||
|
price = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(salePrice)) {
|
||||||
|
salePrice = 0
|
||||||
|
}
|
||||||
if (item.moduleFlg === '1') {
|
if (item.moduleFlg === '1') {
|
||||||
//용량(Kw)은 모듈플래그 1만 합산
|
//용량(Kw)은 모듈플래그 1만 합산
|
||||||
const volKw = (item.pnowW * amount) / 1000
|
const volKw = (item.pnowW * amount) / 1000
|
||||||
totVolKw += volKw
|
totVolKw += volKw
|
||||||
}
|
}
|
||||||
if (item.pkgMaterialFlg === '1') {
|
|
||||||
const pkgPrice = amount * salePrice
|
|
||||||
//YJSS는 PKG제외상품들만 모아서 수량 * 단가를 공급가액에 추가로 더해줌
|
|
||||||
addPkgPrice += pkgPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
// const price
|
// const price
|
||||||
totAmount += amount
|
|
||||||
supplyPrice += price
|
supplyPrice += price
|
||||||
|
totAmount += amount
|
||||||
|
if (item.pkgMaterialFlg === '1') {
|
||||||
|
const pkgPrice = amount * salePrice
|
||||||
|
//다시계산하기
|
||||||
|
//YJSS는 PKG제외상품들만(1) 모아서 수량 * 단가를 공급가액(supplyPrice)에 추가로 더해줌
|
||||||
|
addSupplyPrice += pkgPrice
|
||||||
|
}
|
||||||
|
if (!item.paDispOrder) {
|
||||||
|
//paDispOrder
|
||||||
|
if (item.pkgMaterialFlg === '0') {
|
||||||
|
//item.showSalePrice = '0'
|
||||||
|
//item.showSaleTotPrice = '0'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
supplyPrice += addSupplyPrice
|
||||||
vatPrice = supplyPrice * 0.1
|
vatPrice = supplyPrice * 0.1
|
||||||
totPrice = supplyPrice + vatPrice
|
totPrice = supplyPrice + vatPrice
|
||||||
|
|
||||||
setEstimateContextState({
|
setEstimateContextState({
|
||||||
totAmount: totAmount,
|
totAmount: totAmount,
|
||||||
totVolKw: totVolKw.toFixed(3),
|
totVolKw: totVolKw.toFixed(3),
|
||||||
@ -845,6 +980,23 @@ export default function Estimate({ params }) {
|
|||||||
setEstimateContextState({
|
setEstimateContextState({
|
||||||
fileFlg: e.target.checked ? '1' : '0',
|
fileFlg: e.target.checked ? '1' : '0',
|
||||||
})
|
})
|
||||||
|
if (e.target.checked) {
|
||||||
|
if (specialNoteList.length > 0) {
|
||||||
|
specialNoteList.map((item) => {
|
||||||
|
if (item.code === 'ATTR019') {
|
||||||
|
item.check = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (specialNoteList.length > 0) {
|
||||||
|
specialNoteList.map((item) => {
|
||||||
|
if (item.code === 'ATTR019') {
|
||||||
|
item.check = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="next" style={{ color: '#101010' }}>
|
<label htmlFor="next" style={{ color: '#101010' }}>
|
||||||
@ -927,7 +1079,6 @@ export default function Estimate({ params }) {
|
|||||||
{/* SpecialNoteList반복문 */}
|
{/* SpecialNoteList반복문 */}
|
||||||
{specialNoteList.length > 0 &&
|
{specialNoteList.length > 0 &&
|
||||||
specialNoteList.map((row) => {
|
specialNoteList.map((row) => {
|
||||||
// console.log('rowL::::', row)
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={uuidv4()}
|
key={uuidv4()}
|
||||||
@ -941,7 +1092,7 @@ export default function Estimate({ params }) {
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
id={row.code}
|
id={row.code}
|
||||||
checked={!!row.check}
|
checked={!!row.check}
|
||||||
disabled={row.code === 'ATTR001' || row.code === 'ATTR002' ? true : false}
|
disabled={row.code === 'ATTR001' ? true : false}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
setSpecialNoteList((specialNote) =>
|
setSpecialNoteList((specialNote) =>
|
||||||
specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)),
|
specialNote.map((temp) => (temp.code === row.code ? { ...temp, check: !temp.check } : temp)),
|
||||||
@ -990,19 +1141,19 @@ export default function Estimate({ params }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}</div>
|
||||||
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.totVolKw)}</div>
|
<div className="estimate-name blue">{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}</div>
|
||||||
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.supplyPrice)}</div>
|
<div className="estimate-name blue">{convertNumberToPriceDecimalToFixed(estimateContextState?.supplyPrice, 2)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}</div>
|
||||||
<div className="estimate-name blue">{convertNumberToPriceDecimal(estimateContextState?.vatPrice)}</div>
|
<div className="estimate-name blue">{convertNumberToPriceDecimalToFixed(estimateContextState?.vatPrice, 2)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totPrice')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totPrice')}</div>
|
||||||
<div className="estimate-name red">{convertNumberToPriceDecimal(estimateContextState?.totPrice)}</div>
|
<div className="estimate-name red">{convertNumberToPriceDecimalToFixed(estimateContextState?.totPrice, 2)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1028,7 +1179,7 @@ export default function Estimate({ params }) {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="input-light"
|
className="input-light"
|
||||||
value={estimateContextState?.pkgAsp}
|
value={estimateContextState?.estimateType === 'YJSS' ? estimateContextState?.pkgAsp : '0'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onChangePkgAsp(e.target.value)
|
onChangePkgAsp(e.target.value)
|
||||||
}}
|
}}
|
||||||
@ -1036,9 +1187,9 @@ export default function Estimate({ params }) {
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')}</th>
|
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgWeight')}</th>
|
||||||
<td>{convertNumberToPriceDecimal(estimateContextState?.totVolKw)}</td>
|
<td>{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}</td>
|
||||||
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')}</th>
|
<th>{getMessage('estimate.detail.sepcialEstimateProductInfo.pkgPrice')}</th>
|
||||||
<td>{convertNumberToPriceDecimal(estimateContextState?.pkgTotPrice)}</td>
|
<td>{convertNumberToPriceDecimalToFixed(estimateContextState?.pkgTotPrice, 2)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -1096,13 +1247,11 @@ export default function Estimate({ params }) {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div className="product-edit-btn">
|
<div className="product-edit-btn">
|
||||||
{/* <button className="btn-origin navy mr5" type="button" onClick={addItem}> */}
|
|
||||||
<button
|
<button
|
||||||
className="btn-origin navy mr5"
|
className="btn-origin navy mr5"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
addItem()
|
addItem()
|
||||||
// setItemChangeYn(true)
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="plus"></span>
|
<span className="plus"></span>
|
||||||
@ -1121,19 +1270,20 @@ export default function Estimate({ params }) {
|
|||||||
<table>
|
<table>
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col width={50} />
|
<col width={50} />
|
||||||
<col width={100} />
|
<col width={50} />
|
||||||
<col />
|
<col />
|
||||||
<col width={250} />
|
<col width={250} />
|
||||||
<col width={100} />
|
<col width={90} />
|
||||||
<col width={100} />
|
<col width={80} />
|
||||||
<col width={200} />
|
<col width={140} />
|
||||||
<col width={240} />
|
<col width={190} />
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<div className="d-check-box pop no-text" style={{ display: 'none' }}>
|
{/* <div className="d-check-box pop no-text" style={{ display: 'none' }}> */}
|
||||||
<input type="checkbox" id="ch97" />
|
<div className="d-check-box pop no-text">
|
||||||
|
<input type="checkbox" id="ch97" checked={isSelectedAll()} onChange={onChangeSelectAll} />
|
||||||
<label htmlFor="ch97"></label>
|
<label htmlFor="ch97"></label>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
@ -1219,12 +1369,12 @@ export default function Estimate({ params }) {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="input-light al-r"
|
className="input-light al-r"
|
||||||
// value={item?.amount}
|
value={convertNumberToPriceDecimal(item?.amount?.replaceAll(',', ''))}
|
||||||
value={convertNumberToPriceDecimal(item?.amount.replaceAll(',', ''))}
|
|
||||||
disabled={item.itemId === '' || !!item?.paDispOrder}
|
disabled={item.itemId === '' || !!item?.paDispOrder}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onChangeAmount(e.target.value, item.dispOrder, index)
|
onChangeAmount(e.target.value, item.dispOrder, index)
|
||||||
}}
|
}}
|
||||||
|
maxLength={6}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -1235,7 +1385,8 @@ export default function Estimate({ params }) {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="input-light al-r"
|
className="input-light al-r"
|
||||||
value={convertNumberToPriceDecimal(item?.salePrice.replaceAll(',', ''))}
|
// value={convertNumberToPriceDecimal(item?.showSalePrice === '0' ? null : item?.salePrice?.replaceAll(',', ''))}
|
||||||
|
value={convertNumberToPriceDecimal(item?.salePrice?.replaceAll(',', ''))}
|
||||||
disabled={
|
disabled={
|
||||||
estimateContextState?.estimateType === 'YJSS'
|
estimateContextState?.estimateType === 'YJSS'
|
||||||
? item?.paDispOrder
|
? item?.paDispOrder
|
||||||
@ -1246,6 +1397,7 @@ export default function Estimate({ params }) {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onChangeSalePrice(e.target.value, item.dispOrder, index)
|
onChangeSalePrice(e.target.value, item.dispOrder, index)
|
||||||
}}
|
}}
|
||||||
|
maxLength={12}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="btn-area">
|
{/* <div className="btn-area">
|
||||||
@ -1253,7 +1405,12 @@ export default function Estimate({ params }) {
|
|||||||
</div> */}
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="al-r">{convertNumberToPriceDecimal(item?.saleTotPrice.replaceAll(',', ''))}</td>
|
<td className="al-r">{convertNumberToPriceDecimalToFixed(item?.saleTotPrice?.replaceAll(',', ''), 2)}</td>
|
||||||
|
{/* {item?.showSaleTotPrice === '0' ? (
|
||||||
|
<td className="al-r"></td>
|
||||||
|
) : (
|
||||||
|
<td className="al-r">{convertNumberToPriceDecimalToFixed(item?.saleTotPrice?.replaceAll(',', ''), 2)}</td>
|
||||||
|
)} */}
|
||||||
</tr>
|
</tr>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,22 +1,20 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
import { useContext, useEffect } from 'react'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
//import { useRecoilState } from 'recoil'
|
||||||
import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
|
|
||||||
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
//import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
|
//import { correntObjectNoState } from '@/store/settingAtom'
|
||||||
import '@/styles/contents.scss'
|
import '@/styles/contents.scss'
|
||||||
|
|
||||||
export default function FloorPlan({ children }) {
|
export default function FloorPlan({ children }) {
|
||||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
//const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
||||||
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
//const [correntObjectNo, setCorrentObjectNo] = useRecoilState(correntObjectNoState)
|
||||||
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
|
||||||
const { closeAll } = usePopup()
|
const { closeAll } = usePopup()
|
||||||
|
|
||||||
const { menuNumber, setMenuNumber } = useCanvasMenu()
|
const { menuNumber, setMenuNumber } = useCanvasMenu()
|
||||||
|
|
||||||
const { fetchSettings } = useCanvasSetting()
|
const { fetchSettings } = useCanvasSetting()
|
||||||
|
|
||||||
const modalProps = {
|
const modalProps = {
|
||||||
@ -25,11 +23,13 @@ export default function FloorPlan({ children }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
///setCorrentObjectNo(floorPlanState.objectNo)
|
||||||
|
//console.log('FloorPlan objectNo ', floorPlanState.objectNo, correntObjectNo)
|
||||||
fetchSettings()
|
fetchSettings()
|
||||||
return () => {
|
return () => {
|
||||||
closeAll()
|
closeAll()
|
||||||
}
|
}
|
||||||
}, [objectNo])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
import { useContext, useEffect } from 'react'
|
import { useContext, useEffect } from 'react'
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,7 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
handleFix,
|
handleFix,
|
||||||
buttonAct,
|
buttonAct,
|
||||||
setButtonAct,
|
setButtonAct,
|
||||||
|
cutAuxiliary,
|
||||||
} = useAuxiliaryDrawing(id)
|
} = useAuxiliaryDrawing(id)
|
||||||
|
|
||||||
const outerLineProps = {
|
const outerLineProps = {
|
||||||
@ -151,6 +152,9 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
<button className="btn-frame modal mr5" onClick={handleRollback}>
|
<button className="btn-frame modal mr5" onClick={handleRollback}>
|
||||||
{getMessage('modal.cover.outline.rollback')}
|
{getMessage('modal.cover.outline.rollback')}
|
||||||
</button>
|
</button>
|
||||||
|
<button className="btn-frame modal mr5" onClick={cutAuxiliary}>
|
||||||
|
{getMessage('contextmenu.auxiliary.cut')}
|
||||||
|
</button>
|
||||||
<button className="btn-frame modal act" onClick={() => handleFix(id)}>
|
<button className="btn-frame modal act" onClick={() => handleFix(id)}>
|
||||||
{getMessage('apply')}
|
{getMessage('apply')}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { currentObjectState } from '@/store/canvasAtom'
|
import { currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useLine } from '@/hooks/useLine'
|
|
||||||
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
|
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
|
||||||
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
|
||||||
export default function AuxiliaryEdit(props) {
|
export default function AuxiliaryEdit(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -18,9 +18,13 @@ export default function AuxiliaryEdit(props) {
|
|||||||
const [horizonSize, setHorizonSize] = useState('0')
|
const [horizonSize, setHorizonSize] = useState('0')
|
||||||
const [arrow1, setArrow1] = useState(null)
|
const [arrow1, setArrow1] = useState(null)
|
||||||
const [arrow2, setArrow2] = useState(null)
|
const [arrow2, setArrow2] = useState(null)
|
||||||
const { addLine, removeLine } = useLine()
|
|
||||||
const currentObject = useRecoilValue(currentObjectState)
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
|
const { swalFire } = useSwal()
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
|
if (!horizonSize || !verticalSize || !arrow1 || !arrow2) {
|
||||||
|
swalFire({ title: '길이와 방향을 입력하세요.', type: 'alert' })
|
||||||
|
return
|
||||||
|
}
|
||||||
if (type === 'copy') {
|
if (type === 'copy') {
|
||||||
if (currentObject) {
|
if (currentObject) {
|
||||||
copy(
|
copy(
|
||||||
|
|||||||
@ -3,12 +3,14 @@ import WithDraggable from '@/components/common/draggable/WithDraggable'
|
|||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
|
import { useCanvas } from '@/hooks/useCanvas'
|
||||||
|
|
||||||
export default function AuxiliarySize(props) {
|
export default function AuxiliarySize(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition } = props
|
const { id, pos = contextPopupPosition } = props
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
|
const { currentObject } = useCanvas()
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap xm mount`}>
|
<div className={`modal-pop-wrap xm mount`}>
|
||||||
@ -26,7 +28,7 @@ export default function AuxiliarySize(props) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="outline-form mb15">
|
<div className="outline-form mb15">
|
||||||
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
|
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={100} />
|
<input type="text" className="input-origin block" defaultValue={currentObject?.length} readOnly={true} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -45,14 +47,14 @@ export default function AuxiliarySize(props) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="outline-form mb15">
|
<div className="outline-form mb15">
|
||||||
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
|
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={100} />
|
<input type="text" className="input-origin block" defaultValue={100} readOnly={true} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
|
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input type="text" className="input-origin block" defaultValue={100} />
|
<input type="text" className="input-origin block" defaultValue={currentObject?.length} readOnly={true} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -82,7 +82,7 @@ const PentagonDormer = forwardRef((props, refs) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="discrimination-box">
|
<div className="discrimination-box">
|
||||||
<div className="discrimination-tit">方向の選択</div>
|
<div className="discrimination-tit">{getMessage('modal.object.setting.direction.select')}</div>
|
||||||
<div className="object-direction-wrap">
|
<div className="object-direction-wrap">
|
||||||
<div className="plane-direction">
|
<div className="plane-direction">
|
||||||
<span className="top">{getMessage('commons.north')}</span>
|
<span className="top">{getMessage('commons.north')}</span>
|
||||||
|
|||||||
@ -60,7 +60,7 @@ const TriangleDormer = forwardRef((props, refs) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="discrimination-box">
|
<div className="discrimination-box">
|
||||||
<div className="discrimination-tit">方向の選択</div>
|
<div className="discrimination-tit">{getMessage('modal.object.setting.direction.select')}</div>
|
||||||
<div className="object-direction-wrap">
|
<div className="object-direction-wrap">
|
||||||
<div className="plane-direction">
|
<div className="plane-direction">
|
||||||
<span className="top">{getMessage('commons.north')}</span>
|
<span className="top">{getMessage('commons.north')}</span>
|
||||||
|
|||||||
@ -1,19 +1,46 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
import { setSurfaceShapePattern } from '@/util/canvas-util'
|
||||||
|
|
||||||
export default function FirstOption() {
|
export default function FirstOption() {
|
||||||
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
|
||||||
const { settingModalFirstOptions, setSettingModalFirstOptions } = useCanvasSetting()
|
|
||||||
const { settingModalSecondOptions, setSettingModalSecondOptions } = useCanvasSetting()
|
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { canvas, settingModalFirstOptions, setSettingModalFirstOptions } = useCanvasSetting()
|
||||||
const { fetchSettings, frontSettings, onClickOption } = useCanvasSetting()
|
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||||
|
|
||||||
// 데이터를 최초 한 번만 조회
|
// 데이터를 최초 한 번만 조회
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('FirstOption useEffect 실행')
|
console.log('FirstOption useEffect 실행')
|
||||||
}, [objectNo])
|
}, [])
|
||||||
|
|
||||||
|
const onClickOption = async (item) => {
|
||||||
|
//치수 표시(단 건 선택)
|
||||||
|
if (item.column === 'corridorDimension' || item.column === 'realDimension' || item.column === 'noneDimension') {
|
||||||
|
const options = settingModalFirstOptions?.dimensionDisplay.map((option) => {
|
||||||
|
option.selected = option.id === item.id
|
||||||
|
return option
|
||||||
|
})
|
||||||
|
|
||||||
|
//화면 표시(단 건 선택)
|
||||||
|
} else if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') {
|
||||||
|
const options2 = settingModalFirstOptions?.option2.map((option2) => {
|
||||||
|
option2.selected = option2.id === item.id
|
||||||
|
return option2
|
||||||
|
})
|
||||||
|
|
||||||
|
const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
|
||||||
|
polygons.forEach((polygon) => {
|
||||||
|
setSurfaceShapePattern(polygon, item.column)
|
||||||
|
})
|
||||||
|
//디스플레이 설정 표시(단 건 선택)
|
||||||
|
} else {
|
||||||
|
item.selected = !item.selected
|
||||||
|
}
|
||||||
|
|
||||||
|
setSettingModalFirstOptions({ ...settingModalFirstOptions, option1, option2, dimensionDisplay, fontFlag: true })
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -16,32 +16,40 @@ export default function SecondOption() {
|
|||||||
const [showDimensionLineSettingModal, setShowDimensionLineSettingModal] = useState(false)
|
const [showDimensionLineSettingModal, setShowDimensionLineSettingModal] = useState(false)
|
||||||
const [showPlanSizeSettingModal, setShowPlanSizeSettingModal] = useState(false)
|
const [showPlanSizeSettingModal, setShowPlanSizeSettingModal] = useState(false)
|
||||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||||
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
|
||||||
const { settingModalSecondOptions, setSettingModalSecondOptions } = useCanvasSetting()
|
|
||||||
const { adsorptionPointMode, setAdsorptionPointMode } = useCanvasSetting()
|
|
||||||
const { fetchSettings, frontSettings, onClickOption } = useCanvasSetting()
|
|
||||||
const commonFont = useRecoilValue(fontSelector('commonText'))
|
const commonFont = useRecoilValue(fontSelector('commonText'))
|
||||||
const flowFont = useRecoilValue(fontSelector('flowText'))
|
const flowFont = useRecoilValue(fontSelector('flowText'))
|
||||||
const lengthFont = useRecoilValue(fontSelector('lengthText'))
|
const lengthFont = useRecoilValue(fontSelector('lengthText'))
|
||||||
const circuitNumberTextFont = useRecoilValue(fontSelector('circuitNumberText'))
|
const circuitNumberTextFont = useRecoilValue(fontSelector('circuitNumberText'))
|
||||||
|
|
||||||
const [dimensionId, setDimensionId] = useState(uuidv4())
|
const [dimensionId, setDimensionId] = useState(uuidv4())
|
||||||
const [fontId, setFontId] = useState(uuidv4())
|
const [fontId, setFontId] = useState(uuidv4())
|
||||||
const [planSizeId, setPlanSizeId] = useState(uuidv4())
|
const [planSizeId, setPlanSizeId] = useState(uuidv4())
|
||||||
|
|
||||||
|
const {
|
||||||
|
//horizon, setHorizon, vertical, setVertical,
|
||||||
|
// originHorizon,
|
||||||
|
// setOriginHorizon,
|
||||||
|
// originVertical,
|
||||||
|
// setOriginVertical,
|
||||||
|
planSizeSettingMode,
|
||||||
|
setPlanSizeSettingMode,
|
||||||
|
settingModalSecondOptions,
|
||||||
|
setSettingModalSecondOptions,
|
||||||
|
adsorptionPointMode,
|
||||||
|
setAdsorptionPointMode,
|
||||||
|
setAdsorptionRange,
|
||||||
|
} = useCanvasSetting()
|
||||||
|
const { option3, option4 } = settingModalSecondOptions
|
||||||
|
|
||||||
|
// const [horizon, setHorizon] = useState(originHorizon)
|
||||||
|
// const [vertical, setVertical] = useState(originVertical)
|
||||||
|
|
||||||
// 데이터를 최초 한 번만 조회
|
// 데이터를 최초 한 번만 조회
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//fetchSettings()
|
console.log('SecondOption useEffect 실행', planSizeSettingMode)
|
||||||
}, [objectNo])
|
}, [])
|
||||||
|
|
||||||
const dimensionProps = {
|
|
||||||
id: dimensionId,
|
|
||||||
isShow: showDimensionLineSettingModal,
|
|
||||||
setIsShow: setShowDimensionLineSettingModal,
|
|
||||||
}
|
|
||||||
|
|
||||||
const [horizon, setHorizon] = useState(1600)
|
|
||||||
const [vertical, setVertical] = useState(1600)
|
|
||||||
const handlePopup = (type) => {
|
const handlePopup = (type) => {
|
||||||
|
setShowDimensionLineSettingModal(false)
|
||||||
setShowPlanSizeSettingModal(false)
|
setShowPlanSizeSettingModal(false)
|
||||||
setShowFontSettingModal(false)
|
setShowFontSettingModal(false)
|
||||||
|
|
||||||
@ -51,8 +59,8 @@ export default function SecondOption() {
|
|||||||
setShowFontSettingModal(true)
|
setShowFontSettingModal(true)
|
||||||
setShowDimensionLineSettingModal(false)
|
setShowDimensionLineSettingModal(false)
|
||||||
fontProps.type = 'commonText'
|
fontProps.type = 'commonText'
|
||||||
fontProps.id = fontId + 1
|
|
||||||
fontProps.font = commonFont
|
fontProps.font = commonFont
|
||||||
|
fontProps.id = fontId + 1
|
||||||
addPopup(fontId + 1, 2, <FontSetting {...fontProps} />, true)
|
addPopup(fontId + 1, 2, <FontSetting {...fontProps} />, true)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -96,9 +104,9 @@ export default function SecondOption() {
|
|||||||
setShowDimensionLineSettingModal(true)
|
setShowDimensionLineSettingModal(true)
|
||||||
fontProps.font = {
|
fontProps.font = {
|
||||||
fontFamily: '',
|
fontFamily: '',
|
||||||
fontColor: '',
|
|
||||||
fontSize: '',
|
|
||||||
fontWeight: '',
|
fontWeight: '',
|
||||||
|
fontSize: '',
|
||||||
|
fontColor: '',
|
||||||
}
|
}
|
||||||
addPopup(dimensionId, 2, <DimensionLineSetting {...dimensionProps} />, true)
|
addPopup(dimensionId, 2, <DimensionLineSetting {...dimensionProps} />, true)
|
||||||
} else {
|
} else {
|
||||||
@ -110,9 +118,13 @@ export default function SecondOption() {
|
|||||||
|
|
||||||
case 'planSize': {
|
case 'planSize': {
|
||||||
//도면크기 설정
|
//도면크기 설정
|
||||||
setShowPlanSizeSettingModal(true)
|
if (!showPlanSizeSettingModal) {
|
||||||
setShowDimensionLineSettingModal(false)
|
setShowPlanSizeSettingModal(true)
|
||||||
addPopup(planSizeId, 2, <PlanSizeSetting {...planSizeProps} />, true)
|
addPopup(planSizeId, 2, <PlanSizeSetting {...planSizeProps} />, true)
|
||||||
|
} else {
|
||||||
|
setShowPlanSizeSettingModal(false)
|
||||||
|
closePopup(planSizeId, true)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,11 +135,12 @@ export default function SecondOption() {
|
|||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[fontProps.type]: {
|
[fontProps.type]: {
|
||||||
fontFamily: font.fontFamily,
|
fontFamily: font.fontFamily.value,
|
||||||
fontWeight: font.fontWeight,
|
fontWeight: font.fontWeight.value,
|
||||||
fontSize: font.fontSize,
|
fontSize: font.fontSize.value,
|
||||||
fontColor: font.fontColor,
|
fontColor: font.fontColor.value,
|
||||||
},
|
},
|
||||||
|
fontFlag: true,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -140,16 +153,48 @@ export default function SecondOption() {
|
|||||||
isConfig: true,
|
isConfig: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dimensionProps = {
|
||||||
|
id: dimensionId,
|
||||||
|
isShow: showDimensionLineSettingModal,
|
||||||
|
setIsShow: setShowDimensionLineSettingModal,
|
||||||
|
}
|
||||||
|
|
||||||
const planSizeProps = {
|
const planSizeProps = {
|
||||||
id: planSizeId,
|
id: planSizeId,
|
||||||
horizon,
|
// horizon,
|
||||||
setHorizon,
|
// setHorizon,
|
||||||
vertical,
|
// vertical,
|
||||||
setVertical,
|
// setVertical,
|
||||||
|
horizon: planSizeSettingMode.originHorizon,
|
||||||
|
vertical: planSizeSettingMode.originVertical,
|
||||||
|
isShow: showPlanSizeSettingModal,
|
||||||
setIsShow: setShowPlanSizeSettingModal,
|
setIsShow: setShowPlanSizeSettingModal,
|
||||||
pos: { x: 1025, y: 180 },
|
pos: { x: 1025, y: 180 },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onClickOption = async (item) => {
|
||||||
|
//흡착범위 설정(단 건 선택)
|
||||||
|
if (
|
||||||
|
item.column === 'adsorpRangeSmall' ||
|
||||||
|
item.column === 'adsorpRangeSmallSemi' ||
|
||||||
|
item.column === 'adsorpRangeMedium' ||
|
||||||
|
item.column === 'adsorpRangeLarge'
|
||||||
|
) {
|
||||||
|
// 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
|
||||||
|
})
|
||||||
|
|
||||||
|
setSettingModalSecondOptions({ ...settingModalSecondOptions, option3, option4, fontFlag: true })
|
||||||
|
} else if (item === 'adsorpPoint') {
|
||||||
|
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: !adsorptionPointMode.adsorptionPoint, fontFlag: true })
|
||||||
|
}
|
||||||
|
//setAdsorptionRange(item.range) //사용여부 확인 필요
|
||||||
|
setAdsorptionRange(50)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="modal-check-btn-wrap">
|
<div className="modal-check-btn-wrap">
|
||||||
@ -184,12 +229,12 @@ export default function SecondOption() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="adsorption-point act"
|
className="adsorption-point act"
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
setAdsorptionPointMode(!adsorptionPointMode)
|
onClickOption('adsorpPoint')
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{getMessage('modal.canvas.setting.font.plan.absorption.point')}</span>
|
<span>{getMessage('modal.canvas.setting.font.plan.absorption.point')}</span>
|
||||||
<i>{adsorptionPointMode ? 'ON' : 'OFF'}</i>
|
<i>{adsorptionPointMode.adsorptionPoint ? 'ON' : 'OFF'}</i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -9,6 +9,28 @@ import { useMessage } from '@/hooks/useMessage'
|
|||||||
import { dimensionLineSettingsState } from '@/store/commonUtilsAtom'
|
import { dimensionLineSettingsState } from '@/store/commonUtilsAtom'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { globalFontAtom } from '@/store/fontAtom'
|
import { globalFontAtom } from '@/store/fontAtom'
|
||||||
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
|
|
||||||
|
const fonts = [
|
||||||
|
{ id: 1, name: 'MS PGothic', value: 'MS PGothic' },
|
||||||
|
{ id: 2, name: '@Yu Gothic', value: '@Yu Gothic' },
|
||||||
|
{ id: 3, name: 'Yu Gothic', value: 'Yu Gothic' },
|
||||||
|
{ id: 4, name: '@Yu Gothic UI', value: '@Yu Gothic UI' },
|
||||||
|
{ id: 5, name: 'Yu Gothic UI', value: 'Yu Gothic UI' },
|
||||||
|
//3,
|
||||||
|
]
|
||||||
|
|
||||||
|
const fontSizes = [
|
||||||
|
...Array.from({ length: 4 }).map((_, index) => {
|
||||||
|
return { id: index + 8, name: index + 8, value: index + 8 }
|
||||||
|
}),
|
||||||
|
...Array.from({ length: 9 }).map((_, index) => {
|
||||||
|
return { id: (index + 6) * 2, name: (index + 6) * 2, value: (index + 6) * 2 }
|
||||||
|
}),
|
||||||
|
{ id: 36, name: 36, value: 36 },
|
||||||
|
{ id: 48, name: 48, value: 48 },
|
||||||
|
{ id: 72, name: 72, value: 72 },
|
||||||
|
]
|
||||||
|
|
||||||
export default function DimensionLineSetting(props) {
|
export default function DimensionLineSetting(props) {
|
||||||
const { isShow, setIsShow, id, pos = { x: 985, y: 180 } } = props
|
const { isShow, setIsShow, id, pos = { x: 985, y: 180 } } = props
|
||||||
@ -16,28 +38,79 @@ export default function DimensionLineSetting(props) {
|
|||||||
const pixels = Array.from({ length: 5 }).map((_, index) => {
|
const pixels = Array.from({ length: 5 }).map((_, index) => {
|
||||||
return { id: index, name: index + 1, value: index + 1 }
|
return { id: index, name: index + 1, value: index + 1 }
|
||||||
})
|
})
|
||||||
const [dimensionLineSettings, setDimensionLineSettings] = useRecoilState(dimensionLineSettingsState)
|
//const [dimensionLineSettings, setDimensionLineSettings] = useRecoilState(dimensionLineSettingsState)
|
||||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
//const [originPixel, setOriginPixel] = useState(dimensionLineSettings.pixel)
|
||||||
const [originPixel, setOriginPixel] = useState(dimensionLineSettings.pixel)
|
//const [originColor, setOriginColor] = useState(dimensionLineSettings.color)
|
||||||
const [originColor, setOriginColor] = useState(dimensionLineSettings.color)
|
//const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||||
const [originFont, setOriginFont] = useState(globalFont.dimensionLineText.fontFamily)
|
|
||||||
const [originFontColor, setOriginFontColor] = useState(globalFont.dimensionLineText.fontColor)
|
|
||||||
const [originFontSize, setOriginFontSize] = useState(globalFont.dimensionLineText.fontSize)
|
|
||||||
const [originFontWeight, setOriginFontWeight] = useState(globalFont.dimensionLineText.fontWeight)
|
|
||||||
const [fontModalId, setFontModalId] = useState(uuidv4())
|
|
||||||
|
|
||||||
|
const [fontModalId, setFontModalId] = useState(uuidv4())
|
||||||
const [colorModalId, setColorModalId] = useState(uuidv4())
|
const [colorModalId, setColorModalId] = useState(uuidv4())
|
||||||
const [showColorPickerModal, setShowColorPickerModal] = useState(false)
|
const [showColorPickerModal, setShowColorPickerModal] = useState(false)
|
||||||
const [showFontModal, setShowFontModal] = useState(false)
|
const [showFontModal, setShowFontModal] = useState(false)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|
||||||
|
const { globalFont, setGlobalFont, dimensionLineSettings, setDimensionLineSettings } = useCanvasSetting()
|
||||||
|
|
||||||
|
const [originFont, setOriginFont] = useState(globalFont.dimensionLineText.fontFamily)
|
||||||
|
const [originFontWeight, setOriginFontWeight] = useState(globalFont.dimensionLineText.fontWeight)
|
||||||
|
const [originFontSize, setOriginFontSize] = useState(globalFont.dimensionLineText.fontSize)
|
||||||
|
const [originFontColor, setOriginFontColor] = useState(globalFont.dimensionLineText.fontColor)
|
||||||
|
|
||||||
|
const [originPixel, setOriginPixel] = useState(dimensionLineSettings.pixel)
|
||||||
|
const [originColor, setOriginColor] = useState(dimensionLineSettings.color)
|
||||||
|
|
||||||
|
const fontOptions = [
|
||||||
|
{ id: 'normal', name: getMessage('font.style.normal'), value: 'normal' },
|
||||||
|
{ id: 'italic', name: getMessage('font.style.italic'), value: 'italic' },
|
||||||
|
{ id: 'bold', name: getMessage('font.style.bold'), value: 'bold' },
|
||||||
|
{ id: 'boldAndItalic', name: getMessage('font.style.bold.italic'), value: 'boldAndItalic' },
|
||||||
|
]
|
||||||
|
const fontColors = [
|
||||||
|
{ id: 'black', name: getMessage('color.black'), value: 'black' },
|
||||||
|
{ id: 'red', name: getMessage('color.red'), value: 'red' },
|
||||||
|
{ id: 'blue', name: getMessage('color.blue'), value: 'blue' },
|
||||||
|
{ id: 'gray', name: getMessage('color.gray'), value: 'gray' },
|
||||||
|
{ id: 'yellow', name: getMessage('color.yellow'), value: 'yellow' },
|
||||||
|
{ id: 'green', name: getMessage('color.green'), value: 'green' },
|
||||||
|
{ id: 'pink', name: getMessage('color.pink'), value: 'pink' },
|
||||||
|
{ id: 'gold', name: getMessage('color.gold'), value: 'gold' },
|
||||||
|
{ id: 'darkblue', name: getMessage('color.darkblue'), value: 'darkblue' },
|
||||||
|
]
|
||||||
|
|
||||||
|
let originPixelView
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (originPixel) {
|
if (originPixel) {
|
||||||
setOriginPixel(pixels?.filter((data) => data.value === originPixel)[0])
|
setOriginPixel(pixels?.filter((data) => data.value === originPixel)[0])
|
||||||
|
originPixelView = originPixel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (globalFont.dimensionLineText.fontFamily) {
|
||||||
|
setOriginFont(fonts.filter((data) => data.value === globalFont.dimensionLineText.fontFamily)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalFont.dimensionLineText.fontWeight) {
|
||||||
|
setOriginFontWeight(fontOptions.filter((data) => data.value === globalFont.dimensionLineText.fontWeight)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalFont.dimensionLineText.fontSize) {
|
||||||
|
setOriginFontSize(fontSizes.filter((data) => data.value === globalFont.dimensionLineText.fontSize)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalFont.dimensionLineText.fontColor) {
|
||||||
|
setOriginFontColor(fontColors.filter((data) => data.value === globalFont.dimensionLineText.fontColor)[0])
|
||||||
|
}
|
||||||
|
|
||||||
setIsShow(true)
|
setIsShow(true)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (originPixel.name) {
|
||||||
|
originPixelView = originPixel.name
|
||||||
|
setOriginPixel(originPixel)
|
||||||
|
}
|
||||||
|
}, [originPixel])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isShow) {
|
if (!isShow) {
|
||||||
closePopups([fontModalId, colorModalId])
|
closePopups([fontModalId, colorModalId])
|
||||||
@ -46,9 +119,9 @@ export default function DimensionLineSetting(props) {
|
|||||||
|
|
||||||
const handleFontSave = (font) => {
|
const handleFontSave = (font) => {
|
||||||
setOriginFont(font.fontFamily)
|
setOriginFont(font.fontFamily)
|
||||||
|
setOriginFontWeight(font.fontWeight)
|
||||||
setOriginFontSize(font.fontSize)
|
setOriginFontSize(font.fontSize)
|
||||||
setOriginFontColor(font.fontColor)
|
setOriginFontColor(font.fontColor)
|
||||||
setOriginFontWeight(font.fontWeight)
|
|
||||||
}
|
}
|
||||||
const handleColorSave = () => {}
|
const handleColorSave = () => {}
|
||||||
|
|
||||||
@ -69,10 +142,10 @@ export default function DimensionLineSetting(props) {
|
|||||||
isShow: showFontModal,
|
isShow: showFontModal,
|
||||||
setIsShow: setShowFontModal,
|
setIsShow: setShowFontModal,
|
||||||
font: {
|
font: {
|
||||||
fontFamily: originFont,
|
fontFamily: originFont?.value,
|
||||||
fontSize: originFontSize,
|
fontWeight: originFontWeight?.value,
|
||||||
fontColor: originFontColor,
|
fontSize: originFontSize?.value,
|
||||||
fontWeight: originFontWeight,
|
fontColor: originFontColor?.value,
|
||||||
},
|
},
|
||||||
onSave: handleFontSave,
|
onSave: handleFontSave,
|
||||||
isConfig: true,
|
isConfig: true,
|
||||||
@ -99,17 +172,18 @@ export default function DimensionLineSetting(props) {
|
|||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
dimensionLineText: {
|
dimensionLineText: {
|
||||||
fontFamily: originFont,
|
fontFamily: originFont.value,
|
||||||
fontWeight: originFontWeight,
|
fontWeight: originFontWeight.value,
|
||||||
fontSize: originFontSize,
|
fontSize: originFontSize.value,
|
||||||
fontColor: originFontColor,
|
fontColor: originFontColor.value,
|
||||||
},
|
},
|
||||||
|
fontFlag: true,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setDimensionLineSettings((prev) => {
|
setDimensionLineSettings((prev) => {
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
pixel: originPixel?.value,
|
pixel: originPixel.name,
|
||||||
color: originColor,
|
color: originColor,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -125,8 +199,8 @@ export default function DimensionLineSetting(props) {
|
|||||||
<button
|
<button
|
||||||
className="modal-close"
|
className="modal-close"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
closePopups([fontModalId, colorModalId, id])
|
|
||||||
setIsShow(false)
|
setIsShow(false)
|
||||||
|
closePopups([fontModalId, colorModalId, id])
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
닫기
|
닫기
|
||||||
@ -160,10 +234,10 @@ export default function DimensionLineSetting(props) {
|
|||||||
className="font"
|
className="font"
|
||||||
style={{
|
style={{
|
||||||
fontFamily: originFont?.value ?? '',
|
fontFamily: originFont?.value ?? '',
|
||||||
color: originFontColor.value ?? 'black',
|
fontWeight: originFontWeight?.value?.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
||||||
|
fontStyle: originFontWeight?.value?.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||||
fontSize: originFontSize?.value ?? '12px',
|
fontSize: originFontSize?.value ?? '12px',
|
||||||
fontStyle: originFontWeight?.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
color: originFontColor?.value ?? 'black',
|
||||||
fontWeight: originFontWeight?.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
9,999
|
9,999
|
||||||
@ -173,7 +247,7 @@ export default function DimensionLineSetting(props) {
|
|||||||
style={{
|
style={{
|
||||||
backgroundColor: originColor,
|
backgroundColor: originColor,
|
||||||
borderColor: originColor,
|
borderColor: originColor,
|
||||||
height: originPixel?.value,
|
height: originPixel.name,
|
||||||
}}
|
}}
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,18 +1,64 @@
|
|||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
|
import { onlyNumberInputChange } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function PlanSizeSetting(props) {
|
export default function PlanSizeSetting(props) {
|
||||||
const { horizon, setHorizon, vertical, setVertical, id, pos = { x: 985, y: 180 }, setIsShow } = props
|
const { setIsShow, horizon, vertical, id, pos = { x: 985, y: 180 } } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const [originHorizon, setOriginHorizon] = useState(horizon)
|
|
||||||
const [originVertical, setOriginVertical] = useState(vertical)
|
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
|
||||||
|
// const [originHorizon, setOriginHorizon] = useCanvasSetting(horizon)
|
||||||
|
// const [originVertical, setOriginVertical] = useCanvasSetting(vertical)
|
||||||
|
// const { originHorizon, setOriginHorizon, originVertical, setOriginVertical } = useCanvasSetting()
|
||||||
|
const { planSizeSettingMode, setPlanSizeSettingMode } = useCanvasSetting()
|
||||||
|
|
||||||
|
// 데이터를 최초 한 번만 조회
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('PlanSizeSetting useEffect 실행')
|
||||||
|
console.log('11111', planSizeSettingMode)
|
||||||
|
//setOriginHorizon({ originHorizon: horizon, flag: false })
|
||||||
|
//setOriginVertical({ originVertical: vertical, flag: false })
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const onSave = () => {
|
||||||
|
console.log('22222', planSizeSettingMode)
|
||||||
|
setPlanSizeSettingMode((prev) => {
|
||||||
|
console.log('4', prev)
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
originHorizon: planSizeSettingMode.originHorizon,
|
||||||
|
originVertical: planSizeSettingMode.originVertical,
|
||||||
|
flag: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.setWidth(planSizeSettingMode.originHorizon)
|
||||||
|
canvas.setHeight(planSizeSettingMode.originVertical)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
setIsShow(false)
|
||||||
|
closePopup(id, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeInput = (value, e) => {
|
||||||
|
const { name } = e.target
|
||||||
|
console.log('name', name, value)
|
||||||
|
setPlanSizeSettingMode((prev) => {
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
[name]: value,
|
||||||
|
flag: false,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap xsm mount`}>
|
<div className={`modal-pop-wrap xsm mount`}>
|
||||||
@ -33,7 +79,15 @@ export default function PlanSizeSetting(props) {
|
|||||||
<div className="outline-form mb10">
|
<div className="outline-form mb10">
|
||||||
<span style={{ width: 'auto' }}>{getMessage('common.horizon')}</span>
|
<span style={{ width: 'auto' }}>{getMessage('common.horizon')}</span>
|
||||||
<div className="input-grid mr5" style={{ width: '90px' }}>
|
<div className="input-grid mr5" style={{ width: '90px' }}>
|
||||||
<input type="text" className="input-origin block" value={originHorizon} onChange={(e) => setOriginHorizon(Number(e.target.value))} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
name={`originHorizon`}
|
||||||
|
value={planSizeSettingMode.originHorizon}
|
||||||
|
//onChange={(e) => setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: Number(e.target.value), flag: false })}
|
||||||
|
//onFocus={(e) => (originHorizon.current.value = '')}
|
||||||
|
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -43,26 +97,18 @@ export default function PlanSizeSetting(props) {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={originVertical}
|
name={`originVertical`}
|
||||||
onChange={(e) => setOriginVertical(Number(e.target.value))}
|
value={planSizeSettingMode.originVertical}
|
||||||
|
//onChange={(e) => setPlanSizeSettingMode({ ...planSizeSettingMode, originVertical: Number(e.target.value), flag: false })}
|
||||||
|
//onFocus={(e) => (originVertical.current.value = '')}
|
||||||
|
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button
|
<button className="btn-frame modal act" onClick={onSave}>
|
||||||
className="btn-frame modal act"
|
|
||||||
onClick={() => {
|
|
||||||
setHorizon(originHorizon)
|
|
||||||
setVertical(originVertical)
|
|
||||||
setIsShow(false)
|
|
||||||
closePopup(id)
|
|
||||||
canvas.setWidth(originHorizon)
|
|
||||||
canvas.setHeight(originVertical)
|
|
||||||
canvas.renderAll()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{getMessage('modal.common.save')}
|
{getMessage('modal.common.save')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export function useFont() {
|
|||||||
const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText'))
|
const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText'))
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas) {
|
if (canvas && commonText.fontWeight?.value) {
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'commonText')
|
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'commonText')
|
||||||
textObjs.forEach((obj) => {
|
textObjs.forEach((obj) => {
|
||||||
obj.set({
|
obj.set({
|
||||||
@ -28,7 +28,7 @@ export function useFont() {
|
|||||||
}, [commonText])
|
}, [commonText])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas) {
|
if (canvas && dimensionLineText.fontWeight?.value) {
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'dimensionLineText')
|
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'dimensionLineText')
|
||||||
textObjs.forEach((obj) => {
|
textObjs.forEach((obj) => {
|
||||||
obj.set({
|
obj.set({
|
||||||
@ -44,8 +44,8 @@ export function useFont() {
|
|||||||
}, [dimensionLineText])
|
}, [dimensionLineText])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas) {
|
if (canvas && flowText.fontWeight?.value) {
|
||||||
const textObjs = canvas.getObjects().filter((obj) => obj.name === 'flowText')
|
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'flowText')
|
||||||
textObjs.forEach((obj) => {
|
textObjs.forEach((obj) => {
|
||||||
obj.set({
|
obj.set({
|
||||||
fontFamily: flowText.fontFamily.value,
|
fontFamily: flowText.fontFamily.value,
|
||||||
@ -60,8 +60,8 @@ export function useFont() {
|
|||||||
}, [flowText])
|
}, [flowText])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas) {
|
if (canvas && lengthText.fontWeight?.value) {
|
||||||
const textObjs = canvas.getObjects().filter((obj) => obj.name === 'lengthText')
|
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'lengthText')
|
||||||
textObjs.forEach((obj) => {
|
textObjs.forEach((obj) => {
|
||||||
obj.set({
|
obj.set({
|
||||||
fontFamily: lengthText.fontFamily.value,
|
fontFamily: lengthText.fontFamily.value,
|
||||||
|
|||||||
@ -80,7 +80,7 @@ export const useEstimateController = (planNo) => {
|
|||||||
itemId: '', //제품번호
|
itemId: '', //제품번호
|
||||||
itemNo: '',
|
itemNo: '',
|
||||||
itemName: '', //형명
|
itemName: '', //형명
|
||||||
amount: '', //수량
|
amount: '0', //수량
|
||||||
unitPrice: '0',
|
unitPrice: '0',
|
||||||
unit: '', //단위
|
unit: '', //단위
|
||||||
salePrice: '', //단가
|
salePrice: '', //단가
|
||||||
@ -185,13 +185,14 @@ export const useEstimateController = (planNo) => {
|
|||||||
return alert(getMessage('estimate.detail.save.requiredItem'))
|
return alert(getMessage('estimate.detail.save.requiredItem'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('최종 아이템 정보::;', estimateData.itemList)
|
||||||
estimateData.itemList.map((item) => {
|
estimateData.itemList.map((item) => {
|
||||||
item.amount = item.amount.replaceAll(',', '')
|
item.amount = item.amount?.replaceAll(',', '')
|
||||||
item.salePrice = parseFloat(item.salePrice.replaceAll(',', '')).toFixed(2)
|
item.salePrice = parseFloat(item.salePrice?.replaceAll(',', '')).toFixed(2)
|
||||||
item.saleTotPrice = parseFloat(item.saleTotPrice.replaceAll(',', '')).toFixed(2)
|
item.saleTotPrice = parseFloat(item.saleTotPrice?.replaceAll(',', '')).toFixed(2)
|
||||||
})
|
})
|
||||||
console.log('최종 정보::;', estimateData)
|
|
||||||
|
|
||||||
|
console.log('최종 정보::;', estimateData)
|
||||||
//2. 상세데이터 저장
|
//2. 상세데이터 저장
|
||||||
// return
|
// return
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { rectToPolygon, setSurfaceShapePattern } from '@/util/canvas-util'
|
|||||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
import { roofDisplaySelector } from '@/store/settingAtom'
|
||||||
import offsetPolygon from '@/util/qpolygon-utils'
|
import offsetPolygon from '@/util/qpolygon-utils'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom'
|
import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common'
|
import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common'
|
||||||
@ -53,6 +54,11 @@ export function useModuleBasicSetting() {
|
|||||||
setupSurface.setViewLengthText(false)
|
setupSurface.setViewLengthText(false)
|
||||||
|
|
||||||
canvas.add(setupSurface)
|
canvas.add(setupSurface)
|
||||||
|
bottomModuleLine(setupSurface)
|
||||||
|
topModuleLine(setupSurface)
|
||||||
|
leftModuleLine(setupSurface)
|
||||||
|
// rightModuleLine(setupSurface)
|
||||||
|
|
||||||
//지붕면 선택 금지
|
//지붕면 선택 금지
|
||||||
roof.set({
|
roof.set({
|
||||||
selectable: false,
|
selectable: false,
|
||||||
@ -597,7 +603,7 @@ export function useModuleBasicSetting() {
|
|||||||
name: 'module',
|
name: 'module',
|
||||||
})
|
})
|
||||||
tempModule.setViewLengthText(false)
|
tempModule.setViewLengthText(false)
|
||||||
canvas?.add(tempModule)
|
// canvas?.add(tempModule)
|
||||||
moduleSetupArray.push(tempModule)
|
moduleSetupArray.push(tempModule)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -617,7 +623,7 @@ export function useModuleBasicSetting() {
|
|||||||
lineRow: row,
|
lineRow: row,
|
||||||
name: 'module',
|
name: 'module',
|
||||||
})
|
})
|
||||||
canvas?.add(tempModule)
|
// canvas?.add(tempModule)
|
||||||
moduleSetupArray.push(tempModule)
|
moduleSetupArray.push(tempModule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -765,41 +771,417 @@ export function useModuleBasicSetting() {
|
|||||||
return hull
|
return hull
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcMinXByHeightDistance = (nowSurface, index, reverse) => {
|
const bottomModuleLine = (nowSurface) => {
|
||||||
function calculateSlopeIntercept(x1, y1, x2, y2) {
|
let selectedLine = null
|
||||||
console.log('Intercept', x1, y1, x2, y2)
|
|
||||||
|
|
||||||
const slope = (y2 - y1) / (x2 - x1)
|
const sortedLines = sortLinesByTopLeft(nowSurface.lines)
|
||||||
const intercept = y1 - slope * x1
|
|
||||||
|
|
||||||
return { slope, intercept }
|
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
|
||||||
|
|
||||||
|
// if (nowSurface.flowDirection === 'east') {
|
||||||
|
// const leftFlow = nowSurface.lines.reduce(
|
||||||
|
// (acc, line, index) => {
|
||||||
|
// if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
|
||||||
|
// return { x1: line.x1, y1: line.y1, index: index }
|
||||||
|
// }
|
||||||
|
// return acc
|
||||||
|
// },
|
||||||
|
// { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
// )
|
||||||
|
// selectedLine = leftFlow
|
||||||
|
// } else if (nowSurface.flowDirection === 'west') {
|
||||||
|
// const rightFlow = nowSurface.lines.reduce(
|
||||||
|
// (acc, line, index) => {
|
||||||
|
// if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) {
|
||||||
|
// return { x1: line.x1, y1: line.y1, index: index }
|
||||||
|
// }
|
||||||
|
// return acc
|
||||||
|
// },
|
||||||
|
// { x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
// )
|
||||||
|
// selectedLine = rightFlow
|
||||||
|
// } else if (nowSurface.flowDirection === 'north') {
|
||||||
|
// const topFlow = nowSurface.lines.reduce(
|
||||||
|
// (acc, line, index) => {
|
||||||
|
// if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
|
||||||
|
// return { x1: line.x1, y1: line.y1, index: index }
|
||||||
|
// }
|
||||||
|
// return acc
|
||||||
|
// },
|
||||||
|
// { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
// )
|
||||||
|
// selectedLine = topFlow
|
||||||
|
// } else {
|
||||||
|
const bottomFlow = nowSurface.lines.reduce(
|
||||||
|
(acc, line, index) => {
|
||||||
|
if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.x1 > acc.x1)) {
|
||||||
|
return { x1: line.x1, y1: line.y1, index: index }
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{ x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
)
|
||||||
|
selectedLine = bottomFlow
|
||||||
|
// }
|
||||||
|
|
||||||
|
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
||||||
|
let nextLines = nowSurface.lines[selectedLine.index]
|
||||||
|
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
|
||||||
|
|
||||||
|
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
|
||||||
|
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
|
||||||
|
|
||||||
|
const c1 = prevLines.y1 - m1 * prevLines.x1
|
||||||
|
const c2 = nextLines.y1 - m2 * nextLines.x1
|
||||||
|
|
||||||
|
// Step 2: Calculate intersection point
|
||||||
|
|
||||||
|
let xIntersectPrev = 0
|
||||||
|
let yIntersectPrev = 0
|
||||||
|
let xIntersectNext = 0
|
||||||
|
let yIntersectNext = 0
|
||||||
|
|
||||||
|
let endPoint = prevLines.y1 > nextLines.y2 ? prevLines.y1 : nextLines.y2
|
||||||
|
let biggerEndPoint = prevLines.y1 > nextLines.y2 ? 'left' : 'right'
|
||||||
|
|
||||||
|
//bottom일 경우
|
||||||
|
xIntersectPrev = (endPoint - c1) / m1
|
||||||
|
yIntersectPrev = m1 * xIntersectPrev + c1
|
||||||
|
xIntersectNext = (endPoint - c2) / m2
|
||||||
|
yIntersectNext = m2 * xIntersectNext + c2
|
||||||
|
|
||||||
|
let lineCoords
|
||||||
|
let polygonCoords
|
||||||
|
let ratio = 1
|
||||||
|
if (biggerEndPoint === 'left') {
|
||||||
|
//왼쪽이 더 밑이면 우측 라인에 절편으로 계산
|
||||||
|
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
|
||||||
|
polygonCoords = [
|
||||||
|
{ x: prevLines.x1, y: yIntersectNext },
|
||||||
|
{ x: xIntersectNext, y: yIntersectNext },
|
||||||
|
{ x: overlapCoords.x, y: overlapCoords.y },
|
||||||
|
]
|
||||||
|
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
|
||||||
|
} else {
|
||||||
|
lineCoords = [xIntersectPrev, yIntersectPrev, nextLines.x2, yIntersectPrev]
|
||||||
|
polygonCoords = [
|
||||||
|
{ x: xIntersectPrev, y: yIntersectPrev },
|
||||||
|
{ x: nextLines.x2, y: yIntersectPrev },
|
||||||
|
{ x: overlapCoords.x, y: overlapCoords.y },
|
||||||
|
]
|
||||||
|
ratio = moduleWidthLength / Math.abs(nextLines.x2 - xIntersectPrev)
|
||||||
}
|
}
|
||||||
|
|
||||||
let prevLines = nowSurface.lines[(index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
const tempTriangle = new QPolygon(polygonCoords, {
|
||||||
let nextLines = nowSurface.lines[index]
|
fill: 'transparent',
|
||||||
|
stroke: 'green',
|
||||||
|
strokeWidth: 2,
|
||||||
|
originY: 'bottom',
|
||||||
|
strokeDashArray: [5, 5],
|
||||||
|
// fontSize: 15,
|
||||||
|
})
|
||||||
|
|
||||||
// 선분 정보
|
// canvas.add(tempTriangle)
|
||||||
const l1 = prevLines
|
|
||||||
const l2 = nextLines
|
|
||||||
const lineLength = 172.2
|
|
||||||
|
|
||||||
// l1과 l2의 기울기 및 절편
|
let cloneCoords = []
|
||||||
let { slope: m1, intercept: b1 } = calculateSlopeIntercept(l1.x1, l1.y1, l1.x2, l1.y2)
|
tempTriangle.clone((clone) => {
|
||||||
let { slope: m2, intercept: b2 } = calculateSlopeIntercept(l2.x1, l2.y1, l2.x2, l2.y2)
|
clone.scale(ratio)
|
||||||
|
cloneCoords = clone.getCurrentPoints()
|
||||||
|
})
|
||||||
|
|
||||||
console.log(m1, b1, m2, b2)
|
//아래쪽에선 잴 작은
|
||||||
|
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['y'] > point['y'] ? acc : point))
|
||||||
|
|
||||||
// 가로선 x1 계산
|
const differenceDistance = overlapCoords.x - vertexPoints.x
|
||||||
const x1 = (m2 * lineLength + b2 - b1) / (m1 - m2)
|
|
||||||
const x2 = x1 + lineLength // 끝점 x2
|
|
||||||
|
|
||||||
// 가로선 y값 계산
|
const newTriangleCoords = cloneCoords.map((point) => {
|
||||||
const y0 = m1 * x1 + b1
|
return { x: point.x + differenceDistance, y: point.y }
|
||||||
|
})
|
||||||
|
|
||||||
// 결과 출력
|
const deleteBottomPoint = newTriangleCoords.reduce((acc, point) => (acc['y'] > point['y'] ? acc : point))
|
||||||
|
const deleteIndex = newTriangleCoords.indexOf(deleteBottomPoint)
|
||||||
|
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
|
||||||
|
|
||||||
console.log({ x1: x1, y1: y0, x2: x2, y2: y0 })
|
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
|
||||||
return { x1: x1, y1: y0, x2: x2, y2: y0 }
|
fill: 'transparent',
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: 14,
|
||||||
|
})
|
||||||
|
canvas.add(newLine)
|
||||||
|
return newLine
|
||||||
|
}
|
||||||
|
|
||||||
|
const topModuleLine = (nowSurface) => {
|
||||||
|
let selectedLine = null
|
||||||
|
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
|
||||||
|
|
||||||
|
const topFlow = nowSurface.lines.reduce(
|
||||||
|
(acc, line, index) => {
|
||||||
|
if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
|
||||||
|
return { x1: line.x1, y1: line.y1, index: index }
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
)
|
||||||
|
selectedLine = topFlow
|
||||||
|
|
||||||
|
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
||||||
|
let nextLines = nowSurface.lines[selectedLine.index]
|
||||||
|
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
|
||||||
|
|
||||||
|
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
|
||||||
|
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
|
||||||
|
|
||||||
|
const c1 = prevLines.y1 - m1 * prevLines.x1
|
||||||
|
const c2 = nextLines.y1 - m2 * nextLines.x1
|
||||||
|
|
||||||
|
// Step 2: Calculate intersection point
|
||||||
|
|
||||||
|
let xIntersectPrev = 0
|
||||||
|
let yIntersectPrev = 0
|
||||||
|
let xIntersectNext = 0
|
||||||
|
let yIntersectNext = 0
|
||||||
|
|
||||||
|
let endPoint = prevLines.y1 > nextLines.y2 ? nextLines.y2 : prevLines.y1
|
||||||
|
let biggerEndPoint = prevLines.y1 < nextLines.y2 ? 'left' : 'right'
|
||||||
|
|
||||||
|
//bottom일 경우
|
||||||
|
xIntersectPrev = (endPoint - c1) / m1
|
||||||
|
yIntersectPrev = m1 * xIntersectPrev + c1
|
||||||
|
xIntersectNext = (endPoint - c2) / m2
|
||||||
|
yIntersectNext = m2 * xIntersectNext + c2
|
||||||
|
|
||||||
|
let lineCoords
|
||||||
|
let polygonCoords
|
||||||
|
let ratio = 1
|
||||||
|
|
||||||
|
if (biggerEndPoint === 'left') {
|
||||||
|
//왼쪽이 더 밑이면 우측 라인에 절편으로 계산
|
||||||
|
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
|
||||||
|
polygonCoords = [
|
||||||
|
{ x: prevLines.x1, y: yIntersectNext },
|
||||||
|
{ x: xIntersectNext, y: yIntersectNext },
|
||||||
|
{ x: overlapCoords.x, y: overlapCoords.y },
|
||||||
|
]
|
||||||
|
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
|
||||||
|
} else {
|
||||||
|
lineCoords = [xIntersectPrev, yIntersectPrev, nextLines.x2, yIntersectPrev]
|
||||||
|
polygonCoords = [
|
||||||
|
{ x: xIntersectPrev, y: yIntersectPrev },
|
||||||
|
{ x: nextLines.x2, y: yIntersectPrev },
|
||||||
|
{ x: overlapCoords.x, y: overlapCoords.y },
|
||||||
|
]
|
||||||
|
ratio = moduleWidthLength / Math.abs(nextLines.x2 - xIntersectPrev)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempTriangle = new QPolygon(polygonCoords, {
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'green',
|
||||||
|
strokeWidth: 2,
|
||||||
|
originY: 'top',
|
||||||
|
strokeDashArray: [5, 5],
|
||||||
|
// fontSize: 15,
|
||||||
|
})
|
||||||
|
|
||||||
|
// canvas.add(tempTriangle)
|
||||||
|
|
||||||
|
let cloneCoords = []
|
||||||
|
tempTriangle.clone((clone) => {
|
||||||
|
clone.scale(ratio)
|
||||||
|
cloneCoords = clone.getCurrentPoints()
|
||||||
|
})
|
||||||
|
|
||||||
|
//아래쪽에선 잴 작은
|
||||||
|
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['y'] < point['y'] ? acc : point))
|
||||||
|
|
||||||
|
const differenceDistance = overlapCoords.x - vertexPoints.x
|
||||||
|
|
||||||
|
const newTriangleCoords = cloneCoords.map((point) => {
|
||||||
|
return { x: point.x + differenceDistance, y: point.y }
|
||||||
|
})
|
||||||
|
|
||||||
|
// const newTriangle1 = new QPolygon(newTriangleCoords, {
|
||||||
|
// fill: 'transparent',
|
||||||
|
// stroke: 'red',
|
||||||
|
// strokeWidth: 1,
|
||||||
|
// selectable: true,
|
||||||
|
// fontSize: 14,
|
||||||
|
// })
|
||||||
|
// canvas.add(newTriangle1)
|
||||||
|
|
||||||
|
const deleteBottomPoint = newTriangleCoords.reduce((acc, point) => (acc['y'] < point['y'] ? acc : point))
|
||||||
|
const deleteIndex = newTriangleCoords.indexOf(deleteBottomPoint)
|
||||||
|
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
|
||||||
|
|
||||||
|
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 2,
|
||||||
|
selectable: true,
|
||||||
|
fontSize: 14,
|
||||||
|
})
|
||||||
|
canvas.add(newLine)
|
||||||
|
return newLine
|
||||||
|
}
|
||||||
|
|
||||||
|
const leftModuleLine = (nowSurface) => {
|
||||||
|
let selectedLine = null
|
||||||
|
|
||||||
|
sortLinesByTopLeft(nowSurface)
|
||||||
|
|
||||||
|
console.log('nowSurface', nowSurface)
|
||||||
|
|
||||||
|
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
|
||||||
|
|
||||||
|
const leftFlow = nowSurface.lines.reduce(
|
||||||
|
(acc, line, index) => {
|
||||||
|
if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
|
||||||
|
return { x1: line.x1, y1: line.y1, index: index }
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
)
|
||||||
|
selectedLine = leftFlow
|
||||||
|
|
||||||
|
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
||||||
|
let nextLines = nowSurface.lines[selectedLine.index]
|
||||||
|
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
|
||||||
|
|
||||||
|
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
|
||||||
|
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
|
||||||
|
|
||||||
|
const c1 = prevLines.y1 - m1 * prevLines.x1
|
||||||
|
const c2 = nextLines.y1 - m2 * nextLines.x1
|
||||||
|
|
||||||
|
// Step 2: Calculate intersection point
|
||||||
|
|
||||||
|
let xIntersectPrev = 0
|
||||||
|
let yIntersectPrev = 0
|
||||||
|
let xIntersectNext = 0
|
||||||
|
let yIntersectNext = 0
|
||||||
|
|
||||||
|
let biggerEndPoint = prevLines.x1 > nextLines.x2 ? 'top' : 'bottom'
|
||||||
|
console.log('prevLines.x1', prevLines.x1)
|
||||||
|
console.log('nextLines.x2', nextLines.x2)
|
||||||
|
console.log('biggerEndPoint', biggerEndPoint)
|
||||||
|
|
||||||
|
//bottom일 경우
|
||||||
|
xIntersectPrev = prevLines.x1
|
||||||
|
yIntersectPrev = m1 * xIntersectPrev + c1
|
||||||
|
xIntersectNext = prevLines.x1
|
||||||
|
yIntersectNext = m2 * xIntersectNext + c2
|
||||||
|
|
||||||
|
let lineCoords
|
||||||
|
let polygonCoords
|
||||||
|
let ratio = 1
|
||||||
|
|
||||||
|
if (biggerEndPoint === 'top') {
|
||||||
|
//윗쪽이이 더 밑이면 아래 라인에 절편으로 계산
|
||||||
|
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
|
||||||
|
polygonCoords = [
|
||||||
|
{ x: prevLines.x1, y: yIntersectNext },
|
||||||
|
{ x: xIntersectNext, y: yIntersectNext },
|
||||||
|
{ x: overlapCoords.x, y: overlapCoords.y },
|
||||||
|
]
|
||||||
|
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
|
||||||
|
} else {
|
||||||
|
lineCoords = [xIntersectPrev, prevLines.y1, xIntersectPrev, yIntersectPrev]
|
||||||
|
polygonCoords = [
|
||||||
|
{ x: xIntersectNext, y: prevLines.y1 },
|
||||||
|
{ x: xIntersectNext, y: yIntersectNext },
|
||||||
|
{ x: overlapCoords.x, y: overlapCoords.y },
|
||||||
|
]
|
||||||
|
ratio = moduleWidthLength / Math.abs(prevLines.y1 - yIntersectNext)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempTriangle = new QPolygon(polygonCoords, {
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'green',
|
||||||
|
strokeWidth: 2,
|
||||||
|
originX: 'left',
|
||||||
|
strokeDashArray: [5, 5],
|
||||||
|
// fontSize: 15,
|
||||||
|
selectable: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// canvas.add(tempTriangle)
|
||||||
|
|
||||||
|
let cloneCoords = []
|
||||||
|
tempTriangle.clone((clone) => {
|
||||||
|
clone.scale(ratio)
|
||||||
|
cloneCoords = clone.getCurrentPoints()
|
||||||
|
// canvas.add(clone)
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.remove(tempTriangle)
|
||||||
|
|
||||||
|
//left에선 가장 왼쪽
|
||||||
|
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['x'] < point['x'] ? acc : point))
|
||||||
|
const differenceDistance = overlapCoords.y - vertexPoints.y
|
||||||
|
|
||||||
|
const newTriangleCoords = cloneCoords.map((point) => {
|
||||||
|
return { x: point.x, y: point.y + differenceDistance }
|
||||||
|
})
|
||||||
|
|
||||||
|
// const newTriangle1 = new QPolygon(newTriangleCoords, {
|
||||||
|
// fill: 'transparent',
|
||||||
|
// stroke: 'red',
|
||||||
|
// strokeWidth: 1,
|
||||||
|
// selectable: true,
|
||||||
|
// fontSize: 14,
|
||||||
|
// })
|
||||||
|
// canvas.add(newTriangle1)
|
||||||
|
|
||||||
|
const deleteLeftPoint = newTriangleCoords.reduce((acc, point) => (acc['x'] < point['x'] ? acc : point))
|
||||||
|
const deleteIndex = newTriangleCoords.indexOf(deleteLeftPoint)
|
||||||
|
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
|
||||||
|
|
||||||
|
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
|
||||||
|
fill: 'transparent',
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 2,
|
||||||
|
viewLengthText: false,
|
||||||
|
// selectable: true,
|
||||||
|
fontSize: 14,
|
||||||
|
})
|
||||||
|
canvas.add(newLine)
|
||||||
|
return newLine
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortLinesByTopLeft(surface) {
|
||||||
|
// 좌측 상단 기준으로 정렬
|
||||||
|
const sortedLines = surface.lines.sort((a, b) => {
|
||||||
|
// x1, y1 값을 기준으로 정렬
|
||||||
|
if (a.x1 !== b.x1) {
|
||||||
|
return a.x1 - b.x1 // x1 기준 정렬
|
||||||
|
} else {
|
||||||
|
return a.y1 - b.y1 // x1이 같으면 y1 기준 정렬
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 정렬된 결과를 기반으로 좌표 재정렬
|
||||||
|
sortedLines.forEach((line) => {
|
||||||
|
// 좌측 상단이 (0,0) 기준이 되도록 좌표 이동
|
||||||
|
const minX = Math.min(line.x1, line.x2)
|
||||||
|
const minY = Math.min(line.y1, line.y2)
|
||||||
|
|
||||||
|
line.set({
|
||||||
|
x1: line.x1 - minX,
|
||||||
|
y1: line.y1 - minY,
|
||||||
|
x2: line.x2 - minX,
|
||||||
|
y2: line.y2 - minY,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
surface.set({
|
||||||
|
sortedLines: sortedLines,
|
||||||
|
})
|
||||||
|
|
||||||
|
return sortedLines
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,16 +1,22 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { adsorptionPointModeState, adsorptionRangeState, canvasState } from '@/store/canvasAtom'
|
import { adsorptionPointModeState, adsorptionRangeState, canvasState, planSizeSettingState } from '@/store/canvasAtom'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { corridorDimensionSelector, settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
|
import { correntObjectNoState, corridorDimensionSelector, settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
|
||||||
import { setSurfaceShapePattern } from '@/util/canvas-util'
|
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
||||||
|
import { dimensionLineSettingsState } from '@/store/commonUtilsAtom'
|
||||||
|
|
||||||
|
let objectNo
|
||||||
|
|
||||||
export function useCanvasSetting() {
|
export function useCanvasSetting() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
// canvas가 null이 아닐 때에만 getObjects 호출
|
||||||
|
const canvasObjects = canvas ? canvas.getObjects() : []
|
||||||
|
const [correntObjectNo, setCorrentObjectNo] = useRecoilState(correntObjectNoState)
|
||||||
|
|
||||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
||||||
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
||||||
@ -25,9 +31,21 @@ export function useCanvasSetting() {
|
|||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
|
|
||||||
const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState)
|
const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState)
|
||||||
const setAdsorptionRange = useSetRecoilState(adsorptionRangeState)
|
const [adsorptionRange, setAdsorptionRange] = useRecoilState(adsorptionRangeState)
|
||||||
|
const [planSizeSettingMode, setPlanSizeSettingMode] = useRecoilState(adsorptionRangeState)
|
||||||
|
//const setAdsorptionRange = useSetRecoilState(adsorptionRangeState)
|
||||||
|
|
||||||
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
const [selectedFont, setSelectedFont] = useState()
|
||||||
|
const [selectedFontWeight, setSelectedFontWeight] = useState()
|
||||||
|
const [selectedFontSize, setSelectedFontSize] = useState()
|
||||||
|
const [selectedFontColor, setSelectedFontColor] = useState()
|
||||||
|
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||||
|
//const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
||||||
|
|
||||||
|
const [dimensionLineSettings, setDimensionLineSettings] = useRecoilState(dimensionLineSettingsState)
|
||||||
|
|
||||||
|
//const [originHorizon, setOriginHorizon] = useState({ originHorizon: 1600, flag: false })
|
||||||
|
//const [originVertical, setOriginVertical] = useState({ originVertical: 1600, flag: false })
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
@ -56,199 +74,354 @@ export function useCanvasSetting() {
|
|||||||
})
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
canvas.renderAll()
|
canvas?.renderAll()
|
||||||
}, [corridorDimension])
|
}, [corridorDimension])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('useCanvasSetting useEffect 실행1')
|
console.log('useCanvasSetting useEffect 실행1', correntObjectNo)
|
||||||
fetchSettings()
|
}, [])
|
||||||
}, [objectNo])
|
|
||||||
|
|
||||||
|
//흡착점 ON/OFF 변경 시
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('useCanvasSetting useEffect 실행2')
|
console.log('useCanvasSetting useEffect 실행2', adsorptionPointMode.fontFlag, correntObjectNo)
|
||||||
//fetchSettings()
|
|
||||||
//onClickOption()
|
if (adsorptionPointMode.fontFlag) {
|
||||||
//fetchSettings()
|
onClickOption2()
|
||||||
|
frontSettings()
|
||||||
|
fetchSettings()
|
||||||
|
}
|
||||||
}, [adsorptionPointMode])
|
}, [adsorptionPointMode])
|
||||||
|
|
||||||
|
// 1 과 2 변경 시
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('useCanvasSetting useEffect 실행3')
|
console.log('useCanvasSetting useEffect 실행3', settingModalFirstOptions.fontFlag, settingModalSecondOptions.fontFlag, correntObjectNo)
|
||||||
//fetchSettings()
|
if (settingModalFirstOptions.fontFlag || settingModalSecondOptions.fontFlag) {
|
||||||
//onClickOption()
|
onClickOption2()
|
||||||
//fetchSettings()
|
fetchSettings()
|
||||||
|
}
|
||||||
|
frontSettings()
|
||||||
}, [settingModalFirstOptions, settingModalSecondOptions])
|
}, [settingModalFirstOptions, settingModalSecondOptions])
|
||||||
|
|
||||||
|
// 글꼴 변경 시
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('useCanvasSetting useEffect 실행4', globalFont.fontFlag, correntObjectNo)
|
||||||
|
if (globalFont.fontFlag) {
|
||||||
|
onClickOption2()
|
||||||
|
frontSettings()
|
||||||
|
fetchSettings()
|
||||||
|
}
|
||||||
|
}, [globalFont])
|
||||||
|
|
||||||
|
// 도명크기 변경 시
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(
|
||||||
|
'useCanvasSetting useEffect 실행5',
|
||||||
|
correntObjectNo,
|
||||||
|
planSizeSettingMode.flag,
|
||||||
|
planSizeSettingMode.originHorizon,
|
||||||
|
planSizeSettingMode.originVertical,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (planSizeSettingMode.flag) {
|
||||||
|
onClickOption2()
|
||||||
|
frontSettings()
|
||||||
|
fetchSettings()
|
||||||
|
}
|
||||||
|
}, [planSizeSettingMode.flag])
|
||||||
|
|
||||||
const fetchSettings = async () => {
|
const fetchSettings = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` })
|
const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${correntObjectNo}` })
|
||||||
console.log('res', res)
|
console.log('res', res)
|
||||||
const optionData1 = settingModalFirstOptions.option1.map((item) => ({ ...item, selected: res[item.column] }))
|
|
||||||
const optionData2 = settingModalFirstOptions.option2.map((item) => ({ ...item, selected: res[item.column] }))
|
|
||||||
const optionData3 = settingModalSecondOptions.option3.map((item) => ({ ...item }))
|
|
||||||
const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] }))
|
|
||||||
const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item }))
|
|
||||||
|
|
||||||
const patternData = {
|
if (res) {
|
||||||
adsorpPoint: res.adsorpPoint,
|
const optionData1 = settingModalFirstOptions.option1.map((item) => ({ ...item, selected: res[item.column] }))
|
||||||
|
const optionData2 = settingModalFirstOptions.option2.map((item) => ({ ...item, selected: res[item.column] }))
|
||||||
|
const optionData3 = settingModalSecondOptions.option3.map((item) => ({ ...item }))
|
||||||
|
const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] }))
|
||||||
|
const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item }))
|
||||||
|
|
||||||
|
//setObjectNo(floorPlanState.objectNo)
|
||||||
|
|
||||||
|
//흡착점 ON/OFF
|
||||||
|
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint, fontFlag: false })
|
||||||
|
|
||||||
|
//치수선 설정
|
||||||
|
setDimensionLineSettings({ ...dimensionLineSettings, pixel: res.originPixel, color: res.originColor })
|
||||||
|
|
||||||
|
//도면크기 설정
|
||||||
|
setPlanSizeSettingMode({
|
||||||
|
...planSizeSettingMode,
|
||||||
|
originHorizon: res.originHorizon,
|
||||||
|
originVertical: res.originVertical,
|
||||||
|
flag: false,
|
||||||
|
})
|
||||||
|
// setOriginHorizon({
|
||||||
|
// ...originHorizon,
|
||||||
|
// originHorizon: res.originHorizon,
|
||||||
|
// flag: false,
|
||||||
|
// })
|
||||||
|
// setOriginVertical({
|
||||||
|
// ...originVertical,
|
||||||
|
// originVertical: res.originVertical,
|
||||||
|
// flag: false,
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 데이터 설정
|
||||||
|
setSettingModalFirstOptions({
|
||||||
|
...settingModalFirstOptions,
|
||||||
|
option1: optionData1,
|
||||||
|
option2: optionData2,
|
||||||
|
dimensionDisplay: optionData5,
|
||||||
|
fontFlag: false,
|
||||||
|
})
|
||||||
|
setSettingModalSecondOptions({
|
||||||
|
...settingModalSecondOptions,
|
||||||
|
option3: optionData3,
|
||||||
|
option4: optionData4,
|
||||||
|
fontFlag: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
const fontPatternData = {
|
||||||
|
commonText: {
|
||||||
|
//문자 글꼴 조회 데이터
|
||||||
|
fontFamily: res.wordFont,
|
||||||
|
fontWeight: res.wordFontStyle,
|
||||||
|
fontSize: res.wordFontSize,
|
||||||
|
fontColor: res.wordFontColor,
|
||||||
|
},
|
||||||
|
flowText: {
|
||||||
|
//흐름방향 글꼴 조회 데이터
|
||||||
|
fontFamily: res.flowFont,
|
||||||
|
fontWeight: res.flowFontStyle,
|
||||||
|
fontSize: res.flowFontSize,
|
||||||
|
fontColor: res.flowFontColor,
|
||||||
|
},
|
||||||
|
dimensionLineText: {
|
||||||
|
//치수 글꼴 조회 데이터
|
||||||
|
fontFamily: res.dimensioFont,
|
||||||
|
fontWeight: res.dimensioFontStyle,
|
||||||
|
fontSize: res.dimensioFontSize,
|
||||||
|
fontColor: res.dimensioFontColor,
|
||||||
|
},
|
||||||
|
circuitNumberText: {
|
||||||
|
//회로번호 글꼴 조회 데이터
|
||||||
|
fontFamily: res.circuitNumFont,
|
||||||
|
fontWeight: res.circuitNumFontStyle,
|
||||||
|
fontSize: res.circuitNumFontSize,
|
||||||
|
fontColor: res.circuitNumFontColor,
|
||||||
|
},
|
||||||
|
lengthText: {
|
||||||
|
//치수선 글꼴 조회 데이터
|
||||||
|
fontFamily: res.lengthFont,
|
||||||
|
fontWeight: res.lengthFontStyle,
|
||||||
|
fontSize: res.lengthFontSize,
|
||||||
|
fontColor: res.lengthFontColor,
|
||||||
|
},
|
||||||
|
//글꼴 설정 Flag
|
||||||
|
fontFlag: false,
|
||||||
|
}
|
||||||
|
//console.log('fontPatternData', fontPatternData)
|
||||||
|
|
||||||
|
//조회된 글꼴 데이터 set
|
||||||
|
setGlobalFont(fontPatternData)
|
||||||
|
} else {
|
||||||
|
//조회된 글꼴 데이터가 없는 경우
|
||||||
|
|
||||||
|
//흡착점 ON/OFF
|
||||||
|
setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false, fontFlag: false })
|
||||||
|
|
||||||
|
//치수선 설정
|
||||||
|
setDimensionLineSettings({ ...dimensionLineSettings })
|
||||||
|
|
||||||
|
//도면크기 설정
|
||||||
|
setPlanSizeSettingMode({
|
||||||
|
...planSizeSettingMode,
|
||||||
|
flag: false,
|
||||||
|
})
|
||||||
|
// setOriginHorizon({
|
||||||
|
// ...originHorizon,
|
||||||
|
// flag: false,
|
||||||
|
// })
|
||||||
|
// setOriginVertical({
|
||||||
|
// ...originVertical,
|
||||||
|
// flag: false,
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 데이터 설정
|
||||||
|
setSettingModalFirstOptions({
|
||||||
|
...settingModalFirstOptions,
|
||||||
|
fontFlag: false,
|
||||||
|
})
|
||||||
|
setSettingModalSecondOptions({
|
||||||
|
...settingModalSecondOptions,
|
||||||
|
fontFlag: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
//console.log('globalFont2', globalFont)
|
||||||
|
const fontPatternData = {
|
||||||
|
commonText: {
|
||||||
|
//문자 글꼴
|
||||||
|
fontFamily: globalFont.commonText.fontFamily.value,
|
||||||
|
fontWeight: globalFont.commonText.fontWeight.value,
|
||||||
|
fontSize: globalFont.commonText.fontSize.value,
|
||||||
|
fontColor: globalFont.commonText.fontColor.value,
|
||||||
|
},
|
||||||
|
flowText: {
|
||||||
|
//흐름방향 글꼴
|
||||||
|
fontFamily: globalFont.flowText.fontFamily.value,
|
||||||
|
fontWeight: globalFont.flowText.fontWeight.value,
|
||||||
|
fontSize: globalFont.flowText.fontSize.value,
|
||||||
|
fontColor: globalFont.flowText.fontColor.value,
|
||||||
|
},
|
||||||
|
dimensionLineText: {
|
||||||
|
//치수 글꼴
|
||||||
|
fontFamily: globalFont.dimensionLineText.fontFamily.value,
|
||||||
|
fontWeight: globalFont.dimensionLineText.fontWeight.value,
|
||||||
|
fontSize: globalFont.dimensionLineText.fontSize.value,
|
||||||
|
fontColor: globalFont.dimensionLineText.fontColor.value,
|
||||||
|
},
|
||||||
|
circuitNumberText: {
|
||||||
|
//회로번호 글꼴
|
||||||
|
fontFamily: globalFont.circuitNumberText.fontFamily.value,
|
||||||
|
fontWeight: globalFont.circuitNumberText.fontWeight.value,
|
||||||
|
fontSize: globalFont.circuitNumberText.fontSize.value,
|
||||||
|
fontColor: globalFont.circuitNumberText.fontColor.value,
|
||||||
|
},
|
||||||
|
lengthText: {
|
||||||
|
//치수선 글꼴
|
||||||
|
fontFamily: globalFont.lengthText.fontFamily.value,
|
||||||
|
fontWeight: globalFont.lengthText.fontWeight.value,
|
||||||
|
fontSize: globalFont.lengthText.fontSize.value,
|
||||||
|
fontColor: globalFont.lengthText.fontColor.value,
|
||||||
|
},
|
||||||
|
//글꼴 설정 Flag
|
||||||
|
fontFlag: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('fontPatternData', fontPatternData)
|
||||||
|
|
||||||
|
setGlobalFont(fontPatternData)
|
||||||
|
|
||||||
|
//setGlobalFont({ ...globalFont, fontFlag: false })
|
||||||
}
|
}
|
||||||
|
frontSettings()
|
||||||
// 데이터 설정
|
|
||||||
setSettingModalFirstOptions({
|
|
||||||
option1: optionData1,
|
|
||||||
option2: optionData2,
|
|
||||||
dimensionDisplay: optionData5,
|
|
||||||
})
|
|
||||||
setSettingModalSecondOptions({
|
|
||||||
option3: optionData3,
|
|
||||||
option4: optionData4,
|
|
||||||
})
|
|
||||||
|
|
||||||
setAdsorptionPointMode(patternData.adsorpPoint)
|
|
||||||
|
|
||||||
console.log('adsorptionPointMode', adsorptionPointMode)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Data fetching error:', error)
|
console.error('Data fetching error:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 옵션 클릭 후 저장
|
// 옵션 클릭 후 저장
|
||||||
const onClickOption = async (item) => {
|
const onClickOption2 = useCallback(async () => {
|
||||||
//치수 표시(단 건 선택)
|
// 서버에 전송할 데이터
|
||||||
if (item.column === 'corridorDimension' || item.column === 'realDimension' || item.column === 'noneDimension') {
|
const dataToSend = {
|
||||||
console.log('치수 표시 ', item)
|
firstOption1: option1.map((item) => ({
|
||||||
const options = settingModalFirstOptions?.dimensionDisplay.map((option) => {
|
column: item.column,
|
||||||
option.selected = option.id === item.id
|
selected: item.selected,
|
||||||
return option
|
})),
|
||||||
})
|
firstOption2: option2.map((item) => ({
|
||||||
|
column: item.column,
|
||||||
//화면 표시(단 건 선택)
|
selected: item.selected,
|
||||||
} else if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') {
|
})),
|
||||||
console.log('화면 표시 ', item)
|
firstOption3: dimensionDisplay.map((item) => ({
|
||||||
const options2 = settingModalFirstOptions?.option2.map((option2) => {
|
column: item.column,
|
||||||
option2.selected = option2.id === item.id
|
selected: item.selected,
|
||||||
return option2
|
})),
|
||||||
})
|
secondOption2: option4.map((item) => ({
|
||||||
|
column: item.column,
|
||||||
const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
selected: item.selected,
|
||||||
|
})),
|
||||||
polygons.forEach((polygon) => {
|
|
||||||
setSurfaceShapePattern(polygon, item.column)
|
|
||||||
})
|
|
||||||
|
|
||||||
//흡착범위 설정(단 건 선택)
|
|
||||||
} else if (
|
|
||||||
item.column === 'adsorpRangeSmall' ||
|
|
||||||
item.column === 'adsorpRangeSmallSemi' ||
|
|
||||||
item.column === 'adsorpRangeMedium' ||
|
|
||||||
item.column === 'adsorpRangeLarge'
|
|
||||||
) {
|
|
||||||
console.log('화면 표시2 ', item, option4)
|
|
||||||
// option4에서 한 개만 선택 가능하도록 처리
|
|
||||||
const updatedOption4 = option4.map((option) =>
|
|
||||||
option.id === item.id
|
|
||||||
? { ...option, selected: true }
|
|
||||||
: {
|
|
||||||
...option,
|
|
||||||
selected: false,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
setSettingModalSecondOptions({ option3, option4: updatedOption4 })
|
|
||||||
|
|
||||||
//흡착점 ON / OFF
|
|
||||||
} else if (item === 'adsorpPoint') {
|
|
||||||
console.log('흡착점 ON / OFF ', item)
|
|
||||||
const options2 = settingModalFirstOptions?.option2.map((option2) => {
|
|
||||||
option2.selected = option2.id === item.id
|
|
||||||
return option2
|
|
||||||
})
|
|
||||||
|
|
||||||
const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
|
||||||
|
|
||||||
polygons.forEach((polygon) => {
|
|
||||||
setSurfaceShapePattern(polygon, item.column)
|
|
||||||
})
|
|
||||||
|
|
||||||
//디스플레이 설정(다 건 선택)
|
|
||||||
} else {
|
|
||||||
//console.log('디스플레이 설정1 ', item.column)
|
|
||||||
console.log('디스플레이 설정 ', item)
|
|
||||||
item.selected = !item.selected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setSettingModalFirstOptions({ option1, option2, dimensionDisplay })
|
const patternData = {
|
||||||
|
//견적서 번호
|
||||||
|
objectNo: correntObjectNo,
|
||||||
|
//디스플레이 설정(다중)
|
||||||
|
allocDisplay: dataToSend.firstOption1[0].selected,
|
||||||
|
outlineDisplay: dataToSend.firstOption1[1].selected,
|
||||||
|
gridDisplay: dataToSend.firstOption1[2].selected,
|
||||||
|
lineDisplay: dataToSend.firstOption1[3].selected,
|
||||||
|
wordDisplay: dataToSend.firstOption1[4].selected,
|
||||||
|
circuitNumDisplay: dataToSend.firstOption1[5].selected,
|
||||||
|
flowDisplay: dataToSend.firstOption1[6].selected,
|
||||||
|
trestleDisplay: dataToSend.firstOption1[7].selected,
|
||||||
|
imageDisplay: dataToSend.firstOption1[8].selected,
|
||||||
|
totalDisplay: dataToSend.firstOption1[9].selected,
|
||||||
|
//차수 표시(단 건)
|
||||||
|
corridorDimension: dataToSend.firstOption3[0].selected,
|
||||||
|
realDimension: dataToSend.firstOption3[1].selected,
|
||||||
|
noneDimension: dataToSend.firstOption3[2].selected,
|
||||||
|
//화면 표시(단 건)
|
||||||
|
onlyBorder: dataToSend.firstOption2[0].selected,
|
||||||
|
lineHatch: dataToSend.firstOption2[1].selected,
|
||||||
|
allPainted: dataToSend.firstOption2[2].selected,
|
||||||
|
//흡착범위 설정(단 건)
|
||||||
|
adsorpRangeSmall: dataToSend.secondOption2[0].selected,
|
||||||
|
adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected,
|
||||||
|
adsorpRangeMedium: dataToSend.secondOption2[2].selected,
|
||||||
|
adsorpRangeLarge: dataToSend.secondOption2[3].selected,
|
||||||
|
//흡착점 ON/OFF
|
||||||
|
adsorpPoint: adsorptionPointMode.adsorptionPoint,
|
||||||
|
//??: adsorptionRange, 사용여부 확인 필요
|
||||||
|
|
||||||
try {
|
//글꼴 설정
|
||||||
// 서버에 전송할 데이터
|
//문자 글꼴
|
||||||
const dataToSend = {
|
wordFont: globalFont.commonText.fontFamily,
|
||||||
firstOption1: option1.map((item) => ({
|
wordFontStyle: globalFont.commonText.fontWeight,
|
||||||
column: item.column,
|
wordFontSize: globalFont.commonText.fontSize,
|
||||||
selected: item.selected,
|
wordFontColor: globalFont.commonText.fontColor,
|
||||||
})),
|
|
||||||
firstOption2: option2.map((item) => ({
|
|
||||||
column: item.column,
|
|
||||||
selected: item.selected,
|
|
||||||
})),
|
|
||||||
firstOption3: dimensionDisplay.map((item) => ({
|
|
||||||
column: item.column,
|
|
||||||
selected: item.selected,
|
|
||||||
})),
|
|
||||||
// secondOption1: secondOptions[0].option1.map((item) => ({
|
|
||||||
// name: item.id,
|
|
||||||
// name: item.name,
|
|
||||||
// // 필요한 경우 데이터 항목 추가
|
|
||||||
// })),
|
|
||||||
secondOption2: option4.map((item) => ({
|
|
||||||
column: item.column,
|
|
||||||
selected: item.selected,
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
|
|
||||||
const patternData = {
|
//흐름방향 글꼴
|
||||||
objectNo,
|
flowFont: globalFont.flowText.fontFamily,
|
||||||
//디스플레이 설정(다중)
|
flowFontStyle: globalFont.flowText.fontWeight,
|
||||||
allocDisplay: dataToSend.firstOption1[0].selected,
|
flowFontSize: globalFont.flowText.fontSize,
|
||||||
outlineDisplay: dataToSend.firstOption1[1].selected,
|
flowFontColor: globalFont.flowText.fontColor,
|
||||||
gridDisplay: dataToSend.firstOption1[2].selected,
|
|
||||||
lineDisplay: dataToSend.firstOption1[3].selected,
|
|
||||||
wordDisplay: dataToSend.firstOption1[4].selected,
|
|
||||||
circuitNumDisplay: dataToSend.firstOption1[5].selected,
|
|
||||||
flowDisplay: dataToSend.firstOption1[6].selected,
|
|
||||||
trestleDisplay: dataToSend.firstOption1[7].selected,
|
|
||||||
imageDisplay: dataToSend.firstOption1[8].selected,
|
|
||||||
totalDisplay: dataToSend.firstOption1[9].selected,
|
|
||||||
//차수 표시(단 건)
|
|
||||||
corridorDimension: dataToSend.firstOption3[0].selected,
|
|
||||||
realDimension: dataToSend.firstOption3[1].selected,
|
|
||||||
noneDimension: dataToSend.firstOption3[2].selected,
|
|
||||||
//화면 표시(단 건)
|
|
||||||
onlyBorder: dataToSend.firstOption2[0].selected,
|
|
||||||
lineHatch: dataToSend.firstOption2[1].selected,
|
|
||||||
allPainted: dataToSend.firstOption2[2].selected,
|
|
||||||
//흡착범위 설정(단 건)
|
|
||||||
adsorpRangeSmall: dataToSend.secondOption2[0].selected,
|
|
||||||
adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected,
|
|
||||||
adsorpRangeMedium: dataToSend.secondOption2[2].selected,
|
|
||||||
adsorpRangeLarge: dataToSend.secondOption2[3].selected,
|
|
||||||
//흡착점 ON/OFF
|
|
||||||
adsorpPoint: adsorptionPointMode,
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('patternData ', patternData)
|
//치수 글꼴
|
||||||
|
dimensioFont: globalFont.dimensionLineText.fontFamily,
|
||||||
|
dimensioFontStyle: globalFont.dimensionLineText.fontWeight,
|
||||||
|
dimensioFontSize: globalFont.dimensionLineText.fontSize,
|
||||||
|
dimensioFontColor: globalFont.dimensionLineText.fontColor,
|
||||||
|
|
||||||
// HTTP POST 요청 보내기
|
//회로번호 글꼴
|
||||||
await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }).then((res) => {
|
circuitNumFont: globalFont.circuitNumberText.fontFamily,
|
||||||
|
circuitNumFontStyle: globalFont.circuitNumberText.fontWeight,
|
||||||
|
circuitNumFontSize: globalFont.circuitNumberText.fontSize,
|
||||||
|
circuitNumFontColor: globalFont.circuitNumberText.fontColor,
|
||||||
|
|
||||||
|
//치수선 글꼴
|
||||||
|
lengthFont: globalFont.lengthText.fontFamily,
|
||||||
|
lengthFontStyle: globalFont.lengthText.fontWeight,
|
||||||
|
lengthFontSize: globalFont.lengthText.fontSize,
|
||||||
|
lengthFontColor: globalFont.lengthText.fontColor,
|
||||||
|
|
||||||
|
//치수선 설정
|
||||||
|
originPixel: dimensionLineSettings.pixel,
|
||||||
|
originColor: dimensionLineSettings.color,
|
||||||
|
|
||||||
|
//치수선 설정
|
||||||
|
originHorizon: planSizeSettingMode.originHorizon,
|
||||||
|
originVertical: planSizeSettingMode.originVertical,
|
||||||
|
// originHorizon: originHorizon.originHorizon,
|
||||||
|
// originVertical: originVertical.originVertical,
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('patternData ', patternData)
|
||||||
|
|
||||||
|
// HTTP POST 요청 보내기
|
||||||
|
await post({ url: `/api/canvas-management/canvas-settings`, data: patternData })
|
||||||
|
.then((res) => {
|
||||||
swalFire({ text: getMessage(res.returnMessage) })
|
swalFire({ text: getMessage(res.returnMessage) })
|
||||||
|
|
||||||
// Canvas 디스플레이 설정 시 해당 옵션 적용
|
// Canvas 디스플레이 설정 시 해당 옵션 적용
|
||||||
frontSettings()
|
frontSettings()
|
||||||
})
|
})
|
||||||
} catch (error) {
|
.catch((error) => {
|
||||||
swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
|
swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
|
||||||
}
|
})
|
||||||
|
|
||||||
setAdsorptionRange(item.range)
|
//setAdsorptionRange(item.range)
|
||||||
}
|
}, [settingModalFirstOptions, settingModalSecondOptions, adsorptionPointMode, globalFont, planSizeSettingMode])
|
||||||
|
|
||||||
// Canvas 디스플레이 설정 시 해당 옵션 적용
|
// Canvas 디스플레이 설정 시 해당 옵션 적용
|
||||||
const frontSettings = async () => {
|
const frontSettings = async () => {
|
||||||
@ -260,7 +433,7 @@ export function useCanvasSetting() {
|
|||||||
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
||||||
// 'wordDisplay' 문자 표시
|
// 'wordDisplay' 문자 표시
|
||||||
// 'circuitNumDisplay' 회로번호 표시
|
// 'circuitNumDisplay' 회로번호 표시
|
||||||
// 'flowDisplay' 흐름방향 표시 'arrow'
|
// 'flowDisplay' 흐름방향 표시 'arrow', 'flowText'
|
||||||
// 'trestleDisplay' 가대 표시
|
// 'trestleDisplay' 가대 표시
|
||||||
// 'imageDisplay' 이미지 표시
|
// 'imageDisplay' 이미지 표시
|
||||||
// 'totalDisplay' 집계표 표시
|
// 'totalDisplay' 집계표 표시
|
||||||
@ -304,8 +477,8 @@ export function useCanvasSetting() {
|
|||||||
// 표시 선택 상태(true/false)
|
// 표시 선택 상태(true/false)
|
||||||
optionSelected = option1[i].selected
|
optionSelected = option1[i].selected
|
||||||
|
|
||||||
canvas
|
//canvas.getObjects() >> canvasObjects
|
||||||
.getObjects()
|
canvasObjects
|
||||||
.filter((obj) => optionName.includes(obj.name))
|
.filter((obj) => optionName.includes(obj.name))
|
||||||
//.filter((obj) => obj.name === optionName)
|
//.filter((obj) => obj.name === optionName)
|
||||||
.forEach((obj) => {
|
.forEach((obj) => {
|
||||||
@ -313,7 +486,7 @@ export function useCanvasSetting() {
|
|||||||
//obj.set({ visible: !obj.visible })
|
//obj.set({ visible: !obj.visible })
|
||||||
})
|
})
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas?.renderAll()
|
||||||
|
|
||||||
// console.log(
|
// console.log(
|
||||||
// 'optionName',
|
// 'optionName',
|
||||||
@ -324,14 +497,31 @@ export function useCanvasSetting() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
canvas,
|
||||||
settingModalFirstOptions,
|
settingModalFirstOptions,
|
||||||
setSettingModalFirstOptions,
|
setSettingModalFirstOptions,
|
||||||
settingModalSecondOptions,
|
settingModalSecondOptions,
|
||||||
setSettingModalSecondOptions,
|
setSettingModalSecondOptions,
|
||||||
adsorptionPointMode,
|
adsorptionPointMode,
|
||||||
setAdsorptionPointMode,
|
setAdsorptionPointMode,
|
||||||
|
adsorptionRange,
|
||||||
|
setAdsorptionRange,
|
||||||
fetchSettings,
|
fetchSettings,
|
||||||
onClickOption,
|
//onClickOption,
|
||||||
frontSettings,
|
frontSettings,
|
||||||
|
globalFont,
|
||||||
|
setGlobalFont,
|
||||||
|
selectedFont,
|
||||||
|
setSelectedFont,
|
||||||
|
selectedFontWeight,
|
||||||
|
setSelectedFontWeight,
|
||||||
|
selectedFontSize,
|
||||||
|
setSelectedFontSize,
|
||||||
|
selectedFontColor,
|
||||||
|
setSelectedFontColor,
|
||||||
|
dimensionLineSettings,
|
||||||
|
setDimensionLineSettings,
|
||||||
|
planSizeSettingMode,
|
||||||
|
setPlanSizeSettingMode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,7 +92,7 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
|
|
||||||
addCanvasMouseEventListener('mouse:move', mouseMove)
|
addCanvasMouseEventListener('mouse:move', mouseMove)
|
||||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||||
addDocumentEventListener('contextmenu', document, cutAuxiliary)
|
// addDocumentEventListener('contextmenu', document, cutAuxiliary)
|
||||||
addDocumentEventListener('keydown', document, keydown[type])
|
addDocumentEventListener('keydown', document, keydown[type])
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
@ -135,23 +135,6 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const addBisectorLine = (target) => {
|
|
||||||
const slope = (target.y2 - target.y1) / (target.x2 - target.x1)
|
|
||||||
const bisectorSlope = -1 / slope
|
|
||||||
const length = target.length
|
|
||||||
const dx = length / Math.sqrt(1 + bisectorSlope * bisectorSlope)
|
|
||||||
const dy = bisectorSlope * dx
|
|
||||||
const endX = (target.x1 + target.x2) / 2
|
|
||||||
const endY = (target.y1 + target.y2) / 2
|
|
||||||
|
|
||||||
addLine([dx, dy, endX, endY], {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 1,
|
|
||||||
selectable: true,
|
|
||||||
name: 'auxiliaryLine',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const keydown = {
|
const keydown = {
|
||||||
outerLine: (e) => {
|
outerLine: (e) => {
|
||||||
if (mousePointerArr.current.length === 0) {
|
if (mousePointerArr.current.length === 0) {
|
||||||
@ -565,8 +548,24 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
otherAdsorptionPoints.push(intersectionPoint)
|
otherAdsorptionPoints.push(intersectionPoint)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
let innerLinePoints = []
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.innerLines)
|
||||||
|
.forEach((polygon) => {
|
||||||
|
polygon.innerLines.forEach((line) => {
|
||||||
|
innerLinePoints.push({ x: line.x1, y: line.y1 })
|
||||||
|
innerLinePoints.push({ x: line.x2, y: line.y2 })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
const adsorptionPoints = [...getAdsorptionPoints(), ...roofAdsorptionPoints.current, ...otherAdsorptionPoints, ...intersectionPoints.current]
|
const adsorptionPoints = [
|
||||||
|
...getAdsorptionPoints(),
|
||||||
|
...roofAdsorptionPoints.current,
|
||||||
|
...otherAdsorptionPoints,
|
||||||
|
...intersectionPoints.current,
|
||||||
|
...innerLinePoints,
|
||||||
|
]
|
||||||
|
|
||||||
let arrivalPoint = { x: pointer.x, y: pointer.y }
|
let arrivalPoint = { x: pointer.x, y: pointer.y }
|
||||||
|
|
||||||
@ -825,7 +824,6 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
|
|
||||||
//lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거
|
//lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거
|
||||||
// 겹치는 선 하나는 canvas에서 제거한다.
|
// 겹치는 선 하나는 canvas에서 제거한다.
|
||||||
|
|
||||||
const tempLines = [...lineHistory.current]
|
const tempLines = [...lineHistory.current]
|
||||||
lineHistory.current = []
|
lineHistory.current = []
|
||||||
tempLines.forEach((line) => {
|
tempLines.forEach((line) => {
|
||||||
@ -849,27 +847,30 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
const tempPolygonPoints = [...roofBase.points].map((obj) => {
|
const tempPolygonPoints = [...roofBase.points].map((obj) => {
|
||||||
return { x: Math.round(obj.x), y: Math.round(obj.y) }
|
return { x: Math.round(obj.x), y: Math.round(obj.y) }
|
||||||
})
|
})
|
||||||
const roofInnerLines = innerLines.filter((line) => {
|
const roofInnerLines = [...roofBase.innerLines, ...innerLines].filter((line) => {
|
||||||
const inPolygon1 =
|
const inPolygon1 =
|
||||||
tempPolygonPoints.some((point) => point.x === line.x1 && point.y === line.y1) ||
|
tempPolygonPoints.some((point) => Math.round(point.x) === Math.round(line.x1) && Math.round(point.y) === Math.round(line.y1)) ||
|
||||||
roofBase.inPolygon({ x: line.x1, y: line.y1 }) ||
|
roofBase.inPolygon({ x: Math.round(line.x1), y: Math.round(line.y1) }) ||
|
||||||
roofBase.lines.some((line) => isPointOnLine(line, { x: line.x1, y: line.y1 }))
|
roofBase.lines.some((line) => isPointOnLine(line, { x: Math.round(line.x1), y: Math.round(line.y1) }))
|
||||||
const inPolygon2 =
|
const inPolygon2 =
|
||||||
tempPolygonPoints.some((point) => point.x === line.x2 && point.y === line.y2) ||
|
tempPolygonPoints.some((point) => Math.round(point.x) === Math.round(line.x2) && Math.round(point.y) === Math.round(line.y2)) ||
|
||||||
roofBase.inPolygon({ x: line.x2, y: line.y2 }) ||
|
roofBase.inPolygon({ x: Math.round(line.x2), y: Math.round(line.y2) }) ||
|
||||||
roofBase.lines.some((line) => isPointOnLine(line, { x: line.x2, y: line.y2 }))
|
roofBase.lines.some((line) => isPointOnLine(line, { x: Math.round(line.x2), y: Math.round(line.y2) }))
|
||||||
|
|
||||||
if (inPolygon1 && inPolygon2) {
|
if (inPolygon1 && inPolygon2) {
|
||||||
line.attributes = { ...line.attributes, roofId: roofBase.id, actualSize: 0, planeSize: line.getLength() }
|
line.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
roofId: roofBase.id,
|
||||||
|
actualSize: line.attributes?.actualSize ?? 0,
|
||||||
|
planeSize: line.getLength(),
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
roofBase.innerLines = [...roofInnerLines]
|
roofBase.innerLines = lineHistory.current.length !== 0 ? [...roofInnerLines] : roofBase.innerLines
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,6 +904,6 @@ export function useAuxiliaryDrawing(id) {
|
|||||||
setButtonAct,
|
setButtonAct,
|
||||||
move,
|
move,
|
||||||
copy,
|
copy,
|
||||||
addBisectorLine,
|
cutAuxiliary,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import { useObjectBatch } from '@/hooks/object/useObjectBatch'
|
|||||||
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
||||||
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
|
||||||
export function useContextMenu() {
|
export function useContextMenu() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -56,6 +57,7 @@ export function useContextMenu() {
|
|||||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||||
const { addLine, removeLine } = useLine()
|
const { addLine, removeLine } = useLine()
|
||||||
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
||||||
|
const { swalFire } = useSwal()
|
||||||
|
|
||||||
const currentMenuSetting = () => {
|
const currentMenuSetting = () => {
|
||||||
switch (currentMenu) {
|
switch (currentMenu) {
|
||||||
@ -145,6 +147,9 @@ export function useContextMenu() {
|
|||||||
shortcut: ['d', 'D'],
|
shortcut: ['d', 'D'],
|
||||||
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
|
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
|
||||||
fn: () => {
|
fn: () => {
|
||||||
|
const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]
|
||||||
|
const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id)
|
||||||
|
roof.innerLines = [...innerLines]
|
||||||
canvas.remove(currentObject)
|
canvas.remove(currentObject)
|
||||||
canvas.discardActiveObject()
|
canvas.discardActiveObject()
|
||||||
},
|
},
|
||||||
@ -176,21 +181,34 @@ export function useContextMenu() {
|
|||||||
endY = (currentObject.y1 + currentObject.y2) / 2 - dy
|
endY = (currentObject.y1 + currentObject.y2) / 2 - dy
|
||||||
}
|
}
|
||||||
|
|
||||||
addLine([startX, startY, endX, endY], {
|
const line = addLine([startX, startY, endX, endY], {
|
||||||
stroke: 'red',
|
stroke: 'red',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
name: 'auxiliaryLine',
|
name: 'auxiliaryLine',
|
||||||
|
attributes: { ...currentObject.attributes },
|
||||||
})
|
})
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.id === currentObject.attributes.roofId)[0]
|
||||||
|
.innerLines.push(line)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'auxiliaryCut',
|
|
||||||
name: getMessage('contextmenu.auxiliary.cut'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'auxiliaryRemoveAll',
|
id: 'auxiliaryRemoveAll',
|
||||||
name: getMessage('contextmenu.auxiliary.remove.all'),
|
name: getMessage('contextmenu.auxiliary.remove.all'),
|
||||||
|
fn: () => {
|
||||||
|
if (!currentObject) {
|
||||||
|
swalFire({ text: '지붕을 선택해주세요.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0].innerLines
|
||||||
|
innerLines.forEach((line) => {
|
||||||
|
canvas.remove(line)
|
||||||
|
})
|
||||||
|
innerLines.length = 0
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
])
|
])
|
||||||
|
|||||||
@ -222,6 +222,12 @@ export const adsorptionRangeState = atom({
|
|||||||
default: 50,
|
default: 50,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 도면크기 설정
|
||||||
|
export const planSizeSettingState = atom({
|
||||||
|
key: 'planSizeSettingMode',
|
||||||
|
default: { originHorizon: 1600, originVertical: 1600 },
|
||||||
|
})
|
||||||
|
|
||||||
// 점,선 그리드 설정
|
// 점,선 그리드 설정
|
||||||
export const dotLineGridSettingState = atom({
|
export const dotLineGridSettingState = atom({
|
||||||
key: 'gridSettingState',
|
key: 'gridSettingState',
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { atom, selectorFamily } from 'recoil'
|
import { atom, selectorFamily } from 'recoil'
|
||||||
|
|
||||||
const defaultFont = {
|
const defaultFont = {
|
||||||
fontFamily: { name: 'MS PGothic', value: 'MS PGothic' },
|
fontFamily: { id: 1, name: 'MS PGothic', value: 'MS PGothic' },
|
||||||
fontWeight: { name: '보통', value: 'normal' },
|
fontWeight: { id: 'normal', name: '보통', value: 'normal' },
|
||||||
fontSize: { name: '16', value: '16' },
|
fontSize: { id: 16, name: 16, value: 16 },
|
||||||
fontColor: { name: '검정색', value: 'black' },
|
fontColor: { id: 'black', name: '검정색', value: 'black' },
|
||||||
}
|
}
|
||||||
|
|
||||||
export const globalFontAtom = atom({
|
export const globalFontAtom = atom({
|
||||||
|
|||||||
@ -67,6 +67,13 @@ export const convertNumberToPriceDecimal = (value) => {
|
|||||||
else return ''
|
else return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 43000.458 --> 43,000.46
|
||||||
|
export const convertNumberToPriceDecimalToFixed = (value, fixed) => {
|
||||||
|
if (value) return Number(value).toLocaleString(undefined, { minimumFractionDigits: fixed, maximumFractionDigits: fixed })
|
||||||
|
else if (value === 0) return 0
|
||||||
|
else return ''
|
||||||
|
}
|
||||||
|
|
||||||
// 전화번호, FAX 번호 숫자 or '-'만 입력 체크
|
// 전화번호, FAX 번호 숫자 or '-'만 입력 체크
|
||||||
export const inputTelNumberCheck = (e) => {
|
export const inputTelNumberCheck = (e) => {
|
||||||
const input = e.target
|
const input = e.target
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user