diff --git a/src/apis/Log.js b/src/apis/Log.js index 91b5aac..1d0261e 100644 --- a/src/apis/Log.js +++ b/src/apis/Log.js @@ -58,24 +58,44 @@ export const getExcelProgress = async (token, taskId) => { export const getCurrencyList = async (token, startDate, endDate, order, size, currentPage) => { try { - const response = await Axios.get(`/api/v1/log/currency/list?start_dt=${startDate}&end_dt=${endDate}&orderby=${order}&page_no=${currentPage} - &page_size=${size}`, { + const response = await Axios.get(`/api/v1/log/currency/list?start_dt=${startDate}&end_dt=${endDate} + &orderby=${order}&page_no=${currentPage}&page_size=${size}`, { headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', }, }); - return response.data.data; + return response.data; } catch (error) { console.error('getCurrencyList API error:', error); throw error; } }; -export const getCurrencyDetailList = async (token, searchType, searchData, tranId, startDate, endDate, order, size, currentPage) => { +export const GameCurrencyLogExport = async (token, params, fileName) => { try { - const response = await Axios.get(`/api/v1/log/currency/detail/list?search_type=${searchType}&search_data=${searchData}&tran_id=${tranId}&start_dt=${startDate}&end_dt=${endDate} + await Axios.post(`/api/v1/log/currency/excel-export`, params, { + headers: { Authorization: `Bearer ${token}` }, + responseType: 'blob', + timeout: 300000 + }).then(response => { + + responseFileDownload(response, { + defaultFileName: fileName + }); + }); + } catch (e) { + if (e instanceof Error) { + throw new Error('GameCurrencyLogExport Error', e); + } + } +}; + +export const getCurrencyDetailList = async (token, searchType, searchData, tranId, logAction, currencyType, amountDeltaType, startDate, endDate, order, size, currentPage) => { + try { + const response = await Axios.get(`/api/v1/log/currency/detail/list?search_type=${searchType}&search_data=${searchData}&tran_id=${tranId} + &log_action=${logAction}¤cy_type=${currencyType}&amount_delta_type=${amountDeltaType}&start_dt=${startDate}&end_dt=${endDate} &orderby=${order}&page_no=${currentPage}&page_size=${size}`, { headers: { Authorization: `Bearer ${token}`, @@ -90,8 +110,9 @@ export const getCurrencyDetailList = async (token, searchType, searchData, tranI } }; -export const GameCurrencyLogExport = async (token, params) => { +export const GameCurrencyDetailLogExport = async (token, params, fileName) => { try { + console.log(params); await Axios.post(`/api/v1/log/currency/detail/excel-export`, params, { headers: { Authorization: `Bearer ${token}` }, responseType: 'blob', @@ -99,12 +120,12 @@ export const GameCurrencyLogExport = async (token, params) => { }).then(response => { responseFileDownload(response, { - defaultFileName: 'gameCurrencyLog' + defaultFileName: fileName }); }); } catch (e) { if (e instanceof Error) { - throw new Error('BusinessLogExport Error', e); + throw new Error('GameCurrencyDetailLogExport Error', e); } } }; \ No newline at end of file diff --git a/src/assets/data/adminConstants.js b/src/assets/data/adminConstants.js index bc7b52c..aaea92f 100644 --- a/src/assets/data/adminConstants.js +++ b/src/assets/data/adminConstants.js @@ -10,6 +10,7 @@ export const AUCTION_MIN_MINUTE_TIME = 15; // 15분 export const IMAGE_MAX_SIZE = 5242880; export const STORAGE_MAIL_COPY = 'copyMailData'; export const STORAGE_BUSINESS_LOG_SEARCH = 'businessLogSearchParam'; +export const STORAGE_GAME_LOG_CURRENCY_SEARCH = 'gameLogCurrencySearchParam'; export const LOG_ACTION_FAIL_CALIUM_ECHO = 'FailCaliumEchoSystem'; export { INITIAL_PAGE_SIZE, INITIAL_CURRENT_PAGE, INITIAL_PAGE_LIMIT }; diff --git a/src/assets/data/options.js b/src/assets/data/options.js index 92fa5f4..02e2558 100644 --- a/src/assets/data/options.js +++ b/src/assets/data/options.js @@ -6,13 +6,13 @@ export const languageType = [ export const TabGameLogList = [ { value: 'CURRENCY', name: '재화 로그' }, - { value: 'ITEM', name: '아이템 로그' }, + // { value: 'ITEM', name: '아이템 로그' }, // { value: 'TRADE', name: '거래 로그' }, ]; export const TabEconomicIndexList = [ { value: 'CURRENCY', name: '재화' }, - { value: 'ITEM', name: '아이템' }, + // { value: 'ITEM', name: '아이템' }, // { value: 'VBP', name: 'VBP' }, // { value: 'deco', name: '의상/타투' }, // { value: 'instance', name: '인스턴스' }, diff --git a/src/components/DataManage/CurrencyLogContent.js b/src/components/DataManage/CurrencyLogContent.js index 1102cb8..b5ab026 100644 --- a/src/components/DataManage/CurrencyLogContent.js +++ b/src/components/DataManage/CurrencyLogContent.js @@ -1,9 +1,8 @@ -import React, { Fragment, useMemo, useRef, useState } from 'react'; +import React, { Fragment, useEffect, useMemo, useRef, useState } from 'react'; import styled from 'styled-components'; import { CircularProgressWrapper, - DownloadContainer, FormWrapper, TableStyle, TableWrapper, @@ -12,22 +11,20 @@ import { amountDeltaType, CurrencyType } from '../../assets/data'; import { useTranslation } from 'react-i18next'; import { numberFormatter } from '../../utils'; import { TableSkeleton } from '../Skeleton/TableSkeleton'; -import { useAlert } from '../../context/AlertProvider'; -import { useLoading } from '../../context/LoadingProvider'; -import { alertTypes } from '../../assets/data/types'; import { CurrencyLogSearchBar, useCurrencyLogSearch } from '../searchBar'; import { TopButton, ViewTableInfo } from '../common'; import Pagination from '../common/Pagination/Pagination'; -import { INITIAL_PAGE_LIMIT } from '../../assets/data/adminConstants'; +import { + INITIAL_PAGE_LIMIT, + STORAGE_BUSINESS_LOG_SEARCH, + STORAGE_GAME_LOG_CURRENCY_SEARCH, +} from '../../assets/data/adminConstants'; import ExcelExportButton from '../common/button/ExcelExportButton'; import CircularProgress from '../common/CircularProgress'; -import { GameCurrencyLogExport } from '../../apis'; -const CurrencyLogContent = ({ userInfo }) => { +const CurrencyLogContent = ({ active }) => { const { t } = useTranslation(); const token = sessionStorage.getItem('token'); - const {showModal, showToast} = useAlert(); - const {withLoading} = useLoading(); const tableRef = useRef(null); const [downloadState, setDownloadState] = useState({ loading: false, @@ -46,6 +43,26 @@ const CurrencyLogContent = ({ userInfo }) => { updateSearchParams } = useCurrencyLogSearch(token, 500); + useEffect(() => { + if(active) { + // 세션 스토리지에서 복사된 메일 데이터 가져오기 + const paramsData = sessionStorage.getItem(STORAGE_GAME_LOG_CURRENCY_SEARCH); + + if (paramsData) { + const searchData = JSON.parse(paramsData); + + handleSearch({ + start_dt: new Date(searchData.start_dt), + end_dt: new Date(searchData.end_dt), + search_data: searchData.guid + }); + + // 사용 후 세션 스토리지 데이터 삭제 + sessionStorage.removeItem(STORAGE_GAME_LOG_CURRENCY_SEARCH); + } + } + }, [active]); + const tableHeaders = useMemo(() => { return [ // { id: 'logDay', label: '일자', width: '120px' }, @@ -59,29 +76,11 @@ const CurrencyLogContent = ({ userInfo }) => { { id: 'amountDeltaType', label: '증감유형', width: '120px' }, { id: 'deltaAmount', label: '수량', width: '120px' }, // { id: 'deltaAmount', label: '수량원본', width: '120px' }, + { id: 'currencyAmount', label: '잔량', width: '120px' }, ]; }, []); - const handleSubmit = async (type, param = null) => { - let params = {}; - - switch (type) { - case "gmLevelChangeSubmit": - showModal('USER_GM_CHANGE', { - type: alertTypes.confirm, - onConfirm: () => handleSubmit('gmLevelChange', param) - }); - break; - - case "userKickSubmit": - showModal('USER_KICK_CONFIRM', { - type: alertTypes.confirm, - onConfirm: () => handleSubmit('userKick') - }); - break; - - } - } + if(!active) return null; return ( <> @@ -100,7 +99,7 @@ const CurrencyLogContent = ({ userInfo }) => { { {amountDeltaType.find(data => data.value === item.amountDeltaType)?.name} {numberFormatter.formatCurrency(item.deltaAmount)} {/*{item.deltaAmount}*/} + {numberFormatter.formatCurrency(item.currencyAmount)} ))} @@ -162,11 +162,4 @@ const CurrencyLogContent = ({ userInfo }) => { ); }; -export default CurrencyLogContent; - -const StatusCell = styled.td` - display: flex; - justify-content: space-between; - align-items: center; - padding: 12px; -`; \ No newline at end of file +export default CurrencyLogContent; \ No newline at end of file diff --git a/src/components/IndexManage/CreditContent.js b/src/components/IndexManage/CreditContent.js index a47d95c..cddb38a 100644 --- a/src/components/IndexManage/CreditContent.js +++ b/src/components/IndexManage/CreditContent.js @@ -1,36 +1,31 @@ -import React, { Fragment, useEffect, useMemo, useRef, useState } from 'react'; -import { styled } from 'styled-components'; -import Button from '../../components/common/button/Button'; +import React, { Fragment, useMemo, useRef, useState } from 'react'; -import { CurrencyIndexExport, CurrencyIndexView } from '../../apis'; import { - SelectInput, TableStyle, - TableInfo, - ListOption, - InputLabel, FormWrapper, - DownloadContainer, TableWrapper, + TableWrapper, CircularProgressWrapper, TotalRow, } from '../../styles/Components'; -import { CreditSearchBar, CurrencyLogSearchBar, useCurrencyLogSearch } from '../searchBar'; -import { uniqBy } from 'lodash'; -import { sumBy } from 'lodash'; -import { TopButton, ViewTableInfo } from '../common'; +import { useCurrencyIndexSearch } from '../searchBar'; +import { Button, TopButton, ViewTableInfo } from '../common'; import { TableSkeleton } from '../Skeleton/TableSkeleton'; -import { amountDeltaType, CurrencyType } from '../../assets/data'; import { numberFormatter } from '../../utils'; -import Pagination from '../common/Pagination/Pagination'; -import { INITIAL_PAGE_LIMIT } from '../../assets/data/adminConstants'; -import { useAlert } from '../../context/AlertProvider'; -import { useLoading } from '../../context/LoadingProvider'; -import { alertTypes } from '../../assets/data/types'; +import {STORAGE_GAME_LOG_CURRENCY_SEARCH, } from '../../assets/data/adminConstants'; +import ExcelExportButton from '../common/button/ExcelExportButton'; +import CircularProgress from '../common/CircularProgress'; +import { useTranslation } from 'react-i18next'; +import CurrencyIndexSearchBar from '../searchBar/CurrencyIndexSearchBar'; +import { useNavigate } from 'react-router-dom'; const CreditContent = () => { + const { t } = useTranslation(); const token = sessionStorage.getItem('token'); - const {showModal, showToast} = useAlert(); - const {withLoading} = useLoading(); + const navigate = useNavigate(); const tableRef = useRef(null); + const [downloadState, setDownloadState] = useState({ + loading: false, + progress: 0 + }); const { searchParams, @@ -38,52 +33,88 @@ const CreditContent = () => { data: dataList, handleSearch, handleReset, - handlePageChange, - handleOrderByChange, - handlePageSizeChange, updateSearchParams - } = useCurrencyLogSearch(token, 500); + } = useCurrencyIndexSearch(token); const tableHeaders = useMemo(() => { return [ - // { id: 'logDay', label: '일자', width: '120px' }, - { id: 'logTime', label: '일시', width: '120px' }, + { id: 'logDay', label: '일자', width: '100px' }, { id: 'accountId', label: 'account ID', width: '80px' }, { id: 'userGuid', label: 'GUID', width: '200px' }, { id: 'userNickname', label: '아바타명', width: '150px' }, - { id: 'tranId', label: '트랜잭션 ID', width: '200px' }, - { id: 'action', label: '액션', width: '150px' }, - { id: 'currencyType', label: '재화종류', width: '120px' }, - { id: 'amountDeltaType', label: '증감유형', width: '120px' }, - { id: 'deltaAmount', label: '수량', width: '120px' }, + { id: 'sapphireAcquired', label: '사파이어 획득량', width: '80px' }, + { id: 'sapphireConsumed', label: '사파이어 소모량', width: '80px' }, + { id: 'goldAcquired', label: '골드 획득량', width: '80px' }, + { id: 'goldConsumed', label: '골드 소모량', width: '80px' }, + { id: 'caliumAcquired', label: '칼리움 획득량', width: '80px' }, + { id: 'caliumConsumed', label: '칼리움 소모량', width: '80px' }, + { id: 'beamAcquired', label: 'BEAM 획득량', width: '80px' }, + { id: 'beamConsumed', label: 'BEAM 소모량', width: '80px' }, + { id: 'rubyAcquired', label: '루비 획득량', width: '80px' }, + { id: 'rubyConsumed', label: '루비 소모량', width: '80px' }, + { id: 'sapphireNet', label: '사파이어 계', width: '80px' }, + { id: 'goldNet', label: '골드 계', width: '80px' }, + { id: 'caliumNet', label: '칼리움 계', width: '80px' }, + { id: 'beamNet', label: 'BEAM 계', width: '80px' }, + { id: 'rubyNet', label: '루비 계', width: '80px' }, + { id: 'totalCurrencies', label: '활동 수', width: '80px' }, + { id: 'detail', label: '상세', width: '100px' }, ]; }, []); - const handleSubmit = async (type, param = null) => { - let params = {}; + const totals = useMemo(() => { + if (!dataList?.currency_list?.length) return null; + return dataList.currency_list.reduce((acc, item) => { + return { + sapphireAcquired: (acc.sapphireAcquired || 0) + (item.sapphireAcquired || 0), + sapphireConsumed: (acc.sapphireConsumed || 0) + (item.sapphireConsumed || 0), + goldAcquired: (acc.goldAcquired || 0) + (item.goldAcquired || 0), + goldConsumed: (acc.goldConsumed || 0) + (item.goldConsumed || 0), + caliumAcquired: (acc.caliumAcquired || 0) + (item.caliumAcquired || 0), + caliumConsumed: (acc.caliumConsumed || 0) + (item.caliumConsumed || 0), + beamAcquired: (acc.beamAcquired || 0) + (item.beamAcquired || 0), + beamConsumed: (acc.beamConsumed || 0) + (item.beamConsumed || 0), + rubyAcquired: (acc.rubyAcquired || 0) + (item.rubyAcquired || 0), + rubyConsumed: (acc.rubyConsumed || 0) + (item.rubyConsumed || 0), + sapphireNet: (acc.sapphireNet || 0) + (item.sapphireNet || 0), + goldNet: (acc.goldNet || 0) + (item.goldNet || 0), + caliumNet: (acc.caliumNet || 0) + (item.caliumNet || 0), + beamNet: (acc.beamNet || 0) + (item.beamNet || 0), + rubyNet: (acc.rubyNet || 0) + (item.rubyNet || 0), + totalCurrencies: (acc.totalCurrencies || 0) + (item.totalCurrencies || 0), + }; + }, {}); + }, [dataList?.currency_list]); + + const handleModalSubmit = async (type, param = null) => { switch (type) { - case "gmLevelChangeSubmit": - showModal('USER_GM_CHANGE', { - type: alertTypes.confirm, - onConfirm: () => handleSubmit('gmLevelChange', param) - }); - break; + case "detail": + const params = { + tab: "CURRENCY", + start_dt: (() => { + const date = new Date(param.logDay); + return date; + })(), + end_dt: (() => { + const date = new Date(param.logDay); + date.setDate(date.getDate() + 1); + return date; + })(), + guid: param.userGuid + }; - case "userKickSubmit": - showModal('USER_KICK_CONFIRM', { - type: alertTypes.confirm, - onConfirm: () => handleSubmit('userKick') - }); + // 복사한 데이터를 세션 스토리지에 저장 + sessionStorage.setItem(STORAGE_GAME_LOG_CURRENCY_SEARCH, JSON.stringify(params)); + navigate('/datamanage/gamelogview'); break; - } } return ( <> - { if (executeSearch) { @@ -95,9 +126,23 @@ const CreditContent = () => { onReset={handleReset} /> - - - + + + {downloadState.loading && ( + + + + )} {dataLoading ? : <> @@ -111,33 +156,61 @@ const CreditContent = () => { - {dataList?.currency_detail_list?.map((item, index) => ( + {totals && ( + + 합계 + {numberFormatter.formatCurrency(totals.sapphireAcquired)} + {numberFormatter.formatCurrency(totals.sapphireConsumed)} + {numberFormatter.formatCurrency(totals.goldAcquired)} + {numberFormatter.formatCurrency(totals.goldConsumed)} + {numberFormatter.formatCurrency(totals.caliumAcquired)} + {numberFormatter.formatCurrency(totals.caliumConsumed)} + {numberFormatter.formatCurrency(totals.beamAcquired)} + {numberFormatter.formatCurrency(totals.beamConsumed)} + {numberFormatter.formatCurrency(totals.rubyAcquired)} + {numberFormatter.formatCurrency(totals.rubyConsumed)} + {numberFormatter.formatCurrency(totals.sapphireNet)} + {numberFormatter.formatCurrency(totals.goldNet)} + {numberFormatter.formatCurrency(totals.caliumNet)} + {numberFormatter.formatCurrency(totals.beamNet)} + {numberFormatter.formatCurrency(totals.rubyNet)} + {totals.totalCurrencies} + - + + )} + {dataList?.currency_list?.map((item, index) => ( - {item.logTime} + {item.logDay} {item.accountId} {item.userGuid} {item.userNickname} - {item.tranId} - {item.action} - {CurrencyType.find(data => data.value === item.currencyType).name} - {amountDeltaType.find(data => data.value === item.amountDeltaType).name} - {numberFormatter.formatCurrency(item.deltaAmount)} + {numberFormatter.formatCurrency(item.sapphireAcquired)} + {numberFormatter.formatCurrency(item.sapphireConsumed)} + {numberFormatter.formatCurrency(item.goldAcquired)} + {numberFormatter.formatCurrency(item.goldConsumed)} + {numberFormatter.formatCurrency(item.caliumAcquired)} + {numberFormatter.formatCurrency(item.caliumConsumed)} + {numberFormatter.formatCurrency(item.beamAcquired)} + {numberFormatter.formatCurrency(item.beamConsumed)} + {numberFormatter.formatCurrency(item.rubyAcquired)} + {numberFormatter.formatCurrency(item.rubyConsumed)} + {numberFormatter.formatCurrency(item.sapphireNet)} + {numberFormatter.formatCurrency(item.goldNet)} + {numberFormatter.formatCurrency(item.caliumNet)} + {numberFormatter.formatCurrency(item.beamNet)} + {numberFormatter.formatCurrency(item.rubyNet)} + {item.totalCurrencies} + +