diff --git a/src/assets/css/custom.css b/src/assets/css/custom.css index 0f44874..70639f7 100644 --- a/src/assets/css/custom.css +++ b/src/assets/css/custom.css @@ -250,6 +250,7 @@ h1.logo span{display:block;color:#f4f4f4;font-weight:bold;letter-spacing:2px;fon .left-menu-nav .test .btn-use{margin-left:20px; width: 35px; height: 35px; display: block; border: 0px solid transparent; box-sizing: content-box !important; background-color: #009cad;} .measure-control{position:absolute; z-index:100;} +.area-button{position:relative; z-index:100; margin-top:10px; margin-left:10px;} .control-btn{margin-left: 7px; border-bottom: solid 1px #283046; margin-bottom:5px;} .buffer-input{text-align: center; border-radius: 100px; border: 1px solid #283046; width: 70px; margin-left: 5px;} diff --git a/src/components/basis/flight/plan/FlightPlanArcrft.js b/src/components/basis/flight/plan/FlightPlanArcrft.js new file mode 100644 index 0000000..093d341 --- /dev/null +++ b/src/components/basis/flight/plan/FlightPlanArcrft.js @@ -0,0 +1,112 @@ +import React from 'react'; +import {Button, Card, CardBody, Col, CustomInput, Row, FormGroup, Input, Label} from 'reactstrap'; +import {Search} from 'react-feather'; +import {GridDatabase} from '../../../crud/grid/GridDatatable'; + +const FlightPlanArcrft = ({ arcrftList, handleSelectArcrft }) => { + const columns = [ + {id: 'groupNm', name: '그룹 명', cell: row => (
{row.groupNm}
)}, + {id: 'arcrftModelNm', name: '모델 명', cell: row => (
{row.arcrftModelNm}
)}, + {id: 'idntfTypeCd', name: '종류', cell: row => (
{row.arcrftTypeCd}
)}, + {id: 'ownerNm', name: '소유자 명', cell: row => (
{row.ownerNm}
)}, + {id: 'idntfNum', name: '식별 코드', cell: row => (
{row.idntfNum}
)}, + { + id: 'selectPilot', name: '선택', cell: row => { + return { + handleSelectArcrft(row.arcrftSno) + } + }>선택; + } + } + ]; + + return ( + <> +
+ + +
+
+

검색조건

+
+
+ + + 검색 + +
+
+ + +
+
+
+
+
소유자 명
+
+
+ + + + + + + + +
+
+
+
+
+
+
+
+ + +
+
+
+ + +
+
+

기체 목록

+ 검색결과 총 {!!arcrftList ? arcrftList.length : 0}건 +
+
+
+ +
+ + {/* 검색된 데이터가 없습니다. */} +
+
+
+ +
+
+ + ) + +} + +export default FlightPlanArcrft; \ No newline at end of file diff --git a/src/components/basis/flight/plan/FlightPlanAreaDetailForm.js b/src/components/basis/flight/plan/FlightPlanAreaDetailForm.js new file mode 100644 index 0000000..64d466e --- /dev/null +++ b/src/components/basis/flight/plan/FlightPlanAreaDetailForm.js @@ -0,0 +1,197 @@ +import React, { useEffect, useState } from 'react'; +import { + Card, + CardBody, + Col, + FormGroup, + Input, + Label, + Row, + Button +} from 'reactstrap'; + +const FlightPlanAreaDetailForm = ({ handleSave, handleClose, handleChange, handleBufferList, data }) => { + + const coordList = data ? data[0].coordList : null; + + return ( + + + + + + +
+
+
+

비행 구역 상세 정보

+
+
+ +
+
+
+

좌표 정보

+
+ +
+ + {coordList ? + coordList.map((coord, idx) => { + const latlon = coord.lat + ' / ' + coord.lon; + + return ( + + + + + + + ) + }) + : + + + + + + + } + + +
+
+ +
+
+

기타 정보

+
+ +
+ + + +
+ + { + const {name, value} = e.target; + handleChange({ + name, + value + }) + }} + /> +
+
+ handleBufferList()} + > + 적용 + +
+
+ +
+
+
+ + + + + { + const {name, value} = e.target; + handleChange({ + name, + value + }) + }} + /> + + + +
+
+ + + + + { + const {name, value} = e.target; + handleChange({ + name, + value + }) + }} + /> + + + +
+
+
+
+ +
+ handleSave()} + > + 등록 + + handleClose()} + > + 닫기 + +
+
+
+ +
+
+
+ ) +} + +export default FlightPlanAreaDetailForm; \ No newline at end of file diff --git a/src/components/basis/flight/plan/FlightPlanAreaForm.js b/src/components/basis/flight/plan/FlightPlanAreaForm.js deleted file mode 100644 index 4e9f1c0..0000000 --- a/src/components/basis/flight/plan/FlightPlanAreaForm.js +++ /dev/null @@ -1,115 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import classnames from 'classnames'; -import { - Card, - CardBody, - Col, - FormGroup, - FormFeedback, - Input, - Label, - Row, - Button, - Form -} from 'reactstrap'; - - -const FlightPlanAreaForm = (props) => { - - return ( - - -
-
-
-

상세 정보

-
-
- {/* {props.type === 'update' ? ( - 최종 수정일자 : {props.updateDt} - ) : null} */} -
-
- -
-
-
- - - - - - - - -
-
- - - -
- - -
-
- -
-
- -
-
- - - 확인 - - - props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }) - } - > - 취소 - -
-
-
-
-
- ) -} - -export default FlightPlanAreaForm; \ No newline at end of file diff --git a/src/components/basis/flight/plan/FlightPlanAreaMap.js b/src/components/basis/flight/plan/FlightPlanAreaMap.js index e424b12..30c14d5 100644 --- a/src/components/basis/flight/plan/FlightPlanAreaMap.js +++ b/src/components/basis/flight/plan/FlightPlanAreaMap.js @@ -2,74 +2,183 @@ import React, { useEffect, useState } from 'react'; import { Card, CardBody, - Button + Button, + Row, + Label, + Input, + Col, + FormGroup } from 'reactstrap'; +import { useDispatch, useSelector } from 'react-redux'; +import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; import { FeatureAirZone } from '../../../map/naver/feature/FeatureAirZone'; +import { drawTypeChangeAction, drawCheckAction } from '../../../../modules/control/map/actions/controlMapActions'; +import { FlightPlanDrawTest } from '../../../map/naver/draw/FlightPlanDrawTest'; +import { initFlight, initFlightBas } from '../../../../modules/basis/flight/models/basisFlightModel'; +import { AREA_COORDINATE_LIST_SAVE } from '../../../../modules/basis/flight/actions/basisFlightAction'; const FlightPlanAreaMap = (props) => { + const dispatch = useDispatch(); const naver = window.naver; - const airArea = props.airArea; + const airArea = props.airArea; + const mapControl = useSelector(state => state.controlMapReducer); + const { areaCoordList } = useSelector(state => state.flightState); const [map, setMap] = useState(); const [isMapLoad, setIsMapLoad] = useState(false); + const [mode, setMode] = useState(); + const [mapAreaCoordList, setMapAreaCoordList] = useState(initFlightBas.initDetail.areaList); - useEffect(() => { - NaverMapInit(); + useEffect(() => { + NaverMapInit(); }, []); - useEffect(() => { + + useEffect(() => { setIsMapLoad(true); }, [airArea]); + useEffect(() => { + ModeInit(); + }, [mapControl.drawType]); + + useEffect(() => { + setMapAreaCoordList(areaCoordList) + }, [areaCoordList]); + + const [areaDetail, setAreaDetail] = useState(initFlightBas.initDetail.areaList); + + + const ModeInit = () => { + setMode(mapControl.drawType) + } + const NaverMapInit = () => { const mapOptions = { - center: new naver.maps.LatLng(36.56793936069445, 127.85101412107547), - zoom: 10, + // center: new naver.maps.LatLng(36.56793936069445, 127.85101412107547), + center: new naver.maps.LatLng(37.520357, 126.610166), + // zoom: 10, + zoom: 15, zoomControl: true, - mapTypeId: naver.maps.MapTypeId.HYBRID, + mapTypeId: naver.maps.MapTypeId.NORMAL, zoomControlOptions: { - position: naver.maps.Position.TOP_LEFT, - - style: naver.maps.ZoomControlStyle.SMALL + position: naver.maps.Position.LEFT_CENTER, + style: naver.maps.ZoomControlStyle.SMALL } - }; - - setMap(new naver.maps.Map('map', mapOptions)); + }; + + setMap(new naver.maps.Map('map', mapOptions)); }; + const handlerDrawType = val => { + dispatch(drawTypeChangeAction(val)); + }; + + const handleBufferList = () => { + dispatch(Actions.FLIGHT_PLAN_AREA_BUFFER_LIST.request(areaDetail)); + } + + const handleInitCoordinates = () => { + const init = initFlightBas.initDetail.areaList.concat(); + dispatch(AREA_COORDINATE_LIST_SAVE(init)) + } + + const handleCoordinates = (areaInfo) => { + const initAreaList = initFlightBas.initDetail.areaList.concat() + const coordList = []; + + // radius = 10; + areaInfo.coordinates.forEach((c, i) => { + const coord = Object.assign({}, initFlightBas['coord']); + + coord.lat = c.lat; + coord.lon = c.lon; + + coordList.push(coord); + }); + + // initAreaList[0].bufferZone = areaInfo.bufferZone; + // initAreaList[0].areaType = areaInfo.areaType; + + const areaList = initAreaList.map((area, i) => { + return { + ...area, + bufferZone: areaInfo.bufferZone, + areaType: areaInfo.areaType, + coordList : coordList + } + }) + + // dispatch(AREA_COORDINATE_LIST_SAVE(areaList)) + setMapAreaCoordList(areaList); + } return ( - +

지도 영역

-
+
+
+ + +
+
+ {isMapLoad ? : null} + + props.handleConfirm(mapAreaCoordList)} + > + 확인 + + handlerDrawType('RESET')} + > + 초기화 +
-
- - - {isMapLoad ? ( - + + {isMapLoad ? ( + ) : null} - -
handlerDrawType('LINE')} > - Line + WayPoint - handlerDrawType('CIRCLE')} > Circle -
+ handlerDrawType('POLYGON')} + > + Polygon + +
) diff --git a/src/components/basis/flight/plan/FlightPlanAreaModal.js b/src/components/basis/flight/plan/FlightPlanAreaModal.js deleted file mode 100644 index 3bcee8f..0000000 --- a/src/components/basis/flight/plan/FlightPlanAreaModal.js +++ /dev/null @@ -1,49 +0,0 @@ -import { useState } from 'react'; -import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -import FlightPlanAreaContainer from '../../../../containers/basis/flight/plan/FlightPlanAreaContainer'; - -export const FlightPlanAreaModal = props => { - - const [onSubmit, setOnSubmit] = useState(false); - - return ( -
- - props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }) - } - className='modal-dialog-centered modal-xl' - > - - props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }) - } - > - {props.modal.title} - - - - - {/* - - */} - -
- ); -}; diff --git a/src/components/basis/flight/plan/FlightPlanForm.js b/src/components/basis/flight/plan/FlightPlanForm.js index 555fbd1..3487aa3 100644 --- a/src/components/basis/flight/plan/FlightPlanForm.js +++ b/src/components/basis/flight/plan/FlightPlanForm.js @@ -2,585 +2,796 @@ import React from 'react'; import { Card, CardBody, - Col, + Col, FormGroup, Input, Label, - Row, - Button + Row, + Button } from 'reactstrap'; import Flatpickr from 'react-flatpickr'; import '@styles/react/libs/flatpickr/flatpickr.scss'; +import moment from 'moment'; +import {initFlight, initFlightBas} from '../../../../modules/basis/flight/models/basisFlightModel'; +import FlightPlanPilotContainer from '../../../../containers/basis/flight/plan/FlightPlanPilotContainer'; +import { FlightPlanModal } from './FlightPlanModal'; +import FlightPlanArcrftContainer from '../../../../containers/basis/flight/plan/FlightPlanArcrftContainer'; +import FlightPlanAreaContainer from '../../../../containers/basis/flight/plan/FlightPlanAreaContainer'; +import { X } from 'react-feather'; +import { useDispatch } from 'react-redux'; -const FlightPlanForm = (props) => { - return ( - - - - - - +const FlightPlanForm = ({data, handleModal, handleChange, handleSave, handleDelete, modal, handleDeleteArray }) => { + const {areaList, pilotList, arcrftList} = data; + + return ( + + - -
-
-
-

상세정보

-
-
- {/* {props.type === 'update' ? ( - 최종 수정일자 : {props.updateDt} - ) : null} */} -
-
- -
-
-
-

신청인 정보

-
-
- - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - -
- - - {/*
- - - - - - - - - - - - - - -
*/} -
- -
-
-

비행 계획 정보

-
-
- - - - - - - - - - - - - - - - - - - {/* CDNOT 코드연동 필요 */} - {/* {ARCTFT_TYPE_CD.map(item => { - return ( - - ); - })} */} - - - - -
-
- - {/* - - - - - CDNOT 코드연동 필요 - {ARCTFT_TYPE_CD.map(item => { - return ( - - ); - })} - - - */} - - {/* - - - - {props.errors && props.errors.arcrftModelNm && ( - - {props.errors.arcrftModelNm.message} - - )} - - */} -
-
- -
-
-

비행 구역 정보

- - 비행 구역 설정 - -
-
- - - - - - - - - -
- - -
-
- -
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-
-
-
-

조종사 정보

- - 조종사 조회 - -
-
- - - - - - - - - - - - - - -
-
- - - -
- - -
-
- -
-
- - - - - - - -
-
-
-
-
-

기체 정보

- -  기체 조회  - -
-
- - - - - - - - - - - - - - -
-
- - - - - - - - - -
- - -
-
- -
-
- - -
-
-
- -
- - 저장 - - - 삭제 - -
- -
-
-
+ + + + + +
+
+
+
+
+ +
+
+
+

신청인 정보

+
+
+ + + + + + { + const {name, value} = e.target; + handleChange({ + type: 'plan', + name, + value, + }) + }} + + bsSize='sm' + placeholder='' + /> + + + + + +
+ + { + const {name, value} = e.target; + handleChange({ + type: 'plan', + name, + value, + }) + }} + readOnly + /> +
+
+ { + const {name, value} = e.target; + handleChange({ + type: 'plan', + name, + value, + }) + }} + placeholder='010-0000-0000' + /> +
+
+ + + + + { + const {name, value} = e.target; + handleChange({ + type: 'plan', + name, + value, + }) + }} + // innerRef={props.data} + placeholder='' + /> + + +
+
+
+
+
+

비행 계획 정보

+
+
+ + + + + { + const value = moment(date[0]).format('YYYY-MM-DD HH:mm:ss') || ''; + handleChange({ + type: 'plan', + name: 'schFltStDt', + value + }) + }} + placeholder='비행 시작일자 선택(클릭)'/> + + + + + + + { + const value = moment(date[0]).format('YYYY-MM-DD HH:mm:ss') || ''; + handleChange({ + type: 'plan', + name: 'schFltEndDt', + value + }) + }} + placeholder='비행 종료일자 선택(클릭)'/> + + + + + + + { + const {name, value} = e.target; + handleChange({ + type: 'plan', + name, + value, + }) + }} + // innerRef={props.data} + // className={classnames({ + // 'is-invalid': props.errors.arcrftTypeCd + // })} + > + {/* TODO CDNOT 코드연동 필요 */} + + + + + + + + + + + + +
+
+
+ {/* TODO area 다건 표출 */} +
+

비행 구역 정보

+ { + handleModal({target: 'area', isOpen: true}) + }} + > + 비행 구역 설정 + +
+ {areaList + ? areaList.map((item, i) => + ) + : } +
+
+
+

조종사 정보

+ { + handleModal({target: 'pilot', isOpen: true}) + }} + > + 조종사 조회 + +
+ {pilotList + ? pilotList.map((item, i) => + ) + : } +
+
+
+

기체 정보

+ { + handleModal({target: 'arcrft', isOpen: true}); + }} + > + 기체 조회 + +
+ {arcrftList + ? arcrftList.map((item, i) => + ) + + : } +
+ +
+ + 저장 + + + 삭제 + +
+ +
+
+
+
+ + +
+
- - -
-
-
- -
+ + + ) } -export default FlightPlanForm; \ No newline at end of file +export default FlightPlanForm; + +const SelectModal = ({handleModal, modal}) => { + let title = ''; + let description = ''; + let type = ''; + let isOpen = false; + + if(modal.pilot) { + isOpen = modal.pilot; + title = '조종사 조회'; + type = 'pilot'; + description = + } + + if(modal.arcrft) { + isOpen = modal.arcrft; + title = '기체 조회'; + type = 'arcrft'; + description = ; + } + + if(modal.area) { + isOpen = modal.area; + title = '비행 구역 설정'; + type = 'area'; + description = ; + } + + return ( + + ) + +} + + +const AreaForm = ({data, handleChange, index}) => { + + return (
+ + + + + {data && data.coordList && data.coordList.length > 0 + ? data.coordList.map((item, i) => { + return { + // const {name, value} = e.target; + // handleChange({ + // type: 'coord', + // name, + // value, + // index: i, + // pIndex: index + // }) + // }} + // style={{marginBottom: 5}} + readOnly + /> + }) : { + const {name, value} = e.target; + handleChange({ + type: 'coord', + name, + value, + index: 0, + pIndex: index + }) + }} + readOnly + />} + + + + + + +
+ + { + const {name, value} = e.target; + handleChange({ + type: 'area', + name, + value, + index + }) + }} + readOnly + /> +
+
+ { + const {name, value} = e.target; + handleChange({ + type: 'area', + name, + value, + index + }) + }} + readOnly + /> +
+
+ + + + + { + const {name, value} = e.target; + handleChange({ + type: 'area', + name, + value, + index + }) + }} + readOnly + /> + + +
+
) +} +const PilotForm = ({data, handleChange, index, handleDeleteArray}) => { + return (
+ + + + + { + const {name, value} = e.target; + handleChange({ + type: 'pilot', + name, + value, + index + }) + }} + /> + + + + + + { + const {name, value} = e.target; + handleChange({ + type: 'pilot', + name, + value, + index + }) + }} + + /> + + + + +
+ + { + const {name, value} = e.target; + handleChange({ + type: 'pilot', + name, + value, + index + }) + }} + readOnly + /> +
+
+ { + const {name, value} = e.target; + handleChange({ + type: 'pilot', + name, + value, + index + }) + }} + + /> +
+
+ + + + + { + const {name, value} = e.target; + handleChange({ + type: 'pilot', + name, + value, + index + }) + }} + + /> + + + {index !== 0 ? + + + handleDeleteArray({ type: 'pilot', index }) + } + outline + > + + 삭제 + + + : + null + } +
+
) +} + + +const ArcrftForm = ({data, handleChange, index, handleDeleteArray}) => { + return (
+ + + + + { + const {name, value} = e.target; + handleChange({ + type: 'arcrft', + name, + value, + index + }) + }} + + /> + + + + + + { + const {name, value} = e.target; + handleChange({ + type: 'arcrft', + name, + value, + index + }) + }} + + /> + + + + + + { + const {name, value} = e.target; + handleChange({ + type: 'arcrft', + name, + value, + index + }) + }} + + /> + + + + + + { + const {name, value} = e.target; + handleChange({ + type: 'arcrft', + name, + value, + index + }) + }} + + /> + + + {index !== 0 ? + + + handleDeleteArray({ type: 'arcrft', index }) + } + outline + > + + 삭제 + + + : + null + } + +
) +} diff --git a/src/components/basis/flight/plan/FlightPlanGrid.js b/src/components/basis/flight/plan/FlightPlanGrid.js index 062c220..6973bce 100644 --- a/src/components/basis/flight/plan/FlightPlanGrid.js +++ b/src/components/basis/flight/plan/FlightPlanGrid.js @@ -1,66 +1,70 @@ import React from 'react'; -import { - Row, - Col, - Table, - Badge, - UncontrolledDropdown, - DropdownMenu, - DropdownItem, - DropdownToggle, - Card, - CardHeader, - CardBody, - CardTitle, - CardSubtitle, - ButtonGroup, - Button, - Input, - CustomInput, - FormGroup - } from 'reactstrap'; -import { GridDatabase } from '../../../crud/grid/GridDatatable'; +import {Button, Card, Col, Row} from 'reactstrap'; +import {GridDatabase} from '../../../crud/grid/GridDatatable'; +import {Redirect} from 'react-router-dom'; -const FlightPlanGrid = (props) => { - return ( -
- - -
-
- {/*

{"비행 계획"} 목록

*/} -

{"비행계획서 신청"} 목록

- 검색결과 총 0건 -
-
- - {/* 계획서 생성 */} - 비행계획서 신청 - -
-
-
- -
- - {/* 검색된 데이터가 없습니다. */} -
-
-
- -
-
- ) + +const FlightPlanGrid = ({movePage, planListData, handleMoveDetail}) => { + + const columns = [ + {id: 'planSno', name: '번호', cell: (row, i) => (
{i+1}
)}, + {id: 'fltPurpose', name: '비행목적', cell: row => (
{row.fltPurpose}
)}, + { + id: 'fltMethod', name: '비행방식', cell: row => { + const displayName = row.areaList && row.areaList.length > 0 && row.areaList[0].fltMethod || '-'; + return
{displayName}
+ } + }, + {id: 'schFltStDt', name: '출발일', cell: row => (
{row.schFltStDt}
)}, + {id: 'aprvlYn', name: '승인여부', cell: row => (
{row.aprvlYn}
)}, + { + id: 'moveDetail', name: '상세보기', cell: row => { + return { + handleMoveDetail(row.planSno)} + }>상세; + } + } + ]; + + return ( +
+ + +
+
+

비행계획서 신청 목록

+ 검색결과 총 {!!planListData ? planListData.length : 0}건 +
+
+ + {/* 계획서 생성 */} + 비행계획서 신청 + +
+
+
+ +
+ + {/* 검색된 데이터가 없습니다. */} +
+
+
+ +
+
+ ) } -export default FlightPlanGrid; \ No newline at end of file +export default FlightPlanGrid; diff --git a/src/components/basis/flight/plan/FlightPlanGroupGrid.js b/src/components/basis/flight/plan/FlightPlanGroupGrid.js new file mode 100644 index 0000000..8efc285 --- /dev/null +++ b/src/components/basis/flight/plan/FlightPlanGroupGrid.js @@ -0,0 +1,67 @@ +import React, {} from 'react'; +import { GridDatabase } from "../../../crud/grid/GridDatatable"; +import { + Card, + Button +} from 'reactstrap'; + + +const FlightPlanGroupGrid = ({ data, count, selectGroup, handlerGroupCancel, handleGroupSelect }) => { + + const columns = [ + {id: 'groupNm', name: '그룹 명', minWidth: '102px', cell: row => (
{row.groupNm}
)}, + {id: 'groupId', name: '그룹 코드', minWidth: '102px', sortable: true, cell: row => (
{row.groupId}
)}, + {sortable: true, cell: row => { + return selectGroup?.groupId === row?.groupId ? ( + handlerGroupCancel()} + > + 선택취소 + + ) : ( + { + handleGroupSelect({ + groupId: row?.groupId, + groupNm: row?.groupNm, + groupAuthCd: row?.groupAuthCd + }) + } + } + > + 상세보기 + + ) + }} + ]; + + return ( + <> +
+
+

나의 그룹 목록

+ 검색결과 총 {count}건 +
+
+
+
+ +
+ +
+
+
+ + ) + +} + +export default FlightPlanGroupGrid; \ No newline at end of file diff --git a/src/components/basis/flight/plan/FlightPlanModal.js b/src/components/basis/flight/plan/FlightPlanModal.js new file mode 100644 index 0000000..b2d35d3 --- /dev/null +++ b/src/components/basis/flight/plan/FlightPlanModal.js @@ -0,0 +1,29 @@ +import { useState } from 'react'; +import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import FlightPlanAreaContainer from '../../../../containers/basis/flight/plan/FlightPlanAreaContainer'; + +export const FlightPlanModal = ({isOpen, title, description, type, handleModal}) => { + + return ( +
+ + handleModal(({target: type, isOpen: false})) + } + className='modal-dialog-centered modal-xl' + > + + handleModal(({target: type, isOpen: false})) + } + > + {title} + + + {description} + + +
+ ); +}; diff --git a/src/components/basis/flight/plan/FlightPlanPilot.js b/src/components/basis/flight/plan/FlightPlanPilot.js new file mode 100644 index 0000000..bd38999 --- /dev/null +++ b/src/components/basis/flight/plan/FlightPlanPilot.js @@ -0,0 +1,107 @@ +import React from 'react'; +import {Button, Card, CardBody, Col, CustomInput, Row, FormGroup, Input, Label} from 'reactstrap'; +import {Search} from 'react-feather'; +import {GridDatabase} from '../../../crud/grid/GridDatatable'; + +const FlightPlanPilot = ({ pilotList, handleSelectPilot }) => { + const columns = [ + {id: 'groupNm', name: '그룹 명', cell: row => (
{row.groupNm}
)}, + {id: 'memberName', name: '성명', cell: row => (
{row.memberName}
)}, + {id: 'hpno', name: '핸드폰 번호', cell: row => (
{row.hpno}
)}, + {id: 'email', name: '이메일', cell: row => (
{row.email}
)}, + { + id: 'selectPilot', name: '선택', cell: row => { + return { + handleSelectPilot(row.cstmrSno) + } + }>선택; + } + } + ]; + + return ( + <> +
+ + +
+
+

검색조건

+
+
+ + + 검색 + +
+
+ + +
+
+
+
+
성명
+
+
+ + + + + + + + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
+

조종사 목록

+ 검색결과 총 {!!pilotList ? pilotList.length : 0}건 +
+
+
+
+ +
+ +
+
+
+
+ + ) + +} + +export default FlightPlanPilot; \ No newline at end of file diff --git a/src/components/basis/flight/plan/FlightPlanSearch.js b/src/components/basis/flight/plan/FlightPlanSearch.js index 2bbcb88..2344390 100644 --- a/src/components/basis/flight/plan/FlightPlanSearch.js +++ b/src/components/basis/flight/plan/FlightPlanSearch.js @@ -1,174 +1,175 @@ -import React, { useEffect, useState } from 'react'; -import { - Row, - Col, - Table, - Badge, - UncontrolledDropdown, - DropdownMenu, - DropdownItem, - DropdownToggle, - Card, - CardHeader, - CardBody, - CardTitle, - CardSubtitle, - ButtonGroup, - Button, - Input, - CustomInput, - FormGroup - } from 'reactstrap'; -import { Calendar, Search } from 'react-feather'; +import React, {useState} from 'react'; +import {Button, Card, CardBody, Col, CustomInput, Row} from 'reactstrap'; +import {Search} from 'react-feather'; import Flatpickr from 'react-flatpickr'; +import moment from 'moment'; -const FlightPlanSearch = (props) => { +const FlightPlanSearch = ({searchData, handleChangeSearchData, handleSearch}) => { - const [isCheck, setIsCheck] = useState({ - all: true, - yes: false, - no: false - }); - - useEffect(() => { - let aprvYn = ''; - - if (!isCheck.all) { - if (isCheck.yes) { - aprvYn = 'Y'; - } else if (isCheck.no) { - aprvYn = 'N'; - } else { - aprvYn = '-'; - } + const {schFltStDt, schFltEndDt, aprvlYn} = searchData; + const initCheckState = { + 'all': aprvlYn == 'A', + 'yes': (aprvlYn == 'Y' || aprvlYn == 'A'), + 'no': (aprvlYn == 'N' || aprvlYn == 'A'), } - - // props.setParams({ - // ...props.params, - // aprvYn: aprvYn - // }); - }, [isCheck]); - - return ( -
- - -
-
-

검색조건

-
-
- props.handlerSearch()} - > - - 검색 - -
-
- - -
-
-
-
-
신청일
-
-
- - -
- - props.handlerInput('searchDate', val) - } - onKeyPress={props.onKeyPress} - className='form-control flat-picker bg-transparent border-0 shadow-none' - /> -
- -
+ const [checkState, setCheckState] = useState(initCheckState); + const handleClickSearch = (e) => { + handleSearch(searchData); + } + const handleChangeInput = (dates, value, config) => { + if (dates.length === 2) { + const schFltStDt = moment(dates[0]).format('YYYY-MM-DD HH:mm:ss'); + const schFltEndDt = moment(dates[1]).set({'h': 23, 'm': 59, 's': 59}).format('YYYY-MM-DD HH:mm:ss'); + handleChangeSearchData({schFltStDt, schFltEndDt}) + } + } + const handleChangeCheckbox = (e) => { + const {name, value, checked} = e.target; + let val; + switch (value) { + case 'A': + val = checked ? 'A' : ''; + handleChangeSearchData({[name]: val}) + setCheckState({ + 'all': checked, + 'yes': checked, + 'no': checked + }) + break; + case 'Y': + if (checked && checkState.no) val = 'A' + else if (checked && !checkState.no) val = 'Y' + else if (!checked && checkState.no) val = 'N' + else if (!checked && !checkState.no) val = '' + handleChangeSearchData({[name]: val}) + setCheckState(prevState => ({ + 'all': prevState.no && checked, + 'yes': checked, + 'no': prevState.no + })) + break; + case 'N': + if (checked && checkState.yes) val = 'A' + else if (checked && !checkState.yes) val = 'N' + else if (!checked && checkState.yes) val = 'Y' + else if (!checked && !checkState.yes) val = '' + handleChangeSearchData({[name]: val}) + setCheckState(prevState => ({ + 'all': prevState.yes && checked, + 'yes': prevState.yes, + 'no': checked + })) + break; + default: + break; + } + } + return ( +
+ + +
+
+

검색조건

-
-
-
- -
-
-
승인여부
-
- {/*
- -
*/} -
- - setIsCheckBox({ - all: !isCheck.all, - yes: !isCheck.all, - no: !isCheck.all - }) - } - /> - - setIsCheckBox({ - all: false, - yes: !isCheck.yes - }) - } - /> - - setIsCheckBox({ - all: false, - no: !isCheck.no - }) - } - /> +
+ + + 검색 +
-
-
-
-
-
-
- - -
-
- ) + + +
+
+
+
+
신청일
+
+
+ + +
+ +
+ +
+
+
+
+
+ +
+
+
승인여부
+
+
+ + + +
+
+
+
+
+
+
+
+ + + + + ) } -export default FlightPlanSearch; \ No newline at end of file +export default FlightPlanSearch; diff --git a/src/components/map/naver/draw/FlightPlanDraw.js b/src/components/map/naver/draw/FlightPlanDraw.js new file mode 100644 index 0000000..e193de5 --- /dev/null +++ b/src/components/map/naver/draw/FlightPlanDraw.js @@ -0,0 +1,652 @@ +import $ from 'jquery'; +import '../../../../assets/css/custom.css'; +import { CustomInput } from 'reactstrap'; + +import buffer from '@turf/buffer' + +export const FlightPlanDraw = props => { + const {naver} = props; + const {map} = props; + + + var Measure = function(buttons) { + this.$btnLine = buttons.line; + this.$btnPolygon = buttons.polygon; + this.$btnCircle = buttons.circle; + this.$btnRectangle = buttons.rectangle; + + this._mode = null; + + this._bindDOMEvents(); + }; + + $.extend( + Measure.prototype,{ + constructor: Measure, + + setMap: function(map) { + console.log('setMap') + if (this.map) { + this._unbindMap(this.map); + } + + this.map = map; + + if (map) { + this._bindMap(map); + } + }, + + startMode: function(mode) { + console.log('startMode') + if (!mode) return; + + if (mode === 'line') { + this._startDistance(); + } if (mode === 'polygon') { + this._startArea(); + } if (mode === 'circle') { + this._startCircle(); + } if (mode === 'rectangle') { + this._startRectangle(); + } + }, + + _startDistance: function() { + console.log('startDistance') + var map = this.map; + this._distanceListeners = [ + naver.maps.Event.addListener(map, 'click', this._onClickDistance.bind(this)) + ]; + }, + + _startArea: function() { + console.log('startArea') + var map = this.map; + + this._areaListeners = [ + naver.maps.Event.addListener(map, 'click', this._onClickArea.bind(this)), + naver.maps.Event.addListener(map, 'rightclick', this._finishArea.bind(this)) + ]; + + $(document).on('mousemove.measure', this._onMouseMoveArea.bind(this)); + }, + + _startCircle: function() { + console.log('startCircle') + var map = this.map; + this._circleListeners = [ + naver.maps.Event.addListener(map, 'click', this._onClickCircle.bind(this)), + naver.maps.Event.addListener(map, 'rightclick', this._finishCircle.bind(this)) + ]; + }, + + _startRectangle: function() { + console.log('startRectangle') + var map = this.map; + this._rectangleListeners = [ + naver.maps.Event.addListener(map, 'click', this._onClickRectangle.bind(this)), + naver.maps.Event.addListener(map, 'rightclick', this._finishRectangle.bind(this)) + ] + }, + + _finishDistance: function() { + console.log('finishDistance') + + naver.maps.Event.removeListener(this._distanceListeners); + delete this._distanceListeners; + + $(document).off('mousemove.measure'); + + if (this._guideline) { + this._guideline.setMap(null); + delete this._guideline; + } + + if (this._polyline) { + // console.log(this._polyline.getPath()._array, 'path') + let polypaths = this._polyline.getPath()._array; + + //파싱 + let polypathJSON = new Array(); + for(let i = 0; i< polypaths.length; i++) { + + //파싱 + let obj = new Object(); + + obj.x = '' + polypaths[i]._lng + ''; + obj.y = '' + polypaths[i]._lat + ''; + + obj = JSON.stringify(obj); + polypathJSON.push(JSON.parse(obj)); + } + console.log(polypathJSON, 'json polyline path') + + + //버퍼 생성에 필요한 coordinates 배열 변환 + let lineStringPaths = []; + for(let i = 0; i < this._polyline.getPath().length; i++) { + lineStringPaths.push([this._polyline.getPath()._array[i].x, this._polyline.getPath()._array[i].y]); + } + console.log(lineStringPaths, 'polyline path') + + //버퍼 생성을 위한 line 객체 + const originalGeojson = { + type: "FeatureCollection", + features: [ + { + type: "Feature", + properties: {}, + geometry: { + type: "LineString", + coordinates: lineStringPaths + } + } + ] + }; + console.log(originalGeojson) + + //버퍼 객체 + const bufferObj = buffer(originalGeojson, 50, {units:'meters'}); + + //버퍼 라인 생성 + let bufferPath = bufferObj.features[0].geometry.coordinates[0]; + console.log(bufferPath, 'buffer path') + + this.bufferPolyline = new naver.maps.Polyline({ + strokeColor: '#ff0000', + strokeWeight: 2, + strokeStyle: [4, 4], + strokeOpacity: 0.6, + path : bufferPath, + map: map + }); + + // 이거 하면 그동안 한거 싹 사라짐 -> 얘를 통해서 drawType이 바뀌면 다 날라가는 걸로 해보면 될듯 + // this._polyline.setMap(null) + delete this._polyline; + + } + //onfocus()의 반대기능 = blur() + this.$btnLine.removeClass('control-on').blur(); + + this._mode = null; + }, + + _finishArea: function() { + console.log('finishArea') + naver.maps.Event.removeListener(this._areaListeners); + delete this._areaListeners; + + $(document).off('mousemove.measure'); + + if (this._polygon) { + var path = this._polygon.getPath(); + path.pop(); + + delete this._polygon; + } + + this.$btnPolygon.removeClass('control-on').blur(); + + this._mode = null; + }, + + _finishCircle: function() { + console.log('finishCircle') + + naver.maps.Event.removeListener(this._circleListeners); + delete this._circleListeners; + + $(document).off('mousemove.measure'); + + if(this._guidecircle) { + this._guidecircle.setMap(null); + this._radius.setMap(null); + delete this._raidus; + delete this._guidecircle; + } + + if (this._circle) { + // this._circle.setMap(null); + delete this._circle; + } + + this.$btnCircle.removeClass('control-on').blur(); + + // delete this._lastDistance; + this._mode = null; + }, + + _finishRectangle: function() { + console.log('finishRectangle') + + naver.maps.Event.removeListener(this._rectangleListeners); + delete this._rectangleListeners; + + $(document).off('mousemove.measure'); + + if(this._rectangle) { + this._guiderectangle.setMap(null); + delete this._guiderectangle; + } + + this.$btnRectangle.removeClass('control-on').blur(); + + this._mode = null; + }, + + finishMode: function(mode) { + console.log('finishMode') + if (!mode) return; + + if (mode === 'line') { + this._finishDistance(); + } if (mode === 'polygon') { + this._finishArea(); + } if (mode === 'circle') { + this._finishCircle(); + } if (mode === 'rectangle') { + this._finishRectangle(); + } + }, + + _fromMetersToText: function(meters) { + meters = meters || 0; + + var km = 1000, + text = meters; + + if(meters >= km) { + text = parseFloat((meters / km).toFixed(1)) + 'km'; + } else { + text = parseFloat(meters.toFixed(1)) + 'm'; + } + + return text; + }, + + _addMileStone: function(coord, text, css) { + if(!this._ms) this._ms = []; + + let content; + if(text == 'Start') { + content = '
'+ text +'
' + } else { + content = '
'+ text +'
' + } + + var ms = new naver.maps.Marker({ + position: coord, + icon: { + content: content, + anchor: new naver.maps.Point(-5, -5) + }, + map: this.map + }); + + var msElement = $(ms.getElement()); + + if(css) { + msElement.css(css); + } else { + msElement.css('font-size', '13px'); + } + + this._ms.push(ms); + }, + + _onClickDistance: function(e) { + console.log('onClickDistance') + var map = this.map, + coord = e.coord; + + if (!this._polyline) { + // 임시로 보여줄 점선 폴리라인을 생성합니다. + this._guideline = new naver.maps.Polyline({ + strokeColor: '#0000ff', + strokeWeight: 3, + strokeStyle: [4, 4], + strokeOpacity: 0.2, + path: [coord], + map: map + }); + + // this._lastDistance = this._guideline.getDistance(); + + $(document).on('mousemove.measure', this._onMouseMoveDistance.bind(this)); + this._distanceListeners.push(naver.maps.Event.addListener(map, 'rightclick', this._finishDistance.bind(this))); + + // 실제 거리재기에 사용되는 폴리라인을 생성합니다. + this._polyline = new naver.maps.Polyline({ + strokeLineCap: 'round', + strokeLineJoin: 'round', + strokeColor: '#0000ff', + strokeWeight: 3, + strokeOpacity: 0.6, + path: [coord], + map: map + }); + + this._lastDistance = this._polyline.getDistance(); + this._addMileStone(coord, 'Start'); + + } else { + this._guideline.setPath([e.coord]); + this._polyline.getPath().push(coord); + + var distance = this._polyline.getDistance(); + this._addMileStone(coord, this._fromMetersToText(distance - this._lastDistance)); + this._lastDistance = distance; + } + }, + + _onMouseMoveDistance: function(e) { + console.log('onMouseMoveDistance') + var map = this.map, + proj = this.map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = this._guideline.getPath(); + + if (path.getLength() === 2) { + //맨 뒷 값 삭제 = 기존클릭좌표만 남겨둬라 = 실시간으로 좌표들어가야 하니까 + path.pop(); + } + + // [기존 클릭 좌표, 실시간 좌표] + path.push(coord); + }, + + _onClickArea: function(e) { + console.log('onClickArea') + var map = this.map, + coord = e.coord; + + if (!this._polygon) { + this._polygon = new naver.maps.Polygon({ + strokeOpacity: 0.8, + fillColor: '#0000ff', + fillOpacity: 0.1, + paths: [coord], + map: map + }); + } else { + this._polygon.getPath().push(coord); + } + }, + + _onMouseMoveArea: function(e) { + console.log('onMouseMoveArea') + if (!this._polygon) return; + + var map = this.map, + proj = this.map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = this._polygon.getPath(); + + if (path.getLength() >= 2) { + path.pop(); + } + + path.push(coord); + }, + + _onClickCircle: function(e) { + console.log('onClickCircle') + var map = this.map, + coord = e.coord; + + if(!this._circle) { + + //가이드 라인 + this._radius = new naver.maps.Polyline({ + strokeStyle: [4, 4], + strokeOpacity: 0.6, + path: [coord], + map: map + }); + this._lastDistance = this._radius.getDistance(); + + // 임시로 보여줄 원형 + this._guidecircle = new naver.maps.Circle({ + strokeOpacity: 0.8, + strokeStyle: [4, 4], + fillColor: '#0000ff', + fillOpacity: 0.1, + center: coord, + radius: this._lastDistance, + map: map + }); + + $(document).on('mousemove.measure', this._onMouseMoveCircle.bind(this)); + this._circleListeners.push(naver.maps.Event.addListener(map, 'rightclick', this._finishCircle.bind(this))); + + // 실제 사용되는 원형 + this._circle = new naver.maps.Circle({ + strokeOpacity: 0.8, + fillColor: '#0000ff', + fillOpacity: 0.1, + center: coord, + radius: this._lastDistance, + map: map + }); + + } else { + // this._guidecircle.setCenter(e.coord); + // this._circle.setCenter(coord); + // if(this._radius.getPath().length() === 2) { + // this._radius.getPath().pop(); + // } + + // this._radius.getPath().push(coord); + + var distance = this._radius.getDistance(); + this._lastDistance = distance; + this._circle.setRadius(this._lastDistance); + + + } + }, + + _onMouseMoveCircle: function(e) { + console.log('onMouseMoveCircle') + if(!this._circle) return; + + var map = this.map, + proj = this.map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = this._radius.getPath(), + center = this._guidecircle.getCenter(), //LatLng으로 나옴 + r = proj.getDistance(coord, center); + + if(path.getLength() === 2) { + path.pop(); + } + path.push(coord); + this._guidecircle.setRadius(r); + }, + + _onClickRectangle: function(e) { + console.log('onClickRectangle') + var map = this.map, + coord = e.coord; + + this.max_x = 0; + this.max_y = 0; + + + if(!this._rectangle) { + //min = 고정값 + this.fixed = coord; + this.min = [this.fixed.x, this.fixed.y]; + this.max = [this.max_x, this.max_y]; + this.boundscoord = [this.min[0], this.min[1], this.min[0], this.min[1]]; + + // 임시로 보여줄 사각형 + this._guiderectangle = new naver.maps.Rectangle({ + strokeStyle: [4, 4], + strokeOpacity: 0.6, + bounds: this.boundscoord, + map: map + }); + + $(document).on('mousemove.measure', this._onMouseMoveRectangle.bind(this)); + this._rectangleListeners.push(naver.maps.Event.addListener(map, 'rightclick', this._finishRectangle.bind(this))); + + //실제 사용되는 사각형 + this._rectangle = new naver.maps.Rectangle({ + strokeOpacity: 0.8, + fillColor: '#0000ff', + fillOpacity: 0.1, + bounds: this.boundscoord, + map: map + }); + + } else { + this.max = [coord.x, coord.y]; + this.boundscoord = [this.min[0], this.min[1], this.max[0], this.max[1]]; + this._rectangle.setBounds(this.boundscoord); + } + }, + + _onMouseMoveRectangle: function(e) { + console.log('onMouseMoveRectangle') + if(!this._rectangle) return; + + var map = this.map, + proj = this.map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + bounds = this._guiderectangle.getBounds(), + max = [coord.x, coord.y]; + + this.boundscoord = [this.min[0], this.min[1],max[0], max[1]]; + this._guiderectangle.setBounds(this.boundscoord); + }, + + _bindMap: function(map) { + console.log('bindMap') + }, + + _unbindMap: function() { + console.log('unbindMap') + this.unbindAll(); + }, + + _bindDOMEvents: function() { + console.log('bindDOMEvents') + this.$btnLine.on('click.measure', this._onClickButton.bind(this, 'line')); + this.$btnPolygon.on('click.measure', this._onClickButton.bind(this, 'polygon')); + this.$btnCircle.on('click.measure', this._onClickButton.bind(this, 'circle')); + this.$btnRectangle.on('click.measure', this._onClickButton.bind(this, 'rectangle')); + + }, + + _onClickButton: function(newMode, e) { + //newMode는 방금 클릭한 값(line, polygon, circle...) + console.log('onClickButton') + e.preventDefault(); + + var btn = $(e.target), + map = this.map, + mode = this._mode; + //this._mode는 클릭하기 전 값(첫 클릭이면 null) + + if (btn.hasClass('control-on')) { + console.log('remove') + btn.removeClass('control-on'); + } else { + console.log('add') + btn.addClass('control-on'); + } + + this._clearMode(mode); + + if (mode === newMode) { + this._mode = null; + return; + } + + this._mode = newMode; + + this.startMode(newMode); + }, + + _clearMode: function(mode) { + console.log('clearMode') + if (!mode) return; + + if (mode === 'line') { + if (this._polyline) { + this._polyline.setMap(null); + delete this._polyline; + } + + this._finishDistance(); + } else if (mode === 'polygon') { + if (this._polygon) { + this._polygon.setMap(null); + delete this._polygon; + } + + this._finishArea(); + } else if (mode === 'circle') { + if (this._circle) { + this._circle.setMap(null); + delete this._circle; + } + + this._finishCircle(); + } else if (mode === 'rectangle') { + if(this._rectangle) { + this._rectangle.setMap(null); + delete this._rectangle; + } + } + } + }); + + // id랑 매치시켜서 옵션 지정함 + var measures = new Measure({ + line: $('#line'), + polygon: $('#polygon'), + circle: $('#circle'), + rectangle: $('#rectangle') + }); + + measures.setMap(map); + + return( + <> +
+
    +
  • + + + + +
  • +
+
+ + ) +} \ No newline at end of file diff --git a/src/components/map/naver/draw/FlightPlanDrawTest.js b/src/components/map/naver/draw/FlightPlanDrawTest.js new file mode 100644 index 0000000..da4df93 --- /dev/null +++ b/src/components/map/naver/draw/FlightPlanDrawTest.js @@ -0,0 +1,676 @@ +import $ from 'jquery'; +import { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + +export const FlightPlanDrawTest = props => { + const mapControl = useSelector(state => state.controlMapReducer); + + const [pastPolyline, setPolyline] = useState(); + const [pastBuffer, setBuffer] = useState(); + + const [pastPolygon, setPolygon] = useState(); + + // const [pastCircle, setCircle] = useState(); + const [pastCircle, setCircle] = useState([]); + const [pastEve, setEve] = useState(); + + const [pastDragCircle, setDragCircle] = useState([]); + + const [pastMarker, setMarker] = useState([]); + + const naver = props.naver; + const map = props.map; + let mode = props.mode; + + let areaInfo; + let lastDistance; + + let polyline; + let guideline; + let bufferPolygon; + + let polygon; + + let circle; + let radiusline; + + let Eve = { + clickEve: '', + mousedownEve: '', + rightclickEve: '' + } + + let dragCircle = []; + let dragCircleEve = []; + + let check; + + let distanceMarker = []; + + useEffect(() => { + drawInit(); + }, [mapControl.drawType]) + + useEffect(() => { + handleDetailDrwa(); + }, [props.areaCoordList]) + + const drawInit = () => { + console.log(mapControl.drawType); + if (mapControl.drawType === 'LINE') { + onClickButton('LINE'); + } else if (mapControl.drawType === 'CIRCLE') { + onClickButton('CIRCLE'); + } else if (mapControl.drawType === 'POLYGON') { + onClickButton('POLYGON'); + } else if (mapControl.drawType === 'RESET') { + onClickReset('RESET') + } + } + + const onClickButton = (newMode) => { + console.log('onClickButton'); + + clearMode(mode); + + if (mode === newMode) { + mode = null; + return; + } + + // mode = newMode; + + startMode(newMode); + } + + const clearMode = (mode) => { + console.log('clearMode') + + // if(!mode) return; + + if (pastPolyline) { + console.log('clear polyline ', pastPolyline) + pastPolyline.setMap(null); + pastDragCircle.forEach(c => c.setMap(null)); + pastBuffer.setMap(null); + setPolyline(); + setDragCircle([]); + setBuffer(); + } + if (pastCircle) { + console.log('clear circle ', pastCircle) + pastCircle.forEach(prev => prev.setMap(null)) + naver.maps.Event.removeListener(pastEve); + + // setCircle(); + setCircle([]); + } + if (pastPolygon) { + console.log('clear polygon ', pastPolygon) + pastPolygon.setMap(null); + pastDragCircle.forEach(c => c.setMap(null)); + + setPolygon(); + setDragCircle([]); + } + if (pastMarker) { + console.log('clear marker ', pastMarker) + pastMarker.forEach(m => m.setMap(null)); + } + + finishDraw(); + props.handleInitCoordinates(); + } + + const startMode = (mode) => { + console.log('startMode') + + if (!mode) return; + + if (mode === 'LINE') { + Eve.clickEve = naver.maps.Event.addListener(map, 'click', function (e) { onClickPolyline(e) }); + } else if (mode === 'POLYGON') { + Eve.clickEve = naver.maps.Event.addListener(map, 'click', function (e) { onClickPolygon(e) }); + } else if (mode === 'CIRCLE') { + setEve(naver.maps.Event.addListener(map, 'click', function (e) { onClickCircle(e) })) + } + } + + const removeListener = () => { + console.log('removeListener') + + naver.maps.Event.removeListener(Eve.clickEve); + naver.maps.Event.removeListener(Eve.mousedownEve); + naver.maps.Event.removeListener(Eve.rightclickEve); + if (!circle) $(document).off('mousemove.measure'); + // if(pastCircle) naver.maps.Event.removeListener(pastEve); + naver.maps.Event.removeListener(pastEve); + } + + const finishDraw = () => { + console.log('finishDraw') + removeListener(); + + if (polyline) { + if (guideline) { + guideline.setMap(null); + guideline = ''; + } + + let polypaths = polyline.getPath()._array; + + if (polypaths.length >= 2) { + setPolyline(polyline); + setAreaInfo(polypaths); + } else { + polyline.setMap(null); + polyline = ''; + } + + polyline.setMap(null) + } else if (polygon) { + let path = polygon.getPath(); + path.pop(); + + let polygonpaths = polygon.getPath()._array; + + setPolygon(polygon); + setAreaInfo(polygonpaths); + + polygon.setMap(null) + } + } + + const onClickPolyline = (e) => { + console.log('onClickPolyline') + var coord = e.coord; + + // if (!check) { + if (!polyline) { + //가이드라인 + guideline = new naver.maps.Polyline({ + strokeColor: '#283046', + strokeWeight: 2, + strokeOpacity: 0.3, + path: [coord], + map: map + }); + lastDistance = guideline.getDistance(); + + //실제 사용되는 라인 + polyline = new naver.maps.Polyline({ + strokeLineCap: 'round', + strokeLineJoin: 'round', + // strokeColor: '#283046', + strokeColor: '#ff0000', + strokeWeight: 3, + strokeOpacity: 1, + path: [coord], + map: map + }); + + Eve.rightclickEve = naver.maps.Event.addListener(map, 'rightclick', function () { finishDraw() }) + $(document).on('mousemove.measure', function (e) { onMouseMovePolyline(e); }); + + lastDistance = polyline.getDistance(); + addMileStone(coord, 'Start') + } else { + guideline.setPath([e.coord]); + polyline.getPath().push(coord); + + var distance = polyline.getDistance(); + addMileStone(coord, fromMetersToText(distance - lastDistance)); + lastDistance = distance; + } + // } + } + + const onMouseMovePolyline = (e) => { + console.log('onMouseMovePolyline') + var proj = map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = guideline.getPath(); + + if (path.getLength() === 2) { + path.pop(); + } + + path.push(coord); + } + + const onClickPolygon = (e) => { + console.log('onClickPolygon') + var coord = e.coord; + + if (!polygon) { + polygon = new naver.maps.Polygon({ + strokeColor: '#283046', + strokeOpacity: 1, + fillColor: '#7367F0', + fillOpacity: 0.1, + paths: [coord], + map: map + }); + + Eve.rightclickEve = naver.maps.Event.addListener(map, 'rightclick', function () { finishDraw() }) + $(document).on('mousemove.measure', function (e) { onMouseMovePolygon(e) }); + } else { + polygon.getPath().push(coord); + } + } + + const onMouseMovePolygon = (e) => { + console.log('onMouseMovePolygon') + if (!polygon) return; + + var proj = map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)), + path = polygon.getPath(); + + if (path.getLength() >= 2) { + path.pop(); + } + + path.push(coord); + } + + const onClickCircle = (e) => { + console.log('onClickCircle') + var coord = e.coord; + + if(!circle) { + radiusline = new naver.maps.Polyline({ + strokeStyle: [4, 4], + strokeOpacity: 0.6, + path: [coord], + map: map + }) + lastDistance = radiusline.getDistance(); + + circle = new naver.maps.Circle({ + strokeColor: '#283046', + strokeOpacity: 1, + fillColor: '#7367F0', + fillOpacity: 0.1, + center: coord, + radius: 100, + // map: map, + clickable: true + }) + + Eve.mousedownEve = naver.maps.Event.addListener(circle, 'mousedown', function () { onMouseDownDrag(0); }) + } else { + circle.setCenter(coord); + circle.setRadius(100); + } + // setCircle(circle); + setCircle(prev => ([...prev, circle])) + setAreaInfo(''); + } + + const onMouseDownDrag = (index) => { + console.log('onMouseDownDrag') + + if (circle) { + naver.maps.Event.removeListener(Eve.clickEve); + } + + map.setOptions({ + draggable: false, + pinchZoom: false, + scrollWheel: false, + keyboardShortcuts: false, + disableDoubleTapZoom: true, + disableDoubleClickZoom: true, + disableTwoFingerTapZoom: true + }) + + $(document).on('mousemove.measure', function (e) { onMouseMoveDrag(e, index) }); + $(document).on('mouseup.measure', function () { onMouseUpDrag() }); + } + + const onMouseMoveDrag = (e, index) => { + console.log('onMouseMoveDrag') + + check = true; + + var proj = map.getProjection(), + coord = proj.fromPageXYToCoord(new naver.maps.Point(e.pageX, e.pageY)); + + if (polyline) { + var polypaths = polyline.getPath()._array; + + let movepath = []; + for (let i = 0; i < polypaths.length; i++) { + let path; + if (i === index) { + path = coord; + } else { + path = polypaths[i] + } + movepath.push(path); + } + + polyline.setPath(movepath); + + } else if (polygon) { + var polygonpaths = polygon.getPath()._array; + + let movepath = []; + for (let i = 0; i < polygonpaths.length; i++) { + let path; + if (i === index) { + path = coord; + } else { + path = polygonpaths[i] + } + movepath.push(path); + } + polygon.setPaths(movepath) + + } else if (circle) { + // var circlepath = radiusline.getPath(), + // center = circle.getCenter(), + // r = proj.getDistance(coord, center); + var center = circle.getCenter(), + r = proj.getDistance(coord, center); + + // if (circlepath.getLength() === 2) { + // circlepath.pop(); + // } + // circlepath.push(coord); + circle.setRadius(r); + } + + if (!circle) { + dragCircle[index].setCenter(coord); + } + } + + const onMouseUpDrag = () => { + console.log('onMouseUpDrag') + + map.setOptions({ + draggable: true, + pinchZoom: true, + scrollWheel: true, + keyboardShortcuts: true, + disableDoubleTapZoom: false, + disableDoubleClickZoom: false, + disableTwoFingerTapZoom: false + }) + + if (polyline) { + var path = polyline.getPath()._array; + setPolyline(polyline); + setAreaInfo(path); + props.handleBufferList(); + } + + if (polygon) { + var path = polygon.getPath()._array; + setPolygon(polygon); + setAreaInfo(path); + } + + $(document).off('mousemove.measure'); + $(document).off('mouseup.measure'); + + if (circle) { + // Eve.clickEve = naver.maps.Event.addListener(map, 'click', function(e) { onClickCircle(e); }) + setEve(naver.maps.Event.addListener(map, 'click', function (e) { onClickCircle(e) })) + // setCircle(circle); + setCircle(prev => ([...prev, circle])) + setAreaInfo(''); + } + + check = false; + } + + const setAreaInfo = (path) => { + areaInfo = { + coordinates: [], + bufferZone: 0, + }; + + let prePath = []; + if (path) { + path.forEach((item) => { + const p = { + lat: item.y, + lon: item.x + } + + prePath.push(p); + }) + // path.forEach(prev=> prePath.push([prev.x, prev.y])) + } + + if (polyline) { + areaInfo.coordinates = prePath; + areaInfo.areaType = 'LINE'; + } else if (polygon) { + areaInfo.coordinates = prePath; + areaInfo.areaType = 'POLYGON'; + } else if (circle) { + const point = { + lat: circle.getCenter().y, + lon: circle.getCenter().x + } + + areaInfo.coordinates.push(point); + areaInfo.bufferZone = circle.getRadius(); + areaInfo.areaType = 'CIRCLE'; + } + props.handleCoordinates(areaInfo); + // console.log(areaInfo, 'areaInfo') + } + + const onClickReset = () => { + console.log('onClickRest - ', mapControl.drawType); + if (mapControl.drawType === 'RESET') { + clearMode('RESET'); + } + } + + const handleDetailDrwa = () => { + if (props.areaCoordList) { + console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>') + + const areas = props.areaCoordList[0]; + + const paths = []; + + areas.coordList.forEach((coord) => { + const path = new naver.maps.LatLng(coord.lat, coord.lon) + + paths.push(path); + }); + + if (areas.areaType && areas.areaType === 'LINE') { + //polyline 생성 + if(pastPolyline) { + pastPolyline.setMap(null); + pastDragCircle.forEach(c => c.setMap(null)); + } + polyline = new naver.maps.Polyline({ + strokeLineCap: 'round', + strokeLineJoin: 'round', + strokeColor: '#283046', + strokeWeight: 3, + strokeOpacity: 1, + path: paths, + map: map + }); + + setPolyline(polyline) + + //dragCircle 생성 + for(let i = 0; i < paths.length; i++) { + dragCircle.push( + new naver.maps.Circle({ + strokestrokeOpacity: 1, + strokeColor: '#000000', + fillColor: '#ffffff', + fillOpacity: 1, + center: paths[i], + radius: 15, + map: map, + clickable: true + }) + ) + dragCircleEve.push(naver.maps.Event.addListener(dragCircle[i], 'mousedown', function () { onMouseDownDrag(i) })) + } + + setDragCircle(dragCircle); + + if (areas.bufferCoordList) { + const bufferPaths = []; + + areas.bufferCoordList.forEach((bfCoord) => { + const path = new naver.maps.LatLng(bfCoord.lat, bfCoord.lon); + + bufferPaths.push(path); + }); + console.log('buffer test : ',areas.bufferCoordList); + + if(pastBuffer) { + pastBuffer.setMap(null); + } + + // console.log(bufferPaths) + //bufferline 생성 + bufferPolygon = new naver.maps.Polyline({ + strokeColor: '#283046', + strokeOpacity: 1, + // fillColor: '#7367F0', + // fillOpacity: 0.1, + path: bufferPaths, + map: map + }); + // console.log(bufferPolygon); + setBuffer(bufferPolygon); + } + } + + if (areas.areaType && areas.areaType === 'POLYGON') { + //polygon 생성 + if(pastPolygon) { + pastPolygon.setMap(null); + pastDragCircle.forEach(c => c.setMap(null)); + } + polygon = new naver.maps.Polygon({ + strokeColor: '#283046', + strokeOpacity: 1, + fillColor: '#7367F0', + fillOpacity: 0.1, + paths: paths, + map: map + }); + + setPolygon(polygon); + + //dragCircle 생성 + for(let i = 0; i < paths.length; i++) { + dragCircle.push( + new naver.maps.Circle({ + strokestrokeOpacity: 1, + strokeColor: '#000000', + fillColor: '#ffffff', + fillOpacity: 1, + center: paths[i], + radius: 15, + map: map, + clickable: true + }) + ) + dragCircleEve.push(naver.maps.Event.addListener(dragCircle[i], 'mousedown', function () { onMouseDownDrag(i) })) + } + + setDragCircle(dragCircle); + } + + if (areas.areaType && areas.areaType === 'CIRCLE') { + //circle 생성 + if(pastCircle) { + // pastCircle.setMap(null); + console.log(pastCircle) + pastCircle.forEach(prev => prev.setMap(null)); + } + if(circle) { + circle.setMap(null); + } + // radiusline = new naver.maps.Polyline({ + // strokeStyle: [4, 4], + // strokeOpacity: 0.6, + // path: [coord], + // map: map + // }) + circle = new naver.maps.Circle({ + strokeColor: '#283046', + strokeOpacity: 1, + // fillColor: '#ff0000', + fillColor: '#7367F0', + fillOpacity: 0.1, + center: paths[0], + radius: areas.bufferZone, + map: map, + clickable: true + }); + Eve.mousedownEve = naver.maps.Event.addListener(circle, 'mousedown', function () { onMouseDownDrag(0); }) + + setCircle([circle]); + } + } + } + + const addMileStone = (coord, text, css) => { + if(distanceMarker) distanceMarker = []; + + let content; + if(text == 'Start') { + content = '
'+ text +'
' + } else { + content = '
'+ text +'
' + } + + var _ms = new naver.maps.Marker({ + position: coord, + icon: { + content: content, + anchor: new naver.maps.Point(-5, -5) + }, + map: map + }); + + var msElement = $(_ms.getElement()); + + if(css) { + msElement.css(css); + } else { + msElement.css('font-size', '13px'); + } + + distanceMarker.push(_ms); + setMarker(prev => ([...prev, _ms])) + } + + const fromMetersToText = (meters) => { + meters = meters || 0; + + var km = 1000, + text = meters; + + if(meters >= km) { + text = parseFloat((meters / km).toFixed(1)) + 'km'; + } else { + text = parseFloat(meters.toFixed(1)) + 'm'; + } + return text; + } + + return ( + <> + + ); +}; \ No newline at end of file diff --git a/src/components/mapDraw/naver/draw/JQueryDraw.js b/src/components/mapDraw/naver/draw/JQueryDraw.js index 65f4560..e36f419 100644 --- a/src/components/mapDraw/naver/draw/JQueryDraw.js +++ b/src/components/mapDraw/naver/draw/JQueryDraw.js @@ -2,8 +2,6 @@ import $ from 'jquery'; import '../../../../assets/css/custom.css'; import { CustomInput } from 'reactstrap'; -import buffer from '@turf/buffer' - export const JQueryDraw = props => { const {naver} = props; const {map} = props; diff --git a/src/containers/basis/flight/plan/FlightPlanArcrftContainer.js b/src/containers/basis/flight/plan/FlightPlanArcrftContainer.js new file mode 100644 index 0000000..e6e377c --- /dev/null +++ b/src/containers/basis/flight/plan/FlightPlanArcrftContainer.js @@ -0,0 +1,45 @@ +import React, {useEffect, useState} from 'react'; +import {useDispatch, useSelector} from 'react-redux'; +import FlightPlanArcrft from '../../../../components/basis/flight/plan/FlightPlanArcrft'; +import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; +// import FlightPlanPilot from '../../../../components/basis/flight/plan/FlightPlanPilot'; + +const FlightPlanArcrftContainer = ({handleModal, type}) => { + const dispatch = useDispatch(); + const { arcrftList } = useSelector(state => state.flightState); + + + /* 기체 조회 */ + const handleSearch = () => { + const groupId = sessionStorage.getItem('groupId'); + + if(groupId) { + dispatch(Actions.FLIGHT_PLAN_ARCRFT_LIST.request(groupId)); + } + } + + /* 기체 선택 */ + const handleSelectArcrft = (arcrftSno) => { + handleModal({target: 'arcrft', isOpen: false}); + + const arcrft = arcrftList.find(arcrft => { + return arcrft.arcrftSno === arcrftSno; + }); + /* 기체 정보 Redux 저장 */ + dispatch(Actions.ARCRFT_SELECT(arcrft)); + } + + useEffect(() => { + handleSearch(); + }, []) + + + return ( + + ) +} + +export default FlightPlanArcrftContainer; \ No newline at end of file diff --git a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js index 39dc57e..3ae27cb 100644 --- a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js @@ -2,74 +2,61 @@ import React, { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import {useHistory} from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; -import FlightPlanAreaForm from '../../../../components/basis/flight/plan/FlightPlanAreaForm'; import {Col, Row, Form } from 'reactstrap'; import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; import FlightPlanAreaMap from '../../../../components/basis/flight/plan/FlightPlanAreaMap'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; +import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions'; +import FlightPlanAreaDetailContainer from './FlightPlanAreaDetailContainer'; -const FlightPlanAreaContainer = (props) => { - const dispatch = useDispatch(); - const history = useHistory(); - - const { areaList } = useSelector(state => state.flightState); - const [airArea, setAirArea] = useState(null); - - const validSchema = yup.object().shape({ - }); - - const { register, getValues, setValue, errors, handleSubmit } = useForm({ - defaultValues: { - coodinates: [], - radius: '', - altitude_m: '', - altitude_ft: '', - }, - resolver: yupResolver(validSchema) - }); +const FlightPlanAreaContainer = ({handleModal}) => { + const dispatch = useDispatch(); + const { publicAreaList} = useSelector(state => state.flightState); + const [airArea, setAirArea] = useState(null); const getAirAreaList = () => { - dispatch(Actions.AREA_LIST.request()); - } - - const createAirArea = async data => { - dispatch(Actions.FLIGHT_PLAN_AREA.request(data)); - - props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }); - props.setOnSubmit(false); + dispatch(Actions.PUBLIC_AREA_LIST.request()); + } + + const handleConfirm = (areaList) => { + if(areaList === undefined) { + alert('영역을 설정해주세요.') + return false; + } + + dispatch(Actions.AREA_COORDINATE_LIST_SAVE(areaList)) } - useEffect(() => { + useEffect(() => { + dispatch(drawTypeChangeAction('')); getAirAreaList(); }, []); - useEffect(() => { - setAirArea(areaList); - }, [areaList]) + useEffect(() => { + setAirArea(publicAreaList); + }, [publicAreaList]) + - return ( + return ( {airArea != null ? ( - ) : null} - - - - - - + ) : null} + + + + + + ) } -export default FlightPlanAreaContainer; \ No newline at end of file +export default FlightPlanAreaContainer; diff --git a/src/containers/basis/flight/plan/FlightPlanAreaDetailContainer.js b/src/containers/basis/flight/plan/FlightPlanAreaDetailContainer.js new file mode 100644 index 0000000..c6e5443 --- /dev/null +++ b/src/containers/basis/flight/plan/FlightPlanAreaDetailContainer.js @@ -0,0 +1,86 @@ +import React, { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { Col, Row, Form } from 'reactstrap'; +import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; +import FlightPlanAreaDetailForm from '../../../../components/basis/flight/plan/FlightPlanAreaDetailForm'; +import {initFlightBas} from '../../../../modules/basis/flight/models/basisFlightModel'; + + +const FlightPlanAreaDetailContainer = ({ handleModal }) => { + const dispatch = useDispatch(); + + const { areaCoordList, detail } = useSelector(state => state.flightState); + const [areaDetail, setAreaDetail] = useState(initFlightBas.initDetail.areaList); + + const handleClose = (status) => { + handleModal({ type: 'area', isOpne: false}); + } + + const handleSave = () => { + const resultAreaDetail = areaDetail.map((area, i) => { + return { + ...area, + coordList : areaDetail[0].coordList + } + }); + + dispatch(Actions.AREA_DETAIL_LIST_SAVE(resultAreaDetail)); + + handleModal({ type: 'area', isOpne: false}); + } + + const handleChange = ({ name, value }) => { + setAreaDetail(prevState => { + const areaList = prevState.map((area, i) => { + return { + ...area, + [name] : value + } + }); + + return areaList; + }) + } + + const handleBufferList = () => { + dispatch(Actions.FLIGHT_PLAN_AREA_BUFFER_LIST.request(areaDetail)); + } + + useEffect(() => { + // 좌표등록 (등록 시 데이터 초기화) + if(areaCoordList !== undefined) { + setAreaDetail(areaCoordList); // 새로 만든 영역 + } + }, [areaCoordList]); + + useEffect(() => { + // detail의 area 정보가 존재하면 detail 정보로 매핑 + if(detail.areaList) { + if(detail.areaList[0].planAreaSno !== 0) { + setAreaDetail(detail.areaList); + + dispatch(Actions.AREA_DETAIL_LIST_SAVE(detail.areaList)); + } + } + + }, []) + + + return ( + + + + + + + ) +} + +export default FlightPlanAreaDetailContainer; \ No newline at end of file diff --git a/src/containers/basis/flight/plan/FlightPlanContainer.js b/src/containers/basis/flight/plan/FlightPlanContainer.js index 51f71b2..033ea4c 100644 --- a/src/containers/basis/flight/plan/FlightPlanContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanContainer.js @@ -1,38 +1,138 @@ -import React, { useState } from 'react'; -import moment from 'moment'; -import { Link, useHistory } from 'react-router-dom'; +import React, {useEffect, useState} from 'react'; +import moment, { suppressDeprecationWarnings } from 'moment'; +import {Link, Redirect, useHistory} from 'react-router-dom'; import FlightPlanGrid from '../../../../components/basis/flight/plan/FlightPlanGrid'; -import { CustomMainLayout } from '../../../../components/layout/CustomMainLayout'; +import {CustomMainLayout} from '../../../../components/layout/CustomMainLayout'; import FlightPlanSearch from '../../../../components/basis/flight/plan/FlightPlanSearch'; +import {useDispatch, useSelector, shallowEqual} from 'react-redux'; +import * as FlightAction from '../../../../modules/basis/flight/actions/basisFlightAction'; +import {FlightPlanListRqData} from '../../../../modules/basis/flight/models/basisFlightModel'; +import { Row, Col } from 'reactstrap'; +import { JOIN_LIST } from "../../../../modules/basis/group/actions/basisGroupAction"; +import FlightPlanGroupGrid from '../../../../components/basis/flight/plan/FlightPlanGroupGrid'; -const FlightPlanContainer = () => { +const initSearchData = { + schFltStDt: moment().set({'m': 7, 'date': 1, 'h': 0, 'm': 0, 's': 0}).format('YYYY-MM-DD HH:mm:ss'), + schFltEndDt: moment().set({'h': 23, 'm': 59, 's': 59}).format('YYYY-MM-DD HH:mm:ss'), + aprvlYn: 'N', + groupId: '', + cstmrSno: 0, +} +const columns = [{}] +const FlightPlanContainer = () => { + const dispatch = useDispatch(); const history = useHistory(); + const [searchData, setSerchData] = useState(initSearchData); + const {list: planListData, detail: planDetailData, selectGroup, areaCoordList } = useSelector(state => state.flightState); + const { joinList, joinListCount } = useSelector(state => state.groupState); + const { user } = useSelector(state => state.authState, shallowEqual); - const moveFlightPlan = () => { + const [ params, setParams ] = useState({}); + + + const moveFlightPlanDetailPage = () => { + if(planDetailData){ + dispatch(FlightAction.FLIGHT_PLAN_DETAIL_INIT()); + } + if(areaCoordList) { + dispatch(FlightAction.AREA_DETAIL_INIT()); + } history.push('/basis/flight/plan/create'); }; - const [times, setTimes] = useState({ - stDate: moment().subtract(1, 'day').format('YYYY-MM-DD'), - endDate: moment().subtract(-1, 'day').format('YYYY-MM-DD'), - search1: '' - }) + const handleSearch = (data) => { + dispatch(FlightAction.FLIGHT_PLAN_LIST.request(data)); + } + + const handleChangeSearchData = (values) => { + setSerchData(prevState => ({ + ...prevState, + ...values + })) + } + + const handleMoveDetail = (id) => { + history.push(`/basis/flight/plan/detail/${id}`) + } + + const handleGroupSelect = ({ groupId, groupNm, groupAuthCd }) => { + // 권한 상관 없이 모두 조회 가능 + console.log('select group : ', groupId) + const param = searchData; + + param.cstmrSno = user.cstmrSno; + param.groupId = groupId; + + dispatch(FlightAction.FLIGHT_PLAN_GROUP_SELECT( {cstmrSno: user.cstmrSno, groupId: groupId, groupNm: groupNm} )); + + // groupId sessionStorage에 보관 (1 브라우저 1 tab에만 유효) + sessionStorage.setItem('groupId', groupId); + + setSerchData(prevState => { + return { + ...prevState, + cstmrSno: user.cstmrSno, + groupId: groupId + } + }); + + dispatch(FlightAction.FLIGHT_PLAN_LIST.request(param)); + } - // console.log(history, 'history') + const handlerGroupCancel = () => { + dispatch(FlightAction.FLIGHT_PLAN_GROUP_SELECT( {cstmrSno: 0, groupId: '', groupNm: ''} )); + } + useEffect(() => { + if (user?.cstmrSno) { + dispatch( + JOIN_LIST.request({ + cstmrSno: user?.cstmrSno + }) + ); + } + }, [user]) return ( - // - - +
+ + + + + + {selectGroup.cstmrSno !== 0 ? ( + <> + + + + ) : ( +
+ 나의 그룹 목록에서 상세보기를 클릭하세요. +
+ )} + + +
+
) } -export default FlightPlanContainer; \ No newline at end of file +export default FlightPlanContainer; diff --git a/src/containers/basis/flight/plan/FlightPlanDetailContainer.js b/src/containers/basis/flight/plan/FlightPlanDetailContainer.js index 3df9a61..fd9d613 100644 --- a/src/containers/basis/flight/plan/FlightPlanDetailContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanDetailContainer.js @@ -1,68 +1,377 @@ import React, {useEffect, useState} from 'react'; import FlightPlanForm from '../../../../components/basis/flight/plan/FlightPlanForm'; -import { CustomDetailLayout } from '../../../../components/layout/CustomDetailLayout'; -import { FlightPlanAreaModal } from '../../../../components/basis/flight/plan/FlightPlanAreaModal'; -import FlightPlanAreaContainer from './FlightPlanAreaContainer'; -import {useHistory} from 'react-router-dom'; -import { useDispatch, useSelector } from 'react-redux'; -import * as yup from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; +import {CustomDetailLayout} from '../../../../components/layout/CustomDetailLayout'; +import {useHistory, useLocation, useParams} from 'react-router-dom'; +import {useDispatch, useSelector} from 'react-redux'; import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; -import { useForm } from 'react-hook-form'; +import {initFlightBas} from '../../../../modules/basis/flight/models/basisFlightModel'; + + +const initModal = { + area: false, + pilot: false, + arcrft: false +} const FlightPlanDetailContainer = () => { const dispatch = useDispatch(); const history = useHistory(); - - const { flightPlanArea } = useSelector(state => state.flightState); - const [areaInfo, setAreaInfo] = useState(); - const [modal, setModal] = useState({ - isOpen: false, - title: '', - }); - - /* Form Validation Checking */ - const validSchema = yup.object().shape({ - }); - const {} = useForm({ - defaultValues: { - coodinates: [], - radius: '', - altitude_m: '', - altitude_ft: '', - }, - resolver: yupResolver(validSchema) - }) - - const saveFlightPlanArea = () => { - console.log('비행 구역 설정 저장'); - } + const location = useLocation(); + const urlParams = useParams(); + const flightState = useSelector(state => state.flightState); + const { detail, pilotSelect, arcrftSelect, areaList, selectGroup } = flightState; + const [modal, setModal] = useState(initModal); + const [detailData, setDetailData] = useState(initFlightBas.initDetail); + + useEffect(() => { + if (Object.keys(urlParams).length === 0 && urlParams.constructor === Object) return; + dispatch(Actions.FLIGHT_PLAN_DETAIL.request(urlParams.planSno)); + }, [urlParams]) - const openModal = () => { - setModal({ - isOpen: true, - title: '비행 구역 설정', + useEffect(() => { + setDetailData({ + ...detail, + cstmrSno: selectGroup.cstmrSno, + groupId: selectGroup.groupId, }); - } + }, [detail]) + + useEffect(() => { + if(pilotSelect !== undefined) { + const pilotList = detailData.pilotList.concat(); + const pilot = Object.assign({}, initFlightBas['pilot']); + + pilot.cstmrSno = pilotSelect.cstmrSno; + pilot.groupNm = pilotSelect.groupNm; + pilot.clncd = pilotSelect.clncd; + pilot.email = pilotSelect.email; + pilot.memberName = pilotSelect.memberName; + pilot.hpno = pilotSelect.hpno; + + pilotList.forEach((p, i) => { + if(p.cstmrSno === 0) { + pilotList[i] = pilot + } else { + if(i === pilotList.length-1) { + return pilotList.push(pilot); + } + } + }); + + setDetailData(prevState => { + return { + ...prevState, + ['pilotList']: pilotList + } + }) + } + + }, [pilotSelect]) + + useEffect(() => { + if(arcrftSelect !== undefined) { + const arcrftList = detailData.arcrftList.concat(); + const arcrft = Object.assign({}, initFlightBas['arcrft']); + + arcrft.arcrftSno = arcrftSelect.arcrftSno; + arcrft.groupId = arcrftSelect.groupId; + arcrft.groupNm = arcrftSelect.groupNm; + arcrft.arcrftModelNm = arcrftSelect.arcrftModelNm; + arcrft.idntfTypeCd = arcrftSelect.idntfTypeCd; + arcrft.arcrftTypeCd = arcrftSelect.arcrftTypeCd; + arcrft.idntfNum = arcrftSelect.idntfNum; + arcrft.ownerNm = arcrftSelect.ownerNm; + + arcrftList.forEach((p, i) => { + if(p.arcrftSno === 0) { + arcrftList[i] = arcrft + } else { + if(i === arcrftList.length-1) { + return arcrftList.push(arcrft); + } + } + }); + + setDetailData(prevState => { + return { + ...prevState, + ['arcrftList']: arcrftList + } + }) + } + }, [arcrftSelect]) + + useEffect(() => { + if(areaList !== undefined) { + const areas = detailData.areaList.concat(); + + const createAreaList = areas.map((area, i) => { + const targetArea = areaList[i]; + + let targetCoordList = area.coordList; + if(targetArea.coordList) { + targetCoordList = targetArea.coordList.map((coord, j) => { + return { + ...coord, + planAreaSno : area.planAreaSno, + planAreaCoordSno : 0 + } + }) + } + + + return { + ...area, + areaType : targetArea.areaType, + bufferZone: targetArea.bufferZone, + fltElev : targetArea.fltElev, + fltMethod : targetArea.fltMethod, + coordList : targetCoordList + } + }); + + setDetailData(prevState => { + return { + ...prevState, + ['areaList']: createAreaList + } + }) + + // dispatch(Actions.AREA_DETAIL_INIT()); + } + + }, [areaList]); useEffect(() => { - setAreaInfo(flightPlanArea); - }, [flightPlanArea]); + // 조종사, 기체 정보 Redux 초기화 + dispatch(Actions.PILOT_ARCRFT_SELECT_INIT()); + }, []); + + const handleModal = (modal) => { + if(modal.target === 'area' && modal.isOpen) { + if(detailData.areaList) { + dispatch(Actions.FLIGHT_PLAN_AREA_BUFFER_LIST.request(detailData.areaList)); + } + } + + setModal(prevState => ({ + ...initModal, + [modal.target]: modal.isOpen + })) + } + + // 변경감지 + const handleChange = ({name, value, type, index, pIndex}) => { + const arrName = `${type}List`; + switch (type) { + case 'coord': + // TODO 추후 삭제 필요 start + if(name == 'lonlat'){ + const values = value.split("/"); + let latValue = 1 + let lonValue = 1 + if(values.length == 1){ + latValue = values[0].trim(); + } else if(values.length == 2){ + latValue = values[0].trim(); + lonValue = values[1].trim(); + } else { + return; + } + setDetailData(prevState => { + const areaList = prevState.areaList.map((area, i) => { + if(i !== pIndex) return {...area}; + + const coordList = area.coordList.map((coord, j) => { + if(j !== index) return {...coord}; + return { + ...coord, + lat: latValue, + lon: lonValue + } + }) + return { + ...area, + coordList + } + }) + return { + ...prevState, + areaList + } + }) + return; + } + // TODO 추후 삭제 필요 end + + setDetailData(prevState => { + const areaArr = [...prevState.areaList]; + const coordArr = areaArr[pIndex].coordList; + const updateData = { + ...coordArr[index], + [name]: value + } + coordArr[index] = updateData; + areaArr[pIndex] = coordArr + return { + ...prevState, + areaList: areaArr + } + }) + break; + case 'area': + case 'pilot': + case 'arcrft': + setDetailData(prevState => { + const arr = [...prevState[arrName]]; + const updateData = { + ...prevState[arrName][index], + [name]: value + } + arr[index] = updateData; + return { + ...prevState, + [arrName]: arr + } + }) + break; + case 'plan': + default: + setDetailData(prevState => ({ + ...prevState, + [name]: value + })) + break; + } + } + + // 추가 + const handleAddArray = ({type, pIndex}) => { + const arrName = `${type}List`; + switch (type) { + case 'coord': + setDetailData(prevState => { + const areaArr = [...prevState.areaList]; + const coordArr = [...areaArr[pIndex].coordList, initFlightBas[type]]; + areaArr[pIndex] = coordArr; + return { + ...prevState, + areaList: [...areaArr] + } + }) + break; + case 'area': + case 'pilot': + setDetailData(prevState => { + return { + ...prevState, + [arrName]: [...prevState[arrName], initFlightBas[type]] + } + }) + break; + case 'arcrft': + setDetailData(prevState => { + return { + ...prevState, + [arrName]: [...prevState[arrName], initFlightBas[type]] + } + }) + break; + default: + break; + } + } + // 삭제 + const handleDeleteArray = ({type, index, pIndex}) => { + const arrName = `${type}List`; + switch (type) { + case 'coord': + setDetailData(prevState => { + const areaArr = [...prevState.areaList]; + const coordArr = [...areaArr[pIndex]]; + const deleteData = coordArr.splice(index, 1); + areaArr[pIndex] = coordArr; + return { + ...prevState, + areaList: [...areaArr] + } + }) + break; + case 'area': + case 'pilot': + setDetailData(prevState => { + const arr = [...prevState[arrName]]; + const deleteData = arr.splice(index, 1); + + return { + ...prevState, + [arrName]: arr + } + }) + case 'arcrft': + setDetailData(prevState => { + const arr = [...prevState[arrName]]; + const deleteData = arr.splice(index, 1); + + if(arr.length > 0) { + return { + ...prevState, + [arrName]: arr + } + } else { + return { + ...prevState, + ['pilotList']: initFlightBas[arrName] + } + } + + }) + default: + break; + } + } + + + // 저장 + const handleSave = () => { + if (!detailData.planSno) { + dispatch(Actions.FLIGHT_PLAN_CREATE.request(detailData)); + } else { + dispatch(Actions.FLIGHT_PLAN_UPDATE.request(detailData)); + } + + dispatch(FlightAction.FLIGHT_PLAN_GROUP_SELECT( {cstmrSno: 0, groupId: '', groupNm: ''} )); + } + // 삭제 + const handleDelete = () => { + dispatch(Actions.FLIGHT_PLAN_DELETE.request(urlParams.planSno)); + } return ( - + data={detailData} + handleModal={handleModal} + handleSave={handleSave} + handleDelete={handleDelete} + handleChange={handleChange} + handleAddArray={handleAddArray} + handleDeleteArray={handleDeleteArray} + // handlerSave={ + // pageType === 'create' ? handlerCreate : handlerUpdate + // } + // onChange={onChange} + // handlerDelete={handlerDelete} + // handlerInput={handlerInput} + /> + {/**/} ) +}; -} - -export default FlightPlanDetailContainer; \ No newline at end of file +export default FlightPlanDetailContainer; diff --git a/src/containers/basis/flight/plan/FlightPlanPilotContainer.js b/src/containers/basis/flight/plan/FlightPlanPilotContainer.js new file mode 100644 index 0000000..80efada --- /dev/null +++ b/src/containers/basis/flight/plan/FlightPlanPilotContainer.js @@ -0,0 +1,44 @@ +import React, {useEffect, useState} from 'react'; +import {useDispatch, useSelector} from 'react-redux'; +import * as Actions from '../../../../modules/basis/flight/actions/basisFlightAction'; +import FlightPlanPilot from '../../../../components/basis/flight/plan/FlightPlanPilot'; + +const FlightPlanPilotContainer = ({handleModal, type}) => { + const dispatch = useDispatch(); + const { pilotList, selectGroup } = useSelector(state => state.flightState); + + + /* 조종사 조회 */ + const handleSearch = () => { + const groupId = sessionStorage.getItem('groupId'); + + if(groupId) { + dispatch(Actions.FLIGHT_PLAN_PILOT_LIST.request(groupId)); + } + } + + /* 조종사 선택 */ + const handleSelectPilot = (cstmrSno) => { + handleModal({target: 'poilot', isOpen: false}); + + const pilot = pilotList.find(pilot => { + return pilot.cstmrSno === cstmrSno; + }); + /* 파일럿 정보 Redux 저장 */ + dispatch(Actions.PILOT_SELECT(pilot)); + } + + useEffect(() => { + handleSearch(); + }, []) + + + return ( + + ) +} + +export default FlightPlanPilotContainer; \ No newline at end of file diff --git a/src/modules/basis/flight/actions/basisFlightAction.ts b/src/modules/basis/flight/actions/basisFlightAction.ts index 402a7ba..3202115 100644 --- a/src/modules/basis/flight/actions/basisFlightAction.ts +++ b/src/modules/basis/flight/actions/basisFlightAction.ts @@ -1,33 +1,197 @@ import { AxiosError } from 'axios'; -import { createAsyncAction, ActionType} from 'typesafe-actions'; -import { FlightAreaData, FlightPlanArea } from '../models/basisFlightModel'; +import { createAsyncAction, ActionType, createAction } from 'typesafe-actions'; +import { + PublicAreaData, + FlightPlanArcrftData, + FlightPlanArcrftDataList, + FlightPlanAreaDataList, + // FlightPlanArea, + FlightPlanData, + FlightPlanListRqData, FlightPlanPilotDataList, PilotSelectData, SelectGroupData +} from '../models/basisFlightModel'; // 공역 조회 -const AREA_LIST_REQUEST = 'basis/flight/area/LIST_REQUEST'; -const AREA_LIST_SUCCESS = 'basis/flight/area/LIST_SUCCESS'; -const AREA_LIST_FAILURE = 'basis/flight/area/LIST_FAILURE'; +const PUBLIC_AREA_LIST_REQUEST = 'basis/flight/public_area/LIST_REQUEST'; +const PUBLIC_AREA_LIST_SUCCESS = 'basis/flight/public_area/LIST_SUCCESS'; +const PUBLIC_AREA_LIST_FAILURE = 'basis/flight/public_area/LIST_FAILURE'; // 비행 구역 설정 -const FLIGHT_PLAN_AREA_REQUEST = 'basis/flight/plan/area/LIST_REQUEST'; -const FLIGHT_PLAN_AREA_SUCCESS = 'basis/flight/plan/area/LIST_SUCCESS'; -const FLIGHT_PLAN_AREA_FAILURE = 'basis/flight/plan/area/LIST_FAILURE'; - -export const AREA_LIST = createAsyncAction( - AREA_LIST_REQUEST, - AREA_LIST_SUCCESS, - AREA_LIST_FAILURE -)(); - -export const FLIGHT_PLAN_AREA = createAsyncAction( - FLIGHT_PLAN_AREA_REQUEST, - FLIGHT_PLAN_AREA_SUCCESS, - FLIGHT_PLAN_AREA_FAILURE -)(); +// const FLIGHT_PLAN_AREA_REQUEST = 'basis/flight/plan/area/LIST_REQUEST'; +// const FLIGHT_PLAN_AREA_SUCCESS = 'basis/flight/plan/area/LIST_SUCCESS'; +// const FLIGHT_PLAN_AREA_FAILURE = 'basis/flight/plan/area/LIST_FAILURE'; + +// 목록 +const FLIGHT_PLAN_LIST_REQUEST = 'basis/flight/plan/list/LIST_REQUEST'; +const FLIGHT_PLAN_LIST_SUCCESS = 'basis/flight/plan/list/LIST_SUCCESS'; +const FLIGHT_PLAN_LIST_FAILURE = 'basis/flight/plan/list/LIST_FAILURE'; + +// 상세 +const FLIGHT_PLAN_DETAIL_REQUEST = 'basis/flight/plan/detail/DETAIL_REQUEST'; +const FLIGHT_PLAN_DETAIL_SUCCESS = 'basis/flight/plan/detail/DETAIL_SUCCESS'; +const FLIGHT_PLAN_DETAIL_FAILURE = 'basis/flight/plan/detail/DETAIL_FAILURE'; +// 상세 초기화 +const FLIGHT_PLAN_DETAIL_INITIAL = 'basis/flight/plan/detail/DETAIL_INIT'; +// 생성 +const FLIGHT_PLAN_CREATE_REQUEST = 'basis/flight/plan/create/CREATE_REQUEST'; +const FLIGHT_PLAN_CREATE_SUCCESS = 'basis/flight/plan/create/CREATE_SUCCESS'; +const FLIGHT_PLAN_CREATE_FAILURE = 'basis/flight/plan/create/CREATE_FAILURE'; + +// 수정 +const FLIGHT_PLAN_UPDATE_REQUEST = 'basis/flight/plan/update/UPDATE_REQUEST'; +const FLIGHT_PLAN_UPDATE_SUCCESS = 'basis/flight/plan/update/UPDATE_SUCCESS'; +const FLIGHT_PLAN_UPDATE_FAILURE = 'basis/flight/plan/update/UPDATE_FAILURE'; + +// 삭제 +const FLIGHT_PLAN_DELETE_REQUEST = 'basis/flight/plan/delete/DELETE_REQUEST'; +const FLIGHT_PLAN_DELETE_SUCCESS = 'basis/flight/plan/delete/DELETE_SUCCESS'; +const FLIGHT_PLAN_DELETE_FAILURE = 'basis/flight/plan/delete/DELETE_FAILURE'; + +// 조종사 조회 +const FLIGHT_PLAN_PILOT_LIST_REQUEST = 'basis/flight/plan/pilot_list/PILOT_LIST_REQUEST'; +const FLIGHT_PLAN_PILOT_LIST_SUCCESS = 'basis/flight/plan/pilot_list/PILOT_LIST_SUCCESS'; +const FLIGHT_PLAN_PILOT_LIST_FAILURE = 'basis/flight/plan/pilot_list/PILOT_LIST_FAILURE'; + +// 조종사 선택 +const FLIGHT_PLAN_PILOT_SELECT = 'basis/flight/plan/pilot_list/PILOT_SELECT'; + +// 기체 조회 +const FLIGHT_PLAN_ARCRFT_LIST_REQUEST = 'basis/flight/plan/arcrft_list/ARCRFT_LIST_REQUEST'; +const FLIGHT_PLAN_ARCRFT_LIST_SUCCESS = 'basis/flight/plan/arcrft_list/ARCRFT_LIST_SUCCESS'; +const FLIGHT_PLAN_ARCRFT_LIST_FAILURE = 'basis/flight/plan/arcrft_list/ARCRFT_LIST_FAILURE'; + +// 기체 선택 +const FLIGHT_PLAN_ARCRFT_SELECT = 'basis/flight/plan/arcrft_list/ARCRFT_SELECT'; + +// 조종사, 기체 선택 초기화 +const PILOT_ARCRFT_SELECT_INITIAL = 'basis/flight/plan/detail/SELECT_INIT'; + +// 비행 구역 좌표 저장 +const AREA_COORDINATE_LIST = 'basis/flight/plan/area/COORDINATE_LIST'; + +// 비행 구역 상세 저장 +const AREA_DETAIL_LIST = 'basis/flight/plan/area/DETAIL_LIST'; + +// 비행계획서 그룹 선택 +const ROUP_SELECT = 'basis/flight/plan/group/select'; + +// 조종사, 기체 선택 초기화 +const AREA_DETAIL_INITIAL = 'basis/flight/plan/detail/AREA_DETAIL_INIT'; + +// 버퍼 좌표 가져오기 +const AREA_BUFFER_LIST_REQUEST = 'basis/flight/plan/area/BUFFER_LIST_REQUEST'; +const AREA_BUFFER_LIST_SUCCESS = 'basis/flight/plan/area/BUFFER_LIST_SUCCESS'; +const AREA_BUFFER_LIST_FAILURE = 'basis/flight/plan/area/BUFFER_LIST_FAILURE'; + +export const PUBLIC_AREA_LIST = createAsyncAction( + PUBLIC_AREA_LIST_REQUEST, + PUBLIC_AREA_LIST_SUCCESS, + PUBLIC_AREA_LIST_FAILURE +)(); + +// export const FLIGHT_PLAN_AREA = createAsyncAction( +// FLIGHT_PLAN_AREA_REQUEST, +// FLIGHT_PLAN_AREA_SUCCESS, +// FLIGHT_PLAN_AREA_FAILURE +// )(); + +// 목록 +export const FLIGHT_PLAN_LIST = createAsyncAction( + FLIGHT_PLAN_LIST_REQUEST, + FLIGHT_PLAN_LIST_SUCCESS, + FLIGHT_PLAN_LIST_FAILURE +)(); + +// 상세 +export const FLIGHT_PLAN_DETAIL = createAsyncAction( + FLIGHT_PLAN_DETAIL_REQUEST, + FLIGHT_PLAN_DETAIL_SUCCESS, + FLIGHT_PLAN_DETAIL_FAILURE +)(); +// 상세 초기화 +export const FLIGHT_PLAN_DETAIL_INIT = createAction(FLIGHT_PLAN_DETAIL_INITIAL)(); +// 생성 +export const FLIGHT_PLAN_CREATE = createAsyncAction( + FLIGHT_PLAN_CREATE_REQUEST, + FLIGHT_PLAN_CREATE_SUCCESS, + FLIGHT_PLAN_CREATE_FAILURE +)(); + +// 수정 +export const FLIGHT_PLAN_UPDATE = createAsyncAction( + FLIGHT_PLAN_UPDATE_REQUEST, + FLIGHT_PLAN_UPDATE_SUCCESS, + FLIGHT_PLAN_UPDATE_FAILURE +)(); + +// 삭제 +export const FLIGHT_PLAN_DELETE = createAsyncAction( + FLIGHT_PLAN_DELETE_REQUEST, + FLIGHT_PLAN_DELETE_SUCCESS, + FLIGHT_PLAN_DELETE_FAILURE +)(); + +// 조종사 목록 +export const FLIGHT_PLAN_PILOT_LIST = createAsyncAction( + FLIGHT_PLAN_PILOT_LIST_REQUEST, + FLIGHT_PLAN_PILOT_LIST_SUCCESS, + FLIGHT_PLAN_PILOT_LIST_FAILURE +)(); + +// 조종사 선택 +export const PILOT_SELECT = createAction(FLIGHT_PLAN_PILOT_SELECT)(); + +// 기체 목록 +export const FLIGHT_PLAN_ARCRFT_LIST = createAsyncAction( + FLIGHT_PLAN_ARCRFT_LIST_REQUEST, + FLIGHT_PLAN_ARCRFT_LIST_SUCCESS, + FLIGHT_PLAN_ARCRFT_LIST_FAILURE +)(); + +// 조종사 선택 +export const ARCRFT_SELECT = createAction(FLIGHT_PLAN_ARCRFT_SELECT)(); + +// 조종사, 기체 선택 초기화 +export const PILOT_ARCRFT_SELECT_INIT = createAction(PILOT_ARCRFT_SELECT_INITIAL)(); + +// 비행 구역 좌표 저장 (스텝2 데이터 공유) +export const AREA_COORDINATE_LIST_SAVE = createAction(AREA_COORDINATE_LIST)(); + +// 비행 구역 상세 저장 +export const AREA_DETAIL_LIST_SAVE = createAction(AREA_DETAIL_LIST)(); + +// 비행 계획서 그룹 선택 +export const FLIGHT_PLAN_GROUP_SELECT = createAction(ROUP_SELECT)(); + +// 비행 구역 상세 값 초기화 +export const AREA_DETAIL_INIT = createAction(AREA_DETAIL_INITIAL)(); + +// 버퍼 좌표 가져오기 +export const FLIGHT_PLAN_AREA_BUFFER_LIST = createAsyncAction( + AREA_BUFFER_LIST_REQUEST, + AREA_BUFFER_LIST_SUCCESS, + AREA_BUFFER_LIST_FAILURE +)(); const actions = { - AREA_LIST, - FLIGHT_PLAN_AREA + PUBLIC_AREA_LIST, + // FLIGHT_PLAN_AREA, + FLIGHT_PLAN_LIST, + FLIGHT_PLAN_DETAIL, + FLIGHT_PLAN_DETAIL_INIT, + FLIGHT_PLAN_CREATE, + FLIGHT_PLAN_UPDATE, + FLIGHT_PLAN_DELETE, + FLIGHT_PLAN_PILOT_LIST, + FLIGHT_PLAN_ARCRFT_LIST, + PILOT_SELECT, + ARCRFT_SELECT, + PILOT_ARCRFT_SELECT_INIT, + AREA_COORDINATE_LIST_SAVE, + AREA_DETAIL_LIST_SAVE, + FLIGHT_PLAN_GROUP_SELECT, + FLIGHT_PLAN_AREA_BUFFER_LIST, + AREA_DETAIL_INIT }; -export type FlightAction = ActionType; \ No newline at end of file +export type FlightAction = ActionType; diff --git a/src/modules/basis/flight/apis/basisFlightApi.ts b/src/modules/basis/flight/apis/basisFlightApi.ts index 32ca049..191289a 100644 --- a/src/modules/basis/flight/apis/basisFlightApi.ts +++ b/src/modules/basis/flight/apis/basisFlightApi.ts @@ -1,9 +1,63 @@ import axios from '../../../utils/customAxiosUtil'; import qs from 'qs'; +import { FlightPlanAreaData, FlightPlanAreaDataList, FlightPlanData, FlightPlanListRqData } from '../models/basisFlightModel'; export const flightPlanAPI = { - area: async () => { - return await axios.get(`api/bas/flight/area`); - } -} \ No newline at end of file + area: async () => { + const res = await axios.get(`api/bas/flight/area`); + return res; + }, + list: async (data: FlightPlanListRqData) => { + const queryString = qs.stringify(data, { + addQueryPrefix: true, + arrayFormat: 'repeat' + }); + const res = await axios.get(`api/bas/flight/plan/list${queryString}`); + return res; + }, + detail: async (planSno: number) => { + const res = await axios.get(`api/bas/flight/plan/detail/${planSno}`); + return res; + }, + create: async (data: FlightPlanData) => { + console.log('>>> rq : ', data) + const res = await axios.post(`api/bas/flight/plan/create`, data); + console.log('>>> rs : ', res); + return res; + }, + update: async (data: FlightPlanData) => { + console.log('>>> rq : ', data) + const res = await axios.put(`api/bas/flight/plan/update`, data); + console.log('>>> rs : ', res); + return res; + }, + delete: async (planSno: number) => { + console.log('>>> rq : ', planSno) + const res = await axios.get(`api/bas/flight/plan/delete/${planSno}`); + console.log('>>> rs : ', res); + return res; + }, + listPilot: async (groupId: string) => { + console.log('>>> rq : ', groupId) + const res = await axios.get(`api/bas/flight/plan/pilot/${groupId}`); + console.log('>>> rs : ', res); + return res; + }, + listArcrft: async (groupId: string) => { + console.log('>>> rq : ', groupId) + const res = await axios.get(`api/bas/flight/plan/arcrft/${groupId}`); + console.log('>>> rs : ', res); + return res; + }, + listBuffer: async (data: FlightPlanAreaDataList) => { + console.log('>>> rq : ', data) + const queryString = qs.stringify(data, { + addQueryPrefix: true, + arrayFormat: 'brackets' + }); + const res = await axios.post(`api/bas/flight/plan/area/buffer`, data); + console.log('>>> rs : ', res); + return res; + } +} diff --git a/src/modules/basis/flight/models/basisFlightModel.ts b/src/modules/basis/flight/models/basisFlightModel.ts index abcedbc..b89ba5e 100644 --- a/src/modules/basis/flight/models/basisFlightModel.ts +++ b/src/modules/basis/flight/models/basisFlightModel.ts @@ -1,21 +1,471 @@ +import moment from "moment"; + export interface FlightState { - areaList: FlightAreaData | undefined - flightPlanArea: FlightPlanArea | undefined + publicAreaList: PublicAreaData | undefined + flightPlanArea: FlightPlanArea | undefined + list: [FlightPlanData] | undefined + detail: FlightPlanData | undefined + pilotList: FlightPlanPilotDataList | undefined + arcrftList: FlightPlanArcrftDataList | undefined + pilotSelect: PilotSelectData | undefined + arcrftSelect: FlightPlanArcrftData | undefined + areaCoordList: FlightPlanAreaData[] | undefined + areaList: FlightPlanAreaData[] | undefined + selectGroup: SelectGroupData | undefined +} + +export interface SelectGroupData { + cstmrSno: number, + groupId: string, + groupNm: string, } -export interface FlightAreaData { - areaList: [] +export interface PublicAreaData { + publicAreaList: [] } export interface FlightPlanArea { - address : '', - coordinates : '', - redius : '', - altitude_m : '', - altitude_ft : '', + address: string, + coordinates: string, + redius: string, + altitude_m: string, + altitude_ft: string, +} + +export interface FlightPlanData { + planSno?: number, + groupId: string, + cstmrSno: number, + memberName: string, + email: string, + hpno: string, + clncd: string, + addr: string, + addrDtlCn: string, + zip: string, + schFltStDt: string, + schFltEndDt: string, + fltPurpose: string, + aprvlYn: string, + delYn: string, + createUserId: string, + createDt: string, + updateUserId: string, + updateDt: string, + areaList?: FlightPlanAreaDataList | undefined, + pilotList?: FlightPlanPilotDataList | undefined, + arcrftList?: FlightPlanArcrftDataList | undefined + // docState: string +} + +export interface FlightPlanAreaData { + planAreaSno?: number, + planSno: number, + areaType: string, + fltMethod: string, + bufferZone: number, + fltElev: string, + createUserId?: string, + createDt?: string, + updateUserId?: string, + updateDt?: string, + coordList?: FlightPlanAreaCoordDataList | undefined + bufferCoordList?: FlightPlanAreaCoordDataList | undefined + // docState: string, +} + +export interface FlightPlanAreaDataList extends Array {}; + +export interface FlightPlanAreaCoordData { + planAreaCoordSno?: number, + planAreaSno?: number, + lat: number, + lon: number, + createUserId?: string, + createDt?: string + // docState: string +} + +export interface FlightPlanAreaCoordDataList extends Array {}; + +export interface FlightPlanPilotData { + planPilotSno?: number, + planSno?: number, + cstmrSno?: number, + groupNm: string, + memberName: string, + email: string, + hpno: string, + clncd: string, + addr: string, + addrDtlCn: string, + zip: string, + qlfcNo: string, + carrer: string, + createUserId: string, + createDt: string, + updateUserId: string, + updateDt: string + // docState: string +} + +export interface FlightPlanPilotDataList extends Array {}; + +export interface FlightPlanArcrftData { + planArcrftSno: number, + planSno: number, + arcrftSno: number, + idntfNum: string, + groupNm: string, + prdctNum: string, + arcrftTypeCd: string, + arcrftModelNm: string, + prdctCmpnNm: string, + prdctDate: string, + arcrftLngth: number, + arcrftWdth: number, + arcrftHght: number, + arcrftWght: number, + wghtTypeCd: string, + imageUrl: string, + takeoffWght: number, + useYn: string, + cameraYn: string, + insrncYn: string, + ownerNm: string, + createUserId: string, + createDt: string, + updateUserId: string, + updateDt: string + // docState: string +} + +export interface FlightPlanArcrftDataList extends Array {}; + +// rq +export interface FlightPlanListRqData { + groupId: string, + cstmrSno: number, + schFltStDt: string, + schFltEndDt: string, + aprvlYn: string +} + +export interface FlightPlanAprovRqData { + planSnoList: [number], + aprvlYn: string +} + +export interface PilotSelectData { + groupNm: string, + cstmrSno: string, + memberName: string, + email: string, + hpno: string, + clncd: string, + addr: string, + addrDtlCn: string, + zip: string } export const initFlight = { + selectGroup: { + cstmrSno: 0, + groupId: '', + groupNm: '' + }, + publicAreaList: undefined, + flightPlanArea: undefined, + list: undefined, + detail: { + planSno: 0, + groupId: '', + cstmrSno: 0, + memberName: '', + email: '', + hpno: '', + clncd: '+81', + addr: '', + addrDtlCn: '', + zip: '', + schFltStDt: moment().set({'h': 0, 'm': 0, 's': 0}).format('YYYY-MM-DD HH:mm:ss'), + schFltEndDt: moment().set({'h': 0, 'm': 0, 's': 0}).format('YYYY-MM-DD HH:mm:ss'), + fltPurpose: '', + aprvlYn: '', + delYn: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '', + areaList: [{ + planAreaSno: 0, + planSno: 0, + areaType: '', + fltMethod: '', + bufferZone: 0, + fltElev: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '', + coordList: [{ + planAreaCoordSno: 0, + planAreaSno: 0, + lat: 0, + lon: 0, + createUserId: '', + createDt: '' + }], + bufferCoordList: [{ + planAreaCoordSno: 0, + planAreaSno: 0, + lat: 0, + lon: 0, + createUserId: '', + createDt: '' + }], + }], + pilotList: [{ + planPilotSno: 0, + planSno: 0, + cstmrSno: 0, + groupNm: '', + memberName: '', + email: '', + hpno: '', + clncd: '+81', + addr: '', + addrDtlCn: '', + zip: '', + qlfcNo: '', + carrer: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '' + }], + arcrftList: [{ + planArcrftSno: 0, + planSno: 0, + arcrftSno: 0, + idntfNum: '', + groupNm: '', + prdctNum: '', + arcrftTypeCd: '', + arcrftModelNm: '', + prdctCmpnNm: '', + prdctDate: '', + arcrftLngth: 0, + arcrftWdth: 0, + arcrftHght: 0, + arcrftWght: 0, + wghtTypeCd: '', + imageUrl: '', + takeoffWght: 0, + useYn: '', + cameraYn: '', + insrncYn: '', + ownerNm: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '' + }] + }, + pilotList: undefined, + arcrftList: undefined, + pilotSelect: undefined, + arcrftSelect: undefined, + areaCoordList: undefined, + areaList: undefined, +}; + + +export const initFlightBas = { + plan: { + planSno: 0, + groupId: '', + cstmrSno: 0, + memberName: '', + email: '', + hpno: '', + clncd: '+81', + addr: '', + addrDtlCn: '', + zip: '', + schFltStDt: moment().set({'h': 0, 'm': 0, 's': 0}).format('YYYY-MM-DD HH:mm:ss'), + schFltEndDt: moment().set({'h': 0, 'm': 0, 's': 0}).format('YYYY-MM-DD HH:mm:ss'), + fltPurpose: '', + aprvlYn: '', + delYn: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '', areaList: undefined, - flightPlanArea: undefined -}; \ No newline at end of file + pilotList: undefined, + arcrftList: undefined, + }, + pilot: { + planPilotSno: 0, + planSno: 0, + cstmrSno: 0, + groupNm: '', + memberName: '', + email: '', + hpno: '', + clncd: '+81', + addr: '', + addrDtlCn: '', + zip: '', + qlfcNo: '', + carrer: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '' + }, + arcrft: { + planArcrftSno: 0, + planSno: 0, + arcrftSno: 0, + idntfNum: '', + groupNm: '', + prdctNum: '', + arcrftTypeCd: '', + arcrftModelNm: '', + prdctCmpnNm: '', + prdctDate: '', + arcrftLngth: 0, + arcrftWdth: 0, + arcrftHght: 0, + arcrftWght: 0, + wghtTypeCd: '', + imageUrl: '', + takeoffWght: 0, + useYn: '', + cameraYn: '', + insrncYn: '', + ownerNm: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '' + }, + area: { + planAreaSno: 0, + planSno: 0, + areaType: '', + fltMethod: '', + bufferZone: 0, + fltElev: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '', + coordList: undefined + }, + coord: { + planAreaCoordSno: 0, + planAreaSno: 0, + lat: 0, + lon: 0, + createUserId: '', + createDt: '' + }, + initDetail: { + planSno: 0, + groupId: '', + cstmrSno: 0, + memberName: '', + email: '', + hpno: '', + clncd: '+81', + addr: '', + addrDtlCn: '', + zip: '', + schFltStDt: moment().set({'h': 0, 'm': 0, 's': 0}).format('YYYY-MM-DD HH:mm:ss'), + schFltEndDt: moment().set({'h': 0, 'm': 0, 's': 0}).format('YYYY-MM-DD HH:mm:ss'), + fltPurpose: '', + aprvlYn: '', + delYn: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '', + areaList: [{ + planAreaSno: 0, + planSno: 0, + areaType: '', + fltMethod: '', + bufferZone: 0, + fltElev: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '', + coordList: [{ + planAreaCoordSno: 0, + planAreaSno: 0, + lat: 0, + lon: 0, + createUserId: '', + createDt: '' + }], + bufferCoordList: [{ + planAreaCoordSno: 0, + planAreaSno: 0, + lat: 0, + lon: 0, + createUserId: '', + createDt: '' + }], + }], + pilotList: [{ + planPilotSno: 0, + planSno: 0, + cstmrSno: 0, + groupNm: '', + memberName: '', + email: '', + hpno: '', + clncd: '+81', + addr: '', + addrDtlCn: '', + zip: '', + qlfcNo: '', + carrer: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '' + }], + arcrftList: [{ + planArcrftSno: 0, + planSno: 0, + arcrftSno: 0, + idntfNum: '', + groupNm: '', + prdctNum: '', + arcrftTypeCd: '', + arcrftModelNm: '', + prdctCmpnNm: '', + prdctDate: '', + arcrftLngth: 0, + arcrftWdth: 0, + arcrftHght: 0, + arcrftWght: 0, + wghtTypeCd: '', + imageUrl: '', + takeoffWght: 0, + useYn: '', + cameraYn: '', + insrncYn: '', + ownerNm: '', + createUserId: '', + createDt: '', + updateUserId: '', + updateDt: '' + }] + } +} diff --git a/src/modules/basis/flight/reducers/basisFlightReducer.ts b/src/modules/basis/flight/reducers/basisFlightReducer.ts index 708445a..9f87ac1 100644 --- a/src/modules/basis/flight/reducers/basisFlightReducer.ts +++ b/src/modules/basis/flight/reducers/basisFlightReducer.ts @@ -2,20 +2,112 @@ import { createReducer } from 'typesafe-actions'; import produce from 'immer'; import * as Actions from '../actions/basisFlightAction'; -import { FlightState, initFlight } from '../models/basisFlightModel'; +import { FlightState, initFlight, initFlightBas } from '../models/basisFlightModel'; import { any } from 'prop-types'; -export const flightReducer = createReducer ( initFlight ) -.handleAction(Actions.AREA_LIST.success, (state, action) => +export const flightReducer = createReducer(initFlight) + .handleAction(Actions.PUBLIC_AREA_LIST.success, (state, action) => produce(state, draft => { - const {data} = action.payload; - draft.areaList = data; + const { data } = action.payload; + draft.publicAreaList = data; }) -) -.handleAction(Actions.FLIGHT_PLAN_AREA.request, (state, action) => - produce(state, draft => { - const data = action.payload; - draft.flightPlanArea = data; + ) + // .handleAction(Actions.FLIGHT_PLAN_AREA.request, (state, action) => + // produce(state, draft => { + // const data = action.payload; + // draft.flightPlanArea = data; + // }) + // ) + // 목록 + .handleAction(Actions.FLIGHT_PLAN_LIST.success, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.list = data; + }) + ) + // 상세 + .handleAction(Actions.FLIGHT_PLAN_DETAIL.success, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.detail = data; + }) + ) + .handleAction(Actions.FLIGHT_PLAN_DETAIL_INIT, (state, action) => + produce(state, draft => { + draft.detail = initFlightBas.initDetail + }) + ) + // 조종사 조회 + .handleAction(Actions.FLIGHT_PLAN_PILOT_LIST.success, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.pilotList = data; + }) + ) + // 조종사 선택 + .handleAction(Actions.PILOT_SELECT, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.pilotSelect = data; + }) + ) + // 기체 조회 + .handleAction(Actions.FLIGHT_PLAN_ARCRFT_LIST.success, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.arcrftList = data; + }) + ) + // 기체 선택 + .handleAction(Actions.ARCRFT_SELECT, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.arcrftSelect = data; + }) + ) + // 조종사, 기체 선택 초기화 + .handleAction(Actions.PILOT_ARCRFT_SELECT_INIT, (state, action) => + produce(state, draft => { + draft.arcrftSelect = undefined; + draft.pilotSelect = undefined; + // draft.areaList = undefined; + // draft.areaCoordList = undefined; + }) + ) + // 비행 구역 좌표 저장 + .handleAction(Actions.AREA_COORDINATE_LIST_SAVE, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.areaCoordList = data; + }) + ) + // 비행 구역 상세 저장 + .handleAction(Actions.AREA_DETAIL_LIST_SAVE, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.areaList = data; + draft.areaCoordList = data; + }) + ) + // 비행 계획서 그룹 선택 + .handleAction(Actions.FLIGHT_PLAN_GROUP_SELECT, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.selectGroup = data; + }) + ) + // 비행 계획서 버퍼 영역 조회 + .handleAction(Actions.FLIGHT_PLAN_AREA_BUFFER_LIST.success, (state, action) => + produce(state, draft => { + const data = action.payload; + draft.areaCoordList = data; + }) + ) + // 조종사, 기체 선택 초기화 + .handleAction(Actions.AREA_DETAIL_INIT, (state, action) => + produce(state, draft => { + draft.areaList = undefined; + draft.areaCoordList = undefined; }) -) \ No newline at end of file + ) diff --git a/src/modules/basis/flight/sagas/basisFlightSaga.ts b/src/modules/basis/flight/sagas/basisFlightSaga.ts index 82362ef..4cce3d3 100644 --- a/src/modules/basis/flight/sagas/basisFlightSaga.ts +++ b/src/modules/basis/flight/sagas/basisFlightSaga.ts @@ -9,53 +9,320 @@ import { import * as MessageActions from '../../../comn/message/actions/comnMessageAction'; import * as Actions from '../actions/basisFlightAction'; import * as Apis from '../apis/basisFlightApi'; +import { FlightPlanData } from "../models/basisFlightModel"; +import { + FLIGHT_PLAN_ARCRFT_LIST, + FLIGHT_PLAN_CREATE, FLIGHT_PLAN_DELETE, + FLIGHT_PLAN_DETAIL, + FLIGHT_PLAN_PILOT_LIST, FLIGHT_PLAN_UPDATE +} from "../actions/basisFlightAction"; + +function* listAreaSaga(action: ActionType) { + try { + const response = yield call(Apis.flightPlanAPI.area); + + if (response.errorCode) { + yield put( + MessageActions.IS_ERROR({ + errorCode: response.errorCode, + errorMessage: response.errorMessage, + isHistoryBack: false, + isRefresh: false + }) + ); + return; + } + + yield put( + Actions.PUBLIC_AREA_LIST.success({ + data: response + }) + ); + } catch (error: any) { + yield put( + Actions.PUBLIC_AREA_LIST.failure(error) + ); + } +} + +// function* createFlightPlanArea(action: ActionType) { +// try { +// const data = action.payload; +// +// yield put( +// Actions.FLIGHT_PLAN_AREA.success({ +// data: data +// }) +// ) +// +// } catch (error: any) { +// yield put( +// Actions.FLIGHT_PLAN_AREA.failure(error) +// ) +// } +// } + +// 비행계획서 목록 +function* listPlanSaga(action: ActionType) { + try { + const data = action.payload; + const response = yield call(Apis.flightPlanAPI.list, data); + if (response.errorCode) { + yield put( + MessageActions.IS_ERROR({ + errorCode: response.errorCode, + errorMessage: response.errorMessage, + isHistoryBack: false, + isRefresh: false + }) + ); + return; + } + + yield put( + Actions.FLIGHT_PLAN_LIST.success(response.data) + ); + } catch (error: any) { + yield put( + Actions.FLIGHT_PLAN_LIST.failure(error) + ); + } +} +// 비행계획서 상세 +function* detailPlanSaga(action: ActionType) { + try { + const data = action.payload; + const response = yield call(Apis.flightPlanAPI.detail, data); + if (response.errorCode) { + yield put( + MessageActions.IS_ERROR({ + errorCode: response.errorCode, + errorMessage: response.errorMessage, + isHistoryBack: false, + isRefresh: false + }) + ); + return; + } -function* listAreaSaga(action: ActionType) { - try { - const response = yield call(Apis.flightPlanAPI.area); - - if(response.errorCode) { - yield put( - MessageActions.IS_ERROR({ - errorCode: response.errorCode, - errorMessage: response.errorMessage, - isHistoryBack: false, - isRefresh: false - }) - ); - return; - } + yield put( + Actions.FLIGHT_PLAN_DETAIL.success(response.data) + ); + } catch (error: any) { + yield put( + Actions.FLIGHT_PLAN_DETAIL.failure(error) + ); + } +} +// 비행계획서 등록 +function* createPlanSaga(action: ActionType) { + try { + const detail = action.payload; + + const res = yield call(Apis.flightPlanAPI.create, detail); + const { data } = res; + + if (data.result) { + yield put( + MessageActions.IS_MESSAGE({ + messageCode: SAVE_MESSAGE.code, + message: SAVE_MESSAGE.message, + isHistoryBack: true, + isRefresh: false + }) + ); + } else { + if (data.errorCode === 'DT002') { yield put( - Actions.AREA_LIST.success({ - data: response - }) + MessageActions.IS_ERROR({ + errorCode: DUPLATE_MESSAGE.code, + errorMessage: '제작번호 ' + DUPLATE_MESSAGE.message, + isHistoryBack: false, + isRefresh: false + }) ); - } catch (error: any) { + } else { + throw Error; + } + } + } catch (error) { + yield put( + MessageActions.IS_ERROR({ + errorCode: ERROR_MESSAGE.code, + errorMessage: ERROR_MESSAGE.message, + isHistoryBack: false, + isRefresh: false + }) + ); + // yield put(Actions.FLIGHT_PLAN_CREATE.failure(error)); + } +} +// 비행계획서 수정 +function* updatePlanSaga(action: ActionType) { + try { + const detail = action.payload; + + const res = yield call(Apis.flightPlanAPI.update, detail); + + const { data } = res; + + if (data.result) { + yield put( + MessageActions.IS_MESSAGE({ + messageCode: SAVE_MESSAGE.code, + message: SAVE_MESSAGE.message, + isHistoryBack: true, + isRefresh: false + }) + ); + } else { + if (data.errorCode === 'DT002') { yield put( - Actions.AREA_LIST.failure(error) + MessageActions.IS_ERROR({ + errorCode: DUPLATE_MESSAGE.code, + errorMessage: '제작번호 ' + DUPLATE_MESSAGE.message, + isHistoryBack: false, + isRefresh: false + }) ); + } else { + throw Error; + } } + } catch (error) { + yield put( + MessageActions.IS_ERROR({ + errorCode: ERROR_MESSAGE.code, + errorMessage: ERROR_MESSAGE.message, + isHistoryBack: false, + isRefresh: false + }) + ); + // yield put(Actions.FLIGHT_PLAN_UPDATE.failure(error)); + } } +// 비행계획서 삭제 +function* deletePlanSaga(action: ActionType) { + try { + const id = action.payload; + const res = yield call(Apis.flightPlanAPI.delete, id); -function* createFlightPlanArea(action: ActionType) { - try { - const data = action.payload; + const { data } = res; - yield put( - Actions.FLIGHT_PLAN_AREA.success({ - data: data - }) - ) + if (data.result) { + yield put( + MessageActions.IS_MESSAGE({ + messageCode: DELETE_MESSAGE.code, + message: DELETE_MESSAGE.message, + isHistoryBack: true, + isRefresh: false + }) + ); + } else { + throw Error; + } + } catch (error) { + yield put( + MessageActions.IS_ERROR({ + errorCode: ERROR_MESSAGE.code, + errorMessage: ERROR_MESSAGE.message, + isHistoryBack: false, + isRefresh: false + }) + ); + // yield put(Actions.FLIGHT_PLAN_DELETE.failure(error)); + } +} +// 조종사 목록 +function* listPilotSaga(action: ActionType) { + try { + const data = action.payload; + const response = yield call(Apis.flightPlanAPI.listPilot, data); + if (response.errorCode) { + yield put( + MessageActions.IS_ERROR({ + errorCode: response.errorCode, + errorMessage: response.errorMessage, + isHistoryBack: false, + isRefresh: false + }) + ); + return; + } - } catch (error: any) { - yield put( - Actions.FLIGHT_PLAN_AREA.failure(error) - ) + yield put( + Actions.FLIGHT_PLAN_PILOT_LIST.success(response.data) + ); + } catch (error: any) { + yield put( + Actions.FLIGHT_PLAN_PILOT_LIST.failure(error) + ); + } +} +// 기체 목록 +function* listArcrftSaga(action: ActionType) { + try { + const data = action.payload; + const response = yield call(Apis.flightPlanAPI.listArcrft, data); + if (response.errorCode) { + yield put( + MessageActions.IS_ERROR({ + errorCode: response.errorCode, + errorMessage: response.errorMessage, + isHistoryBack: false, + isRefresh: false + }) + ); + return; + } + + yield put( + Actions.FLIGHT_PLAN_ARCRFT_LIST.success(response.data) + ); + } catch (error: any) { + yield put( + Actions.FLIGHT_PLAN_ARCRFT_LIST.failure(error) + ); + } +} + +// get buffer list +function* listBuffer(action: ActionType) { + try { + const data = action.payload; + const response = yield call(Apis.flightPlanAPI.listBuffer, data); + if (response.errorCode) { + yield put( + MessageActions.IS_ERROR({ + errorCode: response.errorCode, + errorMessage: response.errorMessage, + isHistoryBack: false, + isRefresh: false + }) + ); + return; } + + yield put( + Actions.FLIGHT_PLAN_AREA_BUFFER_LIST.success(response.data) + ); + } catch (error: any) { + yield put( + Actions.FLIGHT_PLAN_AREA_BUFFER_LIST.failure(error) + ); + } } export function* flightSaga() { - yield takeEvery(Actions.AREA_LIST.request, listAreaSaga); - yield takeEvery(Actions.FLIGHT_PLAN_AREA.request, createFlightPlanArea); -} \ No newline at end of file + yield takeEvery(Actions.PUBLIC_AREA_LIST.request, listAreaSaga); + // yield takeEvery(Actions.FLIGHT_PLAN_AREA.request, createFlightPlanArea); + yield takeEvery(Actions.FLIGHT_PLAN_LIST.request, listPlanSaga) + yield takeEvery(Actions.FLIGHT_PLAN_DETAIL.request, detailPlanSaga) + yield takeEvery(Actions.FLIGHT_PLAN_CREATE.request, createPlanSaga) + yield takeEvery(Actions.FLIGHT_PLAN_UPDATE.request, updatePlanSaga) + yield takeEvery(Actions.FLIGHT_PLAN_DELETE.request, deletePlanSaga) + yield takeEvery(Actions.FLIGHT_PLAN_PILOT_LIST.request, listPilotSaga) + yield takeEvery(Actions.FLIGHT_PLAN_ARCRFT_LIST.request, listArcrftSaga) + yield takeEvery(Actions.FLIGHT_PLAN_AREA_BUFFER_LIST.request, listBuffer) +} diff --git a/src/modules/control/map/reducers/controlMapReducer.ts b/src/modules/control/map/reducers/controlMapReducer.ts index f822aa0..0eb82f5 100644 --- a/src/modules/control/map/reducers/controlMapReducer.ts +++ b/src/modules/control/map/reducers/controlMapReducer.ts @@ -11,9 +11,9 @@ const initialState = { area0006: true, // 초경량비행장치 sensor: 'dust', - drawType: '', + drawType: null, - drawCheck: false + drawCheck: '' }; const controlReducerReducer = (state = initialState, action) => { diff --git a/src/router/routes/RouteBasis.js b/src/router/routes/RouteBasis.js index ce7dd1f..fd48c46 100644 --- a/src/router/routes/RouteBasis.js +++ b/src/router/routes/RouteBasis.js @@ -48,7 +48,7 @@ const RouteBasis = [ component: lazy(() => import('../../views/basis/flight/plan/FlightPlanDetail')) }, { - path: '/basis/flight/plan/detail/:id', + path: '/basis/flight/plan/detail/:planSno', component: lazy(() => import('../../views/basis/flight/plan/FlightPlanDetail')) }, ];