Browse Source

feat/운항과 관제과 로직 변경

master
sanguu516 1 month ago
parent
commit
8f2ddc437f
  1. 105
      src/components/flight/ControlApprovalsTable.js
  2. 68
      src/components/flight/NewFlightApprovalsReport.js
  3. 102
      src/components/flight/OperationApprovalsTable.js
  4. 79
      src/components/flight/OperationCheckBoxModal.js

105
src/components/flight/ControlApprovalsTable.js

@ -88,6 +88,7 @@ export default function ControlApprovalsTable(props) {
dtl: record.dtl,
era: record.era,
rm: record.rm,
reqRadius: record.reqRadius,
...record
});
setEditingKey(record.key);
@ -112,7 +113,8 @@ export default function ControlApprovalsTable(props) {
fltElev: row.fltElev || '',
dtl: row.dtl || '',
era: row.era || '',
rm: row.rm || ''
rm: row.rm || '',
reqRadius: row.reqRadius || ''
}
])
);
@ -544,12 +546,14 @@ export default function ControlApprovalsTable(props) {
width: '130px',
render: (areaList, record) =>
areaList.length <= 1 ? (
areaList[0].reviewedType === 'U' ? (
'검토불필요'
) : areaList[0].reviewedType === 'R' ? (
areaList[0].reviewedType === 'R' ? (
'검토완료'
) : areaList[0].reviewedType === 'W' ? (
'검토대기'
) : areaList[0].reviewedType === 'C' ? (
'검토요청취소'
) : areaList[0].reviewedType === 'Q' ? (
'검토요청'
) : areaList[0].reviewedType === 'A' ? (
'검토재요청'
) : (
<Button color='flat-dark' onClick={() => handleIsModal(record)}>
<>
@ -812,12 +816,14 @@ export default function ControlApprovalsTable(props) {
align: 'center',
width: '130px',
render: (text, record) => {
return text === 'U' ? (
'검토불필요'
) : text === 'R' ? (
return text === 'R' ? (
'검토완료'
) : text === 'W' ? (
'검토대기'
) : text === 'C' ? (
'검토요청취소'
) : text === 'Q' ? (
'검토요청'
) : text === 'A' ? (
'검토재요청'
) : (
<Button color='flat-dark' onClick={() => handleIsModal(record)}>
<>
@ -1212,40 +1218,58 @@ export default function ControlApprovalsTable(props) {
}
};
// 체크박스 업데이트 함수
const handleCheckbox = async () => {
// 체크박스 핸들러
const handleCheckbox = async type => {
if (checkList.length === 0) {
return handlerErrorModal(
'검토 실패',
'검토할 항목을 선택해주세요.',
false
);
return handlerErrorModal('검토 실패', '검토 항목을 선택해주세요.', false);
}
const planAreaSnoList = [
...new Set(
checkList
.filter(item => item.startsWith('child_'))
.map(item => item.split('_').pop())
)
];
const res = laancAprvList.flatMap(item =>
item.areaList.filter(area =>
planAreaSnoList.includes(area.planAreaSno.toString())
)
);
// 검토 완료, 요청 반려 조건 확인
const checkCondition =
type === 'R'
? item => item.reviewedType !== 'Q'
: item => item.reviewedType !== 'R';
// 에러 메시지
const errorMessages = {
R: ['검토 완료', '확인결과 대기인 신청건만 검토완료 요청이 가능합니다.'],
C: ['요청 반려', '확인결과 대기인 신청건만 요청반려 요청이 가능합니다.']
};
// 검토 완료, 요청 반려 조건 확인
if (res.some(checkCondition)) {
return handlerErrorModal(...errorMessages[type]);
}
// 요청 성공 호출
try {
const planAreaSnoList = [
...new Set(
checkList
.filter(item => item.startsWith('child_')) // 'child_'로 시작하는 항목 필터링
.map(item => item.split('_').pop()) // 마지막 언더바 이후의 숫자 추출
)
];
dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: 'R' })
).then(() => {
props.handlerSearch(
props.filterId,
{
startDate: props.startDate,
endDate: props.endDate
},
props.filterArea
);
});
await dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: type })
);
props.handlerSearch(
props.filterId,
{ startDate: props.startDate, endDate: props.endDate },
props.filterArea
);
setCheckList([]);
} catch (error) {
return handlerErrorModal(
'검토 실패',
'검토를 실패하였습니다. 다시 시도해주세요.',
'검토 요청을 실패하였습니다. 다시 시도해주세요.',
false
);
}
@ -1274,9 +1298,12 @@ export default function ControlApprovalsTable(props) {
</span>
</div>
<div className='download'>
<Button color='primary' size='sm' onClick={() => handleCheckbox()}>
<Button color='primary' size='sm' onClick={() => handleCheckbox('R')}>
검토 완료
</Button>
<Button color='primary' size='sm' onClick={() => handleCheckbox('C')}>
요청 반려
</Button>
<Button
color='primary'
size='sm'

68
src/components/flight/NewFlightApprovalsReport.js

@ -1,6 +1,14 @@
import { useState, useEffect, useRef } from 'react';
import Flatpickr from 'react-flatpickr';
import { Button, Input, CustomInput, Col, Row, FormGroup, Label } from '@component/ui';
import {
Button,
Input,
CustomInput,
Col,
Row,
FormGroup,
Label
} from '@component/ui';
import { Search, Calendar } from 'react-feather';
import dayjs from 'dayjs';
import {
@ -57,24 +65,24 @@ export default function NewFlightApprovalsReport(props) {
<FormGroup>
<Label for='searchDate'>신청일자</Label>
<div className='calendar-flat'>
<Flatpickr
ref={flatPickerRef}
placeholder='날짜를 선택해주세요'
id='searchDate'
options={{
mode: 'range',
defaultDate: [searchDate.startDate, searchDate.endDate]
}}
onChange={date => {
setSearchDate({
startDate: dayjs(date[0]).format('YYYY-MM-DD'),
endDate: dayjs(date[1]).format('YYYY-MM-DD')
});
}}
className='form-control flat-picker bg-transparent border-0 shadow-none'
/>
<Calendar size={14} />
</div>
<Flatpickr
ref={flatPickerRef}
placeholder='날짜를 선택해주세요'
id='searchDate'
options={{
mode: 'range',
defaultDate: [searchDate.startDate, searchDate.endDate]
}}
onChange={date => {
setSearchDate({
startDate: dayjs(date[0]).format('YYYY-MM-DD'),
endDate: dayjs(date[1]).format('YYYY-MM-DD')
});
}}
className='form-control flat-picker bg-transparent border-0 shadow-none'
/>
<Calendar size={14} />
</div>
</FormGroup>
</div>
</div>
@ -82,22 +90,22 @@ export default function NewFlightApprovalsReport(props) {
<div className='list-input'>
<div className='layer-content'>
<FormGroup>
<Label for=''>신청번호</Label>
<Input
type='text'
bsSize='sm'
placeholder='신청번호 또는 검토결과를 입력해주세요.'
value={props.filterId}
onChange={e => props.setFilterId(e.target.value)}
onKeyPress={handleKeyDown}
/>
</FormGroup>
<Label for='filterId'>신청번호</Label>
<Input
type='text'
bsSize='sm'
placeholder='신청번호 또는 검토결과를 입력해주세요.'
value={props.filterId}
onChange={e => props.setFilterId(e.target.value)}
onKeyPress={handleKeyDown}
/>
</FormGroup>
</div>
</div>
<div className='list-input'>
<div className='layer-content'>
<FormGroup>
<FormGroup>
<Label for='reviewedType'>검토결과</Label>
<CustomInput
type='select'

102
src/components/flight/OperationApprovalsTable.js

@ -104,6 +104,8 @@ export default function OperationApprovalsTable(props) {
text = '검토완료';
} else if (type === 'W') {
text = '검토대기';
} else if (type === 'Q') {
text = '검토요청';
} else if (type === 'C') {
text = '검토취소';
}
@ -498,6 +500,8 @@ export default function OperationApprovalsTable(props) {
counts.unapproved += 1;
} else if (item.reviewedType === 'R') {
counts.reviewed += 1;
} else if (item.reviewedType === 'Q') {
counts.request += 1;
} else if (item.reviewedType === 'W') {
counts.wait += 1;
} else if (item.reviewedType === 'C') {
@ -505,7 +509,7 @@ export default function OperationApprovalsTable(props) {
}
return counts;
},
{ reviewed: 0, wait: 0, cancel: 0, unapproved: 0 }
{ reviewed: 0, wait: 0, cancel: 0, unapproved: 0, request: 0 }
);
return (
@ -514,7 +518,10 @@ export default function OperationApprovalsTable(props) {
<>
검토완료: {approvalCounts.reviewed} <br />
검토대기:{approvalCounts.wait} <br />
검토취소:
검토요청:
{approvalCounts.request}
<br />
검토요청취소:
{approvalCounts.cancel}
<br />
검토불필요:
@ -765,7 +772,9 @@ export default function OperationApprovalsTable(props) {
: text === 'R'
? '검토완료'
: text === 'C'
? '검토취소'
? '검토요청취소'
: text === 'Q'
? '검토요청'
: '검토대기';
}
},
@ -944,6 +953,7 @@ export default function OperationApprovalsTable(props) {
dtl: record.dtl,
era: record.era,
rm: record.rm,
reqRadius: record.reqRadius,
...record
});
setEditingKey(record.key);
@ -968,7 +978,8 @@ export default function OperationApprovalsTable(props) {
fltElev: row.fltElev || '',
dtl: row.dtl || '',
era: row.era || '',
rm: row.rm || ''
rm: row.rm || '',
reqRadius: row.reqRadius || ''
}
])
);
@ -1211,64 +1222,54 @@ export default function OperationApprovalsTable(props) {
// 체크박스 업데이트 함수
const handleCheckbox = async type => {
if (checkList.length === 0) {
return handlerErrorModal(
type === 'R' ? '재 요청 요청 실패' : '검토 요청 실패',
type === 'R'
? '재 요청 항목을 선택해주세요.'
: '검토 항목을 선택해주세요.',
false
);
return handlerErrorModal('검토 실패', '검토 항목을 선택해주세요.', false);
}
const planAreaSnoList = [
...new Set(
checkList
.filter(item => item.startsWith('child_')) // 'child_'로 시작하는 항목 필터링
.map(item => item.split('_').pop()) // 마지막 언더바 이후의 숫자 추출
.filter(item => item.startsWith('child_'))
.map(item => item.split('_').pop())
)
];
// res에서 planAreaSnoList에 해당하는 데이터만 추출 2차원 배열 말고 1차원 배열로 추출
const res = laancAprvList.flatMap(item =>
item.areaList.filter(area =>
planAreaSnoList.includes(area.planAreaSno.toString())
)
);
if (type === 'A') {
const check = !res.some(item => item.approvalCd !== 'R');
if (!check) {
return handlerErrorModal(
'재 요청 요청 실패',
'검토결과 완료인 신청건만 재 요청이 가능합니다.'
);
} else {
// 검토 요청, 재 요청 조건
const checkCondition = {
A: item => item.reviewedType !== 'R',
Q: item => item.reviewedType !== 'W'
};
// 요청 실패 시 에러 메시지
const errorMessages = {
A: [
'재 요청 요청 실패',
'검토결과 완료인 신청건만 재 요청이 가능합니다.'
],
Q: ['검토 요청 실패', '검토결과 대기인 신청건만 요청이 가능합니다.']
};
// 요청 성공 시 액션 핸들러
const actionHandlers = {
A: () => {
setCheckData(res);
setIsCheckBoxModal(true);
}
} else if (type === 'R') {
const check = res.some(
item => item.approvalCd !== 'R' && item.approvalCd !== 'C'
);
if (!check) {
return handlerErrorModal(
'검토 요청 실패',
'검토결과 대기인 신청건만 요청이 가능합니다.'
);
} else {
},
Q: async () => {
try {
dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: 'R' })
).then(() => {
props.handlerSearch(
props.filterId,
{
startDate: props.startDate,
endDate: props.endDate
},
props.filterArea
);
});
await dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: 'Q' })
);
props.handlerSearch(
props.filterId,
{ startDate: props.startDate, endDate: props.endDate },
props.filterArea
);
setCheckList([]);
} catch (error) {
return handlerErrorModal(
@ -1278,8 +1279,17 @@ export default function OperationApprovalsTable(props) {
);
}
}
};
// 요청 실패 시 에러 메시지 핸들러
if (res.some(checkCondition[type])) {
return handlerErrorModal(...errorMessages[type]);
}
// 요청 성공 시 액션 핸들러 실행
await actionHandlers[type]();
};
return (
<div className='layer-content'>
<div className='layer-ti'>
@ -1324,7 +1334,7 @@ export default function OperationApprovalsTable(props) {
</span>
</div>
<div className='download'>
<Button color='primary' size='sm' onClick={() => handleCheckbox('R')}>
<Button color='primary' size='sm' onClick={() => handleCheckbox('Q')}>
검토 요청
</Button>
<Button color='primary' size='sm' onClick={() => handleCheckbox('A')}>

79
src/components/flight/OperationCheckBoxModal.js

@ -100,45 +100,52 @@ export default function OperationCheckBoxModal(props) {
};
const handleConfirm = async () => {
if (tempDataSource.filter(item => !item.reviewedReason).length > 0) {
return props.handlerErrorModal(
'필수값 입력 오류',
'재검토 항목을 입력 해 주세요.',
false
try {
// 필수값 체크
if (tempDataSource.filter(item => !item.reviewedReason).length > 0) {
return props.handlerErrorModal(
'필수값 입력 오류',
'재검토 항목을 입력 해 주세요.',
false
);
}
const planAreaSnoList = tempDataSource.map(item => item.planAreaSno);
// 첫 번째 비동기 요청 - 완료될 때까지 기다립니다.
const updateRes = await dispatch(updateLaancAprv(tempDataSource));
// 첫 번째 요청이 성공적으로 완료되었는지 확인
if (updateRes.meta.requestStatus !== 'fulfilled') {
throw new Error('요청 처리에 실패했습니다.');
}
// 두 번째 비동기 요청 - 첫 번째 요청이 성공했을 때만 실행됩니다.
await dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: 'A' })
);
}
const planAreaSnoList = tempDataSource.map(item => item.planAreaSno);
dispatch(updateLaancAprv(tempDataSource))
.then(updateRes => {
if (updateRes.meta.requestStatus === 'fulfilled') {
return dispatch(
updateLaancAprvReview({ planAreaSnoList, reviewedType: 'A' })
);
} else {
throw new Error('요청 처리에 실패했습니다.');
}
})
.then(() => {
props.handlerSearch(
props.filterId,
{
startDate: props.startDate,
endDate: props.endDate
},
props.filterArea
);
props.handlerErrorModal('성공', '재검토 요청이 완료되었습니다.', false);
props.setIsCheckBoxModal(false);
})
.catch(err => {
props.handlerErrorModal(
'실패',
'재검토 요청을 실패하였습니다. 다시 시도해주세요.',
true
);
});
// 두 요청이 모두 성공했을 때 후속 작업
props.handlerSearch(
props.filterId,
{
startDate: props.startDate,
endDate: props.endDate
},
props.filterArea
);
props.handlerErrorModal('성공', '재검토 요청이 완료되었습니다.', false);
props.setIsCheckBoxModal(false);
} catch (err) {
// 에러 발생 시 처리
props.handlerErrorModal(
'실패',
'재검토 요청을 실패하였습니다. 다시 시도해주세요.',
true
);
}
};
const defaultColumns = [
{
title: (

Loading…
Cancel
Save