component 정리

currencyLogSearchBar 생성
currencyLogCOntent 생성
excelExportButton api호출 방식 수정
This commit is contained in:
2025-06-12 14:08:11 +09:00
parent dc7934d906
commit 6f9f0307ac
52 changed files with 791 additions and 1143 deletions

View File

@@ -1,312 +1,148 @@
import { useEffect, useState } from 'react';
import React, { Fragment, useEffect, useMemo, useRef, useState } from 'react';
import { styled } from 'styled-components';
import Button from '../../components/common/button/Button';
import { CurrencyIndexExport, CurrencyIndexView } from '../../apis';
import { SelectInput, TableStyle, TableInfo, ListOption, InputLabel } from '../../styles/Components';
import {
SelectInput,
TableStyle,
TableInfo,
ListOption,
InputLabel,
FormWrapper,
DownloadContainer, TableWrapper,
} from '../../styles/Components';
import CreditSeacrhBar from '../../components/IndexManage/CreditSearchBar';
import { CreditSearchBar, CurrencyLogSearchBar, useCurrencyLogSearch } from '../searchBar';
import { uniqBy } from 'lodash';
import { sumBy } from 'lodash';
import { 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';
const CreditContent = () => {
const token = sessionStorage.getItem('token');
let d = new Date();
const START_DATE = new Date(new Date(d.setDate(d.getDate() - 1)).setHours(0, 0, 0, 0));
const END_DATE = new Date();
const CURRENCY_LIST = [
{ "key": "Gold", "name": "골드" },
{ "key": "Sapphire", "name": "사파이어" },
{ "key": "Calium", "name": "칼리움" },
{ "key": "Onyxium", "name": "오닉시움" }
];
const {showModal, showToast} = useAlert();
const {withLoading} = useLoading();
const tableRef = useRef(null);
const [sendDate, setSendDate] = useState(START_DATE);
const [finishDate, setFinishDate] = useState(END_DATE);
const [currencyType, setCurrencyType] = useState('Gold');
const [currencyText, setCurrencyText] = useState('골드');
const {
searchParams,
loading: dataLoading,
data: dataList,
handleSearch,
handleReset,
handlePageChange,
handleOrderByChange,
handlePageSizeChange,
updateSearchParams
} = useCurrencyLogSearch(token, 500);
const [dataList, setDataList] = useState([]);
const [routeData, setRouteData] = useState([]);
const tableHeaders = useMemo(() => {
return [
// { id: 'logDay', label: '일자', width: '120px' },
{ id: 'logTime', label: '일시', width: '120px' },
{ 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' },
];
}, []);
const handleSubmit = async (type, param = null) => {
let params = {};
useEffect(() => {
fetchData(sendDate, finishDate, currencyType);
}, [currencyType]);
switch (type) {
case "gmLevelChangeSubmit":
showModal('USER_GM_CHANGE', {
type: alertTypes.confirm,
onConfirm: () => handleSubmit('gmLevelChange', param)
});
break;
const fetchData = async (startDate, endDate) => {
const newStartDate = new Date(startDate);
const newEndDate = new Date(endDate);
case "userKickSubmit":
showModal('USER_KICK_CONFIRM', {
type: alertTypes.confirm,
onConfirm: () => handleSubmit('userKick')
});
break;
const startDateToLocal =
newStartDate.getFullYear() +
'-' +
(newStartDate.getMonth() + 1 < 9 ? '0' + (newStartDate.getMonth() + 1) : newStartDate.getMonth() + 1) +
'-' +
(newStartDate.getDate() < 9 ? '0' + newStartDate.getDate() : newStartDate.getDate());
const endDateToLocal =
newEndDate.getFullYear() +
'-' +
(newEndDate.getMonth() + 1 < 9 ? '0' + (newEndDate.getMonth() + 1) : newEndDate.getMonth() + 1) +
'-' +
(newEndDate.getDate() < 9 ? '0' + newEndDate.getDate() : newEndDate.getDate());
setDataList(await CurrencyIndexView(token, startDateToLocal, endDateToLocal, currencyType));
setSendDate(startDateToLocal);
setFinishDate(endDateToLocal);
setRoutArray(await CurrencyIndexView(token, startDateToLocal, endDateToLocal, currencyType));
};
const handleCurrencyChange = e => {
let value = e.target.value;
setCurrencyType(value);
CURRENCY_LIST.filter(data => data.key === value).map(data => {
setCurrencyText(data.name);
});
};
//route data
const setRoutArray = async (data) => {
let routeArray = [];
let routeAcqArr = [];
let routeConArr = [];
//생산량 route
data.list && data.list[0].daily_data.filter(routeData => routeData.delta_type === 'ACQUIRE').map(routeData => {
routeData.data.map(routeData => {
if(!routeAcqArr.includes(routeData.route) ){
routeAcqArr.push(routeData.route);
}
})
});
routeArray.ACQUIRE = routeAcqArr;
//소진량 route
data.list && data.list[0].daily_data.filter(routeData => routeData.delta_type === 'CONSUME').map(routeData => {
routeData.data.map(routeData => {
if(!routeConArr.includes(routeData.route) ){
routeConArr.push(routeData.route);
}
})
});
routeArray.CONSUME = routeConArr;
setRouteData(routeArray);
};
// 엑셀 다운로드
const handleXlsxExport = () => {
const fileName = 'Caliverse_Credit_Index.xlsx';
CurrencyIndexExport(token, fileName, sendDate, finishDate, currencyType);
};
}
}
return (
<>
<CreditSeacrhBar fetchData={fetchData} />
<TableInfo2>
<SelectInput onChange={handleCurrencyChange}>
{CURRENCY_LIST.map((item, index) => (
<option value={item.key} key={index}>
{item.name}
</option>
))}
</SelectInput>
<ListOption>
<Button theme="line" text="엑셀 다운로드" handleClick={handleXlsxExport} />
</ListOption>
</TableInfo2>
<TableWrapper>
<EconomicTable>
<thead>
<tr>
<th colSpan="2" className="text-center" width="300">
Product
</th>
{dataList.list && uniqBy(dataList.list, 'date').map(data =>
<th width="160" key={data.date}>{data.date}</th>
)}
</tr>
</thead>
<tbody>
<tr>
<TableTitle colSpan="2">(Total) {currencyText} 생산량</TableTitle>
{dataList.list &&
dataList.list.map((data) =>
(data.total).filter(totalData => data.date === totalData.date && totalData.delta_type === 'ACQUIRE')
.map((totalData, index) => (
<TableData key={index}
$state={totalData.dif !== "" && totalData.dif !== "Infinity" ? "danger" : ""}>
{totalData.quantity}
{
totalData.dif !== "" && totalData.dif !== "Infinity"
? (<span>({totalData.dif})</span>)
: ("")
}
</TableData>
)
))
}
</tr>
<tr>
<TableTitle colSpan="2">(Total) {currencyText} 소진량</TableTitle>
{dataList.list &&
dataList.list.map((data) =>
(data.total).filter(totalData => data.date === totalData.date && totalData.delta_type === 'CONSUME')
.map((totalData, index) => (
<TableData key={index}
$state={totalData.dif !== "" && totalData.dif !== "Infinity" ? "danger" : ""}>
{totalData.quantity}
{
totalData.dif !== "" && totalData.dif !== "Infinity"
? (<span>({totalData.dif})</span>)
: ("")
}
</TableData>
)
))
}
</tr>
<tr>
<TableTitle colSpan="2">(Total) {currencyText} 보유량</TableTitle>
{dataList.list &&
dataList.list.map((data, index) => (
<TableData key={index}>
{sumBy(
data.total.filter(totalData => data.date === totalData.date && totalData.delta_type === 'ACQUIRE'),
'quantity',
) -
sumBy(
data.total.filter(totalData => data.date === totalData.date && totalData.delta_type === 'CONSUME'),
'quantity',
)}
</TableData>
))
}
</tr>
{/* 획득 GET */}
{
routeData.ACQUIRE && routeData.ACQUIRE.map((route, index) => (
<tr key={index}>
<TableTitle>GET</TableTitle>
<TableTitle>{route}</TableTitle>
{dataList.list &&
dataList.list.map((data) =>
data.daily_data.filter(dailyData => data.date === dailyData.date && dailyData.delta_type === 'ACQUIRE')
.map(dailyData => (dailyData.data).filter(routeData => data.date === routeData.date && routeData.route === route)
.map((routeData, i) => (
<TableData key={i} data={routeData.date}>{routeData.quantity}</TableData>
)))
)
}
</tr>
))
<FormWrapper>
<CurrencyLogSearchBar
searchParams={searchParams}
onSearch={(newParams, executeSearch = true) => {
if (executeSearch) {
handleSearch(newParams);
} else {
updateSearchParams(newParams);
}
{/* 소진 USE CONSUME */}
{
routeData.CONSUME && routeData.CONSUME.map((route, index) => (
<tr key={index}>
<TableTitle>USE</TableTitle>
<TableTitle>{route}</TableTitle>
{dataList.list &&
dataList.list.map((data) =>
data.daily_data.filter(dailyData => data.date === dailyData.date && dailyData.delta_type === 'CONSUME')
.map(dailyData => (dailyData.data).filter(routeData => data.date === routeData.date && routeData.route === route)
.map((routeData, i) => (
<TableData key={i} data={routeData.date}>{routeData.quantity}</TableData>
)))
)
}
</tr>
))
}
</tbody>
</EconomicTable>
</TableWrapper>
}}
onReset={handleReset}
/>
</FormWrapper>
<ViewTableInfo orderType="asc" pageType="B" total={dataList?.total} total_all={dataList?.total_all}>
<DownloadContainer>
</DownloadContainer>
</ViewTableInfo>
{dataLoading ? <TableSkeleton width='100%' count={15} /> :
<>
<TableWrapper>
<TableStyle ref={tableRef}>
<thead>
<tr>
{tableHeaders.map(header => (
<th key={header.id} width={header.width}>{header.label}</th>
))}
</tr>
</thead>
<tbody>
{dataList?.currency_detail_list?.map((item, index) => (
<Fragment key={index}>
<tr>
<td>{item.logTime}</td>
<td>{item.accountId}</td>
<td>{item.userGuid}</td>
<td>{item.userNickname}</td>
<td>{item.tranId}</td>
<td>{item.action}</td>
<td>{CurrencyType.find(data => data.value === item.currencyType).name}</td>
<td>{amountDeltaType.find(data => data.value === item.amountDeltaType).name}</td>
<td>{numberFormatter.formatCurrency(item.deltaAmount)}</td>
</tr>
</Fragment>
))}
</tbody>
</TableStyle>
</TableWrapper>
{dataList?.currency_detail_list &&
<Pagination
postsPerPage={searchParams.page_size}
totalPosts={dataList?.total_all}
setCurrentPage={handlePageChange}
currentPage={searchParams.page_no}
pageLimit={INITIAL_PAGE_LIMIT}
/>
}
<TopButton />
</>
}
</>
);
};
export default CreditContent;
const TableWrapper = styled.div`
width: 100%;
min-width: 680px;
overflow: auto;
&::-webkit-scrollbar {
height: 4px;
}
&::-webkit-scrollbar-thumb {
background: #666666;
}
&::-webkit-scrollbar-track {
background: #d9d9d9;
}
${TableStyle} {
width: 100%;
min-width: 900px;
th {
&.cell-nru {
background: #f0f0f0;
border-left: 1px solid #aaa;
border-right: 1px solid #aaa;
}
}
td {
&.blank {
background: #f9f9f9;
}
&.cell-nru {
background: #fafafa;
border-left: 1px solid #aaa;
border-right: 1px solid #aaa;
}
}
}
`;
const TableInfo2 = styled(TableInfo)`
justify-content: space-between;
${InputLabel} {
font-size: 12px;
}
${SelectInput} {
width: auto;
min-width: 100px;
height: 24px;
}
`;
const TableDate = styled.th`
color: ${props => (props.$state === 'danger' ? '#d60000' : '#2c2c2c')};
`;
const TableData = styled.td`
background: ${props => (props.$state === 'danger' ? '#d60000' : props.$state === 'blank' ? '#F9F9F9' : 'transparent')};
color: ${props => (props.$state === 'danger' ? '#fff' : '#2c2c2c')};
`;
const perData = styled.span`
display: ${props => (props.$view === 'hidden' ? 'none' : 'block')};
`;
const TableTitle = styled.td`
text-align: center;
`;
const EconomicTable = styled(TableStyle)`
${TableData} {
text-align: left;
}
tbody {
tr:nth-child(1),
tr:nth-child(2),
tr:nth-child(3) {
background: #f5fcff;
}
}
`;
export default CreditContent;