Browse Source

Merge branch 'feature/flight-plan' of http://gitea.palntour.com/pav/pav-home into feature/flight-plan

feature/flight-plan
sanguu 2 years ago
parent
commit
2f493bee77
  1. 1406
      package-lock.json
  2. 2
      package.json
  3. 28
      src/components/map/naver/NaverMap.js
  4. 88
      src/components/map/naver/dron/DronMarker.js
  5. 5
      src/components/mapDraw/naver/NaverMap.js
  6. 149
      src/components/mapDraw/naver/draw/JQueryDraw.js
  7. 21
      src/components/websocket/WebsocketClient.js
  8. 10
      src/containers/basis/dron/BasisDronContainer.js
  9. 18
      src/modules/control/gp/actions/controlGpAction.ts
  10. 15
      src/modules/control/gp/apis/controlGpApi.ts
  11. 22
      src/modules/control/gp/models/controlGpModel.ts
  12. 18
      src/modules/control/gp/reducers/controlGpReducer.ts
  13. 77
      src/modules/control/gp/sagas/controlGpSaga.ts
  14. 2
      src/modules/control/map/reducers/controlMapReducer.ts
  15. 4
      src/redux/reducers/rootReducer.ts

1406
package-lock.json generated

File diff suppressed because it is too large Load Diff

2
package.json

@ -14,6 +14,8 @@
"@fullcalendar/timeline": "5.7.2", "@fullcalendar/timeline": "5.7.2",
"@hookform/resolvers": "1.3.4", "@hookform/resolvers": "1.3.4",
"@stomp/stompjs": "^6.1.0", "@stomp/stompjs": "^6.1.0",
"@turf/buffer": "^6.5.0",
"@turf/turf": "^6.5.0",
"@types/googlemaps": "^3.43.3", "@types/googlemaps": "^3.43.3",
"@types/history": "^4.7.8", "@types/history": "^4.7.8",
"@types/jest": "^26.0.23", "@types/jest": "^26.0.23",

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

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'; 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 dronicon from '../../../assets/control/icon/drone.png';
import { DronMarker } from './dron/DronMarker'; import { DronMarker } from './dron/DronMarker';
import { DronHistory } from './dron/DronHistory'; import { DronHistory } from './dron/DronHistory';
@ -9,34 +9,26 @@ import { NaverMapSearch } from './search/NaverMapSearch';
import { FeatureAirZone } from './feature/FeatureAirZone'; import { FeatureAirZone } from './feature/FeatureAirZone';
import geoJson from '../geojson/airArea.json'; import geoJson from '../geojson/airArea.json';
import SensorZone from "./sensor/SensorZone"; import SensorZone from "./sensor/SensorZone";
import { controlGroupAuthAction } from '../../../modules/control/gp';
export const NaverCustomMap = () => { export const NaverCustomMap = () => {
const dispatch = useDispatch();
const naver = window.naver; const naver = window.naver;
let map;
const [isMapLoad, setIsMapLoad] = useState(false); const [isMapLoad, setIsMapLoad] = useState(false);
const [mapObject, setMapObject] = useState(null); const [mapObject, setMapObject] = useState(null);
let arrMarkers = []; // 마커 배열 let arrMarkers = []; // 마커 배열
let arrPolyline = []; // 폴리라인 배열 let arrPolyline = []; // 폴리라인 배열
let features = geoJson.features; let features = geoJson.features;
useEffect(() => { useEffect(() => {
NaverMapInit(); NaverMapInit();
// console.log(map); dispatch(controlGroupAuthAction.request());
// console.log(features);
// setIsMapLoad(true);
}, []); }, []);
useEffect(() => { useEffect(() => {
// console.log('==============11111==================', mapObject); }, [mapObject]);
}, [mapObject]);
const removeArrMarkers = arrData => {
arrMarkers = arrData;
};
const test = aaaa => { const test = aaaa => {
console.log(aaaa); console.log(aaaa);
@ -73,9 +65,7 @@ export const NaverCustomMap = () => {
<> <>
<DronMarker <DronMarker
map={mapObject} map={mapObject}
naver={naver} naver={naver}
arrMarkers={arrMarkers}
removeArrMarkers={removeArrMarkers}
test={test} test={test}
/> />

88
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 { useDispatch, useSelector } from 'react-redux';
import '../../../../assets/css/custom.css'; import '../../../../assets/css/custom.css';
import DronIconPulple from '../../../../assets/images/drone-marker-icon-pulple.png'; import DronIconPulple from '../../../../assets/images/drone-marker-icon-pulple.png';
import DronIcon from '../../../../assets/images/drone-marker-icon.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'; import { objectClickAction } from '../../../../modules/control/map/actions/controlMapActions';
export const DronMarker = props => { export const DronMarker = props => {
@ -21,14 +21,14 @@ export const DronMarker = props => {
content: contentString content: contentString
}); });
const [arrMarkers, setArrMarkers] = useState([]);
useEffect(() => { useEffect(() => {
markerInit(); markerInit();
}, [controlGpList]); }, [controlGpList]);
useEffect(() => { useEffect(() => {
console.log('>>>>>>>>>>>>>>>>', objectId, isClickObject); arrMarkers.map(clickMarker => {
props.arrMarkers.map(clickMarker => {
if (objectId === clickMarker.id && isClickObject) { if (objectId === clickMarker.id && isClickObject) {
// clickMarker.setIcon(DronIconPulple); // clickMarker.setIcon(DronIconPulple);
clickMarker.setIcon({ clickMarker.setIcon({
@ -36,26 +36,20 @@ export const DronMarker = props => {
origin: new naver.maps.Point(0, 0), origin: new naver.maps.Point(0, 0),
anchor: new naver.maps.Point(15, 15), anchor: new naver.maps.Point(15, 15),
}); });
} else { } else {
// clickMarker.setIcon(DronIcon);
clickMarker.setIcon({ clickMarker.setIcon({
url: DronIcon, url: DronIcon,
origin: new naver.maps.Point(0, 0), origin: new naver.maps.Point(0, 0),
anchor: new naver.maps.Point(15, 15), anchor: new naver.maps.Point(15, 15),
}); });
} }
}); });
// }else{
// }
}, [objectId, isClickObject]); }, [objectId, isClickObject]);
useEffect(() => { useEffect(() => {
props.arrMarkers.map(clickMarker => { arrMarkers.map(clickMarker => {
if (objectId === clickMarker.id) { if (objectId === clickMarker.id) {
console.log(clickMarker); props.map.setCenter(clickMarker.getPosition());
props.map.setCenter(clickMarker.getPosition());
// $('#btn_modal').click();
props.map.setZoom(13, true); props.map.setZoom(13, true);
} }
}); });
@ -84,30 +78,18 @@ export const DronMarker = props => {
naver.maps.Event.addListener(marker, 'click', function (e) { naver.maps.Event.addListener(marker, 'click', function (e) {
handlerDronClick(marker); handlerDronClick(marker);
}); });
props.arrMarkers.push(marker); setArrMarkers(m => [...m, marker]);
}; };
const handlerDronClick = marker => { const handlerDronClick = marker => {
if (marker.getAnimation() != null) { // const markerId = marker.id;
// marker.setAnimation(null); const contorlId = marker.controlId;
// 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 contorlId = marker.controlId;
console.log('contorlId ::::::::::< ', marker.controlId);
//히스토리 불러오기
dispatch(objectClickAction(markerId)); //히스토리 불러오기
dispatch(controlGpDtlAction.request(contorlId)); dispatch(objectClickAction(contorlId));
dispatch(controlGpDtlAction.request(contorlId));
}; };
//마커를 삭제 한다. //마커를 삭제 한다.
@ -116,52 +98,54 @@ export const DronMarker = props => {
}; };
//마커에 위치를 이동한다. //마커에 위치를 이동한다.
const moveMarkers = (marker, position) => { const moveMarkers = (marker, position) => {
// console.log(marker);
marker.setPosition(position); marker.setPosition(position);
}; };
//데이터가 없는 마커를 모두 삭제 한다. //데이터가 없는 마커를 모두 삭제 한다.
const allRemoveMarkers = () => { const allRemoveMarkers = () => {
if (props.arrMarkers && controlGpList) { if (arrMarkers && controlGpList) {
props.arrMarkers.map(marker => { arrMarkers.map(marker => {
const isExists = controlGpList.find( const isExists = controlGpList.find(
item => item.objectId === marker.id item => item.objectId === marker.id
); );
if (!isExists) { if (!isExists) {
removeMarkers(marker); removeMarkers(marker);
const arrData = props.arrMarkers.filter( const arrData = arrMarkers.filter(
item => item.objectId != marker.id item => item.id != marker.id
); );
props.removeArrMarkers(arrData); removeArrMarkers(arrData);
} }
}); });
} }
// }
}; };
//마커를 셋팅 한다. //마커를 셋팅 한다.
const markerInit = () => { const markerInit = () => {
if (controlGpList) { if (controlGpList) {
allRemoveMarkers(); allRemoveMarkers();
controlGpList.map(item => { controlGpList.map(item => {
const position = new naver.maps.LatLng(item.lat, item.lng); 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 ele => ele.id === item.objectId
); );
if (isExists) { if (isExists) {
moveMarkers(isExists, position); moveMarkers(isExists, position);
} else { } else {
// console.log(' ADD >>>', props.arrMarkers);
addMarkers(position, item.objectId, item.controlId); addMarkers(position, item.objectId, item.controlId);
} }
} else { } else {
addMarkers(position, item.objectId, item.controlId); addMarkers(position, item.objectId, item.controlId);
} }
}); });
} }
}; };
const removeArrMarkers = arrData => {
setArrMarkers(arrData);
};
return null; return null;
}; };

5
src/components/mapDraw/naver/NaverMap.js

@ -6,7 +6,6 @@ import { FeatureAirZone } from './feature/FeatureAirZone';
import { DrawMap } from './draw/DrawMap'; import { DrawMap } from './draw/DrawMap';
import { JQueryDraw } from './draw/JQueryDraw'; import { JQueryDraw } from './draw/JQueryDraw';
export const NaverCustomMap = () => { export const NaverCustomMap = () => {
const naver = window.naver; const naver = window.naver;
const [mapObject, setMapObject] = useState(null); const [mapObject, setMapObject] = useState(null);
@ -50,9 +49,7 @@ export const NaverCustomMap = () => {
{/* 그리기 도구 모음 불러오는 거 */} {/* 그리기 도구 모음 불러오는 거 */}
<DrawMap map={mapObject} naver={naver} /> <DrawMap map={mapObject} naver={naver} />
{/* <Test map={mapObject} naver={naver} /> */}
{/* <JQueryConv map={mapObject} naver={naver} /> */}
</> </>
) : null} ) : null}

149
src/components/mapDraw/naver/draw/JQueryDraw.js

@ -2,10 +2,6 @@ import $ from 'jquery';
import '../../../../assets/css/custom.css'; import '../../../../assets/css/custom.css';
import { CustomInput } from 'reactstrap'; import { CustomInput } from 'reactstrap';
import GeoJSONReader from 'jsts/org/locationtech/jts/io/GeoJSONReader'
import GeoJSONWriter from 'jsts/org/locationtech/jts/io/GeoJSONWriter'
import {BufferOp} from 'jsts/org/locationtech/jts/operation/buffer'
export const JQueryDraw = props => { export const JQueryDraw = props => {
const {naver} = props; const {naver} = props;
const {map} = props; const {map} = props;
@ -107,54 +103,67 @@ export const JQueryDraw = props => {
if (this._polyline) { if (this._polyline) {
// console.log(this._polyline.getPath()._array, 'path') // console.log(this._polyline.getPath()._array, 'path')
let te = this._polyline.getPath()._array; let polypaths = this._polyline.getPath()._array;
let co = [];
for(let i = 0; i< te.length; i++) {
co.push([te[i]._lat, te[i]._lng]);
}
console.log(co, 'co')
let coords = { //파싱
"type": "LineString", let polypathJSON = new Array();
"coordinates": co for(let i = 0; i< polypaths.length; i++) {
};
//파싱
let obj = new Object();
obj.x = '' + polypaths[i]._lng + '';
obj.y = '' + polypaths[i]._lat + '';
const reader = new GeoJSONReader(); obj = JSON.stringify(obj);
const writer = new GeoJSONWriter(); polypathJSON.push(JSON.parse(obj));
}
console.log(polypathJSON, 'json polyline path')
const distance = (100 * 0.001) / 111.12;
const line = reader.read(coords);
const buffer = BufferOp.bufferOp(line, distance);
const polygon = writer.write(buffer);
// console.log(buffer._shell._points._coordinates, 'coords'); //버퍼 생성에 필요한 coordinates 배열 변환
let bu = buffer._shell._points._coordinates; let lineStringPaths = [];
let buffers = []; for(let i = 0; i < this._polyline.getPath().length; i++) {
for(let i = 0; i< bu.length; i++) { lineStringPaths.push([this._polyline.getPath()._array[i].x, this._polyline.getPath()._array[i].y]);
buffers.push([bu[i].y, bu[i].x]);
} }
console.log(buffers, 'buffers') 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'});
const poly = new naver.maps.Polyline({ //버퍼 라인 생성
let bufferPath = bufferObj.features[0].geometry.coordinates[0];
console.log(bufferPath, 'buffer path')
this.bufferPolyline = new naver.maps.Polyline({
strokeColor: '#ff0000', strokeColor: '#ff0000',
strokeWeight: 2, strokeWeight: 2,
strokeStyle: [4, 4], strokeStyle: [4, 4],
strokeOpacity: 0.6, strokeOpacity: 0.6,
path : buffers, path : bufferPath,
map: map map: map
}) });
console.log(poly, 'poly')
// 이거 하면 그동안 한거 싹 사라짐 -> 얘를 통해서 drawType이 바뀌면 다 날라가는 걸로 해보면 될듯 // 이거 하면 그동안 한거 싹 사라짐 -> 얘를 통해서 drawType이 바뀌면 다 날라가는 걸로 해보면 될듯
// this._polyline.setMap(null) // this._polyline.setMap(null)
delete this._polyline; delete this._polyline;
//버퍼 테스트
delete this._buffercircle;
delete this._buffercoord;
} }
//onfocus()의 반대기능 = blur() //onfocus()의 반대기능 = blur()
this.$btnLine.removeClass('control-on').blur(); this.$btnLine.removeClass('control-on').blur();
@ -240,13 +249,56 @@ export const JQueryDraw = props => {
} }
}, },
_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 = '<div style="display:inline-block;padding:5px;text-align:center;background-color:#fff;border:1px solid #000;font-size:14px;color:#ff0000;"><span>'+ text +'</span></div>'
} else {
content = '<div style="display:inline-block;padding:5px;text-align:center;background-color:#fff;border:1px solid #000;color:#737373;"><span>'+ text +'</span></div>'
}
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) { _onClickDistance: function(e) {
console.log('onClickDistance') console.log('onClickDistance')
var map = this.map, var map = this.map,
coord = e.coord; coord = e.coord;
// console.log(coord, '클릭좌표1');
if (!this._polyline) { if (!this._polyline) {
// 임시로 보여줄 점선 폴리라인을 생성합니다. // 임시로 보여줄 점선 폴리라인을 생성합니다.
this._guideline = new naver.maps.Polyline({ this._guideline = new naver.maps.Polyline({
@ -274,9 +326,16 @@ export const JQueryDraw = props => {
map: map map: map
}); });
this._lastDistance = this._polyline.getDistance();
this._addMileStone(coord, 'Start');
} else { } else {
this._guideline.setPath([e.coord]); this._guideline.setPath([e.coord]);
this._polyline.getPath().push(coord); this._polyline.getPath().push(coord);
var distance = this._polyline.getDistance();
this._addMileStone(coord, this._fromMetersToText(distance - this._lastDistance));
this._lastDistance = distance;
} }
}, },
@ -519,11 +578,11 @@ export const JQueryDraw = props => {
this._polyline.setMap(null); this._polyline.setMap(null);
delete this._polyline; delete this._polyline;
this._buffercircle.setMap(null); // this._buffercircle.setMap(null);
delete this._buffercircle; // delete this._buffercircle;
this._buffercoord.setMap(null) // this._buffercoord.setMap(null)
delete this._buffercoord; // delete this._buffercoord;
} }
this._finishDistance(); this._finishDistance();
@ -589,12 +648,6 @@ export const JQueryDraw = props => {
className='control-btn' className='control-btn'
src='http://static.naver.net/maps/mantle/drawing/1x/rectangle.png' src='http://static.naver.net/maps/mantle/drawing/1x/rectangle.png'
/> />
<br/>
<CustomInput
id='input'
type='input'
className='buffer-input'
/>
</li> </li>
</ul> </ul>
</div> </div>

21
src/components/websocket/WebsocketClient.js

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

10
src/containers/basis/dron/BasisDronContainer.js

@ -106,16 +106,6 @@ export const BasisDronContainer = props => {
return row?.prdctCmpnNm; return row?.prdctCmpnNm;
} }
}, },
{
name: '운영자 명',
selector: 'ownerNm',
minWidth: '102px',
sortable: true,
cell: row => {
return row?.ownerNm;
}
},
{ {
name: '수정일자', name: '수정일자',
selector: 'updateDt', selector: 'updateDt',

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

@ -1,11 +1,13 @@
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { create } from 'sortablejs';
import { ActionType, createAsyncAction } from 'typesafe-actions'; import { ActionType, createAsyncAction } from 'typesafe-actions';
import { import {
ControlDetailData, ControlDetailData,
ControlGpData, ControlGpData,
ControlGpDtlState, ControlGpDtlState,
ControlGpHisState, ControlGpHisState,
ControlGpState ControlGpState,
ControlGroupAuthState
} from '../models/controlGpModel'; } from '../models/controlGpModel';
const CONTROL_GP_REQUEST = 'control/gp/CONTROL_GP_REQUEST'; 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_SUCCESS = 'control/gp/CONTROL_GP_RTDTL_SUCCESS';
const CONTROL_GP_RTDTL_FAILURE = 'control/gp/CONTROL_GP_RTDTL_FAILURE'; 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( export const controlGpAction = createAsyncAction(
CONTROL_GP_REQUEST, CONTROL_GP_REQUEST,
CONTROL_GP_SUCCESS, CONTROL_GP_SUCCESS,
@ -48,11 +55,18 @@ export const controlGpRtDtlAction = createAsyncAction(
CONTROL_GP_RTDTL_FAILURE CONTROL_GP_RTDTL_FAILURE
)<ControlGpData, ControlGpDtlState, AxiosError>(); )<ControlGpData, ControlGpDtlState, AxiosError>();
export const controlGroupAuthAction = createAsyncAction(
CONTROL_GROUP_AUTH_REQUEST,
CONTROL_GROUP_AUTH_SUCCESS,
CONTROL_GROUP_AUTH_FAILURE
)<string, ControlGroupAuthState, AxiosError>();
const actions = { const actions = {
controlGpAction, controlGpAction,
controlGpHisAction, controlGpHisAction,
controlGpDtlAction, controlGpDtlAction,
controlGpRtDtlAction controlGpRtDtlAction,
controlGroupAuthAction
}; };
export type ControlGpAction = ActionType<typeof actions>; export type ControlGpAction = ActionType<typeof actions>;

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

@ -1,5 +1,5 @@
import axios from '../../../utils/customAxiosUtil'; import axios from '../../../utils/customAxiosUtil';
import { ReponseControlGpHistory } from '../models/controlGpModel'; import { ReponseControlGpHistory, ControlGroupAuthData, ResponseControlGroupAuth} from '../models/controlGpModel';
export const controlGpApi = { export const controlGpApi = {
getHistory: async (id: string) => { getHistory: async (id: string) => {
@ -8,12 +8,21 @@ export const controlGpApi = {
return null; return null;
} }
const { data }: ReponseControlGpHistory = await axios.get( const { data }: ReponseControlGpHistory = await axios.get(
`api/ctr/cntrl/history/${id}` `api/ctr/cntrl/history/list/${id}`
); );
return data; return data;
}, },
getDetail: async (id: string) => { getDetail: async (id: string) => {
return await axios.get(`api/ctr/cntrl/detail/${id}`); 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; controlDetail: ControlDetailData | undefined;
} }
export interface ControlGroupAuthState {
controlGroupAuthInfo : ControlGroupAuthData[] | undefined;
}
export interface ControlGpHistoryData { export interface ControlGpHistoryData {
objectId: String; objectId: String;
lat: number; lat: number;
@ -78,13 +82,29 @@ export interface ControlGpData {
heading: number; heading: number;
} }
export interface ControlGroupAuthData {
cstmrSno: number,
userId: string,
groupId: string,
groupNm: string,
groupAuthCd: string,
arcrftSno: number,
idntfNum: string,
createUserId: string
}
export interface ReponseControlGpHistory { export interface ReponseControlGpHistory {
data: ControlGpHistoryData[]; data: ControlGpHistoryData[];
} }
export interface ResponseControlGroupAuth {
data: ControlGroupAuthData[];
}
export const initiaResponseControlGpData = { export const initiaResponseControlGpData = {
controlGpList: undefined, controlGpList: undefined,
controlGpDetail: undefined, controlGpDetail: undefined,
controlGpHistory: undefined, controlGpHistory: undefined,
controlDetail: undefined controlDetail: undefined,
controlGroupAuthInfo: undefined,
}; };

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

@ -5,13 +5,15 @@ import {
controlGpAction, controlGpAction,
controlGpDtlAction, controlGpDtlAction,
controlGpHisAction, controlGpHisAction,
controlGpRtDtlAction controlGpRtDtlAction,
controlGroupAuthAction
} from '../actions/controlGpAction'; } from '../actions/controlGpAction';
import { import {
ControlDetailData, ControlDetailData,
ControlGpDtlState, ControlGpDtlState,
ControlGpHisState, ControlGpHisState,
ControlGpState, ControlGpState,
ControlGroupAuthState,
initiaResponseControlGpData initiaResponseControlGpData
} from '../models/controlGpModel'; } from '../models/controlGpModel';
@ -54,3 +56,15 @@ export const controlGpDtlReducer = createReducer<
draft.controlDetail = data; 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;
})
)

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

@ -1,41 +1,63 @@
import { call, put, select, takeEvery } from '@redux-saga/core/effects'; import { call, put, select, takeEvery } from '@redux-saga/core/effects';
import { ActionType } from 'typesafe-actions'; 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 * as Actions from '../actions/controlGpAction';
import { controlGpApi } from '../apis/controlGpApi'; import { controlGpApi } from '../apis/controlGpApi';
import decode from 'jwt-decode';
import { ControlGpData } from '../models/controlGpModel';
function* getControlGpSaga( function* getControlGpSaga(
action: ActionType<typeof Actions.controlGpAction.request> action: ActionType<typeof Actions.controlGpAction.request>
) { ) {
try { try {
// console.log("-------------------------------") const data = action.payload;
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( yield put(
Actions.controlGpAction.success({ Actions.controlGpAction.success({
controlGpList: data controlGpList: gpsData
}) })
); );
const state = yield select();
const { objectId, isClickObject } = state.controlMapReducer;
let detailData;
if (objectId && isClickObject) { if (objectId && isClickObject) {
let detailData;
//History 호출 //History 호출
yield put(Actions.controlGpHisAction.request({ id: objectId })); yield put(Actions.controlGpHisAction.request({ id: objectId }));
//상세 정보에서 실시간 데이터 호출 //상세 정보에서 실시간 데이터 호출
data.map(item => { data.map(item => {
if (item.objectId === objectId) { if (item.controlId === objectId) {
detailData = item; detailData = item;
} }
}); });
yield put(Actions.controlGpRtDtlAction.request(detailData)); yield put(Actions.controlGpRtDtlAction.request(detailData));
} }
} catch (error) { } catch (error) {
yield put(Actions.controlGpAction.failure(error)); yield put(Actions.controlGpAction.failure(error));
} }
} }
@ -44,10 +66,10 @@ function* getControlGpHistorySaga(
action: ActionType<typeof Actions.controlGpHisAction.request> action: ActionType<typeof Actions.controlGpHisAction.request>
) { ) {
try { try {
const { id } = action.payload; const { id } = action.payload;
const data = yield call(controlGpApi.getHistory, id);
const data = yield call(controlGpApi.getHistory, id);
// console.log('>>>>>>>1111>>>>> ', rsponse);
yield put( yield put(
Actions.controlGpHisAction.success({ Actions.controlGpHisAction.success({
controlGpHistory: data controlGpHistory: data
@ -80,7 +102,7 @@ function* controlDtlSaga(
action: ActionType<typeof Actions.controlGpDtlAction.request> action: ActionType<typeof Actions.controlGpDtlAction.request>
) { ) {
try { try {
const controlId = action.payload; const controlId = action.payload;
const { data } = yield call(controlGpApi.getDetail, controlId); const { data } = yield call(controlGpApi.getDetail, controlId);
console.log('data>>>>>>>>>>>>>>>>>>>>>', data); console.log('data>>>>>>>>>>>>>>>>>>>>>', 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() { export function* controlGpSaga() {
yield takeEvery(Actions.controlGpAction.request, getControlGpSaga); yield takeEvery(Actions.controlGpAction.request, getControlGpSaga);
yield takeEvery(Actions.controlGpHisAction.request, getControlGpHistorySaga); yield takeEvery(Actions.controlGpHisAction.request, getControlGpHistorySaga);
yield takeEvery(Actions.controlGpRtDtlAction.request, controlGpRtDtlSaga); yield takeEvery(Actions.controlGpRtDtlAction.request, controlGpRtDtlSaga);
yield takeEvery(Actions.controlGpDtlAction.request, controlDtlSaga); yield takeEvery(Actions.controlGpDtlAction.request, controlDtlSaga);
yield takeEvery(Actions.controlGroupAuthAction.request, controlGroupAuthSaga);
} }

2
src/modules/control/map/reducers/controlMapReducer.ts

@ -21,7 +21,7 @@ const controlReducerReducer = (state = initialState, action) => {
case 'MAP_TYPE_CHANGE': case 'MAP_TYPE_CHANGE':
return {...state, mapType: action.value}; return {...state, mapType: action.value};
case 'OBJECT_CLICK': case 'OBJECT_CLICK':
return {...state, objectId: action.value, isClickObject: true}; return {...state, objectId: action.value, isClickObject: true};
case 'OBEJCT_UN_CLICK': case 'OBEJCT_UN_CLICK':

4
src/redux/reducers/rootReducer.ts

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

Loading…
Cancel
Save