390 lines
12 KiB
JavaScript
390 lines
12 KiB
JavaScript
import React, { useState, Fragment, useRef } from 'react';
|
|
import { useRecoilValue } from 'recoil';
|
|
import { useTranslation } from 'react-i18next';
|
|
import 'react-datepicker/dist/react-datepicker.css';
|
|
|
|
import {
|
|
BattleConfigView,
|
|
BattleEventDelete,
|
|
BattleEventDetailView, BattleEventStop,
|
|
BattleEventView,
|
|
BattleRewardView, GameModeView,
|
|
} from '../../apis/Battle';
|
|
|
|
import { authList } from '../../store/authList';
|
|
import {
|
|
authType,
|
|
modalTypes,
|
|
landAuctionStatusType,
|
|
landAuctionStatus,
|
|
landSize,
|
|
caliumStatus, commonStatus,
|
|
} from '../../assets/data';
|
|
import { Title, FormWrapper, TableStyle, TableWrapper} from '../../styles/Components';
|
|
import {
|
|
CheckBox,
|
|
Button,
|
|
DynamicModal,
|
|
Pagination,
|
|
ViewTableInfo, ExcelDownButton,
|
|
} from '../../components/common';
|
|
import { convertKTC, convertKTCDate, convertUTC, timeDiffMinute } from '../../utils';
|
|
import { BattleEventModal } from '../../components/ServiceManage';
|
|
import {
|
|
INITIAL_PAGE_SIZE,
|
|
INITIAL_PAGE_LIMIT,
|
|
BATTLE_EVENT_OPERATION_TIME_WAIT_SECONDS,
|
|
} from '../../assets/data/adminConstants';
|
|
import { useDataFetch, useModal, useTable, withAuth } from '../../hooks/hook';
|
|
import { StatusWapper, StatusLabel } from '../../styles/ModuleComponents';
|
|
import { battleEventStatus, battleRepeatType } from '../../assets/data/options';
|
|
import BattleEventSearchBar, {
|
|
useBattleEventSearch,
|
|
} from '../../components/searchBar/BattleEventSearchBar';
|
|
import { getDateOnly, getTimeOnly, secondToMinutes } from '../../utils/date';
|
|
import { alertTypes, battleEventStatusType } from '../../assets/data/types';
|
|
import { useAlert } from '../../context/AlertProvider';
|
|
import { useLoading } from '../../context/LoadingProvider';
|
|
import LogDetailModal from '../../components/common/modal/LogDetailModal';
|
|
import { historyTables } from '../../assets/data/data';
|
|
import { LogHistory } from '../../apis';
|
|
import { AnimatedPageWrapper } from '../../components/common/Layout';
|
|
|
|
const BattleEvent = () => {
|
|
const token = sessionStorage.getItem('token');
|
|
const userInfo = useRecoilValue(authList);
|
|
const { t } = useTranslation();
|
|
const tableRef = useRef(null);
|
|
const { showToast, showModal } = useAlert();
|
|
const {withLoading} = useLoading();
|
|
|
|
const [detailData, setDetailData] = useState({});
|
|
const [historyData, setHistoryData] = useState({});
|
|
|
|
const {
|
|
modalState,
|
|
handleModalView,
|
|
handleModalClose
|
|
} = useModal({
|
|
detail: 'hidden',
|
|
history: 'hidden'
|
|
});
|
|
const [modalType, setModalType] = useState('regist');
|
|
|
|
const {
|
|
searchParams,
|
|
data: dataList,
|
|
handleSearch,
|
|
handleReset,
|
|
handlePageChange,
|
|
handlePageSizeChange,
|
|
handleOrderByChange,
|
|
updateSearchParams
|
|
} = useBattleEventSearch(token, INITIAL_PAGE_SIZE);
|
|
|
|
const {
|
|
selectedRows,
|
|
handleSelectRow,
|
|
isRowSelected
|
|
} = useTable(dataList?.event_list || [], {mode: 'single'});
|
|
|
|
const {
|
|
data: battleConfigData
|
|
} = useDataFetch(() => BattleConfigView(token), [token]);
|
|
|
|
const {
|
|
data: battleRewardData
|
|
} = useDataFetch(() => BattleRewardView(token), [token]);
|
|
|
|
const {
|
|
data: gameModeData
|
|
} = useDataFetch(() => GameModeView(token), [token]);
|
|
|
|
const endTime = (start_dt, operation_time) =>{
|
|
const startDate = new Date(start_dt);
|
|
|
|
startDate.setSeconds(startDate.getSeconds() + operation_time + BATTLE_EVENT_OPERATION_TIME_WAIT_SECONDS);
|
|
|
|
return startDate;
|
|
}
|
|
|
|
const isStopMinutes = (time) => {
|
|
const givenDate = new Date(time);
|
|
|
|
const currentDate = convertUTC(new Date());
|
|
|
|
// 시간만 비교하기 위해 년,월,일을 동일하게 설정
|
|
givenDate.setFullYear(currentDate.getFullYear());
|
|
givenDate.setMonth(currentDate.getMonth());
|
|
givenDate.setDate(currentDate.getDate());
|
|
|
|
// 두 시간의 차이를 밀리초로 계산
|
|
const timeDifference = currentDate.getTime() - givenDate.getTime();
|
|
|
|
// 밀리초로 변환
|
|
const fiveMinutesInMs = 5 * 60 * 1000;
|
|
|
|
return timeDifference < 0 && Math.abs(timeDifference) <= fiveMinutesInMs;
|
|
}
|
|
|
|
const isRunningTime = (time, operation_time) =>{
|
|
const startDate = new Date(time);
|
|
const endDate = new Date(startDate.getTime() + (operation_time * 1000));
|
|
const currentDate = convertUTC(new Date());
|
|
|
|
return currentDate >= startDate && currentDate <= endDate;
|
|
}
|
|
|
|
const handleModalSubmit = async (type, param = null) => {
|
|
switch (type) {
|
|
case "history":
|
|
const params = {};
|
|
params.db_type = "MYSQL"
|
|
params.sql_id = param.id;
|
|
params.table_name = historyTables.battleEvent
|
|
|
|
await LogHistory(token, params).then(data => {
|
|
setHistoryData(data);
|
|
handleModalView('history');
|
|
});
|
|
break;
|
|
case "regist":
|
|
setModalType('regist');
|
|
handleModalView('detail');
|
|
break;
|
|
case "detail":
|
|
await BattleEventDetailView(token, param).then(data => {
|
|
setDetailData(data.event_detail);
|
|
setModalType('modify');
|
|
handleModalView('detail');
|
|
});
|
|
break;
|
|
case "delete":
|
|
const date_check = selectedRows.every(row => {
|
|
const timeDiff = timeDiffMinute(convertKTC(row.auction_start_dt), (new Date));
|
|
return timeDiff < 3;
|
|
});
|
|
if(date_check){
|
|
showToast('LAND_AUCTION_DELETE_DATE_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
if(selectedRows[0].status === landAuctionStatusType.auction_start || selectedRows[0].status === landAuctionStatusType.stl_end){
|
|
showToast('LAND_AUCTION_DELETE_STATUS_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
showModal('BATTLE_EVENT_SELECT_DELETE', {
|
|
type: alertTypes.confirm,
|
|
onConfirm: () => handleModalSubmit('deleteConfirm')
|
|
});
|
|
break;
|
|
|
|
case "stop":
|
|
const select_item = selectedRows[0];
|
|
if(select_item.status === battleEventStatusType.running){
|
|
showToast('BATTLE_EVENT_STATUS_RUNNING_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
const isStopTimeCheck = isStopMinutes(select_item.event_start_dt);
|
|
if(isStopTimeCheck){
|
|
showToast('BATTLE_EVENT_STOP_5MINUTES_DATE_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
if(isRunningTime(select_item.event_start_dt, select_item.event_operation_time)){
|
|
showToast('BATTLE_EVENT_STATUS_RUNNING_WARNING', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
|
|
showModal('BATTLE_EVENT_SELECT_STOP', {
|
|
type: alertTypes.confirm,
|
|
onConfirm: () => handleModalSubmit('stopConfirm')
|
|
});
|
|
break;
|
|
|
|
case "stopConfirm":
|
|
const stop_item = selectedRows[0];
|
|
|
|
await withLoading(async () => {
|
|
return await BattleEventStop(token, stop_item.id, stop_item);
|
|
}).then(data => {
|
|
if(data.result === "SUCCESS") {
|
|
showToast('STOP_COMPLETE', {type: alertTypes.success});
|
|
handleSearch(updateSearchParams);
|
|
}else if(data.result === "ERROR_BATTLE_EVENT_STATUS_START_IMPOSSIBLE"){
|
|
showToast('BATTLE_EVENT_STATUS_RUNNING_WARNING', {type: alertTypes.error});
|
|
}else{
|
|
showToast('STOP_FAIL', {type: alertTypes.error});
|
|
}
|
|
}).catch(reason => {
|
|
showToast('API_FAIL', {type: alertTypes.error});
|
|
});
|
|
|
|
break;
|
|
|
|
case "deleteConfirm":
|
|
let list = [];
|
|
let isChecked = false;
|
|
|
|
selectedRows.map(data => {
|
|
// const row = dataList.list.find(row => row.id === Number(data.id));
|
|
// if(row.status !== commonStatus.wait) isChecked = true;
|
|
list.push({
|
|
id: data.id,
|
|
});
|
|
});
|
|
|
|
if(isChecked) {
|
|
showToast('LAND_AUCTION_WARNING_DELETE', {type: alertTypes.warning});
|
|
return;
|
|
}
|
|
|
|
await BattleEventDelete(token, list).then(data => {
|
|
|
|
if(data.result === "SUCCESS") {
|
|
showToast('DEL_COMPLETE', {type: alertTypes.success});
|
|
handleSearch(updateSearchParams);
|
|
}else if(data.result === "ERROR_AUCTION_STATUS_IMPOSSIBLE"){
|
|
showToast('LAND_AUCTION_ERROR_DELETE_STATUS', {type: alertTypes.error});
|
|
}else{
|
|
showToast('DELETE_FAIL', {type: alertTypes.error});
|
|
}
|
|
}).catch(reason => {
|
|
showToast('API_FAIL', {type: alertTypes.error});
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<AnimatedPageWrapper>
|
|
<Title>전투시스템 타임 스케줄러</Title>
|
|
<FormWrapper>
|
|
<BattleEventSearchBar
|
|
searchParams={searchParams}
|
|
onSearch={(newParams, executeSearch = true) => {
|
|
if (executeSearch) {
|
|
handleSearch(newParams);
|
|
} else {
|
|
updateSearchParams(newParams);
|
|
}
|
|
}}
|
|
onReset={handleReset}
|
|
configData={battleConfigData}
|
|
rewardData={battleRewardData}
|
|
gameModeData={gameModeData}
|
|
/>
|
|
</FormWrapper>
|
|
<ViewTableInfo total={dataList?.total} total_all={dataList?.total_all} handleOrderBy={handleOrderByChange} handlePageSize={handlePageSizeChange}>
|
|
<ExcelDownButton tableRef={tableRef} fileName={t('FILE_BATTLE_EVENT')} />
|
|
{/*{userInfo.auth_list?.some(auth => auth.id === authType.battleEventDelete) && (*/}
|
|
{/* <Button theme={selectedRows.length === 0 ? 'disable' : 'line'} text="이벤트 삭제" handleClick={() => handleModalSubmit('delete')} />*/}
|
|
{/*)}*/}
|
|
{userInfo.auth_list?.some(auth => auth.id === authType.battleEventDelete) && (
|
|
<Button theme={selectedRows.length === 0 ? 'disable' : 'line'} text="이벤트 중단" handleClick={() => handleModalSubmit('stop')} />
|
|
)}
|
|
{userInfo.auth_list?.some(auth => auth.id === authType.battleEventUpdate) && (
|
|
<Button
|
|
theme="primary"
|
|
text="이벤트 등록"
|
|
type="button"
|
|
handleClick={e => handleModalSubmit('regist')}
|
|
/>
|
|
)}
|
|
</ViewTableInfo>
|
|
<TableWrapper>
|
|
<TableStyle ref={tableRef}>
|
|
<caption></caption>
|
|
<thead>
|
|
<tr>
|
|
<th width="40"></th>
|
|
<th width="90">그룹</th>
|
|
<th width="70">이벤트 ID</th>
|
|
<th width="200">이벤트명</th>
|
|
<th width="90">게임모드</th>
|
|
<th width="80">반복</th>
|
|
<th width="100">기간 시작일(KST)</th>
|
|
<th width="100">기간 종료일(KST)</th>
|
|
<th width="100">이벤트 시작시간(KST)</th>
|
|
<th width="100">이벤트 종료시간(KST)</th>
|
|
<th width="90">이벤트 상태</th>
|
|
{/*<th width="90">라운드 시간</th>*/}
|
|
{/*<th width="90">배정포드</th>*/}
|
|
{/*<th width="70">라운드 수</th>*/}
|
|
<th width="70">핫타임</th>
|
|
<th width="100">확인 / 수정</th>
|
|
<th width="150">히스토리</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{dataList?.event_list?.map(battle => (
|
|
<tr key={battle.row_num}>
|
|
<td>
|
|
<CheckBox name={'select'} id={battle.id}
|
|
setData={(e) => handleSelectRow(e, battle)}
|
|
checked={isRowSelected(battle.id)} />
|
|
</td>
|
|
<td>{battle.group_id}</td>
|
|
<td>{battle.id}</td>
|
|
<td>{battle.event_name}</td>
|
|
<td>{battle.game_mode_id}</td>
|
|
<StatusWapper>
|
|
<StatusLabel $status={battle.repeat_type}>
|
|
{battleRepeatType.find(data => data.value === battle.repeat_type).name}
|
|
</StatusLabel>
|
|
</StatusWapper>
|
|
<td>{getDateOnly(convertKTCDate(battle.event_start_dt))}</td>
|
|
<td>{getDateOnly(battle.event_end_dt)}</td>
|
|
<td>{getTimeOnly(convertKTCDate(battle.event_start_dt))}</td>
|
|
<td>{getTimeOnly(endTime(convertKTCDate(battle.event_start_dt), battle.event_operation_time))}</td>
|
|
<StatusWapper>
|
|
<StatusLabel $status={battle.status}>
|
|
{battleEventStatus.find(data => data.value === battle.status).name}
|
|
</StatusLabel>
|
|
</StatusWapper>
|
|
{/*<td>{secondToMinutes(battle.round_time)}분</td>*/}
|
|
{/*<td>{battle.reward_group_id}</td>*/}
|
|
{/*<td>{battle.round_count}</td>*/}
|
|
<td>{battle.hot_time}</td>
|
|
<td>
|
|
<Button theme="line" text="상세보기"
|
|
handleClick={e => handleModalSubmit('detail', battle.id)} />
|
|
</td>
|
|
<td><Button theme="line" text="히스토리"
|
|
handleClick={e => handleModalSubmit('history', battle)} /></td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</TableStyle>
|
|
</TableWrapper>
|
|
|
|
<Pagination postsPerPage={searchParams.pageSize} totalPosts={dataList?.total_all} setCurrentPage={handlePageChange} currentPage={searchParams.currentPage} pageLimit={INITIAL_PAGE_LIMIT} />
|
|
|
|
{/*상세*/}
|
|
<BattleEventModal
|
|
modalType={modalType}
|
|
detailView={modalState.detailModal}
|
|
handleDetailView={() =>{
|
|
handleModalClose('detail');
|
|
handleSearch(updateSearchParams);
|
|
}}
|
|
content={detailData}
|
|
setDetailData={setDetailData}
|
|
configData={battleConfigData}
|
|
rewardData={battleRewardData}
|
|
gameModeData={gameModeData}
|
|
/>
|
|
|
|
<LogDetailModal
|
|
viewMode="changed"
|
|
detailView={modalState.historyModal}
|
|
handleDetailView={() => handleModalClose('history')}
|
|
changedData={historyData}
|
|
title="히스토리"
|
|
/>
|
|
|
|
</AnimatedPageWrapper>
|
|
)
|
|
};
|
|
|
|
export default withAuth(authType.battleEventRead)(BattleEvent);
|