노승철
2 years ago
28 changed files with 4791 additions and 1193 deletions
@ -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 => (<div>{row.groupNm}</div>)}, |
||||
{id: 'arcrftModelNm', name: '모델 명', cell: row => (<div>{row.arcrftModelNm}</div>)}, |
||||
{id: 'idntfTypeCd', name: '종류', cell: row => (<div>{row.arcrftTypeCd}</div>)}, |
||||
{id: 'ownerNm', name: '소유자 명', cell: row => (<div>{row.ownerNm}</div>)}, |
||||
{id: 'idntfNum', name: '식별 코드', cell: row => (<div>{row.idntfNum}</div>)}, |
||||
{ |
||||
id: 'selectPilot', name: '선택', cell: row => { |
||||
return <Button.Ripple color='primary' size='sm' onClick={() => { |
||||
handleSelectArcrft(row.arcrftSno)
|
||||
} |
||||
}>선택</Button.Ripple>; |
||||
}
|
||||
} |
||||
]; |
||||
|
||||
return ( |
||||
<> |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col> |
||||
<div |
||||
className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>검색조건</h4> |
||||
</div> |
||||
<div className='d-flex align-items-center'> |
||||
<Button.Ripple |
||||
color='primary' |
||||
size='sm' |
||||
// onClick={handleClickSearch}
|
||||
> |
||||
<Search size={16}/> |
||||
검색 |
||||
</Button.Ripple> |
||||
</div> |
||||
</div> |
||||
<Card> |
||||
<CardBody className='pal-card-body'> |
||||
<div className='search-cont'> |
||||
<dl>
|
||||
<dt>
|
||||
<div className='search-box'> |
||||
<div className='search-list-ti'>소유자 명</div> |
||||
<div className='search-list'> |
||||
<div className='search-list-cont'> |
||||
<Row> |
||||
<Col className='list-input' xl='4' md='4' sm='12'> |
||||
<FormGroup className='form-label-group'> |
||||
<Input |
||||
type='text' |
||||
id='ownerNm' |
||||
name='ownerNm' |
||||
// value={props.params.groupNm}
|
||||
// onChange={props.handlerInput}
|
||||
bsSize='sm' |
||||
// onKeyPress={props.onKeyPress}
|
||||
placeholder='소유자 명을 입력하세요' |
||||
/> |
||||
<Label for='test'>소유자 명</Label> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</dt> |
||||
</dl> |
||||
</div> |
||||
</CardBody> |
||||
</Card> |
||||
|
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col> |
||||
<div className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>기체 목록</h4> |
||||
<span className='search-case'>검색결과 총 {!!arcrftList ? arcrftList.length : 0}건</span> |
||||
</div> |
||||
</div> |
||||
<div className='invoice-list-wrapper'> |
||||
<Card> |
||||
<div className='invoice-list-dataTable'> |
||||
<GridDatabase
|
||||
data={arcrftList} |
||||
count={arcrftList ? arcrftList.length : 0} |
||||
columns={columns} |
||||
// pagination={props.pagination}
|
||||
/> |
||||
{/* 검색된 데이터가 없습니다. */} |
||||
</div> |
||||
</Card> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default FlightPlanArcrft; |
@ -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 (
|
||||
<Card className='mb-0'> |
||||
<CardBody> |
||||
<Row> |
||||
<Col> |
||||
<Card> |
||||
<CardBody className='pal-card-body'> |
||||
<div className='search-cont search-info pd-0'> |
||||
<div className='cont-ti mb-1 d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>비행 구역 상세 정보</h4> |
||||
</div> |
||||
</div> |
||||
|
||||
<dl> |
||||
<dt> |
||||
<div className='search-info-ti d-flex justify-content-between'> |
||||
<h4 className='ti'>좌표 정보</h4> |
||||
</div> |
||||
|
||||
<div className='search-info-box'> |
||||
<Row> |
||||
{coordList ?
|
||||
coordList.map((coord, idx) => { |
||||
const latlon = coord.lat + ' / ' + coord.lon; |
||||
|
||||
return ( |
||||
<Col key={idx} className='list-input' lg={6} md={6} sm={12}> |
||||
<FormGroup> |
||||
<Label for='test'><span className='necessary'>*</span>좌표 {idx+1} </Label> |
||||
<Input |
||||
type='text'
|
||||
name='coord' |
||||
bsSize='sm' |
||||
placeholdeer='' |
||||
readOnly |
||||
value={latlon} |
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
) |
||||
}) |
||||
: |
||||
<Col className='list-input' lg={6} md={6} sm={12}> |
||||
<FormGroup> |
||||
<Label for='test'><span className='necessary'>*</span>좌표 1</Label> |
||||
<Input |
||||
type='text'
|
||||
name='coord' |
||||
bsSize='sm' |
||||
placeholdeer='' |
||||
readOnly
|
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
}
|
||||
|
||||
</Row> |
||||
</div> |
||||
</dt> |
||||
|
||||
<dt> |
||||
<div className='search-info-ti d-flex justify-content-between'> |
||||
<h4 className='ti'>기타 정보</h4> |
||||
</div> |
||||
|
||||
<div className='search-info-box'> |
||||
<Row> |
||||
<Col className='list-input' lg={6} md={6} sm={12}> |
||||
<FormGroup className='m_ft'>
|
||||
<div className='m_ft_box'> |
||||
<Label for='test'><span className='necessary'>*</span>반경(m)</Label> |
||||
<Input |
||||
type='text' |
||||
id='bufferZone' |
||||
name='bufferZone' |
||||
bsSize='sm' |
||||
placeholder='반경'
|
||||
value={data ? data[0].bufferZone : ''}
|
||||
onChange={(e) => { |
||||
const {name, value} = e.target; |
||||
handleChange({ |
||||
name, |
||||
value |
||||
}) |
||||
}}
|
||||
/> |
||||
</div> |
||||
<div className='m_ft_box'> |
||||
<Button.Ripple |
||||
className='mr-1' |
||||
color='primary' |
||||
size='sm' |
||||
onClick={() => handleBufferList()} |
||||
> |
||||
적용 |
||||
</Button.Ripple> |
||||
</div> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div className='search-info-box'> |
||||
<Row> |
||||
<Col className='list-input' lg={6} md={6} sm={12}> |
||||
<FormGroup>
|
||||
<Label for='test'><span className='necessary'>*</span>고도(ft)</Label> |
||||
<Input |
||||
type='text' |
||||
id='fltElev' |
||||
name='fltElev' |
||||
bsSize='sm' |
||||
placeholder='고도'
|
||||
value={data ? data[0].fltElev : ''}
|
||||
onChange={(e) => { |
||||
const {name, value} = e.target; |
||||
handleChange({ |
||||
name, |
||||
value |
||||
}) |
||||
}}
|
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div className='search-info-box'> |
||||
<Row> |
||||
<Col className='list-input' lg={6} md={6} sm={12}> |
||||
<FormGroup> |
||||
<Label for='test'><span className='necessary'>*</span>비행 방식</Label> |
||||
<Input |
||||
type='text' |
||||
id='fltMethod' |
||||
name='fltMethod' |
||||
bsSize='sm' |
||||
placeholder='비행 방식'
|
||||
value={data ? data[0].fltMethod : ''}
|
||||
onChange={(e) => { |
||||
const {name, value} = e.target; |
||||
handleChange({ |
||||
name, |
||||
value |
||||
}) |
||||
}} |
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</dt> |
||||
</dl> |
||||
</div> |
||||
|
||||
<div className='d-flex align-items-center mt-2'> |
||||
<Button.Ripple |
||||
type='submit' |
||||
className='mr-1' |
||||
color='primary' |
||||
onClick={e => handleSave()} |
||||
> |
||||
등록 |
||||
</Button.Ripple> |
||||
<Button.Ripple |
||||
className='mr-1' |
||||
color='primary' |
||||
onClick={e => handleClose()} |
||||
> |
||||
닫기 |
||||
</Button.Ripple> |
||||
</div> |
||||
</CardBody> |
||||
</Card> |
||||
</Col> |
||||
</Row> |
||||
</CardBody> |
||||
</Card> |
||||
) |
||||
} |
||||
|
||||
export default FlightPlanAreaDetailForm; |
@ -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 (
|
||||
<Card> |
||||
<CardBody>
|
||||
<div className='search-cont search-info pd-0'> |
||||
<div className='cont-ti mb-1 d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>상세 정보</h4> |
||||
</div> |
||||
<div className='final'> |
||||
{/* {props.type === 'update' ? ( |
||||
<span>최종 수정일자 : {props.updateDt}</span> |
||||
) : null} */} |
||||
</div> |
||||
</div> |
||||
|
||||
<dl> |
||||
<dt>
|
||||
<div className='search-info-box'> |
||||
<Row> |
||||
<Col className='list-input' lg={6} md={6} sm={12}> |
||||
<FormGroup> |
||||
<Label for='test'> |
||||
<span className='necessary'></span>반경(m) |
||||
</Label> |
||||
<Input |
||||
type='text' |
||||
id='radius' |
||||
name='radius'
|
||||
size='sm' |
||||
placeholder=''
|
||||
innerRef={props.data}
|
||||
/> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div className='search-info-box'> |
||||
<Row> |
||||
<Col className='list-input' lg={6} md={6} sm={12}> |
||||
<FormGroup className='m_ft'> |
||||
<div className='m_ft_box'> |
||||
<Label for='test'> |
||||
<span className='necessary'></span>고도(m/ft) |
||||
</Label> |
||||
<Input |
||||
type='text' |
||||
id='altitude_m' |
||||
name='altitude_m'
|
||||
size='sm' |
||||
placeholder='m'
|
||||
innerRef={props.data}
|
||||
/> |
||||
</div> |
||||
<div className='m_ft_box'>
|
||||
<Input |
||||
type='text' |
||||
id='altitude' |
||||
name='altitude'
|
||||
size='sm' |
||||
placeholder='ft'
|
||||
innerRef={props.data}
|
||||
/> |
||||
</div> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
|
||||
<Button.Ripple |
||||
className='mr-1' |
||||
color='primary' |
||||
size='sm' |
||||
onClick={ |
||||
props.submit |
||||
} |
||||
> |
||||
확인 |
||||
</Button.Ripple> |
||||
<Button.Ripple |
||||
className='mr-1' |
||||
color='danger' |
||||
size='sm' |
||||
onClick={() =>
|
||||
props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }) |
||||
} |
||||
> |
||||
취소 |
||||
</Button.Ripple> |
||||
</dt> |
||||
</dl> |
||||
</div> |
||||
</CardBody> |
||||
</Card> |
||||
) |
||||
} |
||||
|
||||
export default FlightPlanAreaForm; |
@ -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 ( |
||||
<div className='vertically-centered-modal'> |
||||
<Modal |
||||
isOpen={props.modal.isOpen} |
||||
toggle={() => |
||||
props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }) |
||||
}
|
||||
className='modal-dialog-centered modal-xl' |
||||
> |
||||
<ModalHeader |
||||
toggle={() => |
||||
props.setModal({ ...props.modal, isOpen: !props.modal.isOpen }) |
||||
} |
||||
> |
||||
{props.modal.title} |
||||
</ModalHeader> |
||||
<ModalBody> |
||||
<FlightPlanAreaContainer |
||||
modal={props.modal} |
||||
setModal={props.setModal}
|
||||
onSubmit={onSubmit}
|
||||
setOnSubmit={setOnSubmit}
|
||||
/> |
||||
</ModalBody> |
||||
{/* <ModalFooter> |
||||
<Button |
||||
type="submit" |
||||
color='primary' |
||||
// onClick={() =>
|
||||
// // props.setModal({ ...props.modal, isOpen: !props.modal.isOpen })
|
||||
// setOnSubmit(true)
|
||||
// }
|
||||
outline |
||||
> |
||||
저장 |
||||
</Button> |
||||
</ModalFooter> */} |
||||
</Modal> |
||||
</div> |
||||
); |
||||
}; |
File diff suppressed because it is too large
Load Diff
@ -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 ( |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col> |
||||
<div className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
{/* <h4>{"비행 계획"} 목록</h4> */} |
||||
<h4>{"비행계획서 신청"} 목록</h4> |
||||
<span className='search-case'>검색결과 총 0건</span> |
||||
</div> |
||||
<div className='d-flex align-items-center'> |
||||
<Button.Ripple |
||||
color='primary' |
||||
size='sm' |
||||
onClick={props.moveFlightPlan} |
||||
> |
||||
{/* 계획서 생성 */} |
||||
비행계획서 신청 |
||||
</Button.Ripple> |
||||
</div> |
||||
</div> |
||||
<div className='invoice-list-wrapper'> |
||||
<Card> |
||||
<div className='invoice-list-dataTable'> |
||||
<GridDatabase |
||||
title={'비행이력'} |
||||
// data={props.data}
|
||||
count={0} |
||||
// columns={props.columns}
|
||||
// pagination={props.pagination}
|
||||
/> |
||||
{/* 검색된 데이터가 없습니다. */} |
||||
</div> |
||||
</Card> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
) |
||||
|
||||
const FlightPlanGrid = ({movePage, planListData, handleMoveDetail}) => { |
||||
|
||||
const columns = [ |
||||
{id: 'planSno', name: '번호', cell: (row, i) => (<div>{i+1}</div>)}, |
||||
{id: 'fltPurpose', name: '비행목적', cell: row => (<div>{row.fltPurpose}</div>)}, |
||||
{ |
||||
id: 'fltMethod', name: '비행방식', cell: row => { |
||||
const displayName = row.areaList && row.areaList.length > 0 && row.areaList[0].fltMethod || '-'; |
||||
return <div>{displayName}</div> |
||||
} |
||||
}, |
||||
{id: 'schFltStDt', name: '출발일', cell: row => (<div>{row.schFltStDt}</div>)}, |
||||
{id: 'aprvlYn', name: '승인여부', cell: row => (<div>{row.aprvlYn}</div>)}, |
||||
{ |
||||
id: 'moveDetail', name: '상세보기', cell: row => { |
||||
return <Button.Ripple color='primary' size='sm' onClick={() => { |
||||
handleMoveDetail(row.planSno)} |
||||
}>상세</Button.Ripple>; |
||||
} |
||||
} |
||||
]; |
||||
|
||||
return ( |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col> |
||||
<div |
||||
className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>비행계획서 신청 목록</h4> |
||||
<span className='search-case'>검색결과 총 {!!planListData ? planListData.length : 0}건</span> |
||||
</div> |
||||
<div className='d-flex align-items-center'> |
||||
<Button.Ripple |
||||
color='primary' |
||||
size='sm' |
||||
onClick={movePage} |
||||
> |
||||
{/* 계획서 생성 */} |
||||
비행계획서 신청 |
||||
</Button.Ripple> |
||||
</div> |
||||
</div> |
||||
<div className='invoice-list-wrapper'> |
||||
<Card> |
||||
<div className='invoice-list-dataTable'> |
||||
<GridDatabase |
||||
title={'비행이력'} |
||||
data={planListData}
|
||||
columns={columns} |
||||
count={!!planListData ? planListData.length : 0} |
||||
// pagination={props.pagination}
|
||||
/> |
||||
{/* 검색된 데이터가 없습니다. */} |
||||
</div> |
||||
</Card> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default FlightPlanGrid; |
||||
export default FlightPlanGrid; |
||||
|
@ -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 => (<div>{row.groupNm}</div>)}, |
||||
{id: 'groupId', name: '그룹 코드', minWidth: '102px', sortable: true, cell: row => (<div>{row.groupId}</div>)}, |
||||
{sortable: true, cell: row => { |
||||
return selectGroup?.groupId === row?.groupId ? (
|
||||
<Button.Ripple
|
||||
color='danger' |
||||
className='badge badge-danger' |
||||
onClick={() => handlerGroupCancel()} |
||||
> |
||||
선택취소 |
||||
</Button.Ripple> |
||||
) : ( |
||||
<Button.Ripple |
||||
color='primary' |
||||
className='badge badge-primary' |
||||
onClick={() => { |
||||
handleGroupSelect({ |
||||
groupId: row?.groupId, |
||||
groupNm: row?.groupNm, |
||||
groupAuthCd: row?.groupAuthCd |
||||
})
|
||||
} |
||||
} |
||||
> |
||||
상세보기 |
||||
</Button.Ripple> |
||||
) |
||||
}} |
||||
]; |
||||
|
||||
return ( |
||||
<> |
||||
<div className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>나의 그룹 목록</h4> |
||||
<span className='search-case'>검색결과 총 {count}건</span> |
||||
</div> |
||||
<div className='d-flex align-items-center'></div> |
||||
</div> |
||||
<div className='invoice-list-wrapper'> |
||||
<Card> |
||||
<div className='invoice-list-dataTable'> |
||||
<GridDatabase
|
||||
data={data} |
||||
count={count} |
||||
columns={columns} |
||||
/> |
||||
</div> |
||||
</Card> |
||||
</div> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default FlightPlanGroupGrid; |
@ -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 ( |
||||
<div className='vertically-centered-modal'> |
||||
<Modal |
||||
isOpen={isOpen} |
||||
toggle={() => |
||||
handleModal(({target: type, isOpen: false})) |
||||
}
|
||||
className='modal-dialog-centered modal-xl' |
||||
> |
||||
<ModalHeader |
||||
toggle={() => |
||||
handleModal(({target: type, isOpen: false})) |
||||
} |
||||
> |
||||
{title} |
||||
</ModalHeader> |
||||
<ModalBody> |
||||
{description} |
||||
</ModalBody> |
||||
</Modal> |
||||
</div> |
||||
); |
||||
}; |
@ -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 => (<div>{row.groupNm}</div>)}, |
||||
{id: 'memberName', name: '성명', cell: row => (<div>{row.memberName}</div>)}, |
||||
{id: 'hpno', name: '핸드폰 번호', cell: row => (<div>{row.hpno}</div>)}, |
||||
{id: 'email', name: '이메일', cell: row => (<div>{row.email}</div>)}, |
||||
{ |
||||
id: 'selectPilot', name: '선택', cell: row => { |
||||
return <Button.Ripple color='primary' size='sm' onClick={() => { |
||||
handleSelectPilot(row.cstmrSno)
|
||||
} |
||||
}>선택</Button.Ripple>; |
||||
}
|
||||
} |
||||
]; |
||||
|
||||
return ( |
||||
<> |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col> |
||||
<div |
||||
className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>검색조건</h4> |
||||
</div> |
||||
<div className='d-flex align-items-center'> |
||||
<Button.Ripple |
||||
color='primary' |
||||
size='sm' |
||||
// onClick={handleClickSearch}
|
||||
> |
||||
<Search size={16}/> |
||||
검색 |
||||
</Button.Ripple> |
||||
</div> |
||||
</div> |
||||
<Card> |
||||
<CardBody className='pal-card-body'> |
||||
<div className='search-cont'> |
||||
<dl>
|
||||
<dt>
|
||||
<div className='search-box'> |
||||
<div className='search-list-ti'>성명</div> |
||||
<div className='search-list'> |
||||
<div className='search-list-cont'> |
||||
<Row> |
||||
<Col className='list-input' xl='4' md='4' sm='12'> |
||||
<FormGroup className='form-label-group'> |
||||
<Input |
||||
type='text' |
||||
id='memberName' |
||||
name='memberName' |
||||
// value={props.params.groupNm}
|
||||
// onChange={props.handlerInput}
|
||||
bsSize='sm' |
||||
// onKeyPress={props.onKeyPress}
|
||||
placeholder='성명을 입력하세요' |
||||
/> |
||||
<Label for='test'>성명</Label> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</dt> |
||||
</dl> |
||||
</div> |
||||
</CardBody> |
||||
</Card> |
||||
|
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div className='pal-card-box'>
|
||||
<div className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>조종사 목록</h4> |
||||
<span className='search-case'>검색결과 총 {!!pilotList ? pilotList.length : 0}건</span> |
||||
</div> |
||||
<div className='d-flex align-items-center'></div> |
||||
</div> |
||||
<div className='invoice-list-wrapper'> |
||||
<Card> |
||||
<div className='invoice-list-dataTable'> |
||||
<GridDatabase
|
||||
data={pilotList} |
||||
count={pilotList ? pilotList.length : 0} |
||||
columns={columns} |
||||
// pagination={props.pagination}
|
||||
/> |
||||
</div> |
||||
</Card> |
||||
</div> |
||||
</div> |
||||
</> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default FlightPlanPilot; |
@ -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 ( |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col> |
||||
<div className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>검색조건</h4> |
||||
</div> |
||||
<div className='d-flex align-items-center'> |
||||
<Button.Ripple |
||||
color='primary' |
||||
size='sm' |
||||
onClick={e => props.handlerSearch()} |
||||
> |
||||
<Search size={16} /> |
||||
검색 |
||||
</Button.Ripple> |
||||
</div> |
||||
</div> |
||||
<Card> |
||||
<CardBody className='pal-card-body'> |
||||
<div className='search-cont'> |
||||
<dl> |
||||
<dt> |
||||
<div className='search-box'> |
||||
<div className='search-list-ti'>신청일</div> |
||||
<div className='search-list'> |
||||
<div className='search-list-cont'> |
||||
<Row> |
||||
<Col className='list-input' xl='4' md='6' sm='12'> |
||||
<div className='d-flex align-items-center calendar-flat'> |
||||
<Flatpickr |
||||
id='searchDate' |
||||
value={[ |
||||
props.params.stDate, |
||||
props.params.endDate |
||||
]} |
||||
options={{ |
||||
mode: 'range', |
||||
defaultDate: [ |
||||
props.params.stDate, |
||||
props.params.endDate |
||||
] |
||||
}} |
||||
onChange={val => |
||||
props.handlerInput('searchDate', val) |
||||
} |
||||
onKeyPress={props.onKeyPress} |
||||
className='form-control flat-picker bg-transparent border-0 shadow-none' |
||||
/> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
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 ( |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col> |
||||
<div |
||||
className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row'> |
||||
<div> |
||||
<h4>검색조건</h4> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</dt> |
||||
|
||||
<dt> |
||||
<div className='search-box'> |
||||
<div className='search-list-ti'>승인여부</div> |
||||
<div className='search-list'> |
||||
{/* <div className="search-list-cont"> |
||||
<Input size='sm'/> |
||||
</div> */} |
||||
<div className='search-list-cont'> |
||||
<CustomInput |
||||
inline |
||||
type='checkbox' |
||||
id='exampleCustomCheckbox' |
||||
label='전체' |
||||
checked={isCheck.all} |
||||
onClick={() => |
||||
setIsCheckBox({ |
||||
all: !isCheck.all, |
||||
yes: !isCheck.all, |
||||
no: !isCheck.all |
||||
}) |
||||
} |
||||
/> |
||||
<CustomInput |
||||
inline |
||||
type='checkbox' |
||||
id='exampleCustomCheckbox2' |
||||
label='승인' |
||||
checked={isCheck.yes || isCheck.all} |
||||
onClick={() => |
||||
setIsCheckBox({ |
||||
all: false, |
||||
yes: !isCheck.yes |
||||
}) |
||||
} |
||||
/> |
||||
<CustomInput |
||||
inline |
||||
type='checkbox' |
||||
id='exampleCustomCheckbox3' |
||||
label='미승인' |
||||
checked={isCheck.no || isCheck.all} |
||||
onClick={() => |
||||
setIsCheckBox({ |
||||
all: false, |
||||
no: !isCheck.no |
||||
}) |
||||
} |
||||
/> |
||||
<div className='d-flex align-items-center'> |
||||
<Button.Ripple |
||||
color='primary' |
||||
size='sm' |
||||
onClick={handleClickSearch} |
||||
> |
||||
<Search size={16}/> |
||||
검색 |
||||
</Button.Ripple> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</dt> |
||||
</dl> |
||||
</div> |
||||
</CardBody> |
||||
</Card> |
||||
|
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
) |
||||
<Card> |
||||
<CardBody className='pal-card-body'> |
||||
<div className='search-cont'> |
||||
<dl> |
||||
<dt> |
||||
<div className='search-box'> |
||||
<div className='search-list-ti'>신청일</div> |
||||
<div className='search-list'> |
||||
<div className='search-list-cont'> |
||||
<Row> |
||||
<Col className='list-input' xl='4' md='6' sm='12'> |
||||
<div className='d-flex align-items-center calendar-flat'> |
||||
<Flatpickr |
||||
id='searchDate' |
||||
value={[ |
||||
schFltStDt, |
||||
schFltEndDt |
||||
]} |
||||
options={{ |
||||
mode: 'range', |
||||
// defaultDate: [
|
||||
// props.params.stDate,
|
||||
// props.params.endDate
|
||||
// ]
|
||||
}} |
||||
onChange={handleChangeInput} |
||||
className='form-control flat-picker bg-transparent border-0 shadow-none' |
||||
/> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</dt> |
||||
|
||||
<dt> |
||||
<div className='search-box'> |
||||
<div className='search-list-ti'>승인여부</div> |
||||
<div className='search-list'> |
||||
<div className='search-list-cont'> |
||||
<CustomInput |
||||
inline |
||||
type='checkbox' |
||||
id='exampleCustomCheckbox' |
||||
label='전체' |
||||
name="aprvlYn" |
||||
value="A" |
||||
// checked={true}
|
||||
checked={checkState.all} |
||||
onChange={handleChangeCheckbox} |
||||
/> |
||||
<CustomInput |
||||
inline |
||||
type='checkbox' |
||||
id='exampleCustomCheckbox2' |
||||
label='승인' |
||||
name="aprvlYn" |
||||
value="Y" |
||||
checked={checkState.yes} |
||||
onChange={handleChangeCheckbox} |
||||
/> |
||||
<CustomInput |
||||
inline |
||||
type='checkbox' |
||||
id='exampleCustomCheckbox3' |
||||
label='미승인' |
||||
name="aprvlYn" |
||||
value="N" |
||||
checked={checkState.no} |
||||
onChange={handleChangeCheckbox} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</dt> |
||||
</dl> |
||||
</div> |
||||
</CardBody> |
||||
</Card> |
||||
|
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default FlightPlanSearch; |
||||
export default FlightPlanSearch; |
||||
|
@ -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 = '<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) { |
||||
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( |
||||
<> |
||||
<div style={{ position: 'relative' }}> |
||||
<ul className="measure-control"> |
||||
<li> |
||||
<CustomInput |
||||
id='line' |
||||
type='image' |
||||
className='control-btn' |
||||
src='http://static.naver.net/maps/mantle/drawing/1x/polyline.png' |
||||
/> |
||||
<CustomInput |
||||
id='polygon' |
||||
type='image' |
||||
className='control-btn' |
||||
src='http://static.naver.net/maps/mantle/drawing/1x/polygon.png' |
||||
/> |
||||
<CustomInput |
||||
id='circle' |
||||
type='image' |
||||
className='control-btn' |
||||
src='http://static.naver.net/maps/mantle/drawing/1x/ellipse.png' |
||||
/> |
||||
<CustomInput |
||||
id='rectangle' |
||||
type='image' |
||||
className='control-btn' |
||||
src='http://static.naver.net/maps/mantle/drawing/1x/rectangle.png' |
||||
/> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</> |
||||
) |
||||
} |
@ -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 = '<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: 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 ( |
||||
<> |
||||
</> |
||||
); |
||||
}; |
@ -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 ( |
||||
<FlightPlanArcrft |
||||
arcrftList = {arcrftList} |
||||
handleSelectArcrft={handleSelectArcrft} |
||||
/> |
||||
) |
||||
} |
||||
|
||||
export default FlightPlanArcrftContainer; |
@ -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 ( |
||||
<Row> |
||||
<Col> |
||||
<FlightPlanAreaDetailForm |
||||
handleClose={handleClose} |
||||
handleSave={handleSave} |
||||
handleChange={handleChange} |
||||
handleBufferList={handleBufferList} |
||||
areaCoordList={areaCoordList} |
||||
data={areaDetail} |
||||
/> |
||||
</Col> |
||||
</Row> |
||||
|
||||
) |
||||
} |
||||
|
||||
export default FlightPlanAreaDetailContainer; |
@ -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 ( |
||||
// <CustomMainLayout title={"비행 계획 관리"}>
|
||||
<CustomMainLayout title={"비행계획서 신청"}> |
||||
<FlightPlanSearch
|
||||
params={times} |
||||
/> |
||||
<FlightPlanGrid
|
||||
moveFlightPlan={moveFlightPlan} |
||||
/> |
||||
<div className='pal-card-box'> |
||||
<Row> |
||||
<Col sm='4'> |
||||
<FlightPlanGroupGrid |
||||
data = {joinList} |
||||
count = {joinListCount} |
||||
selectGroup = {selectGroup} |
||||
handleGroupSelect = {handleGroupSelect} |
||||
handlerGroupCancel = {handlerGroupCancel} |
||||
/> |
||||
</Col> |
||||
<Col sm='8'> |
||||
{selectGroup.cstmrSno !== 0 ? ( |
||||
<> |
||||
<FlightPlanSearch |
||||
searchData={searchData} |
||||
handleChangeSearchData={handleChangeSearchData} |
||||
handleSearch={handleSearch} |
||||
/> |
||||
<FlightPlanGrid |
||||
movePage={moveFlightPlanDetailPage} |
||||
planListData={planListData} |
||||
columns={columns} |
||||
handleMoveDetail={handleMoveDetail} |
||||
/> |
||||
</> |
||||
) : ( |
||||
<div className='no-dataTable'> |
||||
나의 그룹 목록에서 상세보기를 클릭하세요. |
||||
</div> |
||||
)} |
||||
|
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</CustomMainLayout> |
||||
) |
||||
} |
||||
|
||||
export default FlightPlanContainer; |
||||
export default FlightPlanContainer; |
||||
|
@ -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 ( |
||||
<CustomDetailLayout title={"비행 계획 신청서"}> |
||||
<FlightPlanForm |
||||
openModal={openModal} |
||||
areaInfo={areaInfo} |
||||
/> |
||||
<FlightPlanAreaModal
|
||||
modal={modal} |
||||
save={saveFlightPlanArea} |
||||
setModal={setModal} |
||||
/> |
||||
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}
|
||||
/> |
||||
{/*<FlightPlanAreaModal*/} |
||||
{/* modal={modal}*/} |
||||
{/* save={saveFlightPlanArea}*/} |
||||
{/* setModal={setModal}*/} |
||||
{/*/>*/} |
||||
</CustomDetailLayout> |
||||
) |
||||
}; |
||||
|
||||
} |
||||
|
||||
export default FlightPlanDetailContainer;
|
||||
export default FlightPlanDetailContainer; |
||||
|
@ -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 ( |
||||
<FlightPlanPilot
|
||||
pilotList = {pilotList} |
||||
handleSelectPilot={handleSelectPilot} |
||||
/> |
||||
) |
||||
} |
||||
|
||||
export default FlightPlanPilotContainer; |
@ -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 |
||||
)<FlightAreaData, { data: FlightAreaData }, AxiosError>(); |
||||
|
||||
export const FLIGHT_PLAN_AREA = createAsyncAction( |
||||
FLIGHT_PLAN_AREA_REQUEST, |
||||
FLIGHT_PLAN_AREA_SUCCESS, |
||||
FLIGHT_PLAN_AREA_FAILURE |
||||
)<FlightPlanArea, { data: FlightPlanArea }, AxiosError>(); |
||||
// 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 |
||||
)<PublicAreaData, { data: PublicAreaData }, AxiosError>(); |
||||
|
||||
// export const FLIGHT_PLAN_AREA = createAsyncAction(
|
||||
// FLIGHT_PLAN_AREA_REQUEST,
|
||||
// FLIGHT_PLAN_AREA_SUCCESS,
|
||||
// FLIGHT_PLAN_AREA_FAILURE
|
||||
// )<FlightPlanArea, { data: FlightPlanArea }, AxiosError>();
|
||||
|
||||
// 목록
|
||||
export const FLIGHT_PLAN_LIST = createAsyncAction( |
||||
FLIGHT_PLAN_LIST_REQUEST, |
||||
FLIGHT_PLAN_LIST_SUCCESS, |
||||
FLIGHT_PLAN_LIST_FAILURE |
||||
)<FlightPlanListRqData, [FlightPlanData], AxiosError>(); |
||||
|
||||
// 상세
|
||||
export const FLIGHT_PLAN_DETAIL = createAsyncAction( |
||||
FLIGHT_PLAN_DETAIL_REQUEST, |
||||
FLIGHT_PLAN_DETAIL_SUCCESS, |
||||
FLIGHT_PLAN_DETAIL_FAILURE |
||||
)<number, FlightPlanData, AxiosError>(); |
||||
// 상세 초기화
|
||||
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 |
||||
)<FlightPlanData, string, AxiosError>(); |
||||
|
||||
// 수정
|
||||
export const FLIGHT_PLAN_UPDATE = createAsyncAction( |
||||
FLIGHT_PLAN_UPDATE_REQUEST, |
||||
FLIGHT_PLAN_UPDATE_SUCCESS, |
||||
FLIGHT_PLAN_UPDATE_FAILURE |
||||
)<FlightPlanData, string, AxiosError>(); |
||||
|
||||
// 삭제
|
||||
export const FLIGHT_PLAN_DELETE = createAsyncAction( |
||||
FLIGHT_PLAN_DELETE_REQUEST, |
||||
FLIGHT_PLAN_DELETE_SUCCESS, |
||||
FLIGHT_PLAN_DELETE_FAILURE |
||||
)<number, string, AxiosError>(); |
||||
|
||||
// 조종사 목록
|
||||
export const FLIGHT_PLAN_PILOT_LIST = createAsyncAction( |
||||
FLIGHT_PLAN_PILOT_LIST_REQUEST, |
||||
FLIGHT_PLAN_PILOT_LIST_SUCCESS, |
||||
FLIGHT_PLAN_PILOT_LIST_FAILURE |
||||
)<string, FlightPlanPilotDataList, AxiosError>(); |
||||
|
||||
// 조종사 선택
|
||||
export const PILOT_SELECT = createAction(FLIGHT_PLAN_PILOT_SELECT)<PilotSelectData>(); |
||||
|
||||
// 기체 목록
|
||||
export const FLIGHT_PLAN_ARCRFT_LIST = createAsyncAction( |
||||
FLIGHT_PLAN_ARCRFT_LIST_REQUEST, |
||||
FLIGHT_PLAN_ARCRFT_LIST_SUCCESS, |
||||
FLIGHT_PLAN_ARCRFT_LIST_FAILURE |
||||
)<string, FlightPlanArcrftDataList, AxiosError>(); |
||||
|
||||
// 조종사 선택
|
||||
export const ARCRFT_SELECT = createAction(FLIGHT_PLAN_ARCRFT_SELECT)<FlightPlanArcrftData>(); |
||||
|
||||
// 조종사, 기체 선택 초기화
|
||||
export const PILOT_ARCRFT_SELECT_INIT = createAction(PILOT_ARCRFT_SELECT_INITIAL)(); |
||||
|
||||
// 비행 구역 좌표 저장 (스텝2 데이터 공유)
|
||||
export const AREA_COORDINATE_LIST_SAVE = createAction(AREA_COORDINATE_LIST)<FlightPlanAreaDataList>(); |
||||
|
||||
// 비행 구역 상세 저장
|
||||
export const AREA_DETAIL_LIST_SAVE = createAction(AREA_DETAIL_LIST)<FlightPlanAreaDataList>(); |
||||
|
||||
// 비행 계획서 그룹 선택
|
||||
export const FLIGHT_PLAN_GROUP_SELECT = createAction(ROUP_SELECT)<SelectGroupData>(); |
||||
|
||||
// 비행 구역 상세 값 초기화
|
||||
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 |
||||
)<FlightPlanAreaDataList, FlightPlanAreaDataList, AxiosError>(); |
||||
|
||||
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<typeof actions>; |
||||
export type FlightAction = ActionType<typeof actions>; |
||||
|
@ -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`); |
||||
} |
||||
} |
||||
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; |
||||
} |
||||
} |
||||
|
@ -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<FlightPlanAreaData> {}; |
||||
|
||||
export interface FlightPlanAreaCoordData { |
||||
planAreaCoordSno?: number, |
||||
planAreaSno?: number, |
||||
lat: number, |
||||
lon: number, |
||||
createUserId?: string, |
||||
createDt?: string |
||||
// docState: string
|
||||
} |
||||
|
||||
export interface FlightPlanAreaCoordDataList extends Array<FlightPlanAreaCoordData> {}; |
||||
|
||||
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<FlightPlanPilotData> {}; |
||||
|
||||
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<FlightPlanArcrftData> {}; |
||||
|
||||
// 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
|
||||
}; |
||||
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: '' |
||||
}] |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue