diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index 66d149ac..80b34f9f 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -234,6 +234,7 @@ export default function Login() { onBlur={() => setSecFocus(false)} /> @@ -1767,7 +1870,7 @@ export default function StuffDetail() { TEMP상세:{getMessage('stuff.detail.btn.save')} )} - + diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 0326f28e..1822140e 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -128,7 +128,6 @@ export default function StuffSearchCondition() { useEffect(() => { if (isObjectNotEmpty(sessionState)) { // storeId가 T01 이거나 1차점일때만 판매대리점 선택 활성화 - // get({ url: `/api/object/saleStore/TEMP02/list` }).then((res) => { get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => { if (!isEmptyArray(res)) { res.map((row) => { diff --git a/src/hooks/common/useCanvasConfigInitialize.js b/src/hooks/common/useCanvasConfigInitialize.js new file mode 100644 index 00000000..7421c53f --- /dev/null +++ b/src/hooks/common/useCanvasConfigInitialize.js @@ -0,0 +1,32 @@ +import { use, useEffect } from 'react' +import { useRecoilValue } from 'recoil' +import { settingModalFirstOptionsState } from '@/store/settingAtom' +import { canvasState } from '@/store/canvasAtom' +import { setSurfaceShapePattern } from '@/util/canvas-util' + +export function useCanvasConfigInitialize() { + const canvas = useRecoilValue(canvasState) + const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState) + + const canvasLoadInit = () => { + roofInit() //화면표시 초기화 + } + + //치수표시, 화면표시, 글꼴등 초기화 + const roofInit = () => { + if (canvas) { + const roofDisplay = settingModalFirstOptions.option2.filter((item) => item.selected) + + canvas + .getObjects() + .filter((polygon) => polygon.name === 'roof') + .forEach((polygon) => { + setSurfaceShapePattern(polygon, roofDisplay[0].column) + }) + + canvas.renderAll() + } + } + + return { canvasLoadInit } +} diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index dd92253d..8d0412c1 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -2,13 +2,18 @@ import { useEffect } from 'react' import { useRecoilValue } from 'recoil' import { wordDisplaySelector } from '@/store/settingAtom' import { useEvent } from '@/hooks/useEvent' -import { checkLineOrientation, getDistance } from '@/util/canvas-util' +import { checkLineOrientation, getDistance, setSurfaceShapePattern } from '@/util/canvas-util' import { dimensionLineSettingsState } from '@/store/commonUtilsAtom' +import { fontSelector } from '@/store/fontAtom' +import { canvasState } from '@/store/canvasAtom' -export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionState }) { +export function useCommonUtils({ commonFunctionState, setCommonFunctionState }) { + const canvas = useRecoilValue(canvasState) const wordDisplay = useRecoilValue(wordDisplaySelector) const { addCanvasMouseEventListener, addDocumentEventListener, initEvent } = useEvent() const dimensionSettings = useRecoilValue(dimensionLineSettingsState) + const dimensionLineTextFont = useRecoilValue(fontSelector('dimensionLineText')) + const commonTextFont = useRecoilValue(fontSelector('commonText')) useEffect(() => { initEvent() @@ -19,7 +24,7 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS } else if (commonFunctionState.distance) { commonDistanceMode() } - }, [commonFunctionState, dimensionSettings]) + }, [commonFunctionState, dimensionSettings, commonTextFont, dimensionLineTextFont]) const commonTextMode = () => { let textbox @@ -30,10 +35,13 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS left: pointer.x, top: pointer.y, width: 200, - fontSize: 14, editable: true, name: 'commonText', visible: wordDisplay, + fill: commonTextFont.fontColor.value, + fontFamily: commonTextFont.fontFamily.value, + fontSize: commonTextFont.fontSize.value, + fontStyle: commonTextFont.fontWeight.value, }) canvas?.add(textbox) @@ -187,21 +195,19 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS canvas.add(arrow1) canvas.add(arrow2) - console.log(dimensionSettings) - - // 거리 텍스트가 이미 있으면 업데이트하고, 없으면 새로 생성 distanceText = new fabric.Text(`${distance * 10} `, { left: (p1CenterX + p2CenterX) / 2 + (lineDirection === 'horizontal' ? 0 : -15), top: (p1CenterY + p2CenterY) / 2 + (lineDirection === 'horizontal' ? +15 : 0), - fill: dimensionSettings.fontColor, - fontSize: dimensionSettings.fontSize, - // fontFamily : dimensionSettings.font, //폰트 - // fontStyle : dimensionSettings.fontStyle, //폰트스타일 + fill: dimensionLineTextFont.fontColor.value, + fontSize: dimensionLineTextFont.fontSize.value, + fontFamily: dimensionLineTextFont.fontFamily.value, + fontStyle: dimensionLineTextFont.fontWeight.value, selectable: true, textAlign: 'center', originX: 'center', originY: 'center', angle: lineDirection === 'horizontal' ? 0 : 270, + name: 'dimensionLineText', // lockMovementX: false, // lockMovementY: false, }) @@ -272,50 +278,70 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS addCanvasMouseEventListener('mouse:down', function (options) { const pointer = canvas.getPointer(options.e) let point + let cross = {} if (points.length === 0) { - // 첫 번째 포인트는 그대로 클릭한 위치에 추가 - point = new fabric.Circle({ - left: pointer.x - 5, // 반지름 반영 - top: pointer.y - 5, // 반지름 반영 - ...circleOptions, + point = new fabric.Line([pointer.x - 10, pointer.y, pointer.x + 10, pointer.y], { + stroke: 'black', + strokeWidth: 1, + originX: 'center', + originY: 'center', }) - points.push(point) canvas.add(point) + cross['x'] = parseInt(point.left.toFixed(0)) + + // 세로 선 생성 (십자 모양의 다른 축) + point = new fabric.Line([pointer.x, pointer.y - 10, pointer.x, pointer.y + 10], { + stroke: 'black', + strokeWidth: 1, + originX: 'center', + originY: 'center', + }) + cross['y'] = parseInt(point.top.toFixed(0)) + + canvas.add(point) + points.push(cross) } else if (points.length === 1) { // 두 번째 포인트는 첫 번째 포인트를 기준으로 수평 또는 수직으로만 배치 const p1 = points[0] - point = new fabric.Circle({ - left: pointer.x - 5, // 반지름 반영 - top: pointer.y - 5, // 반지름 반영 - ...circleOptions, + point = new fabric.Line([pointer.x - 10, pointer.y, pointer.x + 10, pointer.y], { + stroke: 'black', + strokeWidth: 1, + originX: 'center', + originY: 'center', }) - - points.push(point) canvas.add(point) + cross['x'] = parseInt(point.left.toFixed(0)) + // 세로 선 생성 (십자 모양의 다른 축) + point = new fabric.Line([pointer.x, pointer.y - 10, pointer.x, pointer.y + 10], { + stroke: 'black', + strokeWidth: 1, + originX: 'center', + originY: 'center', + }) + canvas.add(point) + cross['y'] = parseInt(point.top.toFixed(0)) + points.push(cross) + + let isParallel = false + + if (points[0].x === points[1].x || points[0].y === points[1].y) { + isParallel = true + } // 두 포인트의 중심 좌표 계산 const p2 = points[1] - const p1CenterX = p1.left + p1.radius - const p1CenterY = p1.top + p1.radius - const p2CenterX = p2.left + p2.radius - const p2CenterY = p2.top + p2.radius - - const p3 = new fabric.Point(p2CenterX, p1CenterY) + const p1CenterX = p1.x + const p1CenterY = p1.y + const p2CenterX = p2.x + const p2CenterY = p2.y // 두 포인트 간에 직선을 그림 (중심을 기준으로) const line = new fabric.Line([p1CenterX, p1CenterY, p2CenterX, p2CenterY], lineOptions) - const line2 = new fabric.Line([p2CenterX, p2CenterY, p3.x, p3.y], lineOptions) - const line3 = new fabric.Line([p3.x, p3.y, p1CenterX, p1CenterY], lineOptions) canvas.add(line) - canvas.add(line2) - canvas.add(line3) - const distance1 = getDistance(p1CenterX, p1CenterY, p2CenterX, p2CenterY) - const distance2 = getDistance(p2CenterX, p2CenterY, p3.x, p3.y) - const distance3 = getDistance(p3.x, p3.y, p1CenterX, p1CenterY) // 거리 텍스트가 이미 있으면 업데이트하고, 없으면 새로 생성 distanceText = new fabric.Text(`${distance1 * 10}`, { @@ -324,18 +350,28 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS ...textOptions, }) canvas.add(distanceText) - distanceText = new fabric.Text(`${distance2 * 10}`, { - left: (p2CenterX + p3.x) / 2, - top: (p2CenterY + p3.y) / 2, - ...textOptions, - }) - canvas.add(distanceText) - distanceText = new fabric.Text(`${distance3 * 10}`, { - left: (p3.x + p1CenterX) / 2, - top: (p3.y + p1CenterY) / 2, - ...textOptions, - }) - canvas.add(distanceText) + + if (!isParallel) { + const p3 = new fabric.Point(p2CenterX, p1CenterY) + const line2 = new fabric.Line([p2CenterX, p2CenterY, p3.x, p3.y], lineOptions) + const line3 = new fabric.Line([p3.x, p3.y, p1CenterX, p1CenterY], lineOptions) + canvas.add(line2) + canvas.add(line3) + const distance2 = getDistance(p2CenterX, p2CenterY, p3.x, p3.y) + const distance3 = getDistance(p3.x, p3.y, p1CenterX, p1CenterY) + distanceText = new fabric.Text(`${distance2 * 10}`, { + left: (p2CenterX + p3.x) / 2, + top: (p2CenterY + p3.y) / 2, + ...textOptions, + }) + canvas.add(distanceText) + distanceText = new fabric.Text(`${distance3 * 10}`, { + left: (p3.x + p1CenterX) / 2, + top: (p3.y + p1CenterY) / 2, + ...textOptions, + }) + canvas.add(distanceText) + } // 거리 계산 후, 다음 측정을 위해 초기화 points = [] @@ -361,7 +397,7 @@ export function useCommonUtils({ canvas, commonFunctionState, setCommonFunctionS } } - setCommonFunctionState(tempStates) + if (setCommonFunctionState) setCommonFunctionState(tempStates) } return { diff --git a/src/hooks/common/useFont.js b/src/hooks/common/useFont.js index 383997a0..28c78f14 100644 --- a/src/hooks/common/useFont.js +++ b/src/hooks/common/useFont.js @@ -11,9 +11,35 @@ export function useFont() { const lengthText = useRecoilValue(fontSelector('lengthText')) const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText')) - useEffect(() => {}, [commonText]) + useEffect(() => { + if (canvas) { + const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'commonText') + textObjs.forEach((obj) => { + obj.set({ + fontFamily: commonText.fontFamily.value, + fontWeight: commonText.fontWeight.value, + fontSize: commonText.fontSize.value, + fill: commonText.fontColor.value, + }) + }) + canvas.renderAll() + } + }, [commonText]) - useEffect(() => {}, [dimensionLineText]) + useEffect(() => { + if (canvas) { + const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'dimensionLineText') + textObjs.forEach((obj) => { + obj.set({ + fontFamily: dimensionLineText.fontFamily.value, + fontWeight: dimensionLineText.fontWeight.value, + fontSize: dimensionLineText.fontSize.value, + fill: dimensionLineText.fontColor.value, + }) + }) + canvas.renderAll() + } + }, [dimensionLineText]) useEffect(() => { if (canvas) { diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 26d26339..19b9a879 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -290,12 +290,12 @@ export function usePlan() { addPlan(userId, objectNo, currentCanvasData()) }, denyFn: () => { - addPlan(userId, objectNo) + addPlan(userId, objectNo, '') }, }) - : addPlan(userId, objectNo) + : addPlan(userId, objectNo, '') } - const addPlan = (userId, objectNo, canvasStatus = '') => { + const addPlan = (userId, objectNo, canvasStatus) => { const id = uuidv4() const newPlan = { id: id, diff --git a/src/locales/ja.json b/src/locales/ja.json index 521f4ac6..5a93188a 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -516,6 +516,8 @@ "stuff.detail.btn.moveList": "商品リスト", "stuff.detail.btn.save": "保存", "stuff.detail.btn.tempSave": "一時保存", + "stuff.detail.save.valierror1": "垂直説説は0より大きい値を入力してください", + "stuff.detail.save.valierror2": "設置高さ0より大きい値を入力してください", "stuff.planReqPopup.popTitle": "設計依頼検索", "stuff.planReqPopup.btn1": "検索", "stuff.planReqPopup.btn2": "初期化", diff --git a/src/locales/ko.json b/src/locales/ko.json index 693d94b4..651e8473 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -521,6 +521,8 @@ "stuff.detail.btn.moveList": "물건목록", "stuff.detail.btn.save": "저장", "stuff.detail.btn.tempSave": "임시저장", + "stuff.detail.save.valierror1": "수직적설량은 0보다 큰 값을 입력하세요", + "stuff.detail.save.valierror2": "설치높이는 0보다 큰 값을 입력하세요", "stuff.planReqPopup.popTitle": "설계 요청 검색", "stuff.planReqPopup.btn1": "검색", "stuff.planReqPopup.btn2": "초기화",