From 24b4556db7f20c6dbf441b9b95cb2a19e0dcd13a Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 17 Oct 2024 14:17:12 +0900 Subject: [PATCH 1/2] =?UTF-8?q?line,=20polygon=20=EB=B3=80=ED=99=98=20?= =?UTF-8?q?=EC=8B=9C=20=EA=B8=B8=EC=9D=B4=20=EC=95=88=EB=A7=9E=EB=8A=94=20?= =?UTF-8?q?=EA=B2=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/fabric/QLine.js | 4 +-- src/components/fabric/QPolygon.js | 4 +-- src/components/floor-plan/CanvasFrame.jsx | 4 --- src/components/floor-plan/CanvasMenu.jsx | 7 ++-- src/hooks/roofcover/useAuxiliaryDrawing.js | 32 ++++++++++++----- .../roofcover/useRoofAllocationSetting.js | 6 +++- .../roofcover/useRoofShapePassivitySetting.js | 35 ++++++++++++++++--- src/hooks/roofcover/useRoofShapeSetting.js | 9 +++-- src/hooks/useEvent.js | 1 - 9 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index ae3c6c62..616143fe 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -75,7 +75,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { const y2 = this.top + this.height * scaleY const dx = x2 - x1 const dy = y2 - y1 - this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) + this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) }, addLengthText() { @@ -150,7 +150,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { getLength() { //10배 곱해진 값 return - return Number(this.length.toFixed(1) * 10) + return Number(this.length.toFixed(0) * 10) }, setViewLengthText(bool) { diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 7c027c2f..64c897c6 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -199,7 +199,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { const end = points[(i + 1) % points.length] const dx = end.x - start.x const dy = end.y - start.y - const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10 + const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(0)) * 10 let midPoint @@ -224,7 +224,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { const degree = (Math.atan2(dy, dx) * 180) / Math.PI // Create new text object if it doesn't exist - const text = new fabric.Text(length.toFixed(0), { + const text = new fabric.Text(length.toString(), { left: midPoint.x, top: midPoint.y, fontSize: this.fontSize, diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index f34d1cb6..d6a4e179 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -13,11 +13,7 @@ export default function CanvasFrame({ plan }) { const canvasRef = useRef(null) const { canvas } = useCanvas('canvas') const { contextMenu, currentContextMenu, setCurrentContextMenu } = useContextMenu() - const currentObject = useRecoilValue(currentObjectState) - useEffect(() => { - console.log(currentObject) - }, [currentObject]) useEvent() const loadCanvas = () => { diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index ae8cc79d..96115d98 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -19,6 +19,7 @@ import { MENU } from '@/common/common' import KO from '@/locales/ko.json' import JA from '@/locales/ja.json' import { settingModalFirstOptionsState } from '@/store/settingAtom' +import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' const canvasMenus = [ { index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING }, @@ -58,7 +59,8 @@ export default function CanvasMenu(props) { const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState) const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore) const setCurrentMenu = useSetRecoilState(currentMenuState) - const setPoints = useSetRecoilState(outerLinePointsState) + const setOuterLinePoints = useSetRecoilState(outerLinePointsState) + const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState) const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState) @@ -140,7 +142,8 @@ export default function CanvasMenu(props) { } const handleClear = () => { - setPoints([]) + setOuterLinePoints([]) + setPlacementPoints([]) canvas?.clear() } diff --git a/src/hooks/roofcover/useAuxiliaryDrawing.js b/src/hooks/roofcover/useAuxiliaryDrawing.js index cb33f407..94a7e989 100644 --- a/src/hooks/roofcover/useAuxiliaryDrawing.js +++ b/src/hooks/roofcover/useAuxiliaryDrawing.js @@ -23,10 +23,11 @@ import { outerLineLength2State, outerLineTypeState, } from '@/store/outerLineAtom' -import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util' +import { calculateDistance, calculateIntersection, distanceBetweenPoints, findClosestPoint, polygonToTurfPolygon } from '@/util/canvas-util' import { fabric } from 'fabric' import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint' import { useSwal } from '@/hooks/useSwal' +import { booleanPointInPolygon } from '@turf/turf' // 보조선 작성 export function useAuxiliaryDrawing(setShowAuxiliaryModal) { @@ -76,6 +77,8 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) { useEffect(() => { typeRef.current = type + clear() + addDocumentEventListener('keydown', document, keydown[type]) }, [type]) useEffect(() => { @@ -103,12 +106,8 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) { } }, []) - useEffect(() => { - clear() - addDocumentEventListener('keydown', document, keydown[type]) - }, [type]) - const clear = () => { + addCanvasMouseEventListener('mouse:move', mouseMove) setLength1(0) setLength2(0) @@ -459,8 +458,9 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) { } const mouseDown = (e) => { - addCanvasMouseEventListener('mouse:move', mouseMove) + canvas.renderAll() const pointer = getIntersectMousePoint(e) + console.log(pointer) mousePointerArr.current.push(pointer) if (mousePointerArr.current.length === 2) { @@ -621,10 +621,24 @@ export function useAuxiliaryDrawing(setShowAuxiliaryModal) { return } - const roofBases = canvas.getObjects().find((obj) => obj.name === 'roofBase') + const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase') const innerLines = [...lineHistory.current] - roofBases.innerLines = [...innerLines] + roofBases.forEach((roofBase) => { + const roofInnerLines = innerLines.filter((line) => { + const turfPolygon = polygonToTurfPolygon(roofBase) + + // innerLines의 두 점이 모두 polygon 안에 있는지 확인 + const inPolygon1 = booleanPointInPolygon([line.x1, line.y1], turfPolygon) + const inPolygon2 = booleanPointInPolygon([line.x2, line.y2], turfPolygon) + + if (inPolygon1 && inPolygon2) { + return true + } + }) + + roofBase.innerLines = [...roofInnerLines] + }) setShowAuxiliaryModal(false) } diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 6533fe79..bc55c921 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -95,7 +95,11 @@ export function useRoofAllocationSetting(setShowRoofAllocationSettingModal) { const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase') const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine') roofBases.forEach((roofBase) => { - splitPolygonWithLines(roofBase) + try { + splitPolygonWithLines(roofBase) + } catch (e) { + return + } roofBase.innerLines.forEach((line) => { canvas.remove(line) diff --git a/src/hooks/roofcover/useRoofShapePassivitySetting.js b/src/hooks/roofcover/useRoofShapePassivitySetting.js index 217e71bc..83ecf7ed 100644 --- a/src/hooks/roofcover/useRoofShapePassivitySetting.js +++ b/src/hooks/roofcover/useRoofShapePassivitySetting.js @@ -33,6 +33,9 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod const [type, setType] = useState(TYPES.EAVES) + const isFix = useRef(false) + const initLines = useRef([]) + const buttons = [ { id: 1, name: getMessage('eaves'), type: TYPES.EAVES }, { id: 2, name: getMessage('gable'), type: TYPES.GABLE }, @@ -52,9 +55,11 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod useEffect(() => { addCanvasMouseEventListener('mouse:down', mouseDown) const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine') - canvas.remove(wallLines) + + canvas?.remove(...wallLines) const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + initLines.current = outerLines.map((line) => ({ ...line })) outerLines.forEach((outerLine, idx) => { if (idx === 0) { currentLineRef.current = outerLine @@ -66,6 +71,7 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod canvas?.renderAll() return () => { + handleLineToPolygon() canvas?.discardActiveObject() initEvent() } @@ -166,6 +172,14 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod } const handleSave = () => { + isFix.current = true + handleLineToPolygon() + + setShowRoofShapePassivitySettingModal(false) + } + + const handleLineToPolygon = () => { + const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase') const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine') const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') exceptObjs.forEach((obj) => { @@ -176,13 +190,26 @@ export function useRoofShapePassivitySetting(setShowRoofShapePassivitySettingMod hideLine(line) }) - const wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' }) + let wall + + if (isFix.current) { + wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' }) + } else { + // 그냥 닫을 경우 처리 + wall = addPolygonByLines([...initLines.current], { name: 'wallLine', fill: 'transparent', stroke: 'black' }) + lines.forEach((line, idx) => { + line.attributes = initLines.current[idx].attributes + }) + } wall.lines = [...lines] - + // 기존 그려진 지붕이 없다면 + if (roofBases.length === 0) { + return + } const roof = drawRoofPolygon(wall) canvas.renderAll() - setShowRoofShapePassivitySettingModal(false) } + return { handleSave, handleConfirm, buttons, type, setType, TYPES, offsetRef, pitchRef, handleRollback } } diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index 1722e287..016cd365 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -244,8 +244,13 @@ export function useRoofShapeSetting(setShowRoofShapeSettingModal) { } } - // 기존 wallLine 제거 - canvas?.remove(canvas.getObjects().filter((obj) => obj.name === 'wallLine')) + // 기존 wallLine, roofBase 제거 + canvas + .getObjects() + .filter((obj) => obj.name === 'wallLine' || obj.name === 'roofBase') + .forEach((line) => { + canvas.remove(line) + }) const polygon = addPolygonByLines(outerLines, { name: 'wallLine' }) polygon.lines = [...outerLines] diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index 639b61b3..d14fa7e5 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -43,7 +43,6 @@ export function useEvent() { //default Event 추가 addCanvasMouseEventListener('mouse:move', defaultMouseMoveEvent) addCanvasMouseEventListener('mouse:out', defaultMouseOutEvent) - addDocumentEventListener('keydown', document, defaultKeyboardEvent) addDocumentEventListener('contextmenu', document, defaultContextMenuEvent) if (adsorptionPointAddMode) { addCanvasMouseEventListener('mouse:down', adsorptionPointAddModeStateEvent) From 7f8a862dc8c9cc38db9adb3f7be68dcf409fe837 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 17 Oct 2024 14:48:51 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=ED=98=84=ED=99=A9=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/Stuff.jsx | 10 +- .../management/StuffSearchCondition.jsx | 6 -- .../management/popup/PlanRequestPop.jsx | 96 ++++++++++++++++--- src/locales/ja.json | 5 + src/locales/ko.json | 5 + 5 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index cedf1975..30fab787 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -406,14 +406,14 @@ export default function Stuff() {
-

물건목록

+

{getMessage('stuff.search.grid.title')}

  • - 전체 + {getMessage('stuff.search.grid.all')} {convertNumberToPriceDecimal(totalCount)}
  • - 선택 + {getMessage('stuff.search.grid.selected')} {convertNumberToPriceDecimal(selectedRowDataCount)}
@@ -421,8 +421,8 @@ export default function Stuff() {
diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index a8f86718..cf310719 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -99,7 +99,6 @@ export default function StuffSearchCondition() { useEffect(() => { if (isObjectNotEmpty(sessionState)) { - // console.log('판매대리점 리스트 가져오기 위한 세션정보::::::::', sessionState) // storeId가 T01 이거나 1차점일때만 판매대리점 선택 활성화 // get({ url: `/api/object/saleStore/201TES01/list` }).then((res) => { get({ url: `/api/object/saleStore/${sessionState?.storeId}/list` }).then((res) => { @@ -190,7 +189,6 @@ export default function StuffSearchCondition() { { setObjectNo(e.target.value) @@ -205,7 +203,6 @@ export default function StuffSearchCondition() { { setSaleStoreName(e.target.value) @@ -220,7 +217,6 @@ export default function StuffSearchCondition() { { setAddress(e.target.value) @@ -237,7 +233,6 @@ export default function StuffSearchCondition() { { setobjectName(e.target.value) @@ -252,7 +247,6 @@ export default function StuffSearchCondition() { { setDispCompanyName(e.target.value) diff --git a/src/components/management/popup/PlanRequestPop.jsx b/src/components/management/popup/PlanRequestPop.jsx index 224519d0..46afad46 100644 --- a/src/components/management/popup/PlanRequestPop.jsx +++ b/src/components/management/popup/PlanRequestPop.jsx @@ -12,6 +12,9 @@ import dayjs from 'dayjs' import PlanRequestPopQGrid from './PlanRequestPopQGrid' import { sessionStore } from '@/store/commonAtom' import { planReqSearchState } from '@/store/planReqAtom' +import { isObjectNotEmpty } from '@/util/common-utils' + +import Select from 'react-select' export default function PlanRequestPop(props) { const sessionState = useRecoilValue(sessionStore) @@ -20,6 +23,7 @@ export default function PlanRequestPop(props) { const { get } = useAxios(globalLocaleState) const { getMessage } = useMessage() + const ref = useRef() // 검색조건 달력 셋팅 const [startDate, setStartDate] = useState(dayjs(new Date()).add(-3, 'month').format('YYYY-MM-DD')) const [endDate, setEndDate] = useState(dayjs(new Date()).format('YYYY-MM-DD')) @@ -34,7 +38,6 @@ export default function PlanRequestPop(props) { setStartDate: setEndDate, } - const ref = useRef() const resetPlanReqRecoil = useResetRecoilState(planReqSearchState) const [planReqSearch, setPlanReqSearch] = useRecoilState(planReqSearchState) @@ -47,14 +50,42 @@ export default function PlanRequestPop(props) { const [schDateGbn, setSchDateGbn] = useState('S') //기간구분코드(S/R) //초기화 - const resetRecoil = () => {} + const resetRecoil = () => { + console.log('초기화') + setSchPlanReqNo('') + setSchTitle('') + setSchAddress('') + setSchSaleStoreName('') + setSchPlanReqName('') + setSchDateGbn('S') + setStartDate(dayjs(new Date()).add(-3, 'month').format('YYYY-MM-DD')) + setEndDate(dayjs(new Date()).format('YYYY-MM-DD')) + setSchPlanStatCd('') + handleClear() //셀렉트 자동완성 초기화 + resetPlanReqRecoil() + } - //초기화 눌렀을 때 자동완성도.. + //셀렉트 자동완성 초기화 const handleClear = () => { - if (ref.current.state.dropDown) { - ref.current.methods.dropDown() + if (ref.current) { + ref.current.clearValue() + } + } + + // 상태 검색조건 변경 + const onSelectionChange = (key) => { + //임시작업 + console.log('E::::::::', key) + if (isObjectNotEmpty(key)) { + setSchPlanStatCd(key.value) + setPlanReqSearch({ + ...planReqSearch, + schPlanStatCd: key.value, + }) } else { - ref.current.state.values = [] + //X누름 + setSchPlanStatCd('') + setPlanReqSearch({ ...planReqSearch, schPlanStatCd: '' }) } } @@ -63,6 +94,11 @@ export default function PlanRequestPop(props) { setEndDate(planReqSearch?.schEndDt ? planReqSearch.schEndDt : dayjs(new Date()).format('YYYY-MM-DD')) }, [planReqSearch]) + // 조회 + const onSubmit = () => { + console.log('조회!!!!', planReqSearch) + } + const [gridProps, setGridProps] = useState({ gridData: [], isPageable: false, @@ -117,6 +153,25 @@ export default function PlanRequestPop(props) { ], }) + const tempList = [ + { + label: '완료', + value: 'C', + }, + { + label: '저장', + value: 'I', + }, + { + label: '접수', + value: 'R', + }, + { + label: '제출', + value: 'S', + }, + ] + return (
@@ -132,8 +187,12 @@ export default function PlanRequestPop(props) {

{getMessage('stuff.planReqPopup.popTitle')}

- - + +
@@ -223,13 +282,22 @@ export default function PlanRequestPop(props) { {getMessage('stuff.planReqPopup.search.planStatName')} -
- - - - - + + + + + */} +