From 38fa323db6a80880935c95181a4cb37145647b3b Mon Sep 17 00:00:00 2001 From: bcjang Date: Thu, 12 Jun 2025 14:16:26 +0900 Subject: [PATCH] =?UTF-8?q?Log=20currency=20=EA=B4=80=EB=A0=A8=20API=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EC=B6=94=EA=B0=80=20components=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=20=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95=20excelExpo?= =?UTF-8?q?rtButton=EC=97=90=20functionName=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EA=B2=8C=EC=9E=84=20=EB=A1=9C=EA=B7=B8=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/Log.js | 119 ++++----- src/apis/index.js | 1 + src/assets/data/index.js | 5 +- src/assets/data/options.js | 22 +- src/assets/data/types.js | 2 +- src/pages/DataManage/BusinessLogView.js | 20 +- src/pages/DataManage/ContentsView.js | 2 +- src/pages/DataManage/CryptView.js | 2 +- src/pages/DataManage/GameLogView.js | 302 +++------------------- src/pages/DataManage/LandInfoView.js | 4 +- src/pages/DataManage/UserView.js | 16 +- src/pages/IndexManage/EconomicIndex.js | 106 ++------ src/pages/ServiceManage/BattleEvent.js | 2 +- src/pages/ServiceManage/Event.js | 2 +- src/pages/ServiceManage/EventRegist.js | 6 +- src/pages/ServiceManage/LandAuction.js | 2 +- src/pages/ServiceManage/Mail.js | 2 +- src/pages/ServiceManage/MailRegist.js | 6 +- src/pages/ServiceManage/MenuBanner.js | 2 +- src/pages/ServiceManage/MenuBanner_bak.js | 4 +- src/pages/UserManage/DataInitView.js | 2 +- 21 files changed, 171 insertions(+), 458 deletions(-) diff --git a/src/apis/Log.js b/src/apis/Log.js index 96b5acd..91b5aac 100644 --- a/src/apis/Log.js +++ b/src/apis/Log.js @@ -1,6 +1,6 @@ //운영 정보 관리 - 로그 api 연결 -import { Axios } from '../utils'; +import { Axios, responseFileDownload } from '../utils'; // 비즈니스 로그 조회 export const BusinessLogList = async (token, params) => { @@ -25,67 +25,9 @@ export const BusinessLogExport = async (token, params) => { responseType: 'blob', timeout: 300000 }).then(response => { - if (!response.data) { - console.log(response); - throw new Error('No data received'); - } - - const contentType = response.headers['content-type'] || response.headers['Content-Type']; - const contentDisposition = response.headers['content-disposition'] || response.headers['Content-Disposition']; - - // Excel이나 ZIP 파일이 아닌 경우 - if (!contentType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') && - !contentType.includes('application/zip')) { - console.log(response); - throw new Error(`잘못된 파일 형식입니다. Content-Type: ${contentType}`); - } - - let fileName = 'businessLog'; - let fileExtension = '.xlsx'; - let mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; - - // ZIP 파일인지 확인 - if (contentType && contentType.includes('application/zip')) { - fileExtension = '.zip'; - mimeType = 'application/zip'; - fileName = 'businessLog_multiple_files'; - } - - // Content-Disposition에서 파일명 추출 - if (contentDisposition) { - const fileNameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); - if (fileNameMatch && fileNameMatch[1]) { - const extractedFileName = decodeURIComponent(fileNameMatch[1].replace(/['"]/g, '')); - fileName = extractedFileName; - } - } else { - // Content-Disposition이 없으면 기본 파일명 사용 - fileName = fileName + fileExtension; - } - - const blob = new Blob([response.data], { type: mimeType }); - - // 빈 파일 체크 - if (blob.size === 0) { - throw new Error('다운로드된 파일이 비어있습니다.'); - } - - // 너무 작은 파일 체크 (실제 Excel 파일은 최소 몇 KB 이상) - if (blob.size < 1024) { // 1KB 미만 - throw new Error('파일 크기가 너무 작습니다. 올바른 Excel 파일이 아닐 수 있습니다.'); - } - - const href = URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = href; - link.download = fileName; - link.style.display = 'none'; - link.rel = 'noopener noreferrer'; - document.body.appendChild(link); - link.click(); - - link.remove(); - window.URL.revokeObjectURL(href); + responseFileDownload(response, { + defaultFileName: 'businessLog' + }); }); } catch (e) { if (e instanceof Error) { @@ -112,4 +54,57 @@ export const getExcelProgress = async (token, taskId) => { console.error('Progress API error:', error); throw error; } +}; + +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}`, { + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); + + return response.data.data; + } catch (error) { + console.error('getCurrencyList API error:', error); + throw error; + } +}; + +export const getCurrencyDetailList = async (token, searchType, searchData, tranId, 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}&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; + } catch (error) { + console.error('getCurrencyDetailList API error:', error); + throw error; + } +}; + +export const GameCurrencyLogExport = async (token, params) => { + try { + await Axios.post(`/api/v1/log/currency/detail/excel-export`, params, { + headers: { Authorization: `Bearer ${token}` }, + responseType: 'blob', + timeout: 300000 + }).then(response => { + + responseFileDownload(response, { + defaultFileName: 'gameCurrencyLog' + }); + }); + } catch (e) { + if (e instanceof Error) { + throw new Error('BusinessLogExport Error', e); + } + } }; \ No newline at end of file diff --git a/src/apis/index.js b/src/apis/index.js index 976da98..2449418 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -17,6 +17,7 @@ export * from './Calium'; export * from './Land'; export * from './Menu'; export * from './OpenAI'; +export * from './Log'; const apiModules = {}; const allApis = {}; diff --git a/src/assets/data/index.js b/src/assets/data/index.js index 2b875c9..7f27c2f 100644 --- a/src/assets/data/index.js +++ b/src/assets/data/index.js @@ -1,4 +1,4 @@ -export {authType, ivenTabType, modalTypes, TabList, tattooSlot, commonStatus, ViewTitleCountType, landAuctionStatusType} from './types' +export {authType, ivenTabType, modalTypes, TabUserList, tattooSlot, commonStatus, ViewTitleCountType, landAuctionStatusType} from './types' export { mailSendType, mailType, @@ -7,7 +7,7 @@ export { adminLevelType, logOption, eventStatus, - currencyType, + currencyItemCode, blockStatus, blockSanctions, blockPeriod, @@ -27,5 +27,6 @@ export { opYNType, opUserSessionType, opMailType, + amountDeltaType } from './options' export {benItems, MinuteList, HourList, caliumRequestInitData, STATUS_STYLES, months, PAGE_SIZE_OPTIONS, ORDER_OPTIONS} from './data' \ No newline at end of file diff --git a/src/assets/data/options.js b/src/assets/data/options.js index 89f7f8b..92fa5f4 100644 --- a/src/assets/data/options.js +++ b/src/assets/data/options.js @@ -4,6 +4,20 @@ export const languageType = [ { value: 'JA', name: '일본어' }, ]; +export const TabGameLogList = [ + { value: 'CURRENCY', name: '재화 로그' }, + { value: 'ITEM', name: '아이템 로그' }, + // { value: 'TRADE', name: '거래 로그' }, +]; + +export const TabEconomicIndexList = [ + { value: 'CURRENCY', name: '재화' }, + { value: 'ITEM', name: '아이템' }, + // { value: 'VBP', name: 'VBP' }, + // { value: 'deco', name: '의상/타투' }, + // { value: 'instance', name: '인스턴스' }, +]; + export const mailSendType = [ { value: 'ALL', name: '전체' }, { value: 'RESERVE_SEND', name: '예약 발송' }, @@ -81,7 +95,7 @@ export const landAuctionStatus = [ { value: 'FAIL', name: '실패' }, ]; -export const currencyType = [ +export const currencyItemCode = [ { value: '19010001', name: '골드' }, { value: '19010002', name: '사파이어' }, { value: '19010005', name: '루비' }, @@ -205,6 +219,12 @@ export const CurrencyType = [ {value: 'Ruby', name: '루비' } ] +export const amountDeltaType = [ + {value: 'Acquire', name: '획득' }, + {value: 'Consume', name: '소모' }, + {value: 'None', name: '' }, +] + export const battleEventStatus = [ { value: 'ALL', name: '전체' }, { value: 'WAIT', name: '대기' }, diff --git a/src/assets/data/types.js b/src/assets/data/types.js index a16a1dc..b4d6af3 100644 --- a/src/assets/data/types.js +++ b/src/assets/data/types.js @@ -75,7 +75,7 @@ export const adminAuthLevel = { DEVELOPER: "Developer", } -export const TabList = [ +export const TabUserList = [ { title: '기본정보' }, { title: '아바타' }, { title: '의상' }, diff --git a/src/pages/DataManage/BusinessLogView.js b/src/pages/DataManage/BusinessLogView.js index c18aafd..395a6de 100644 --- a/src/pages/DataManage/BusinessLogView.js +++ b/src/pages/DataManage/BusinessLogView.js @@ -10,7 +10,7 @@ import { TableDetailContainer, TableDetailFlex, TableDetailColumn, - DetailTableInfo, + DetailTableInfo, DownloadContainer, CircularProgressWrapper, } from '../../styles/Components'; import { withAuth } from '../../hooks/hook'; @@ -23,7 +23,7 @@ import { ViewTableInfo, } from '../../components/common'; import { TableSkeleton } from '../../components/Skeleton/TableSkeleton'; -import BusinessLogSearchBar, { useBusinessLogSearch } from '../../components/ServiceManage/searchBar/BusinessLogSearchBar'; +import BusinessLogSearchBar, { useBusinessLogSearch } from '../../components/searchBar/BusinessLogSearchBar'; import styled from 'styled-components'; import CircularProgress from '../../components/common/CircularProgress'; // import MessageInput from '../../components/common/input/MessageInput'; @@ -34,7 +34,6 @@ import { } from '../../assets/data/adminConstants'; import ExcelExportButton from '../../components/common/button/ExcelExportButton'; import Pagination from '../../components/common/Pagination/Pagination'; -import useCommonSearchOld from '../../hooks/useCommonSearchOld'; const BusinessLogView = () => { const token = sessionStorage.getItem('token'); @@ -186,6 +185,7 @@ const BusinessLogView = () => { { ); }; -export default withAuth(authType.businessLogRead)(BusinessLogView); - -const DownloadContainer = styled.div` - display: flex; - align-items: center; - gap: 10px; -`; - -const CircularProgressWrapper = styled.div` - display: flex; - align-items: center; - justify-content: center; -`; \ No newline at end of file +export default withAuth(authType.businessLogRead)(BusinessLogView); \ No newline at end of file diff --git a/src/pages/DataManage/ContentsView.js b/src/pages/DataManage/ContentsView.js index e3cc218..c7d4242 100644 --- a/src/pages/DataManage/ContentsView.js +++ b/src/pages/DataManage/ContentsView.js @@ -4,7 +4,7 @@ import { Fragment, useState } from 'react'; import { Title, TableStyle, BtnWrapper, ButtonClose, ModalText } from '../../styles/Components'; -import LandSearchBar from '../../components/DataManage/LandSearchBar'; +import LandSearchBar from '../../components/searchBar/LandSearchBar'; import Button from '../../components/common/button/Button'; import QuestDetailModal from '../../components/DataManage/QuestDetailModal'; import LandDetailModal from '../../components/DataManage/LandDetailModal'; diff --git a/src/pages/DataManage/CryptView.js b/src/pages/DataManage/CryptView.js index c036173..6c2b2a7 100644 --- a/src/pages/DataManage/CryptView.js +++ b/src/pages/DataManage/CryptView.js @@ -3,7 +3,7 @@ import { Fragment, useState } from 'react'; import { Title, TableStyle, ButtonClose, ModalText, BtnWrapper } from '../../styles/Components'; -import UserSearchBar from '../../components/DataManage/UserSearchBar'; +import UserSearchBar from '../../components/searchBar/UserSearchBar'; import Modal from '../../components/common/modal/Modal'; import Button from '../../components/common/button/Button'; diff --git a/src/pages/DataManage/GameLogView.js b/src/pages/DataManage/GameLogView.js index 64bb1eb..ebc4f4c 100644 --- a/src/pages/DataManage/GameLogView.js +++ b/src/pages/DataManage/GameLogView.js @@ -4,23 +4,33 @@ import { Link } from 'react-router-dom'; import Button from '../../components/common/button/Button'; import Pagination from '../../components/common/Pagination/Pagination'; -import DatePicker, { registerLocale } from 'react-datepicker'; +import { registerLocale } from 'react-datepicker'; import { ko } from 'date-fns/esm/locale'; import 'react-datepicker/dist/react-datepicker.css'; -import { getMonth, getYear } from 'date-fns'; -import range from 'lodash/range'; -import { Title, SelectInput, BtnWrapper, TableStyle, TableInfo, ListCount, ListOption, ButtonClose, ModalText } from '../../styles/Components'; +import { + Title, + SelectInput, + BtnWrapper, + TableStyle, + TableInfo, + ListCount, + ListOption, + ButtonClose, + ModalText, + TabScroll, TabItem, TabWrapper, +} from '../../styles/Components'; import { styled } from 'styled-components'; -import ItemLogSearchBar from '../../components/DataManage/ItemLogSearchBar'; -import GoodsLogSearchBar from '../../components/DataManage/CreditLogSearchBar'; -import TradeLogSerchBar from '../../components/DataManage/TradeLogSearchBar'; import Modal from '../../components/common/modal/Modal'; import { useNavigate } from 'react-router-dom'; import { authList } from '../../store/authList'; import { useRecoilValue } from 'recoil'; +import { withAuth } from '../../hooks/hook'; +import { authType, TabUserList } from '../../assets/data'; +import { TabGameLogList } from '../../assets/data/options'; +import CurrencyLogContent from '../../components/DataManage/CurrencyLogContent'; registerLocale('ko', ko); @@ -41,7 +51,6 @@ const ItemLogContent = () => { ]; return ( <> - 총 : 117건 / 000 건 @@ -98,193 +107,8 @@ const ItemLogContent = () => { ); }; -const GoodsLogContent = () => { - const mokupData = [ - { - date: '2023-08-05 12:11:32', - name: '홍길동', - id: '16CD2ECD-4798-46CE-9B6B-F952CF11F196', - gold: '99800', - blue: '400', - black: '500', - red: '500', - action: '소진', - location: '유저 거래', - goldchange: '-', - bluechange: '-100', - blackchange: '-', - redchange: '-', - key: 'User_trade_key', - }, - ]; - return ( - <> - - - 총 : 117건 / 000 건 - - - - - - - - - -