Merge branch 'dev' into dev-yj
This commit is contained in:
commit
7197e20537
@ -17,6 +17,8 @@ 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 } from '@/util/common-utils'
|
||||||
import ProductFeaturesPop from './popup/ProductFeaturesPop'
|
import ProductFeaturesPop from './popup/ProductFeaturesPop'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
export default function Estimate({ params }) {
|
export default function Estimate({ params }) {
|
||||||
const [itemChangeYn, setItemChangeYn] = useState(false)
|
const [itemChangeYn, setItemChangeYn] = useState(false)
|
||||||
const { session } = useContext(SessionContext)
|
const { session } = useContext(SessionContext)
|
||||||
@ -307,22 +309,25 @@ export default function Estimate({ params }) {
|
|||||||
//제품 삭제
|
//제품 삭제
|
||||||
const removeItem = () => {
|
const removeItem = () => {
|
||||||
const array = [...selection]
|
const array = [...selection]
|
||||||
let tempList = []
|
let delList = []
|
||||||
state.itemList.filter((row) => {
|
state.itemList.filter((row) => {
|
||||||
array.map((row2) => {
|
array.map((row2) => {
|
||||||
if (row2 === row.dispOrder) {
|
if (row2 === row.dispOrder) {
|
||||||
tempList.push({ ...row })
|
delList.push({ ...row })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 필터안하고 플래그로 관리하는거로 변경하기
|
const updateList = state.itemList.map((item) => {
|
||||||
const result = state.itemList.filter((item) => {
|
const isDeleted = delList.some((row) => item.dispOrder === row.dispOrder)
|
||||||
return !tempList.some((other) => other.dispOrder === item.dispOrder)
|
return {
|
||||||
|
...item,
|
||||||
|
delFlg: isDeleted ? '1' : '0',
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
itemList: result,
|
itemList: updateList,
|
||||||
})
|
})
|
||||||
|
|
||||||
setSelection(new Set())
|
setSelection(new Set())
|
||||||
@ -331,8 +336,8 @@ export default function Estimate({ params }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (itemChangeYn) {
|
if (itemChangeYn) {
|
||||||
// console.log('아이템에 뭔가 변화가 일어났어', itemChangeYn)
|
console.log('아이템에 뭔가 변화가 일어났어', itemChangeYn)
|
||||||
// console.log('아이템상태가져오기::::::::::', state.itemList)
|
console.log('아이템상태가져오기::::::::::', state.itemList)
|
||||||
}
|
}
|
||||||
|
|
||||||
//다시 false로 돌리기 여기서할지 가격정보 변경하는거 끝나고할지..
|
//다시 false로 돌리기 여기서할지 가격정보 변경하는거 끝나고할지..
|
||||||
@ -527,8 +532,8 @@ export default function Estimate({ params }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={`form-flex-wrap ${style}`}>
|
<div className={`form-flex-wrap ${style}`} key={uuidv4()}>
|
||||||
<div className="input-wrap mr5" style={{ width: '610px' }}>
|
<div className="input-wrap mr5" style={{ width: '610px' }} key={`roof${index}`}>
|
||||||
<input type="text" className="input-light" defaultValue={roofList} readOnly />
|
<input type="text" className="input-light" defaultValue={roofList} readOnly />
|
||||||
</div>
|
</div>
|
||||||
<div className="input-wrap" style={{ width: '200px' }}>
|
<div className="input-wrap" style={{ width: '200px' }}>
|
||||||
@ -613,7 +618,7 @@ export default function Estimate({ params }) {
|
|||||||
{originFiles.length > 0 &&
|
{originFiles.length > 0 &&
|
||||||
originFiles.map((originFile) => {
|
originFiles.map((originFile) => {
|
||||||
return (
|
return (
|
||||||
<li className="file-item">
|
<li className="file-item" key={uuidv4()}>
|
||||||
<span onClick={() => handleEstimateFileDownload(originFile)}>
|
<span onClick={() => handleEstimateFileDownload(originFile)}>
|
||||||
{originFile.faileName}
|
{originFile.faileName}
|
||||||
<button
|
<button
|
||||||
@ -657,6 +662,7 @@ export default function Estimate({ params }) {
|
|||||||
specialNoteList.map((row) => {
|
specialNoteList.map((row) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
key={uuidv4()}
|
||||||
className="special-note-check-item"
|
className="special-note-check-item"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
settingShowContent(row.code, event)
|
settingShowContent(row.code, event)
|
||||||
@ -686,7 +692,7 @@ export default function Estimate({ params }) {
|
|||||||
{specialNoteList.map((row) => {
|
{specialNoteList.map((row) => {
|
||||||
if (row.code === showContentCode) {
|
if (row.code === showContentCode) {
|
||||||
return (
|
return (
|
||||||
<dl>
|
<dl key={uuidv4()}>
|
||||||
<dt>{row.codeNm}</dt>
|
<dt>{row.codeNm}</dt>
|
||||||
<dd dangerouslySetInnerHTML={{ __html: row.remarks }}></dd>
|
<dd dangerouslySetInnerHTML={{ __html: row.remarks }}></dd>
|
||||||
</dl>
|
</dl>
|
||||||
@ -710,24 +716,24 @@ export default function Estimate({ params }) {
|
|||||||
<div className="esimate-wrap">
|
<div className="esimate-wrap">
|
||||||
<div className="estimate-list-wrap one">
|
<div className="estimate-list-wrap one">
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totPcs')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totAmount')}</div>
|
||||||
<div className="estimate-name blue">74</div>
|
<div className="estimate-name blue">{convertNumberToPriceDecimal(state?.totAmount)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vol')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}</div>
|
||||||
<div className="estimate-name blue">8300</div>
|
<div className="estimate-name blue">{convertNumberToPriceDecimal(state?.totVolKw)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.netAmt')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.supplyPrice')}</div>
|
||||||
<div className="estimate-name blue">6,798,900</div>
|
<div className="estimate-name blue">{convertNumberToPriceDecimal(state?.supplyPrice)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="estimate-box">
|
<div className="estimate-box">
|
||||||
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vat')}</div>
|
<div className="estimate-tit">{getMessage('estimate.detail.sepcialEstimateProductInfo.vatPrice')}</div>
|
||||||
<div className="estimate-name blue">679,890</div>
|
<div className="estimate-name blue">{convertNumberToPriceDecimal(state?.vatPrice)}</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">7,478,790</div>
|
<div className="estimate-name red">{convertNumberToPriceDecimal(state?.totPrice)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -769,6 +775,7 @@ export default function Estimate({ params }) {
|
|||||||
<div className="select-wrap">
|
<div className="select-wrap">
|
||||||
{session?.storeLvl === '1' ? (
|
{session?.storeLvl === '1' ? (
|
||||||
<select
|
<select
|
||||||
|
key={uuidv4()}
|
||||||
className="select-light"
|
className="select-light"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setTempPriceCd(e.target.value)
|
setTempPriceCd(e.target.value)
|
||||||
@ -777,7 +784,7 @@ export default function Estimate({ params }) {
|
|||||||
{storePriceList.length > 0 && storePriceList.map((row) => <option value={row.priceCd}>{row.priceNm}</option>)}
|
{storePriceList.length > 0 && storePriceList.map((row) => <option value={row.priceCd}>{row.priceNm}</option>)}
|
||||||
</select>
|
</select>
|
||||||
) : (
|
) : (
|
||||||
<select className="select-light">
|
<select key={uuidv4()} className="select-light">
|
||||||
<option value="UNIT_PRICE">{getMessage('estimate.detail.header.unitPrice')}</option>
|
<option value="UNIT_PRICE">{getMessage('estimate.detail.header.unitPrice')}</option>
|
||||||
</select>
|
</select>
|
||||||
)}
|
)}
|
||||||
@ -857,7 +864,7 @@ export default function Estimate({ params }) {
|
|||||||
{state?.itemList.length > 0 &&
|
{state?.itemList.length > 0 &&
|
||||||
state.itemList.map((item, index) => {
|
state.itemList.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<tr key={index}>
|
<tr key={uuidv4()}>
|
||||||
<td className="al-c">
|
<td className="al-c">
|
||||||
<div className="d-check-box light no-text">
|
<div className="d-check-box light no-text">
|
||||||
<input
|
<input
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { currentMenuState } from '@/store/canvasAtom'
|
import { canvasState, currentMenuState } from '@/store/canvasAtom'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { menuTypeState, subMenusState } from '@/store/menuAtom'
|
import { menuTypeState, subMenusState } from '@/store/menuAtom'
|
||||||
import useMenu from '@/hooks/common/useMenu'
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
@ -9,6 +9,7 @@ import { useEffect } from 'react'
|
|||||||
|
|
||||||
export default function MenuDepth01() {
|
export default function MenuDepth01() {
|
||||||
const type = useRecoilValue(menuTypeState)
|
const type = useRecoilValue(menuTypeState)
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { handleMenu } = useMenu()
|
const { handleMenu } = useMenu()
|
||||||
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
|
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
|
||||||
@ -24,6 +25,7 @@ export default function MenuDepth01() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleMenu(type)
|
handleMenu(type)
|
||||||
|
canvas.discardActiveObject()
|
||||||
}, [currentMenu])
|
}, [currentMenu])
|
||||||
return (
|
return (
|
||||||
<div className="canvas-depth2-inner">
|
<div className="canvas-depth2-inner">
|
||||||
|
|||||||
@ -107,7 +107,7 @@ export function useRoofAllocationSetting(id) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
if (currentObject && currentObject.name && !currentObject.name.toLowerCase().includes('text')) {
|
if (currentObject && currentObject.name && ['auxiliaryLine', 'ridge', 'hip'].includes(currentObject.name)) {
|
||||||
currentObject.set({
|
currentObject.set({
|
||||||
strokeWidth: 4,
|
strokeWidth: 4,
|
||||||
stroke: '#EA10AC',
|
stroke: '#EA10AC',
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, fontFamilyState, fontSizeState, pitchTextSelector } from '@/store/canvasAtom'
|
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, fontFamilyState, fontSizeState, pitchTextSelector } from '@/store/canvasAtom'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { getDegreeByChon, getDegreeInOrientation, getDirectionByPoint, isPointOnLine } from '@/util/canvas-util'
|
import { findAndRemoveClosestPoint, getDegreeByChon, getDegreeInOrientation, getDirectionByPoint, isPointOnLine } from '@/util/canvas-util'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils'
|
import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils'
|
||||||
import { flowDisplaySelector } from '@/store/settingAtom'
|
import { flowDisplaySelector } from '@/store/settingAtom'
|
||||||
@ -86,8 +86,8 @@ export const usePolygon = () => {
|
|||||||
parentDirection: line.direction,
|
parentDirection: line.direction,
|
||||||
parentDegree: degree,
|
parentDegree: degree,
|
||||||
parentId: polygon.id,
|
parentId: polygon.id,
|
||||||
planeSize,
|
planeSize: planeSize ?? length,
|
||||||
actualSize,
|
actualSize: actualSize ?? length,
|
||||||
editable: false,
|
editable: false,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
lockRotation: true,
|
lockRotation: true,
|
||||||
@ -669,62 +669,107 @@ export const usePolygon = () => {
|
|||||||
const splitPolygonWithLines = (polygon) => {
|
const splitPolygonWithLines = (polygon) => {
|
||||||
polygon.set({ visible: false })
|
polygon.set({ visible: false })
|
||||||
let innerLines = [...polygon.innerLines]
|
let innerLines = [...polygon.innerLines]
|
||||||
|
|
||||||
|
canvas.renderAll()
|
||||||
let polygonLines = [...polygon.lines]
|
let polygonLines = [...polygon.lines]
|
||||||
const roofs = []
|
const roofs = []
|
||||||
|
|
||||||
let delIndexs = []
|
//polygonLines를 순회하며 innerLines와 교차하는 점을 line의 속성에 배열로 저장한다.
|
||||||
let newLines = []
|
polygonLines.forEach((line) => {
|
||||||
|
const intersections = []
|
||||||
polygonLines.forEach((line, index) => {
|
|
||||||
line.tempIndex = index
|
|
||||||
innerLines.forEach((innerLine) => {
|
innerLines.forEach((innerLine) => {
|
||||||
let newLine1, newLine2
|
|
||||||
if (isPointOnLine(line, innerLine.startPoint)) {
|
if (isPointOnLine(line, innerLine.startPoint)) {
|
||||||
// 해당 line을 startPoint로 나눈 line2개를 canvas에 추가 하고 기존 line을 제거한다.
|
if (isSamePoint(line.startPoint, innerLine.startPoint) || isSamePoint(line.endPoint, innerLine.startPoint)) {
|
||||||
newLine1 = new QLine([line.x1, line.y1, innerLine.startPoint.x, innerLine.startPoint.y], {
|
return
|
||||||
fontSize: polygon.fontSize,
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 3,
|
|
||||||
})
|
|
||||||
|
|
||||||
newLine2 = new QLine([innerLine.startPoint.x, innerLine.startPoint.y, line.x2, line.y2], {
|
|
||||||
fontSize: polygon.fontSize,
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 3,
|
|
||||||
})
|
|
||||||
delIndexs.push(polygonLines.indexOf(line))
|
|
||||||
canvas.remove(polygonLines[polygonLines.indexOf(line)])
|
|
||||||
if (newLine1.length / 10 > 10) {
|
|
||||||
newLines.push(newLine1)
|
|
||||||
}
|
|
||||||
if (newLine2.length / 10 > 10) {
|
|
||||||
newLines.push(newLine2)
|
|
||||||
}
|
}
|
||||||
|
intersections.push(innerLine.startPoint)
|
||||||
}
|
}
|
||||||
if (isPointOnLine(line, innerLine.endPoint)) {
|
if (isPointOnLine(line, innerLine.endPoint)) {
|
||||||
newLine1 = new QLine([line.x1, line.y1, innerLine.endPoint.x, innerLine.endPoint.y], {
|
if (isSamePoint(line.startPoint, innerLine.endPoint) || isSamePoint(line.startPoint, innerLine.endPoint)) {
|
||||||
fontSize: polygon.fontSize,
|
return
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 3,
|
|
||||||
})
|
|
||||||
|
|
||||||
newLine2 = new QLine([innerLine.endPoint.x, innerLine.endPoint.y, line.x2, line.y2], {
|
|
||||||
fontSize: polygon.fontSize,
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 3,
|
|
||||||
})
|
|
||||||
delIndexs.push(polygonLines.indexOf(line))
|
|
||||||
canvas.remove(polygonLines[polygonLines.indexOf(line)])
|
|
||||||
if (newLine1.length / 10 > 10) {
|
|
||||||
newLines.push(newLine1)
|
|
||||||
}
|
|
||||||
if (newLine2.length / 10 > 10) {
|
|
||||||
newLines.push(newLine2)
|
|
||||||
}
|
}
|
||||||
|
intersections.push(innerLine.endPoint)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
line.set({ intersections })
|
||||||
})
|
})
|
||||||
polygonLines = polygonLines.filter((line) => !delIndexs.includes(line.tempIndex))
|
|
||||||
|
const divideLines = polygonLines.filter((line) => line.intersections.length > 0)
|
||||||
|
let newLines = []
|
||||||
|
divideLines.forEach((line) => {
|
||||||
|
const { intersections, startPoint, endPoint } = line
|
||||||
|
|
||||||
|
if (intersections.length === 1) {
|
||||||
|
// 한 점만 교차하는 경우
|
||||||
|
const newLinePoint1 = [line.x1, line.y1, intersections[0].x, intersections[0].y]
|
||||||
|
const newLinePoint2 = [intersections[0].x, intersections[0].y, line.x2, line.y2]
|
||||||
|
const newLine1 = new QLine(newLinePoint1, {
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 3,
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
attributes: line.attributes,
|
||||||
|
})
|
||||||
|
const newLine2 = new QLine(newLinePoint2, {
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 3,
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
attributes: line.attributes,
|
||||||
|
})
|
||||||
|
newLine1.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
planeSize: Math.round(Math.sqrt(Math.pow(newLine1.x1 - newLine1.x2, 2) + Math.pow(newLine1.y1 - newLine1.y2, 2))) * 10,
|
||||||
|
actualSize: Math.round(Math.sqrt(Math.pow(newLine1.x1 - newLine1.x2, 2) + Math.pow(newLine1.y1 - newLine1.y2, 2))) * 10,
|
||||||
|
}
|
||||||
|
newLine2.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
planeSize: Math.round(Math.sqrt(Math.pow(newLine2.x1 - newLine2.x2, 2) + Math.pow(newLine2.y1 - newLine2.y2, 2))) * 10,
|
||||||
|
actualSize: Math.round(Math.sqrt(Math.pow(newLine2.x1 - newLine2.x2, 2) + Math.pow(newLine2.y1 - newLine2.y2, 2))) * 10,
|
||||||
|
}
|
||||||
|
newLines.push(newLine1)
|
||||||
|
newLines.push(newLine2)
|
||||||
|
} else {
|
||||||
|
// 두 점 이상 교차하는 경우
|
||||||
|
//1. intersections중에 startPoint와 가장 가까운 점을 찾는다.
|
||||||
|
//2. 가장 가까운 점을 기준으로 line을 나눈다.
|
||||||
|
|
||||||
|
let currentPoint = startPoint
|
||||||
|
|
||||||
|
while (intersections.length !== 0) {
|
||||||
|
const minDistancePoint = findAndRemoveClosestPoint(currentPoint, intersections)
|
||||||
|
const newLinePoint = [currentPoint.x, currentPoint.y, minDistancePoint.x, minDistancePoint.y]
|
||||||
|
const newLine = new QLine(newLinePoint, {
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 3,
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
attributes: line.attributes,
|
||||||
|
})
|
||||||
|
newLine.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
planeSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
|
||||||
|
actualSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
|
||||||
|
}
|
||||||
|
newLines.push(newLine)
|
||||||
|
currentPoint = minDistancePoint
|
||||||
|
}
|
||||||
|
|
||||||
|
const newLinePoint = [currentPoint.x, currentPoint.y, endPoint.x, endPoint.y]
|
||||||
|
const newLine = new QLine(newLinePoint, {
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 3,
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
attributes: line.attributes,
|
||||||
|
})
|
||||||
|
newLine.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
planeSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
|
||||||
|
actualSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
|
||||||
|
}
|
||||||
|
newLines.push(newLine)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//polygonLines에서 divideLines를 제거하고 newLines를 추가한다.
|
||||||
|
polygonLines = polygonLines.filter((line) => !divideLines.includes(line))
|
||||||
polygonLines = [...polygonLines, ...newLines]
|
polygonLines = [...polygonLines, ...newLines]
|
||||||
|
|
||||||
const allLines = [...polygonLines, ...innerLines]
|
const allLines = [...polygonLines, ...innerLines]
|
||||||
@ -756,6 +801,9 @@ export const usePolygon = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
polygonLines.forEach((line) => {
|
polygonLines.forEach((line) => {
|
||||||
|
line.set({ strokeWidth: 5, stroke: 'green' })
|
||||||
|
canvas.add(line)
|
||||||
|
canvas.renderAll()
|
||||||
const startPoint = line.startPoint // 시작점
|
const startPoint = line.startPoint // 시작점
|
||||||
let arrivalPoint = line.endPoint // 도착점
|
let arrivalPoint = line.endPoint // 도착점
|
||||||
|
|
||||||
@ -819,17 +867,18 @@ export const usePolygon = () => {
|
|||||||
roofPoints.push(currentPoint)
|
roofPoints.push(currentPoint)
|
||||||
cnt++
|
cnt++
|
||||||
if (cnt > 100) {
|
if (cnt > 100) {
|
||||||
throw new Error('무한루프')
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
roofs.push(roofPoints)
|
roofs.push(roofPoints)
|
||||||
|
canvas.remove(line)
|
||||||
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
const newRoofs = removeDuplicatePolygons(roofs)
|
const newRoofs = removeDuplicatePolygons(roofs.filter((roof) => roof.length < 100))
|
||||||
|
|
||||||
newRoofs.forEach((roofPoint, index) => {
|
newRoofs.forEach((roofPoint, index) => {
|
||||||
let defense, pitch
|
let defense, pitch
|
||||||
const polygonLines = [...polygon.lines]
|
|
||||||
|
|
||||||
let representLines = []
|
let representLines = []
|
||||||
let representLine
|
let representLine
|
||||||
@ -901,7 +950,7 @@ export const usePolygon = () => {
|
|||||||
|
|
||||||
//allLines중 생성된 roof와 관련있는 line을 찾는다.
|
//allLines중 생성된 roof와 관련있는 line을 찾는다.
|
||||||
|
|
||||||
roof.lines = [...polygon.lines, ...polygon.innerLines].filter((line) => {
|
roof.lines = [...polygonLines, ...polygon.innerLines].filter((line) => {
|
||||||
let startFlag = false
|
let startFlag = false
|
||||||
let endFlag = false
|
let endFlag = false
|
||||||
const startPoint = line.startPoint
|
const startPoint = line.startPoint
|
||||||
|
|||||||
@ -831,10 +831,10 @@
|
|||||||
"estimate.detail.header.fileList2": "添付ファイル一覧",
|
"estimate.detail.header.fileList2": "添付ファイル一覧",
|
||||||
"estimate.detail.header.specialEstimate": "見積もりの具体的な",
|
"estimate.detail.header.specialEstimate": "見積もりの具体的な",
|
||||||
"estimate.detail.header.specialEstimateProductInfo": "製品情報",
|
"estimate.detail.header.specialEstimateProductInfo": "製品情報",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.totPcs": "数量 (PCS)",
|
"estimate.detail.sepcialEstimateProductInfo.totAmount": "数量 (PCS)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.vol": "容量 (Kw)",
|
"estimate.detail.sepcialEstimateProductInfo.totVolKw": "容量 (Kw)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.netAmt": "供給価格",
|
"estimate.detail.sepcialEstimateProductInfo.supplyPrice": "供給価格",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.vat": "付加価値税 (10%)",
|
"estimate.detail.sepcialEstimateProductInfo.vatPrice": "付加価値税 (10%)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.totPrice": "総額",
|
"estimate.detail.sepcialEstimateProductInfo.totPrice": "総額",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価 (W)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価 (W)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG容量 (Kw)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG容量 (Kw)",
|
||||||
|
|||||||
@ -841,10 +841,10 @@
|
|||||||
"estimate.detail.header.fileList2": "첨부파일 목록",
|
"estimate.detail.header.fileList2": "첨부파일 목록",
|
||||||
"estimate.detail.header.specialEstimate": "견적특이사항",
|
"estimate.detail.header.specialEstimate": "견적특이사항",
|
||||||
"estimate.detail.header.specialEstimateProductInfo": "제품정보",
|
"estimate.detail.header.specialEstimateProductInfo": "제품정보",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.totPcs": "수량 (PCS)",
|
"estimate.detail.sepcialEstimateProductInfo.totAmount": "수량 (PCS)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.vol": "용량 (Kw)",
|
"estimate.detail.sepcialEstimateProductInfo.totVolKw": "용량 (Kw)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.netAmt": "공급가액",
|
"estimate.detail.sepcialEstimateProductInfo.supplyPrice": "공급가액",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.vat": "부가세 (10%)",
|
"estimate.detail.sepcialEstimateProductInfo.vatPrice": "부가세 (10%)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.totPrice": "총액",
|
"estimate.detail.sepcialEstimateProductInfo.totPrice": "총액",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "주택PKG단가 (W)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "주택PKG단가 (W)",
|
||||||
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG 용량 (Kw)",
|
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG 용량 (Kw)",
|
||||||
|
|||||||
@ -977,3 +977,27 @@ export const getDegreeInOrientation = (degree) => {
|
|||||||
|
|
||||||
return value * 15
|
return value * 15
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function findAndRemoveClosestPoint(targetPoint, points) {
|
||||||
|
if (points.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let closestPoint = points[0]
|
||||||
|
let closestDistance = distanceBetweenPoints(targetPoint, points[0])
|
||||||
|
let closestIndex = 0
|
||||||
|
|
||||||
|
for (let i = 1; i < points.length; i++) {
|
||||||
|
const distance = distanceBetweenPoints(targetPoint, points[i])
|
||||||
|
if (distance < closestDistance) {
|
||||||
|
closestDistance = distance
|
||||||
|
closestPoint = points[i]
|
||||||
|
closestIndex = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the closest point from the array
|
||||||
|
points.splice(closestIndex, 1)
|
||||||
|
|
||||||
|
return closestPoint
|
||||||
|
}
|
||||||
|
|||||||
@ -2949,7 +2949,8 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
|
|||||||
gable3.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
|
gable3.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
|
||||||
gable3.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
|
gable3.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
|
||||||
canvas?.add(gable3)
|
canvas?.add(gable3)
|
||||||
roof.innerLines.push(gable3)
|
|
||||||
|
// roof.innerLines.push(gable3)
|
||||||
|
|
||||||
const hip1 = new QLine([currentRoof.x1, currentRoof.y1, gable1.x1, gable1.y1], {
|
const hip1 = new QLine([currentRoof.x1, currentRoof.y1, gable1.x1, gable1.y1], {
|
||||||
fontSize: roof.fontSize,
|
fontSize: roof.fontSize,
|
||||||
@ -2967,7 +2968,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
|
|||||||
hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
|
hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
|
||||||
hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
|
hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
|
||||||
canvas?.add(hip1)
|
canvas?.add(hip1)
|
||||||
roof.innerLines.push(hip1)
|
// roof.innerLines.push(hip1)
|
||||||
|
|
||||||
const hip2 = new QLine([currentRoof.x2, currentRoof.y2, gable2.x1, gable2.y1], {
|
const hip2 = new QLine([currentRoof.x2, currentRoof.y2, gable2.x1, gable2.y1], {
|
||||||
fontSize: roof.fontSize,
|
fontSize: roof.fontSize,
|
||||||
@ -2985,7 +2986,14 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
|
|||||||
hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
|
hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
|
||||||
hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
|
hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
|
||||||
canvas?.add(hip2)
|
canvas?.add(hip2)
|
||||||
roof.innerLines.push(hip2)
|
// roof.innerLines.push(hip2)
|
||||||
|
|
||||||
|
hip1.set({ visible: false })
|
||||||
|
hip1.setViewLengthText(false)
|
||||||
|
gable3.set({ visible: false })
|
||||||
|
gable3.setViewLengthText(false)
|
||||||
|
hip2.set({ visible: false })
|
||||||
|
hip2.setViewLengthText(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user