Browse Source

[비행 관제] 그룹 별 드론 표출 작업

pull/2/head
노승철 2 years ago
parent
commit
02828e33e5
  1. 18
      src/components/map/naver/NaverMap.js
  2. 60
      src/components/map/naver/dron/DronMarker.js
  3. 9
      src/components/websocket/WebsocketClient.js
  4. 18
      src/modules/control/gp/actions/controlGpAction.ts
  5. 13
      src/modules/control/gp/apis/controlGpApi.ts
  6. 22
      src/modules/control/gp/models/controlGpModel.ts
  7. 16
      src/modules/control/gp/reducers/controlGpReducer.ts
  8. 61
      src/modules/control/gp/sagas/controlGpSaga.ts
  9. 4
      src/redux/reducers/rootReducer.ts

18
src/components/map/naver/NaverMap.js

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
import dronicon from '../../../assets/control/icon/drone.png';
import { DronMarker } from './dron/DronMarker';
import { DronHistory } from './dron/DronHistory';
@ -9,10 +9,11 @@ import { NaverMapSearch } from './search/NaverMapSearch';
import { FeatureAirZone } from './feature/FeatureAirZone';
import geoJson from '../geojson/airArea.json';
import SensorZone from "./sensor/SensorZone";
import { controlGroupAuthAction } from '../../../modules/control/gp';
export const NaverCustomMap = () => {
const dispatch = useDispatch();
const naver = window.naver;
let map;
const [isMapLoad, setIsMapLoad] = useState(false);
const [mapObject, setMapObject] = useState(null);
@ -23,21 +24,12 @@ export const NaverCustomMap = () => {
useEffect(() => {
NaverMapInit();
// console.log(map);
// console.log(features);
// setIsMapLoad(true);
dispatch(controlGroupAuthAction.request());
}, []);
useEffect(() => {
// console.log('==============11111==================', mapObject);
}, [mapObject]);
const removeArrMarkers = arrData => {
arrMarkers = arrData;
};
const test = aaaa => {
console.log(aaaa);
};
@ -74,8 +66,6 @@ export const NaverCustomMap = () => {
<DronMarker
map={mapObject}
naver={naver}
arrMarkers={arrMarkers}
removeArrMarkers={removeArrMarkers}
test={test}
/>

60
src/components/map/naver/dron/DronMarker.js

@ -1,9 +1,9 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import '../../../../assets/css/custom.css';
import DronIconPulple from '../../../../assets/images/drone-marker-icon-pulple.png';
import DronIcon from '../../../../assets/images/drone-marker-icon.png';
import { controlGpDtlAction } from '../../../../modules/control/gp';
import { controlGpDtlAction, controlGpHisAction, controlDbHisAction } from '../../../../modules/control/gp';
import { objectClickAction } from '../../../../modules/control/map/actions/controlMapActions';
export const DronMarker = props => {
@ -21,14 +21,14 @@ export const DronMarker = props => {
content: contentString
});
const [arrMarkers, setArrMarkers] = useState([]);
useEffect(() => {
markerInit();
}, [controlGpList]);
useEffect(() => {
console.log('>>>>>>>>>>>>>>>>', objectId, isClickObject);
props.arrMarkers.map(clickMarker => {
arrMarkers.map(clickMarker => {
if (objectId === clickMarker.id && isClickObject) {
// clickMarker.setIcon(DronIconPulple);
clickMarker.setIcon({
@ -37,7 +37,6 @@ export const DronMarker = props => {
anchor: new naver.maps.Point(15, 15),
});
} else {
// clickMarker.setIcon(DronIcon);
clickMarker.setIcon({
url: DronIcon,
origin: new naver.maps.Point(0, 0),
@ -45,17 +44,12 @@ export const DronMarker = props => {
});
}
});
// }else{
// }
}, [objectId, isClickObject]);
useEffect(() => {
props.arrMarkers.map(clickMarker => {
arrMarkers.map(clickMarker => {
if (objectId === clickMarker.id) {
console.log(clickMarker);
props.map.setCenter(clickMarker.getPosition());
// $('#btn_modal').click();
props.map.setZoom(13, true);
}
});
@ -86,27 +80,15 @@ export const DronMarker = props => {
handlerDronClick(marker);
});
props.arrMarkers.push(marker);
setArrMarkers(m => [...m, marker]);
};
const handlerDronClick = marker => {
if (marker.getAnimation() != null) {
// marker.setAnimation(null);
// infowindow.close();
// dispatch(Actions.controlGpHisAction.request(controlGpList));
} else {
// infowindow.open(props.map, marker);
// marker.setAnimation(naver.maps.Animation.BOUNCE);
}
// marker.setIcon(DronIconPulple);
// console.log(marker.id);
const markerId = marker.id;
// const markerId = marker.id;
const contorlId = marker.controlId;
console.log('contorlId ::::::::::< ', marker.controlId);
//히스토리 불러오기
dispatch(objectClickAction(markerId));
//히스토리 불러오기
dispatch(objectClickAction(contorlId));
dispatch(controlGpDtlAction.request(contorlId));
};
@ -117,27 +99,25 @@ export const DronMarker = props => {
//마커에 위치를 이동한다.
const moveMarkers = (marker, position) => {
// console.log(marker);
marker.setPosition(position);
};
//데이터가 없는 마커를 모두 삭제 한다.
const allRemoveMarkers = () => {
if (props.arrMarkers && controlGpList) {
props.arrMarkers.map(marker => {
if (arrMarkers && controlGpList) {
arrMarkers.map(marker => {
const isExists = controlGpList.find(
item => item.objectId === marker.id
);
if (!isExists) {
removeMarkers(marker);
const arrData = props.arrMarkers.filter(
item => item.objectId != marker.id
const arrData = arrMarkers.filter(
item => item.id != marker.id
);
props.removeArrMarkers(arrData);
removeArrMarkers(arrData);
}
});
}
// }
};
//마커를 셋팅 한다.
@ -146,14 +126,14 @@ export const DronMarker = props => {
allRemoveMarkers();
controlGpList.map(item => {
const position = new naver.maps.LatLng(item.lat, item.lng);
if (props.arrMarkers) {
const isExists = props.arrMarkers.find(
if (arrMarkers) {
const isExists = arrMarkers.find(
ele => ele.id === item.objectId
);
if (isExists) {
moveMarkers(isExists, position);
} else {
// console.log(' ADD >>>', props.arrMarkers);
addMarkers(position, item.objectId, item.controlId);
}
} else {
@ -163,5 +143,9 @@ export const DronMarker = props => {
}
};
const removeArrMarkers = arrData => {
setArrMarkers(arrData);
};
return null;
};

9
src/components/websocket/WebsocketClient.js

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { VscLoading } from 'react-icons/vsc';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { WS_HOST } from '../../configs/constants';
import * as Actions from '../../modules/control/gp/actions/controlGpAction';
@ -15,10 +15,7 @@ const WebsocketClient = () => {
}, []);
const connect = () => {
// let websocket = new WebSocket('ws://localhost:8081/ws');
// console.log('WS_HOST>>>>>>>>>>', WS_HOST);
let websocket = new WebSocket(WS_HOST);
// let websocket = new WebSocket("ws://localhost:8002/test2");
websocket.onopen = () => {
setIsConnection(true);
@ -27,12 +24,8 @@ const WebsocketClient = () => {
websocket.onmessage = e => {
const data = e.data;
// console.log(data);
const controlGpList = JSON.parse(data);
// const controlGpList : ControlGpData[] = JSON.parse(messageObject.message);
// console.log(controlGpList);
dispatch(Actions.controlGpAction.request(controlGpList));
};

18
src/modules/control/gp/actions/controlGpAction.ts

@ -1,11 +1,13 @@
import { AxiosError } from 'axios';
import { create } from 'sortablejs';
import { ActionType, createAsyncAction } from 'typesafe-actions';
import {
ControlDetailData,
ControlGpData,
ControlGpDtlState,
ControlGpHisState,
ControlGpState
ControlGpState,
ControlGroupAuthState
} from '../models/controlGpModel';
const CONTROL_GP_REQUEST = 'control/gp/CONTROL_GP_REQUEST';
@ -24,6 +26,11 @@ const CONTROL_GP_RTDTL_REQUEST = 'control/gp/CONTROL_GP_RTDTL_REQUEST';
const CONTROL_GP_RTDTL_SUCCESS = 'control/gp/CONTROL_GP_RTDTL_SUCCESS';
const CONTROL_GP_RTDTL_FAILURE = 'control/gp/CONTROL_GP_RTDTL_FAILURE';
// [관제] 그룹 권한 및 기체 식별번호 조회
const CONTROL_GROUP_AUTH_REQUEST = 'control/group/CONTROL_GROUP_AUTH_REQUEST';
const CONTROL_GROUP_AUTH_SUCCESS = 'control/group/CONTROL_GROUP_AUTH_SUCCESS';
const CONTROL_GROUP_AUTH_FAILURE = 'control/group/CONTROL_GROUP_AUTH_FAILURE';
export const controlGpAction = createAsyncAction(
CONTROL_GP_REQUEST,
CONTROL_GP_SUCCESS,
@ -48,11 +55,18 @@ export const controlGpRtDtlAction = createAsyncAction(
CONTROL_GP_RTDTL_FAILURE
)<ControlGpData, ControlGpDtlState, AxiosError>();
export const controlGroupAuthAction = createAsyncAction(
CONTROL_GROUP_AUTH_REQUEST,
CONTROL_GROUP_AUTH_SUCCESS,
CONTROL_GROUP_AUTH_FAILURE
)<string, ControlGroupAuthState, AxiosError>();
const actions = {
controlGpAction,
controlGpHisAction,
controlGpDtlAction,
controlGpRtDtlAction
controlGpRtDtlAction,
controlGroupAuthAction
};
export type ControlGpAction = ActionType<typeof actions>;

13
src/modules/control/gp/apis/controlGpApi.ts

@ -1,5 +1,5 @@
import axios from '../../../utils/customAxiosUtil';
import { ReponseControlGpHistory } from '../models/controlGpModel';
import { ReponseControlGpHistory, ControlGroupAuthData, ResponseControlGroupAuth} from '../models/controlGpModel';
export const controlGpApi = {
getHistory: async (id: string) => {
@ -8,12 +8,21 @@ export const controlGpApi = {
return null;
}
const { data }: ReponseControlGpHistory = await axios.get(
`api/ctr/cntrl/history/${id}`
`api/ctr/cntrl/history/list/${id}`
);
return data;
},
getDetail: async (id: string) => {
return await axios.get(`api/ctr/cntrl/detail/${id}`);
},
getGroupAuth: async (id: number) => {
if(!id) {
return null;
}
const { data }:ResponseControlGroupAuth = await axios.get(
`api/ctr/cntrl/group?cstmrSno=${id}`
);
return data;
},
};

22
src/modules/control/gp/models/controlGpModel.ts

@ -11,6 +11,10 @@ export interface ControlGpDtlState {
controlDetail: ControlDetailData | undefined;
}
export interface ControlGroupAuthState {
controlGroupAuthInfo : ControlGroupAuthData[] | undefined;
}
export interface ControlGpHistoryData {
objectId: String;
lat: number;
@ -78,13 +82,29 @@ export interface ControlGpData {
heading: number;
}
export interface ControlGroupAuthData {
cstmrSno: number,
userId: string,
groupId: string,
groupNm: string,
groupAuthCd: string,
arcrftSno: number,
idntfNum: string,
createUserId: string
}
export interface ReponseControlGpHistory {
data: ControlGpHistoryData[];
}
export interface ResponseControlGroupAuth {
data: ControlGroupAuthData[];
}
export const initiaResponseControlGpData = {
controlGpList: undefined,
controlGpDetail: undefined,
controlGpHistory: undefined,
controlDetail: undefined
controlDetail: undefined,
controlGroupAuthInfo: undefined,
};

16
src/modules/control/gp/reducers/controlGpReducer.ts

@ -5,13 +5,15 @@ import {
controlGpAction,
controlGpDtlAction,
controlGpHisAction,
controlGpRtDtlAction
controlGpRtDtlAction,
controlGroupAuthAction
} from '../actions/controlGpAction';
import {
ControlDetailData,
ControlGpDtlState,
ControlGpHisState,
ControlGpState,
ControlGroupAuthState,
initiaResponseControlGpData
} from '../models/controlGpModel';
@ -54,3 +56,15 @@ export const controlGpDtlReducer = createReducer<
draft.controlDetail = data;
})
);
export const controlGroupAuthReducer = createReducer<
ControlGroupAuthState,
ControlGpAction
>(initiaResponseControlGpData)
.handleAction(controlGroupAuthAction.success, (state, action) =>
produce(state, draft => {
const { controlGroupAuthInfo } = action.payload;
draft.controlGroupAuthInfo = controlGroupAuthInfo;
})
)

61
src/modules/control/gp/sagas/controlGpSaga.ts

@ -1,34 +1,56 @@
import { call, put, select, takeEvery } from '@redux-saga/core/effects';
import { ActionType } from 'typesafe-actions';
import { LoginData } from '../../../account/login/models/authModel';
import { cookieStorage, COOKIE_ACCESS_TOKEN } from '../../../account/login/service/cookie';
import * as Actions from '../actions/controlGpAction';
import { controlGpApi } from '../apis/controlGpApi';
import decode from 'jwt-decode';
import { ControlGpData } from '../models/controlGpModel';
function* getControlGpSaga(
action: ActionType<typeof Actions.controlGpAction.request>
) {
try {
// console.log("-------------------------------")
const data = action.payload;
const state = yield select();
const { objectId, isClickObject } = state.controlMapReducer;
const { controlGroupAuthInfo } = state.controlGroupAuthState;
let gpsData: ControlGpData[] = [];
if(controlGroupAuthInfo.length > 0) {
controlGroupAuthInfo.forEach((auth) => {
if(auth.groupAuthCd === 'CREATER' || auth.groupAuthCd === 'ADMIN') {
if(gpsData.length > 0) return false;
gpsData = data.filter(gps => auth.idntfNum === gps.objectId);
}
if(auth.groupAuthCd === 'USER') {
if(gpsData.length > 0) return false;
// console.log(">>>>>>>>>>>" , data?.length);
gpsData.filter(gps => auth.createUserId && auth.idntfNum === gps.objectId);
}
});
}
yield put(
Actions.controlGpAction.success({
controlGpList: data
controlGpList: gpsData
})
);
const state = yield select();
const { objectId, isClickObject } = state.controlMapReducer;
let detailData;
if (objectId && isClickObject) {
let detailData;
//History 호출
yield put(Actions.controlGpHisAction.request({ id: objectId }));
//상세 정보에서 실시간 데이터 호출
data.map(item => {
if (item.objectId === objectId) {
if (item.controlId === objectId) {
detailData = item;
}
});
@ -47,7 +69,7 @@ function* getControlGpHistorySaga(
const { id } = action.payload;
const data = yield call(controlGpApi.getHistory, id);
// console.log('>>>>>>>1111>>>>> ', rsponse);
yield put(
Actions.controlGpHisAction.success({
controlGpHistory: data
@ -90,9 +112,32 @@ function* controlDtlSaga(
}
}
function* controlGroupAuthSaga (
action: ActionType<typeof Actions.controlGroupAuthAction.request>
) {
const token = cookieStorage.getCookie(COOKIE_ACCESS_TOKEN);
try {
if(token) {
console.log("group auth token : ", token);
const user = decode<LoginData>(token);
const data = yield call(controlGpApi.getGroupAuth, user.cstmrSno);
console.log("group auth data : ", data);
yield put(Actions.controlGroupAuthAction.success({
controlGroupAuthInfo: data
}));
}
} catch (error) {
yield put(Actions.controlGroupAuthAction.failure(error));
}
}
export function* controlGpSaga() {
yield takeEvery(Actions.controlGpAction.request, getControlGpSaga);
yield takeEvery(Actions.controlGpHisAction.request, getControlGpHistorySaga);
yield takeEvery(Actions.controlGpRtDtlAction.request, controlGpRtDtlSaga);
yield takeEvery(Actions.controlGpDtlAction.request, controlDtlSaga);
yield takeEvery(Actions.controlGroupAuthAction.request, controlGroupAuthSaga);
}

4
src/redux/reducers/rootReducer.ts

@ -18,8 +18,9 @@ import {
controlGpDtlReducer,
controlGpHisReducer,
controlGpReducer,
controlGroupAuthReducer,
controlGpSaga,
ControlGpState
ControlGpState,
} from '../../modules/control/gp';
import controlMapReducer from '../../modules/control/map/reducers/controlMapReducer';
import { mainDahReducer } from '../../modules/main/dash/reducers/mainDashReducer';
@ -62,6 +63,7 @@ const rootReducer = combineReducers({
controlGpState: controlGpReducer,
controlGpHisState: controlGpHisReducer,
controlGpDtlState: controlGpDtlReducer,
controlGroupAuthState: controlGroupAuthReducer,
menuState: menuReducer,
analysisHistoryState: analysisHistoryReducer,
analysisSimulatorState: analysisSimulatorReducer,

Loading…
Cancel
Save