Merge branch 'dev' into feature/design-remake
This commit is contained in:
commit
1ccabd3efb
@ -340,13 +340,19 @@ export const CalculatorInput = forwardRef(
|
||||
|
||||
// Tab 키는 계산기 숨기고 기본 동작 허용
|
||||
if (e.key === 'Tab') {
|
||||
if (hasOperation) {
|
||||
handleCompute(true) // 계산 수행
|
||||
}
|
||||
setShowKeypad(false)
|
||||
return
|
||||
}
|
||||
|
||||
// 모든 방향키는 기본 동작 허용
|
||||
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight' || e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
||||
setShowKeypad(true)
|
||||
if (hasOperation) {
|
||||
handleCompute(true) // 계산 수행
|
||||
}
|
||||
setShowKeypad(false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -360,6 +366,12 @@ export const CalculatorInput = forwardRef(
|
||||
return
|
||||
}
|
||||
|
||||
// --- 여기서부터는 브라우저의 기본 입력을 막고 계산기 로직만 적용함 ---
|
||||
if (e.key !== 'Process') { // 한글 입력 등 특수 상황 방지 (필요시)
|
||||
// e.preventDefault() 호출 위치를 확인하세요.
|
||||
}
|
||||
|
||||
|
||||
e.preventDefault()
|
||||
const calculator = calculatorRef.current
|
||||
const { allowDecimal } = options
|
||||
|
||||
@ -1465,19 +1465,19 @@ export default function Estimate({}) {
|
||||
: 'none',
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="estimateType"
|
||||
id="YJSS"
|
||||
value={'YJSS'}
|
||||
checked={estimateContextState?.estimateType === 'YJSS' ? true : false}
|
||||
onChange={(e) => {
|
||||
//주문분류
|
||||
setHandlePricingFlag(true)
|
||||
setEstimateContextState({ estimateType: e.target.value, setEstimateContextState })
|
||||
}}
|
||||
/>
|
||||
<label htmlFor="YJSS">{getMessage('estimate.detail.estimateType.yjss')}</label>
|
||||
{/*<input*/}
|
||||
{/* type="radio"*/}
|
||||
{/* name="estimateType"*/}
|
||||
{/* id="YJSS"*/}
|
||||
{/* value={'YJSS'}*/}
|
||||
{/* checked={estimateContextState?.estimateType === 'YJSS' ? true : false}*/}
|
||||
{/* onChange={(e) => {*/}
|
||||
{/* //주문분류*/}
|
||||
{/* setHandlePricingFlag(true)*/}
|
||||
{/* setEstimateContextState({ estimateType: e.target.value, setEstimateContextState })*/}
|
||||
{/* }}*/}
|
||||
{/*/>*/}
|
||||
{/*<label htmlFor="YJSS">{getMessage('estimate.detail.estimateType.yjss')}</label>*/}
|
||||
</div>
|
||||
<div className="d-check-radio light">
|
||||
<input
|
||||
|
||||
@ -72,13 +72,17 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
||||
|
||||
setLength() {
|
||||
// Ensure all required properties are valid numbers
|
||||
const { x1, y1, x2, y2 } = this;
|
||||
const { x1, y1, x2, y2 } = this
|
||||
if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2)) {
|
||||
logger.error('Invalid coordinates in QLine:', { x1, y1, x2, y2 });
|
||||
this.length = 0;
|
||||
return;
|
||||
logger.error('Invalid coordinates in QLine:', { x1, y1, x2, y2 })
|
||||
this.length = 0
|
||||
return
|
||||
}
|
||||
this.length = calcLinePlaneSize({ x1, y1, x2, y2 }) / 10;
|
||||
this.length = calcLinePlaneSize({ x1, y1, x2, y2 }) / 10
|
||||
},
|
||||
|
||||
setLengthByValue(length) {
|
||||
this.length = length / 10
|
||||
},
|
||||
|
||||
addLengthText() {
|
||||
|
||||
@ -26,17 +26,15 @@ export default function DoublePitch({ props }) {
|
||||
arrow2Ref,
|
||||
} = props
|
||||
|
||||
const getLength2 = () => {
|
||||
const angle1Value = angle1Ref.current.value
|
||||
const angle2Value = angle2Ref.current.value
|
||||
const length1Value = length1Ref.current.value
|
||||
const getLength2 = (angle1, angle2, length1) => {
|
||||
const angle1Value = angle1 !== undefined ? angle1 : angle1Ref.current?.value
|
||||
const angle2Value = angle2 !== undefined ? angle2 : angle2Ref.current?.value
|
||||
const length1Value = length1 !== undefined ? length1 : length1Ref.current?.value
|
||||
|
||||
const arrow1Value = arrow1Ref.current
|
||||
const arrow2Value = arrow2Ref.current
|
||||
|
||||
if (angle1Value !== 0 && length1Value !== 0 && angle2Value !== 0 && arrow1Value !== '') {
|
||||
if (!isNaN(Number(angle1Value)) && !isNaN(Number(length1Value)) && !isNaN(Number(angle2Value)) && arrow1Value) {
|
||||
const radian1 = (getDegreeByChon(angle1Value) * Math.PI) / 180
|
||||
|
||||
const radian2 = (getDegreeByChon(angle2Value) * Math.PI) / 180
|
||||
return Math.floor((Math.tan(radian1) * length1Value) / Math.tan(radian2))
|
||||
}
|
||||
@ -178,7 +176,7 @@ export default function DoublePitch({ props }) {
|
||||
ref={angle2Ref}
|
||||
onChange={(value) => {
|
||||
setAngle2(value)
|
||||
setLength2(getLength2())
|
||||
setLength2(getLength2(angle1Ref.current?.value, value, length1Ref.current?.value))
|
||||
}}
|
||||
placeholder="45"
|
||||
onFocus={() => (angle2Ref.current.value = '')}
|
||||
|
||||
@ -61,28 +61,40 @@ export default function RightAngle({ props }) {
|
||||
<div className="grid-direction">
|
||||
<button
|
||||
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault(); // 포커스가 input에서 버튼으로 옮겨가는 것을 원천 차단
|
||||
}}
|
||||
onClick={(e) => {
|
||||
setArrow1('↑')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault(); // 포커스가 input에서 버튼으로 옮겨가는 것을 원천 차단
|
||||
}}
|
||||
onClick={(e) => {
|
||||
setArrow1('↓')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault(); // 포커스가 input에서 버튼으로 옮겨가는 것을 원천 차단
|
||||
}}
|
||||
onClick={(e) => {
|
||||
setArrow1('←')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
|
||||
onClick={() => {
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault(); // 포커스가 input에서 버튼으로 옮겨가는 것을 원천 차단
|
||||
}}
|
||||
onClick={(e) => {
|
||||
setArrow1('→')
|
||||
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
|
||||
}}
|
||||
|
||||
@ -44,6 +44,9 @@ export const useTrestle = () => {
|
||||
// exposedBottomPoints는 노출 최하면 들의 centerPoint 배열.
|
||||
|
||||
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
||||
surfaces.forEach((surface) => {
|
||||
surface.set({ quotationParam: null })
|
||||
})
|
||||
// 기존 eaveBar를 삭제
|
||||
canvas.getObjects().forEach((obj) => {
|
||||
if (obj.name === 'eaveBar' || obj.name === 'rack' || obj.name === 'halfEaveBar' || obj.name === 'smartRack') {
|
||||
@ -744,18 +747,17 @@ export const useTrestle = () => {
|
||||
return
|
||||
}
|
||||
//itemList = data
|
||||
// itemList에 northModuleYn 추가
|
||||
itemList = data.map(item => {
|
||||
if (item.itemTpCd === "MODULE") {
|
||||
const matchedModule = modules.find(module => module.moduleItemId === item.itemId);
|
||||
// itemList에 northModuleYn 추가
|
||||
itemList = data.map((item) => {
|
||||
if (item.itemTpCd === 'MODULE') {
|
||||
const matchedModule = modules.find((module) => module.moduleItemId === item.itemId)
|
||||
return {
|
||||
...item,
|
||||
northModuleYn: matchedModule?.northModuleYn || 'N'
|
||||
};
|
||||
northModuleYn: matchedModule?.northModuleYn || 'N',
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
return item
|
||||
})
|
||||
|
||||
//northArrangement 북면 설치 여부
|
||||
const northArrangement = getNorthArrangement()
|
||||
@ -820,11 +822,11 @@ export const useTrestle = () => {
|
||||
// 발전 시뮬레이션 용 각도 재계산
|
||||
const getAzimuth = (parent) => {
|
||||
if (typeof parent === 'string') {
|
||||
console.warn('getAzimuth: parent is string, expected object', parent);
|
||||
return 0; // 또는 적절한 기본값
|
||||
console.warn('getAzimuth: parent is string, expected object', parent)
|
||||
return 0 // 또는 적절한 기본값
|
||||
}
|
||||
|
||||
const { moduleCompass, surfaceCompass, direction } = parent || {};
|
||||
const { moduleCompass, surfaceCompass, direction } = parent || {}
|
||||
|
||||
if (surfaceCompass) {
|
||||
return -surfaceCompass
|
||||
@ -2603,7 +2605,7 @@ export const useTrestle = () => {
|
||||
return {
|
||||
moduleTpCd: module.moduleInfo.itemTp,
|
||||
moduleItemId: module.moduleInfo.itemId,
|
||||
northModuleYn: module?.moduleInfo?.northModuleYn || 'N' // 기본값 'N'
|
||||
northModuleYn: module?.moduleInfo?.northModuleYn || 'N', // 기본값 'N'
|
||||
}
|
||||
})
|
||||
|
||||
@ -2615,7 +2617,7 @@ export const useTrestle = () => {
|
||||
moduleTpCd: cur.moduleTpCd,
|
||||
moduleItemId: cur.moduleItemId,
|
||||
cnt: 0,
|
||||
northModuleYn: cur.northModuleYn
|
||||
northModuleYn: cur.northModuleYn,
|
||||
}
|
||||
}
|
||||
acc[key].cnt++
|
||||
@ -2628,7 +2630,7 @@ export const useTrestle = () => {
|
||||
moduleTpCd: groupedParam.moduleTpCd,
|
||||
moduleItemId: groupedParam.moduleItemId,
|
||||
moduleCnt: groupedParam.cnt,
|
||||
northModuleYn: groupedParam.northModuleYn
|
||||
northModuleYn: groupedParam.northModuleYn,
|
||||
// northModuleYn: params.find(p =>
|
||||
// p.moduleTpCd === groupedParam.moduleTpCd &&
|
||||
// p.moduleItemId === groupedParam.moduleItemId
|
||||
|
||||
@ -185,7 +185,7 @@ export function useRoofAllocationSetting(id) {
|
||||
})
|
||||
}
|
||||
|
||||
const firstRes = Array.isArray(res) && res.length > 0 ? res[0] : null
|
||||
const firstRes = Array.isArray(response) && response.length > 0 ? response[0] : null
|
||||
|
||||
setBasicSetting({
|
||||
...basicSetting,
|
||||
@ -323,42 +323,19 @@ export function useRoofAllocationSetting(id) {
|
||||
}
|
||||
|
||||
const drawOriginRoofLine = () => {
|
||||
// outerLinePoints 배열을 이용하여 빨간색 Line 객체들 생성
|
||||
if (outerLinePoints && outerLinePoints.length > 1) {
|
||||
// 연속된 점들을 연결하여 라인 생성
|
||||
for (let i = 0; i < outerLinePoints.length - 1; i++) {
|
||||
const point1 = outerLinePoints[i]
|
||||
const point2 = outerLinePoints[i + 1]
|
||||
|
||||
const line = new fabric.Line([point1.x, point1.y, point2.x, point2.y], {
|
||||
stroke: 'black',
|
||||
strokeDashArray: [5, 2],
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'originRoofOuterLine',
|
||||
visible: outlineDisplay,
|
||||
})
|
||||
|
||||
canvas.add(line)
|
||||
}
|
||||
|
||||
// 마지막 점과 첫 점을 연결하여 폐곡선 만들기
|
||||
if (outerLinePoints.length > 2) {
|
||||
const lastPoint = outerLinePoints[outerLinePoints.length - 1]
|
||||
const firstPoint = outerLinePoints[0]
|
||||
|
||||
const closingLine = new fabric.Line([lastPoint.x, lastPoint.y, firstPoint.x, firstPoint.y], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 2,
|
||||
selectable: false,
|
||||
name: 'originRoofOuterLine',
|
||||
})
|
||||
|
||||
canvas.add(closingLine)
|
||||
}
|
||||
|
||||
canvas.renderAll()
|
||||
}
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
/** 벽면 삭제 */
|
||||
wallLines.forEach((wallLine) => {
|
||||
wallLine.set({
|
||||
stroke: 'black',
|
||||
strokeDashArray: [5, 2],
|
||||
strokeWidth: 1,
|
||||
selectable: false,
|
||||
name: 'originRoofOuterLine',
|
||||
visible: outlineDisplay,
|
||||
})
|
||||
})
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
} from '@/store/canvasAtom'
|
||||
import { QLine } from '@/components/fabric/QLine'
|
||||
import { basicSettingState } from '@/store/settingAtom'
|
||||
import { calcLineActualSize } from '@/util/qpolygon-utils'
|
||||
import { calcLineActualSizeByLineLength } from '@/util/qpolygon-utils'
|
||||
import { getDegreeByChon } from '@/util/canvas-util'
|
||||
import { useText } from '@/hooks/useText'
|
||||
import { fontSelector } from '@/store/fontAtom'
|
||||
@ -181,7 +181,7 @@ export const useLine = () => {
|
||||
if (isVertical) {
|
||||
line.attributes = {
|
||||
...line.attributes,
|
||||
actualSize: calcLineActualSize(line, getDegreeByChon(pitch)),
|
||||
actualSize: calcLineActualSizeByLineLength(lineLength, getDegreeByChon(pitch)),
|
||||
}
|
||||
} else if (isDiagonal) {
|
||||
const yLength = Math.abs(y2 - y1) * 10
|
||||
@ -195,7 +195,7 @@ export const useLine = () => {
|
||||
if (isHorizontal) {
|
||||
line.attributes = {
|
||||
...line.attributes,
|
||||
actualSize: calcLineActualSize(line, getDegreeByChon(pitch)),
|
||||
actualSize: calcLineActualSizeByLineLength(lineLength, getDegreeByChon(pitch)),
|
||||
}
|
||||
} else if (isDiagonal) {
|
||||
const xLength = Math.abs(x2 - x1) * 10
|
||||
|
||||
@ -1380,6 +1380,8 @@ export const usePolygon = () => {
|
||||
// 나눠서 중복 제거된 roof return
|
||||
let newRoofs = getSplitRoofsPoints(allLines)
|
||||
|
||||
const createdRoofs = []
|
||||
|
||||
newRoofs = newRoofs.filter((roof) => roof.length !== 0)
|
||||
newRoofs.forEach((roofPoint, index) => {
|
||||
let defense, pitch
|
||||
@ -1622,8 +1624,8 @@ export const usePolygon = () => {
|
||||
})
|
||||
})
|
||||
|
||||
canvas.add(roof)
|
||||
addLengthText(roof)
|
||||
// canvas.add(roof)
|
||||
createdRoofs.push(roof)
|
||||
canvas.remove(polygon)
|
||||
canvas.renderAll()
|
||||
})
|
||||
@ -1633,6 +1635,11 @@ export const usePolygon = () => {
|
||||
auxiliaryLines.forEach((line) => {
|
||||
canvas.remove(line)
|
||||
})
|
||||
|
||||
createdRoofs.forEach((roof) => {
|
||||
canvas.add(roof)
|
||||
})
|
||||
|
||||
canvas.renderAll()
|
||||
canvas.discardActiveObject()
|
||||
}
|
||||
@ -1967,6 +1974,22 @@ export const usePolygon = () => {
|
||||
return
|
||||
}
|
||||
|
||||
// createdRoofs들의 모든 lines를 확인해서 length값이 1이하인 차이가 있으면 통일 시킨다.
|
||||
const allRoofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
const allRoofLines = allRoofs.flatMap((roof) => roof.lines)
|
||||
for (let i = 0; i < allRoofLines.length; i++) {
|
||||
for (let j = i + 1; j < allRoofLines.length; j++) {
|
||||
const line1 = allRoofLines[i]
|
||||
const line2 = allRoofLines[j]
|
||||
const diff = Math.abs(line1.length - line2.length)
|
||||
if (diff > 0 && diff <= 1) {
|
||||
const minLength = Math.min(line1.length, line2.length)
|
||||
line1.setLengthByValue(minLength * 10)
|
||||
line2.setLengthByValue(minLength * 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
polygon.lines.forEach((line) => {
|
||||
setActualSize(line, polygon.direction, +polygon.roofMaterial?.pitch)
|
||||
})
|
||||
|
||||
@ -656,7 +656,7 @@
|
||||
"myinfo.message.password.error": "パスワードが間違っています。",
|
||||
"login": "ログイン",
|
||||
"login.auto.page.text": "自動ログイン中です。",
|
||||
"login.fail": "계정이 없거나 비밀번호가 잘못되었습니다.",
|
||||
"login.fail": "アカウント未登録か、パスワードが正しくありません。",
|
||||
"login.id.save": "ID保存",
|
||||
"login.id.placeholder": "IDを入力してください。",
|
||||
"login.password.placeholder": "パスワードを入力してください。",
|
||||
|
||||
@ -5992,6 +5992,17 @@ export const calcLineActualSize = (points, degree = 0) => {
|
||||
return Big(planeSize).div(theta).round().toNumber()
|
||||
}
|
||||
|
||||
/**
|
||||
* 포인트와 기울기를 기준으로 선의 길이를 구한다.
|
||||
* @param lineLength
|
||||
* @param degree
|
||||
* @returns number
|
||||
*/
|
||||
export const calcLineActualSizeByLineLength = (lineLength, degree = 0) => {
|
||||
const theta = Big(Math.cos(Big(degree).times(Math.PI).div(180)))
|
||||
return Big(lineLength).div(theta).round().toNumber()
|
||||
}
|
||||
|
||||
export const createLinesFromPolygon = (points) => {
|
||||
const lines = []
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user