Merge branch 'dev' into feature/design-remake

This commit is contained in:
Jaeyoung Lee 2026-01-09 17:15:59 +09:00
commit 1ccabd3efb
11 changed files with 128 additions and 89 deletions

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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 = '')}

View File

@ -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' }))
}}

View File

@ -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

View File

@ -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()
}
/**

View File

@ -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

View File

@ -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)
})

View File

@ -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": "パスワードを入力してください。",

View File

@ -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++) {